From 7038de3c2a555f0ce2c971878fca713833964637 Mon Sep 17 00:00:00 2001 From: jpbl <jpbl> Date: Wed, 9 Nov 2005 20:14:02 +0000 Subject: [PATCH] *** empty log message *** --- src/gui/qt/Account.cpp | 60 + src/gui/qt/Account.hpp | 67 + src/gui/qt/Call.cpp | 141 ++ src/gui/qt/Call.hpp | 142 ++ src/gui/qt/CallManager.hpp | 30 + src/gui/qt/CallManagerImpl.cpp | 68 + src/gui/qt/CallManagerImpl.hpp | 53 + src/gui/qt/CallStatus.cpp | 56 + src/gui/qt/CallStatus.hpp | 41 + src/gui/qt/CallStatusFactory.hpp | 29 + src/gui/qt/ConfigurationManager.hpp | 30 + src/gui/qt/ConfigurationManagerImpl.cpp | 152 ++ src/gui/qt/ConfigurationManagerImpl.hpp | 158 ++ src/gui/qt/ConfigurationPanel.ui | 1530 +++++++++++++++++ src/gui/qt/ConfigurationPanel.ui.h | 358 ++++ src/gui/qt/ConfigurationPanelImpl.cpp | 71 + src/gui/qt/ConfigurationPanelImpl.hpp | 69 + src/gui/qt/DebugOutput.hpp | 30 + src/gui/qt/DebugOutputImpl.cpp | 32 + src/gui/qt/DebugOutputImpl.hpp | 37 + src/gui/qt/Event.cpp | 73 + src/gui/qt/Event.hpp | 63 + src/gui/qt/EventFactory.hpp | 98 ++ src/gui/qt/EventFactory.inl | 95 + src/gui/qt/Factory.hpp | 58 + src/gui/qt/Factory.inl | 52 + src/gui/qt/INSTALL | 1 + src/gui/qt/JPushButton.cpp | 153 ++ src/gui/qt/JPushButton.hpp | 80 + src/gui/qt/Launcher.cpp | 93 + src/gui/qt/Launcher.hpp | 52 + src/gui/qt/NumericKeypad.cpp | 264 +++ src/gui/qt/NumericKeypad.hpp | 79 + src/gui/qt/ObjectFactory.hpp | 98 ++ src/gui/qt/ObjectFactory.inl | 95 + src/gui/qt/ObjectPool.hpp | 53 + src/gui/qt/ObjectPool.inl | 51 + src/gui/qt/PhoneLine.cpp | 435 +++++ src/gui/qt/PhoneLine.hpp | 185 ++ src/gui/qt/PhoneLineButton.cpp | 113 ++ src/gui/qt/PhoneLineButton.hpp | 73 + src/gui/qt/PhoneLineLocker.cpp | 39 + src/gui/qt/PhoneLineLocker.hpp | 51 + src/gui/qt/PhoneLineManager.hpp | 30 + src/gui/qt/PhoneLineManagerImpl.cpp | 700 ++++++++ src/gui/qt/PhoneLineManagerImpl.hpp | 328 ++++ src/gui/qt/QjListBoxPixmap.cpp | 159 ++ src/gui/qt/QjListBoxPixmap.hpp | 73 + src/gui/qt/README | 38 + src/gui/qt/Request.cpp | 243 +++ src/gui/qt/Request.hpp | 245 +++ src/gui/qt/Requester.hpp | 30 + src/gui/qt/RequesterImpl.cpp | 200 +++ src/gui/qt/RequesterImpl.hpp | 148 ++ src/gui/qt/RequesterImpl.inl | 40 + src/gui/qt/SFLCallStatus.hpp | 35 + src/gui/qt/SFLEvents.cpp | 144 ++ src/gui/qt/SFLEvents.hpp | 101 ++ src/gui/qt/SFLLcd.cpp | 276 +++ src/gui/qt/SFLLcd.hpp | 78 + src/gui/qt/SFLPhoneApp.cpp | 213 +++ src/gui/qt/SFLPhoneApp.hpp | 54 + src/gui/qt/SFLPhoneWindow.cpp | 322 ++++ src/gui/qt/SFLPhoneWindow.hpp | 126 ++ src/gui/qt/SFLPhoneWindow.ui | 63 + src/gui/qt/SFLRequest.cpp | 417 +++++ src/gui/qt/SFLRequest.hpp | 278 +++ src/gui/qt/Session.cpp | 180 ++ src/gui/qt/Session.hpp | 122 ++ src/gui/qt/SessionFactory.hpp | 56 + src/gui/qt/SessionIO.hpp | 61 + src/gui/qt/SessionIOFactory.hpp | 31 + src/gui/qt/Skin.cpp | 62 + src/gui/qt/Skin.hpp | 64 + src/gui/qt/SkinManagerImpl.cpp | 74 + src/gui/qt/SkinManagerImpl.hpp | 52 + src/gui/qt/TCPSessionIO.cpp | 140 ++ src/gui/qt/TCPSessionIO.hpp | 101 ++ src/gui/qt/TCPSessionIOCreator.cpp | 39 + src/gui/qt/TCPSessionIOCreator.hpp | 41 + src/gui/qt/TODO | 21 + src/gui/qt/TransparentWidget.cpp | 125 ++ src/gui/qt/TransparentWidget.hpp | 66 + src/gui/qt/Url.cpp | 61 + src/gui/qt/Url.hpp | 33 + src/gui/qt/VolumeControl.cpp | 173 ++ src/gui/qt/VolumeControl.hpp | 75 + src/gui/qt/globals.h | 53 + src/gui/qt/images/about.png | Bin 0 -> 2395 bytes src/gui/qt/images/audio.png | Bin 0 -> 1968 bytes src/gui/qt/images/clear_off.png | Bin 0 -> 1385 bytes src/gui/qt/images/clear_on.png | Bin 0 -> 1383 bytes src/gui/qt/images/close_off.png | Bin 0 -> 785 bytes src/gui/qt/images/close_on.png | Bin 0 -> 812 bytes src/gui/qt/images/conference_off.png | Bin 0 -> 2359 bytes src/gui/qt/images/conference_on.png | Bin 0 -> 2379 bytes src/gui/qt/images/directory_off.png | Bin 0 -> 2066 bytes src/gui/qt/images/directory_on.png | Bin 0 -> 2099 bytes src/gui/qt/images/dtmf_0_off.png | Bin 0 -> 1623 bytes src/gui/qt/images/dtmf_0_on.png | Bin 0 -> 1675 bytes src/gui/qt/images/dtmf_1_off.png | Bin 0 -> 1422 bytes src/gui/qt/images/dtmf_1_on.png | Bin 0 -> 1441 bytes src/gui/qt/images/dtmf_2_off.png | Bin 0 -> 2231 bytes src/gui/qt/images/dtmf_2_on.png | Bin 0 -> 2278 bytes src/gui/qt/images/dtmf_3_off.png | Bin 0 -> 2234 bytes src/gui/qt/images/dtmf_3_on.png | Bin 0 -> 2277 bytes src/gui/qt/images/dtmf_4_off.png | Bin 0 -> 2087 bytes src/gui/qt/images/dtmf_4_on.png | Bin 0 -> 2110 bytes src/gui/qt/images/dtmf_5_off.png | Bin 0 -> 1984 bytes src/gui/qt/images/dtmf_5_on.png | Bin 0 -> 2007 bytes src/gui/qt/images/dtmf_6_off.png | Bin 0 -> 2266 bytes src/gui/qt/images/dtmf_6_on.png | Bin 0 -> 2237 bytes src/gui/qt/images/dtmf_7_off.png | Bin 0 -> 2239 bytes src/gui/qt/images/dtmf_7_on.png | Bin 0 -> 2311 bytes src/gui/qt/images/dtmf_8_off.png | Bin 0 -> 2239 bytes src/gui/qt/images/dtmf_8_on.png | Bin 0 -> 2320 bytes src/gui/qt/images/dtmf_9_off.png | Bin 0 -> 2570 bytes src/gui/qt/images/dtmf_9_on.png | Bin 0 -> 2639 bytes src/gui/qt/images/dtmf_close_off.png | Bin 0 -> 778 bytes src/gui/qt/images/dtmf_close_on.png | Bin 0 -> 806 bytes src/gui/qt/images/dtmf_main.png | Bin 0 -> 14015 bytes src/gui/qt/images/dtmf_off.png | Bin 0 -> 1440 bytes src/gui/qt/images/dtmf_on.png | Bin 0 -> 1451 bytes src/gui/qt/images/dtmf_pound_off.png | Bin 0 -> 1535 bytes src/gui/qt/images/dtmf_pound_on.png | Bin 0 -> 1640 bytes src/gui/qt/images/dtmf_star_off.png | Bin 0 -> 1487 bytes src/gui/qt/images/dtmf_star_on.png | Bin 0 -> 1535 bytes src/gui/qt/images/gsm.png | Bin 0 -> 1041 bytes src/gui/qt/images/hangup_off.png | Bin 0 -> 1882 bytes src/gui/qt/images/hangup_on.png | Bin 0 -> 2091 bytes src/gui/qt/images/hold_off.png | Bin 0 -> 1496 bytes src/gui/qt/images/hold_on.png | Bin 0 -> 1503 bytes src/gui/qt/images/l.png | Bin 0 -> 419 bytes src/gui/qt/images/l1_off.png | Bin 0 -> 1047 bytes src/gui/qt/images/l1_on.png | Bin 0 -> 1018 bytes src/gui/qt/images/l2_off.png | Bin 0 -> 1111 bytes src/gui/qt/images/l2_on.png | Bin 0 -> 1090 bytes src/gui/qt/images/l3_off.png | Bin 0 -> 1149 bytes src/gui/qt/images/l3_on.png | Bin 0 -> 1127 bytes src/gui/qt/images/l4_off.png | Bin 0 -> 1103 bytes src/gui/qt/images/l4_on.png | Bin 0 -> 1084 bytes src/gui/qt/images/l5_off.png | Bin 0 -> 1113 bytes src/gui/qt/images/l5_on.png | Bin 0 -> 1087 bytes src/gui/qt/images/l6_off.png | Bin 0 -> 1158 bytes src/gui/qt/images/l6_on.png | Bin 0 -> 1165 bytes src/gui/qt/images/logo_ico.png | Bin 0 -> 1515 bytes src/gui/qt/images/main.png | Bin 0 -> 33448 bytes src/gui/qt/images/minimize_off.png | Bin 0 -> 768 bytes src/gui/qt/images/minimize_on.png | Bin 0 -> 761 bytes src/gui/qt/images/mute_off.png | Bin 0 -> 1522 bytes src/gui/qt/images/mute_on.png | Bin 0 -> 1513 bytes src/gui/qt/images/network.png | Bin 0 -> 1895 bytes src/gui/qt/images/ok_off.png | Bin 0 -> 1090 bytes src/gui/qt/images/ok_on.png | Bin 0 -> 1087 bytes src/gui/qt/images/overscreen.png | Bin 0 -> 1338 bytes src/gui/qt/images/preferences.png | Bin 0 -> 2342 bytes src/gui/qt/images/screen_main.png | Bin 0 -> 14357 bytes src/gui/qt/images/setup_off.png | Bin 0 -> 1529 bytes src/gui/qt/images/setup_on.png | Bin 0 -> 1523 bytes src/gui/qt/images/sfl-logo.png | Bin 0 -> 12635 bytes src/gui/qt/images/sflphone_logo.png | Bin 0 -> 10468 bytes src/gui/qt/images/signalisations.png | Bin 0 -> 2270 bytes src/gui/qt/images/slider.png | Bin 0 -> 716 bytes src/gui/qt/images/splash.png | Bin 0 -> 114424 bytes src/gui/qt/images/transfer_off.png | Bin 0 -> 2081 bytes src/gui/qt/images/transfer_on.png | Bin 0 -> 2091 bytes src/gui/qt/images/tray-icon.png | Bin 0 -> 1356 bytes src/gui/qt/images/video.png | Bin 0 -> 2442 bytes src/gui/qt/images/voicemail_off.png | Bin 0 -> 2049 bytes src/gui/qt/images/voicemail_on.png | Bin 0 -> 2083 bytes src/gui/qt/images/volume.png | Bin 0 -> 514 bytes src/gui/qt/images/volume_off.png | Bin 0 -> 433 bytes src/gui/qt/images/volume_on.png | Bin 0 -> 436 bytes src/gui/qt/main.cpp | 74 + src/gui/qt/sflphone-qt.pro | 180 ++ src/gui/qt/sflphone-qt_fr.qm | Bin 0 -> 4753 bytes src/gui/qt/sflphone-qt_fr.ts | 635 +++++++ src/gui/qt/sflphone.qrc | 40 + src/gui/qt/skin.ini | 39 + src/gui/qt/utilspp/EmptyType.hpp | 32 + src/gui/qt/utilspp/Functors.hpp | 29 + src/gui/qt/utilspp/NonCopyable.hpp | 41 + src/gui/qt/utilspp/NullType.hpp | 32 + src/gui/qt/utilspp/Singleton.hpp | 2 + src/gui/qt/utilspp/SmartPtr.hpp | 186 ++ src/gui/qt/utilspp/ThreadingFactoryMutex.hpp | 44 + src/gui/qt/utilspp/ThreadingFactoryMutex.inl | 37 + src/gui/qt/utilspp/ThreadingSingle.hpp | 52 + src/gui/qt/utilspp/ThreadingSingle.inl | 50 + src/gui/qt/utilspp/TypeList.hpp | 216 +++ src/gui/qt/utilspp/TypeTrait.hpp | 916 ++++++++++ .../qt/utilspp/singleton/CreationStatic.hpp | 49 + .../qt/utilspp/singleton/CreationStatic.inl | 43 + .../qt/utilspp/singleton/CreationUsingNew.hpp | 43 + .../qt/utilspp/singleton/CreationUsingNew.inl | 42 + .../qt/utilspp/singleton/LifetimeDefault.hpp | 43 + .../qt/utilspp/singleton/LifetimeDefault.inl | 42 + .../qt/utilspp/singleton/LifetimeLibrary.hpp | 104 ++ .../qt/utilspp/singleton/LifetimeLibrary.inl | 33 + .../singleton/LifetimeWithLongevity.hpp | 56 + .../singleton/LifetimeWithLongevity.inl | 56 + .../qt/utilspp/singleton/PrivateMembers.hpp | 93 + .../qt/utilspp/singleton/PrivateMembers.inl | 30 + .../qt/utilspp/singleton/SingletonHolder.hpp | 66 + .../qt/utilspp/singleton/SingletonHolder.inl | 126 ++ 205 files changed, 14910 insertions(+) create mode 100644 src/gui/qt/Account.cpp create mode 100644 src/gui/qt/Account.hpp create mode 100644 src/gui/qt/Call.cpp create mode 100644 src/gui/qt/Call.hpp create mode 100644 src/gui/qt/CallManager.hpp create mode 100644 src/gui/qt/CallManagerImpl.cpp create mode 100644 src/gui/qt/CallManagerImpl.hpp create mode 100644 src/gui/qt/CallStatus.cpp create mode 100644 src/gui/qt/CallStatus.hpp create mode 100644 src/gui/qt/CallStatusFactory.hpp create mode 100644 src/gui/qt/ConfigurationManager.hpp create mode 100644 src/gui/qt/ConfigurationManagerImpl.cpp create mode 100644 src/gui/qt/ConfigurationManagerImpl.hpp create mode 100644 src/gui/qt/ConfigurationPanel.ui create mode 100644 src/gui/qt/ConfigurationPanel.ui.h create mode 100644 src/gui/qt/ConfigurationPanelImpl.cpp create mode 100644 src/gui/qt/ConfigurationPanelImpl.hpp create mode 100644 src/gui/qt/DebugOutput.hpp create mode 100644 src/gui/qt/DebugOutputImpl.cpp create mode 100644 src/gui/qt/DebugOutputImpl.hpp create mode 100644 src/gui/qt/Event.cpp create mode 100644 src/gui/qt/Event.hpp create mode 100644 src/gui/qt/EventFactory.hpp create mode 100644 src/gui/qt/EventFactory.inl create mode 100644 src/gui/qt/Factory.hpp create mode 100644 src/gui/qt/Factory.inl create mode 100644 src/gui/qt/INSTALL create mode 100644 src/gui/qt/JPushButton.cpp create mode 100644 src/gui/qt/JPushButton.hpp create mode 100644 src/gui/qt/Launcher.cpp create mode 100644 src/gui/qt/Launcher.hpp create mode 100644 src/gui/qt/NumericKeypad.cpp create mode 100644 src/gui/qt/NumericKeypad.hpp create mode 100644 src/gui/qt/ObjectFactory.hpp create mode 100644 src/gui/qt/ObjectFactory.inl create mode 100644 src/gui/qt/ObjectPool.hpp create mode 100644 src/gui/qt/ObjectPool.inl create mode 100644 src/gui/qt/PhoneLine.cpp create mode 100644 src/gui/qt/PhoneLine.hpp create mode 100644 src/gui/qt/PhoneLineButton.cpp create mode 100644 src/gui/qt/PhoneLineButton.hpp create mode 100644 src/gui/qt/PhoneLineLocker.cpp create mode 100644 src/gui/qt/PhoneLineLocker.hpp create mode 100644 src/gui/qt/PhoneLineManager.hpp create mode 100644 src/gui/qt/PhoneLineManagerImpl.cpp create mode 100644 src/gui/qt/PhoneLineManagerImpl.hpp create mode 100644 src/gui/qt/QjListBoxPixmap.cpp create mode 100644 src/gui/qt/QjListBoxPixmap.hpp create mode 100644 src/gui/qt/README create mode 100644 src/gui/qt/Request.cpp create mode 100644 src/gui/qt/Request.hpp create mode 100644 src/gui/qt/Requester.hpp create mode 100644 src/gui/qt/RequesterImpl.cpp create mode 100644 src/gui/qt/RequesterImpl.hpp create mode 100644 src/gui/qt/RequesterImpl.inl create mode 100644 src/gui/qt/SFLCallStatus.hpp create mode 100644 src/gui/qt/SFLEvents.cpp create mode 100644 src/gui/qt/SFLEvents.hpp create mode 100644 src/gui/qt/SFLLcd.cpp create mode 100644 src/gui/qt/SFLLcd.hpp create mode 100644 src/gui/qt/SFLPhoneApp.cpp create mode 100644 src/gui/qt/SFLPhoneApp.hpp create mode 100644 src/gui/qt/SFLPhoneWindow.cpp create mode 100644 src/gui/qt/SFLPhoneWindow.hpp create mode 100644 src/gui/qt/SFLPhoneWindow.ui create mode 100644 src/gui/qt/SFLRequest.cpp create mode 100644 src/gui/qt/SFLRequest.hpp create mode 100644 src/gui/qt/Session.cpp create mode 100644 src/gui/qt/Session.hpp create mode 100644 src/gui/qt/SessionFactory.hpp create mode 100644 src/gui/qt/SessionIO.hpp create mode 100644 src/gui/qt/SessionIOFactory.hpp create mode 100644 src/gui/qt/Skin.cpp create mode 100644 src/gui/qt/Skin.hpp create mode 100644 src/gui/qt/SkinManagerImpl.cpp create mode 100644 src/gui/qt/SkinManagerImpl.hpp create mode 100644 src/gui/qt/TCPSessionIO.cpp create mode 100644 src/gui/qt/TCPSessionIO.hpp create mode 100644 src/gui/qt/TCPSessionIOCreator.cpp create mode 100644 src/gui/qt/TCPSessionIOCreator.hpp create mode 100644 src/gui/qt/TODO create mode 100644 src/gui/qt/TransparentWidget.cpp create mode 100644 src/gui/qt/TransparentWidget.hpp create mode 100644 src/gui/qt/Url.cpp create mode 100644 src/gui/qt/Url.hpp create mode 100644 src/gui/qt/VolumeControl.cpp create mode 100644 src/gui/qt/VolumeControl.hpp create mode 100644 src/gui/qt/globals.h create mode 100644 src/gui/qt/images/about.png create mode 100644 src/gui/qt/images/audio.png create mode 100644 src/gui/qt/images/clear_off.png create mode 100644 src/gui/qt/images/clear_on.png create mode 100644 src/gui/qt/images/close_off.png create mode 100644 src/gui/qt/images/close_on.png create mode 100644 src/gui/qt/images/conference_off.png create mode 100644 src/gui/qt/images/conference_on.png create mode 100644 src/gui/qt/images/directory_off.png create mode 100644 src/gui/qt/images/directory_on.png create mode 100644 src/gui/qt/images/dtmf_0_off.png create mode 100644 src/gui/qt/images/dtmf_0_on.png create mode 100644 src/gui/qt/images/dtmf_1_off.png create mode 100644 src/gui/qt/images/dtmf_1_on.png create mode 100644 src/gui/qt/images/dtmf_2_off.png create mode 100644 src/gui/qt/images/dtmf_2_on.png create mode 100644 src/gui/qt/images/dtmf_3_off.png create mode 100644 src/gui/qt/images/dtmf_3_on.png create mode 100644 src/gui/qt/images/dtmf_4_off.png create mode 100644 src/gui/qt/images/dtmf_4_on.png create mode 100644 src/gui/qt/images/dtmf_5_off.png create mode 100644 src/gui/qt/images/dtmf_5_on.png create mode 100644 src/gui/qt/images/dtmf_6_off.png create mode 100644 src/gui/qt/images/dtmf_6_on.png create mode 100644 src/gui/qt/images/dtmf_7_off.png create mode 100644 src/gui/qt/images/dtmf_7_on.png create mode 100644 src/gui/qt/images/dtmf_8_off.png create mode 100644 src/gui/qt/images/dtmf_8_on.png create mode 100644 src/gui/qt/images/dtmf_9_off.png create mode 100644 src/gui/qt/images/dtmf_9_on.png create mode 100644 src/gui/qt/images/dtmf_close_off.png create mode 100644 src/gui/qt/images/dtmf_close_on.png create mode 100644 src/gui/qt/images/dtmf_main.png create mode 100644 src/gui/qt/images/dtmf_off.png create mode 100644 src/gui/qt/images/dtmf_on.png create mode 100644 src/gui/qt/images/dtmf_pound_off.png create mode 100644 src/gui/qt/images/dtmf_pound_on.png create mode 100644 src/gui/qt/images/dtmf_star_off.png create mode 100644 src/gui/qt/images/dtmf_star_on.png create mode 100644 src/gui/qt/images/gsm.png create mode 100644 src/gui/qt/images/hangup_off.png create mode 100644 src/gui/qt/images/hangup_on.png create mode 100644 src/gui/qt/images/hold_off.png create mode 100644 src/gui/qt/images/hold_on.png create mode 100644 src/gui/qt/images/l.png create mode 100644 src/gui/qt/images/l1_off.png create mode 100644 src/gui/qt/images/l1_on.png create mode 100644 src/gui/qt/images/l2_off.png create mode 100644 src/gui/qt/images/l2_on.png create mode 100644 src/gui/qt/images/l3_off.png create mode 100644 src/gui/qt/images/l3_on.png create mode 100644 src/gui/qt/images/l4_off.png create mode 100644 src/gui/qt/images/l4_on.png create mode 100644 src/gui/qt/images/l5_off.png create mode 100644 src/gui/qt/images/l5_on.png create mode 100644 src/gui/qt/images/l6_off.png create mode 100644 src/gui/qt/images/l6_on.png create mode 100644 src/gui/qt/images/logo_ico.png create mode 100644 src/gui/qt/images/main.png create mode 100644 src/gui/qt/images/minimize_off.png create mode 100644 src/gui/qt/images/minimize_on.png create mode 100644 src/gui/qt/images/mute_off.png create mode 100644 src/gui/qt/images/mute_on.png create mode 100644 src/gui/qt/images/network.png create mode 100644 src/gui/qt/images/ok_off.png create mode 100644 src/gui/qt/images/ok_on.png create mode 100644 src/gui/qt/images/overscreen.png create mode 100644 src/gui/qt/images/preferences.png create mode 100644 src/gui/qt/images/screen_main.png create mode 100644 src/gui/qt/images/setup_off.png create mode 100644 src/gui/qt/images/setup_on.png create mode 100644 src/gui/qt/images/sfl-logo.png create mode 100644 src/gui/qt/images/sflphone_logo.png create mode 100644 src/gui/qt/images/signalisations.png create mode 100644 src/gui/qt/images/slider.png create mode 100644 src/gui/qt/images/splash.png create mode 100644 src/gui/qt/images/transfer_off.png create mode 100644 src/gui/qt/images/transfer_on.png create mode 100644 src/gui/qt/images/tray-icon.png create mode 100644 src/gui/qt/images/video.png create mode 100644 src/gui/qt/images/voicemail_off.png create mode 100644 src/gui/qt/images/voicemail_on.png create mode 100644 src/gui/qt/images/volume.png create mode 100644 src/gui/qt/images/volume_off.png create mode 100644 src/gui/qt/images/volume_on.png create mode 100644 src/gui/qt/main.cpp create mode 100644 src/gui/qt/sflphone-qt.pro create mode 100644 src/gui/qt/sflphone-qt_fr.qm create mode 100644 src/gui/qt/sflphone-qt_fr.ts create mode 100644 src/gui/qt/sflphone.qrc create mode 100644 src/gui/qt/skin.ini create mode 100644 src/gui/qt/utilspp/EmptyType.hpp create mode 100644 src/gui/qt/utilspp/Functors.hpp create mode 100644 src/gui/qt/utilspp/NonCopyable.hpp create mode 100644 src/gui/qt/utilspp/NullType.hpp create mode 100644 src/gui/qt/utilspp/Singleton.hpp create mode 100644 src/gui/qt/utilspp/SmartPtr.hpp create mode 100644 src/gui/qt/utilspp/ThreadingFactoryMutex.hpp create mode 100644 src/gui/qt/utilspp/ThreadingFactoryMutex.inl create mode 100644 src/gui/qt/utilspp/ThreadingSingle.hpp create mode 100644 src/gui/qt/utilspp/ThreadingSingle.inl create mode 100644 src/gui/qt/utilspp/TypeList.hpp create mode 100644 src/gui/qt/utilspp/TypeTrait.hpp create mode 100644 src/gui/qt/utilspp/singleton/CreationStatic.hpp create mode 100644 src/gui/qt/utilspp/singleton/CreationStatic.inl create mode 100644 src/gui/qt/utilspp/singleton/CreationUsingNew.hpp create mode 100644 src/gui/qt/utilspp/singleton/CreationUsingNew.inl create mode 100644 src/gui/qt/utilspp/singleton/LifetimeDefault.hpp create mode 100644 src/gui/qt/utilspp/singleton/LifetimeDefault.inl create mode 100644 src/gui/qt/utilspp/singleton/LifetimeLibrary.hpp create mode 100644 src/gui/qt/utilspp/singleton/LifetimeLibrary.inl create mode 100644 src/gui/qt/utilspp/singleton/LifetimeWithLongevity.hpp create mode 100644 src/gui/qt/utilspp/singleton/LifetimeWithLongevity.inl create mode 100644 src/gui/qt/utilspp/singleton/PrivateMembers.hpp create mode 100644 src/gui/qt/utilspp/singleton/PrivateMembers.inl create mode 100644 src/gui/qt/utilspp/singleton/SingletonHolder.hpp create mode 100644 src/gui/qt/utilspp/singleton/SingletonHolder.inl diff --git a/src/gui/qt/Account.cpp b/src/gui/qt/Account.cpp new file mode 100644 index 0000000000..79b7c55382 --- /dev/null +++ b/src/gui/qt/Account.cpp @@ -0,0 +1,60 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "Account.hpp" +#include "Requester.hpp" +#include "Call.hpp" + +Account::Account(const QString &sessionId, + const QString &name) + : mSessionId(sessionId) + , mId(name) +{} + +Request * +Account::registerAccount() const +{ + std::list< QString > args; + args.push_back(mId); + return Requester::instance().send(mSessionId, "register", args); +} + +Request * +Account::unregisterAccount() const +{ + std::list< QString > args; + args.push_back(mId); + return Requester::instance().send(mSessionId, "unregister", args); +} + +Request * +Account::createCall(Call * &call, const QString &to) const +{ + QString callId = Requester::instance().generateCallId(); + call = new Call(mSessionId, mId, callId, to); + + std::list< QString> args; + args.push_back(mId); + args.push_back(callId); + args.push_back(to); + return Requester::instance().send(mSessionId, "call", args); +} + + diff --git a/src/gui/qt/Account.hpp b/src/gui/qt/Account.hpp new file mode 100644 index 0000000000..d298b8c162 --- /dev/null +++ b/src/gui/qt/Account.hpp @@ -0,0 +1,67 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef SFLPHONEGUI_ACCOUNT_H +#define SFLPHONEGUI_ACCOUNT_H + +#include <qstring.h> + +#include "Call.hpp" + +class Request; + +class Account { + public: + Account(const QString &sessionId, + const QString &name); + + /** + * This will generate a call ready to be used. + */ + Request *registerAccount() const; + Request *unregisterAccount() const; + + /** + * This function will create a call. The call pointer will + * point to a newly allocated memory. You're responsible for + * deleting this memory. + */ + Request *createCall(Call * &call, const QString &to) const; + + + QString id() const + {return mId;} + +private: + Account(); + + /** + * This is the session id that we are related to. + */ + QString mSessionId; + + /** + * This is the account id that we are related to. + */ + QString mId; +}; + + +#endif diff --git a/src/gui/qt/Call.cpp b/src/gui/qt/Call.cpp new file mode 100644 index 0000000000..e538641c9c --- /dev/null +++ b/src/gui/qt/Call.cpp @@ -0,0 +1,141 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <qstring.h> +#include <list> + +#include "Account.hpp" +#include "Call.hpp" +#include "CallManager.hpp" +#include "Session.hpp" +#include "Requester.hpp" + + +Call::Call(const QString &sessionId, + const QString &accountId, + const QString &callId, + const QString &peer, + bool incomming) + : mSessionId(sessionId) + , mAccountId(accountId) + , mId(callId) + , mPeer(peer) + , mIsIncomming(incomming) +{ + CallManager::instance().registerCall(*this); +} + +Call::Call(const Session &session, + const Account &account, + const QString &callId, + const QString &peer, + bool incomming) + : mSessionId(session.id()) + , mAccountId(account.id()) + , mId(callId) + , mPeer(peer) + , mIsIncomming(incomming) +{ + CallManager::instance().registerCall(*this); +} + +bool +Call::isIncomming() +{return mIsIncomming;} + +Request * +Call::answer() +{ + mIsIncomming = false; + std::list< QString> args; + args.push_back(mId); + return Requester::instance().send(mSessionId, "answer", args); +} + +Request * +Call::hangup() +{ + std::list< QString> args; + args.push_back(mId); + return Requester::instance().send(mSessionId, "hangup", args); +} + +Request * +Call::cancel() +{ + std::list< QString> args; + args.push_back(mId); + return Requester::instance().send(mSessionId, "cancel", args); +} + +Request * +Call::hold() +{ + std::list< QString> args; + args.push_back(mId); + return Requester::instance().send(mSessionId, "hold", args); +} + +Request * +Call::unhold() +{ + std::list< QString> args; + args.push_back(mId); + return Requester::instance().send(mSessionId, "unhold", args); +} + +Request * +Call::refuse() +{ + mIsIncomming = false; + std::list< QString> args; + args.push_back(mId); + return Requester::instance().send(mSessionId, "refuse", args); +} + +Request * +Call::notAvailable() +{ + mIsIncomming = false; + std::list< QString> args; + args.push_back(mId); + return Requester::instance().send(mSessionId, "notavailable", args); +} + +Request * +Call::transfer(const QString &to) +{ + std::list< QString> args; + args.push_back(mId); + args.push_back(to); + return Requester::instance().send(mSessionId, "transfer", args); +} + +Request * +Call::sendDtmf(char c) +{ + std::list< QString> args; + args.push_back(mId); + QString s; + s += c; + args.push_back(s); + return Requester::instance().send(mSessionId, "senddtmf", args); +} + diff --git a/src/gui/qt/Call.hpp b/src/gui/qt/Call.hpp new file mode 100644 index 0000000000..d3d626c68e --- /dev/null +++ b/src/gui/qt/Call.hpp @@ -0,0 +1,142 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef SFLPHONEGUI_CALL_H +#define SFLPHONEGUI_CALL_H + +#include <qstring.h> + +class Account; +class Request; +class Session; + +class Call +{ + public: + /** + * A call is automaticaly registered in + * the CallManager. However, a call isn't + * registered when you have a copy constructor. + */ + Call(const QString &sessionId, + const QString &accountId, + const QString &callId, + const QString &destination, + bool incomming = false); + Call(const Session &session, + const Account &account, + const QString &callId, + const QString &destination, + bool incomming = false); + + /** + * This function returns true if the + * call is waiting to be picked up. + */ + bool isIncomming(); + + QString id() const + {return mId;} + + QString peer() const + {return mPeer;} + + /** + * This function will answer the call. + */ + Request *answer(); + + /** + * This function will try to transfer the + * call to the peer. + */ + Request *transfer(const QString &to); + + /** + * This function will hangup on a call. + */ + Request *hangup(); + + /** + * ///TODO need to clarify this function. + */ + Request *cancel(); + + /** + * This function will put the call on hold. + * This *should* stop temporarly the streaming. + */ + Request *hold(); + + /** + * This function will unhold a holding call. + * This *should* restart a stopped streaming. + */ + Request *unhold(); + + /** + * This function refuse and incomming call. + * It means that the phone is ringing but we + * don't want to answer. + */ + Request *refuse(); + + /** + * This function will set this client to be + * not able to receive the call. It means that + * the phone can still ring. But if every client + * sent notavailable, then it will be refused. + */ + Request *notAvailable(); + + + /** + * This function will send a tone to the line. + * This is used if you make a choice when you + * have a voice menu. + */ + Request *sendDtmf(char c); + + private: + + /** + * This is the session id that we belong to. + */ + QString mSessionId; + + /** + * This is the account id that we belong to. + */ + QString mAccountId; + + /** + * This is the unique identifier of the call. + */ + QString mId; + + /** + * This is the destination of the call. + */ + QString mPeer; + + bool mIsIncomming; +}; + +#endif diff --git a/src/gui/qt/CallManager.hpp b/src/gui/qt/CallManager.hpp new file mode 100644 index 0000000000..8eff2b2f68 --- /dev/null +++ b/src/gui/qt/CallManager.hpp @@ -0,0 +1,30 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author : Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __CALL_MANAGER_HPP__ +#define __CALL_MANAGER_HPP__ + +#include "utilspp/Singleton.hpp" +#include "CallManagerImpl.hpp" + +typedef utilspp::SingletonHolder< CallManagerImpl > CallManager; + +#endif + diff --git a/src/gui/qt/CallManagerImpl.cpp b/src/gui/qt/CallManagerImpl.cpp new file mode 100644 index 0000000000..e09a411843 --- /dev/null +++ b/src/gui/qt/CallManagerImpl.cpp @@ -0,0 +1,68 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <qobject.h> +#include <stdexcept> + +#include "CallManagerImpl.hpp" +#include "DebugOutput.hpp" + +void +CallManagerImpl::registerCall(const Call &call) +{ + mCalls.insert(std::make_pair(call.id(), call)); +} + +void +CallManagerImpl::unregisterCall(const Call &call) +{ + unregisterCall(call.id()); +} + +void +CallManagerImpl::unregisterCall(const QString &id) +{ + std::map< QString, Call >::iterator pos = mCalls.find(id); + if(pos != mCalls.end()) { + mCalls.erase(pos); + } +} + +bool +CallManagerImpl::exist(const QString &id) +{ + std::map< QString, Call >::iterator pos = mCalls.find(id); + if(pos == mCalls.end()) { + return false; + } + + return true; +} + +Call +CallManagerImpl::getCall(const QString &id) +{ + std::map< QString, Call >::iterator pos = mCalls.find(id); + if(pos == mCalls.end()) { + throw std::runtime_error("Trying to retreive an unregistred call\n"); + } + + return pos->second; +} diff --git a/src/gui/qt/CallManagerImpl.hpp b/src/gui/qt/CallManagerImpl.hpp new file mode 100644 index 0000000000..a7e02aa225 --- /dev/null +++ b/src/gui/qt/CallManagerImpl.hpp @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __CALL_MANAGER_IMPL_HPP__ +#define __CALL_MANAGER_IMPL_HPP__ + +#include <qmutex.h> +#include <qstring.h> +#include <map> + +#include "Call.hpp" + +class CallManagerImpl +{ +public: + void registerCall(const Call &call); + void unregisterCall(const Call &call); + void unregisterCall(const QString &id); + + /** + * Return true if the call is registered. + */ + bool exist(const QString &id); + + /** + * Return the call with the given id. If + * there's no such call it will throw a + * std::runtime_error. + */ + Call getCall(const QString &id); + +private: + std::map< QString, Call > mCalls; +}; + +#endif diff --git a/src/gui/qt/CallStatus.cpp b/src/gui/qt/CallStatus.cpp new file mode 100644 index 0000000000..2ed447d80e --- /dev/null +++ b/src/gui/qt/CallStatus.cpp @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "globals.h" + +#include "CallStatus.hpp" +#include "PhoneLineManager.hpp" + +CallStatus::CallStatus(const QString &code, + const std::list< QString > &args) + : CallRelatedEvent(code, args) +{ + std::list< QString > l = getUnusedArgs(); + if(l.size() >= 3) { + mAccountId = *l.begin(); + l.pop_front(); + mDestination = *l.begin(); + l.pop_front(); + mStatus = *l.begin(); + l.pop_front(); + setUnusedArgs(l); + } +} + +void +CallStatus::execute() +{ + QString id = getCallId(); + if(id.length() > 0) { + DebugOutput::instance() << QObject::tr("%1 status received for call ID: %2.\n") + .arg(mStatus) + .arg(id); + PhoneLineManager::instance().addCall(mAccountId, getCallId(), mDestination, mStatus); + } + else { + DebugOutput::instance() << QObject::tr("Status invalid: %1\n").arg(toString()); + } +} + diff --git a/src/gui/qt/CallStatus.hpp b/src/gui/qt/CallStatus.hpp new file mode 100644 index 0000000000..3b648d0ead --- /dev/null +++ b/src/gui/qt/CallStatus.hpp @@ -0,0 +1,41 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __CALLSTATUS_HPP__ +#define __CALLSTATUS_HPP__ + +#include "Event.hpp" + +class CallStatus : public CallRelatedEvent +{ +public: + CallStatus(const QString &code, + const std::list< QString > &args); + + void execute(); + +protected: + QString mAccountId; + QString mDestination; + QString mStatus; +}; + +#endif + diff --git a/src/gui/qt/CallStatusFactory.hpp b/src/gui/qt/CallStatusFactory.hpp new file mode 100644 index 0000000000..83e467b6ec --- /dev/null +++ b/src/gui/qt/CallStatusFactory.hpp @@ -0,0 +1,29 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __CALLSTATUSFACTORY_HPP__ +#define __CALLSTATUSFACTORY_HPP__ + +#include "EventFactory.hpp" + +typedef utilspp::SingletonHolder< EventFactoryImpl< Event > > CallStatusFactory; + +#endif + diff --git a/src/gui/qt/ConfigurationManager.hpp b/src/gui/qt/ConfigurationManager.hpp new file mode 100644 index 0000000000..1cc5abe819 --- /dev/null +++ b/src/gui/qt/ConfigurationManager.hpp @@ -0,0 +1,30 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author : Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __CONFIGURATION_MANAGER_HPP__ +#define __CONFIGURATION_MANAGER_HPP__ + +#include "utilspp/Singleton.hpp" +#include "ConfigurationManagerImpl.hpp" + +typedef utilspp::SingletonHolder< ConfigurationManagerImpl > ConfigurationManager; + +#endif + diff --git a/src/gui/qt/ConfigurationManagerImpl.cpp b/src/gui/qt/ConfigurationManagerImpl.cpp new file mode 100644 index 0000000000..918ced3e23 --- /dev/null +++ b/src/gui/qt/ConfigurationManagerImpl.cpp @@ -0,0 +1,152 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "ConfigurationManagerImpl.hpp" +#include "DebugOutput.hpp" +#include "Session.hpp" + +ConfigurationManagerImpl::ConfigurationManagerImpl() + : mSession(NULL) +{} + +ConfigurationManagerImpl::~ConfigurationManagerImpl() +{ + delete mSession; +} + +void +ConfigurationManagerImpl::setCurrentSpeakerVolume(unsigned int ) +{ +} + +void +ConfigurationManagerImpl::setCurrentMicrophoneVolume(unsigned int ) +{ +} + +void +ConfigurationManagerImpl::setSession(const Session &session) +{ + mSession = new Session(session); +} + +void +ConfigurationManagerImpl::save() +{ + if(mSession) { + SectionMap::iterator pos = mEntries.begin(); + while(pos != mEntries.end()) { + VariableMap::iterator vpos = pos->second.begin(); + while(vpos != pos->second.end()) { + ConfigEntry entry(vpos->second); + mSession->configSet(entry.section, entry.name, entry.value); + vpos++; + } + + pos++; + } + + mSession->configSave(); + } + else { + DebugOutput::instance() << QObject::tr("ConfigurationManagerImpl::save(): " + "We don't have a valid session.\n"); + } +} + +void +ConfigurationManagerImpl::finishSave() +{ + emit saved(); +} + +void +ConfigurationManagerImpl::add(const ConfigEntry &entry) +{ + mEntries[entry.section][entry.name] = entry; +} + +void +ConfigurationManagerImpl::addAudioDevice(QString index, + QString hostApiName, + QString deviceName) +{ + AudioDevice device; + device.index = index; + device.hostApiName = hostApiName; + device.deviceName = deviceName; + add(device); +} + +void +ConfigurationManagerImpl::add(const AudioDevice &entry) +{ + mAudioDevices.push_back(entry); + emit audioDevicesUpdated(); +} + +void +ConfigurationManagerImpl::addRingtone(QString index, QString filename) +{ + Ringtone tone; + tone.index = index; + tone.filename = filename; + add(tone); +} + + +void +ConfigurationManagerImpl::add(const Ringtone &entry) +{ + mRingtones.push_back(entry); + emit ringtonesUpdated(); +} + +void +ConfigurationManagerImpl::set(const QString §ion, + const QString &name, + const QString &value) +{ + SectionMap::iterator pos = mEntries.find(section); + if(pos != mEntries.end()) { + VariableMap::iterator vpos = pos->second.find(name); + if(vpos != pos->second.end()) { + vpos->second.value = value; + } + } +} + +QString +ConfigurationManagerImpl::get(const QString §ion, + const QString &name) +{ + QString value; + SectionMap::iterator pos = mEntries.find(section); + if(pos != mEntries.end()) { + VariableMap::iterator vpos = pos->second.find(name); + if(vpos != pos->second.end()) { + value = vpos->second.value; + } + } + + return value; +} + + diff --git a/src/gui/qt/ConfigurationManagerImpl.hpp b/src/gui/qt/ConfigurationManagerImpl.hpp new file mode 100644 index 0000000000..edc3d7c0b0 --- /dev/null +++ b/src/gui/qt/ConfigurationManagerImpl.hpp @@ -0,0 +1,158 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifndef __CONFIGURATION_MANAGER_IMPL_HPP__ +#define __CONFIGURATION_MANAGER_IMPL_HPP__ + + +#include <list> +#include <map> +#include <qobject.h> +#include <vector> + +struct AudioDevice +{ +public: + QString index; + QString hostApiName; + QString deviceName; +}; + +struct Ringtone +{ +public: + QString index; + QString filename; +}; + +/** + * This is the representation of a configuration + * entry. + */ +struct ConfigEntry +{ +public: + ConfigEntry(){} + + ConfigEntry(QString s, + QString n, + QString t, + QString d, + QString v) + { + section = s; + name = n; + type = t; + def = d; + value = v; + } + + QString section; + QString name; + QString type; + QString def; + QString value; +}; + + +class Session; + +class ConfigurationManagerImpl : public QObject +{ + Q_OBJECT + +signals: + void audioDevicesUpdated(); + void ringtonesUpdated(); + void updated(); + void saved(); + +public: + ConfigurationManagerImpl(); + ~ConfigurationManagerImpl(); + + /** + * will set the session to use. + */ + void setSession(const Session &session); + + /** + * This function will set the current speaker volume + * to the given percentage. If it's greater than 100 + * it will be set to 100. + */ + void setCurrentSpeakerVolume(unsigned int percentage); + + /** + * This function will set the current microphone volume + * to the given percentage. If it's greater than 100 + * it will be set to 100. + */ + void setCurrentMicrophoneVolume(unsigned int percentage); + + + void set(const QString §ion, + const QString &name, + const QString &value); + + QString get(const QString §ion, + const QString &name); + + + + void clearAudioDevices() + {mAudioDevices.clear();} + + std::list< AudioDevice > getAudioDevices() + {return mAudioDevices;} + + std::list< Ringtone > getRingtones() + {return mRingtones;} + + void complete() + {emit updated();} + + void save(); + + void finishSave(); + +public slots: + void add(const ConfigEntry &entry); + + void addAudioDevice(QString index, QString hostApiName, QString deviceName); + void add(const AudioDevice &entry); + + void addRingtone(QString index, QString filename); + void add(const Ringtone &entry); + + +private: + typedef std::map< QString, ConfigEntry > VariableMap; + typedef std::map< QString, VariableMap > SectionMap; + SectionMap mEntries; + + std::list< AudioDevice > mAudioDevices; + std::list< Ringtone > mRingtones; + + Session *mSession; +}; + +#endif diff --git a/src/gui/qt/ConfigurationPanel.ui b/src/gui/qt/ConfigurationPanel.ui new file mode 100644 index 0000000000..f8e88bc05c --- /dev/null +++ b/src/gui/qt/ConfigurationPanel.ui @@ -0,0 +1,1530 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>ConfigurationPanel</class> +<widget class="QDialog"> + <property name="name"> + <cstring>ConfigurationPanel</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>571</width> + <height>548</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>5</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="caption"> + <string>Configuration panel</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <widget class="QListBox"> + <property name="name"> + <cstring>Menu</cstring> + </property> + <property name="geometry"> + <rect> + <x>11</x> + <y>11</y> + <width>100</width> + <height>484</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="cursor"> + <cursor>13</cursor> + </property> + <property name="currentItem"> + <number>-1</number> + </property> + <property name="selectionMode"> + <enum>Single</enum> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout17</cstring> + </property> + <property name="geometry"> + <rect> + <x>120</x> + <y>10</y> + <width>437</width> + <height>484</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>TitleTab</cstring> + </property> + <property name="font"> + <font> + <bold>1</bold> + </font> + </property> + <property name="text"> + <string>Setup signalisation</string> + </property> + </widget> + <widget class="Line"> + <property name="name"> + <cstring>line2</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QTabWidget"> + <property name="name"> + <cstring>Tab_Signalisations</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>SIPPage</cstring> + </property> + <attribute name="title"> + <string>SIP Authentication</string> + </attribute> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout24</cstring> + </property> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>410</width> + <height>393</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox1</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <property name="title"> + <string></string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="0" column="0"> + <property name="name"> + <cstring>textLabel2</cstring> + </property> + <property name="text"> + <string>Full name</string> + </property> + </widget> + <widget class="QLineEdit" row="1" column="0"> + <property name="name"> + <cstring>fullName</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + <widget class="QLineEdit" row="3" column="0"> + <property name="name"> + <cstring>userPart</cstring> + </property> + </widget> + <widget class="QLabel" row="2" column="0"> + <property name="name"> + <cstring>textLabel3</cstring> + </property> + <property name="text"> + <string>User Part of SIP URL</string> + </property> + </widget> + <widget class="QLabel" row="4" column="0"> + <property name="name"> + <cstring>textLabel2_3</cstring> + </property> + <property name="text"> + <string>Authorization user</string> + </property> + </widget> + <widget class="QLineEdit" row="5" column="0"> + <property name="name"> + <cstring>username</cstring> + </property> + </widget> + <widget class="QLineEdit" row="9" column="0"> + <property name="name"> + <cstring>hostPart</cstring> + </property> + </widget> + <widget class="QLineEdit" row="11" column="0"> + <property name="name"> + <cstring>sipproxy</cstring> + </property> + </widget> + <widget class="QLabel" row="10" column="0"> + <property name="name"> + <cstring>textLabel3_2_2</cstring> + </property> + <property name="text"> + <string>SIP proxy</string> + </property> + </widget> + <widget class="QLineEdit" row="7" column="0"> + <property name="name"> + <cstring>password</cstring> + </property> + <property name="echoMode"> + <enum>Password</enum> + </property> + </widget> + <widget class="QLabel" row="6" column="0"> + <property name="name"> + <cstring>textLabel1_3</cstring> + </property> + <property name="text"> + <string>Password</string> + </property> + </widget> + <widget class="QLabel" row="8" column="0"> + <property name="name"> + <cstring>textLabel3_2</cstring> + </property> + <property name="text"> + <string>Host part of SIP URL</string> + </property> + </widget> + </grid> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout23</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout19</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>autoregister</cstring> + </property> + <property name="text"> + <string>Auto-register</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer7</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>201</width> + <height>21</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>Register</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="text"> + <string>Register</string> + </property> + </widget> + </hbox> + </widget> + <spacer> + <property name="name"> + <cstring>spacer9</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>21</height> + </size> + </property> + </spacer> + </vbox> + </widget> + </vbox> + </widget> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>STUNPage</cstring> + </property> + <attribute name="title"> + <string>STUN</string> + </attribute> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox3</cstring> + </property> + <property name="geometry"> + <rect> + <x>10</x> + <y>110</y> + <width>253</width> + <height>100</height> + </rect> + </property> + <property name="title"> + <string>Settings </string> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_5</cstring> + </property> + <property name="geometry"> + <rect> + <x>10</x> + <y>38</y> + <width>229</width> + <height>16</height> + </rect> + </property> + <property name="text"> + <string>STUN server (address:port)</string> + </property> + </widget> + <widget class="QLineEdit"> + <property name="name"> + <cstring>STUNserver</cstring> + </property> + <property name="geometry"> + <rect> + <x>10</x> + <y>60</y> + <width>229</width> + <height>23</height> + </rect> + </property> + </widget> + </widget> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>stunButtonGroup</cstring> + </property> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>410</width> + <height>90</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>2</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Use STUN</string> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QRadioButton"> + <property name="name"> + <cstring>useStunNo</cstring> + </property> + <property name="text"> + <string>No</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <widget class="QRadioButton"> + <property name="name"> + <cstring>useStunYes</cstring> + </property> + <property name="text"> + <string>Yes</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </vbox> + </widget> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>DTMFPage</cstring> + </property> + <attribute name="title"> + <string>DTMF</string> + </attribute> + <widget class="QGroupBox"> + <property name="name"> + <cstring>SettingsDTMF</cstring> + </property> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>301</width> + <height>130</height> + </rect> + </property> + <property name="title"> + <string>Settings</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout11</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout10</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QCheckBox"> + <property name="name"> + <cstring>playTones</cstring> + </property> + <property name="text"> + <string>Play tones locally</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer6</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>111</width> + <height>20</height> + </size> + </property> + </spacer> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout7</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>labelPulseLength</cstring> + </property> + <property name="text"> + <string>Pulse length</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer3</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>115</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QSpinBox"> + <property name="name"> + <cstring>pulseLength</cstring> + </property> + <property name="suffix"> + <string> ms</string> + </property> + <property name="maxValue"> + <number>1500</number> + </property> + <property name="minValue"> + <number>10</number> + </property> + <property name="value"> + <number>250</number> + </property> + </widget> + </hbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout8</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>labelSendDTMF</cstring> + </property> + <property name="text"> + <string>Send DTMF as</string> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>85</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>SIP INFO</string> + </property> + </item> + <property name="name"> + <cstring>sendDTMFas</cstring> + </property> + <property name="currentItem"> + <number>0</number> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + </grid> + </widget> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>TabPage</cstring> + </property> + <attribute name="title"> + <string>Options</string> + </attribute> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout16_7</cstring> + </property> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>260</width> + <height>23</height> + </rect> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>labelToneZone_4</cstring> + </property> + <property name="text"> + <string>Zone tone:</string> + </property> + </widget> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>North America</string> + </property> + </item> + <item> + <property name="text"> + <string>France</string> + </property> + </item> + <item> + <property name="text"> + <string>Australia</string> + </property> + </item> + <item> + <property name="text"> + <string>United Kingdom</string> + </property> + </item> + <item> + <property name="text"> + <string>Spain</string> + </property> + </item> + <item> + <property name="text"> + <string>Italy</string> + </property> + </item> + <item> + <property name="text"> + <string>Japan</string> + </property> + </item> + <property name="name"> + <cstring>zoneToneChoice</cstring> + </property> + </widget> + <spacer> + <property name="name"> + <cstring>spacer5_4</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>31</width> + <height>21</height> + </size> + </property> + </spacer> + </hbox> + </widget> + </widget> + </widget> + <widget class="QTabWidget"> + <property name="name"> + <cstring>Tab_Audio</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>DriversPage</cstring> + </property> + <attribute name="title"> + <string>Drivers</string> + </attribute> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>DriverChoice</cstring> + </property> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>410</width> + <height>180</height> + </rect> + </property> + <property name="title"> + <string>Drivers list</string> + </property> + </widget> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>CodecsPage</cstring> + </property> + <attribute name="title"> + <string>Codecs</string> + </attribute> + <widget class="QButtonGroup"> + <property name="name"> + <cstring>CodecsChoice</cstring> + </property> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>200</width> + <height>157</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Supported codecs</string> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout18</cstring> + </property> + <property name="geometry"> + <rect> + <x>10</x> + <y>20</y> + <width>110</width> + <height>120</height> + </rect> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget" row="0" column="0"> + <property name="name"> + <cstring>layout17</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>G711u</string> + </property> + </item> + <item> + <property name="text"> + <string>G711a</string> + </property> + </item> + <item> + <property name="text"> + <string>GSM</string> + </property> + </item> + <property name="name"> + <cstring>codec1</cstring> + </property> + </widget> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>G711a</string> + </property> + </item> + <item> + <property name="text"> + <string>G711u</string> + </property> + </item> + <item> + <property name="text"> + <string>GSM</string> + </property> + </item> + <property name="name"> + <cstring>codec2</cstring> + </property> + </widget> + <widget class="QComboBox"> + <item> + <property name="text"> + <string>G711u</string> + </property> + </item> + <item> + <property name="text"> + <string>G711a</string> + </property> + </item> + <item> + <property name="text"> + <string>GSM</string> + </property> + </item> + <property name="name"> + <cstring>codec3</cstring> + </property> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget" row="0" column="1"> + <property name="name"> + <cstring>layout18</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_4</cstring> + </property> + <property name="text"> + <string>1</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_4_2</cstring> + </property> + <property name="text"> + <string>2</string> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>textLabel1_4_3</cstring> + </property> + <property name="text"> + <string>3</string> + </property> + </widget> + </vbox> + </widget> + </grid> + </widget> + </widget> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>RingPage</cstring> + </property> + <attribute name="title"> + <string>Ringtones</string> + </attribute> + <widget class="QGroupBox"> + <property name="name"> + <cstring>groupBox5</cstring> + </property> + <property name="geometry"> + <rect> + <x>10</x> + <y>10</y> + <width>410</width> + <height>62</height> + </rect> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="title"> + <string>Ringtones</string> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QComboBox" row="0" column="0"> + <property name="name"> + <cstring>ringsChoice</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + </widget> + </grid> + </widget> + </widget> + </widget> + <widget class="QTabWidget"> + <property name="name"> + <cstring>Tab_Preferences</cstring> + </property> + <property name="enabled"> + <bool>true</bool> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>DriversPage</cstring> + </property> + <attribute name="title"> + <string>Themes</string> + </attribute> + <widget class="QComboBox"> + <property name="name"> + <cstring>SkinChoice</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="geometry"> + <rect> + <x>12</x> + <y>42</y> + <width>110</width> + <height>27</height> + </rect> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonApplySkin</cstring> + </property> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="geometry"> + <rect> + <x>136</x> + <y>40</y> + <width>80</width> + <height>32</height> + </rect> + </property> + <property name="text"> + <string>&Apply</string> + </property> + <property name="accel"> + <string>Alt+A</string> + </property> + </widget> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>TabPage</cstring> + </property> + <attribute name="title"> + <string>Options</string> + </attribute> + </widget> + </widget> + <widget class="QTabWidget"> + <property name="name"> + <cstring>Tab_About</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>DriversPage</cstring> + </property> + <attribute name="title"> + <string>About SFLPhone</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QTabWidget" row="0" column="0"> + <property name="name"> + <cstring>tabWidget6</cstring> + </property> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>Tab 1</string> + </attribute> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>tab</cstring> + </property> + <attribute name="title"> + <string>Tab 2</string> + </attribute> + </widget> + </widget> + <widget class="QTextEdit" row="0" column="0"> + <property name="name"> + <cstring>textEdit1</cstring> + </property> + </widget> + <widget class="QFrame" row="0" column="0"> + <property name="name"> + <cstring>frame4</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="paletteBackgroundColor"> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </property> + <property name="frameShape"> + <enum>StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>Raised</enum> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <spacer row="0" column="2"> + <property name="name"> + <cstring>spacer22</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="0" column="0"> + <property name="name"> + <cstring>spacer23</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + <spacer row="1" column="1"> + <property name="name"> + <cstring>spacer9_2</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="2" column="1"> + <property name="name"> + <cstring>textLabel1_2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string><p align="center"> +Copyright (C) 2004-2005 Savoir-faire Linux inc.<br /><br /> +Jean-Philippe Barrette-LaPierre <br> +&nbsp;&nbsp;&nbsp;&lt;jean-philippe.barrette-lapierre@savoirfairelinux.com&gt;<br /> +Laurielle LEA <br/> &nbsp;&nbsp;&nbsp;&lt;laurielle.lea@savoirfairelinux.com&gt;<br /> +Yan Morin <br/>&nbsp;&nbsp;&nbsp;&lt;yan.morin@savoirfairelinux.com&gt;<br /> +Jérome Oufella <br/> &nbsp;&nbsp;&nbsp;&lt;jerome.oufella@savoirfairelinux.com&gt;<br /> + +<br />SFLPhone-0.5 is released under the General Public License.For more information, see http://www.sflphone.org</p></string> + </property> + </widget> + <widget class="QLabel" row="0" column="1"> + <property name="name"> + <cstring>pixmapLabel1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>4</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="paletteBackgroundColor"> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </property> + <property name="pixmap"> + <pixmap>image0</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + </grid> + </widget> + </grid> + </widget> + <widget class="QWidget"> + <property name="name"> + <cstring>CodecsPage</cstring> + </property> + <attribute name="title"> + <string>About Savoir-faire Linux inc.</string> + </attribute> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QFrame" row="0" column="0"> + <property name="name"> + <cstring>frame12</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>3</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="paletteBackgroundColor"> + <color> + <red>255</red> + <green>255</green> + <blue>255</blue> + </color> + </property> + <property name="frameShape"> + <enum>StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>Raised</enum> + </property> + <grid> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel" row="2" column="0" rowspan="1" colspan="3"> + <property name="name"> + <cstring>textLabel1</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>7</hsizetype> + <vsizetype>3</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string><p align="center">Website: http://www.savoirfairelinux.com<br><br> +5505, Saint-Laurent - bureau 3030<br> +Montreal, Quebec H2T 1S6</p></string> + </property> + </widget> + <spacer row="1" column="1"> + <property name="name"> + <cstring>spacer19</cstring> + </property> + <property name="orientation"> + <enum>Vertical</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + <spacer row="0" column="0"> + <property name="name"> + <cstring>spacer21</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QLabel" row="0" column="1"> + <property name="name"> + <cstring>pixmapLabel2</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>4</hsizetype> + <vsizetype>4</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="pixmap"> + <pixmap>image1</pixmap> + </property> + <property name="scaledContents"> + <bool>true</bool> + </property> + </widget> + <spacer row="0" column="2"> + <property name="name"> + <cstring>spacer20</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </grid> + </widget> + </grid> + </widget> + </widget> + </vbox> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout19</cstring> + </property> + <property name="geometry"> + <rect> + <x>11</x> + <y>501</y> + <width>543</width> + <height>36</height> + </rect> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <widget class="Line"> + <property name="name"> + <cstring>line1</cstring> + </property> + <property name="frameShape"> + <enum>HLine</enum> + </property> + <property name="frameShadow"> + <enum>Sunken</enum> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout28</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <property name="margin"> + <number>0</number> + </property> + <spacer> + <property name="name"> + <cstring>Horizontal Spacing2</cstring> + </property> + <property name="orientation"> + <enum>Horizontal</enum> + </property> + <property name="sizeType"> + <enum>Expanding</enum> + </property> + <property name="sizeHint"> + <size> + <width>160</width> + <height>20</height> + </size> + </property> + </spacer> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonOk</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>2</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&OK</string> + </property> + <property name="accel"> + <string>Alt+O</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>buttonCancel</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>1</hsizetype> + <vsizetype>2</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text"> + <string>&Cancel</string> + </property> + <property name="accel"> + <string>F, Backspace</string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> +</widget> +<images> + <image name="image0"> + <data format="XPM.GZ" length="58862">789ced5d596fe3b8b27e9f5f114cbd0d0eea6475625cdc878eb3b4b34ca72799e9745f9c07c74b76c776363b07e7bfdf629194488ad49249e4f40151109292488a923e7dac85a2fff9dbc2e9d1e1c26ffffce5fea1f370d95de85e74260bbff51e6f6f67fff7affffdf72fbfae2c2d2f34971696165717967ffdc72fbfe21f0bdd05682c37d61a52ffcc7a87f40eebbb4a6f2a7d47e93da57f17fafa4aa3b7be2274e8487d7d49eab8a4f43575fc96f533d2cf58df547a53e953a5f794fe22f48d95f5de866caf2df58d25a9c34ce96beaf8b9d4cf96cf56f9f890f5333a2edb1b2bbd29757c547a4f1d1f495dd7c78b44efb13e507a43e9db426fae6ef49af27c7da93797943e50fa9ad4f145ea49fd65a577947ea8f5ee1ad7df557a5f1e872dadcbe3f8c47a97daefb2fea0f4a6d2ef95de53faa5d4757de849bdbbacf496d03babcd5e47f6ff52ea9d25a583d2d7a48e7da927f59f125d5ecf27a537947ec47a97eacbfe4c94de51fab1d2fb528767a927f5af94de913a74b5de93e7df577a5f955f14fad96aa7af9ee758eac9f36d28bda1f0b22775dd1e9e28bdaff403a9f79695bece7a2f799e23a5ebe7f9ac74f5fc7045eaba3e7c4af43e1f5f557a43eac0f8eaae25cffb4eeafa7ee354e90da5f7a4aeebe3b5d23baa3d7e3fba3d7d3fe14ee9ea7ee250e9eafec195d4757dfc5debfd06eb6b4aefabf62fb42e8fc367a9f79795ceef5b6f2db99f33a927f7734fe90da57f937a52ff20d1657fba4a6fa8fefc99e8f238bf2fd43b7d3f51e9fa7a6e95aefa8f9b52d7f5e14ce91dd5de86d0fb0d7d7df855eaba7fd854baea0fec285dd587b6d607f2f8b5d2fbaafd2f5a57c7f97dee27fdc153a5ebf6264ad7f5ffd2baac8f37521f2c2bfd4ce90da5ff10fa20391fee4b3d29df52ba2edf49f4019fff46e91da533df0c06fa3882d2d5f1af0f4a1f683d4a94fa24622e4add123117a56e89988b52b744cc45a95b22e6a2d42d117351ea9688b928754bc45c94ba25622e4add123117a56e89988b52b744cc45a95b22e6a2d42d7f177308d821399bf77544f979e4b598c32ef6b08f033cc70bb55de2155ee3cdbcafe8e30bdee210ef7084639ce03d3ee0233ed1df09e9cf38c519decebb87ef2bd53147ac768d2f8cb601612dfbf7136ecefbaa3ea2600bb70855dbb883bbf8b960dbc5366171847bb83fef7ebfbd54c51c1e58dc16da0e3f0eeef81df91dbfbc4bdbfb848b23622d282cf99570f4c7abb6e379dfc1b7962a98c31b1a3ffddce6fb7b52aac53f091107344a5ff2d87c42e8f8eb2daf0fbf25fd7973d4e1293392e0a5eff8a3a0ec6221b785b6a5b7eef7bca53ce6e8e915f39bbd2de7f916c43f57c17a2b7ebb903c966f6447ae166c6b29be08cdbaddde5bdf3b6c187c342a28bbe4e1b0255c278edcc0267e05c42d00e8f8b80ef0ad7b3e5f298b39465c96cb06849b2b42c8359ce1267433c797b1e36d0d88db2e0ab8f2c41db108a56539f602bfa9f324fbe1cd31077d838f724740ea4786bf60e02b07e7597b0fcedfbae7f3957298f372dc00d7ac327f911597e5ac818fb108a7699915dc14c8c40e9cc105f48cba874ead9ea7fdd0c67da3676df8d56f7defc8df4cb928b7751a855deeea602b507694e1bac5b7eef97ca50ce6f08b974baecd32c47321cec93c0db2e0521f37c38364e3ad32838ae3dfac73749df69709bb3d204e931bc915fd774dffabbec14d5e3ffeae900f9a72513ee6006e1d9edb0a9786a1c373776fddf3f94a29cc2dfbb8c4ba4b6730cae19c15abb52fc9fee073a267744163ab331a1242cd7657a13016581fcf6151d99151760727b9656fd9fa53e561f8d6fd9eb714638ec63eafdd649559ceb7afe0dadb5ec5f8b1652f96b2ce98e7743fde97e7c685a587e42734b3f13698900771ef29dfa211f9166790d766618c46956bc2234ee9fca76f7d0f5e234598a3912ec45f3725caa80d9e8c7bfca4f62f57ed2b3c57e5ac6a3c87fb70477e64533c49dcc7198ef101a6f81d66788477d9676ff1dc1fd2d2a7e7fa0c973084195c12b70523bad4b3676a7da6f90c3a30a61acd40e91f7847e567844260940e71421ecc928e1e877009f7e40bbfa49c293816c80dae7ae7df568a30079fcac4df380b96ef4b265137b6d5c4fe4f55fb6ad87307256b54b0e70861a94fd9f1c6ca1c5bdee439e6ba4e12af4bda8147efb9a6b0e9cf3f402bcb4584c5cf057ddbf58dd6701eb80eb204ca32e47b4821cf0d82fc3548fb4dcfd66bf319db956a2fe144c8b1a2037d49ec39b82859a302cf116b14e604888b8c676bf35cb0ceb6739e0d62a6dc3a84310311706ff154f83cb6853d8171ee39a64551ecf7937ccc4149eee2d859418e425bfc894ffa37ecb9b29833edb97c8cc343b9bc00f99f498cc3e539ff465c6322085d2ef46e064e7156a65fcca98955483ed8b0b04e7b5e5c5780b96e0e772dbb1126f20ef2b84e656089add27c43a5ab4eed3928392e97e7395f3e1436c9f619e13d8f50e9fe84e9caf11c6d897f41c8dec91cff4ee36cb64edab359e9dc6ce2e11253da1cb8497bc66401dad7f72131c7fe68c817ddf194ff421e4288eb5655995563ff7295b900863d57d287b0ecb9c3dc92599e3347d16d63ffae1e95b23c0703c2e83159edf6fe84b518a5d639a4f5c6734edaceb199aa93e1397811ef029dcbe52e957f33f2c09f79144d7c06f2904d3bf27b282efdbe92873908fba397e18c395c046cc0849bac5cc33969d7e5f2ef567ceeba548dd7f39ce32fc038cb412ecfe9d82db6c0e226d00c3fb4b8a7a351a5fbca2832b849ed77788ed84af11379d98e1da86a3c18fb3fdb769b7d9daead598fe4610ebf0438ab2036a66c3bb75e12d123241c7a8ef7b1879b79715e279fbb92df0bae61c6e772633336cfd93618f779cb3caef6d93c67645c9969b2e56d2ef5cc0ae051362dc3fce4f09cc54d60e571a1aff6764c4ecc9c636a5c67e6681d928bb96e96af60b7242765e78c185164c2c20a86e6e1898cd6375f9b467c4ee57269cf09b1a42d9be96c1693e7f27d0887e71a9eb34f8de3724434796ed78ec5391cc8c74c5b0ebc36059c5b9cc628b679ce9e1940bd36cb735c86fc629b17ad5929ecc398c7e71025ce1d5bcf325c5421a606570e9739f32838bf15f6750fb3a36726df1afeab50f76a7bce1335b5388547c5bc3c04581c28222c840593af02790b93a3a41de8f09c937b25de73cb8f1c3b8fd80cef69ef049f4c8e53dbccdf8ff7945c9edb7478a56214173edbf5bde7001ac1d788ad2e3dbce7ccb374f2ad79db4dd27aba2f17738e9de3cb45ad1bfcf0cc7bcc7925ce1be5d85a6453c1a3c55781f94966ec0ea6bcc7b6e79cecabe5f34a9e9b94f673c5f6fc1628aa26b93cd7b6b8a354ae8afcd6d574ae0878edb990e00d95bfb238cb9a7f97999f774863ab98a3796d6e84f4c4267c9d3d07de397f8c22cd5b6ced59f69c930720567379cea8af6d35cf3dc8f4c3e1b90da757e30ccfdd67b82c67f3e749de577279cef65bd3b9b7c44df464fd3697f4493fe9a33c37d3f15bf385ce7a62d88f8615e6d873d725be427815cff96d2df23a537e38e23da6cde662ceb60f7f64e6c505ec28b8346d446ec9e63907ab561f183fe4d796e5b85d7a6be610a32b88cfa5398313b56713b59de68d3d305e64fcaec7333121c9af96f0339356560dae4bfc34d39e2b9789b0ecb9f27eab27f2e8f014fb9c16cfb9b195877c9e0bcd37b7da6cf31e8be7dc6cbe555ef2dc83cd6564cd1d1147cf5c216fe263c68493f9bc623612f9142f066f9c786b98b9089e73492894ba971773ceece42fac7c6bc95cadc573b963bbc34b9ef920786c1c67abaa22cfd97c159887697d3721f754e4393cb2ec46af9d305f29c0dcb5b68792586f9abff4320d5c383ee441e29b56fad69ff854b7b39ab49dda732539d3b2e7cef3de6b87973c2c0426dfb0556571cc716e7b82e79a165f79470998581cb5ce67a9ca730dab8dc2797df54b01e63a094f64e36dde6f02c907f5fb92157d5e6c2575137e34f2adaf9957720139b90bc76fcde484a83fd9785b259e7338cc6bd1d9795299d7a8cc73b7561b7e0b08e6397bb370fedc5e300ee6650d62466f79a8b8a289f18d57ea8526f65cd9d62c7bee22ef8b5b273eb7eb8eae3831b84667a52ad9733cea99e7c85eb39527d57da8ca734e1ee2366b27e0a2884e136fcf213627a4107367c118981f7327deb2b93ea3b79d6b6d131afbd2f85cc9595036cfe5f1a39b6fd579247517d0e21a9d4bafca734de71c1607e186fd0dace6daaa3ca7a2d7693b632b5b36219426b6dec7cbf1ababfa1488f5fba3584f5e4eec5a2d7e29c20c8d6487b23e18350d7baee437f98e3d27da7bc26bfe4aec0c76f026b5313df34a1e93f9235bc416296725b9d86af61cd77062678487a9980bcf2b99d8f3eabeeb79ead5790ef7ed6f64a9f777c4a12d7a73d6ad3cc72eeebd359eca4809cc75d03f4fe44f4fd91b1f278215eb861ecab973413f965a39d4fc68bda3697cae24e65c9ef36df024d8cfbf9e08bc40dfcab38a2dc9c556e539f12e79e7cae5e607aaf31cc7654a9c43e639ea9752df1afee9e52e8f756ac5d5923cab3d57c498537268e62cd4d18ecafecbfa16b68cf85ce9b547f025688f5a9c5d7a9ef0d8988d6bd671fc43e215b3debeb17fa9c479ccb97b95798ef717ae8f42e89fd3ecf492dff11f7839c2f10369b4cae44c61e4ceedc41bd8b2ca5c72066b8dc6bc7dec9bf1347b44b66276a5a39999b928be6d10e2b90cefb5cc33e3c4389659338e9ea93e66dd01f12d56ee7976ecd89df33d843b37fbd8386665897196c7a9e4417cd0ef218c2b58f172841127232bed30cb21bed9c41cc53bcce59e174260c6e6c3dfd5f10a1e49609d15fbef75a9ef2176325fd3fc20ab4b1e6b7bce7cac8e7dcfe6f3f1ab9527357dd5a32c16f029e1a6ec9a08a9afbbebe662bf8a6fd9be67cf43e79e8b1da7a5c2ba4c2b7e8e202611ab21f9befbbac89b794e185dc1cb6c7be4b3acf96b243c7a55e50af10b5c65e6d8a5f24d62db89cf6d8ad506f116ce0939c46770e7fff29438eb0e4710f2e167b01d5ef781fcd4291e93bdb8091db21bc70070e79bcfc2e74142cfc8df07f2b7ee704cfdf0f7615f7c718b47d4fe0c0506a7f3febab5e2fa73df8cfc6be15ff2154a45d1e89e7dc12e1c10a20af334342e1f54cba1951587e7d6dfe31c51a4545b67932cfcb273d856e77d65d5c4b1e7fecb57f49daf545f4f18ce3cebcc59f3e4b057cc581f4d2c9efb3ecfafdcfffbe575eba613dfadaa58b1c96dcb7812b2c53eba58f3e7e6f265cacf254994fb156b6cffbddf87c01659619bbcc666096bec230b790c29cfcdbd37957b7f1b9a1bf54ee79b605bcc3026ff7b884fc15253ff4c82f83b385ae025b1e77e8a95cac9537dd4cf148f0803019ff75dcedda7bbb52efa407f3d7122eed30f98fa675245cc6949e69ded64e35c1f51a08f6d9d8703a0ff6bf47b08ed7c6e62b2761073b774ccfbf646cca5c22b03ce7e8e5f01c12631db4b92d53f224ea9317b8adb74be06af36360dadb543e3ee4be4b9aa8220a2baf82c249d394c96df3eaf8ad8247c9a6b81006ee008c5bccb75f5053e582b324d6cfe34d6779af1d7a723dc4a66ac00b5b108e7380cc589517c952884bf06123c074311b9a636c4b70fd64a50740d47b84eef53c1db04f738c6276a690cad74bd46c2ce3936685ba7f6f5fcaa323c774ac7bcbf60103117161abd8e047a080153fdcee20f7a26e24edf132a1e04d7c84c83989706537af6e2c91fd3336b094b3bcd55c13d3dc9699a3d23dc3e0a1c93d5d3a2273862643cc240cdeedc127692380fb5ef99274f3d7a54fd78e49537c56a9a6dfebda60798d179fa12a9544eac43774c489ca2f82e312707c1f938d9c63db5a1381487b84d75c53b764af7635baf6020ed39be2f219e8310f746cc85c5e405badb6da103f38bcea0121bb465665d7872aebf4b8c933c0f40ae97cc04854769f513e2da3ac34a3ca34ac09d6431f20a037379457d3ece7599e7668a5d9b023bb28764a3b6d3160889399683b8428d4a14efceb6ea53bab2a5e895fc46a304cf718b5e8c47cc95131ecbf6388ed74e5732a7777906721d89470fe6c8e6d2775da09339418f4e13815562b7a9594bd86522064123aae0b87e78ee07f1a4e04048eb19ebe22d4aeb9d38746622826c84b66f25163ec69c9a9ffbc73d7d8d65ec3931c3c0bf3f62ae8c306371448a79cef8f681ac37f915ea3a3353c35979eb51e7f84539168dc16dc144b2969e1387fb0223e249499ecbff5d0818a4f612fbad49691a0fd9cee335eddae96a13c2560bc51e39da92fb8d188fad8a87cbf15c287a1331972fbc7afabde4288101c173e69a21642bb5d53aeb6c0d11f7b4d2df39c4b1b4e8041f12beee68ec92df729dca919af889ed3042e494acf47b14489ae9b857becd0f2de2448d6830ed3ee6e24bf9a6703bf41fa1f888da7e0afd2e19db0ea17b704a0c3911f6a8b01f794f097b2e2c117321c1167b09fcf536bde3438939e639e38b6ec154fa7fb27deea43f49a5e52a3a5bd25aa367ced8a3b148f2c4a2fcc2465873f42cd14597e4b982fedda74cc83c675a9fcc73b0adbcd912d11fb6e63c5fe4d01508bbe007db78e2ad929e45299e0b49c45c48c4334d474acef69c2b9e33ec7ab6d2adf71c26621c250e427e4ec2b34cd0c156d8808f4b5d708767652469cf15f58fb84dfb32c29e4b7a21ceca3c37947fcb5e6d766c657b33b100c5fb26cb94b3e7421231e717810ecbba9f04786e94c58688a7249ee391b2e3b46fda521ea9f47685e5e5fb6587923c67d973e6ac7969cf9d9a9e72416b23ee97b326077be3497e83af3df2dcbb094cf819682ff394b5a987e746ca9e33c625b6a75ea4b720d0435c90c6e59e9903d3b89df00492f9bf34864ba40ec379cca4ec84da51dfae727c2ec3733c86bfa4ab7d91b5300dfa98fb6caf6d2719dc0deaa988eebda416204764c6b2d7ca9e1be6d97310f855b388b990f00828be09ddc031fb93722685e00e234a4b969a8c9534e8dd5f17bf8e04d2a6532312790f633342c1f113834f84374825d6a9ddafb00d331561c6222f52fbd26a55b2a30ccfc9d8728bfde545dc00b16eec76deec059cb1cd3aa41a138ef08937e996e37e77e25de0b743c70f5b9263a5671c686f3fe621aa0bee894c02bdef7b34aaece9cc8fbd8616dd5995d1a2e313fe052f61bf19712ef1bcac1a5fed118cd8846a127300e156b10c79230d7745cdac48bb51b02e21d62a0d8f464e6e28fa457d1a17fdde35e1f252bc5d847cd01904eafdb6f88e82aeee2b217028475a7a0ff95706443fc3bf688c81bc47c4dccf2c345abef91783ef3fc721622e4add123117a56e89988b52b744cc45a95b22e6a2d42d117351ea9688b928754bc45c94ba25622e4add123117a56e89988b52b744cc45a95b22e6a2d42d117351ea9688b928754bc45c94ba25622e4add123117a56e89988b52b744cc45a95b7efdcffffcf2ff6d14cd7e</data> + </image> + <image name="image1"> + <data format="XPM.GZ" length="68046">789ced7d5973eb38b2e67bff8a8ac65bc704aef62526e6c1b2655b5e655b5e27e6012b49efbb2ddf98ff3e496482a224522665d739a77b5c1951559f052480c487446221f95ffffaeb6cb8fbd7bffeeb1f4fcfe239527fa9503cfef52ffd727333fedfffe77ffdf73ffe59afd6feea56ff6ab53b7fd5fef93ffef1cf90ffa5fe62ad8aa88a6e8c83c0e1a6a80b1563bde6b0111d5989b1b50e5bd111d6fd7e47b82bab4e9f242c65c3a5bf8c71bbe2d3ab178f49dfa6c355f8ddc498dd27d8a53723c2a4dfd6138cf50f082bd98cb174ed69d7e077a79f3d385cf7d8ae3adc1082eabbe2700bb0fb3df820acb1fec10d61235b0e1f24b8edea5775b80ded75fa82cd04d79dfeaec3d01a4c6f9f1dee26fadf11cbaa143116cebe6dd1aeb5b17d4f8821bdc3914eb0d31f840976fa4c40d8a03dc211618b3840fb43eba5eb6f317058b6eb6da78fdd21067bbaf644970976e51b41d8a23dd8196259911da70fcb57ed461bdbf786d8d7df7c2418ebbf42d860fdc31a618b980d1dd6ed661bdbd3439ce8bb254ced13c661d36eb55dfd84e36fdbb6e11fc78f27c29db6ab6f887cb350beab8fbe460ced71f9a5245cc5fe93ae7e9d8acf2ffa84bb6d1c3f1162c8efeac35e128cfc39235c437b057b0976f999e357a7eaf5294358b41d3fcc2a62682ff2eb3dc168af53c4509ec3a2e970cde757ef84655bbaf67611fbfa062dc255ac6fb44298ea2b1c1f3a759f5fdc12566de72f827bc4be7c799960d4df275c257e3e10aea17df507e13ada4339fb771ac000eddaf78ad8ebd3f784499f584930dadba727fd668d709dec6f093724d6bf4bb82d9d3fb23dc21de5fc837a74b8090c73bf73b467d397afb708d7b07cf344b881e33be8116e49d71e7b40b8abdc7893cebf755ac050e7fff81162afcfea04bbf6084eb88e386c24d8b54fbe11a6f285f34f9db6d7afb0fded4ea5e3dac72f10fbf2f898701db1784cb02b4f350837b0bf8c4f4fed511d873b5ebfb8275cedb8df39b6b7e3f5458f843b687f739360acaff32f9daecfafb608d73ace1fb010b1d7c7b70937a8bf7708b7a4e3af6c3b2c3af58e1b4fea04b14f1fdd136e62fbec5d829d3dd92361af0ffb57761a1dc77f8ef697901efb633dc1e87f4f09b7910f6cdf61d56976d07f30c43ebddc20dc421cde11eea2bd3496af3bad0efa2ffc5d437a575fbd4bb88df58d5e087790ff6687b0203e62fb0c3004fbbb4d18fe71f6c0f10ab321eab7db0976fa830bc202c78f1e11560ae7b3b704e3fcd527ac956bbfba72d8faf2c43ae16ec7b55f0bc4be3ce9fc65b7e27f1755c21050b8dfd710437b5d7af69660d77ee1fc5fb7ead39b016148e0fa730731d8dba5673ac1aeffc23dc2d4be3024ac15f2cbd9ab5bf3fa34eaaff9fcd1156141fa2a84ad72fda99cffefd68121189fed13d61d979e6f21f6f9ed4982911f1dc2543fd324acb1bff5b1c30daf4fad13361df47758ff86d767df084bc4e1056185fd2db0bca6cfaf6e09db8e1bcf4c2186fc18efbd12a6fce13a61aa9f3d256cd09ec6f9bf6ecbeb332b88bb952e968fed6f4985fac34b8f51bfd9204cfa05f667dbe7971dc2d5aefbdd3c23f6f9f92b614dfa2e095be47384f56fab0af1d98d672067adebec1fa03d3a3ebf6e2618db3b246c68bcdc20067d38bfec13ae2a8c4f90bfdd6ebdebec63df11437e8ce702c4aa86e905b65f741b5d8cbfb07ce1d3f34a8291cf02319487f1c107e11a6279e8b0ec36bb381f3f20067bb8fc364c30f61fda5b427b305ebc244ced892ce19a72e35fbf136e2a1cafc877053d8ef3d53962d087ed5f235cc7fcccf997ae861ec5f6370883c370f947887d7dd813e12af9a72e61af8ff2ab96c2f182bf1baf4f22bf8dcfafb0bf2cf410c68b686fb00ef2233c235c477b868f09467b30c24d85f38f6b9fa8400f3acc0788bd3ebe9b60d4b74398f4070f84495f5021dc26fb3abe892af428fabf087192df106e2a8c5f9b8485c6f9d9b547d4a0879c3ed527acbbe8ef2462af8f3d136e607bc301e116d64f617beb6061f4472f887d7a7544b889fda39e09b7b07ecaf967d1f0f9c52a61db457f748dd8e70f0f09537e4bf9bd7d4c9bb0d0e86f3e084bedf8ae5dbc259a5ebfc6fc4d5111e83f2e1127e545843ba8df7a4cfa14d6a705eb751c9f847dfd84f31710ecd7048ed713c449fbeb84db684f53230c2184cb5f4930c6c38ab0c2f6055784b5c6f181e577445db8f126ef117bfdfa817087ca538415b687a1fdbba221305e0a11fbfa9863c2945eb9784608b020f21beb23805e2e7df89c6057ff708db05438ff397f22a4cf2fba845b02f93c42ecf3b373c252213f9c3f170a2cecf8c6b07ca5048e7f1311d6c87fe3e27ba1c142e82f38629f3eba262c115bb497d6158dfe14eb67c042aeff38a637be3dc13161ea1ff1445823b62b887515f529b4af050bbafe08b7112b85fac26a825d7b851b4fb20216c278e510b1ff3d6810d688cd1d6183e5b33a62688fb3b7dd205cd3383e1d5f64152c8ae3e99030acf05d7b03c45ebf7df118f5eb3a61ab31be72fe4ad67c7e7549d8e0fe52b885d8d7cf0609c6fda00fc216b16e2518c7b34c30ce2fd8fe1ad8d7b52f7a265c437b5b93605cdf6e2718dbeff820ebbe7efa80b0a5fdb257c4be7efc8630d52f8a107bfdaa45b8a171bcbbf12c1b893ed41faf9f5dfba301e244df43825d7be51562df3e7b94606cdf3ee13a962fb17f9a5ebf1a12aee27e12c3fa36810f38febb849b1ae373c74f19af6fd17f61fe16a477f6e62b84ab8835dabfedd3eb27c275dc1fe1d81f6d9f3ed0846bd81ef94eb88eed09b60937b03d419b704b23ff5d7c2b3b5ebf1e126ed0fe15eaef4079e8cf2ce11a62db264cf68a9e08b735c6f3ce5fcbaed7a739e126ed9fe0f8e87a7d7a35c1185f62fd844fcff608b768ff00ed2da07cec4f45b881ed8f04e116f607c3f11aaf4fb1be387ea4b7176f10a6fc612bc1185f217f145808fd1f8e37e5d307bb84a9fdccad5fa58616e37c8bedd75e1fdf23dc44cc2e08b7703c9933c21decaf4012161afd19fa27588fd27ecc3a62d087f9cf0993bea84fb88dfa4c48b8ab717d564f30ae6fd05e162c86f3a922ac70bda8b0bfadd72f6f0993fe7095b034387e1c1f5525c92f086b5cdff14dc4901fe3c967c2d45eedc6a3aafaf4ea94b0a1f5da0d629fdfb40877b0ff831ae12ef68f70fda56a3e3fab20f6e92523aca8fe6ebcab3a58c0d547be22f6e9b921dcc5f6cb3e6181f6d5ce9e10dd55687df44ab84aeb9333c43e3fab2518e7ff3161d26776096b83f184e31b445fa4cf5c10aee17a85df2286fcc8cf2a6189fa6425c1b8bebc22ecdb8fe5b7bc3e31225cc7f5093f46ecf5471b842562b34ed8607dc5598271fde4c623445ba44f56093768bd3244eceb6b1e092be4ab6e13b606d7bfce9f43f445f9f519e126ae2722e45b07f263fcf29a608c474e096bb447b0ef31dac3387f08d115e9532b845b18ff73ec8f6ea26f8330e9b37dc206f5856f884d05ed13ac2518f79fddfc06c1451bd70716eb2bbc3ef346d8a23d03e4af305583f5433e49b000fa8723c4da607e7ee031d6275845ecf30bccafa085383eeb887d7a63085bc41ac76f1c1fe2f87842ecfb4735119b1aea0f3b84eb06d74fad04e37e37f2338e17717c058415c6b71cfbdf78fd01470cf6c3f91af9697d7a8b7cb6dede518f7015ed179e2718e7c357c2543f7b91609c1f9c3fd571fc88f1ef0031e4c7f95f2518e3bb63c23eff05e10662ad138cf38de3abae428b91ef06b1d717dc11ae219622c1b87fe37f6f60fdcd15e126ea57a81fe2418a7f0927fa2618f5ad11ae63ff055b845b06e335177fc1ec5ac1f854bd11ae627c667711437eb4ef71829d3e734d98f431b7ded70d9f5f9d13ae61fcc5b17d0d9f5faf106e10bf2ce136ead38e4f305b527e7d4eb88ef195d946ecf3739d609cef07847d7bb17e2d9f5f87841b142fa1bd5b606fe44f8d700bed2f1d1f75dba7d701e126c537b788213ff285116e21b61eb70dee2f20df3a5003ec6ffcbde3d3eb31e18ec178f088701731c3f677a106b87f718018f4637df1770125205e45ec7fb79d043bfb44fef70ee2604c1896782ebff3afe0ddbb387f877dc43ebd6d12a6fa9977c294dfd4138cfedc1096884d27c16efc48e49bf2e5c9066181f3b9467b29281ff11be12ee1f504bbfad847c2549ff088b02f5f1256583e437e6a6831da1bdba3bdfe684cd8a777f134786b85f329477b1a280fe3b367c212cbb7878495c17805cbb35022fa27e4bff5f9f93d61ca1f9c2718e3434698ea63fdef9af43b6c2a50433cefea21f6faf40e6185fac40b6163717fdaf93f53851aa2ff6920f6e9a377c206cb0b373ca6fc6ebd0bdea982f38f8c0857d1ff734598f4d92a618ded096f138ced71f6066f42f9c51ee11afa732608537ee37fa7fa29e7dfc05b507ab947b88efed48e081bcccff7138cf1c13d625bb158beeb4f18fd945f8e0837d07ff22e619f7f1d31e4c778cb8d5718fd945e0e0937c9bf55095bb467c411fbfccaf93f13fb1bdccff198d2f307c4901ee7ff1bc255acbfae2518e7ab6bc235c4519860dc8f73fed57492f27609b7d17f71ec9f8eb74f68087bfd1dc2a44fbb78ce747d7ed123dc417fc5914f5d5f5f2e138cfbfd6784499f443e0b9f5f5f12ee92bf3a460ce9f17cea25c158bf2ae13aea53680fe9f3b323c202fd0143fdd2e737f784eb16e737ca6f1b88a59b8f4dec7fd03f617d15a4c778fd34c1185f9f2418e79b16e186c5780cc757ec8fd0bf60ff6a9f3f3822dc202c083731bfc0fa19d080ebbd26625f5f734a98d2eb7e82717d8cfd6ffd78b1d83e0bbf637d25e116a60f77138cf1931b2fb6021a707c9f22f67ce5823095cf2ce11662fb9460d4bf49b88dfa95eb4f600be95303c2c4a74811267dbc93608c6f1f08933ee67fef58dc0f77f32ff43ee9934dc2c42ffd4898f4c907c26dc4c1907007f50b672fe83dca6faf09537a5e4b30d6a74d98ea23d13e0dcfa7f09430e90f5f128ce91d3fc0bac40f7d4b987ee72dc25d6aef6b8291ffaebfa175d4df22224cf60cf709537e354a30aeff4f080bc4f226c1b89e40fbb6bd3e51274cf6608630e50f9e128cf193222c110bb457c7e797cf84c93efa8a30e5679230e58f6e138ceb75ac6fd7e7976784a9bdfc9130e597d709c6f12a082bc4c2f903289df2eb8830b58f33c2943e6c2718e76fe7dfe2d2b03cbe4e98d2eb6a8231fd98b046cc102b9f9eaf11a6dfc55b8271fdfc48d82066681f9da41709c6f9744898d273e74f6284589c2718f7d3de095bc407d85f76827fe4477e9dfc70ee477eb5fc70ee477eb5fc70ee477eb5fc70ee477eb57c3fe738e3824baeb8e6865b1ef090472097fc8a5ff31b7ecbeff83d7f8034ec77b7fd477e8f7c27e7f82330ed893ff317fecadff87bae8cf907a459e13dbecad77eb7057ee457cb77708ef7f93adfe09b7cc0b716726d56b6f90edfe57b7c1f7ce3f0775be2477e957c9573c037c90ff8213f2ac1b57919f1637ef2e3f3feff90af700ef876cacff839cc955fe11bca05af80c7abf2feefb6c88ffcddb22ce7f890d780235bbcfe0d7c9bc4793bbcc19b3ffeee3f5b96e31c6ff136f8b7afcda779f20abeb3f3bbedf2237f9f2cc339de659cb1bf856f7e9e0d99f89965ff53a52ce798e46da6fe260f379123a6f92d33bfdb3a3ff2774839ce31cb0216fecd7c4b8445ecf277dbe747be5fca708e37d9d5b7ae193e933abbe627bfdb42fffec26ed8edefae435a8a728ef7f90344f74bcd93e0b1eed83d7b608fec89c5a7142f7cc45e58216dec8dbd7fcf3a968dd9075b613db6cad6589fadb30db6c9066cebcf891ba186db6c87ed7e973ede8716efb17d366407ec901d95cc3b62c7ec848dbfbf9dc538078c5b85756a9979f1949db17376c12aacca6aacce1aacc95aac8d3dcc3aac2b78415d1f8209f1d5760a2994881fa3b22909a03f564528a2efb7eb9275bc845a5d7d9bbe6b7123026aeb2ddb2e9397dd8a3bc875ff7d2360220539d7150fc5d70de2513c8967f1225ec59b78cfb4c6587c8895c2fc557cf52b6de47dd113ab622db63d1b8abe58171b621370dc1f03712bb644a9fef8bb44ec885d18037bdfa30d5a0d1e0e1907ff1d8a8392b90fc5911889e3ef6f6711cef1137152dcc389537126ce17b6e64254f84529aff9067e76e939908d8055d6f1ab2a6aa24e7fdd15bba2219aee9796687fbf6d7faf88e3f8ddd124dd3f29a2fb9c735c42245f981d12922fb4c4580a29cbf08df42aa9976d23eb01dbe287730c5b9966aeb432000f5095e1df319e7faf88ed645e35f20f891e503ee31c6ff1a0b84f9297f24a5ee76b9337f256de95671cc891bc970fcbb41078f5e818f70433d7dc6807af1bb191fcedfdf0ddc26ee54be2e5fe96a86c7959cc393e94af65f67fe51b6b2db08391cbb06d222bcbdcf3946388d89ce5e5c7efb6f6af12de972bb297706ec0367f778dd2b298737255ae9562c5a5bcc9d5752dfb72fd2b9c931b7209dbc901ac1a623fd7935be572421cb827b7d90afc7b67369a646371cd32dbcac672372b3a1475b927f7d9891ccadc689edd4e7b62b7dbb1c232fcf3276dde9287c9cc8a51c5dc3ea73c9223b92f8fe5893ccd8e95e5d974b962479ecb91881645d630675cc86db1270ef2ebbc8873fc943d9764c57df63ad58dbccad718e7e4bc7c5427abb2e6ec5e978dc279e2773db6645b76645771c5643b7e1bf084b330230f95943da5667382ad5795141b2a554f712c57d83af89d4b6560cd722bebac2fabc0a6995e018e6b65c5dda44fd909db8fdf9bab0271a34276286ec4502eec73141561049bf274eb6227e9090be3700b346b68dda53c64fbea4abea8ebf45e1cbb15fb71fb27bb7af240dd884b7129ebea16f2dd418dee451247c55ad583d8528fd0cac7b88d624b06f228abaef99ce36beaa9eccd38f59c670fd6562f5f665c5cc26bd9f955bda977dc2f009bd58b310ed61503e813258fc8dae398b7eac33389ddaa0fc7e3d6b446de572b714ad99ef815b6a57a2ade171ca855b5a642d557eb0cf44b037d325dd30757cffd894ea8b19d15b5f1b9d7735c4de581d1b1e97b46c6abd821c4783d3570f84c8cd456ec0be5fea4f7e4998adfea6b54b28b2477d5d64c4d8c4a78ac76d51efcadaff6d550c050743b02461dcadd79462ce0dc49c9793566c4911ae5f4fcf177300e4a3861399e344fc4b5b795926cc38ff6859cdb565b6c8d6d4fc63d1babd0f1e1d0e787ff43dfb93255d6b1706fe305cf483e91ddc0aa39de8f69b23db90bfd7d2ca4e8c98172f551a7e9fab85d58ab82893f5567338c1b00cb0f3ff773e258ad80b7f5dc7857e793b6c0ecb829362062d849a5be703b791b93541009c4ef290e5425f9cbdecc8efa4076448f746e41bd02b505ed72b76ee3530c5583911680179d8b68f238c7d7d51227abaaa19a399c6b7d0fe7f83b7b2e77df04c6e04612db04625df560a6fb9007f93d076bbe33369ed95519c57dc8f625ed3caa37377b19753ad5d7d2ed3c07ead2fb2255737f69415c789bae933c566de8b59a4aeddea84bc790a427e12fdd94af7a82197b471c17dba7041eddf99d1258af8fd3658b9dd9132de65a079e38890844843be6ea3eb140948a1007b2ad2ebc0d21b605bf1daf54d275837254fc57cd67fd721ee734d3621946c4ef70cdd4a7bf8b73724397bce304d17217e7d7a417b486394a9d2b5dc4ef39bb7ea855c87929c2a49766e224d74ad72becc0cf3930afb6630eea704edf2d4474e05be4636a2625cec9646763c239d0b9c146655a8d33753c67aa4f774ac02fb9b95806fe2f9e736212cf4d3807de1666ef8449f2231e57ec40cfec02aa6b7796b7ae676e0765734e5fa9527b2429ce5debccd59cbed577fafe7b58a71ff46319ebc7169463d188a3a814f302f5a8daaacb76646e143a119817db6e77b54a9c8168def5d2a148ed47ea27f7b7b63fc1d5cff17cc4fa5927e5a2eefa79a0925d47cf393648fee23937d02f6577ad259d7bc94355fd2c2d8c0d9c859373edc4cf25a365c239b6cfa6d60610bd815dd5e3dcda7e575d41fa35fd3afdf71ccebd2de7e51c2372e22d3dd61fdfc4baba5ec92e6391c07c361277102169dd9bf27a03f5c18eb3f73d527d12124f23af0df9045e29a98b3c93eeb449912e98df0ea1378289f7986185dbb5d5d6f7553ee7644b0d32eb752b4fd908d6bb07f38c943e9adb979fdc2881d655f064565df8bf2de05ca0a6635858a593f73b9f8947b6310294dd69eb66714e08bdfa052fb4a633bd06f4d23afff81e4fc7f8b2cfc3b231db95e72284a8792de5f56ec57e9e1f01e628b7d2437e26f307c4d4ebae076ac98a70e43c57e06f70c0ea25fe628b9417399a435c6ff8d9359773037195e9298ff506ac13bb6a5fdca88bd935b93c2ac23976cb56b4a55367abf9e79c936d39158f884351252b6ec80b3fe3c2083f712bdf58eba6b49f718e193df802e7b674ce2d0d71ae77f4ee77f83a75c2bf78bb491cc77b702a898a656f9a19ec16e6be11db84de5e8398cbafd80622898d44db7931abf790adb056a9b9be6bf99326f0ab2df8bd2773c6875c713db2efd3e7714e3ea95a66fe8bd48e88993d6b00d6e4722e6e9d6cb26d71a5f6a4914f5e8b1ea672e7f9b90d39b56e6293138f40056c15acba29427da0d6219a6bc66fd59f1d31599cd3856f19e5b0ee30ff5e893ed223bdf50d9eae9257427101cffb82379c9cdca5c6e88e7e912d7dac4fc0a247fa1456bef7e4e752f6d667183be36a4fc6ec8b531cf85585bcd03db7d61de5706ee47ab1ea63ec3cce29c932573afa5c3da66284997b77a29ecd39988fb754a498ded74fec44487624461077399faf8bccadabd35e2bfeb2169524217251ba129fdc282de3539c0b793ebf4337cf3958c35c7d910f5c2f885a754dd7bfe1199e974577098a8a1ca9a4cfd82a8e46986d76605608c44d7aa680b9d7602c9fb2f635f6b9eaeb4b1de993d8cba9f7c98e81041f12ff45e68c4058efc5b1f7aa5f85e4734e656a10db7a72a66ad58c9f93cfd99c038ec4df84db00be1dfbd6e90a9e0feac6e79c9b9d29216ac3f16844add8edd70cce3575f38b7eaeb5781dc8a46eeb8eee7e89d78aef7f03e78e2627e17a133927b761c61a405cdc4bb70263b3f4cacecda638b70562536de1fcab6e553216e496e18ea7399c536f6ee6ecf85dd3b29c63b76ad370dd03391677b3f19cd8c9e21c1bc43be4bac73ed2ad6363bc6b27138695e0dc05325f9d153d159ee79c597267ce4bfc1587cfcbe58ff1d70f96f777eac47cc39388f2791211a9fb987310e974dc989dd9519356adcd720e38b1929adb70ed96ba1d09bdbeea3c59ceb3ba300b175ab7e671ced9b11fdf0bc8d22f8ee73927daae4603636753e389c7329c13d7428ba935ef6732cb39dee7e62bef1f318199dbffccb1d6904b137d61967dfefa1becd847728638d06771cfb1ddd8b210a3cdec4d809fbb9de79cdca57b527e7e1eaaa93b7e6adbedfb66fa7d79e676afac9ea45e82730bda36c6182dcd393972b3bd9cbdd5c5fb6e0dbe14e7e814c24e4e2c3e9339ceb578895bc1738cbb345765ee908bb1b93637aac4cdf7945c167bc304782e60d0ec1e395a5a067e9700fae2107bc571e7607a6d065ab631e299e61cdbd29b69ce293b7d6a2f9b8ed330bbcedf8552bd988fb0c238f37f53fc7b39477b6efb93134f7612c712c0b9a99b4d60870bb4c3329c7311dd5a3c5fcfdfa080f5cad1fc1ed41ce79a7c7749bedd9a3b5398eb13310fe6d13c2d51deb37929a25f5ea83518eb2ff278f69c4b5dcb43daa35b633d64a53c703d05f1709a25d24a7ab6608673b7fad53fe7e2a43b5bba3a753bc7ab6a773a7e520ff1acaeded3e7adb8479ce61c5bfb929f73a344dc4c6ef3a96b7decc6c0c654ca91a2bdca09e7e401ae99529c3bc196ce730e4ac2fb2f57d31616c7ea5c1dce4629199c2bf5bc4d8a01afe64dbcce6a2f267c68decdd894dc2f5627acd01e9ddc71eb04889dd59a1c0809d1433f8e82e4875bbfe1aedb50500c0a63bee552afcb136403fc65177e0fb23817efb1a5f6c806ea6daef4f82eca40046625be2944658f55a402f8ab513c7d7f53a39fdb9adc24472f1a7ff97119ced1aa7a6de2e36175bde9d875cf06be75108f0dfd0e5d9a73eefe5530d93d917bc861b63abf3a055b5ee1bd1dffbc30b4f286eda9d82673f76c6739677a65673ab36ad64c5f7cf9d95bb36e364a965cf0d6b0dc5187607f3a75005b564507ef71ba31df1357e999571c2a17f9438a23118a7dd1d53d98212f63d6a977363353c058e6c4c7813ccc3a85176dd6539d3872971d5835dce93dd97627623dbd31bd57aa5c9d4cdaf3b9930a33504b3c7f04abdafd69d6b832aad4babae26cd36c0958b9ab00ace3da30d97b663726b6573f75eadfc3f3e19c33914371837716f48508d926db80083110f73ae3b6df1ce7b64b7bb81db3fb1defa316e766cfec9739a53085cfbfa4d5e7ba6156a66f80c99a5ad55c5e4cdb908de58a399071b435000fb3af847a90fb6c53bfaaa1d89d3f2f67bbe0c96ec1be1d1d66ef1680c6b138521fc919f95074d4307d33836ab925b6744fa64a602bfa584973b8cc9390bcaf76d499ba9b3d05117bb0b6de7723f05234d886da94db6c47f55485ed4d9e816563fd2a8dea4f6e3088ba8668505de53d9b0d6cde8058a59fb471dd1cb0edac387a8e73a5d69166648ecd37be51c49c9a3359d8db9952518e8ed8ae1c42bc5b633d71672e4c45699857324f59459d1dc17cb1ab2f6573c20cd090e9cde3930a3962bbf9ef5980f91956bef24429063dac7661759c71b2002c1900ef52bfc44f5d88de6cfc545480eb76fec6a4bb8fb9252379ae4f277703e66fd5c933f631fd1c36c4ba4750bfdcfb2d309b57630b8397db067b7ce4ddca9e8be76e0bf7b8fbfef272d6c817f11e7f85b8d8e918fba39edafc91a232e7e70adee7550dd3e69927cf5f97f8dbcb856af10da75f3ff2eb659673b6d09b6bccb365f6cbefadc917fc66e40fe7fe336519ceb1a7623b635f11de8fbffdb9b81e36e72ee48ffcd93217cf9d7dc6381b9abd5ff1ce36605d642f17d6a5f06d61f960aff82dab9823d3fb1575ffb5c299bde6b5e5da25c65cf0539e79d79fb7f8aabd92abf0ef9b72daf91adf875cb79a9997cf9f35e49f9c08d83b9bfbdcf432621feca37dcab3876ad9054f75b3827ece5eb137becdc7fc82d7d509bb624bae03131bf5d9a57d1127fc8371beb1a837789f1ff00adfe15b7cc06fd87b76df7e525a8baff01bbe91fd2b931081efc80db9214eb429f7764821ecab7d931b8c817ddab3ede02d7da84ef8b63a019b31fb6ec7459eb78bbf51a357a1c56f98d77ef0b9b78994db9f630f768927111689edd955bb66fb763dbbefec86ddccad4fa1a75298b4b3e326f3d982e2221ff895bf9ba0ea8b9e07b25be9f7cbcb3b5629cf3a60ed7b7c0f36e75735790ad986bcc08d9e743b6cd2db4cd999dd1b3eb4bb36c506e0d00dcf799234c9d367712dd2d60ee74f0be6fcdceaa29b1e76cf2cf56ea405bdb21feb15dc0eed813d9c7fca015a7e947bcfa5d0ee3cbb6433ab9172fb7a19751ed9c957cd764c233f25cce45363586ef0d2bbbbbce1f2be668fc9f49d6ebb5dee7973de4de73573fbfa30eff6a6de1f3d56f545be8ef7e5ead4ddcb23796f33fcc21ce71e6ceed9973db567d9a58931ac34cfed85adf07b5beafb49b6365542dd366cd3b6d2b337442bedacb79181df1e15b2ac044f3f9df78b6fb2348d94c6ba5d70bb85dff39979833198494acd80d631438bec7bd1363d1edf16d525a31dbdd468580ff87c0a3e34db33e7ef9736e7a96e21f853fae625f8c5679df99eda32f74a82b991c08741fc289d0a7460021b042e5558e6992cae66dffd1f44c1657095be2f105c0737f3b561aad84cf237736ea1b79de71cb4ef16e2ba32a3f297700e4670e60d0d21340bd2e70447fc32eb5df67c2db84bbf5910fe7f2fcf2716bd3f17dc070f694b058fc153f01cbce866f01a4c7d3f3328e5df837190719f2458097ac1ea84bbc15ad09f4bf5526c2d30cfb960bd4c0d33fa6a9a73770bcacee01c44120f65be7bf17b3917cf98a60731da24e23a02549d7eab387f0c36588a05f22ed8c8f671b1cc716ea89eb222ba603348226f711e6c05dbc1acf7f0294bbdd3d19e077bd97af851b01f10eb583b38982be7b0d8cd8279cea99c7572e1befa22e7400641e137e7ff6ece39fb5f06a3342becb6e5b6aa1f99b1d7102fbf839f4a73e6753e364ccbfcf3107ac566799ee3803caa780d4e83b31c9ec4294b45e8763dc87f73ec765009dc2d0b98c36bd3bfa993a0e059ef1fc9b971d028fafe8b3f8173d012c1f88c2ffae087fc1a56154fd3b7328226bf5ffc6d8579ce0547f3cf7d05ad80d65b4127e8e6d8d149c8c352f79a6c2b5cf0c44fd00fa5957c28de4335f3dbc7a2f5e294b5e6e3b92fbee9f41b38076b0fbec20ac5a37f06e7c0173d86faf3bb95f63d6f8d3191ace75bc18fce6832afa189ef7c84360c16971986e6747189d3c23a61f489c6cbf02abc0e2ad37f2dfe46b079ce850bdf4d52a0afbec039c6ecb6f717b2d0fb1bff14cec5519bfdeceec5887ffa3e9eece7f883b93357a01acc47e16d78177e72a752be973bfb5723f1e9b310e143f818cea49285efc1cf73ce2c78cf76a1be5a8a738cf1bd50d98e7eb383f0395ead6b018cf974dfe4cfe11c30e0852f78ab08ac227491157916e7c217f636ad4d0fc2d7f0edf3b7ec87efe1b8dcc998be0a97786f0ef4d8273be2a97e9fe3dc57df3bb104e7e21d8607cf2fdee78f9ab1677ec4de6cc6bb4fa7e54fe21c94d7c9ff726fd028b6f398fd5e263e77a3235c097b79654dc4dc8625bf9214be84a5df200b7258fc0b60f39c2bee2373faaa3ce75ee7f7afe54308ac8399f6932ffce03bb2fe14ce9917f190db2b392706b392fdfeb9b0bfdc9743c2f530e72c3a4fc2cdb0fc3ba0ea65deb4f927f8b9702b6b9f9c37e3b52044dd9d85f704aeff24cef1fdd9397022baa0bfc9e61c6f85dbcb3c611fee8425bfb81274c2bcfdb95c51f5624f53535be6e3b92f9eb796e75c5e7f86fb3073d6e3b82ecf6ff3167e4ff2cfe01c5f0b87f9fd62df8bac20f2df271c1ed8d24f8001e70e83927b5fe15138b74a5e2c729d3f95393bcaf0735fbceb599e7322777dca1fb975377e0cbb9c6f151f0677b85bfa67702e3c5ef8cde88b6054e46c28f7bde94ce7cfdbf99c3b297b63ddf4e4e27b99f3320a4bedc6cc73aee81c905be7f273eb82ef5886fbea09c6515d3cc84dbe9e9e83799f091f3dfd7ecef1357ec76677496765ccae3ebfad95ff7d083b2a1fd3856765e7d6b0d4978841b617f55fa6ade6f7e7967c2f6cd257dfca39777bc3d0d9cf8e0dcc3670a1ca845c65c1c4abe4722e7523439d94b30d4fbfc1f78d2f9ca138e3b7b3df318aef7aeac1dc3ef1213f593c0f2df826c93ac41aa5beb20ab6bdb02563a5b052b2846ad9e7b733fc5ccefdc7a2f2dd9cc31bbbc92d3f58cb8a133d989ec5f238a759ea76e1912d77d69de2abfdb00bbe8fcd0c3f9be2d618a2cc4d7e17c67734c73c98faed883d2f8eeb167defcbbcf04fce08e618510b4b3df10a3169a38c7e58e3158a52a7ca98df2b515f7b26e2fb39e7ee47dee5df5ccce71c13e91ba9e6bcccdd3c963e53dacaff925a781a1cf2a95b23f2958b4949ccd8abb0995e734244a0f26fb42dfeaea16165e7d7b01596b8091b764a697f2bb77aa07e9f3f6fbdd0acf8fe5e8655fe06ceb9d4ab41ee13ed799ce3359eba7f284e6ce1e72f999dbab39fbbe369b7a66fb7d97793f1f608f04f53a998022f9ac3ff4fbedfbac64bf921b06e37cab86f9a2d621ce5ee6967890d8a9d8acfb4619e73601156297e923167dfbf8b737dfd36f334c1e79ceb9b617a66933977d8e7f2315649e53bcafbe2863d0e46e9084b37d97bb607d38f7cea3dd47a6007d975f9ec3bd5e129f0b744546756a3c21e247c658f85351f4572b9e7b5b238075287f8f78137ec182276696f7813668b8e7c900feeb9bd5a780af2a24659d1e3dfc539772a761234b37646f338e776f00ed3e9ccd1e76ff716e380a7ee911ff1ebac1b96bc6f47d373265372c1896aa4c2ad74146ab7f959d64d8ccf38e7faac545417e9a8d0298195d127cf4ca7256c16bdbb9451ff9cdba51351275ad813986bced913447b03be1b49fec22fd995ed9aedd9fee0fb537b06dfc8b95860963a9c1fe5f99c8b9fa549df3e931b10a72df0e1c0a41b7e96e2c611bbcebe6d2e57cdf4939ee7a697afd7e5a9b169aebcd9ee3ceb3ee79c7b66a1c417e2f47d144405de291c4551e19d39bb1df6978dc082a3e84bdf1e8015ddcc7cc537d2678e59d14d927209cec16cf9c2c3595fb79073b07ae4e93da77124cd30fbab2d91e2c77c30f50cca207337ba2f37a777e3c403f8f74f7799ec7534fd6c433dd4b34fb816e15cbc7b981fdd664974b3f8dc35ba8deea2c26f9a63dab0e5579a10932ef9b65a928b607ddad630fb267d0633d482f7d9f22ac54c25df93c90c0fa677c3d81b5ff81407b3d1034bbf87fe024a8e421dd4ed2d8f9fc4bf0a38a0a6dc48f9d023f06367595fdc95d7fc606aafe68247b6e097e52132799eaafb45743d7d13bf18e7f850b3725f8d881ea3a7bc91295ea3e7a8f857abb7cc66b9a7f3e66abf0aac5be26bb4d8d74163f6194d88baeed0f303e336e79f539f48b81ffb58b99ef725e5051c326668d3a7e99fee29f235fdc69fed7bc1e87b3b68b2c08eb2c6321fdaf1f4335ce170f689eb45a2afa2d7e978864d4527c538e7f6ca1b6566d8f09dbd446fd1bb789bfab2c7bb10d138fa085e8beab1dbb6f3d5f7c64204b365ab86c94d534ac263be2a7598f13e20beceabf636ecf36afed34d287295efe59fb62eac35946186fa903d435c1965455c19791ecd8bd9e62b6193c5b3b397d892099277918428b507aba69c91cc87d1ab3d71efdab8805115f2d5725f698ef90ff3f01ecccd17b180d79b8ab58a722e167bacea65fd45b462a2a8171eb0f768355a8bfad17a89dc173016ffc6378efd270b5f679786d95d63a20dbe19de449bbc0dab21f6f9d30a130de129acdbbf744e0891a6fcfc7d258bc5de440f4b7e4564995cd7fc9bdf54f1237f8294e39c8b5036f4e01bbe11f789d86df5b42852fa917f5f29cb391741efc31c5ff2f4bf94d4f925c44a5fbcfdf1237faa94e75c2cbcc3cfcc8237c37d49b658a5e8bafc47fe1d6539cec52b13580b76d9dbb7fa3b58254503bbf3b59d911ff9d36559cec5c2877c9f0576b9f5c19c30151c16d9e9fe917f77f90ae762e16b5273b3e8e65711d14df5644bdfc6fc917f4ff92ae762017ff7681ad1161fc9b552fb77752d7845bdea37fef895fb6c3ff2ef25dfc1392fbc2557f9b17ae5bb9feca61c411c78ae0ff96d78a01ffff3de63fe238be53b3987c21f799357d93b6faba7709b1f46923dd9f87db803550fb76d378afd5ad7ee943f83fc91ff0cf97ecefdc88f2c961fcefdc8af961fcefdc8af967ffedffff98fff0759629c80</data> + </image> +</images> +<connections> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>ConfigurationPanel</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonApplySkin</sender> + <signal>clicked()</signal> + <receiver>ConfigurationPanel</receiver> + <slot>applySkinSlot()</slot> + </connection> + <connection> + <sender>Menu</sender> + <signal>clicked(QListBoxItem*)</signal> + <receiver>ConfigurationPanel</receiver> + <slot>changeTabSlot()</slot> + </connection> + <connection> + <sender>DriverChoice</sender> + <signal>clicked(int)</signal> + <receiver>ConfigurationPanel</receiver> + <slot>driverSlot(int)</slot> + </connection> + <connection> + <sender>buttonCancel</sender> + <signal>clicked()</signal> + <receiver>ConfigurationPanel</receiver> + <slot>reject()</slot> + </connection> + <connection> + <sender>buttonOk</sender> + <signal>clicked()</signal> + <receiver>ConfigurationPanel</receiver> + <slot>saveSlot()</slot> + </connection> + <connection> + <sender>Menu</sender> + <signal>clicked(QListBoxItem*)</signal> + <receiver>Tab_Signalisations</receiver> + <slot>setFocus()</slot> + </connection> + <connection> + <sender>stunButtonGroup</sender> + <signal>clicked(int)</signal> + <receiver>ConfigurationPanel</receiver> + <slot>useStunSlot(int)</slot> + </connection> +</connections> +<tabstops> + <tabstop>fullName</tabstop> + <tabstop>userPart</tabstop> + <tabstop>username</tabstop> + <tabstop>password</tabstop> + <tabstop>hostPart</tabstop> + <tabstop>sipproxy</tabstop> + <tabstop>autoregister</tabstop> + <tabstop>Register</tabstop> + <tabstop>buttonOk</tabstop> + <tabstop>buttonCancel</tabstop> + <tabstop>Tab_Signalisations</tabstop> + <tabstop>SkinChoice</tabstop> + <tabstop>useStunYes</tabstop> + <tabstop>STUNserver</tabstop> + <tabstop>playTones</tabstop> + <tabstop>pulseLength</tabstop> + <tabstop>sendDTMFas</tabstop> + <tabstop>Menu</tabstop> + <tabstop>Tab_Audio</tabstop> + <tabstop>codec1</tabstop> + <tabstop>codec2</tabstop> + <tabstop>codec3</tabstop> + <tabstop>Tab_Preferences</tabstop> + <tabstop>Tab_About</tabstop> + <tabstop>useStunNo</tabstop> + <tabstop>buttonApplySkin</tabstop> +</tabstops> +<includes> + <include location="local" impldecl="in implementation">ConfigurationPanel.ui.h</include> +</includes> +<signals> + <signal>needRegister()</signal> +</signals> +<slots> + <slot>generate()</slot> + <slot>saveSlot()</slot> + <slot>changeTabSlot()</slot> + <slot>useStunSlot( int id )</slot> + <slot>applySkinSlot()</slot> + <slot>driverSlot( int id )</slot> + <slot>updateRingtones()</slot> + <slot>updateAudioDevices()</slot> +</slots> +<functions> + <function access="private" specifier="non virtual">init()</function> +</functions> +<layoutdefaults spacing="6" margin="11"/> +</UI> diff --git a/src/gui/qt/ConfigurationPanel.ui.h b/src/gui/qt/ConfigurationPanel.ui.h new file mode 100644 index 0000000000..19b5a02ecc --- /dev/null +++ b/src/gui/qt/ConfigurationPanel.ui.h @@ -0,0 +1,358 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/**************************************************************************** +** ui.h extension file, included from the uic-generated form implementation. +** +** If you want to add, delete, or rename functions or slots, use +** Qt Designer to update this file, preserving your code. +** +** You should not define a constructor or destructor in this file. +** Instead, write your code in functions called init() and destroy(). +** These will automatically be called by the form's constructor and +** destructor. +*****************************************************************************/ +#include <qdir.h> +#include <qmessagebox.h> +#include <qstringlist.h> + +#include "globals.h" +#include "ConfigurationManager.hpp" +#include "DebugOutput.hpp" +#include "QjListBoxPixmap.hpp" +#include "TransparentWidget.hpp" + +#define SIGNALISATIONS_IMAGE "signalisations.png" +#define AUDIO_IMAGE "audio.png" +#define PREFERENCES_IMAGE "preferences.png" +#define ABOUT_IMAGE "about.png" + + +void ConfigurationPanel::init() +{ + DebugOutput::instance() << "ConfigurationPanel::init()\n"; + Tab_Signalisations->show(); + Tab_Audio->hide(); + Tab_Preferences->hide(); + Tab_About->hide(); + + /* + // For reading settings at application startup + // List skin choice from "skins" directory + QDir dir(Skin::getPath(QString(SKINDIR))); + if ( !dir.exists() ) { + _debug("\nCannot find 'skins' directory\n"); + return; + } else { + dir.setFilter( QDir::Dirs | QDir::NoSymLinks); + dir.setSorting( QDir::Name ); + + QStringList list; + list = dir.entryList(); + for (unsigned int i = 0; i < dir.count(); i++) { + if (list[i] != "." && list[i] != ".." && list[i] != "CVS") { + SkinChoice->insertItem(list[i]); + } + } + } + */ + + /* + // For preferences tab + SkinChoice->setCurrentText(QString(manager.getConfigString( + PREFERENCES, SKIN_CHOICE))); + confirmationToQuit->setChecked(manager.getConfigInt( + PREFERENCES, CONFIRM_QUIT)); + zoneToneChoice->setCurrentText(QString(manager.getConfigString( + PREFERENCES, ZONE_TONE))); + checkedTray->setChecked(manager.getConfigInt( + PREFERENCES, CHECKED_TRAY)); + voicemailNumber->setText(QString(manager.getConfigString( + PREFERENCES, VOICEMAIL_NUM))); + */ + // Init tab view order + + // Set items for QListBox + + new QjListBoxPixmap (QjListBoxPixmap::Above, + TransparentWidget::retreive(SIGNALISATIONS_IMAGE), + "Signalisation", + Menu); + new QjListBoxPixmap (QjListBoxPixmap::Above, + TransparentWidget::retreive(AUDIO_IMAGE), + "Audio", Menu ); + //new QjListBoxPixmap (QjListBoxPixmap::Above, + // TransparentWidget::retreive(PREFERENCES_IMAGE), + // "Preferences", + // Menu); + new QjListBoxPixmap (QjListBoxPixmap::Above, + TransparentWidget::retreive(ABOUT_IMAGE), + "About", + Menu); + + QObject::connect(Register, SIGNAL(clicked()), + this, SIGNAL(needRegister())); +} + +void +ConfigurationPanel::generate() +{ + // For audio tab + codec1->setCurrentText(ConfigurationManager::instance() + .get(AUDIO_SECTION, AUDIO_CODEC1)); + codec2->setCurrentText(ConfigurationManager::instance() + .get(AUDIO_SECTION, AUDIO_CODEC2)); + codec3->setCurrentText(ConfigurationManager::instance() + .get(AUDIO_SECTION, AUDIO_CODEC3)); + + + ringsChoice->setCurrentText(ConfigurationManager::instance() + .get(AUDIO_SECTION, + AUDIO_RINGTONE)); + + // For signalisations tab + fullName->setText(ConfigurationManager::instance() + .get(SIGNALISATION_SECTION, + SIGNALISATION_FULL_NAME)); + userPart->setText(ConfigurationManager::instance() + .get(SIGNALISATION_SECTION, + SIGNALISATION_USER_PART)); + username->setText(ConfigurationManager::instance() + .get(SIGNALISATION_SECTION, + SIGNALISATION_AUTH_USER_NAME)); + password->setText(ConfigurationManager::instance() + .get(SIGNALISATION_SECTION, + SIGNALISATION_PASSWORD)); + hostPart->setText(ConfigurationManager::instance() + .get(SIGNALISATION_SECTION, + SIGNALISATION_HOST_PART)); + sipproxy->setText(ConfigurationManager::instance() + .get(SIGNALISATION_SECTION, + SIGNALISATION_PROXY)); + autoregister->setChecked(ConfigurationManager::instance() + .get(SIGNALISATION_SECTION, + SIGNALISATION_AUTO_REGISTER).toUInt()); + playTones->setChecked(ConfigurationManager::instance() + .get(SIGNALISATION_SECTION, + SIGNALISATION_PLAY_TONES).toUInt()); + pulseLength->setValue(ConfigurationManager::instance() + .get(SIGNALISATION_SECTION, + SIGNALISATION_PULSE_LENGTH).toUInt()); + sendDTMFas->setCurrentItem(ConfigurationManager::instance() + .get(SIGNALISATION_SECTION, + SIGNALISATION_SEND_DTMF_AS).toUInt()); + STUNserver->setText(ConfigurationManager::instance() + .get(SIGNALISATION_SECTION, + SIGNALISATION_STUN_SERVER)); + ((QRadioButton*)stunButtonGroup->find(ConfigurationManager::instance() + .get(SIGNALISATION_SECTION, + SIGNALISATION_USE_STUN).toUInt()))->setChecked(true); + QRadioButton* device = + static_cast< QRadioButton * >(DriverChoice->find(ConfigurationManager::instance() + .get(AUDIO_SECTION, + AUDIO_DEFAULT_DEVICE).toUInt())); + if(device) { + device->setChecked(true); + } +} + +// For saving settings at application 'save' +void ConfigurationPanel::saveSlot() +{ + ConfigurationManager::instance().set(SIGNALISATION_SECTION, + SIGNALISATION_FULL_NAME, + fullName->text()); + ConfigurationManager::instance().set(SIGNALISATION_SECTION, + SIGNALISATION_USER_PART, + userPart->text()); + ConfigurationManager::instance().set(SIGNALISATION_SECTION, + SIGNALISATION_AUTH_USER_NAME, + username->text()); + ConfigurationManager::instance().set(SIGNALISATION_SECTION, + SIGNALISATION_PASSWORD, + password->text()); + ConfigurationManager::instance().set(SIGNALISATION_SECTION, + SIGNALISATION_HOST_PART, + hostPart->text()); + ConfigurationManager::instance().set(SIGNALISATION_SECTION, + SIGNALISATION_PROXY, + sipproxy->text()); + ConfigurationManager::instance().set(SIGNALISATION_SECTION, + SIGNALISATION_AUTO_REGISTER, + QString::number(autoregister->isChecked())); + ConfigurationManager::instance().set(SIGNALISATION_SECTION, + SIGNALISATION_PULSE_LENGTH, + QString::number(pulseLength->value())); + ConfigurationManager::instance().set(SIGNALISATION_SECTION, + SIGNALISATION_PLAY_TONES, + QString::number(playTones->isChecked())); + ConfigurationManager::instance().set(SIGNALISATION_SECTION, + SIGNALISATION_SEND_DTMF_AS, + QString::number(sendDTMFas->currentItem())); + ConfigurationManager::instance().set(SIGNALISATION_SECTION, + SIGNALISATION_STUN_SERVER, + STUNserver->text()); + + ConfigurationManager::instance().set(AUDIO_SECTION, + AUDIO_CODEC1, + codec1->currentText()); + ConfigurationManager::instance().set(AUDIO_SECTION, + AUDIO_CODEC2, + codec2->currentText()); + ConfigurationManager::instance().set(AUDIO_SECTION, + AUDIO_CODEC3, + codec3->currentText()); + + if (ringsChoice->currentText() != NULL) { + ConfigurationManager::instance().set(AUDIO_SECTION, + AUDIO_RINGTONE, + ringsChoice->currentText()); + } + + ConfigurationManager::instance().set("Preferences", "Themes.skinChoice", + SkinChoice->currentText()); + ConfigurationManager::instance().set("Preferences", "Options.zoneToneChoice", + zoneToneChoice->currentText()); +#if 0 + QMessageBox::information(this, "Save settings", + "You must restart SFLPhone", + QMessageBox::Yes); +#endif + + ConfigurationManager::instance().save(); +} + +// Handle tab view according to current item of listbox +void ConfigurationPanel::changeTabSlot() +{ + switch (Menu->currentItem()) { + case 0: + TitleTab->setText("Setup signalisation"); + Tab_Signalisations->show(); + Tab_Audio->hide(); + Tab_Preferences->hide(); + Tab_About->hide(); + break; + case 1: + TitleTab->setText("Setup audio"); + Tab_Signalisations->hide(); + Tab_Audio->show(); + Tab_Preferences->hide(); + Tab_About->hide(); + break; + case 2: +/* TitleTab->setText("Setup preferences"); */ +/* Tab_Signalisations->hide(); */ +/* Tab_Audio->hide(); */ +/* Tab_Preferences->show(); */ +/* Tab_About->hide(); */ +/* break; */ + case 3: + TitleTab->setText("About"); + Tab_Signalisations->hide(); + Tab_Audio->hide(); + Tab_Preferences->hide(); + Tab_About->show(); + break; + } +} + + +void ConfigurationPanel::useStunSlot(int id) +{ + ConfigurationManager::instance().set(SIGNALISATION_SECTION, + SIGNALISATION_USE_STUN, + QString::number(id)); +} + + +void ConfigurationPanel::applySkinSlot() +{ + //Manager::instance().setConfig("Preferences", "Themes.skinChoice", + //string(SkinChoice->currentText().ascii())); +} + + +void ConfigurationPanel::driverSlot(int id) +{ + ConfigurationManager::instance().set(AUDIO_SECTION, + AUDIO_DEFAULT_DEVICE, + QString::number(id)); +} + +void ConfigurationPanel::updateRingtones() +{ + std::list< Ringtone > rings = ConfigurationManager::instance().getRingtones(); + std::list< Ringtone >::iterator pos; + + ringsChoice->clear(); + + for (pos = rings.begin(); pos != rings.end(); pos++) { + ringsChoice->insertItem(pos->filename); + } +} + + + +void ConfigurationPanel::updateAudioDevices() +{ + static std::list< QRadioButton * > buttons; + + while(buttons.begin() != buttons.end()) { + DriverChoice->remove(*buttons.begin()); + buttons.pop_front(); + } + + int top = 0; + std::list< AudioDevice > audio = ConfigurationManager::instance().getAudioDevices(); + std::list< AudioDevice >::iterator pos; + + for (pos = audio.begin(); pos != audio.end(); pos++) { + QString hostApiName = pos->hostApiName; + QString deviceName = pos->deviceName; + + QString name = hostApiName + + QObject::tr(" (device #%1)").arg(pos->index); + + // New radio button with found device name + QRadioButton* device = new QRadioButton(DriverChoice); + buttons.push_back(device); + DriverChoice->insert(device, pos->index.toUInt()); + device->setGeometry( QRect( 10, 30 + top, 390, 21 ) ); + // Set label of radio button + //device->setText(deviceName); + // Add tooltip for each one + QString text = deviceName + " " + name; + + if(text.length() > 50) { + device->setText(text.left(50) + "..."); + } + else { + device->setText(text); + } + + QToolTip::add(device, text); + + + top += 30; + } + // Set position of the button group, with appropriate length + DriverChoice->setGeometry( QRect( 10, 10, 410, top + 30 ) ); +} diff --git a/src/gui/qt/ConfigurationPanelImpl.cpp b/src/gui/qt/ConfigurationPanelImpl.cpp new file mode 100644 index 0000000000..06dfc4c006 --- /dev/null +++ b/src/gui/qt/ConfigurationPanelImpl.cpp @@ -0,0 +1,71 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <qbutton.h> +#include <qhbox.h> +#include <qlabel.h> +#include <qlineedit.h> +#include <qsizepolicy.h> + +#include "ConfigurationPanelImpl.hpp" + +ConfigurationPanelImpl::ConfigurationPanelImpl(QWidget *parent) + : QDialog(parent) +{ + mLayout = new QVBoxLayout(this); + +} + +void +ConfigurationPanelImpl::add(const ConfigEntry &entry) +{ + mEntries[entry.section].push_back(entry); +} + +void +ConfigurationPanelImpl::generate() +{ + std::map< QString, std::list< ConfigEntry > >::iterator pos = mEntries.begin(); + while(pos != mEntries.end()) { + QVBoxLayout *l = new QVBoxLayout(this); + + std::list< ConfigEntry > entries = pos->second; + std::list< ConfigEntry >::iterator entrypos = entries.begin(); + while(entrypos != entries.end()) { + QHBox *hbox = new QHBox(this); + mLayout->addWidget(hbox); + + QLabel *label = new QLabel(hbox); + label->setText((*entrypos).name); + QLineEdit *edit = new QLineEdit(hbox); + edit->setText((*entrypos).value); + + entrypos++; + } + + pos++; + } + + QButton *ok = new QButton(this); + ok->setText(QObject::tr("Ok")); + mLayout->addWidget(ok); + + show(); +} diff --git a/src/gui/qt/ConfigurationPanelImpl.hpp b/src/gui/qt/ConfigurationPanelImpl.hpp new file mode 100644 index 0000000000..b8aeeddafb --- /dev/null +++ b/src/gui/qt/ConfigurationPanelImpl.hpp @@ -0,0 +1,69 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __CONFIGURATION_PANEL_IMPL_HPP__ +#define __CONFIGURATION_PANEL_IMPL_HPP__ + +#include <list> +#include <map> +#include <qlayout.h> +#include <qdialog.h> + +struct ConfigEntry +{ +public: + ConfigEntry(QString s, + QString n, + QString t, + QString d, + QString v) + { + section = s; + name = n; + type = t; + def = d; + value = v; + } + + QString section; + QString name; + QString type; + QString def; + QString value; +}; + +class ConfigurationPanelImpl : public QDialog +{ + Q_OBJECT + +public: + ConfigurationPanelImpl(QWidget *parent = NULL); + +public slots: + void add(const ConfigEntry &entry); + void generate(); + +private: + std::map< QString, std::list< ConfigEntry > > mEntries; + QVBoxLayout *mLayout; +}; + + +#endif diff --git a/src/gui/qt/DebugOutput.hpp b/src/gui/qt/DebugOutput.hpp new file mode 100644 index 0000000000..0001320532 --- /dev/null +++ b/src/gui/qt/DebugOutput.hpp @@ -0,0 +1,30 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author : Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __DEBUGOUTPUT_HPP__ +#define __DEBUGOUTPUT_HPP__ + +#include "utilspp/Singleton.hpp" +#include "DebugOutputImpl.hpp" + +typedef utilspp::SingletonHolder< DebugOutputImpl > DebugOutput; + +#endif + diff --git a/src/gui/qt/DebugOutputImpl.cpp b/src/gui/qt/DebugOutputImpl.cpp new file mode 100644 index 0000000000..20348d9036 --- /dev/null +++ b/src/gui/qt/DebugOutputImpl.cpp @@ -0,0 +1,32 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#include "globals.h" +#include <qfile.h> +#include "DebugOutputImpl.hpp" + +DebugOutputImpl::DebugOutputImpl() +#ifdef DEBUG + : QTextStream(stdout, IO_WriteOnly) +#else + : QTextStream(&mOutputString, IO_WriteOnly) +#endif +{} diff --git a/src/gui/qt/DebugOutputImpl.hpp b/src/gui/qt/DebugOutputImpl.hpp new file mode 100644 index 0000000000..0541aa319a --- /dev/null +++ b/src/gui/qt/DebugOutputImpl.hpp @@ -0,0 +1,37 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __DEBUGOUTPUTIMPL_HPP__ +#define __DEBUGOUTPUTIMPL_HPP__ + +#include <qtextstream.h> + +class DebugOutputImpl : public QTextStream +{ +public: + DebugOutputImpl(); + +private: +#ifdef DEBUG + QString mOutputString; +#endif +}; + +#endif diff --git a/src/gui/qt/Event.cpp b/src/gui/qt/Event.cpp new file mode 100644 index 0000000000..67f0964704 --- /dev/null +++ b/src/gui/qt/Event.cpp @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <qobject.h> + +#include "globals.h" + +#include "Call.hpp" +#include "DebugOutput.hpp" +#include "Event.hpp" + +Event::Event(const QString &code, + const std::list< QString > &args) + : mCode(code) + , mUnusedArgs(args) + , mArgs(args) +{} + + +void +Event::execute() +{ + DebugOutput::instance() << QObject::tr("Event: Received: %1\n").arg(toString()); +} + +QString +Event::toString() +{ + QString output(mCode); + for(std::list< QString >::iterator pos = mArgs.begin(); + pos != mArgs.end(); + pos++) { + output += " "; + output += *pos; + } + + return output; +} + +CallRelatedEvent::CallRelatedEvent(const QString &code, + const std::list< QString > &args) + : Event(code, args) +{ + std::list< QString > l(getUnusedArgs()); + if(l.size() != 0) { + mCallId = *l.begin(); + l.pop_front(); + setUnusedArgs(l); + } +} + +QString +CallRelatedEvent::getCallId() +{ + return mCallId; +} diff --git a/src/gui/qt/Event.hpp b/src/gui/qt/Event.hpp new file mode 100644 index 0000000000..1fea8a1762 --- /dev/null +++ b/src/gui/qt/Event.hpp @@ -0,0 +1,63 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __EVENT_HPP__ +#define __EVENT_HPP__ + +#include <list> +#include <qstring.h> + +class Event +{ +public: + Event(const QString &code, + const std::list< QString > &args); + virtual ~Event(){} + + virtual void execute(); + + virtual QString toString(); + + std::list< QString > getUnusedArgs() + {return mUnusedArgs;} + + void setUnusedArgs(const std::list< QString > &args) + {mUnusedArgs = args;} + +private: + QString mCode; + std::list< QString > mUnusedArgs; + std::list< QString > mArgs; +}; + +class CallRelatedEvent : public Event +{ +public: + CallRelatedEvent(const QString &code, + const std::list< QString > &args); + + QString getCallId(); + +private: + QString mCallId; +}; + + +#endif diff --git a/src/gui/qt/EventFactory.hpp b/src/gui/qt/EventFactory.hpp new file mode 100644 index 0000000000..1a21f15688 --- /dev/null +++ b/src/gui/qt/EventFactory.hpp @@ -0,0 +1,98 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __EVENTFACTORY_HPP__ +#define __EVENTFACTORY_HPP__ + +#include <list> +#include <map> +#include <qstring.h> + +#include "Event.hpp" + +/** + * This is the base class that we will use to + * create an object from the "create" function. + */ +template< typename Base > +class EventCreatorBase +{ + public: + virtual ~EventCreatorBase(){} + virtual Base *create(const QString &code, + const std::list< QString > &args) = 0; + + virtual EventCreatorBase *clone() = 0; +}; + +/** + * This is the actual class that will create + * the request. It will return a Request + */ +template< typename Base, typename Actual > + class EventCreator : public EventCreatorBase< Base > +{ + public: + virtual Actual *create(const QString &code, + const std::list< QString > &args); + + virtual EventCreatorBase< Base > *clone(); +}; + + +/** + * This class is used to create object related to + * a string. However, thoses objects will be created + * with the default constructor. + */ +template< typename Base > +class EventFactoryImpl +{ +public: + EventFactoryImpl(); + + /** + * Ask for a new object linked to the string. + */ + Base *create(const QString &code, + const std::list< QString > &args); + + /** + * Register the string to return a Actual type. + */ + template< typename Actual > + void registerEvent(const QString &code); + + template< typename Actual > + void registerDefaultEvent(); + + private: + std::map< QString, EventCreatorBase< Base > * > mEventCreators; + EventCreatorBase< Base > *mDefaultCreator; +}; + +#include "EventFactory.inl" + +#include "utilspp/Singleton.hpp" + +typedef utilspp::SingletonHolder< EventFactoryImpl< Event > > EventFactory; + + +#endif diff --git a/src/gui/qt/EventFactory.inl b/src/gui/qt/EventFactory.inl new file mode 100644 index 0000000000..369d47e217 --- /dev/null +++ b/src/gui/qt/EventFactory.inl @@ -0,0 +1,95 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifndef __EVENTFACTORY_INL__ +#define __EVENTFACTORY_INL__ + +#include <qobject.h> +#include <stdexcept> + +#include "DebugOutput.hpp" + +template< typename Base, typename Actual > +Actual * +EventCreator< Base, Actual >::create(const QString &code, + const std::list< QString > &args) +{ + return new Actual(code, args); +} + +template< typename Base, typename Actual > +EventCreatorBase< Base > * +EventCreator< Base, Actual >::clone() +{ + return new EventCreator< Base, Actual >(); +} + +template< typename Base > +EventFactoryImpl< Base >::EventFactoryImpl() + : mDefaultCreator(NULL) +{} + +template< typename Base > +Base * +EventFactoryImpl< Base >::create(const QString &code, + const std::list< QString > &args) +{ + typename std::map< QString, EventCreatorBase< Base > * >::iterator pos = mEventCreators.find(code); + if(pos == mEventCreators.end()) { + if(mDefaultCreator) { + return mDefaultCreator->create(code, args); + } + else{ + DebugOutput::instance() << QObject::tr("The code %1 has no creator registered.\n" + "and there's no default creator").arg(code); + } + } + + return pos->second->create(code, args); +} + +template< typename Base > +template< typename Actual > +void +EventFactoryImpl< Base >::registerEvent(const QString &code) +{ + if(mEventCreators.find(code) != mEventCreators.end()) { + delete mEventCreators[code]; + } + + mEventCreators[code] = new EventCreator< Base, Actual >(); +} + +template< typename Base > +template< typename Actual > +void +EventFactoryImpl< Base >::registerDefaultEvent() +{ + if(mDefaultCreator) { + delete mDefaultCreator; + } + + mDefaultCreator = new EventCreator< Base, Actual >(); +} + + +#endif + diff --git a/src/gui/qt/Factory.hpp b/src/gui/qt/Factory.hpp new file mode 100644 index 0000000000..a89cf9212f --- /dev/null +++ b/src/gui/qt/Factory.hpp @@ -0,0 +1,58 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __FACTORY_HPP__ +#define __FACTORY_HPP__ + +template< typename T > +struct Creator +{ + virtual ~Creator(){} + + virtual T *create() = 0; +}; + +template< typename T > +class Factory +{ +public: + Factory(); + ~Factory(); + + /** + * This function will set the creator. The + * Factory owns the creator instance. + */ + void setCreator(Creator< T > *creator); + + /** + * It ask the creator to create a SessionIO. + * If there's no creator set, it will throw + * a std::logic_error. + */ + T *create(); + +private: + Creator< T > *mCreator; +}; + +#include "Factory.inl" + +#endif diff --git a/src/gui/qt/Factory.inl b/src/gui/qt/Factory.inl new file mode 100644 index 0000000000..5b96b6474b --- /dev/null +++ b/src/gui/qt/Factory.inl @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <stdexcept> + +template< typename T > +Factory< T >::Factory() + : mCreator(0) +{} + +template< typename T > +Factory< T >::~Factory() +{ + delete mCreator; +} + +template< typename T > +void +Factory< T >::setCreator(Creator< T > *creator) +{ + mCreator = creator; +} + +template< typename T > +T * +Factory< T >::create() +{ + if(!mCreator) { + throw std::logic_error("Trying to create without a creator."); + } + else { + return mCreator->create(); + } +} + diff --git a/src/gui/qt/INSTALL b/src/gui/qt/INSTALL new file mode 100644 index 0000000000..4aaabb5573 --- /dev/null +++ b/src/gui/qt/INSTALL @@ -0,0 +1 @@ +read README file. \ No newline at end of file diff --git a/src/gui/qt/JPushButton.cpp b/src/gui/qt/JPushButton.cpp new file mode 100644 index 0000000000..6e64b26290 --- /dev/null +++ b/src/gui/qt/JPushButton.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jerome Oufella (jerome.oufella@savoirfairelinux.com) + * + * Portions (c) Jean-Philippe Barrette-LaPierre + * (jean-philippe.barrette-lapierre@savoirfairelinux.com) + * Portions (c) Valentin Heinitz + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with dpkg; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <qbitmap.h> +#include <qevent.h> +#include <qimage.h> +#include <qevent.h> + +#include "globals.h" + +#include "DebugOutput.hpp" +#include "JPushButton.hpp" +#include "TransparentWidget.hpp" + +JPushButton::JPushButton(const QString &released, + const QString &pressed, + QWidget* parent) + : QLabel(parent) + , mIsPressed(false) + , mIsToggling(false) +{ + mImages[0] = transparize(released); + mImages[1] = transparize(pressed); + release(); +} + +JPushButton::~JPushButton() +{} + +void +JPushButton::setToggle(bool toggle) +{ + mIsToggling = toggle; +} + +QPixmap +JPushButton::transparize(const QString &image) +{ + return TransparentWidget::transparize(image); +} + +void +JPushButton::release() +{ + mIsPressed = false; + releaseImage(); +} + +void +JPushButton::press() +{ + mIsPressed = true; + pressImage(); +} + +void +JPushButton::releaseImage() +{ + setPixmap(mImages[0]); + if(mImages[0].hasAlpha()) { + setMask(*mImages[0].mask()); + } + resize(mImages[0].size()); +} + +void +JPushButton::pressImage() +{ + setPixmap(mImages[1]); + if(mImages[1].hasAlpha()) { + setMask(*mImages[1].mask()); + } + resize(mImages[1].size()); +} + +// Mouse button released +void +JPushButton::mousePressEvent(QMouseEvent *e) +{ + switch (e->button()) { + case Qt::LeftButton: + pressImage(); + break; + + default: + e->ignore(); + break; + } +} + +// Mouse button released +void +JPushButton::mouseReleaseEvent (QMouseEvent *e) { + switch (e->button()) { + case Qt::LeftButton: + if (this->rect().contains(e->pos())) { + if(mIsToggling) { + mIsPressed = !mIsPressed; + if(mIsPressed) { + press(); + } + else { + release(); + } + emit clicked(mIsPressed); + } + else { + release(); + emit clicked(); + } + } + else { + if(isPressed()) { + press(); + } + else { + release(); + } + } + break; + + default: + e->ignore(); + break; + } +} + +void +JPushButton::mouseMoveEvent(QMouseEvent *e) +{ + e->accept(); +} + diff --git a/src/gui/qt/JPushButton.hpp b/src/gui/qt/JPushButton.hpp new file mode 100644 index 0000000000..c71e3114bd --- /dev/null +++ b/src/gui/qt/JPushButton.hpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jerome Oufella (jerome.oufella@savoirfairelinux.com) + * + * Portions (c) Jean-Philippe Barrette-LaPierre + * (jean-philippe.barrette-lapierre@savoirfairelinux.com) + * Portions (c) Valentin Heinitz + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with dpkg; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __J_PUSH_BUTTON_H__ +#define __J_PUSH_BUTTON_H__ + +#include <qlabel.h> +#include <qpixmap.h> +#include <qimage.h> + +/** + * This class Emulate a PushButton but takes two + * images to display its state. + */ +class JPushButton : public QLabel +{ + Q_OBJECT + +public: + JPushButton(const QString &released, + const QString &pressed, + QWidget *parent); + ~JPushButton(); + + bool isPressed() + {return mIsPressed;} + + static QPixmap transparize(const QString &image); + +public slots: + /** + * This function will switch the button + */ + virtual void press(); + virtual void release(); + + virtual void setToggle(bool toggled); + + private slots: + virtual void pressImage(); + virtual void releaseImage(); + +protected: + QPixmap mImages[2]; + bool mIsPressed; + +protected: + void mousePressEvent(QMouseEvent *); + void mouseReleaseEvent(QMouseEvent *); + void mouseMoveEvent(QMouseEvent *); + +signals: + void clicked(bool); + void clicked(); + +private: + bool mIsToggling; +}; + +#endif // defined(__J_PUSH_BUTTON_H__) diff --git a/src/gui/qt/Launcher.cpp b/src/gui/qt/Launcher.cpp new file mode 100644 index 0000000000..14f4f93bbd --- /dev/null +++ b/src/gui/qt/Launcher.cpp @@ -0,0 +1,93 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "DebugOutput.hpp" +#include "Launcher.hpp" + +Launcher::Launcher() + : mProc(NULL) +{} + +Launcher::~Launcher() +{ + delete mProc; +} + +void +Launcher::start() +{ + if(!mProc) { + DebugOutput::instance() << QObject::tr("Launcher::start()\n"); + mProc = new QProcess(this); + mProc->addArgument("sflphoned"); + + connect(mProc, SIGNAL(processExited()), + this, SLOT(stop())); + connect(mProc, SIGNAL(readyReadStdout()), + this, SLOT(readOutput())); + connect(mProc, SIGNAL(readyReadStderr()), + this, SLOT(readError())); + + if(!mProc->start()) { + DebugOutput::instance() << tr("Launcher: Couldn't launch sflphoned.\n"); + emit error(); + } + else { + DebugOutput::instance() << tr("Launcher: sflphoned launched.\n"); + emit started(); + } + } +} + +void +Launcher::stop() +{ + if(mProc) { + mProc->kill(); + delete mProc; + mProc = NULL; + emit stopped(); + } +} + +void +Launcher::readOutput() +{ + if(mProc) { + //emit daemonOutputAvailable(mProc->readLineStdout()); + DebugOutput::instance() << tr("%1\n").arg(mProc->readLineStdout()); + } + else { + DebugOutput::instance() << tr("Launcher: Trying to read output without " + "a valid process.\n"); + } +} + +void +Launcher::readError() +{ + if(mProc) { + DebugOutput::instance() << tr("%1\n").arg(mProc->readLineStderr()); + } + else { + DebugOutput::instance() << tr("Launcher: Trying to read error without " + "a valid process.\n"); + } +} diff --git a/src/gui/qt/Launcher.hpp b/src/gui/qt/Launcher.hpp new file mode 100644 index 0000000000..346f10c840 --- /dev/null +++ b/src/gui/qt/Launcher.hpp @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __LAUNCHER_HPP__ +#define __LAUNCHER_HPP__ + +#include <qobject.h> +#include <qprocess.h> + +class Launcher : public QObject +{ + Q_OBJECT + +public: + Launcher(); + virtual ~Launcher(); + +signals: + void started(); + void stopped(); + void error(); + void daemonOutputAvailable(QString); + void daemonErrorAvailable(QString); + +public slots: + void start(); + void stop(); + void readOutput(); + void readError(); + +private: + QProcess *mProc; +}; + +#endif diff --git a/src/gui/qt/NumericKeypad.cpp b/src/gui/qt/NumericKeypad.cpp new file mode 100644 index 0000000000..a87908e0ec --- /dev/null +++ b/src/gui/qt/NumericKeypad.cpp @@ -0,0 +1,264 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <string> +#include <qapplication.h> +#include <qevent.h> + +#include "DebugOutput.hpp" +#include "NumericKeypad.hpp" + +#define PIXMAP_KEYPAD_IMAGE QString("dtmf_main.png") +#define DTMF_0_RELEASED_IMAGE QString("dtmf_0_off.png") +#define DTMF_0_PRESSED_IMAGE QString("dtmf_0_on.png") +#define DTMF_1_RELEASED_IMAGE QString("dtmf_1_off.png") +#define DTMF_1_PRESSED_IMAGE QString("dtmf_1_on.png") +#define DTMF_2_RELEASED_IMAGE QString("dtmf_2_off.png") +#define DTMF_2_PRESSED_IMAGE QString("dtmf_2_on.png") +#define DTMF_3_RELEASED_IMAGE QString("dtmf_3_off.png") +#define DTMF_3_PRESSED_IMAGE QString("dtmf_3_on.png") +#define DTMF_4_RELEASED_IMAGE QString("dtmf_4_off.png") +#define DTMF_4_PRESSED_IMAGE QString("dtmf_4_on.png") +#define DTMF_5_RELEASED_IMAGE QString("dtmf_5_off.png") +#define DTMF_5_PRESSED_IMAGE QString("dtmf_5_on.png") +#define DTMF_6_RELEASED_IMAGE QString("dtmf_6_off.png") +#define DTMF_6_PRESSED_IMAGE QString("dtmf_6_on.png") +#define DTMF_7_RELEASED_IMAGE QString("dtmf_7_off.png") +#define DTMF_7_PRESSED_IMAGE QString("dtmf_7_on.png") +#define DTMF_8_RELEASED_IMAGE QString("dtmf_8_off.png") +#define DTMF_8_PRESSED_IMAGE QString("dtmf_8_on.png") +#define DTMF_9_RELEASED_IMAGE QString("dtmf_9_off.png") +#define DTMF_9_PRESSED_IMAGE QString("dtmf_9_on.png") +#define DTMF_STAR_RELEASED_IMAGE QString("dtmf_star_off.png") +#define DTMF_STAR_PRESSED_IMAGE QString("dtmf_star_on.png") +#define DTMF_POUND_RELEASED_IMAGE QString("dtmf_pound_off.png") +#define DTMF_POUND_PRESSED_IMAGE QString("dtmf_pound_on.png") +#define DTMF_CLOSE_RELEASED_IMAGE QString("dtmf_close_off.png") +#define DTMF_CLOSE_PRESSED_IMAGE QString("dtmf_close_on.png") + +NumericKeypad::NumericKeypad() +//: TransparentWidget(PIXMAP_KEYPAD_IMAGE, NULL) + : QDialog(NULL, + "DTMF Keypad", + false, + Qt::WStyle_Customize) +{ + TransparentWidget::setPaletteBackgroundPixmap(this, PIXMAP_KEYPAD_IMAGE); + resize(TransparentWidget::retreive(PIXMAP_KEYPAD_IMAGE).size()); + this->setCaption("DTMF Keypad"); + //setMaximumSize(getSourceImage().width(), getSourceImage().height()); + + // Buttons initialisation + mKey0 = new JPushButton(DTMF_0_RELEASED_IMAGE, + DTMF_0_PRESSED_IMAGE, + this); + mKey1 = new JPushButton(DTMF_1_RELEASED_IMAGE, + DTMF_1_PRESSED_IMAGE, + this); + mKey2 = new JPushButton(DTMF_2_RELEASED_IMAGE, + DTMF_2_PRESSED_IMAGE, + this); + mKey3 = new JPushButton(DTMF_3_RELEASED_IMAGE, + DTMF_3_PRESSED_IMAGE, + this); + mKey4 = new JPushButton(DTMF_4_RELEASED_IMAGE, + DTMF_4_PRESSED_IMAGE, + this); + mKey5 = new JPushButton(DTMF_5_RELEASED_IMAGE, + DTMF_5_PRESSED_IMAGE, + this); + mKey6 = new JPushButton(DTMF_6_RELEASED_IMAGE, + DTMF_6_PRESSED_IMAGE, + this); + mKey7 = new JPushButton(DTMF_7_RELEASED_IMAGE, + DTMF_7_PRESSED_IMAGE, + this); + mKey8 = new JPushButton(DTMF_8_RELEASED_IMAGE, + DTMF_8_PRESSED_IMAGE, + this); + mKey9 = new JPushButton(DTMF_9_RELEASED_IMAGE, + DTMF_9_PRESSED_IMAGE, + this); + mKeyStar = new JPushButton(DTMF_STAR_RELEASED_IMAGE, + DTMF_STAR_PRESSED_IMAGE, + this); + mKeyHash = new JPushButton(DTMF_POUND_RELEASED_IMAGE, + DTMF_POUND_PRESSED_IMAGE, + this); + mKeyClose = new JPushButton(DTMF_CLOSE_RELEASED_IMAGE, + DTMF_CLOSE_PRESSED_IMAGE, + this); + connect(mKey0, SIGNAL(clicked()), + this, SLOT(dtmf0Click())); + connect(mKey1, SIGNAL(clicked()), + this, SLOT(dtmf1Click())); + connect(mKey2, SIGNAL(clicked()), + this, SLOT(dtmf2Click())); + connect(mKey3, SIGNAL(clicked()), + this, SLOT(dtmf3Click())); + connect(mKey4, SIGNAL(clicked()), + this, SLOT(dtmf4Click())); + connect(mKey5, SIGNAL(clicked()), + this, SLOT(dtmf5Click())); + connect(mKey6, SIGNAL(clicked()), + this, SLOT(dtmf6Click())); + connect(mKey7, SIGNAL(clicked()), + this, SLOT(dtmf7Click())); + connect(mKey8, SIGNAL(clicked()), + this, SLOT(dtmf8Click())); + connect(mKey9, SIGNAL(clicked()), + this, SLOT(dtmf9Click())); + connect(mKeyStar, SIGNAL(clicked()), + this, SLOT(dtmfStarClick())); + connect(mKeyHash, SIGNAL(clicked()), + this, SLOT(dtmfHashClick())); + + + mKey0->move(58, 157); + mKey1->move(12, 22); + mKey2->move(58, 22); + mKey3->move(104, 22); + mKey4->move(12, 67); + mKey5->move(58, 67); + mKey6->move(104, 67); + mKey7->move(12, 112); + mKey8->move(58, 112); + mKey9->move(104, 112); + mKeyStar->move(12, 157); + mKeyHash->move(104, 157); + mKeyClose->move(141,5); + + mKeys.insert(std::make_pair(Qt::Key_0, mKey0)); + mKeys.insert(std::make_pair(Qt::Key_1, mKey1)); + mKeys.insert(std::make_pair(Qt::Key_2, mKey2)); + mKeys.insert(std::make_pair(Qt::Key_3, mKey3)); + mKeys.insert(std::make_pair(Qt::Key_4, mKey4)); + mKeys.insert(std::make_pair(Qt::Key_5, mKey5)); + mKeys.insert(std::make_pair(Qt::Key_6, mKey6)); + mKeys.insert(std::make_pair(Qt::Key_7, mKey7)); + mKeys.insert(std::make_pair(Qt::Key_8, mKey8)); + mKeys.insert(std::make_pair(Qt::Key_9, mKey9)); + mKeys.insert(std::make_pair(Qt::Key_Asterisk, mKeyStar)); + mKeys.insert(std::make_pair(Qt::Key_NumberSign, mKeyHash)); + + connect(mKeyClose, SIGNAL(clicked()), + this, SLOT(hide())); + connect(mKeyClose, SIGNAL(clicked()), + this, SIGNAL(hidden())); +} + +NumericKeypad::~NumericKeypad() +{} + +void +NumericKeypad::keyReleaseEvent (QKeyEvent* e) { + std::map< Qt::Key, JPushButton * >::iterator pos = mKeys.find(Qt::Key(e->key())); + if(pos != mKeys.end()) { + QMouseEvent me(QEvent::MouseButtonRelease, + QPoint(0,0), + Qt::LeftButton, + Qt::LeftButton); + QApplication::sendEvent(pos->second, + &me); + } +} + +void +NumericKeypad::keyPressEvent (QKeyEvent* e) { + //QApplication::sendEvent(QApplication::mainWindow, e); + // TODO: Key appears pressed when done. + std::map< Qt::Key, JPushButton * >::iterator pos = mKeys.find(Qt::Key(e->key())); + if(pos != mKeys.end()) { + QMouseEvent me(QEvent::MouseButtonPress, + QPoint(0,0), + Qt::LeftButton, + Qt::LeftButton); + QApplication::sendEvent(pos->second, + &me); + } + else { + emit keyPressed(Qt::Key(e->key())); + } +} + + +void +NumericKeypad::mousePressEvent(QMouseEvent *e) +{ + mLastPos = e->pos(); +} + +void +NumericKeypad::mouseMoveEvent(QMouseEvent *e) +{ + // Note that moving the windows is very slow + // 'cause it redraw the screen each time. + // Usually it doesn't. We could do it by a timer. + move(e->globalPos() - mLastPos); +} + +void +NumericKeypad::dtmf0Click() +{ + emit keyPressed(Qt::Key_0); +} + +void +NumericKeypad::dtmf1Click() +{emit keyPressed(Qt::Key_1);} + +void +NumericKeypad::dtmf2Click() +{emit keyPressed(Qt::Key_2);} + +void +NumericKeypad::dtmf3Click() +{emit keyPressed(Qt::Key_3);} + +void +NumericKeypad::dtmf4Click() +{emit keyPressed(Qt::Key_4);} + +void +NumericKeypad::dtmf5Click() +{emit keyPressed(Qt::Key_5);} + +void +NumericKeypad::dtmf6Click() +{emit keyPressed(Qt::Key_6);} + +void +NumericKeypad::dtmf7Click() +{emit keyPressed(Qt::Key_7);} + +void +NumericKeypad::dtmf8Click() +{emit keyPressed(Qt::Key_8);} + +void +NumericKeypad::dtmf9Click() +{emit keyPressed(Qt::Key_9);} + +void +NumericKeypad::dtmfStarClick() +{emit keyPressed(Qt::Key_Asterisk);} + +void +NumericKeypad::dtmfHashClick() +{emit keyPressed(Qt::Key_NumberSign);} diff --git a/src/gui/qt/NumericKeypad.hpp b/src/gui/qt/NumericKeypad.hpp new file mode 100644 index 0000000000..f6daf78533 --- /dev/null +++ b/src/gui/qt/NumericKeypad.hpp @@ -0,0 +1,79 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __NUMERIC_KEYPAD_HPP__ +#define __NUMERIC_KEYPAD_HPP__ + +#include <qdialog.h> +#include <qpoint.h> + +#include "JPushButton.hpp" +#include "TransparentWidget.hpp" + +class NumericKeypad : public QDialog +{ + Q_OBJECT +public: + // Default Constructor and destructor + NumericKeypad(); + ~NumericKeypad(); + + JPushButton *mKey0; + JPushButton *mKey1; + JPushButton *mKey2; + JPushButton *mKey3; + JPushButton *mKey4; + JPushButton *mKey5; + JPushButton *mKey6; + JPushButton *mKey7; + JPushButton *mKey8; + JPushButton *mKey9; + JPushButton *mKeyStar; + JPushButton *mKeyHash; + JPushButton *mKeyClose; + +public slots: + void mousePressEvent(QMouseEvent *e); + void mouseMoveEvent(QMouseEvent *e); + void keyPressEvent(QKeyEvent *e); + void keyReleaseEvent(QKeyEvent *e); + + void dtmf0Click(); + void dtmf1Click(); + void dtmf2Click(); + void dtmf3Click(); + void dtmf4Click(); + void dtmf5Click(); + void dtmf6Click(); + void dtmf7Click(); + void dtmf8Click(); + void dtmf9Click(); + void dtmfStarClick(); + void dtmfHashClick(); + +signals: + void keyPressed(Qt::Key k); + void hidden(); + +private: + QPoint mLastPos; + std::map< Qt::Key, JPushButton * > mKeys; +}; + +#endif // __NUMERIC_KEYPAD_H__ diff --git a/src/gui/qt/ObjectFactory.hpp b/src/gui/qt/ObjectFactory.hpp new file mode 100644 index 0000000000..4cb8dd0a01 --- /dev/null +++ b/src/gui/qt/ObjectFactory.hpp @@ -0,0 +1,98 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef SFLPHONEGUI_OBJECTFACTORY_H +#define SFLPHONEGUI_OBJECTFACTORY_H + +#include <list> +#include <map> +#include <qstring.h> + +/** + * This is the base class that we will use to + * create an object from the "create" function. + */ +template< typename Base > +class ObjectCreatorBase +{ + public: + virtual ~ObjectCreatorBase(){} + virtual Base *create(const QString &command, + const QString &sequenceId, + const std::list< QString > &args) = 0; + + virtual ObjectCreatorBase *clone() = 0; +}; + +/** + * This is the actual class that will create + * the request. It will return a Request + */ +template< typename Base, typename Actual > + class ObjectCreator : public ObjectCreatorBase< Base > +{ + public: + virtual Actual *create(const QString &command, + const QString &sequenceId, + const std::list< QString > &args); + + virtual ObjectCreatorBase< Base > *clone(); +}; + + +/** + * This class is used to create object related to + * a string. However, thoses objects will be created + * with the default constructor. + */ +template< typename Base > +class ObjectFactory +{ +public: + ObjectFactory(); + + /** + * Ask for a new object linked to the string. + */ + Base *create(const QString &requestname, + const QString &sequenceId, + const std::list< QString > &args); + + /** + * Register the string to return a Actual type. + */ + template< typename Actual > + void registerObject(const QString &name); + + /** + * Register the default object to be created, + * when the object wanted isn't registered. + */ + template< typename Actual > + void registerDefaultObject(); + + private: + std::map< QString, ObjectCreatorBase< Base > * > mObjectCreators; + ObjectCreatorBase< Base > *mDefaultObjectCreator; +}; + +#include "ObjectFactory.inl" + +#endif diff --git a/src/gui/qt/ObjectFactory.inl b/src/gui/qt/ObjectFactory.inl new file mode 100644 index 0000000000..09a5e643d1 --- /dev/null +++ b/src/gui/qt/ObjectFactory.inl @@ -0,0 +1,95 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifndef SFLPHONEGUI_OBJECTFACTORY_INL +#define SFLPHONEGUI_OBJECTFACTORY_INL + +#include <qobject.h> +#include <stdexcept> + +#include "DebugOutput.hpp" + +template< typename Base, typename Actual > +Actual * +ObjectCreator< Base, Actual >::create(const QString &command, + const QString &sequenceId, + const std::list< QString > &args) +{ + return new Actual(sequenceId, command, args); +} + +template< typename Base, typename Actual > +ObjectCreatorBase< Base > * +ObjectCreator< Base, Actual >::clone() +{ + return new ObjectCreator< Base, Actual >(); +} + +template< typename Base > +ObjectFactory< Base >::ObjectFactory() + : mDefaultObjectCreator(NULL) +{} + +template< typename Base > +Base * +ObjectFactory< Base >::create(const QString &command, + const QString &sequenceId, + const std::list< QString > &args) +{ + typename std::map< QString, ObjectCreatorBase< Base > * >::iterator pos = mObjectCreators.find(command); + if(pos == mObjectCreators.end()) { + if(!mDefaultObjectCreator) { + throw std::logic_error("ObjectFactory: You need to specify a default creator.\n"); + } + + return mDefaultObjectCreator->create(command, sequenceId, args); + } + + return pos->second->create(command, sequenceId, args); +} + +template< typename Base > +template< typename Actual > +void +ObjectFactory< Base >::registerObject(const QString &name) +{ + if(mObjectCreators.find(name) != mObjectCreators.end()) { + delete mObjectCreators[name]; + } + + mObjectCreators[name] = new ObjectCreator< Base, Actual >(); +} + +template< typename Base > +template< typename Actual > +void +ObjectFactory< Base >::registerDefaultObject() +{ + if(mDefaultObjectCreator) { + delete mDefaultObjectCreator; + } + + mDefaultObjectCreator = new ObjectCreator< Base, Actual >(); +} + + +#endif + diff --git a/src/gui/qt/ObjectPool.hpp b/src/gui/qt/ObjectPool.hpp new file mode 100644 index 0000000000..612161f9e5 --- /dev/null +++ b/src/gui/qt/ObjectPool.hpp @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef SFLPHONEGUI_OBJECTPOOL_H +#define SFLPHONEGUI_OBJECTPOOL_H + +#include <list> +#include <qstring.h> +#include <QMutex> +#include <QWaitCondition> + +template< typename T > +class ObjectPool +{ + public: + /** + * This function will push a line in the pool. + */ + void push(const T &line); + + /** + * This function will wait for an available line. + */ + bool pop(T &value, unsigned long time = ULONG_MAX); + + private: + std::list< T > mPool; + + QMutex mMutex; + QWaitCondition mDataAvailable; +}; + +#include "ObjectPool.inl" + +#endif + diff --git a/src/gui/qt/ObjectPool.inl b/src/gui/qt/ObjectPool.inl new file mode 100644 index 0000000000..b389eb92b1 --- /dev/null +++ b/src/gui/qt/ObjectPool.inl @@ -0,0 +1,51 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef SFLPHONEGUI_OBJECTPOOL_INL +#define SFLPHONEGUI_OBJECTPOOL_INL + +template< typename T > +void +ObjectPool< T >::push(const T &value) +{ + QMutexLocker guard(&mMutex); + mPool.push_back(value); + mDataAvailable.wakeOne(); +} + +template< typename T > +bool +ObjectPool< T >::pop(T &value, unsigned long time) +{ + QMutexLocker guard(&mMutex); + mDataAvailable.wait(guard.mutex(), time); + + if(mPool.begin() == mPool.end()) { + return false; + } + else { + typename std::list< T >::iterator pos = mPool.begin(); + mPool.pop_front(); + value = (*pos); + return true; + } +} + +#endif diff --git a/src/gui/qt/PhoneLine.cpp b/src/gui/qt/PhoneLine.cpp new file mode 100644 index 0000000000..59ecf60f93 --- /dev/null +++ b/src/gui/qt/PhoneLine.cpp @@ -0,0 +1,435 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <iostream> + +#include "globals.h" +#include "Call.hpp" +#include "DebugOutput.hpp" +#include "PhoneLine.hpp" +#include "Request.hpp" + +PhoneLine::PhoneLine(const Session &session, + const Account &account, + unsigned int line) + : mSession(session) + , mAccount(account) + , mCall(NULL) + , mLine(line) + , mSelected(false) + , mLineStatus("test") + , mActionTimer(new QTimer(this)) + , mTalking(false) + , mIsOnError(false) + , mIsTransfering(false) +{ + QObject::connect(mActionTimer, SIGNAL(timeout()), + this, SLOT(resetAction())); + QObject::connect(this, SIGNAL(transfered()), + this, SLOT(finishTransfer())); +} + +PhoneLine::~PhoneLine() +{ + clearCall(); +} + +void +PhoneLine::clearCall() +{ + if(mCall) { + delete mCall; + mCall = NULL; + } + + clearPeer(); +} + +void +PhoneLine::setCall(const Call &call) +{ + setCall(new Call(call)); +} + +void +PhoneLine::setCall(Call *call) +{ + clearCall(); + + mCall = call; + setPeer(mCall->peer()); +} + + +void +PhoneLine::setPeer(const QString &peer) +{ + mPeer = peer; + emit peerUpdated(peer); +} + +void +PhoneLine::clearPeer() +{ + mPeer = ""; + emit peerCleared(); +} + +QString +PhoneLine::getLineStatus() +{ + return mLineStatus; +} + +void +PhoneLine::resetAction() +{ + setAction(""); +} + +void +PhoneLine::setLineStatus(QString status) +{ + mActionTimer->stop(); + mAction = ""; + + mLineStatus = status; + emit lineStatusChanged(mLineStatus); +} + +void +PhoneLine::setAction(QString status) +{ + mActionTimer->stop(); + mAction = status; + emit actionChanged(mAction); +} + +void +PhoneLine::setTempAction(QString status) +{ + mActionTimer->stop(); + mActionTimer->start(3000); + mAction = status; + emit actionChanged(mAction); +} + +unsigned int +PhoneLine::line() +{ + return mLine; +} + +void +PhoneLine::lock() +{ + //mPhoneLineMutex.lock(); +} + +void +PhoneLine::unlock() +{ + //mPhoneLineMutex.unlock(); +} + +void +PhoneLine::select(bool hardselect) +{ + if(!mSelected) { + mSelected = true; + + if(!hardselect) { + if(mCall) { + if(mIsOnError) { + close(); + } + else if(mCall->isIncomming()) { + answer(); + } + else { + unhold(); + } + } + else { + setLineStatus(QObject::tr("Ready.")); + setAction(""); + } + } + + emit selected(); + } + +} + +void +PhoneLine::disconnect() +{ + mSelected = false; + close(); + + emit unselected(); +} + +void +PhoneLine::close() +{ + clearCall(); + mIsOnError = false; +} + +void +PhoneLine::error(QString message) +{ + setLineStatus(message); + mIsOnError = true; +} + +void +PhoneLine::unselect(bool hardselect) +{ + DebugOutput::instance() << tr("PhoneLine %1: I am unselected.\n").arg(mLine); + setAction(""); + mSelected = false; + if(mIsOnError) { + close(); + } + + if(mCall) { + if(!hardselect) { + mCall->hold(); + } + emit backgrounded(); + } + else { + emit unselected(); + } +} + +void +PhoneLine::incomming(const Call &call) +{ + if(mCall) { + DebugOutput::instance() << tr("PhoneLine %1: Trying to set a phone line to an active call.\n").arg(mLine); + } + else { + setCall(call); + emit backgrounded(); + } +} + +void +PhoneLine::clear() +{ + mBuffer = ""; + emit bufferStatusChanged(mBuffer); +} + +void +PhoneLine::sendKey(Qt::Key c) +{ + DebugOutput::instance() << tr("PhoneLine %1: Received the character:%2.\n") + .arg(mLine) + .arg(c); + switch(c) { + case Qt::Key_Enter: + case Qt::Key_Return: + if(!mCall) { + return call(); + } + if(mCall && mIsTransfering) { + return transfer(); + } + break; + + case Qt::Key_Backspace: + if((!mCall || mIsTransfering) && mBuffer.length() > 0) { + mBuffer.remove(mBuffer.length() - 1, 1); + emit bufferStatusChanged(mBuffer); + } + break; + + default: + if(!mCall || mIsTransfering) { + mBuffer += c; + emit bufferStatusChanged(mBuffer); + } + + if (QChar(c).isDigit() || c == Qt::Key_Asterisk || c == Qt::Key_NumberSign) { + if(!mCall) { + mSession.playDtmf(c); + } + else { + mCall->sendDtmf(c); + } + } + } +} + +void +PhoneLine::call() +{ + if(mBuffer.length()) { + call(mBuffer); + } +} + +void +PhoneLine::call(const QString &to) +{ + DebugOutput::instance() << tr("PhoneLine %1: Calling %2.\n").arg(mLine).arg(to); + if(!mCall) { + setLineStatus(tr("Calling %1...").arg(to)); + Call *call; + Request *r = mAccount.createCall(call, to); + // entry + connect(r, SIGNAL(entry(QString, QString)), + this, SLOT(setLineStatus(QString))); + + connect(r, SIGNAL(error(QString, QString)), + this, SLOT(error(QString))); + + connect(r, SIGNAL(success(QString, QString)), + this, SLOT(setTalkingState())); + + setCall(call); + clear(); + } +} + +void +PhoneLine::setTalkingState() +{ + mTalking = true; + mTalkingTime.start(); + talkingStarted(mTalkingTime); + setLineStatus(tr("Talking to: %1").arg(mPeer)); + setAction(""); +} + +void +PhoneLine::transfer() +{ + if(mCall) { + if(mBuffer.length() == 0) { + DebugOutput::instance() << tr("PhoneLine %1: We're now in transfer mode.\n"); + setAction(tr("Transfer to:")); + clear(); + unselect(); + mIsTransfering = true; + } + else { + DebugOutput::instance() << tr("PhoneLine %1: Trying to transfer to \"%2\".\n") + .arg(mLine) + .arg(mBuffer); + connect(mCall->transfer(mBuffer), SIGNAL(success(QString, QString)), + this, SIGNAL(transfered())); + clear(); + + unselect(true); + } + } +} + +void +PhoneLine::finishTransfer() +{ + clearCall(); + stopTalking(); + + if(mIsTransfering) { + mIsTransfering = false; + emit transfered(); + } +} + +void +PhoneLine::hold() +{ + if(mCall) { + setAction(tr("Holding...")); + DebugOutput::instance() << tr("PhoneLine %1: Trying to Hold.\n").arg(mLine); + mCall->hold(); + } + + unselect(); +} + +void +PhoneLine::unhold() +{ + if(mCall) { + setAction("Unholding..."); + DebugOutput::instance() << tr("PhoneLine %1: Trying to Unhold.\n").arg(mLine); + mCall->unhold(); + } +} + +void +PhoneLine::answer() +{ + if(mCall) { + setAction("Answering..."); + DebugOutput::instance() << tr("PhoneLine %1: Trying to answer.\n").arg(mLine); + mCall->answer(); + } +} + +void +PhoneLine::stopTalking() +{ + mTalking = false; + emit talkingStopped(); +} + +void +PhoneLine::hangup(bool sendrequest) +{ + stopTalking(); + + if(sendrequest) { + setAction(tr("Hanguping...")); + } + else { + setAction(tr("Hanguped.")); + } + + if(mCall) { + if(sendrequest) { + mCall->hangup(); + } + clearCall(); + } + + clear(); + clearPeer(); + unselect(); +} + +QString +PhoneLine::getCallId() +{ + QString id; + if(mCall) { + id = mCall->id(); + } + + return id; +} + diff --git a/src/gui/qt/PhoneLine.hpp b/src/gui/qt/PhoneLine.hpp new file mode 100644 index 0000000000..aeb2c6abb7 --- /dev/null +++ b/src/gui/qt/PhoneLine.hpp @@ -0,0 +1,185 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <qobject.h> +#include <qstring.h> +#include <qtimer.h> +#include <qdatetime.h> + +#include "Account.hpp" +#include "Session.hpp" + +class Call; + +class PhoneLine : public QObject +{ + Q_OBJECT + +public: + PhoneLine(const Session &session, + const Account &account, + unsigned int line); + ~PhoneLine(); + + void call(const QString &to); + void call(); + void answer(); + void hangup(bool sendrequest = true); + void hold(); + void unhold(); + + QString getCallId(); + + unsigned int line(); + + /** + * This will lock the current phone line. + * + * Note: this will only lock the phone line + * for those that uses this lock, unlock + * mechanism. PhoneLineManager always uses + * this mechanism. So, if you work only with + * PhoneLineManager, it will be thread safe. + */ + void lock(); + + /** + * This will unlock the current phone line. + * See the Note of the lock function. + */ + void unlock(); + + + /** + * This function will return true if there's no + * activity on this line. It means that even + * if we typed something on this line, but haven't + * started any communication, this will be available. + */ + bool isAvailable() + {return !mCall;} + + bool isTalking() + {return mTalking;} + + void sendKey(Qt::Key c); + + QTime getTalkingTime() + {return mTalkingTime;} + + QString getLineStatus(); + QString getBuffer() + {return mBuffer;} + +public slots: + void setLineStatus(QString); + void setAction(QString); + void setTempAction(QString); + void resetAction(); + void incomming(const Call &call); + + /** + * Clears the buffer of the line. + */ + void clear(); + + /** + * The user selected this line. + */ + void select(bool hardselect = false); + + /** + * This phoneline is no longer selected. + */ + void unselect(bool hardselect = false); + + /** + * This will do a hard unselect. it means it + * will remove the call if there's one. + */ + void disconnect(); + + /** + * This will close the current call. it means it + * will remove the call if there's one. + */ + void close(); + + /** + * This will close the current call. it means it + * will remove the call if there's one. The line + * will be in an error state. + */ + void error(QString); + + /** + * This function will put the line on hold + * and will wait for the numbre to compose. + */ + void transfer(); + + void finishTransfer(); + + void setPeer(const QString &peer); + void clearPeer(); + void setState(const QString &){} + + void setTalkingState(); + void stopTalking(); + +signals: + void selected(); + void unselected(); + void backgrounded(); + void lineStatusChanged(QString); + void actionChanged(QString); + void bufferStatusChanged(QString); + void peerUpdated(QString); + void peerCleared(); + void talkingStarted(QTime); + void talkingStopped(); + void transfered(); + +private: + void setCall(Call *call); + void setCall(const Call &call); + void clearCall(); + + + Session mSession; + Account mAccount; + Call *mCall; + unsigned int mLine; + + bool mSelected; + bool mInUse; + //This is the buffer when the line is not in use; + QString mBuffer; + + QString mLineStatus; + QString mAction; + QTimer *mActionTimer; + QTime mTalkingTime; + bool mTalking; + QString mPeer; + + bool mIsOnError; + bool mIsTransfering; +}; diff --git a/src/gui/qt/PhoneLineButton.cpp b/src/gui/qt/PhoneLineButton.cpp new file mode 100644 index 0000000000..8a0128e3ef --- /dev/null +++ b/src/gui/qt/PhoneLineButton.cpp @@ -0,0 +1,113 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "globals.h" + +#include "PhoneLineButton.hpp" + +#include <qevent.h> +#include <qtimer.h> +#include <qtooltip.h> + + +PhoneLineButton::PhoneLineButton(const QString &released, + const QString &pressed, + unsigned int line, + QWidget *parent) + : JPushButton(released, pressed, parent) + , mLine(line) + , mFace(0) +{ + mTimer = new QTimer(this); + connect(mTimer, SIGNAL(timeout()), + this, SLOT(swap())); +} + +void +PhoneLineButton::setToolTip(QString tip) +{ + QToolTip::add(this, tip); +} + +void +PhoneLineButton::clearToolTip() +{ + QToolTip::remove(this); +} + +void +PhoneLineButton::suspend() +{ + if(isPressed()) { + mFace = 1; + } + else { + mFace = 0; + } + swap(); + mTimer->start(500); +} + +void +PhoneLineButton::swap() +{ + mFace = (mFace + 1) % 2; + resize(mImages[mFace].size()); + setPixmap(mImages[mFace]); +} + +void +PhoneLineButton::press() +{ + mTimer->stop(); + JPushButton::press(); +} + +void +PhoneLineButton::release() +{ + mTimer->stop(); + JPushButton::release(); +} + +void +PhoneLineButton::mouseReleaseEvent (QMouseEvent *e) +{ + switch (e->button()) { + case Qt::LeftButton: + // Emulate the left mouse click + if (this->rect().contains(e->pos())) { + emit clicked(mLine); + } + else { + if(isPressed()) { + press(); + } + else { + release(); + } + } + break; + + default: + e->ignore(); + break; + } +} diff --git a/src/gui/qt/PhoneLineButton.hpp b/src/gui/qt/PhoneLineButton.hpp new file mode 100644 index 0000000000..d74615cee4 --- /dev/null +++ b/src/gui/qt/PhoneLineButton.hpp @@ -0,0 +1,73 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifndef __PHONELINEBUTTON_HPP__ +#define __PHONELINEBUTTON_HPP__ + +#include <qlabel.h> +#include <qobject.h> +#include <qpixmap.h> + +#include "JPushButton.hpp" + +class QTimer; + + +/** + * This class Emulate a PushButton but takes two + * images to display its state. + */ +class PhoneLineButton : public JPushButton +{ + Q_OBJECT + +public: + PhoneLineButton(const QString &released, + const QString &pressed, + unsigned int line, + QWidget *parent); + + virtual ~PhoneLineButton(){} + +signals: + void clicked(unsigned int); + +public slots: + virtual void suspend(); + virtual void press(); + virtual void release(); + virtual void setToolTip(QString); + virtual void clearToolTip(); + +private slots: + void swap(); + +protected: + void mouseReleaseEvent(QMouseEvent *); + +private: + unsigned int mLine; + QTimer *mTimer; + unsigned int mFace; + +}; + +#endif // defined(__J_PUSH_BUTTON_H__) diff --git a/src/gui/qt/PhoneLineLocker.cpp b/src/gui/qt/PhoneLineLocker.cpp new file mode 100644 index 0000000000..ebde9d86ee --- /dev/null +++ b/src/gui/qt/PhoneLineLocker.cpp @@ -0,0 +1,39 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "PhoneLineLocker.hpp" +#include "PhoneLine.hpp" + +PhoneLineLocker::PhoneLineLocker(PhoneLine *line, bool lock) + : mPhoneLine(line) +{ + if(mPhoneLine && lock) { + mPhoneLine->lock(); + } +} + +PhoneLineLocker::~PhoneLineLocker() +{ + if(mPhoneLine) { + mPhoneLine->unlock(); + } +} + + diff --git a/src/gui/qt/PhoneLineLocker.hpp b/src/gui/qt/PhoneLineLocker.hpp new file mode 100644 index 0000000000..7bdcbbeb40 --- /dev/null +++ b/src/gui/qt/PhoneLineLocker.hpp @@ -0,0 +1,51 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef SFLPHONEGUI_PHONELINELOCKER_HPP +#define SFLPHONEGUI_PHONELINELOCKER_HPP + +class PhoneLine; + +/** + * This class is used as a Lock. It means + * that it will lock a phone line on its + * constructor, and unlock it in its + * destructor. This is generaly used to + * be exception safe. + */ +class PhoneLineLocker +{ +public: + /** + * Retreive the "line" PhoneLine and + * locks it. + */ + PhoneLineLocker(PhoneLine *line, bool lock = true); + + /** + * Unlock the currently locked PhoneLine. + */ + ~PhoneLineLocker(); + +private: + PhoneLine *mPhoneLine; +}; + +#endif diff --git a/src/gui/qt/PhoneLineManager.hpp b/src/gui/qt/PhoneLineManager.hpp new file mode 100644 index 0000000000..3d166fdafa --- /dev/null +++ b/src/gui/qt/PhoneLineManager.hpp @@ -0,0 +1,30 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author : Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PHONELINEMANAGER_HPP__ +#define __PHONELINEMANAGER_HPP__ + +#include "utilspp/Singleton.hpp" +#include "PhoneLineManagerImpl.hpp" + +typedef utilspp::SingletonHolder< PhoneLineManagerImpl > PhoneLineManager; + +#endif + diff --git a/src/gui/qt/PhoneLineManagerImpl.cpp b/src/gui/qt/PhoneLineManagerImpl.cpp new file mode 100644 index 0000000000..b5fc75abd6 --- /dev/null +++ b/src/gui/qt/PhoneLineManagerImpl.cpp @@ -0,0 +1,700 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <iostream> +#include <stdexcept> + +#include "globals.h" + +#include "CallStatusFactory.hpp" +#include "ConfigurationManager.hpp" +#include "SFLEvents.hpp" +#include "SFLCallStatus.hpp" +#include "PhoneLine.hpp" +#include "PhoneLineLocker.hpp" +#include "PhoneLineManager.hpp" +#include "Request.hpp" + +#include <qmessagebox.h> + +PhoneLineManagerImpl::PhoneLineManagerImpl() + : mSession(NULL) + , mAccount(NULL) + , mCurrentLine(NULL) + , mIsInitialized(false) + , mVolume(-1) + , mMicVolume(-1) + , mIsConnected(false) + , mIsStopping(false) +{ + EventFactory::instance().registerDefaultEvent< DefaultEvent >(); + // TODO: 000 + EventFactory::instance().registerEvent< CallRelatedEvent >("000"); + EventFactory::instance().registerEvent< IncommingEvent >("001"); + EventFactory::instance().registerEvent< HangupEvent >("002"); + // TODO: 020 + EventFactory::instance().registerEvent< LoadSetupEvent >("010"); + EventFactory::instance().registerEvent< CallRelatedEvent >("020"); + EventFactory::instance().registerEvent< VolumeEvent >("021"); + EventFactory::instance().registerEvent< MicVolumeEvent >("022"); + EventFactory::instance().registerEvent< MessageTextEvent >("030"); + EventFactory::instance().registerEvent< TryingStatus >("110"); + EventFactory::instance().registerEvent< RingingStatus >("111"); + EventFactory::instance().registerEvent< HoldStatus >("112"); + EventFactory::instance().registerEvent< EstablishedStatus >("113"); + EventFactory::instance().registerEvent< BusyStatus >("114"); + EventFactory::instance().registerEvent< CongestionStatus >("115"); + EventFactory::instance().registerEvent< WrongNumberStatus >("116"); + QObject::connect(this, SIGNAL(disconnected()), + this, SLOT(closeSession())); + QObject::connect(this, SIGNAL(readyToHandleEvents()), + this, SLOT(handleEvents())); + QObject::connect(this, SIGNAL(connected()), + this, SIGNAL(readyToSendStatus())); + QObject::connect(this, SIGNAL(readyToSendStatus()), + this, SLOT(startSession())); + +} + +PhoneLineManagerImpl::~PhoneLineManagerImpl() +{ + delete mSession; + delete mAccount; + for(std::vector< PhoneLine * >::iterator pos = mPhoneLines.begin(); + pos != mPhoneLines.end(); + pos++) { + delete *pos; + } +} + + +void +PhoneLineManagerImpl::hasDisconnected() +{ + if(!mIsStopping) { + emit disconnected(); + } + else { + emit stopped(); + } +} + +void +PhoneLineManagerImpl::initialize(const Session &session) +{ + if(!mIsInitialized) { + mIsInitialized = true; + mSession = new Session(session); + mAccount = new Account(mSession->getDefaultAccount()); + } +} + +void PhoneLineManagerImpl::isInitialized() +{ + if(!mIsInitialized) { + throw std::logic_error("Trying to use PhoneLineManager without prior initialize."); + } +} + +void +PhoneLineManagerImpl::connect() +{ + isInitialized(); + + emit globalStatusSet(QString(tr("Trying to connect to sflphone server.."))); + mSession->connect(); +} + +void +PhoneLineManagerImpl::registerToServer() +{ + isInitialized(); + + Request *r = mSession->registerToServer(); + QObject::connect(r, SIGNAL(success()), + this, SIGNAL(registered())); +} + +void +PhoneLineManagerImpl::stop() +{ + isInitialized(); + + emit globalStatusSet(QString(tr("Stopping sflphone server.."))); + mIsStopping = true; + if(mIsConnected) { + mSession->stop(); + } + else { + emit stopped(); + } +} + +void +PhoneLineManagerImpl::startSession() +{ + isInitialized(); + + closeSession(); + + mIsConnected = true; + emit globalStatusSet(QString(tr("Trying to get line status..."))); + mSession->getCallStatus(); +} + +void +PhoneLineManagerImpl::handleEvents() +{ + isInitialized(); + + emit globalStatusSet(QString(tr("Welcome to SFLPhone"))); + mSession->getEvents(); + + Request *r; + r = mSession->list("ringtones"); + QObject::connect(r, SIGNAL(parsedEntry(QString, QString, QString, QString, QString)), + &ConfigurationManager::instance(), SLOT(addRingtone(QString, QString))); + QObject::connect(r, SIGNAL(success(QString, QString)), + &ConfigurationManager::instance(), SIGNAL(ringtonesUpdated())); + + r = mSession->list("audiodevice"); + QObject::connect(r, SIGNAL(parsedEntry(QString, QString, QString, QString, QString)), + &ConfigurationManager::instance(), SLOT(addAudioDevice(QString, + QString, + QString))); + QObject::connect(r, SIGNAL(success(QString, QString)), + &ConfigurationManager::instance(), SIGNAL(audioDevicesUpdated())); +} + + +void +PhoneLineManagerImpl::closeSession() +{ + isInitialized(); + + mCurrentLine = NULL; + mIsConnected = false; + + unsigned int i = 0; + while(i < mPhoneLines.size()) { + mPhoneLines[i]->disconnect(); + i++; + } + + emit lineStatusSet(""); + emit bufferStatusSet(""); + emit actionSet(""); + emit globalStatusSet("Disconnected."); +} + + +PhoneLine * +PhoneLineManagerImpl::getCurrentLine() +{ + isInitialized(); + + return mCurrentLine; +} + +void +PhoneLineManagerImpl::setNbLines(unsigned int nb) +{ + isInitialized(); + + mPhoneLines.clear(); + for(unsigned int i = 0; i < nb; i++) { + PhoneLine *p = new PhoneLine(*mSession, *mAccount, i + 1); + QObject::connect(p, SIGNAL(lineStatusChanged(QString)), + this, SIGNAL(unselectedLineStatusSet(QString))); + mPhoneLines.push_back(p); + } +} + +PhoneLine * +PhoneLineManagerImpl::getNextAvailableLine() +{ + isInitialized(); + + PhoneLine *selectedLine = NULL; + PhoneLine *current = mCurrentLine; + + + unsigned int i = 0; + while(i < mPhoneLines.size() && !selectedLine) { + if(mPhoneLines[i]->isAvailable() && + mPhoneLines[i] != current) { + selectedLine = mPhoneLines[i]; + } + else { + i++; + } + } + + return selectedLine; +} + +PhoneLine * +PhoneLineManagerImpl::getLine(const Call &call) +{ + isInitialized(); + + PhoneLine *selectedLine = NULL; + + unsigned int i = 0; + while(i < mPhoneLines.size() && !selectedLine) { + if(mPhoneLines[i]->getCallId() == call.id()) { + selectedLine = mPhoneLines[i]; + } + else { + i++; + } + } + + return selectedLine; +} + +PhoneLine * +PhoneLineManagerImpl::getLine(unsigned int line) +{ + isInitialized(); + + PhoneLine *selectedLine = NULL; + + if(line < mPhoneLines.size()) { + selectedLine = mPhoneLines[line]; + } + + return selectedLine; +} + +void +PhoneLineManagerImpl::select(PhoneLine *line, bool hardselect) +{ + if(line && (mCurrentLine != line)) { + unselect(); + + QObject::disconnect(line, SIGNAL(lineStatusChanged(QString)), + this, SIGNAL(unselectedLineStatusSet(QString))); + QObject::connect(line, SIGNAL(lineStatusChanged(QString)), + this, SIGNAL(lineStatusSet(QString))); + QObject::connect(line, SIGNAL(actionChanged(QString)), + this, SIGNAL(actionSet(QString))); + QObject::connect(line, SIGNAL(bufferStatusChanged(QString)), + this, SIGNAL(bufferStatusSet(QString))); + QObject::connect(line, SIGNAL(talkingStarted(QTime)), + this, SIGNAL(talkingStarted(QTime))); + QObject::connect(line, SIGNAL(talkingStopped()), + this, SIGNAL(talkingStopped())); + QObject::connect(line, SIGNAL(transfered()), + this, SLOT(unselect())); + + + mCurrentLine = line; + mCurrentLine->select(hardselect); + if(mCurrentLine->isAvailable() && !hardselect) { + mSession->playTone(); + } + if(mCurrentLine->isTalking()) { + emit talkingStarted(mCurrentLine->getTalkingTime()); + } + emit lineStatusSet(mCurrentLine->getLineStatus()); + emit bufferStatusSet(mCurrentLine->getBuffer()); + } +} + +void +PhoneLineManagerImpl::unselect() +{ + if(mCurrentLine) { + QObject::disconnect(mCurrentLine, SIGNAL(lineStatusChanged(QString)), + this, SIGNAL(lineStatusSet(QString))); + QObject::disconnect(mCurrentLine, SIGNAL(actionChanged(QString)), + this, SIGNAL(actionSet(QString))); + QObject::disconnect(mCurrentLine, SIGNAL(bufferStatusChanged(QString)), + this, SIGNAL(bufferStatusSet(QString))); + QObject::disconnect(mCurrentLine, SIGNAL(talkingStarted(QTime)), + this, SIGNAL(talkingStarted(QTime))); + QObject::disconnect(mCurrentLine, SIGNAL(talkingStopped()), + this, SIGNAL(talkingStopped())); + QObject::disconnect(mCurrentLine, SIGNAL(transfered()), + this, SLOT(unselect())); + QObject::connect(mCurrentLine, SIGNAL(lineStatusChanged(QString)), + this, SIGNAL(unselectedLineStatusSet(QString))); + if(mCurrentLine->isAvailable()) { + mSession->stopTone(); + } + mCurrentLine->unselect(); + mCurrentLine = NULL; + + emit lineStatusSet(""); + emit actionSet(""); + emit bufferStatusSet(""); + emit talkingStopped(); + } +} + +PhoneLine * +PhoneLineManagerImpl::selectNextAvailableLine() +{ + isInitialized(); + + PhoneLine *selectedLine = getNextAvailableLine(); + + // If we found one available line. + if(selectedLine) { + unselect(); + select(selectedLine); + } + + return selectedLine; +} + + + +PhoneLine * +PhoneLineManagerImpl::getPhoneLine(unsigned int line) +{ + isInitialized(); + + if(mPhoneLines.size() <= line) { + throw std::runtime_error("Trying to get an invalid Line"); + } + + return mPhoneLines[line]; +} + +PhoneLine * +PhoneLineManagerImpl::getPhoneLine(const QString &callId) +{ + isInitialized(); + + PhoneLine *selectedLine = NULL; + + unsigned int i = 0; + while(i < mPhoneLines.size() && + !selectedLine) { + if(mPhoneLines[i]->getCallId() == callId) { + selectedLine = mPhoneLines[i]; + } + else { + i++; + } + } + + return selectedLine; +} + + +void +PhoneLineManagerImpl::sendKey(Qt::Key c) +{ + isInitialized(); + + PhoneLine *selectedLine = getCurrentLine(); + + // Only digits that select a line if there's + // no current line. + switch(c) { + case Qt::Key_F1: + case Qt::Key_F2: + case Qt::Key_F3: + case Qt::Key_F4: + case Qt::Key_F5: + case Qt::Key_F6: + selectLine(c - Qt::Key_F1); + break; + + default: + if (!selectedLine) { + selectedLine = selectNextAvailableLine(); + } + + if(selectedLine) { + selectedLine->sendKey(c); + } + } +} + + +void +PhoneLineManagerImpl::selectLine(const QString &callId, bool hardselect) +{ + isInitialized(); + + PhoneLine *selectedLine = NULL; + unsigned int line = 0; + while(!selectedLine && line < mPhoneLines.size()) { + if(mPhoneLines[line]->getCallId() == callId) { + selectedLine = mPhoneLines[line]; + } + else { + line++; + } + } + + if(selectedLine) { + selectLine(line, hardselect); + } + else { + DebugOutput::instance() << QObject::tr("PhoneLineManager: Tried to selected line with call ID (%1), " + "which appears to be invalid.\n").arg(callId); + } +} + +/** + * Warning: This function might 'cause a problem if + * we select 2 line in a very short time. + */ +void +PhoneLineManagerImpl::selectLine(unsigned int line, bool hardselect) +{ + isInitialized(); + + PhoneLine *selectedLine = NULL; + // getting the wanted line; + { + if(mPhoneLines.size() > line) { + selectedLine = mPhoneLines[line]; + } + } + + if(selectedLine != NULL) { + PhoneLine *oldLine = mCurrentLine; + + if(oldLine != selectedLine) { + select(selectedLine, hardselect); + } + } + else { + DebugOutput::instance() << QObject::tr("PhoneLineManager: Tried to selected line %1, " + "which appears to be invalid.\n").arg(line); + } +} + +void +PhoneLineManagerImpl::call(const QString &to) +{ + PhoneLine *current = getCurrentLine(); + if(current) { + current->call(to); + } +} + + +void +PhoneLineManagerImpl::call() +{ + PhoneLine *current = getCurrentLine(); + if(current) { + current->call(); + } +} + +void +PhoneLineManagerImpl::transfer() +{ + if(mCurrentLine) { + mCurrentLine->transfer(); + } +} + + + +void +PhoneLineManagerImpl::hold() +{ + PhoneLine *selectedLine = mCurrentLine; + mCurrentLine = NULL; + + if(selectedLine) { + if(selectedLine->isAvailable()) { + mSession->stopTone(); + } + selectedLine->hold(); + } +} + +void +PhoneLineManagerImpl::hangup(bool sendrequest) +{ + PhoneLine *selectedLine = mCurrentLine; + mCurrentLine = NULL; + + if(selectedLine) { + if(selectedLine->isAvailable()) { + mSession->stopTone(); + } + selectedLine->hangup(sendrequest); + lineStatusSet(""); + } +} + +void +PhoneLineManagerImpl::mute(bool muting) +{ + if(muting) { + mute(); + } + else { + unmute(); + } +} + +void +PhoneLineManagerImpl::mute() +{ + isInitialized(); + + mSession->mute(); +} + +void +PhoneLineManagerImpl::setup() +{ + isInitialized(); + + mSession->configGetAll(); +} + +void +PhoneLineManagerImpl::unmute() +{ + isInitialized(); + + mSession->unmute(); +} + +void +PhoneLineManagerImpl::hangup(const QString &callId, bool sendrequest) +{ + PhoneLine *selectedLine = getPhoneLine(callId); + hangup(selectedLine, sendrequest); +} + +void +PhoneLineManagerImpl::hangup(unsigned int line, bool sendrequest) +{ + PhoneLine *selectedLine = getPhoneLine(line); + hangup(selectedLine, sendrequest); +} + +void +PhoneLineManagerImpl::hangup(PhoneLine *line, bool sendrequest) +{ + if(line) { + line->hangup(sendrequest); + if(mCurrentLine == line) { + unselect(); + } + } +} + +void +PhoneLineManagerImpl::clear() +{ + PhoneLine *selectedLine = mCurrentLine; + + if(selectedLine) { + selectedLine->clear(); + } +} + +void +PhoneLineManagerImpl::incomming(const QString &accountId, + const QString &callId, + const QString &peer) +{ + Call call(mSession->id(), accountId, callId, peer, true); + PhoneLine *line = addCall(call, QObject::tr("Incomming")); + if(line) { + line->setLineStatus(QObject::tr("Ringing (%1)...").arg(peer)); + } +} + +PhoneLine * +PhoneLineManagerImpl::addCall(const QString &accountId, + const QString &callId, + const QString &peer, + const QString &state) +{ + return addCall(Call(mSession->id(), accountId, callId, peer), state); +} + +PhoneLine * +PhoneLineManagerImpl::addCall(Call call, + const QString &state) +{ + PhoneLine *selectedLine = getNextAvailableLine(); + + if(selectedLine) { + selectedLine->incomming(call); + selectedLine->setLineStatus(state); + } + else { + DebugOutput::instance() << QObject::tr("PhoneLineManager: There's no available lines" + "here for the incomming call ID: %1.\n") + .arg(call.id()); + call.notAvailable(); + } + + return selectedLine; +} + +void +PhoneLineManagerImpl::updateVolume(int volume) +{ + mVolume = volume; + emit volumeUpdated((unsigned int)volume); +} + +void +PhoneLineManagerImpl::updateMicVolume(int volume) +{ + mMicVolume = volume; + emit micVolumeUpdated((unsigned int)volume); +} + +void +PhoneLineManagerImpl::setVolume(int volume) +{ + if(mVolume != volume) { + mSession->volume(volume); + updateVolume(volume); + } +} + +void +PhoneLineManagerImpl::setMicVolume(int volume) +{ + if(mMicVolume != volume) { + mSession->micVolume(volume); + updateMicVolume(volume); + } +} + +void +PhoneLineManagerImpl::incomingMessageText(const QString& message) +{ + QMessageBox messageBox; + messageBox.setText(message); + messageBox.exec(); +} + + diff --git a/src/gui/qt/PhoneLineManagerImpl.hpp b/src/gui/qt/PhoneLineManagerImpl.hpp new file mode 100644 index 0000000000..ec5c1a6d64 --- /dev/null +++ b/src/gui/qt/PhoneLineManagerImpl.hpp @@ -0,0 +1,328 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __PHONELINEMANAGERIMPL_HPP__ +#define __PHONELINEMANAGERIMPL_HPP__ + +//#include <qt.h> +#include <qobject.h> +#include <qdatetime.h> +#include <utility> +#include <vector> + +class PhoneLine; + +#include "Account.hpp" +#include "Call.hpp" +#include "EventFactory.hpp" +#include "Session.hpp" + +/** + * This is the class that manages phone lines + */ +class PhoneLineManagerImpl : public QObject +{ + Q_OBJECT + +public: + PhoneLineManagerImpl(); + ~PhoneLineManagerImpl(); + + /** + * Will return the PhoneLine linked to the line + * number. + */ + PhoneLine *getPhoneLine(unsigned int line); + + /** + * Will return the PhoneLine with the call ID. + * If there's no PhoneLine of call ID, it will + * return NULL. + */ + PhoneLine *getPhoneLine(const QString &callId); + + PhoneLine *getCurrentLine(); + + void setNbLines(unsigned int line); + +signals: + void unselected(unsigned int); + void selected(unsigned int); + void connected(); + void disconnected(); + void readyToSendStatus(); + void readyToHandleEvents(); + void gotErrorOnGetEvents(QString); + void gotErrorOnCallStatus(QString); + void globalStatusSet(QString); + void bufferStatusSet(QString); + void actionSet(QString); + void unselectedLineStatusSet(QString); + void lineStatusSet(QString); + void talkingStarted(QTime); + void talkingStopped(); + + void stopped(); + void registered(); + + void volumeUpdated(int); + void micVolumeUpdated(int); + +public slots: + + void transfer(); + + void hasDisconnected(); + + void registerToServer(); + + /** + * You need to call this function once. It must be + * call before doing anything in this class. + */ + void initialize(const Session &session); + + /** + * This function will make the process to start. + * It will connect to the server, and start the + * event handling. + */ + void connect(); + + void sendKey(Qt::Key c); + + /** + * This function will put the current line + * on hold. If there's no current line, + * it will do nothing. + */ + void hold(); + + /** + * This function will hanp up the current line + * If there's no current line, it will do nothing. + */ + void hangup(bool sendrequest = true); + + /** + * This function will mute the microphone if muting + * is true, it will unmute otherwise. + */ + void mute(bool); + + /** + * This function will mute the microphone + */ + void mute(); + + /** + * This function will unmute the microphone + */ + void unmute(); + + void setup(); + + /** + * This function will hanp up the line number given + * argument. Be aware that the first line is 1, not + * zero. + */ + void hangup(unsigned int line, bool sendrequest = true); + + /** + * This function will hanp up the line with the + * following call ID. If there's no line with + * the call ID, it will do nothing. + */ + void hangup(const QString &callId, bool sendrequest = true); + + /** + * This function will hanp up the given line. If the + * line is NULL, nothing will be done. + */ + void hangup(PhoneLine *line, bool sendrequest = true); + + /** + * This function will make a call on the + * current line. If there's no selected + * line, it will choose the first available. + */ + void call(const QString &to); + + /** + * This function will add an incomming call + * on a phone line. + */ + void incomming(const QString &accountId, + const QString &callId, + const QString &peer); + + /** + * This function is used to add a call on a + * phone line. + */ + PhoneLine *addCall(Call call, + const QString &state); + PhoneLine *addCall(const QString &accountId, + const QString &callId, + const QString &peer, + const QString &state); + + /** + * This function will make a call on the + * current line. If there's no selected + * line. It will do nothing. It will call + * the destination contained in the + * PhoneLine buffer, if any. + */ + void call(); + + /** + * This function will switch the lines. If the line + * is invalid, it just do nothing. + */ + void selectLine(unsigned int line, + bool hardselect = false); + + /** + * This function will switch the line to the line having + * the given call id. If the line is invalid, it just do + * nothing. + */ + void selectLine(const QString &callId, + bool hardselect = false); + + /** + * This function will clear the buffer of the active + * line. If there's no active line, it will do nothing. + */ + void clear(); + + /** + * This function will return the next available line. + * The line is locked, So you'll need to unlock it. + */ + PhoneLine *getNextAvailableLine(); + + /** + * This function will return the PhoneLine with the + * given id. If there's no such line, it will return + * NULL. The line is locked, So you'll need to unlock it. + */ + PhoneLine *getLine(unsigned int line); + + /** + * This function will return the PhoneLine with the + * given call id. If there's no such line, it will + * return NULL. The line is locked, So you'll need to + * unlock it. + */ + PhoneLine *getLine(const Call &call); + + /** + * This function will return the next available line. + * The line is NOT locked. + */ + PhoneLine *selectNextAvailableLine(); + + /** + * This function will send the getevents request + * to the server. + * + * NOTE: This function MUST be called AFTER getcallstatus's + * completion. + */ + void handleEvents(); + + /** + * This function will simply signal the volume change. + */ + void updateVolume(int volume); + + /** + * This function will send a request to sflphoned + * to change the volume to the given percentage. + */ + void setVolume(int volume); + + /** + * This function will simply signal the mic volume change. + */ + void updateMicVolume(int volume); + + /** + * This function will send a request to sflphoned + * to change the mic volume to the given percentage. + */ + void setMicVolume(int volume); + + /** + * This function will simply signal a incoming text message + */ + void incomingMessageText(const QString &message); + + void errorOnGetEvents(const QString &message) + {emit gotErrorOnGetEvents(message);} + + void errorOnCallStatus(const QString &message) + {emit gotErrorOnCallStatus(message);} + + void stop(); + + void finishStop() + {emit stopped();} + + void unselect(); + + private slots: + /** + * This will send all the command needed when a + * connection has just been established. + */ + void startSession(); + + /** + * This function is called when we are disconnected + * from the server. This will unselect all phone lines. + */ + void closeSession(); + + +private: + void isInitialized(); + void select(PhoneLine *line, bool hardselect = false); + +private: + Session *mSession; + Account *mAccount; + + std::vector< PhoneLine * > mPhoneLines; + PhoneLine *mCurrentLine; + bool mIsInitialized; + + int mVolume; + int mMicVolume; + + bool mIsConnected; + bool mIsStopping; +}; + + +#endif diff --git a/src/gui/qt/QjListBoxPixmap.cpp b/src/gui/qt/QjListBoxPixmap.cpp new file mode 100644 index 0000000000..ab57fd5e9b --- /dev/null +++ b/src/gui/qt/QjListBoxPixmap.cpp @@ -0,0 +1,159 @@ +/* + Copyright(C)2004 Johan Thelin + johan.thelin -at- digitalfanatics.org + + Visit: http://www.digitalfanatics.org/e8johan/projects/jseries/index.html + + This file is part of the JSeries. + + JSeries is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + JSeries is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JSeries; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <qpainter.h> +#include <qstyle.h> + +#include "QjListBoxPixmap.hpp" + +QjListBoxPixmap::QjListBoxPixmap( PixmapLocation location, const QPixmap &pixmap, const QString &text, QListBox *listbox ) : QListBoxItem( listbox ) +{ + m_location = location; + m_pixmap = pixmap; + setText( text ); +} + +QjListBoxPixmap::QjListBoxPixmap( PixmapLocation location, const QPixmap &pixmap, const QString &text, QListBox *listbox, QListBoxItem *after ) : QListBoxItem( listbox, after ) +{ + m_location = location; + m_pixmap = pixmap; + setText( text ); +} + +QjListBoxPixmap::PixmapLocation QjListBoxPixmap::location() const +{ + return m_location; +} + +const QPixmap *QjListBoxPixmap::pixmap() const +{ + return &m_pixmap; +} + +void QjListBoxPixmap::setPixmap( const QPixmap &pixmap ) +{ + m_pixmap = pixmap; + listBox()->repaint(); +} + +int QjListBoxPixmap::height( const QListBox *lb ) const +{ + switch( m_location ) + { + case Above: + case Under: + + return 6 + m_pixmap.height() + lb->fontMetrics().height(); + + case Left: + case Right: + + if( m_pixmap.height() > lb->fontMetrics().height() ) + return 4 + m_pixmap.height(); + else + return 4 + lb->fontMetrics().height(); + + default: + return 0; + } +} + +int QjListBoxPixmap::width( const QListBox *lb ) const +{ + int tw; + + switch( m_location ) + { + case Above: + case Under: + + tw = lb->fontMetrics().width( text() ); + + if( tw > m_pixmap.width() ) + return 4 + tw; + else + return 4 + m_pixmap.width(); + + case Left: + case Right: + + return 6 + m_pixmap.width() + lb->fontMetrics().width( text() ); + + default: + return 0; + } +} + +void QjListBoxPixmap::setLocation( PixmapLocation location ) +{ + if( m_location == location ) + return; + + m_location = location; + listBox()->repaint(); +} + +void QjListBoxPixmap::paint( QPainter *p ) +{ + if( !( listBox() && listBox()->viewport() == p->device() ) ) + return; + + QRect r( 0, 0, listBox()->width(), height( listBox() ) ); + + if( isSelected() ) + p->eraseRect( r ); + + int tw = listBox()->fontMetrics().width( text() ); + int th = listBox()->fontMetrics().height(); + int pw = m_pixmap.width(); + int ph = m_pixmap.height(); + int xo = (listBox()->width() - width( listBox() ))/2; + int tyo = listBox()->fontMetrics().ascent(); + + switch( m_location ) + { + case Above: + p->drawText( (listBox()->width()-tw)/2, ph+4+tyo, text() ); + p->drawPixmap( (listBox()->width()-pw)/2, 2, m_pixmap ); + + break; + case Under: + p->drawText( (listBox()->width()-tw)/2, 2+tyo, text() ); + p->drawPixmap( (listBox()->width()-pw)/2, 4+th, m_pixmap ); + + break; + case Left: + p->drawText( xo+2+pw, (height( listBox() )-th)/2+tyo, text() ); + p->drawPixmap( xo, (height( listBox() )-ph)/2, m_pixmap ); + + break; + case Right: + p->drawText( xo, (height( listBox() )-th)/2+tyo, text() ); + p->drawPixmap( xo+2+tw, (height( listBox() )-ph)/2, m_pixmap ); + + break; + } + + if( isCurrent() ) + listBox()->style().drawPrimitive( QStyle::PE_FocusRect, p, r, listBox()->colorGroup() ); +} diff --git a/src/gui/qt/QjListBoxPixmap.hpp b/src/gui/qt/QjListBoxPixmap.hpp new file mode 100644 index 0000000000..d8839e30f4 --- /dev/null +++ b/src/gui/qt/QjListBoxPixmap.hpp @@ -0,0 +1,73 @@ +/* + Copyright(C)2004 Johan Thelin + johan.thelin -at- digitalfanatics.org + + Visit: http://www.digitalfanatics.org/e8johan/projects/jseries/index.html + + This file is part of the JSeries. + + JSeries is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + JSeries is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JSeries; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef QjLISTBOXPIXMAP_H +#define QjLISTBOXPIXMAP_H + +#include <qlistbox.h> +#include <qstring.h> +#include <qpixmap.h> + +/** \brief The JPixmapItem is a listbox item showing a pixmap and a text. The location of the pixmap in relation to the text can be altered. + * + * \image html jpmi.png + * The location of the pixmap in relation to the text can be altered using the location and setLocation members. + */ +class QjListBoxPixmap : public QListBoxItem +{ +public: + /** Specifies the location of the pixmap in relation to the text. */ + enum PixmapLocation + { Above, /**< The pixmap is above the text. */ + Under, /**< The pixmap is under the text. */ + Left, /**< The pixmap is to the left of the text. */ + Right /**< The pixmap is to the right of the text. */ + }; + + /** Creates a JPixmapItem. */ + QjListBoxPixmap( PixmapLocation location, const QPixmap &pixmap, const QString &text, QListBox *listbox=0 ); + /** Creates a JPixmapItem at a certain position in the listbox. */ + QjListBoxPixmap( PixmapLocation location, const QPixmap &pixmap, const QString &text, QListBox *listbox, QListBoxItem *after ); + + /** Returns the pixmap location in relation to the text. */ + PixmapLocation location() const; + /** Sets the pixmap location in relation to the text. This does not generate a re-paint of the listbox. */ + void setLocation( PixmapLocation ); + + /** Returns the pixmap. */ + const QPixmap *pixmap() const; + /** Sets the pixmap. This does not generate a re-paint of the listbox. */ + void setPixmap( const QPixmap &pixmap ); + + int height( const QListBox *lb ) const; + int width( const QListBox *lb ) const; + +protected: + void paint( QPainter *p ); + +private: + QPixmap m_pixmap; + PixmapLocation m_location; +}; + +#endif // QjLISTBOXPIXMAP_H diff --git a/src/gui/qt/README b/src/gui/qt/README new file mode 100644 index 0000000000..2473e79d7a --- /dev/null +++ b/src/gui/qt/README @@ -0,0 +1,38 @@ +Description: + + Read this if you want to know how to build SFLPhone + using TrollTech's qmake. + + Why have qmake enter the picture? Frankly; I find the + GNU auto tools to be a great idea - if you never have + to figure them out. However, the GNU auto-tools are + not a simple solution for OSX and Windows users. + +Requirements: + + Guess what? You are going to need qmake. If you have + Qt installed then you probably already have qmake + installed. If not then go to www.trolltech.com and + get it. If you're on a Linux system, it is probably + already included in your distribution. + + I recommend getting the whole Qt C++ class library. It + is large and takes quite awhile to build but once complete + you will have the tiny qmake program AND everything you + need to build the cool GUI stuff included in SFLPhone. + +Make & Install: + + The qmake project files have .pro extensions. You may want + to edit them to your liking. + + Here are the steps to build using qmake; + + 1. $ qmake + 2. $ make + + Currently; these qmake project files lack an install but... + + You can copy the binary (sflphone) to your PATH or copy it + somewhere like /usr/local/bin. The binary is self-sufficient. + diff --git a/src/gui/qt/Request.cpp b/src/gui/qt/Request.cpp new file mode 100644 index 0000000000..9c0ed301f8 --- /dev/null +++ b/src/gui/qt/Request.cpp @@ -0,0 +1,243 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <qobject.h> +#include <qstringlist.h> +#include <qurl.h> + +#include "globals.h" +#include "DebugOutput.hpp" +#include "CallManager.hpp" +#include "Request.hpp" +#include "Requester.hpp" +#include "Url.hpp" + +Request::Request(const QString &sequenceId, + const QString &command, + const std::list< QString > &args) + : mSequenceId(sequenceId) + , mCommand(command) + , mArgs(args) +{} + +std::list< QString > +Request::parseArgs(const QString &message) +{ + QStringList list(QStringList::split(" ", message)); + std::list< QString > args; + for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { + QString qs(*it); + Url::decode(qs); + args.push_back(qs); + } + + return args; +} + +void +Request::onError(const QString &code, const QString &message) +{ + DebugOutput::instance() << QObject::tr("Received an error:\n " + "Code: %1\n " + "SequenceID: %2\n Message: %3\n") + .arg(code) + .arg(mSequenceId) + .arg(message); + + emit error(message, code); +} + +void +Request::onEntry(const QString &code, const QString &message) +{ + DebugOutput::instance() << QObject::tr("Received a temp info:\n " + "Code: %1\n " + "SequenceID: %2\n " + "Message: %3\n") + .arg(code) + .arg(mSequenceId) + .arg(message); + + emit entry(message, code); + + // This is bad code, I know. I need to find a better way. + std::list< QString > args = parseArgs(message); + QString arg1, arg2, arg3, arg4, arg5; + if(args.size() >= 1) { + arg1 = *args.begin(); + args.pop_front(); + } + if(args.size() >= 1) { + arg2 = *args.begin(); + args.pop_front(); + } + if(args.size() >= 1) { + arg3 = *args.begin(); + args.pop_front(); + } + if(args.size() >= 1) { + arg4 = *args.begin(); + args.pop_front(); + } + if(args.size() >= 1) { + arg5 = *args.begin(); + args.pop_front(); + } + emit parsedEntry(arg1, arg2, arg3, arg4, arg5); +} + +void +Request::onSuccess(const QString &code, const QString &message) +{ + DebugOutput::instance() << QObject::tr("Received a success info:\n " + "Code: %1\n " + "SequenceID: %2\n " + "Message: %3\n") + .arg(code) + .arg(mSequenceId) + .arg(message); + + emit success(message, code); +} + +QString +Request::toString() +{ + QString output = mCommand + " " + mSequenceId; + for(std::list< QString >::const_iterator pos = mArgs.begin(); + pos != mArgs.end(); + pos++) { + QString ostring(*pos); + QUrl::encode(ostring); + output += " " + ostring; + } + output += "\n"; + + return output; +} + + +CallRelatedRequest::CallRelatedRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args) + : Request(sequenceId, command, args) +{ + if(args.begin() != args.end()) { + mCallId = *args.begin(); + } +} + +void +CallRelatedRequest::onError(const QString &code, const QString &message) +{ + if(CallManager::instance().exist(mCallId)) { + onError(CallManager::instance().getCall(mCallId), + code, + message); + } + else { + DebugOutput::instance() << QObject::tr("CallRelatedRequest: Trying to retreive an unregistred call (%1)\n").arg(mCallId); + } +} + +void +CallRelatedRequest::onError(Call, const QString &, const QString &) +{} + +void +CallRelatedRequest::onEntry(const QString &code, const QString &message) +{ + if(CallManager::instance().exist(mCallId)) { + onEntry(CallManager::instance().getCall(mCallId), + code, + message); + } + else { + DebugOutput::instance() << QObject::tr("CallRelatedRequest: Trying to retreive an unregistred call (%1)\n").arg(mCallId); + } +} + +void +CallRelatedRequest::onEntry(Call, const QString &, const QString &) +{} + +void +CallRelatedRequest::onSuccess(const QString &code, const QString &message) +{ + if(CallManager::instance().exist(mCallId)) { + onSuccess(CallManager::instance().getCall(mCallId), + code, + message); + } + else { + DebugOutput::instance() << QObject::tr("CallRelatedRequest: Trying to retreive an unregistred call (%1)\n").arg(mCallId); + } +} + +void +CallRelatedRequest::onSuccess(Call, const QString &, const QString &) +{} + +AccountRequest::AccountRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args) + : Request(sequenceId, command, args) + , mAccountId(*args.begin()) +{} + +void +AccountRequest::onError(const QString &code, const QString &message) +{ + onError(Account(Requester::instance().getSessionIdFromSequenceId(getSequenceId()), + mAccountId), + code, + message); +} + +void +AccountRequest::onError(Account, const QString &, const QString &) +{} + +void +AccountRequest::onEntry(const QString &code, const QString &message) +{ + onEntry(Account(Requester::instance().getSessionIdFromSequenceId(getSequenceId()), + mAccountId), + code, + message); +} + +void +AccountRequest::onEntry(Account, const QString &, const QString &) +{} + +void +AccountRequest::onSuccess(const QString &code, const QString &message) +{ + onSuccess(Account(Requester::instance().getSessionIdFromSequenceId(getSequenceId()), + mAccountId), + code, + message); +} + +void +AccountRequest::onSuccess(Account, const QString &, const QString &) +{} + diff --git a/src/gui/qt/Request.hpp b/src/gui/qt/Request.hpp new file mode 100644 index 0000000000..63c2cdb4ca --- /dev/null +++ b/src/gui/qt/Request.hpp @@ -0,0 +1,245 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef SFLPHONEGUI_REQUEST_H +#define SFLPHONEGUI_REQUEST_H + +#include <list> +#include <qobject.h> +#include <qstring.h> + + +#include "Account.hpp" +#include "Call.hpp" + +class Request : public QObject +{ + Q_OBJECT + +signals: + /** + * Be aware that the first string is the message, + * and the second is the code. This is done that + * way because usually the message is more important + * than the code. + */ + void error(QString, QString); + void success(QString, QString); + void entry(QString, QString); + void parsedEntry(QString, QString, QString, QString, QString); + +public: + Request(const QString &sequenceId, + const QString &command, + const std::list< QString > &args); + + virtual ~Request(){} + + /** + * This function will parse the message and will cut the message + * in many arguments. + */ + static std::list< QString > parseArgs(const QString &message); + + /** + * This function will be called when the request + * receive its answer, if the request didn't successfully + * ended. + */ + virtual void onError(const QString &code, const QString &message); + + /** + * This function will be called when the request + * receive an answer, but there's other answers to come. + */ + virtual void onEntry(const QString &code, const QString &message); + + /** + * This function will be called when the request + * receive its answer, if the request successfully + * ended. + */ + virtual void onSuccess(const QString &code, const QString &message); + + /** + * This function will translate the function into a string. + * This is used for sending the request through a text channel. + */ + QString toString(); + + /** + * Return the sequence ID. + */ + QString getSequenceId() + {return mSequenceId;} + + /** + * Return the command. + */ + QString getCommand() + {return mCommand;} + + /** + * Return the args. + */ + std::list< QString > getArgs() + {return mArgs;} + + + private: + const QString mSequenceId; + const QString mCommand; + const std::list< QString > mArgs; +}; + +class CallRelatedRequest : public Request +{ + public: + CallRelatedRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args); + + + /** + * This function will be called when the request + * receive its answer, if the request didn't successfully + * ended. + */ + virtual void onError(Call call, + const QString &code, + const QString &message); + + /** + * This function will be called when the request + * receive an answer, but there's other answers to come. + */ + virtual void onEntry(Call call, + const QString &code, + const QString &message); + + /** + * This function will be called when the request + * receive its answer, if the request successfully + * ended. + */ + virtual void onSuccess(Call call, + const QString &code, + const QString &message); + + private: + /** + * This function will be called when the request + * receive its answer, if the request didn't successfully + * ended. This function will call the onError, but with + * the call linked to this request. + */ + virtual void onError(const QString &code, + const QString &message); + + /** + * This function will be called when the request + * receive its answer, if the there's other answer to + * come. This function will call the onEntry, but with + * the call linked to this request. + */ + virtual void onEntry(const QString &code, + const QString &message); + + /** + * This function will be called when the request + * receive its answer, if the request successfully + * ended. This function will call the onSuccess function, + * but with the call linked to this request. + */ + virtual void onSuccess(const QString &code, + const QString &message); + + + private: + QString mCallId; +}; + +class AccountRequest : public Request +{ + public: + AccountRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args); + + /** + * This function will be called when the request + * receive its answer, if the request didn't successfully + * ended. + */ + virtual void onError(Account account, + const QString &code, + const QString &message); + + /** + * This function will be called when the request + * receive an answer, but there's other answers to come. + */ + virtual void onEntry(Account account, + const QString &code, + const QString &message); + + /** + * This function will be called when the request + * receive its answer, if the request successfully + * ended. + */ + virtual void onSuccess(Account account, + const QString &code, + const QString &message); + + private: + /** + * This function will be called when the request + * receive its answer, if the request didn't successfully + * ended. This function will call the onError, but with + * the account linked to this request. + */ + virtual void onError(const QString &code, + const QString &message); + + /** + * This function will be called when the request + * receive its answer, if the there's other answer to + * come. This function will call the onEntry, but with + * the account linked to this request. + */ + virtual void onEntry(const QString &code, + const QString &message); + + /** + * This function will be called when the request + * receive its answer, if the request successfully + * ended. This function will call the onSuccess function, + * but with the account linked to this request. + */ + virtual void onSuccess(const QString &code, + const QString &message); + + + private: + const QString mAccountId; +}; + +#endif diff --git a/src/gui/qt/Requester.hpp b/src/gui/qt/Requester.hpp new file mode 100644 index 0000000000..2d6e4b20cd --- /dev/null +++ b/src/gui/qt/Requester.hpp @@ -0,0 +1,30 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author : Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef SFLPHONEGUI_REQUESTER_H +#define SFLPHONEGUI_REQUESTER_H + +#include "utilspp/Singleton.hpp" +#include "RequesterImpl.hpp" + +typedef utilspp::SingletonHolder< RequesterImpl > Requester; + +#endif + diff --git a/src/gui/qt/RequesterImpl.cpp b/src/gui/qt/RequesterImpl.cpp new file mode 100644 index 0000000000..167c534a77 --- /dev/null +++ b/src/gui/qt/RequesterImpl.cpp @@ -0,0 +1,200 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <qtextstream.h> +#include <iostream> +#include <stdexcept> +#include <sstream> + +#include "globals.h" +#include "DebugOutput.hpp" +#include "RequesterImpl.hpp" +#include "SessionIO.hpp" + +RequesterImpl::RequesterImpl() + : mCallIdCount(0) + , mSessionIdCount(0) + , mSequenceIdCount(0) +{} + +SessionIO * +RequesterImpl::getSessionIO(const QString &sessionId) +{ + std::map< QString, SessionIO * >::iterator pos = mSessions.find(sessionId); + if(pos == mSessions.end()) { + throw std::runtime_error("The session is not valid."); + } + + return (*pos).second; +} + +Request * +RequesterImpl::send(const QString &sessionId, + const QString &command, + const std::list< QString > &args) +{ + // We retreive the internal of a session. + SessionIO *session = getSessionIO(sessionId); + + // We ask the factory to create the request. + QString sequenceId = generateSequenceId(); + Request *request = mRequestFactory.create(command, sequenceId, args); + + registerRequest(sessionId, sequenceId, request); + session->send(request->toString()); + + return request; +} + +void +RequesterImpl::registerRequest(const QString &sessionId, + const QString &sequenceId, + Request *request) +{ + if(mRequests.find(sequenceId) != mRequests.end()) { + throw std::logic_error("Registering an already know sequence ID"); + } + + mRequests.insert(std::make_pair(sequenceId, request)); + mSequenceToSession.insert(std::make_pair(sequenceId, sessionId)); +} + +Request * +RequesterImpl::getRequest(const QString &sequenceId) +{ + Request *r = NULL; + + std::map< QString, Request * >::iterator pos = mRequests.find(sequenceId); + if(pos == mRequests.end()) { + r = pos->second; + } + + return r; +} + +void +RequesterImpl::registerSession(const QString &id, + SessionIO *s) +{ + if(mSessions.find(id) != mSessions.end()) { + throw std::logic_error("Registering an already know Session ID"); + } + + mSessions.insert(std::make_pair(id, s)); +} + +void +RequesterImpl::connect(const QString &id) +{ + std::map< QString, SessionIO * >::iterator pos = mSessions.find(id); + if(pos == mSessions.end()) { + throw std::logic_error("Trying to connect an unknown session."); + } + + pos->second->connect(); +} + + +int +RequesterImpl::getCodeCategory(const QString &code) +{ + return code.toInt() / 100; +} + +void +RequesterImpl::receiveAnswer(const QString &answer) +{ + QString a(answer); + QString code; + QString seq; + QString message; + + QTextStream s(&a, IO_ReadOnly); + s >> code >> seq; + message = s.readLine(); + message.remove(0, 1); + receiveAnswer(code, seq, message); +} + + +void +RequesterImpl::receiveAnswer(const QString &code, + const QString &sequence, + const QString &message) +{ + int c = getCodeCategory(code); + + std::map< QString, Request * >::iterator pos; + pos = mRequests.find(sequence); + if(pos == mRequests.end()) { + DebugOutput::instance() << QObject::tr("Requester: We received an answer " + "with an unknown sequence (%1).\n") + .arg(sequence); + return; + } + + if(c <= 1) { + //Other answers will come for this request. + pos->second->onEntry(code, message); + } + else{ + //This is the final answer of this request. + if(c == 2) { + pos->second->onSuccess(code, message); + } + else { + pos->second->onError(code, message); + } + delete pos->second; + mRequests.erase(pos); + } +} + +QString +RequesterImpl::generateCallId() +{ + return QString("cCallID:%1").arg(mCallIdCount++); +} + +QString +RequesterImpl::generateSessionId() +{ + return QString("cSessionID:%1").arg(mSequenceIdCount++); +} + +QString +RequesterImpl::generateSequenceId() +{ + return QString("cSequenceID:%1").arg(mSequenceIdCount++); +} + +void +RequesterImpl::inputIsDown(const QString &sessionId) +{ + std::map< QString, SessionIO * >::iterator pos; + pos = mSessions.find(sessionId); + if(pos == mSessions.end()) { + // we will not thow an exception, but this is + // a logic error + DebugOutput::instance() << QObject::tr("Requester: SessionIO input for session %1 is down, " + "but we don't have that session.\n") + .arg(sessionId); + } +} diff --git a/src/gui/qt/RequesterImpl.hpp b/src/gui/qt/RequesterImpl.hpp new file mode 100644 index 0000000000..5ab6ef2341 --- /dev/null +++ b/src/gui/qt/RequesterImpl.hpp @@ -0,0 +1,148 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef SFLPHONEGUI_REQUESTERIMPL_H +#define SFLPHONEGUI_REQUESTERIMPL_H + +#include "Request.hpp" +#include "ObjectFactory.hpp" + +class AnswerReceiver; +class Call; +class SessionIO; + +class RequesterImpl +{ + public: + RequesterImpl(); + + /** + * Will send the command to the sflphone's server. + * This command is non-blocking. The command linked + * to this command will be executed. + */ + Request *send(const QString &sessionId, + const QString &command, + const std::list< QString > &args); + + void receiveAnswer(const QString &answer); + void receiveAnswer(const QString &code, + const QString &sequence, + const QString &message); + + + static int getCodeCategory(const QString &code); + + /** + * Generate a unique call ID. + */ + QString generateCallId(); + + /** + * Generate a unique session ID. + */ + QString generateSessionId(); + + /** + * Generate a unique sequence ID. + */ + QString generateSequenceId(); + + /** + * Register the string to return a Actual type. + */ + template< typename Actual > + void registerObject(const QString &name); + + /** + * Register the default request to be created if + * the command isn't registered. + */ + template< typename Actual > + void registerDefaultObject(); + + + QString getSessionIdFromSequenceId(const QString &sequence) + {return mSequenceToSession[sequence];} + + /** + * Register the session. + */ + void registerSession(const QString &id, SessionIO *io); + + /** + * Will ask the session IO with id to connect. + */ + void connect(const QString &id); + + /** + * This function is used to notify that the SessionIO + * input of a session is down. It means that we no longer + * can receive answers. + * + * Note: Only SessionIO related classes should call this function. + */ + void inputIsDown(const QString &sessionId); + + /** + * This function is used to notify that the SessionIO + * output of a session is down. It means that we no longer + * can send requests. + * + * Note: Only SessionIO related classes should call this function. + */ + void outputIsDown(const QString &sessionId); + + private: + + /** + * Return the SessionIO instance related to + * the session ID. + */ + SessionIO *getSessionIO(const QString &sessionId); + + /** + * Register the string to return a Actual type. + */ + void registerRequest(const QString &sessionId, + const QString &sequenceId, + Request *request); + + Request *getRequest(const QString &sessionId); + + + private: + ObjectFactory< Request > mRequestFactory; + std::map< QString, SessionIO * > mSessions; + std::map< QString, Request * > mRequests; + std::map< QString, QString > mSequenceToSession; + + + /** + * This is the integer used to generate the call IDs. + */ + unsigned long mCallIdCount; + unsigned long mSessionIdCount; + unsigned long mSequenceIdCount; +}; + +#include "RequesterImpl.inl" + +#endif diff --git a/src/gui/qt/RequesterImpl.inl b/src/gui/qt/RequesterImpl.inl new file mode 100644 index 0000000000..ed09e3a187 --- /dev/null +++ b/src/gui/qt/RequesterImpl.inl @@ -0,0 +1,40 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifndef SFLPHONEGUI_REQUESTERIMPL_INL +#define SFLPHONEGUI_REQUESTERIMPL_INL + +template< typename Actual > +void +RequesterImpl::registerObject(const QString &name) +{ + mRequestFactory.registerObject< Actual >(name); +} + +template< typename Actual > +void +RequesterImpl::registerDefaultObject() +{ + mRequestFactory.registerDefaultObject< Actual >(); +} + + +#endif diff --git a/src/gui/qt/SFLCallStatus.hpp b/src/gui/qt/SFLCallStatus.hpp new file mode 100644 index 0000000000..e322da49f9 --- /dev/null +++ b/src/gui/qt/SFLCallStatus.hpp @@ -0,0 +1,35 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __SFLCALLSTATUS_HPP__ +#define __SFLCALLSTATUS_HPP__ + +#include "CallStatus.hpp" + + +typedef CallStatus TryingStatus; +typedef CallStatus RingingStatus; +typedef CallStatus HoldStatus; +typedef CallStatus EstablishedStatus; +typedef CallStatus BusyStatus; +typedef CallStatus CongestionStatus; +typedef CallStatus WrongNumberStatus; + +#endif diff --git a/src/gui/qt/SFLEvents.cpp b/src/gui/qt/SFLEvents.cpp new file mode 100644 index 0000000000..ccfd0bb81a --- /dev/null +++ b/src/gui/qt/SFLEvents.cpp @@ -0,0 +1,144 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "globals.h" + +#include "PhoneLineManager.hpp" +#include "SFLEvents.hpp" + +DefaultEvent::DefaultEvent(const QString &code, + const std::list< QString > &args) + : Event(code, args) +{ +} + +void +DefaultEvent::execute() +{ + DebugOutput::instance() << QObject::tr("DefaultEvent: We don't handle: %1\n").arg(toString()); +} + + +HangupEvent::HangupEvent(const QString &code, + const std::list< QString > &args) + : CallRelatedEvent(code, args) +{} + +void +HangupEvent::execute() +{ + QString id = getCallId(); + if(id.length() > 0) { + DebugOutput::instance() << QObject::tr("Hangup Event received for call ID: %1.\n") + .arg(id); + PhoneLineManager::instance().hangup(id, false); + } + else { + DebugOutput::instance() << QObject::tr("Hangup Event invalid (missing call ID): %1\n") + .arg(toString()); + } +} + +IncommingEvent::IncommingEvent(const QString &code, + const std::list< QString > &args) + : CallRelatedEvent(code, args) +{ + std::list< QString > l = getUnusedArgs(); + if(l.size() >= 2) { + mAccountId = *l.begin(); + l.pop_front(); + mOrigin = *l.begin(); + l.pop_front(); + setUnusedArgs(l); + } +} + +void +IncommingEvent::execute() +{ + QString id = getCallId(); + if(id.length() > 0) { + DebugOutput::instance() << QObject::tr("Incomming Event received for call ID: %1.\n") + .arg(id); + PhoneLineManager::instance().incomming(mAccountId, getCallId(), mOrigin); + } + else { + DebugOutput::instance() << QObject::tr("Incomming Event invalid: %1\n") + .arg(toString()); + } +} + +VolumeEvent::VolumeEvent(const QString &code, + const std::list< QString > &args) + : Event(code, args) +{ + std::list< QString > l = getUnusedArgs(); + if(l.size() >= 1) { + mVolume = l.begin()->toUInt(); + l.pop_front(); + setUnusedArgs(l); + } +} + +void +VolumeEvent::execute() +{ + PhoneLineManager::instance().updateVolume(mVolume); +} + +MicVolumeEvent::MicVolumeEvent(const QString &code, + const std::list< QString > &args) + : VolumeEvent(code, args) +{} + +void +MicVolumeEvent::execute() +{ + PhoneLineManager::instance().updateMicVolume(mVolume); +} + +MessageTextEvent::MessageTextEvent(const QString &code, + const std::list< QString > &args) + : Event(code, args) +{ + std::list< QString > l = getUnusedArgs(); + if(l.size() >= 1) { + mMessage = *l.begin(); + l.pop_front(); + setUnusedArgs(l); + } +} + +void +MessageTextEvent::execute() +{ + PhoneLineManager::instance().incomingMessageText(mMessage); +} + +LoadSetupEvent::LoadSetupEvent(const QString &code, + const std::list< QString > &args) + : Event(code, args) +{} + +void +LoadSetupEvent::execute() +{ + PhoneLineManager::instance().setup(); +} diff --git a/src/gui/qt/SFLEvents.hpp b/src/gui/qt/SFLEvents.hpp new file mode 100644 index 0000000000..664051e4bc --- /dev/null +++ b/src/gui/qt/SFLEvents.hpp @@ -0,0 +1,101 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __SFLEVENTS_HPP__ +#define __SFLEVENTS_HPP__ + +#include "Event.hpp" + +class DefaultEvent : public Event +{ +public: + DefaultEvent(const QString &code, + const std::list< QString > &args); + + virtual void execute(); +}; + +class HangupEvent : public CallRelatedEvent +{ +public: + HangupEvent(const QString &code, + const std::list< QString > &args); + + virtual void execute(); +}; + +class IncommingEvent : public CallRelatedEvent +{ +public: + IncommingEvent(const QString &code, + const std::list< QString > &args); + + virtual void execute(); + +private: + QString mAccountId; + QString mOrigin; +}; + + +class VolumeEvent : public Event +{ +public: + VolumeEvent(const QString &code, + const std::list< QString > &args); + + virtual void execute(); + +protected: + unsigned int mVolume; +}; + +class MicVolumeEvent : public VolumeEvent +{ +public: + MicVolumeEvent(const QString &code, + const std::list< QString > &args); + + virtual void execute(); + +}; + +class MessageTextEvent : public Event +{ +public: + MessageTextEvent(const QString &code, + const std::list< QString > &args); + + virtual void execute(); + +protected: + QString mMessage; +}; + +class LoadSetupEvent : public Event +{ +public: + LoadSetupEvent(const QString &code, + const std::list< QString > &args); + + virtual void execute(); +}; + +#endif diff --git a/src/gui/qt/SFLLcd.cpp b/src/gui/qt/SFLLcd.cpp new file mode 100644 index 0000000000..25f9b9158a --- /dev/null +++ b/src/gui/qt/SFLLcd.cpp @@ -0,0 +1,276 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <qdatetime.h> +#include <qpainter.h> +#include <qevent.h> + +#include "globals.h" +#include "JPushButton.hpp" +#include "SFLLcd.hpp" +#include "TransparentWidget.hpp" + +#define FONT_FAMILY "Courier" +// Others fixed font support "Monospace", "Fixed", "MiscFixed" +#define FONT_SIZE 10 + +#define SCREEN "screen_main.png" +#define OVERSCREEN "overscreen.png" + +SFLLcd::SFLLcd(QWidget *parent) + : QLabel(parent, "SFLLcd", Qt::WNoAutoErase) + , mScreen(TransparentWidget::retreive(SCREEN)) + , mOverscreen(TransparentWidget::retreive(OVERSCREEN)) + , mGlobalStatusPos(-1) + , mUnselectedLineStatusPos(-1) + , mLineStatusPos(-1) + , mBufferStatusPos(-1) + , mActionPos(-1) + , mIsTimed(false) + , mFont(FONT_FAMILY, FONT_SIZE) +{ + resize(mScreen.size()); + move(22,44); + + mUnselectedLineTimer = new QTimer(this); + QObject::connect(mUnselectedLineTimer, SIGNAL(timeout()), + this, SLOT(updateGlobalText())); + + mTimer = new QTimer(this); + QObject::connect(mTimer, SIGNAL(timeout()), + this, SLOT(updateText())); + QObject::connect(mTimer, SIGNAL(timeout()), + this, SLOT(update())); + mTimer->start(100); +} + +void +SFLLcd::updateText() +{ + if(mGlobalStatusPos >= 0) { + mGlobalStatusPos++; + } + + if(mLineStatusPos >= 0) { + mLineStatusPos++; + } + + if(mBufferStatusPos >= 0) { + mBufferStatusPos++; + } + + if(mActionPos >= 0) { + mActionPos++; + } +} + +void +SFLLcd::updateGlobalText() +{ + mUnselectedLineStatus = ""; +} + +void +SFLLcd::setLineTimer(QTime time) +{ + mIsTimed = true; + mTime = time; +} + +void +SFLLcd::clearLineTimer() +{ + mIsTimed = false; +} + +void +SFLLcd::setGlobalStatus(QString global) +{ + if(textIsTooBig(global)) { + mGlobalStatusPos = 0; + } + else { + mGlobalStatusPos = -1; + } + mGlobalStatus = global; +} + +void +SFLLcd::setBufferStatus(QString buffer) +{ + if(textIsTooBig(buffer)) { + mBufferStatusPos = 0; + } + else { + mBufferStatusPos = -1; + } + mBufferStatus = buffer; +} + +void +SFLLcd::setLineStatus(QString line) +{ + if(textIsTooBig(line)) { + mLineStatusPos = 0; + } + else { + mLineStatusPos = -1; + } + mLineStatus = line; +} + +void +SFLLcd::setUnselectedLineStatus(QString line) +{ + if(textIsTooBig(line)) { + mUnselectedLineStatusPos = 0; + } + else { + mUnselectedLineStatusPos = -1; + } + mUnselectedLineStatus = line; + mUnselectedLineTimer->start(3000, true); +} + +void +SFLLcd::setAction(QString line) +{ + if(textIsTooBig(line)) { + mActionPos = 0; + } + else { + mActionPos = -1; + } + mAction = line; +} + +QString +SFLLcd::getTimeStatus() +{ + if(mIsTimed) { + int seconds = mTime.elapsed() / 1000 ; + return QTime(seconds / 60 / 60, seconds / 60, seconds % 60).toString("hh:mm:ss"); + } + else { + QTime t(QTime::currentTime()); + QString s; + if(t.second() % 2) { + s = t.toString("hh:mm"); + } + else { + s = t.toString("hh mm"); + } + + return s; + } +} + +void +SFLLcd::paintEvent(QPaintEvent *event) +{ + static QPixmap pixmap(size()); + + QRect rect = event->rect(); + QSize newSize = rect.size().expandedTo(pixmap.size()); + pixmap.resize(newSize); + pixmap.fill(this, rect.topLeft()); + QPainter p(&pixmap, this); + + // Painter settings + QFontMetrics fm(mFont); + + int *globalStatusPos; + QString globalStatus; + if(mUnselectedLineStatus.length() > 0) { + globalStatus = mUnselectedLineStatus; + globalStatusPos = &mUnselectedLineStatusPos; + } + else { + globalStatus = mGlobalStatus; + globalStatusPos = &mGlobalStatusPos; + } + + int margin = 2; + p.setFont(mFont); + p.drawPixmap(0,0, mScreen); + p.drawText(QPoint(margin, fm.height()), + extractVisibleText(globalStatus, *globalStatusPos)); + p.drawText(QPoint(margin, 2*fm.height()), + extractVisibleText(mLineStatus, mLineStatusPos)); + p.drawText(QPoint(margin, 3*fm.height()), + extractVisibleText(mAction, mActionPos)); + p.drawText(QPoint(margin, 4*fm.height()), + extractVisibleText(mBufferStatus, mBufferStatusPos)); + + p.drawText(QPoint(margin, mScreen.size().height() - margin), getTimeStatus()); + p.drawPixmap(0,0, mOverscreen); + p.end(); + + bitBlt(this, event->rect().topLeft(), &pixmap); +} + +bool +SFLLcd::textIsTooBig(const QString &text) +{ + QFontMetrics fm(mFont); + + int screenWidth = mScreen.width() - 4; + int textWidth = fm.boundingRect(text).width(); + + if(textWidth > screenWidth) { + return true; + } + else { + return false; + } +} + +QString +SFLLcd::extractVisibleText(const QString &text, int &pos) +{ + QFontMetrics fm(mFont); + QString tmp(text); + + int nbCharBetween = 8; + + if(pos > 0 && ((unsigned int)pos >= tmp.length() + nbCharBetween)) { + pos = 0; + } + + // Chop the text until it's not too big + if(textIsTooBig(tmp)) { + // We add automatiquely the space the the text again at + // the end. + tmp += QString().fill(QChar(' '), nbCharBetween); + tmp += text; + + if(pos == -1) { + pos = 0; + } + + tmp.remove(0, pos); + while(textIsTooBig(tmp)) { + tmp.remove(tmp.length() - 1, 1); + } + } + + return tmp; +} + diff --git a/src/gui/qt/SFLLcd.hpp b/src/gui/qt/SFLLcd.hpp new file mode 100644 index 0000000000..d2d431b94b --- /dev/null +++ b/src/gui/qt/SFLLcd.hpp @@ -0,0 +1,78 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __SFLLCD_HPP__ +#define __SFLLCD_HPP__ + +#include <qlabel.h> +#include <qobject.h> +#include <qpixmap.h> +#include <qdatetime.h> +#include <qtimer.h> + +class SFLLcd : public QLabel +{ + Q_OBJECT + +public: + SFLLcd(QWidget *parent = NULL); + + bool textIsTooBig(const QString &text); + +public slots: + virtual void paintEvent(QPaintEvent *event); + QString getTimeStatus(); + + void setGlobalStatus(QString global); + void setUnselectedLineStatus(QString line); + void setLineStatus(QString line); + void setAction(QString line); + void setBufferStatus(QString line); + void setLineTimer(QTime time); + void clearLineTimer(); + + void updateText(); + void updateGlobalText(); + QString extractVisibleText(const QString &text, int &pos); + +private: + QPixmap mScreen; + QPixmap mOverscreen; + + QString mGlobalStatus; + QString mUnselectedLineStatus; + QString mLineStatus; + QString mBufferStatus; + QString mAction; + int mGlobalStatusPos; + int mUnselectedLineStatusPos; + int mLineStatusPos; + int mBufferStatusPos; + int mActionPos; + + bool mIsTimed; + QTime mTime; + QTimer *mTimer; + QTimer *mUnselectedLineTimer; + + QFont mFont; +}; + +#endif diff --git a/src/gui/qt/SFLPhoneApp.cpp b/src/gui/qt/SFLPhoneApp.cpp new file mode 100644 index 0000000000..81fce8ee20 --- /dev/null +++ b/src/gui/qt/SFLPhoneApp.cpp @@ -0,0 +1,213 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "globals.h" + +#include "ConfigurationManager.hpp" +#include "Launcher.hpp" +#include "NumericKeypad.hpp" +#include "PhoneLine.hpp" +#include "PhoneLineButton.hpp" +#include "Requester.hpp" +#include "Session.hpp" +#include "SessionIOFactory.hpp" +#include "SFLLcd.hpp" +#include "SFLPhoneApp.hpp" +#include "SFLPhoneWindow.hpp" +#include "SFLRequest.hpp" +#include "TCPSessionIOCreator.hpp" +#include "VolumeControl.hpp" + + + +SFLPhoneApp::SFLPhoneApp(int argc, char **argv) + : QApplication(argc, argv) + , mLauncher(new Launcher()) +{ + mSettings.setPath("savoirfairelinux.com", PROGNAME); + + SessionIOFactory::instance().setCreator(new TCPSessionIOCreator(QString("localhost"), 3999)); + + Session session; + + ConfigurationManager::instance().setSession(session); + + PhoneLineManager::instance().initialize(session); + PhoneLineManager::instance().setNbLines(NB_PHONELINES); + Requester::instance().registerDefaultObject< Request >(); + Requester::instance().registerObject< Request >(QString("playtone")); + Requester::instance().registerObject< Request >(QString("stoptone")); + Requester::instance().registerObject< Request >(QString("playdtmf")); + + Requester::instance().registerObject< ConfigGetAllRequest >(QString("configgetall")); + Requester::instance().registerObject< ConfigSaveRequest >(QString("configsave")); + Requester::instance().registerObject< StopRequest >(QString("stop")); + + + Requester::instance().registerObject< EventRequest >(QString("getevents")); + Requester::instance().registerObject< CallStatusRequest >(QString("getcallstatus")); + Requester::instance().registerObject< PermanentRequest >(QString("answer")); + Requester::instance().registerObject< PermanentRequest >(QString("notavailable")); + Requester::instance().registerObject< PermanentRequest >(QString("refuse")); + Requester::instance().registerObject< PermanentRequest >(QString("hangup")); + Requester::instance().registerObject< TemporaryRequest >(QString("unmute")); + Requester::instance().registerObject< TemporaryRequest >(QString("hold")); + Requester::instance().registerObject< TemporaryRequest >(QString("unhold")); + Requester::instance().registerObject< TemporaryRequest >(QString("senddtmf")); + Requester::instance().registerObject< Request >(QString("setspkrvolume")); + Requester::instance().registerObject< Request >(QString("setmicvolume")); + Requester::instance().registerObject< Request >(QString("mute")); + + mKeypad = new NumericKeypad(); +} + +void +SFLPhoneApp::launch() +{ + if(mLauncher) { + mLauncher->start(); + } +} + +void +SFLPhoneApp::initConnections(SFLPhoneWindow *w) +{ + // We connect the phone line buttons to the PhoneLineManager + unsigned int i = 0; + for(std::list< PhoneLineButton * >::iterator pos = w->mPhoneLineButtons.begin(); + pos != w->mPhoneLineButtons.end(); + pos++) { + PhoneLine *line = PhoneLineManager::instance().getPhoneLine(i); + QObject::connect(*pos, SIGNAL(clicked(unsigned int)), + &PhoneLineManager::instance(), SLOT(selectLine(unsigned int))); + QObject::connect(line, SIGNAL(selected()), + *pos, SLOT(press())); + QObject::connect(line, SIGNAL(unselected()), + *pos, SLOT(release())); + QObject::connect(line, SIGNAL(backgrounded()), + *pos, SLOT(suspend())); + QObject::connect(line, SIGNAL(peerUpdated(QString)), + *pos, SLOT(setToolTip(QString))); + QObject::connect(line, SIGNAL(peerCleared()), + *pos, SLOT(clearToolTip())); + + i++; + } + + + QObject::connect(w, SIGNAL(needRegister()), + &PhoneLineManager::instance(), SLOT(registerToServer())); + //QObject::connect(&PhoneLineManager::instance(), SIGNAL(registered()), + // w, SIGNAL(registered())); + QObject::connect(w->mOk, SIGNAL(clicked()), + &PhoneLineManager::instance(), SLOT(call())); + QObject::connect(w->mMute, SIGNAL(clicked(bool)), + &PhoneLineManager::instance(), SLOT(mute(bool))); + QObject::connect(w->mDtmf, SIGNAL(clicked(bool)), + mKeypad, SLOT(setShown(bool))); + QObject::connect(mKeypad, SIGNAL(hidden()), + w->mDtmf, SLOT(release())); + QObject::connect(w->mSetup, SIGNAL(clicked()), + &PhoneLineManager::instance(), SLOT(setup())); + QObject::connect(w->mHangup, SIGNAL(clicked()), + &PhoneLineManager::instance(), SLOT(hangup())); + QObject::connect(w->mHold, SIGNAL(clicked()), + &PhoneLineManager::instance(), SLOT(hold())); + QObject::connect(w->mClear, SIGNAL(clicked()), + &PhoneLineManager::instance(), SLOT(clear())); + QObject::connect(w->mTransfer, SIGNAL(clicked()), + &PhoneLineManager::instance(), SLOT(transfer())); + QObject::connect(w, SIGNAL(keyPressed(Qt::Key)), + &PhoneLineManager::instance(), SLOT(sendKey(Qt::Key))); + + + // Keypad connections + QObject::connect(mKeypad, SIGNAL(keyPressed(Qt::Key)), + &PhoneLineManager::instance(), SLOT(sendKey(Qt::Key))); + + // LCD Connections. + QObject::connect(&PhoneLineManager::instance(), SIGNAL(lineStatusSet(QString)), + w->mLcd, SLOT(setLineStatus(QString))); + QObject::connect(&PhoneLineManager::instance(), SIGNAL(unselectedLineStatusSet(QString)), + w->mLcd, SLOT(setUnselectedLineStatus(QString))); + QObject::connect(&PhoneLineManager::instance(), SIGNAL(actionSet(QString)), + w->mLcd, SLOT(setAction(QString))); + QObject::connect(&PhoneLineManager::instance(), SIGNAL(globalStatusSet(QString)), + w->mLcd, SLOT(setGlobalStatus(QString))); + QObject::connect(&PhoneLineManager::instance(), SIGNAL(bufferStatusSet(QString)), + w->mLcd, SLOT(setBufferStatus(QString))); + QObject::connect(&PhoneLineManager::instance(), SIGNAL(talkingStarted(QTime)), + w->mLcd, SLOT(setLineTimer(QTime))); + QObject::connect(&PhoneLineManager::instance(), SIGNAL(talkingStopped()), + w->mLcd, SLOT(clearLineTimer())); + + + //Volume connections + QObject::connect(w->mVolume, SIGNAL(valueUpdated(int)), + &PhoneLineManager::instance(), SLOT(setVolume(int))); + QObject::connect(w->mMicVolume, SIGNAL(valueUpdated(int)), + &PhoneLineManager::instance(), SLOT(setMicVolume(int))); + QObject::connect(&PhoneLineManager::instance(), SIGNAL(volumeUpdated(int)), + w->mVolume, SLOT(setValue(int))); + QObject::connect(&PhoneLineManager::instance(), SIGNAL(micVolumeUpdated(int)), + w->mMicVolume, SLOT(setValue(int))); + + + //Line events connections + QObject::connect(&PhoneLineManager::instance(), SIGNAL(disconnected()), + w, SLOT(askReconnect())); + QObject::connect(&PhoneLineManager::instance(), SIGNAL(disconnected()), + w, SLOT(show())); + QObject::connect(&PhoneLineManager::instance(), SIGNAL(connected()), + w, SLOT(show())); + QObject::connect(w, SIGNAL(reconnectAsked()), + &PhoneLineManager::instance(), SLOT(connect())); + QObject::connect(&PhoneLineManager::instance(), SIGNAL(stopped()), + w, SLOT(close())); + QObject::connect(w, SIGNAL(needToCloseDaemon()), + &PhoneLineManager::instance(), SLOT(stop())); + + //sflphoned launch + QObject::connect(w, SIGNAL(launchAsked()), + mLauncher, SLOT(start())); + QObject::connect(mLauncher, SIGNAL(error()), + w, SLOT(askLaunch())); + QObject::connect(mLauncher, SIGNAL(started()), + &PhoneLineManager::instance(), SLOT(connect())); + + QObject::connect(&PhoneLineManager::instance(), SIGNAL(gotErrorOnCallStatus(QString)), + w, SLOT(askResendStatus(QString))); + QObject::connect(&PhoneLineManager::instance(), SIGNAL(gotErrorOnGetEvents(QString)), + w, SLOT(askResendStatus(QString))); + QObject::connect(w, SIGNAL(resendStatusAsked()), + &PhoneLineManager::instance(), SIGNAL(readyToSendStatus())); + + + //Configuration events. + QObject::connect(&ConfigurationManager::instance(), SIGNAL(updated()), + w, SLOT(showSetup())); + QObject::connect(&ConfigurationManager::instance(), SIGNAL(ringtonesUpdated()), + w, SIGNAL(ringtonesUpdated())); + QObject::connect(&ConfigurationManager::instance(), SIGNAL(audioDevicesUpdated()), + w, SIGNAL(audioDevicesUpdated())); + //QObject::connect(&ConfigurationManager::instance(), SIGNAL(saved()), + // w, SLOT(hideSetup())); +} + diff --git a/src/gui/qt/SFLPhoneApp.hpp b/src/gui/qt/SFLPhoneApp.hpp new file mode 100644 index 0000000000..001e60beb0 --- /dev/null +++ b/src/gui/qt/SFLPhoneApp.hpp @@ -0,0 +1,54 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __SFLPHONEAPP_HPP__ +#define __SFLPHONEAPP_HPP__ + +#include <qapplication.h> +#include <qsettings.h> + +#include "PhoneLineManager.hpp" +#include "Session.hpp" +#include "Account.hpp" + +class SFLPhoneWindow; +class Launcher; +class NumericKeypad; + +class SFLPhoneApp : public QApplication +{ +public: + SFLPhoneApp(int argc, char **argv); + + /** + * This function will make the widgets + * connections. + */ + void initConnections(SFLPhoneWindow *w); + + void launch(); + +private: + Launcher *mLauncher; + NumericKeypad *mKeypad; + QSettings mSettings; +}; + +#endif diff --git a/src/gui/qt/SFLPhoneWindow.cpp b/src/gui/qt/SFLPhoneWindow.cpp new file mode 100644 index 0000000000..451bcc7a42 --- /dev/null +++ b/src/gui/qt/SFLPhoneWindow.cpp @@ -0,0 +1,322 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "SFLPhoneWindow.hpp" + +#include <qbitmap.h> + +//To test if we are in QT4 +#ifdef QT3_SUPPORT +#include <QIcon> +#endif + + +#include <qlabel.h> +#include <qmessagebox.h> +#include <qevent.h> +#include <qpixmap.h> +#include <iostream> + +#include "globals.h" +#include "JPushButton.hpp" +#include "PhoneLineButton.hpp" +#include "SFLLcd.hpp" +#include "VolumeControl.hpp" + +#define LOGO_IMAGE "logo_ico.png" +#define BACKGROUND_IMAGE "main.png" +#define HANGUP_RELEASED_IMAGE "hangup_off.png" +#define HANGUP_PRESSED_IMAGE "hangup_on.png" +#define HOLD_RELEASED_IMAGE "hold_off.png" +#define HOLD_PRESSED_IMAGE "hold_on.png" +#define OK_RELEASED_IMAGE "ok_off.png" +#define OK_PRESSED_IMAGE "ok_on.png" +#define CLEAR_RELEASED_IMAGE "clear_off.png" +#define CLEAR_PRESSED_IMAGE "clear_on.png" +#define MUTE_RELEASED_IMAGE "mute_off.png" +#define MUTE_PRESSED_IMAGE "mute_on.png" +#define DTMF_RELEASED_IMAGE "dtmf_off.png" +#define DTMF_PRESSED_IMAGE "dtmf_on.png" +#define VOLUME_IMAGE "volume.png" +#define CLOSE_RELEASED_IMAGE "close_off.png" +#define CLOSE_PRESSED_IMAGE "close_on.png" +#define MINIMIZE_RELEASED_IMAGE "minimize_off.png" +#define MINIMIZE_PRESSED_IMAGE "minimize_on.png" +#define SETUP_RELEASED_IMAGE "setup_off.png" +#define SETUP_PRESSED_IMAGE "setup_on.png" +#define TRANSFERT_RELEASE_IMAGE "transfer_off.png" +#define TRANSFERT_PRESSED_IMAGE "transfer_on.png" + + +SFLPhoneWindow::SFLPhoneWindow() +#ifdef QT3_SUPPORT + : QMainWindow(NULL, Qt::FramelessWindowHint) +#else + : QMainWindow(NULL, NULL, + Qt::WDestructiveClose | + Qt::WStyle_Customize | + Qt::WStyle_NoBorder) +#endif +{ + mLastWindowPos = pos(); + mSetupPanel = new ConfigurationPanel(this, "ConfigurationPanel"); + connect(this, SIGNAL(ringtonesUpdated()), + mSetupPanel, SLOT(updateRingtones())); + connect(this, SIGNAL(audioDevicesUpdated()), + mSetupPanel, SLOT(updateAudioDevices())); + connect(mSetupPanel, SIGNAL(needRegister()), + this, SIGNAL(needRegister())); + + // Initialize the background image + mMain = new QLabel(this); + QPixmap main(JPushButton::transparize(BACKGROUND_IMAGE)); + mMain->setPixmap(main); + if(main.hasAlpha()) { + setMask(*main.mask()); + } + + mPaintTimer = new QTimer(this); + connect(mPaintTimer, SIGNAL(timeout()), + this, SLOT(delayedPaint())); + mPaintTimer->start(50); + + + resize(main.size()); + mMain->resize(main.size()); + + QPixmap logo(QPixmap::fromMimeSource(LOGO_IMAGE)); +#ifdef QIcon + setWindowIcon(QIcon(logo)); +#else + setIcon(logo); +#endif + + mLastPos = pos(); + + initGUIButtons(); + initWindowButtons(); + initLineButtons(); + initLCD(); +} + +SFLPhoneWindow::~SFLPhoneWindow() +{} + +void +SFLPhoneWindow::initLCD() +{ + mLcd = new SFLLcd(mMain); + mLcd->show(); +} + +void +SFLPhoneWindow::initGUIButtons() +{ + mHangup = new JPushButton(QString(HANGUP_RELEASED_IMAGE), + QString(HANGUP_PRESSED_IMAGE), + mMain); + mHangup->move(225,156); + + mHold = new JPushButton(QString(HOLD_RELEASED_IMAGE), + QString(HOLD_PRESSED_IMAGE), + mMain); + mHold->move(225,68); + + + mOk = new JPushButton(QString(OK_RELEASED_IMAGE), + QString(OK_PRESSED_IMAGE), + mMain); + mOk->move(225,182); + + mClear = new JPushButton(QString(CLEAR_RELEASED_IMAGE), + QString(CLEAR_PRESSED_IMAGE), + mMain); + mClear->move(225,130); + + mMute = new JPushButton(QString(MUTE_RELEASED_IMAGE), + QString(MUTE_PRESSED_IMAGE), + mMain); + mMute->move(225,94); + mMute->setToggle(true); + + mDtmf = new JPushButton(QString(DTMF_RELEASED_IMAGE), + QString(DTMF_PRESSED_IMAGE), + mMain); + mDtmf->move(20,181); + mDtmf->setToggle(true); + + mSetup = new JPushButton(QString(SETUP_RELEASED_IMAGE), + QString(SETUP_PRESSED_IMAGE), + mMain); + //mSetup->move(225,42); + mSetup->move(318,68); + + mTransfer = new JPushButton(QString(TRANSFERT_RELEASE_IMAGE), + QString(TRANSFERT_PRESSED_IMAGE), + mMain); + mTransfer->move(225,42); + //mTransfer->hide(); + + mVolume = new VolumeControl(QString(VOLUME_IMAGE), + mMain); + mVolume->setOrientation(VolumeControl::Vertical); + mVolume->move(365,91); + QObject::connect(mVolume, SIGNAL(valueUpdated(int)), + this, SIGNAL(volumeUpdated(int))); + + mMicVolume = new VolumeControl(QString(VOLUME_IMAGE), + mMain); + mMicVolume->setOrientation(VolumeControl::Vertical); + mMicVolume->move(347,91); + QObject::connect(mVolume, SIGNAL(valueUpdated(int)), + this, SIGNAL(micVolumeUpdated(int))); + +} + +void +SFLPhoneWindow::initLineButtons() +{ + int xpos = 21; + int ypos = 151; + int offset = 31; + for(int i = 0; i < NB_PHONELINES; i++) { + PhoneLineButton *line = new PhoneLineButton(QString("l%1_off.png").arg(i + 1), + QString("l%1_on.png").arg(i + 1), + i, + mMain); + line->move(xpos, ypos); + xpos += offset; + mPhoneLineButtons.push_back(line); + } +} + +void SFLPhoneWindow::initWindowButtons() +{ + mCloseButton = new JPushButton(CLOSE_RELEASED_IMAGE, + CLOSE_PRESSED_IMAGE, + mMain); + QObject::connect(mCloseButton, SIGNAL(clicked()), + this, SLOT(finish())); + mCloseButton->move(374,5); + mMinimizeButton = new JPushButton(MINIMIZE_RELEASED_IMAGE, + MINIMIZE_PRESSED_IMAGE, + mMain); + QObject::connect(mMinimizeButton, SIGNAL(clicked()), + this, SLOT(showMinimized())); + mMinimizeButton->move(353,5); +} + +void +SFLPhoneWindow::keyPressEvent(QKeyEvent *e) { + // Misc. key + emit keyPressed(Qt::Key(e->key())); +} + +void +SFLPhoneWindow::finish() +{ + emit needToCloseDaemon(); +} + +void +SFLPhoneWindow::askReconnect() +{ + QMessageBox::critical(NULL, + tr("SFLPhone error"), + tr("We got an error launching sflphone. Check the debug \n" + "output with \"[sflphoned]\" for more details. The \n" + "application will close."), + tr("Quit")); + close(); +} + +void +SFLPhoneWindow::askLaunch() +{ + QMessageBox::critical(NULL, + tr("SFLPhone daemon problem"), + tr("The SFLPhone daemon couldn't be started. Check \n" + "if sflphoned is in your PATH. The application will \n" + "close.\n"), + tr("Quit")); + close(); +} + + +void +SFLPhoneWindow::showSetup() +{ + mSetupPanel->generate(); + mSetupPanel->show(); +} + +void +SFLPhoneWindow::hideSetup() +{ + mSetupPanel->hide(); +} + +void +SFLPhoneWindow::askResendStatus(QString message) +{ + int ret = QMessageBox::critical(NULL, + tr("SFLPhone status error"), + tr("The server returned an error for the lines status.\n" + "\n%1\n\n" + "Do you want to try to resend this command? If not,\n" + "the application will close.").arg(message), + QMessageBox::Retry | QMessageBox::Default, + QMessageBox::No | QMessageBox::Escape); + if (ret == QMessageBox::Retry) { + emit resendStatusAsked(); + } + else { + close(); + } +} + +void +SFLPhoneWindow::mousePressEvent(QMouseEvent *e) +{ + mLastPos = e->pos(); +} + +void +SFLPhoneWindow::mouseMoveEvent(QMouseEvent *e) +{ + // Note that moving the windows is very slow + // 'cause it redraw the screen each time. + // Usually it doesn't. We could do it by a timer. + delayedMove(e->globalPos() - mLastPos); +} + +void +SFLPhoneWindow::delayedMove(const QPoint &point) +{ + mLastWindowPos = point; +} + +void +SFLPhoneWindow::delayedPaint() +{ + if(pos() != mLastWindowPos) { + move(mLastWindowPos); + } +} diff --git a/src/gui/qt/SFLPhoneWindow.hpp b/src/gui/qt/SFLPhoneWindow.hpp new file mode 100644 index 0000000000..e20e2eddd6 --- /dev/null +++ b/src/gui/qt/SFLPhoneWindow.hpp @@ -0,0 +1,126 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <qlabel.h> +#include <qmainwindow.h> +#include <qobject.h> +#include <qpoint.h> +#include <qtimer.h> +#include <list> + +#include "ConfigurationPanel.h" + +class JPushButton; +class PhoneLineButton; +class SFLLcd; +class VolumeControl; + +class SFLPhoneWindow : public QMainWindow +{ + Q_OBJECT; + + friend class SFLPhoneApp; + +public: + SFLPhoneWindow(); + ~SFLPhoneWindow(); + +private: + void initLCD(); + void initGUIButtons(); + void initLineButtons(); + void initWindowButtons(); + +signals: + void keyPressed(Qt::Key); + void launchAsked(); + void reconnectAsked(); + void resendStatusAsked(); + void volumeUpdated(int); + void micVolumeUpdated(int); + void needToCloseDaemon(); + void ringtonesUpdated(); + void audioDevicesUpdated(); + void needRegister(); + +public slots: + void delayedMove(const QPoint &point); + void delayedPaint(); + + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + + /** + * This function will prompt a message box, to ask + * if the user want to reconnect to sflphoned. + */ + void askReconnect(); + + /** + * This function will prompt a message box, to ask + * if the user want to launch sflphoned. + */ + void askLaunch(); + + /** + * This function will ask if you want to close + * sflphoned. + */ + void finish(); + + /** + * This function will prompt a message box, to ask + * if the user want to resend the getcallstatus request. + */ + void askResendStatus(QString); + + void showSetup(); + void hideSetup(); + +protected: + void keyPressEvent(QKeyEvent *e); + +private: + std::list< PhoneLineButton * > mPhoneLineButtons; + + JPushButton *mCloseButton; + JPushButton *mMinimizeButton; + + JPushButton *mHangup; + JPushButton *mHold; + JPushButton *mOk; + JPushButton *mClear; + JPushButton *mMute; + JPushButton *mDtmf; + JPushButton *mSetup; + JPushButton *mTransfer; + + VolumeControl *mVolume; + VolumeControl *mMicVolume; + + SFLLcd *mLcd; + QLabel *mMain; + + QPoint mLastPos; + QPoint mLastWindowPos; + QTimer *mPaintTimer; + + ConfigurationPanel *mSetupPanel; +}; diff --git a/src/gui/qt/SFLPhoneWindow.ui b/src/gui/qt/SFLPhoneWindow.ui new file mode 100644 index 0000000000..1a78dddbbf --- /dev/null +++ b/src/gui/qt/SFLPhoneWindow.ui @@ -0,0 +1,63 @@ +<ui version="4.0" > + <author></author> + <comment></comment> + <exportmacro></exportmacro> + <class>SFLPhoneWindow</class> + <widget class="QMainWindow" name="SFLPhoneWindow" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>395</width> + <height>219</height> + </rect> + </property> + <property name="sizePolicy" > + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="windowTitle" > + <string>MainWindow</string> + </property> + <widget class="QWidget" name="centralWidget" > + <widget class="QPushButton" name="pushButton" > + <property name="geometry" > + <rect> + <x>260</x> + <y>80</y> + <width>91</width> + <height>31</height> + </rect> + </property> + <property name="text" > + <string/> + </property> + </widget> + <widget class="QLabel" name="label" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>395</width> + <height>219</height> + </rect> + </property> + <property name="text" > + <string/> + </property> + <property name="pixmap" > + <pixmap resource="sflphone.qrc" >:/images/images/main.png</pixmap> + </property> + </widget> + </widget> + </widget> + <pixmapfunction></pixmapfunction> + <resources> + <include location="sflphone.qrc" /> + </resources> + <connections/> +</ui> diff --git a/src/gui/qt/SFLRequest.cpp b/src/gui/qt/SFLRequest.cpp new file mode 100644 index 0000000000..eb2292c423 --- /dev/null +++ b/src/gui/qt/SFLRequest.cpp @@ -0,0 +1,417 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <iostream> +#include <memory> +#include <sstream> +#include <string> +#include <qstring.h> + +#include "globals.h" +#include "CallManager.hpp" +#include "CallStatus.hpp" +#include "CallStatusFactory.hpp" +#include "ConfigurationManager.hpp" +#include "PhoneLine.hpp" +#include "PhoneLineLocker.hpp" +#include "PhoneLineManager.hpp" +#include "SFLRequest.hpp" + +EventRequest::EventRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args) + : Request(sequenceId, command, args) +{} + + +void +EventRequest::onError(const QString &code, const QString &message) +{ + DebugOutput::instance() << QObject::tr("EventRequest error: (%1) %1\n") + .arg(code) + .arg(message); + PhoneLineManager::instance().errorOnGetEvents(message); +} + +void +EventRequest::onEntry(const QString &code, const QString &message) +{ + std::auto_ptr< Event > + e(EventFactory::instance().create(code, Request::parseArgs(message))); + e->execute(); +} + +void +EventRequest::onSuccess(const QString &code, const QString &message) +{ + DebugOutput::instance() << QObject::tr("EventRequest success: (%1) %1\n") + .arg(code) + .arg(message); + PhoneLineManager::instance().connect(); +} + +CallStatusRequest::CallStatusRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args) + : Request(sequenceId, command, args) +{} + + +void +CallStatusRequest::onError(const QString &code, const QString &message) +{ + DebugOutput::instance() << QObject::tr("CallStatusRequest error: (%1) %1\n") + .arg(code) + .arg(message); + PhoneLineManager::instance().errorOnCallStatus(message); +} + +void +CallStatusRequest::onEntry(const QString &code, const QString &message) +{ + std::auto_ptr< Event > + e(EventFactory::instance().create(code, Request::parseArgs(message))); + e->execute(); +} + +void +CallStatusRequest::onSuccess(const QString &code, const QString &message) +{ + DebugOutput::instance() << QObject::tr("CallStatusRequest success: (%1) %1\n") + .arg(code) + .arg(message); + if(code == "206") { + std::list< QString > args = Request::parseArgs(message); + if(args.size() >= 2) { + PhoneLineManager::instance().selectLine(*args.begin(), true); + } + else { + DebugOutput::instance() << QObject::tr("CallStatusRequest Error: cannot get current line.\n"); + } + } + PhoneLineManager::instance().handleEvents(); +} + + +PermanentRequest::PermanentRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args) + : CallRelatedRequest(sequenceId, command, args) +{} + +void +PermanentRequest::onError(Call call, + const QString &, + const QString &message) +{ + DebugOutput::instance() << QObject::tr("PermanentRequest: Error: %1").arg(toString()); + PhoneLine *line = PhoneLineManager::instance().getLine(call); + if(line) { + PhoneLineLocker guard(line, false); + line->error(message); + line->setAction(""); + } + else { + DebugOutput::instance() << + QObject::tr("We received an error on a call " + "that doesn't have a phone line (%1).\n") + .arg(call.id()); + } +} + +void +PermanentRequest::onEntry(Call call, + const QString &, + const QString &message) +{ + PhoneLine *line = PhoneLineManager::instance().getLine(call); + if(line) { + PhoneLineLocker guard(line, false); + line->setLineStatus(message); + line->setAction(""); + } + else { + DebugOutput::instance() << + QObject::tr("We received a status on a call related request " + "that doesn't have a phone line (%1).\n") + .arg(call.id()); + } +} + +void +PermanentRequest::onSuccess(Call call, + const QString &, + const QString &message) +{ + PhoneLine *line = PhoneLineManager::instance().getLine(call); + if(line) { + PhoneLineLocker guard(line, false); + line->setLineStatus(message); + line->setAction(""); + } + else { + DebugOutput::instance() << + QObject::tr("We received a success on a call related request " + "that doesn't have a phone line (%1).\n") + .arg(call.id()); + } +} + +TemporaryRequest::TemporaryRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args) + : CallRelatedRequest(sequenceId, command, args) +{} + +void +TemporaryRequest::onError(Call call, + const QString &code, + const QString &message) +{ + onSuccess(call, code, message); +} + +void +TemporaryRequest::onEntry(Call call, + const QString &code, + const QString &message) +{ + onSuccess(call, code, message); +} + +void +TemporaryRequest::onSuccess(Call call, + const QString &, + const QString &message) +{ + PhoneLine *line = PhoneLineManager::instance().getLine(call); + if(line) { + PhoneLineLocker guard(line, false); + line->setTempAction(message); + } + else { + DebugOutput::instance() << + QObject::tr("We received an answer on a temporary call " + "related request that doesn't have a phone " + "line (%1).\n") + .arg(call.id()); + } +} + +CallRequest::CallRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args) + : AccountRequest(sequenceId, command, args) +{ + + std::list< QString >::const_iterator pos = args.begin(); + pos++; + mCallId = *pos; +} + +void +CallRequest::onError(Account, + const QString &, + const QString &message) +{ + if(CallManager::instance().exist(mCallId)) { + PhoneLine *line = + PhoneLineManager::instance().getLine(CallManager::instance().getCall(mCallId)); + if(line) { + PhoneLineLocker guard(line, false); + line->error(message); + } + else { + DebugOutput::instance() << + QObject::tr("We received an error on a call " + "that doesn't have a phone line (%1).\n") + .arg(mCallId); + } + } + else { + DebugOutput::instance() << QObject::tr("CallRequest: Trying to retreive an unregistred call (%1)\n").arg(mCallId); + } +} + +void +CallRequest::onEntry(Account, + const QString &, + const QString &message) +{ + if(CallManager::instance().exist(mCallId)) { + PhoneLine *line = + PhoneLineManager::instance().getLine(CallManager::instance().getCall(mCallId)); + if(line) { + PhoneLineLocker guard(line, false); + line->setLineStatus(message); + } + else { + DebugOutput::instance() << + QObject::tr("We received a status on a call related request " + "that doesn't have a phone line (%1).\n") + .arg(mCallId); + } + } + else { + DebugOutput::instance() << QObject::tr("CallRequest: Trying to retreive an unregistred call (%1)\n").arg(mCallId); + } +} + +void +CallRequest::onSuccess(Account, + const QString &, + const QString &message) +{ + if(CallManager::instance().exist(mCallId)) { + PhoneLine *line = + PhoneLineManager::instance().getLine(CallManager::instance().getCall(mCallId)); + if(line) { + PhoneLineLocker guard(line, false); + line->setLineStatus(message); + } + else { + DebugOutput::instance() << + QObject::tr("We received a success on a call related request " + "that doesn't have a phone line (%1).\n") + .arg(mCallId); + } + } + else { + DebugOutput::instance() << QObject::tr("CallRequest: Trying to retreive an unregistred call (%1)\n").arg(mCallId); + } +} + + + +ConfigGetAllRequest::ConfigGetAllRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args) + : Request(sequenceId, command, args) +{} + + +void +ConfigGetAllRequest::onError(const QString &code, const QString &message) +{ + DebugOutput::instance() << QObject::tr("ConfigGetAllRequest error: (%1) %1\n") + .arg(code) + .arg(message); +} + +void +ConfigGetAllRequest::onEntry(const QString &, const QString &message) +{ + std::list< QString > args = Request::parseArgs(message); + if(args.size() >= 3) { + QString section, variable, type, def, val; + section = *args.begin(); + args.pop_front(); + variable = *args.begin(); + args.pop_front(); + type = *args.begin(); + args.pop_front(); + if(args.size() >= 1) { + val = *args.begin(); + args.pop_front(); + } + if(args.size() >= 1) { + def = *args.begin(); + args.pop_front(); + } + ConfigurationManager::instance().add(ConfigEntry(section, variable, type, def, val)); + } +} + +void +ConfigGetAllRequest::onSuccess(const QString &, const QString &) +{ + ConfigurationManager::instance().complete(); +} + + +ConfigSaveRequest::ConfigSaveRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args) + : Request(sequenceId, command, args) +{} + + +void +ConfigSaveRequest::onError(const QString &code, const QString &message) +{ + DebugOutput::instance() << QObject::tr("ConfigSaveRequest error: (%1) %1\n") + .arg(code) + .arg(message); +} + +void +ConfigSaveRequest::onSuccess(const QString &, const QString &) +{ + ConfigurationManager::instance().finishSave(); +} + +StopRequest::StopRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args) + : Request(sequenceId, command, args) +{} + + +void +StopRequest::onError(const QString &code, const QString &message) +{ + DebugOutput::instance() << QObject::tr("StopRequest error: (%1) %1\n") + .arg(code) + .arg(message); +} + +void +StopRequest::onSuccess(const QString &, const QString &) +{ + PhoneLineManager::instance().finishStop(); +} + +SignalizedRequest::SignalizedRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args) + : Request(sequenceId, command, args) +{} + +void +SignalizedRequest::onError(const QString &code, + const QString &message) +{ + emit error(message, code); +} + +void +SignalizedRequest::onEntry(const QString &code, + const QString &message) +{ + emit entry(message, code); +} + +void +SignalizedRequest::onSuccess(const QString &code, + const QString &message) +{ + emit success(message, code); +} + diff --git a/src/gui/qt/SFLRequest.hpp b/src/gui/qt/SFLRequest.hpp new file mode 100644 index 0000000000..03e38ddf24 --- /dev/null +++ b/src/gui/qt/SFLRequest.hpp @@ -0,0 +1,278 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + + + +#ifndef SFLPHONEGUI_SFLREQUEST_HPP +#define SFLPHONEGUI_SFLREQUEST_HPP + +#include "Request.hpp" + +class EventRequest : public Request +{ +public: + EventRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args); + + + virtual ~EventRequest(){} + + /** + * This function will be called when the request + * receive its answer, if the request didn't successfully + * ended. When we have an error on an EventRequest, we should + * quit the program. + */ + virtual void onError(const QString &code, const QString &message); + + /** + * This function will be called when the request + * receive an answer, but there's other answers to come. + * This will be dispatched to the valid event. + */ + virtual void onEntry(const QString &code, const QString &message); + + /** + * This function will be called when the request + * receive its answer, if the request successfully + * ended. The event handling is gone, so we should + * quit. + */ + virtual void onSuccess(const QString &code, const QString &message); + +}; + +class CallStatusRequest : public Request +{ +public: + CallStatusRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args); + + + virtual ~CallStatusRequest(){} + + /** + * This function will be called when the request + * receive its answer, if the request didn't successfully + * ended. When we have an error on an EventRequest, we should + * quit the program. + */ + virtual void onError(const QString &code, const QString &message); + + /** + * This function will be called when the request + * receive an answer, but there's other answers to come. + * This will be dispatched to the valid event. + */ + virtual void onEntry(const QString &code, const QString &message); + + /** + * This function will be called when the request + * receive its answer, if the request successfully + * ended. The event handling is gone, so we should + * quit. + */ + virtual void onSuccess(const QString &code, const QString &message); + +}; + + +class CallRequest : public AccountRequest +{ + public: + CallRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args); + + /** + * This function will be called when the request + * receive its answer, if the request didn't successfully + * ended. + */ + virtual void onError(Account account, + const QString &code, + const QString &message); + + /** + * This function will be called when the request + * receive an answer, but there's other answers to come. + */ + virtual void onEntry(Account account, + const QString &code, + const QString &message); + + /** + * This function will be called when the request + * receive its answer, if the request successfully + * ended. + */ + virtual void onSuccess(Account account, + const QString &code, + const QString &message); + +private: + QString mCallId; +}; + + +class PermanentRequest : public CallRelatedRequest +{ + public: + PermanentRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args); + + + /** + * This function will be called when the request + * receive its answer, if the request didn't successfully + * ended. + */ + virtual void onError(Call call, + const QString &code, + const QString &message); + + /** + * This function will be called when the request + * receive an answer, but there's other answers to come. + */ + virtual void onEntry(Call call, + const QString &code, + const QString &message); + + /** + * This function will be called when the request + * receive its answer, if the request successfully + * ended. + */ + virtual void onSuccess(Call call, + const QString &code, + const QString &message); +}; + +class TemporaryRequest : public CallRelatedRequest +{ + public: + TemporaryRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args); + + + /** + * This function will be called when the request + * receive its answer, if the request didn't successfully + * ended. + */ + virtual void onError(Call call, + const QString &code, + const QString &message); + + /** + * This function will be called when the request + * receive an answer, but there's other answers to come. + */ + virtual void onEntry(Call call, + const QString &code, + const QString &message); + + /** + * This function will be called when the request + * receive its answer, if the request successfully + * ended. + */ + virtual void onSuccess(Call call, + const QString &code, + const QString &message); +}; + +class ConfigGetAllRequest : public Request +{ +public: + ConfigGetAllRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args); + + + virtual ~ConfigGetAllRequest(){} + + + virtual void onError(const QString &code, const QString &message); + virtual void onEntry(const QString &code, const QString &message); + virtual void onSuccess(const QString &code, const QString &message); +}; + +class ConfigSaveRequest : public Request +{ +public: + ConfigSaveRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args); + + + virtual ~ConfigSaveRequest(){} + + + virtual void onError(const QString &code, const QString &message); + virtual void onSuccess(const QString &code, const QString &message); +}; + +class StopRequest : public Request +{ +public: + StopRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args); + + + virtual ~StopRequest(){} + virtual void onError(const QString &code, const QString &message); + virtual void onSuccess(const QString &code, const QString &message); +}; + + +class SignalizedRequest : public Request +{ + Q_OBJECT + +public: + SignalizedRequest(const QString &sequenceId, + const QString &command, + const std::list< QString > &args); + + virtual void onError(const QString &code, const QString &message); + virtual void onEntry(const QString &code, const QString &message); + virtual void onSuccess(const QString &code, const QString &message); + +signals: + /** + * Be aware that the first string is the message, + * and the second is the code. This is done that + * way because usually the message is more important + * than the code. + */ + void error(QString, QString); + void success(QString, QString); + void entry(QString, QString); +}; + +#endif diff --git a/src/gui/qt/Session.cpp b/src/gui/qt/Session.cpp new file mode 100644 index 0000000000..aaeb56ffb6 --- /dev/null +++ b/src/gui/qt/Session.cpp @@ -0,0 +1,180 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <iostream> +#include <qstring.h> + +#include "Session.hpp" +#include "Requester.hpp" +#include "SessionIOFactory.hpp" + + +Session::Session(const QString &id) + : mId(id) +{} + +Session::Session() +{ + mId = Requester::instance().generateSessionId(); + SessionIO *s = SessionIOFactory::instance().create(); + Requester::instance().registerSession(mId, s); +} + +QString +Session::id() const +{ + return mId; +} + +Request * +Session::playTone() const +{ + return Requester::instance().send(mId, "playtone", std::list< QString >()); +} + +Request * +Session::stopTone() const +{ + return Requester::instance().send(mId, "stoptone", std::list< QString >()); +} + +void +Session::connect() const +{ + return Requester::instance().connect(mId); +} + + +Request * +Session::getEvents() const +{ + return Requester::instance().send(mId, "getevents", std::list< QString >()); +} + + +Request * +Session::configSet(const QString §ion, + const QString &name, + const QString &value) const +{ + std::list< QString > args; + args.push_back(section); + args.push_back(name); + args.push_back(value); + return Requester::instance().send(mId, "configset", args); +} + + +Request * +Session::configGetAll() const +{ + return Requester::instance().send(mId, "configgetall", std::list< QString >()); +} + +Request * +Session::configSave() const +{ + return Requester::instance().send(mId, "configsave", std::list< QString >()); +} + +Request * +Session::close() const +{ + return Requester::instance().send(mId, "close", std::list< QString >()); +} + +Request * +Session::stop() const +{ + return Requester::instance().send(mId, "stop", std::list< QString >()); +} + +Request * +Session::mute() const +{ + return Requester::instance().send(mId, "mute", std::list< QString >()); +} + +Request * +Session::unmute() const +{ + return Requester::instance().send(mId, "unmute", std::list< QString >()); +} + +Request * +Session::volume(unsigned int volume) const +{ + std::list< QString > args; + args.push_back(QString("%1").arg(volume)); + return Requester::instance().send(mId, "setspkrvolume", args); +} + +Request * +Session::micVolume(unsigned int volume) const +{ + std::list< QString > args; + args.push_back(QString("%1").arg(volume)); + return Requester::instance().send(mId, "setmicvolume", args); +} + +Request * +Session::getCallStatus() const +{ + return Requester::instance().send(mId, "getcallstatus", std::list< QString >()); +} + +Request * +Session::playDtmf(char c) const +{ + QString s; + s += c; + std::list< QString > args; + args.push_back(s); + return Requester::instance().send(mId, "playdtmf", args); +} + +Request * +Session::list(const QString &category) const +{ + std::list< QString > args; + args.push_back(category); + return Requester::instance().send(mId, "list", args); +} + +Request * +Session::registerToServer() const +{ + std::list< QString > args; + args.push_back(getDefaultAccount().id()); + return Requester::instance().send(mId, "register", args); +} + +Account +Session::getAccount(const QString &name) const +{ + return Account(mId, name); +} + +Account +Session::getDefaultAccount() const +{ + return Account(mId, QString("mydefaultaccount")); +} + diff --git a/src/gui/qt/Session.hpp b/src/gui/qt/Session.hpp new file mode 100644 index 0000000000..1d79d63144 --- /dev/null +++ b/src/gui/qt/Session.hpp @@ -0,0 +1,122 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef SFLPHONEGUI_SESSION_H +#define SFLPHONEGUI_SESSION_H + +#include <qstring.h> + +#include "Account.hpp" + +class Session +{ + public: + Session(); + Session(const QString &id); + + /** + * retreive the account identified by name. + */ + Account getAccount(const QString &name) const; + + Account getDefaultAccount() const; + + /** + * This function will play a tone. This is + * just a ear candy. + */ + Request *playDtmf(char c) const; + + + /** + * This function will retreive the given list. + */ + Request *list(const QString &category) const; + + /** + * This function will register to receive events + */ + Request *getEvents() const; + + /** + * This function will ask for all calls status. + */ + Request *getCallStatus() const; + + /** + * This function will mute the microphone. + */ + Request *mute() const; + + /** + * This function will ask sflphoned to close + * the session. This will only close the session, + * so sflphoned will still be running after. + */ + Request *close() const; + + /** + * This function will register with the default account. + */ + Request *registerToServer() const; + + /** + * This function will stop sflphoned. + */ + Request *stop() const; + + Request *configSet(const QString §ion, + const QString &name, + const QString &value) const; + Request *configSave() const; + Request *configGetAll() const; + + /** + * This function will set the volume to + * the given percentage + */ + Request *volume(unsigned int volume) const; + + /** + * This function will set the mic volume to + * the given percentage + */ + Request *micVolume(unsigned int volume) const; + + /** + * This function will unmute the microphone. + */ + Request *unmute() const; + + /** + * This function will ask to the SessionIO + * linked to this session to connect. + */ + void connect() const; + + QString id() const; + Request *stopTone() const; + Request *playTone() const; + + private: + QString mId; +}; + +#endif diff --git a/src/gui/qt/SessionFactory.hpp b/src/gui/qt/SessionFactory.hpp new file mode 100644 index 0000000000..c2a474e6cd --- /dev/null +++ b/src/gui/qt/SessionFactory.hpp @@ -0,0 +1,56 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __FACTORY_HPP__ +#define __FACTORY_HPP__ + +template< T > +struct Creator +{ + virtual T *create(); +}; + +template< typename T > +class Factory +{ +public: + Factory(); + ~Factory(); + + /** + * This function will set the creator. The + * Factory owns the creator instance. + */ + void setCreator(Creator< T > *creator); + + /** + * It ask the creator to create a SessionIO. + * If there's no creator set, it will throw + * a std::logic_error. + */ + T *create(); + +private: + Creator< T > *mCreator; +} + +#include "Factory.inl" + +#endif diff --git a/src/gui/qt/SessionIO.hpp b/src/gui/qt/SessionIO.hpp new file mode 100644 index 0000000000..e845e8e00c --- /dev/null +++ b/src/gui/qt/SessionIO.hpp @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __SESSIONIO_HPP__ +#define __SESSIONIO_HPP__ + +#include <qobject.h> +#include <qstring.h> + +/** + * This is the main class that will handle + * the IO. + */ +class SessionIO : public QObject +{ + Q_OBJECT + + public: + virtual ~SessionIO(){} + +public slots: + virtual void connect() {} + + /** + * You can use this function for sending request. + * The sending is non-blocking. This function will + * send the data as it is; it will NOT add an EOL. + * the stream will be "sync"ed. + */ + virtual void send(const QString &request) = 0; + + /** + * You can use this function to receive answers. + * This function will wait until there's an + * answer to be processed. + */ + virtual void receive(QString &answer) = 0; + +}; + + + +#endif + diff --git a/src/gui/qt/SessionIOFactory.hpp b/src/gui/qt/SessionIOFactory.hpp new file mode 100644 index 0000000000..af82d47a9e --- /dev/null +++ b/src/gui/qt/SessionIOFactory.hpp @@ -0,0 +1,31 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __SESSIONIOFACTORY_HPP__ +#define __SESSIONIOFACTORY_HPP__ + +#include "utilspp/Singleton.hpp" +#include "Factory.hpp" +#include "SessionIO.hpp" + +typedef utilspp::SingletonHolder< Factory< SessionIO > > SessionIOFactory; + +#endif + diff --git a/src/gui/qt/Skin.cpp b/src/gui/qt/Skin.cpp new file mode 100644 index 0000000000..d3e1e75bd3 --- /dev/null +++ b/src/gui/qt/Skin.cpp @@ -0,0 +1,62 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <qwidget.h> + +#include "Skin.hpp" + +Skin::Skin(QSettings settings) +{ + load(settings); +} + +void +Skin::load(QSettings settings) +{ + QStringList keys = settings.subkeyList("/"); + for(QStringList::Iterator it = keys.begin(); it != keys.end(); ++it) { + settings.beginGroup("/" + *it); + SkinElement elem; + + bool pixname, x, y; + elem.pixname = settings.readEntry("/pixname", QString::null, okay); + elem.x = settings.readNumEntry("/x", 0, &okay); + elem.y = settings.readNumEntry("/y", 0, &okay); + if(!pixname || !x || !y) { + DebugOutput::instance() << QObject::tr("The Skin entry %1 isn't complete") + .arg(*it); + } + else { + mSettings.insert(std::make_pair(*it, elem)); + } + } +} + +template< typename T > +void +Skin::update(T *widget) +{ + SettingsType::iterator pos = mSettings.find(widget->name()); + if(pos != mSettings.end()) { + w->setPixmap(pos->second.pixmap); + w->move(pos->second.x, pos->second.y); + } +} + diff --git a/src/gui/qt/Skin.hpp b/src/gui/qt/Skin.hpp new file mode 100644 index 0000000000..78b4683639 --- /dev/null +++ b/src/gui/qt/Skin.hpp @@ -0,0 +1,64 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifndef __SKIN_HPP__ +#define __SKIN_HPP__ + +class QWidget; + +struct SkinElement +{ + QString pixname; + unsigned int x; + unsigned int y; +}; + + +class Skin +{ +public: + /** + * This function will create a Skin from QSettings entries. + * see load function for more details. + */ + Skin(QSettings settings); + + /** + * This function will load a Skin from QSettings entries. + * the settings instance must be in the group of the skin. + */ + void load(QSettings settings); + + /** + * This function will update the widget to his entry + * of the skin. The widget must have a name that is + * in the settings. If not, nothing will be done. + */ + template< typename T > + void update(T *widget); + +private: + std::map< QString, QString > mSettings; +}; + + +#endif + diff --git a/src/gui/qt/SkinManagerImpl.cpp b/src/gui/qt/SkinManagerImpl.cpp new file mode 100644 index 0000000000..44391b922d --- /dev/null +++ b/src/gui/qt/SkinManagerImpl.cpp @@ -0,0 +1,74 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "globals.h" +#include "Skin.hpp" +#include "SkinManagerImpl.hpp" + +SkinManagerImpl::SkinManagerImpl(QSettings settings) +{ + load(settings); +} + +void +SkinManagerImpl::load(QSettings settings) +{ + mSettings = settings; + mSettings.beginGroup("/Skins"); + + QStringList skins = mSettings.subkeyList("/"); + for(QStringList::Iterator it = skins.begin(); it != skins.end(); ++it) { + mSettings.beginGroup("/" + *it); + mSkins.insert(std::make_pair(*it, Skin(mSettings))); + mSettings.endGroup(): + } + + mDefaultSkinName = mSettings.readEntry("/default"); + + loadDefaultSkin(); +} + +void +SkinManagerImpl::loadSkin(QString skin) +{ + SkinsType::iterator pos = mSkins.find(skin); + if(pos != mSkins.end()) { + mCurrent = pos->second(); + } +} + +void +SkinManagerImpl::loadDefaultSkin() +{ + loadSkin(mDefaultSkinName); +} + +void +SkinManagerImpl::update() +{ + QWidgetList *list = QApplication::allWidgets(); + QWidgetListIt it(*list); // iterate over the widgets + QWidget * w; + while ((w=it.current()) != 0) { // for each widget... + ++it; + mCurrent->update(w); + } + delete list; +} diff --git a/src/gui/qt/SkinManagerImpl.hpp b/src/gui/qt/SkinManagerImpl.hpp new file mode 100644 index 0000000000..c33a56274f --- /dev/null +++ b/src/gui/qt/SkinManagerImpl.hpp @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifndef __SKIN_MANAGER_IMPL_HPP__ +#define __SKIN_MANAGER_IMPL_HPP__ + +class SkinManagerImpl +{ +public: + SkinManagerImpl(); + + public slots: + /** + * This function load a given skin. If the + * skin is invalid, nothing is done. + */ + loadSkin(QString skin); + + /** + * This function load the default skin. If the + * skin is invalid, nothing is done. + */ + loadDefaultSkin(); + + void update(); + +private: + QSettings mSettings; + QString mDefaultSkin; + Skin mCurrent; +}; + +#endif + diff --git a/src/gui/qt/TCPSessionIO.cpp b/src/gui/qt/TCPSessionIO.cpp new file mode 100644 index 0000000000..dd1f38a7b0 --- /dev/null +++ b/src/gui/qt/TCPSessionIO.cpp @@ -0,0 +1,140 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "globals.h" +#include "DebugOutput.hpp" +#include "Requester.hpp" +#include "TCPSessionIO.hpp" + +#define NB_MAX_TRIES 4 + +TCPSessionIO::TCPSessionIO(const QString &hostname, Q_UINT16 port) + : mSocket(new QSocket(this)) + , mHostname(hostname) + , mPort(port) + , mNbConnectTries(0) +{ + mReconnectTimer = new QTimer(this); + QObject::connect(mReconnectTimer, SIGNAL(timeout()), + this, SLOT(connect())); + + QObject::connect(mSocket, SIGNAL(readyRead()), + this, SLOT(receive())); + QObject::connect(mSocket, SIGNAL(connected()), + this, SLOT(sendWaitingRequests())); + QObject::connect(mSocket, SIGNAL(connected()), + this, SLOT(resetConnectionTries())); + QObject::connect(mSocket, SIGNAL(connected()), + this, SIGNAL(connected())); + QObject::connect(mSocket, SIGNAL(connectionClosed()), + this, SIGNAL(disconnected())); + QObject::connect(mSocket, SIGNAL(error(int)), + this, SLOT(error(int))); +} + +TCPSessionIO::~TCPSessionIO() +{} + +void +TCPSessionIO::resetConnectionTries() +{ + mNbConnectTries = 0; +} + +void +TCPSessionIO::error(int err) +{ + mNbConnectTries++; + if(mNbConnectTries >= NB_MAX_TRIES) { + DebugOutput::instance() << QObject::tr("TCPSessionIO: Connection failed: %1\n") + .arg(err); + mNbConnectTries = 0; + emit disconnected(); + } + else { + mReconnectTimer->start(2000, true); + } + //mSocket->close(); +} + +void +TCPSessionIO::receive() +{ + QString s; + while(mSocket->canReadLine()) { + receive(s); + Requester::instance().receiveAnswer(s); + } +} + +void +TCPSessionIO::connect() +{ + DebugOutput::instance() << QObject::tr("TCPSessionIO: Tring to connect to %1:%2.\n") + .arg(mHostname) + .arg(mPort); + mSocket->connectToHost(mHostname, mPort); +} + +void +TCPSessionIO::sendWaitingRequests() +{ + DebugOutput::instance() << QObject::tr("TCPSessionIO: Connected.\n"); + QTextStream stream(mSocket); + while(mSocket->state() == QSocket::Connected && + mStack.size() > 0) { + stream << *mStack.begin(); + mStack.pop_front(); + mSocket->flush(); + } +} + +void +TCPSessionIO::send(const QString &request) +{ + QTextStream stream(mSocket); + if(mSocket->state() == QSocket::Connected) { + DebugOutput::instance() << QObject::tr("TCPSessioIO: Sending request to sflphone: %1") + .arg(request); + stream << request; + mSocket->flush(); + } + else { + mStack.push_back(request); + } +} + +void +TCPSessionIO::receive(QString &answer) +{ + if(mSocket->isReadable()) { + QTextStream stream(mSocket); + answer = stream.readLine(); + DebugOutput::instance() << QObject::tr("TCPSessionIO: Received answer from sflphone: %1\n") + .arg(answer); + } +} + + + + + + + diff --git a/src/gui/qt/TCPSessionIO.hpp b/src/gui/qt/TCPSessionIO.hpp new file mode 100644 index 0000000000..6ddf34df64 --- /dev/null +++ b/src/gui/qt/TCPSessionIO.hpp @@ -0,0 +1,101 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __TCPSESSIONIO_HPP__ +#define __TCPSESSIONIO_HPP__ + +#include <qobject.h> +#include <qstring.h> +#include <qsocket.h> +#include <qtextstream.h> +#include <qtimer.h> +#include <list> + +#include "SessionIO.hpp" + +#ifdef QT3_SUPPORT +#include <Q3Socket> +typedef Q3Socket QSocket; +#else +#include <qsocket.h> +#endif + + +class TCPSessionIO : public SessionIO +{ + Q_OBJECT + +public: + TCPSessionIO(const QString &hostname, + Q_UINT16 port); + + virtual ~TCPSessionIO(); + +signals: + void connected(); + void disconnected(); + +public slots: + /** + * This function send the request that we were + * unable to send. + */ + void sendWaitingRequests(); + + /** + * Those function are the actual function + * that write to the socket. + */ + virtual void send(const QString &request); + + /** + * This function is called when we have + * incomming data on the socket. + */ + virtual void receive(); + + /** + * Those function are the actual function + * that read from the socket. + */ + virtual void receive(QString &answer); + virtual void connect(); + + void resetConnectionTries(); + + private slots: + /** + * This function is called when we have an error + * on the socket. + */ + void error(int); + +private: + QSocket *mSocket; + QString mHostname; + Q_UINT16 mPort; + + std::list< QString > mStack; + + unsigned int mNbConnectTries; + QTimer *mReconnectTimer; +}; + +#endif diff --git a/src/gui/qt/TCPSessionIOCreator.cpp b/src/gui/qt/TCPSessionIOCreator.cpp new file mode 100644 index 0000000000..7e34f64119 --- /dev/null +++ b/src/gui/qt/TCPSessionIOCreator.cpp @@ -0,0 +1,39 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "TCPSessionIOCreator.hpp" +#include "PhoneLineManager.hpp" + +TCPSessionIOCreator::TCPSessionIOCreator(const QString &hostname, + Q_UINT16 port) + : mHostname(hostname) + , mPort(port) +{} + +TCPSessionIO * +TCPSessionIOCreator::create() +{ + TCPSessionIO *t = new TCPSessionIO(mHostname, mPort); + QObject::connect(t, SIGNAL(connected()), + &PhoneLineManager::instance(), SIGNAL(connected())); + QObject::connect(t, SIGNAL(disconnected()), + &PhoneLineManager::instance(), SLOT(hasDisconnected())); + return t; +} diff --git a/src/gui/qt/TCPSessionIOCreator.hpp b/src/gui/qt/TCPSessionIOCreator.hpp new file mode 100644 index 0000000000..32b7abc7bd --- /dev/null +++ b/src/gui/qt/TCPSessionIOCreator.hpp @@ -0,0 +1,41 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __TCPSESSIONIOCREATOR_HPP__ +#define __TCPSESSIONIOCREATOR_HPP__ + +#include "Factory.hpp" +#include "TCPSessionIO.hpp" + +class TCPSessionIOCreator : public Creator< SessionIO > +{ +public: + TCPSessionIOCreator(const QString &hostname, + Q_UINT16 port); + virtual ~TCPSessionIOCreator(){} + + virtual TCPSessionIO *create(); + +private: + QString mHostname; + Q_UINT16 mPort; +}; + +#endif diff --git a/src/gui/qt/TODO b/src/gui/qt/TODO new file mode 100644 index 0000000000..c58f2a1168 --- /dev/null +++ b/src/gui/qt/TODO @@ -0,0 +1,21 @@ +Design: +- Need to consolidate Request and Answers. + +Behavior: +- Link lines with F* keys. (done) +- Backspace should work. (done) +- Add tooltip on lines with the caller id. (done) +- Zone Tone in Signalisation. (done) +- Add keypad. (done) +- Add caller id on the LCD. (done) +- Time of communication. (done) + +- put Transfert button. +- Skin system (important). +- Keypad must be attracted to the main window. + +- Add the solo option. (later) +- Add a timed paint event. (later) +- Add "Confirmation to quit". (later) + +- Put codec on the LCD (won't be done) diff --git a/src/gui/qt/TransparentWidget.cpp b/src/gui/qt/TransparentWidget.cpp new file mode 100644 index 0000000000..9d7f9cd125 --- /dev/null +++ b/src/gui/qt/TransparentWidget.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * (jean-philippe.barrette-lapierre@savoirfairelinux.com) + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with dpkg; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <qbitmap.h> +#include <qcolor.h> +#include <qdragobject.h> +#include <qmime.h> +#include <iostream> + +#include "DebugOutput.hpp" +#include "TransparentWidget.hpp" + + +TransparentWidget::TransparentWidget(const QString &pixmap, + QWidget* parent) + : QLabel(parent) +{ + mImage = transparize(pixmap); + setPixmap(mImage); + updateMask(this, mImage); + + resize(mImage.size()); +} + +TransparentWidget::TransparentWidget(QWidget* parent) + : QLabel(parent) +{} + +void +TransparentWidget::updateMask(QWidget *w, QPixmap image) +{ +#ifdef QT3_SUPPORT + if(image.hasAlpha()) { + w->setMask(image.mask()); + } +#else + if(image.mask()) { + w->setMask(*image.mask()); + } +#endif +} + +QPixmap +TransparentWidget::retreive(const QString &image) +{ + return QPixmap::fromMimeSource(image); +} + +QPixmap +TransparentWidget::transparize(const QSize &) +{ + /* + QImage image(size, QImage::Format_RGB32); + QColor c(12,32,35,123); + image.fill(c.rgb()); + + QPixmap p(QPixmap::fromImage(image)); + p.setMask(p.createHeuristicMask()); + //p.setMask(p.alphaChannel()); + */ + return QPixmap(); +} + +TransparentWidget::~TransparentWidget() +{} + + +void +TransparentWidget::setPaletteBackgroundPixmap(QWidget *w, const QString &pixmap) +{ + QPixmap p(transparize(pixmap)); + w->setPaletteBackgroundPixmap(p); + updateMask(w, p); +} + +QPixmap +TransparentWidget::transparize(const QString &image) +{ +#ifdef QT3_SUPPORT + QPixmap p(retreive(image)); + if (!p.mask()) { + if (p.hasAlphaChannel()) { + p.setMask(p.alphaChannel()); + } + else { + p.setMask(p.createHeuristicMask()); + } + } +#else + // QPixmap p(QPixmap::fromMimeSource(image)); + QImage img(QImage::fromMimeSource(image)); + QPixmap p; + p.convertFromImage(img); + + + QBitmap bm; + if (img.hasAlphaBuffer()) { + bm = img.createAlphaMask(); + } + else { + bm = img.createHeuristicMask(); + } + p.setMask(bm); +#endif + return p; +} + + diff --git a/src/gui/qt/TransparentWidget.hpp b/src/gui/qt/TransparentWidget.hpp new file mode 100644 index 0000000000..f0ca17d25c --- /dev/null +++ b/src/gui/qt/TransparentWidget.hpp @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * (jean-philippe.barrette-lapierre@savoirfairelinux.com) + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with dpkg; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __TRANSPARENT_WIDGET_HPP__ +#define __TRANSPARENT_WIDGET_HPP__ + +#include <qbitmap.h> +#include <qlabel.h> +#include <qpixmap.h> +#include <qimage.h> + +/** + * This class Emulate a PushButton but takes two + * images to display its state. + */ +class TransparentWidget : public QLabel +{ + Q_OBJECT + +public: + TransparentWidget(const QString &pixmap, + QWidget *parent); + TransparentWidget(QWidget *parent); + ~TransparentWidget(); + + static QPixmap retreive(const QString &size); + static QPixmap transparize(const QSize &size); + static QPixmap transparize(const QString &image); + static void setPaletteBackgroundPixmap(QWidget *w, const QString &pixmap); + + /** + * This function will update the mask of the widget + * to the QPixmap mask. + */ + static void updateMask(QWidget *w, QPixmap image); + + + bool hasAlpha() + {return mImage.hasAlpha();} + + QBitmap mask() const + {return *mImage.mask();} + +private: + QPixmap mImage; + +}; + +#endif diff --git a/src/gui/qt/Url.cpp b/src/gui/qt/Url.cpp new file mode 100644 index 0000000000..2c95432f11 --- /dev/null +++ b/src/gui/qt/Url.cpp @@ -0,0 +1,61 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <qurl.h> + +#include "Url.hpp" + +static uchar hex_to_int( uchar c ) +{ + if ( c >= 'A' && c <= 'F' ) + return c - 'A' + 10; + if ( c >= 'a' && c <= 'f') + return c - 'a' + 10; + if ( c >= '0' && c <= '9') + return c - '0'; + return 0; +} + +void Url::decode( QString& url ) +{ + int oldlen = url.length(); + if ( !oldlen ) + return; + + int newlen = 0; + + std::string newUrl; + + int i = 0; + while ( i < oldlen ) { + ushort c = url[ i++ ].unicode(); + if ( c == '%' ) { + c = hex_to_int( url[ i ].unicode() ) * 16 + hex_to_int( url[ i + 1 ].unicode() ); + i += 2; + } + else if ( c == '+' ) { + c = ' '; + } + newUrl += c; + newlen++; + } + + url = QString::fromUtf8(newUrl.c_str()); +} diff --git a/src/gui/qt/Url.hpp b/src/gui/qt/Url.hpp new file mode 100644 index 0000000000..2494433e90 --- /dev/null +++ b/src/gui/qt/Url.hpp @@ -0,0 +1,33 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifndef __URL_HPP__ +#define __URL_HPP__ + +#include <qstring.h> + +namespace Url +{ + void decode(QString &url); +} + +#endif + diff --git a/src/gui/qt/VolumeControl.cpp b/src/gui/qt/VolumeControl.cpp new file mode 100644 index 0000000000..aa32415950 --- /dev/null +++ b/src/gui/qt/VolumeControl.cpp @@ -0,0 +1,173 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Laurielle Lea <laurielle.lea@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <qevent.h> +#include <iostream> + + +#include "TransparentWidget.hpp" +#include "VolumeControl.hpp" + +#define SLIDER_IMAGE "slider.png" + +VolumeControl::VolumeControl (const QString &pixname, + QWidget *parent, + int minValue, + int maxValue) + : QLabel(parent) + , mMin(minValue) + , mMax(maxValue) + , mValue(minValue) + , mOrientation(VolumeControl::Horizontal) + , mSlider(new TransparentWidget(pixname, this)) + , mMaxPosition(100) +{ + resize(); +} + +VolumeControl::~VolumeControl() +{} + +void +VolumeControl::resize() +{ + QPixmap q(QPixmap::fromMimeSource(SLIDER_IMAGE)); + setPixmap(q); + if(q.hasAlpha()) { + setMask(*q.mask()); + } + + QWidget::resize(q.size()); + mMaxPosition = q.height() - mSlider->height(); +} + +void +VolumeControl::setOrientation(VolumeControl::Orientation orientation) +{ + mOrientation = orientation; +} + +void +VolumeControl::setMax(int value) +{ + if(value >= mMin) { + mMax = value; + } +} + +void +VolumeControl::setMin(int value) +{ + if(value <= mMax) { + mMin = value; + } +} + +void +VolumeControl::setValue(int value) +{ + if(value != mValue) { + if(value <= mMax && value >= mMin) { + mValue = value; + updateSlider(value); + emit valueUpdated(mValue); + } + } +} + +void +VolumeControl::mouseMoveEvent (QMouseEvent *e) { + if (mOrientation == VolumeControl::Vertical) { + // If the slider for the volume is vertical + int newpos = mSlider->y() + e->globalY() - mPos.y(); + + mPos = e->globalPos(); + if(newpos < 0) { + mPos.setY(mPos.y() - newpos); + newpos = 0; + } + + if(newpos > mMaxPosition) { + mPos.setY(mPos.y() - (newpos - mMaxPosition)); + newpos = mMaxPosition; + } + + mSlider->move(mSlider->x(), newpos); + updateValue(); + } + else { + mSlider->move(e->y() - mPos.x(), mSlider->y()); + } +} + +void +VolumeControl::updateValue() +{ + int value = (int)((float)offset() / mMaxPosition * (mMax - mMin)); + if(mValue != value) { + mValue = value; + emit valueUpdated(mValue); + } +} + + +void +VolumeControl::updateSlider(int value) +{ + if(mOrientation == VolumeControl::Vertical) { + mSlider->move(mSlider->x(), mMaxPosition - (int)((float)value / (mMax - mMin) * mMaxPosition)); + } + else { + mSlider->move(value / (mMax - mMin) * mMaxPosition, mSlider->y()); + } +} + +int +VolumeControl::offset() +{ + if(mOrientation == VolumeControl::Vertical) { + return mMaxPosition - mSlider->y(); + } + else { + return mSlider->x(); + } +} + +void +VolumeControl::mousePressEvent (QMouseEvent *e) +{ + mPos = e->globalPos(); + int newpos = e->pos().y() - (mSlider->height() / 2); + + mPos = e->globalPos(); + if(newpos < 0) { + mPos.setY(mPos.y() - newpos); + newpos = 0; + } + + if(newpos > mMaxPosition) { + mPos.setY(mPos.y() - (newpos - mMaxPosition)); + newpos = mMaxPosition; + } + + mSlider->move(mSlider->x(), newpos); + updateValue(); +} + +// EOF diff --git a/src/gui/qt/VolumeControl.hpp b/src/gui/qt/VolumeControl.hpp new file mode 100644 index 0000000000..0ca082afc6 --- /dev/null +++ b/src/gui/qt/VolumeControl.hpp @@ -0,0 +1,75 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __VOLUMECONTROL_HPP__ +#define __VOLUMECONTROL_HPP__ + +#include <qlabel.h> +#include "TransparentWidget.hpp" + +class VolumeControl : public QLabel +{ + Q_OBJECT + +public: + typedef enum {Vertical = 0, Horizontal} Orientation; + + VolumeControl(const QString &pixmap, + QWidget *parent = 0, + int minValue = 0, + int maxValue = 100); + ~VolumeControl(void); + + int getValue() + {return mValue;} + + int offset(); + int minY(); + int maxY(); + +signals: + void valueUpdated(int); + +public slots: + void updateValue(); + void setMin(int value); + void setMax(int value); + void setValue(int value); + void resize(); + void setOrientation(Orientation orientation); + +private: + void updateSlider(int value); + void mouseMoveEvent(QMouseEvent*); + void mousePressEvent(QMouseEvent*); + + + int mMin; + int mMax; + int mValue; + + VolumeControl::Orientation mOrientation; + QPoint mPos; + + TransparentWidget *mSlider; + int mMaxPosition; +}; + +#endif // __VOLUME_CONTROL_H__ diff --git a/src/gui/qt/globals.h b/src/gui/qt/globals.h new file mode 100644 index 0000000000..e1e1e3d27f --- /dev/null +++ b/src/gui/qt/globals.h @@ -0,0 +1,53 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef SFLPHONE_GLOBAL_H +#define SFLPHONE_GLOBAL_H + +#define DEBUG + +#define NB_PHONELINES 6 +#define PROGNAME "SFLPhone" +#define VERSION "0.4.2" + +#define AUDIO_SECTION "Audio" +#define AUDIO_DEFAULT_DEVICE "Drivers.driverName" +#define AUDIO_CODEC1 "Codecs.codec1" +#define AUDIO_CODEC2 "Codecs.codec2" +#define AUDIO_CODEC3 "Codecs.codec3" +#define AUDIO_RINGTONE "Rings.ringChoice" + + +#define SIGNALISATION_SECTION "VoIPLink" +#define SIGNALISATION_FULL_NAME "SIP.fullName" +#define SIGNALISATION_USER_PART "SIP.userPart" +#define SIGNALISATION_AUTH_USER_NAME "SIP.username" +#define SIGNALISATION_PASSWORD "SIP.password" +#define SIGNALISATION_HOST_PART "SIP.hostPart" +#define SIGNALISATION_PROXY "SIP.proxy" +#define SIGNALISATION_AUTO_REGISTER "SIP.autoregister" +#define SIGNALISATION_PLAY_TONES "DTMF.playTones" +#define SIGNALISATION_PULSE_LENGTH "DTMF.pulseLength" +#define SIGNALISATION_SEND_DTMF_AS "DTMF.sendDTMFas" +#define SIGNALISATION_STUN_SERVER "STUN.STUNserver" +#define SIGNALISATION_USE_STUN "STUN.useStun" + + +#endif diff --git a/src/gui/qt/images/about.png b/src/gui/qt/images/about.png new file mode 100644 index 0000000000000000000000000000000000000000..03600d6b0ac02bf687795ff13aab794e4ba8f5e6 GIT binary patch literal 2395 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 N002ovPDHLkV1jJScW(dy literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/audio.png b/src/gui/qt/images/audio.png new file mode 100644 index 0000000000000000000000000000000000000000..d43e938810f27edf8f62a0d3cf5914e92e14086b GIT binary patch literal 1968 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 C@v}+* literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/clear_off.png b/src/gui/qt/images/clear_off.png new file mode 100644 index 0000000000000000000000000000000000000000..be1436097c210a578bb51be5f8d15f89da387314 GIT binary patch literal 1385 zcmV-v1(y1WP)<h;3K|Lk000e1NJLTq002z@000sQ0ssI2k+a0b000FrNkl<Zc%0pr zdu&rx9LIn6(RJ(Ag$1|rNHt^2Ac2}O1yRv0z?3kvZh?fv@Q79kYIqooE<}P5A0>t` zgs_Ot7#WEWd58l8GmaQGP}x}4bz^jK;4Eymqg~g>?LEJ9j(^-yx&;Z|k*IwCXqs=o zJ?Hni_uO-TM{v1Zl+tiGObB6&an9kE7-NDUFvb!N=Ufnk#OD}4@jcl|#290uC?@}! zJRRp;6vgC>Hah@}8Tl>_=R7g5AP9mW7z_rJ$s~%R9E-*J`};dOI);ab2_f(RNs=U! z$&{Cumy?qt4-5=+cXyYSm07LU)YR0(rTV{%bFL^#Utizp)2At=vfJ%0EiJWJEQ+Fp z!(siL7#|!80;FbSq#KR$eXUuKIOnn~TP&7Eix$<_*NdT02oWQZh_-0CE_oVjt-1My zg^w2&&dSfvb=0}I;&NE6bzR{^Cfs${nxtA+Q1cbfF{{;Dea@dqb{$@yh^?<V6Vz1_ z01!eVkq9D2B2hUI2nd2eDb;=D2F~wUu&TQ1aNCxpwp3Jn*E)L!O@v-o0Yp#<Nzr1= zAOYA;^)^0b1_a>oNJt?7*mV3;0NDA}kE`caqyqqeK|+9SSArX&&0iKSam<<DzI=MR zzS=adP-sY26a^8r%~sb?k;a;8sA|}<F#Ed4Lj@@%ZED`b%20p-0C1Yv+mHc3ZaN$C z4}k!{kWdZ~Y5)8aca?L4vue}%YtI)?kpY0gFqBLX{Qm6OMF4=5=-wbHrHH5~ij0Vq zQc5XLdQbcV#jiCrLG_N@-Wvf82T42%07wCVQ;LWqoRk5a_+Xo*z^KG0maJXzgb|>( z@#}N8n)=tv)2epwKI3|Ng$)2G%Y?I+e{P?A_4`_YHKo(dsH*xn8Dko%%ornt5JE&z z)H4!Ei2x|UL6V*_%0~tOz%c24asViK&TgAP1Y?d!2m#-zw~pHPt?laky~tUzwW|I~ z#f)4dFrE%jvu|@v^JO^R7o9ZJ9n|~2)94su<K{F@DYwC<lNT4fG-s4g83*7DZgWxq zC@(I4)XGJm;Xi$$@a4uD0NdX6s|b5&(qw>xXD+_@^4x3+UMQ(;Xjr<xXhOwm=UL|q zCY_k0Iko3g@BNe(Zr=cvZ|t<}e`Uc;6R3edy4*p_{8?fqz)+w+l9myt6eMFBWdOf* zUhGseAWlIt$}Qh~WOFvPZknqV^uyc6vV#{YW-q2pfWaFVe(|iVKl#NYWjnsje|Jfq zZcapGjLCRQIyoT>MO!Z&%9_1=&7t>3EXUsO=24OX;9Onl)U3xgp4c)KpySob#UsXR zo1-V-;}5f%o0~N!f8_z#y|T^w><q|+iJ1aM-Geia9jnT(T=nG4hT^FyV`si+PDGTo zMXRc+BuTnB!S89a%v*=bMqeN%%W_&)7WKCOde!(D;(<g62QPUT;+waPpikVhy|4AB zUNW-J_ZvzO(c9J(dgc(W3!FdK6~EaNEPMy?eQ$e{=cb-#lv1hz3gzYHcDp?%Cr6T` zaW#EXs@Y_ql#*!lKhh<0&MBpSzyHXQqjEt(f!pmCMbT_F%d$KURCO?RKdT(4IOm8s zJUr}jxe5yMWxL(JYu7GSRkO3RjYi{x)W^r;ai7oU^?Dr+htSf}A_ziVU0qL4Pbd`n zx68YqGMmlQrcGP6Y*{Q86IxqaMNu@FOa_BNk|aL*^bAR7*}sz(NL~nc{0qO+>HIF4 rd+g7&c6H2|UK1j!su~CcD5ZY^er&fFBW)|400000NkvXXu0mjftfi6q literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/clear_on.png b/src/gui/qt/images/clear_on.png new file mode 100644 index 0000000000000000000000000000000000000000..9605e89ae9d104ab2d627a27f7c4ddcffb42ff94 GIT binary patch literal 1383 zcmV-t1(^DYP)<h;3K|Lk000e1NJLTq002z@000sQ0ssI2k+a0b000FpNkl<Zc%0o= zTTB#J82-+gv+nM|O4u#BsmdjV2n8fIYQ=^I6H6@-teRljM$3b#HEoa*Bc(O5BqpS` zR!cEyf~8hsR34;;jh7ax)>|t#8>+%8i>?K>h^#Iwv%7Qa!{CZkn`ZE#^?R6{^PO-0 z`M)`5&YYigbacqFJTfvOilU+@s;a803IIU3p(qN*fe;cN(qx2?@p_HXy5rm9H5z1D z9v^nRM!Ql<Cp_yPm@uz}qLdm82A=0BrA!b6x7%G`U+;3cd_EtZB3LYz*x1;mOP9`^ zIg`}Y)$QE5(`K_-tyYuC6n?4ycc`iw2n2?Ph6V=*3kwU$+O=y1K}bkQ;CY@grr)O` z`GrxyU^E&TqfazvJy2CulBChm(Vm_jj^mii<;u*=wA<}Qqmfdb`FSp%EU&5ycQf8B zdv_teE~-e~vMXzbQ6q!B7mBy-3u_9>b}WwN0f?UFqVk%&;_bP!E!t4;g>Sd*yQsAn ztk|$RXAZ9`D@9R)!61M$XU;N3QEWC_L_~yclXp8E<yA*Y54L^0GR-6fZr{Ax+4HB% zGcXlMoE6FF*xq1DNCeUy*BcjEAOd%<oc{UxJwSFj&jDy?cju&Lm;e9?i7~*|t3w-w z^Lt-dR+5qN)q)u&eYr8ltX3-_V2m-d*~}Qz>oaiU^bwSvD48?t*uOu>j8=Q>v<Q`P zgaDLHVRURq<v@XWq3c{@5DW<T{fsdLdQTnbDy=B`w5;-0-kua22LN;!*}SW<G4i?D z0BqAE8PjJIilS)l7<V5!eTpN_7JN|=d7`Bo9LK5By?)m{fYYK;%5h^tsuG}~vI;RQ zBu34BJ?D7?hrX^~n$vfGzvfj_S>=JwzO<L)0jMMjr@C5R3I4Ia5m>h*IlAwb&L06G zM03XoAz`<ABGG9<V7Sk1H$42#i3)&FF1#lZ2>@~m3R9-a#K6lVJ_+8-yN>5qt#52< zPOr!=FS|65mH4ay5+Z<_h8nbV<M7QR=JsPu?}W;-tZlALbF6>eTBhfxW7A3Jq1Tch z9*_VKGKJ%$F`o(n@)y0B6eDpE?>Mjf#hxp*Kw8!2t%4LYV-|4ux9*%-snH7QMfRSb zj<5P=e)P&WKKgEBwn^6%;Qo9PLKvlVQtLJ-W_?nGRa<MLDpoH_G9%>kbUS^|%uBIE z0Y1N1CPq<FKn)R;0IrU+?bFN<6;K21I=wr+;%rOFd;p4~G?ki{9q(E)=Osoc25&hW z=L;GfHSx>#&P{r6aqMJ#Qc4*igi@-x)fGwzrEY0I6g_u!nd8ebs&L0aj*}yR&o`_a zqcYalei#q@Ui{A6V?^Nx!DINW!hH1TQH@D>s}_}Ox`!5~U@B};W-fH`M)KkM(xeq7 z^V1Gx+NbEVN-2G?ZuNhkfVZ=mpZC5f6yNp=j4^X`wB&9*bIn*SinU>pbo<vUiYRV+ zKn!_k_4XSVe(1XYTo1_-MbUk+>2BOXvG~r(A1?)b*9Ouyi{dtSYt!X{kiPV^bxZQ| z^OrAQZnat`br=G`nJm0PQIwG1FY1r-B%vLNyk2j8eLYJ_N%43*7K=rjU;S1k!RHg6 zXr7aTR(Oe`*x%ouoSe+^^75*yt5sFC+wDBB?|}6m#pvj$$K!E2odpF2q_wq`QmWNu z!^6W*Q@s)y85tKBmz$gG_xnj(TN|a6=Xry{z;WD!5*B}}j2{^h<ErGx-7=xzex!0j pf&MT3JWec0QYaMidcCqN{{>?<WUmm$e2xGB002ovPDHLkV1g&En7{x4 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/close_off.png b/src/gui/qt/images/close_off.png new file mode 100644 index 0000000000000000000000000000000000000000..e962b31b1630f1cfababa9f153fd97d7ee56058f GIT binary patch literal 785 zcmV+s1Md8ZP)<h;3K|Lk000e1NJLTq000gE000jN1^@s6)D-@700006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)d~d<2o+rs=5YW30-i}k zK~yNuHIqwk8&v>C&%JYJ#^ZT8PHZQtN*<J^F*J&U8o{D<p(|J*RR|<D{JW}4#IkXf zDhPxqNKHhVf`?)RNhor#XA(CPdnR*PMErtJ=jeQ*)9C=9f!^;g_3rL2`};3=@oN`T zDBirjNOPsh>gp=<3-dxC01%HhHxWYcWNS-*yZsGIZ(L=))uJ&s2WVdX{fcKhyS)7K z588J>pxtf@0Huq9C)?Zl>xU1y|Ix?Xz4sxDD=UPR3PK1@lZ58dHMX}N^VNd~6k6-{ zojXGHdOiL9W`}z>Zm>Q(OI>TsexLDRfYu-{E@<e2R%4D)v&j#g$1KdxYZXNiSJQKv zhK0TNGo$_?lQ7_tMN?=^o}6O$2P{j)@GK?jb`hW4zO6TM&9W*8l%QPkQGt&%Z3Ix{ zW3psKI!qYmny4^%W=NFmMqF85p<?EgLzhyuN+}F6EbG$tBx7tjSO%#0HD?paPSiy; zEQ^W>!CV6`^l_@w*j|8X+aTZ~&zPK?klH4ulMo*sQ&T2trq#mCPjIRg{OKxQFop61 z4Eu7im}KOJfl>yAl$giI%(T{!vm3W~osO~GfO0s6?RzNCMFu`1@G*Q3I|wNSA(j_1 zKA+IoxP@G}d6UC(!00SRmOKbTq~}4YjC4JO=c4@pRrW~FQ~q*%7T4C0)3qA)`=7D% ze2;(Q0TXGETQ-y(wBu0NB_@VJJUZp4y?yGReon1kN5ye0-hOvoKbL|>PrqYnIN-`# z*O{8BVVDNPfBGE$7ST%*yf41woz^->M@K^ZA9=lA*Ljw)_v2GW(JxHmV*uRg2G-&= zR^NLc%d$8)I1m7$)9IkK2EcI~U9DDeT^A`O09lrirYT915XbT5HGuyBCYJ)#+bKYJ P00000NkvXXu0mjff1h90 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/close_on.png b/src/gui/qt/images/close_on.png new file mode 100644 index 0000000000000000000000000000000000000000..747c7fb09c461bef92cb4fdf9af9cc03fa7e9731 GIT binary patch literal 812 zcmV+{1JnG8P)<h;3K|Lk000e1NJLTq000gE000jN1^@s6)D-@700006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)d~d<3=6|@9u@!q0=Y>< zK~yNuHPc^DQ)d8x@#j7N+CzbsLQmVE(jo)tX6>oNXbhCiD|fNPEL*aheF+wC`~+V4 z9ZZaO8qH!Nbr_tB5oZKN+<Me5lY&dNoCAeZ+j3qnj341ievc@Z%K%8A`udezSy^Fi z?FBFXsh|su!{b?UlR5JFJR_MAArJtF+w=1XA-KD+Anz~UWAxBLindKModzUtH{bGP zd4*U1{Yz=~8%m{;0MKL*aCdQ0-ne>|b7#L}_RP0rCnt%<VhADF@jP;)V=OM*;rf*; z1X9Y<%#6^g)vA0jU*^n_BNS69EGg0Jbv`s2ND0dRK1ms1C(|@@IUbhpkQo_~n&UVe z^jqXqgV5?Tn)Mp(Xg{A?B!QH4y&XdJ1`~?L)}D`3sUW_eo|Y%Nk_j!KUlRn8Ft0oN z498*!pys(`H4U}7$5vP31S(Hd1x=|q3{OlF)4TLUBQ*37*B(FRz<@{1+eQWfb5l0a zu#V>Lve#Bvb}DE|!yu+Ze>zETw2yRrkjus6oV<7mfTas_w70kM8}HFg54ZM?gr=hm z**1Cz%y^7GE5SAj=WpJkkj+rYX885mZ@3crEQ@e_06hdlb^$GQVv610Z(&6G>4^@o zR@)?#PBCNWk-#6z&)96WIWU;QZ*}<4YLh%Yg_b#b6z9Qx4)6I`;a;YvzGk*GgVYU# zs!+0z5$yVOT^GOghBsy(<AnmsU?PEa?njoNukzk)&{kBsMhJRLq-hd_!n9Qtx4FY# zt7}+4{6xaC&|KFQUmh>Y=ZfI=(w~fOH5mS4oPnVPs;;v2f1TP(hpOk%`|~e+Wf$4l z*bw3~a?7%0x6@(u(GpGPZ`$rV03w4)jO-Zslcz8YgZ1@w0U*ldGEzzaOw*L{c$`Qi qf}$t@bUGb;-^cSjT-W`y2JjKSa~^f36p%6i0000<MNUMnLSTY-uyX4F literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/conference_off.png b/src/gui/qt/images/conference_off.png new file mode 100644 index 0000000000000000000000000000000000000000..e395b4c1545ab57b5f717c5e5e61d9866fad2704 GIT binary patch literal 2359 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 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/conference_on.png b/src/gui/qt/images/conference_on.png new file mode 100644 index 0000000000000000000000000000000000000000..a565e16d30e2a96b5a4b06f0767bc40dffbae0d8 GIT binary patch literal 2379 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 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/directory_off.png b/src/gui/qt/images/directory_off.png new file mode 100644 index 0000000000000000000000000000000000000000..549106a473846a7fc39cec736876a4d57b7ef3d9 GIT binary patch literal 2066 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 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/directory_on.png b/src/gui/qt/images/directory_on.png new file mode 100644 index 0000000000000000000000000000000000000000..265075178051802e1195dfa022b596310b1caccf GIT binary patch literal 2099 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 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_0_off.png b/src/gui/qt/images/dtmf_0_off.png new file mode 100644 index 0000000000000000000000000000000000000000..1b4a2ebe466177aaa91c951c306cf139940983d2 GIT binary patch literal 1623 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 VWxO<z9r^$O002ovPDHLkV1j?$5o`be literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_0_on.png b/src/gui/qt/images/dtmf_0_on.png new file mode 100644 index 0000000000000000000000000000000000000000..57c0f4fcee858e98d94a5c8d0663622b33065366 GIT binary patch literal 1675 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 VOn7m*;~D?}002ovPDHLkV1k~gI^O^Q literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_1_off.png b/src/gui/qt/images/dtmf_1_off.png new file mode 100644 index 0000000000000000000000000000000000000000..0b47b61c32f73d098a994a3b87796bad9f24cf4c GIT binary patch literal 1422 zcmV;91#$X`P)<h;3K|Lk000e1NJLTq001oj001lq1^@s6@kTK}00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?8vtC-+CcyS1sh33 zK~z}7%~?%P>P!@VTBgRJ$ifALEyk!MMi%Z&NQ@g@`Q!Wv?)?LP>`ZiH@Pn`s;=%+M z0u>O1PWvv*^p3|fLwPTYJ4w@a(wUx*=bZD*jB|N;8MWJOJU>69-EQOa^AkZ3005#W zg5x+)O+7n~gD8sFXRdK`nBM7sgb-L-TEgn;DmFGYu)4Ym;rl*nwHgYA0uBxiP%IXa z&1UhhG~f5}^74XewTfD;hH|+K=j7xhT3lSj;o%_)g#!N7)@rqIadClEDh2oJ>kH*_ zITkn!Lqt*Z;|jwtzPNYQ$Bm<RZXP<0yK=c4wzjs=>2x4Eoepxj9D2PThQlF(Ac!$) zYC4W-pTeVh*6$Rvw2zM0aqW2?^7%Zv-7bWb5~I;5w(`6h4dTCPK@ea(9%C|@U^pB? zP*={g&0{{LxRer7O1Q2I;W!S$FhmdptYwm>Hf7mHqk+4-JJjoSTwPt^{QUfv<*64a zl+-`MF#OT43@a3db*tF$XtH1wMYzAe$MNwoN~IE7trp(j-+#@k3qS=o-StaK30K!X z3`0mMt#|dzz3=bu<Ms6wkB^V2R4TDs)i*&9#NR3bZ1d~i>Iw@LfaCF)wX~^naW2ke zGRR~ysMTt5znYh`s;!UCABG`Z*9Cy@K;+!=e}d`h>4{B=CWUqD={R;>_ZOD+CMcdc zZouK4%d@j)6D}>%fYkd`zbl0J<t9_0O(R1lLAgRS3&Em>a&^<w^hVuh`;o~Tj^j)f z(xxbv4qexESu4^Xaj7p!9@mw(<#_HJ6D4p>uCw7V2`8Brh&I?zE9=j3%1cVnxhkeZ zX%@^UfgBfzQ51a_7n3Dy*fl9+qXJ3dLN^A@8Zo9-#o;Vy3NRBbeRz04sZ>I#RKnTW z834rZr>Cb@BiM{V`-Dp5lnW%GniOwGM@P85y=8x1C=}rPzENQ=Cb;(>#l_@a8@Z=~ zXEGV=?(P~D?{>RWVP>KTtfi^&`lMX4rwT<;gj%g;q@c7^+u}g~2bJ#!rnw?w!?lU8 zOxrG?F=NBG$s=wmm6|Eqxk_hR_nC4$$KSc&)92Kcb)}TX9BL~pwrDrOM;FEvBewLX z`h_V^+m=FqyB_4?MLkm*N@WSd@VkuDi?aw9peFpASQ?jcxR|g7s1V{$_L$XzCd((~ z)ih&qFyds8QvR`YlAxegu$6lo-!SF=X%GVNy)9-7q*)dNf3p{olsv`UV;Yy9R(3fh zX^e0JoA|j6dhr&5iF0rTCn?=DEg(z*OO@pep^p`=>l*j)O!=BC7Mvn#UUjz>8*ZHG zdtnMFuAf_((}3j^oW>w^E34(7ZHG(f37uQm+7<w`%yJb@ZLpY%28E8Q&|F<$_wv+- z`o^D$DA_8cK8^}&@|G!RsdA}Q3c~Zec)yIx!8SJ~al37UXO<MH-vwt`DsYk&_$-SB z&h@s1F*T^`c^*DKK7O5#=mdpgmJ%46DY%V#Iu|`_F)gUoyi&^VqYEJ*(&;ps%_i2? z*08X!kZ9{5={Zc&(w^juXEYk2*=!=4%|a9k1=Q<xq*5tlv)Neic^o^;>o{aQ9;4Ig zpwVbxdwUyVeSIChUJuvT*H~U&Mn0cMI-Q2+d2>I1nf2gEN{N2IkGHos^!t76?CfB3 za}#1P7+`O24=XDxs8*}Exw(Pw`<P57M%ri!u35Hzr!6j`D1zsC$Y!%B7K^A<DkzuB c7z_sZ4;?{fypp#~w*UYD07*qoM6N<$g2PLm#Q*>R literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_1_on.png b/src/gui/qt/images/dtmf_1_on.png new file mode 100644 index 0000000000000000000000000000000000000000..737e614cf153e1e6d2abdf6c2318bbefb54bd48b GIT binary patch literal 1441 zcmV;S1z!4zP)<h;3K|Lk000e1NJLTq001oj001lq1^@s6@kTK}00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?8ynWD6RiLM1ujWM zK~z}7y;)65a!nY%&NxRhIkwUyN+gN`7x65@Rm*7GABffw{il9M1TBK7U4ap{D3LHy z$&4iPc;-9{8J}^SFMHt~5YNYb?wPsn?|Zz9i;MW_=?S;Dw|IYl$M^R)q9}src>sVo zj=_iLdE<M}^Wb?N7-JL9RfE5ug^tgiNF)#h0kYXF%H=XvS64wBjRtORZqV=dk<aH5 z1OXC>1QLnFn2E^f{~Dg>A&Mdl1_ShZJ+#|xTwPruolb)`n@#-u{9t2a1G!ud^Yima zCX*A0@@o+-)h5JmM0(S((S%`$UayB%tA$#vhE}Tu`uX{Zd_Iptp@4;j1yD*sDV<ud zPL!_CXF*upd>DoZf&i&h3SVDeXf~UmolXbq>+8s5GDxLTQ@b`Ht3&9&qAR{jCX?`e zA8{OGd3hPHudkru3qpu?Qd#u6_bRk>YNawx`CC4G-$yc;#9%N0C4_(wGV!5Fyz)C0 zY9bByE-Ejh;-$Oio`h05LR$0^Hbhl}F9-nY^*SCN9`OA9jO*)boSvRe7_tipI<WXV z8it`0Gn>DS;~0;Rk2pR)MyXW7+uIx3?e?#XQpX<vq9_81;~0!Fi2pL`{Mtkp$1x5L z4$x>cP^na~v$HdWl8m@+F3w*@c#JgHXHgww-|XVbJkLWA1PFov=jZ26;+{oSM7yA( zq433vMk59ao3)>vomuTc7pUX~%g-2NV~0UhZpdZ#a&979y1ZFgRZMf51|bB*_kCyA zrb1B{bX3w%EndaPq>7BO5z?xUObm1=*>Vp4Of{Da+MI@{P*4RA{!`J~7NPPQItl8) z6VqWL1_oP{Q|Ya2OtY$yF8UdDTF2a!-I<Ka6dY7)CrZ&}@o^l3BoYbbVnuPusG5+{ z*?=k$QYB9=gAN7*V<P05;CP;gYPE`!lamRWy}dmEz|qkW_V@Rl1CGgqP)ey5N!R3w z(;XfjqFgR3rM9%Rgi592l+TzX3IJ3N1iE}y7gWSaf*`>5_O^C&@}hrJ8I5xf7j-Zd zxvDTei{Ew4amIdnI2>v#2Hn4{teVBBWZo(-BVSYQJygC{r8=evIZH-p(rbC%DfM8C zX%Uixg{$v1ZAxbovWqpfDTt1_YbNI6ZFFg^%SPofu3T*BsdURFlBp2XsgaDZP7;*T ze>!bzny7Ss7QI%r5o|nFKrqHYhr^+<T9zl$1p!+$)6tq@f(kH7DF|<YnF;_?i@}si z&gwl>h|8XgF{VyUZAN0tjZONj(s|LHn(}mBsgGTr3rae7XcE89)tS0dHc3*h+$zg8 z8I`FG?Amy7)oXqqMG*)glMzu@7U?!)i(E1gBE8(E&`C+AkD_RlFfqo!)kI{bnnc&f zvqdq}wax(L&G0qSFbtJQi`MGmicEE+P4p@?;q!`FC~r$s-}lD^GBcM$AW;G~I@<|? zYO^AL#u&md{AY-+{WYDKU7GE)_V#4k829p0sT4Y$4sy91c(=)<qo(lu+cvK5dr@7Y zD8k3b2j=GHMvJc3>nIkBqYz2RRHxFGleipHnA&BwDxWcie!q`Kqk+xMP0*E<72Mz7 z<L>Sb#bR+PGTG|5SsRG6o`ms5*J?F%yIo|nS<uDBMQm+t;qvkl)oK;FTn_1UdVHef za;o~<V%27p;u#_U?C$QOP$-PN$DcockV>Uctyb~!@`7%+3tl@;R1Abn^sh~ek`JF$ vO&{Blp6~m}WHMM=TSKW-La9`O@B8=*gTEC_twh@`00000NkvXXu0mjfgdU(L literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_2_off.png b/src/gui/qt/images/dtmf_2_off.png new file mode 100644 index 0000000000000000000000000000000000000000..6e8a44e7d7f87a785267c478e84e54795eba1987 GIT binary patch literal 2231 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 FV1mDmQOy7V literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_2_on.png b/src/gui/qt/images/dtmf_2_on.png new file mode 100644 index 0000000000000000000000000000000000000000..978fe76f592f570279a9a7d267d9595b23e68f7e GIT binary patch literal 2278 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 ABLDyZ literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_3_off.png b/src/gui/qt/images/dtmf_3_off.png new file mode 100644 index 0000000000000000000000000000000000000000..6688cadc488b61b25592a5edfc553e4dd309e95d GIT binary patch literal 2234 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 IM6N<$f;?(U0{{R3 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_3_on.png b/src/gui/qt/images/dtmf_3_on.png new file mode 100644 index 0000000000000000000000000000000000000000..28f1b655763540078018b971c8d8bad761e6bf57 GIT binary patch literal 2277 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 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_4_off.png b/src/gui/qt/images/dtmf_4_off.png new file mode 100644 index 0000000000000000000000000000000000000000..d37207a4b98c686cf6ea0c058edb59a08baf71cc GIT binary patch literal 2087 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 R38?@8002ovPDHLkV1i$O4!ZyV literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_4_on.png b/src/gui/qt/images/dtmf_4_on.png new file mode 100644 index 0000000000000000000000000000000000000000..1ef21959008f13919df13d48e9695013a84816d7 GIT binary patch literal 2110 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 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_5_off.png b/src/gui/qt/images/dtmf_5_off.png new file mode 100644 index 0000000000000000000000000000000000000000..48ce1373bf1970c0b711566f71ed08473b2ca6a4 GIT binary patch literal 1984 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 S5kO7=0000<MNUMnLSTXg715~x literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_5_on.png b/src/gui/qt/images/dtmf_5_on.png new file mode 100644 index 0000000000000000000000000000000000000000..40b08cb37d6e9cab1002c29e963acf51ec0126d7 GIT binary patch literal 2007 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 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_6_off.png b/src/gui/qt/images/dtmf_6_off.png new file mode 100644 index 0000000000000000000000000000000000000000..33667c242a61ecc99f97f2cda4ebd00065b4e750 GIT binary patch literal 2266 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 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_6_on.png b/src/gui/qt/images/dtmf_6_on.png new file mode 100644 index 0000000000000000000000000000000000000000..cc36556546babec6de6da07db5e03e4af759a63c GIT binary patch literal 2237 zcmV;u2txOXP)<h;3K|Lk000e1NJLTq001oj001lq1^@s6@kTK}00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?8$0d9Gi3k(2uevr zK~z}7wV7*dRB0K<f9Eo%wUlW{Vc2phHCzhigM?6mCO~WgZ6qSFn~jnsejpgs@PX7A z6Qf*Y*O*i`esD37lCZ?OVub8glG2H~%YsD#ce}9Lixhj?-sp80rtO(I=k>$%3};Ty zWoqJ^Oy<1jy*>Bm|GY=)?d=sE9Ua`heVc)S0VXFW(RCeJmJvcAgutswl7tWfNs<6O z=i2Axx}PLTn5K!MD1^gdB9RE&w{K_d+O?=%U0vL~d6TiRF^Y?eS+QaTs;Z(WO5h>? z&n8I{hGC%VI*CMr;o)I!-MWRUs;Hx*qdb59oOSEg5s5@7C@3Hl3T1I_HT$!r38xgD zOj=TN&T(qT>N{I9nIw@&uw=;+o;-QN)2B~S2L}f!Dk`G1w3Ki-Oehq}5N+SkOTG4Y zewtaxn7yA$r6?>cBtJi&SS-fK$O!7><Rq(Bts)!_Q&3Ql#j%rnOKSEegg};M&o$2V zK_=nsYnql3;_B6_85$Zw6+)1gmq#cRLQxb~NxC(=irxA_@4e<Z|E;E~Dw?K|N~KUu z)0`J6oTlJLp!3=Cb}z!6w(A#7tbI(=%vxgw2h~!o(}}ESYXdh1>`rALzjo~!jg5`; z_4NTzQ&U4#RTW#eZuN9*FJU;(F-;TI$-S5Aa_yfyd6L1wLC&8)Penxqu~>|jmKH`v zMivx4-6EF|A|3LC5SXSJm`J>w#=hqI_3J!(^oaKMcFN1kGw-XassM;aqd6xYuXm<t zqFO;b7iaO4Ho(=ZS2=q0DCOnlM5EE1GoV{|b)I3FMk<v`OInuYjL`?BWiLWHJ3AR0 z8)N6roisN$yRLUSp><}EFzlgKlBBexoeS*wKggafViqr648Z2io4Iu95{-?G^!N9( za^*_)@88dX0|(|s5I56s6PR;cwy5_CQ}%@7mRziUEEWTxwzd{s*SUQ8GWYJ?qo$^Y z3l}bM`t)hfFt`v$7eb)wy6(x5mj?WtasB%BT)cQO)3=`M>+9+0=wRc<jlMBED7gtC zP(z`RC&zAp#>?iz;V=Nlj~}PGxj9SqhYug7zP{d-05@~-%BVsJ6h%R{M-EH<UK01y zMny#h08>*_^R#2xyBm>S(Zb8|4Z}e8!wYWevL9d{tE{Y~xVV_6rlxrewY9YYuw%y# z-#voB)|?X}JM+7rbNJa?G#cg9sZ-R|)p6&}oebmS<KxuU*0Ou|ZYnD)=Mm|I1VJG% zlg9lP`C(nBSD!d>f}Wlp&YnF>MMVWgMMbo<w6JT}E*cvf=Ve5<ecjG;Ml;oJUw)a- z&%3S7nwy)ctE=PKv11u$Ja_I~CXIW=V!tft)>l<k_008t=+4Q6o$$ST_hw-aD?@t0 z+gvN13}6cK+8})32H5Q(&nq7LnL|*mnHBQfVz6Ib=O%S8+~QS8<QhHf^Ho2o1p%HQ zJmM$Og%-Z{CI_Wvw`}EiKrR5wD?R%qGdmr!RUdk(%xx^!V!=%tPSE9yUO{FggqSaB zKO6JAQt*<T8$9sRSkU!FrsT3q+N<QrrF!wpW?riIs_OmXv?NK$ZonmLv6$uFmDl;* zKRRe@`VH09)l?t;1)WnmPe1x|x?f$*yPpiC*P(O&%Ih@zvy;cSuB69b{VBJ*CtmEW zPw=<5&t=x0{{3GWPvQ%nEGf&fj66F#>zj!L8e#K4T>i-kZoG7ao`J_Se6xoWuYR4^ z?!LsQeSQ4>t>e6P;Vu&bkn%F~zd!R;y862L<9EjSS;IpTLLiAaO+Wq~KhJ-S$D=Wx zjdXD|^as9mu8D+4n6yiO?w&@TH|R7AC2k_W`4`?hx{cAkIO}%og{{A2xZyYq53^+3 zE{OLb^f{YL0H+#BoZ82;p)t08<43S)8HIq}-_H3@#<}ssuMz+E$Na178T(HD8t%SH z>%g=xW|t(1WHOm90^G7tmU<+Kg9WqPdeDXt0)1i}Ru<Cs;eBQSGZ6<#CY(2S5b$#8 zBJQ@dl9D7wlSvo`15lSmp!5huV;u~~Qb^JapGjek6fI)u63r8{TmPD-rJ<=|7`{#< z0m9H<*p(uINHJ?^LP>9E+Of#&BuVS8A|=3DD*?S%`1JFc%ss|z&u3hjdXA=qGG|yn z(=;>pGKOK0N~K;Dw)VknXOJ+30BqytoII_~&GbBhKnM_sx#1UwBS}a={+cgSw<<#Y zhaVG93ecx${orl*(i?oGRLc<R6rd&8yu7?LV6upD;?^wt5;mM6g(3VxvNC{HG`AMg z<k`X)!1DCm_|P-HeLqU<&>mj-)kvDEy>HMOJ;v07`@UIK2$7bwlUR#OixE?39DL^q z4Tm;l##g_59^>LGXmfM4wfjgt`7LD{m}ne)r;CO|8!~&SUpzqSPlwTj0AqstT{1s- z|8rvF<BX5TNWJ%6)XtBXuxZ;eTer$ZI&<cXShj2#B_$<TPU&}_<_De@I`0dGg(w)r z<I{mfh_34l4Gq!T+nap>xe&k;lnry4Hyw}XTol-?K+Vt3XL53q<;#}`Vqm`;d@nHX zhP89q&-rW^1``t#D2jp_i9~qt-~nsatU;D#6h-mH*11AdH#4zc(EELKa-Lxr1~W4= z3=9mgVZ#R0l9Cb<i3F{!t(29Ox!%|10^D<9z^}OQV#Lx?cXv05L?TUNdwaWRX=&lc zjT<DBNtP~Mn)NO5f0b^~x0PJJ^6I+I^z<|%Bk9n%XU`tCZQGXqP_$*s7DAyA4<A0H zyStnI{(h3lq;K@d#c^^i&AdJoX_`i1VIgH@Wo+8CiSqJtOw;7Q>*z)s+eJih00000 LNkvXXu0mjfOx9Fi literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_7_off.png b/src/gui/qt/images/dtmf_7_off.png new file mode 100644 index 0000000000000000000000000000000000000000..a401f432537fd4498cadf001cbd6ad65905bbcda GIT binary patch literal 2239 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 N002ovPDHLkV1gs@RQCV? literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_7_on.png b/src/gui/qt/images/dtmf_7_on.png new file mode 100644 index 0000000000000000000000000000000000000000..e6adb35e516c38b24193ceb3c5a4f40c13d52778 GIT binary patch literal 2311 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 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_8_off.png b/src/gui/qt/images/dtmf_8_off.png new file mode 100644 index 0000000000000000000000000000000000000000..4db35c37d7613a166808fd8e5854a9f163c5d674 GIT binary patch literal 2239 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 N002ovPDHLkV1kuQNCp4^ literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_8_on.png b/src/gui/qt/images/dtmf_8_on.png new file mode 100644 index 0000000000000000000000000000000000000000..50f0bf36beacbe9a30246ad0c4dd1aedc95e4570 GIT binary patch literal 2320 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 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_9_off.png b/src/gui/qt/images/dtmf_9_off.png new file mode 100644 index 0000000000000000000000000000000000000000..8a678a4c63eab850e5cebeebc0fa1f34966eb078 GIT binary patch literal 2570 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 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_9_on.png b/src/gui/qt/images/dtmf_9_on.png new file mode 100644 index 0000000000000000000000000000000000000000..12e4c1a11c756f793080a0ac7ae433376918fe91 GIT binary patch literal 2639 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 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_close_off.png b/src/gui/qt/images/dtmf_close_off.png new file mode 100644 index 0000000000000000000000000000000000000000..85006d153f47c13b06938e1fdd81544bbac0649e GIT binary patch literal 778 zcmV+l1NHogP)<h;3K|Lk000e1NJLTq000gE000jN1^@s6)D-@700006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?8zcUxt1|!q0+&fd zK~yNuHIiL#+f)ER&%M63<HR3n+9a)}(GSMD239pitKebFU{COXG$D|9;onVrL_DsU zIu(Hs18J@3I*1uT(3YW;#BQ^?v0Yyt#?Bu&I?@r{ZdU_np#S@Gc6WE#-+#ulUwfEB z@#fV<S}QG9S67)|m`5N05DzvtwGe_wTU&g){S8ZRTxPx9ra3nUXkPsNf+st>Jpc0# zI=4Td)9C=9bW!kVdz-KC-{<Z}A9MT8hb*qF5LBxOAvld=T1!{h-g?Ma_wG?>P3P7v zRKMTn`^_$Qu3ck&c9w?Ln1cb6;SjAsUR==B1?}b><5r6wx(`{HpGSpZ$mQgmmSJJ< z{mgi9NE-P6w`dBj$>US(!H{LC7@Z}Ay&mF|n>Y1Fu31(Ez7mwH9?JKSri}oKd_oqF zNk%cFToV=sPYj8Yy^u@GD^$&#a!{dEt5FI949fyQrx_E=!7@NaFF8vkJ7Eviv@EJ7 z_;XF%z{9CcW4k`4ZG(V|JR?0hA+b$NCnh>PrmjrXOuLPlpWxK0c+)jpe+uRK81^e; zk!IwEfl>yAl$giI%(T~#vl};fnM|-MKILEv+jCKF1?hVT-^1`+Y(Jpn2Uu>v<UFOh zaRa$<{W^zbpYd6OEV<wZNY{l@8Ch`=ZUyc6sIp6Pp759BvADK|oUYet-2IH5r+fSx z4N0XzZrM<F(2hf4mq-nRXne{~d;2s#{hWHEfr_Gtx8GgosT4eT{2fc9A(!5|%G699 z!!#KEGvM&IkbWHFe(@#mwAVR0IzqgjywPZoXBm4xK4u*LLK+<dP?>IGEnZ>uz4x&! zi-UuMSCe<UU9GhSz;PUEwHlR51t}!}S(cF`32__~MG>$04*~f7!;aGHga7~l07*qo IM6N<$f>E$wWB>pF literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_close_on.png b/src/gui/qt/images/dtmf_close_on.png new file mode 100644 index 0000000000000000000000000000000000000000..0a962cb18c1178e8012a8d859ad6489a8e6bd017 GIT binary patch literal 806 zcmV+>1KIqEP)<h;3K|Lk000e1NJLTq000gE000jN1^@s6)D-@700006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?8ZwOox_|%x0<%d( zK~yNuHPT;CQ)d8x@#j7N+CzbsLQmVE(xQTNv+Jp1GzQA%)x0n<%a-hBU&6&3Kf$j2 z4kpGsml<Osbr}2;BWeUibUkX9Nx`LB&Vj<IZ8`5QoX<CSlAkD-%Mw5W)wge0T3TXd z<s~ows-O#v{bN~j6FKtvJR_MA1OfnYb9Pn=A-Fv^$G!PGjPBb@(Y8sZ(}3jt`g@)( zF7f7{zbVapOQ}=>K$Ahh?fH5BxN?QF-=AjY)OTbjCWyvj2qD<=JaVH4n4i1F@0TwV zNJ(jW8m(Hb@?f^isY8b-rczi^qSxzuYBZ1%l-*sDGQduzY36b~EZ-tCGJ@tf4txC; zIn^Mv{G4XJMmyU7|BED$lCHN!sNP^)(b(AWaVizWnW-sxtScGU0{S&U5DD|Pv&(QS zh5%}wOIFiRn>%cDB~GC7R8`QFio@{u1Tno!Pc%Y94{`O$GxiL4)Vxh(5O8kNCK}e! z+--K+3X4t!Eom6Ubm&hf>5cZ0jt_FFc!cA>T?Am^!a3TToA`~7=%$BT`#?g|QHE?A zJp^VvMxT{n6NU5FZcxZ(C}cDIdi6T4gg(n693Mar!H``*OC6hJ`_CH~k$!rj1FY26 z$)r<E+j%5#ckwyvtu}iGQ~0e8pIU8_CnwP|hY#aCxX1n-A1mC;)Z|fSO4CT)K&T2O z`x}C7pRViTx8Cv2>|?A@Kp9LVu+IL-;)`WIx((WjO4kTMkBKx*f>4;Ys^T`cc)YxV z^}|mjEDOzbUA{U}<b@)*xp1G+jRwO9#~2t&pz10c|JJF!cBpzDy+8lL*LIP$wKc>S z<d$X8?Q~dvv_R8&Mce%VKx8n9kv%~E_z4WdV0Cr%GxBn|ETxnHn5IcQ9w!ospePCe kolXbe_whUr*LC^Qf0@)7b7<U1U;qFB07*qoM6N<$g4FhM)c^nh literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_main.png b/src/gui/qt/images/dtmf_main.png new file mode 100644 index 0000000000000000000000000000000000000000..37086908a03304b29e5de1e638f9e16e16b932ea GIT binary patch literal 14015 zcma*OcTf}W7dHx`s1zmAi&4lI>AeYrA_PK5Iw6465Sl1OdJ}<ALzmv05TpeVrAQAY z^j@WR=|vH^`Q3T%pLgcno!y<;nVosg?s?90K4l|bYe6Z=n8=8Th$vN6Ai9KWKH->q zKuS3OUQ&BPxR6?@Lm@=B|J!q$OA-lp9==n7xe*bOQ~&QECQ8p_Al$s~uBxeYf1HAj zh*^xx4`@Y1^qfc)@=D)pcEaDg%GtwXLuzx+_xI_G`{v~j0h`mK)quQy;^^sgqW22Y z4jPJcnogra4;Pq7p0bn1EOfs%nSGGJz<Sq;GZEV+&!Gg3DOw*c?B7XHlPILoeIByh z_G2~e3f-~jvb1Ej3t#%X@1K(l_t;(V+^D^nb-bKxXqiaEBl55Rtxw%roo7-9>OZOg zCd@d!$kKvhp6$z?dTrbk5A}Lq*UNc&&tt4jWxIW2<~M85z1~izb+K=O$<#T1`QC?8 z+te-B4NKX4bWt^Rb?hN+^4+V|0|*ghbe5Lgl>gbS<Ao!~#NR+~;StC2Tg|1)x&8JF z6}j>czJHjuj@GNOH?}v3gQ?#cS|!D=3ei(<wGYZ~$KOc%N1tc@bzXRD6qz5_)ujY8 zH&0o1=N$4KJdrA9U3}m3v=)!oguQw5d4JzIO{+wDk%*DZ_hUuRI3=H0@#&j=k-~0- z%#twMuJ^XJZV2Yhf7`u$+CaC_y2Ll0L}xwrVHV9T=M204yBDk-6VanS3&-{5l^lfN z>FDWgZ*Q(^YHHXxa{OHFKC=d#mA}byc6RQaoi$m%x67e<qJn!3RvZV@Tcal3e42rx zkb`T?Q0AhM1f(AhrPL8wITqjToLmy|&-qS2#vgm?G1e-kSl$}$*?R81+d!+N!?>De zmp$`^;wYu{n{B-@Z{Nm7adeOMS!W?IN+|B{wFkP3!Kz`7(zo-kDugs#_wN4HBxQl$ zvwb$r=8uTyDN|~cH8(z-dybXM%>fQ9X9rH9Gk-m+n>f{2N6E{lc6<B!A}L;wNNyTz zx|0FoN6uA9$J!og8{aVZ?l*x)`uXBneH%+@(?{+FgG<gBM^_V=kURd^DyCjQMO;?E zi(RpJXq~H^jZ^yl32;8*+xAjMMn+HUYWUZi;k|8bufP1C9YbHN0qPP>nIdS@>lE_+ znvy@;hn0pR1U}my&x)QF=fO@8oT9#AHAlZL){sXpy+>E+%oG)}=^69sYAS~J%vkKp za+}}myzg)AZ#wz`J&0d9Qb&J&+rTrnt&a~JeHU+tGPE_2(=ieI496Ioi%_mh2SSf4 zh88$4u5psbdIEmO)<d#vZ<>~0c%L>_em>Fit?_9?(#ILqNrc3SuWz`$0U7;UDOu0h z%%QLZ?C0B1jtDc5KUIw~EdQoPIe(nJZmsSMXF4xpaEY-kpZ?g$MEy~$;7q}RnSqh) zPtRiD^T3OqR-PQ+i7&^AxBu<}(s27znV`?+w_~myZ)9F67XU=v`=zJc#!lBhNM)HV z_g<hBw_D`b?lq@Tge#Wq*vjOe!(LBhW^?GzKR<|W+IE-9k_+I~H3o);N~bfh9e;Dy z$M-}dxXIDflGqxysHiB{+s|@r^lxr8{!H`Ts%E?8zLWWCi?Ww>Hpl^<va$&ShYIKR z`>mjB$OevP^Pz!tSFnq>Uw#<s7`!iOzu32iA*66*uMJyb?_D~|?Fm4r<Li+Q29~mx z{@c%?udd&(_wIh+5YCDih-{%aXx2188I()%H1#k47scUTw&@|I_-855ugLVWjadn@ z7ISceZMv!uhzmUk)LXoYbX<$hkmKK!b@sRkSiM>+BfqT$Z%@gwmMon~A3HY4sq;(j zqMB|#K1QK%jsfeQ>;ClFto>tOaF?=w2Cf8>m%eQ?pFH-P6u>=ezTI5Q0j4s~%FQ2b zy8g)!NESfh>^GYX3|;6Y-3?i<0|KF?>dT3LA7*R3D2`7WQkTi!P!dBzPcXB-UP|%n zdC-FRXk`#rUn1;9Eap}2j($0BbNkPeZ<B6niW+*TEMNfdLM(2?x8=FfzezFIbK6z{ z`pmzbPb;q$G6MDZ|NW|&zchN2Sb{!?Q#U^o|Ffpr&@0e-3SCbcYhi8m8IxG!SiD{x zP19Omb_r0HJwGey%gOo1ma){N*AlQWas0Q{|A*=ApIg?egDXexg*kzwnLN4VCBHKf zi1?K4c2Z6vT;Ojh3qzoh>`_@xeEFbXn(5Jw9d56!vaf&1?@QB7%~GPkzy6ZmkU+QE zrfs@-ksc5u1*!f-1`}K2%DBMRcMhI0ic={}kB!XAyO&8vUc3vTq4!|M#&P+aWlQFj z4XX`v`@c(V#5zvqzn{Zf?=;W#`&mh4scm<0Bt}H{tnM^4eOE4sCnO`|qi|sc3L8NN z6+774*CA6-AU7Mw(?t$A9A39{(Cd8gLn-^H@(pi!#$y~whyQUx4%MI0hE@<Wvy9~R zKXS;|R>PJLw_#3B^8&ZmA*~<*zs>UX!}IS>lrPv^<LA#K0tJTrN2%94^_HF+HEXVI zIJUAqrX&^Kl2I~0irnm{HYyh0KS&Hb)`+jGb57HEaU9rs3IlkD|7&j?N?gCG$vn-U z>h;y4Z9EVv;Cu@C1DAuYAGEiBJiWR$Yb8vKo&D>8H+^pAx7V+7Zu7x9XNLo)aK_8- zlK_gJnTAy<4cM{`VQ8jvMAKe#P6D}9PIBN??8(}%gIjIy4!6ex2TR}Kzp3I|uVyEX zzgFUx4t_muejRWbA8u3M#LLlg>EZg-ltUtL7vSBC_E-P<O?^$TQbsA|vl3mTX1v|A zl<TOdn#<`|{>NkH{Kv_*u)VWFiOcMNGd*&=2S1LYj%#X%QhX1d{K?yaS44r`45Y@s zXguRFBo&D#N&KVK<<luTVDc_v%H%Yfi_a8%85Ug5t!Qdul2BB{&K3EQEY#4KheH(p zhm(BC*oLI2g$@w!E0MD1?c!7U?_9>S@5f+ZD9iWle%DFWD7OCa^&W`LYRu>U2^X)) z!6;j)Wc$r8$Hh_Fi6?U2&ETs)5~$3pIoH0n2#pu(zJrBu#zb7RXW*-~U+NIZ+O6M) zmG_dw8=i)RfKZln{Muyr+vHuF8<`g%K>XnR$pC_F^m9?HN{PgU`_|o(s)$epucv4f zs|o$9w@ChGtIDZFD>t`V*DLe)LC+~Fj9*13t5izzy<TxIP9r>f-wu?9|9(6g^)=yQ z{#LDVtwbON9dKiPoKO9zPhH?v_0Og4L9(3hIdm;EQ9JHvBz*m*j@^4U;y$6`G*<p& zj7Q%<|KPIN4sJTe){SFYwAXI0<NeNg1d=40F8^cvcTK-Os~z!gFIgaw767}t$zr=7 zUQ;a@H`4qjW%uSYu8rQg*GW9FV@TFu?dvVKM8I}VFLO?ye9Lv?<Nhl`d0EBuKANQ7 zq4hnCxmP9;>|(5_E%0c+oqMbzf9c@h5LL>KAYL?-jyb{@8vNGj$J{jhnSRQFFc@sy z(_X`cZ1#4^omn=X3j`WupY#zDrK5a(sd<0G^^f(C_YC_~Z+K3P%Z)5YCfnyMKG#1L z^u7H#b-IjwUc%JzcDSXbfBcfyn+G(2_}ZmE4;!~m6@{5%*1R|W(Mz6%sjt`B`Dv_; zldnlEx&{CHdw-E%?u{wWvs)vVc=UDnkM++1>lLmssHR{4qSo6*ZcJ_vFGZqA4}5*- zi>Cgl<P@AWG47;p0?@2X3*L_c*OQF~AF;fw>IXSABhaK9LPqIvz&QE|euhdVWZ2De z3d_@I+xPDcQa;l=9Gt|N`X9qwFT&*no=IJ7Pq_VV+FrsrzLkWxcr0Yto^KThZ&l!K zk{7jHL>E&En5k!417XEuUz~t4+|3gtqX&c90~RNxPG}$3Uq8w2qURirV27G|ObpC_ zcN@^kAQ&8;K{A^np$<1SM4tQLaY6Y_ulh*}-+iLXj=TT$_raO1ZIJ+*2xE-$g#Xg* z4(0LEn&_VpkpLU0rNp!>+woaJjbs|`X2O6A`&*$w;OgSp)ooue33@>;aHwb^WK?3d zfES(_`gZzaxNOA-{c_Y%IlE?VfAD>$)PD&~ko3E77Vz2;m`<CyOYM_Ei0*y&xpzyw z$M77mQT7kf<n7bx)$HT^H;Fu7XF2>qIsKMBkZF+=&!_|-)!mNsIJ;jA&*gpn{mrDN zOx<Fb(q%>!KQZ*X8|24n|4rj<vBug)FhGEca8P%C8PNMl(ip5OvOC?9Vx~M@Ofj0u zdgRJ5ukmgWUs<A(j|G>0wx?p{ff)nWGb-=S<15xD;h#5^RUS8r3Rdn+{CX0F?ZYmD zZwi!rhTH3V<ZIXzb!c>X`T6@sN1r$y!CaEU7Efb%iyPJfGeGxG3>mV@1!ZDFkPnEi zJ0XC6lMMQ@hGncy@M)(A#Xb`G^_il;sY&y}cPLAYvaXYplS;!}GGQ&5uBd8H2nCr; zzbOogI4!9g+VFpd_L_4?u<sK)a*Xshh>j|#frqP<^kI%+rHuAFXS$p{<q2Yn*g^X? zLo<||@rHuOYB}{YK=_Do?)MSnFCRAnGi7t>uo2gm)57Q4$WVjF?_!BYAGAaq%jwv4 zInKc{HE1;ZPbT+26iv4Vwz7b|UPtB&S~8-aT31(8lraWRat3nu78~Lelz-ELQhFd= zYFe?#(3<(O8IewvSO&|f=S;>nFNy~a%7+I|)7|V0Q`;_0FO>^|?KJ?EdTW%rgx4TS z9IjA&&)oOg+y+OtSw(4u;SkPk9z=>JR8;VB?VPfS+gU|aJ5{&0D>_A~pA>qa$%yxV z2Kg5n_qG9Gm)&~H!>+FmPM!<&KCw>IFR($=Pcj$8ePJXiw(LUQqE3I-c!@@%h5S07 z*WA=S3V7tVdWI-4d%`1dipU%JbMak}j^E^<Z`|eJ;>zu^c<G>AGT*?KO;Hgjgx@!Q zNWJTD{s6ETp{N(Zd-T!r&iWdPX?_(S;}}Z3x{SHP(B+6F9he!XZ}Pq=nVy|3WB5Lj zUCH5>GzYVEh49!YyJ@&D+aH9?W??+7DO0oV*_Rtftf5k*?!w<sz3*(Z5Da&5UBfkP z7ItXFx8E~p9vNn_hvmnu%A_oBDXCIOuH6r#wPt-HxhdDzQY{;(Gbn=u0u1WRTf$uh zc604XLn0rNUntH>4s4FgdYXvAt&0pho*Beu(<@PIHSdWPzz_$L=63AYnMzOF?Eaue zh<#64CZB^ZN$Y?zHD8m%g$_0KQ}|1aEtT)3hap5C4ZHsYnt81r8NW#E%{&!kd6WmW z=>ey`4`NZc%Om+DFBs-se6i49hNiW&qKs!R^O+T+3yLk?1|M|$g{w#<Og{M^4qRWi zg~4F<_lD2Q5a`n&a2k}PKUq+f+GU8U*@``@2gfR7%%%R+vo?|z;)AR;uI5kSjGf+g z-}qvgMH+_C1#2^8t<?UV0fx~B+Xqm|EkfY2P@8f@lCQ|97qIlHJ#h_Rzk^qqti{ta z6diNVF{-o%j|aG|X;TRv#IqWcoMwOaQ4!q<LYe|L)aQUB1<68LY=E@6H#;M*w}#jH zriTYsQ0BjpXSI5O7lplBXP-wrRcNgX*feykc+1OZkKXd~+O4PSP&z+`vOEgcO>%we z^m~&r#p6lAXqOJUG`OwN>bIsVWQ}$fc_b86pORR=4FGKPeTdw-mF@O;S?t|DTI?!{ zmH9b6wuMlrHFzM@$PHh6KGa240(}p0mv+#0_@W{TwTa|?Aqp4N?uGNI<>l+A4<1vc zv>6XWZ4m72Kb0wQC#8}$#KkYIrUmFu*xAm?L;cCeq2M;0Au(RWSGOBjoVJ207*UD* zzCzQ!Kb-|Ktd#U@zQ+Vt5_uMXo|)``Twv6sh=jQW-;Kspp(vmypSDlLoT!)MO1YI6 zQ@6$7^oIAAs$Qcu9*!l(8c%DUV~}x!M?vqf;IW+-_F-)_Jh;T?qlzYiUdmlWc*&Pm zYyQvu^t6s9mNPPkonCPclm_*rMKLUxuSR}3GByuqm&+Y0Z~k!Y-@iK0H|h<<s3PkT zE^%Ph>smTTM@QO}v2&U?NeqsZ%0k9D_xnXF(whT*tn2VGbnb{E^#aTVrgfuZYFuJ_ zXx{w2uo0FdMT&G9yJUBWbUyG4DSPXZndA%*hEP;2;Ri8D4xTKh(<)`dlt;nK8g|`2 zu?Bb78S?Kf=}YD(cN7`3?1na#F)~^?bUHtt-t_8}LRMD4Q|qvB?NrJ8lyEifW<n#4 zR_^{O%qzkn0mTsQs|=2Q@~6%VRyvk>Y;pEhae30jBgIE~h$=0U{vljAi?%Xy@CXI? zR=%wrOj<s()*NFl!Xq;Z*$)0gp%Eo;zr}tQ)(fk#HkiWY78r<_M6{iz^HA<5JWd(B z<JhHUg9u&d>S+lu@pp8v*z>6pbvdF-EV*M~Sjotzd`c0&zh<0IBFU+6oth_(7#tuY zAO0L!-DM#dN1#oT{X@R9<J7&n$mTqbXx;z@8Ck{F-e!-!gOtY<(Q@nsHJ>w?f9*D0 z*rVg3yS0f-_F)oYim?F$hZ@Lu1q2!tqHVk8-BceV`}mu`>-5}P50iATNO@!x3&kE+ z)6iPjTl6F{WF(%X)DGTDZ1M@iS-g#AHF?S2af&EI?7DpTX%2eqct1-B(y3gHBTYG~ zXI1aPGV&>oOUd(&G$a&74gUmhTcIuY4ayp$I%bAlmh+Kz?mq904crKkI4oBmM%~M= z6|FHvGyIYBF{MqHQH1y!QuY7$-5>}ce_XbKL=G`#TTS%G%{qRfwDz!@c9=@6E4S`y z^feS^N;f#Qr*~|an~>19U*@2PMq~Tf_Lz%Z%Gnn%vTVYJJW_%NBEsgKaoTP!pQyZ) zLc4w))oUraLFoRgL{&G6@R%<H*kvG1I)$6N>rD@S+TGjRT^#>T^g4E{uJg5})kAJ2 zeVl6~Edug$42l6;eZPZ;!-K*34R)cSE={2_$Yt%amr;ir2nT>S#3fpkG7a#Oow9Ax zuja#>|3nMgJA`vt{2?)59Xg(nHj4{Wk#w<MGZ#yPG@wp0s|>OND^=L;<3*Ze_pVc= z+KTwZ-aNTo;)~r`SjqHzU6*@IWcbn_Az)<XRE80L-P~GJv=^S}XpmH@P{I5Xj;YEh zVR+9j@aA+JGyBm6ET8%`Kw&KsSt)t;Hsuw3T&R30CR1OMk%-v2A`*+L*4bwsKfR!N z&Y=C|DXj(hS8;H@L}G%X4~j;S@JX|1qZpVQFR=%3Ol9Tg8jBgH|7A5H$}b8-%yxXC z^93?I=J)!J0b+D@b|@V+dR-xF1rgoo38MY8vor75Z{NSqe(UOyf3_v7?y3C4tfOT5 zU5~pVwx_`!MR$@Gn%WnKsJmq=d<d~XVK0r_d-x|cby!HSW3))~wq@rk=wc7GWsQ`W z<m(u*lL5oqXeQ&nVXbmIZQZv5lW;E}?Ux8|5gtvXMS5EbWpX|XJD*W5>t$FkKqhY5 zk-WHzVr)fS=5BvWZ>S4HZ#-u)<1&v4x21{b5$-{H9@2cG4^R;KWZPJgUER(Azvu%W zqKYSG6>x~xZf4=1Shf`XM!=yNuvcNF74p)+1dwx;3&XbLsSjq+TFJ-Q%q-de>O8b4 zYQ`V$w97lXqS*fgbcptB6|<;(N*;5XTj45yNRe?+Q!C`lWyV6hF|t%Jf|TuQXl&$C z()qbxXtD)i9R_tf?9uI?4f_K_x~;t&>1nLk;d~ACe^8B*Z0WFw8f)+|1X9@R2-A9z z*y#Sgb*Zvjm2ZBKBr<JyZ&}4;dU8?1==;l$cb;dCd`xm>hrVw0sw8&S_wv$ksho=L zrpFG|f}l1JDp350btB-Xke{|L=Sp*3J#^9|VvXjpC<;Ju8!+uvxq};BxG&S};$afU zX>26h!9V)M-oh17K6N{lR)wq>8D1r>wxSVn&_m6l>GrC)EBw>=NH1Q;2gw5+uhJ@K zY9QUKu>Lp=L07jP+gq4d)?=9JR7Luulzs7Zu+NNQD9%@2K!8qeDqYTbw#pSLqt$;{ z3BV5IM}^o6bc&}@jk^j%xDb`|h$o>{6M|6oSW(2Yw$*eR^W~fi*5deO5n-J9ubEk8 za;Y4i23979L^k(<Qp~IEqlWG%kAx4;dqRZ7@w9V6E^HsQoZJs_&s6Nf_zdGL*HMDi ze6lH+ydxe@l~}=$Bg})udlgtAt;i;ij4<R``V5OumR<d);W}z-Z&A|WdWsQ85n*Nq z3`>HJyZjdgG4Oit1>0ZWNb9_>;dL)0JeP;enb^n<W>rrqM#^;=i5R>ma2i@`Q0d#r zuJ%HP*^3Ga9ch(4^MnVn-{?usCw<7BX~unI$I4F2`fytD$W(+BkK~Co?sb!a1CZ%g z-KDPL{Oqhl{o)<fSjZn#ywyE}THrH)w^rq^8X{*jX*Vv?_yWeJ);RH1Y0g1c%yB6T z?_Dys?T1if=D=sID5fUXJ=Eth#FW$Nbm+>rd>IWfz+mgLM1{NTDyoJrQ9#T`g@7?G z*~$*xR-(SZ{;1|*^PsK;hUpOdEZC4G)&(<2CXzce+&P==ILJsl92xU>7eeezInYog zH{NUs{?5T|pi1xJ<TUWd;uCaS>mzM?{PCT{A*7zyWHi<Qf?Wo{<fWgaUwkB`qr^)B z0cZV;l+K?#3|9*uK%HtT8AHd#jdFzyMBtdU^Ypag0iszQd6N?q7ytBKs0{<8kz)UC zgRc|)n?{c^)hGcw&9`Hra?ZrFPG!T0Sd>ELrVjSd!2`@7|6_X~a)R0p>?dX+m!)N| zcv^a9IMIi_98URo`XP$p$5c?g2Zg9?eu{`Na3pc7YD0~|Pk?*8_Y<O@%gb%n<D2u; z#urm2h7}rz3BfyUa~4a2h4&{x4x?RkxmnV^2-drR+|+%Hpj`9|Dl&Y0*Yc0Bl5+*2 z`iE^n3(D&rPuMt#Rsj_khfiGZW<Xldw1C&K$lx{Sv-D=#wyky^^m`r8v&Ntg`jpXp zhWSR0v0)#ys#i3RCOoSIC9OVzgJ}FlgsjS^Os$+Cl)TM>Qdv6*Ag15lzxB=qU-k3& zketsx2v$};<WybUAi7JtPQ$a9`eo{7tZ*MATlFFM`BRAUGr%&cRByGqvA@TNO~brB z>MK8*W6OTh*pV|8@KHR9Rsb69(`hO{m$70kN*(X@MA)wzp8t_&7B;gE=+_C(<W9U+ z*xH$Df@|FmPaf(|E~@4K&&F$Hc>a8Yt2=HE2ViU(wOY~-GrrMbvK|ldN&ux){g`sL zcSD4xby-Hzy2n>FGFi<UbA|M*jfmm_q-i2r4&D%L*G`Z#;VG?IN2+_}*`Z`4ALP}1 z-)O%~5`xq_oV!9!U2L8VIkr`2(O1?!(Ydg5h3pIAgbG75&ZX9^>FMY;qB`j5>6e52 zf1B1C3FhvXqyUhL#@SFCDM<~_2aNd!DuO3K4Lf#E{h(xiWgq}A1|1cmWT*tMSO}(4 zQ!~c_8E8qnLB*DfA?VlNtm~ZfCE4I&wLemutF`)H?{phYO&|IEFyTCV003?W^W}=7 zjT!Sx&?ur!6cYoeeQjM5#r~U?XMjvJ3FN>uo6c&IXEJva>#9f|@M=~<W9#C(^xnpo zt&h+8cMTmZaQPs`od+PN?}wZBC2L*5Dv!;D+D&tTuktCy1nZ@3Uirl3nSE_gvA2je zd|tcQE<%P4h+Y6E4~mIAW!A?CiY%VpPAyXxay(6DiP%8##^Q#54!5M>e8>-0zWCr5 z-ZpUSQ>6uOW03CtkHHALux8EsC{#aYrtVWp>JY-?wWxn5F6jDbn)@e%*4!@N&V`X1 zesLgj%6gDh#;fa<7P6kkx?&S5Eif|dH1f0Q^)w`9Fp;JHGNkknX?-t!5?01+6$;wm z?l$?Bwdp_X#-OOcT}!bYyxnAs))d2{H+{&<uSRH~r_Wi6eOLCMVP%I15F3xjOU4>6 zfxFtDW(Nyq4}cT};rFJ?(%O{f7P*5IGJ7O!IBmB*FBoR&{^bi{M;14WN4vhT5+syH zC<_Itfo#W%i_&knFX<rQdx0_p-P1!ADifn%A;@_rOz*?2TgBqn5>0BIXxmS@U`34b zy}qS+%^a?|Spw-WEeXsS7GZFNn#<^e+FqltaFP7>uR|rcgTz}UoR8{~L2N2q!kM=I zOKJl$x-1Y;>`Xi8K6Jd@k!Bd-VJ4cYauTF@e~)p5EeWLDP3&5237JOeFWZloUZOO+ z1!l_98oy6d_3}=|{<f;`%t;@>ARCQrKHT+COI>9m&H;sWCrGh<Lka=W6J?UKj`hDD zi9;cL9jH|4c9Q0s+OEA3bG^AaOcAffgWAHVw8K~ve-&q5=oRT%dI810nIzk4*;oio zmU9FZHN&OS6-73a@!EA<o-chtvV>0$n^}h=zIB}ZKOUJca`bgBX)2-o>74Shku6r< z-i_%n%gZ41O%hrj`)Ml*+Wl7}CVnPQo)K@Mdp_vWwN#gl(O5;4P706WaIg7zllE;( zdTd^@3|?T2d4^wm<~{W5Ah0PHe2(;h0vf<JM$qD$X98oUV9m?SZ4zHA6^aLoq<+@t z>ASmpuAM_^R-y5}V{b1$i33v0WyDK-AhnY~nE*o9F}EeQ>2CeH75ouY%-6E~?pq=$ zLN#14G`Ozm$6E%J#ZNDYyHMeeONPs^FYR^BY)o!Y>C5<{INsbWYt-Ie)I^1voSw|H zhD8pUY`RugOG`^&y83yHIJZTcgyEwEb1q<4tLg-XeP^-MftgSXl^9_zZ49&K7<t9A zx)jfoan>eT(YgN>GO?GrUq(rUR|vzvk?KQOt&5`4tcn6gyz^#uF}YT(YSCv3;_6Ar z5P!Yf?BrBmLbbjBHR6L=YOnm=O2QH}^D%@~?71R@uL(Cv?A&3LxL-&SyJdinPKW;a z=7Z&oTuFUx$4scN?B#6|13ppnkJJ-mKN<+yiwg1>4R9I8Nmwd~sHY<xP>p#o=@-rB zF0x%lH7=<spU(tLWB}`Q$}<v7t=viPh=}Oq|K|nZO6K|?nmNKG$$49GK#zR~;qja! z-?l2h^EMqMtY7~i)B4(M-w`qQCi_*sSfg_s5IneQ&i}8v^FCM}POWOCP`UAHCoejU zZ{)iWFczsqj>RRIB|0)%iGd9sO;0J-t~*bU5cA{=KX}w=AmVUjuaHAwJ+~_cw`iFN zKhuqR+px<&UC({+SF(48I|!UVRXcfX>KK|a;j*Me!c%g|5GJ0$j{uu6XC>oko~1*^ zqWetN%e@ylw^<W9l-!!IFOOX%!qBK<VwsQzUG{!hXcR3Ei-|IGFQA|>yqN-z)F%pF z*PQriEH7<q-%$4w%su|)2qe=Bz%$Y)2?-e1H#G1l+B_&jvE*&f{<CJFwUF`V-wqD8 zOU<sLBXc|d<~1SJF68F3^<em`D7HTfkAZ|wELw(_#3g0X)ys$pA`nt)q)M-8)Jaav zjSAdg9E05A`M~&4msHzdoa4UDdxR;*Gv13dD%kv82PNSAu)y$6e#WP{IA!n0RfuJJ z{5MyX$Jwt-jM(9T$P||UX>9?m+D3T8jwR_fpnpI4AI&lZ&*ue4*?g#vg^6c2^n_x> zTFaOA9YK0l{09U@*t6(|AuHsg2FQI6wI2C}=$r7hE18jgQWbNh1bhi%ExHeJz}XHN zuUSrtz<@fdN*e=W@O#<~b6IGz=dxDt4!x20x|O5#(-In~_&-NwH(Q+iwTC_A6{R5^ z`j`P-l@DHJy`)#J_uc^586n_&`WnUx`5{ovRXQUYhvlj>mlXD@NA>EESc?Z$J6Jfs z`KiNtYesUeQp+Ut#<<J48|0%zF<bk@J76&Bc^`mLe(nxN#tL(8UF~PgG6EmZ4nuU# zYcKuCev+$SIJP|?hV3sFp(dNtjmAI310kPYoV(J6!z(TMF!SVjgQzFv1}fNlNYE%m zU#R}(+wwck-QC^48(efy8+!{1*`D+CX8xh0yV$yYW8ik1ND>lh+wK#~%0?2&`|s#i zsoJ*XOP1eT7(ogO0XrLt>W8tVGCgBZn+bdqOSL@`QEr8Z6u_gKor&mjV+;=+z7=@N zS))AUeF>XvZN7&g7)@J|UJ<L}uE~Flnj8=ni7lgjyuBI^5d@j-(Sn!|{XZor5Jqxe zC8Ii;#q*5_?9?PuG~EcldgL|Lp2L!-<t|N~UT{dsoZh^`)5lcvLC3MbMoiTj5tJPa z!#GH$Tl+-yH6J>9L-6k^(vo9hDE+<qsKp~ujlKqM%vQe*34?rp3Pv+H>f~Tpgmh`4 zhd7mqy^)`o-w{e}W1kLZzI5hue&Bxu{c#}rtt0*Kn3k{=aRXQT+6ZpAPi!}U?*0Hw zW4!Ycga1mv(xldawD^~teX5M&I$~NT*OqIj(yo%wmr?zj1iFamrK0j7#f&4&Cz2-p zNSIHSZV-iBf=o+Dy5Y^E1oHFt*FV4eDO*zeM5t4|Yrbwcx=Kla!-fKImd>au`C*qj zk{h$hht`I#7HYub@UR~XzXt~+jclGjQJ@)){hv)>x5jyUb+ipc8I6!t>;z3x3fCM$ zPaK$bm8_8>KQ4K#_^ghMl}J0FHUgMP2Ka9UMPU5VCk*e?xfN@Ll1ZPFU(dpHi`i%F z88Fnq)KEFh>yq#vN~C)_%V{;PqR1YQgJ5>nHijThOHw*nS`r@vn(xX;OcA;xmt$=a z3iT^xo{yLno^UjZK$Xypnuu8HG>Bqq#<uq!{NQY`rtET{6^?$IqMu>@X(Ol^fm%#A z4ST-K*qD5h3lu0zcQf$=C_<DIe7O0BtPQu7qiE3wsTm+2N7ppN!Y_II74j!wHnv7# zd3WZ5J0tjPOnALAJMZDr70Yb(coXB8qgD)KjHKYLa2PI{3!>n*?eFQt5%W`m?xvel zrmFdk=p}Hyy}Fxz0XdvhGSzKbdw;2lc@K0*>9{p1Xlyd9S)#}F_xk1$8f9WN5F{fF zwq@jeVyVz+yiv{R-QcP+4m)z~z)IlV4O1T(-TfXhkR<2_sWi5Pr<~2V%z}%K0B%SN z=dbeCQtXqvf_w@uPDMs?HCcqxLHXIW_hV~UvjP9p(+tijj}emtk?V}{33Sxi8G8d` z-1yU<tdCi^3^7qDl<?UumXU#Kq))skTMZSLSgy~>PdLl(r-_kh<8EYygI1yiI<LYX zfbJSg;eFa)W_f`TG*7i$TC1{V+ha6L83f5ZSCy&{XX*9c4Lbk(_b(W#v6&7M0hZoD zT!?MT%MQ@IA&4H^ppCddzLw|5|KZ9_y86sx$dF-3OLX?PpxzcP_Gg$+EMGi?Xt;-d ztd|B?cj%?xA7Yh(5IL^_U|q&Z{j6eDEZf$VUNtI@O{UKoR19r6BdxxozhSX=;eNnp znj%y@?!JAul6f#5US80s&rXl^Ns@t>WA@|qm^1NAaqb|x0MOZ273AdI+|<R!50(bA z63ooZqx&BWitcwV)po1aMT(f%*Y0xhl0>|PpB-vNjTEf+8&=LpMVPk~#nXwxq|mgh zgqeDtHvy}D{;blq;s2Ah=)^o$36`|+_P1CtPMsEv#u+Xkr*dfN7`1U#F5nwr?b#T& zA?8t1s6@@*8K)?;4l}>1MAyyr)%vftkRK@u%9kjUOC<x5TFIZ^9mWzPC`J<N6j$=M zuP1~22^9VRNV{bMxdDx?a-^c<6{glZ0`w2hcl(f6uFOZ7*D8~!Cv&7~0m>^0T@mt5 zETievWl&>{yKm!Sd*a5Jxt%Ce@8o0(|2U(L@?jaG*w}KJwZ6-iQmCkW8r&6GKeeX( z9zxf0RJepS9lj!jK%hwK3&wWOHuU^>wW-)Mft2OF*|Y*vSpLWd&j3aAi%KibT+VJo zYFPD;hUX@mW74<g^xf@ByJl&B3D%3iM@vaT^%4`^3{1x;3~yE)fQWrQK4uS>O7#n9 z->UQ%n?ipvX=|*YqOpsf;fk@@#^(7Qw2y-A>e>PbBt5-i#{M6+gJPXCP+|C1b~4L8 zbH%SCFu#Lm&0>t0#Rs~=3ag@Rep!LKDwW3szVp%2+Pl4`O=I{ywmGe4?(B#7_!M?B zNy*GEPRpq=rpQkS!y<AIrRf6(%O&HSR?f)wQ&ef$*|AKLFYLai2!r9xBj+k~fEJeb zDc`>%!$qGET?)Qkuk&;n2PU7`DVVC9oeuP{fUMl`Jr(QSD$?aPiPE#Jc#jG&FZXz( zQ5TsA_pqp_h;&*-YcsL0`?A4km&$e<xwcM=B|mF^j6Xh_H;co}RDm*`RajIIG5Gli zrShZu&ajxGbu;tHQ?_jt6Lt3=3xO<zWm)LL^kJgt(K*Ekfqfyqda&K52HW|TVSpis zAQ@ee9@UWdooe5|X^|+3aAk8uYaPL^ogQ~Y{S=i$J#)$D>jBjmi1alx+JhgD$6|?Q zQf$S*MU>OEKmcE8bTpZ0@BghtRYjvuU{(H)L^ZO(b+Cdu2BbA2Ix~-=r+&ym3GHu6 ztt-AXtUes{D7>T53R8C&ZV+v&Wu^c9TQ9#X<vk0x#bQaeV=`y#C4)S?Uv=&j^}sDg zjo#=gUA;X-i6qLMmraDn5G`E7Icj1WKd5&18+xl%ko$oSQz|X68QDprG27Kn1KX1_ zC)h2#%e&saoG<bZY09(}q&o$q!Bihs>5v?Q9Uj4gxMCU3qq_Ve)UF*ARO!;DRvs$X zlOeOyW(;=#6}vB2kfO6(;}P$qKWw5V90$!@g1Zez2B3v9c127ko}_rOk{tH@)1RnP zcyg634O4x@I~9FekV|GcX+24cWgeB|MaDh4f~$PVe9~=}#}A<WA{B2F5DXgCAHfgV zWD4(v*y&RYXNG{37w@-AtkXOzK%*3D@8t;=+yUD0Te<tj@Dz7jdp}M27bIJGK6`e- zhZf;c-}J6}kvEgx{Ob6>vmp~qMTLQ})|{T7jul3Xq07P_Ai0uRHnZCR2Tpu^h0zKT zU*A0Y$k#Q^d9~rCaa0tj{UXsiNL(@cY(o;P82wYCbmzQVb%u^rv2*zE!rnmShnmq| z<;RXTw%b$;gYF2-rm@oNSXPrm&18^?q-kVVwK=XlJ)X5#dHy`eKNgA!IcFj-5v6zm zjiyoKY}A%1X{bzN>^mll;?((w2k^*CC)A2sE<vW&YW`&3ukvZgd*>LzSCl;>0(r5i z)SjYY*HxbH2DZBU+u^TXZkvO+w@bm)fErp<#|O7iJ4)&|hOJGgwdpDQ8vhDfj=(+% z*%mu6zSO(%;pre`!5%-sGB>sZ*CVl>3MulALTJ$G2KnHTLiu(mCyt&cPjRmRJ3SP2 zLT(5{<DeGZ=%*B<KhDK`Av#0<zmilu{xJPKW{LwL%`@qUBwbt1(Wutd29<@%O_KVG zH$oTjbKFeqGPztoPIr`_(kC%*lm^4d16{%S$>^d|B6Sk!?9S=T%!W)4{?xSz5eTW9 zHN{9f7h|!6o)|o^mgJnt+gN%lnw3pFQc1ijx`7fVRg6b6=1&q^MYJUIntdYOP^I^! zaIDnDo3RXr1(4G#Nf(SobrAXvgyCy)bm$vis;r{;b)Qb$?Z|4`@E#+Z?j)2qam$cc znW(osy&zA<&MVSDK+&NRARaxDWm#^fJ^3}3cJnuE1c@{pDKWzkl<p;PQD}}Si_j={ zRFz9=OGS!%?OznmxMJ(4J|5=<P?W_t0~CJI($a<W%t_JW0kF6xw(gBVj8`Z$>6Ge7 zIX;_UhGiqlp{=U))!V%zFPT5}L^1T?lPJ4wV@X0~WBauYG6V{l1#eVT$OA{_YTMf- z7TbaQby(BE4yCj&N^5{-p;1vA<zGpnci|_!v;OhJ(PWSNgIrGmV#g2|hJrL?!3~d` z{LiyF)WFsUVi0zkTQ|BBN4C4n_&U1{0P2doH&EhjK(<tvJ;9u9)uY->i{un7`2FZO zmw<xJ#UB5^hQu;tLc@!xGESXP6Nz{A#+DM=LMv+KEn8n;b@!IMf&``ieZtX>n7i#P z@P^cvS|hJgJc2(b5>pLNmZ=Z~r-_zVnt|HHACLYU(IKw?<<J505#f?73|A5A<R_kz zEm4Y&G4-3h;G3M9QioMJ)khjBZ4v_2&)ba2;16|ze^1R?vHm^vAq)G8<V1X0B#)7+ z+u{E-JEmr4&hsnQxsTm*ilhq`zAo!IeY2M0nO&U|g+%=sP|&bdshtf3jNWAvgqZm8 zE?d*@7Mlhe#-8Na@@{o15tJq!!R8H9AyvnXw2B)>v8trJEW@Gf!g+H{!y%Ykm-+-@ zm_GbdG=z_tTS-#Q<g5J2WVerG{{1Ju&TZIKOB25@;TAIzjfa#V$tPW+AU`E_c8#bP zK*m=hH2888Nh^IFwx^DzHrtr88Mw<XBb)H^H6^~|FP}S#q`=Xn5+qArB0M;%I$C6p zqH7`LIVDIY+#EgOi&1%8US3|~veZ)LF7%@^%{fcS#19Fxx_e_OK3yxBuk15yDEZtg z4DUHJliHlbA4_zybufYy%~_e7pHIr?{PjVX&pn@N3t%nwA?n;`OBVfVRj8?soUA&b zA_YF@*E!DuAb|22A)q%K+vr*yFGpgp>Gy9fFX!9$!MUjf02x~t>b&poRul!|Bx+~m zQ{ggly?YjQ!8EKK8s2kCaD^fLUR{BuT_It^ky}=V0qd_`J}^B;yuq6JIaO1eCGM`H za8v+>y?91!nYi8iZzXyAl-k}32c?|HgMmV68r-sMQmhoq<2!l<!_jvo=h7X|1Hf$~ zqVzT<ekv+Yv*uZf!s}fjl)Kon_l`dorCy*kPZ_Rwa!5DM9Qw<2GDK^ekk~1wc#kxl z5Y&@Tn*hMQNc$uEg9xlk9ILW|FLj<4cFx5580qcFt{(pBJp;)Ioj)`(nMHB@9d9=k z;}c%>=!s+d$0AXCE7k}U8(AG-l!PpA^5{ZJvUIu}Y_(0BQGdy6LF4}b?+>N19y6_` zynMm7)v0_R{V&)ZF>Q5^(J=M_H33fbGBLHfhOa#kVHk=Ogbk}PuNLCq1WDAeG7S$H z^G2vYFq0Nafm#ze_fs{CgKC4@`dAs2?k92Ucj#sN3FNnyyrkRlF?MuyqrcfJV$DDN zngt<vWw?`xgW`>12G$?}*b^5sUX92+|D`^vx{%J_>=D0EzCso*6%E76uPQc0D%2{= zqW5Sb!t9G{6GU1=D7xT98+pV8q$$=}QBi@|<%?TWNkTJl8NL?VJp#mUo|5sC51%6~ zqA@5B!UCKG-#5WlyfCOeUzo}Cl*$^kE5^Pbo#&GMBniuque0j<?f?+uy|<RZEo0oJ z2A@*}>G@5Pk;kC7+PFE_B(hdcq<GKBbN@9oO_P`Z8T|E@Vy_K5h}jgJl`ymmWgNCc zS~(AiZAOzJyOggz@`LJ0H{jFHb`}MJ3)IQn)f-m+{>=&vjN)X>|2I+;`DqRwq04)I zRfEO;M{pZ2D9yXS5h45XKR8x~s5kE27Zb@#BgPg4VK)GJrd1DPae^pUhS_AmxsNXR zySF~w=M;!d3+#DA*XP<74cqNG^+e9%21pSoByZ}3)5NPz3P_Q=;Ew3piSPvmfPwu4 zQ#Z&FTKKZ&k3Y=JG<jmez|*=3TG3EuNKj7eX$l+Qozu;v*b3|1BS2kd{1GY}5-w)c z{>xV<Pm5sj(Q3;W`+eq<Ec8`#vd{~;8z4FDo5{<^*J~p@qZDV$amcHcXGjU6Y9bT> zMIQ^9{1;|U#IucwPIL-X#E~<DWG5ZSJ9)zcUY(=NvaV~WrrU(a?vV%1f!dEKb2!Pb zTUccMjQbY+M$Bs)csbMrEgE#Zvpzi_BT%@zGOrbWd#JH3^+Z14gkt57>wWNxkrwz2 z?HAPEm&@VnZGm3zZf<I4G#393HViy+mNVD#+0k47)Dcebn^qr3YZ7>8MPpwb3?wIq zU`NpN^KCZx`O)P(k~F2(j$KnsP5W{<<Z<7^#XQK!+}pN97y^jTxn6G=pqolrFHF=* zcqV()>5%JSY57X#Qsd}j)3f8(>8y^RyG)G4_O>8&0r7$14KtTvlaSu{%?TK-3?63C zPI<&eXyo2O#=m@FMy8R+_E-}<sfky=n~hpdvJP-1mCf~1-?IKjwH$pO%y16$gr8Tk z#C3!}?r&2JxAC@D^+Drn3I7~??_o4!$$oKz({rc{afNgrHlGq}3Mz|F7p&aTJQC`T zIt9p7ZhAvBS2{zI32XqE0^L(n*USff=C2R*`b7+zGfjlc2JXg&ER4twGY1|u&FpPy zkU~j?7lB3%a{q83cemz>o+|WEqd>d<QFIFNdsv9WZex7UddsuFU(s^zrGIbRby?N5 kjZ=oquQ+ysuWo<dK63p%Nuf#j)r?40Nel8-!Q$ip16QY2*#H0l literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_off.png b/src/gui/qt/images/dtmf_off.png new file mode 100644 index 0000000000000000000000000000000000000000..c6d28ea168800a4c5038d271910b65ffb3547492 GIT binary patch literal 1440 zcmV;R1z-A!P)<h;3K|Lk000e1NJLTq002Y)000sQ0ssI2ZKm%J00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?8aW!#V+a5M1uaQL zK~zY`rB_{S6jc;HcV>3Ct1V^wV|NjShb9PUh=Q@wfG_1qDuINUfQl%Rh>1TjghV3| z@QK7X6N5oSeBvhpB9*jI3{8wQY7qqs$hMRst=+QBZnv{@?>+bUaLZ&ev)z_>A8yY5 zIe+(j=gb+_-rkOg#bQxPNkjm^7y|$RAR@ysh{)UV2yX<Aw1kpJ{#ncPE^FGGJvjk& zo;?AsNF-8GQDK^<C4|Ukv%|x~LI}Sp(;R+R%WwYwQBtgFn(=si?%cWc_4Sr*+m7S3 zwzf7jG(@9O#+aWW!0&&#@;;QI1CjIxq`V3*T>ikit~)d|)Ya8RL{=t~X=!Pxt*zyp zkB^UgaSTZG3kpCnKnIZK-z)>9@T*ORUcVVSGIe!z&CSgn9UYeIx`^mFj%k{VF{PBp zuNeZqg`wzO(>lT~`Q?<n5OARUPJmZRiHL|;EV_nm+l(>27DDJ*2qC5P?&(b_rM{q- z*N*Q<dgJkz_jX)#q|Eo8NTpKAWHOaXX(E|S9=bAm_1KP7Ds}R@tz}9nd-lJTdS+X1 zj${7nw#OPhN$(v0Q>)gxJX#yzw?y6>hzJ0=oNeej=8XW4Ur^uzLwo6-^BmC`&)@3Y z+WqFLE#LlLv2ZPS97KNM^Ou(H`I#d+4u5sQ%$P+0u=(tz3Ca2EM|O7rs2HH6NM=UM zZ=)`9?mB$`i;MiK1Gah39rmYKELu`ZrIb=?`lW0FPQXm&-t6yZ%!oET{q?zhH7^{v zwqhP1GYPQ>WCFk0*JqeaAt3-%KZ|=$rq?|2Xq4HPx~{C*viQtDTuRB10dRY;|1JOn zP*d9xC?`auU9yx?n(}`ZrsJ3b0F*)q0N{LB)Gl0QzkVnC(X1K^09*o4LP!Y`06@68 zO`q*(KK90sy_?oAs62Pz^w#aWe(3y^P)bq>yQA&9_E{B7sH!E;El!x_9<hWaN+F_B z%2G<{@EL|N<yXRgq=*1e2%&YLlf?&~no-H5l=_r0(lh`Nz#V$9dDF&?hcB&8&V29o z+JQvm3rQ%YWJCZpsrr<~92SqEki<%=4#z|<wF?u@=seTTl&s5vN}^{)z?jm>2LNMz z7r(Dsw4Dhlfru0lDb!sBV+@H#@{YNDWz(@OU$TeZ{djj_Y=i+Ql!7o@y<*w&WwR~A zB$2uOuOld2)5~E*DV;2qSF)5+fl!w0GJG`}KnW?O0+qY*>nH2p|L{alLby57o&#fq zh!d~|2E^~!iEZn$tG_Y3KQIf!8~_Lrfq-bFZ-AnuaUMojxb$m(EL{^g=cZ}iS98H) z$#a`mF42pJ*B<)m`tvFGkAX4pfJI7Y6aX*+W&k>)PriNR%q#KQe0GEg01PQ5Qvd*j z_aJ%SL&J=7ZYia5xm+X?K|~K}ffl1=OEP=)F8SK-d&hEg;P0OFUGM%Q>%Te!gXjMm z(#zTF_MN7|?%tshQ8TYz4BQejI_GHmQ2&KrhH1{x^x+#l-9zpa9bHM_5fLI53I(Nz z?cBN3G|l<*=T}u#8HVBYwt?g+Q%uVDW0N&U;r2PKD~#~40aD6Bp>X-~Wg=xYH8mYP zc#v~mS63H{#mc<RG^^ZXJ>rx*_p4N&x~`kaWCjNZH*DCzIy*ZnD=XXD+S2KCKA)c~ z`2yu-njhA1F%4(%bb?<}pysNsu5N5>Y;A27La<Y(PMM~eNF?I%xQ1Cc!~txSEZmdP uf#0%{?>*Vu`yD9hr|v4Hl=*xf0R988aU5MX$s*SP0000<MNUMnLSTYzYOUh{ literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_on.png b/src/gui/qt/images/dtmf_on.png new file mode 100644 index 0000000000000000000000000000000000000000..a2eeddc4460f4f560a12bb532d7d9ae3686e8ea4 GIT binary patch literal 1451 zcmV;c1yuTpP)<h;3K|Lk000e1NJLTq002Y)000sQ0ssI2ZKm%J00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?8w^!>mTCY11vp7W zK~zY`wHIw{6jg9$-rMVLds=#wD-?lVNx)#D2`C8Rh-mvmVqzLdG}u2@)J6o2fnfZK z(e#fALSurOU^QZ53IYjQniNk?(*mM=#AwnK>{)tPdTpil?zp|%+kO7n@>qB84*0?R z*t|DyKHtonnZ=%-9@8{+UC-z9LI^|@LI3~&Afo-1cp`%9;M%%?h-^7FnUmO-=9DA1 zPVFv?(*Vn|qzXh-6h&24&N(*>V{~-1x3@PQk0+B!Dc$Lqt<1T08sWlw%`Jf}fp?yk zpsB2^4243Cjg7Unwb;?o(b?HqQ&Tf@=1f&pozZZyxq{{-a5`U*x1cDemBj*5OqX<3 z*Y$~si9{mN($a#ht*rnM3WYRHQxpa6B)D>>1i>wW5F($?XEK>sEQW}Dcz8G*4hMrl zpU=k_b6%47{diBkckCo{aTUy4mwa#fxfZTq3L&!DEC58KKXL#F1Onyd<;7levD+Fs zv2W|HBhwrI(v~exH!cmCmrpjo`k{;R<=tN_8alXj*SFg~`f|l=%@#P=vwO$kiuT=` z=EBIQ&u>4L$=Sq@ytZ@m%K0~qlJk^vUR6~^gv2>lRh2QuuY+q%L^g&oCXX0nwR6=~ zAD`3>Bb}a#_qF}q{&sucP<42Vo=zKves)ju$~`A^!$_qwJJ!sfR~H0;PX@<qA&NDA zuJasdv*z8UF#kQgdfl&M*9=|P)B2IEk2%$qFwAL;s;Y{jOq<I&ch$#&uk(N9i%`jp zM!LJnr&Z2b^wm$FRX?%+ukgK*M1MYKvRq!lM5Mc$6lNJF5y6aAsc+6CRxg~xFcrTz zv|;muKa5yJJ^={U=x@=Zy5Iz0nVj>|G4Uq6?Hdu1qA0dM&I_<H-n)@oLI7a`W0sk_ z8t?xD7e1NlVR;iQi*q!DKw$x6mIc6=nVWj9{hhrJ^$v_=ID`IUKW}^C@nx7~#2LfD zR3vij)Y;Rg`}%(W*SwJk-k3<Eou@Jw8~~*C1$&DNBatQ|ATh@5Z6-0AuUIx~mPT0< z5g7s?*cAl;ID@MOd${G<O<!Mrbawgs<4+BgiM@G2j4@#ffZF>O%_G!Ft@d%t)9buV z%=tw`B0@w?4!FHK3jlyN7b0fj16>vOZ)cEW3;+m7zzvxQIF`I-tX{X`=t~Dh^(*gw zFg6)S0Z7Dv{<*s$99~mHz(sEOVk~Kj+bZ{Vnh_DVeX;{rtSc96zyye3GR7=nCgbOK zzWBzQ-<=PLM1m|tM4V1#={b=#G46l;nW?6I%Bi=^^pG`urGNx*rGFr$*eb|jh+BJ! z*#Z%{bjuYPZ{Kxg9arZ>Th~YJ<Jt}TPyD&ACiTljWQ^JAD*$BN6hwi<jPVDy9QeLj zt4dzc%a{P6FwR640GN+4D%_MxbUArsE2XlsGQ%)r=1FimDWm6HELi_uUc%76@Qleb zgX5BZLG$O4jY}lUg659M#wA2BW>hQ=nqxXZdHvzR19cjKR)1))b8$Jt>)=vkuU!_( zwe6u{7(Sm5+uGU!fk1tIz0c>f8H#o5Vk510j=IGmt;7K4RZ(z$v&ZLbHXDn@CMPHP z^5x6By1IlA!C+9+v^z19-E@e)>1gcbmA9P9WD<$Qg$oy&nws$V@#B8KKN^i*x^yX( zO3A>v#(P(d_A2)F*;^djidpGG7St<*@caFBb#)C54TfQG`?qZE+O?Xd$@l6id`?fC zb;A2oRnSjoLy*SFTXX%-N%n#Tz&i?<rfC>PDwP6&{{ZdwNdZ)EaPj~E002ovPDHLk FV1gN+w!;7b literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_pound_off.png b/src/gui/qt/images/dtmf_pound_off.png new file mode 100644 index 0000000000000000000000000000000000000000..e89be9d7191880865d4ac22face1277c60f95454 GIT binary patch literal 1535 zcmV<b1pxYqP)<h;3K|Lk000e1NJLTq001oj001lq1^@s6@kTK}00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?8y2V=Zx8?g1&m2V zK~z}7%~?-NJ3ACTiK&8JSp6whH-d-=wrDqQ+^8U^D+RxXF7#6rbm8X^bR`sZDTvjD zC{#hAB8b?E{fE%n>EtbB=9lK(WX897W@BgOCb_ve_uP}n9v&WKp-{m6{XO2_-%+d8 z;5ZH#V~|opN(rh-DZv;60N>VTM}1e{QNI~uh(sdj?(W8)KYuVjK8}Hb0kDgU3z^Mk z(bw09L?VHakrDLt^x(I&N~MCQrzc!rU!zzoVrps%Y=3`WHX02qEG%GXXb8Wxy}rKU z`1lwAz-zS{5{ZQGu#^(6>%w*2w%<X|VZM2AQ|(OldY{3;K_rt&l*?s^kB<-Z_xGb( zt)gD9!*QH8yy_U!u}RtK&FiQ3_xjo1do2=)AQFin9*?71twJ;!4b<y(Ytq@0@V|Wj zX{*=kXf~T@Hk)u92f}k!b=t-T6f5YF()$OE7iK=kao{)(06?@_Ex4|WR;y)n&IAM7 zw*MshdH|?}sF)WNhA3yfXLVrpT@bFrelz`5=N62ywyf0?EC}mfe?5x&E~v%IhIbQG zIOl$}h3D|s*OzgtOc`&2iYc-t#xOAvwQ$B5glD8ii`p8`MvsPG?oCmr7E484@2~Ep zloFhCa5dv?*i%<ZVO&k1)6-L=(`o;EI-SPJ$w?>;qWhwc?Yb_w9w}R4F>R$j@$>UD z*4Ea1yQ`}!tgo*d$JFQ3b3pIIO%B*pTM&O|G8xRw%m4rig#rLzcz8He(V^H(&jC&q z0#g>7<fHnoSS&(HiQ(a406@81#?sOf?(Xi$WDVQYxrM5oDY~NQNXPN%=_xihH?8p5 z-Q5KM9335DWMsq&F+FkhKyuExk#2%$%WE4O8~$Rpx3_V4c<4V*PEO+G<;8zqSy>6x zEw*RQ`FC-#@g+5Z?)cr^oljSpOa@z9Tgc^dC=?1lR6LuoqRdphT-OCxvy;NCshm=r z`~LpkmUQKE8OzJd$mMdO9W+%{)d!)fGCjgnb=1EX3I)v1&xgYE-rgP-7Z-mVZGC=D zRXIurP(02U!`$3l8=emi4vcu#lhvm7C`R)!ZHo{koJ@EI(1zz?vFJlZwXsQ9O6ux; zT-W`}9@MIB<yBwM+uK_ko=c??mX?-$Jcl`8sD}|-Dd$15(=@Oyn$)CYjN$C;470Pd zp~ux7q)NE=TbKqgDKquAr*Ro$SY2Jk>gp<Txg4aF*xA_u06)?uCb03pw*b{g*LA<o zh&Ekp;%wbcr8UM_+cUMBLBX;qKyJcKP-O~p^`#$nZCc$Fc`A>%O#+&<uZbE>Tps3H zL9ZA34S`B|+$)hLnz4!WpX>-lXSM*Cu-<C5AXLh;;Wx-Jk3+-gW1B=(l^rE5IOpF7 zTS{<;y#x74g6UA9qD(Q>zp7$KM+f=Q6ipN9+X{s(2Xv^JG>{rF|AxsHWz)&oc1Sgy z*2CnD>W{uNUteE;^)xl8s%0t6s<vLCq2QqQv)P5wA3})lL~ONMWE6D)t`6oUuxdv! ziH=k1&d`=eYSr~`m~5JY!lM^8HG0$nZNkfBN7;C1SoNFmZcO#4gsF5vmyxzJr_D~c z(E}ue5dNxk%$nW>U6E1mY*jYwy`G0@&N)Z5T5Zc%9Uj#AkfJp8e<Y@JC*`!x7N-CG zl*{Gs;?mpOi+nzhv9U39c6Np;9;V3Jj%;CUY;!ak4dnBA#9}dscs!2F%S&{0bfBlF z$9Md<G{zVjjRs1k67u;xlF1~*#KZ(%Ute*4evW7~ig-MZXfz5T#Q*NF<2d;I{KVVa z8)~&0QmGUYi3Hf~?XB$U>OwY~#m&tP9v>f3sZ`KxHmz0gC--uuKBkLv&pr}~AQp>Z lbaWKc)6+<$Qm9la_y@yop_iWZQau0w002ovPDHLkV1kIf>f8VT literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_pound_on.png b/src/gui/qt/images/dtmf_pound_on.png new file mode 100644 index 0000000000000000000000000000000000000000..1a1fa6e065782ea2b159df1668f9ea4eb581cae6 GIT binary patch literal 1640 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 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_star_off.png b/src/gui/qt/images/dtmf_star_off.png new file mode 100644 index 0000000000000000000000000000000000000000..b3702b2418328d20e6e433a14e0094e386f9c810 GIT binary patch literal 1487 zcmV;=1u*)FP)<h;3K|Lk000e1NJLTq001oj001lq1^@s6@kTK}00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?8Z7_|w{-vj1zbr) zK~z}7%~{P(DoYUlrl&D65OCo^Fl_vZhJ}e3b*I6^6>ix168Z){fi8UopFtLGi3?Yn zC<{%Lgb*VOg#ZR*hPjJ#dv4Qqb<epAb2^zYL;p-w^;cD2*ErQ`HF$r2$J5gj-rwKx z`T2>_Xau=AjssJ390x%VgyY1sI!69q9t$9xFRudtu~-c8cpS5{vshVK!LMJxz+0^r z?(grB&1O+77O}Lngj6bpzom6L9n|Y}+}_^e_VyNqLIKYC`FSusJ&jVSglsm8zqP%- zzT)cY3XCzZ&(BY+udgGM$sh;<jK^b)$72LRFmb8>t7FtY^)mJ8#)+{4I+;ucYin!h zbUNVOZWozM2HkEKgTVlv=Y`toa4G*sJ*zlX*OD=-8?U~XbB?L0Da_5yq1|qSk47U5 z1_J;HHT#K1Ii9W!heLRthtX(+(P#uNCi=b~DLSZDpe(N2DXL$NDAXL!^Wb?N#^W)# zu&`=n)dEp0L(S0%7S+mf6PV|!wyF^7vpilEFv@)OUN=TnL><dzkEWb~f``tEI=>L( zL?2^}bW&476LUg%42MHf5S`Xk*0Wj5lu0Q(t7~%Cb-&?87Kp;4Ng)|ZB7LiCif1Z> z%I_00iHpf`S>*)c()HOaLs?44L8yE{aT(^it~LbeETD59lOyZaqISa+M%7;?!ibH{ zQ5L5{m%OG99&(=v_v-tCAOK^GX(v*Fo(f}81XAH;+YQPP6PBhdYRYsv++SQ=;Q09X zn=rPJrdm|p!7zF-#;gmf8BAwY0BE&ZNT<`--`__(9*5&N==b{ofOtG^4P`chCdM*3 zsZh>Bd9#ewR;z`*y*-?qoS@NYAeYPG^z;;^QVGpwQ>(0QXQ`8o{4N%COH7f$aU2wj zMKqgD933420CKq;%H=Yu)hf#6veiFSVbw?`Ure>2&H-)2CI|x5YBkKy&m);k;_U1U zl}ZJTMgyy>tEkm#-|%mOg}S>FiG{KMFim+k#mICD-rU^a;NSq4mzT)r^H^9|Ksueq z+S(eKNh#r}s1yVNnBdVW=4?)(+kx%vZCqYnVry#)i9`aGN(G09ht`Neo!oW*O;}n7 ze$)NGL4Km|;o$*WTU#L<Ha9m>tJO$n(+MkcAKh+-m^P(k>Yn1)LSO*l{hx3YlTw04 zGb#b7k;KHOsi;6HsY~&;OgKT9DE?q#cvLjeSw0G0O<7Z?AdgBZZRE+c-L?!%l^*1N z#g|y5%%p=66>V&E)x<k&&JW;s$TNj9Dz@4(8HGoRfZ5`;Xs+x2J_MK+Go4(hLxO4C zpF&6#-1q&-G_E5`CMf8f)wUxh$E9{$g)7rpQdPu6qD(}GT06>)n%>Vn&x7y#)-V)> z7nu5O3C5Pt<QUI6=iiEt>hWC^S4=OmvA`&0FhLDWmD%xl4DS0rbfihH7U_zU>ef=V zK;27qek6odWs#K#D@>HL*^c;fpH6V9?4UbrsKPpq6GB#mWLXI=EU9K6RVW)4Z9YJi zccYx_RVBIWx>_QmS}*EXfGB*KqM@>HnM%aWbzQXE?TM|`SwsFFA}_8!+v*vnv!C22 zmo@}^+U+)Cu^4zNl|sE<$MW(rrlzKh8P8UOi)!WnGiNv);`#X*$z&3Ic6JtzkB{J- zBbiKwg8yW*DfjjDg^!O9yu7?%V`Bq6pU<P;@8kOV8i_;#>2w<LcpR}<?8iSEsm=F& z^m;wKy}hB=>!DC6AfL~J_j*0-?Cc<wO5yJA4mUS9=yW>ar)JY<HQVXh^vTV}vBjsj pnVA_ZE-qqscNc|10o`sF{{V+lXJ+j+Ap`&b002ovPDHLkV1kr2zJ&k) literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/dtmf_star_on.png b/src/gui/qt/images/dtmf_star_on.png new file mode 100644 index 0000000000000000000000000000000000000000..b77a5221bda7d438d51c3fefb6924fa602f1fcb5 GIT binary patch literal 1535 zcmV<b1pxYqP)<h;3K|Lk000e1NJLTq001oj001lq1^@s6@kTK}00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?8z5()`iTGl1&m2V zK~z}7wOKt+8%+>?c5m-2EICLHF%q%~N-SAW&;%*}Afik}<%SCW0yRCN=5Nqha=JKe z1T8ceL5OSxD<Z^TbGMtqx_g&pcK4j*T?zTP+pn2<X6D&h*6DOqx7)>+FJEwdeU0I8 zh&YbH7y|$(rC@7}F({?7-+$RJT{{Q@lu9L3Diyqa`xf<j9pe1_9Gy-F_xJaxR4OQy zN(h1gK@fNs`9B+D3`vq;JRalMuV3i(dgydIC=?11{eB;#(Fl!31C>ez#bOa*7(S6c zZMr6?KBkaqUsKzrMj2yItjid~Xf(obI7GQz#@X2!dc7XRU@*Y^{5%#H7co0K3n2u; zFnlyHueK@k+Jwt94*<k*jAzfDVP<9qKY#wj_wU~!Zf|c<uh+8=x@OXaIp<TE)h2}b zJ<nWG6lF@RR;&2-?HfdrBq$UL2*WVjoVj5N5>zvtjdDN}68czED1B@ghA0#YkWxYj zA+n97O-lL1#3>G46H`K%FtM$pf44y_2m&ajAf%K}Hbvplg;i?YG}g)UUP_tmQBaaj zyTHHdp9gxJ^NFTY2~w^9O>A|+#TQ+CErk<jjAj2&=Cr*tql^v1)EqW}d<sbw{Kye0 zXEU*G!?)gtN=QDzd=`>YX3<TIMkCUMKCa-?mMhHp-n$YKV+>pf@kpDtOqe$k*epW{ zLapob0i_gpp3tP@*L=2RJ8I(;Ol)(zgywn{v`uPiM1SXs?Uc~21Y~O6mNj`C$D~Oq z#$}sK*E(YihlhvQ-QBguT31x^jp3X_1VP|*G%BXrCLat2D3{CF*x10r!U7m$7!HR} zN}*URI-QQfuW99s4<$)LYK_98EetB9aD9D^X0wU?{e4_sUZPg3;o#r^TU%RC_%dZ7 z3MQ1FD5WOJ#pN)r5T>_gvx%=?zhY-+2LMp5R<XIciO-)u<HLs!R?M0N$re8K(+sy| zu)MrC?bmL%v9Pd!+1Xj_?d_q}YT@GI0*yukA3uKdMkHI9G?gfXfS?Gzj}uVGFQpU? z4-c`uy^U6@g+`-+SFc_H02+;kRg08UQ@GcmDfE-KD-%&BG|m0~{d-iaRjjS80RUR9 z7S`6*&~CSL9|)+>s=p6{U=lqj-eB``S1fL~+j#fx9op?S06cpB6B<kTkd*Sjj7Wtx zeNf)>UaHmf*+qzS<=7n2w2+h%TtB(EHbf;B8&9#NXj2J!Hc#Q2yEbXlur0mjDHr(4 z3pOs4#c0mK^^BPJTxSa6N>0<B2`MY;ze$qNA<q?4De{zuaJjT>V~95Eit%{tWO2TQ zY$ujHhY1@kpg2d`!Y~AnqR5J8pH`+J`>wj3FM8-Lj^j!6@Wn{i=FG`$c&11eby}j< zHhqS>Fl|evzQ{pk(mdLw-cw2wqtWOQ?o6DS*~rFm)4qBi{Uq(8yEf-Gm5`MXqA1E< zP<1@hbY?-v+?-3}wzTX!l`Ex?BuUm^NGXy2=@R)0EUx;63(K}mxyYGb0ppxQP{)7W zq?7=Z*=;1Bb56p;=0E!SdTl&Q;b|?;#G$Ei7r&;;!qj&g)wD&K)FJipQp!n2jG~Av z2l$GF(_C-(Hkzk=oNihOF)8&91_Qi!@#4`1kr_RFh4Vi-MC5^-&N+Vk_%XTNnwy(L zx7)?i(h|~Qq|KbZ8vs`+ZQA=o^Ty!*{vKCXS6EqDfq4G>IgXBwaD04>rKP28(|>a# zmG_b}FASxW=ytofy}d=XT7`J|@+IE9d4o@%KH>EAG`mYo<M%XNInQ@jsy4?wJUrm; z?hgHaADnZnudkz4t4*ls>gp;Ag#u1aPH=H?ft#Bf#BrRv=xyT&dCI{qs6|nPQmKU3 luU}(%c^NA!D@c+AzX7){9a7zY%bNfI002ovPDHLkV1hm_(e3~M literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/gsm.png b/src/gui/qt/images/gsm.png new file mode 100644 index 0000000000000000000000000000000000000000..888e7c550a528295e235a7e878fdd1b0af0ece9d GIT binary patch literal 1041 zcmV+s1n&EZP)<h;3K|Lk000e1NJLTq000dD000&U1^@s68~PR`00009a7bBm000XU z000XU0RWnu7ytkO1ZP1_K>z@;j(q!3lK=n!AY({UO#lFTB>(_`g8%^e{{R4h=>PzA zFaQARU;qF*m;eA5Z<1fdMgRZ<he<?1RCwBKjZ17)RRBQGz3<)kW~TG&6sA8b0c<d| zSRqCPF(F-87C@p2TNeg*#>A~#SH``%GbTz<6Qd?163|3abwQ{Ep)IBK2c6E8&J5Fb zX5R1K>%znpXMfH?YmKqm`{vSD(-$vZY^|-WjazGpq6lLWtkvkq5JfRb5|JbkQc6P{ z#;R3s4%RlR`Q?X8CjlG>gy5M-0MGY3#X_;FlbHMW7fu2QDX`CWa1+1<>-%0!DaFF# zgQI{FxbgpG1y&1;{cr6G<AMYylZz9t!0oxp=;fcUeqvNQYSed*HtSo3@k1kjzIA5u zBVz~vTw*KmMK%!fK%9SpPHfYkes|-;Fpki>5gBQ?J$LWenbQ+j(y7v~)+9))!c4%u z^XprShXUCHDW9a%CT=zm1jK%d^=eZsKUzKt0xd0azVZ2Im+y{$UG4mm6UHM!VwH#T z6e(*ko9k?C)cI$A=>&kW3K=E!!A=Bwo{O=`4y~Er$*=#-K(IoeQ>7Cwvc0p!%&ps_ z5c{66xO;kztSAMJs<ORu6Amg0r(VbF%cJr+-X1%|_Utlq-(P>e9qbJEq)JP&keayU z$qdq|ksB!T#{2Ja;e&UXoH%BtUK}^Cl*;TA!WyFrtB=;E0NfsTXujYb*xb%OEN4p& z&1--0xVlMYafRCQs%UMt&`FB=Zo>5R^x4CsFaO}WB46E`J~dlYcgwwb!OiOrxO3$u zLJFDA^^z$JllY$KKCMt$f06}uT!3=+)miC&aXLR3k{UUJR58*<5QGF_gwVSv;qYW< z_W*P<5?~;GVkYZn$o4KF;~1hYHVCj`7hyC2LP)9`E!F9^)6x>ioIiTCm>FBi6{~n| zh>b&pF$e+HBw#eIFw`6E{>Ibom!z>y3Y^AJ`pw@8#R|D>fQdCiM~FltjYVpMi)FVJ zvQ@85NVFRR&PZ-*wpel~^))aNkQk&fU^GU@2rEbeO}*X}QcA7C?v~QWzbzLJ*Y*sp zB5|<Rl30r|0*p)8hWcicjY?fgAwz4evEV)4Up)U~|40P_O}7!zBV6|8It-O-3?96} zxpx}8cKk?NSla>X1Cn;KaQ5=8$)EnX){(w2^be;g5B7BX2llRy3?I8QTDmaZD^GtZ zbkYU{Ah4)`<?Tx!8?_P@Qez7_XWx^w*gvCfvI>6JNeWmI%YO#|rrN_%iPh5800000 LNkvXXu0mjfd>q-h literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/hangup_off.png b/src/gui/qt/images/hangup_off.png new file mode 100644 index 0000000000000000000000000000000000000000..094405f83d55d1e565370581d244379f7ac11d85 GIT binary patch literal 1882 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 U1q8{?&Hw-a07*qoM6N<$f}U)XYybcN literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/hangup_on.png b/src/gui/qt/images/hangup_on.png new file mode 100644 index 0000000000000000000000000000000000000000..56313f6df102d7926a5b898a4c0126f7a5351219 GIT binary patch literal 2091 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 VCI?CBVaWgh002ovPDHLkV1nYU@Q?ri literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/hold_off.png b/src/gui/qt/images/hold_off.png new file mode 100644 index 0000000000000000000000000000000000000000..8cd06ad5fd2d71dd654eb5636bf6c635a7d89735 GIT binary patch literal 1496 zcmV;}1t<E6P)<h;3K|Lk000e1NJLTq002z@000sQ0ssI2k+a0b00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9WK^Ga0mbZ1!YM@ zK~z}7y;ogqR7Dg%GxzRq7m7_`fl`V=5($zJ{``SrN(_pDtdU5JNJ)rjB*Yhk#Q2~O zJ~R=1P-EPLfV_YY6eEzJCbU8^X^aw^wk&ju)Ih0Cx9x84Zujn;Gc!KS_IlZS_ZFjZ z9yVvsJ#)@?=FIsS(%;`NgeVq^j4>euIF=BC5Tbq+M@p$^^(&=R93cdyRBg98gb<rh zk`+oS%&AY5QYC3?0I%ibD}}Zdr9p9YU5`W}lv15iIzB$0N~H|LV2r_ROMy^ItAY5R zS2ZM>rbVOCrlzL4x;j0R$qWt-wzRaw<MB`^<P4qX5&HP4IJQ8A9`~j2gy@!cid9&5 z^4&zKR2m%}?ds|xgpg!1+1%V5kH>`&h)5~*wCXl&Gu<})kI9YF)0U?Ow~Qy#jwhvb zY;3HfqeC|ggL7Ui7Ad7F$13)FLU*34ooQ}xe;<dyNuvOIsJ15TR9;QqeZFqDZK!Uh zq7jjEj)?hufo8K=0N|Xfcyi7eV~EHYQ$mVXOhqfgmQ-~5)S=eXeK@lQP955Dx=(4i z_jCKghQ>8}_dfc_!;9Wb4&{+C#*Lc?*X`?{vTU`+&F>aD)_W%|jug?xpa>hA4Z!B8 zWy>o8&N%=~P33gcG?j;*k@O6#XP(e#c$x+fQE_M_6s7@0%-=Y-F7eidf${Cj=Mg!5 z_0!!?zQC`Y-(M$#mKF(0WNfB@>jE}>G12`-jIrs=@5f(xX6>(;o}(|--hZK-F?2(% zs1!m7&beuty7F5H;l3DdMLx+RC1?Q+5!K&dfDjZMi&sw`-F2pa^PK$9P*zI1`oNcm z+tzdq?%LTXK!V_$^D;Ot0072r-=5SoJy3V>-1nCoHvDw(*=<cV)%uE0&9n1DMOatC zWQ<i*pntk(aPH-=jwMs`m5of-g#`!pqm>=`aXN80@Mo^5#76JYwOi(WJuv*-qB%f7 zazva-CjkIpF(wgNsWfE9UfejpH)~)+$j7edp*z!6UDdLms?vIv!3XSJXy(Y%JNCZ3 zikTP)2X2MWoh)&N)Dprf<S`g5OG+#Wp@l-orIb=2vKhF@1%R~UOVG4HE|?dw@5lop zapL#z(;g{Em3*ky7}Qq=uxZJXxzSn@BT~r4i#JS2fikvg^V}a&!|OLTmNkpqFITeL zkHi@p0|3F1&!`nbf|T6$s_@6z?y-GQO-(PJz1rW&`~0*^lkI1<yW#&8q$F&5d}3Tl z=8yvgMAm%d{Z}{ceEj^CCl=R$w0he=`n=)Dz<gq4Bmh{Jg@OnG07@i)D4B>MA<XQZ zZ{B_V;yY)K)svANy2lJ3JQWSEoS&9u{U`Ye5(p9Y<fusi$&s0p3ll?~$CtHi2|l*k z>g$EwAK&bJjiqle<V&YJpMUDx^7dUHbRJj=*WTW=zRdXWY<GU!vKxIv_%A@&y+<d6 z7={rH1~pBqHplri7+bP&&xuPg+<pC?5?iw8#3i`feSL)8>DQMh(43mg6(JCLs7BuE z?VGR!gql7Xo%qaF!LogKg-S(btB|>K{kOrAS4H(KAD(@Mb6zMExR9i+t&MZOa^=cc zELP#F=YZxOEUS%m_tknm91H72@O;tqoZUQM3!X5124H7FQO(mZj8rNGAoZ<Vw<eQG z%d+b0>qDW?tQqe=aQkoZ?0B<Q_y_#z4nV0?%49Ob!^5qutt6dJ3nALu+tcZ^ngKmu z13uGywe$8FIXvU$?uXT01@7s^Q)g{$?TQsE5{U$3jP&&MP)eiGXfPPGOOabkHCLUl yZKs&~B6$wwvpyAOeXmq|=&5^aS(afKi1-&sbAl&HZwgcZ0000<MNUMnLSTZ;JJQMk literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/hold_on.png b/src/gui/qt/images/hold_on.png new file mode 100644 index 0000000000000000000000000000000000000000..c02be220b2e97a82f5387660fc81fe3d2548912a GIT binary patch literal 1503 zcmV<51t9u~P)<h;3K|Lk000e1NJLTq002z@000sQ0ssI2k+a0b00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9ULB%A&39~1#C$~ zK~z}7y;ogq6jc;H_uQG;pKNK_mZi4a%2v=I(HIdiShYfHnkeF8;6YImK^}-E5Cx(< zm>A;&m>LLCG?5sBX@bVYq7*_?2n3KAfh{bRuDA)<pLA(Ux80xFnZ4JC*&WCE*)BYI z9wvA0oO{l>^POK3jYb(`>2z9ERbC_j008TP5W+b}L=&5~uP-!C#+ZJ@C`2b+h<?QQ zNqcI#jN0|5b;l$J5k*mSyWNN=AmYf#NLN=^EEb!Xn6Rp}C0&!gFs;j{8Bdi~VKmsZ zuBxgEg+i^Zt+lnaq^GB+qobpyrlz{O+U<5*RT@Q@_Dz4<iQmd;+_CbMbIQtZ(#|>0 zX0zkt<D;Xa8#ZhpTeoh_WHO;p$m8({f^ZLjIH~*}$X2x;M5?N0GMRWhE{dWMi^ZCo zn*)J>%jH5uYqXeL)D#IO7;RmSa}G>RWn_+Gh1X^4sJ8f9!_R1y2|#OnGR9<C=A55C zeMVr6`Tc&c*Gnla0n3b_4fpQ(7Q-L3G-|Iyy?gdy_|uj~0GJp!vuWpEap6LxzaN&Z z|6=otb6kYTL!ZBUaP{6DjqZY3^5Adlw(Qacwr|}2>WU>*!pz=Y0#!<>-|r^`3K>Zd z1WKt;ByDYdnur>xZb7|oeuK^yd@xwQpn+1F8$7pZ=iVdN6X{4q$t6#Phc@p#nx>Tc zf|b7dd9y@acx5mMPwY$NluT-R{AP4{|G~HSpOmSiJ(N;JG?`&COb`U^cK_}YLP`X> zlc(u!gM?6*q>162yG7s%5h#!KcCJ2r<&o*DN4t|iJd57^>b+fy2S(bL23^1b2vS;f zJchv4-;Z_YCCObmcVpM_vyDq*iRT`#b=%et6Qov?wAxm<FaT&jhEiHO%a<+yT$*+A zQ0Kgdyqe<lm0xP!S}RaBdm;DowyEeyS`Y*P<&TSlk3Cy?_|EjQ`#nGasX&VoFi(JU zMk(a;+3}%seSue=oO2mL5QG_2m;9<hC=fz4e2q!SnhdPLU;<ywCCT$Iy|d<FRaONT zjemdkP!5n*Fb?TElT@U|Q|U~eNmbQI00598g@Rb52tW`KG)3}QinIG_{fMelg|tmk zrpp)HTX%Hro-^hfCkBS3IantV$y4D`mHgbgC1VO9V&$S|Do*@0Hh*EDaGa+vow?Kg zejQDX5+HySi(&}@Ab_+8aC-R2h1+j<C4s?=WwQho?nwyIE~({PQ}b0$ucLjU07RJ@ zy<K=ss|*n-QJ>!S(fX&>J^I~|#kF1n%C)ZjU)JyFpUsD}2mlO#0x&{2CzJr>Wk#u( z&u5cEKYzUC`1T*ZuEAJ>=-prW<=xmD7W`JbBqEk5j86TH&Oi%b6#P>nzyT=c$7)u_ zd%p=SUs<RtYd*VvYGbPJG9qb6oeaP5Q$fnA507nn050!nUs2fj<i}s9S{ou4V^l}j zVvH3P8^g5tbh%uLqUiV5|AF;x*8FB<oA>&G6Y%%>=#aMA_}YOUxOF}{oE^M2J%5#& zT|1G?fasp>VX?lxDMG;8)G<1~PnVyYh}>eTs_Gi26F0A3`ZG@m+O?v#wN&ffjRS_( z6}en4vU~S#pU>CS)FergaR?~U+1^WEMkSv|g1nN-=A2re(z=|Q0b_D9WhTzKEX(nD zd~$M9XlZHb?Cj*62Lb_)$5X!R-(|q0Qps`$l)D;zO61#YHk(K!1_lPg;V_BCVgS(H z-F@T6jbt)utu9XUp{;b=E~50DWecnorLt=He>pWjZEI_jWtl`G5k&NQy^<suo!e=& zb()@x3Tz9nagxvj%(gN+<rODSb}H|xsw#?-OePs){{ZxS;jXDzo6`UQ002ovPDHLk FV1g7w&tm`p literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/l.png b/src/gui/qt/images/l.png new file mode 100644 index 0000000000000000000000000000000000000000..fe035f1a4d380363b5afaf11b0081b846a11edd0 GIT binary patch literal 419 zcmV;U0bKrxP)<h;3K|Lk000e1NJLTq000UA000UI1^@s6jWW-@00004b3#c}2nYxW zd<bNS0000HbVXQnQ*UN;cVTj608?*dX>f03X_Vs^&;S4dJxN4CR2Y?Akk2cFaU92A zpYO9}_ME0>GTJOrwAhKXqZSvJU0j!|Kfsw<9C20dw39e!HARU7k~qxD@1;!2te$Mo z$ALNQb$s_eyx%Y350fBml9C~$5ddE0-aXPy_naJn09YxO2WJN6$GXSuVK<H-T$?LS zpHFJnJ2&f%eHJhY(tT^a)zWiGTe&OWY5!`pY7(T4NlGRV3fQsk7_CIQA_T)h+ax7p zS!r4Ln0*VK<u0g|YeYJtIF7^i;TGAGC61;FxJ7mFuE?dWmfC8m|I282uTy(=L+bxD z+RVLKx%B804?rA1{KCg{h2NL*KS5u3wD`s`gEDEN(hi`mf`Z6zv2md9^$lI5smE6^ zm62PY=8Iv?7sDFA@~N+2Dprc+e~(S!o(bkgV{JnK7bWMWe#}Nw_zxT4i{R!hl(ql> N002ovPDHLkV1j3Tx;g*= literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/l1_off.png b/src/gui/qt/images/l1_off.png new file mode 100644 index 0000000000000000000000000000000000000000..864c2556cdfd48c1717d01ac1ee2da0bba9c64d0 GIT binary patch literal 1047 zcmV+y1nB#TP)<h;3K|Lk000e1NJLTq0018V000*V0ssI2e4hgY00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9syRr9+Ch61Efhr zK~zY`rB%OgBSjQ`vmWnx?Twwpk-T;y-AQpA5ei4HQY1o9a1jx7a0NAjii!eVgHBK( zYN+lHKqpS<gv2E$0R>XhAQB6a0-Y@sF4)L+yk2|P>z$cLG4^Eaq(I~q<MEq$zrOeF z8?wK@PYCfm&-eWx2sq~eKnPK*F1m&gf`~Jxlv2yGY}>YNn-D?)pxtiQYPC+M<NLn! zj);VinHc|N6OYGj+g?~$SX*1mX0tSkqFSxyIL_|w?&|7lCX<01NVnUq*Xzf}$JJ`J zTrS79wze{v%--H!sZ>fN5^ys~Bog_2-f^7s^Ye>~3nK`EN~PjB4kC&xqLhdz_iEMu z>h}R4m&<K#Zn~~Zec#XJa-Qc6hr=j}X1XLBAZ@PQ$eX&JQfiv!^73*J1T>1GFbsRW z-V6cS)n`x6vhTi8F{g<$@;Wd6to`!ykFA&9`QVk?SHTIxFp46^7-P&}jOoQH={<k+ z$-}b<E;RrEB6xiF^;bWA`1KcG{XP=<k-q1gGsZaQR7X}7i-?KT5)`bM5Mn}506?(b z|KqQZ;_T7Am%k*StN_3;3?YQ_AcWwYQ+XzYP+AF}G*Z@+U)E{9X!Ed-d<lq5Rv9W+ z>OP%;<uW(`01D29_DvE(KmZDX0DzoxK2AmJnciyJXfz~7Gi>1qfH(?6F;S{C0U077 z@-PfRJDnL7jYfkO3I)9`<$Vme5JIEi7+DYq2!IM`mAhU<p-`Z@Yn|P45kipZk`WOA z0SHXEU>JrnHw;4$Ks9$LQyy!`97LU#>&7`pL_(;&kd6aHg8{=~ANfD6Zr@MFZrKSC z%8)Upz%dMiA|fB#6O|nzqM3rH_wPQPq>+8?n<t;&xfTBK;O&o}{S5%{?Y(V)2akVx z^G;d^R>4IGF_b$sD`c?SZ+*rl!a3*7?<+P4u;2UcY^>p&G4|o+lDsdo<eaPF0|3;r zEZ24C=H~S7BVz0MZ|&(h0|11KYSmva$ur$Xy|=wyk5WpL$z;7=FBXfYX<qvtT`N}~ zrm0yp8rAFd`T2R8&*x81Ph+uICX<l?ZYW_G$~R<veVvv{CC~E?4-ZqRl;b$bWHKI) z|3ANsvB6-_Y&QG-ez{!U*w~=H?{9B!r_<?^lar&PBiD81)YJ*CqpU0SBl)PN)9GTd zxU;iUE|*)a7CAULSX^9OSy{0x%QQ{>bI>hkCdsuSB^{$E8V-kzMx)#9{tH0aDVmD- RyafON002ovPDHLkV1mpa;g0|S literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/l1_on.png b/src/gui/qt/images/l1_on.png new file mode 100644 index 0000000000000000000000000000000000000000..b6bffb37d75b3ff1a0501e3e9fea45821ccb2a8f GIT binary patch literal 1018 zcmV<W0|oqvP)<h;3K|Lk000e1NJLTq0018V000*V0ssI2e4hgY00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9U|ZLJR<-A1BXdO zK~zY`omS0n8$}d<Z$8%c+72YfO(H9~<l-BV6X3!je+ELma6<@*dqD_Mseb|zM=l(Y zkWjhQB8SpSDIoziC53RomGVKVd^ol@UVC?E9*41~V>=Bh@37jPnfLX3^L}r!UauqK z+1XjQ+fCDyhyVZp5D|ugh(v^l_QkBb?`Dg0E~WH+zf>v#fB=9-qp`EI(`+_-y`I+E zC|EbHSnFfERz(Qm`+m7xuGMNwOH1P7;vxuwFbv=1+%K0o=ZrCUc|k<2b&@1e6#aI3 zy0Nj5$z;U-{(e6U*NVmI>FHc9CxoyHCO{h(W6TZN#n9%IBuTH=n>s&#*zF!39*SnO zIXgEuS1c9^1<tu^eG-BH6s45!`=00B2*Z<;6A?wxTSDaX`D`|OWxg+ET?k>~TM5JM zIA#DKrIb=K#t@MWCEWl0e(+R}E+V4pU!EQ`HrKyj|MS#cchx!Pp64m0SRBWkb0RVz z5RulJh^V#o&HczO4h~Sfb^G>b-#y&ATR+d`XhMvxag(O0aP{4a`BSgKY~CYMBS__M z-o5vsNY`(@^DX077TGl=UW6=Z0vI(702KfI$77wQEmE(*3k$BbHcw%4nQR|&8q&Q& zDp3H)005qM7LFb^i$uhNAkbP5uqM(&0T}o<TUu+SlsyJC*i=fnTK2HkItT)>y1Hr{ zx*ULrgM756QA!~q0MtW(ZJ2J~na^6SHmIsnN(kXrW(1{i=m@SlIaXLA5|gZABGOQR zwABh<#eojyiUm%j`h5*50yuAVqLOAJ<8icI?J}U0QW!L?Lz^keEIj)1lSf0J#n(Un z^t~H0+4=g;SHT4Uz>l8?05@;ld1E$jqqguG=mlfUT6eRXef#~*&5v9PdHU<tKXKvR zFYbN7pI_p3<MET@%dyl=VG&W}a=A{sJu@@o@)rO++xz92L+C@z-jkm;#wNyS!3R{_ z>2xwvQ>;)Z{H#<Q$7V3uZZ@fz3un-CF|@n3aqLw|(=?9bZK6`CBr284?(XhimzR}F z<^Ro%Nm!1Kj#^5U%VjY?Kfk=Z{KJC>qTOCa92+3lOu@++kfv!AMcYJL>$SDDg@py- zdEUy(itqb-dwbgl2kqnIBuTCb?Hb0HQWlHF#l^*HwOXxKIp<if*X<zBX0uXCOV(oy oGxnEoB_>Id^!xoNicCrV1$^fOyzktgKL7v#07*qoM6N<$g0rsL3;+NC literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/l2_off.png b/src/gui/qt/images/l2_off.png new file mode 100644 index 0000000000000000000000000000000000000000..c770ff6bce5cb7458b4b5d018e1d6a729d7a6d5d GIT binary patch literal 1111 zcmV-d1gQIoP)<h;3K|Lk000e1NJLTq0018V000*V0ssI2e4hgY00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9snV@E(8Do1LR3W zK~zY`rBz>O97PzPnVr4cWZk`s*W~V!(83u`LJpE5J_T|pMdO1)LHgj6h;POR9~8+; z6-#Zw`cUveP<)Xp{-G@uNvl#43n2&!2Zi9#JBg_|FWy~lZts%aote*vNw=H5C}O{d zWxj8AzWL_&`~KkN<z<X<r_<?nySux)oO6T_Ap~QL4hqH?0D^Vc9;mvm4-5>LrfFFg zA%w<au|}g&E|;6lrsFuA^RSn&udopS`i;u_;NV~?m718CNTpJ=*=&|drF1%7EEaRQ zTq2P`4<PM!yIQT5N~LnSY}>XrJ3E_9Cg<np^ZC4C80f*oFpNwlGcq!=wY9agvqK!m znVy~=9UVmoNhtvU0D?uoDy39vun5+Hn#p7eg~ImsHtqF#>2#Vgwzs$E`+mS)|MyTP zB3l?^P19nrST>vOcDuy)eb;q6osR3e>V6@Fl(PQI(#O|++7lwMNGZYD`tH+<FP}U) z_UN-`Fa7YBD}t@ytn0eHUeEJ9-}i|S0sw>%DwaT4<;&9_{qBV@K?t#ppTDXdedm)) zcYeGe&n?WneZ_&OAcTYvzV8D72~Z11A%rl@BWT>zLYQ*S?c*<8J^xZ}#5Tug-nx1Q zUB7YH;o(zZKb&)_Zi~PQ01^NxK0}4$vHC_wsa*j!!dhHIQp%v3!Y?3%&>;2*O8^)l zkP-xvk%9sM4D8CeMfCjp$Kv2|2p4nkr<9V`YBeE*!aYnq2S5OxyC?gS8cTNL-BYh` zzFPV0sojk~_&?-+tyUx1Y&M**_cK>L^k8-iA!Kj!!zZ74?U4(At}T$wyIyEFB4cA? zR8idDOhE3lAAT=}&gI1yFD`uHz47>OzuxId6sZqFNSFYs^ni-M5h51y8x6*Em8?j! zhU~_z&rg3}``}IE=FMBXzC@U&$H(GW5<(PnVT1vIVvGY*5Iz8aZla~dr<d;i`|uNA zfAgMAb%f9>CyM*VBPT9jJAW*W6?&1^Q%Xs=y(oH>di1$7;+}BMMg96?524(tvr6Th z3n4`9+v9@}98tssFd&4euIr33%d#S|H!HWB2U|Hp2vu%34jUi}76tu&RWn8@rO9Nn zQmN$gd0p2dXZ}SZsT~<!p669670a^d@bK{Z`Z}f5w(WR4{vZ2zf7iTU&z{$6wW`%> zp-`Zclaq|G)zwwgG&7luX_}PM|2H}~=Z@pl>vc6VrlzJSW2{&#CK8EKskFAX)^4{| zmp^obM%sD=Mul@Omz$fLo0*wuwOV*(Wo2k+D4k9lhN0`arfG*x=R=2e#Jfsv&bjNl d^?IE#_BZZBp&zc#bLId5002ovPDHLkV1hpK5^(?k literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/l2_on.png b/src/gui/qt/images/l2_on.png new file mode 100644 index 0000000000000000000000000000000000000000..7fbc7cded84d6d659a5b0a7a311b37f3c0c0f25f GIT binary patch literal 1090 zcmV-I1ikx-P)<h;3K|Lk000e1NJLTq0018V000*V0ssI2e4hgY00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9Vf4!$gBVW1J6lB zK~zY`l~qk>TvZf4_wVIp-kXrjyx1m&K%x?e5R(aYCAu)sMHlV@McfF5ik3pfZfeDq zLQ!-jZv5#&7sZ7?D}Rs<j7ihZ500WH3ZY~&NkbAdnaRwXdGFoh;*M`_-%P}w)qUsP z`<?H6_ndP{I-Mqj?C$QmuIqVT5Cnt}03d`QVz>r?h*P)FLn$>3!?LVoGD#`rLWuSC z^=vk~x3^cT)f74*L`vBcLZKsKcRWPoocH(lJB~9yKR-D+$xEeDCX+cjI!Yn-I}T%v zQmUW-pQZ@;zF)7`e?B<KX0t;>L%duryRQ3;Z6^{5(=<8f`fi;vrBtUZrR-ME^E}se z2ln@Ws#dqQw)oD@&hYT?N!zw<n{&<>)9E~D20;+SVll%o9;(+%r4si%?-Zq$Wtpbg zGv5b7=bWqT=W4ZFqrs(=+%SX?Vd4t0dbfCI*LpfN$@Cb_gW}3k=GL#pO+3ALX5q=l z<AUg?!Wf2ONY|yF=P||*F%$t2rIbPC_KmcQng<c<`x`m`u}g2g^X12vt*<_L?TeL$ z?3@a>snV2EQvF|O0AR(Fa3Ur&4<Zge@!b0t&J3`YYd(DL-SbdftF@vBRg88L$K4wO z0AQr%-R-{$+iJOg=$SycW&Br-Qk6>&0{|f1yxM<ced)6g;MvnB1mH0yrKH7TF$e-( zH7TW(QnA<lK@hYz__f@Pw?F;+?AI^NA2p>8r%bI2g#w+Mn^TD>v9weG06`1cb~Sgu zz4GQqkG}fd^~LJypG^(4qbec*%+AiXbyxqo?;zqqS-*Aty>HH5TYmnLKMKE81MImu zWY=!aP}Z=yCD`B}R%%D2eYK=NZXf=Z`Mg-Ud=9?<aj6v`0v${w1cgYigkiWM9yWa^ z6>h@vhp#XHODsNf<?4%rb_@WnU3jJK97tV#;{}Ix=8u9>3n2to^C*-xw3APrUs<`> zDK7}t^LK)omsb`q>2u|7K3i_eh(6&xal<gyY&&s3IwIa%&FyqgvEOs|?w|Fcp5dpG zp<1mPLqpVYoXyS6R;%UvzFyj4LVBr%PF0<eUQq#j-)}aXIe=s`$sNbZ=ksf|+UV%0 zdX*ym7I}<%4rl$^5V2e?A0m#7jPS9su~aJc!_AwtQaMGbX_`Wa$it?Oz@DIL;rqVp zy0?P>02US&#>dAwV{B$-rmwGWb#*nnu~FIH_I+P}Lc6QJo4DF0gowxE6B85D)6-K^ zQ-lzbPNx}Tj4{iygb+dqLWp`=BLR*B4GUV)Z?#&DMnh5j2c)!J(SqXli~s-t07*qo IM6N<$f=q=AB>(^b literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/l3_off.png b/src/gui/qt/images/l3_off.png new file mode 100644 index 0000000000000000000000000000000000000000..345206f17d79376685c24ad9970ca157c8b0b25b GIT binary patch literal 1149 zcmV-@1cLjCP)<h;3K|Lk000e1NJLTq0018V000*V0ssI2e4hgY00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9TjItnJfSR1PVz+ zK~zY`rBzLATSX9_-M9Y1j_ubp#;-;qp|OIZBqXF<I8+WOQ4c^7;=%>Ug#%I!AbLVb zmG}`7Nc02;M1??z3qO}46@(fIA(AK@P@0IgPVuW6N41lfC%+%t&)y#nn>^Of;z#P7 zW_NaHcD`?B7Ok(ZBZM5s@jTD-JjNIR002UWbB+)aLdc~MB3J@Ips1p0S|X7c7#K*U zQV1c^?RM++dZ|>hEX(seN-6xSs9`Y1oO8J;t%Q(dGC4RnI5svmG&DpyozC|5b}pBj zpPwHY8OdZaa2I0RwrQH1o15iwS=V)KZf-7-NGvQY6bglSJPvm!u~^J7jBGYrsZ=b> z!u5K6a&poz4ACo`bIy5a8QM{gNk#IJ%jKq~rYy@MuIn0x;W$pa-R^d~A$<Fn0mOlX zj%k`EGq7zNQ%c+Iw&OUy?=!}NH}3uR{l!ba`kZsl8DrAatzZA-o!6du^5lIFKJ~$u zSE?<lUXjOq-}gMv_kBt!4$SfiGHU>^%U_+pSm|(~?su9_^x@||{kn8x`OVtfFQ58w zxubv?WI&IENJCKOvf2P3o*aUFLgS1pP~3C!u~!~Kj@uOa>GK~ie(`y;!@1TAT~M!_ zb0U4o7=aD|TmXRJy|8xO`W;UOYyE!h3XGhN9+}lHlY%iOD(@<FTnG??F~*LVlqR=Q zx>2=mE`RjK`it8?ok9Bttgp)gKV)}zmr@!aBfVgZxj+D-+x7+OLCkaa%v;snJ0+-Z z{_^wHM;<sHf;7-~c6M++pO@=^dH~>@a}a<)ZU+U<7&A_tU0PbY@NIST-4ly1T`0F$ zsP+SWczBoq0AoxID;3TK2(FrBzTSSNybl179)A=>DK0qYe?L4pEW;3$3ON@s#zF{$ zQ$YW$+jfL8Ap{^Tbu5D$wHi<6j}0K^eD~Qo(4S4kK#o$GwE7N=G0`-QF(zHh$cIow z2H^7RXD%PzIR5xIm)_4eu08SetA{)HzwpD4=k9G)8%IT=k}tgx=}tydn_~FvTa3M@ z(8X?VUA0d<-*gt6o=<@cW>eO!o431E{SQK;f)GM%+m^##rT*ZLtpg>~!$<9xuQ%e+ zC_#c(c1+PbY81}6<2ah85nb0!(<~GUu~@ACmw?`42LRUc{MLVbFYR{QG)-OCiD4L9 zTU&&XbUGc4M*nF>{(tFoI+kUX%jN0mX)-=OZdumK%1SbsGz=q=NJJu${u$dpc>9G? z>UmzRR&!l<W@ct$VuHA?TPzmS>Ga0N#@gCiqtT$0h8j=BM-3C2_=J#5CNnxZS}Yc4 zXJ?zuCR$xx&15p!Y&IT`M<NmV5r=xZztKZ%OBgjxlY`gy{k^?C+qVA#E%|aVh&m%; P00000NkvXXu0mjf#%T+; literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/l3_on.png b/src/gui/qt/images/l3_on.png new file mode 100644 index 0000000000000000000000000000000000000000..d28d55755f9adbec98d7f0aed848055801dc09d0 GIT binary patch literal 1127 zcmV-t1ep7YP)<h;3K|Lk000e1NJLTq0018V000*V0ssI2e4hgY00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9V|Fa5hMTr1N2Em zK~zY`omD|>8&wdU|M&mZde<=|S*kcF!Xgrta3M+?ixUwC$fbaK0U~iiq7oMn;=rY- zf&-TxdH@6hi7OHua_Iq~qEJ+kAlESo0t?w~R9x4sn>w}|XS4C&|A)hmm-RYSz#P8D z<9RzXZ|2V@`FtJ#n$4!?c|r)K6e1Er000r8FN6@K6s1(3h^XDPPY5A|aLygaab1@X z!h{f;o14XAacgVK^E@f#FgT`!KSQCE0)SGAF=pGg>$-DubJNq)tkr523WavNeFDIC zUBfUarNj7tBZw%3*xTFNXtj#PqU*Y>Ua#-&?#?^T=;&x7kzkC)0MW#wQNzD<ty&L) z!1w*s_V!P$R<&AXwOY+}-3i-HCX<XY!!Sak|3~^k5ZJbDn&uJDYcv|n_x%$9j^kLC z6?4^%`cJ|+=bQt;Y`44Nc}z;lEsJxmI}^&iKQ{`^k@@3~8hu&-K<(5oUHpEnoWFK! z>iL&X&OenMF$R**6fwp)=cp7_N*RWsheVH~KJi}Rn@f99mJv}R89RRJ!}Ci^U%Vxj zzI^w)-vR^;(WubVFpMAwXw($WI3n7~F_>^T4oKpW+~TuO7`?7Y9X);K1!!^vjAamh z3IJGaNdB%701(xnvDd7Ynp$n&DX+rh>lQ%p4?Q4+upkJ+fCB^9PbY@)oAsOR?(JW{ z{i^!n(x<t*<?F-uOLGMPbbWnYYltYN40+ezALs<4Qi@Q~?fSmofcDj&FK_Hisg#mZ zhSY~rC=}@I>}-@QeJZ680T4;VqQUOt&nzy!^3J)7U%&a#xsNW~5pkdv0LbNXOk1Ut zhctjhTGp3#?P|LQ0C42tV?e4S21I8eN=^_2EZXjHH4;J;Bq8W@x(^bKAvBS6pxf#| zVmxU<;QesnJS3lU7zRPSnK}&9qL*qkxKaw31*@OGx7r6KpFDH+wejBV58nUmz%p_2 z<4;~q-KuO4?xlfi6>VBHg^8!%$midV80Gb~E8Ce<mw$Z8_k{$SdcbaO{(ep3@TNSt zUx>^!&9ZHe4f2kNjX%~J!@KNeY5i`(vP_DyT<Xe5nxUfKnVp>-%XOLSx|K?$H#un- zhF%GwYp91M6GD1>yTbRPmIEgH@0U`l*XykT933BL>2$hSELJL&bULjg-+v3<e>3Zx z>h*e;(sVk_rlzKHx!m&dGITm~gjkjpQWUK>_5==xA%qAa_V@R%C`AZaSXjtpGK^9> zGc#jZR;g6_<;IQ9)|TE4(N}c1phNAZX{J)C$1<60Hk-|6P17VRD=U;z##kbe;G8qY t2qCduA4~R7ay0cq2qA>;`$7mr{0q&LBtDRBr0xI!002ovPDHLkV1gb~5Ul_J literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/l4_off.png b/src/gui/qt/images/l4_off.png new file mode 100644 index 0000000000000000000000000000000000000000..bef390ac4082e50f4934ca6b947e4f558493daf2 GIT binary patch literal 1103 zcmV-V1hD&wP)<h;3K|Lk000e1NJLTq0018V000*V0ssI2e4hgY00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9Xq?8l;Z#Z1KdeO zK~zY`rBzXABUKc=Z|2QRY9<M6(_{mdQrlAOh7t<>68d2)ekgv4;D?|q!u|>(vhJcT zg2;lOBCCi9>W?d8L01v{Sgh?zXl<#mHDqHpD;sT+<|UKNWahr-$7|kB((Z!m{dmmW zd*6NcoqO(mWMg9k02pJA<8(TmAP5K{aCaeuD2E|WP17i)BO@cRSS%io0{|65)M~Z8 zy}f$9?l_L``<kW+Apk%KA!EtkV<W2bq%)<|w(Zf;(b?JAWHLz+u}~<Cjg2iYFHcNN z$TRO-7-Qvfd1q&*P$(o434Lj4DH4gStgK8;O<9%&|4%H-N~KcCWU^AJG#U-9*=)|w z&u20j0N|W+&czXtN@X2d!y++Er_<SNmN7;dW2sb%G3L5%5Cjr#g|9?YDHYICA66<8 zrPMHtbUJ--aG?3V@49ZQ)$%+K5fM>l@%QF;AFclCB8HVx5K#oR??3r$v)UcX9T8pE zbsVSH>mi~hcOv2t8m;1&Z+uwx0mN~#{rQE{ufO_N*OMuSO@t6c41&P(JgSgYx04=L zGzkwzb<TMR7Ku`O_nRlqUIqZ2=n~8!;tC;T(p1wlSx-geKH2*z4Wdt+8*e`Q+WWu! zp1kyA4SWC#?l=yYhlZIDE+z^AAP`aOmr)2o!2j{W3zyG*`{{J-i;^!mAY!=G;Rr$q zTB%edOyMRZgrEQb(Q{oM(%-)N!I|r4svn=a@#k#;U;ucYcQ@{r%Vjz~KCTKf$hpG= zct0c3Exq&dB}hE>%1hT;o%Yv1-F)P&=T{eAJpbI16)KF1GdVd)C1H-<PJVFCiRu9B zq4%!-%&G2r+|-@<Yn#F8cb_?RQb**29Y6??Xj3_}2Es{{NeukjezR#H0)PNLb|QH) zlL5{(0s_Ru!w>kgGbiGH<De}<q#PJ(x~|J})M!0K$&A94vyWftgEji-SF0EGs(V-- z;Rixs{nkDiQG}PKFu4yob94YqJoPr>MYRV2Z|?5=<MnqE>**g#`mO7K?03RgOJ}uG z(=-`lwrwloOGB-=yMJVu-02D4EB>}A&kj>rCC(T#O_Rps@nW$!Gc#kF=CO~%Jsznr z1;TlFo>wduZQG`qOlEs~+c1oHJZ_riv6JsVNw3#yG#aH+DVNL9xw*Mot+uwdX4`f; zosLGMl+yc)8w7#lIMr&k-EJ=|EM&7;lF#R((P%!O-`d(L6bj8|b7;yBUH=}@DW!=- zVtRTym&+|KE_S<JvcA3^i^Wo@R3s8H3`5aBJki2Ik9}LzH|IPE0^j%R^?JMA{uj1E VM!;Aw4y6D9002ovPDHLkV1oRG`2PR^ literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/l4_on.png b/src/gui/qt/images/l4_on.png new file mode 100644 index 0000000000000000000000000000000000000000..e63427d93bf11ca89fcc57cc79c1698ba0a7fa23 GIT binary patch literal 1084 zcmV-C1jGA@P)<h;3K|Lk000e1NJLTq0018V000*V0ssI2e4hgY00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9XiaJq;&uQ1IbB5 zK~zY`l~qk>V^tJB_uTt#^3vBSHKY?VLmTKyAp;J`qc95>Dt6&wcC&UN?nF^H3c7Qc zg$q#zMY<7Dh7kl;PB;EwW74EL)RwVOrg2D_Hlaydlf0LAe`ax;H!m-51kWOzoO9m2 z=Y01&=a5RJ0s!rHyVvUlK_I0hga7~lXstut2pLJ#h=^e@B67~BrlxYa8~`w__3rL& zy<Ts%TK#@s2w^_fTEm18Lc%Mf0ilIbIz2r-H#g_H?&9JiJ2^So*x2ZFI+wN1WV4h~ zL^P+s{}DonQYr`n&-3oK+w1G=*=&|I8jWtZd&RbA3kBP@8DrrGu{2|VBtj>I@H}t& z=xD9o-rL(_hlhu`TrQu<IF7>@qm+i_C)OU~6Ehl-Qf4w4&iUM6&}y|<uh+Y*wc|MH zbUJp{WU`?p>Wb=&F;o4sz20`ek4h=avKV6+5kg4s!Cyc9abF=CCd9lH`kTM}*7#Q# zuOZT7FQt}c0RRdi5K)f{0I1{jTR#tsKIy&x>vuQ5{W=(-A3j5f7$W+<&ti^Hrp{#{ z?^s%^33_-BYS+Ih1AxV?L~1Fe%$XP^NmQiLkaRS74{v|`)w?UVK6>SX)FSa)b0s38 zlu{>2w5G>K9sGIwv$fYgd3jcJngIZrj0wS1N@1;5Q%adXMlm`NZE6fHN~!kdoiAF~ z?p(dF-8@19oU$+=8m6_DQdX-~=DKcpzv(waXRQH7S)3I-JotX)M{wL5AJ$I2L8X3p z32vkpUb^=DGc3{sCMQD3($W$WLTJSB9mb9$<E>&ZzWwD2P%`i}XI|;ecjVQ#UR*fW z?R3R>;2A!IFiL4+e=C>*aeUmHCCWT4v1ihlnWkFv6ewk%FQ#PSJkq|@8Y0~ry@naG z$E->zU^bLLf4@93IhWr1;8ofjjAn}p0A%~0hnx~ZU>uXP2OxwgrPO#M7$tw@^-AT9 zh($IwYWw~OK$3pp(;r~(?)E`HM)?q4g2+;-)DGuQjc^Zr2Y=TOljiVQ?%Lb>eJxt? zhzn=bI6XaeE?&f3F4t@}ecum)AVx~l3Q<d<68+U$3n7NXVI9D69G1`LtJUhx&Q76F z2p8Lbtd1vn&7?GU?C<XnENgy#o-HgaxURdpx~lKpdk!&`N<C>dOwRh)CJ;jSzQ3*% zA}%j47mG#4Id@&xah$EKt<6TG+vx;BFu9RqStnM&IiH!CdAe9El}e>jiE~cM<uW2t zN^RS=EX%SiGd~j-TXeA~rA%0~gQS!}5DbSy1JNV0Yb`Ns)p=e30000<MNUMnLSTXy C9_T*+ literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/l5_off.png b/src/gui/qt/images/l5_off.png new file mode 100644 index 0000000000000000000000000000000000000000..1303ed2ce264f2d335f79e04fb5ec6738b0cdea4 GIT binary patch literal 1113 zcmV-f1g86mP)<h;3K|Lk000e1NJLTq0018V000*V0ssI2e4hgY00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9T$m4_y7O^1LjFY zK~zY`rB+RB8$}d;vpeHW<BjbQ$E&E2Sc*AB4iSkXRY(z`3KEA(l|URS=%EMBaN$w} zlmj4Cp<a3edgR296u6Y1E6RZoIY}dtgw%?o2&`<A^=`fP?#|5Pu<>@B1R=HWwEOnW z`@Z?!H=`x1tE+?%$8mh$_kCXo0RV&$I4j~jAp{XMO*>tn>v}q!Hcc~^%ON5~MBBDE zH#cqD_I*DLLqbTrUd2#*ommhkDWwAg1H;3^6B85pe4a*8w6(RB%jM?g=ElaxGMNlK zLAb8FySuxwv9YqUQmIt*`T6-&Dz&h%Fg`wR7zR997=~e4Rz9EK-`{UGo0{i&larH{ zWg#LW%HBwl>cfcw^)<#Q6bj{X*>N1&Y&Hvpg6DaiPA7_@Gv|qjr^lNllO=J6F~%6P zEX(se$~kYh+c5=o{o&d#i+e*?FU>HuX>|1K4?i^m2>=AbPWHL0mny6mxYOx`VaPcT zf<Ozy5D|qC*c;9J-`u#f7j`u{j?nw={SQC+^8gWBz7Rl8E<*$WAw(2KLI|oVnD`74 z`_g$h->*w4RL|*}2JqGO4=#@ygb)y&M&nQ_haj<O%$UY6i7bhlh$r<%L_i<}yrah7 zj3r6ZyD)AQBWdc;V||1WQc8&cfLw?;A16f^0l-@?U%7Gn>)&e!$CXlw-m*j@TCdmR z>@kt<HaQ{yMnTYHm(=-N)qA)2!_}YfytZ)R&D)FDFOI8{s!i(kIxQB93Dl#_b`6J8 zqGCP_LXznxZ0N;nH@Ba8>e+X`edC39M-44eLv2zl7HKR+V%y`UF&s)EM8b;@0uXu4 zCL%VE9#C@_f<LH~LiBJagd|g>k7z2C0RYGVM28Ptm&KxiHjv9Q*>O9VNuML_gT*gC zg$o}&eGWpN5W<8<e2G#ON<DR$O2ggvUb)-d>d?jSfBd{C|9ShR*H^g!0J!qm#+R?+ z{vLK)pRk{lk|w8Ag#m!k%O7)oGchtDvVL#P)}H_Epz*L1Kq`|rVehYPyDOclt)^+m z-23|aT-P;CGrqwS3WxVM4twPygdiSl@3m68PNZFL2kIe8W=06%oO_<f7^9|X)@rp< zsgz2kRB?J{poD07!C9Zw`XC5uwOS^Vp(7(B)oNAO^=vj913X?N-Gd--9H&;R&CJZu za=C2V_R`XlX_}U0_4oHP#vTuVbKYvT8jXhMd6i0KYHEtCt*se`vAn!otyXt-b{xmy zoU3=v>7l9CQlA-P*=)8{DosyM&(6-a+ikMGzMf8}2L}fkW0X=|*QJ#I^-u7>;>5R2 f6h*G<`o8}!dd^2`UQQv<00000NkvXXu0mjfVG{tM literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/l5_on.png b/src/gui/qt/images/l5_on.png new file mode 100644 index 0000000000000000000000000000000000000000..d77e64e18edd5db14005f0d060e352c59ba245c3 GIT binary patch literal 1087 zcmV-F1i<@=P)<h;3K|Lk000e1NJLTq0018V000*V0ssI2e4hgY00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9XVBy_0IqR1I$T8 zK~zY`g;vjN8%Gp=GdsI0ug0R1f?^#ER=|hSh@__2sMxvnq`x8*N}-fODU{G3^pH~t zJr{b(B{cD&$*raZL(@Yl+i@eC*okCXi@3HU+j5lE%3AHtydK6`k0d*Jhh_Hd%zN+q z=JCBH<#L%2vbVSAd0r3%hzPw#2th<bh+0Qa<y7nFl~QV&Cg(hp$si&_#Ep%Og@uLP z-CdP{QVIZ4%Dx18roJL5rHF`#jIm@gnayUWr>Doq$62G%D3wa}di}BxPAX*>2BmcH z{8^^Ml2V3Y*lxGW&z{ZC&zq*nHa9m94-aP?CzVRYVll?pspk<<6{w?$LPr*cVW-nc zG#Y<38e3ai?BL)aolcK94(FUPW*Ek)ybo4A=qH4PVdyxHWm)NVyI!v|&-31ul5-x5 z#m<7?SKw>>j4_3N!t<)W&j7%(EXG(wpTg_bRu=c;S0*kPdKA%GS$Nb85dZ*#fRA07 zxWEROGz`NuO(6vJeP1V3Ef7&Q7ia(I;43F0N-0r@hqv$i(h!_;%jTT(<6hBBl}ITK zf`EZ`UN0e@NW=NKi70ii8M7(*=IV#<XG}^dblpm&)*WCh>SlHprxFpMH#7iB2>>s) zD{K4Yjm;{A7(}K+Ji&DA6A}Qv|MJG2U;o^wH&6TnCZ$9~S}K*)O7<E8DvUj!hR%Qf z^X%PQ*NfxghwrZ4ezYA0iWbr9($W$w6bkxf_AvpySg_-H?e<Y<T`Ycj_r^!}@0IFZ zdE5n3MvSY?Q&Uq+ol^-<O8~v?<R9$&0I*-*;Rc7W!zm2*TT~8Jn$;Ht5hZX4Up76@ zbzRqWU%IUj07KvF_y7Q%7x(Yogo`s7yC<j~hcU(!s7O>#GO-vu`0?upuOJLx`s&-O z8E}8PcKshA0RTSuWcG`h!zUFTt_l@h71OckgpAC5Tq=F0H&|_X@jv>`&EJ1J>UM#} z-x?DCu01{);4`{mLI{h;;}t2BLg?y<h|ixqe11w3Z?9CFj%kAEthG9k@apqKA!xN) zL&+o?9v)s_U+<2LP)ZHMi1z8~std2*a=RLhky1uNErjTHyMI%9>D)OsIy$<%yj-nT zv)QaZ$#jA3n@z6~VO7@7&Q9Ajv)L>g8yhPW3UhOF;_1`(2(fKDqUenis&7LWhQ9AF zAu`5_#bPd(W43KiPEI<Gv%0$axK?X6o4)V&)!Ro-M4CQh2_cqcB@&6ZbGdvzpU>wh zrKDUgQ%WhNwryLMrKs1XO%JCJ4SgQytr7%*`nQl${tpKHGnR1gt0Vvb002ovPDHLk FV1frz_n-g( literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/l6_off.png b/src/gui/qt/images/l6_off.png new file mode 100644 index 0000000000000000000000000000000000000000..d5e7ec474e364a66ee009cfbbcdeb50e9be651f5 GIT binary patch literal 1158 zcmV;11bO?3P)<h;3K|Lk000e1NJLTq0018V000*V0ssI2e4hgY00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9XKMF#aRFV1QSU_ zK~zY`rBz*M990xPcjoR)k}*4xWPg-4NteauhlQ9X<V|QISdm8jLj=VKAH)}Z6I4(T zLC}JPf>2OFM5$=2RFwE)Kr8__4bcr7*Mw|0x^4C+<L=CCW@hKky*^C#X0oe&XupTy z%$alVoco<~zKe3X9Aiw^^+uy%Sr#FLF$MsFAOHYk3?T#n0MKdp2*zNHdwP1p;cz${ z1^^rig{sx+#>PgaQZY@_-<>Z&2>Cy|g&hROSW%QnBr-ZWIxsMRR#sNh>9ne<sZ?rk zaM1tfZNo5(ot>R*HftEh^z^hiH#Zjwg=S}G6N!W@%W!9qWjPv+_V@P}i^WExA=GNM zv9YmOEXEk40k8n*QM5U^?fU^B8jX&OjO_02V#6>Zk%(a!wr%s0c2+M~IzOh3dj3@u zMOl_(v6yL^g5x;0ZR@)3IF9FeJfq6mj~`w6)gr|6Jl{_U@jQ=``nAjF=T8hJ&d$H` z{-sj$V2Rg)<2a2*!?tbPwguO9{iFGba5nVquipCjZ<hi00{~F-hc_R7bU|Op<g%Y% zczUd-=^hfu!w4aS5K1ZLthF7#OBsNBdqhSlJ7mVn{q*9eg{!3xMxpMayU#p3V(nG- zy@L+s%Xwk&k<<bP<tGVH|K~5~;rWaAxi@My1wm+-M`nue%d-&xpp7`+_G7q*Qc8(l zTDP7&#lBg1Es;zn5{U~-8?M(5P6MSB7YYTxT)`{^LGS<oSkrOn;Rn=x5B~b)XCD0d z59{5}_O5+<Y~~Smap}47fgmj$g+f6X9v=47=VTpJf-wkmHDioY*WM-Y>gA`BUEA4Q z^Y{Z_K5^peO`R`qn~9;JA<P)_JTKV12gFeZz$m5A>TW>F@Tt2XTe@DZVTANjai399 z3i;=5(<PrD0b|T*3O)h#f~!?)HBHkrP21DzP0u>{_&NCErN#AKN~v|@_Yc1-zHt9> zz8#+lu7kK$LxvCvP9u{PSbY7V#TJYGr!QSOC#zG}mp&OjedY}S0C@ZR-{y~r`KlWn zTAvJG!!bgrv)LJAgJ<6%<h{cwXWn1gO!c3g=E=t#eZHdGU23Fj|K`R{<^NOxA%rDK z(sjMJw>PLKjIq7#^}SYHP}b|kt&G&ANVrxl?Kck?r<C$YgplWXhGB@Jh{NG<KA%q} zlaeF_Z=bfy;fRD0v$lUL9d;ZipU?O8_2GCtzPh?9ilVBjk|e<$quFd~nwHP!XJ%$_ zDwQgi%gf8lilW5haYa%5F1ig6LQK;vm&>MUPEJmakB_5FCL_yoI-OoyTie>&s@Lm; zkWN`|8^z970FWd}Rn=rNIWaLYH8thBF52AO?C$PXRaI=kZ=udM=zRT8r{D6ru3MJ% YFBzw+rRXG50000007*qoM6N<$f?#?lKL7v# literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/l6_on.png b/src/gui/qt/images/l6_on.png new file mode 100644 index 0000000000000000000000000000000000000000..383d3dd4197ef1661950535f79b3fb46de0dc4ec GIT binary patch literal 1165 zcmV;81akX{P)<h;3K|Lk000e1NJLTq0018V000*V0ssI2e4hgY00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9XKMF#aRFV1R6<1 zK~zY`rB+>NTtyT<Gk5Oo-Jfi1vPry##YTf5i=i5l;MNwa=0UL{`0j%*6<>m{D%A%G zLJ@pYS_O-sh{b;~Py<y-T+(c-hS0Lfrp?bLZko+zv%7Wo?wy(A!<gyaO)3G;!{yAm zbN;^h=G;rt=`<qd^Z81p!a0{xf=>t`gb=O!?MgvJzfLK&Z95bSb#`_lA~Q`hlgUg> zOsuV~6^ljB^ZdJ^Q3xR_od1>DPY97xT9(z?+Uht?B9Z9r?Pbf$%j4tY`F#GNdOg_I zW*7#gw8?)zqN01ASF6=#R#zt{CnJ#vTUlAz+S)o|+Xo%Twr$fi{XV*J)wMsR)^+WO z$T_doYAuDrbUvTWX4(4sdV72O-N9fu9A=CehOs9a`|Lmn5ex<`%Q{%CuCA^!*L5G3 zG878gw*4Pn?=w1Mj4=iPhbxs#waPf>mSvfysT$XT%1blTo8e=R+{YS$qTnt}Up#;A z`;~hS^*{Ld3(pQj=)cWrU&feaSwaXVgrJm4DW#MO1eHT<U;5(bM~@zs=r0^=mp^~| zZ06X9=fCWb<*TV#CQt%u0CjyTX7fR*B_f6+QRoU<J4Pk$+O@O4ZhrLft6idA!*Kub zaCd<0_Enb#5g8)FUa$&@03aHTH?RKyCq~<Iv)PgW!zko)d!nz>7>2>5l;~@!ksjD^ zYrw5#`S3vf!dIVu@a-f3JpamTPsY2A9m+N(;GEM`DkY^<?f4Y{1R!!p5K*8V?qEN? z`&Q`bk;$p#kLTX`=Kax&OWQ&SA%xzhL`s=TrRdPm&~DrT0097y`0OZoZG*#$r=RNN ze_pzhkHklxxM$&(*95xO2L}h4S_mN&PaE+AsgofB33SIpuy8Y-JwO18*&7upSs;M^ zJpcfpo1iLaL)C}?AR!E5yHu%^%jHt3R4P|ER-L0GaN+djr6K^hn>W6m*f{Y(hh~T_ z|2FXzUX;?N<ixZgdFGAeP9NdE*WY}}#{0iJbLzR1r#=AyfRpcimT0Y9tKKGsx-=@L zVHiv=nhw3|$jehxBR-VG;+5&YHWrG99{cT=@#3wz8NSObW&g<ht#7HWT|ZeM5STa3 zwq4QJ)0fwG4KhMV{`zduZfOZHzL=@FLf6|w$8x!RpskHYqtRS0SFhLAhsiIR0Ge>h z=v7OFLZMXkcDM`v{hV{xb$_Qc8jUi?agxd8{QSJ*I12s$DN@Q@E?2XxSS-eRdU_Ix z#Ms!FmrnNs*tWd~HSaK%HC*aQJ<oGpH-%_f)-%VC$6_%?DIFLX2m}H%Gc#8g7mLLr z=Uh*PJ3aNdR-h}~Ez62TBJrM{zP`SAJWeSkb8~Zq5K5_OntJwY2S0iD{1xz*4*;BV fA%yF?>J0t?XnQ(NIeZ(%00000NkvXXu0mjfB|9uE literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/logo_ico.png b/src/gui/qt/images/logo_ico.png new file mode 100644 index 0000000000000000000000000000000000000000..d40cbdb2a827b91e537d23e4282520e5008f2427 GIT binary patch literal 1515 zcmV<H1r+*;P)<h;3K|Lk000e1NJLTq001rk001xu1^@s6Ze>W^00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)CmU_Gy<A+T@e5P1$aqB zK~#9!y;@OB8)Y2--G!1agmEma?d)8y$%JHOa?IGqv5a$3mJk9RF~-D*jgE&s7}<lv z$0okWUTk9aBoB4-VeX*<E`)3mx+Nu{Q#>MQs9R_?NZXP1a6xN9&xej~?Ol8K9asKu zci-3Ve)qfI_y7OD|GyLrwz#+{#l_8{dz_5{W3Hu)e9o>G6SFxfoJb=ae~54*4Iw2~ zoX<Nf;H(UI_8`11hp9aWE+jKjAR5Ei@+!pamaYdgW)r+Eb_}_j!Py$Assb018ENR2 zfN&yhsJwWG1;Ji7Sf-9L6u6kpN&Y)a2t;G3ruk31;O}gu3;`}AGm>v2s;Xb3jI%Nr zd-Iek`;;1J{@RRg9qTp5Y(n^*S1W3tG8}Z{exSCdaM{<?fOlJ-0|3k=MU2cY83Mk> z5YV+X7&+C7f#XMDt2dXOc3__gBePmv?H2fJGZ2y)NeMiqv=Q0QZxS&b>hHk0WA=)3 z1}6oK&c}4gCjLQ>EP%-v_uhz*$)j<<DrnF32%`5_bq2XDcyB~x_vvRZ0&_8m)JLCp z+Ekg=3wp=Gi8O)>E0Q8`F`JY8cNY!y4tG}4y5yl`L$`i}n9WHt;Q0Y^w>P@FUUuxO zU;Z$R1TnjXz+9}DaWR{d#+G${&eS6;rZyCZK77e(=obt`V+Gb}00=I`cNJvbpHY@r ztF-|mXE;My-y!%3@ReOHSZVWJI@xR}_#L^>adA^JA`kiI=gQzi{T)RSRj&yt5pi)- zqIGMV(3hV(X2;rvZk#{Syz9q>6KT*wDzj_QYXiKdskVAEzUbx<ewzoZ2lTU^6hX(u zzjQCq=W=3gfUlUJC|Re|0%`Cy44-uAmJ5YXzLto8S+@_NvnN#Lp*2YHlk-64Pon&V z*2VJq*9`%^!~WU;5BE{+>xtPd0^qeZ2=#Yh?A*)5($J#)xwkrqq*J4H1OD{JD`>Sg zRQ2TZ=@}Oem`xa-7F6fbT9^)ZpQt)$(txE3Jk;Ysr_*96xW&{4Jl7*-gO(QXG|SYL z9dsYH8@35cbC~G;RrH4<psq~e@@x#r$5|QpK9{p>C4l0u&L|%qYHP4|p<A{QN9R{? zGqH~G^^Lp>%WZ=`V#U7$on)1$D^oHTNFT9c;Vf5>W%6+rhemG$n|~Ld(pv1GdB;Iz zxA(&HMW8>PUIO*mw-}tfhw-HqAoU2yZ36&4I^0A~yF%Xb-)|`#|MI(nglzR@^szQY z#%a#RD6V^va}?g1x-yk7E0nx>;Y?X(4PBPoMt>-R%d`0`u*cD)ShAzbRZTmcmi(u> z8di;J)z}Ba(*iu#BN+VQfh=nBtc9X?G^2FLJv4e-Jrp<YubOL&-e1j2vP9nncR1vh zr<$Ylv9i)A+EDfT_Ov|bd(rt6IL}(BN^Y@|z1P&RXP|k91w3n^iUN@Tw7wMc;XgXh zswEQ8V$WhM0Qa>yDc(UIA;;G@bfvPpVOw6w>f&@UR~q%yjI`dum`w=wy36M(oUM@x zbhVS8yzf0AD<UobPPTqmyR6VJOR|PM&6KZ=C0cmo`(@3ae{fRJ<gK1cn1!#+NomRs z16}RltOU_8w+()BUKRZ1*%(nRG2hhkC<aKX{P8F!@mFVvdp~_HCoXc1qEz_KN*b5u zekH2fdRy!W_PWb9c2%2KzKJ<0xDemlAk)T{Wm+@vCuJ|me|NF!O)SQ2LZGW%QPaAB z1Nk1kZz5`VbGBH|+MBe*t>|z(E&1;*8TJCa!vg<lS5a`O3h<|8u#6O3h+{0aiqd~e zs2R)D!P{)dkf)ib4Q>eVQW=F4X~e}%2q{sv7Z|e%oRtB~)PZ+cbc21?{s(<VKf2od RJ-Gk?002ovPDHLkV1m3a+Vubc literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/main.png b/src/gui/qt/images/main.png new file mode 100644 index 0000000000000000000000000000000000000000..ddf434171b5f5b93f31616615a603bbb593b4475 GIT binary patch literal 33448 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 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/minimize_off.png b/src/gui/qt/images/minimize_off.png new file mode 100644 index 0000000000000000000000000000000000000000..ad531e82f19c89cce2944b8943571cffc4788067 GIT binary patch literal 768 zcmV+b1ONPqP)<h;3K|Lk000e1NJLTq000gE000jN1^@s6)D-@700006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)d~d<3n^Js$u$4~0*y&T zK~yNuEzjF-6IU2O;q~v?v&WwCICcmOG$wLGYH$*YQ`)MET0sTk72vv0($_)af;&!W zY$PN^D^(Gs#4)KFLal<EgJXw@J&tGhqAclqfF<>M9kAHcvbEK+&DR@jH=A^J{>Ivr zsnRr`Uz(@7xWMd%SrJi)fUK;nU@bg*+OX^O2IW$Tg|C*FjLxAH?EUkejkPu2?7XFR z^CsUdFN+d|R*u6jj~?0e`}etV{RZFO`jNBMd4hZ%tnjhdrCPbbuaE1j-o3{tN$d~T zu8V%tYT4$4CwyO>rB;oI3X0I~BS(jTB_zcb6ib&P(#|ZuJ$%CXa@p$b%}r(`=JJf8 zC@q}MJCeQuQJ>z&sN)d@HQ?fTO}{;6XKM?m;<`UC&3Md}EqQ+zBL`^PLy!BY^blvX zhZ=rBP7ct@Vy)rT>v!nMf8R2<Tw!WzNG?>k*$^j_M;Q+Q#tCEZ5Ks4TbwV%BQ22cl zJr!vtPiexULl9=rxzk{BSZxpi(gcP+o-rsBQ~W5LIiu0p$|BkfFu4MHVgeQ9!OMd- zAOh(KVhtj=>ImcRlKEm0?N`3xc=!NJ3H%8Na*zqY%Yp)u1XKzl*knvRhzTxULrqs} zH1~XZgArqsg&+@M2!0lV;D6x+*7NBPM{Ml*Ojm0tN4w~SJ3M>&7oGh>MyUod-~@mV zPKFaS`$tDSf3=O8zl{}z_B>DKuY7I)5XHmikD1%;QYz1J>U0EFI5_C=zWpby<`D0* zpSWDRN~hBiSzTR4M2Mou4vu5iU%p`2U&Ee!00A$14kz;^3s;u$Jdbv}EdbJJG_ckJ y;JU6Y7K`}4kK;Iq2uYGK7!2rkyToxUeCj_7t^5VYGKMPv0000<MNUMnLSTX&rd<aB literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/minimize_on.png b/src/gui/qt/images/minimize_on.png new file mode 100644 index 0000000000000000000000000000000000000000..20bb4e175433a92bef6c12cac6ac849e574e4229 GIT binary patch literal 761 zcmV<V0tWqwP)<h;3K|Lk000e1NJLTq000gE000jN1^@s6)D-@700006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)d~d<3=l~d*ZKee0)|OM zK~yNub&+3BQ)e82pWl1lb545>EiH5&l}b8f#RAT<e=%fE7mZ)R-FUOlun({gvzsNm z@J>KRYhq%yC59-IQZYkZGp#^d3WxTTo_7~+ciWRZAK=L&l}ZILnAotrT{pGoo9xtT zG<W~Rn3!CCf)6jvQktJ*>f)4$C`3S3S649x9zCp@jY^e5KF{1I3ycNlPzv_{dc)@W zIxlu#QNDGHtBZ@GM4^>s@$>Ss*|>L)n>TLq#qF;-TbjjBr@;uvhiyv5i~PD$VeQAC z7(|h|cKwFv7xlWS-G9KBr76m#fFPqtnFHjg0~k`on2ciKQb63C;<u#-TqqQb-r3q> zQbI0II%K7e)qG9VbwJcV?L*YbfQ;%fb3xN>4B6e@#wyzO_Y0FQ(*;A?+ryC-+8m;X zT~yq`8tkL`Z;{g$S{aOSc=r4?dhFdRrWcFka(zZpit)P-`7c^Oe1)we4#NbQCtK)T zpcxz2q_P%%D#8CTlFgx<knFK==8Q%si}Prwhcl8vkB(xVd<SkCv;!g#4<PIiA9t|T z5stk_;-h)ASNxol{(W%r;EjSm0tp}7Bq$(?K*b<}iH3x|5P#-6YNAx8w(oJ+8!&W| z;HM##0xt=^|K8Ln#`Wm-2W;+pOq9wfOWWwVZ+P_d51I!Z2C)Wl!14hPtOTcM4vvm^ z{A>p`dj}&5?YgeaUir-YE{dhcD@^aT$rq*>{~!P(v|3HxG+t7#^>NRC%jNQ?G@DJ4 zwY4=wgdhk^?<8d7=`ZxV>zLEGAmAp?VI@9h?#d#r>(Xd61VF0QD#jQ9Y}+>3Y!=V+ ruq+D^A&Me;y&mm$n=lOJ-#vc=#2fpuid`MJ00000NkvXXu0mjf7%g36 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/mute_off.png b/src/gui/qt/images/mute_off.png new file mode 100644 index 0000000000000000000000000000000000000000..42bf8f657c0b094768097ef2622a68f6fcd07ff0 GIT binary patch literal 1522 zcmV<O1r7R%P)<h;3K|Lk000e1NJLTq002z@000sQ0ssI2k+a0b00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9TSc#JQ)B01%F9I zK~z}7y;o~&R7Dg%Gke)>i%?37ZBZ$$s01_-13qF=c_>k8LLxyDtwA&)Dhb4hB>XY{ z(Ec(pnphGNK_iI<QnY`Fsl-$iiI8oG=+Z}8kuIfl+wQBo_wJlC<Bz#qFZZ!3M(4-P z%$YOa%$f6;@3O(cK`CXSP(VZ}rBVv6H7O-yOn<dpDW&_)S8M87N6oG2L37W#w^K?* zA`v3uoa><*Uw0g#GjyP|jt1nM>n{KphEZ8r$vHPH%bJ*&=<n~(=kr1c_`jOljQ<Fe zb6!<d)!f`XfBt+Ul}Zf{53gOjw!XeT7K=Ie=eQ`)jgBAOj`jH2FLyh~9R)XLe^@{{ zds&t>K0e;t+e<{oz`(%j)vIf3YfGh4u~_sR)W6shpMe1!s8;5_!fwG6`5q|0(A}hz zhGEp!*0#2`o;Y#B$Y!&MSS%JJk%)uq<fK18Js0Vo^_%J*y3g%d<zMbMFU)Lr-g+(z z5s3&93xy(2r_+ovA|fIo1iG45a?2fwS0^{{=F%k%Z-1F{G_UrxH!s@Nogk4v`qHY; zE=+11O8>fJ=i!XVeYNZU22b02WG2_Ycj=ObhK9z*#>U3R-QDLAQSWXqCvqf02xrPU zn8y$zVvJ?88E%@Ud$BX^plEb=-@S*uN=2noaQNe2rfiVm)5m*?r7D9XDWd>4MZt!K zXr*O<tlV;Fs8k{``E%Q%P4P*SN+q%Xg{X?A=B|%VS|m!sG!JdL*E!X7+l6$TQ+b?W znx^4ggFoUur6_RL9ufh-LuTLcGlO?Ob~{(o-+rFl_v)GpN@`?9gopqjQA!>ow5Bd! zngYcz2MT6V$&oZL06<~@lo=gK17l1_q(49XS?wP>FO8HE5e+G&_L7vcj3t4RKkE=u zs$tu^AFf#Q`j0QSHpPa|zP0kX(<{C?nUMk!7$|Am$w)F#gs5LICI|qiR6@l7fRU=n z^nAMi;LS0XVRf4}KT#JAt-WFC>ZwMW7Z|!Hgm50{u(Ix_2acSRVj^47^1z;}d(MqL zIq&<UA8kFr&UOJPL{b1uF(CwFjFAE|5s}*qr2-`h1ps4=p;Q15KDF`A3TA;(Gm8*I z9~)1d4?MQ^qHU)RWlbZzjtY861K^Oj$QI42t@}2vKlsT#XYV_(!x|TgafwJusVh@y znm11=#nDOw5Ta0uF-F>-h^T-u21L`<kKeKQmih?e3e!^=as3+`_WT4oL)T#)s)i0) zJBxe|W?+{369c3I05LONx9-{L-A|wHJO!zlf>KIKfyUAeH9LDQY}mfCg2C1Ey<fBD z4n)#xr2+tuL>h;bl5!$B#%D2UQ<`!)8RivterhioPMNYHZ>TXT0YC~IGnV(AJXv+? zg6Z+eSqkc-lCXH!i{0<P@@VU-(MOiYzRNuG!>QNg<x#X3Uh^lnahi&~8z1hraW}uy z`^LK1zhHtoZiNsAV=R};#bPmSr{9_Whz;QJ(WYY~M}F@+Gd7u8(9|SSNg?pI=MNsH z(KG#5E+(yQU;MT`JDn4%X2INv#JNj4?EqAC@v)I37vn#Tmu#H(uB1M2!m>0Oj}KZQ z$rAWG;W;xA<@0$d73=8ekWwyNwruw7*@j`1E2=@fRE6Y^KZ`2o%!zU+Wb-1NA^TZz zAhq%ky+9)E7@0^U02GVI<DH$I3l}b|tE-E}V&yq>;NE3;xrZtT648J99}`Bu{c4tF zrBbP6GTGkV&Ju|P0CaVA4Gj%x4j7j4VO0JvQa6ZZgq2Xg$NYZ+WvY(n<ki*HEiEl= zZEdD$vP2@mIj^XwFbpFSiToW(?b+2q_Z0NNsPp?j@CPt#U%x%NIgg?{MK$TmWHLnb Y2RK|O8LLJ8^Z)<=07*qoM6N<$g7$U9@c;k- literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/mute_on.png b/src/gui/qt/images/mute_on.png new file mode 100644 index 0000000000000000000000000000000000000000..e46a9a8d663abb9b2fdec0b6bdd226cd1884962c GIT binary patch literal 1513 zcmV<F1s3{=P)<h;3K|Lk000e1NJLTq002z@000sQ0ssI2k+a0b00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9X7=;=w1K-1$Ie9 zK~z}7rC42T6jc;HKeOH0{=1e<LECQm3#idxVhpJXSXhlnOd~Obh_OD9i1JsHCMt<< z`p_r@6MRrZOb`<w8W4;HW2OAOn1-kXigvRtEw-?2+3eQ+>&)Ei!z`2O%<gQh=V5d2 zxo5s}&pqd!bME5M(2x)!lga41E`*R$N+}W18~^|Sm;;j!0Ej4rFvoVj5Tewo1Ii>s zGz`N5Vvz~rz!5?akzH6yNkpcwwND~4@qIp@s;We!<n#IQ@$s`~&qkxsL?Qtt$bxnZ z-1~EE!oKPjE~=#zvNxGV+CQnQt7~m-jYJ}ijg8pb+k5EHp-?Ck3<gzIwLIof>7l@G zRVjg@OLl&#@qYqzP&S*Lo}P}!<DH$I*wxjQ&1PF$TLXcBqA2$Bm?vCWa^uYN1pg07 zDRo`XWHKWoBh0KsqtUjuwooYK_xsJzw_N1joJUxe4K@q8s0xSWMej(_fk(g#A@cb= z09?FyNihr~7z|ccRua*I4;b^~pYP~CzwxcFUu#nd0RWQGkKWv0z5C-mYeW4#yY=k{ z+Lu%T0A|Myd^xmpSKHOY`wsR`%|VImKKA<ZuXc3*l$|vh>)!cf*V<-}pl~NP`;?iP zIT#Eg0{MJCGh!7*VP^Zlnp#Y|fPIy#n;LuyT(}gUHCK3Q^yXE~SQ=i;N=;bxuY9P! zfLYi4aCNw*qG9iuv21QOKl#Vz=8l2Mtd`5=PIfocG${?62I3hlm&>KoXZCEcYgguy za}Uf!<lrcZqN-|PPWP$o&2dNU{V)@RxHk9uZ^IMIpJ)P+{If6d?#}gpkwSz-h(ye0 zkr2QtWB&T3zUyEhOCiMVfxdA83}7IFG^Vay_%SD$8I0MYQDzTs$G{;bgeV+`<zHql zmHNx3ctm}wvGc=E*R=1sx%tU(#l+~rr?+2z{O9+lNl_R9fLKvXSpz__qDTM$mWB=h zAb|^!Mi0*P9sg!Yl>%uBZg{@!0blvD<jpr7saU?Yin7NQwcqkN=+ZzfDI3>xC%Q+I z&r}VbKfJ9Y_v^Pvz)T1L<YN{906-`;B9dlwNCOa%hyhI;09e26)fIl61?2ocX&pS$ zm7`#~%{KiB00leQjH-DQvErd3k+f7MMX$WKDRS!cqt~ALVn_0p2Ec{uFqz7(4g~-J zrIC<8%mp+c1O#Lzlv0Akd$o~eix<@sC}2#CWr)gztGnfLP{EOiXx;(ycb<Xj%;rE6 zP-LfT+qWjWUK;r9vUWG85l949Dpx&Mzqfz*hpmtK0qzZ6IZrG0GwbHoB?15`Oob@{ z$h)Isc?JUjkeTMFvzk6fNi*#!WhWvQ>?9)P{sk&q)7{+?0wMr2-@!+&_V-scHB5}& zQ4tsUh)G}e#`gzzu6uFg-)*b?S7u(md}SZRqM~3JNRWtR`V%EIr+?Y<!s&wUjt_eG zKI<=0!{?JPEjvk7RZY{ZcF*)O*~sp2HwO`!8PwMAVkcHsF(f8y!(lN!g@`TNj~v^w z3K4IO<vNd#q$Vd%^xe)3A8AV5HmnRESaxdo<jP7m(IBw&K>VJr>zbx%nx-FnyME4I z$kOQEl||MaG>y_U&F}YPPft&6ZEZLluBfQ6mR)57i}o}g?XFwEUtR4d$jziR&s4YI zhSn`3gwQlC7K<g5NhK1A96fqe2oVZ}0)fE7I!TWwi^WN&)AJPec*HnzZ`nRR9*++V z4Rv&M;EfwMi0It8bFo-#W@e^r_vq+Xz4eu9M;CTd-c`ii+}708w6wIex3_0985|rO zBqFmpa-=Nl*;+KM+uya0n&dtUcMIk1y7`pxqW=NdKQs(O)3j77Wf;c4QY4zBm*7{+ P00000NkvXXu0mjf;=Iu1 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/network.png b/src/gui/qt/images/network.png new file mode 100644 index 0000000000000000000000000000000000000000..197b2355ec454b96a32c0b252da3646504ae8a65 GIT binary patch literal 1895 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 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/ok_off.png b/src/gui/qt/images/ok_off.png new file mode 100644 index 0000000000000000000000000000000000000000..3434c1ff8b6928c42729b5a867b3c9f310773456 GIT binary patch literal 1090 zcmV-I1ikx-P)<h;3K|Lk000e1NJLTq002z@000sQ0ssI2k+a0b00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9W`7gx#R!<1J6lB zK~z}7-B({|TV)hK_q$(uo3z;~B}6(>Hxr_;7AC`o;i_1hK3M0FY3)#aaajK_MexCg zfprhQ6-AJV+K1o}I>Cn-)U?7>Xk~V@jUi^~Kh4^viD^ym&Asi-{r>rIO$Z&x9&!iv zJX}70-~G<Hzr(rb`yDBfNHE59T_=Pv#)J?6002S=A%rAJoO4N%>X905gZ2|4v<s=7 zsyVdJLe=Wmb`;JzLdeEz-fTa&BDFyE4(q=V09-DY+wDdOVbe78`FtvsDwoTI5ZFT| z%d*?;4hDlhpAYA9xy8lBfq{WQAkf_0Tua{n-GmUPX|AlS#N%-x1kPkKkx0bv_nW4v z>$*ccE9&MJh1UJ;E%?sy#2EYi{=UAxSS*G#O{0_=hG7@2Xt<ewj=dfTbsc%(^pX1y z1wNQqu;KLB;NXR%y}o*3FfcM<HZ&{%5JC*Ypp+WMHZGM)k|Z(4oJp%1J<)T%|I!9K z)h0k+jvo*AZeN^!>zE%riY~hdA=&TFJ^fz)%Fa_XS88~Buz6{kicQm`loCShZr0#( zUH<<3jgxcJkEsg_8vxkz;N?rt-8*vS%vYy`fcAZgzBJzZT5fvdQ<hz=IFM$>7^T!S zO-w0ejMd*L4YaL|b?AOrDXi}>0062LWdAYveLSn4^oo5y#6N!NjV~_FZ{PFxa)~-p zPMmX_D(0LMLI@!Up@xS+vIRgilQdP4ot+AR+ysPyfc*!8028rq4nG=ns2kbrIOopt zY&p;c$*;3|??L5Xq?r8;x=(aAkw1jiee~JSKJ54SB53sTt37u+&eQ%so!}|_J@0qF zGWgLWlV^{60IdA=cZZ{I$L1>A1{VP3?Ci~>TeD+r4?NlSN$i=!cR9h6Qp!2Uv}#W9 zq<@*uPh~2n?~6PH!5}Ox!8_x#Z+1Z<OJxB764kRee2?Fp9O;Za;r;yEzD|!5JSnBv zE?Ud7WLb8gaJCY&=*2JT%SO?#przf%3h8SL1pqj7CVm|){ghZIxm5n(SxV2Xr+&^9 zD-G|rHbD#ks;VlABFnNPVu%#3{W#g|@w#LnsX4QHPp|%ZWwrXs=Hf4ti;hSl##p&r z=3L-#IGjqQ5JFzB7h~*@?z61TJFjmkrR8!tnM{VmA!%xAYIJn8qoc#;^C^n5mvnrk zQYjXTYin!6!^2WKou-sVqtW^Kc}>&y(p={CdPAYm(9n=&S<=kR3__^2wH0G5%kr&r z@PF&1+HU;}eLK=>*UViToojRUuC02{w^?+IG0U=4Rb`C*17vMA#)H<FLI3~&07*qo IM6N<$f^mx#7XSbN literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/ok_on.png b/src/gui/qt/images/ok_on.png new file mode 100644 index 0000000000000000000000000000000000000000..7c8327dba56f3702dd3d7e584028efef8cea7308 GIT binary patch literal 1087 zcmV-F1i<@=P)<h;3K|Lk000e1NJLTq002z@000sQ0ssI2k+a0b00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9T8w9T{Qpz1I$T8 zK~z}7-B)jDTU8W4_r9B?FaN4}S^`-u!8#II3dN#S#V=wh!v@q@SiwSNA5<Jego)y| zZ~8$-VMWv;esDH)UBO6)*h($hZli10(w5QMg|um%NlD0-G=E;+efM2IyqJ}26NJ2d z==pT-x%Y6+@1Ebi_Z+mew8R+8<#Lo##u(?Ea}EFiP&KGb5kj1EP17o?2q6Hd(p2_8 zNO@mhd)-x;+^eZFtOQVr(_}J<qKGjjvMg_HZH2?(Xf&G5W?>(R!{KObZ0zjp^msfd z6bcOt3`mmXa=Gg2>h#R)1L2&@vYbw*Q>j#6Umxo2?JX9IUa!|`wGu)M!l@SX1r02s z&4M2uPE}P4g~G<hh9C$e8jZHMx4YeLi^YPm0a4K8)DNdeu0c~1#A49(?wP|aZUDG7 z)jvYt_@Ltn0EkTVpUu2{?#&icO+9OxRw|VMV0wCnXqqNTlFeo_1SAwDKRZ3rHM}$P zx|2b1bK(X6t79L2@tW_EM!(xkpCp7Qub)5rV|Ogs{YQ9KuC;qYh|A?d2nZoW6h%Ua z5jbi5=J0lK;p3LeLqiz=+kw`fhI<a4+Uz>iW=0@6MV|icldrXzo%dEQjjM!^S_hzM znvRYL|B4YfON2q-#pIRwoFE7Qa(sEc{#m$rAxEEcL;dfQ!>M1#zF*Cnu7=ZsAQ(U= zgpiJoAcQJtYwo7rsR0zz>~5xZGkE}0gM)CyK{^-!_<86X^0cS+sRRH3#+d%N5*@KY zymfdE!OEo+^EH^un#^A}AP{V_3!5k#XgxA`uG87jA)oy6=rfOjVfjP|5sa~Myj7*= z`vb?1Uu-?!+a>}i$(658hCUiQkuPl%K#=`&VxjH!;<t~s9&>&E-QlO42I0gQ6NC`P zSVvoX+U(rvo>`NR`rbNH{#Q<2SUl03n_d%40D#RxF*2*Z5}P>F)bV!xK<K3dV$EZ~ z7~kcsLH83NfBov6zKisod@`?qO?q7Yd-=+Z+kzl8ANyq<uZ>^ZR^m&s=JzT6^w#3k za-!xx3zT_lu~-yE(Nk<lF{GyEr^f4S4ig5tvLG|iFGzf0G7jZ&Haa^VEuVdDOCkWE zl$y<E;`jR#iG;)9(DQ3h-B-+Iix0iN<(yMW<MFu9=Oe*jaBy&tbMAJ#tyb%P>Q@Sd zLL!k^UtjO(=|QWjtBkSH(a}gGvb(#xpZXQM-R|{zgTY{_R6=uea~Na0-L6*)_w9H8 zgZ=+^Y43}_cbk5`m6rWMCRLsNy?*!V8Dol~WHK4X*grht-*gPM(C+{M002ovPDHLk FV1j=x3_<_^ literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/overscreen.png b/src/gui/qt/images/overscreen.png new file mode 100644 index 0000000000000000000000000000000000000000..704cbbdbac5174e79260c345834cf47c78984134 GIT binary patch literal 1338 zcmV-A1;zS_P)<h;3K|Lk000e1NJLTq005f+001Be1^@s61#AjB00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3labT3lag+-G2N4000McNliru)C?8?9W*N;iE;n{1jk84 zK~#9!?VRa$+DH(EZ%IPfvE$5S_V<6fSu??L42V|E5320znnsAl4mMrq^pTJnNvJ<= zb@e8AgQltiK(=HP09EFgW{z=U>n*<yTt_HRF7N*yUqtjRmW!Ma9NV5t2F}NG698=n zriWVsr~zC8XhyuF7Qi%f--V@Zuq6OX0G$CkWXsGob;EBMdmg6%u$%~JjTOGDO-&H^ z`HIxV^ZWUl&esITHrU?LeKhk<lwfN!>c+6iz;zt9mF;8TxjF!I%j@cy0;FBI&WiG@ z<>h-N07*ppHvt>DE(u^%!3|ZxJylldZ3Y$?46SYbI~N2=MM~z^t0@1_Z=Vpfno%ar zz>J_+X#;Hhei@i;1)dBPC6Jck*xZ2g`$aW$U=snnu&r)Lec1BxqbQ^7021ey%=a5B zJcq*za!SfH*|0yg&qAO~2qsp(2#KF>!gI;U-!BKgtFeWkBlBw5CUU<F6DwIF_<H)B z2-uDka7BNVRY)Cec|Q$2qmBVmMuJwGnoOzS8~WEf91~KRA=qkCtBR5kKvkxKj-Zyv zDCk?MTuXon!A<rVkTvri4d3Yqwk`u)gsltU_2i~~I|r~3k=0(XscKD%aRuN5fExm8 zN}&0EOtHRI2RB!pN|16!mV!&?eWhb5<XxF7PPFgaTL7N{+&Q$l`k@S{*?RyV4KfGq zl0cdSRpV<_1CgSfQY3t)rUR~h)4AU2hKUr?!Mg`A1Msh<PXO+sTa^rG6NBq#06!UU zSLR0ROl5zJ3)>c^7yI@B;<jKay5^{a3j^*GfIk5I31G&qwaL`YZUFoS;8y_O1GqNj zsxl3leJQWA2310}$*WYYeePBDRz%VRYy{c|1ML?B?Oh1*Q534!fD+c`1wqOus(K3` zHI(TFz>k)0j823QyI8R?@J#`HM-i?9m^G$qt<}wbFfu1b=AyjAVtazunx|Y?0CDG$ z<b~DEt}PRX!X;`fb_j5lRl$@SV_OOsy5csA?P(P;Gz0J#*6nb8Ln`L|Yf^%MVh7gQ zI;<Ocf43%(dlBgyJa*Vt2AoHs6^2JB6e|`Z(H_7TtQ&U!HsF@txGU83(PG_e;5`Oc z=2pjcAQwANH4|#JaL_*6e#gBC57I~D$}TNX_-I@1zbw!di|lwW!VJJa2H8B<DgPwW zG~j%6#x>UMZSV0oO0}q5F;=wRs$pLYHdnK3&(f12(I$CGRk^=wVQP1Q$8M{>KzFu~ zRTNOp0erP+bB^_BU>y@dAfs|(s&-*@IB)PRcHVAtX)5;BAX{R@M4ep*PqwCTta2zS zcQ$GUQnPzY-8MDb3AUheH7T7B<>m<^1-iFaFY}>AOH21wwMx6rOW3(9N>zRK(}Yy6 z%1CXo*Y7Stb$3^?)xMKo_UiW}rQ6iqRbYGluyuHx)#dXK4w^uHP$zqEuPsHZJYl84 z_d4M6`nR`4_!Po~BhAu3%7~5t9nVi-zh7MJ>A}V2p`>E{F(ErDY#Hb(f-N_}7bwG* zUfOg+89aam8j<}R%QZYpVTVc0ysSc*S#=uFF=#w?@mbdddG<mND+=*a3<bJx1KN{i w74U+qCcRi;hn0$UT_&N}aUjD>DA*?Z58a~&(}HMd5dZ)H07*qoM6N<$f)D>-CIA2c literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/preferences.png b/src/gui/qt/images/preferences.png new file mode 100644 index 0000000000000000000000000000000000000000..9fcf92510ff9170dde910c8387b88f9606942115 GIT binary patch literal 2342 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 M07*qoM6N<$g5FP6+yDRo literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/screen_main.png b/src/gui/qt/images/screen_main.png new file mode 100644 index 0000000000000000000000000000000000000000..dace67850cc0a380da03d9938cb85508feb93d66 GIT binary patch literal 14357 zcmV+wIO@lVP)<h;3K|Lk000e1NJLTq006iE003eL1^@s6<CYnY00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9V4jn47C6NAOJ~3 zK~#9!ja^Ze<j9R9nK^CW|7%aPH`w#++Fc6nhZI2oq<TDl&(l*~nW>Z_7$g9K{$Kz7 zKWT1eY4<;V|0^@i(#-w&0sNDe=H{0BMbGc;pX)#M9(jL&-|xSF?#b_K^!s&D_mBO) zHn;m4&iiCt{PVl_Po66}e|7(EKG*Ed-x05?-Yd+`wHe<iGYffdGw<&iaBa`M3y=1B z`?~4#pWk=i-zMp^>NCv}e*{nLem>7%$+O<SyDuZ@|DHGXx{uF)KHn?MGU4t&>muvf z*SdJFW4{3|iSsjFEA%MN7c}{jaxdUUe6Q;oexV+Et~6R9c|Vx5aMQ+r&g(7V<$m9s z<OgTr&&T?3Q@p*eZkTX~Teu$z>=S>vN0yekHwkQ!O!`{6F1_#kklhWR+4C0gS=qja z$#bj6bl;WzLw;ZV?sd=3hPS-$$9Zh<8VFwgyw`a*uLX+lw?8LyoxhLgIhy%dAGF6; zZ7O%T#`Gs3xFxJLGrKp6_24lF8(ely_hDti15W#Xz8_iq@TD!!8`jRS+JzF8_Xn-D zEF#VV!pIv@QTO~0_Q~EfCtB{er-g}&!794!4S=tK-{A$7u*seWLN~0UgGYT|kG_cU z1d)AE(d>PF^FrOPbvY6C&rTHQQ_sWU#Jw*J7c!mzdqW%CV-I-OloP?yEI#c-&s<Lg z$A^-ZAJ@3j1C7n6WNj<gxXPOw0%Dq-6EZR=D13i@|G;r?_X5N>@iiQI)2YB0yi*+f z9{VQWZ=Ds5SG|#+V=65dEO@Vtks7a8KWp9Wy#A~|<5MNvZ9)35ALdD&APsZZ2jk{v zC)KI3@1<L9FpLjpz55Wx*FMb>mo)?v?+fF(#=P#$x2~iOymHY3=i3D7;&NCp$pOa9 zd?loC^)|78zBihgErawHZx05jaM%-RZVLiseehZM{+t%Dn-bEmYeD2bzw7p;{4cyd zBfW3IX`!Es&%RUL+Cs_9I=)xJ&CDm-rCHYQU28oz$!Rx3;@;~7*jW4F;_^s6{w~ga zPYSjp2j$QE*oS;QAx}=XWeJ-KmSTM{->=Hx%y)Wpf&fNk2_ThAm}B~hoAe1Hp77$} z`^IS>$F7rFK3kPix&1tM!a)J{x#w9qIR*L)(!dj7*OR{BTDsbrt3c5TN6Y<Op1=97 zeWP|E;WiYC_x96WjiD{@7?*-`AD<@z?zag^ONLWmzZWe!ESB7c9NkV1dZ!n?Xz?+} zwXsO%oOJk1gAas7M-^MzsWqrtv%V1wqNLe#$~=pIQThaFffn7#C+EJry$RcC=u!hg z5wSN~p1i#_p@mtT)2nKq{a&%}zq`dBQh<{R%ldLH>R}_>bl)Y=e*gM@TgpI-6W%n> zaZ@|mj2Ga&$kW_EW|p?{E_w_QgO!Ub<irJss7OVs`!)6cnDHJ|2R2xLuR1Ol<i$SZ z%`JbRf{Sa4%8Tu!cv=RYjkh?u;@{aptu*hv>lVZ8)Z<)DnBUK32(N@($OcZ!dtuUv zX7#&JMB{rwgy2HnxHd7WBUYuJ&&geXC#P8g(zcelhvg~s{V8DWAYl|2)}rW>nfCqt z^Ftda5D{=eN}SSveserRA$Rw4H0AjsRpr-B+dqrg(Jx?;n|)3sHY$1@%R|R>s4Dgz zINZ{fIeZ44v31d0EI!-eel650)(g+)j?+TMqxVkL7Q=8mkgSB0rwVLu@F}Dj7IobM zeL9502Jb#6Z+JAAw?}x`%)9o)%|kHby%9G!vVXRJj&PoPocEzq{PQ`dNqoNtmfXej zS>)|hE;#c0i4YvtDRS;Y0T%(L9Gv(*3oLdXn<te&i`NvU+lB4@g;%coGcd1rvupL# z1s4#WY*@rCSp50ijVhE@->}ZOdz}Ig{^fFNKrv{LGvC+np~ZOL6Tso|TBWcZQ>7tI z;*+at28@a>3mZR!@%7rJ81*S#I5o$ED4pUt;X5Eaxz~%p&9o3|>u2J1*01eUI@fyM zD({o{$@9-4n2WCYyViQe95p984{pdA3#xlkisx85Dat?;of_|{{A=f}o_;`Dl+TyK z!U6$4&B;&k3N=JMSWGvZP?UqGM-F&2;K>wiW#hrAvXYn$IGzDm-&r<9<9Z4F9CF}& z5}e1fgg85Scoxb5%PN6@aex<7a($|wc7pMoyqvB;3W*C_Qc?^$?#XD<e%j8*17Hgf z0NvKA`v~QLeG^HI%$DcJ^M%tGsw*<2uvR`i>*=h$lVLF#;kq0qC_@b(i|{(0Pl^ch zCoi4w-C%g(L^nt1ftb=492AL`<mIs+e9|UEHUU0w*ANE<$a=_65ou2fR1dquYqk-y zgRa2?hA*<#qSv^h6p7@_KoH&q(4lM3hS`xW{Ur~Fnhu@|ts#P{{A?I39t+yc{c%rL z;pe0=^Wt5Mi`nl)bMMk|-{f66-~SEg5)m;jH^u?F@>dAYWGUP?CEC$d#UCsoI@T*K z!iaI-hq|_VeLYb>lZd3XhKtMvsK=@e;?5fmPC~<n)HZKQnx;(aW(PZU>fz>#QK9gM zSn~jAsk71UT*DE3D^O@#<R94BzL7?a=CWWh=g&GVHyyESE|YY`&hsCL7w2>;BZOS5 z`@4VojR+%Ljd^H8F1L1HFtUO{D^2p^Wa=7Ns2s|)`~6ps1_6;X`G_6!(jDQ2^+Ukh zg{|e($y+LwX68S8<D{xz8YAmcbGYjjiL_zg^N+Pt4Ix%!DCPOv0*%W|b+eoU(IF*q zToDeetpJ76<(OJ8m=v0uoYI5DQ5x~Q8bAtjGhgfQ2wH?A`@diFjZd5_N~`Mq6izWj zUA(V3=`WJ<tNn{P6tNTbT>0Wuknj<UG<6A!cK&CSpYOx#UeA0IBxr2vrj=f!(6NxR z`nk^7YaljLcJk8*>l-m8Jv)CDO<SV)v<K$Ean~&Ss3y9bA2y|8fZU|e<E6<#G6<iq z8wS}#7?$J@otr>NwP~k7f^jrZkP;%YWxLi99!Bf2@4x=_Z@LMJC}6sPk)d{I-Sqor zKVNy}Ig(4chYCEeeCoh?rB}f<9g5mGLR_lbfWimWYpQ0$hbaOq*4lUj3tJJJb@NwV zgyYlqa0kd#&n~Alf*C!=;Qb+g5b4<n&8C9%nJP2M#dIgFk-<gfCF1t}K#O>~usq4n zy|~{mPTssz&S(G!=k%nFl4nkeRGVvy??3+WiwljB#Dr>G<ei)Ga@aa&r^-dFRTOrf zf8XzY0W^?{8PjzE27mC{2dogC3X(VZpbQQW-YpLRaTP#UnNy+3n<u20cB==6_2nH) zd1Lt~@iaQ_J^T(#QJZ+9J^^8KN9?5Qa?*qxJUW!T5ovC||9MhAX3naOvnD(R(E?@a zSu=JDXo4TT<#e3JtpNz29EAan?}=2am@#~9pgvnfI|xB3tEEuerh6N6WnC$V3Ov+x zvuKS|mXnujYO}QNaXN)e4s;ZRA;Ge*ec6v>-Wut+4%u)=ohsJ!+x|d+E7x5_T0Z~2 zr5O7cm#;yRdvEHc>PvX|esv`1rtEQ*J3cN*Vcd?QdF#JlB!bSFqSP|VnBa3PvV>&< zCWWhu*y<sU2-Qg@dIB^6>*R8xVJTts!NCt<?xh*u8V8Iv7@b;CXxTS|!HvZj2(S}j z^81N=l&7hzvKF8=GxW5EH)(LVLbPZ=5#3E_Y;SeQq@hQ$g<&<LP3QEztu=%Ag9q0l z>6kNYxr(xJ5WfZ@owb1o4+=FLp7GjbojljfRtcW<;4Y_3_N|az4}QMK!-Ah*l}zdT zzyJ4t<CkjDD`!S61@6lOU#+%LNUjMTBDPq6;$E3#eG%v~GHV4V>74T+i*^n1(4eWm zCwX|+9ba@0NY_JZoPnyw$B+nt_0A!D{_(K65un|Hqg*8dC{5TT*<16;(d$1@Vg)zW zS<fV@6WPNj#iZOs-k@M*qWL4v_4?%kHz(H#C%1jR{UM}^<up7Ip6mGj`t{2?Fe`G? zeS@R^+|=l>E2u?ls@1$}#u*c>?u=53Izf~7@2}Qbv`>|yq1S8Y5ot`|AuA5=(224H zQRr}H$O#pN9lJ<Y5eeE092WMuXCEorT%;5^w41reec@+o%SpF3p9*^^sIzzXn53p0 z@Ul`;bJ4}<iMimtR_Xt74^c-MON3cBZ^UBm;P<_Len58slGw%3`DT*fc+8@|IQIk! zI;}0hy2d;UJ3#2Z@y%TecnZc28@jqlSo(R6G1Qer)fg-B=J(b+By)CDHSg_XMK44n zIHujLc>O859D7w4AW;yx7Jnb^vZ|al745on&r#cwu-I<sd2fU~T78E4{OGnZ4Z1b( zs{s+E@+`KM_z>bE+`@a0)6NpjnMroPqqwIYK%8-W<MTO*x+z3RO8jTnUHL?x<W?ur zIYW<K8WmVth;G?tIz}^I&HF^aYn+>dOVpLHyEW2AdMgI+8!41LY#jXEE%r$y12Df# z&GUw4kbUnG0?8>F^EtwWSc8DG@>WBluqq<%^v2`Ji~T4dt?>Hnx*&zv_DRy~F<87$ z3Ya3-uq7M9K<D$ECZBLRaWHbz@q=AGZ+d-vn8}&p_qu*4I|<R@`@j@!jIZ+Bp_4wX zi`k{{*%y}XN1x=x*nw>Kg02#jb$Kn2ol0ESqFuVgA)w{pP<-7f{MC?(%E7ZqL{ic@ z#%j&96%R?K17!Tv!@MJ8r>h&*T!P5^d-}4>w9BrR4p4)P54{C=+G3WknQL%sUfR!) z<F5h)1d=>UD1${={vwtOH(NiQ@x5{9VtEn1UG<^gUw{1?J7_SPQm4)kIXk>t<N^!p z^C%1*j*=8jgMOyH9IhutMFw&s+#BW$KT#LOV;m7nR<KhXbOUIFh!6FJ+@IDRV}p!U zAvVot@j8V?#n-Ksuexjp&SB%t2}Nu6q-RKVMG8BhIa%fi^lU=u70~Zs6!3^)>$kQZ z=3pL~2}0ZVwHAVR8XhR0g#6VZq_+nM#o`vs$CIbq5oks8DET}&VgzI5MH2W>t()o6 z$ZZku<gi=%i;?5!XAwfOq|#TN`u*B#L`58tpPVT`<p@+^ISYx5*v8Vt&4s^;+7Mw` zAT>4?Qc_nvA|m&*2-8kD!+QlO6p=lU!XAR}q0qNjFKEXkY*u-q@Wz>}@XWL^7@%DG z03e{y{Hn)Dr)(EJfYXhFp~3DV;{n!AN6$t&JY3%6-skJ`o|r#!Pp>;BElmnxx+oDv zq3BMz`6zj()Fqe{nS?_xYRDFGRL^a_nIyCKinbyRh%|rlYX_JNp-rbYI1{F`HUU9@ zPkNUofy}tiGxz@>%*PX>%K_mjP8TCV*wkT97d@K*c}u79v_Y*)W{1g<Bfzeq@9uG& zbO5b&AK(&EZF9c03&N<K7!lmCaBM1~2Sn$BE=W&4FtdaH#NEYoN52bbj~$wVTh8Q+ z(GQe9<KryD+WFwl%?~WPRP$1sV8eK-qq+Zn3AzC~_%YuQQV{eb^gWy*H)4xjG&*kO z$^}rQlZ4=@XF<2p88Lfw+#F1%VBwl;C$xCD*nXfM{BDwsv53fIa^VxvMOgyH^=|2s zkw#M}xH8(zL~+Ca!NpHzVk(j{ijak<ERcg%!$I$Lv_b5Z+`$97nki^cl)@nl*W9t6 z)XNKn>M|xfQW|*AP0Q-1#XMH@EMyL}A$r$>7nFsfCZzKIw4;Rx%~{`Fy_T%0o{Wz0 znJOZ7G6#TflSKZyX72Uy-N)Fuyvuk2z|s0+*9^^=H9@=^8~j-Bmu-;?g+f>~?1wi} z+`FrsljT#0uEjflt<_+yOkVVBMJtYNxbawAF%IdXhj)?VS3W-CDj$JZ;Pi3m=QN0x zxKPQ5P!)inL=1}~v&ih&xY~B?exv$kX|Wbj8|ISZ+tiBr6qPHR#KGlgK7Ay~4r-@E zMVe_+Sg&tHNI}BAkU@n;%*~?!FNs~|fXtwHO1e2L<UOD$*?o$whr_6FDs3>^xheMU zgZ~{ufhNd|J-Y5qB$Q0GepW|hZ{NeFje^S3SlhTt6Jz{fpXR^&x*S=??5D5Q21Gxb zO-Oy{y9X=!#2unKb0*wa8Z}0+fBL)UzdzB_;Rt56UyM=n{*t}pM--r6v=BHu0Cw}D z6}aH|{IizwRg|PT;-GKX05_!tT?u(?GESsDMM!CoBLsNzvU>Bd-W4LK&P`5)Fqw?+ zheJobg?zmL=JsLhy0FE3l7J3JT?97;`{bzWBGM99+EWW<btdhWJS^a<qbCVd935&g zXq{6xntzU&_Ih;#(Z&&g{yS&`I5X&&-#mZ*em~#yVIi7<bCE!dv^3%r8B%chB<tlo z<@lontL|8Mr83h$;dDc9sj~>j-7RBDQLX3(yT(?-hcJHB9KmgLsIhR>PGnPMo#u}t zof=wQTsonSViWY>?rJQAQq-Lig;lWc_k8-t^+cmIQl2qrLbg~ef_pGS)tdt-KQ*od z*fsOt)t^zEMz#?@)`dyy5i8}obJAt?Z_1mO%0Gi3s%);b4<@~hA6<Y-!M|J6tQKap z5TP(#7zNT+mNnW*YcStjfU64Yk+vGyvQ~GhGBWJ+nP67kg(IQPdE~xt={eY|u`de~ zcF#l4BD?m_E-B8jU5!jGPe;w79660sVtNj_K;98gamYbwap%IwA50i5d0RHPwHNQ- z-@kvi9!J8Q;AUxWGU`wCh`pVy&^BVwrG(fJST#n_QHc*AjgWx5YbU7&S&!D_S{j9o zc7MGeqAYg6%u^b=k7&yN{nA`8S@u>;+u$<mD#A_He~{t7xn1iTYNzBh3oR?m+QzU1 zO^Lm*)W!z>#LT`dM$(_;MHqO{=HNC$G8+;`+(ml4Qu|H&A)c8x(No2vP7v^uJNmu= zSpVsLu_FO<dNvQ*k)_}hN?tp>w^f@5cM*jUe7AFe3y2X9tf}>Zb=4o)Co}1y|E*5C zj!Ew%SW`*qqq;M-;zJ(Ofk;6z$HXiLJ~MMr7J8D{YSL`S$7_*4-Xc>ZjHi%1=KAi| z4L>TyU61ng<MD7IMt!uFFaC@ua(m34HriQ!DbPW+@@C7yolQ6C_w)JCgV<GZn@pgr z9YS--`tH*N?bRK>4AO!eDsdahzkZA*Lx{|ll{&HIHV}bVs#y`cNR=iVi``xLd-KC{ za}lgLbHiSWMWWydc8pi(wDRp)KT?g~k`T)nk$sOMy)%Qy?*uxrq~h3r_tu7;=XAV( zc0JbDDCNj&wwgEZ#!%E>`+{d^ji=TZ-|YohIB+ugk%Qn|?A%P65^h$@3B(_55a4Q? z$)kzizemr_p^c2bFaz?|X8df;O6$tEfz|byipPiG{rg}vdGkIL&ZMwu(SMXYwoXJo zgzCI5lOI@uDV<L%LD?*pXU3-n$(BL(n(bf&+X#&C7`at#s$Ka0KHsTn=>Z|d_tq2W zdrM0ZyM0{x*CIP*5~pYI8ww#|OLq3difvy#^}MsSCj+b*`@FHe@xiyea;OOS;n?iJ zrIvEW>b}xkdlUYsPG?p?4v;V|@<3L#qebO1)+H5$5IuVEG5<%gm2rTg99+BVU7ZxV zrgIC#Hlnn9ICq0dtZ1}XqGdEf!%K?frd~x8sOk=)dh3Z?-(TOq#%h&VNHduV29Y<_ zHbw;USvnLdG|AAWYp*+v-3@3uo{sbnu!XL@dV}Af4GpoPJ)atCCZv*22E>(z@g*XH znhL^0{={6^k!Rn)p?YKcCIU?SNpsqq+<ajogKZ+SCz1y`^bR#p*P3vuF-@P?pO@L) z$0&mTzJ5#P+dIkkQ(2bH0zk*|v7qLOEbF2cHXAM+^O-*hhi17j=oK&r)@bT|^SU_2 zBF{5Tee0w4DkVE9$?D@zjycbEArSMOvysqMcJX(O^%Pz*8)@yS4RAtovjL|SGzEf8 zl(L~D=(MoU*=cr>+LB<0&e8&0dpL#tZq8}$vnOb4yjF94+qMyEvET#|vOnP<Gu>@x z=%T85x-=^^X(!s&=Uf0yP;w3h2SJfkT(V1tyOKS9fTXr_xz9o@vtIPz9GiP_yATtD zM@!zC51egtme$t33p~4zXU{qX6SOtROk?`8(Ghc&8<VajKT>D-pdBgIWhz3oJCx8I zX^2v4r0Op?ct^Pg8#s9P?~*A4u^3zQX|m|Bc$YXHg|s#)K8X=T(*f0ZZ;~kop;ZGv z2|s<AMv>MObT|fOBO2UQlvMQUz$z_Mrv_mM&B*IRdD_mrY2>X>Mu-}q>iF=%f`YX2 z>E!!(JsSxNwS<1f(-OD}by{bnfC(M15!+$NfOQ+_<EJA=Q=vZPm2>M{w06j+Oo7XM z#8$*OI82>|;srD))Xf8I8QLYE2)9tJSYSO(C<CU>j64<3l(j2O4AXC9AwdhmBKSPG zEy5LeLpB>*7<QibZ6ozgDt7-4dMSFjPM&9lEo9{q6_A!-^iLY$;Xv$QqwsO31)4j( zRF7rO$yH*Rj&7(X8M%61d(sgYYNfiER)@(fC2W)t6FCL~L;|`GrgdeTLU#hqwhRHi z`ck<wl3i)`T}!&?n5Vwu;0`s*=-4E0y+FefH8}5-F3#puFOwrhg$IA45jI>nHy<<6 z!}DNBXLj)N7`5CXwrYG{>Ok3E-RSra55|wF+2Rpqr`aou*pHt)Qc@SayZJq$k2hy` zyV}R?qK+*MUMUU6NoGVl|0j8Lt5CD)b`VB3;Z>B(a%gOzKF}SAN#Q6O&NTb}`s=R_ z8xaU3`7;zw8%k7jPL(bm4Mj3WoW{Am7C8x(@;VDSiE=kJ1GT)5-g8XnK;iP3Z<nTH zWa>z3;&m_8mP}{SyUx?uR?LG97S=fv7Z8(+Yjzamw0JcKDYR(dVmv255B0aP8W4<r zf_Pf&V6<Q|nj#)%?@i>}Q7LU5sq@*e`w}w+mCtVIpGgn<yH<)({cHh6C{X6XDsiMT z%4E?mBV;zt$z5gPq{uD_nHcOJMy0M#MdF{a=m?)Zd)(VdZCwl22E{V9e~$X-jUi3r z?lpbcs4vwz)$Tk#vAidfbTPRjJ=6y4jAn$NXSaq<@bXwox^LFv!WvGiBc%?%5BB4o z(-(R^7QjA5VP{4|?KIH1lgE<QH~E_9EiZIduBlJ%eG|D~FEd|?VwCYM5~-sqnP>iR zH_01OVb3Hj^+we8Hfr3(<9Y2|6Gwa$EV#(lp^KNoZ!s4IVQ4K|Cq)a=iBt#9>>XIp zmk=-D#o%ssc@Bc6=h|%nIVJ(hYIv7Ew{udOHLt&#^wQhRZWml@)7#F*e*)dQ7BpaR z;8BOiE=5r1*#)DH7C3rYCr>gTCUY7nwPlHsG#HEziD`zrk#T++P6NmTXYJpM2(V|1 zfl%r;2b3<M2Ve73$^Lrkc5xVlm4I~k7|l23=*CgfVXmi+DbW!p&Hi*Gt{%xQIQQNg zsW!+#uK<^3eSJ;JI64scv*ON2z5vpQgp?o$X>z4v0qq?y%G|2qya0md9pe%3?dWZt zp>5W^AO^hOFGlb<Vcg@_k7CP5jR{T0eJl$;=%E1&m!=7-@m5n8>OOg4uC|tVY6PCJ z=i3^ha%Z)TOUYMi?ztcviGIQc!=nmm;ZT#@?9oQ^t;d~fN|W-$b<MX^IyQ++*=W*f zc(XHkP5o;eRG!HG9k?^lmUy=+zF^<2(<MnKAJlLjrwA5Dh|$2*8oS*|vGPnwk{zG> zAD?q7eH#>mA%CUlg7S#`mC_GzBP9i)xh)@tj}qp+;KGMiCQG|6QUC4ZbR`vU1v2F6 zzHe;uxhZ+(5joD8c}9=p)u?C+1M#1PM6KIJJXTm+KF<?Xbi*YW<zVdTv=B?ze#o9= zeY;{Fdm2ZwO1+)peoW_UIz!U?a`%)@1j&(SahU!Prz;BK+oOO<CeGF_Sf6YBu65OM zySDu=R@*sS<B}Z!_j0z@Bhh&9B2S9;VPQE?@nmlRku|<7X{F=NIFjxNiFq;(a6;VQ zCW|%HPT<kL2J!(V#6vsSWJ$pu--9W8m%exX&!pVbqdwI#`c8EYvng&2>2{dvYJjNI z!cMSou+ZMcb=|X^ruT`Uiv7S5PF3Q}L3fD-JUZB#eZSvt<$0n7(Se<fw$=xE7HVPU z{%rd##l;A$|8{q1rLrN?^UwE=CNY*#W&up2!k#&L{YA*Inlpv>zIo+6^1NF_qvmb$ zBX@Smq7+84^)#|g)5VJ2L^@YThXc?6C&w{_EF_sGT;wqHz_m}UZCE5`(z-Mer!52h zC(ve}mQiSrp*M{iv$%|M+V|YBeg3#udI=`RgIa45(?}7TyXewC$UcQR3fOx@7W?tB zGorLB{t5wVpJf}}tvRoB!SwOpCX2`#GUV1hyopC3o&7W6!GgXtYOeRjUWwB!xCtb6 zmW_8+V}P16O=i#IiO?pqft|5<8ct4PiC%?&qtaC6qc(t(_WRsF)-B=le#|#feFpMT z@3`&Cv<Q*DW@&~~Ccvx*yF4O#RPOmpcf6d=WjvFhbel2zV{&i3g)CpjgX!tem_6A9 zoMxeYnva~xG5K^JyQl&&{`x*H79X0GEk(1P!!@`!!Q7e}3;raG!wJPZ5UvZ-%Q}K; zKQBm8mNocI?AP8V(VaiTh>fHo%gHEeQ~%IazeJ!jWIazbTuU!SD&3S$A75=S6m6=w zzx>w4xR{u`uzso|*M^1IJ)~Hec{O|g-9HgN6hG3NIoRH!6<l^5@Uflf*&~i4e}c$? z9$!RtMNph36r|RvX&ZYjpB$AWwFd(3njVETcgol1&13omAOLQDIt8;gAVkcz9PMO4 zKqTVD{`t)4`HS-CDd$!}PLOD5@b?2uRxxQ(=B0tNVL$)?7nVsxK~z@$)>tk~m(=kH z|6U8s5dFjbbn+CLu84#+DIg3yHA=bquqKvxHZ%lhc)FM-d2a%lRFFC+llncuXy<-D zPK36jW<RvZOm-T}+5L-M)5eBKVJE$Np1>f0KiO!wtev-^ukCXlJ-7ky^8Nkq-!{!{ zOt5QE7(IuW5-n=+MBH{9>1L8C0Vwmtn{L(zRl5v9wP74e8Q?F<U3G)C$#VWD0;1=X zeSuFok?3{_HJEIi4M-h@J*yU2ey0P=Y@7g%x@I-6r%v^$qv{CiyJa7W(y(a8mPa=x z;fRQX%@iV_!{!w`Bq1=b(9emi@qQ}bfBf?wZ9mN)UeR#u-WdDfJ2Zt+g*)8wWlow2 zHE!3>P`yb{H=NR$&#`4zjZN85(1RWArO_jI9<5iAzr4LEs)x+Cacc(kwLoMV#SRcp zIu-8Y1U2m(P|0zdr12*&L1Pc@T^ATMU6`@cR}npClZ`cxcu_hqdpHxcrJ8N_gb8N2 zzdt`ei~;}M(ILj>ld{cZGFlNdOBlMEd5AgL?LcMJHdSI(S3Qp02KEp+uL}n|UOPH$ zck4~MVjVZ?-;yD{=Fx{d!jQ6{ze?_scpE`_Hkh{N(Q|Q)hMVN%B}^*%6LMX~T}JAd z)kX!j4!~vBGZ8?Ymz+pD5?_=qr1oS&-yQ;t(I#OG<tX~1EVSt&S1C0&G&1%fB*VKy zm4|kO_dGY?efaogv|ya0;5vXci7F;28riz+r_G`v01t(b(0e#IQCaGYO-)sB!{yxa zBQtnV;N@a6v|+L1)r{AXLm#X;8EE1pHZ@o!_cE&*p)sU5=SLb=#!f4ke(lHGFGn`^ z_9{xYgp+Q29=4E8OtwitJdwYj2;#2^E*i`b+wp<KgdD9#zS_Nr+G$AZezAVT%J?3K zp!5iz+8Rd=T1mrCPqQ%Qh|cvy&@7^1Al1_l!V}eI$?jNQF&#{#otxfUZ+)@KUi#Li zV;|;&sXI3B>ZyZ&7rhT)-?zXqe7F)F=K8E0rWVi8Y#%npDN)kNv%nHKsVCDgCwM0R zrCDiF*bC2?l15Z?nJrJgArHgkLQJrm6nA5%bb0q&5Al#UwB!-=Ke~|x?PMuam9@J* zle>io)iGe0$9X*CWUK~VW~$h|U_zQNljusoI5Lh8sW~}f5fSV(>tMNOGQTIqNPa?} z&oEfllGSO4y_1RBcQ5U+ach}cL?qwbDk2B?)O|;0c7|tJMp-u-%zph|*TphMWiEw~ z>DBq<DI(Ay9-oPF+B{Zi2&Wa%R8t8&0vOVs8u6*);Em4L74FTjF~+$yoR>I|RtB0J zBi2<1m*!A7?KZJ#6bGC4tW5R-cN_w<C||#}3oyXAt&q~$Fh@@#qt{=!me=u)Qef{B zm1>*mSy5xdWaI1|IwoYS57>g)k9Q89&_k&{+)e|}_k&xoAe;v^K_dVgdRqG;^xuL! zkZt6#X#qbyH<EJVW<)bi)Rfb6IPGjPLYt1glD=TxOw<KFdS>=ZflhGpK7_tP!Jp5B z2-J>Xr@lwi>5uHso)(cdSQB@e{-F2y!XKTO<TQG_c_{A7_`nI5!7yPa4H7E|Fi2n0 zZK#dL8?phZLqI{^BnUVE{_~&zBwBVK?@T>&!z$@325BcRyOb=blQ{Q#F5{7btkH0o zPSzZ#Abq&Zc#tb+%QDCP8YfZca4Jqay^YUF7Zdg-N(&nOaj#i$Avi_3cWhoE$Z1^Q z5q?R2OuT@4vM}Mn`7-x5PHIPoTw7t_Ft%hn_XmVs25|F+*SEIBpu;Gyiz!Mxov65; z$9aE$|Ndc5J~W*49@$P;buKwNK!f63E#ZS?+;^K{I7k4!K~*akh-}2Kn@lE|)<*+& zToi38@bhIOYEo{SQRApUOgWYCRE%mk7H6<igvp#o10D5-#atM3!sXN0wG}l8(t7CA zlwfU7G$czB++Jl8ul4yz2i@^L`Zg8)NcO#U<LMyBTEl_Vfeb=j4QjCuLwBDaeSfZ> z7GG<Pz!0jm<}1=DUFpHZ8_9*mA|GgPJ%S9y`9xH>U@fGkt3^BcYoHKoo#PXx9xTRo z7p66l4Mv?ExaP)aLRXwmEE9c5S18KnGPBDs_&Z=CvEj()&+Ld$zhK1sNp9<2sL<05 zA1^A?dxVM1xN)5Rfq4HSK;KjGRkfux>l2e<((zw^ec8la^{D{xhbZYdGN5XYn+P<w zIxS4wW&rZK(o*12SrPhtK8~*w4BpPsm)1OiGHp@Tn>ZX%*tyC(cjwS`r8H~UC?U`> zd<SwgQqFePbszgr^T}@6tJEM&eIXn++8F@{n7@a!S0Oem`_K?!-J#dFZA8AqMhDJY z>x5-@xA<tezy#LaWHT6Z>WM&;EV8ARY1Lc0U-w<>f$tu8M{RQNyly?_n>-^NH5F8a zo6WSZ_-da;{rDPe3ybBexv=8gO~vWAixnyj***a#@tWI*ZgSekW1O^{sZ!Dxa6&qQ zZ0xE0gRQd6x<r5OaFI)d%OuCAsoT8^wS+s^pLN~CQ11=*n0B7~w$`9Ex#uWpP-Fk| zF4~%!lDcEqn_1|K3`4d5?Q_^9=wUJ!>$@>ZU-$qxs*|_el_G$OJ6%DTaTThP!w{(e zGka_f2st5Ug`y!KtE&D6b>V!_FdNa796BsEL(5rJEo4G&q`e3sKQ_=<&^{MLLT`CP zom@#xGTW-cvpT2JCGA0i?8q%nC+ss{%DL_Eppi+P`sjB^wiXW76{H00uC*L>^Z1CT z17QUbTU#47Sn7ljT<l*OwDe%A8@{;(JSB>W5B4zfk#RS&+DOKPI}t2g+3SfULqvrz z;>e0Z9^T&f+N#cY4JJ5e{nFFI-L4DVu>xNMI+?w<PlIfEEAFXeDV~bQ(jZwLad+vb zJw_uULq$Z&WjL(Wi1MA1B(&9eSA$M^I7DnnmH8|_LxvOM2WVKzC#F6(D7Bd;UF4wF zG@1)_K3u(7{H19b{(NTikZd(Uo@hwLx+RM6UFvD+z^?&x2`L6*vUv!M1)Vxwi|&KH zgab(<_$VAvN*o;LC}U3-O;J9dSxe)i%Fc%-Yiq?VdT_tW9|wK^M3i8WkIe|H5k2fg z5aOlIY@xl3T+cQoEiF$07&>jjnbXLXHV$MvxmHR#=wvbHgv>B?7VhN3vy$yXzV|pf z?m#brOYd4H4{$hgmKfZlAv+qW6E1!t`l39JybiZZtmJOl5E_<bvdLvFkn5$fqhMg3 zJdvWX+QdUj*NLJb<BGlBS2Pb&S~8kYHkZ%J#!bLodGP^>-Seo$8T2S<`@v>qFml{G z%9T(jm2*Fc(z3>~S6v`8{q~$v15Nq{6M$eNp`Y<Mah1M&!$ZtqoTaW%)KK+p^<f;j z(9fc*8nklOJi5bZZxCBIJ$KgutU=>ASXwK>GCD1gMeNszY-*@}P;?R6jnhYbo5UsT zy8jf6W}?52p()q-<Qt(tXITRGU?zD<ZXF5@+cjjVy%~Gb(}5RLv#^S^0I+x)1gl!K zXr@p&^dOs$`1jr<WkGNv(W+iQoT0h$68WnSN4MDyR~}WhQ+JGv|2Rx4^-)6Wl}v!c z5r!TZ{ZKi&n+m}B>N$OGc+$b;)+w*#W{)8KdLxv@WM}dvacGKVh2k#A1x4|o#d*Ij zh(yc5S@)zX7CZ^~B`4AXaM_}%&rNqO_551%T+l`^T|)Ay8ggjZrfC{LG^*N|wCrl1 zTv}o0oIC6>wXZQ3{(x+)xxsq-*BdlsFA6=f0ZKFyN>ZF5%XjeZpSi!#@plIV=AJMI z7GTe&xXAJ?MehyhgQ5GTBi99DARj32Da8P<lP5B6tv*X8I6=o6q#7ffAzZO%E<c$L z+0pot0EHrqH)-C6v>0O4>}v`^_I}<~i$(gxwlE_F;YvUomNy^EePh4h?^h;oZD{Ue z%_GFUMFgFljvY2U%d)qJQSYN^8ev1Kz_8q(W?Y(@xhJMCDf;c`9U+;<mgaxZ$^Wft zuT|xJMx=R9;lJABDA!R*?nwt0ph}ohB3SUr&pWe<&l*|O6Uk@8%RaP~Yb6^<E#2if ziETd{oW88njMdjZvyG6p@3j{7`0WLGW}!p$JQ`r^B6n*HndW{|PHNZyARC68o*5JE z5oc&)3l<-6J^b^eC^%c|>blQSH`;p|Yn+{mMvNmiQQg+2AUH+hN#w*VE4^+T5aFnq zq4~EYw$@J4I{tGG7s*{W6Ul!Hb?^swF;+d&<E0-mn=oB#HFKwVV3^$RXDxo$x`v|P zN95{S>_nu)Ly<mn^0`Zz*O<^Em7d#BOH>SbJP31`f{WUg1no_x2)uNJN+Y053SGRx zK59vIrsEwwsRyXtykV+1{Y7bWxDamen#%-dJnnaD*~l+U50kwV*OQ{X`R$OjK-gk! zm`<LSx92&X--C(D8bhLuXH3@J$PFx^MbaG?wbX6hhE$$L2;N=M%;#gGpF?^o)2Y9( zEA0v^R}TyWhzZ5YTV7k*m1?-%q$!RZDh)W0BXrN6lw|2j#8p-rn|+-riqUP*-bPQS z*v7%w7VbM#twu#AY|J>p_(bgzTIJLbo;?1V^e-m9;bPKrTKUY$0z|<?<RMHLX#Wo! zmq;6K+hmoSUlRN;H@cKiZz%Ee#iGt%Jv<DikvR?dWNE6mZufXL&~}dHriN#OBsU4S z+}v$$bpjDS<IwiPkojy!fHKjcP!6?`NU`3MZWtftU$)5o_Jrwltlao645KXCFv7<D z5OH1(AuzNQfenP_h$LGOQDAyUmaq}yG=NCM%30uNY+j#9x=-?sp1mMa-sjR|W}v=4 z-(SD}Qb@85SV|nh0W@q**sL2teq<+R<t4pOi?tS2*p7p$v_tzv*tyXV)GoW}?00XQ zco#vT&Z<IduE9PGyPEvU8S+v^r_72+X0xOYY$ts-*&RRM1zQ1rDXQZpe@UZ_qd7kH zPa^GnI&1WG;)~)=f-SYP%YC#yxcJtRUwX~^k87%jY|f>ICg<<E5}=nHtI^FwIdzy? z+vQr=q~)QGbMo7k&J5ICI3+^WvPM>9t=Mr&iM(O;MdzDrYU4}=?sL-V5KlMG0uS%e zxoMlRV^8W@yo;_{__;MGp>AL%jB7U&_2)Yy=0!UCp+HL{k#sEgwFLFar<wR!m<v&; zs}-0uj1{jHkON;Q$D)2#nm}tW^?qZzQofms*h&r2@eRXjtn|+1RyNO&N|$R2#2K#% z&{bLzK!0d`rM_Dea54jDI@qdegWVy7=tAuye<##co1_|fT5JK=`yrUCPGRn5vQNM> zgnDD+Nntf?*L9()p(#gs^d@v*kEi^%#yj$9m82+z^)=iaML<&`{<RXui|6rJ&vn7T zTkAgbxDH5ARg}C#X?BMAK5Oq@Ta^`j<5PamE-gS<B_~X@@?orCLpg@|G7Io$e?e<> zZcjhzCd$5x^WTm#>KnzOvSw|vTmw^7GmHwn>^L~~rKZW?(xW=O3+&iZ*L6q83>UoK z%wtu-zQlwyu#M2H4dXraPW9g6^JEHr((q4R?*^l4RIH(XWBX?xn=JlDqA<G%pQch| zz8apM6y;z4{;fV_Z8i;di=%ykj+-N(&sE;|XY$5gB04gAUCfWPH#~ra?PP-4Hxo$Y zWeVP8%AZLU9W#QHmCX=IU~TgGW1l2=#>(8O_@mU5H29WJ_z(@!?C0LtYb6_2YJ)<Q zj^8!a8759p{iTEo&hxZ#AI3sg(^C^5fy*72VF5{oMtwGYwr(<H7v0Ui-|vU2Y71*$ z@+_u3<ny_wA7ke!dy#>@0tfCxA(B0+bWvQ%5xu92n7=yE*+`7^4Tku3K-(OKVy6)= z&idYie4q+*a-E%6I7~^*CL?$xWmKA4tf43G$M(>}?;Kl^Fv(zZM0R@bX^5+<+2?^_ z7a8{VYkm{jrLdzmr&snesqLv__Wk|-{{3Uvv{?BsTNB^^{PZOYxTS-sP8&Hr%qwYK zB3b=|H4I>h4%r&qmChg_F5=iNce`oBS*|;6!JF*_5A<XRlt$a79_wxRIXItjN4#1! zDDFJwrrBL#$$?-kvO-3b3#Vf=vB=**n0j)$!g@zE2AkW{)RluuerLwnGR;3*c$UL} z*Xj*5k!PP^iQ+l8r|EdWV5i0DCtq|LLvo_~pd{02Y9r_?<({^35+ZQ=0FzM<w6i%_ zE{q?1-teaymskkYu-41i>K9Fu*aO9Unt&#zoC(_96j=iiLTr}LfWgC5>e&wIRGbC! zq`PKa8~-vYTj$iO7|gT;$u$3b#?vCz7k-+dKJ@I81)KHB+vuBO(1^XCcPV1;fc6;R z|7Sb|83387d7rTTFY|Y>Q^<!gcv|y=j+sREBF9uKT^^W~r!CI`G70shp4#Tb125eB z49x7k*3BGWN27Z-pPEyQg9$yQZi}O_gI1j6tS_;ok$KRcNq-ib<(j`U)KV0pyM-3% zhlB_mrocj@2ivkCy3@eETs*J~NV#vshYP$HEz6sbUiAs|z@2;ebbwRHV5eGp-qDk7 z2{;T`dILZX6`jU{B(P#2eYbN>uO^o`tt@5i%g7XpOqkrjCYWt6G_uSn2#%Tta-XJX zma585wywbDmh()%a5FzMg))tD)WdIbhb6f|FbRW*9omfeG$u$#pDT$*&z^7Wcd!1; zKB9tNkk*YDC!Sd>#<+1Ig?{bL5}5MS=D4Z=4Va98!Y!V!Q~D3bv;uS=PF+hS@+$Zc z9>R;J{Ju)*@6nOyHXt%B5SHcw=MpvOHD$6h1`6-82|}i%A9UH`IZ5lK5kgEI-vS*O z^y4)cv(tCc|3kL{eIjY}qu8~%3`tYkP?_0pb(d$`y`|IG{@c%3Wmw#0;<Ksm6e1v* zBFtU$C1328b1r*VCvHe>t$7i-R@zx|0ry_@Kk!~;E#$S<<6Z?UA<A)G5u1CdginS( z{sN1>2~=`K3rrN8uT=eupbAgEwbl(cI&%|fwb9I-GKYRuCx32)PEY!@ZT>dw>7{?c z?wngsvrfiyT~3=fX;dM<uNJ^2&J^FEmago_wz-*qposr47w8|u=Ev%S??+V|bwWF~ z^ynC&-yD~C>Xxn>_Rqrxia4`>yiE}>GmFosPhXH$vWi|Q4qg*B%dhG1m{UQ97SL*w z;0ldxNNge6V`P$FMQf!}8O3Qt4C#lA8BEK2u8~PJR@Em8@vZCkiQJPJPguZD1t|uH zZtU9A<Nbc$pX-{3Vh;brKw0;cMQMMSq>vn)&keYeE^uvK21c}}%GtZ$)xSei9<Pn& zVn`HVJyB+%@2bCX{*Z#P0HJBKLeF2FCN~5&{HD<$Q^UDN&?kAi{jYVu_HwcfmnpC8 zC^or|O_%^ImdnM55l#*bUZ|v`@78dCJCf&`otdZB*llwRv}nVe%Q#0i6D@B-y5K*5 z>A#isPEDt7<6QPbP{?Q#ngav2znvL_966IFqun|8qOG02jGd_l+W6Qf7~%CMgPqV~ ztxph>g8<!}(nzd+oUN>|WD^Fl>XQ(Mu^7fD;{M|Xg#goiC-<=6dTZkClG8v<WgI5G znTacvOavj*&F!v)Cqe{(8)~kJwRX~}j=G}Ew69tZ)3gWZuBI-IR4bN&UCRX0C!PZK z(Pao#O!w|>fW4OOXbj`;IDRkm`lL^fXb!gcoo>Zt;Xu{J9q_ZDl%$3RKv6p=7L}!Z z>zY#wJCAouv|~@V^IT`-#oiVN<={8)aAX56ojKK^AY=UuwAsa(ur%Nv*Xi4~&fIeS zylxy#dvY9fZanbz*__`kV?6Y#Iq8y_y_4Lhk3y?l@R(f&hHJygKt3EXEcnlv!fm-1 zSNn=w3{r^NsAA@b80%#9cELkMpURpdwnyh#AE?^kNE`I!HZ}&_shf{2Y;-bC+`<~H z(Gt7_hen8OAq?COhSO7P1%uIrj3C~mple6^$VFs(h?t8bz=4DoKDqw~jLLyi5Z4*H P00000NkvXXu0mjf`fnI> literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/setup_off.png b/src/gui/qt/images/setup_off.png new file mode 100644 index 0000000000000000000000000000000000000000..233d26f6005cfc67509606e2cc8213d71ef49b92 GIT binary patch literal 1529 zcmV<V1qS+wP)<h;3K|Lk000e1NJLTq002P%000sQ0ssI2i;pBr00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9W%8>9MJ#(1%^pP zK~zY`%~xG)6jc;HXJ&S%r7gvkLbr&7k_a}05CJiv7Mp0=G$Do%l)eb5iNPRI6#t&& zfykTj0SWO3h!mqJiKz-fO)L=-wJ8E6Erf=a7Mm<xw)@-JnS0K?KFl&KGuusl^FG|% zd+wQgzH{#R8|>@rBO=?jg%He)h)O8{aAyFJQu>HWDVKtX%v?+f@_Xyz5u|u@MD*lp zn&!^x-tgoiVki^}hr@<p7`AQ4<MFYvv3x%70{VZBV)Xz((=^jG8yXrSk%*B_r{nQ> zTU%RweZ6U#0N}9}TgxT-F7g;WV;7$W`HLyRBkw|=h~QQ!W!rWv7VGWpWoBb^bhNd# zb^iSMj^kLCRSd`ny?FMCEa@A;d&)pBiM!;&oejf?L?SIMEvHYPHm0YiiO8}nUDsWy z#m4YJc)nhcLsl|tn^iRxh8EP#`^3A-4U*vV76(kwI^HE7FqZ)liHMnrh={dRDg^-d z_QcHYS_t9J-oiVL^`EMLWa)|(E0!)^bmID57TF)(dny`@*1O}~lLO!GbC=O*)TKw) z?7p5#eb=?N`&ztkRdR6W?h`4Z^tCeuo@jK(hewB#d6&T(K|CH907$1(nq^rolc$FF zrJJezr%v+pEBp5U6=P;;r8*mHh!x)AgBN3xg=1Ud@b=X&ePrc@qQsHb#fPrkk?iD0 zyPGOe&#CG#7BE4$!Zv^iLJHO$N-$fAo0~2leDln8pY1%v#j}UUwrzumq?F7Y^l4wD z7S>8tXxin0{*lOIsE0zxMC2$rhf+63vVe%76hH<+Ns>xwnb^o^Mgx$F6@p@RWg$t4 zVaW^<0C93;Bpj|<|HA4IbiFt|`dr%Qt5QlKgdwGLHM{TY<p)-6{pr&^t2&N#yms=P z?W^i*5M(%_A3gs0!~!#!kxy>gx~i@M01(Iqg+xLK06<^_RFa8EDTOQ%KnS5r0LrHw zM-2VG`;D{j|8jtcW|?i>2QXY!gb<ph%_cDeko9mgr^bH#<n8C5S-1Dt*&S;af`X@; zpKWiPYdcUgFLVzC0RSj=w+JMa0tE$?SfaF<NJ$+o?pfCa(EReLKW?-)sFAzVv#Av> z@`4VoZ@J|#n4UeS@@ASGzmlxp@cQvvYo1uL_s`8=c325|w6U>nfvM|YrKWNu0RR*M zfMOOxAfi$P2(d((=G6iKk~5_gGb?sr{b$(=U6o2CV-q)G>6xVaG;uvhN@;i@;%hN{ zxbJ%;<tFah^$TfqC^<cuge8kimSNPglM`{QU|A@lh^Q1R0HtKXzcIZ0xp}*O9ct@Z zYXaQ8dhRSPJwU_?fb)Zw{??15t_ZiU)E1{*H}M#b;|L)f$I*3tR^cF~j=Z?-`)q!t zp<j(|`>pp?oV*=gV!YMSQs8LV^37L!msB8t3;_xzBG-hpysPKqof|i-y}fZ|#ktg$ z^A~o>iQ6O<)GH#A|FQdU-$4jrD5Wx)OgJ3&dbMCL@IWgTe*EjHq?5_yrCvL4&Yf!m zqhxd(zCmBydut_bUb=Y4R)FS~pGR<XVCc@Yd&#YT>>VdZy3)yvP!HA3jbFPmMr1Z_ z=2Loq-=I^fNS7($Qp#K|$1HLG{{4v9)YMc}Rb?244|j>&iU^>Ym6e7jt?aaXP+qXJ z2qx>w>S|NRTq;8Wcl9|>u#52+m^qux4h{}7lhNGV+}+*nI8I$%T__atvQx=0Dj#Yy z^=BoMM42`zX!2mDaog?j@$t^iPVDdRHw>evr)PM0IFregiRqboyI?^q-wOuY!7}A_ zCWe}tnq|wDwYRtDaydMI{=BAXwY9aTX%;`iOl?_E!{EP5@U*0l`H;C=FU9+u*=Iy% fwrx9+ND$G#W?yF^K4ym800000NkvXXu0mjfHDljn literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/setup_on.png b/src/gui/qt/images/setup_on.png new file mode 100644 index 0000000000000000000000000000000000000000..cba7b68c9fac21e5ec9c2c909d179361f3d35b65 GIT binary patch literal 1523 zcmV<P1q}L$P)<h;3K|Lk000e1NJLTq002P%000sQ0ssI2i;pBr00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9Sj2_G3)>U1%OFJ zK~zY`y;o~&R7Dg%b7uDLZs~3xp=^tFYmKDx1A{!G!3HV_i8e}Fh|+{0q#>j+O{;-4 z#-IKm@lgXvqA5hFzkoC$A~b|lX`n%@H7N3sVs{bC(st=<pZ76${4vYT?cQx|B=P*X znLBsRnRCu}UYGRu_Zx<hPNxmSFilek0RYxhE(js^9qSbUBnu*%rfKcKOtKD3Ui+pc z-}-7ljEI&FS(+dsW6b06AR<#$H4=&R^z?+o;i;)9aFBJeb%&+L|3+Cl0D#}`4+euZ zH8p`ifOK_rb#!zD0)gV<Vz1Y0c_pXzmQc$W=cjp+oy#e~DLD%wRaK+W=*Y-OLqh{; zZf@3fy|S`0FE5W$n&soi(Q=*!{5M!Q=gDL;6bf<9Stt~$uC5LQ0*azY17^cvM);aq zETJl%JcZ%hzO>eMnOVVYKa+L983l4Jgz))%0C3?#FEdS3MiC<BbdPg$`p(71_YcZ- z(}Axyl(EZ4-~II5SmyJ_=1-mt?>%&ShLpnU1Bdq9IoM)sZ(qN70RWKHz4jx6P0j1c zaR2t!kL0P9b-Q=gtuOV``JllVD=I2NB<OOvJRT2Yj4?(Z5wnr~l~T&6{(F1phnMf` zx~?ZCT30QmE?-5`b!Z@>Yw2_<kv_R^)4tAlB4udNj+*k%uSRq|oqW(;T~hFr*IiX! zlo3@BEYGhfV9ftSIjlY$)%9fb&z;dTM}LcEDUhXuT~$l-%)14*z4$n*kPvyLigNw( z+3vALpe*oHol-Oq@<y(m9o8vD0;U0QpMt7UO$Z+T<?LOdFrsmS06<6va4>;-38g3~ zaP8;rZs99^{;lPsdWlpfE8gtEY!&g0#|a^nQbd%ZbLu_A22!}?%$IG;>pH6&+IQDg zEnI*Uy~VWi#PJpRERht;UVgQzSTPL2sHuWL0LF+3z$hgI0Ff~Q00g)IA#Vj!O9G^C zo^NYC_uhAHjK}8_OPq6QEhB_TC=k(}e6yG5<fyXRn7n)D@ZQaDzuEZlv8~GjLcqFB z^{-d>HC-sEP9+S9C}#XF;Y9#Kh(f7sf`~$Aj1jKD)wcRK0AAQ}^2fnf{Lw2zskys^ zwU%l#i2!3vHpRKivwX(?zVZF|!j<oQ6I!*Rvh~*H17+$sf3hN2P{dq}Ohtw%wIwA% z#?Xp~(O7b+HxB@a;FB2xRe148?9xszS4YEx{o%=s(f?MIWh@~gBadhf&KYDRBNOT( zO8*$><B@52y39wZ2QfbK*Mqdexc~sm1_A&CGu}Z@)y9IB-tbG?mMKC^-0C|=mV7{| zK@jx#Prbd8Me^p1XKTu^uQRbEGb3khb@pS#)bYk0rxWR=jNUBU_QQoe?t3A31#7CW z&G3|NKK4~h&_e)(0z^lolnNmL^k;T``&rYv*ES4SFLhsv)nDvuA)z5e0;PzQl9?&% zs3ke3gp3Vtw_DeBxn)Nqt36py;d}1H<fI;pr8q4t^p4)THiX{Sz8Ex)KDtt<cLoMV zQ~|`j^?aBN{d!|GDW!$)rFNaT+c-Tjt&8Fk-`Mr5VM07hwisQc|H^d@K<bclzHpXJ z&beV2E|-h!-@m`Gu&}bS((QKV%;_A>l2EtTtDu>TC(T@Q)ZD@7$<J31QqytWfwQxh zJCl<TB1dCQ(}sqI#>dCmnl)=qojL^oB_$<t=9^<mu}q4`rn08!c@DEeh(sds_+xB3 zogNz-yM6n1ZEY<X7#MK5Ts=KKp-?Cmi^=?R4%=DYa!xfl{g<;i&Svx6P}onJrkS6g z9}EW9u3a0C$4OsbA0fo=_sjo@oc|)TVUja*Ow-KjsZPsho9bsX!|6)Sxu$6kA3o%q Z{{v2Rm$=?TNIw7o002ovPDHLkV1jK{+~5EJ literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/sfl-logo.png b/src/gui/qt/images/sfl-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..27301e9050c698c85091716ce6566762eddde38f GIT binary patch literal 12635 zcmX|Iby$<{_ntUp5>g{XV&bUL-7%0D-Q69dI|La5(k0y>-5?+>BHdB~0s_({-SFGz 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 Vo?6kHeYEBQKu9aUt(G)J{U0aibl3m@ literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/sflphone_logo.png b/src/gui/qt/images/sflphone_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..a1637322248865099cc2b88d75cbf6d091d84f24 GIT binary patch literal 10468 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 WcE<9r)+N}c2$7RgmMj-HhW{TZJqYFi literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/signalisations.png b/src/gui/qt/images/signalisations.png new file mode 100644 index 0000000000000000000000000000000000000000..61a34b98a02d84d9e13f2f5df19e146e054b402c GIT binary patch literal 2270 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 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/slider.png b/src/gui/qt/images/slider.png new file mode 100644 index 0000000000000000000000000000000000000000..22d9e9ed3bed149d3416a02ff3ed7edd7e82bb0a GIT binary patch literal 716 zcmV;-0yF)IP)<h;3K|Lk000e1NJLTq000UA002@50ssI2;*HX900009a7bBm000XU z000XU0RWnu7ytkO2XskIMF-Ui1r97O9595$0000TbVXQnLvL+uWo~o;Lvm$dbY)~9 zcWHEJAXI2&AV*0}Q14_VZU6uRLP<nHR7l5#R&8tBFc3aV=P2%+mO@L&R@e*c|0lm@ zj4=vrploGqBy7ZveYX!%?leo9^(oOw_wqc?om_3VTL55YNES0=RaNo-_#6?TF($sv z%yNO5(OT<&z5Mv~@c3+u{qS~kwYu;p@N_!)U!T7|zH)f~@eQ*P|E8|%x~>uN;pzMO z_WGh}UT@asyl}tYhuF;4T5IiUwc72TLhR*o=@YKb%Q@$qQ}ZNY0FX^Q9*-#?ecuQ3 zr0$ULc@yipPR)oI%tSQ75&(u_2%!4dlM^1RVr;1b7mGz&n2$|F{}38y&dkOb?7HrM zv4zmsjclT?p?F)&acnhbQIm4=u{{_>q@YeT>UU6>Px%G_6l(K)OYA(~Sx}XdaU9dz zL=-X?VdT|PLM;?lid|I|Go!yZxh<P{%$;+=xkn(|1^|Guw~X_W)--n725J^z#AbmK zt+l?y6g2?AVHi@g-WKQaiN5axYBQ8bl5vH~_lz7wR+HFMSSAe|D9JJ=n|ajKxs2TS zgv1J&XO&tc)b~b^LrSRXJS${%-ZV{Gx3sOvK2eI#jLxMY(#(tft<GmM7jn`ERNs;! z-)-Bbb+>IB%%#Z`oM#92%;3_x(}@`uHivo15X9uUBcix4o#!)|XWuc^d3L5M-(t?c zL|Gwgf5$!MeRN%?I#&b0IF92u9u9|TY$AGhcl+(-=jGMq?>}9Qp|is0i?#Ot{aru8 yr!Tu>*V*&Z*qimuW_=TXTNUe;6D9>D-uVmg(B;FAx)84b0000<MNUMnLSTXb2vQXQ literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/splash.png b/src/gui/qt/images/splash.png new file mode 100644 index 0000000000000000000000000000000000000000..948c7efafc593cdc05019094c11b80b32e483710 GIT binary patch literal 114424 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 JIz^kP{|6GEa7X|E literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/transfer_off.png b/src/gui/qt/images/transfer_off.png new file mode 100644 index 0000000000000000000000000000000000000000..7e9db097e9c97687121206985c8e173781a506ec GIT binary patch literal 2081 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 LNkvXXu0mjfC8FjF literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/transfer_on.png b/src/gui/qt/images/transfer_on.png new file mode 100644 index 0000000000000000000000000000000000000000..806f06de449184ef527220dae7b6228ace2d727f GIT binary patch literal 2091 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 Viy)*|5-tD$002ovPDHLkV1fy7`<MU# literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/tray-icon.png b/src/gui/qt/images/tray-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f9af862f1bcd76ea726a900648521b7fe5e70ff3 GIT binary patch literal 1356 zcmV-S1+)5zP)<h;3K|Lk000e1NJLTq000yK000#T1^@s6M%B)!00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C>j?Cl}z*(v|=K1ldVM zK~#9!Wm8LRR8<)M&biN-x$|nL9j4PMb$F!Z6-cn9Q9#lKi4llmq9_;=7bGqe6L)TK zYhnxwqX`Q!L1K(X12JKtBx*DQm6jGPrG?hE!_0IZojZ5t&Yk->$Ax7m^k1Ev^PT_k zecw;8Dsr_3`Ee>EPnN2^gk%5hg1*^wy=@82w~vA#U$=g97`xFKP)0la%B|grwuM~H zvd`?_*2*D1I*jF(>7NV5?$K;z-}P+y&1%ybC^wpss_jybaR7io=|R6F90=)Rp);V2 zH(hpaduRC9xk|m#8ws#h!m->ky*&MJ!&K2Ybu+j8%Kb{c*LFQZ34tOB5CjTUppZaN zwru&K(MXmWc9-6CQdQgi-eLUfvE1_go$I1Zyi?H0wM;2Fv8126mMNXg7*?Ch7@>rq zKNiA)bR6xP4?#&lwqoMj$$8A{CM?$@^SZg!Wjvt>R7+^;**gV&QP2(^Q~p{kzjQNK zd1uiu6E5Qf05nCy+q*X4{bx60U#cAx1V7DWF<H=Idkg@;I7r=beWv4e)g5mxSGVrc zh$;<bYK_y2hS~Ed833rFh@P+?odE?QS;SXkv$!&og<-p^b%e_}S*V&lnW}j@EK5Ul zVo4vKt<?H#kI~gYy=miiK}WUe0082eim)ny5UdH?V|2Ds?;BszhlRwU6CY2NjP)Mp zYk-NM4|`KFL{%9*VLt>)kgr>)+Ai2rc*kQ>XF%}_{)4Z7o~>C=bSDWEo7zJ-x+R67 zWE)gbKvb2mwIhu6Q4LMTk*`~@T(9-V;~YUniVL;pU;fBpto0yJg5h)m?+t9mp^XW& z`D73Pgb--5h>cMV+dIOLL=h89m6kvNP<LD^xciTud32#EGLCIqk57hoV4y3Cpd#UE z$^=3XRb}i+wjr#@xK}b@*e>}0V?&e#3fp4{$Rb|t@5YDE^&zUtC|WiYfg++v5LPLX zuQ%~$ri>21j3a$Xs3OIu*Qas6Y(NnOh{>SOo2}G^4N(m*Zb~3ivvA?|JpMII3?*ZD zt-l*#xwWAvSq{#P&tbV{;e~V@dy{S0)7_4Fy^fxc-xH&%JUUOz-Rm?JcS{D&UZ2Kj zwhVz1q{9Iy^a;Jd2~e>ejAYB0E>|&;i^1U>vOp14rBP84=oOzNY@NvKzJH1aaz+C# zV+i{d!~#AjB3)}d0x-_8+_3S>gFFOEpa`_#lf)}D74~24@GCO~)8ZMu4tGUyi4Z6P zT_cL)c<`Dou;N48^I&@(j|Y^QO>Np$nhN_zwseHPiTRY`>MbyA2UA5I70UsCY+j7! zm$9gutDEI9pPcWHg)Sz7{t@BCyC1lkBo-Xb(#w{UwmeS&Kp5vR9fpWcMu%U4$2tDa zRd9ZM4!4#nV4Q;x@TgBV(-G~v-bmn!fv&b90f0Xiit?p<nZciD^T!vB#*sq38D}d* zKNHokD;|L+i<m4L7+<QuXgZ*TARbWisZijDfv)J6HOCz}e|V6!hCF%c8g&^@H5~8w zc)s#Rv0<kT+fiNi<j#teA}EVi%r8IK*%`eURK*L7^M&(=2iXb*kK?l&Go)xXwMD}m zoY&30jPpZ=?e5CeEdao}fQq0jj*66C?g{&UPinqvz0pAJtsT9ss{aA<oJwGGfO!!B O0000<MNUMnLSTZBVRPI7 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/video.png b/src/gui/qt/images/video.png new file mode 100644 index 0000000000000000000000000000000000000000..f642e00ba09a024c240475438db64c3c955e1838 GIT binary patch literal 2442 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 IM6N<$g4pSqRsaA1 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/voicemail_off.png b/src/gui/qt/images/voicemail_off.png new file mode 100644 index 0000000000000000000000000000000000000000..9dea4984d90c0b28220d059b16368ef8a6dbb6c3 GIT binary patch literal 2049 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 literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/voicemail_on.png b/src/gui/qt/images/voicemail_on.png new file mode 100644 index 0000000000000000000000000000000000000000..9c0f1666dd69251add93b7ecb1d8ec58be4c0ff4 GIT binary patch literal 2083 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 N002ovPDHLkV1mOk2nhfH literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/volume.png b/src/gui/qt/images/volume.png new file mode 100644 index 0000000000000000000000000000000000000000..4a4da95f8879bc66fddbee530cdeb2c14eb1509e GIT binary patch literal 514 zcmV+d0{#7oP)<h;3K|Lk000e1NJLTq000UA000UI1^@s6jWW-@00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)d~a@9W0%0qnQ8z03CEi zSad^gZEa<4bO1wgWnpw>WFU8GbZ8({Xk{QrNlj4iWF>9@00Cx6L_t&-(>2h~E2ME8 z!14F@dA?(wXW4m}C&@Imrft@bN#-QvB5hh}+7$T@9F)6Uw#L~>qTF4OAx*o9959O7 zl(zOFMPi#3!~F0J9|yeuf_E>)Tl<+qS=&D2_%sIyt&sp7u`0eN`V@cySV{eq<c^QY zZ&B*Q4gi<ucZ@HeFx~4hGBlvn+`^(vWNMih?w}=PVHzL;r7|3y6_{E&V7B`j^Y2sJ zkBe9npB=$_Dso#Y@V}7f>ORN$!!1W;kITJd^rNzf)>QJZWWv2d@r>|#m3=gc)>Lwl z2kqFJi2IRHwT)F#f$jH!K;A23YK<p~(+?Wm`NhR{1JpS-Relr8Zy-Ri^h~bk$J83T z-ol7Sd`LP;z|njPYZ^laO(BDZuqNPWjC7Koc<_~Hb^VuQcDG23j$zjZK|%5QhSdBF z?Oi<#Ci;|m2j56<%Ab?pWV2aB1lM(Gj>Q@1|Ed690IX1WzH-KbasU7T07*qoM6N<$ Ef_f<5rT_o{ literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/volume_off.png b/src/gui/qt/images/volume_off.png new file mode 100644 index 0000000000000000000000000000000000000000..fd7a004e8909c524d5f67bd336a6b800a94f5385 GIT binary patch literal 433 zcmV;i0Z#sjP)<h;3K|Lk000e1NJLTq000UA000UI0ssI20#I1$00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru)C?8?9VXbA_&NXp0X|7Y zK~xyiCD6}H!cZIl@b7zjx*x7BeNjyoIl?j|@|Yc>vWo_F?d+*je}WzC?Eg^rAR45X zpi_q+2*H9bLd;BJfx71Abgx67KjDKIV*qe-+jx3)o9!V0+c1=^tSs_?F-E3ox;{RC zh+Z6LG+hONt~EHjZq*8b#D}=kb50w4`6w@F+JH&@P~zqn%cboTQ?R}q?tQx1$!1nm z7EHaqKl&NDJ!feB_May~_pwRFNJz(H-#!NpLJ%?l0A!E3bUfB^fv6%e=uC1}6rxd) zj{pNVm~eyy47DXf@~c#&%7QA&JSXs&0eF5m^mvXCQ4?^^h_HH9QOUAS){;1r#3`L9 zD#7*YUM_)+CAwQEeOy+k^C=Tgj(BrU*Sf0g>=#pd0{yq#HSXV9FSczn#wexh+1z3A b008~~>WO*4P4uZ?00000NkvXXu0mjfT^_Rn literal 0 HcmV?d00001 diff --git a/src/gui/qt/images/volume_on.png b/src/gui/qt/images/volume_on.png new file mode 100644 index 0000000000000000000000000000000000000000..13189014b3b0c34c25dd7b65f1ce4900d4f86e1e GIT binary patch literal 436 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V6Od#Ih<F90*pj^6T^Rm@;DWu&Cj&(|3p^r= z85p>QL70(Y)*K0-AbW|YuPggiMri>P*$<(Qd>9xQ9X(wfLnJOUnlYaI$N2yMf1s)j zn|5qJaO>**Hw+B_)no<yU3EFx8JL)u7&mX;{Ou=G*^0YqHnPHEJV2#yUw!RAaDPg) zDi`}drl&8zq%67@;AF%mBJ$-Q+vmS*i~@o_R=N?3Up#s7h56E3q1Os>lAOQ){Q2?q z*RM}Mf4u+x_0{*!H-G=QbMPd~Zw7W*K92W485tNE85sTn4F|gJ<8Nje9`@Hi7+84N znI-wSM7UYmSXtRwS^od~_v_z(Cg$IN|1&)2U}n*g<7eaN7Utz-XZpv+1`3&<zy2|b zOE5is#xBgp<Zh$EaAE-$7o&t2vz!Pc5J`$LGyM6$baG*+rwNmytZ-yZ^2_aW_`bj8 zWc~$2{NLZc-Z3{KCRss72pTNgcI>@=^}@xA7lDTB>FH@|8+d!V0NH}pRa<+Kl^z3` N44$rjF6*2Ung9%enEwC( literal 0 HcmV?d00001 diff --git a/src/gui/qt/main.cpp b/src/gui/qt/main.cpp new file mode 100644 index 0000000000..dd556cdc94 --- /dev/null +++ b/src/gui/qt/main.cpp @@ -0,0 +1,74 @@ +/** + * Copyright (C) 2004-2005 Savoir-Faire Linux inc. + * Author: Jean-Philippe Barrette-LaPierre + * <jean-philippe.barrette-lapierre@savoirfairelinux.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <iostream> +#include <stdexcept> +#include <qcolor.h> +#include <qsplashscreen.h> +#include <qstring.h> +#include <qtextcodec.h> +#include <qtimer.h> +#include <qtranslator.h> + +#include "PhoneLineManager.hpp" +#include "SFLPhoneApp.hpp" +#include "SFLPhoneWindow.hpp" +#include "TransparentWidget.hpp" + +int main(int argc, char **argv) +{ + SFLPhoneApp app(argc, argv); + + QSplashScreen *splash = new QSplashScreen(TransparentWidget::retreive("splash.png")); + splash->show(); + + // translation file for Qt + QTranslator qt(NULL); + qt.load( QString( "qt_" ) + QTextCodec::locale(), "." ); + app.installTranslator( &qt ); + + + QTranslator myapp(NULL); + myapp.load( QString( "sflphone-qt_" ) + QTextCodec::locale(), "." ); + app.installTranslator( &myapp ); + + SFLPhoneWindow* sfl = new SFLPhoneWindow(); + app.initConnections(sfl); +#ifndef QT3_SUPPORT + app.setMainWidget(sfl); +#endif + + app.launch(); + PhoneLineManager::instance().connect(); + //splash->finish(sfl); + //sfl->show(); + QObject::connect(&PhoneLineManager::instance(), SIGNAL(connected()), + splash, SLOT(hide())); + // QTimer *timer = new QTimer(sfl); + // QObject::connect(timer, SIGNAL(timeout()), + // sfl, SLOT(show())); +// QObject::connect(timer, SIGNAL(timeout()), +// splash, SLOT(close())); + +// timer->start(1500, true); + + //delete splash; + return app.exec(); +} diff --git a/src/gui/qt/sflphone-qt.pro b/src/gui/qt/sflphone-qt.pro new file mode 100644 index 0000000000..e723fa146e --- /dev/null +++ b/src/gui/qt/sflphone-qt.pro @@ -0,0 +1,180 @@ +###################################################################### +# Automatically generated by qmake (2.00a) Thu Sep 22 11:58:09 2005 +###################################################################### + +TEMPLATE = app +TARGET += +#DEPENDPATH += . +#INCLUDEPATH += . +# This line is for qt4: +# INCLUDEPATH += /usr/lib/qt4/include/Qt/ +QT += network qt3support +CONFIG += debug +DEFINES += QT_THREAD_SUPPORT +DISTFILES += INSTALL README +VERSION = 0.6.0 + +TRANSLATIONS = sflphone-qt_fr.ts + +FORMS = ConfigurationPanel.ui + +IMAGES += \ +images/about.png \ +images/audio.png \ +images/clear_off.png \ +images/clear_on.png \ +images/close_off.png \ +images/close_on.png \ +images/conference_off.png \ +images/conference_on.png \ +images/directory_off.png \ +images/directory_on.png \ +images/dtmf_0_off.png \ +images/dtmf_0_on.png \ +images/dtmf_1_off.png \ +images/dtmf_1_on.png \ +images/dtmf_2_off.png \ +images/dtmf_2_on.png \ +images/dtmf_3_off.png \ +images/dtmf_3_on.png \ +images/dtmf_4_off.png \ +images/dtmf_4_on.png \ +images/dtmf_5_off.png \ +images/dtmf_5_on.png \ +images/dtmf_6_off.png \ +images/dtmf_6_on.png \ +images/dtmf_7_off.png \ +images/dtmf_7_on.png \ +images/dtmf_8_off.png \ +images/dtmf_8_on.png \ +images/dtmf_9_off.png \ +images/dtmf_9_on.png \ +images/dtmf_close_off.png \ +images/dtmf_close_on.png \ +images/dtmf_main.png \ +images/dtmf_off.png \ +images/dtmf_on.png \ +images/dtmf_pound_off.png \ +images/dtmf_pound_on.png \ +images/dtmf_star_off.png \ +images/dtmf_star_on.png \ +images/gsm.png \ +images/hangup_off.png \ +images/hangup_on.png \ +images/hold_off.png \ +images/hold_on.png \ +images/l.png \ +images/l1_off.png \ +images/l1_on.png \ +images/l2_off.png \ +images/l2_on.png \ +images/l3_off.png \ +images/l3_on.png \ +images/l4_off.png \ +images/l4_on.png \ +images/l5_off.png \ +images/l5_on.png \ +images/l6_off.png \ +images/l6_on.png \ +images/logo_ico.png \ +images/main.png \ +images/minimize_off.png \ +images/minimize_on.png \ +images/mute_off.png \ +images/mute_on.png \ +images/network.png \ +images/ok_off.png \ +images/ok_on.png \ +images/overscreen.png \ +images/preferences.png \ +images/screen_main.png \ +images/setup_off.png \ +images/setup_on.png \ +images/sfl-logo.png \ +images/sflphone_logo.png \ +images/signalisations.png \ +images/slider.png \ +images/splash.png \ +images/transfer_off.png \ +images/transfer_on.png \ +images/tray-icon.png \ +images/video.png \ +images/voicemail_off.png \ +images/voicemail_on.png \ +images/volume.png \ +images/volume_off.png \ +images/volume_on.png + +# Input +HEADERS += Account.hpp \ + CallManager.hpp \ + CallManagerImpl.hpp \ + Call.hpp \ + CallStatus.hpp \ + CallStatusFactory.hpp \ + ConfigurationManager.hpp \ + ConfigurationManagerImpl.hpp \ + DebugOutput.hpp \ + DebugOutputImpl.hpp \ + Event.hpp \ + EventFactory.hpp EventFactory.inl \ + Factory.hpp Factory.inl \ + globals.h \ + JPushButton.hpp \ + Launcher.hpp \ + NumericKeypad.hpp \ + ObjectFactory.hpp ObjectFactory.inl \ + ObjectPool.hpp \ + PhoneLine.hpp \ + PhoneLineButton.hpp \ + PhoneLineLocker.hpp \ + PhoneLineManager.hpp \ + PhoneLineManagerImpl.hpp \ + QjListBoxPixmap.hpp \ + Request.hpp \ + Requester.hpp \ + RequesterImpl.hpp RequesterImpl.inl \ + Session.hpp \ + SessionIO.hpp \ + SessionIOFactory.hpp \ + SFLCallStatus.hpp \ + SFLEvents.hpp \ + SFLLcd.hpp \ + SFLPhoneApp.hpp \ + SFLPhoneWindow.hpp \ + SFLRequest.hpp \ + TCPSessionIO.hpp \ + TCPSessionIOCreator.hpp \ + TransparentWidget.hpp \ + Url.hpp \ + VolumeControl.hpp +SOURCES += Account.cpp \ + Call.cpp \ + CallManagerImpl.cpp \ + CallStatus.cpp \ + ConfigurationManagerImpl.cpp \ + DebugOutputImpl.cpp \ + Event.cpp \ + JPushButton.cpp \ + Launcher.cpp \ + main.cpp \ + NumericKeypad.cpp \ + PhoneLine.cpp \ + PhoneLineButton.cpp \ + PhoneLineLocker.cpp \ + PhoneLineManagerImpl.cpp \ + QjListBoxPixmap.cpp \ + Request.cpp \ + RequesterImpl.cpp \ + Session.cpp \ + SFLEvents.cpp \ + SFLLcd.cpp \ + SFLPhoneApp.cpp \ + SFLPhoneWindow.cpp \ + SFLRequest.cpp \ + TCPSessionIO.cpp \ + TCPSessionIOCreator.cpp \ + TransparentWidget.cpp \ + Url.cpp \ + VolumeControl.cpp +RESOURCES += sflphone.qrc diff --git a/src/gui/qt/sflphone-qt_fr.qm b/src/gui/qt/sflphone-qt_fr.qm new file mode 100644 index 0000000000000000000000000000000000000000..ea75d6647bdcbec0094b92fa0f51038a404b58b9 GIT binary patch literal 4753 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 XN@kmSdb=gErZJ`mx2K&%W}EyCz(O<o literal 0 HcmV?d00001 diff --git a/src/gui/qt/sflphone-qt_fr.ts b/src/gui/qt/sflphone-qt_fr.ts new file mode 100644 index 0000000000..162bfda8d3 --- /dev/null +++ b/src/gui/qt/sflphone-qt_fr.ts @@ -0,0 +1,635 @@ +<!DOCTYPE TS><TS> +<context> + <name>ConfigurationPanel</name> + <message> + <source>Configuration panel</source> + <translation>Panneau de configuration</translation> + </message> + <message> + <source>Setup signalisation</source> + <translation>Signalisation</translation> + </message> + <message> + <source>SIP Authentication</source> + <translation>Authentification SIP</translation> + </message> + <message> + <source>Full name</source> + <translation>Nom complet</translation> + </message> + <message> + <source>User Part of SIP URL</source> + <translation>Partie usager de l'URL SIP</translation> + </message> + <message> + <source>Authorization user</source> + <translation>Utilisateur d'authentification</translation> + </message> + <message> + <source>SIP proxy</source> + <translation>Proxy SIP</translation> + </message> + <message> + <source>Password</source> + <translation>Mot de passe</translation> + </message> + <message> + <source>Host part of SIP URL</source> + <translation>Section de l'hôte de l'URL SIP</translation> + </message> + <message> + <source>Auto-register</source> + <translation>Enregistrement Automatique</translation> + </message> + <message> + <source>Register</source> + <translation>Enregistrement</translation> + </message> + <message> + <source>STUN</source> + <translation>STUN</translation> + </message> + <message> + <source>Settings </source> + <translation>Paramètres</translation> + </message> + <message> + <source>STUN server (address:port)</source> + <translation>Serveur STUN (adresse:port)</translation> + </message> + <message> + <source>Use STUN</source> + <translation>Utilisation de STUN</translation> + </message> + <message> + <source>No</source> + <translation>Non</translation> + </message> + <message> + <source>Yes</source> + <translation>Oui</translation> + </message> + <message> + <source>DTMF</source> + <translation>Pavé numérique</translation> + </message> + <message> + <source>Settings</source> + <translation>Paramètres</translation> + </message> + <message> + <source>Play tones locally</source> + <translation>Jouer les tonalités localement</translation> + </message> + <message> + <source>Pulse length</source> + <translation></translation> + </message> + <message> + <source> ms</source> + <translation>ms</translation> + </message> + <message> + <source>Send DTMF as</source> + <translation>Envoyer DTMF en tant que</translation> + </message> + <message> + <source>SIP INFO</source> + <translation>Information SIP</translation> + </message> + <message> + <source>Options</source> + <translation>Options</translation> + </message> + <message> + <source>Zone tone:</source> + <translation>Zones de tonalités:</translation> + </message> + <message> + <source>North America</source> + <translation>Amérique du Nord</translation> + </message> + <message> + <source>France</source> + <translation>France</translation> + </message> + <message> + <source>Australia</source> + <translation>Australie</translation> + </message> + <message> + <source>United Kingdom</source> + <translation>Angleterre</translation> + </message> + <message> + <source>Spain</source> + <translation>Espagne</translation> + </message> + <message> + <source>Italy</source> + <translation>Italie</translation> + </message> + <message> + <source>Japan</source> + <translation>Japon</translation> + </message> + <message> + <source>Drivers</source> + <translation>Pilotes</translation> + </message> + <message> + <source>Drivers list</source> + <translation>Liste de pilotes</translation> + </message> + <message> + <source>Codecs</source> + <translation>Codecs</translation> + </message> + <message> + <source>Supported codecs</source> + <translation>Codecs supportés</translation> + </message> + <message> + <source>G711u</source> + <translation>G711u</translation> + </message> + <message> + <source>G711a</source> + <translation>G711a</translation> + </message> + <message> + <source>GSM</source> + <translation>GSM</translation> + </message> + <message> + <source>1</source> + <translation>1</translation> + </message> + <message> + <source>2</source> + <translation>2</translation> + </message> + <message> + <source>3</source> + <translation>3</translation> + </message> + <message> + <source>Ringtones</source> + <translation>Tonalités de sonnerie</translation> + </message> + <message> + <source>Themes</source> + <translation>Thèmes</translation> + </message> + <message> + <source>&Apply</source> + <translation>&Appliquer</translation> + </message> + <message> + <source>Alt+A</source> + <translation>Alt+A</translation> + </message> + <message> + <source>About SFLPhone</source> + <translation>À propos de SFLPhone</translation> + </message> + <message> + <source>Tab 1</source> + <translation>Onglet 1</translation> + </message> + <message> + <source>Tab 2</source> + <translation>Onglet 2</translation> + </message> + <message encoding="UTF-8"> + <source><p align="center"> +Copyright (C) 2004-2005 Savoir-faire Linux inc.<br /><br /> +Jean-Philippe Barrette-LaPierre <br> +&nbsp;&nbsp;&nbsp;&lt;jean-philippe.barrette-lapierre@savoirfairelinux.com&gt;<br /> +Laurielle LEA <br/> &nbsp;&nbsp;&nbsp;&lt;laurielle.lea@savoirfairelinux.com&gt;<br /> +Yan Morin <br/>&nbsp;&nbsp;&nbsp;&lt;yan.morin@savoirfairelinux.com&gt;<br /> +Jérome Oufella <br/> &nbsp;&nbsp;&nbsp;&lt;jerome.oufella@savoirfairelinux.com&gt;<br /> + +<br />SFLPhone-0.5 is released under the General Public License.For more information, see http://www.sflphone.org</p></source> + <translation type="unfinished"></translation> + </message> + <message> + <source>About Savoir-faire Linux inc.</source> + <translation>À Propos de Savoir-faire Linux inc.</translation> + </message> + <message> + <source><p align="center">Website: http://www.savoirfairelinux.com<br><br> +5505, Saint-Laurent - bureau 3030<br> +Montreal, Quebec H2T 1S6</p></source> + <translation></translation> + </message> + <message> + <source>&OK</source> + <translation>&Ok</translation> + </message> + <message> + <source>Alt+O</source> + <translation>Alt+O</translation> + </message> + <message> + <source>&Cancel</source> + <translation>&Annuler</translation> + </message> + <message> + <source>F, Backspace</source> + <translation>F, Backspace</translation> + </message> +</context> +<context> + <name>Launcher</name> + <message> + <source>Launcher: Couldn't launch sflphoned. +</source> + <translation>Launcher: N'a pu lancer sflphoned.</translation> + </message> + <message> + <source>Launcher: sflphoned launched. +</source> + <translation>Launcher: sflphoned lancé.</translation> + </message> + <message> + <source>%1 +</source> + <translation>%1</translation> + </message> + <message> + <source>Launcher: Trying to read output without a valid process. +</source> + <translation>Launcher: Tentative de lecture de la sortie sans un processus valide.</translation> + </message> + <message> + <source>Launcher: Trying to read error without a valid process. +</source> + <translation>Launcher: Tentative de lecture de la sortie d'erreur sans un processus valide.</translation> + </message> +</context> +<context> + <name>PhoneLine</name> + <message> + <source>PhoneLine %1: I am unselected. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>PhoneLine %1: Trying to set a phone line to an active call. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>PhoneLine %1: Received the character:%2. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>PhoneLine %1: Calling %2. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Calling %1...</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Talking to: %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>PhoneLine %1: We're now in transfer mode. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Transfer to:</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>PhoneLine %1: Trying to transfer to "%2". +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Holding...</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>PhoneLine %1: Trying to Hold. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>PhoneLine %1: Trying to Unhold. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>PhoneLine %1: Trying to answer. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Hanguping...</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Hanguped.</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>PhoneLineManagerImpl</name> + <message> + <source>Trying to connect to sflphone server..</source> + <translation>Tentative de connection sur le serveur sflphoned..</translation> + </message> + <message> + <source>Stopping sflphone server..</source> + <translation>Arrêt de SFLPhone..</translation> + </message> + <message> + <source>Trying to get line status...</source> + <translation>Tentative d'intégoration du status de la ligne...</translation> + </message> + <message> + <source>Welcome to SFLPhone</source> + <translation type="unfinished">SFLPhone vous souhaite la bienvenue</translation> + </message> +</context> +<context> + <name>QObject</name> + <message> + <source> (device #%1)</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>The code %1 has no creator registered. +and there's no default creator</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>%1 status received for call ID: %2. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Status invalid: %1 +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>ConfigurationManagerImpl::save(): We don't have a valid session. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Event: Received: %1 +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Launcher::start() +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ready.</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>PhoneLineManager: Tried to selected line with call ID (%1), which appears to be invalid. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>PhoneLineManager: Tried to selected line %1, which appears to be invalid. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Incomming</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Ringing (%1)...</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>PhoneLineManager: There's no available lineshere for the incomming call ID: %1. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Received an error: + Code: %1 + SequenceID: %2 + Message: %3 +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Received a temp info: + Code: %1 + SequenceID: %2 + Message: %3 +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Received a success info: + Code: %1 + SequenceID: %2 + Message: %3 +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>CallRelatedRequest: Trying to retreive an unregistred call (%1) +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Requester: We received an answer with an unknown sequence (%1). +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Requester: SessionIO input for session %1 is down, but we don't have that session. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>DefaultEvent: We don't handle: %1 +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Hangup Event received for call ID: %1. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Hangup Event invalid (missing call ID): %1 +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Incomming Event received for call ID: %1. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>Incomming Event invalid: %1 +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>EventRequest error: (%1) %1 +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>EventRequest success: (%1) %1 +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>CallStatusRequest error: (%1) %1 +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>CallStatusRequest success: (%1) %1 +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>CallStatusRequest Error: cannot get current line. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>PermanentRequest: Error: %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>We received an error on a call that doesn't have a phone line (%1). +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>We received a status on a call related request that doesn't have a phone line (%1). +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>We received a success on a call related request that doesn't have a phone line (%1). +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>We received an answer on a temporary call related request that doesn't have a phone line (%1). +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>CallRequest: Trying to retreive an unregistred call (%1) +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>ConfigGetAllRequest error: (%1) %1 +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>ConfigSaveRequest error: (%1) %1 +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>StopRequest error: (%1) %1 +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>TCPSessionIO: Connection failed: %1 +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>TCPSessionIO: Tring to connect to %1:%2. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>TCPSessionIO: Connected. +</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>TCPSessioIO: Sending request to sflphone: %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <source>TCPSessionIO: Received answer from sflphone: %1 +</source> + <translation type="unfinished"></translation> + </message> +</context> +<context> + <name>SFLPhoneWindow</name> + <message> + <source>SFLPhone error</source> + <translation>Erreur SFLPhone</translation> + </message> + <message> + <source>We got an error launching sflphone. Check the debug +output with "[sflphoned]" for more details. The +application will close.</source> + <translation type="unfinished">Une erreur est survenue au lancement de SFLPhone. +Vérifier la sortie de "debug" commençant par +"[sflphoned]" pour plus de détails. L'application +va se fermer.</translation> + </message> + <message> + <source>Quit</source> + <translation>Quitter</translation> + </message> + <message> + <source>SFLPhone daemon problem</source> + <translation>Problème du démon SFLPhone</translation> + </message> + <message> + <source>The SFLPhone daemon couldn't be started. Check +if sflphoned is in your PATH. The application will +close. +</source> + <translation>Le démon SFLPhone n'a pu être lancé. Vérifiez +que le programme "sflphoned" est dans votre +"PATH". L'application va se fermer.</translation> + </message> + <message> + <source>SFLPhone status error</source> + <translation>Erreur de status de SFLPhone</translation> + </message> + <message> + <source>The server returned an error for the lines status. + +%1 + +Do you want to try to resend this command? If not, +the application will close.</source> + <translation>SFLPhone a retourné une erreur de status pour les +lignes. + +%1 + +Voulez-vous renvoyer cette commande? Si non, +l'application se terminera.</translation> + </message> +</context> +</TS> diff --git a/src/gui/qt/sflphone.qrc b/src/gui/qt/sflphone.qrc new file mode 100644 index 0000000000..0a2d796cc6 --- /dev/null +++ b/src/gui/qt/sflphone.qrc @@ -0,0 +1,40 @@ +<RCC> + <qresource prefix="/sflphone" > + <file>images/audio.png</file> + <file>images/clear_off.png</file> + <file>images/clear_on.png</file> + <file>images/close_off.png</file> + <file>images/close_on.png</file> + <file>images/directory_on.png</file> + <file>images/hangup_off.png</file> + <file>images/hangup_on.png</file> + <file>images/hold_off.png</file> + <file>images/hold_on.png</file> + <file>images/l1_off.png</file> + <file>images/l1_on.png</file> + <file>images/l2_off.png</file> + <file>images/l2_on.png</file> + <file>images/l3_off.png</file> + <file>images/l3_on.png</file> + <file>images/l4_off.png</file> + <file>images/l4_on.png</file> + <file>images/l5_off.png</file> + <file>images/l5_on.png</file> + <file>images/l6_off.png</file> + <file>images/l6_on.png</file> + <file>images/logo_ico.png</file> + <file>images/main.png</file> + <file>images/minimize_off.png</file> + <file>images/minimize_on.png</file> + <file>images/mute_off.png</file> + <file>images/mute_on.png</file> + <file>images/ok_off.png</file> + <file>images/ok_on.png</file> + <file>images/overscreen.png</file> + <file>images/screen_main.png</file> + <file>images/slider.png</file> + <file>images/volume.png</file> + <file>images/volume_off.png</file> + <file>images/volume_on.png</file> + </qresource> +</RCC> diff --git a/src/gui/qt/skin.ini b/src/gui/qt/skin.ini new file mode 100644 index 0000000000..8500847e83 --- /dev/null +++ b/src/gui/qt/skin.ini @@ -0,0 +1,39 @@ +# Main window +l1=21,151 +l2=52,151 +l3=83,151 +l4=114,151 +l5=145,151 +l6=176,151 +hangup=225,156 +ok=225,182 +mute=225,94 +conference=225,69 +hold=225,68 +transfer=225,42 +voicemail=310,43 +setup=310,68 +dtmf=20,181 +directory=140,181 +screen=22,44 +minimize=353,5 +close=374,5 +vol_mic=347,155-100 +vol_spkr=365,155-100 +# +# DTMF Keypad +dtmf_1=12,22 +dtmf_2=58,22 +dtmf_3=104,22 +dtmf_4=12,67 +dtmf_5=58,67 +dtmf_6=104,67 +dtmf_7=12,112 +dtmf_8=58,112 +dtmf_9=104,112 +dtmf_star=12,157 +dtmf_0=58,157 +dtmf_pound=104,157 +dtmf_close=141,5 +# +# EOF diff --git a/src/gui/qt/utilspp/EmptyType.hpp b/src/gui/qt/utilspp/EmptyType.hpp new file mode 100644 index 0000000000..42a64f9a78 --- /dev/null +++ b/src/gui/qt/utilspp/EmptyType.hpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef UTILSPP_EMPTYTYPE_HPP +#define UTILSPP_EMPTYTYPE_HPP + +namespace utilspp +{ + struct EmptyType {}; +}; + +#endif diff --git a/src/gui/qt/utilspp/Functors.hpp b/src/gui/qt/utilspp/Functors.hpp new file mode 100644 index 0000000000..1751185d96 --- /dev/null +++ b/src/gui/qt/utilspp/Functors.hpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef UTILSPP_FUNCTORS_HPP +#define UTILSPP_FUNCTORS_HPP + +#include "functor/Functor.hpp" + +#endif diff --git a/src/gui/qt/utilspp/NonCopyable.hpp b/src/gui/qt/utilspp/NonCopyable.hpp new file mode 100644 index 0000000000..eb54431293 --- /dev/null +++ b/src/gui/qt/utilspp/NonCopyable.hpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef UTILSPP_NONCOPYABLE_HPP +#define UTILSPP_NONCOPYABLE_HPP + +namespace utilspp +{ + class NonCopyable + { + public: + NonCopyable() + {} + + private: + NonCopyable(const NonCopyable& r) + {} + }; +}; + +#endif diff --git a/src/gui/qt/utilspp/NullType.hpp b/src/gui/qt/utilspp/NullType.hpp new file mode 100644 index 0000000000..819026474b --- /dev/null +++ b/src/gui/qt/utilspp/NullType.hpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef UTILSPP_NULLTYPE_HPP +#define UTILSPP_NULLTYPE_HPP + +namespace utilspp +{ + struct NullType; +}; + +#endif diff --git a/src/gui/qt/utilspp/Singleton.hpp b/src/gui/qt/utilspp/Singleton.hpp new file mode 100644 index 0000000000..487cbebb5d --- /dev/null +++ b/src/gui/qt/utilspp/Singleton.hpp @@ -0,0 +1,2 @@ +#include "ThreadingSingle.hpp" +#include "singleton/SingletonHolder.hpp" diff --git a/src/gui/qt/utilspp/SmartPtr.hpp b/src/gui/qt/utilspp/SmartPtr.hpp new file mode 100644 index 0000000000..43c400be97 --- /dev/null +++ b/src/gui/qt/utilspp/SmartPtr.hpp @@ -0,0 +1,186 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef UTILSPP_SMARTPTR_HPP +#define UTILSPP_SMARTPTR_HPP + +#include <stdexcept> +#include "NonCopyable.hpp" + +#define NULL_BODY_ERROR "the smart pointer contain a NULL pointer" + +namespace utilspp +{ + + template < typename Type = unsigned int > + class FastCount + { + public: + FastCount(Type count = 1) : mCount(count) + {} + + FastCount &operator++() + { + mCount++; + return *this; + } + + FastCount &operator--() + { + mCount--; + return *this; + } + + operator Type() + { + return mCount; + } + + Type useCount() + { + return mCount; + } + + private: + Type mCount; + }; + + + template < typename ContentType, typename CountPolicy = FastCount > + class CountingBody : public utilspp::NonCopyable + { + public: + CountingBody(ContentType *body) : mBody(body) + {} + + void inc() + { + ++mCount; + } + + void dec() + { + --mCount; + if (mCount <= 0) { + delete this; + } + } + + ContentType *get() + { + return mBody; + } + + protected: + ~CountingBody() + { + if (mBody != NULL) { + delete mBody; + mBody = NULL; + } + } + + private: + CountPolicy mCount; + ContentType *mBody; + }; + + + template < typename ContentType, typename CountingBodyPolicy = CountingBody> + class SharedPtr + { + public: + SharedPtr() : mContent(new CountingPolicy< ContentType >(NULL)) + {} + + explicit SharedPtr(ContentType *content) : mContent(new CountingBodyPolicy< ContentType >(content)) + {} + + ~SharedPtr() + { + mContent->dec(); + } + + SharedPtr(const SharedPtr &other) : mContent(other.mContent) + { + mContent->inc(); + } + + SharedPtr& operator=(const SharedPtr &other) + { + if(mContent->get() != other.mContent->get()) { + mContent->dec(); + mContent = other.mContent; + mContent->inc(); + } + return ( *this ); + } + + SharedPtr& operator=(ContentType *content) + { + mContent--; + mContent = new CountingBodyPolicy< ContentType >(content); + } + + bool operator==(const SharedPtr &other) const + { + return (mContent->get() == other.mContent->get()); + } + + bool operator!=(const SharedPtr &other) const + { + return (mContent->get() != other.mContent->get()); + } + + bool operator<(const SharedPtr &other) const + { + return (mContent->get() < other.mContent->get()); + } + + operator ContentType*() + { + return mContent->get(); + } + + ContentType& operator*() + { + if(mContent->get() == NULL) { + throw std::runtime_error(NULL_BODY_ERROR); + } + return *mContent->get(); + } + + ContentType* operator->() + { + if(mContent->get() == NULL) { + throw std::runtime_error(NULL_BODY_ERROR); + } + return mContent->get(); + } + + private: + CountingBodyPolicy * mContent; + }; +}; + +#endif diff --git a/src/gui/qt/utilspp/ThreadingFactoryMutex.hpp b/src/gui/qt/utilspp/ThreadingFactoryMutex.hpp new file mode 100644 index 0000000000..5bd6225f29 --- /dev/null +++ b/src/gui/qt/utilspp/ThreadingFactoryMutex.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef THREADING_FACTORY_MUTEX_HPP +#define THREADING_FACTORY_MUTEX_HPP + +namespace utilspp +{ + template < typename T > + struct ThreadingFactoryMutex + { + struct lock + { + lock(); + lock( const T & ); + }; + + typedef T VolatileType; + }; +}; + +#include "ThreadingFactoryMutex.inl" + +#endif diff --git a/src/gui/qt/utilspp/ThreadingFactoryMutex.inl b/src/gui/qt/utilspp/ThreadingFactoryMutex.inl new file mode 100644 index 0000000000..c9a9f62fbd --- /dev/null +++ b/src/gui/qt/utilspp/ThreadingFactoryMutex.inl @@ -0,0 +1,37 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef THREADING_FACTORY_MUTEX_INL +#define THREADING_FACTORY_MUTEX_INL + +template< typename T > +inline +utilspp::ThreadingSingle< T >::lock::lock() +{}; + +template< typename T > +inline +utilspp::ThreadingSingle< T >::lock::lock( const T & ) +{}; + +#endif \ No newline at end of file diff --git a/src/gui/qt/utilspp/ThreadingSingle.hpp b/src/gui/qt/utilspp/ThreadingSingle.hpp new file mode 100644 index 0000000000..bbab15b5c4 --- /dev/null +++ b/src/gui/qt/utilspp/ThreadingSingle.hpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SINGLE_THREADED_HPP +#define SINGLE_THREADED_HPP + +#include "NullType.hpp" + +namespace utilspp +{ + template < typename T = utilspp::NullType > + struct ThreadingSingle + { + struct mutex + { + void lock(); + void unlock(); + }; + + struct lock + { + lock(); + lock( mutex &m ); + }; + + typedef T VolatileType; + }; +}; + +#include "ThreadingSingle.inl" + +#endif diff --git a/src/gui/qt/utilspp/ThreadingSingle.inl b/src/gui/qt/utilspp/ThreadingSingle.inl new file mode 100644 index 0000000000..fcb395ba20 --- /dev/null +++ b/src/gui/qt/utilspp/ThreadingSingle.inl @@ -0,0 +1,50 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SINGLE_THREADED_INL +#define SINGLE_THREADED_INL + +template< typename T > +inline +utilspp::ThreadingSingle< T >::lock::lock() +{}; + +template< typename T > +inline +utilspp::ThreadingSingle< T >::lock::lock( + utilspp::ThreadingSingle< T >::mutex & ) +{} + +template< typename T > +inline +void +utilspp::ThreadingSingle< T >::mutex::lock() +{}; + +template< typename T > +inline +void +utilspp::ThreadingSingle< T >::mutex::unlock() +{}; + +#endif diff --git a/src/gui/qt/utilspp/TypeList.hpp b/src/gui/qt/utilspp/TypeList.hpp new file mode 100644 index 0000000000..98cdee69f8 --- /dev/null +++ b/src/gui/qt/utilspp/TypeList.hpp @@ -0,0 +1,216 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef TYPE_LIST_HPP +#define TYPE_LIST_HPP + +#include "NullType.hpp" + + + +#define TYPE_LIST_1( T1 ) utilspp::tl::TypeList< T1, utilspp::NullType > +#define TYPE_LIST_2( T1, T2 ) ::utilspp::tl::TypeList< T1, TYPE_LIST_1( T2 ) > +#define TYPE_LIST_3( T1, T2, T3 ) ::utilspp::tl::TypeList< T1, TYPE_LIST_2( T2, T3 ) > +#define TYPE_LIST_4( T1, T2, T3, T4 ) ::utilspp::tl::TypeList< T1, TYPE_LIST_3( T2, T3, T4 ) > +#define TYPE_LIST_5( T1, T2, T3, T4, T5 ) \ + ::utilspp::tl::TypeList< T1, TYPE_LIST_4( T2, T3, T4, T5 ) > +#define TYPE_LIST_6( T1, T2, T3, T4, T5, T6 ) \ + ::utilspp::tl::TypeList< T1, TYPE_LIST_5( T2, T3, T4, T5, T6 ) > +#define TYPE_LIST_7( T1, T2, T3, T4, T5, T6, T7 ) \ + ::utilspp::tl::TypeList< T1, TYPE_LIST_6( T2, T3, T4, T5, T6, T7 ) > +#define TYPE_LIST_8( T1, T2, T3, T4, T5, T6, T7, T8 ) \ + ::utilspp::tl::TypeList< T1, TYPE_LIST_7( T2, T3, T4, T5, T6, T7, T8 ) > +#define TYPE_LIST_9( T1, T2, T3, T4, T5, T6, T7, T8, T9 ) \ + ::utilspp::tl::TypeList< T1, TYPE_LIST_8( T2, T3, T4, T5, T6, T7, T8, T9 ) > +#define TYPE_LIST_10( T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 ) \ + ::utilspp::tl::TypeList< T1, TYPE_LIST_9( T2, T3, T4, T5, T6, T7, T8, T9, T10 ) > +#define TYPE_LIST_11( T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 ) \ + ::utilspp::tl::TypeList< T1, TYPE_LIST_10( T2, T3, T4, T5, T6, T7, T8, T9, T10, T11 ) > +#define TYPE_LIST_12( T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 ) \ + ::utilspp::tl::TypeList< T1, TYPE_LIST_11( T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 ) > +#define TYPE_LIST_13( T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 ) \ + ::utilspp::tl::TypeList< T1, TYPE_LIST_12( T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 ) > +#define TYPE_LIST_14( T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 ) \ + ::utilspp::tl::TypeList< T1, TYPE_LIST_13( T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 ) > +#define TYPE_LIST_15( T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 ) \ + ::utilspp::tl::TypeList< T1, TYPE_LIST_14( T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 ) > + + +namespace utilspp +{ + namespace tl + { + template< class T, class U > + struct TypeList + { + typedef T head; + typedef U tail; + }; + + //Calculating length of TypeLists + template< class TList > + struct length; + + template<> + struct length< NullType > + { + enum { value = 0 }; + }; + + template< class T, class U > + struct length< TypeList< T, U > > + { + enum { value = 1 + length< U >::value }; + }; + + /** + * Returns the type at a given position (zero-based) + * in TList. If the index is greather than or equal to + * the length of TList, a compile-time error occurs. + */ + template< class TList, unsigned int index > + struct TypeAt; + + template< class THead, class TTail > + struct TypeAt< TypeList< THead, TTail >, 0 > + { + typedef THead Result; + }; + + template< class THead, class TTail, unsigned int i > + struct TypeAt< TypeList< THead, TTail >, i > + { + typedef typename TypeAt< TTail, i - 1 >::Result Result; + }; + + /** + * Returns the type at a given position (zero-based) + * in TList. If the index is greather than or equal to + * the length of TList, OutOfBound template class is + * returned. + */ + template< class TList, unsigned int index, class OutOfBound = utilspp::NullType > + struct TypeAtNonStrict; + + template< class THead, class TTail, class OutOfBound > + struct TypeAtNonStrict< TypeList< THead, TTail >, 0, OutOfBound > + { + typedef THead Result; + }; + + template< class THead, class TTail, unsigned int i, class OutOfBound > + struct TypeAtNonStrict< TypeList< THead, TTail >, i, OutOfBound > + { + typedef typename TypeAtNonStrict< TTail, i - 1 >::Result Result; + }; + + template< unsigned int i, class OutOfBound > + struct TypeAtNonStrict< utilspp::NullType, i , OutOfBound> + { + typedef OutOfBound Result; + }; + + + //Searching TypeLists + template< class TList, class T > + struct IndexOf; + + template< class T > + struct IndexOf< NullType, T > + { + enum { value = -1 }; + }; + + template< class TTail, class T > + struct IndexOf< TypeList< T, TTail >, T > + { + enum { value = 0 }; + }; + + template< class THead, class TTail, class T > + struct IndexOf< TypeList< THead, TTail >, T > + { + private: + enum { temp = IndexOf< TTail, T >::value }; + + public: + enum { value = temp == -1 ? -1 : 1 + temp }; + }; + + //Appending to TypeLists + template< class TList, class T > + struct append; + + template <> + struct append< NullType, NullType > + { + typedef NullType Result; + }; + + template< class T > + struct append< NullType, T > + { + typedef TYPE_LIST_1( T ) Result; + }; + + template< class THead, class TTail > + struct append< NullType, TypeList< THead, TTail > > + { + typedef TypeList< THead, TTail > Result; + }; + + template < class THead, class TTail, class T > + struct append< TypeList< THead, TTail >, T > + { + typedef TypeList< THead, typename append< TTail, T >::Result > + Result; + }; + + //Erasing a type from a TypeList + template< class TList, class T > + struct erase; + + template< class T > + struct erase< NullType, T > + { + typedef NullType Result; + }; + + template< class T, class TTail > + struct erase< TypeList< T, TTail >, T > + { + typedef TTail Result; + }; + + template< class THead, class TTail, class T > + struct erase< TypeList< THead, TTail >, T > + { + typedef TypeList< THead, typename erase< TTail, T >::Result > + Result; + }; + }; +}; + + +#endif + diff --git a/src/gui/qt/utilspp/TypeTrait.hpp b/src/gui/qt/utilspp/TypeTrait.hpp new file mode 100644 index 0000000000..7046f6ee01 --- /dev/null +++ b/src/gui/qt/utilspp/TypeTrait.hpp @@ -0,0 +1,916 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef UTILSPP_TYPETRAIT_HPP +#define UTILSPP_TYPETRAIT_HPP + +#include "NullType.hpp" + +namespace utilspp +{ + template< typename T > + class TypeTrait + { + private: + template< typename U > + struct unreference + { + typedef U type; + }; + + template< typename U > + struct unreference< U & > + { + typedef U type; + }; + + template< typename U > + struct unconst + { + typedef U type; + }; + + template< typename U > + struct unconst< const U > + { + typedef U type; + }; + + public: + typedef typename unreference< T >::type NonReference; + typedef typename unconst< T >::type NonConst; + typedef typename unconst< unreference< T >::type >::type NonParam; + }; + + template< class T > + struct PointerOnMemberFunction + { + typedef utilspp::NullType ClassType; + typedef utilspp::NullType ReturnType; + typedef utilspp::NullType Param1Type; + typedef utilspp::NullType Param2Type; + typedef utilspp::NullType Param3Type; + typedef utilspp::NullType Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef utilspp::NullType ParamList; + }; + + template< typename V, typename W > + struct PointerOnMemberFunction< W(V::*)() > + { + typedef V ClassType; + typedef W ReturnType; + + typedef utilspp::NullType Param1Type; + typedef utilspp::NullType Param2Type; + typedef utilspp::NullType Param3Type; + typedef utilspp::NullType Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef utilspp::NullType ParamList; + }; + + template< typename V, typename W, typename X > + struct PointerOnMemberFunction< W(V::*)(X) > + { + typedef V ClassType; + typedef W ReturnType; + typedef X ParamType; + typedef utilspp::NullType Param2Type; + typedef utilspp::NullType Param3Type; + typedef utilspp::NullType Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_1(X) ParamList; + }; + + template< typename V, typename W, typename X, typename Y > + struct PointerOnMemberFunction< W(V::*)(X, Y) > + { + typedef V ClassType; + typedef W ReturnType; + typedef X ParamType; + typedef Y Param2Type; + typedef utilspp::NullType Param3Type; + typedef utilspp::NullType Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_2(X, Y) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z > + struct PointerOnMemberFunction< W(V::*)(X, Y, Z) > + { + typedef V ClassType; + typedef W ReturnType; + typedef X ParamType; + typedef Y Param2Type; + typedef Z Param3Type; + typedef utilspp::NullType Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_3(X, Y, Z) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z > + struct PointerOnMemberFunction< W(V::*)(X, Y, Z) > + { + typedef V ClassType; + typedef W ReturnType; + typedef X ParamType; + typedef Y Param2Type; + typedef Z Param3Type; + typedef utilspp::NullType Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_3(X, Y, Z) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z > + struct PointerOnMemberFunction< W(V::*)(X, Y, Z) > + { + typedef V ClassType; + typedef W ReturnType; + typedef X ParamType; + typedef Y Param2Type; + typedef Z Param3Type; + typedef utilspp::NullType Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_3(X, Y, Z) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A > + struct PointerOnMemberFunction< W(V::*)(X, Y, Z, A) > + { + typedef V ClassType; + typedef W ReturnType; + typedef X ParamType; + typedef Y Param2Type; + typedef Z Param3Type; + typedef A Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_4(X, Y, Z, A) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B > + struct PointerOnMemberFunction< W(V::*)(X, Y, Z, A, B) > + { + typedef V ClassType; + typedef W ReturnType; + typedef X ParamType; + typedef Y Param2Type; + typedef Z Param3Type; + typedef A Param4Type; + typedef B Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_5(X, Y, Z, A, B) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C > + struct PointerOnMemberFunction< W(V::*)(X, Y, Z, A, B, C) > + { + typedef V ClassType; + typedef W ReturnType; + typedef X Param1Type; + typedef Y Param2Type; + typedef Z Param3Type; + typedef A Param4Type; + typedef B Param5Type; + typedef C Param6Type; + typedef utilspp::NullType Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_6(X, Y, Z, A, B, C) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C, typename D > + struct PointerOnMemberFunction< W(V::*)(X, Y, Z, A, B, C, D) > + { + typedef V ClassType; + typedef W ReturnType; + typedef X Param1Type; + typedef Y Param2Type; + typedef Z Param3Type; + typedef A Param4Type; + typedef B Param5Type; + typedef C Param6Type; + typedef D Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_7(X, Y, Z, A, B, C, D) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C, typename D, typename E > + struct PointerOnMemberFunction< W(V::*)(X, Y, Z, A, B, C, D, E) > + { + typedef V ClassType; + typedef W ReturnType; + typedef X Param1Type; + typedef Y Param2Type; + typedef Z Param3Type; + typedef A Param4Type; + typedef B Param5Type; + typedef C Param6Type; + typedef D Param7Type; + typedef E Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_8(X, Y, Z, A, B, C, D, E) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C, typename D, typename E, typename F > + struct PointerOnMemberFunction< W(V::*)(X, Y, Z, A, B, C, D, E, F) > + { + typedef V ClassType; + typedef W ReturnType; + typedef X Param1Type; + typedef Y Param2Type; + typedef Z Param3Type; + typedef A Param4Type; + typedef B Param5Type; + typedef C Param6Type; + typedef D Param7Type; + typedef E Param8Type; + typedef F Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_9(X, Y, Z, A, B, C, D, E, F) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C, typename D, typename E, typename F, typename G > + struct PointerOnMemberFunction< W(V::*)(X, Y, Z, A, B, C, D, E, F, G) > + { + typedef V ClassType; + typedef W ReturnType; + typedef X Param1Type; + typedef Y Param2Type; + typedef Z Param3Type; + typedef A Param4Type; + typedef B Param5Type; + typedef C Param6Type; + typedef D Param7Type; + typedef E Param8Type; + typedef F Param9Type; + typedef G Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_10(X, Y, Z, A, B, C, D, E, F, G) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > + struct PointerOnMemberFunction< W(V::*)(X, Y, Z, A, B, C, D, E, F, G, H) > + { + typedef V ClassType; + typedef W ReturnType; + typedef X Param1Type; + typedef Y Param2Type; + typedef Z Param3Type; + typedef A Param4Type; + typedef B Param5Type; + typedef C Param6Type; + typedef D Param7Type; + typedef E Param8Type; + typedef F Param9Type; + typedef G Param10Type; + typedef H Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_11(X, Y, Z, A, B, C, D, E, F, G, H) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > + struct PointerOnMemberFunction< W(V::*)(X, Y, Z, A, B, C, D, E, F, G, H, I) > + { + typedef V ClassType; + typedef W ReturnType; + typedef X Param1Type; + typedef Y Param2Type; + typedef Z Param3Type; + typedef A Param4Type; + typedef B Param5Type; + typedef C Param6Type; + typedef D Param7Type; + typedef E Param8Type; + typedef F Param9Type; + typedef G Param10Type; + typedef H Param11Type; + typedef I Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_12(X, Y, Z, A, B, C, D, E, F, G, H, I) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > + struct PointerOnMemberFunction< W(V::*)(X, Y, Z, A, B, C, D, E, F, G, H, I, J) > + { + typedef V ClassType; + typedef W ReturnType; + typedef X Param1Type; + typedef Y Param2Type; + typedef Z Param3Type; + typedef A Param4Type; + typedef B Param5Type; + typedef C Param6Type; + typedef D Param7Type; + typedef E Param8Type; + typedef F Param9Type; + typedef G Param10Type; + typedef H Param11Type; + typedef I Param12Type; + typedef J Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_13(X, Y, Z, A, B, C, D, E, F, G, H, I, J) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > + struct PointerOnMemberFunction< W(V::*)(X, Y, Z, A, B, C, D, E, F, G, H, I, J, K) > + { + typedef V ClassType; + typedef W ReturnType; + typedef X Param1Type; + typedef Y Param2Type; + typedef Z Param3Type; + typedef A Param4Type; + typedef B Param5Type; + typedef C Param6Type; + typedef D Param7Type; + typedef E Param8Type; + typedef F Param9Type; + typedef G Param10Type; + typedef H Param11Type; + typedef I Param12Type; + typedef J Param13Type; + typedef K Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_14(X, Y, Z, A, B, C, D, E, F, G, H, I, J, K) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K, typename L > + struct PointerOnMemberFunction< W(V::*)(X, Y, Z, A, B, C, D, E, F, G, H, I, J, K, L) > + { + typedef V ClassType; + typedef W ReturnType; + typedef X Param1Type; + typedef Y Param2Type; + typedef Z Param3Type; + typedef A Param4Type; + typedef B Param5Type; + typedef C Param6Type; + typedef D Param7Type; + typedef E Param8Type; + typedef F Param9Type; + typedef G Param10Type; + typedef H Param11Type; + typedef I Param12Type; + typedef J Param13Type; + typedef K Param14Type; + typedef L Param15Type; + + typedef TYPE_LIST_15(X, Y, Z, A, B, C, D, E, F, G, H, I, J, K, L) ParamList; + }; + + template< typename T > + struct PointerOnFunction + { + typedef utilspp::NullType ReturnType; + + typedef utilspp::NullType Param1Type; + typedef utilspp::NullType Param2Type; + typedef utilspp::NullType Param3Type; + typedef utilspp::NullType Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef utilspp::NullType ParamList; + }; + + template< typename V > + struct PointerOnFunction< V(*)() > + { + typedef V ReturnType; + typedef utilspp::NullType Param1Type; + typedef utilspp::NullType Param2Type; + typedef utilspp::NullType Param3Type; + typedef utilspp::NullType Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef utilspp::NullType ParamList; + }; + + template< typename V, typename W > + struct PointerOnFunction< V(*)(W) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef utilspp::NullType Param2Type; + typedef utilspp::NullType Param3Type; + typedef utilspp::NullType Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_1(W) ParamList; + }; + + template< typename V, typename W, typename X > + struct PointerOnFunction< V(*)(W, X) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef utilspp::NullType Param3Type; + typedef utilspp::NullType Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_2(W, X) ParamList; + }; + + template< typename V, typename W, typename X, typename Y > + struct PointerOnFunction< V(*)(W, X, Y) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef Y Param3Type; + typedef utilspp::NullType Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_3(W, X, Y) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z > + struct PointerOnFunction< V(*)(W, X, Y, Z) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef Y Param3Type; + typedef Z Param4Type; + typedef utilspp::NullType Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_4(W, X, Y, Z) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A > + struct PointerOnFunction< V(*)(W, X, Y, Z, A) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef Y Param3Type; + typedef Z Param4Type; + typedef A Param5Type; + typedef utilspp::NullType Param6Type; + typedef utilspp::NullType Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_5(W, X, Y, Z, A) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B > + struct PointerOnFunction< V(*)(W, X, Y, Z, A, B) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef Y Param3Type; + typedef Z Param4Type; + typedef A Param5Type; + typedef B Param6Type; + typedef utilspp::NullType Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_6(W, X, Y, Z, A, B) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C > + struct PointerOnFunction< V(*)(W, X, Y, Z, A, B, C) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef Y Param3Type; + typedef Z Param4Type; + typedef A Param5Type; + typedef B Param6Type; + typedef C Param7Type; + typedef utilspp::NullType Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_7(W, X, Y, Z, A, B, C) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C, typename D > + struct PointerOnFunction< V(*)(W, X, Y, Z, A, B, C, D) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef Y Param3Type; + typedef Z Param4Type; + typedef A Param5Type; + typedef B Param6Type; + typedef C Param7Type; + typedef D Param8Type; + typedef utilspp::NullType Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_8(W, X, Y, Z, A, B, C, D) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C, typename D, typename E > + struct PointerOnFunction< V(*)(W, X, Y, Z, A, B, C, D, E) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef Y Param3Type; + typedef Z Param4Type; + typedef A Param5Type; + typedef B Param6Type; + typedef C Param7Type; + typedef D Param8Type; + typedef E Param9Type; + typedef utilspp::NullType Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_9(W, X, Y, Z, A, B, C, D, E) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C, typename D, typename E, typename F > + struct PointerOnFunction< V(*)(W, X, Y, Z, A, B, C, D, E, F) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef Y Param3Type; + typedef Z Param4Type; + typedef A Param5Type; + typedef B Param6Type; + typedef C Param7Type; + typedef D Param8Type; + typedef E Param9Type; + typedef F Param10Type; + typedef utilspp::NullType Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_10(W, X, Y, Z, A, B, C, D, E, F) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C, typename D, typename E, typename F, typename G > + struct PointerOnFunction< V(*)(W, X, Y, Z, A, B, C, D, E, F, G) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef Y Param3Type; + typedef Z Param4Type; + typedef A Param5Type; + typedef B Param6Type; + typedef C Param7Type; + typedef D Param8Type; + typedef E Param9Type; + typedef F Param10Type; + typedef G Param11Type; + typedef utilspp::NullType Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_11(W, X, Y, Z, A, B, C, D, E, F, G) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H > + struct PointerOnFunction< V(*)(W, X, Y, Z, A, B, C, D, E, F, G, H) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef Y Param3Type; + typedef Z Param4Type; + typedef A Param5Type; + typedef B Param6Type; + typedef C Param7Type; + typedef D Param8Type; + typedef E Param9Type; + typedef F Param10Type; + typedef G Param11Type; + typedef H Param12Type; + typedef utilspp::NullType Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_12(W, X, Y, Z, A, B, C, D, E, F, G, H) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I > + struct PointerOnFunction< V(*)(W, X, Y, Z, A, B, C, D, E, F, G, H, I) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef Y Param3Type; + typedef Z Param4Type; + typedef A Param5Type; + typedef B Param6Type; + typedef C Param7Type; + typedef D Param8Type; + typedef E Param9Type; + typedef F Param10Type; + typedef G Param11Type; + typedef H Param12Type; + typedef I Param13Type; + typedef utilspp::NullType Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_13(W, X, Y, Z, A, B, C, D, E, F, G, H, I ) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J > + struct PointerOnFunction< V(*)(W, X, Y, Z, A, B, C, D, E, F, G, H, I, J) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef Y Param3Type; + typedef Z Param4Type; + typedef A Param5Type; + typedef B Param6Type; + typedef C Param7Type; + typedef D Param8Type; + typedef E Param9Type; + typedef F Param10Type; + typedef G Param11Type; + typedef H Param12Type; + typedef I Param13Type; + typedef J Param14Type; + typedef utilspp::NullType Param15Type; + + typedef TYPE_LIST_14(W, X, Y, Z, A, B, C, D, E, F, G, H, I, J ) ParamList; + }; + + template< typename V, typename W, typename X, typename Y, typename Z, typename A, typename B, typename C, typename D, typename E, typename F, typename G, typename H, typename I, typename J, typename K > + struct PointerOnFunction< V(*)(W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K) > + { + typedef V ReturnType; + typedef W Param1Type; + typedef X Param2Type; + typedef Y Param3Type; + typedef Z Param4Type; + typedef A Param5Type; + typedef B Param6Type; + typedef C Param7Type; + typedef D Param8Type; + typedef E Param9Type; + typedef F Param10Type; + typedef G Param11Type; + typedef H Param12Type; + typedef I Param13Type; + typedef J Param14Type; + typedef K Param15Type; + + typedef TYPE_LIST_15(W, X, Y, Z, A, B, C, D, E, F, G, H, I, J, K) ParamList; + }; + +}; + +#endif diff --git a/src/gui/qt/utilspp/singleton/CreationStatic.hpp b/src/gui/qt/utilspp/singleton/CreationStatic.hpp new file mode 100644 index 0000000000..27570f5308 --- /dev/null +++ b/src/gui/qt/utilspp/singleton/CreationStatic.hpp @@ -0,0 +1,49 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef CREATION_STATIC_HPP +#define CREATION_STATIC_HPP + +/** + * This class is a creation policy for the utilspp::singleton_holder. The + * policy is creating the singleton by a static memory. The constructor is + * called the first time we call the utilspp::creation_static::create() + * function. + * + * Note don't use this class because it's not complete, and at this time it's + * not REALY complyant with the lifetime policy. + */ +namespace utilspp +{ + template< typename T > + class CreationStatic + { + public: + static T* create(); + static void destroy( T* obj ); + }; +}; + +#include "CreationStatic.inl" + +#endif diff --git a/src/gui/qt/utilspp/singleton/CreationStatic.inl b/src/gui/qt/utilspp/singleton/CreationStatic.inl new file mode 100644 index 0000000000..9572e5eca7 --- /dev/null +++ b/src/gui/qt/utilspp/singleton/CreationStatic.inl @@ -0,0 +1,43 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef CREATION_STATIC_INL +#define CREATION_STATIC_INL + +template< typename T > +T* +utilspp::CreationStatic::create() +{ + static T mObj; + return new(&mObj) T; +}; + +template< typename T > +void +utilspp::CreationStatic::destroy( T* obj ) +{ + obj->~T(); +} + + +#endif \ No newline at end of file diff --git a/src/gui/qt/utilspp/singleton/CreationUsingNew.hpp b/src/gui/qt/utilspp/singleton/CreationUsingNew.hpp new file mode 100644 index 0000000000..5055db5b8f --- /dev/null +++ b/src/gui/qt/utilspp/singleton/CreationUsingNew.hpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef CREATION_USING_NEW_HPP +#define CREATION_USING_NEW_HPP + +/** + * This class is a creation policy for the utilspp::singleton_holder. The + * policy is creating the singleton by a "new" call. + */ +namespace utilspp +{ + template< typename T > + struct CreationUsingNew + { + static T *create(); + static void destroy( T *obj ); + }; +}; + +#include "CreationUsingNew.inl" + +#endif diff --git a/src/gui/qt/utilspp/singleton/CreationUsingNew.inl b/src/gui/qt/utilspp/singleton/CreationUsingNew.inl new file mode 100644 index 0000000000..adb66ede9e --- /dev/null +++ b/src/gui/qt/utilspp/singleton/CreationUsingNew.inl @@ -0,0 +1,42 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef CREATION_USING_NEW_INL +#define CREATION_USING_NEW_INL + +template< typename T > +T * +utilspp::CreationUsingNew< T >::create() +{ + return new T; +} + +template< typename T > +void +utilspp::CreationUsingNew< T >::destroy( T *obj ) +{ + delete obj; +} + + +#endif diff --git a/src/gui/qt/utilspp/singleton/LifetimeDefault.hpp b/src/gui/qt/utilspp/singleton/LifetimeDefault.hpp new file mode 100644 index 0000000000..9c77138109 --- /dev/null +++ b/src/gui/qt/utilspp/singleton/LifetimeDefault.hpp @@ -0,0 +1,43 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LIFETIME_DEFAULT_HPP +#define LIFETIME_DEFAULT_HPP + +#include <stdexcept> +#include <cstdlib> + +namespace utilspp +{ + template< typename T > + class LifetimeDefault + { + public: + static void scheduleDestruction( T *obj, void (*func)() ); + static void onDeadReference(); + }; +}; + +#include "LifetimeDefault.inl" + +#endif diff --git a/src/gui/qt/utilspp/singleton/LifetimeDefault.inl b/src/gui/qt/utilspp/singleton/LifetimeDefault.inl new file mode 100644 index 0000000000..1397d7b420 --- /dev/null +++ b/src/gui/qt/utilspp/singleton/LifetimeDefault.inl @@ -0,0 +1,42 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LIFETIME_DEFAULT_INL +#define LIFETIME_DEFAULT_INL + +template< typename T > +void +utilspp::LifetimeDefault< T >::scheduleDestruction( T *, void (*func)() ) +{ + std::atexit(func); +} + +template< typename T > +void +utilspp::LifetimeDefault< T >::onDeadReference() +{ + throw std::logic_error( "utilspp::LifetimeDefault: Dead reference detected" ); +} + + +#endif diff --git a/src/gui/qt/utilspp/singleton/LifetimeLibrary.hpp b/src/gui/qt/utilspp/singleton/LifetimeLibrary.hpp new file mode 100644 index 0000000000..80fba716ab --- /dev/null +++ b/src/gui/qt/utilspp/singleton/LifetimeLibrary.hpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LIFETIME_LIBRARY_HPP +#define LIFETIME_LIBRARY_HPP + +#include <cassert> + +#include "PrivateMembers.hpp" +#include "CreationUsingNew.hpp" + +namespace utilspp +{ + + template< typename T > + unsigned int getLongevity( T *p ); + + /** + * Assigns an object a longevity. Ensures ordered destructions of objects + * registered thusly during the exit sequence of the application. + */ + template< typename T, typename TDestroyer > + void setLibraryLongevity( + T *obj, + unsigned int longevity, + TDestroyer d = utilspp::PrivateMembers::Deleter< T >::deleteObject + ); + + /** + * This class is a lifetime policy for the singleton. This + * class allow you to terminate the singleton explicitly. + * You can terminate by calling: + * + * LifetimeLibrarySingleton::instance().terminate() + * + * This singleton use the utilspp::LifetimeWithLongevity policy. + */ + template< typename T > + struct LifetimeLibrary + { + static void scheduleDestruction( T *obj, void (*func)() ); + static void onDeadReference(); + }; + + class LifetimeLibraryImpl + { + public: + LifetimeLibraryImpl(); + ~LifetimeLibraryImpl(); + + void add( utilspp::PrivateMembers::LifetimeTracker *tracker ); + void terminate(); + + private: + utilspp::PrivateMembers::TrackerArray mTrackerArray; + int mNbElements; + }; + + unsigned int getLongevity( utilspp::LifetimeLibraryImpl *p ); + + typedef utilspp::SingletonHolder< + utilspp::LifetimeLibraryImpl, + utilspp::CreationUsingNew, + utilspp::LifetimeWithLongevity + > LifetimeLibrarySingleton; + + /** + * This class will ensure that + * + * LifetimeLibraryImpl::terminate() + * + * is called. + */ + template< typename T = utilspp::LifetimeLibrarySingleton > + class LifetimeLibraryGuard + { + public: + ~LifetimeLibraryGuard(); + }; +}; + +#include "LifetimeLibrary.inl" + +#endif diff --git a/src/gui/qt/utilspp/singleton/LifetimeLibrary.inl b/src/gui/qt/utilspp/singleton/LifetimeLibrary.inl new file mode 100644 index 0000000000..b7ab8e6d66 --- /dev/null +++ b/src/gui/qt/utilspp/singleton/LifetimeLibrary.inl @@ -0,0 +1,33 @@ +template< typename T, typename TDestroyer > +void +utilspp::setLibraryLongevity( T *obj, unsigned int longevity, TDestroyer d ) +{ + using namespace utilspp::PrivateMembers; + + LifetimeTracker *p = new ConcreteLifetimeTracker< T, TDestroyer >( + obj, longevity, d); + + utilspp::LifetimeLibrarySingleton::instance().add( p ); +}; + +template< typename T > +void +utilspp::LifetimeLibrary< T >::scheduleDestruction( T *obj, void (*func)() ) +{ + utilspp::PrivateMembers::adapter<T> adapter = { func }; + utilspp::setLibraryLongevity( obj, getLongevity( obj ), adapter ); +} + +template< typename T > +void +utilspp::LifetimeLibrary< T >::onDeadReference() +{ + throw std::logic_error("Dead reference detected"); +} + +template< typename T > +utilspp::LifetimeLibraryGuard< T >::~LifetimeLibraryGuard() +{ + T::instance().terminate(); +} + diff --git a/src/gui/qt/utilspp/singleton/LifetimeWithLongevity.hpp b/src/gui/qt/utilspp/singleton/LifetimeWithLongevity.hpp new file mode 100644 index 0000000000..8884751264 --- /dev/null +++ b/src/gui/qt/utilspp/singleton/LifetimeWithLongevity.hpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LIFETIME_WITH_LONGEVITY_HPP +#define LIFETIME_WITH_LONGEVITY_HPP + +#include <cassert> + +#include "PrivateMembers.hpp" + +namespace utilspp +{ + + template< typename T > + unsigned int getLongevity( T *p ); + + /** + * Assigns an object a longevity. Ensures ordered destructions of objects + * registered thusly during the exit sequence of the application. + */ + template< typename T, typename TDestroyer > + void setLongevity(T *obj, + unsigned int longevity, + TDestroyer d = utilspp::PrivateMembers::Deleter< T >::deleteObject); + + template< typename T > + struct LifetimeWithLongevity + { + static void scheduleDestruction( T *obj, void (*func)() ); + static void onDeadReference(); + }; +}; + +#include "LifetimeWithLongevity.inl" + +#endif diff --git a/src/gui/qt/utilspp/singleton/LifetimeWithLongevity.inl b/src/gui/qt/utilspp/singleton/LifetimeWithLongevity.inl new file mode 100644 index 0000000000..aaaf0ebfb5 --- /dev/null +++ b/src/gui/qt/utilspp/singleton/LifetimeWithLongevity.inl @@ -0,0 +1,56 @@ +template< typename T, typename TDestroyer > +void +utilspp::setLongevity( T *obj, unsigned int longevity, TDestroyer d ) +{ + using namespace utilspp::PrivateMembers; + + TrackerArray newArray = static_cast< TrackerArray >( + std::realloc(mTrackerArray, mNbElements + 1)); + if( newArray == NULL ) + { + throw std::bad_alloc(); + } + + LifetimeTracker *p = + new ConcreteLifetimeTracker< T, TDestroyer >(obj, longevity, d); + + mTrackerArray = newArray; + + TrackerArray pos = std::upper_bound( + mTrackerArray, + mTrackerArray + mNbElements, + p, + &LifetimeTracker::compare); + std::copy_backward( + pos, + mTrackerArray + mNbElements, + mTrackerArray + mNbElements + 1); + + *pos = p; + mNbElements++; + std::atexit( &atExitFunc ); +}; + +template< typename T > +void +utilspp::LifetimeWithLongevity< T >::scheduleDestruction( T *obj, void (*func)() ) +{ + utilspp::PrivateMembers::adapter<T> adapter = { func }; + utilspp::setLongevity( obj, getLongevity( obj ), adapter ); +} + +template< typename T > +void +utilspp::LifetimeWithLongevity< T >::onDeadReference() +{ + throw std::logic_error("Dead reference detected"); +} + +template< typename T > +unsigned int +utilspp::getLongevity( T * ) +{ + return 1000; +} + + diff --git a/src/gui/qt/utilspp/singleton/PrivateMembers.hpp b/src/gui/qt/utilspp/singleton/PrivateMembers.hpp new file mode 100644 index 0000000000..b1fb8cd22e --- /dev/null +++ b/src/gui/qt/utilspp/singleton/PrivateMembers.hpp @@ -0,0 +1,93 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef PRIVATE_MEMBERS_HPP +#define PRIVATE_MEMBERS_HPP + +#include <cassert> + +namespace utilspp +{ + namespace PrivateMembers + { + /** + * Helper class for utils::setLongevity + */ + class LifetimeTracker + { + public: + LifetimeTracker( unsigned int longevity ); + virtual ~LifetimeTracker(); + static bool compare( + const LifetimeTracker *l, + const LifetimeTracker *r + ); + + private: + unsigned int mLongevity; + }; + + typedef LifetimeTracker** TrackerArray; + + extern TrackerArray mTrackerArray; + extern int mNbElements; + + /** + * Helper class for Destroyer + */ + template< typename T > + struct Deleter + { + void deleteObject( T *obj ); + }; + + /** + * Concrete lifetime tracker for objects of type T + */ + template< typename T, typename TDestroyer > + class ConcreteLifetimeTracker : public LifetimeTracker + { + public: + ConcreteLifetimeTracker(T *obj, unsigned int longevity, TDestroyer d); + + ~ConcreteLifetimeTracker(); + + private: + T* mTracked; + TDestroyer mDestroyer; + }; + + void atExitFunc(); + + template <class T> + struct adapter + { + void operator()(T*); + void (*mFunc)(); + }; + }; +}; + +#include "PrivateMembers.inl" + +#endif diff --git a/src/gui/qt/utilspp/singleton/PrivateMembers.inl b/src/gui/qt/utilspp/singleton/PrivateMembers.inl new file mode 100644 index 0000000000..8f3609416c --- /dev/null +++ b/src/gui/qt/utilspp/singleton/PrivateMembers.inl @@ -0,0 +1,30 @@ + +template< typename T > +void +utilspp::PrivateMembers::Deleter< T >::deleteObject( T *obj ) +{ + delete obj; +} + +template< typename T, typename TDestroyer > +utilspp::PrivateMembers::ConcreteLifetimeTracker< T, TDestroyer >::ConcreteLifetimeTracker( + T *obj, unsigned int longevity, TDestroyer d) +: LifetimeTracker( longevity ) +, mTracked( obj ) +, mDestroyer( d ) +{} + +template< typename T, typename TDestroyer > +utilspp::PrivateMembers::ConcreteLifetimeTracker< T, TDestroyer >::~ConcreteLifetimeTracker() +{ + mDestroyer( mTracked ); +} + + +template < typename T > +void +utilspp::PrivateMembers::adapter< T >::operator()(T*) +{ + return (*mFunc)(); +} + diff --git a/src/gui/qt/utilspp/singleton/SingletonHolder.hpp b/src/gui/qt/utilspp/singleton/SingletonHolder.hpp new file mode 100644 index 0000000000..8a8590a7b2 --- /dev/null +++ b/src/gui/qt/utilspp/singleton/SingletonHolder.hpp @@ -0,0 +1,66 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SINGLETON_HOLDER_HPP +#define SINGLETON_HOLDER_HPP + +#include <cassert> + +#include "CreationUsingNew.hpp" +#include "LifetimeDefault.hpp" +#include "LifetimeWithLongevity.hpp" +#include "../ThreadingSingle.hpp" + +namespace utilspp +{ + template + < class T, + template < class > class CreationPolicy = utilspp::CreationUsingNew, + template < class > class LifetimePolicy = utilspp::LifetimeDefault, + template < class > class ThreadingModel = utilspp::ThreadingSingle > + class SingletonHolder + { + public: + //the accessor method. + static T& instance(); + static void makeInstance(); + static void terminate(); + + protected: + //protected to be sure that nobody may create one by himself. + SingletonHolder(); + + private: + static void destroySingleton(); + + private: + typedef typename ThreadingModel< T * >::VolatileType InstanceType; + static InstanceType mInstance; + static bool mDestroyed; + }; + +}; + +#include "SingletonHolder.inl" + +#endif diff --git a/src/gui/qt/utilspp/singleton/SingletonHolder.inl b/src/gui/qt/utilspp/singleton/SingletonHolder.inl new file mode 100644 index 0000000000..84f27bea9f --- /dev/null +++ b/src/gui/qt/utilspp/singleton/SingletonHolder.inl @@ -0,0 +1,126 @@ +/* + * Copyright (c) <2002-2004> <Jean-Philippe Barrette-LaPierre> + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files + * (cURLpp), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef SINGLETON_HOLDER_INL +#define SINGLETON_HOLDER_INL + +template +< +class T, +template < class > class CreationPolicy, +template < class > class LifetimePolicy, +template < class > class ThreadingModel +> +T& +utilspp::SingletonHolder +< +T, +CreationPolicy, +LifetimePolicy, +ThreadingModel +> +::instance() +{ + if ( mInstance == NULL ) + { + makeInstance(); + } + + return ( *mInstance ); +}; + +template +< +class T, +template < class > class CreationPolicy, +template < class > class LifetimePolicy, +template < class > class ThreadingModel +> +void +utilspp::SingletonHolder +< +T, +CreationPolicy, +LifetimePolicy, +ThreadingModel +>::makeInstance() +{ + if ( mInstance == NULL ) + { + typename ThreadingModel< T >::lock guard; + (void)guard; + + if ( mInstance == NULL ) { + if ( mDestroyed ) + { + LifetimePolicy< T >::onDeadReference(); + mDestroyed = false; + } + + mInstance = CreationPolicy< T >::create(); + LifetimePolicy< T >::scheduleDestruction( mInstance, &destroySingleton ); + } + } +} + +template +< +class T, +template < class > class CreationPolicy, +template < class > class LifetimePolicy, +template < class > class ThreadingModel +> +void +utilspp::SingletonHolder +< +T, +CreationPolicy, +LifetimePolicy, +ThreadingModel +> +::destroySingleton() +{ + assert( !mDestroyed ); + CreationPolicy< T >::destroy( mInstance ); + mInstance = NULL; + mDestroyed = true; +} + +template < class T, +template < class > class C, +template < class > class L, +template < class > class M +> +typename utilspp::SingletonHolder< T, C, L, M>::InstanceType +utilspp::SingletonHolder< T, C, L, M >::mInstance; + +template +< +class T, +template < class > class C, +template < class > class L, +template < class > class M +> +bool utilspp::SingletonHolder< T, C, L, M >::mDestroyed; + +#endif -- GitLab