summaryrefslogtreecommitdiffstats
path: root/Swift
diff options
context:
space:
mode:
Diffstat (limited to 'Swift')
-rw-r--r--Swift/ChangeLog.md65
-rw-r--r--Swift/Controllers/AdHocController.cpp20
-rw-r--r--Swift/Controllers/AdHocController.h17
-rw-r--r--Swift/Controllers/AdHocManager.cpp120
-rw-r--r--Swift/Controllers/AdHocManager.h49
-rw-r--r--Swift/Controllers/BlockListController.cpp273
-rw-r--r--Swift/Controllers/BlockListController.h39
-rw-r--r--Swift/Controllers/CertificateMemoryStorageFactory.h28
-rw-r--r--Swift/Controllers/Chat/AutoAcceptMUCInviteDecider.h71
-rw-r--r--Swift/Controllers/Chat/ChatController.cpp782
-rw-r--r--Swift/Controllers/Chat/ChatController.h194
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.cpp577
-rw-r--r--Swift/Controllers/Chat/ChatControllerBase.h202
-rw-r--r--Swift/Controllers/Chat/ChatMessageParser.cpp358
-rw-r--r--Swift/Controllers/Chat/ChatMessageParser.h22
-rw-r--r--Swift/Controllers/Chat/ChatsManager.cpp1672
-rw-r--r--Swift/Controllers/Chat/ChatsManager.h316
-rw-r--r--Swift/Controllers/Chat/MUCController.cpp1824
-rw-r--r--Swift/Controllers/Chat/MUCController.h315
-rw-r--r--Swift/Controllers/Chat/MUCSearchController.cpp248
-rw-r--r--Swift/Controllers/Chat/MUCSearchController.h220
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp519
-rw-r--r--Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp1831
-rw-r--r--Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp998
-rw-r--r--Swift/Controllers/Chat/UnitTest/MockChatListWindow.h32
-rw-r--r--Swift/Controllers/Chat/UserSearchController.cpp583
-rw-r--r--Swift/Controllers/Chat/UserSearchController.h138
-rw-r--r--Swift/Controllers/ChatMessageSummarizer.cpp56
-rw-r--r--Swift/Controllers/ChatMessageSummarizer.h14
-rw-r--r--Swift/Controllers/ConnectionSettings.h54
-rw-r--r--Swift/Controllers/Contact.cpp83
-rw-r--r--Swift/Controllers/Contact.h31
-rw-r--r--Swift/Controllers/ContactEditController.cpp139
-rw-r--r--Swift/Controllers/ContactEditController.h78
-rw-r--r--Swift/Controllers/ContactProvider.h6
-rw-r--r--Swift/Controllers/ContactSuggester.cpp75
-rw-r--r--Swift/Controllers/ContactSuggester.h40
-rw-r--r--Swift/Controllers/ContactsFromXMPPRoster.cpp21
-rw-r--r--Swift/Controllers/ContactsFromXMPPRoster.h18
-rw-r--r--Swift/Controllers/DummySoundPlayer.h8
-rw-r--r--Swift/Controllers/DummySystemTray.h16
-rw-r--r--Swift/Controllers/EventNotifier.cpp82
-rw-r--r--Swift/Controllers/EventNotifier.h65
-rw-r--r--Swift/Controllers/EventWindowController.cpp61
-rw-r--r--Swift/Controllers/EventWindowController.h33
-rw-r--r--Swift/Controllers/FileTransfer/FileTransferController.cpp179
-rw-r--r--Swift/Controllers/FileTransfer/FileTransferController.h72
-rw-r--r--Swift/Controllers/FileTransfer/FileTransferOverview.cpp89
-rw-r--r--Swift/Controllers/FileTransfer/FileTransferOverview.h32
-rw-r--r--Swift/Controllers/FileTransfer/FileTransferProgressInfo.cpp26
-rw-r--r--Swift/Controllers/FileTransfer/FileTransferProgressInfo.h22
-rw-r--r--Swift/Controllers/FileTransferListController.cpp50
-rw-r--r--Swift/Controllers/FileTransferListController.h24
-rw-r--r--Swift/Controllers/HighlightAction.cpp52
-rw-r--r--Swift/Controllers/HighlightAction.h118
-rw-r--r--Swift/Controllers/HighlightEditorController.cpp43
-rw-r--r--Swift/Controllers/HighlightEditorController.h45
-rw-r--r--Swift/Controllers/HighlightManager.cpp150
-rw-r--r--Swift/Controllers/HighlightManager.h93
-rw-r--r--Swift/Controllers/HighlightRule.cpp215
-rw-r--r--Swift/Controllers/HighlightRule.h120
-rw-r--r--Swift/Controllers/Highlighter.cpp36
-rw-r--r--Swift/Controllers/Highlighter.h39
-rw-r--r--Swift/Controllers/HistoryController.cpp26
-rw-r--r--Swift/Controllers/HistoryController.h36
-rw-r--r--Swift/Controllers/HistoryViewController.cpp537
-rw-r--r--Swift/Controllers/HistoryViewController.h102
-rw-r--r--Swift/Controllers/Intl.h5
-rw-r--r--Swift/Controllers/MainController.cpp1431
-rw-r--r--Swift/Controllers/MainController.h351
-rw-r--r--Swift/Controllers/PresenceNotifier.cpp189
-rw-r--r--Swift/Controllers/PresenceNotifier.h96
-rw-r--r--Swift/Controllers/PreviousStatusStore.cpp52
-rw-r--r--Swift/Controllers/PreviousStatusStore.h29
-rw-r--r--Swift/Controllers/ProfileController.cpp125
-rw-r--r--Swift/Controllers/ProfileController.h63
-rw-r--r--Swift/Controllers/ProfileSettingsProvider.cpp68
-rw-r--r--Swift/Controllers/ProfileSettingsProvider.h38
-rw-r--r--Swift/Controllers/Roster/ContactRosterItem.cpp147
-rw-r--r--Swift/Controllers/Roster/ContactRosterItem.h136
-rw-r--r--Swift/Controllers/Roster/FuzzyRosterFilter.h38
-rw-r--r--Swift/Controllers/Roster/GroupRosterItem.cpp309
-rw-r--r--Swift/Controllers/Roster/GroupRosterItem.h66
-rw-r--r--Swift/Controllers/Roster/ItemOperations/AppearOffline.h24
-rw-r--r--Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h34
-rw-r--r--Swift/Controllers/Roster/ItemOperations/SetAvailableFeatures.h38
-rw-r--r--Swift/Controllers/Roster/ItemOperations/SetAvatar.h34
-rw-r--r--Swift/Controllers/Roster/ItemOperations/SetBlockingState.h56
-rw-r--r--Swift/Controllers/Roster/ItemOperations/SetMUC.h38
-rw-r--r--Swift/Controllers/Roster/ItemOperations/SetName.h34
-rw-r--r--Swift/Controllers/Roster/ItemOperations/SetPresence.h28
-rw-r--r--Swift/Controllers/Roster/ItemOperations/SetVCard.h38
-rw-r--r--Swift/Controllers/Roster/LeastCommonSubsequence.h173
-rw-r--r--Swift/Controllers/Roster/OfflineRosterFilter.h23
-rw-r--r--Swift/Controllers/Roster/Roster.cpp367
-rw-r--r--Swift/Controllers/Roster/Roster.h82
-rw-r--r--Swift/Controllers/Roster/RosterController.cpp525
-rw-r--r--Swift/Controllers/Roster/RosterController.h192
-rw-r--r--Swift/Controllers/Roster/RosterFilter.h10
-rw-r--r--Swift/Controllers/Roster/RosterGroupExpandinessPersister.cpp61
-rw-r--r--Swift/Controllers/Roster/RosterGroupExpandinessPersister.h31
-rw-r--r--Swift/Controllers/Roster/RosterItem.cpp26
-rw-r--r--Swift/Controllers/Roster/RosterItem.h32
-rw-r--r--Swift/Controllers/Roster/RosterVCardProvider.cpp22
-rw-r--r--Swift/Controllers/Roster/RosterVCardProvider.h38
-rw-r--r--Swift/Controllers/Roster/TableRoster.cpp291
-rw-r--r--Swift/Controllers/Roster/TableRoster.h141
-rw-r--r--Swift/Controllers/Roster/UnitTest/LeastCommonSubsequenceTest.cpp565
-rw-r--r--Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp781
-rw-r--r--Swift/Controllers/Roster/UnitTest/RosterTest.cpp252
-rw-r--r--Swift/Controllers/Roster/UnitTest/TableRosterTest.cpp126
-rw-r--r--Swift/Controllers/SConscript190
-rw-r--r--Swift/Controllers/SettingConstants.cpp9
-rw-r--r--Swift/Controllers/SettingConstants.h176
-rw-r--r--Swift/Controllers/Settings/DummySettingsProvider.h84
-rw-r--r--Swift/Controllers/Settings/SettingsProvider.h108
-rw-r--r--Swift/Controllers/Settings/SettingsProviderHierachy.cpp124
-rw-r--r--Swift/Controllers/Settings/SettingsProviderHierachy.h56
-rw-r--r--Swift/Controllers/Settings/UnitTest/SettingsProviderHierachyTest.cpp120
-rw-r--r--Swift/Controllers/Settings/XMLSettingsProvider.cpp120
-rw-r--r--Swift/Controllers/Settings/XMLSettingsProvider.h77
-rw-r--r--Swift/Controllers/ShowProfileController.cpp76
-rw-r--r--Swift/Controllers/ShowProfileController.h50
-rw-r--r--Swift/Controllers/SoundEventController.cpp42
-rw-r--r--Swift/Controllers/SoundEventController.h44
-rw-r--r--Swift/Controllers/SoundPlayer.h12
-rw-r--r--Swift/Controllers/StatusCache.cpp136
-rw-r--r--Swift/Controllers/StatusCache.h45
-rw-r--r--Swift/Controllers/StatusTracker.cpp66
-rw-r--r--Swift/Controllers/StatusTracker.h32
-rw-r--r--Swift/Controllers/StatusUtil.cpp23
-rw-r--r--Swift/Controllers/StatusUtil.h2
-rw-r--r--Swift/Controllers/Storages/AvatarFileStorage.cpp130
-rw-r--r--Swift/Controllers/Storages/AvatarFileStorage.h45
-rw-r--r--Swift/Controllers/Storages/CapsFileStorage.cpp22
-rw-r--r--Swift/Controllers/Storages/CapsFileStorage.h27
-rw-r--r--Swift/Controllers/Storages/CertificateFileStorage.cpp67
-rw-r--r--Swift/Controllers/Storages/CertificateFileStorage.h32
-rw-r--r--Swift/Controllers/Storages/CertificateFileStorageFactory.h34
-rw-r--r--Swift/Controllers/Storages/CertificateMemoryStorage.cpp18
-rw-r--r--Swift/Controllers/Storages/CertificateMemoryStorage.h16
-rw-r--r--Swift/Controllers/Storages/CertificateStorage.cpp4
-rw-r--r--Swift/Controllers/Storages/CertificateStorage.h12
-rw-r--r--Swift/Controllers/Storages/CertificateStorageFactory.h14
-rw-r--r--Swift/Controllers/Storages/CertificateStorageTrustChecker.h39
-rw-r--r--Swift/Controllers/Storages/FileStorages.cpp52
-rw-r--r--Swift/Controllers/Storages/FileStorages.h80
-rw-r--r--Swift/Controllers/Storages/FileStoragesFactory.h28
-rw-r--r--Swift/Controllers/Storages/MemoryStoragesFactory.h29
-rw-r--r--Swift/Controllers/Storages/RosterFileStorage.cpp12
-rw-r--r--Swift/Controllers/Storages/RosterFileStorage.h18
-rw-r--r--Swift/Controllers/Storages/StoragesFactory.h14
-rw-r--r--Swift/Controllers/Storages/VCardFileStorage.cpp178
-rw-r--r--Swift/Controllers/Storages/VCardFileStorage.h51
-rw-r--r--Swift/Controllers/SystemTray.h18
-rw-r--r--Swift/Controllers/SystemTrayController.cpp36
-rw-r--r--Swift/Controllers/SystemTrayController.h30
-rw-r--r--Swift/Controllers/Translator.cpp16
-rw-r--r--Swift/Controllers/Translator.h28
-rw-r--r--Swift/Controllers/UIEvents/AcceptWhiteboardSessionUIEvent.h24
-rw-r--r--Swift/Controllers/UIEvents/AddContactUIEvent.h50
-rw-r--r--Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h23
-rw-r--r--Swift/Controllers/UIEvents/CancelWhiteboardSessionUIEvent.h24
-rw-r--r--Swift/Controllers/UIEvents/CreateImpromptuMUCUIEvent.h41
-rw-r--r--Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h27
-rw-r--r--Swift/Controllers/UIEvents/InviteToMUCUIEvent.h59
-rw-r--r--Swift/Controllers/UIEvents/JoinMUCUIEvent.h47
-rw-r--r--Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h23
-rw-r--r--Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h19
-rw-r--r--Swift/Controllers/UIEvents/RenameGroupUIEvent.h33
-rw-r--r--Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h27
-rw-r--r--Swift/Controllers/UIEvents/RequestAdHocUIEvent.h19
-rw-r--r--Swift/Controllers/UIEvents/RequestAdHocWithJIDUIEvent.h26
-rw-r--r--Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h25
-rw-r--r--Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h48
-rw-r--r--Swift/Controllers/UIEvents/RequestChatUIEvent.h20
-rw-r--r--Swift/Controllers/UIEvents/RequestChatWithUserDialogUIEvent.h8
-rw-r--r--Swift/Controllers/UIEvents/RequestContactEditorUIEvent.h25
-rw-r--r--Swift/Controllers/UIEvents/RequestHighlightEditorUIEvent.h4
-rw-r--r--Swift/Controllers/UIEvents/RequestHistoryUIEvent.h4
-rw-r--r--Swift/Controllers/UIEvents/RequestInviteToMUCUIEvent.h77
-rw-r--r--Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h29
-rw-r--r--Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h12
-rw-r--r--Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h24
-rw-r--r--Swift/Controllers/UIEvents/RequestXMLConsoleUIEvent.h8
-rw-r--r--Swift/Controllers/UIEvents/SendFileUIEvent.h45
-rw-r--r--Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h23
-rw-r--r--Swift/Controllers/UIEvents/ShowWhiteboardUIEvent.h24
-rw-r--r--Swift/Controllers/UIEvents/UIEvent.cpp4
-rw-r--r--Swift/Controllers/UIEvents/UIEvent.h14
-rw-r--r--Swift/Controllers/UIEvents/UIEventStream.h23
-rw-r--r--Swift/Controllers/UIInterfaces/AdHocCommandWindow.h16
-rw-r--r--Swift/Controllers/UIInterfaces/AdHocCommandWindowFactory.h15
-rw-r--r--Swift/Controllers/UIInterfaces/BlockListEditorWidget.h29
-rw-r--r--Swift/Controllers/UIInterfaces/BlockListEditorWidgetFactory.h12
-rw-r--r--Swift/Controllers/UIInterfaces/ChatListWindow.cpp4
-rw-r--r--Swift/Controllers/UIInterfaces/ChatListWindow.h168
-rw-r--r--Swift/Controllers/UIInterfaces/ChatListWindowFactory.h16
-rw-r--r--Swift/Controllers/UIInterfaces/ChatWindow.h443
-rw-r--r--Swift/Controllers/UIInterfaces/ChatWindowFactory.h20
-rw-r--r--Swift/Controllers/UIInterfaces/ContactEditWindow.h34
-rw-r--r--Swift/Controllers/UIInterfaces/ContactEditWindowFactory.h10
-rw-r--r--Swift/Controllers/UIInterfaces/EventWindow.h30
-rw-r--r--Swift/Controllers/UIInterfaces/EventWindowFactory.h18
-rw-r--r--Swift/Controllers/UIInterfaces/FileTransferListWidget.h8
-rw-r--r--Swift/Controllers/UIInterfaces/FileTransferListWidgetFactory.h12
-rw-r--r--Swift/Controllers/UIInterfaces/HighlightEditorWidget.h14
-rw-r--r--Swift/Controllers/UIInterfaces/HighlightEditorWidgetFactory.h12
-rw-r--r--Swift/Controllers/UIInterfaces/HighlightEditorWindow.h20
-rw-r--r--Swift/Controllers/UIInterfaces/HighlightEditorWindowFactory.h12
-rw-r--r--Swift/Controllers/UIInterfaces/HistoryWindow.h44
-rw-r--r--Swift/Controllers/UIInterfaces/HistoryWindowFactory.h12
-rw-r--r--Swift/Controllers/UIInterfaces/JoinMUCWindow.h23
-rw-r--r--Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h12
-rw-r--r--Swift/Controllers/UIInterfaces/LoginWindow.h55
-rw-r--r--Swift/Controllers/UIInterfaces/LoginWindowFactory.h28
-rw-r--r--Swift/Controllers/UIInterfaces/MUCSearchWindow.h33
-rw-r--r--Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h16
-rw-r--r--Swift/Controllers/UIInterfaces/MainWindow.h75
-rw-r--r--Swift/Controllers/UIInterfaces/MainWindowFactory.h18
-rw-r--r--Swift/Controllers/UIInterfaces/ProfileWindow.h37
-rw-r--r--Swift/Controllers/UIInterfaces/ProfileWindowFactory.h10
-rw-r--r--Swift/Controllers/UIInterfaces/UIFactory.h64
-rw-r--r--Swift/Controllers/UIInterfaces/UserSearchWindow.h82
-rw-r--r--Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h16
-rw-r--r--Swift/Controllers/UIInterfaces/WhiteboardWindow.h30
-rw-r--r--Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h22
-rw-r--r--Swift/Controllers/UIInterfaces/XMLConsoleWidget.cpp4
-rw-r--r--Swift/Controllers/UIInterfaces/XMLConsoleWidget.h16
-rw-r--r--Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h16
-rw-r--r--Swift/Controllers/UnitTest/ChatMessageSummarizerTest.cpp206
-rw-r--r--Swift/Controllers/UnitTest/ContactSuggesterTest.cpp216
-rw-r--r--Swift/Controllers/UnitTest/HighlightRuleTest.cpp488
-rw-r--r--Swift/Controllers/UnitTest/MockChatWindow.cpp4
-rw-r--r--Swift/Controllers/UnitTest/MockChatWindow.h241
-rw-r--r--Swift/Controllers/UnitTest/MockMainWindow.h40
-rw-r--r--Swift/Controllers/UnitTest/MockMainWindowFactory.h26
-rw-r--r--Swift/Controllers/UnitTest/PresenceNotifierTest.cpp522
-rw-r--r--Swift/Controllers/UnitTest/PreviousStatusStoreTest.cpp44
-rw-r--r--Swift/Controllers/WhiteboardManager.cpp240
-rw-r--r--Swift/Controllers/WhiteboardManager.h87
-rw-r--r--Swift/Controllers/XMLConsoleController.cpp44
-rw-r--r--Swift/Controllers/XMLConsoleController.h50
-rw-r--r--Swift/Controllers/XMPPEvents/ErrorEvent.h35
-rw-r--r--Swift/Controllers/XMPPEvents/EventController.cpp80
-rw-r--r--Swift/Controllers/XMPPEvents/EventController.h41
-rw-r--r--Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h24
-rw-r--r--Swift/Controllers/XMPPEvents/MUCInviteEvent.h49
-rw-r--r--Swift/Controllers/XMPPEvents/MessageEvent.h49
-rw-r--r--Swift/Controllers/XMPPEvents/StanzaEvent.h36
-rw-r--r--Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h65
-rw-r--r--Swift/Controllers/XMPPURIController.cpp34
-rw-r--r--Swift/Controllers/XMPPURIController.h35
-rw-r--r--Swift/Packaging/Debian/debian/control.in2
-rwxr-xr-xSwift/Packaging/Debian/package_all_platforms.sh2
-rw-r--r--Swift/Packaging/MacOSX/Swift.dmg.gzbin517911 -> 539857 bytes
-rwxr-xr-xSwift/Packaging/MacOSX/package.sh6
-rwxr-xr-xSwift/Packaging/Source/package.sh21
-rw-r--r--Swift/QtUI/ApplicationTest/main.cpp59
-rw-r--r--Swift/QtUI/CAPICertificateSelector.cpp114
-rw-r--r--Swift/QtUI/CAPICertificateSelector.h4
-rw-r--r--Swift/QtUI/ChatList/ChatListDelegate.cpp191
-rw-r--r--Swift/QtUI/ChatList/ChatListDelegate.h46
-rw-r--r--Swift/QtUI/ChatList/ChatListGroupItem.h63
-rw-r--r--Swift/QtUI/ChatList/ChatListItem.h23
-rw-r--r--Swift/QtUI/ChatList/ChatListMUCItem.cpp32
-rw-r--r--Swift/QtUI/ChatList/ChatListMUCItem.h40
-rw-r--r--Swift/QtUI/ChatList/ChatListModel.cpp231
-rw-r--r--Swift/QtUI/ChatList/ChatListModel.h66
-rw-r--r--Swift/QtUI/ChatList/ChatListRecentItem.cpp31
-rw-r--r--Swift/QtUI/ChatList/ChatListRecentItem.h41
-rw-r--r--Swift/QtUI/ChatList/ChatListWhiteboardItem.cpp60
-rw-r--r--Swift/QtUI/ChatList/ChatListWhiteboardItem.h39
-rw-r--r--Swift/QtUI/ChatList/QtChatListWindow.cpp250
-rw-r--r--Swift/QtUI/ChatList/QtChatListWindow.h86
-rw-r--r--Swift/QtUI/ChatSnippet.cpp118
-rw-r--r--Swift/QtUI/ChatSnippet.h108
-rw-r--r--Swift/QtUI/ChatView/main.cpp286
-rw-r--r--Swift/QtUI/CocoaApplicationActivateHelper.h32
-rw-r--r--Swift/QtUI/CocoaApplicationActivateHelper.mm42
-rw-r--r--Swift/QtUI/CocoaUIHelpers.h12
-rw-r--r--Swift/QtUI/CocoaUIHelpers.mm48
-rw-r--r--Swift/QtUI/EventViewer/EventDelegate.cpp110
-rw-r--r--Swift/QtUI/EventViewer/EventDelegate.h34
-rw-r--r--Swift/QtUI/EventViewer/EventModel.cpp132
-rw-r--r--Swift/QtUI/EventViewer/EventModel.h38
-rw-r--r--Swift/QtUI/EventViewer/EventView.cpp6
-rw-r--r--Swift/QtUI/EventViewer/EventView.h10
-rw-r--r--Swift/QtUI/EventViewer/QtEvent.cpp132
-rw-r--r--Swift/QtUI/EventViewer/QtEvent.h34
-rw-r--r--Swift/QtUI/EventViewer/QtEventWindow.cpp149
-rw-r--r--Swift/QtUI/EventViewer/QtEventWindow.h62
-rw-r--r--Swift/QtUI/EventViewer/TwoLineDelegate.cpp83
-rw-r--r--Swift/QtUI/EventViewer/TwoLineDelegate.h30
-rw-r--r--Swift/QtUI/EventViewer/main.cpp42
-rw-r--r--Swift/QtUI/FreeDesktopNotifier.cpp62
-rw-r--r--Swift/QtUI/FreeDesktopNotifier.h25
-rw-r--r--Swift/QtUI/MUCSearch/MUCSearchDelegate.cpp111
-rw-r--r--Swift/QtUI/MUCSearch/MUCSearchDelegate.h26
-rw-r--r--Swift/QtUI/MUCSearch/MUCSearchEmptyItem.cpp46
-rw-r--r--Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h23
-rw-r--r--Swift/QtUI/MUCSearch/MUCSearchItem.h18
-rw-r--r--Swift/QtUI/MUCSearch/MUCSearchModel.cpp130
-rw-r--r--Swift/QtUI/MUCSearch/MUCSearchModel.h44
-rw-r--r--Swift/QtUI/MUCSearch/MUCSearchRoomItem.cpp30
-rw-r--r--Swift/QtUI/MUCSearch/MUCSearchRoomItem.h30
-rw-r--r--Swift/QtUI/MUCSearch/MUCSearchServiceItem.cpp78
-rw-r--r--Swift/QtUI/MUCSearch/MUCSearchServiceItem.h47
-rw-r--r--Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.cpp28
-rw-r--r--Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.h29
-rw-r--r--Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp277
-rw-r--r--Swift/QtUI/MUCSearch/QtMUCSearchWindow.h84
-rw-r--r--Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui62
-rw-r--r--Swift/QtUI/MessageSnippet.cpp60
-rw-r--r--Swift/QtUI/MessageSnippet.h30
-rw-r--r--Swift/QtUI/NotifierTest/NotifierTest.cpp20
-rw-r--r--Swift/QtUI/QtAboutWidget.cpp179
-rw-r--r--Swift/QtUI/QtAboutWidget.h33
-rw-r--r--Swift/QtUI/QtAdHocCommandWindow.cpp226
-rw-r--r--Swift/QtUI/QtAdHocCommandWindow.h76
-rw-r--r--Swift/QtUI/QtAdHocCommandWithJIDWindow.cpp48
-rw-r--r--Swift/QtUI/QtAdHocCommandWithJIDWindow.h30
-rw-r--r--Swift/QtUI/QtAddBookmarkWindow.cpp26
-rw-r--r--Swift/QtUI/QtAddBookmarkWindow.h26
-rw-r--r--Swift/QtUI/QtAffiliationEditor.cpp87
-rw-r--r--Swift/QtUI/QtAffiliationEditor.h45
-rw-r--r--Swift/QtUI/QtAvatarWidget.cpp165
-rw-r--r--Swift/QtUI/QtAvatarWidget.h69
-rw-r--r--Swift/QtUI/QtBlockListEditorWindow.cpp304
-rw-r--r--Swift/QtUI/QtBlockListEditorWindow.h57
-rw-r--r--Swift/QtUI/QtBookmarkDetailWindow.cpp102
-rw-r--r--Swift/QtUI/QtBookmarkDetailWindow.h34
-rw-r--r--Swift/QtUI/QtCachedImageScaler.cpp47
-rw-r--r--Swift/QtUI/QtCachedImageScaler.h10
-rw-r--r--Swift/QtUI/QtCertificateViewerDialog.cpp187
-rw-r--r--Swift/QtUI/QtCertificateViewerDialog.h28
-rw-r--r--Swift/QtUI/QtChatTabs.cpp644
-rw-r--r--Swift/QtUI/QtChatTabs.h118
-rw-r--r--Swift/QtUI/QtChatTabsBase.h8
-rw-r--r--Swift/QtUI/QtChatTabsShortcutOnlySubstitute.cpp101
-rw-r--r--Swift/QtUI/QtChatTabsShortcutOnlySubstitute.h32
-rw-r--r--Swift/QtUI/QtChatTheme.cpp96
-rw-r--r--Swift/QtUI/QtChatTheme.h57
-rw-r--r--Swift/QtUI/QtChatView.cpp5
-rw-r--r--Swift/QtUI/QtChatView.h80
-rw-r--r--Swift/QtUI/QtChatWindow.cpp1284
-rw-r--r--Swift/QtUI/QtChatWindow.h401
-rw-r--r--Swift/QtUI/QtChatWindowFactory.cpp96
-rw-r--r--Swift/QtUI/QtChatWindowFactory.h48
-rw-r--r--Swift/QtUI/QtChatWindowJSBridge.cpp12
-rw-r--r--Swift/QtUI/QtChatWindowJSBridge.h19
-rw-r--r--Swift/QtUI/QtClickableLabel.cpp6
-rw-r--r--Swift/QtUI/QtClickableLabel.h16
-rw-r--r--Swift/QtUI/QtClosableLineEdit.cpp48
-rw-r--r--Swift/QtUI/QtClosableLineEdit.h24
-rw-r--r--Swift/QtUI/QtColorToolButton.cpp40
-rw-r--r--Swift/QtUI/QtColorToolButton.h36
-rw-r--r--Swift/QtUI/QtConnectionSettingsWindow.cpp272
-rw-r--r--Swift/QtUI/QtConnectionSettingsWindow.h48
-rw-r--r--Swift/QtUI/QtContactEditWidget.cpp258
-rw-r--r--Swift/QtUI/QtContactEditWidget.h73
-rw-r--r--Swift/QtUI/QtContactEditWindow.cpp116
-rw-r--r--Swift/QtUI/QtContactEditWindow.h52
-rw-r--r--Swift/QtUI/QtDBUSURIHandler.cpp44
-rw-r--r--Swift/QtUI/QtDBUSURIHandler.h11
-rw-r--r--Swift/QtUI/QtEditBookmarkWindow.cpp28
-rw-r--r--Swift/QtUI/QtEditBookmarkWindow.h29
-rw-r--r--Swift/QtUI/QtElidingLabel.cpp56
-rw-r--r--Swift/QtUI/QtElidingLabel.h36
-rw-r--r--Swift/QtUI/QtEmoticonCell.cpp22
-rw-r--r--Swift/QtUI/QtEmoticonCell.h28
-rw-r--r--Swift/QtUI/QtEmoticonsGrid.cpp64
-rw-r--r--Swift/QtUI/QtEmoticonsGrid.h32
-rw-r--r--Swift/QtUI/QtFileTransferListItemModel.cpp158
-rw-r--r--Swift/QtUI/QtFileTransferListItemModel.h48
-rw-r--r--Swift/QtUI/QtFileTransferListWidget.cpp98
-rw-r--r--Swift/QtUI/QtFileTransferListWidget.h30
-rw-r--r--Swift/QtUI/QtFormResultItemModel.cpp85
-rw-r--r--Swift/QtUI/QtFormResultItemModel.h28
-rw-r--r--Swift/QtUI/QtFormWidget.cpp390
-rw-r--r--Swift/QtUI/QtFormWidget.h31
-rw-r--r--Swift/QtUI/QtHighlightEditor.cpp786
-rw-r--r--Swift/QtUI/QtHighlightEditor.h98
-rw-r--r--Swift/QtUI/QtHighlightEditorWidget.cpp149
-rw-r--r--Swift/QtUI/QtHighlightEditorWidget.h44
-rw-r--r--Swift/QtUI/QtHighlightEditorWidget.ui124
-rw-r--r--Swift/QtUI/QtHighlightRulesItemModel.cpp284
-rw-r--r--Swift/QtUI/QtHighlightRulesItemModel.h64
-rw-r--r--Swift/QtUI/QtHistoryWindow.cpp333
-rw-r--r--Swift/QtUI/QtHistoryWindow.h117
-rw-r--r--Swift/QtUI/QtJoinMUCWindow.cpp71
-rw-r--r--Swift/QtUI/QtJoinMUCWindow.h117
-rw-r--r--Swift/QtUI/QtLineEdit.cpp12
-rw-r--r--Swift/QtUI/QtLineEdit.h20
-rw-r--r--Swift/QtUI/QtLoginWindow.cpp753
-rw-r--r--Swift/QtUI/QtLoginWindow.h169
-rw-r--r--Swift/QtUI/QtMUCConfigurationWindow.cpp66
-rw-r--r--Swift/QtUI/QtMUCConfigurationWindow.h47
-rw-r--r--Swift/QtUI/QtMainWindow.cpp504
-rw-r--r--Swift/QtUI/QtMainWindow.h164
-rw-r--r--Swift/QtUI/QtNameWidget.cpp118
-rw-r--r--Swift/QtUI/QtNameWidget.h66
-rw-r--r--Swift/QtUI/QtPlainChatView.cpp611
-rw-r--r--Swift/QtUI/QtPlainChatView.h220
-rw-r--r--Swift/QtUI/QtProfileWindow.cpp178
-rw-r--r--Swift/QtUI/QtProfileWindow.h50
-rw-r--r--Swift/QtUI/QtResourceHelper.cpp20
-rw-r--r--Swift/QtUI/QtRosterHeader.cpp169
-rw-r--r--Swift/QtUI/QtRosterHeader.h82
-rw-r--r--Swift/QtUI/QtScaledAvatarCache.cpp103
-rw-r--r--Swift/QtUI/QtScaledAvatarCache.h17
-rw-r--r--Swift/QtUI/QtSettingsProvider.cpp126
-rw-r--r--Swift/QtUI/QtSettingsProvider.h50
-rw-r--r--Swift/QtUI/QtSingleWindow.cpp70
-rw-r--r--Swift/QtUI/QtSingleWindow.h46
-rw-r--r--Swift/QtUI/QtSoundPlayer.cpp45
-rw-r--r--Swift/QtUI/QtSoundPlayer.h30
-rw-r--r--Swift/QtUI/QtSpellCheckHighlighter.cpp22
-rw-r--r--Swift/QtUI/QtSpellCheckHighlighter.h20
-rw-r--r--Swift/QtUI/QtSpellCheckerWindow.cpp129
-rw-r--r--Swift/QtUI/QtSpellCheckerWindow.h60
-rw-r--r--Swift/QtUI/QtSpellCheckerWindow.ui45
-rw-r--r--Swift/QtUI/QtStatusWidget.cpp453
-rw-r--r--Swift/QtUI/QtStatusWidget.h108
-rw-r--r--Swift/QtUI/QtStrings.h2
-rw-r--r--Swift/QtUI/QtSubscriptionRequestWindow.cpp112
-rw-r--r--Swift/QtUI/QtSubscriptionRequestWindow.h44
-rw-r--r--Swift/QtUI/QtSwift.cpp444
-rw-r--r--Swift/QtUI/QtSwift.h127
-rw-r--r--Swift/QtUI/QtSystemTray.cpp92
-rw-r--r--Swift/QtUI/QtSystemTray.h68
-rw-r--r--Swift/QtUI/QtTabWidget.cpp48
-rw-r--r--Swift/QtUI/QtTabWidget.h23
-rw-r--r--Swift/QtUI/QtTabbable.cpp66
-rw-r--r--Swift/QtUI/QtTabbable.h51
-rw-r--r--Swift/QtUI/QtTextEdit.cpp332
-rw-r--r--Swift/QtUI/QtTextEdit.h95
-rw-r--r--Swift/QtUI/QtTranslator.h28
-rw-r--r--Swift/QtUI/QtUIFactory.cpp198
-rw-r--r--Swift/QtUI/QtUIFactory.h125
-rw-r--r--Swift/QtUI/QtUISettingConstants.cpp11
-rw-r--r--Swift/QtUI/QtUISettingConstants.h55
-rw-r--r--Swift/QtUI/QtURIHandler.cpp24
-rw-r--r--Swift/QtUI/QtURIHandler.h15
-rw-r--r--Swift/QtUI/QtURLValidator.cpp11
-rw-r--r--Swift/QtUI/QtURLValidator.h12
-rw-r--r--Swift/QtUI/QtUpdateFeedSelectionDialog.cpp83
-rw-r--r--Swift/QtUI/QtUpdateFeedSelectionDialog.h30
-rw-r--r--Swift/QtUI/QtUpdateFeedSelectionDialog.ui146
-rw-r--r--Swift/QtUI/QtUtilities.cpp20
-rw-r--r--Swift/QtUI/QtUtilities.h14
-rw-r--r--Swift/QtUI/QtVCardWidget/QtCloseButton.cpp40
-rw-r--r--Swift/QtUI/QtVCardWidget/QtCloseButton.h24
-rw-r--r--Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.cpp58
-rw-r--r--Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h18
-rw-r--r--Swift/QtUI/QtVCardWidget/QtResizableLineEdit.cpp42
-rw-r--r--Swift/QtUI/QtVCardWidget/QtResizableLineEdit.h34
-rw-r--r--Swift/QtUI/QtVCardWidget/QtTagComboBox.cpp108
-rw-r--r--Swift/QtUI/QtVCardWidget/QtTagComboBox.h46
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardAddressField.cpp236
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardAddressField.h74
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.cpp108
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.h38
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.cpp51
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.h43
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.cpp59
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.h42
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h74
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardGeneralField.cpp172
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h124
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardHomeWork.cpp24
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardHomeWork.h28
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.cpp87
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.h44
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardJIDField.cpp71
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardJIDField.h42
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.cpp178
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.h50
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.cpp126
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.h66
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardRoleField.cpp35
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardRoleField.h40
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.cpp130
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.h42
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardTitleField.cpp37
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardTitleField.h40
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardURLField.cpp72
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardURLField.h42
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardWidget.cpp674
-rw-r--r--Swift/QtUI/QtVCardWidget/QtVCardWidget.h87
-rw-r--r--Swift/QtUI/QtWebKitChatView.cpp1489
-rw-r--r--Swift/QtUI/QtWebKitChatView.h336
-rw-r--r--Swift/QtUI/QtWebView.cpp123
-rw-r--r--Swift/QtUI/QtWebView.h49
-rw-r--r--Swift/QtUI/QtWin32NotifierWindow.h30
-rw-r--r--Swift/QtUI/QtXMLConsoleWidget.cpp126
-rw-r--r--Swift/QtUI/QtXMLConsoleWidget.h43
-rw-r--r--Swift/QtUI/Roster/DelegateCommons.cpp179
-rw-r--r--Swift/QtUI/Roster/DelegateCommons.h48
-rw-r--r--Swift/QtUI/Roster/GroupItemDelegate.cpp168
-rw-r--r--Swift/QtUI/Roster/GroupItemDelegate.h32
-rw-r--r--Swift/QtUI/Roster/QtFilterWidget.cpp218
-rw-r--r--Swift/QtUI/Roster/QtFilterWidget.h60
-rw-r--r--Swift/QtUI/Roster/QtOccupantListWidget.cpp80
-rw-r--r--Swift/QtUI/Roster/QtOccupantListWidget.h28
-rw-r--r--Swift/QtUI/Roster/QtRosterWidget.cpp227
-rw-r--r--Swift/QtUI/Roster/QtRosterWidget.h24
-rw-r--r--Swift/QtUI/Roster/QtTreeWidget.cpp322
-rw-r--r--Swift/QtUI/Roster/QtTreeWidget.h102
-rw-r--r--Swift/QtUI/Roster/RosterDelegate.cpp86
-rw-r--r--Swift/QtUI/Roster/RosterDelegate.h44
-rw-r--r--Swift/QtUI/Roster/RosterModel.cpp343
-rw-r--r--Swift/QtUI/Roster/RosterModel.h102
-rw-r--r--Swift/QtUI/Roster/RosterTooltip.cpp275
-rw-r--r--Swift/QtUI/Roster/RosterTooltip.h10
-rw-r--r--Swift/QtUI/Roster/main.cpp97
-rw-r--r--Swift/QtUI/SConscript682
-rw-r--r--Swift/QtUI/Swift.qrc8
-rw-r--r--Swift/QtUI/SwiftUpdateFeeds.h29
-rw-r--r--Swift/QtUI/SystemMessageSnippet.cpp24
-rw-r--r--Swift/QtUI/SystemMessageSnippet.h24
-rw-r--r--Swift/QtUI/Trellis/QtDNDTabBar.cpp220
-rw-r--r--Swift/QtUI/Trellis/QtDNDTabBar.h55
-rw-r--r--Swift/QtUI/Trellis/QtDynamicGridLayout.cpp786
-rw-r--r--Swift/QtUI/Trellis/QtDynamicGridLayout.h98
-rw-r--r--Swift/QtUI/Trellis/QtGridSelectionDialog.cpp222
-rw-r--r--Swift/QtUI/Trellis/QtGridSelectionDialog.h91
-rw-r--r--Swift/QtUI/UserSearch/ContactListDelegate.cpp40
-rw-r--r--Swift/QtUI/UserSearch/ContactListDelegate.h20
-rw-r--r--Swift/QtUI/UserSearch/ContactListModel.cpp145
-rw-r--r--Swift/QtUI/UserSearch/ContactListModel.h68
-rw-r--r--Swift/QtUI/UserSearch/QtContactListWidget.cpp93
-rw-r--r--Swift/QtUI/UserSearch/QtContactListWidget.h44
-rw-r--r--Swift/QtUI/UserSearch/QtSuggestingJIDInput.cpp298
-rw-r--r--Swift/QtUI/UserSearch/QtSuggestingJIDInput.h62
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchDetailsPage.cpp32
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchDetailsPage.h43
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchFieldsPage.cpp38
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchFieldsPage.h27
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp115
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.h67
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchFirstPage.cpp58
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchFirstPage.h34
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchResultsPage.cpp36
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchResultsPage.h24
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchWindow.cpp917
-rw-r--r--Swift/QtUI/UserSearch/QtUserSearchWindow.h172
-rw-r--r--Swift/QtUI/UserSearch/UserSearchDelegate.cpp72
-rw-r--r--Swift/QtUI/UserSearch/UserSearchDelegate.h26
-rw-r--r--Swift/QtUI/UserSearch/UserSearchModel.cpp92
-rw-r--r--Swift/QtUI/UserSearch/UserSearchModel.h52
-rw-r--r--Swift/QtUI/Whiteboard/ColorWidget.cpp57
-rw-r--r--Swift/QtUI/Whiteboard/ColorWidget.h36
-rw-r--r--Swift/QtUI/Whiteboard/FreehandLineItem.cpp157
-rw-r--r--Swift/QtUI/Whiteboard/FreehandLineItem.h45
-rw-r--r--Swift/QtUI/Whiteboard/GView.cpp981
-rw-r--r--Swift/QtUI/Whiteboard/GView.h118
-rw-r--r--Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp736
-rw-r--r--Swift/QtUI/Whiteboard/QtWhiteboardWindow.h138
-rw-r--r--Swift/QtUI/Whiteboard/TextDialog.cpp92
-rw-r--r--Swift/QtUI/Whiteboard/TextDialog.h60
-rw-r--r--Swift/QtUI/Whiteboard/WhiteboardElementDrawingVisitor.h350
-rw-r--r--Swift/QtUI/WinUIHelpers.cpp88
-rw-r--r--Swift/QtUI/WinUIHelpers.h11
-rw-r--r--Swift/QtUI/WindowsNotifier.cpp46
-rw-r--r--Swift/QtUI/WindowsNotifier.h35
-rw-r--r--Swift/QtUI/main.cpp144
-rw-r--r--Swift/QtUI/swift-open-uri.cpp31
-rw-r--r--Swift/SConscript24
-rw-r--r--Swift/Translations/swift_ca.ts2
-rw-r--r--Swift/Translations/swift_cs.ts2
-rw-r--r--Swift/Translations/swift_de.ts2
-rw-r--r--Swift/Translations/swift_es.ts2
-rw-r--r--Swift/Translations/swift_fr.ts2
-rw-r--r--Swift/Translations/swift_gl.ts2
-rw-r--r--Swift/Translations/swift_he.ts4
-rw-r--r--Swift/Translations/swift_hu.ts2
-rw-r--r--Swift/Translations/swift_nl.ts2
-rw-r--r--Swift/Translations/swift_pl.ts2
-rw-r--r--Swift/Translations/swift_ru.ts2
-rw-r--r--Swift/Translations/swift_sk.ts2
-rw-r--r--Swift/Translations/swift_sv.ts2
-rw-r--r--Swift/resources/icons/avatar.pngbin2096 -> 0 bytes
-rw-r--r--Swift/resources/icons/avatar.svg4788
-rw-r--r--Swift/resources/icons/delivery-failure.svg14
-rw-r--r--Swift/resources/icons/delivery-success.svg11
-rw-r--r--Swift/resources/icons/delivery-warning.svg18
-rw-r--r--Swift/resources/logo/logo-shaded-text.256.pngbin18541 -> 0 bytes
-rw-r--r--Swift/resources/logo/logo-shaded-text.pngbin0 -> 11177 bytes
-rw-r--r--Swift/resources/logo/logo-shaded-text.svg65
-rwxr-xr-xSwift/resources/themes/Default/Demo.html91
-rwxr-xr-xSwift/resources/themes/Default/Header.html5
-rw-r--r--[-rwxr-xr-x]Swift/resources/themes/Default/Incoming/Content.html47
-rwxr-xr-xSwift/resources/themes/Default/Incoming/Context.html30
-rw-r--r--[-rwxr-xr-x]Swift/resources/themes/Default/Incoming/NextContent.html26
-rwxr-xr-xSwift/resources/themes/Default/Incoming/NextContext.html7
-rw-r--r--Swift/resources/themes/Default/Incoming/buddy_icon.pngbin12047 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/LICENSE.txt15
-rw-r--r--Swift/resources/themes/Default/Lato2OFL/Lato-Black.ttfbin0 -> 614544 bytes
-rw-r--r--Swift/resources/themes/Default/Lato2OFL/Lato-BlackItalic.ttfbin0 -> 672480 bytes
-rw-r--r--Swift/resources/themes/Default/Lato2OFL/Lato-Bold.ttfbin0 -> 657188 bytes
-rw-r--r--Swift/resources/themes/Default/Lato2OFL/Lato-BoldItalic.ttfbin0 -> 699008 bytes
-rw-r--r--Swift/resources/themes/Default/Lato2OFL/Lato-Hairline.ttfbin0 -> 584784 bytes
-rw-r--r--Swift/resources/themes/Default/Lato2OFL/Lato-HairlineItalic.ttfbin0 -> 609436 bytes
-rw-r--r--Swift/resources/themes/Default/Lato2OFL/Lato-Heavy.ttfbin0 -> 665420 bytes
-rw-r--r--Swift/resources/themes/Default/Lato2OFL/Lato-HeavyItalic.ttfbin0 -> 698924 bytes
-rw-r--r--Swift/resources/themes/Default/Lato2OFL/Lato-Italic.ttfbin0 -> 723544 bytes
-rw-r--r--Swift/resources/themes/Default/Lato2OFL/Lato-Light.ttfbin0 -> 644556 bytes
-rw-r--r--Swift/resources/themes/Default/Lato2OFL/Lato-LightItalic.ttfbin0 -> 658212 bytes
-rw-r--r--Swift/resources/themes/Default/Lato2OFL/Lato-Medium.ttfbin0 -> 637068 bytes
-rw-r--r--Swift/resources/themes/Default/Lato2OFL/Lato-MediumItalic.ttfbin0 -> 695588 bytes
-rw-r--r--Swift/resources/themes/Default/Lato2OFL/Lato-Regular.ttfbin0 -> 657212 bytes
-rw-r--r--Swift/resources/themes/Default/Lato2OFL/Lato-Semibold.ttfbin0 -> 669228 bytes
-rw-r--r--Swift/resources/themes/Default/Lato2OFL/Lato-SemiboldItalic.ttfbin0 -> 698028 bytes
-rw-r--r--Swift/resources/themes/Default/Lato2OFL/Lato-Thin.ttfbin0 -> 627220 bytes
-rw-r--r--Swift/resources/themes/Default/Lato2OFL/Lato-ThinItalic.ttfbin0 -> 654216 bytes
-rwxr-xr-xSwift/resources/themes/Default/Lato2OFL/OFL.txt94
-rwxr-xr-xSwift/resources/themes/Default/Lato2OFL/README.txt72
-rw-r--r--[-rwxr-xr-x]Swift/resources/themes/Default/Outgoing/Content.html47
-rwxr-xr-xSwift/resources/themes/Default/Outgoing/Context.html31
-rw-r--r--[-rwxr-xr-x]Swift/resources/themes/Default/Outgoing/NextContent.html24
-rwxr-xr-xSwift/resources/themes/Default/Outgoing/NextContext.html6
-rw-r--r--Swift/resources/themes/Default/Outgoing/buddy_icon.pngbin12047 -> 0 bytes
-rw-r--r--[-rwxr-xr-x]Swift/resources/themes/Default/Status.html40
-rw-r--r--[-rwxr-xr-x]Swift/resources/themes/Default/Template.html359
-rw-r--r--Swift/resources/themes/Default/Unread.html1
-rw-r--r--Swift/resources/themes/Default/Variants/Blue on Green Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Blue on Green No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Blue on Green No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Blue on Green.css90
-rw-r--r--Swift/resources/themes/Default/Variants/Blue on Red Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Blue on Red No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Blue on Red No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Blue on Red.css89
-rw-r--r--Swift/resources/themes/Default/Variants/Blue on Steel Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Blue on Steel No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Blue on Steel No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Blue on Steel.css91
-rw-r--r--Swift/resources/themes/Default/Variants/Blue on Yellow Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Blue on Yellow No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Blue on Yellow No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Blue on Yellow.css91
-rw-r--r--Swift/resources/themes/Default/Variants/Green on Blue Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Green on Blue No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Green on Blue No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Green on Blue.css91
-rw-r--r--Swift/resources/themes/Default/Variants/Green on Red Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Green on Red No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Green on Red No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Green on Red.css91
-rw-r--r--Swift/resources/themes/Default/Variants/Green on Steel Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Green on Steel No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Green on Steel No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Green on Steel.css91
-rw-r--r--Swift/resources/themes/Default/Variants/Green on Yellow Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Green on Yellow No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Green on Yellow No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Green on Yellow.css91
-rw-r--r--Swift/resources/themes/Default/Variants/Red on Blue Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Red on Blue No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Red on Blue No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Red on Blue.css90
-rw-r--r--Swift/resources/themes/Default/Variants/Red on Green Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Red on Green No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Red on Green No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Red on Green.css95
-rw-r--r--Swift/resources/themes/Default/Variants/Red on Steel Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Red on Steel No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Red on Steel No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Red on Steel.css93
-rw-r--r--Swift/resources/themes/Default/Variants/Red on Yellow Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Red on Yellow No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Red on Yellow No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Red on Yellow.css91
-rw-r--r--Swift/resources/themes/Default/Variants/Steel on Blue Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Steel on Blue No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Steel on Blue No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Steel on Blue.css92
-rw-r--r--Swift/resources/themes/Default/Variants/Steel on Green Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Steel on Green No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Steel on Green No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Steel on Green.css97
-rw-r--r--Swift/resources/themes/Default/Variants/Steel on Red Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Steel on Red No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Steel on Red No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Steel on Red.css89
-rw-r--r--Swift/resources/themes/Default/Variants/Steel on Yellow Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Steel on Yellow No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Steel on Yellow No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Steel on Yellow.css92
-rw-r--r--Swift/resources/themes/Default/Variants/Yellow on Blue Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Yellow on Blue No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Yellow on Blue No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Yellow on Blue.css91
-rw-r--r--Swift/resources/themes/Default/Variants/Yellow on Green Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Yellow on Green No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Yellow on Green No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Yellow on Green.css96
-rw-r--r--Swift/resources/themes/Default/Variants/Yellow on Red Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Yellow on Red No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Yellow on Red No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Yellow on Red.css91
-rw-r--r--Swift/resources/themes/Default/Variants/Yellow on Steel Alternating.css7
-rw-r--r--Swift/resources/themes/Default/Variants/Yellow on Steel No Names Alt.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Yellow on Steel No Names.css2
-rw-r--r--Swift/resources/themes/Default/Variants/Yellow on Steel.css91
-rw-r--r--Swift/resources/themes/Default/alternating.css16
-rwxr-xr-xSwift/resources/themes/Default/images/DummyContact.pngbin754 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/alert.pngbin5305 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/blueBackground.gifbin198 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/blueBackground.pngbin165 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/blueCurves.gifbin3320 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/blueCurves.pngbin1218 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/blueIndicator.gifbin536 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/blueIndicator.pngbin370 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/blueIndicator2.pngbin380 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/blueIndicatorAlt.gifbin526 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/greenBackground.gifbin117 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/greenBackground.pngbin166 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/greenCurves.gifbin3259 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/greenCurves.pngbin1234 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/greenIndicator.gifbin530 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/greenIndicator.pngbin334 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/greenIndicator2.pngbin345 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/greenIndicatorAlt.gifbin529 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/redBackground.gifbin117 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/redBackground.pngbin160 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/redCurves.gifbin2527 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/redCurves.pngbin1194 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/redIndicator.gifbin527 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/redIndicator.pngbin410 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/redIndicator2.pngbin402 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/redIndicatorAlt.gifbin527 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/silverBackground.gifbin117 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/silverCurves.gifbin2778 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/steelBackground.gifbin122 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/steelBackground.pngbin156 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/steelCurves.gifbin2169 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/steelCurves.pngbin1179 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/steelHeading.jpgbin321 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/steelIndicator.gifbin328 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/steelIndicator.pngbin375 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/steelIndicator2.pngbin392 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/steelIndicatorAlt.gifbin326 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/typing-left.pngbin1702 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/typing-right.pngbin1710 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/yellowBackground.gifbin117 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/yellowBackground.pngbin162 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/yellowCurves.gifbin3202 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/yellowCurves.pngbin1200 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/yellowHeading.jpgbin1447 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/images/yellowIndicator.gifbin532 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/yellowIndicator.pngbin380 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/yellowIndicator2.pngbin400 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/yellowIndicatorAlt.gifbin931 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/yellowTL.pngbin326 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/images/yellowTR.pngbin364 -> 0 bytes
-rwxr-xr-xSwift/resources/themes/Default/incoming_icon.pngbin23643 -> 0 bytes
-rw-r--r--Swift/resources/themes/Default/lato.css143
-rw-r--r--[-rwxr-xr-x]Swift/resources/themes/Default/main.css401
-rw-r--r--Swift/resources/themes/Default/noname.css3
-rwxr-xr-xSwift/resources/themes/Default/outgoing_icon.pngbin23643 -> 0 bytes
762 files changed, 38979 insertions, 34931 deletions
diff --git a/Swift/ChangeLog.md b/Swift/ChangeLog.md
index 097de4d..4c88d88 100644
--- a/Swift/ChangeLog.md
+++ b/Swift/ChangeLog.md
@@ -1,5 +1,52 @@
-3.0-beta1
----------
+4.0-in-progress
+---------------
+- Fix UI layout issue for translations that require right-to-left (RTL) layout
+- macOS releases are now code-signed with a key from Apple, so they can be run without Gatekeeper trust warnings
+- Handle sessions being closed by the server
+
+4.0-beta2 ( 2016-07-20 )
+------------------------
+- Fix Swift bug introduced in 4.0-beta1 that results in the UI sometimes getting stuck during login
+
+4.0-beta1 ( 2016-07-15 )
+------------------------
+- Support for message carbons (XEP-0280)
+- Improved spell checker support on Linux
+- Enabled trellis mode as a default feature, allowing several tiled chats windows to be shown at once
+- New chat theme including a new font
+- And assorted smaller features and usability enhancements
+
+3.0 ( 2016-02-24 )
+------------------
+- File transfer and Mac Notification Center issues fixed
+- Fix connection to servers with invalid or untrusted certificates on OS/X
+- Support for the Notification Center on OS X
+- Users can now authenticate using certificates (and smart cards on Windows) when using the 'BOSH' connection type.
+- Encryption on OS X now uses the platform's native 'Secure Transport' mechanisms.
+- Emoticons menu in chat dialogs
+- Bookmark for rooms can now be edited directly from the ‘Recent Chats’ list
+- Adds option to workaround servers that don’t interoperate well with Windows (schannel) encryption
+- Rooms entered while offline will now get entered on reconnect
+- Chats can now be seamlessly upgraded to multi-person chats by either inviting someone via the ‘cog’ menu, or dragging them from the roster. This relies on server-side support with an appropriate chatroom (MUC) service.
+- Highlighting of keywords and messages from particular users can now be configured (Keyword Highlighting Blog post).
+- Full profile vcards (contact information etc.) are now supported and can be configured for the user and queried for contacts.
+- Simple Communication Blocking is now supported (subject to server support) to allow the blocking of nuisance users.
+- Swift can now transfer files via the ‘Jingle File Transfer’ protocol.
+- The status setter will now remember previously set statuses and will allow quick access to these when the user types part of a recently used status.
+- Tooltips for contacts in the roster now show their vcard profile information
+- The top of the roster window now shows a tooltip with your vcard profile information in
+- Chatrooms (MUCs) can now be bookmarked by right-clicking on their entry in the Recent Chats list, or from the ‘cog’ menu for any room you’re currently in.
+- The tooltips for MUC occupants now show their affiliation and role in the room (e.g. Administrator)
+- Support for ‘right-to-left’ languages has been improved.
+- A small number of emoticons will be automatically rendered when receiving text, e.g. :), this can be disabled from the View menu.
+- Swift now distinguishes between contacts who have chosen to show as ‘away’ and those whose clients have noticed they’re idle (requires support in contacts' clients).
+- Typing search terms with the roster selected will start to search for contacts matching the terms (useful for users with large rosters).
+- An experimental ‘Trellis’ view for viewing several chats and rooms at once has been added. This is currently hidden; contact us if you’re interested in testing this feature.
+- And assorted smaller features and usability enhancements.
+
+
+3.0-beta1 ( 2015-02-23 )
+------------------------
- Allow toggling of a more compact roster display.
- Remember status settings and provide quick access to them with searching of recent selections in the status setter.
@@ -7,8 +54,8 @@
---
- Fixed potential crash when using proxies on Mac OS X.
-2.0-beta2
----------
+2.0-beta2 ( 2012-10-07 )
+------------------------
- Enable auto-completion of nicknames that don't start with a letter.
- Generate crash dumps on Windows.
- Connection timeouts are now on each connection separately, instead of on the complete connection process.
@@ -28,8 +75,8 @@
Thanks to Tobias Markmann.
-2.0-beta1
----------
+2.0-beta1 ( 2012-04-29 )
+------------------------
- Windows packages are now built in Microsoft Installer's ".msi" format. Please
uninstall any older NSIS-based Swift packages before upgrading to this release.
- Suitable names will now be suggested from the contact's vcard when adding/editing their roster entry.
@@ -55,6 +102,6 @@ Thanks to Tobias Markmann, Jan Kaluza, Thilo Cestonaro, Arnt Gulbrandsen, Vlad V
Yoann Blein, Catalin Badea, Pavol Babincak, Mateusz Piekos, Alexey Melnikov and Soren Dreijer.
-1.0
----
-- Initial release.
+1.0 ( 2011-04-18 )
+------------------
+- Initial release. \ No newline at end of file
diff --git a/Swift/Controllers/AdHocController.cpp b/Swift/Controllers/AdHocController.cpp
index b48b832..5e10beb 100644
--- a/Swift/Controllers/AdHocController.cpp
+++ b/Swift/Controllers/AdHocController.cpp
@@ -1,31 +1,33 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include <boost/bind.hpp>
#include <Swift/Controllers/AdHocController.h>
+
+#include <boost/bind.hpp>
+
#include <Swift/Controllers/UIInterfaces/AdHocCommandWindowFactory.h>
namespace Swift {
-AdHocController::AdHocController(AdHocCommandWindowFactory* factory, boost::shared_ptr<OutgoingAdHocCommandSession> command) {
- window_ = factory->createAdHocCommandWindow(command);
- window_->onClosing.connect(boost::bind(&AdHocController::handleWindowClosed, this));
+AdHocController::AdHocController(AdHocCommandWindowFactory* factory, std::shared_ptr<OutgoingAdHocCommandSession> command) {
+ window_ = factory->createAdHocCommandWindow(command);
+ window_->onClosing.connect(boost::bind(&AdHocController::handleWindowClosed, this));
}
AdHocController::~AdHocController() {
- window_->onClosing.disconnect(boost::bind(&AdHocController::handleWindowClosed, this));
- delete window_;
+ window_->onClosing.disconnect(boost::bind(&AdHocController::handleWindowClosed, this));
+ delete window_;
}
void AdHocController::setOnline(bool online) {
- window_->setOnline(online);
+ window_->setOnline(online);
}
void AdHocController::handleWindowClosed() {
- onDeleting();
+ onDeleting();
}
}
diff --git a/Swift/Controllers/AdHocController.h b/Swift/Controllers/AdHocController.h
index 1ac148c..a6a5c70 100644
--- a/Swift/Controllers/AdHocController.h
+++ b/Swift/Controllers/AdHocController.h
@@ -1,12 +1,13 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
+
#include <Swiften/AdHoc/OutgoingAdHocCommandSession.h>
namespace Swift {
@@ -16,13 +17,13 @@ class AdHocCommandWindow;
class AdHocController {
public:
- AdHocController(AdHocCommandWindowFactory* factory, boost::shared_ptr<OutgoingAdHocCommandSession> command);
- ~AdHocController();
- boost::signal<void ()> onDeleting;
- void setOnline(bool online);
+ AdHocController(AdHocCommandWindowFactory* factory, std::shared_ptr<OutgoingAdHocCommandSession> command);
+ ~AdHocController();
+ boost::signals2::signal<void ()> onDeleting;
+ void setOnline(bool online);
private:
- void handleWindowClosed();
- AdHocCommandWindow* window_;
+ void handleWindowClosed();
+ AdHocCommandWindow* window_;
};
}
diff --git a/Swift/Controllers/AdHocManager.cpp b/Swift/Controllers/AdHocManager.cpp
index a572846..717f083 100644
--- a/Swift/Controllers/AdHocManager.cpp
+++ b/Swift/Controllers/AdHocManager.cpp
@@ -1,94 +1,94 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/AdHocManager.h>
+#include <memory>
+
#include <boost/bind.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-#include <Swiften/Base/foreach.h>
-#include <Swiften/Queries/IQRouter.h>
#include <Swiften/AdHoc/OutgoingAdHocCommandSession.h>
-#include <Swift/Controllers/UIInterfaces/MainWindow.h>
-#include <Swift/Controllers/UIInterfaces/AdHocCommandWindowFactory.h>
+#include <Swiften/Queries/IQRouter.h>
+
+#include <Swift/Controllers/UIEvents/RequestAdHocUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestAdHocWithJIDUIEvent.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
-#include <Swift/Controllers/UIEvents/RequestAdHocUIEvent.h>
+#include <Swift/Controllers/UIInterfaces/AdHocCommandWindowFactory.h>
+#include <Swift/Controllers/UIInterfaces/MainWindow.h>
namespace Swift {
AdHocManager::AdHocManager(const JID& jid, AdHocCommandWindowFactory* factory, IQRouter* iqRouter, UIEventStream* uiEventStream, MainWindow* mainWindow) : jid_(jid) {
- iqRouter_ = iqRouter;
- uiEventStream_ = uiEventStream;
- mainWindow_ = mainWindow;
- factory_ = factory;
+ iqRouter_ = iqRouter;
+ uiEventStream_ = uiEventStream;
+ mainWindow_ = mainWindow;
+ factory_ = factory;
- uiEventStream_->onUIEvent.connect(boost::bind(&AdHocManager::handleUIEvent, this, _1));
+ uiEventStream_->onUIEvent.connect(boost::bind(&AdHocManager::handleUIEvent, this, _1));
}
AdHocManager::~AdHocManager() {
- uiEventStream_->onUIEvent.disconnect(boost::bind(&AdHocManager::handleUIEvent, this, _1));
- for (size_t i = 0; i < controllers_.size(); ++i) {
- controllers_[i]->onDeleting.disconnect(boost::bind(&AdHocManager::removeController, this, controllers_[i]));
- }
+ uiEventStream_->onUIEvent.disconnect(boost::bind(&AdHocManager::handleUIEvent, this, _1));
+ for (auto& controller : controllers_) {
+ controller->onDeleting.disconnect(boost::bind(&AdHocManager::removeController, this, controller));
+ }
}
-void AdHocManager::removeController(boost::shared_ptr<AdHocController> controller) {
- controller->onDeleting.disconnect(boost::bind(&AdHocManager::removeController, this, controller));
- controllers_.erase(std::find(controllers_.begin(), controllers_.end(), controller));
+void AdHocManager::removeController(std::shared_ptr<AdHocController> controller) {
+ controller->onDeleting.disconnect(boost::bind(&AdHocManager::removeController, this, controller));
+ controllers_.erase(std::find(controllers_.begin(), controllers_.end(), controller));
}
-void AdHocManager::setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info) {
- if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::CommandsFeature)) {
- if (discoItemsRequest_) {
- discoItemsRequest_->onResponse.disconnect(boost::bind(&AdHocManager::handleServerDiscoItemsResponse, this, _1, _2));
- discoItemsRequest_.reset();
- }
- discoItemsRequest_ = GetDiscoItemsRequest::create(JID(jid_.getDomain()), DiscoInfo::CommandsFeature, iqRouter_);
- discoItemsRequest_->onResponse.connect(boost::bind(&AdHocManager::handleServerDiscoItemsResponse, this, _1, _2));
- discoItemsRequest_->send();
- } else {
- mainWindow_->setAvailableAdHocCommands(std::vector<DiscoItems::Item>());
- }
+void AdHocManager::setServerDiscoInfo(std::shared_ptr<DiscoInfo> info) {
+ if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::CommandsFeature)) {
+ if (discoItemsRequest_) {
+ discoItemsRequest_->onResponse.disconnect(boost::bind(&AdHocManager::handleServerDiscoItemsResponse, this, _1, _2));
+ discoItemsRequest_.reset();
+ }
+ discoItemsRequest_ = GetDiscoItemsRequest::create(JID(jid_.getDomain()), DiscoInfo::CommandsFeature, iqRouter_);
+ discoItemsRequest_->onResponse.connect(boost::bind(&AdHocManager::handleServerDiscoItemsResponse, this, _1, _2));
+ discoItemsRequest_->send();
+ } else {
+ mainWindow_->setAvailableAdHocCommands(std::vector<DiscoItems::Item>());
+ }
}
void AdHocManager::setOnline(bool online) {
- foreach (boost::shared_ptr<AdHocController> controller, controllers_) {
- controller->setOnline(online);
- }
+ for (auto&& controller : controllers_) {
+ controller->setOnline(online);
+ }
}
-void AdHocManager::handleServerDiscoItemsResponse(boost::shared_ptr<DiscoItems> items, ErrorPayload::ref error) {
- std::vector<DiscoItems::Item> commands;
- if (!error) {
- foreach (DiscoItems::Item item, items->getItems()) {
- if (item.getNode() != "http://isode.com/xmpp/commands#test") {
- commands.push_back(item);
- }
- }
- }
- mainWindow_->setAvailableAdHocCommands(commands);
+void AdHocManager::handleServerDiscoItemsResponse(std::shared_ptr<DiscoItems> items, ErrorPayload::ref error) {
+ std::vector<DiscoItems::Item> commands;
+ if (!error) {
+ for (const auto& item : items->getItems()) {
+ if (item.getNode() != "http://isode.com/xmpp/commands#test") {
+ commands.push_back(item);
+ }
+ }
+ }
+ mainWindow_->setAvailableAdHocCommands(commands);
}
-void AdHocManager::handleUIEvent(boost::shared_ptr<UIEvent> event) {
- boost::shared_ptr<RequestAdHocUIEvent> adHocEvent = boost::dynamic_pointer_cast<RequestAdHocUIEvent>(event);
- if (adHocEvent) {
- boost::shared_ptr<OutgoingAdHocCommandSession> command = boost::make_shared<OutgoingAdHocCommandSession>(adHocEvent->getCommand().getJID(), adHocEvent->getCommand().getNode(), iqRouter_);
- boost::shared_ptr<AdHocController> controller = boost::make_shared<AdHocController>(factory_, command);
- controller->onDeleting.connect(boost::bind(&AdHocManager::removeController, this, controller));
- controllers_.push_back(controller);
- }
- boost::shared_ptr<RequestAdHocWithJIDUIEvent> adHocJIDEvent = boost::dynamic_pointer_cast<RequestAdHocWithJIDUIEvent>(event);
- if (!!adHocJIDEvent) {
- boost::shared_ptr<OutgoingAdHocCommandSession> command = boost::make_shared<OutgoingAdHocCommandSession>(adHocJIDEvent->getJID(), adHocJIDEvent->getNode(), iqRouter_);
- boost::shared_ptr<AdHocController> controller = boost::make_shared<AdHocController>(factory_, command);
- controller->onDeleting.connect(boost::bind(&AdHocManager::removeController, this, controller));
- controllers_.push_back(controller);
- }
+void AdHocManager::handleUIEvent(std::shared_ptr<UIEvent> event) {
+ std::shared_ptr<RequestAdHocUIEvent> adHocEvent = std::dynamic_pointer_cast<RequestAdHocUIEvent>(event);
+ if (adHocEvent) {
+ std::shared_ptr<OutgoingAdHocCommandSession> command = std::make_shared<OutgoingAdHocCommandSession>(adHocEvent->getCommand().getJID(), adHocEvent->getCommand().getNode(), iqRouter_);
+ std::shared_ptr<AdHocController> controller = std::make_shared<AdHocController>(factory_, command);
+ controller->onDeleting.connect(boost::bind(&AdHocManager::removeController, this, controller));
+ controllers_.push_back(controller);
+ }
+ std::shared_ptr<RequestAdHocWithJIDUIEvent> adHocJIDEvent = std::dynamic_pointer_cast<RequestAdHocWithJIDUIEvent>(event);
+ if (!!adHocJIDEvent) {
+ std::shared_ptr<OutgoingAdHocCommandSession> command = std::make_shared<OutgoingAdHocCommandSession>(adHocJIDEvent->getJID(), adHocJIDEvent->getNode(), iqRouter_);
+ std::shared_ptr<AdHocController> controller = std::make_shared<AdHocController>(factory_, command);
+ controller->onDeleting.connect(boost::bind(&AdHocManager::removeController, this, controller));
+ controllers_.push_back(controller);
+ }
}
}
diff --git a/Swift/Controllers/AdHocManager.h b/Swift/Controllers/AdHocManager.h
index 00289b0..0786370 100644
--- a/Swift/Controllers/AdHocManager.h
+++ b/Swift/Controllers/AdHocManager.h
@@ -1,44 +1,51 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
+#pragma once
+
#include <vector>
-#include <Swiften/Base/boost_bsignals.h>
-#include <Swiften/JID/JID.h>
+#include <boost/signals2.hpp>
+
+#include <Swiften/Disco/GetDiscoItemsRequest.h>
#include <Swiften/Elements/DiscoInfo.h>
#include <Swiften/Elements/DiscoItems.h>
#include <Swiften/Elements/ErrorPayload.h>
-#include <Swiften/Disco/GetDiscoItemsRequest.h>
-#include <Swiften/Client/Client.h>
-#include <Swift/Controllers/UIEvents/UIEvent.h>
+#include <Swiften/JID/JID.h>
+
#include <Swift/Controllers/AdHocController.h>
+#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
class IQRouter;
class MainWindow;
class UIEventStream;
class AdHocCommandWindowFactory;
+
class AdHocManager {
public:
- AdHocManager(const JID& jid, AdHocCommandWindowFactory* factory, IQRouter* iqRouter, UIEventStream* uiEventStream, MainWindow* mainWindow);
- ~AdHocManager();
- void removeController(boost::shared_ptr<AdHocController> contoller);
- void setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info);
- void setOnline(bool online);
+ AdHocManager(const JID& jid, AdHocCommandWindowFactory* factory, IQRouter* iqRouter, UIEventStream* uiEventStream, MainWindow* mainWindow);
+ ~AdHocManager();
+ void removeController(std::shared_ptr<AdHocController> contoller);
+ void setServerDiscoInfo(std::shared_ptr<DiscoInfo> info);
+ void setOnline(bool online);
+
+private:
+ void handleServerDiscoItemsResponse(std::shared_ptr<DiscoItems>, ErrorPayload::ref error);
+ void handleUIEvent(std::shared_ptr<UIEvent> event);
+ boost::signals2::signal<void (const AdHocController&)> onControllerComplete;
+
private:
- void handleServerDiscoItemsResponse(boost::shared_ptr<DiscoItems>, ErrorPayload::ref error);
- void handleUIEvent(boost::shared_ptr<UIEvent> event);
- boost::signal<void (const AdHocController&)> onControllerComplete;
- JID jid_;
- IQRouter* iqRouter_;
- UIEventStream* uiEventStream_;
- MainWindow* mainWindow_;
- AdHocCommandWindowFactory* factory_;
- GetDiscoItemsRequest::ref discoItemsRequest_;
- std::vector<boost::shared_ptr<AdHocController> > controllers_;
+ JID jid_;
+ IQRouter* iqRouter_;
+ UIEventStream* uiEventStream_;
+ MainWindow* mainWindow_;
+ AdHocCommandWindowFactory* factory_;
+ GetDiscoItemsRequest::ref discoItemsRequest_;
+ std::vector<std::shared_ptr<AdHocController> > controllers_;
};
}
diff --git a/Swift/Controllers/BlockListController.cpp b/Swift/Controllers/BlockListController.cpp
index be70946..37c536b 100644
--- a/Swift/Controllers/BlockListController.cpp
+++ b/Swift/Controllers/BlockListController.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -14,173 +14,172 @@
#include <boost/bind.hpp>
+#include <Swiften/Base/format.h>
#include <Swiften/Client/ClientBlockListManager.h>
-#include <Swiften/Base/foreach.h>
-#include <Swiften/Base/format.h>
#include <Swift/Controllers/Intl.h>
-#include <Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestBlockListDialogUIEvent.h>
-#include <Swift/Controllers/XMPPEvents/ErrorEvent.h>
+#include <Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h>
#include <Swift/Controllers/UIInterfaces/BlockListEditorWidget.h>
+#include <Swift/Controllers/XMPPEvents/ErrorEvent.h>
#include <Swift/Controllers/XMPPEvents/EventController.h>
namespace Swift {
-BlockListController::BlockListController(ClientBlockListManager* blockListManager, UIEventStream* uiEventStream, BlockListEditorWidgetFactory* blockListEditorWidgetFactory, EventController* eventController) : blockListManager_(blockListManager), blockListEditorWidgetFactory_(blockListEditorWidgetFactory), blockListEditorWidget_(0), eventController_(eventController), remainingRequests_(0), uiEventStream_(uiEventStream) {
- uiEventStream->onUIEvent.connect(boost::bind(&BlockListController::handleUIEvent, this, _1));
- blockListManager_->getBlockList()->onItemAdded.connect(boost::bind(&BlockListController::handleBlockListChanged, this));
- blockListManager_->getBlockList()->onItemRemoved.connect(boost::bind(&BlockListController::handleBlockListChanged, this));
+BlockListController::BlockListController(ClientBlockListManager* blockListManager, UIEventStream* uiEventStream, BlockListEditorWidgetFactory* blockListEditorWidgetFactory, EventController* eventController) : blockListManager_(blockListManager), blockListEditorWidgetFactory_(blockListEditorWidgetFactory), blockListEditorWidget_(nullptr), eventController_(eventController), remainingRequests_(0), uiEventStream_(uiEventStream) {
+ uiEventStream->onUIEvent.connect(boost::bind(&BlockListController::handleUIEvent, this, _1));
+ blockListManager_->getBlockList()->onItemAdded.connect(boost::bind(&BlockListController::handleBlockListChanged, this));
+ blockListManager_->getBlockList()->onItemRemoved.connect(boost::bind(&BlockListController::handleBlockListChanged, this));
}
BlockListController::~BlockListController() {
- uiEventStream_->onUIEvent.disconnect(boost::bind(&BlockListController::handleUIEvent, this, _1));
- blockListManager_->getBlockList()->onItemAdded.disconnect(boost::bind(&BlockListController::handleBlockListChanged, this));
- blockListManager_->getBlockList()->onItemRemoved.disconnect(boost::bind(&BlockListController::handleBlockListChanged, this));
+ uiEventStream_->onUIEvent.disconnect(boost::bind(&BlockListController::handleUIEvent, this, _1));
+ blockListManager_->getBlockList()->onItemAdded.disconnect(boost::bind(&BlockListController::handleBlockListChanged, this));
+ blockListManager_->getBlockList()->onItemRemoved.disconnect(boost::bind(&BlockListController::handleBlockListChanged, this));
}
void BlockListController::blockListDifferences(const std::vector<JID> &newBlockList, std::vector<JID> &jidsToUnblock, std::vector<JID> &jidsToBlock) const {
- foreach (const JID& jid, blockListBeforeEdit) {
- if (std::find(newBlockList.begin(), newBlockList.end(), jid) == newBlockList.end()) {
- jidsToUnblock.push_back(jid);
- }
- }
-
- foreach (const JID& jid, newBlockList) {
- if (std::find(blockListBeforeEdit.begin(), blockListBeforeEdit.end(), jid) == blockListBeforeEdit.end()) {
- jidsToBlock.push_back(jid);
- }
- }
+ for (const auto& jid : blockListBeforeEdit) {
+ if (std::find(newBlockList.begin(), newBlockList.end(), jid) == newBlockList.end()) {
+ jidsToUnblock.push_back(jid);
+ }
+ }
+
+ for (const auto& jid : newBlockList) {
+ if (std::find(blockListBeforeEdit.begin(), blockListBeforeEdit.end(), jid) == blockListBeforeEdit.end()) {
+ jidsToBlock.push_back(jid);
+ }
+ }
}
-void BlockListController::handleUIEvent(boost::shared_ptr<UIEvent> rawEvent) {
- // handle UI dialog
- boost::shared_ptr<RequestBlockListDialogUIEvent> requestDialogEvent = boost::dynamic_pointer_cast<RequestBlockListDialogUIEvent>(rawEvent);
- if (requestDialogEvent != NULL) {
- if (blockListEditorWidget_ == NULL) {
- blockListEditorWidget_ = blockListEditorWidgetFactory_->createBlockListEditorWidget();
- blockListEditorWidget_->onSetNewBlockList.connect(boost::bind(&BlockListController::handleSetNewBlockList, this, _1));
- }
- blockListBeforeEdit = blockListManager_->getBlockList()->getItems();
- blockListEditorWidget_->setCurrentBlockList(blockListBeforeEdit);
- blockListEditorWidget_->setError("");
- blockListEditorWidget_->show();
- return;
- }
-
- // handle block state change
- boost::shared_ptr<RequestChangeBlockStateUIEvent> changeStateEvent = boost::dynamic_pointer_cast<RequestChangeBlockStateUIEvent>(rawEvent);
- if (changeStateEvent != NULL) {
- if (changeStateEvent->getBlockState() == RequestChangeBlockStateUIEvent::Blocked) {
- GenericRequest<BlockPayload>::ref blockRequest = blockListManager_->createBlockJIDRequest(changeStateEvent->getContact());
- blockRequest->onResponse.connect(boost::bind(&BlockListController::handleBlockResponse, this, blockRequest, _1, _2, std::vector<JID>(1, changeStateEvent->getContact()), false));
- blockRequest->send();
- } else if (changeStateEvent->getBlockState() == RequestChangeBlockStateUIEvent::Unblocked) {
- GenericRequest<UnblockPayload>::ref unblockRequest = blockListManager_->createUnblockJIDRequest(changeStateEvent->getContact());
- unblockRequest->onResponse.connect(boost::bind(&BlockListController::handleUnblockResponse, this, unblockRequest, _1, _2, std::vector<JID>(1, changeStateEvent->getContact()), false));
- unblockRequest->send();
- }
- return;
- }
+void BlockListController::handleUIEvent(std::shared_ptr<UIEvent> rawEvent) {
+ // handle UI dialog
+ std::shared_ptr<RequestBlockListDialogUIEvent> requestDialogEvent = std::dynamic_pointer_cast<RequestBlockListDialogUIEvent>(rawEvent);
+ if (requestDialogEvent != nullptr) {
+ if (blockListEditorWidget_ == nullptr) {
+ blockListEditorWidget_ = blockListEditorWidgetFactory_->createBlockListEditorWidget();
+ blockListEditorWidget_->onSetNewBlockList.connect(boost::bind(&BlockListController::handleSetNewBlockList, this, _1));
+ }
+ blockListBeforeEdit = blockListManager_->getBlockList()->getItems();
+ blockListEditorWidget_->setCurrentBlockList(blockListBeforeEdit);
+ blockListEditorWidget_->setError("");
+ blockListEditorWidget_->show();
+ return;
+ }
+
+ // handle block state change
+ std::shared_ptr<RequestChangeBlockStateUIEvent> changeStateEvent = std::dynamic_pointer_cast<RequestChangeBlockStateUIEvent>(rawEvent);
+ if (changeStateEvent != nullptr) {
+ if (changeStateEvent->getBlockState() == RequestChangeBlockStateUIEvent::Blocked) {
+ GenericRequest<BlockPayload>::ref blockRequest = blockListManager_->createBlockJIDRequest(changeStateEvent->getContact());
+ blockRequest->onResponse.connect(boost::bind(&BlockListController::handleBlockResponse, this, blockRequest, _1, _2, std::vector<JID>(1, changeStateEvent->getContact()), false));
+ blockRequest->send();
+ } else if (changeStateEvent->getBlockState() == RequestChangeBlockStateUIEvent::Unblocked) {
+ GenericRequest<UnblockPayload>::ref unblockRequest = blockListManager_->createUnblockJIDRequest(changeStateEvent->getContact());
+ unblockRequest->onResponse.connect(boost::bind(&BlockListController::handleUnblockResponse, this, unblockRequest, _1, _2, std::vector<JID>(1, changeStateEvent->getContact()), false));
+ unblockRequest->send();
+ }
+ return;
+ }
}
-void BlockListController::handleBlockResponse(GenericRequest<BlockPayload>::ref request, boost::shared_ptr<BlockPayload>, ErrorPayload::ref error, const std::vector<JID>& jids, bool originEditor) {
- if (error) {
- std::string errorMessage;
- // FIXME: Handle reporting of list of JIDs in a translatable way.
- errorMessage = str(format(QT_TRANSLATE_NOOP("", "Failed to block %1%.")) % jids.at(0).toString());
- if (!error->getText().empty()) {
- errorMessage = str(format(QT_TRANSLATE_NOOP("", "%1%: %2%.")) % errorMessage % error->getText());
- }
- if (blockListEditorWidget_ && originEditor) {
- blockListEditorWidget_->setError(errorMessage);
- blockListEditorWidget_->setBusy(false);
- }
- else {
- eventController_->handleIncomingEvent(boost::make_shared<ErrorEvent>(request->getReceiver(), errorMessage));
- }
- }
- if (originEditor) {
- remainingRequests_--;
- if (blockListEditorWidget_ && (remainingRequests_ == 0) && !error) {
- blockListEditorWidget_->setBusy(false);
- blockListEditorWidget_->hide();
- }
- }
+void BlockListController::handleBlockResponse(GenericRequest<BlockPayload>::ref request, std::shared_ptr<BlockPayload>, ErrorPayload::ref error, const std::vector<JID>& jids, bool originEditor) {
+ if (error) {
+ std::string errorMessage;
+ // FIXME: Handle reporting of list of JIDs in a translatable way.
+ errorMessage = str(format(QT_TRANSLATE_NOOP("", "Failed to block %1%.")) % jids.at(0).toString());
+ if (!error->getText().empty()) {
+ errorMessage = str(format(QT_TRANSLATE_NOOP("", "%1%: %2%.")) % errorMessage % error->getText());
+ }
+ if (blockListEditorWidget_ && originEditor) {
+ blockListEditorWidget_->setError(errorMessage);
+ blockListEditorWidget_->setBusy(false);
+ }
+ else {
+ eventController_->handleIncomingEvent(std::make_shared<ErrorEvent>(request->getReceiver(), errorMessage));
+ }
+ }
+ if (originEditor) {
+ remainingRequests_--;
+ if (blockListEditorWidget_ && (remainingRequests_ == 0) && !error) {
+ blockListEditorWidget_->setBusy(false);
+ blockListEditorWidget_->hide();
+ }
+ }
}
-void BlockListController::handleUnblockResponse(GenericRequest<UnblockPayload>::ref request, boost::shared_ptr<UnblockPayload>, ErrorPayload::ref error, const std::vector<JID>& jids, bool originEditor) {
- if (error) {
- std::string errorMessage;
- // FIXME: Handle reporting of list of JIDs in a translatable way.
- errorMessage = str(format(QT_TRANSLATE_NOOP("", "Failed to unblock %1%.")) % jids.at(0).toString());
- if (!error->getText().empty()) {
- errorMessage = str(format(QT_TRANSLATE_NOOP("", "%1%: %2%.")) % errorMessage % error->getText());
- }
- if (blockListEditorWidget_ && originEditor) {
- blockListEditorWidget_->setError(errorMessage);
- blockListEditorWidget_->setBusy(false);
- }
- else {
- eventController_->handleIncomingEvent(boost::make_shared<ErrorEvent>(request->getReceiver(), errorMessage));
- }
- }
- if (originEditor) {
- remainingRequests_--;
- if (blockListEditorWidget_ && (remainingRequests_ == 0) && !error) {
- blockListEditorWidget_->setBusy(false);
- blockListEditorWidget_->hide();
- }
- }
+void BlockListController::handleUnblockResponse(GenericRequest<UnblockPayload>::ref request, std::shared_ptr<UnblockPayload>, ErrorPayload::ref error, const std::vector<JID>& jids, bool originEditor) {
+ if (error) {
+ std::string errorMessage;
+ // FIXME: Handle reporting of list of JIDs in a translatable way.
+ errorMessage = str(format(QT_TRANSLATE_NOOP("", "Failed to unblock %1%.")) % jids.at(0).toString());
+ if (!error->getText().empty()) {
+ errorMessage = str(format(QT_TRANSLATE_NOOP("", "%1%: %2%.")) % errorMessage % error->getText());
+ }
+ if (blockListEditorWidget_ && originEditor) {
+ blockListEditorWidget_->setError(errorMessage);
+ blockListEditorWidget_->setBusy(false);
+ }
+ else {
+ eventController_->handleIncomingEvent(std::make_shared<ErrorEvent>(request->getReceiver(), errorMessage));
+ }
+ }
+ if (originEditor) {
+ remainingRequests_--;
+ if (blockListEditorWidget_ && (remainingRequests_ == 0) && !error) {
+ blockListEditorWidget_->setBusy(false);
+ blockListEditorWidget_->hide();
+ }
+ }
}
void BlockListController::handleSetNewBlockList(const std::vector<JID> &newBlockList) {
- std::vector<JID> jidsToBlock;
- std::vector<JID> jidsToUnblock;
-
- blockListDifferences(newBlockList, jidsToUnblock, jidsToBlock);
-
- if (!jidsToBlock.empty()) {
- remainingRequests_++;
- GenericRequest<BlockPayload>::ref blockRequest = blockListManager_->createBlockJIDsRequest(jidsToBlock);
- blockRequest->onResponse.connect(boost::bind(&BlockListController::handleBlockResponse, this, blockRequest, _1, _2, jidsToBlock, true));
- blockRequest->send();
- }
- if (!jidsToUnblock.empty()) {
- remainingRequests_++;
- GenericRequest<UnblockPayload>::ref unblockRequest = blockListManager_->createUnblockJIDsRequest(jidsToUnblock);
- unblockRequest->onResponse.connect(boost::bind(&BlockListController::handleUnblockResponse, this, unblockRequest, _1, _2, jidsToUnblock, true));
- unblockRequest->send();
- }
- if (!jidsToBlock.empty() || !jidsToUnblock.empty()) {
- assert(blockListEditorWidget_);
- blockListEditorWidget_->setBusy(true);
- blockListEditorWidget_->setError("");
- } else {
- blockListEditorWidget_->hide();
- }
+ std::vector<JID> jidsToBlock;
+ std::vector<JID> jidsToUnblock;
+
+ blockListDifferences(newBlockList, jidsToUnblock, jidsToBlock);
+
+ if (!jidsToBlock.empty()) {
+ remainingRequests_++;
+ GenericRequest<BlockPayload>::ref blockRequest = blockListManager_->createBlockJIDsRequest(jidsToBlock);
+ blockRequest->onResponse.connect(boost::bind(&BlockListController::handleBlockResponse, this, blockRequest, _1, _2, jidsToBlock, true));
+ blockRequest->send();
+ }
+ if (!jidsToUnblock.empty()) {
+ remainingRequests_++;
+ GenericRequest<UnblockPayload>::ref unblockRequest = blockListManager_->createUnblockJIDsRequest(jidsToUnblock);
+ unblockRequest->onResponse.connect(boost::bind(&BlockListController::handleUnblockResponse, this, unblockRequest, _1, _2, jidsToUnblock, true));
+ unblockRequest->send();
+ }
+ if (!jidsToBlock.empty() || !jidsToUnblock.empty()) {
+ assert(blockListEditorWidget_);
+ blockListEditorWidget_->setBusy(true);
+ blockListEditorWidget_->setError("");
+ } else {
+ blockListEditorWidget_->hide();
+ }
}
void BlockListController::handleBlockListChanged() {
- if (blockListEditorWidget_) {
- std::vector<JID> jidsToBlock;
- std::vector<JID> jidsToUnblock;
+ if (blockListEditorWidget_) {
+ std::vector<JID> jidsToBlock;
+ std::vector<JID> jidsToUnblock;
- blockListDifferences(blockListEditorWidget_->getCurrentBlockList(), jidsToUnblock, jidsToBlock);
- blockListBeforeEdit = blockListManager_->getBlockList()->getItems();
+ blockListDifferences(blockListEditorWidget_->getCurrentBlockList(), jidsToUnblock, jidsToBlock);
+ blockListBeforeEdit = blockListManager_->getBlockList()->getItems();
- foreach (const JID& jid, jidsToBlock) {
- if (std::find(blockListBeforeEdit.begin(), blockListBeforeEdit.end(), jid) == blockListBeforeEdit.end()) {
- blockListBeforeEdit.push_back(jid);
- }
- }
+ for (const auto& jid : jidsToBlock) {
+ if (std::find(blockListBeforeEdit.begin(), blockListBeforeEdit.end(), jid) == blockListBeforeEdit.end()) {
+ blockListBeforeEdit.push_back(jid);
+ }
+ }
- foreach (const JID& jid, jidsToUnblock) {
- blockListBeforeEdit.erase(std::remove(blockListBeforeEdit.begin(), blockListBeforeEdit.end(), jid), blockListBeforeEdit.end());
- }
+ for (const auto& jid : jidsToUnblock) {
+ blockListBeforeEdit.erase(std::remove(blockListBeforeEdit.begin(), blockListBeforeEdit.end(), jid), blockListBeforeEdit.end());
+ }
- blockListEditorWidget_->setCurrentBlockList(blockListBeforeEdit);
- }
+ blockListEditorWidget_->setCurrentBlockList(blockListBeforeEdit);
+ }
}
}
diff --git a/Swift/Controllers/BlockListController.h b/Swift/Controllers/BlockListController.h
index 99c143c..c1f6fee 100644
--- a/Swift/Controllers/BlockListController.h
+++ b/Swift/Controllers/BlockListController.h
@@ -4,11 +4,18 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
#include <Swiften/Queries/GenericRequest.h>
+
#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <Swift/Controllers/UIInterfaces/BlockListEditorWidgetFactory.h>
@@ -21,29 +28,29 @@ class EventController;
class BlockListController {
public:
- BlockListController(ClientBlockListManager* blockListManager, UIEventStream* uiEventStream, BlockListEditorWidgetFactory* blockListEditorWidgetFactory, EventController* eventController);
- ~BlockListController();
+ BlockListController(ClientBlockListManager* blockListManager, UIEventStream* uiEventStream, BlockListEditorWidgetFactory* blockListEditorWidgetFactory, EventController* eventController);
+ ~BlockListController();
private:
- void blockListDifferences(const std::vector<JID> &newBlockList, std::vector<JID>& jidsToUnblock, std::vector<JID>& jidsToBlock) const;
+ void blockListDifferences(const std::vector<JID> &newBlockList, std::vector<JID>& jidsToUnblock, std::vector<JID>& jidsToBlock) const;
- void handleUIEvent(boost::shared_ptr<UIEvent> event);
+ void handleUIEvent(std::shared_ptr<UIEvent> event);
- void handleBlockResponse(GenericRequest<BlockPayload>::ref, boost::shared_ptr<BlockPayload>, ErrorPayload::ref error, const std::vector<JID>& jids, bool originEditor);
- void handleUnblockResponse(GenericRequest<UnblockPayload>::ref, boost::shared_ptr<UnblockPayload>, ErrorPayload::ref error, const std::vector<JID>& jids, bool originEditor);
+ void handleBlockResponse(GenericRequest<BlockPayload>::ref, std::shared_ptr<BlockPayload>, ErrorPayload::ref error, const std::vector<JID>& jids, bool originEditor);
+ void handleUnblockResponse(GenericRequest<UnblockPayload>::ref, std::shared_ptr<UnblockPayload>, ErrorPayload::ref error, const std::vector<JID>& jids, bool originEditor);
- void handleSetNewBlockList(const std::vector<JID>& newBlockList);
+ void handleSetNewBlockList(const std::vector<JID>& newBlockList);
- void handleBlockListChanged();
+ void handleBlockListChanged();
private:
- ClientBlockListManager* blockListManager_;
- BlockListEditorWidgetFactory* blockListEditorWidgetFactory_;
- BlockListEditorWidget* blockListEditorWidget_;
- EventController* eventController_;
- std::vector<JID> blockListBeforeEdit;
- int remainingRequests_;
- UIEventStream* uiEventStream_;
+ ClientBlockListManager* blockListManager_;
+ BlockListEditorWidgetFactory* blockListEditorWidgetFactory_;
+ BlockListEditorWidget* blockListEditorWidget_;
+ EventController* eventController_;
+ std::vector<JID> blockListBeforeEdit;
+ int remainingRequests_;
+ UIEventStream* uiEventStream_;
};
}
diff --git a/Swift/Controllers/CertificateMemoryStorageFactory.h b/Swift/Controllers/CertificateMemoryStorageFactory.h
index 656c8ed..080b157 100644
--- a/Swift/Controllers/CertificateMemoryStorageFactory.h
+++ b/Swift/Controllers/CertificateMemoryStorageFactory.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swift/Controllers/Storages/CertificateStorageFactory.h>
#include <Swift/Controllers/Storages/CertificateMemoryStorage.h>
+#include <Swift/Controllers/Storages/CertificateStorageFactory.h>
namespace Swift {
- class CertificateFactory;
+ class CertificateFactory;
- class CertificateMemoryStorageFactory : public CertificateStorageFactory {
- public:
- CertificateMemoryStorageFactory() {
- }
+ class CertificateMemoryStorageFactory : public CertificateStorageFactory {
+ public:
+ CertificateMemoryStorageFactory() {
+ }
- virtual CertificateStorage* createCertificateStorage(const JID&) const {
- return new CertificateMemoryStorage();
- }
+ virtual CertificateStorage* createCertificateStorage(const JID&) const {
+ return new CertificateMemoryStorage();
+ }
- private:
- boost::filesystem::path basePath;
- CertificateFactory* certificateFactory;
- };
+ private:
+ boost::filesystem::path basePath;
+ CertificateFactory* certificateFactory;
+ };
}
diff --git a/Swift/Controllers/Chat/AutoAcceptMUCInviteDecider.h b/Swift/Controllers/Chat/AutoAcceptMUCInviteDecider.h
index e49e378..646612b 100644
--- a/Swift/Controllers/Chat/AutoAcceptMUCInviteDecider.h
+++ b/Swift/Controllers/Chat/AutoAcceptMUCInviteDecider.h
@@ -5,49 +5,50 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Roster/XMPPRoster.h>
#include <Swiften/Elements/MUCInvitationPayload.h>
-#include <Swift/Controllers/Settings/SettingsProvider.h>
+#include <Swiften/Roster/XMPPRoster.h>
+
#include <Swift/Controllers/SettingConstants.h>
+#include <Swift/Controllers/Settings/SettingsProvider.h>
namespace Swift {
- class AutoAcceptMUCInviteDecider {
- public:
- AutoAcceptMUCInviteDecider(const JID& domain, XMPPRoster* roster, SettingsProvider* settings) : domain_(domain), roster_(roster), settings_(settings) {
- }
-
- bool isAutoAcceptedInvite(const JID& from, MUCInvitationPayload::ref invite) {
- if (!invite->getIsImpromptu()) {
- return false; /* always ask the user for normal MUC invites */
- }
-
- if (invite->getIsContinuation()) {
- return true;
- }
-
- std::string auto_accept_mode = settings_->getSetting(SettingConstants::INVITE_AUTO_ACCEPT_MODE);
- if (auto_accept_mode == "no") {
- return false;
- } else if (auto_accept_mode == "presence") {
- return roster_->getSubscriptionStateForJID(from) == RosterItemPayload::From || roster_->getSubscriptionStateForJID(from) == RosterItemPayload::Both;
- } else if (auto_accept_mode == "domain") {
- return roster_->getSubscriptionStateForJID(from) == RosterItemPayload::From || roster_->getSubscriptionStateForJID(from) == RosterItemPayload::Both || from.getDomain() == domain_;
- } else {
- assert(false);
- return false;
- }
- }
-
- private:
- JID domain_;
- XMPPRoster* roster_;
- SettingsProvider* settings_;
- };
+ class AutoAcceptMUCInviteDecider {
+ public:
+ AutoAcceptMUCInviteDecider(const JID& domain, XMPPRoster* roster, SettingsProvider* settings) : domain_(domain), roster_(roster), settings_(settings) {
+ }
+
+ bool isAutoAcceptedInvite(const JID& from, MUCInvitationPayload::ref invite) {
+ if (!invite->getIsImpromptu()) {
+ return false; /* always ask the user for normal MUC invites */
+ }
+
+ if (invite->getIsContinuation()) {
+ return true;
+ }
+
+ std::string auto_accept_mode = settings_->getSetting(SettingConstants::INVITE_AUTO_ACCEPT_MODE);
+ if (auto_accept_mode == "no") {
+ return false;
+ } else if (auto_accept_mode == "presence") {
+ return roster_->getSubscriptionStateForJID(from) == RosterItemPayload::From || roster_->getSubscriptionStateForJID(from) == RosterItemPayload::Both;
+ } else if (auto_accept_mode == "domain") {
+ return roster_->getSubscriptionStateForJID(from) == RosterItemPayload::From || roster_->getSubscriptionStateForJID(from) == RosterItemPayload::Both || from.getDomain() == domain_;
+ } else {
+ assert(false);
+ return false;
+ }
+ }
+
+ private:
+ JID domain_;
+ XMPPRoster* roster_;
+ SettingsProvider* settings_;
+ };
}
diff --git a/Swift/Controllers/Chat/ChatController.cpp b/Swift/Controllers/Chat/ChatController.cpp
index a80eee5..cd8fa0c 100644
--- a/Swift/Controllers/Chat/ChatController.cpp
+++ b/Swift/Controllers/Chat/ChatController.cpp
@@ -6,14 +6,13 @@
#include <Swift/Controllers/Chat/ChatController.h>
+#include <memory>
+
#include <boost/bind.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
#include <Swiften/Avatars/AvatarManager.h>
#include <Swiften/Base/Algorithm.h>
-#include <Swiften/Base/DateTime.h>
#include <Swiften/Base/Log.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Base/format.h>
#include <Swiften/Chat/ChatStateNotifier.h>
#include <Swiften/Chat/ChatStateTracker.h>
@@ -33,6 +32,7 @@
#include <Swift/Controllers/Intl.h>
#include <Swift/Controllers/SettingConstants.h>
#include <Swift/Controllers/StatusUtil.h>
+#include <Swift/Controllers/Translator.h>
#include <Swift/Controllers/UIEvents/AcceptWhiteboardSessionUIEvent.h>
#include <Swift/Controllers/UIEvents/CancelWhiteboardSessionUIEvent.h>
#include <Swift/Controllers/UIEvents/InviteToMUCUIEvent.h>
@@ -43,491 +43,509 @@
#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <Swift/Controllers/UIInterfaces/ChatWindowFactory.h>
#include <Swift/Controllers/XMPPEvents/EventController.h>
+#include <Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h>
namespace Swift {
-
+
/**
* The controller does not gain ownership of the stanzaChannel, nor the factory.
*/
-ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, bool userWantsReceipts, SettingsProvider* settings, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, boost::shared_ptr<ChatMessageParser> chatMessageParser, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider)
- : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager, useDelayForLatency, eventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry, highlightManager, chatMessageParser, autoAcceptMUCInviteDecider), eventStream_(eventStream), userWantsReceipts_(userWantsReceipts), settings_(settings), clientBlockListManager_(clientBlockListManager) {
- isInMUC_ = isInMUC;
- lastWasPresence_ = false;
- chatStateNotifier_ = new ChatStateNotifier(stanzaChannel, contact, entityCapsProvider);
- chatStateTracker_ = new ChatStateTracker();
- nickResolver_ = nickResolver;
- presenceOracle_->onPresenceChange.connect(boost::bind(&ChatController::handlePresenceChange, this, _1));
- chatStateTracker_->onChatStateChange.connect(boost::bind(&ChatWindow::setContactChatState, chatWindow_, _1));
- stanzaChannel_->onStanzaAcked.connect(boost::bind(&ChatController::handleStanzaAcked, this, _1));
- nickResolver_->onNickChanged.connect(boost::bind(&ChatController::handleContactNickChanged, this, _1, _2));
- std::string nick = nickResolver_->jidToNick(toJID_);
- chatWindow_->setName(nick);
- std::string startMessage;
- Presence::ref theirPresence;
- if (isInMUC) {
- startMessage = str(format(QT_TRANSLATE_NOOP("", "Starting chat with %1% in chatroom %2%")) % nick % contact.toBare().toString());
- theirPresence = presenceOracle->getLastPresence(contact);
- } else {
- startMessage = str(format(QT_TRANSLATE_NOOP("", "Starting chat with %1% - %2%")) % nick % contact.toBare().toString());
- theirPresence = contact.isBare() ? presenceOracle->getAccountPresence(contact) : presenceOracle->getLastPresence(contact);
- }
- Idle::ref idle;
- if (theirPresence && (idle = theirPresence->getPayload<Idle>())) {
- startMessage += str(format(QT_TRANSLATE_NOOP("", ", who has been idle since %1%")) % dateTimeToLocalString(idle->getSince()));
- }
- startMessage += ": " + statusShowTypeToFriendlyName(theirPresence ? theirPresence->getShow() : StatusShow::None);
- if (theirPresence && !theirPresence->getStatus().empty()) {
- startMessage += " (" + theirPresence->getStatus() + ")";
- }
- lastShownStatus_ = theirPresence ? theirPresence->getShow() : StatusShow::None;
- chatStateNotifier_->setContactIsOnline(theirPresence && theirPresence->getType() == Presence::Available);
- startMessage += ".";
- chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(startMessage), ChatWindow::DefaultDirection);
- chatWindow_->onUserTyping.connect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
- chatWindow_->onUserCancelsTyping.connect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_));
- chatWindow_->onFileTransferStart.connect(boost::bind(&ChatController::handleFileTransferStart, this, _1, _2));
- chatWindow_->onFileTransferAccept.connect(boost::bind(&ChatController::handleFileTransferAccept, this, _1, _2));
- chatWindow_->onFileTransferCancel.connect(boost::bind(&ChatController::handleFileTransferCancel, this, _1));
- chatWindow_->onSendFileRequest.connect(boost::bind(&ChatController::handleSendFileRequest, this, _1));
- chatWindow_->onWhiteboardSessionAccept.connect(boost::bind(&ChatController::handleWhiteboardSessionAccept, this));
- chatWindow_->onWhiteboardSessionCancel.connect(boost::bind(&ChatController::handleWhiteboardSessionCancel, this));
- chatWindow_->onWhiteboardWindowShow.connect(boost::bind(&ChatController::handleWhiteboardWindowShow, this));
- chatWindow_->onBlockUserRequest.connect(boost::bind(&ChatController::handleBlockUserRequest, this));
- chatWindow_->onUnblockUserRequest.connect(boost::bind(&ChatController::handleUnblockUserRequest, this));
- chatWindow_->onInviteToChat.connect(boost::bind(&ChatController::handleInviteToChat, this, _1));
- chatWindow_->onClosed.connect(boost::bind(&ChatController::handleWindowClosed, this));
- ChatController::handleBareJIDCapsChanged(toJID_);
-
- settings_->onSettingChanged.connect(boost::bind(&ChatController::handleSettingChanged, this, _1));
- eventStream_->onUIEvent.connect(boost::bind(&ChatController::handleUIEvent, this, _1));
+ChatController::ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, bool userWantsReceipts, SettingsProvider* settings, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, std::shared_ptr<ChatMessageParser> chatMessageParser, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider)
+ : ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, contact, presenceOracle, avatarManager, useDelayForLatency, eventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry, highlightManager, chatMessageParser, autoAcceptMUCInviteDecider), eventStream_(eventStream), userWantsReceipts_(userWantsReceipts), settings_(settings), clientBlockListManager_(clientBlockListManager) {
+ isInMUC_ = isInMUC;
+ lastWasPresence_ = false;
+ chatStateNotifier_ = new ChatStateNotifier(stanzaChannel, contact, entityCapsProvider);
+ chatStateTracker_ = new ChatStateTracker();
+ nickResolver_ = nickResolver;
+ presenceOracle_->onPresenceChange.connect(boost::bind(&ChatController::handlePresenceChange, this, _1));
+ chatStateTracker_->onChatStateChange.connect(boost::bind(&ChatWindow::setContactChatState, chatWindow_, _1));
+ stanzaChannel_->onStanzaAcked.connect(boost::bind(&ChatController::handleStanzaAcked, this, _1));
+ nickResolver_->onNickChanged.connect(boost::bind(&ChatController::handleContactNickChanged, this, _1, _2));
+ std::string nick = nickResolver_->jidToNick(toJID_);
+ chatWindow_->setName(nick);
+ std::string startMessage;
+ Presence::ref theirPresence;
+ if (isInMUC) {
+ startMessage = str(format(QT_TRANSLATE_NOOP("", "Starting chat with %1% in chatroom %2%")) % nick % contact.toBare().toString());
+ theirPresence = presenceOracle->getLastPresence(contact);
+ } else {
+ startMessage = str(format(QT_TRANSLATE_NOOP("", "Starting chat with %1% - %2%")) % nick % contact.toBare().toString());
+ theirPresence = contact.isBare() ? presenceOracle->getAccountPresence(contact) : presenceOracle->getLastPresence(contact);
+ }
+ Idle::ref idle;
+ if (theirPresence && (idle = theirPresence->getPayload<Idle>())) {
+ startMessage += str(format(QT_TRANSLATE_NOOP("", ", who has been idle since %1%")) % Swift::Translator::getInstance()->ptimeToHumanReadableString(idle->getSince()));
+ }
+ startMessage += ": " + statusShowTypeToFriendlyName(theirPresence ? theirPresence->getShow() : StatusShow::None);
+ if (theirPresence && !theirPresence->getStatus().empty()) {
+ startMessage += " (" + theirPresence->getStatus() + ")";
+ }
+ lastShownStatus_ = theirPresence ? theirPresence->getShow() : StatusShow::None;
+ chatStateNotifier_->setContactIsOnline(theirPresence && theirPresence->getType() == Presence::Available);
+ startMessage += ".";
+ chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(startMessage), ChatWindow::DefaultDirection);
+ chatWindow_->onUserTyping.connect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
+ chatWindow_->onUserCancelsTyping.connect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_));
+ chatWindow_->onFileTransferStart.connect(boost::bind(&ChatController::handleFileTransferStart, this, _1, _2));
+ chatWindow_->onFileTransferAccept.connect(boost::bind(&ChatController::handleFileTransferAccept, this, _1, _2));
+ chatWindow_->onFileTransferCancel.connect(boost::bind(&ChatController::handleFileTransferCancel, this, _1));
+ chatWindow_->onSendFileRequest.connect(boost::bind(&ChatController::handleSendFileRequest, this, _1));
+ chatWindow_->onWhiteboardSessionAccept.connect(boost::bind(&ChatController::handleWhiteboardSessionAccept, this));
+ chatWindow_->onWhiteboardSessionCancel.connect(boost::bind(&ChatController::handleWhiteboardSessionCancel, this));
+ chatWindow_->onWhiteboardWindowShow.connect(boost::bind(&ChatController::handleWhiteboardWindowShow, this));
+ chatWindow_->onBlockUserRequest.connect(boost::bind(&ChatController::handleBlockUserRequest, this));
+ chatWindow_->onUnblockUserRequest.connect(boost::bind(&ChatController::handleUnblockUserRequest, this));
+ chatWindow_->onInviteToChat.connect(boost::bind(&ChatController::handleInviteToChat, this, _1));
+ chatWindow_->onClosed.connect(boost::bind(&ChatController::handleWindowClosed, this));
+ ChatController::handleBareJIDCapsChanged(toJID_);
+
+ settings_->onSettingChanged.connect(boost::bind(&ChatController::handleSettingChanged, this, _1));
+ eventStream_->onUIEvent.connect(boost::bind(&ChatController::handleUIEvent, this, _1));
}
void ChatController::handleContactNickChanged(const JID& jid, const std::string& /*oldNick*/) {
- if (jid.toBare() == toJID_.toBare()) {
- chatWindow_->setName(nickResolver_->jidToNick(toJID_));
- }
+ if (jid.toBare() == toJID_.toBare()) {
+ chatWindow_->setName(nickResolver_->jidToNick(toJID_));
+ }
}
ChatController::~ChatController() {
- eventStream_->onUIEvent.disconnect(boost::bind(&ChatController::handleUIEvent, this, _1));
- settings_->onSettingChanged.disconnect(boost::bind(&ChatController::handleSettingChanged, this, _1));
- nickResolver_->onNickChanged.disconnect(boost::bind(&ChatController::handleContactNickChanged, this, _1, _2));
- delete chatStateNotifier_;
- delete chatStateTracker_;
+ eventStream_->onUIEvent.disconnect(boost::bind(&ChatController::handleUIEvent, this, _1));
+ settings_->onSettingChanged.disconnect(boost::bind(&ChatController::handleSettingChanged, this, _1));
+ nickResolver_->onNickChanged.disconnect(boost::bind(&ChatController::handleContactNickChanged, this, _1, _2));
+ delete chatStateNotifier_;
+ delete chatStateTracker_;
}
JID ChatController::getBaseJID() {
- return isInMUC_ ? toJID_ : ChatControllerBase::getBaseJID();
+ return isInMUC_ ? toJID_ : ChatControllerBase::getBaseJID();
}
void ChatController::cancelReplaces() {
- lastWasPresence_ = false;
+ lastWasPresence_ = false;
}
void ChatController::handleBareJIDCapsChanged(const JID& /*jid*/) {
- FeatureOracle featureOracle(entityCapsProvider_, presenceOracle_);
+ FeatureOracle featureOracle(entityCapsProvider_, presenceOracle_);
- chatWindow_->setCorrectionEnabled(featureOracle.isMessageCorrectionSupported(toJID_));
- chatWindow_->setFileTransferEnabled(isInMUC_ ? No : featureOracle.isFileTransferSupported(toJID_));
- contactSupportsReceipts_ = featureOracle.isMessageReceiptsSupported(toJID_);
+ chatWindow_->setCorrectionEnabled(featureOracle.isMessageCorrectionSupported(toJID_));
+ chatWindow_->setFileTransferEnabled(isInMUC_ ? No : featureOracle.isFileTransferSupported(toJID_));
+ contactSupportsReceipts_ = featureOracle.isMessageReceiptsSupported(toJID_);
- checkForDisplayingDisplayReceiptsAlert();
+ checkForDisplayingDisplayReceiptsAlert();
}
void ChatController::setToJID(const JID& jid) {
- chatStateNotifier_->setContact(jid);
- ChatControllerBase::setToJID(jid);
- Presence::ref presence;
- if (isInMUC_) {
- presence = presenceOracle_->getLastPresence(jid);
- } else {
- presence = jid.isBare() ? presenceOracle_->getAccountPresence(jid.toBare()) : presenceOracle_->getLastPresence(jid);
- }
- chatStateNotifier_->setContactIsOnline(presence && presence->getType() == Presence::Available);
- handleBareJIDCapsChanged(toJID_);
-}
-
-void ChatController::setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) {
- ChatControllerBase::setAvailableServerFeatures(info);
- if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::BlockingCommandFeature)) {
- boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList();
-
- blockingOnStateChangedConnection_ = blockList->onStateChanged.connect(boost::bind(&ChatController::handleBlockingStateChanged, this));
- blockingOnItemAddedConnection_ = blockList->onItemAdded.connect(boost::bind(&ChatController::handleBlockingStateChanged, this));
- blockingOnItemRemovedConnection_ = blockList->onItemRemoved.connect(boost::bind(&ChatController::handleBlockingStateChanged, this));
-
- handleBlockingStateChanged();
- }
-}
-
-bool ChatController::isIncomingMessageFromMe(boost::shared_ptr<Message>) {
- return false;
-}
-
-void ChatController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) {
- if (messageEvent->isReadable()) {
- chatWindow_->flash();
- lastWasPresence_ = false;
- }
- boost::shared_ptr<Message> message = messageEvent->getStanza();
- JID from = message->getFrom();
- if (!from.equals(toJID_, JID::WithResource)) {
- if (toJID_.equals(from, JID::WithoutResource) && toJID_.isBare()){
- // Bind controller to a full JID if message contains body text or is a typing chat state.
- ChatState::ref chatState = message->getPayload<ChatState>();
- if (!message->getBody().get_value_or("").empty() || (chatState && chatState->getChatState() == ChatState::Composing)) {
- setToJID(from);
- }
- }
- }
- chatStateTracker_->handleMessageReceived(message);
- chatStateNotifier_->receivedMessageFromContact(!!message->getPayload<ChatState>());
-
- // handle XEP-0184 Message Receipts
- // incomming receipts
- if (boost::shared_ptr<DeliveryReceipt> receipt = message->getPayload<DeliveryReceipt>()) {
- SWIFT_LOG(debug) << "received receipt for id: " << receipt->getReceivedID() << std::endl;
- if (requestedReceipts_.find(receipt->getReceivedID()) != requestedReceipts_.end()) {
- chatWindow_->setMessageReceiptState(requestedReceipts_[receipt->getReceivedID()], ChatWindow::ReceiptReceived);
- requestedReceipts_.erase(receipt->getReceivedID());
- }
- // incomming errors in response to send out receipts
- } else if (message->getPayload<DeliveryReceiptRequest>() && (message->getType() == Message::Error)) {
- if (requestedReceipts_.find(message->getID()) != requestedReceipts_.end()) {
- chatWindow_->setMessageReceiptState(requestedReceipts_[message->getID()], ChatWindow::ReceiptFailed);
- requestedReceipts_.erase(message->getID());
- }
- // incoming receipt requests
- } else if (message->getPayload<DeliveryReceiptRequest>()) {
- if (receivingPresenceFromUs_) {
- boost::shared_ptr<Message> receiptMessage = boost::make_shared<Message>();
- receiptMessage->setTo(toJID_);
- receiptMessage->addPayload(boost::make_shared<DeliveryReceipt>(message->getID()));
- stanzaChannel_->sendMessage(receiptMessage);
- }
- }
-}
-
-void ChatController::postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent, const HighlightAction& highlight) {
- eventController_->handleIncomingEvent(messageEvent);
- if (!messageEvent->getConcluded()) {
- highlighter_->handleHighlightAction(highlight);
- }
-}
-
-
-void ChatController::preSendMessageRequest(boost::shared_ptr<Message> message) {
- chatStateNotifier_->addChatStateRequest(message);
- if (userWantsReceipts_ && (contactSupportsReceipts_ != No) && message) {
- message->addPayload(boost::make_shared<DeliveryReceiptRequest>());
- }
+ chatStateNotifier_->setContact(jid);
+ ChatControllerBase::setToJID(jid);
+ Presence::ref presence;
+ if (isInMUC_) {
+ presence = presenceOracle_->getLastPresence(jid);
+ } else {
+ presence = jid.isBare() ? presenceOracle_->getAccountPresence(jid.toBare()) : presenceOracle_->getLastPresence(jid);
+ }
+ chatStateNotifier_->setContactIsOnline(presence && presence->getType() == Presence::Available);
+ handleBareJIDCapsChanged(toJID_);
+}
+
+void ChatController::setAvailableServerFeatures(std::shared_ptr<DiscoInfo> info) {
+ ChatControllerBase::setAvailableServerFeatures(info);
+ if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::BlockingCommandFeature)) {
+ std::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList();
+
+ blockingOnStateChangedConnection_ = blockList->onStateChanged.connect(boost::bind(&ChatController::handleBlockingStateChanged, this));
+ blockingOnItemAddedConnection_ = blockList->onItemAdded.connect(boost::bind(&ChatController::handleBlockingStateChanged, this));
+ blockingOnItemRemovedConnection_ = blockList->onItemRemoved.connect(boost::bind(&ChatController::handleBlockingStateChanged, this));
+
+ handleBlockingStateChanged();
+ }
+}
+
+bool ChatController::isIncomingMessageFromMe(std::shared_ptr<Message>) {
+ return false;
+}
+
+void ChatController::preHandleIncomingMessage(std::shared_ptr<MessageEvent> messageEvent) {
+ if (messageEvent->isReadable()) {
+ chatWindow_->flash();
+ lastWasPresence_ = false;
+ }
+ std::shared_ptr<Message> message = messageEvent->getStanza();
+ JID from = message->getFrom();
+ if (!from.equals(toJID_, JID::WithResource)) {
+ if (toJID_.equals(from, JID::WithoutResource) && toJID_.isBare()){
+ // Bind controller to a full JID if message contains body text or is a typing chat state.
+ ChatState::ref chatState = message->getPayload<ChatState>();
+ if (!message->getBody().get_value_or("").empty() || (chatState && chatState->getChatState() == ChatState::Composing)) {
+ setToJID(from);
+ }
+ }
+ }
+ chatStateTracker_->handleMessageReceived(message);
+ chatStateNotifier_->receivedMessageFromContact(!!message->getPayload<ChatState>());
+
+ // handle XEP-0184 Message Receipts
+ // incomming receipts
+ if (std::shared_ptr<DeliveryReceipt> receipt = message->getPayload<DeliveryReceipt>()) {
+ SWIFT_LOG(debug) << "received receipt for id: " << receipt->getReceivedID() << std::endl;
+ if (requestedReceipts_.find(receipt->getReceivedID()) != requestedReceipts_.end()) {
+ chatWindow_->setMessageReceiptState(requestedReceipts_[receipt->getReceivedID()], ChatWindow::ReceiptReceived);
+ requestedReceipts_.erase(receipt->getReceivedID());
+ }
+ // incomming errors in response to send out receipts
+ } else if (message->getPayload<DeliveryReceiptRequest>() && (message->getType() == Message::Error)) {
+ if (requestedReceipts_.find(message->getID()) != requestedReceipts_.end()) {
+ chatWindow_->setMessageReceiptState(requestedReceipts_[message->getID()], ChatWindow::ReceiptFailed);
+ requestedReceipts_.erase(message->getID());
+ }
+ // incoming receipt requests
+ } else if (message->getPayload<DeliveryReceiptRequest>()) {
+ if (receivingPresenceFromUs_) {
+ std::shared_ptr<Message> receiptMessage = std::make_shared<Message>();
+ receiptMessage->setTo(toJID_);
+ receiptMessage->addPayload(std::make_shared<DeliveryReceipt>(message->getID()));
+ stanzaChannel_->sendMessage(receiptMessage);
+ }
+ }
+}
+
+void ChatController::postHandleIncomingMessage(std::shared_ptr<MessageEvent> messageEvent, const ChatWindow::ChatMessage& chatMessage) {
+ eventController_->handleIncomingEvent(messageEvent);
+ if (!messageEvent->getConcluded()) {
+ handleHighlightActions(chatMessage);
+ }
+}
+
+
+void ChatController::preSendMessageRequest(std::shared_ptr<Message> message) {
+ chatStateNotifier_->addChatStateRequest(message);
+ if (userWantsReceipts_ && (contactSupportsReceipts_ != No) && message) {
+ message->addPayload(std::make_shared<DeliveryReceiptRequest>());
+ }
}
void ChatController::setContactIsReceivingPresence(bool isReceivingPresence) {
- receivingPresenceFromUs_ = isReceivingPresence;
+ receivingPresenceFromUs_ = isReceivingPresence;
}
void ChatController::handleSettingChanged(const std::string& settingPath) {
- if (settingPath == SettingConstants::REQUEST_DELIVERYRECEIPTS.getKey()) {
- userWantsReceipts_ = settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS);
- checkForDisplayingDisplayReceiptsAlert();
- }
+ if (settingPath == SettingConstants::REQUEST_DELIVERYRECEIPTS.getKey()) {
+ userWantsReceipts_ = settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS);
+ checkForDisplayingDisplayReceiptsAlert();
+ }
}
void ChatController::checkForDisplayingDisplayReceiptsAlert() {
- boost::optional<ChatWindow::AlertID> newDeliverReceiptAlert;
- if (userWantsReceipts_ && (contactSupportsReceipts_ == No)) {
- newDeliverReceiptAlert = chatWindow_->addAlert(QT_TRANSLATE_NOOP("", "This chat doesn't support delivery receipts."));
- } else if (userWantsReceipts_ && (contactSupportsReceipts_ == Maybe)) {
- newDeliverReceiptAlert = chatWindow_->addAlert(QT_TRANSLATE_NOOP("", "This chat may not support delivery receipts. You might not receive delivery receipts for the messages you send."));
- } else {
- if (deliveryReceiptAlert_) {
- chatWindow_->removeAlert(*deliveryReceiptAlert_);
- deliveryReceiptAlert_.reset();
- }
- }
- if (newDeliverReceiptAlert) {
- if (deliveryReceiptAlert_) {
- chatWindow_->removeAlert(*deliveryReceiptAlert_);
- }
- deliveryReceiptAlert_ = newDeliverReceiptAlert;
- }
+ boost::optional<ChatWindow::AlertID> newDeliverReceiptAlert;
+ if (userWantsReceipts_ && (contactSupportsReceipts_ == No)) {
+ newDeliverReceiptAlert = chatWindow_->addAlert(QT_TRANSLATE_NOOP("", "This chat doesn't support delivery receipts."));
+ } else if (userWantsReceipts_ && (contactSupportsReceipts_ == Maybe)) {
+ newDeliverReceiptAlert = chatWindow_->addAlert(QT_TRANSLATE_NOOP("", "This chat may not support delivery receipts. You might not receive delivery receipts for the messages you send."));
+ } else {
+ if (deliveryReceiptAlert_) {
+ chatWindow_->removeAlert(*deliveryReceiptAlert_);
+ deliveryReceiptAlert_.reset();
+ }
+ }
+ if (newDeliverReceiptAlert) {
+ if (deliveryReceiptAlert_) {
+ chatWindow_->removeAlert(*deliveryReceiptAlert_);
+ }
+ deliveryReceiptAlert_ = newDeliverReceiptAlert;
+ }
}
void ChatController::handleBlockingStateChanged() {
- boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList();
- if (blockList->getState() == BlockList::Available) {
- if (isInMUC_ ? blockList->isBlocked(toJID_) : blockList->isBlocked(toJID_.toBare())) {
- if (!blockedContactAlert_) {
- blockedContactAlert_ = chatWindow_->addAlert(QT_TRANSLATE_NOOP("", "You've currently blocked this contact. To continue your conversation you have to unblock the contact first."));
- }
- chatWindow_->setBlockingState(ChatWindow::IsBlocked);
-
- // disconnect typing events to prevent chat state notifciations to blocked contacts
- chatWindow_->onUserTyping.disconnect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
- chatWindow_->onUserCancelsTyping.disconnect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_));
- } else {
- if (blockedContactAlert_) {
- chatWindow_->removeAlert(*blockedContactAlert_);
- blockedContactAlert_.reset();
- }
- chatWindow_->setBlockingState(ChatWindow::IsUnblocked);
-
- chatWindow_->onUserTyping.connect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
- chatWindow_->onUserCancelsTyping.connect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_));
- }
- }
+ std::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList();
+ if (blockList->getState() == BlockList::Available) {
+ if (isInMUC_ ? blockList->isBlocked(toJID_) : blockList->isBlocked(toJID_.toBare())) {
+ if (!blockedContactAlert_) {
+ blockedContactAlert_ = chatWindow_->addAlert(QT_TRANSLATE_NOOP("", "You've currently blocked this contact. To continue your conversation you have to unblock the contact first."));
+ }
+ chatWindow_->setBlockingState(ChatWindow::IsBlocked);
+
+ // disconnect typing events to prevent chat state notifciations to blocked contacts
+ chatWindow_->onUserTyping.disconnect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
+ chatWindow_->onUserCancelsTyping.disconnect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_));
+ } else {
+ if (blockedContactAlert_) {
+ chatWindow_->removeAlert(*blockedContactAlert_);
+ blockedContactAlert_.reset();
+ }
+ chatWindow_->setBlockingState(ChatWindow::IsUnblocked);
+
+ chatWindow_->onUserTyping.connect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
+ chatWindow_->onUserCancelsTyping.connect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_));
+ }
+ }
}
void ChatController::handleBlockUserRequest() {
- if (isInMUC_) {
- eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Blocked, toJID_));
- } else {
- eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Blocked, toJID_.toBare()));
- }
+ if (isInMUC_) {
+ eventStream_->send(std::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Blocked, toJID_));
+ } else {
+ eventStream_->send(std::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Blocked, toJID_.toBare()));
+ }
}
void ChatController::handleUnblockUserRequest() {
- if (isInMUC_) {
- eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Unblocked, toJID_));
- } else {
- eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Unblocked, toJID_.toBare()));
- }
+ if (isInMUC_) {
+ eventStream_->send(std::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Unblocked, toJID_));
+ } else {
+ eventStream_->send(std::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Unblocked, toJID_.toBare()));
+ }
}
void ChatController::handleInviteToChat(const std::vector<JID>& droppedJIDs) {
- boost::shared_ptr<UIEvent> event(new RequestInviteToMUCUIEvent(toJID_.toBare(), droppedJIDs, RequestInviteToMUCUIEvent::Impromptu));
- eventStream_->send(event);
+ std::shared_ptr<UIEvent> event(new RequestInviteToMUCUIEvent(getToJID(), droppedJIDs, RequestInviteToMUCUIEvent::Impromptu));
+ eventStream_->send(event);
}
void ChatController::handleWindowClosed() {
- onWindowClosed();
+ onWindowClosed();
}
-void ChatController::handleUIEvent(boost::shared_ptr<UIEvent> event) {
- boost::shared_ptr<InviteToMUCUIEvent> inviteEvent = boost::dynamic_pointer_cast<InviteToMUCUIEvent>(event);
- if (inviteEvent && inviteEvent->getRoom() == toJID_.toBare()) {
- onConvertToMUC(detachChatWindow(), inviteEvent->getInvites(), inviteEvent->getReason());
- }
+void ChatController::handleUIEvent(std::shared_ptr<UIEvent> event) {
+ std::shared_ptr<InviteToMUCUIEvent> inviteEvent = std::dynamic_pointer_cast<InviteToMUCUIEvent>(event);
+ if (inviteEvent && inviteEvent->getOriginator() == getToJID()) {
+ onConvertToMUC(detachChatWindow(), inviteEvent->getInvites(), inviteEvent->getReason());
+ }
}
+void ChatController::handleIncomingOwnMessage(std::shared_ptr<Message> message) {
+ if (!message->getBody().get_value_or("").empty()) {
+ postSendMessage(message->getBody().get_value_or(""), message);
+ handleStanzaAcked(message);
+ }
+}
-void ChatController::postSendMessage(const std::string& body, boost::shared_ptr<Stanza> sentStanza) {
- boost::shared_ptr<Replace> replace = sentStanza->getPayload<Replace>();
- if (replace) {
- eraseIf(unackedStanzas_, PairSecondEquals<boost::shared_ptr<Stanza>, std::string>(myLastMessageUIID_));
- replaceMessage(body, myLastMessageUIID_, true, boost::posix_time::microsec_clock::universal_time(), HighlightAction());
- } else {
- myLastMessageUIID_ = addMessage(body, QT_TRANSLATE_NOOP("", "me"), true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel().getLabel() : boost::shared_ptr<SecurityLabel>(), avatarManager_->getAvatarPath(selfJID_), boost::posix_time::microsec_clock::universal_time(), HighlightAction());
- }
+void ChatController::postSendMessage(const std::string& body, std::shared_ptr<Stanza> sentStanza) {
+ std::shared_ptr<Replace> replace = sentStanza->getPayload<Replace>();
+ if (replace) {
+ eraseIf(unackedStanzas_, PairSecondEquals<std::shared_ptr<Stanza>, std::string>(myLastMessageUIID_));
+ replaceMessage(chatMessageParser_->parseMessageBody(body, "", true), myLastMessageUIID_, boost::posix_time::microsec_clock::universal_time());
+ } else {
+ myLastMessageUIID_ = addMessage(chatMessageParser_->parseMessageBody(body, "", true), QT_TRANSLATE_NOOP("", "me"), true, labelsEnabled_ ? chatWindow_->getSelectedSecurityLabel().getLabel() : std::shared_ptr<SecurityLabel>(), avatarManager_->getAvatarPath(selfJID_), boost::posix_time::microsec_clock::universal_time());
+ }
- if (stanzaChannel_->getStreamManagementEnabled() && !myLastMessageUIID_.empty() ) {
- chatWindow_->setAckState(myLastMessageUIID_, ChatWindow::Pending);
- unackedStanzas_[sentStanza] = myLastMessageUIID_;
- }
+ if (stanzaChannel_->getStreamManagementEnabled() && !myLastMessageUIID_.empty() ) {
+ chatWindow_->setAckState(myLastMessageUIID_, ChatWindow::Pending);
+ unackedStanzas_[sentStanza] = myLastMessageUIID_;
+ }
- if (sentStanza->getPayload<DeliveryReceiptRequest>()) {
- requestedReceipts_[sentStanza->getID()] = myLastMessageUIID_;
- chatWindow_->setMessageReceiptState(myLastMessageUIID_, ChatWindow::ReceiptRequested);
- }
+ if (sentStanza->getPayload<DeliveryReceiptRequest>()) {
+ requestedReceipts_[sentStanza->getID()] = myLastMessageUIID_;
+ chatWindow_->setMessageReceiptState(myLastMessageUIID_, ChatWindow::ReceiptRequested);
+ }
- lastWasPresence_ = false;
- chatStateNotifier_->userSentMessage();
+ lastWasPresence_ = false;
+ chatStateNotifier_->userSentMessage();
}
-void ChatController::handleStanzaAcked(boost::shared_ptr<Stanza> stanza) {
- std::map<boost::shared_ptr<Stanza>, std::string>::iterator unackedStanza = unackedStanzas_.find(stanza);
- if (unackedStanza != unackedStanzas_.end()) {
- chatWindow_->setAckState(unackedStanza->second, ChatWindow::Received);
- unackedStanzas_.erase(unackedStanza);
- }
+void ChatController::handleStanzaAcked(std::shared_ptr<Stanza> stanza) {
+ std::map<std::shared_ptr<Stanza>, std::string>::iterator unackedStanza = unackedStanzas_.find(stanza);
+ if (unackedStanza != unackedStanzas_.end()) {
+ chatWindow_->setAckState(unackedStanza->second, ChatWindow::Received);
+ unackedStanzas_.erase(unackedStanza);
+ }
}
void ChatController::setOnline(bool online) {
- if (!online) {
- std::map<boost::shared_ptr<Stanza>, std::string>::iterator it = unackedStanzas_.begin();
- for ( ; it != unackedStanzas_.end(); ++it) {
- chatWindow_->setAckState(it->second, ChatWindow::Failed);
- }
- unackedStanzas_.clear();
+ if (!online) {
+ for (auto& stanzaIdPair : unackedStanzas_) {
+ chatWindow_->setAckState(stanzaIdPair.second, ChatWindow::Failed);
+ }
+ unackedStanzas_.clear();
- Presence::ref fakeOffline(new Presence());
- fakeOffline->setFrom(toJID_);
- fakeOffline->setType(Presence::Unavailable);
- chatStateTracker_->handlePresenceChange(fakeOffline);
- }
- ChatControllerBase::setOnline(online);
+ Presence::ref fakeOffline(new Presence());
+ fakeOffline->setFrom(toJID_);
+ fakeOffline->setType(Presence::Unavailable);
+ chatStateTracker_->handlePresenceChange(fakeOffline);
+ }
+ ChatControllerBase::setOnline(online);
}
void ChatController::handleNewFileTransferController(FileTransferController* ftc) {
- std::string nick = senderDisplayNameFromMessage(ftc->getOtherParty());
- std::string ftID = ftc->setChatWindow(chatWindow_, nick);
- ftControllers[ftID] = ftc;
- lastWasPresence_ = false;
+ std::string nick = senderDisplayNameFromMessage(ftc->getOtherParty());
+ std::string ftID = ftc->setChatWindow(chatWindow_, nick);
+ ftControllers[ftID] = ftc;
+ lastWasPresence_ = false;
+
+ if (ftc->isIncoming()) {
+ auto incomingFileTransferEvent = std::make_shared<IncomingFileTransferEvent>(ftc->getOtherParty());
+ if (hasOpenWindow()) {
+ incomingFileTransferEvent->conclude();
+ }
+ else {
+ unreadMessages_.push_back(incomingFileTransferEvent);
+ updateMessageCount();
+ }
+ eventController_->handleIncomingEvent(incomingFileTransferEvent);
+ }
}
void ChatController::handleWhiteboardSessionRequest(bool senderIsSelf) {
- lastWbID_ = chatWindow_->addWhiteboardRequest(senderIsSelf);
+ lastWbID_ = chatWindow_->addWhiteboardRequest(senderIsSelf);
}
void ChatController::handleWhiteboardStateChange(const ChatWindow::WhiteboardSessionState state) {
- chatWindow_->setWhiteboardSessionStatus(lastWbID_, state);
+ chatWindow_->setWhiteboardSessionStatus(lastWbID_, state);
}
void ChatController::handleFileTransferCancel(std::string id) {
- SWIFT_LOG(debug) << "handleFileTransferCancel(" << id << ")" << std::endl;
- if (ftControllers.find(id) != ftControllers.end()) {
- ftControllers[id]->cancel();
- } else {
- std::cerr << "unknown file transfer UI id" << std::endl;
- }
+ SWIFT_LOG(debug) << "handleFileTransferCancel(" << id << ")" << std::endl;
+ if (ftControllers.find(id) != ftControllers.end()) {
+ ftControllers[id]->cancel();
+ } else {
+ std::cerr << "unknown file transfer UI id" << std::endl;
+ }
}
void ChatController::handleFileTransferStart(std::string id, std::string description) {
- SWIFT_LOG(debug) << "handleFileTransferStart(" << id << ", " << description << ")" << std::endl;
- if (ftControllers.find(id) != ftControllers.end()) {
- ftControllers[id]->start(description);
- } else {
- std::cerr << "unknown file transfer UI id" << std::endl;
- }
+ SWIFT_LOG(debug) << "handleFileTransferStart(" << id << ", " << description << ")" << std::endl;
+ if (ftControllers.find(id) != ftControllers.end()) {
+ ftControllers[id]->start(description);
+ } else {
+ std::cerr << "unknown file transfer UI id" << std::endl;
+ }
}
void ChatController::handleFileTransferAccept(std::string id, std::string filename) {
- SWIFT_LOG(debug) << "handleFileTransferAccept(" << id << ", " << filename << ")" << std::endl;
- if (ftControllers.find(id) != ftControllers.end()) {
- ftControllers[id]->accept(filename);
- } else {
- std::cerr << "unknown file transfer UI id" << std::endl;
- }
+ SWIFT_LOG(debug) << "handleFileTransferAccept(" << id << ", " << filename << ")" << std::endl;
+ if (ftControllers.find(id) != ftControllers.end()) {
+ ftControllers[id]->accept(filename);
+ } else {
+ std::cerr << "unknown file transfer UI id" << std::endl;
+ }
}
void ChatController::handleSendFileRequest(std::string filename) {
- SWIFT_LOG(debug) << "ChatController::handleSendFileRequest(" << filename << ")" << std::endl;
- eventStream_->send(boost::make_shared<SendFileUIEvent>(getToJID(), filename));
+ SWIFT_LOG(debug) << "ChatController::handleSendFileRequest(" << filename << ")" << std::endl;
+ eventStream_->send(std::make_shared<SendFileUIEvent>(getToJID(), filename));
}
void ChatController::handleWhiteboardSessionAccept() {
- eventStream_->send(boost::make_shared<AcceptWhiteboardSessionUIEvent>(toJID_));
+ eventStream_->send(std::make_shared<AcceptWhiteboardSessionUIEvent>(toJID_));
}
void ChatController::handleWhiteboardSessionCancel() {
- eventStream_->send(boost::make_shared<CancelWhiteboardSessionUIEvent>(toJID_));
+ eventStream_->send(std::make_shared<CancelWhiteboardSessionUIEvent>(toJID_));
}
void ChatController::handleWhiteboardWindowShow() {
- eventStream_->send(boost::make_shared<ShowWhiteboardUIEvent>(toJID_));
+ eventStream_->send(std::make_shared<ShowWhiteboardUIEvent>(toJID_));
}
std::string ChatController::senderHighlightNameFromMessage(const JID& from) {
- if (isInMUC_) {
- return nickResolver_->jidToNick(from);
- }
- else {
- return from.toBare().toString();
- }
+ if (isInMUC_) {
+ return nickResolver_->jidToNick(from);
+ }
+ else {
+ return from.toBare().toString();
+ }
}
std::string ChatController::senderDisplayNameFromMessage(const JID& from) {
- return nickResolver_->jidToNick(from);
-}
-
-std::string ChatController::getStatusChangeString(boost::shared_ptr<Presence> presence) {
- std::string nick = senderDisplayNameFromMessage(presence->getFrom());
- std::string response;
- if (!presence || presence->getType() == Presence::Unavailable || presence->getType() == Presence::Error) {
- response = QT_TRANSLATE_NOOP("", "%1% has gone offline");
- } else if (presence->getType() == Presence::Available) {
- StatusShow::Type show = presence->getShow();
- if (show == StatusShow::Online || show == StatusShow::FFC) {
- response = QT_TRANSLATE_NOOP("", "%1% has become available");
- } else if (show == StatusShow::Away || show == StatusShow::XA) {
- response = QT_TRANSLATE_NOOP("", "%1% has gone away");
- } else if (show == StatusShow::DND) {
- response = QT_TRANSLATE_NOOP("", "%1% is now busy");
- }
- }
- Idle::ref idle;
- if ((idle = presence->getPayload<Idle>())) {
- response += str(format(QT_TRANSLATE_NOOP("", " and has been idle since %1%")) % dateTimeToLocalString(idle->getSince()));
- }
-
- if (!response.empty()) {
- response = str(format(response) % nick);
- }
-
- if (!presence->getStatus().empty()) {
- response += " (" + presence->getStatus() + ")";
- }
- return response + ".";
-}
-
-void ChatController::handlePresenceChange(boost::shared_ptr<Presence> newPresence) {
- bool relevantPresence = false;
-
- if (isInMUC_) {
- // For MUC participants we only have a single presence to choose one and
- // even for multi-session nicknames multiple resources are not distinguishable
- // to other participants.
- if (toJID_.equals(newPresence->getFrom(), JID::WithResource)) {
- relevantPresence = true;
- }
- }
- else {
- // For standard chats we retrieve the account presence from the PresenceOracle,
- // as there can be multiple presences to choose from.
- if (toJID_.equals(newPresence->getFrom(), JID::WithoutResource)) {
- // Presence matches ChatController JID.
- newPresence = presenceOracle_->getAccountPresence(toJID_);
- relevantPresence = true;
- }
- }
-
- if (!relevantPresence) {
- return;
- }
-
- if (!newPresence) {
- newPresence = boost::make_shared<Presence>();
- newPresence->setType(Presence::Unavailable);
- }
- lastShownStatus_ = newPresence->getShow();
-
- chatStateTracker_->handlePresenceChange(newPresence);
- chatStateNotifier_->setContactIsOnline(newPresence->getType() == Presence::Available);
- std::string newStatusChangeString = getStatusChangeString(newPresence);
- if (newStatusChangeString != lastStatusChangeString_) {
- if (lastWasPresence_) {
- chatWindow_->replaceLastMessage(chatMessageParser_->parseMessageBody(newStatusChangeString), ChatWindow::UpdateTimestamp);
- } else {
- chatWindow_->addPresenceMessage(chatMessageParser_->parseMessageBody(newStatusChangeString), ChatWindow::DefaultDirection);
- }
- lastStatusChangeString_ = newStatusChangeString;
- lastWasPresence_ = true;
- }
-}
-
-boost::optional<boost::posix_time::ptime> ChatController::getMessageTimestamp(boost::shared_ptr<Message> message) const {
- return message->getTimestamp();
+ return nickResolver_->jidToNick(from);
+}
+
+std::string ChatController::getStatusChangeString(std::shared_ptr<Presence> presence) {
+ std::string nick = senderDisplayNameFromMessage(presence->getFrom());
+ std::string response;
+ if (!presence || presence->getType() == Presence::Unavailable || presence->getType() == Presence::Error) {
+ response = QT_TRANSLATE_NOOP("", "%1% has gone offline");
+ } else if (presence->getType() == Presence::Available) {
+ StatusShow::Type show = presence->getShow();
+ if (show == StatusShow::Online || show == StatusShow::FFC) {
+ response = QT_TRANSLATE_NOOP("", "%1% has become available");
+ } else if (show == StatusShow::Away || show == StatusShow::XA) {
+ response = QT_TRANSLATE_NOOP("", "%1% has gone away");
+ } else if (show == StatusShow::DND) {
+ response = QT_TRANSLATE_NOOP("", "%1% is now busy");
+ }
+ }
+ Idle::ref idle;
+ if ((idle = presence->getPayload<Idle>())) {
+ response += str(format(QT_TRANSLATE_NOOP("", " and has been idle since %1%")) % Swift::Translator::getInstance()->ptimeToHumanReadableString(idle->getSince()));
+ }
+
+ if (!response.empty()) {
+ response = str(format(response) % nick);
+ }
+
+ if (!presence->getStatus().empty()) {
+ response += " (" + presence->getStatus() + ")";
+ }
+ return response + ".";
+}
+
+void ChatController::handlePresenceChange(std::shared_ptr<Presence> newPresence) {
+ bool relevantPresence = false;
+
+ if (isInMUC_) {
+ // For MUC participants we only have a single presence to choose one and
+ // even for multi-session nicknames multiple resources are not distinguishable
+ // to other participants.
+ if (toJID_.equals(newPresence->getFrom(), JID::WithResource)) {
+ relevantPresence = true;
+ }
+ }
+ else {
+ // For standard chats we retrieve the account presence from the PresenceOracle,
+ // as there can be multiple presences to choose from.
+ if (toJID_.equals(newPresence->getFrom(), JID::WithoutResource)) {
+ // Presence matches ChatController JID.
+ newPresence = presenceOracle_->getAccountPresence(toJID_);
+ relevantPresence = true;
+ }
+ }
+
+ if (!relevantPresence) {
+ return;
+ }
+
+ if (!newPresence) {
+ newPresence = std::make_shared<Presence>();
+ newPresence->setType(Presence::Unavailable);
+ }
+ lastShownStatus_ = newPresence->getShow();
+
+ chatStateTracker_->handlePresenceChange(newPresence);
+ chatStateNotifier_->setContactIsOnline(newPresence->getType() == Presence::Available);
+ std::string newStatusChangeString = getStatusChangeString(newPresence);
+ if (newStatusChangeString != lastStatusChangeString_) {
+ if (lastWasPresence_) {
+ chatWindow_->replaceLastMessage(chatMessageParser_->parseMessageBody(newStatusChangeString), ChatWindow::UpdateTimestamp);
+ } else {
+ chatWindow_->addPresenceMessage(chatMessageParser_->parseMessageBody(newStatusChangeString), ChatWindow::DefaultDirection);
+ }
+ lastStatusChangeString_ = newStatusChangeString;
+ lastWasPresence_ = true;
+ }
+}
+
+boost::optional<boost::posix_time::ptime> ChatController::getMessageTimestamp(std::shared_ptr<Message> message) const {
+ return message->getTimestamp();
}
void ChatController::logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool /* isIncoming */) {
- HistoryMessage::Type type;
- if (mucRegistry_->isMUC(fromJID.toBare()) || mucRegistry_->isMUC(toJID.toBare())) {
- type = HistoryMessage::PrivateMessage;
- }
- else {
- type = HistoryMessage::Chat;
- }
+ HistoryMessage::Type type;
+ if (mucRegistry_->isMUC(fromJID.toBare()) || mucRegistry_->isMUC(toJID.toBare())) {
+ type = HistoryMessage::PrivateMessage;
+ }
+ else {
+ type = HistoryMessage::Chat;
+ }
- if (historyController_) {
- historyController_->addMessage(message, fromJID, toJID, type, timeStamp);
- }
+ if (historyController_) {
+ historyController_->addMessage(message, fromJID, toJID, type, timeStamp);
+ }
}
ChatWindow* ChatController::detachChatWindow() {
- chatWindow_->onUserTyping.disconnect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
- chatWindow_->onUserCancelsTyping.disconnect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_));
- return ChatControllerBase::detachChatWindow();
+ chatWindow_->onUserTyping.disconnect(boost::bind(&ChatStateNotifier::setUserIsTyping, chatStateNotifier_));
+ chatWindow_->onUserCancelsTyping.disconnect(boost::bind(&ChatStateNotifier::userCancelledNewMessage, chatStateNotifier_));
+ return ChatControllerBase::detachChatWindow();
}
}
diff --git a/Swift/Controllers/Chat/ChatController.h b/Swift/Controllers/Chat/ChatController.h
index 9ee82eb..7bd6107 100644
--- a/Swift/Controllers/Chat/ChatController.h
+++ b/Swift/Controllers/Chat/ChatController.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -16,101 +16,101 @@
#include <Swift/Controllers/UIInterfaces/ChatWindow.h>
namespace Swift {
- class AvatarManager;
- class ChatStateNotifier;
- class ChatStateTracker;
- class NickResolver;
- class EntityCapsProvider;
- class FileTransferController;
- class SettingsProvider;
- class HistoryController;
- class HighlightManager;
- class ClientBlockListManager;
- class UIEvent;
-
- class ChatController : public ChatControllerBase {
- public:
- ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, bool userWantsReceipts, SettingsProvider* settings, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, boost::shared_ptr<ChatMessageParser> chatMessageParser, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider);
- virtual ~ChatController();
- virtual void setToJID(const JID& jid) SWIFTEN_OVERRIDE;
- virtual void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) SWIFTEN_OVERRIDE;
- virtual void setOnline(bool online) SWIFTEN_OVERRIDE;
- virtual void handleNewFileTransferController(FileTransferController* ftc);
- virtual void handleWhiteboardSessionRequest(bool senderIsSelf);
- virtual void handleWhiteboardStateChange(const ChatWindow::WhiteboardSessionState state);
- virtual void setContactIsReceivingPresence(bool /*isReceivingPresence*/) SWIFTEN_OVERRIDE;
- virtual ChatWindow* detachChatWindow() SWIFTEN_OVERRIDE;
-
- protected:
- virtual void cancelReplaces() SWIFTEN_OVERRIDE;
- virtual JID getBaseJID() SWIFTEN_OVERRIDE;
- virtual void logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming) SWIFTEN_OVERRIDE;
-
- private:
- void handlePresenceChange(boost::shared_ptr<Presence> newPresence);
- std::string getStatusChangeString(boost::shared_ptr<Presence> presence);
- virtual bool isIncomingMessageFromMe(boost::shared_ptr<Message> message) SWIFTEN_OVERRIDE;
- virtual void postSendMessage(const std::string &body, boost::shared_ptr<Stanza> sentStanza) SWIFTEN_OVERRIDE;
- virtual void preHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) SWIFTEN_OVERRIDE;
- virtual void postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent, const HighlightAction&) SWIFTEN_OVERRIDE;
- virtual void preSendMessageRequest(boost::shared_ptr<Message>) SWIFTEN_OVERRIDE;
- virtual std::string senderHighlightNameFromMessage(const JID& from) SWIFTEN_OVERRIDE;
- virtual std::string senderDisplayNameFromMessage(const JID& from) SWIFTEN_OVERRIDE;
- virtual boost::optional<boost::posix_time::ptime> getMessageTimestamp(boost::shared_ptr<Message>) const SWIFTEN_OVERRIDE;
- void handleStanzaAcked(boost::shared_ptr<Stanza> stanza);
- virtual void dayTicked() SWIFTEN_OVERRIDE { lastWasPresence_ = false; }
- void handleContactNickChanged(const JID& jid, const std::string& /*oldNick*/);
- virtual void handleBareJIDCapsChanged(const JID& jid) SWIFTEN_OVERRIDE;
-
- void handleFileTransferCancel(std::string /* id */);
- void handleFileTransferStart(std::string /* id */, std::string /* description */);
- void handleFileTransferAccept(std::string /* id */, std::string /* filename */);
- void handleSendFileRequest(std::string filename);
-
- void handleWhiteboardSessionAccept();
- void handleWhiteboardSessionCancel();
- void handleWhiteboardWindowShow();
-
- void handleSettingChanged(const std::string& settingPath);
- void checkForDisplayingDisplayReceiptsAlert();
-
- void handleBlockingStateChanged();
- void handleBlockUserRequest();
- void handleUnblockUserRequest();
-
- void handleInviteToChat(const std::vector<JID>& droppedJIDs);
-
- void handleWindowClosed();
-
- void handleUIEvent(boost::shared_ptr<UIEvent> event);
-
- private:
- NickResolver* nickResolver_;
- ChatStateNotifier* chatStateNotifier_;
- ChatStateTracker* chatStateTracker_;
- std::string myLastMessageUIID_;
- bool isInMUC_;
- bool lastWasPresence_;
- std::string lastStatusChangeString_;
- std::map<boost::shared_ptr<Stanza>, std::string> unackedStanzas_;
- std::map<std::string, std::string> requestedReceipts_;
- StatusShow::Type lastShownStatus_;
- UIEventStream* eventStream_;
-
- Tristate contactSupportsReceipts_;
- bool receivingPresenceFromUs_;
- bool userWantsReceipts_;
- std::map<std::string, FileTransferController*> ftControllers;
- SettingsProvider* settings_;
- std::string lastWbID_;
-
- ClientBlockListManager* clientBlockListManager_;
- boost::bsignals::scoped_connection blockingOnStateChangedConnection_;
- boost::bsignals::scoped_connection blockingOnItemAddedConnection_;
- boost::bsignals::scoped_connection blockingOnItemRemovedConnection_;
-
- boost::optional<ChatWindow::AlertID> deliveryReceiptAlert_;
- boost::optional<ChatWindow::AlertID> blockedContactAlert_;
- };
+ class AvatarManager;
+ class ChatStateNotifier;
+ class ChatStateTracker;
+ class NickResolver;
+ class EntityCapsProvider;
+ class FileTransferController;
+ class SettingsProvider;
+ class HistoryController;
+ class HighlightManager;
+ class ClientBlockListManager;
+ class UIEvent;
+
+ class ChatController : public ChatControllerBase {
+ public:
+ ChatController(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &contact, NickResolver* nickResolver, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool isInMUC, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, bool userWantsReceipts, SettingsProvider* settings, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, std::shared_ptr<ChatMessageParser> chatMessageParser, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider);
+ virtual ~ChatController();
+ virtual void setToJID(const JID& jid) SWIFTEN_OVERRIDE;
+ virtual void setAvailableServerFeatures(std::shared_ptr<DiscoInfo> info) SWIFTEN_OVERRIDE;
+ virtual void setOnline(bool online) SWIFTEN_OVERRIDE;
+ virtual void handleNewFileTransferController(FileTransferController* ftc);
+ virtual void handleWhiteboardSessionRequest(bool senderIsSelf);
+ virtual void handleWhiteboardStateChange(const ChatWindow::WhiteboardSessionState state);
+ virtual void setContactIsReceivingPresence(bool /*isReceivingPresence*/) SWIFTEN_OVERRIDE;
+ virtual ChatWindow* detachChatWindow() SWIFTEN_OVERRIDE;
+ virtual void handleIncomingOwnMessage(std::shared_ptr<Message> message) SWIFTEN_OVERRIDE;
+
+ protected:
+ virtual void cancelReplaces() SWIFTEN_OVERRIDE;
+ virtual JID getBaseJID() SWIFTEN_OVERRIDE;
+ virtual void logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming) SWIFTEN_OVERRIDE;
+
+ private:
+ void handlePresenceChange(std::shared_ptr<Presence> newPresence);
+ std::string getStatusChangeString(std::shared_ptr<Presence> presence);
+ virtual bool isIncomingMessageFromMe(std::shared_ptr<Message> message) SWIFTEN_OVERRIDE;
+ virtual void postSendMessage(const std::string &body, std::shared_ptr<Stanza> sentStanza) SWIFTEN_OVERRIDE;
+ virtual void preHandleIncomingMessage(std::shared_ptr<MessageEvent> messageEvent) SWIFTEN_OVERRIDE;
+ virtual void postHandleIncomingMessage(std::shared_ptr<MessageEvent> messageEvent, const ChatWindow::ChatMessage& chatMessage) SWIFTEN_OVERRIDE;
+ virtual void preSendMessageRequest(std::shared_ptr<Message>) SWIFTEN_OVERRIDE;
+ virtual std::string senderHighlightNameFromMessage(const JID& from) SWIFTEN_OVERRIDE;
+ virtual std::string senderDisplayNameFromMessage(const JID& from) SWIFTEN_OVERRIDE;
+ virtual boost::optional<boost::posix_time::ptime> getMessageTimestamp(std::shared_ptr<Message>) const SWIFTEN_OVERRIDE;
+ void handleStanzaAcked(std::shared_ptr<Stanza> stanza);
+ virtual void dayTicked() SWIFTEN_OVERRIDE { lastWasPresence_ = false; }
+ void handleContactNickChanged(const JID& jid, const std::string& /*oldNick*/);
+ virtual void handleBareJIDCapsChanged(const JID& jid) SWIFTEN_OVERRIDE;
+
+ void handleFileTransferCancel(std::string /* id */);
+ void handleFileTransferStart(std::string /* id */, std::string /* description */);
+ void handleFileTransferAccept(std::string /* id */, std::string /* filename */);
+ void handleSendFileRequest(std::string filename);
+
+ void handleWhiteboardSessionAccept();
+ void handleWhiteboardSessionCancel();
+ void handleWhiteboardWindowShow();
+
+ void handleSettingChanged(const std::string& settingPath);
+ void checkForDisplayingDisplayReceiptsAlert();
+
+ void handleBlockingStateChanged();
+ void handleBlockUserRequest();
+ void handleUnblockUserRequest();
+
+ void handleInviteToChat(const std::vector<JID>& droppedJIDs);
+
+ void handleWindowClosed();
+
+ void handleUIEvent(std::shared_ptr<UIEvent> event);
+
+ private:
+ NickResolver* nickResolver_;
+ ChatStateNotifier* chatStateNotifier_;
+ ChatStateTracker* chatStateTracker_;
+ std::string myLastMessageUIID_;
+ bool isInMUC_;
+ std::string lastStatusChangeString_;
+ std::map<std::shared_ptr<Stanza>, std::string> unackedStanzas_;
+ std::map<std::string, std::string> requestedReceipts_;
+ StatusShow::Type lastShownStatus_;
+ UIEventStream* eventStream_;
+
+ Tristate contactSupportsReceipts_;
+ bool receivingPresenceFromUs_ = false;
+ bool userWantsReceipts_;
+ std::map<std::string, FileTransferController*> ftControllers;
+ SettingsProvider* settings_;
+ std::string lastWbID_;
+
+ ClientBlockListManager* clientBlockListManager_;
+ boost::signals2::scoped_connection blockingOnStateChangedConnection_;
+ boost::signals2::scoped_connection blockingOnItemAddedConnection_;
+ boost::signals2::scoped_connection blockingOnItemRemovedConnection_;
+
+ boost::optional<ChatWindow::AlertID> deliveryReceiptAlert_;
+ boost::optional<ChatWindow::AlertID> blockedContactAlert_;
+ };
}
diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp
index fef3e7a..da9064e 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.cpp
+++ b/Swift/Controllers/Chat/ChatControllerBase.cpp
@@ -7,19 +7,15 @@
#include <Swift/Controllers/Chat/ChatControllerBase.h>
#include <map>
+#include <memory>
#include <sstream>
#include <boost/algorithm/string.hpp>
#include <boost/bind.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/numeric/conversion/cast.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
#include <Swiften/Avatars/AvatarManager.h>
#include <Swiften/Base/Path.h>
-#include <Swiften/Base/String.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Base/format.h>
#include <Swiften/Client/StanzaChannel.h>
#include <Swiften/Disco/EntityCapsProvider.h>
@@ -42,343 +38,384 @@
namespace Swift {
-ChatControllerBase::ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, boost::shared_ptr<ChatMessageParser> chatMessageParser, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider) : selfJID_(self), stanzaChannel_(stanzaChannel), iqRouter_(iqRouter), chatWindowFactory_(chatWindowFactory), toJID_(toJID), labelsEnabled_(false), presenceOracle_(presenceOracle), avatarManager_(avatarManager), useDelayForLatency_(useDelayForLatency), eventController_(eventController), timerFactory_(timerFactory), entityCapsProvider_(entityCapsProvider), historyController_(historyController), mucRegistry_(mucRegistry), chatMessageParser_(chatMessageParser), autoAcceptMUCInviteDecider_(autoAcceptMUCInviteDecider), eventStream_(eventStream) {
- chatWindow_ = chatWindowFactory_->createChatWindow(toJID, eventStream);
- chatWindow_->onAllMessagesRead.connect(boost::bind(&ChatControllerBase::handleAllMessagesRead, this));
- chatWindow_->onSendMessageRequest.connect(boost::bind(&ChatControllerBase::handleSendMessageRequest, this, _1, _2));
- chatWindow_->onLogCleared.connect(boost::bind(&ChatControllerBase::handleLogCleared, this));
- entityCapsProvider_->onCapsChanged.connect(boost::bind(&ChatControllerBase::handleCapsChanged, this, _1));
- highlighter_ = highlightManager->createHighlighter();
- ChatControllerBase::setOnline(stanzaChannel->isAvailable() && iqRouter->isAvailable());
- createDayChangeTimer();
+ChatControllerBase::ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, std::shared_ptr<ChatMessageParser> chatMessageParser, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider) : selfJID_(self), stanzaChannel_(stanzaChannel), iqRouter_(iqRouter), chatWindowFactory_(chatWindowFactory), toJID_(toJID), labelsEnabled_(false), presenceOracle_(presenceOracle), avatarManager_(avatarManager), useDelayForLatency_(useDelayForLatency), eventController_(eventController), timerFactory_(timerFactory), entityCapsProvider_(entityCapsProvider), historyController_(historyController), mucRegistry_(mucRegistry), chatMessageParser_(chatMessageParser), autoAcceptMUCInviteDecider_(autoAcceptMUCInviteDecider), eventStream_(eventStream) {
+ chatWindow_ = chatWindowFactory_->createChatWindow(toJID, eventStream);
+ chatWindow_->onAllMessagesRead.connect(boost::bind(&ChatControllerBase::handleAllMessagesRead, this));
+ chatWindow_->onSendMessageRequest.connect(boost::bind(&ChatControllerBase::handleSendMessageRequest, this, _1, _2));
+ chatWindow_->onLogCleared.connect(boost::bind(&ChatControllerBase::handleLogCleared, this));
+ entityCapsProvider_->onCapsChanged.connect(boost::bind(&ChatControllerBase::handleCapsChanged, this, _1));
+ highlighter_ = highlightManager->createHighlighter();
+ ChatControllerBase::setOnline(stanzaChannel->isAvailable() && iqRouter->isAvailable());
+ createDayChangeTimer();
}
ChatControllerBase::~ChatControllerBase() {
- if (dateChangeTimer_) {
- dateChangeTimer_->onTick.disconnect(boost::bind(&ChatControllerBase::handleDayChangeTick, this));
- dateChangeTimer_->stop();
- }
+ if (dateChangeTimer_) {
+ dateChangeTimer_->onTick.disconnect(boost::bind(&ChatControllerBase::handleDayChangeTick, this));
+ dateChangeTimer_->stop();
+ }
- delete highlighter_;
- delete chatWindow_;
+ delete highlighter_;
+ delete chatWindow_;
}
void ChatControllerBase::handleLogCleared() {
- cancelReplaces();
+ cancelReplaces();
}
ChatWindow* ChatControllerBase::detachChatWindow() {
- ChatWindow* chatWindow = chatWindow_;
- chatWindow_ = NULL;
- return chatWindow;
+ ChatWindow* chatWindow = chatWindow_;
+ chatWindow_ = nullptr;
+ return chatWindow;
}
void ChatControllerBase::handleCapsChanged(const JID& jid) {
- if (jid.compare(toJID_, JID::WithoutResource) == 0) {
- handleBareJIDCapsChanged(jid);
- }
+ if (jid.compare(toJID_, JID::WithoutResource) == 0) {
+ handleBareJIDCapsChanged(jid);
+ }
}
void ChatControllerBase::setCanStartImpromptuChats(bool supportsImpromptu) {
- if (chatWindow_) {
- chatWindow_->setCanInitiateImpromptuChats(supportsImpromptu);
- }
+ if (chatWindow_) {
+ chatWindow_->setCanInitiateImpromptuChats(supportsImpromptu);
+ }
}
void ChatControllerBase::createDayChangeTimer() {
- if (timerFactory_) {
- boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
- boost::posix_time::ptime midnight(now.date() + boost::gregorian::days(1));
- int millisecondsUntilMidnight = boost::numeric_cast<int>((midnight - now).total_milliseconds());
- dateChangeTimer_ = timerFactory_->createTimer(millisecondsUntilMidnight);
- dateChangeTimer_->onTick.connect(boost::bind(&ChatControllerBase::handleDayChangeTick, this));
- dateChangeTimer_->start();
- }
+ if (timerFactory_) {
+ boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
+ boost::posix_time::ptime midnight(now.date() + boost::gregorian::days(1));
+ int millisecondsUntilMidnight = boost::numeric_cast<int>((midnight - now).total_milliseconds());
+ dateChangeTimer_ = timerFactory_->createTimer(millisecondsUntilMidnight);
+ dateChangeTimer_->onTick.connect(boost::bind(&ChatControllerBase::handleDayChangeTick, this));
+ dateChangeTimer_->start();
+ }
}
void ChatControllerBase::handleDayChangeTick() {
- dateChangeTimer_->stop();
- boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
- chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "The day is now %1%")) % std::string(boost::posix_time::to_iso_extended_string(now)).substr(0,10))), ChatWindow::DefaultDirection);
- dayTicked();
- createDayChangeTimer();
+ dateChangeTimer_->stop();
+ boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
+ chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "The day is now %1%")) % std::string(boost::posix_time::to_iso_extended_string(now)).substr(0,10))), ChatWindow::DefaultDirection);
+ lastWasPresence_ = false;
+ dayTicked();
+ createDayChangeTimer();
}
void ChatControllerBase::setEnabled(bool enabled) {
- chatWindow_->setOnline(enabled);
- chatWindow_->setCanInitiateImpromptuChats(false);
+ chatWindow_->setOnline(enabled);
+ chatWindow_->setCanInitiateImpromptuChats(false);
}
void ChatControllerBase::setOnline(bool online) {
- setEnabled(online);
+ setEnabled(online);
}
JID ChatControllerBase::getBaseJID() {
- return JID(toJID_.toBare());
+ return JID(toJID_.toBare());
}
-void ChatControllerBase::setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) {
- if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::SecurityLabelsCatalogFeature)) {
- GetSecurityLabelsCatalogRequest::ref request = GetSecurityLabelsCatalogRequest::create(getBaseJID(), iqRouter_);
- request->onResponse.connect(boost::bind(&ChatControllerBase::handleSecurityLabelsCatalogResponse, this, _1, _2));
- request->send();
- } else {
- chatWindow_->setSecurityLabelsEnabled(false);
- labelsEnabled_ = false;
- }
+void ChatControllerBase::setAvailableServerFeatures(std::shared_ptr<DiscoInfo> info) {
+ if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::SecurityLabelsCatalogFeature)) {
+ GetSecurityLabelsCatalogRequest::ref request = GetSecurityLabelsCatalogRequest::create(getBaseJID(), iqRouter_);
+ request->onResponse.connect(boost::bind(&ChatControllerBase::handleSecurityLabelsCatalogResponse, this, _1, _2));
+ request->send();
+ } else {
+ chatWindow_->setSecurityLabelsEnabled(false);
+ labelsEnabled_ = false;
+ }
}
void ChatControllerBase::handleAllMessagesRead() {
- if (!unreadMessages_.empty()) {
- targetedUnreadMessages_.clear();
- foreach (boost::shared_ptr<StanzaEvent> stanzaEvent, unreadMessages_) {
- stanzaEvent->conclude();
- }
- unreadMessages_.clear();
- chatWindow_->setUnreadMessageCount(0);
- onUnreadCountChanged();
- }
+ if (!unreadMessages_.empty()) {
+ targetedUnreadMessages_.clear();
+ for (std::shared_ptr<StanzaEvent> stanzaEvent : unreadMessages_) {
+ stanzaEvent->conclude();
+ }
+ unreadMessages_.clear();
+ updateMessageCount();
+ }
}
int ChatControllerBase::getUnreadCount() {
- return boost::numeric_cast<int>(targetedUnreadMessages_.size());
+ return boost::numeric_cast<int>(targetedUnreadMessages_.size());
}
void ChatControllerBase::handleSendMessageRequest(const std::string &body, bool isCorrectionMessage) {
- if (!stanzaChannel_->isAvailable() || body.empty()) {
- return;
- }
- boost::shared_ptr<Message> message(new Message());
- message->setTo(toJID_);
- message->setType(Swift::Message::Chat);
- message->setBody(body);
- if (labelsEnabled_) {
- if (!isCorrectionMessage) {
- lastLabel_ = chatWindow_->getSelectedSecurityLabel();
- }
- SecurityLabelsCatalog::Item labelItem = lastLabel_;
- if (labelItem.getLabel()) {
- message->addPayload(labelItem.getLabel());
- }
- }
- preSendMessageRequest(message);
-
- boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
- if (useDelayForLatency_) {
- message->addPayload(boost::make_shared<Delay>(now, selfJID_));
- }
- if (isCorrectionMessage) {
- message->addPayload(boost::shared_ptr<Replace> (new Replace(lastSentMessageStanzaID_)));
- }
- message->setID(lastSentMessageStanzaID_ = idGenerator_.generateID());
- stanzaChannel_->sendMessage(message);
- postSendMessage(message->getBody().get(), boost::dynamic_pointer_cast<Stanza>(message));
- onActivity(message->getBody().get());
+ if (!stanzaChannel_->isAvailable() || body.empty()) {
+ return;
+ }
+ std::shared_ptr<Message> message(new Message());
+ message->setTo(toJID_);
+ message->setType(Swift::Message::Chat);
+ message->setBody(body);
+ if (labelsEnabled_) {
+ if (!isCorrectionMessage) {
+ lastLabel_ = chatWindow_->getSelectedSecurityLabel();
+ }
+ SecurityLabelsCatalog::Item labelItem = lastLabel_;
+ if (labelItem.getLabel()) {
+ message->addPayload(labelItem.getLabel());
+ }
+ }
+ preSendMessageRequest(message);
+
+ boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
+ if (useDelayForLatency_) {
+ message->addPayload(std::make_shared<Delay>(now, selfJID_));
+ }
+ if (isCorrectionMessage) {
+ message->addPayload(std::shared_ptr<Replace> (new Replace(lastSentMessageStanzaID_)));
+ }
+ message->setID(lastSentMessageStanzaID_ = idGenerator_.generateID());
+ stanzaChannel_->sendMessage(message);
+ postSendMessage(message->getBody().get(), std::dynamic_pointer_cast<Stanza>(message));
+ onActivity(message->getBody().get());
#ifdef SWIFT_EXPERIMENTAL_HISTORY
- logMessage(body, selfJID_, toJID_, now, false);
+ logMessage(body, selfJID_, toJID_, now, false);
#endif
}
-void ChatControllerBase::handleSecurityLabelsCatalogResponse(boost::shared_ptr<SecurityLabelsCatalog> catalog, ErrorPayload::ref error) {
- if (catalog && !error) {
- if (catalog->getItems().size() == 0) {
- chatWindow_->setSecurityLabelsEnabled(false);
- labelsEnabled_ = false;
- } else {
- labelsEnabled_ = true;
- chatWindow_->setAvailableSecurityLabels(catalog->getItems());
- chatWindow_->setSecurityLabelsEnabled(true);
- }
- } else {
- labelsEnabled_ = false;
- chatWindow_->setSecurityLabelsError();
- }
+void ChatControllerBase::handleSecurityLabelsCatalogResponse(std::shared_ptr<SecurityLabelsCatalog> catalog, ErrorPayload::ref error) {
+ if (catalog && !error) {
+ if (catalog->getItems().size() == 0) {
+ chatWindow_->setSecurityLabelsEnabled(false);
+ labelsEnabled_ = false;
+ } else {
+ labelsEnabled_ = true;
+ chatWindow_->setAvailableSecurityLabels(catalog->getItems());
+ chatWindow_->setSecurityLabelsEnabled(true);
+ }
+ } else {
+ labelsEnabled_ = false;
+ chatWindow_->setSecurityLabelsError();
+ }
}
void ChatControllerBase::showChatWindow() {
- chatWindow_->show();
+ chatWindow_->show();
}
void ChatControllerBase::activateChatWindow() {
- chatWindow_->activate();
+ chatWindow_->activate();
}
bool ChatControllerBase::hasOpenWindow() const {
- return chatWindow_ && chatWindow_->isVisible();
+ return chatWindow_ && chatWindow_->isVisible();
}
-std::string ChatControllerBase::addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, const boost::shared_ptr<SecurityLabel> label, const boost::filesystem::path& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
- if (boost::starts_with(message, "/me ")) {
- return chatWindow_->addAction(chatMessageParser_->parseMessageBody(String::getSplittedAtFirst(message, ' ').second), senderName, senderIsSelf, label, pathToString(avatarPath), time, highlight);
- } else {
- return chatWindow_->addMessage(chatMessageParser_->parseMessageBody(message,highlighter_->getNick(),senderIsSelf), senderName, senderIsSelf, label, pathToString(avatarPath), time, highlight);
- }
+ChatWindow::ChatMessage ChatControllerBase::buildChatWindowChatMessage(const std::string& message, bool senderIsSelf, const HighlightAction& fullMessageHighlightAction) {
+ ChatWindow::ChatMessage chatMessage;
+ chatMessage = chatMessageParser_->parseMessageBody(message, highlighter_->getNick(), senderIsSelf);
+ chatMessage.setFullMessageHighlightAction(fullMessageHighlightAction);
+ return chatMessage;
}
-void ChatControllerBase::replaceMessage(const std::string& message, const std::string& id, bool senderIsSelf, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
- if (boost::starts_with(message, "/me ")) {
- chatWindow_->replaceWithAction(chatMessageParser_->parseMessageBody(String::getSplittedAtFirst(message, ' ').second), id, time, highlight);
- } else {
- chatWindow_->replaceMessage(chatMessageParser_->parseMessageBody(message,highlighter_->getNick(),senderIsSelf), id, time, highlight);
- }
+void ChatControllerBase::handleHighlightActions(const ChatWindow::ChatMessage& chatMessage) {
+ std::set<std::string> playedSounds;
+ if (chatMessage.getFullMessageHighlightAction().playSound()) {
+ highlighter_->handleHighlightAction(chatMessage.getFullMessageHighlightAction());
+ playedSounds.insert(chatMessage.getFullMessageHighlightAction().getSoundFile());
+ }
+ for (std::shared_ptr<ChatWindow::ChatMessagePart> part : chatMessage.getParts()) {
+ std::shared_ptr<ChatWindow::ChatHighlightingMessagePart> highlightMessage = std::dynamic_pointer_cast<ChatWindow::ChatHighlightingMessagePart>(part);
+ if (highlightMessage && highlightMessage->action.playSound()) {
+ if (playedSounds.find(highlightMessage->action.getSoundFile()) == playedSounds.end()) {
+ highlighter_->handleHighlightAction(highlightMessage->action);
+ playedSounds.insert(highlightMessage->action.getSoundFile());
+ }
+ }
+ }
+}
+
+void ChatControllerBase::updateMessageCount() {
+ chatWindow_->setUnreadMessageCount(boost::numeric_cast<int>(unreadMessages_.size()));
+ onUnreadCountChanged();
+}
+
+std::string ChatControllerBase::addMessage(const ChatWindow::ChatMessage& chatMessage, const std::string& senderName, bool senderIsSelf, const std::shared_ptr<SecurityLabel> label, const boost::filesystem::path& avatarPath, const boost::posix_time::ptime& time) {
+ if (chatMessage.isMeCommand()) {
+ return chatWindow_->addAction(chatMessage, senderName, senderIsSelf, label, pathToString(avatarPath), time);
+ }
+ else {
+ return chatWindow_->addMessage(chatMessage, senderName, senderIsSelf, label, pathToString(avatarPath), time);
+ }
+}
+
+void ChatControllerBase::replaceMessage(const ChatWindow::ChatMessage& chatMessage, const std::string& id, const boost::posix_time::ptime& time) {
+ if (chatMessage.isMeCommand()) {
+ chatWindow_->replaceWithAction(chatMessage, id, time);
+ }
+ else {
+ chatWindow_->replaceMessage(chatMessage, id, time);
+ }
}
bool ChatControllerBase::isFromContact(const JID& from) {
- return from.toBare() == toJID_.toBare();
-}
-
-void ChatControllerBase::handleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) {
- preHandleIncomingMessage(messageEvent);
- if (messageEvent->isReadable() && !messageEvent->getConcluded()) {
- unreadMessages_.push_back(messageEvent);
- if (messageEvent->targetsMe()) {
- targetedUnreadMessages_.push_back(messageEvent);
- }
- }
- boost::shared_ptr<Message> message = messageEvent->getStanza();
- std::string body = message->getBody().get_value_or("");
- HighlightAction highlight;
- if (message->isError()) {
- if (!message->getTo().getResource().empty()) {
- std::string errorMessage = str(format(QT_TRANSLATE_NOOP("", "Couldn't send message: %1%")) % getErrorMessage(message->getPayload<ErrorPayload>()));
- chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage));
- }
- }
- else if (messageEvent->getStanza()->getPayload<MUCInvitationPayload>()) {
- handleMUCInvitation(messageEvent->getStanza());
- return;
- }
- else if (messageEvent->getStanza()->getPayload<MUCUserPayload>() && messageEvent->getStanza()->getPayload<MUCUserPayload>()->getInvite()) {
- handleMediatedMUCInvitation(messageEvent->getStanza());
- return;
- }
- else {
- if (!messageEvent->isReadable()) {
- return;
- }
- showChatWindow();
- JID from = message->getFrom();
- std::vector<boost::shared_ptr<Delay> > delayPayloads = message->getPayloads<Delay>();
- for (size_t i = 0; useDelayForLatency_ && i < delayPayloads.size(); i++) {
- if (!delayPayloads[i]->getFrom()) {
- continue;
- }
- boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
- std::ostringstream s;
- s << "The following message took " << (now - delayPayloads[i]->getStamp()).total_milliseconds() / 1000.0 << " seconds to be delivered from " << delayPayloads[i]->getFrom()->toString() << ".";
- chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(std::string(s.str())), ChatWindow::DefaultDirection);
- }
- boost::shared_ptr<SecurityLabel> label = message->getPayload<SecurityLabel>();
-
- // Determine the timestamp
- boost::posix_time::ptime timeStamp = boost::posix_time::microsec_clock::universal_time();
- boost::optional<boost::posix_time::ptime> messageTimeStamp = getMessageTimestamp(message);
- if (messageTimeStamp) {
- timeStamp = *messageTimeStamp;
- }
- onActivity(body);
-
- // Highlight
- if (!isIncomingMessageFromMe(message)) {
- highlight = highlighter_->findAction(body, senderHighlightNameFromMessage(from));
- }
-
- boost::shared_ptr<Replace> replace = message->getPayload<Replace>();
- if (replace) {
- std::string body = message->getBody().get_value_or("");
- // Should check if the user has a previous message
- std::map<JID, std::string>::iterator lastMessage;
- lastMessage = lastMessagesUIID_.find(from);
- if (lastMessage != lastMessagesUIID_.end()) {
- replaceMessage(body, lastMessagesUIID_[from], isIncomingMessageFromMe(message), timeStamp, highlight);
- }
- }
- else {
- addMessageHandleIncomingMessage(from, body, isIncomingMessageFromMe(message), label, timeStamp, highlight);
- }
-
- logMessage(body, from, selfJID_, timeStamp, true);
- }
- chatWindow_->show();
- chatWindow_->setUnreadMessageCount(boost::numeric_cast<int>(unreadMessages_.size()));
- onUnreadCountChanged();
- postHandleIncomingMessage(messageEvent, highlight);
-}
-
-void ChatControllerBase::addMessageHandleIncomingMessage(const JID& from, const std::string& message, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& timeStamp, const HighlightAction& highlight) {
- lastMessagesUIID_[from] = addMessage(message, senderDisplayNameFromMessage(from), senderIsSelf, label, avatarManager_->getAvatarPath(from), timeStamp, highlight);
-}
-
-std::string ChatControllerBase::getErrorMessage(boost::shared_ptr<ErrorPayload> error) {
- std::string defaultMessage = QT_TRANSLATE_NOOP("", "Error sending message");
- if (!error->getText().empty()) {
- return error->getText();
- }
- else {
- switch (error->getCondition()) {
- case ErrorPayload::BadRequest: return QT_TRANSLATE_NOOP("", "Bad request");
- case ErrorPayload::Conflict: return QT_TRANSLATE_NOOP("", "Conflict");
- case ErrorPayload::FeatureNotImplemented: return QT_TRANSLATE_NOOP("", "This feature is not implemented");
- case ErrorPayload::Forbidden: return QT_TRANSLATE_NOOP("", "Forbidden");
- case ErrorPayload::Gone: return QT_TRANSLATE_NOOP("", "Recipient can no longer be contacted");
- case ErrorPayload::InternalServerError: return QT_TRANSLATE_NOOP("", "Internal server error");
- case ErrorPayload::ItemNotFound: return QT_TRANSLATE_NOOP("", "Item not found");
- case ErrorPayload::JIDMalformed: return QT_TRANSLATE_NOOP("", "JID Malformed");
- case ErrorPayload::NotAcceptable: return QT_TRANSLATE_NOOP("", "Message was rejected");
- case ErrorPayload::NotAllowed: return QT_TRANSLATE_NOOP("", "Not allowed");
- case ErrorPayload::NotAuthorized: return QT_TRANSLATE_NOOP("", "Not authorized");
- case ErrorPayload::PaymentRequired: return QT_TRANSLATE_NOOP("", "Payment is required");
- case ErrorPayload::RecipientUnavailable: return QT_TRANSLATE_NOOP("", "Recipient is unavailable");
- case ErrorPayload::Redirect: return QT_TRANSLATE_NOOP("", "Redirect");
- case ErrorPayload::RegistrationRequired: return QT_TRANSLATE_NOOP("", "Registration required");
- case ErrorPayload::RemoteServerNotFound: return QT_TRANSLATE_NOOP("", "Recipient's server not found");
- case ErrorPayload::RemoteServerTimeout: return QT_TRANSLATE_NOOP("", "Remote server timeout");
- case ErrorPayload::ResourceConstraint: return QT_TRANSLATE_NOOP("", "The server is low on resources");
- case ErrorPayload::ServiceUnavailable: return QT_TRANSLATE_NOOP("", "The service is unavailable");
- case ErrorPayload::SubscriptionRequired: return QT_TRANSLATE_NOOP("", "A subscription is required");
- case ErrorPayload::UndefinedCondition: return QT_TRANSLATE_NOOP("", "Undefined condition");
- case ErrorPayload::UnexpectedRequest: return QT_TRANSLATE_NOOP("", "Unexpected request");
- }
- }
- assert(false);
- return defaultMessage;
+ return from.toBare() == toJID_.toBare();
+}
+
+void ChatControllerBase::handleIncomingMessage(std::shared_ptr<MessageEvent> messageEvent) {
+ preHandleIncomingMessage(messageEvent);
+ if (messageEvent->isReadable() && !messageEvent->getConcluded()) {
+ unreadMessages_.push_back(messageEvent);
+ if (messageEvent->targetsMe()) {
+ targetedUnreadMessages_.push_back(messageEvent);
+ }
+ }
+
+ std::shared_ptr<Message> message = messageEvent->getStanza();
+ ChatWindow::ChatMessage chatMessage;
+ boost::optional<std::string> optionalBody = message->getBody();
+ std::string body = optionalBody.get_value_or("");
+ if (message->isError()) {
+ if (!message->getTo().getResource().empty()) {
+ std::string errorMessage;
+ if (message->getPayload<Swift::ErrorPayload>()->getCondition() == ErrorPayload::ItemNotFound) {
+ errorMessage = QT_TRANSLATE_NOOP("", "This user could not be found in the room.");
+ }
+ else {
+ errorMessage = str(format(QT_TRANSLATE_NOOP("", "Couldn't send message: %1%")) % getErrorMessage(message->getPayload<ErrorPayload>()));
+ }
+ chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage));
+ }
+ }
+ else if (messageEvent->getStanza()->getPayload<MUCInvitationPayload>()) {
+ handleMUCInvitation(messageEvent->getStanza());
+ return;
+ }
+ else if (messageEvent->getStanza()->getPayload<MUCUserPayload>() && messageEvent->getStanza()->getPayload<MUCUserPayload>()->getInvite()) {
+ handleMediatedMUCInvitation(messageEvent->getStanza());
+ return;
+ }
+ else {
+ if (!messageEvent->isReadable()) {
+ return;
+ }
+ showChatWindow();
+ JID from = message->getFrom();
+ std::vector<std::shared_ptr<Delay> > delayPayloads = message->getPayloads<Delay>();
+ for (size_t i = 0; useDelayForLatency_ && i < delayPayloads.size(); i++) {
+ if (!delayPayloads[i]->getFrom()) {
+ continue;
+ }
+ boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
+ std::ostringstream s;
+ s << "The following message took " << (now - delayPayloads[i]->getStamp()).total_milliseconds() / 1000.0 << " seconds to be delivered from " << delayPayloads[i]->getFrom()->toString() << ".";
+ chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(std::string(s.str())), ChatWindow::DefaultDirection);
+ }
+ std::shared_ptr<SecurityLabel> label = message->getPayload<SecurityLabel>();
+
+ // Determine the timestamp
+ boost::posix_time::ptime timeStamp = boost::posix_time::microsec_clock::universal_time();
+ boost::optional<boost::posix_time::ptime> messageTimeStamp = getMessageTimestamp(message);
+ if (messageTimeStamp) {
+ timeStamp = *messageTimeStamp;
+ }
+ onActivity(body);
+
+ // Highlight
+ HighlightAction fullMessageHighlight;
+ if (!isIncomingMessageFromMe(message)) {
+ fullMessageHighlight = highlighter_->findFirstFullMessageMatchAction(body, senderHighlightNameFromMessage(from));
+ }
+
+ std::shared_ptr<Replace> replace = message->getPayload<Replace>();
+ bool senderIsSelf = isIncomingMessageFromMe(message);
+ if (replace) {
+ // Should check if the user has a previous message
+ std::map<JID, std::string>::iterator lastMessage;
+ lastMessage = lastMessagesUIID_.find(from);
+ if (lastMessage != lastMessagesUIID_.end()) {
+ chatMessage = buildChatWindowChatMessage(body, senderIsSelf, fullMessageHighlight);
+ replaceMessage(chatMessage, lastMessagesUIID_[from], timeStamp);
+ }
+ }
+ else {
+ chatMessage = buildChatWindowChatMessage(body, senderIsSelf, fullMessageHighlight);
+ addMessageHandleIncomingMessage(from, chatMessage, senderIsSelf, label, timeStamp);
+ }
+
+ logMessage(body, from, selfJID_, timeStamp, true);
+ }
+ chatWindow_->show();
+ updateMessageCount();
+ postHandleIncomingMessage(messageEvent, chatMessage);
+}
+
+void ChatControllerBase::addMessageHandleIncomingMessage(const JID& from, const ChatWindow::ChatMessage& message, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& timeStamp) {
+ lastMessagesUIID_[from] = addMessage(message, senderDisplayNameFromMessage(from), senderIsSelf, label, avatarManager_->getAvatarPath(from), timeStamp);
+}
+
+std::string ChatControllerBase::getErrorMessage(std::shared_ptr<ErrorPayload> error) {
+ std::string defaultMessage = QT_TRANSLATE_NOOP("", "Error sending message");
+ if (!error->getText().empty()) {
+ return error->getText();
+ }
+ else {
+ switch (error->getCondition()) {
+ case ErrorPayload::BadRequest: return QT_TRANSLATE_NOOP("", "Bad request");
+ case ErrorPayload::Conflict: return QT_TRANSLATE_NOOP("", "Conflict");
+ case ErrorPayload::FeatureNotImplemented: return QT_TRANSLATE_NOOP("", "This feature is not implemented");
+ case ErrorPayload::Forbidden: return QT_TRANSLATE_NOOP("", "Forbidden");
+ case ErrorPayload::Gone: return QT_TRANSLATE_NOOP("", "Recipient can no longer be contacted");
+ case ErrorPayload::InternalServerError: return QT_TRANSLATE_NOOP("", "Internal server error");
+ case ErrorPayload::ItemNotFound: return QT_TRANSLATE_NOOP("", "Item not found");
+ case ErrorPayload::JIDMalformed: return QT_TRANSLATE_NOOP("", "JID Malformed");
+ case ErrorPayload::NotAcceptable: return QT_TRANSLATE_NOOP("", "Message was rejected");
+ case ErrorPayload::NotAllowed: return QT_TRANSLATE_NOOP("", "Not allowed");
+ case ErrorPayload::NotAuthorized: return QT_TRANSLATE_NOOP("", "Not authorized");
+ case ErrorPayload::PaymentRequired: return QT_TRANSLATE_NOOP("", "Payment is required");
+ case ErrorPayload::RecipientUnavailable: return QT_TRANSLATE_NOOP("", "Recipient is unavailable");
+ case ErrorPayload::Redirect: return QT_TRANSLATE_NOOP("", "Redirect");
+ case ErrorPayload::RegistrationRequired: return QT_TRANSLATE_NOOP("", "Registration required");
+ case ErrorPayload::RemoteServerNotFound: return QT_TRANSLATE_NOOP("", "Recipient's server not found");
+ case ErrorPayload::RemoteServerTimeout: return QT_TRANSLATE_NOOP("", "Remote server timeout");
+ case ErrorPayload::ResourceConstraint: return QT_TRANSLATE_NOOP("", "The server is low on resources");
+ case ErrorPayload::ServiceUnavailable: return QT_TRANSLATE_NOOP("", "The service is unavailable");
+ case ErrorPayload::SubscriptionRequired: return QT_TRANSLATE_NOOP("", "A subscription is required");
+ case ErrorPayload::UndefinedCondition: return QT_TRANSLATE_NOOP("", "Undefined condition");
+ case ErrorPayload::UnexpectedRequest: return QT_TRANSLATE_NOOP("", "Unexpected request");
+ }
+ }
+ assert(false);
+ return defaultMessage;
}
void ChatControllerBase::handleGeneralMUCInvitation(MUCInviteEvent::ref event) {
- unreadMessages_.push_back(event);
- chatWindow_->show();
- chatWindow_->setUnreadMessageCount(boost::numeric_cast<int>(unreadMessages_.size()));
- onUnreadCountChanged();
- chatWindow_->addMUCInvitation(senderDisplayNameFromMessage(event->getInviter()), event->getRoomJID(), event->getReason(), event->getPassword(), event->getDirect(), event->getImpromptu());
- eventController_->handleIncomingEvent(event);
+ unreadMessages_.push_back(event);
+ chatWindow_->show();
+ updateMessageCount();
+ chatWindow_->addMUCInvitation(senderDisplayNameFromMessage(event->getInviter()), event->getRoomJID(), event->getReason(), event->getPassword(), event->getDirect(), event->getImpromptu());
+ eventController_->handleIncomingEvent(event);
+ lastWasPresence_ = false;
}
void ChatControllerBase::handleMUCInvitation(Message::ref message) {
- MUCInvitationPayload::ref invite = message->getPayload<MUCInvitationPayload>();
-
- if (autoAcceptMUCInviteDecider_->isAutoAcceptedInvite(message->getFrom(), invite)) {
- eventStream_->send(boost::make_shared<JoinMUCUIEvent>(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, false, true));
- } else {
- MUCInviteEvent::ref inviteEvent = boost::make_shared<MUCInviteEvent>(toJID_, invite->getJID(), invite->getReason(), invite->getPassword(), true, invite->getIsImpromptu());
- handleGeneralMUCInvitation(inviteEvent);
- }
+ MUCInvitationPayload::ref invite = message->getPayload<MUCInvitationPayload>();
+
+ if (autoAcceptMUCInviteDecider_->isAutoAcceptedInvite(message->getFrom(), invite)) {
+ eventStream_->send(std::make_shared<JoinMUCUIEvent>(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, false, true));
+ } else {
+ MUCInviteEvent::ref inviteEvent = std::make_shared<MUCInviteEvent>(toJID_, invite->getJID(), invite->getReason(), invite->getPassword(), true, invite->getIsImpromptu());
+ handleGeneralMUCInvitation(inviteEvent);
+ }
}
void ChatControllerBase::handleMediatedMUCInvitation(Message::ref message) {
- MUCUserPayload::Invite invite = *message->getPayload<MUCUserPayload>()->getInvite();
- JID from = message->getFrom();
- std::string reason;
- if (!invite.reason.empty()) {
- reason = invite.reason;
- }
- std::string password;
- if (message->getPayload<MUCUserPayload>()->getPassword()) {
- password = *message->getPayload<MUCUserPayload>()->getPassword();
- }
-
- MUCInviteEvent::ref inviteEvent = boost::make_shared<MUCInviteEvent>(invite.from, from, reason, password, false, false);
- handleGeneralMUCInvitation(inviteEvent);
+ MUCUserPayload::Invite invite = *message->getPayload<MUCUserPayload>()->getInvite();
+ JID from = message->getFrom();
+ std::string reason;
+ if (!invite.reason.empty()) {
+ reason = invite.reason;
+ }
+ std::string password;
+ if (message->getPayload<MUCUserPayload>()->getPassword()) {
+ password = *message->getPayload<MUCUserPayload>()->getPassword();
+ }
+
+ MUCInviteEvent::ref inviteEvent = std::make_shared<MUCInviteEvent>(invite.from, from, reason, password, false, false);
+ handleGeneralMUCInvitation(inviteEvent);
}
}
diff --git a/Swift/Controllers/Chat/ChatControllerBase.h b/Swift/Controllers/Chat/ChatControllerBase.h
index 4e68a2b..4255c19 100644
--- a/Swift/Controllers/Chat/ChatControllerBase.h
+++ b/Swift/Controllers/Chat/ChatControllerBase.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,16 +7,16 @@
#pragma once
#include <map>
+#include <memory>
#include <string>
#include <vector>
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/filesystem/path.hpp>
#include <boost/optional.hpp>
-#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
#include <Swiften/Base/IDGenerator.h>
-#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Elements/DiscoInfo.h>
#include <Swiften/Elements/ErrorPayload.h>
#include <Swiften/Elements/SecurityLabelsCatalog.h>
@@ -35,104 +35,110 @@
#include <Swift/Controllers/XMPPEvents/MessageEvent.h>
namespace Swift {
- class IQRouter;
- class StanzaChannel;
- class ChatWindowFactory;
- class AvatarManager;
- class UIEventStream;
- class EventController;
- class EntityCapsProvider;
- class HighlightManager;
- class Highlighter;
- class ChatMessageParser;
- class AutoAcceptMUCInviteDecider;
+ class IQRouter;
+ class StanzaChannel;
+ class ChatWindowFactory;
+ class AvatarManager;
+ class UIEventStream;
+ class EventController;
+ class EntityCapsProvider;
+ class HighlightManager;
+ class Highlighter;
+ class ChatMessageParser;
+ class AutoAcceptMUCInviteDecider;
- class ChatControllerBase : public boost::bsignals::trackable {
- public:
- virtual ~ChatControllerBase();
- void showChatWindow();
- void activateChatWindow();
- bool hasOpenWindow() const;
- virtual void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info);
- void handleIncomingMessage(boost::shared_ptr<MessageEvent> message);
- std::string addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::filesystem::path& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight);
- void replaceMessage(const std::string& message, const std::string& id, bool senderIsSelf, const boost::posix_time::ptime& time, const HighlightAction& highlight);
- virtual void setOnline(bool online);
- void setEnabled(bool enabled);
- virtual void setToJID(const JID& jid) {toJID_ = jid;}
- /** Used for determining when something is recent.*/
- boost::signal<void (const std::string& /*activity*/)> onActivity;
- boost::signal<void ()> onUnreadCountChanged;
- boost::signal<void ()> onWindowClosed;
- int getUnreadCount();
- const JID& getToJID() {return toJID_;}
- void handleCapsChanged(const JID& jid);
- void setCanStartImpromptuChats(bool supportsImpromptu);
- virtual ChatWindow* detachChatWindow();
- boost::signal<void(ChatWindow* /*window to reuse*/, const std::vector<JID>& /*invite people*/, const std::string& /*reason*/)> onConvertToMUC;
+ class ChatControllerBase : public boost::signals2::trackable {
+ public:
+ virtual ~ChatControllerBase();
+ void showChatWindow();
+ void activateChatWindow();
+ bool hasOpenWindow() const;
+ virtual void setAvailableServerFeatures(std::shared_ptr<DiscoInfo> info);
+ virtual void handleIncomingOwnMessage(std::shared_ptr<Message> /*message*/) {}
+ void handleIncomingMessage(std::shared_ptr<MessageEvent> message);
+ std::string addMessage(const ChatWindow::ChatMessage& chatMessage, const std::string& senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const boost::filesystem::path& avatarPath, const boost::posix_time::ptime& time);
+ void replaceMessage(const ChatWindow::ChatMessage& chatMessage, const std::string& id, const boost::posix_time::ptime& time);
+ virtual void setOnline(bool online);
+ void setEnabled(bool enabled);
+ virtual void setToJID(const JID& jid) {toJID_ = jid;}
+ /** Used for determining when something is recent.*/
+ boost::signals2::signal<void (const std::string& /*activity*/)> onActivity;
+ boost::signals2::signal<void ()> onUnreadCountChanged;
+ boost::signals2::signal<void ()> onWindowClosed;
+ int getUnreadCount();
+ const JID& getToJID() {return toJID_;}
+ void handleCapsChanged(const JID& jid);
+ void setCanStartImpromptuChats(bool supportsImpromptu);
+ virtual ChatWindow* detachChatWindow();
+ boost::signals2::signal<void(ChatWindow* /*window to reuse*/, const std::vector<JID>& /*invite people*/, const std::string& /*reason*/)> onConvertToMUC;
- protected:
- ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, boost::shared_ptr<ChatMessageParser> chatMessageParser, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider);
+ protected:
+ ChatControllerBase(const JID& self, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, const JID &toJID, PresenceOracle* presenceOracle, AvatarManager* avatarManager, bool useDelayForLatency, UIEventStream* eventStream, EventController* eventController, TimerFactory* timerFactory, EntityCapsProvider* entityCapsProvider, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, std::shared_ptr<ChatMessageParser> chatMessageParser, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider);
- /**
- * Pass the Message appended, and the stanza used to send it.
- */
- virtual void postSendMessage(const std::string&, boost::shared_ptr<Stanza>) {}
- virtual std::string senderDisplayNameFromMessage(const JID& from) = 0;
- virtual std::string senderHighlightNameFromMessage(const JID& from) = 0;
- virtual bool isIncomingMessageFromMe(boost::shared_ptr<Message>) = 0;
- virtual void preHandleIncomingMessage(boost::shared_ptr<MessageEvent>) {}
- virtual void addMessageHandleIncomingMessage(const JID& from, const std::string& message, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& time, const HighlightAction& highlight);
- virtual void postHandleIncomingMessage(boost::shared_ptr<MessageEvent>, const HighlightAction&) {}
- virtual void preSendMessageRequest(boost::shared_ptr<Message>) {}
- virtual bool isFromContact(const JID& from);
- virtual boost::optional<boost::posix_time::ptime> getMessageTimestamp(boost::shared_ptr<Message>) const = 0;
- virtual void dayTicked() {}
- virtual void handleBareJIDCapsChanged(const JID& jid) = 0;
- std::string getErrorMessage(boost::shared_ptr<ErrorPayload>);
- virtual void setContactIsReceivingPresence(bool /* isReceivingPresence */) {}
- virtual void cancelReplaces() = 0;
- /** JID any iq for account should go to - bare except for PMs */
- virtual JID getBaseJID();
- virtual void logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming) = 0;
+ /**
+ * Pass the Message appended, and the stanza used to send it.
+ */
+ virtual void postSendMessage(const std::string&, std::shared_ptr<Stanza>) {}
+ virtual std::string senderDisplayNameFromMessage(const JID& from) = 0;
+ virtual std::string senderHighlightNameFromMessage(const JID& from) = 0;
+ virtual bool isIncomingMessageFromMe(std::shared_ptr<Message>) = 0;
+ virtual void preHandleIncomingMessage(std::shared_ptr<MessageEvent>) {}
+ virtual void addMessageHandleIncomingMessage(const JID& from, const ChatWindow::ChatMessage& message, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& time);
+ virtual void postHandleIncomingMessage(std::shared_ptr<MessageEvent>, const ChatWindow::ChatMessage&) {}
+ virtual void preSendMessageRequest(std::shared_ptr<Message>) {}
+ virtual bool isFromContact(const JID& from);
+ virtual boost::optional<boost::posix_time::ptime> getMessageTimestamp(std::shared_ptr<Message>) const = 0;
+ virtual void dayTicked() {}
+ virtual void handleBareJIDCapsChanged(const JID& jid) = 0;
+ std::string getErrorMessage(std::shared_ptr<ErrorPayload>);
+ virtual void setContactIsReceivingPresence(bool /* isReceivingPresence */) {}
+ virtual void cancelReplaces() = 0;
+ /** JID any iq for account should go to - bare except for PMs */
+ virtual JID getBaseJID();
+ virtual void logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming) = 0;
+ ChatWindow::ChatMessage buildChatWindowChatMessage(const std::string& message, bool senderIsSelf, const HighlightAction& fullMessageHighlightAction);
+ void handleHighlightActions(const ChatWindow::ChatMessage& chatMessage);
+ void updateMessageCount();
- private:
- IDGenerator idGenerator_;
- std::string lastSentMessageStanzaID_;
- void createDayChangeTimer();
- void handleSendMessageRequest(const std::string &body, bool isCorrectionMessage);
- void handleAllMessagesRead();
- void handleSecurityLabelsCatalogResponse(boost::shared_ptr<SecurityLabelsCatalog>, ErrorPayload::ref error);
- void handleDayChangeTick();
- void handleMUCInvitation(Message::ref message);
- void handleMediatedMUCInvitation(Message::ref message);
- void handleGeneralMUCInvitation(MUCInviteEvent::ref event);
- void handleLogCleared();
+ private:
+ IDGenerator idGenerator_;
+ std::string lastSentMessageStanzaID_;
+ void createDayChangeTimer();
- protected:
- JID selfJID_;
- std::vector<boost::shared_ptr<StanzaEvent> > unreadMessages_;
- std::vector<boost::shared_ptr<StanzaEvent> > targetedUnreadMessages_;
- StanzaChannel* stanzaChannel_;
- IQRouter* iqRouter_;
- ChatWindowFactory* chatWindowFactory_;
- ChatWindow* chatWindow_;
- JID toJID_;
- bool labelsEnabled_;
- std::map<JID, std::string> lastMessagesUIID_;
- PresenceOracle* presenceOracle_;
- AvatarManager* avatarManager_;
- bool useDelayForLatency_;
- EventController* eventController_;
- boost::shared_ptr<Timer> dateChangeTimer_;
- TimerFactory* timerFactory_;
- EntityCapsProvider* entityCapsProvider_;
- SecurityLabelsCatalog::Item lastLabel_;
- HistoryController* historyController_;
- MUCRegistry* mucRegistry_;
- Highlighter* highlighter_;
- boost::shared_ptr<ChatMessageParser> chatMessageParser_;
- AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider_;
- UIEventStream* eventStream_;
- };
+ void handleSendMessageRequest(const std::string &body, bool isCorrectionMessage);
+ void handleAllMessagesRead();
+ void handleSecurityLabelsCatalogResponse(std::shared_ptr<SecurityLabelsCatalog>, ErrorPayload::ref error);
+ void handleDayChangeTick();
+ void handleMUCInvitation(Message::ref message);
+ void handleMediatedMUCInvitation(Message::ref message);
+ void handleGeneralMUCInvitation(MUCInviteEvent::ref event);
+ void handleLogCleared();
+
+ protected:
+ JID selfJID_;
+ std::vector<std::shared_ptr<StanzaEvent> > unreadMessages_;
+ std::vector<std::shared_ptr<StanzaEvent> > targetedUnreadMessages_;
+ StanzaChannel* stanzaChannel_;
+ IQRouter* iqRouter_;
+ ChatWindowFactory* chatWindowFactory_;
+ ChatWindow* chatWindow_;
+ JID toJID_;
+ bool labelsEnabled_;
+ std::map<JID, std::string> lastMessagesUIID_;
+ PresenceOracle* presenceOracle_;
+ AvatarManager* avatarManager_;
+ bool useDelayForLatency_;
+ EventController* eventController_;
+ std::shared_ptr<Timer> dateChangeTimer_;
+ TimerFactory* timerFactory_;
+ EntityCapsProvider* entityCapsProvider_;
+ SecurityLabelsCatalog::Item lastLabel_;
+ HistoryController* historyController_;
+ MUCRegistry* mucRegistry_;
+ Highlighter* highlighter_;
+ std::shared_ptr<ChatMessageParser> chatMessageParser_;
+ AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider_;
+ UIEventStream* eventStream_;
+ bool lastWasPresence_ = false;
+ };
}
diff --git a/Swift/Controllers/Chat/ChatMessageParser.cpp b/Swift/Controllers/Chat/ChatMessageParser.cpp
index 666ec2f..ec7df6c 100644
--- a/Swift/Controllers/Chat/ChatMessageParser.cpp
+++ b/Swift/Controllers/Chat/ChatMessageParser.cpp
@@ -1,197 +1,197 @@
/*
- * Copyright (c) 2013-2015 Isode Limited.
+ * Copyright (c) 2013-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/Chat/ChatMessageParser.h>
-#include <vector>
+#include <memory>
#include <utility>
+#include <vector>
-#include <boost/smart_ptr/make_shared.hpp>
#include <boost/algorithm/string.hpp>
#include <Swiften/Base/Regex.h>
-#include <Swiften/Base/foreach.h>
+#include <Swiften/Base/String.h>
#include <SwifTools/Linkify.h>
-
namespace Swift {
- ChatMessageParser::ChatMessageParser(const std::map<std::string, std::string>& emoticons, HighlightRulesListPtr highlightRules, bool mucMode)
- : emoticons_(emoticons), highlightRules_(highlightRules), mucMode_(mucMode) {
- }
-
- typedef std::pair<std::string, std::string> StringPair;
-
- ChatWindow::ChatMessage ChatMessageParser::parseMessageBody(const std::string& body, const std::string& nick, bool senderIsSelf) {
- ChatWindow::ChatMessage parsedMessage;
- std::string remaining = body;
- /* Parse one, URLs */
- while (!remaining.empty()) {
- bool found = false;
- std::pair<std::vector<std::string>, size_t> links = Linkify::splitLink(remaining);
- remaining = "";
- for (size_t i = 0; i < links.first.size(); i++) {
- const std::string& part = links.first[i];
- if (found) {
- // Must be on the last part, then
- remaining = part;
- }
- else {
- if (i == links.second) {
- found = true;
- parsedMessage.append(boost::make_shared<ChatWindow::ChatURIMessagePart>(part));
- }
- else {
- parsedMessage.append(boost::make_shared<ChatWindow::ChatTextMessagePart>(part));
- }
- }
- }
- }
-
- /* do emoticon substitution */
- parsedMessage = emoticonHighlight(parsedMessage);
-
- if (!senderIsSelf) { /* do not highlight our own messsages */
- /* do word-based color highlighting */
- parsedMessage = splitHighlight(parsedMessage, nick);
- }
-
- return parsedMessage;
- }
-
- ChatWindow::ChatMessage ChatMessageParser::emoticonHighlight(const ChatWindow::ChatMessage& message)
- {
- ChatWindow::ChatMessage parsedMessage = message;
-
- std::string regexString;
- /* Parse two, emoticons */
- foreach (StringPair emoticon, emoticons_) {
- /* Construct a regexp that finds an instance of any of the emoticons inside a group
- * at the start or end of the line, or beside whitespace.
- */
- regexString += regexString.empty() ? "" : "|";
- std::string escaped = "(" + Regex::escape(emoticon.first) + ")";
- regexString += "^" + escaped + "|";
- regexString += escaped + "$|";
- regexString += "\\s" + escaped + "|";
- regexString += escaped + "\\s";
-
- }
- if (!regexString.empty()) {
- regexString += "";
- boost::regex emoticonRegex(regexString);
-
- ChatWindow::ChatMessage newMessage;
- foreach (boost::shared_ptr<ChatWindow::ChatMessagePart> part, parsedMessage.getParts()) {
- boost::shared_ptr<ChatWindow::ChatTextMessagePart> textPart;
- if ((textPart = boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(part))) {
- try {
- boost::match_results<std::string::const_iterator> match;
- const std::string& text = textPart->text;
- std::string::const_iterator start = text.begin();
- while (regex_search(start, text.end(), match, emoticonRegex)) {
- int matchIndex = 0;
- for (matchIndex = 1; matchIndex < static_cast<int>(match.size()); matchIndex++) {
- if (match[matchIndex].length() > 0) {
- //This is the matching subgroup
- break;
- }
- }
- std::string::const_iterator matchStart = match[matchIndex].first;
- std::string::const_iterator matchEnd = match[matchIndex].second;
- if (start != matchStart) {
- /* If we're skipping over plain text since the previous emoticon, record it as plain text */
- newMessage.append(boost::make_shared<ChatWindow::ChatTextMessagePart>(std::string(start, matchStart)));
- }
- boost::shared_ptr<ChatWindow::ChatEmoticonMessagePart> emoticonPart = boost::make_shared<ChatWindow::ChatEmoticonMessagePart>();
- std::string matchString = match[matchIndex].str();
- std::map<std::string, std::string>::const_iterator emoticonIterator = emoticons_.find(matchString);
- assert (emoticonIterator != emoticons_.end());
- const StringPair& emoticon = *emoticonIterator;
- emoticonPart->imagePath = emoticon.second;
- emoticonPart->alternativeText = emoticon.first;
- newMessage.append(emoticonPart);
- start = matchEnd;
- }
- if (start != text.end()) {
- /* If there's plain text after the last emoticon, record it */
- newMessage.append(boost::make_shared<ChatWindow::ChatTextMessagePart>(std::string(start, text.end())));
- }
-
- }
- catch (std::runtime_error) {
- /* Basically too expensive to compute the regex results and it gave up, so pass through as text */
- newMessage.append(part);
- }
- }
- else {
- newMessage.append(part);
- }
- }
- parsedMessage = newMessage;
-
- }
- return parsedMessage;
- }
-
- ChatWindow::ChatMessage ChatMessageParser::splitHighlight(const ChatWindow::ChatMessage& message, const std::string& nick)
- {
- ChatWindow::ChatMessage parsedMessage = message;
-
- for (size_t i = 0; i < highlightRules_->getSize(); ++i) {
- const HighlightRule& rule = highlightRules_->getRule(i);
- if (rule.getMatchMUC() && !mucMode_) {
- continue; /* this rule only applies to MUC's, and this is a CHAT */
- } else if (rule.getMatchChat() && mucMode_) {
- continue; /* this rule only applies to CHAT's, and this is a MUC */
- } else if (rule.getAction().getTextBackground().empty() && rule.getAction().getTextColor().empty()) {
- continue; /* do not try to highlight text, if no highlight color is specified */
- }
- const std::vector<boost::regex> keywordRegex = rule.getKeywordRegex(nick);
- foreach(const boost::regex& regex, keywordRegex) {
- ChatWindow::ChatMessage newMessage;
- foreach (boost::shared_ptr<ChatWindow::ChatMessagePart> part, parsedMessage.getParts()) {
- boost::shared_ptr<ChatWindow::ChatTextMessagePart> textPart;
- if ((textPart = boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(part))) {
- try {
- boost::match_results<std::string::const_iterator> match;
- const std::string& text = textPart->text;
- std::string::const_iterator start = text.begin();
- while (regex_search(start, text.end(), match, regex)) {
- std::string::const_iterator matchStart = match[0].first;
- std::string::const_iterator matchEnd = match[0].second;
- if (start != matchStart) {
- /* If we're skipping over plain text since the previous emoticon, record it as plain text */
- newMessage.append(boost::make_shared<ChatWindow::ChatTextMessagePart>(std::string(start, matchStart)));
- }
- boost::shared_ptr<ChatWindow::ChatHighlightingMessagePart> highlightPart = boost::make_shared<ChatWindow::ChatHighlightingMessagePart>();
- highlightPart->text = match.str();
- highlightPart->foregroundColor = rule.getAction().getTextColor();
- highlightPart->backgroundColor = rule.getAction().getTextBackground();
- newMessage.append(highlightPart);
- start = matchEnd;
- }
- if (start != text.end()) {
- /* If there's plain text after the last emoticon, record it */
- newMessage.append(boost::make_shared<ChatWindow::ChatTextMessagePart>(std::string(start, text.end())));
- }
- }
- catch (std::runtime_error) {
- /* Basically too expensive to compute the regex results and it gave up, so pass through as text */
- newMessage.append(part);
- }
- } else {
- newMessage.append(part);
- }
- }
- parsedMessage = newMessage;
- }
- }
-
- return parsedMessage;
- }
+ ChatMessageParser::ChatMessageParser(const std::map<std::string, std::string>& emoticons, HighlightRulesListPtr highlightRules, bool mucMode)
+ : emoticons_(emoticons), highlightRules_(highlightRules), mucMode_(mucMode) {
+ }
+
+ typedef std::pair<std::string, std::string> StringPair;
+
+ ChatWindow::ChatMessage ChatMessageParser::parseMessageBody(const std::string& body, const std::string& nick, bool senderIsSelf) {
+ ChatWindow::ChatMessage parsedMessage;
+ std::string remaining = body;
+ if (boost::starts_with(body, "/me ")) {
+ remaining = String::getSplittedAtFirst(body, ' ').second;
+ parsedMessage.setIsMeCommand(true);
+ }
+
+ /* Parse one, URLs */
+ while (!remaining.empty()) {
+ bool found = false;
+ std::pair<std::vector<std::string>, size_t> links = Linkify::splitLink(remaining);
+ remaining = "";
+ for (size_t i = 0; i < links.first.size(); i++) {
+ const std::string& part = links.first[i];
+ if (found) {
+ // Must be on the last part, then
+ remaining = part;
+ }
+ else {
+ if (i == links.second) {
+ found = true;
+ parsedMessage.append(std::make_shared<ChatWindow::ChatURIMessagePart>(part));
+ }
+ else {
+ parsedMessage.append(std::make_shared<ChatWindow::ChatTextMessagePart>(part));
+ }
+ }
+ }
+ }
+
+ /* do emoticon substitution */
+ parsedMessage = emoticonHighlight(parsedMessage);
+
+ if (!senderIsSelf) { /* do not highlight our own messsages */
+ /* do word-based color highlighting */
+ parsedMessage = splitHighlight(parsedMessage, nick);
+ }
+
+ return parsedMessage;
+ }
+
+ ChatWindow::ChatMessage ChatMessageParser::emoticonHighlight(const ChatWindow::ChatMessage& message) {
+ ChatWindow::ChatMessage parsedMessage = message;
+
+ std::string regexString;
+ /* Parse two, emoticons */
+ for (StringPair emoticon : emoticons_) {
+ /* Construct a regexp that finds an instance of any of the emoticons inside a group
+ * at the start or end of the line, or beside whitespace.
+ */
+ regexString += regexString.empty() ? "" : "|";
+ std::string escaped = "(" + Regex::escape(emoticon.first) + ")";
+ regexString += "^" + escaped + "|";
+ regexString += escaped + "$|";
+ regexString += "\\s" + escaped + "|";
+ regexString += escaped + "\\s";
+
+ }
+ if (!regexString.empty()) {
+ regexString += "";
+ boost::regex emoticonRegex(regexString);
+
+ ChatWindow::ChatMessage newMessage;
+ for (std::shared_ptr<ChatWindow::ChatMessagePart> part : parsedMessage.getParts()) {
+ std::shared_ptr<ChatWindow::ChatTextMessagePart> textPart;
+ if ((textPart = std::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(part))) {
+ try {
+ boost::match_results<std::string::const_iterator> match;
+ const std::string& text = textPart->text;
+ std::string::const_iterator start = text.begin();
+ while (regex_search(start, text.end(), match, emoticonRegex)) {
+ int matchIndex = 0;
+ for (matchIndex = 1; matchIndex < static_cast<int>(match.size()); matchIndex++) {
+ if (match[matchIndex].length() > 0) {
+ //This is the matching subgroup
+ break;
+ }
+ }
+ std::string::const_iterator matchStart = match[matchIndex].first;
+ std::string::const_iterator matchEnd = match[matchIndex].second;
+ if (start != matchStart) {
+ /* If we're skipping over plain text since the previous emoticon, record it as plain text */
+ newMessage.append(std::make_shared<ChatWindow::ChatTextMessagePart>(std::string(start, matchStart)));
+ }
+ std::shared_ptr<ChatWindow::ChatEmoticonMessagePart> emoticonPart = std::make_shared<ChatWindow::ChatEmoticonMessagePart>();
+ std::string matchString = match[matchIndex].str();
+ std::map<std::string, std::string>::const_iterator emoticonIterator = emoticons_.find(matchString);
+ assert (emoticonIterator != emoticons_.end());
+ const StringPair& emoticon = *emoticonIterator;
+ emoticonPart->imagePath = emoticon.second;
+ emoticonPart->alternativeText = emoticon.first;
+ newMessage.append(emoticonPart);
+ start = matchEnd;
+ }
+ if (start != text.end()) {
+ /* If there's plain text after the last emoticon, record it */
+ newMessage.append(std::make_shared<ChatWindow::ChatTextMessagePart>(std::string(start, text.end())));
+ }
+
+ }
+ catch (std::runtime_error) {
+ /* Basically too expensive to compute the regex results and it gave up, so pass through as text */
+ newMessage.append(part);
+ }
+ }
+ else {
+ newMessage.append(part);
+ }
+ }
+ parsedMessage.setParts(newMessage.getParts());
+ }
+ return parsedMessage;
+ }
+
+ ChatWindow::ChatMessage ChatMessageParser::splitHighlight(const ChatWindow::ChatMessage& message, const std::string& nick) {
+ ChatWindow::ChatMessage parsedMessage = message;
+
+ for (size_t i = 0; i < highlightRules_->getSize(); ++i) {
+ const HighlightRule& rule = highlightRules_->getRule(i);
+ if (rule.getMatchMUC() && !mucMode_) {
+ continue; /* this rule only applies to MUC's, and this is a CHAT */
+ } else if (rule.getMatchChat() && mucMode_) {
+ continue; /* this rule only applies to CHAT's, and this is a MUC */
+ } else if (rule.getAction().getTextBackground().empty() && rule.getAction().getTextColor().empty()) {
+ continue; /* do not try to highlight text, if no highlight color is specified */
+ }
+ const std::vector<boost::regex> keywordRegex = rule.getKeywordRegex(nick);
+ for (const boost::regex& regex : keywordRegex) {
+ ChatWindow::ChatMessage newMessage;
+ for (std::shared_ptr<ChatWindow::ChatMessagePart> part : parsedMessage.getParts()) {
+ std::shared_ptr<ChatWindow::ChatTextMessagePart> textPart;
+ if ((textPart = std::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(part))) {
+ try {
+ boost::match_results<std::string::const_iterator> match;
+ const std::string& text = textPart->text;
+ std::string::const_iterator start = text.begin();
+ while (regex_search(start, text.end(), match, regex)) {
+ std::string::const_iterator matchStart = match[0].first;
+ std::string::const_iterator matchEnd = match[0].second;
+ if (start != matchStart) {
+ /* If we're skipping over plain text since the previous emoticon, record it as plain text */
+ newMessage.append(std::make_shared<ChatWindow::ChatTextMessagePart>(std::string(start, matchStart)));
+ }
+ std::shared_ptr<ChatWindow::ChatHighlightingMessagePart> highlightPart = std::make_shared<ChatWindow::ChatHighlightingMessagePart>();
+ highlightPart->text = match.str();
+ highlightPart->action = rule.getAction();
+ newMessage.append(highlightPart);
+ start = matchEnd;
+ }
+ if (start != text.end()) {
+ /* If there's plain text after the last emoticon, record it */
+ newMessage.append(std::make_shared<ChatWindow::ChatTextMessagePart>(std::string(start, text.end())));
+ }
+ }
+ catch (std::runtime_error) {
+ /* Basically too expensive to compute the regex results and it gave up, so pass through as text */
+ newMessage.append(part);
+ }
+ } else {
+ newMessage.append(part);
+ }
+ }
+ parsedMessage.setParts(newMessage.getParts());
+ }
+ }
+
+ return parsedMessage;
+ }
}
diff --git a/Swift/Controllers/Chat/ChatMessageParser.h b/Swift/Controllers/Chat/ChatMessageParser.h
index e56d21b..4bed669 100644
--- a/Swift/Controllers/Chat/ChatMessageParser.h
+++ b/Swift/Controllers/Chat/ChatMessageParser.h
@@ -12,15 +12,15 @@
namespace Swift {
- class ChatMessageParser {
- public:
- ChatMessageParser(const std::map<std::string, std::string>& emoticons, HighlightRulesListPtr highlightRules, bool mucMode = false);
- ChatWindow::ChatMessage parseMessageBody(const std::string& body, const std::string& nick = "", bool senderIsSelf = false);
- private:
- ChatWindow::ChatMessage emoticonHighlight(const ChatWindow::ChatMessage& parsedMessage);
- ChatWindow::ChatMessage splitHighlight(const ChatWindow::ChatMessage& parsedMessage, const std::string& nick);
- std::map<std::string, std::string> emoticons_;
- HighlightRulesListPtr highlightRules_;
- bool mucMode_;
- };
+ class ChatMessageParser {
+ public:
+ ChatMessageParser(const std::map<std::string, std::string>& emoticons, HighlightRulesListPtr highlightRules, bool mucMode = false);
+ ChatWindow::ChatMessage parseMessageBody(const std::string& body, const std::string& nick = "", bool senderIsSelf = false);
+ private:
+ ChatWindow::ChatMessage emoticonHighlight(const ChatWindow::ChatMessage& parsedMessage);
+ ChatWindow::ChatMessage splitHighlight(const ChatWindow::ChatMessage& parsedMessage, const std::string& nick);
+ std::map<std::string, std::string> emoticons_;
+ HighlightRulesListPtr highlightRules_;
+ bool mucMode_;
+ };
}
diff --git a/Swift/Controllers/Chat/ChatsManager.cpp b/Swift/Controllers/Chat/ChatsManager.cpp
index 49caee4..f55df1e 100644
--- a/Swift/Controllers/Chat/ChatsManager.cpp
+++ b/Swift/Controllers/Chat/ChatsManager.cpp
@@ -6,6 +6,8 @@
#include <Swift/Controllers/Chat/ChatsManager.h>
+#include <memory>
+
#include <boost/algorithm/string.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
@@ -15,18 +17,20 @@
#include <boost/serialization/split_free.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/vector.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
#include <Swiften/Avatars/AvatarManager.h>
#include <Swiften/Base/Log.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Client/ClientBlockListManager.h>
#include <Swiften/Client/NickResolver.h>
#include <Swiften/Client/StanzaChannel.h>
#include <Swiften/Disco/DiscoServiceWalker.h>
+#include <Swiften/Disco/FeatureOracle.h>
+#include <Swiften/Elements/CarbonsReceived.h>
+#include <Swiften/Elements/CarbonsSent.h>
#include <Swiften/Elements/ChatState.h>
#include <Swiften/Elements/DeliveryReceipt.h>
#include <Swiften/Elements/DeliveryReceiptRequest.h>
+#include <Swiften/Elements/Forwarded.h>
#include <Swiften/Elements/MUCInvitationPayload.h>
#include <Swiften/Elements/MUCUserPayload.h>
#include <Swiften/MUC/MUCBookmarkManager.h>
@@ -56,43 +60,43 @@
#include <Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h>
+#include <Swift/Controllers/UIEvents/SendFileUIEvent.h>
#include <Swift/Controllers/UIInterfaces/ChatListWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/JoinMUCWindow.h>
#include <Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h>
#include <Swift/Controllers/WhiteboardManager.h>
#include <Swift/Controllers/XMPPEvents/EventController.h>
-#include <Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h>
BOOST_CLASS_VERSION(Swift::ChatListWindow::Chat, 1)
namespace boost {
namespace serialization {
- template<class Archive> void save(Archive& ar, const Swift::JID& jid, const unsigned int /*version*/) {
- std::string jidStr = jid.toString();
- ar << jidStr;
- }
-
- template<class Archive> void load(Archive& ar, Swift::JID& jid, const unsigned int /*version*/) {
- std::string stringJID;
- ar >> stringJID;
- jid = Swift::JID(stringJID);
- }
-
- template<class Archive> inline void serialize(Archive& ar, Swift::JID& t, const unsigned int file_version){
- split_free(ar, t, file_version);
- }
-
- template<class Archive> void serialize(Archive& ar, Swift::ChatListWindow::Chat& chat, const unsigned int version) {
- ar & chat.jid;
- ar & chat.chatName;
- ar & chat.activity;
- ar & chat.isMUC;
- ar & chat.nick;
- ar & chat.impromptuJIDs;
- if (version > 0) {
- ar & chat.password;
- }
- }
+ template<class Archive> void save(Archive& ar, const Swift::JID& jid, const unsigned int /*version*/) {
+ std::string jidStr = jid.toString();
+ ar << jidStr;
+ }
+
+ template<class Archive> void load(Archive& ar, Swift::JID& jid, const unsigned int /*version*/) {
+ std::string stringJID;
+ ar >> stringJID;
+ jid = Swift::JID(stringJID);
+ }
+
+ template<class Archive> inline void serialize(Archive& ar, Swift::JID& t, const unsigned int file_version){
+ split_free(ar, t, file_version);
+ }
+
+ template<class Archive> void serialize(Archive& ar, Swift::ChatListWindow::Chat& chat, const unsigned int version) {
+ ar & chat.jid;
+ ar & chat.chatName;
+ ar & chat.activity;
+ ar & chat.isMUC;
+ ar & chat.nick;
+ ar & chat.impromptuJIDs;
+ if (version > 0) {
+ ar & chat.password;
+ }
+ }
}
}
@@ -104,950 +108,1008 @@ typedef std::pair<JID, MUCController*> JIDMUCControllerPair;
#define RECENT_CHATS "recent_chats"
ChatsManager::ChatsManager(
- JID jid, StanzaChannel* stanzaChannel,
- IQRouter* iqRouter,
- EventController* eventController,
- ChatWindowFactory* chatWindowFactory,
- JoinMUCWindowFactory* joinMUCWindowFactory,
- NickResolver* nickResolver,
- PresenceOracle* presenceOracle,
- PresenceSender* presenceSender,
- UIEventStream* uiEventStream,
- ChatListWindowFactory* chatListWindowFactory,
- bool useDelayForLatency,
- TimerFactory* timerFactory,
- MUCRegistry* mucRegistry,
- EntityCapsProvider* entityCapsProvider,
- MUCManager* mucManager,
- MUCSearchWindowFactory* mucSearchWindowFactory,
- ProfileSettingsProvider* profileSettings,
- FileTransferOverview* ftOverview,
- XMPPRoster* roster,
- bool eagleMode,
- SettingsProvider* settings,
- HistoryController* historyController,
- WhiteboardManager* whiteboardManager,
- HighlightManager* highlightManager,
- ClientBlockListManager* clientBlockListManager,
- const std::map<std::string, std::string>& emoticons,
- VCardManager* vcardManager) :
- jid_(jid),
- joinMUCWindowFactory_(joinMUCWindowFactory),
- useDelayForLatency_(useDelayForLatency),
- mucRegistry_(mucRegistry),
- entityCapsProvider_(entityCapsProvider),
- mucManager(mucManager),
- ftOverview_(ftOverview),
- roster_(roster),
- eagleMode_(eagleMode),
- settings_(settings),
- historyController_(historyController),
- whiteboardManager_(whiteboardManager),
- highlightManager_(highlightManager),
- emoticons_(emoticons),
- clientBlockListManager_(clientBlockListManager),
- vcardManager_(vcardManager) {
- timerFactory_ = timerFactory;
- eventController_ = eventController;
- stanzaChannel_ = stanzaChannel;
- iqRouter_ = iqRouter;
- chatWindowFactory_ = chatWindowFactory;
- nickResolver_ = nickResolver;
- presenceOracle_ = presenceOracle;
- avatarManager_ = NULL;
- serverDiscoInfo_ = boost::make_shared<DiscoInfo>();
- presenceSender_ = presenceSender;
- uiEventStream_ = uiEventStream;
- mucBookmarkManager_ = NULL;
- profileSettings_ = profileSettings;
- presenceOracle_->onPresenceChange.connect(boost::bind(&ChatsManager::handlePresenceChange, this, _1));
- uiEventConnection_ = uiEventStream_->onUIEvent.connect(boost::bind(&ChatsManager::handleUIEvent, this, _1));
-
- chatListWindow_ = chatListWindowFactory->createChatListWindow(uiEventStream_);
- chatListWindow_->onMUCBookmarkActivated.connect(boost::bind(&ChatsManager::handleMUCBookmarkActivated, this, _1));
- chatListWindow_->onRecentActivated.connect(boost::bind(&ChatsManager::handleRecentActivated, this, _1));
- chatListWindow_->onClearRecentsRequested.connect(boost::bind(&ChatsManager::handleClearRecentsRequested, this));
-
- joinMUCWindow_ = NULL;
- mucSearchController_ = new MUCSearchController(jid_, mucSearchWindowFactory, iqRouter, profileSettings_);
- mucSearchController_->onMUCSelected.connect(boost::bind(&ChatsManager::handleMUCSelectedAfterSearch, this, _1));
- ftOverview_->onNewFileTransferController.connect(boost::bind(&ChatsManager::handleNewFileTransferController, this, _1));
- whiteboardManager_->onSessionRequest.connect(boost::bind(&ChatsManager::handleWhiteboardSessionRequest, this, _1, _2));
- whiteboardManager_->onRequestAccepted.connect(boost::bind(&ChatsManager::handleWhiteboardStateChange, this, _1, ChatWindow::WhiteboardAccepted));
- whiteboardManager_->onSessionTerminate.connect(boost::bind(&ChatsManager::handleWhiteboardStateChange, this, _1, ChatWindow::WhiteboardTerminated));
- whiteboardManager_->onRequestRejected.connect(boost::bind(&ChatsManager::handleWhiteboardStateChange, this, _1, ChatWindow::WhiteboardRejected));
- roster_->onJIDAdded.connect(boost::bind(&ChatsManager::handleJIDAddedToRoster, this, _1));
- roster_->onJIDRemoved.connect(boost::bind(&ChatsManager::handleJIDRemovedFromRoster, this, _1));
- roster_->onJIDUpdated.connect(boost::bind(&ChatsManager::handleJIDUpdatedInRoster, this, _1));
- roster_->onRosterCleared.connect(boost::bind(&ChatsManager::handleRosterCleared, this));
-
- settings_->onSettingChanged.connect(boost::bind(&ChatsManager::handleSettingChanged, this, _1));
-
- userWantsReceipts_ = settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS);
-
- setupBookmarks();
- loadRecents();
-
- autoAcceptMUCInviteDecider_ = new AutoAcceptMUCInviteDecider(jid.getDomain(), roster_, settings_);
+ JID jid, StanzaChannel* stanzaChannel,
+ IQRouter* iqRouter,
+ EventController* eventController,
+ ChatWindowFactory* chatWindowFactory,
+ JoinMUCWindowFactory* joinMUCWindowFactory,
+ NickResolver* nickResolver,
+ PresenceOracle* presenceOracle,
+ PresenceSender* presenceSender,
+ UIEventStream* uiEventStream,
+ ChatListWindowFactory* chatListWindowFactory,
+ bool useDelayForLatency,
+ TimerFactory* timerFactory,
+ MUCRegistry* mucRegistry,
+ EntityCapsProvider* entityCapsProvider,
+ MUCManager* mucManager,
+ MUCSearchWindowFactory* mucSearchWindowFactory,
+ ProfileSettingsProvider* profileSettings,
+ FileTransferOverview* ftOverview,
+ XMPPRoster* roster,
+ bool eagleMode,
+ SettingsProvider* settings,
+ HistoryController* historyController,
+ WhiteboardManager* whiteboardManager,
+ HighlightManager* highlightManager,
+ ClientBlockListManager* clientBlockListManager,
+ const std::map<std::string, std::string>& emoticons,
+ VCardManager* vcardManager) :
+ jid_(jid),
+ joinMUCWindowFactory_(joinMUCWindowFactory),
+ useDelayForLatency_(useDelayForLatency),
+ mucRegistry_(mucRegistry),
+ entityCapsProvider_(entityCapsProvider),
+ mucManager(mucManager),
+ ftOverview_(ftOverview),
+ roster_(roster),
+ eagleMode_(eagleMode),
+ settings_(settings),
+ historyController_(historyController),
+ whiteboardManager_(whiteboardManager),
+ highlightManager_(highlightManager),
+ emoticons_(emoticons),
+ clientBlockListManager_(clientBlockListManager),
+ vcardManager_(vcardManager) {
+ timerFactory_ = timerFactory;
+ eventController_ = eventController;
+ stanzaChannel_ = stanzaChannel;
+ iqRouter_ = iqRouter;
+ chatWindowFactory_ = chatWindowFactory;
+ nickResolver_ = nickResolver;
+ presenceOracle_ = presenceOracle;
+ avatarManager_ = nullptr;
+ serverDiscoInfo_ = std::make_shared<DiscoInfo>();
+ presenceSender_ = presenceSender;
+ uiEventStream_ = uiEventStream;
+ mucBookmarkManager_ = nullptr;
+ profileSettings_ = profileSettings;
+ presenceOracle_->onPresenceChange.connect(boost::bind(&ChatsManager::handlePresenceChange, this, _1));
+ uiEventConnection_ = uiEventStream_->onUIEvent.connect(boost::bind(&ChatsManager::handleUIEvent, this, _1));
+
+ chatListWindow_ = chatListWindowFactory->createChatListWindow(uiEventStream_);
+ chatListWindow_->onMUCBookmarkActivated.connect(boost::bind(&ChatsManager::handleMUCBookmarkActivated, this, _1));
+ chatListWindow_->onRecentActivated.connect(boost::bind(&ChatsManager::handleRecentActivated, this, _1));
+ chatListWindow_->onClearRecentsRequested.connect(boost::bind(&ChatsManager::handleClearRecentsRequested, this));
+
+ joinMUCWindow_ = nullptr;
+ mucSearchController_ = new MUCSearchController(jid_, mucSearchWindowFactory, iqRouter, profileSettings_);
+ mucSearchController_->onMUCSelected.connect(boost::bind(&ChatsManager::handleMUCSelectedAfterSearch, this, _1));
+ ftOverview_->onNewFileTransferController.connect(boost::bind(&ChatsManager::handleNewFileTransferController, this, _1));
+ whiteboardManager_->onSessionRequest.connect(boost::bind(&ChatsManager::handleWhiteboardSessionRequest, this, _1, _2));
+ whiteboardManager_->onRequestAccepted.connect(boost::bind(&ChatsManager::handleWhiteboardStateChange, this, _1, ChatWindow::WhiteboardAccepted));
+ whiteboardManager_->onSessionTerminate.connect(boost::bind(&ChatsManager::handleWhiteboardStateChange, this, _1, ChatWindow::WhiteboardTerminated));
+ whiteboardManager_->onRequestRejected.connect(boost::bind(&ChatsManager::handleWhiteboardStateChange, this, _1, ChatWindow::WhiteboardRejected));
+ roster_->onJIDAdded.connect(boost::bind(&ChatsManager::handleJIDAddedToRoster, this, _1));
+ roster_->onJIDRemoved.connect(boost::bind(&ChatsManager::handleJIDRemovedFromRoster, this, _1));
+ roster_->onJIDUpdated.connect(boost::bind(&ChatsManager::handleJIDUpdatedInRoster, this, _1));
+ roster_->onRosterCleared.connect(boost::bind(&ChatsManager::handleRosterCleared, this));
+
+ settings_->onSettingChanged.connect(boost::bind(&ChatsManager::handleSettingChanged, this, _1));
+
+ userWantsReceipts_ = settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS);
+
+ setupBookmarks();
+ loadRecents();
+
+ autoAcceptMUCInviteDecider_ = new AutoAcceptMUCInviteDecider(jid.getDomain(), roster_, settings_);
}
ChatsManager::~ChatsManager() {
- settings_->onSettingChanged.disconnect(boost::bind(&ChatsManager::handleSettingChanged, this, _1));
- roster_->onJIDAdded.disconnect(boost::bind(&ChatsManager::handleJIDAddedToRoster, this, _1));
- roster_->onJIDRemoved.disconnect(boost::bind(&ChatsManager::handleJIDRemovedFromRoster, this, _1));
- roster_->onJIDUpdated.disconnect(boost::bind(&ChatsManager::handleJIDUpdatedInRoster, this, _1));
- roster_->onRosterCleared.disconnect(boost::bind(&ChatsManager::handleRosterCleared, this));
- delete joinMUCWindow_;
- foreach (JIDChatControllerPair controllerPair, chatControllers_) {
- delete controllerPair.second;
- }
- foreach (JIDMUCControllerPair controllerPair, mucControllers_) {
- delete controllerPair.second;
- }
- delete mucBookmarkManager_;
- delete mucSearchController_;
- delete autoAcceptMUCInviteDecider_;
+ settings_->onSettingChanged.disconnect(boost::bind(&ChatsManager::handleSettingChanged, this, _1));
+ roster_->onJIDAdded.disconnect(boost::bind(&ChatsManager::handleJIDAddedToRoster, this, _1));
+ roster_->onJIDRemoved.disconnect(boost::bind(&ChatsManager::handleJIDRemovedFromRoster, this, _1));
+ roster_->onJIDUpdated.disconnect(boost::bind(&ChatsManager::handleJIDUpdatedInRoster, this, _1));
+ roster_->onRosterCleared.disconnect(boost::bind(&ChatsManager::handleRosterCleared, this));
+ ftOverview_->onNewFileTransferController.disconnect(boost::bind(&ChatsManager::handleNewFileTransferController, this, _1));
+ delete joinMUCWindow_;
+ for (JIDChatControllerPair controllerPair : chatControllers_) {
+ delete controllerPair.second;
+ }
+ for (JIDMUCControllerPair controllerPair : mucControllers_) {
+ delete controllerPair.second;
+ }
+ delete mucBookmarkManager_;
+ delete mucSearchController_;
+ delete autoAcceptMUCInviteDecider_;
}
void ChatsManager::saveRecents() {
- std::stringstream serializeStream;
- boost::archive::text_oarchive oa(serializeStream);
- std::vector<ChatListWindow::Chat> recentsLimited = std::vector<ChatListWindow::Chat>(recentChats_.begin(), recentChats_.end());
- if (recentsLimited.size() > 25) {
- recentsLimited.erase(recentsLimited.begin() + 25, recentsLimited.end());
- }
- if (eagleMode_) {
- foreach(ChatListWindow::Chat& chat, recentsLimited) {
- chat.activity = "";
- }
- }
-
- class RemoveRecent {
- public:
- static bool ifPrivateMessage(const ChatListWindow::Chat& chat) {
- return chat.isPrivateMessage;
- }
- };
-
- recentsLimited.erase(std::remove_if(recentsLimited.begin(), recentsLimited.end(), RemoveRecent::ifPrivateMessage), recentsLimited.end());
-
- oa << recentsLimited;
- std::string serializedStr = Base64::encode(createByteArray(serializeStream.str()));
- profileSettings_->storeString(RECENT_CHATS, serializedStr);
+ std::stringstream serializeStream;
+ boost::archive::text_oarchive oa(serializeStream);
+ std::vector<ChatListWindow::Chat> recentsLimited = std::vector<ChatListWindow::Chat>(recentChats_.begin(), recentChats_.end());
+ if (recentsLimited.size() > 25) {
+ recentsLimited.erase(recentsLimited.begin() + 25, recentsLimited.end());
+ }
+ if (eagleMode_) {
+ for (ChatListWindow::Chat& chat : recentsLimited) {
+ chat.activity = "";
+ }
+ }
+
+ class RemoveRecent {
+ public:
+ static bool ifPrivateMessage(const ChatListWindow::Chat& chat) {
+ return chat.isPrivateMessage;
+ }
+ };
+
+ recentsLimited.erase(std::remove_if(recentsLimited.begin(), recentsLimited.end(), RemoveRecent::ifPrivateMessage), recentsLimited.end());
+
+ oa & recentsLimited;
+ std::string serializedStr = Base64::encode(createByteArray(serializeStream.str()));
+ profileSettings_->storeString(RECENT_CHATS, serializedStr);
}
void ChatsManager::handleClearRecentsRequested() {
- recentChats_.clear();
- saveRecents();
- handleUnreadCountChanged(NULL);
+ recentChats_.clear();
+ saveRecents();
+ handleUnreadCountChanged(nullptr);
}
void ChatsManager::handleJIDAddedToRoster(const JID &jid) {
- updatePresenceReceivingStateOnChatController(jid);
+ updatePresenceReceivingStateOnChatController(jid);
}
void ChatsManager::handleJIDRemovedFromRoster(const JID &jid) {
- updatePresenceReceivingStateOnChatController(jid);
+ updatePresenceReceivingStateOnChatController(jid);
}
void ChatsManager::handleJIDUpdatedInRoster(const JID &jid) {
- updatePresenceReceivingStateOnChatController(jid);
+ updatePresenceReceivingStateOnChatController(jid);
}
void ChatsManager::handleRosterCleared() {
- /* Setting that all chat controllers aren't receiving presence anymore;
- including MUC 1-to-1 chats due to the assumtion that this handler
- is only called on log out. */
- foreach(JIDChatControllerPair pair, chatControllers_) {
- pair.second->setContactIsReceivingPresence(false);
- }
+ /* Setting that all chat controllers aren't receiving presence anymore;
+ including MUC 1-to-1 chats due to the assumtion that this handler
+ is only called on log out. */
+ for (JIDChatControllerPair pair : chatControllers_) {
+ pair.second->setContactIsReceivingPresence(false);
+ }
}
void ChatsManager::updatePresenceReceivingStateOnChatController(const JID &jid) {
- ChatController* controller = getChatControllerIfExists(jid);
- if (controller) {
- if (!mucRegistry_->isMUC(jid.toBare())) {
- RosterItemPayload::Subscription subscription = roster_->getSubscriptionStateForJID(jid);
- controller->setContactIsReceivingPresence(subscription == RosterItemPayload::From || subscription == RosterItemPayload::Both);
- } else {
- controller->setContactIsReceivingPresence(true);
- }
- }
+ ChatController* controller = getChatControllerIfExists(jid);
+ if (controller) {
+ if (!mucRegistry_->isMUC(jid.toBare())) {
+ RosterItemPayload::Subscription subscription = roster_->getSubscriptionStateForJID(jid);
+ controller->setContactIsReceivingPresence(subscription == RosterItemPayload::From || subscription == RosterItemPayload::Both);
+ } else {
+ controller->setContactIsReceivingPresence(true);
+ }
+ }
}
ChatListWindow::Chat ChatsManager::updateChatStatusAndAvatarHelper(const ChatListWindow::Chat& chat) const {
- ChatListWindow::Chat fixedChat = chat;
- if (fixedChat.isMUC) {
- if (mucControllers_.find(fixedChat.jid.toBare()) != mucControllers_.end()) {
- fixedChat.statusType = StatusShow::Online;
- }
- } else {
- if (avatarManager_) {
- fixedChat.avatarPath = avatarManager_->getAvatarPath(fixedChat.jid);
- }
- Presence::ref presence = presenceOracle_->getAccountPresence(fixedChat.jid.toBare());
- fixedChat.statusType = presence ? presence->getShow() : StatusShow::None;
- }
- return fixedChat;
+ ChatListWindow::Chat fixedChat = chat;
+ if (fixedChat.isMUC) {
+ if (mucControllers_.find(fixedChat.jid.toBare()) != mucControllers_.end()) {
+ fixedChat.statusType = StatusShow::Online;
+ }
+ } else {
+ if (avatarManager_) {
+ fixedChat.avatarPath = avatarManager_->getAvatarPath(fixedChat.jid);
+ }
+ Presence::ref presence = presenceOracle_->getAccountPresence(fixedChat.jid.toBare());
+ fixedChat.statusType = presence ? presence->getShow() : StatusShow::None;
+ }
+ return fixedChat;
}
void ChatsManager::loadRecents() {
- std::string recentsString(profileSettings_->getStringSetting(RECENT_CHATS));
- if (recentsString.find("\t") != std::string::npos) {
- // old format
- std::vector<std::string> recents;
- boost::split(recents, recentsString, boost::is_any_of("\n"));
- int i = 0;
- foreach (std::string recentString, recents) {
- if (i++ > 30) {
- break;
- }
- std::vector<std::string> recent;
- boost::split(recent, recentString, boost::is_any_of("\t"));
- if (recent.size() < 4) {
- continue;
- }
- JID jid(recent[0]);
- if (!jid.isValid()) {
- continue;
- }
- std::string activity(recent[1]);
- bool isMUC = recent[2] == "true";
- std::string nick(recent[3]);
- StatusShow::Type type = StatusShow::None;
- boost::filesystem::path path;
-
- ChatListWindow::Chat chat(jid, nickResolver_->jidToNick(jid), activity, 0, type, path, isMUC, false, nick);
- chat = updateChatStatusAndAvatarHelper(chat);
- prependRecent(chat);
- }
- } else if (!recentsString.empty()){
- // boost searilaize based format
- ByteArray debase64 = Base64::decode(recentsString);
- std::vector<ChatListWindow::Chat> recentChats;
- std::stringstream deserializeStream(std::string(reinterpret_cast<const char*>(vecptr(debase64)), debase64.size()));
- try {
- boost::archive::text_iarchive ia(deserializeStream);
- ia >> recentChats;
- } catch (const boost::archive::archive_exception& e) {
- SWIFT_LOG(debug) << "Failed to load recents: " << e.what() << std::endl;
- return;
- }
-
- foreach(ChatListWindow::Chat chat, recentChats) {
- chat.statusType = StatusShow::None;
- chat = updateChatStatusAndAvatarHelper(chat);
- prependRecent(chat);
- }
- }
- handleUnreadCountChanged(NULL);
+ std::string recentsString(profileSettings_->getStringSetting(RECENT_CHATS));
+ if (recentsString.find("\t") != std::string::npos) {
+ // old format
+ std::vector<std::string> recents;
+ boost::split(recents, recentsString, boost::is_any_of("\n"));
+ int i = 0;
+ for (std::string recentString : recents) {
+ if (i++ > 30) {
+ break;
+ }
+ std::vector<std::string> recent;
+ boost::split(recent, recentString, boost::is_any_of("\t"));
+ if (recent.size() < 4) {
+ continue;
+ }
+ JID jid(recent[0]);
+ if (!jid.isValid()) {
+ continue;
+ }
+ std::string activity(recent[1]);
+ bool isMUC = recent[2] == "true";
+ std::string nick(recent[3]);
+ StatusShow::Type type = StatusShow::None;
+ boost::filesystem::path path;
+
+ ChatListWindow::Chat chat(jid, nickResolver_->jidToNick(jid), activity, 0, type, path, isMUC, false, nick);
+ chat = updateChatStatusAndAvatarHelper(chat);
+ prependRecent(chat);
+ }
+ } else if (!recentsString.empty()){
+ // boost searilaize based format
+ ByteArray debase64 = Base64::decode(recentsString);
+ std::vector<ChatListWindow::Chat> recentChats;
+ std::stringstream deserializeStream(std::string(reinterpret_cast<const char*>(vecptr(debase64)), debase64.size()));
+ try {
+ boost::archive::text_iarchive ia(deserializeStream);
+ ia >> recentChats;
+ } catch (const boost::archive::archive_exception& e) {
+ SWIFT_LOG(debug) << "Failed to load recents: " << e.what() << std::endl;
+ return;
+ }
+
+ for (auto chat : recentChats) {
+ chat.statusType = StatusShow::None;
+ chat = updateChatStatusAndAvatarHelper(chat);
+ prependRecent(chat);
+ }
+ }
+ handleUnreadCountChanged(nullptr);
}
void ChatsManager::setupBookmarks() {
- if (!mucBookmarkManager_) {
- mucBookmarkManager_ = new MUCBookmarkManager(iqRouter_);
- mucBookmarkManager_->onBookmarksReady.connect(boost::bind(&ChatsManager::handleBookmarksReady, this));
- mucBookmarkManager_->onBookmarkAdded.connect(boost::bind(&ChatsManager::handleMUCBookmarkAdded, this, _1));
- mucBookmarkManager_->onBookmarkRemoved.connect(boost::bind(&ChatsManager::handleMUCBookmarkRemoved, this, _1));
-
- if (chatListWindow_) {
- chatListWindow_->setBookmarksEnabled(false);
- chatListWindow_->clearBookmarks();
- }
- }
+ if (!mucBookmarkManager_) {
+ mucBookmarkManager_ = new MUCBookmarkManager(iqRouter_);
+ mucBookmarkManager_->onBookmarksReady.connect(boost::bind(&ChatsManager::handleBookmarksReady, this));
+ mucBookmarkManager_->onBookmarkAdded.connect(boost::bind(&ChatsManager::handleMUCBookmarkAdded, this, _1));
+ mucBookmarkManager_->onBookmarkRemoved.connect(boost::bind(&ChatsManager::handleMUCBookmarkRemoved, this, _1));
+
+ if (chatListWindow_) {
+ chatListWindow_->setBookmarksEnabled(false);
+ chatListWindow_->clearBookmarks();
+ }
+ }
}
void ChatsManager::handleBookmarksReady() {
- if (chatListWindow_) {
- chatListWindow_->setBookmarksEnabled(true);
- }
+ if (chatListWindow_) {
+ chatListWindow_->setBookmarksEnabled(true);
+ }
}
void ChatsManager::handleMUCBookmarkAdded(const MUCBookmark& bookmark) {
- std::map<JID, MUCController*>::iterator it = mucControllers_.find(bookmark.getRoom());
- if (it == mucControllers_.end() && bookmark.getAutojoin()) {
- handleJoinMUCRequest(bookmark.getRoom(), bookmark.getPassword(), bookmark.getNick(), false, false, false );
- }
- chatListWindow_->addMUCBookmark(bookmark);
+ std::map<JID, MUCController*>::iterator it = mucControllers_.find(bookmark.getRoom());
+ if (it == mucControllers_.end() && bookmark.getAutojoin()) {
+ handleJoinMUCRequest(bookmark.getRoom(), bookmark.getPassword(), bookmark.getNick(), false, false, false );
+ }
+ chatListWindow_->addMUCBookmark(bookmark);
}
void ChatsManager::handleMUCBookmarkRemoved(const MUCBookmark& bookmark) {
- chatListWindow_->removeMUCBookmark(bookmark);
+ chatListWindow_->removeMUCBookmark(bookmark);
}
ChatListWindow::Chat ChatsManager::createChatListChatItem(const JID& jid, const std::string& activity, bool privateMessage) {
- int unreadCount = 0;
- if (mucRegistry_->isMUC(jid)) {
- MUCController* controller = mucControllers_[jid.toBare()];
- StatusShow::Type type = StatusShow::None;
- std::string nick = "";
- std::string password = "";
- if (controller) {
- unreadCount = controller->getUnreadCount();
- if (controller->isJoined()) {
- type = StatusShow::Online;
- }
- nick = controller->getNick();
-
- if (controller->getPassword()) {
- password = *controller->getPassword();
- }
-
- if (controller->isImpromptu()) {
- ChatListWindow::Chat chat = ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, boost::filesystem::path(), true, privateMessage, nick, password);
- std::map<std::string, JID> participants = controller->getParticipantJIDs();
- chat.impromptuJIDs = participants;
- return chat;
- }
- }
- return ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, boost::filesystem::path(), true, privateMessage, nick, password);
- } else {
- ChatController* controller = getChatControllerIfExists(jid, false);
- if (controller) {
- unreadCount = controller->getUnreadCount();
- }
- JID bareishJID = mucRegistry_->isMUC(jid.toBare()) ? jid : jid.toBare();
- Presence::ref presence = presenceOracle_->getAccountPresence(bareishJID);
- StatusShow::Type type = presence ? presence->getShow() : StatusShow::None;
- boost::filesystem::path avatarPath = avatarManager_ ? avatarManager_->getAvatarPath(bareishJID) : boost::filesystem::path();
- return ChatListWindow::Chat(bareishJID, nickResolver_->jidToNick(bareishJID), activity, unreadCount, type, avatarPath, false, privateMessage);
- }
+ int unreadCount = 0;
+ if (mucRegistry_->isMUC(jid)) {
+ MUCController* controller = mucControllers_[jid.toBare()];
+ StatusShow::Type type = StatusShow::None;
+ std::string nick = "";
+ std::string password = "";
+ if (controller) {
+ unreadCount = controller->getUnreadCount();
+ if (controller->isJoined()) {
+ type = StatusShow::Online;
+ }
+ nick = controller->getNick();
+
+ if (controller->getPassword()) {
+ password = *controller->getPassword();
+ }
+
+ if (controller->isImpromptu()) {
+ ChatListWindow::Chat chat = ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, boost::filesystem::path(), true, privateMessage, nick, password);
+ std::map<std::string, JID> participants = controller->getParticipantJIDs();
+ chat.impromptuJIDs = participants;
+ return chat;
+ }
+ }
+ return ChatListWindow::Chat(jid, jid.toString(), activity, unreadCount, type, boost::filesystem::path(), true, privateMessage, nick, password);
+ } else {
+ ChatController* controller = getChatControllerIfExists(jid, false);
+ if (controller) {
+ unreadCount = controller->getUnreadCount();
+ }
+ JID bareishJID = mucRegistry_->isMUC(jid.toBare()) ? jid : jid.toBare();
+ Presence::ref presence = presenceOracle_->getAccountPresence(bareishJID);
+ StatusShow::Type type = presence ? presence->getShow() : StatusShow::None;
+ boost::filesystem::path avatarPath = avatarManager_ ? avatarManager_->getAvatarPath(bareishJID) : boost::filesystem::path();
+ return ChatListWindow::Chat(bareishJID, nickResolver_->jidToNick(bareishJID), activity, unreadCount, type, avatarPath, false, privateMessage);
+ }
}
void ChatsManager::handleChatActivity(const JID& jid, const std::string& activity, bool isMUC) {
- const bool privateMessage = mucRegistry_->isMUC(jid.toBare()) && !isMUC;
- ChatListWindow::Chat chat = createChatListChatItem(jid, activity, privateMessage);
- /* FIXME: handle nick changes */
- appendRecent(chat);
- handleUnreadCountChanged(NULL);
- saveRecents();
+ const bool privateMessage = mucRegistry_->isMUC(jid.toBare()) && !isMUC;
+ ChatListWindow::Chat chat = createChatListChatItem(jid, activity, privateMessage);
+ /* FIXME: handle nick changes */
+ appendRecent(chat);
+ handleUnreadCountChanged(nullptr);
+ saveRecents();
}
void ChatsManager::handleChatClosed(const JID& /*jid*/) {
- cleanupPrivateMessageRecents();
- chatListWindow_->setRecents(recentChats_);
+ cleanupPrivateMessageRecents();
+ chatListWindow_->setRecents(recentChats_);
}
void ChatsManager::handleUnreadCountChanged(ChatControllerBase* controller) {
- int unreadTotal = 0;
- bool controllerIsMUC = dynamic_cast<MUCController*>(controller);
- bool isPM = controller && !controllerIsMUC && mucRegistry_->isMUC(controller->getToJID().toBare());
- foreach (ChatListWindow::Chat& chatItem, recentChats_) {
- bool match = false;
- if (controller) {
- /* Matching MUC item */
- match |= chatItem.isMUC == controllerIsMUC && chatItem.jid.toBare() == controller->getToJID().toBare();
- /* Matching PM */
- match |= isPM && chatItem.jid == controller->getToJID();
- /* Matching non-PM */
- match |= !isPM && !controllerIsMUC && chatItem.jid.toBare() == controller->getToJID().toBare();
- }
- if (match) {
- chatItem.setUnreadCount(controller->getUnreadCount());
- }
- unreadTotal += chatItem.unreadCount;
- }
- chatListWindow_->setRecents(recentChats_);
- chatListWindow_->setUnreadCount(unreadTotal);
+ int unreadTotal = 0;
+ bool controllerIsMUC = dynamic_cast<MUCController*>(controller);
+ bool isPM = controller && !controllerIsMUC && mucRegistry_->isMUC(controller->getToJID().toBare());
+ for (ChatListWindow::Chat& chatItem : recentChats_) {
+ bool match = false;
+ if (controller) {
+ /* Matching MUC item */
+ match |= chatItem.isMUC == controllerIsMUC && chatItem.jid.toBare() == controller->getToJID().toBare();
+ /* Matching PM */
+ match |= isPM && chatItem.jid == controller->getToJID();
+ /* Matching non-PM */
+ match |= !isPM && !controllerIsMUC && chatItem.jid.toBare() == controller->getToJID().toBare();
+ }
+ if (match) {
+ chatItem.setUnreadCount(controller->getUnreadCount());
+ }
+ unreadTotal += chatItem.unreadCount;
+ }
+ chatListWindow_->setRecents(recentChats_);
+ chatListWindow_->setUnreadCount(unreadTotal);
}
boost::optional<ChatListWindow::Chat> ChatsManager::removeExistingChat(const ChatListWindow::Chat& chat) {
- std::list<ChatListWindow::Chat>::iterator result = std::find(recentChats_.begin(), recentChats_.end(), chat);
- if (result != recentChats_.end()) {
- ChatListWindow::Chat existingChat = *result;
- recentChats_.erase(std::remove(recentChats_.begin(), recentChats_.end(), chat), recentChats_.end());
- return boost::optional<ChatListWindow::Chat>(existingChat);
- } else {
- return boost::optional<ChatListWindow::Chat>();
- }
+ std::list<ChatListWindow::Chat>::iterator result = std::find(recentChats_.begin(), recentChats_.end(), chat);
+ if (result != recentChats_.end()) {
+ ChatListWindow::Chat existingChat = *result;
+ recentChats_.erase(std::remove(recentChats_.begin(), recentChats_.end(), chat), recentChats_.end());
+ return boost::optional<ChatListWindow::Chat>(existingChat);
+ } else {
+ return boost::optional<ChatListWindow::Chat>();
+ }
}
void ChatsManager::cleanupPrivateMessageRecents() {
- /* if we leave a MUC and close a PM, remove it's recent chat entry */
- const std::list<ChatListWindow::Chat> chats = recentChats_;
- foreach (const ChatListWindow::Chat& chat, chats) {
- if (chat.isPrivateMessage) {
- typedef std::map<JID, MUCController*> ControllerMap;
- ControllerMap::iterator muc = mucControllers_.find(chat.jid.toBare());
- if (muc == mucControllers_.end() || !muc->second->isJoined()) {
- ChatController* chatController = getChatControllerIfExists(chat.jid);
- if (!chatController || !chatController->hasOpenWindow()) {
- removeExistingChat(chat);
- break;
- }
- }
- }
- }
+ /* if we leave a MUC and close a PM, remove it's recent chat entry */
+ const std::list<ChatListWindow::Chat> chats = recentChats_;
+ for (const ChatListWindow::Chat& chat : chats) {
+ if (chat.isPrivateMessage) {
+ typedef std::map<JID, MUCController*> ControllerMap;
+ ControllerMap::iterator muc = mucControllers_.find(chat.jid.toBare());
+ if (muc == mucControllers_.end() || !muc->second->isJoined()) {
+ ChatController* chatController = getChatControllerIfExists(chat.jid);
+ if (!chatController || !chatController->hasOpenWindow()) {
+ removeExistingChat(chat);
+ break;
+ }
+ }
+ }
+ }
}
void ChatsManager::appendRecent(const ChatListWindow::Chat& chat) {
- boost::optional<ChatListWindow::Chat> oldChat = removeExistingChat(chat);
- ChatListWindow::Chat mergedChat = chat;
- if (oldChat && !oldChat->impromptuJIDs.empty()) {
- mergedChat.impromptuJIDs.insert(oldChat->impromptuJIDs.begin(), oldChat->impromptuJIDs.end());
- }
- recentChats_.push_front(mergedChat);
+ boost::optional<ChatListWindow::Chat> oldChat = removeExistingChat(chat);
+ ChatListWindow::Chat mergedChat = chat;
+ if (oldChat && !oldChat->impromptuJIDs.empty()) {
+ mergedChat.impromptuJIDs.insert(oldChat->impromptuJIDs.begin(), oldChat->impromptuJIDs.end());
+ }
+ recentChats_.push_front(mergedChat);
}
void ChatsManager::prependRecent(const ChatListWindow::Chat& chat) {
- boost::optional<ChatListWindow::Chat> oldChat = removeExistingChat(chat);
- ChatListWindow::Chat mergedChat = chat;
- if (oldChat && !oldChat->impromptuJIDs.empty()) {
- mergedChat.impromptuJIDs.insert(oldChat->impromptuJIDs.begin(), oldChat->impromptuJIDs.end());
- }
- recentChats_.push_back(mergedChat);
+ boost::optional<ChatListWindow::Chat> oldChat = removeExistingChat(chat);
+ ChatListWindow::Chat mergedChat = chat;
+ if (oldChat && !oldChat->impromptuJIDs.empty()) {
+ mergedChat.impromptuJIDs.insert(oldChat->impromptuJIDs.begin(), oldChat->impromptuJIDs.end());
+ }
+ recentChats_.push_back(mergedChat);
}
void ChatsManager::handleUserLeftMUC(MUCController* mucController) {
- std::map<JID, MUCController*>::iterator it;
- for (it = mucControllers_.begin(); it != mucControllers_.end(); ++it) {
- if ((*it).second == mucController) {
- foreach (ChatListWindow::Chat& chat, recentChats_) {
- if (chat.isMUC && chat.jid == (*it).first) {
- chat.statusType = StatusShow::None;
- }
- }
- mucControllers_.erase(it);
- delete mucController;
- break;
- }
- }
- cleanupPrivateMessageRecents();
- chatListWindow_->setRecents(recentChats_);
+ std::map<JID, MUCController*>::iterator it;
+ for (it = mucControllers_.begin(); it != mucControllers_.end(); ++it) {
+ if ((*it).second == mucController) {
+ for (ChatListWindow::Chat& chat : recentChats_) {
+ if (chat.isMUC && chat.jid == (*it).first) {
+ chat.statusType = StatusShow::None;
+ }
+ }
+ mucControllers_.erase(it);
+ delete mucController;
+ break;
+ }
+ }
+ cleanupPrivateMessageRecents();
+ chatListWindow_->setRecents(recentChats_);
}
void ChatsManager::handleSettingChanged(const std::string& settingPath) {
- if (settingPath == SettingConstants::REQUEST_DELIVERYRECEIPTS.getKey()) {
- userWantsReceipts_ = settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS);
- return;
- }
+ if (settingPath == SettingConstants::REQUEST_DELIVERYRECEIPTS.getKey()) {
+ userWantsReceipts_ = settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS);
+ return;
+ }
}
void ChatsManager::finalizeImpromptuJoin(MUC::ref muc, const std::vector<JID>& jidsToInvite, const std::string& reason, const boost::optional<JID>& reuseChatJID) {
- // send impromptu invites for the new MUC
- std::vector<JID> missingJIDsToInvite = jidsToInvite;
-
- typedef std::pair<std::string, MUCOccupant> StringMUCOccupantPair;
- std::map<std::string, MUCOccupant> occupants = muc->getOccupants();
- foreach(StringMUCOccupantPair occupant, occupants) {
- boost::optional<JID> realJID = occupant.second.getRealJID();
- if (realJID) {
- missingJIDsToInvite.erase(std::remove(missingJIDsToInvite.begin(), missingJIDsToInvite.end(), realJID->toBare()), missingJIDsToInvite.end());
- }
- }
-
- if (reuseChatJID) {
- muc->invitePerson(reuseChatJID.get(), reason, true, true);
- }
- foreach(const JID& jid, missingJIDsToInvite) {
- muc->invitePerson(jid, reason, true);
- }
+ // send impromptu invites for the new MUC
+ std::vector<JID> missingJIDsToInvite = jidsToInvite;
+
+ typedef std::pair<std::string, MUCOccupant> StringMUCOccupantPair;
+ std::map<std::string, MUCOccupant> occupants = muc->getOccupants();
+ for (StringMUCOccupantPair occupant : occupants) {
+ boost::optional<JID> realJID = occupant.second.getRealJID();
+ if (realJID) {
+ missingJIDsToInvite.erase(std::remove(missingJIDsToInvite.begin(), missingJIDsToInvite.end(), realJID->toBare()), missingJIDsToInvite.end());
+ }
+ }
+
+ if (reuseChatJID) {
+ muc->invitePerson(reuseChatJID.get(), reason, true, true);
+ }
+ for (const JID& jid : missingJIDsToInvite) {
+ muc->invitePerson(jid, reason, true);
+ }
}
-void ChatsManager::handleUIEvent(boost::shared_ptr<UIEvent> event) {
- boost::shared_ptr<RequestChatUIEvent> chatEvent = boost::dynamic_pointer_cast<RequestChatUIEvent>(event);
- if (chatEvent) {
- handleChatRequest(chatEvent->getContact());
- return;
- }
- boost::shared_ptr<RemoveMUCBookmarkUIEvent> removeMUCBookmarkEvent = boost::dynamic_pointer_cast<RemoveMUCBookmarkUIEvent>(event);
- if (removeMUCBookmarkEvent) {
- mucBookmarkManager_->removeBookmark(removeMUCBookmarkEvent->getBookmark());
- return;
- }
- boost::shared_ptr<AddMUCBookmarkUIEvent> addMUCBookmarkEvent = boost::dynamic_pointer_cast<AddMUCBookmarkUIEvent>(event);
- if (addMUCBookmarkEvent) {
- mucBookmarkManager_->addBookmark(addMUCBookmarkEvent->getBookmark());
- return;
- }
-
- boost::shared_ptr<CreateImpromptuMUCUIEvent> createImpromptuMUCEvent = boost::dynamic_pointer_cast<CreateImpromptuMUCUIEvent>(event);
- if (createImpromptuMUCEvent) {
- assert(!localMUCServiceJID_.toString().empty());
- // create new muc
- JID roomJID = createImpromptuMUCEvent->getRoomJID().toString().empty() ? JID(idGenerator_.generateID(), localMUCServiceJID_) : createImpromptuMUCEvent->getRoomJID();
-
- // join muc
- MUC::ref muc = handleJoinMUCRequest(roomJID, boost::optional<std::string>(), nickResolver_->jidToNick(jid_), false, true, true);
- mucControllers_[roomJID]->onImpromptuConfigCompleted.connect(boost::bind(&ChatsManager::finalizeImpromptuJoin, this, muc, createImpromptuMUCEvent->getJIDs(), createImpromptuMUCEvent->getReason(), boost::optional<JID>()));
- mucControllers_[roomJID]->activateChatWindow();
- }
-
- boost::shared_ptr<EditMUCBookmarkUIEvent> editMUCBookmarkEvent = boost::dynamic_pointer_cast<EditMUCBookmarkUIEvent>(event);
- if (editMUCBookmarkEvent) {
- mucBookmarkManager_->replaceBookmark(editMUCBookmarkEvent->getOldBookmark(), editMUCBookmarkEvent->getNewBookmark());
- }
- else if (JoinMUCUIEvent::ref joinEvent = boost::dynamic_pointer_cast<JoinMUCUIEvent>(event)) {
- handleJoinMUCRequest(joinEvent->getJID(), joinEvent->getPassword(), joinEvent->getNick(), joinEvent->getShouldJoinAutomatically(), joinEvent->getCreateAsReservedRoomIfNew(), joinEvent->isImpromptu());
- mucControllers_[joinEvent->getJID()]->activateChatWindow();
- }
- else if (boost::shared_ptr<RequestJoinMUCUIEvent> joinEvent = boost::dynamic_pointer_cast<RequestJoinMUCUIEvent>(event)) {
- if (!joinMUCWindow_) {
- joinMUCWindow_ = joinMUCWindowFactory_->createJoinMUCWindow(uiEventStream_);
- joinMUCWindow_->onSearchMUC.connect(boost::bind(&ChatsManager::handleSearchMUCRequest, this));
- }
- joinMUCWindow_->setMUC(joinEvent->getRoom());
- joinMUCWindow_->setNick(nickResolver_->jidToNick(jid_));
- joinMUCWindow_->show();
- }
+void ChatsManager::handleUIEvent(std::shared_ptr<UIEvent> event) {
+ std::shared_ptr<RequestChatUIEvent> chatEvent = std::dynamic_pointer_cast<RequestChatUIEvent>(event);
+ if (chatEvent) {
+ handleChatRequest(chatEvent->getContact());
+ return;
+ }
+ std::shared_ptr<RemoveMUCBookmarkUIEvent> removeMUCBookmarkEvent = std::dynamic_pointer_cast<RemoveMUCBookmarkUIEvent>(event);
+ if (removeMUCBookmarkEvent) {
+ mucBookmarkManager_->removeBookmark(removeMUCBookmarkEvent->getBookmark());
+ return;
+ }
+ std::shared_ptr<AddMUCBookmarkUIEvent> addMUCBookmarkEvent = std::dynamic_pointer_cast<AddMUCBookmarkUIEvent>(event);
+ if (addMUCBookmarkEvent) {
+ mucBookmarkManager_->addBookmark(addMUCBookmarkEvent->getBookmark());
+ return;
+ }
+ std::shared_ptr<SendFileUIEvent> sendFileEvent = std::dynamic_pointer_cast<SendFileUIEvent>(event);
+ if (sendFileEvent) {
+ JID fileReceiver = sendFileEvent->getJID();
+ if (fileReceiver.isBare()) {
+ // See if there is a chat controller for a conversation with a bound
+ // full JID. Check if this JID supports file transfer and use it instead
+ // of the bare JID.
+ ChatController* controller = getChatControllerIfExists(fileReceiver, false);
+ if (controller) {
+ JID controllerJID = controller->getToJID();
+ if (!controllerJID.isBare() && (FeatureOracle(entityCapsProvider_, presenceOracle_).isFileTransferSupported(controllerJID) == Yes)) {
+ fileReceiver = controllerJID;
+ }
+ }
+ }
+ ftOverview_->sendFile(fileReceiver, sendFileEvent->getFilename());
+ return;
+ }
+
+ std::shared_ptr<CreateImpromptuMUCUIEvent> createImpromptuMUCEvent = std::dynamic_pointer_cast<CreateImpromptuMUCUIEvent>(event);
+ if (createImpromptuMUCEvent) {
+ assert(!localMUCServiceJID_.toString().empty());
+ // The room JID is random for new impromptu rooms, or a predefined JID for impromptu rooms resumed from the 'Recent chats' list.
+ JID roomJID = createImpromptuMUCEvent->getRoomJID().toString().empty() ? JID(idGenerator_.generateID(), localMUCServiceJID_) : createImpromptuMUCEvent->getRoomJID();
+
+ // join muc
+ MUC::ref muc = handleJoinMUCRequest(roomJID, boost::optional<std::string>(), nickResolver_->jidToNick(jid_), false, true, true);
+ mucControllers_[roomJID]->onImpromptuConfigCompleted.connect(boost::bind(&ChatsManager::finalizeImpromptuJoin, this, muc, createImpromptuMUCEvent->getJIDs(), createImpromptuMUCEvent->getReason(), boost::optional<JID>()));
+ mucControllers_[roomJID]->activateChatWindow();
+ }
+
+ std::shared_ptr<EditMUCBookmarkUIEvent> editMUCBookmarkEvent = std::dynamic_pointer_cast<EditMUCBookmarkUIEvent>(event);
+ if (editMUCBookmarkEvent) {
+ mucBookmarkManager_->replaceBookmark(editMUCBookmarkEvent->getOldBookmark(), editMUCBookmarkEvent->getNewBookmark());
+ }
+ else if (JoinMUCUIEvent::ref joinEvent = std::dynamic_pointer_cast<JoinMUCUIEvent>(event)) {
+ handleJoinMUCRequest(joinEvent->getJID(), joinEvent->getPassword(), joinEvent->getNick(), joinEvent->getShouldJoinAutomatically(), joinEvent->getCreateAsReservedRoomIfNew(), joinEvent->isImpromptu());
+ mucControllers_[joinEvent->getJID()]->activateChatWindow();
+ }
+ else if (std::shared_ptr<RequestJoinMUCUIEvent> joinEvent = std::dynamic_pointer_cast<RequestJoinMUCUIEvent>(event)) {
+ if (!joinMUCWindow_) {
+ joinMUCWindow_ = joinMUCWindowFactory_->createJoinMUCWindow(uiEventStream_);
+ joinMUCWindow_->onSearchMUC.connect(boost::bind(&ChatsManager::handleSearchMUCRequest, this));
+ }
+ joinMUCWindow_->setMUC(joinEvent->getRoom());
+ joinMUCWindow_->setNick(nickResolver_->jidToNick(jid_));
+ joinMUCWindow_->show();
+ }
}
void ChatsManager::markAllRecentsOffline() {
- foreach (ChatListWindow::Chat& chat, recentChats_) {
- chat.setStatusType(StatusShow::None);
- }
+ for (ChatListWindow::Chat& chat : recentChats_) {
+ chat.setStatusType(StatusShow::None);
+ }
- chatListWindow_->setRecents(recentChats_);
+ chatListWindow_->setRecents(recentChats_);
}
void ChatsManager::handleTransformChatToMUC(ChatController* chatController, ChatWindow* chatWindow, const std::vector<JID>& jidsToInvite, const std::string& reason) {
- JID reuseChatInvite = chatController->getToJID();
- chatControllers_.erase(chatController->getToJID());
- delete chatController;
+ JID reuseChatInvite = chatController->getToJID();
+ chatControllers_.erase(chatController->getToJID());
+ delete chatController;
- // join new impromptu muc
- assert(!localMUCServiceJID_.toString().empty());
+ // join new impromptu muc
+ assert(!localMUCServiceJID_.toString().empty());
- // create new muc
- JID roomJID = JID(idGenerator_.generateID(), localMUCServiceJID_);
+ // create new muc
+ JID roomJID = JID(idGenerator_.generateID(), localMUCServiceJID_);
- // join muc
- MUC::ref muc = handleJoinMUCRequest(roomJID, boost::optional<std::string>(), nickResolver_->jidToNick(jid_), false, true, true, chatWindow);
- mucControllers_[roomJID]->onImpromptuConfigCompleted.connect(boost::bind(&ChatsManager::finalizeImpromptuJoin, this, muc, jidsToInvite, reason, boost::optional<JID>(reuseChatInvite)));
+ // join muc
+ MUC::ref muc = handleJoinMUCRequest(roomJID, boost::optional<std::string>(), nickResolver_->jidToNick(jid_), false, true, true, chatWindow);
+ mucControllers_[roomJID]->onImpromptuConfigCompleted.connect(boost::bind(&ChatsManager::finalizeImpromptuJoin, this, muc, jidsToInvite, reason, boost::optional<JID>(reuseChatInvite)));
}
/**
* If a resource goes offline, release bound chatdialog to that resource.
*/
-void ChatsManager::handlePresenceChange(boost::shared_ptr<Presence> newPresence) {
- if (mucRegistry_->isMUC(newPresence->getFrom().toBare())) return;
-
- foreach (ChatListWindow::Chat& chat, recentChats_) {
- if (newPresence->getFrom().toBare() == chat.jid.toBare() && !chat.isMUC) {
- Presence::ref presence = presenceOracle_->getHighestPriorityPresence(chat.jid.toBare());
- chat.setStatusType(presence ? presence->getShow() : StatusShow::None);
- chatListWindow_->setRecents(recentChats_);
- break;
- }
- }
-
- //if (newPresence->getType() != Presence::Unavailable) return;
- JID fullJID(newPresence->getFrom());
- std::map<JID, ChatController*>::iterator it = chatControllers_.find(fullJID);
- if (it == chatControllers_.end()) return;
- JID bareJID(fullJID.toBare());
- //It doesn't make sense to have two unbound dialogs.
- if (chatControllers_.find(bareJID) != chatControllers_.end()) return;
- rebindControllerJID(fullJID, bareJID);
+void ChatsManager::handlePresenceChange(std::shared_ptr<Presence> newPresence) {
+ if (mucRegistry_->isMUC(newPresence->getFrom().toBare())) return;
+
+ for (ChatListWindow::Chat& chat : recentChats_) {
+ if (newPresence->getFrom().toBare() == chat.jid.toBare() && !chat.isMUC) {
+ Presence::ref presence = presenceOracle_->getHighestPriorityPresence(chat.jid.toBare());
+ chat.setStatusType(presence ? presence->getShow() : StatusShow::None);
+ chatListWindow_->setRecents(recentChats_);
+ break;
+ }
+ }
+
+ //if (newPresence->getType() != Presence::Unavailable) return;
+ JID fullJID(newPresence->getFrom());
+ std::map<JID, ChatController*>::iterator it = chatControllers_.find(fullJID);
+ if (it == chatControllers_.end()) return;
+ JID bareJID(fullJID.toBare());
+ //It doesn't make sense to have two unbound dialogs.
+ if (chatControllers_.find(bareJID) != chatControllers_.end()) return;
+ rebindControllerJID(fullJID, bareJID);
}
void ChatsManager::setAvatarManager(AvatarManager* avatarManager) {
- if (avatarManager_) {
- avatarManager_->onAvatarChanged.disconnect(boost::bind(&ChatsManager::handleAvatarChanged, this, _1));
- }
- avatarManager_ = avatarManager;
- foreach (ChatListWindow::Chat& chat, recentChats_) {
- if (!chat.isMUC) {
- chat.setAvatarPath(avatarManager_->getAvatarPath(chat.jid));
- }
- }
- avatarManager_->onAvatarChanged.connect(boost::bind(&ChatsManager::handleAvatarChanged, this, _1));
+ if (avatarManager_) {
+ avatarManager_->onAvatarChanged.disconnect(boost::bind(&ChatsManager::handleAvatarChanged, this, _1));
+ }
+ avatarManager_ = avatarManager;
+ for (ChatListWindow::Chat& chat : recentChats_) {
+ if (!chat.isMUC) {
+ chat.setAvatarPath(avatarManager_->getAvatarPath(chat.jid));
+ }
+ }
+ avatarManager_->onAvatarChanged.connect(boost::bind(&ChatsManager::handleAvatarChanged, this, _1));
}
void ChatsManager::handleAvatarChanged(const JID& jid) {
- foreach (ChatListWindow::Chat& chat, recentChats_) {
- if (!chat.isMUC && jid.toBare() == chat.jid.toBare()) {
- chat.setAvatarPath(avatarManager_->getAvatarPath(jid));
- break;
- }
- }
+ for (ChatListWindow::Chat& chat : recentChats_) {
+ if (!chat.isMUC && jid.toBare() == chat.jid.toBare()) {
+ chat.setAvatarPath(avatarManager_->getAvatarPath(jid));
+ break;
+ }
+ }
}
-void ChatsManager::setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info) {
- serverDiscoInfo_ = info;
- foreach (JIDChatControllerPair pair, chatControllers_) {
- pair.second->setAvailableServerFeatures(info);
- }
- foreach (JIDMUCControllerPair pair, mucControllers_) {
- pair.second->setAvailableServerFeatures(info);
- }
+void ChatsManager::setServerDiscoInfo(std::shared_ptr<DiscoInfo> info) {
+ serverDiscoInfo_ = info;
+ for (JIDChatControllerPair pair : chatControllers_) {
+ pair.second->setAvailableServerFeatures(info);
+ }
+ for (JIDMUCControllerPair pair : mucControllers_) {
+ pair.second->setAvailableServerFeatures(info);
+ }
}
/**
* This is to be called on connect/disconnect.
- */
+ */
void ChatsManager::setOnline(bool enabled) {
- foreach (JIDChatControllerPair controllerPair, chatControllers_) {
- controllerPair.second->setOnline(enabled);
- }
- foreach (JIDMUCControllerPair controllerPair, mucControllers_) {
- controllerPair.second->setOnline(enabled);
- if (enabled) {
- controllerPair.second->rejoin();
- }
- }
- if (!enabled) {
- markAllRecentsOffline();
- } else {
- setupBookmarks();
- localMUCServiceJID_ = JID();
- localMUCServiceFinderWalker_ = boost::make_shared<DiscoServiceWalker>(jid_.getDomain(), iqRouter_);
- localMUCServiceFinderWalker_->onServiceFound.connect(boost::bind(&ChatsManager::handleLocalServiceFound, this, _1, _2));
- localMUCServiceFinderWalker_->onWalkAborted.connect(boost::bind(&ChatsManager::handleLocalServiceWalkFinished, this));
- localMUCServiceFinderWalker_->onWalkComplete.connect(boost::bind(&ChatsManager::handleLocalServiceWalkFinished, this));
- localMUCServiceFinderWalker_->beginWalk();
- }
-
- if (chatListWindow_) {
- chatListWindow_->setBookmarksEnabled(enabled);
- }
+ for (JIDChatControllerPair controllerPair : chatControllers_) {
+ controllerPair.second->setOnline(enabled);
+ }
+ for (JIDMUCControllerPair controllerPair : mucControllers_) {
+ controllerPair.second->setOnline(enabled);
+ if (enabled) {
+ controllerPair.second->rejoin();
+ }
+ }
+ if (!enabled) {
+ markAllRecentsOffline();
+ } else {
+ setupBookmarks();
+ localMUCServiceJID_ = JID();
+ localMUCServiceFinderWalker_ = std::make_shared<DiscoServiceWalker>(jid_.getDomain(), iqRouter_);
+ localMUCServiceFinderWalker_->onServiceFound.connect(boost::bind(&ChatsManager::handleLocalServiceFound, this, _1, _2));
+ localMUCServiceFinderWalker_->onWalkAborted.connect(boost::bind(&ChatsManager::handleLocalServiceWalkFinished, this));
+ localMUCServiceFinderWalker_->onWalkComplete.connect(boost::bind(&ChatsManager::handleLocalServiceWalkFinished, this));
+ localMUCServiceFinderWalker_->beginWalk();
+ }
+
+ if (chatListWindow_) {
+ chatListWindow_->setBookmarksEnabled(enabled);
+ }
}
void ChatsManager::handleChatRequest(const std::string &contact) {
- ChatController* controller = getChatControllerOrFindAnother(JID(contact));
- controller->activateChatWindow();
+ ChatController* controller = getChatControllerOrFindAnother(JID(contact));
+ controller->activateChatWindow();
}
ChatController* ChatsManager::getChatControllerOrFindAnother(const JID &contact) {
- ChatController* controller = getChatControllerIfExists(contact);
- if (!controller && !mucRegistry_->isMUC(contact.toBare())) {
- foreach (JIDChatControllerPair pair, chatControllers_) {
- if (pair.first.toBare() == contact.toBare()) {
- controller = pair.second;
- break;
- }
- }
- }
- return controller ? controller : createNewChatController(contact);
+ ChatController* controller = getChatControllerIfExists(contact);
+ if (!controller && !mucRegistry_->isMUC(contact.toBare())) {
+ for (JIDChatControllerPair pair : chatControllers_) {
+ if (pair.first.toBare() == contact.toBare()) {
+ controller = pair.second;
+ break;
+ }
+ }
+ }
+ return controller ? controller : createNewChatController(contact);
}
ChatController* ChatsManager::createNewChatController(const JID& contact) {
- assert(chatControllers_.find(contact) == chatControllers_.end());
- boost::shared_ptr<ChatMessageParser> chatMessageParser = boost::make_shared<ChatMessageParser>(emoticons_, highlightManager_->getRules(), false); /* a message parser that knows this is a chat (not a room/MUC) */
- ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, mucRegistry_->isMUC(contact.toBare()), useDelayForLatency_, uiEventStream_, eventController_, timerFactory_, entityCapsProvider_, userWantsReceipts_, settings_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, autoAcceptMUCInviteDecider_);
- chatControllers_[contact] = controller;
- controller->setAvailableServerFeatures(serverDiscoInfo_);
- controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, contact, _1, false));
- controller->onWindowClosed.connect(boost::bind(&ChatsManager::handleChatClosed, this, contact));
- controller->onUnreadCountChanged.connect(boost::bind(&ChatsManager::handleUnreadCountChanged, this, controller));
- controller->onConvertToMUC.connect(boost::bind(&ChatsManager::handleTransformChatToMUC, this, controller, _1, _2, _3));
- updatePresenceReceivingStateOnChatController(contact);
- controller->setCanStartImpromptuChats(!localMUCServiceJID_.toString().empty());
- return controller;
+ assert(chatControllers_.find(contact) == chatControllers_.end());
+ std::shared_ptr<ChatMessageParser> chatMessageParser = std::make_shared<ChatMessageParser>(emoticons_, highlightManager_->getRules(), false); /* a message parser that knows this is a chat (not a room/MUC) */
+ ChatController* controller = new ChatController(jid_, stanzaChannel_, iqRouter_, chatWindowFactory_, contact, nickResolver_, presenceOracle_, avatarManager_, mucRegistry_->isMUC(contact.toBare()), useDelayForLatency_, uiEventStream_, eventController_, timerFactory_, entityCapsProvider_, userWantsReceipts_, settings_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, autoAcceptMUCInviteDecider_);
+ chatControllers_[contact] = controller;
+ controller->setAvailableServerFeatures(serverDiscoInfo_);
+ controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, contact, _1, false));
+ controller->onWindowClosed.connect(boost::bind(&ChatsManager::handleChatClosed, this, contact));
+ controller->onUnreadCountChanged.connect(boost::bind(&ChatsManager::handleUnreadCountChanged, this, controller));
+ controller->onConvertToMUC.connect(boost::bind(&ChatsManager::handleTransformChatToMUC, this, controller, _1, _2, _3));
+ updatePresenceReceivingStateOnChatController(contact);
+ controller->setCanStartImpromptuChats(!localMUCServiceJID_.toString().empty());
+ return controller;
}
ChatController* ChatsManager::getChatControllerOrCreate(const JID &contact) {
- ChatController* controller = getChatControllerIfExists(contact);
- return controller ? controller : createNewChatController(contact);
+ ChatController* controller = getChatControllerIfExists(contact);
+ return controller ? controller : createNewChatController(contact);
}
ChatController* ChatsManager::getChatControllerIfExists(const JID &contact, bool rebindIfNeeded) {
- if (chatControllers_.find(contact) == chatControllers_.end()) {
- if (mucRegistry_->isMUC(contact.toBare())) {
- return NULL;
- }
- //Need to look for an unbound window to bind first
- JID bare(contact.toBare());
- if (chatControllers_.find(bare) != chatControllers_.end()) {
- if (rebindIfNeeded) {
- rebindControllerJID(bare, contact);
- }
- else {
- return chatControllers_[bare];
- }
- } else {
- foreach (JIDChatControllerPair pair, chatControllers_) {
- if (pair.first.toBare() == contact.toBare()) {
- if (rebindIfNeeded) {
- rebindControllerJID(pair.first, contact);
- return chatControllers_[contact];
- } else {
- return pair.second;
- }
- }
- }
- return NULL;
- }
- }
- return chatControllers_[contact];
+ if (chatControllers_.find(contact) == chatControllers_.end()) {
+ if (mucRegistry_->isMUC(contact.toBare())) {
+ return nullptr;
+ }
+ //Need to look for an unbound window to bind first
+ JID bare(contact.toBare());
+ if (chatControllers_.find(bare) != chatControllers_.end()) {
+ if (rebindIfNeeded) {
+ rebindControllerJID(bare, contact);
+ }
+ else {
+ return chatControllers_[bare];
+ }
+ } else {
+ for (JIDChatControllerPair pair : chatControllers_) {
+ if (pair.first.toBare() == contact.toBare()) {
+ if (rebindIfNeeded) {
+ rebindControllerJID(pair.first, contact);
+ return chatControllers_[contact];
+ } else {
+ return pair.second;
+ }
+ }
+ }
+ return nullptr;
+ }
+ }
+ return chatControllers_[contact];
}
void ChatsManager::rebindControllerJID(const JID& from, const JID& to) {
- chatControllers_[to] = chatControllers_[from];
- chatControllers_.erase(from);
- chatControllers_[to]->setToJID(to);
+ chatControllers_[to] = chatControllers_[from];
+ chatControllers_.erase(from);
+ chatControllers_[to]->setToJID(to);
}
MUC::ref ChatsManager::handleJoinMUCRequest(const JID &mucJID, const boost::optional<std::string>& password, const boost::optional<std::string>& nickMaybe, bool addAutoJoin, bool createAsReservedIfNew, bool isImpromptu, ChatWindow* reuseChatwindow) {
- MUC::ref muc;
- if (addAutoJoin) {
- MUCBookmark bookmark(mucJID, mucJID.getNode());
- bookmark.setAutojoin(true);
- if (nickMaybe) {
- bookmark.setNick(*nickMaybe);
- }
- if (password) {
- bookmark.setPassword(*password);
- }
- mucBookmarkManager_->addBookmark(bookmark);
- }
-
- std::map<JID, MUCController*>::iterator it = mucControllers_.find(mucJID);
- if (it != mucControllers_.end()) {
- if (stanzaChannel_->isAvailable()) {
- it->second->rejoin();
- }
- } else {
- std::string nick = (nickMaybe && !(*nickMaybe).empty()) ? nickMaybe.get() : nickResolver_->jidToNick(jid_);
- muc = mucManager->createMUC(mucJID);
- if (createAsReservedIfNew) {
- muc->setCreateAsReservedIfNew();
- }
- if (isImpromptu) {
- muc->setCreateAsReservedIfNew();
- }
-
- MUCController* controller = NULL;
- SingleChatWindowFactoryAdapter* chatWindowFactoryAdapter = NULL;
- if (reuseChatwindow) {
- chatWindowFactoryAdapter = new SingleChatWindowFactoryAdapter(reuseChatwindow);
- }
- boost::shared_ptr<ChatMessageParser> chatMessageParser = boost::make_shared<ChatMessageParser>(emoticons_, highlightManager_->getRules(), true); /* a message parser that knows this is a room/MUC (not a chat) */
- controller = new MUCController(jid_, muc, password, nick, stanzaChannel_, iqRouter_, reuseChatwindow ? chatWindowFactoryAdapter : chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_, roster_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, isImpromptu, autoAcceptMUCInviteDecider_, vcardManager_, mucBookmarkManager_);
- if (chatWindowFactoryAdapter) {
- /* The adapters are only passed to chat windows, which are deleted in their
- * controllers' dtor, which are deleted in ChatManager's dtor. The adapters
- * are also deleted there.*/
- chatWindowFactoryAdapters_[controller] = chatWindowFactoryAdapter;
- }
-
- mucControllers_[mucJID] = controller;
- controller->setAvailableServerFeatures(serverDiscoInfo_);
- controller->onUserLeft.connect(boost::bind(&ChatsManager::handleUserLeftMUC, this, controller));
- controller->onUserJoined.connect(boost::bind(&ChatsManager::handleChatActivity, this, mucJID.toBare(), "", true));
- controller->onUserNicknameChanged.connect(boost::bind(&ChatsManager::handleUserNicknameChanged, this, controller, _1, _2));
- controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, mucJID.toBare(), _1, true));
- controller->onUnreadCountChanged.connect(boost::bind(&ChatsManager::handleUnreadCountChanged, this, controller));
- if (!stanzaChannel_->isAvailable()) {
- /* When online, the MUC is added to the registry in MUCImpl::internalJoin. This method is not
- * called when Swift is offline, so we add it here as only MUCs in the registry are rejoined
- * when going back online.
- */
- mucRegistry_->addMUC(mucJID.toBare());
- }
- handleChatActivity(mucJID.toBare(), "", true);
- }
-
- mucControllers_[mucJID]->showChatWindow();
- return muc;
+ MUC::ref muc;
+ if (addAutoJoin) {
+ MUCBookmark bookmark(mucJID, mucJID.getNode());
+ bookmark.setAutojoin(true);
+ if (nickMaybe) {
+ bookmark.setNick(*nickMaybe);
+ }
+ if (password) {
+ bookmark.setPassword(*password);
+ }
+ mucBookmarkManager_->addBookmark(bookmark);
+ }
+
+ std::map<JID, MUCController*>::iterator it = mucControllers_.find(mucJID);
+ if (it != mucControllers_.end()) {
+ if (stanzaChannel_->isAvailable()) {
+ it->second->rejoin();
+ }
+ } else {
+ std::string nick = (nickMaybe && !(*nickMaybe).empty()) ? nickMaybe.get() : nickResolver_->jidToNick(jid_);
+ muc = mucManager->createMUC(mucJID);
+ if (createAsReservedIfNew) {
+ muc->setCreateAsReservedIfNew();
+ }
+ if (isImpromptu) {
+ muc->setCreateAsReservedIfNew();
+ }
+
+ MUCController* controller = nullptr;
+ SingleChatWindowFactoryAdapter* chatWindowFactoryAdapter = nullptr;
+ if (reuseChatwindow) {
+ chatWindowFactoryAdapter = new SingleChatWindowFactoryAdapter(reuseChatwindow);
+ }
+ std::shared_ptr<ChatMessageParser> chatMessageParser = std::make_shared<ChatMessageParser>(emoticons_, highlightManager_->getRules(), true); /* a message parser that knows this is a room/MUC (not a chat) */
+ controller = new MUCController(jid_, muc, password, nick, stanzaChannel_, iqRouter_, reuseChatwindow ? chatWindowFactoryAdapter : chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory_, eventController_, entityCapsProvider_, roster_, historyController_, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser, isImpromptu, autoAcceptMUCInviteDecider_, vcardManager_, mucBookmarkManager_);
+ if (chatWindowFactoryAdapter) {
+ /* The adapters are only passed to chat windows, which are deleted in their
+ * controllers' dtor, which are deleted in ChatManager's dtor. The adapters
+ * are also deleted there.*/
+ chatWindowFactoryAdapters_[controller] = chatWindowFactoryAdapter;
+ }
+
+ mucControllers_[mucJID] = controller;
+ controller->setAvailableServerFeatures(serverDiscoInfo_);
+ controller->onUserLeft.connect(boost::bind(&ChatsManager::handleUserLeftMUC, this, controller));
+ controller->onUserJoined.connect(boost::bind(&ChatsManager::handleChatActivity, this, mucJID.toBare(), "", true));
+ controller->onUserNicknameChanged.connect(boost::bind(&ChatsManager::handleUserNicknameChanged, this, controller, _1, _2));
+ controller->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, mucJID.toBare(), _1, true));
+ controller->onUnreadCountChanged.connect(boost::bind(&ChatsManager::handleUnreadCountChanged, this, controller));
+ if (!stanzaChannel_->isAvailable()) {
+ /* When online, the MUC is added to the registry in MUCImpl::internalJoin. This method is not
+ * called when Swift is offline, so we add it here as only MUCs in the registry are rejoined
+ * when going back online.
+ */
+ mucRegistry_->addMUC(mucJID.toBare());
+ }
+ handleChatActivity(mucJID.toBare(), "", true);
+ }
+
+ mucControllers_[mucJID]->showChatWindow();
+ return muc;
}
void ChatsManager::handleSearchMUCRequest() {
- mucSearchController_->openSearchWindow();
+ mucSearchController_->openSearchWindow();
}
void ChatsManager::handleUserNicknameChanged(MUCController* mucController, const std::string& oldNickname, const std::string& newNickname) {
- JID oldMUCChatJID = mucController->getToJID().withResource(oldNickname);
- JID newMUCChatJID = mucController->getToJID().withResource(newNickname);
-
- SWIFT_LOG(debug) << "nickname change in " << mucController->getToJID().toString() << " from " << oldNickname << " to " << newNickname << std::endl;
-
- // get current chat controller
- ChatController *chatController = getChatControllerIfExists(oldMUCChatJID);
- if (chatController) {
- // adjust chat controller
- chatController->setToJID(newMUCChatJID);
- nickResolver_->onNickChanged(newMUCChatJID, oldNickname);
- chatControllers_.erase(oldMUCChatJID);
- chatControllers_[newMUCChatJID] = chatController;
-
- chatController->onActivity.disconnect(boost::bind(&ChatsManager::handleChatActivity, this, oldMUCChatJID, _1, false));
- chatController->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, newMUCChatJID, _1, false));
- }
+ JID oldMUCChatJID = mucController->getToJID().withResource(oldNickname);
+ JID newMUCChatJID = mucController->getToJID().withResource(newNickname);
+
+ SWIFT_LOG(debug) << "nickname change in " << mucController->getToJID().toString() << " from " << oldNickname << " to " << newNickname << std::endl;
+
+ // get current chat controller
+ ChatController *chatController = getChatControllerIfExists(oldMUCChatJID);
+ if (chatController) {
+ // adjust chat controller
+ chatController->setToJID(newMUCChatJID);
+ nickResolver_->onNickChanged(newMUCChatJID, oldNickname);
+ chatControllers_.erase(oldMUCChatJID);
+ chatControllers_[newMUCChatJID] = chatController;
+
+ chatController->onActivity.disconnect(boost::bind(&ChatsManager::handleChatActivity, this, oldMUCChatJID, _1, false));
+ chatController->onActivity.connect(boost::bind(&ChatsManager::handleChatActivity, this, newMUCChatJID, _1, false));
+ }
+}
+
+bool ChatsManager::messageCausesSessionBinding(std::shared_ptr<Message> message) {
+ bool causesRebind = false;
+ ChatState::ref chatState = message->getPayload<ChatState>();
+ if (!message->getBody().get_value_or("").empty() || (chatState && chatState->getChatState() == ChatState::Composing)) {
+ causesRebind = true;
+ }
+ return causesRebind;
}
-void ChatsManager::handleIncomingMessage(boost::shared_ptr<Message> message) {
- JID jid = message->getFrom();
- boost::shared_ptr<MessageEvent> event(new MessageEvent(message));
- bool isInvite = !!message->getPayload<MUCInvitationPayload>();
- bool isMediatedInvite = (message->getPayload<MUCUserPayload>() && message->getPayload<MUCUserPayload>()->getInvite());
- if (isMediatedInvite) {
- jid = (*message->getPayload<MUCUserPayload>()->getInvite()).from;
- }
- if (!event->isReadable() && !message->getPayload<ChatState>() && !message->getPayload<DeliveryReceipt>() && !message->getPayload<DeliveryReceiptRequest>() && !isInvite && !isMediatedInvite && !message->hasSubject()) {
- return;
- }
-
- // Try to deliver it to a MUC
- if (message->getType() == Message::Groupchat || message->getType() == Message::Error /*|| (isInvite && message->getType() == Message::Normal)*/) {
- std::map<JID, MUCController*>::iterator i = mucControllers_.find(jid.toBare());
- if (i != mucControllers_.end()) {
- i->second->handleIncomingMessage(event);
- return;
- }
- else if (message->getType() == Message::Groupchat) {
- //FIXME: Error handling - groupchat messages from an unknown muc.
- return;
- }
- }
-
- // check for impromptu invite to potentially auto-accept
- MUCInvitationPayload::ref invite = message->getPayload<MUCInvitationPayload>();
- if (invite && autoAcceptMUCInviteDecider_->isAutoAcceptedInvite(message->getFrom(), invite)) {
- if (invite->getIsContinuation()) {
- // check for existing chat controller for the from JID
- ChatController* controller = getChatControllerIfExists(jid);
- if (controller) {
- ChatWindow* window = controller->detachChatWindow();
- chatControllers_.erase(jid);
- delete controller;
- handleJoinMUCRequest(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, false, true, window);
- return;
- }
- } else {
- handleJoinMUCRequest(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, false, true);
- return;
- }
- }
-
- //if not a mucroom
- if (!event->isReadable() && !isInvite && !isMediatedInvite) {
- /* Only route such messages if a window exists, don't open new windows for them.*/
-
- // Do not bind a controller to a full JID, for delivery receipts or chat state notifications.
- bool bindControllerToJID = false;
- ChatState::ref chatState = message->getPayload<ChatState>();
- if (!message->getBody().get_value_or("").empty() || (chatState && chatState->getChatState() == ChatState::Composing)) {
- bindControllerToJID = true;
- }
-
- ChatController* controller = getChatControllerIfExists(jid, bindControllerToJID);
- if (controller) {
- controller->handleIncomingMessage(event);
- }
- } else {
- getChatControllerOrCreate(jid)->handleIncomingMessage(event);
- }
+void ChatsManager::handleIncomingMessage(std::shared_ptr<Message> incomingMessage) {
+ std::shared_ptr<Message> message = incomingMessage;
+ if (message->getFrom().toBare() == jid_.toBare()) {
+ CarbonsReceived::ref carbonsReceived;
+ CarbonsSent::ref carbonsSent;
+ Forwarded::ref forwarded;
+ Message::ref forwardedMessage;
+ if ((carbonsReceived = incomingMessage->getPayload<CarbonsReceived>()) &&
+ (forwarded = carbonsReceived->getForwarded()) &&
+ (forwardedMessage = std::dynamic_pointer_cast<Message>(forwarded->getStanza()))) {
+ message = forwardedMessage;
+ }
+ else if ((carbonsSent = incomingMessage->getPayload<CarbonsSent>()) &&
+ (forwarded = carbonsSent->getForwarded()) &&
+ (forwardedMessage = std::dynamic_pointer_cast<Message>(forwarded->getStanza()))) {
+ JID toJID = forwardedMessage->getTo();
+
+ ChatController* controller = getChatControllerOrCreate(toJID);
+ if (controller) {
+ controller->handleIncomingOwnMessage(forwardedMessage);
+ }
+ else {
+ SWIFT_LOG(error) << "Carbons message ignored." << std::endl;
+ }
+ return;
+ }
+ }
+ JID fromJID = message->getFrom();
+
+ std::shared_ptr<MessageEvent> event(new MessageEvent(message));
+ bool isInvite = !!message->getPayload<MUCInvitationPayload>();
+ bool isMediatedInvite = (message->getPayload<MUCUserPayload>() && message->getPayload<MUCUserPayload>()->getInvite());
+ if (isMediatedInvite) {
+ fromJID = (*message->getPayload<MUCUserPayload>()->getInvite()).from;
+ }
+ if (!event->isReadable() && !message->getPayload<ChatState>() && !message->getPayload<DeliveryReceipt>() && !message->getPayload<DeliveryReceiptRequest>() && !isInvite && !isMediatedInvite && !message->hasSubject()) {
+ return;
+ }
+
+ // Try to deliver MUC errors to a MUC PM window if a suitable window is open.
+ if (message->getType() == Message::Error) {
+ auto controller = getChatControllerIfExists(fromJID, messageCausesSessionBinding(message));
+ if (controller) {
+ controller->handleIncomingMessage(event);
+ return;
+ }
+ }
+
+ // Try to deliver it to a MUC.
+ if (message->getType() == Message::Groupchat || message->getType() == Message::Error) {
+ // Try to deliver it to a MUC room.
+ std::map<JID, MUCController*>::iterator i = mucControllers_.find(fromJID.toBare());
+ if (i != mucControllers_.end()) {
+ i->second->handleIncomingMessage(event);
+ return;
+ }
+ else if (message->getType() == Message::Groupchat) {
+ //FIXME: Error handling - groupchat messages from an unknown muc.
+ return;
+ }
+ }
+
+ // check for impromptu invite to potentially auto-accept
+ MUCInvitationPayload::ref invite = message->getPayload<MUCInvitationPayload>();
+ if (invite && autoAcceptMUCInviteDecider_->isAutoAcceptedInvite(message->getFrom(), invite)) {
+ if (invite->getIsContinuation()) {
+ // check for existing chat controller for the from JID
+ ChatController* controller = getChatControllerIfExists(fromJID);
+ if (controller) {
+ ChatWindow* window = controller->detachChatWindow();
+ chatControllers_.erase(fromJID);
+ delete controller;
+ handleJoinMUCRequest(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, false, true, window);
+ return;
+ }
+ } else {
+ handleJoinMUCRequest(invite->getJID(), boost::optional<std::string>(), boost::optional<std::string>(), false, false, true);
+ return;
+ }
+ }
+
+ //if not a mucroom
+ if (!event->isReadable() && !isInvite && !isMediatedInvite) {
+ /* Only route such messages if a window exists, don't open new windows for them.*/
+
+ // Do not bind a controller to a full JID, for delivery receipts or chat state notifications.
+ ChatController* controller = getChatControllerIfExists(fromJID, messageCausesSessionBinding(message));
+ if (controller) {
+ controller->handleIncomingMessage(event);
+ }
+ } else {
+ getChatControllerOrCreate(fromJID)->handleIncomingMessage(event);
+ }
}
void ChatsManager::handleMUCSelectedAfterSearch(const JID& muc) {
- if (joinMUCWindow_) {
- joinMUCWindow_->setMUC(muc.toString());
- }
+ if (joinMUCWindow_) {
+ joinMUCWindow_->setMUC(muc.toString());
+ }
}
void ChatsManager::handleMUCBookmarkActivated(const MUCBookmark& mucBookmark) {
- uiEventStream_->send(boost::make_shared<JoinMUCUIEvent>(mucBookmark.getRoom(), mucBookmark.getPassword(), mucBookmark.getNick()));
+ uiEventStream_->send(std::make_shared<JoinMUCUIEvent>(mucBookmark.getRoom(), mucBookmark.getPassword(), mucBookmark.getNick()));
}
void ChatsManager::handleNewFileTransferController(FileTransferController* ftc) {
- ChatController* chatController = getChatControllerOrCreate(ftc->getOtherParty());
- chatController->handleNewFileTransferController(ftc);
- chatController->activateChatWindow();
- if (ftc->isIncoming()) {
- eventController_->handleIncomingEvent(boost::make_shared<IncomingFileTransferEvent>(ftc->getOtherParty()));
- }
+ ChatController* chatController = getChatControllerOrCreate(ftc->getOtherParty());
+ chatController->handleNewFileTransferController(ftc);
+ if (!ftc->isIncoming()) {
+ chatController->activateChatWindow();
+ }
}
void ChatsManager::handleWhiteboardSessionRequest(const JID& contact, bool senderIsSelf) {
- ChatController* chatController = getChatControllerOrCreate(contact);
- chatController->handleWhiteboardSessionRequest(senderIsSelf);
- chatController->activateChatWindow();
+ ChatController* chatController = getChatControllerOrCreate(contact);
+ chatController->handleWhiteboardSessionRequest(senderIsSelf);
+ chatController->activateChatWindow();
}
void ChatsManager::handleWhiteboardStateChange(const JID& contact, const ChatWindow::WhiteboardSessionState state) {
- ChatController* chatController = getChatControllerOrCreate(contact);
- chatController->handleWhiteboardStateChange(state);
- chatController->activateChatWindow();
- if (state == ChatWindow::WhiteboardAccepted) {
- boost::filesystem::path path;
- JID bareJID = contact.toBare();
- if (avatarManager_) {
- path = avatarManager_->getAvatarPath(bareJID);
- }
- ChatListWindow::Chat chat(bareJID, nickResolver_->jidToNick(bareJID), "", 0, StatusShow::None, path, false);
- chatListWindow_->addWhiteboardSession(chat);
- } else {
- chatListWindow_->removeWhiteboardSession(contact.toBare());
- }
+ ChatController* chatController = getChatControllerOrCreate(contact);
+ chatController->handleWhiteboardStateChange(state);
+ chatController->activateChatWindow();
+ if (state == ChatWindow::WhiteboardAccepted) {
+ boost::filesystem::path path;
+ JID bareJID = contact.toBare();
+ if (avatarManager_) {
+ path = avatarManager_->getAvatarPath(bareJID);
+ }
+ ChatListWindow::Chat chat(bareJID, nickResolver_->jidToNick(bareJID), "", 0, StatusShow::None, path, false);
+ chatListWindow_->addWhiteboardSession(chat);
+ } else {
+ chatListWindow_->removeWhiteboardSession(contact.toBare());
+ }
}
void ChatsManager::handleRecentActivated(const ChatListWindow::Chat& chat) {
- if (chat.isMUC && !chat.impromptuJIDs.empty()) {
- typedef std::pair<std::string, JID> StringJIDPair;
- std::vector<JID> inviteJIDs;
- foreach(StringJIDPair pair, chat.impromptuJIDs) {
- inviteJIDs.push_back(pair.second);
- }
- uiEventStream_->send(boost::make_shared<CreateImpromptuMUCUIEvent>(inviteJIDs, chat.jid, ""));
- }
- else if (chat.isMUC) {
- /* FIXME: This means that recents requiring passwords will just flat-out not work */
- uiEventStream_->send(boost::make_shared<JoinMUCUIEvent>(chat.jid, boost::optional<std::string>(), chat.nick));
- }
- else {
- uiEventStream_->send(boost::make_shared<RequestChatUIEvent>(chat.jid));
- }
+ if (chat.isMUC && !chat.impromptuJIDs.empty()) {
+ typedef std::pair<std::string, JID> StringJIDPair;
+ std::vector<JID> inviteJIDs;
+ for (StringJIDPair pair : chat.impromptuJIDs) {
+ inviteJIDs.push_back(pair.second);
+ }
+ uiEventStream_->send(std::make_shared<CreateImpromptuMUCUIEvent>(inviteJIDs, chat.jid, ""));
+ }
+ else if (chat.isMUC) {
+ /* FIXME: This means that recents requiring passwords will just flat-out not work */
+ uiEventStream_->send(std::make_shared<JoinMUCUIEvent>(chat.jid, boost::optional<std::string>(), chat.nick));
+ }
+ else {
+ uiEventStream_->send(std::make_shared<RequestChatUIEvent>(chat.jid));
+ }
}
-void ChatsManager::handleLocalServiceFound(const JID& service, boost::shared_ptr<DiscoInfo> info) {
- foreach (DiscoInfo::Identity identity, info->getIdentities()) {
- if ((identity.getCategory() == "directory"
- && identity.getType() == "chatroom")
- || (identity.getCategory() == "conference"
- && identity.getType() == "text")) {
- localMUCServiceJID_ = service;
- localMUCServiceFinderWalker_->endWalk();
- SWIFT_LOG(debug) << "Use following MUC service for impromptu chats: " << localMUCServiceJID_ << std::endl;
- break;
- }
- }
+void ChatsManager::handleLocalServiceFound(const JID& service, std::shared_ptr<DiscoInfo> info) {
+ for (DiscoInfo::Identity identity : info->getIdentities()) {
+ if ((identity.getCategory() == "directory"
+ && identity.getType() == "chatroom")
+ || (identity.getCategory() == "conference"
+ && identity.getType() == "text")) {
+ localMUCServiceJID_ = service;
+ localMUCServiceFinderWalker_->endWalk();
+ SWIFT_LOG(debug) << "Use following MUC service for impromptu chats: " << localMUCServiceJID_ << std::endl;
+ break;
+ }
+ }
}
void ChatsManager::handleLocalServiceWalkFinished() {
- bool impromptuMUCSupported = !localMUCServiceJID_.toString().empty();
- foreach (JIDChatControllerPair controllerPair, chatControllers_) {
- controllerPair.second->setCanStartImpromptuChats(impromptuMUCSupported);
- }
- foreach (JIDMUCControllerPair controllerPair, mucControllers_) {
- controllerPair.second->setCanStartImpromptuChats(impromptuMUCSupported);
- }
- onImpromptuMUCServiceDiscovered(impromptuMUCSupported);
+ bool impromptuMUCSupported = !localMUCServiceJID_.toString().empty();
+ for (JIDChatControllerPair controllerPair : chatControllers_) {
+ controllerPair.second->setCanStartImpromptuChats(impromptuMUCSupported);
+ }
+ for (JIDMUCControllerPair controllerPair : mucControllers_) {
+ controllerPair.second->setCanStartImpromptuChats(impromptuMUCSupported);
+ }
+ onImpromptuMUCServiceDiscovered(impromptuMUCSupported);
}
std::vector<ChatListWindow::Chat> ChatsManager::getRecentChats() const {
- return std::vector<ChatListWindow::Chat>(recentChats_.begin(), recentChats_.end());
+ return std::vector<ChatListWindow::Chat>(recentChats_.begin(), recentChats_.end());
}
std::vector<Contact::ref> Swift::ChatsManager::getContacts(bool withMUCNicks) {
- std::vector<Contact::ref> result;
- foreach (ChatListWindow::Chat chat, recentChats_) {
- if (!chat.isMUC) {
- result.push_back(boost::make_shared<Contact>(chat.chatName.empty() ? chat.jid.toString() : chat.chatName, chat.jid, chat.statusType, chat.avatarPath));
- }
- }
- if (withMUCNicks) {
- /* collect MUC nicks */
- typedef std::map<JID, MUCController*>::value_type Item;
- foreach (const Item& item, mucControllers_) {
- JID mucJID = item.second->getToJID();
- std::map<std::string, JID> participants = item.second->getParticipantJIDs();
- typedef std::map<std::string, JID>::value_type ParticipantType;
- foreach (const ParticipantType& participant, participants) {
- const JID nickJID = JID(mucJID.getNode(), mucJID.getDomain(), participant.first);
- Presence::ref presence = presenceOracle_->getLastPresence(nickJID);
- const boost::filesystem::path avatar = avatarManager_->getAvatarPath(nickJID);
- result.push_back(boost::make_shared<Contact>(participant.first, JID(), presence->getShow(), avatar));
- }
- }
- }
- return result;
+ std::vector<Contact::ref> result;
+ for (ChatListWindow::Chat chat : recentChats_) {
+ if (!chat.isMUC) {
+ result.push_back(std::make_shared<Contact>(chat.chatName.empty() ? chat.jid.toString() : chat.chatName, chat.jid, chat.statusType, chat.avatarPath));
+ }
+ }
+ if (withMUCNicks) {
+ /* collect MUC nicks */
+ typedef std::map<JID, MUCController*>::value_type Item;
+ for (const Item& item : mucControllers_) {
+ JID mucJID = item.second->getToJID();
+ std::map<std::string, JID> participants = item.second->getParticipantJIDs();
+ typedef std::map<std::string, JID>::value_type ParticipantType;
+ for (const ParticipantType& participant : participants) {
+ const JID nickJID = JID(mucJID.getNode(), mucJID.getDomain(), participant.first);
+ Presence::ref presence = presenceOracle_->getLastPresence(nickJID);
+ const boost::filesystem::path avatar = avatarManager_->getAvatarPath(nickJID);
+ result.push_back(std::make_shared<Contact>(participant.first, JID(), presence->getShow(), avatar));
+ }
+ }
+ }
+ return result;
}
ChatsManager::SingleChatWindowFactoryAdapter::SingleChatWindowFactoryAdapter(ChatWindow* chatWindow) : chatWindow_(chatWindow) {}
ChatsManager::SingleChatWindowFactoryAdapter::~SingleChatWindowFactoryAdapter() {}
ChatWindow* ChatsManager::SingleChatWindowFactoryAdapter::createChatWindow(const JID &, UIEventStream*) {
- return chatWindow_;
+ return chatWindow_;
}
}
diff --git a/Swift/Controllers/Chat/ChatsManager.h b/Swift/Controllers/Chat/ChatsManager.h
index 58a9017..593624d 100644
--- a/Swift/Controllers/Chat/ChatsManager.h
+++ b/Swift/Controllers/Chat/ChatsManager.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,10 +7,9 @@
#pragma once
#include <map>
+#include <memory>
#include <string>
-#include <boost/shared_ptr.hpp>
-
#include <Swiften/Base/IDGenerator.h>
#include <Swiften/Elements/DiscoInfo.h>
#include <Swiften/Elements/Message.h>
@@ -27,159 +26,160 @@
#include <Swift/Controllers/UIInterfaces/ChatWindowFactory.h>
namespace Swift {
- class EventController;
- class ChatController;
- class ChatControllerBase;
- class MUCController;
- class MUCManager;
- class JoinMUCWindow;
- class JoinMUCWindowFactory;
- class NickResolver;
- class PresenceOracle;
- class AvatarManager;
- class StanzaChannel;
- class IQRouter;
- class PresenceSender;
- class MUCBookmarkManager;
- class ChatListWindowFactory;
- class TimerFactory;
- class EntityCapsProvider;
- class DirectedPresenceSender;
- class MUCSearchWindowFactory;
- class ProfileSettingsProvider;
- class MUCSearchController;
- class FileTransferOverview;
- class FileTransferController;
- class XMPPRoster;
- class SettingsProvider;
- class WhiteboardManager;
- class HistoryController;
- class HighlightManager;
- class ClientBlockListManager;
- class ChatMessageParser;
- class DiscoServiceWalker;
- class AutoAcceptMUCInviteDecider;
- class VCardManager;
-
- class ChatsManager : public ContactProvider {
- public:
- ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, JoinMUCWindowFactory* joinMUCWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsProvider* entityCapsProvider, MUCManager* mucManager, MUCSearchWindowFactory* mucSearchWindowFactory, ProfileSettingsProvider* profileSettings, FileTransferOverview* ftOverview, XMPPRoster* roster, bool eagleMode, SettingsProvider* settings, HistoryController* historyController_, WhiteboardManager* whiteboardManager, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, const std::map<std::string, std::string>& emoticons, VCardManager* vcardManager);
- virtual ~ChatsManager();
- void setAvatarManager(AvatarManager* avatarManager);
- void setOnline(bool enabled);
- void setServerDiscoInfo(boost::shared_ptr<DiscoInfo> info);
- void handleIncomingMessage(boost::shared_ptr<Message> message);
- std::vector<ChatListWindow::Chat> getRecentChats() const;
- virtual std::vector<Contact::ref> getContacts(bool withMUCNicks);
-
- boost::signal<void (bool supportsImpromptu)> onImpromptuMUCServiceDiscovered;
-
- private:
- class SingleChatWindowFactoryAdapter : public ChatWindowFactory {
- public:
- SingleChatWindowFactoryAdapter(ChatWindow* chatWindow);
- virtual ~SingleChatWindowFactoryAdapter();
- virtual ChatWindow* createChatWindow(const JID &, UIEventStream*);
-
- private:
- ChatWindow* chatWindow_;
- };
-
- private:
- ChatListWindow::Chat createChatListChatItem(const JID& jid, const std::string& activity, bool privateMessage);
- void handleChatRequest(const std::string& contact);
- void finalizeImpromptuJoin(MUC::ref muc, const std::vector<JID>& jidsToInvite, const std::string& reason, const boost::optional<JID>& reuseChatJID = boost::optional<JID>());
- MUC::ref handleJoinMUCRequest(const JID& muc, const boost::optional<std::string>& password, const boost::optional<std::string>& nick, bool addAutoJoin, bool createAsReservedIfNew, bool isImpromptu, ChatWindow* reuseChatwindow = 0);
- void handleSearchMUCRequest();
- void handleMUCSelectedAfterSearch(const JID&);
- void rebindControllerJID(const JID& from, const JID& to);
- void handlePresenceChange(boost::shared_ptr<Presence> newPresence);
- void handleUIEvent(boost::shared_ptr<UIEvent> event);
- void handleMUCBookmarkAdded(const MUCBookmark& bookmark);
- void handleMUCBookmarkRemoved(const MUCBookmark& bookmark);
- void handleUserLeftMUC(MUCController* mucController);
- void handleUserNicknameChanged(MUCController* mucController, const std::string& oldNickname, const std::string& newNickname);
- void handleBookmarksReady();
- void handleChatActivity(const JID& jid, const std::string& activity, bool isMUC);
- void handleChatClosed(const JID& jid);
- void handleNewFileTransferController(FileTransferController*);
- void handleWhiteboardSessionRequest(const JID& contact, bool senderIsSelf);
- void handleWhiteboardStateChange(const JID& contact, const ChatWindow::WhiteboardSessionState state);
- boost::optional<ChatListWindow::Chat> removeExistingChat(const ChatListWindow::Chat& chat);
- void cleanupPrivateMessageRecents();
- void appendRecent(const ChatListWindow::Chat& chat);
- void prependRecent(const ChatListWindow::Chat& chat);
- void setupBookmarks();
- void loadRecents();
- void saveRecents();
- void handleChatMadeRecent();
- void handleMUCBookmarkActivated(const MUCBookmark&);
- void handleRecentActivated(const ChatListWindow::Chat&);
- void handleUnreadCountChanged(ChatControllerBase* controller);
- void handleAvatarChanged(const JID& jid);
- void handleClearRecentsRequested();
- void handleJIDAddedToRoster(const JID&);
- void handleJIDRemovedFromRoster(const JID&);
- void handleJIDUpdatedInRoster(const JID&);
- void handleRosterCleared();
- void handleSettingChanged(const std::string& settingPath);
- void markAllRecentsOffline();
- void handleTransformChatToMUC(ChatController* chatController, ChatWindow* chatWindow, const std::vector<JID>& jidsToInvite, const std::string& reason);
-
- void handleLocalServiceFound(const JID& service, boost::shared_ptr<DiscoInfo> info);
- void handleLocalServiceWalkFinished();
-
- void updatePresenceReceivingStateOnChatController(const JID&);
- ChatListWindow::Chat updateChatStatusAndAvatarHelper(const ChatListWindow::Chat& chat) const;
-
-
- ChatController* getChatControllerOrFindAnother(const JID &contact);
- ChatController* createNewChatController(const JID &contact);
- ChatController* getChatControllerOrCreate(const JID &contact);
- ChatController* getChatControllerIfExists(const JID &contact, bool rebindIfNeeded = true);
-
- private:
- std::map<JID, MUCController*> mucControllers_;
- std::map<JID, ChatController*> chatControllers_;
- std::map<ChatControllerBase*, SingleChatWindowFactoryAdapter*> chatWindowFactoryAdapters_;
- EventController* eventController_;
- JID jid_;
- StanzaChannel* stanzaChannel_;
- IQRouter* iqRouter_;
- ChatWindowFactory* chatWindowFactory_;
- JoinMUCWindowFactory* joinMUCWindowFactory_;
- NickResolver* nickResolver_;
- PresenceOracle* presenceOracle_;
- AvatarManager* avatarManager_;
- PresenceSender* presenceSender_;
- UIEventStream* uiEventStream_;
- MUCBookmarkManager* mucBookmarkManager_;
- boost::shared_ptr<DiscoInfo> serverDiscoInfo_;
- ChatListWindow* chatListWindow_;
- JoinMUCWindow* joinMUCWindow_;
- boost::bsignals::scoped_connection uiEventConnection_;
- bool useDelayForLatency_;
- TimerFactory* timerFactory_;
- MUCRegistry* mucRegistry_;
- EntityCapsProvider* entityCapsProvider_;
- MUCManager* mucManager;
- MUCSearchController* mucSearchController_;
- std::list<ChatListWindow::Chat> recentChats_;
- ProfileSettingsProvider* profileSettings_;
- FileTransferOverview* ftOverview_;
- XMPPRoster* roster_;
- bool eagleMode_;
- bool userWantsReceipts_;
- SettingsProvider* settings_;
- HistoryController* historyController_;
- WhiteboardManager* whiteboardManager_;
- HighlightManager* highlightManager_;
- std::map<std::string, std::string> emoticons_;
- ClientBlockListManager* clientBlockListManager_;
- JID localMUCServiceJID_;
- boost::shared_ptr<DiscoServiceWalker> localMUCServiceFinderWalker_;
- AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider_;
- IDGenerator idGenerator_;
- VCardManager* vcardManager_;
- };
+ class EventController;
+ class ChatController;
+ class ChatControllerBase;
+ class MUCController;
+ class MUCManager;
+ class JoinMUCWindow;
+ class JoinMUCWindowFactory;
+ class NickResolver;
+ class PresenceOracle;
+ class AvatarManager;
+ class StanzaChannel;
+ class IQRouter;
+ class PresenceSender;
+ class MUCBookmarkManager;
+ class ChatListWindowFactory;
+ class TimerFactory;
+ class EntityCapsProvider;
+ class DirectedPresenceSender;
+ class MUCSearchWindowFactory;
+ class ProfileSettingsProvider;
+ class MUCSearchController;
+ class FileTransferOverview;
+ class FileTransferController;
+ class XMPPRoster;
+ class SettingsProvider;
+ class WhiteboardManager;
+ class HistoryController;
+ class HighlightManager;
+ class ClientBlockListManager;
+ class ChatMessageParser;
+ class DiscoServiceWalker;
+ class AutoAcceptMUCInviteDecider;
+ class VCardManager;
+
+ class ChatsManager : public ContactProvider {
+ public:
+ ChatsManager(JID jid, StanzaChannel* stanzaChannel, IQRouter* iqRouter, EventController* eventController, ChatWindowFactory* chatWindowFactory, JoinMUCWindowFactory* joinMUCWindowFactory, NickResolver* nickResolver, PresenceOracle* presenceOracle, PresenceSender* presenceSender, UIEventStream* uiEventStream, ChatListWindowFactory* chatListWindowFactory, bool useDelayForLatency, TimerFactory* timerFactory, MUCRegistry* mucRegistry, EntityCapsProvider* entityCapsProvider, MUCManager* mucManager, MUCSearchWindowFactory* mucSearchWindowFactory, ProfileSettingsProvider* profileSettings, FileTransferOverview* ftOverview, XMPPRoster* roster, bool eagleMode, SettingsProvider* settings, HistoryController* historyController_, WhiteboardManager* whiteboardManager, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, const std::map<std::string, std::string>& emoticons, VCardManager* vcardManager);
+ virtual ~ChatsManager();
+ void setAvatarManager(AvatarManager* avatarManager);
+ void setOnline(bool enabled);
+ void setServerDiscoInfo(std::shared_ptr<DiscoInfo> info);
+ void handleIncomingMessage(std::shared_ptr<Message> incomingMessage);
+ std::vector<ChatListWindow::Chat> getRecentChats() const;
+ virtual std::vector<Contact::ref> getContacts(bool withMUCNicks);
+
+ boost::signals2::signal<void (bool supportsImpromptu)> onImpromptuMUCServiceDiscovered;
+
+ private:
+ class SingleChatWindowFactoryAdapter : public ChatWindowFactory {
+ public:
+ SingleChatWindowFactoryAdapter(ChatWindow* chatWindow);
+ virtual ~SingleChatWindowFactoryAdapter();
+ virtual ChatWindow* createChatWindow(const JID &, UIEventStream*);
+
+ private:
+ ChatWindow* chatWindow_;
+ };
+
+ private:
+ ChatListWindow::Chat createChatListChatItem(const JID& jid, const std::string& activity, bool privateMessage);
+ void handleChatRequest(const std::string& contact);
+ void finalizeImpromptuJoin(MUC::ref muc, const std::vector<JID>& jidsToInvite, const std::string& reason, const boost::optional<JID>& reuseChatJID = boost::optional<JID>());
+ MUC::ref handleJoinMUCRequest(const JID& muc, const boost::optional<std::string>& password, const boost::optional<std::string>& nick, bool addAutoJoin, bool createAsReservedIfNew, bool isImpromptu, ChatWindow* reuseChatwindow = nullptr);
+ void handleSearchMUCRequest();
+ void handleMUCSelectedAfterSearch(const JID&);
+ void rebindControllerJID(const JID& from, const JID& to);
+ void handlePresenceChange(std::shared_ptr<Presence> newPresence);
+ void handleUIEvent(std::shared_ptr<UIEvent> event);
+ void handleMUCBookmarkAdded(const MUCBookmark& bookmark);
+ void handleMUCBookmarkRemoved(const MUCBookmark& bookmark);
+ void handleUserLeftMUC(MUCController* mucController);
+ void handleUserNicknameChanged(MUCController* mucController, const std::string& oldNickname, const std::string& newNickname);
+ void handleBookmarksReady();
+ void handleChatActivity(const JID& jid, const std::string& activity, bool isMUC);
+ void handleChatClosed(const JID& jid);
+ void handleNewFileTransferController(FileTransferController*);
+ void handleWhiteboardSessionRequest(const JID& contact, bool senderIsSelf);
+ void handleWhiteboardStateChange(const JID& contact, const ChatWindow::WhiteboardSessionState state);
+ boost::optional<ChatListWindow::Chat> removeExistingChat(const ChatListWindow::Chat& chat);
+ bool messageCausesSessionBinding(std::shared_ptr<Message> message);
+ void cleanupPrivateMessageRecents();
+ void appendRecent(const ChatListWindow::Chat& chat);
+ void prependRecent(const ChatListWindow::Chat& chat);
+ void setupBookmarks();
+ void loadRecents();
+ void saveRecents();
+ void handleChatMadeRecent();
+ void handleMUCBookmarkActivated(const MUCBookmark&);
+ void handleRecentActivated(const ChatListWindow::Chat&);
+ void handleUnreadCountChanged(ChatControllerBase* controller);
+ void handleAvatarChanged(const JID& jid);
+ void handleClearRecentsRequested();
+ void handleJIDAddedToRoster(const JID&);
+ void handleJIDRemovedFromRoster(const JID&);
+ void handleJIDUpdatedInRoster(const JID&);
+ void handleRosterCleared();
+ void handleSettingChanged(const std::string& settingPath);
+ void markAllRecentsOffline();
+ void handleTransformChatToMUC(ChatController* chatController, ChatWindow* chatWindow, const std::vector<JID>& jidsToInvite, const std::string& reason);
+
+ void handleLocalServiceFound(const JID& service, std::shared_ptr<DiscoInfo> info);
+ void handleLocalServiceWalkFinished();
+
+ void updatePresenceReceivingStateOnChatController(const JID&);
+ ChatListWindow::Chat updateChatStatusAndAvatarHelper(const ChatListWindow::Chat& chat) const;
+
+
+ ChatController* getChatControllerOrFindAnother(const JID &contact);
+ ChatController* createNewChatController(const JID &contact);
+ ChatController* getChatControllerOrCreate(const JID &contact);
+ ChatController* getChatControllerIfExists(const JID &contact, bool rebindIfNeeded = true);
+
+ private:
+ std::map<JID, MUCController*> mucControllers_;
+ std::map<JID, ChatController*> chatControllers_;
+ std::map<ChatControllerBase*, SingleChatWindowFactoryAdapter*> chatWindowFactoryAdapters_;
+ EventController* eventController_;
+ JID jid_;
+ StanzaChannel* stanzaChannel_;
+ IQRouter* iqRouter_;
+ ChatWindowFactory* chatWindowFactory_;
+ JoinMUCWindowFactory* joinMUCWindowFactory_;
+ NickResolver* nickResolver_;
+ PresenceOracle* presenceOracle_;
+ AvatarManager* avatarManager_;
+ PresenceSender* presenceSender_;
+ UIEventStream* uiEventStream_;
+ MUCBookmarkManager* mucBookmarkManager_;
+ std::shared_ptr<DiscoInfo> serverDiscoInfo_;
+ ChatListWindow* chatListWindow_;
+ JoinMUCWindow* joinMUCWindow_;
+ boost::signals2::scoped_connection uiEventConnection_;
+ bool useDelayForLatency_;
+ TimerFactory* timerFactory_;
+ MUCRegistry* mucRegistry_;
+ EntityCapsProvider* entityCapsProvider_;
+ MUCManager* mucManager;
+ MUCSearchController* mucSearchController_;
+ std::list<ChatListWindow::Chat> recentChats_;
+ ProfileSettingsProvider* profileSettings_;
+ FileTransferOverview* ftOverview_;
+ XMPPRoster* roster_;
+ bool eagleMode_;
+ bool userWantsReceipts_;
+ SettingsProvider* settings_;
+ HistoryController* historyController_;
+ WhiteboardManager* whiteboardManager_;
+ HighlightManager* highlightManager_;
+ std::map<std::string, std::string> emoticons_;
+ ClientBlockListManager* clientBlockListManager_;
+ JID localMUCServiceJID_;
+ std::shared_ptr<DiscoServiceWalker> localMUCServiceFinderWalker_;
+ AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider_;
+ IDGenerator idGenerator_;
+ VCardManager* vcardManager_;
+ };
}
diff --git a/Swift/Controllers/Chat/MUCController.cpp b/Swift/Controllers/Chat/MUCController.cpp
index 409fe1f..ceed776 100644
--- a/Swift/Controllers/Chat/MUCController.cpp
+++ b/Swift/Controllers/Chat/MUCController.cpp
@@ -7,14 +7,15 @@
#include <Swift/Controllers/Chat/MUCController.h>
#include <algorithm>
+#include <memory>
#include <boost/bind.hpp>
#include <boost/regex.hpp>
#include <boost/algorithm/string.hpp>
+#include <boost/range/adaptor/reversed.hpp>
#include <Swiften/Avatars/AvatarManager.h>
#include <Swiften/Base/Log.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Base/format.h>
#include <Swiften/Base/Tristate.h>
#include <Swiften/Client/BlockList.h>
@@ -58,1163 +59,1158 @@
namespace Swift {
class MUCBookmarkPredicate {
- public:
- MUCBookmarkPredicate(const JID& mucJID) : roomJID_(mucJID) { }
- bool operator()(const MUCBookmark& operand) {
- return operand.getRoom() == roomJID_;
- }
-
- private:
- JID roomJID_;
+ public:
+ MUCBookmarkPredicate(const JID& mucJID) : roomJID_(mucJID) { }
+ bool operator()(const MUCBookmark& operand) {
+ return operand.getRoom() == roomJID_;
+ }
+
+ private:
+ JID roomJID_;
};
/**
* The controller does not gain ownership of the stanzaChannel, nor the factory.
*/
MUCController::MUCController (
- const JID& self,
- MUC::ref muc,
- const boost::optional<std::string>& password,
- const std::string &nick,
- StanzaChannel* stanzaChannel,
- IQRouter* iqRouter,
- ChatWindowFactory* chatWindowFactory,
- PresenceOracle* presenceOracle,
- AvatarManager* avatarManager,
- UIEventStream* uiEventStream,
- bool useDelayForLatency,
- TimerFactory* timerFactory,
- EventController* eventController,
- EntityCapsProvider* entityCapsProvider,
- XMPPRoster* roster,
- HistoryController* historyController,
- MUCRegistry* mucRegistry,
- HighlightManager* highlightManager,
- ClientBlockListManager* clientBlockListManager,
- boost::shared_ptr<ChatMessageParser> chatMessageParser,
- bool isImpromptu,
- AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider,
- VCardManager* vcardManager,
- MUCBookmarkManager* mucBookmarkManager) :
- ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc->getJID(), presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry, highlightManager, chatMessageParser, autoAcceptMUCInviteDecider), muc_(muc), nick_(nick), desiredNick_(nick), password_(password), renameCounter_(0), isImpromptu_(isImpromptu), isImpromptuAlreadyConfigured_(false), clientBlockListManager_(clientBlockListManager), mucBookmarkManager_(mucBookmarkManager) {
- parting_ = true;
- joined_ = false;
- lastWasPresence_ = false;
- shouldJoinOnReconnect_ = true;
- doneGettingHistory_ = false;
- events_ = uiEventStream;
- xmppRoster_ = roster;
-
- roster_ = new Roster(false, true);
- rosterVCardProvider_ = new RosterVCardProvider(roster_, vcardManager, JID::WithResource);
- completer_ = new TabComplete();
- chatWindow_->setRosterModel(roster_);
- chatWindow_->setTabComplete(completer_);
- chatWindow_->onClosed.connect(boost::bind(&MUCController::handleWindowClosed, this));
- chatWindow_->onOccupantSelectionChanged.connect(boost::bind(&MUCController::handleWindowOccupantSelectionChanged, this, _1));
- chatWindow_->onOccupantActionSelected.connect(boost::bind(&MUCController::handleActionRequestedOnOccupant, this, _1, _2));
- chatWindow_->onChangeSubjectRequest.connect(boost::bind(&MUCController::handleChangeSubjectRequest, this, _1));
- chatWindow_->onBookmarkRequest.connect(boost::bind(&MUCController::handleBookmarkRequest, this));
- chatWindow_->onConfigureRequest.connect(boost::bind(&MUCController::handleConfigureRequest, this, _1));
- chatWindow_->onConfigurationFormCancelled.connect(boost::bind(&MUCController::handleConfigurationCancelled, this));
- chatWindow_->onDestroyRequest.connect(boost::bind(&MUCController::handleDestroyRoomRequest, this));
- chatWindow_->onInviteToChat.connect(boost::bind(&MUCController::handleInvitePersonToThisMUCRequest, this, _1));
- chatWindow_->onGetAffiliationsRequest.connect(boost::bind(&MUCController::handleGetAffiliationsRequest, this));
- chatWindow_->onChangeAffiliationsRequest.connect(boost::bind(&MUCController::handleChangeAffiliationsRequest, this, _1));
- chatWindow_->onUnblockUserRequest.connect(boost::bind(&MUCController::handleUnblockUserRequest, this));
- muc_->onJoinComplete.connect(boost::bind(&MUCController::handleJoinComplete, this, _1));
- muc_->onJoinFailed.connect(boost::bind(&MUCController::handleJoinFailed, this, _1));
- muc_->onOccupantJoined.connect(boost::bind(&MUCController::handleOccupantJoined, this, _1));
- muc_->onOccupantNicknameChanged.connect(boost::bind(&MUCController::handleOccupantNicknameChanged, this, _1, _2));
- muc_->onOccupantPresenceChange.connect(boost::bind(&MUCController::handleOccupantPresenceChange, this, _1));
- muc_->onOccupantLeft.connect(boost::bind(&MUCController::handleOccupantLeft, this, _1, _2, _3));
- muc_->onRoleChangeFailed.connect(boost::bind(&MUCController::handleOccupantRoleChangeFailed, this, _1, _2, _3));
- muc_->onAffiliationListReceived.connect(boost::bind(&MUCController::handleAffiliationListReceived, this, _1, _2));
- muc_->onConfigurationFailed.connect(boost::bind(&MUCController::handleConfigurationFailed, this, _1));
- muc_->onConfigurationFormReceived.connect(boost::bind(&MUCController::handleConfigurationFormReceived, this, _1));
- highlighter_->setMode(isImpromptu_ ? Highlighter::ChatMode : Highlighter::MUCMode);
- highlighter_->setNick(nick_);
- if (timerFactory && stanzaChannel_->isAvailable()) {
- loginCheckTimer_ = boost::shared_ptr<Timer>(timerFactory->createTimer(MUC_JOIN_WARNING_TIMEOUT_MILLISECONDS));
- loginCheckTimer_->onTick.connect(boost::bind(&MUCController::handleJoinTimeoutTick, this));
- loginCheckTimer_->start();
- }
- else {
- chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "You are currently offline. You will enter this room when you are connected.")), ChatWindow::DefaultDirection);
- }
- if (isImpromptu) {
- muc_->onUnlocked.connect(boost::bind(&MUCController::handleRoomUnlocked, this));
- chatWindow_->convertToMUC(ChatWindow::ImpromptuMUC);
- } else {
- muc_->onOccupantRoleChanged.connect(boost::bind(&MUCController::handleOccupantRoleChanged, this, _1, _2, _3));
- muc_->onOccupantAffiliationChanged.connect(boost::bind(&MUCController::handleOccupantAffiliationChanged, this, _1, _2, _3));
- chatWindow_->convertToMUC(ChatWindow::StandardMUC);
- chatWindow_->setName(muc->getJID().getNode());
- }
- if (stanzaChannel->isAvailable()) {
- MUCController::setOnline(true);
- }
- if (avatarManager_ != NULL) {
- avatarChangedConnection_ = (avatarManager_->onAvatarChanged.connect(boost::bind(&MUCController::handleAvatarChanged, this, _1)));
- }
- MUCController::handleBareJIDCapsChanged(muc->getJID());
- eventStream_->onUIEvent.connect(boost::bind(&MUCController::handleUIEvent, this, _1));
-
-
- // setup handling of MUC bookmark changes
- mucBookmarkManagerBookmarkAddedConnection_ = (mucBookmarkManager_->onBookmarkAdded.connect(boost::bind(&MUCController::handleMUCBookmarkAdded, this, _1)));
- mucBookmarkManagerBookmarkRemovedConnection_ = (mucBookmarkManager_->onBookmarkRemoved.connect(boost::bind(&MUCController::handleMUCBookmarkRemoved, this, _1)));
-
- std::vector<MUCBookmark> mucBookmarks = mucBookmarkManager_->getBookmarks();
- std::vector<MUCBookmark>::iterator bookmarkIterator = std::find_if(mucBookmarks.begin(), mucBookmarks.end(), MUCBookmarkPredicate(muc->getJID()));
- if (bookmarkIterator != mucBookmarks.end()) {
- updateChatWindowBookmarkStatus(*bookmarkIterator);
- }
- else {
- updateChatWindowBookmarkStatus(boost::optional<MUCBookmark>());
- }
+ const JID& self,
+ MUC::ref muc,
+ const boost::optional<std::string>& password,
+ const std::string &nick,
+ StanzaChannel* stanzaChannel,
+ IQRouter* iqRouter,
+ ChatWindowFactory* chatWindowFactory,
+ PresenceOracle* presenceOracle,
+ AvatarManager* avatarManager,
+ UIEventStream* uiEventStream,
+ bool useDelayForLatency,
+ TimerFactory* timerFactory,
+ EventController* eventController,
+ EntityCapsProvider* entityCapsProvider,
+ XMPPRoster* roster,
+ HistoryController* historyController,
+ MUCRegistry* mucRegistry,
+ HighlightManager* highlightManager,
+ ClientBlockListManager* clientBlockListManager,
+ std::shared_ptr<ChatMessageParser> chatMessageParser,
+ bool isImpromptu,
+ AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider,
+ VCardManager* vcardManager,
+ MUCBookmarkManager* mucBookmarkManager) :
+ ChatControllerBase(self, stanzaChannel, iqRouter, chatWindowFactory, muc->getJID(), presenceOracle, avatarManager, useDelayForLatency, uiEventStream, eventController, timerFactory, entityCapsProvider, historyController, mucRegistry, highlightManager, chatMessageParser, autoAcceptMUCInviteDecider), muc_(muc), nick_(nick), desiredNick_(nick), password_(password), renameCounter_(0), isImpromptu_(isImpromptu), isImpromptuAlreadyConfigured_(false), clientBlockListManager_(clientBlockListManager), mucBookmarkManager_(mucBookmarkManager) {
+ parting_ = true;
+ joined_ = false;
+ lastWasPresence_ = false;
+ shouldJoinOnReconnect_ = true;
+ doneGettingHistory_ = false;
+ events_ = uiEventStream;
+ xmppRoster_ = roster;
+
+ roster_ = new Roster(false, true);
+ rosterVCardProvider_ = new RosterVCardProvider(roster_, vcardManager, JID::WithResource);
+ completer_ = new TabComplete();
+ chatWindow_->setRosterModel(roster_);
+ chatWindow_->setTabComplete(completer_);
+ chatWindow_->onClosed.connect(boost::bind(&MUCController::handleWindowClosed, this));
+ chatWindow_->onOccupantSelectionChanged.connect(boost::bind(&MUCController::handleWindowOccupantSelectionChanged, this, _1));
+ chatWindow_->onOccupantActionSelected.connect(boost::bind(&MUCController::handleActionRequestedOnOccupant, this, _1, _2));
+ chatWindow_->onChangeSubjectRequest.connect(boost::bind(&MUCController::handleChangeSubjectRequest, this, _1));
+ chatWindow_->onBookmarkRequest.connect(boost::bind(&MUCController::handleBookmarkRequest, this));
+ chatWindow_->onConfigureRequest.connect(boost::bind(&MUCController::handleConfigureRequest, this, _1));
+ chatWindow_->onConfigurationFormCancelled.connect(boost::bind(&MUCController::handleConfigurationCancelled, this));
+ chatWindow_->onDestroyRequest.connect(boost::bind(&MUCController::handleDestroyRoomRequest, this));
+ chatWindow_->onInviteToChat.connect(boost::bind(&MUCController::handleInvitePersonToThisMUCRequest, this, _1));
+ chatWindow_->onGetAffiliationsRequest.connect(boost::bind(&MUCController::handleGetAffiliationsRequest, this));
+ chatWindow_->onChangeAffiliationsRequest.connect(boost::bind(&MUCController::handleChangeAffiliationsRequest, this, _1));
+ chatWindow_->onUnblockUserRequest.connect(boost::bind(&MUCController::handleUnblockUserRequest, this));
+ muc_->onJoinComplete.connect(boost::bind(&MUCController::handleJoinComplete, this, _1));
+ muc_->onJoinFailed.connect(boost::bind(&MUCController::handleJoinFailed, this, _1));
+ muc_->onOccupantJoined.connect(boost::bind(&MUCController::handleOccupantJoined, this, _1));
+ muc_->onOccupantNicknameChanged.connect(boost::bind(&MUCController::handleOccupantNicknameChanged, this, _1, _2));
+ muc_->onOccupantPresenceChange.connect(boost::bind(&MUCController::handleOccupantPresenceChange, this, _1));
+ muc_->onOccupantLeft.connect(boost::bind(&MUCController::handleOccupantLeft, this, _1, _2, _3));
+ muc_->onRoleChangeFailed.connect(boost::bind(&MUCController::handleOccupantRoleChangeFailed, this, _1, _2, _3));
+ muc_->onAffiliationListReceived.connect(boost::bind(&MUCController::handleAffiliationListReceived, this, _1, _2));
+ muc_->onConfigurationFailed.connect(boost::bind(&MUCController::handleConfigurationFailed, this, _1));
+ muc_->onConfigurationFormReceived.connect(boost::bind(&MUCController::handleConfigurationFormReceived, this, _1));
+ highlighter_->setMode(isImpromptu_ ? Highlighter::ChatMode : Highlighter::MUCMode);
+ highlighter_->setNick(nick_);
+ if (timerFactory && stanzaChannel_->isAvailable()) {
+ loginCheckTimer_ = std::shared_ptr<Timer>(timerFactory->createTimer(MUC_JOIN_WARNING_TIMEOUT_MILLISECONDS));
+ loginCheckTimer_->onTick.connect(boost::bind(&MUCController::handleJoinTimeoutTick, this));
+ loginCheckTimer_->start();
+ }
+ else {
+ chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "You are currently offline. You will enter this room when you are connected.")), ChatWindow::DefaultDirection);
+ }
+ if (isImpromptu) {
+ muc_->onUnlocked.connect(boost::bind(&MUCController::handleRoomUnlocked, this));
+ chatWindow_->convertToMUC(ChatWindow::ImpromptuMUC);
+ } else {
+ muc_->onOccupantRoleChanged.connect(boost::bind(&MUCController::handleOccupantRoleChanged, this, _1, _2, _3));
+ muc_->onOccupantAffiliationChanged.connect(boost::bind(&MUCController::handleOccupantAffiliationChanged, this, _1, _2, _3));
+ chatWindow_->convertToMUC(ChatWindow::StandardMUC);
+ chatWindow_->setName(muc->getJID().getNode());
+ }
+ if (stanzaChannel->isAvailable()) {
+ MUCController::setOnline(true);
+ }
+ if (avatarManager_ != nullptr) {
+ avatarChangedConnection_ = (avatarManager_->onAvatarChanged.connect(boost::bind(&MUCController::handleAvatarChanged, this, _1)));
+ }
+ MUCController::handleBareJIDCapsChanged(muc->getJID());
+ eventStream_->onUIEvent.connect(boost::bind(&MUCController::handleUIEvent, this, _1));
+
+
+ // setup handling of MUC bookmark changes
+ mucBookmarkManagerBookmarkAddedConnection_ = (mucBookmarkManager_->onBookmarkAdded.connect(boost::bind(&MUCController::handleMUCBookmarkAdded, this, _1)));
+ mucBookmarkManagerBookmarkRemovedConnection_ = (mucBookmarkManager_->onBookmarkRemoved.connect(boost::bind(&MUCController::handleMUCBookmarkRemoved, this, _1)));
+
+ std::vector<MUCBookmark> mucBookmarks = mucBookmarkManager_->getBookmarks();
+ std::vector<MUCBookmark>::iterator bookmarkIterator = std::find_if(mucBookmarks.begin(), mucBookmarks.end(), MUCBookmarkPredicate(muc->getJID()));
+ if (bookmarkIterator != mucBookmarks.end()) {
+ updateChatWindowBookmarkStatus(*bookmarkIterator);
+ }
+ else {
+ updateChatWindowBookmarkStatus(boost::optional<MUCBookmark>());
+ }
}
MUCController::~MUCController() {
- eventStream_->onUIEvent.disconnect(boost::bind(&MUCController::handleUIEvent, this, _1));
- chatWindow_->setRosterModel(NULL);
- delete rosterVCardProvider_;
- delete roster_;
- if (loginCheckTimer_) {
- loginCheckTimer_->stop();
- }
- chatWindow_->setTabComplete(NULL);
- delete completer_;
+ eventStream_->onUIEvent.disconnect(boost::bind(&MUCController::handleUIEvent, this, _1));
+ chatWindow_->setRosterModel(nullptr);
+ delete rosterVCardProvider_;
+ delete roster_;
+ if (loginCheckTimer_) {
+ loginCheckTimer_->stop();
+ }
+ chatWindow_->setTabComplete(nullptr);
+ delete completer_;
}
void MUCController::cancelReplaces() {
- lastWasPresence_ = false;
+ lastWasPresence_ = false;
}
void MUCController::handleWindowOccupantSelectionChanged(ContactRosterItem* item) {
- std::vector<ChatWindow::OccupantAction> actions;
-
- if (item) {
- MUCOccupant::Affiliation affiliation = muc_->getOccupant(getNick()).getAffiliation();
- MUCOccupant::Role role = muc_->getOccupant(getNick()).getRole();
- if (role == MUCOccupant::Moderator && !isImpromptu_)
- {
- if (affiliation == MUCOccupant::Admin || affiliation == MUCOccupant::Owner) {
- actions.push_back(ChatWindow::Ban);
- }
-
- actions.push_back(ChatWindow::Kick);
- actions.push_back(ChatWindow::MakeModerator);
- actions.push_back(ChatWindow::MakeParticipant);
- actions.push_back(ChatWindow::MakeVisitor);
- }
- // Add contact is available only if the real JID is also available
- if (muc_->getOccupant(item->getJID().getResource()).getRealJID()) {
- actions.push_back(ChatWindow::AddContact);
- }
- actions.push_back(ChatWindow::ShowProfile);
- }
- chatWindow_->setAvailableOccupantActions(actions);
+ std::vector<ChatWindow::OccupantAction> actions;
+
+ if (item) {
+ MUCOccupant::Affiliation affiliation = muc_->getOccupant(getNick()).getAffiliation();
+ MUCOccupant::Role role = muc_->getOccupant(getNick()).getRole();
+ if (role == MUCOccupant::Moderator && !isImpromptu_)
+ {
+ if (affiliation == MUCOccupant::Admin || affiliation == MUCOccupant::Owner) {
+ actions.push_back(ChatWindow::Ban);
+ }
+
+ actions.push_back(ChatWindow::Kick);
+ actions.push_back(ChatWindow::MakeModerator);
+ actions.push_back(ChatWindow::MakeParticipant);
+ actions.push_back(ChatWindow::MakeVisitor);
+ }
+ // Add contact is available only if the real JID is also available
+ if (muc_->getOccupant(item->getJID().getResource()).getRealJID()) {
+ actions.push_back(ChatWindow::AddContact);
+ }
+ actions.push_back(ChatWindow::ShowProfile);
+ }
+ chatWindow_->setAvailableOccupantActions(actions);
}
void MUCController::handleActionRequestedOnOccupant(ChatWindow::OccupantAction action, ContactRosterItem* item) {
- JID mucJID = item->getJID();
- MUCOccupant occupant = muc_->getOccupant(mucJID.getResource());
- JID realJID;
- if (occupant.getRealJID()) {
- realJID = occupant.getRealJID().get();
- }
- switch (action) {
- case ChatWindow::Kick: muc_->kickOccupant(mucJID);break;
- case ChatWindow::Ban: muc_->changeAffiliation(realJID, MUCOccupant::Outcast);break;
- case ChatWindow::MakeModerator: muc_->changeOccupantRole(mucJID, MUCOccupant::Moderator);break;
- case ChatWindow::MakeParticipant: muc_->changeOccupantRole(mucJID, MUCOccupant::Participant);break;
- case ChatWindow::MakeVisitor: muc_->changeOccupantRole(mucJID, MUCOccupant::Visitor);break;
- case ChatWindow::AddContact: if (occupant.getRealJID()) events_->send(boost::make_shared<RequestAddUserDialogUIEvent>(realJID, occupant.getNick()));break;
- case ChatWindow::ShowProfile: events_->send(boost::make_shared<ShowProfileForRosterItemUIEvent>(mucJID));break;
- }
+ JID mucJID = item->getJID();
+ MUCOccupant occupant = muc_->getOccupant(mucJID.getResource());
+ JID realJID;
+ if (occupant.getRealJID()) {
+ realJID = occupant.getRealJID().get();
+ }
+ switch (action) {
+ case ChatWindow::Kick: muc_->kickOccupant(mucJID);break;
+ case ChatWindow::Ban: muc_->changeAffiliation(realJID, MUCOccupant::Outcast);break;
+ case ChatWindow::MakeModerator: muc_->changeOccupantRole(mucJID, MUCOccupant::Moderator);break;
+ case ChatWindow::MakeParticipant: muc_->changeOccupantRole(mucJID, MUCOccupant::Participant);break;
+ case ChatWindow::MakeVisitor: muc_->changeOccupantRole(mucJID, MUCOccupant::Visitor);break;
+ case ChatWindow::AddContact: if (occupant.getRealJID()) events_->send(std::make_shared<RequestAddUserDialogUIEvent>(realJID, occupant.getNick()));break;
+ case ChatWindow::ShowProfile: events_->send(std::make_shared<ShowProfileForRosterItemUIEvent>(mucJID));break;
+ }
}
void MUCController::handleBareJIDCapsChanged(const JID& /*jid*/) {
- Tristate support = Yes;
- bool any = false;
- foreach (const std::string& nick, currentOccupants_) {
- DiscoInfo::ref disco = entityCapsProvider_->getCaps(toJID_.toBare().toString() + "/" + nick);
- if (disco && disco->hasFeature(DiscoInfo::MessageCorrectionFeature)) {
- any = true;
- } else {
- support = Maybe;
- }
- }
- if (!any) {
- support = No;
- }
- chatWindow_->setCorrectionEnabled(support);
+ Tristate support = Yes;
+ bool any = false;
+ for (const auto& nick : currentOccupants_) {
+ DiscoInfo::ref disco = entityCapsProvider_->getCaps(toJID_.toBare().toString() + "/" + nick);
+ if (disco && disco->hasFeature(DiscoInfo::MessageCorrectionFeature)) {
+ any = true;
+ } else {
+ support = Maybe;
+ }
+ }
+ if (!any) {
+ support = No;
+ }
+ chatWindow_->setCorrectionEnabled(support);
}
/**
* Join the MUC if not already in it.
*/
void MUCController::rejoin() {
- if (parting_) {
- joined_ = false;
- parting_ = false;
- if (password_) {
- muc_->setPassword(*password_);
- }
- //FIXME: check for received activity
+ if (parting_) {
+ joined_ = false;
+ parting_ = false;
+ if (password_) {
+ muc_->setPassword(*password_);
+ }
+ //FIXME: check for received activity
#ifdef SWIFT_EXPERIMENTAL_HISTORY
- if (lastActivity_ == boost::posix_time::not_a_date_time && historyController_) {
- lastActivity_ = historyController_->getLastTimeStampFromMUC(selfJID_, toJID_);
- }
+ if (lastActivity_ == boost::posix_time::not_a_date_time && historyController_) {
+ lastActivity_ = historyController_->getLastTimeStampFromMUC(selfJID_, toJID_);
+ }
#endif
- if (lastActivity_ == boost::posix_time::not_a_date_time) {
- muc_->joinAs(nick_);
- }
- else {
- muc_->joinWithContextSince(nick_, lastActivity_);
- }
- }
+ if (lastActivity_ == boost::posix_time::not_a_date_time) {
+ muc_->joinAs(nick_);
+ }
+ else {
+ muc_->joinWithContextSince(nick_, lastActivity_);
+ }
+ }
}
bool MUCController::isJoined() {
- return joined_;
+ return joined_;
}
const std::string& MUCController::getNick() {
- return nick_;
+ return nick_;
}
const boost::optional<std::string> MUCController::getPassword() const {
- return password_;
+ return password_;
}
bool MUCController::isImpromptu() const {
- return isImpromptu_;
+ return isImpromptu_;
}
std::map<std::string, JID> MUCController::getParticipantJIDs() const {
- std::map<std::string, JID> participants;
- typedef std::pair<std::string, MUCOccupant> MUCOccupantPair;
- std::map<std::string, MUCOccupant> occupants = muc_->getOccupants();
- foreach(const MUCOccupantPair& occupant, occupants) {
- if (occupant.first != nick_) {
- participants[occupant.first] = occupant.second.getRealJID().is_initialized() ? occupant.second.getRealJID().get().toBare() : JID();
- }
- }
- return participants;
+ std::map<std::string, JID> participants;
+ std::map<std::string, MUCOccupant> occupants = muc_->getOccupants();
+ for (const auto& occupant : occupants) {
+ if (occupant.first != nick_) {
+ participants[occupant.first] = occupant.second.getRealJID().is_initialized() ? occupant.second.getRealJID().get().toBare() : JID();
+ }
+ }
+ return participants;
}
void MUCController::sendInvites(const std::vector<JID>& jids, const std::string& reason) const {
- foreach (const JID& jid, jids) {
- muc_->invitePerson(jid, reason, isImpromptu_);
- }
+ for (const auto& jid : jids) {
+ muc_->invitePerson(jid, reason, isImpromptu_);
+ }
}
void MUCController::handleJoinTimeoutTick() {
- receivedActivity();
- chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "Room %1% is not responding. This operation may never complete.")) % toJID_.toString())), ChatWindow::DefaultDirection);
+ receivedActivity();
+ chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "Room %1% is not responding. This operation may never complete.")) % toJID_.toString())), ChatWindow::DefaultDirection);
}
void MUCController::receivedActivity() {
- if (loginCheckTimer_) {
- loginCheckTimer_->stop();
- }
+ if (loginCheckTimer_) {
+ loginCheckTimer_->stop();
+ }
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wswitch-enum"
-void MUCController::handleJoinFailed(boost::shared_ptr<ErrorPayload> error) {
- receivedActivity();
- std::string errorMessage = QT_TRANSLATE_NOOP("", "Unable to enter this room");
- std::string rejoinNick;
- if (error) {
- switch (error->getCondition()) {
- case ErrorPayload::Conflict:
- rejoinNick = nick_ + "_";
- errorMessage = str(format(QT_TRANSLATE_NOOP("", "Unable to enter this room as %1%, retrying as %2%")) % nick_ % rejoinNick);
- break;
- case ErrorPayload::JIDMalformed:
- errorMessage += ": ";
- errorMessage += QT_TRANSLATE_NOOP("", "No nickname specified");
- break;
- case ErrorPayload::NotAuthorized:
- errorMessage += ": ";
- errorMessage += QT_TRANSLATE_NOOP("", "The correct room password is needed");
- break;
- case ErrorPayload::RegistrationRequired:
- errorMessage += ": ";
- errorMessage += QT_TRANSLATE_NOOP("", "Only members may enter");
- break;
- case ErrorPayload::Forbidden:
- errorMessage += ": ";
- errorMessage += QT_TRANSLATE_NOOP("", "You are banned from the room");
- break;
- case ErrorPayload::ServiceUnavailable:
- errorMessage += ": ";
- errorMessage += QT_TRANSLATE_NOOP("", "The room is full");
- break;
- case ErrorPayload::ItemNotFound:
- errorMessage += ": ";
- errorMessage += QT_TRANSLATE_NOOP("", "The room does not exist");
- break;
-
- default: break;
- }
- }
- errorMessage = str(format(QT_TRANSLATE_NOOP("", "Couldn't enter room: %1%.")) % errorMessage);
- chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage));
- parting_ = true;
- if (!rejoinNick.empty() && renameCounter_ < 10) {
- renameCounter_++;
- setNick(rejoinNick);
- rejoin();
- }
+void MUCController::handleJoinFailed(std::shared_ptr<ErrorPayload> error) {
+ receivedActivity();
+ std::string errorMessage = QT_TRANSLATE_NOOP("", "Unable to enter this room");
+ std::string rejoinNick;
+ if (error) {
+ switch (error->getCondition()) {
+ case ErrorPayload::Conflict:
+ rejoinNick = nick_ + "_";
+ errorMessage = str(format(QT_TRANSLATE_NOOP("", "Unable to enter this room as %1%, retrying as %2%")) % nick_ % rejoinNick);
+ break;
+ case ErrorPayload::JIDMalformed:
+ errorMessage += ": ";
+ errorMessage += QT_TRANSLATE_NOOP("", "No nickname specified");
+ break;
+ case ErrorPayload::NotAuthorized:
+ errorMessage += ": ";
+ errorMessage += QT_TRANSLATE_NOOP("", "The correct room password is needed");
+ break;
+ case ErrorPayload::RegistrationRequired:
+ errorMessage += ": ";
+ errorMessage += QT_TRANSLATE_NOOP("", "Only members may enter");
+ break;
+ case ErrorPayload::Forbidden:
+ errorMessage += ": ";
+ errorMessage += QT_TRANSLATE_NOOP("", "You are banned from the room");
+ break;
+ case ErrorPayload::ServiceUnavailable:
+ errorMessage += ": ";
+ errorMessage += QT_TRANSLATE_NOOP("", "The room is full");
+ break;
+ case ErrorPayload::ItemNotFound:
+ errorMessage += ": ";
+ errorMessage += QT_TRANSLATE_NOOP("", "The room does not exist");
+ break;
+
+ default: break;
+ }
+ }
+ errorMessage = str(format(QT_TRANSLATE_NOOP("", "Couldn't enter room: %1%.")) % errorMessage);
+ chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage));
+ parting_ = true;
+ if (!rejoinNick.empty() && renameCounter_ < 10) {
+ renameCounter_++;
+ setNick(rejoinNick);
+ rejoin();
+ }
}
#pragma clang diagnostic pop
void MUCController::handleJoinComplete(const std::string& nick) {
- receivedActivity();
- renameCounter_ = 0;
- joined_ = true;
- std::string joinMessage;
- if (isImpromptu_) {
- joinMessage = str(format(QT_TRANSLATE_NOOP("", "You have joined the chat as %1%.")) % nick);
- } else {
- joinMessage = str(format(QT_TRANSLATE_NOOP("", "You have entered room %1% as %2%.")) % toJID_.toString() % nick);
- }
- setNick(nick);
- chatWindow_->replaceSystemMessage(chatMessageParser_->parseMessageBody(joinMessage), lastJoinMessageUID_, ChatWindow::UpdateTimestamp);
- lastJoinMessageUID_ = "";
+ receivedActivity();
+ renameCounter_ = 0;
+ joined_ = true;
+ std::string joinMessage;
+ if (isImpromptu_) {
+ joinMessage = str(format(QT_TRANSLATE_NOOP("", "You have joined the chat as %1%.")) % nick);
+ } else {
+ joinMessage = str(format(QT_TRANSLATE_NOOP("", "You have entered room %1% as %2%.")) % toJID_.toString() % nick);
+ }
+ setNick(nick);
+ chatWindow_->replaceSystemMessage(chatMessageParser_->parseMessageBody(joinMessage), lastJoinMessageUID_, ChatWindow::UpdateTimestamp);
+ lastJoinMessageUID_ = "";
#ifdef SWIFT_EXPERIMENTAL_HISTORY
- addRecentLogs();
+ addRecentLogs();
#endif
- clearPresenceQueue();
- shouldJoinOnReconnect_ = true;
- setEnabled(true);
- if (isImpromptu_) {
- setAvailableRoomActions(MUCOccupant::NoAffiliation, MUCOccupant::Participant);
- } else {
- MUCOccupant occupant = muc_->getOccupant(nick);
- setAvailableRoomActions(occupant.getAffiliation(), occupant.getRole());
- }
- onUserJoined();
+ clearPresenceQueue();
+ shouldJoinOnReconnect_ = true;
+ setEnabled(true);
+ if (isImpromptu_) {
+ setAvailableRoomActions(MUCOccupant::NoAffiliation, MUCOccupant::Participant);
+ } else {
+ MUCOccupant occupant = muc_->getOccupant(nick);
+ setAvailableRoomActions(occupant.getAffiliation(), occupant.getRole());
+ }
+ onUserJoined();
- if (isImpromptu_) {
- setImpromptuWindowTitle();
- }
+ if (isImpromptu_) {
+ setImpromptuWindowTitle();
+ }
}
void MUCController::handleAvatarChanged(const JID& jid) {
- if (parting_ || !jid.equals(toJID_, JID::WithoutResource)) {
- return;
- }
- roster_->applyOnItems(SetAvatar(jid, avatarManager_->getAvatarPath(jid), JID::WithResource));
+ if (parting_ || !jid.equals(toJID_, JID::WithoutResource)) {
+ return;
+ }
+ roster_->applyOnItems(SetAvatar(jid, avatarManager_->getAvatarPath(jid), JID::WithResource));
}
void MUCController::handleWindowClosed() {
- parting_ = true;
- shouldJoinOnReconnect_ = false;
- muc_->part();
- onUserLeft();
+ parting_ = true;
+ shouldJoinOnReconnect_ = false;
+ muc_->part();
+ onUserLeft();
}
void MUCController::handleOccupantJoined(const MUCOccupant& occupant) {
- if (nick_ != occupant.getNick()) {
- completer_->addWord(occupant.getNick());
- }
- receivedActivity();
- JID jid(nickToJID(occupant.getNick()));
- JID realJID;
- if (occupant.getRealJID()) {
- realJID = occupant.getRealJID().get();
- }
- currentOccupants_.insert(occupant.getNick());
- NickJoinPart event(occupant.getNick(), Join);
- appendToJoinParts(joinParts_, event);
- MUCOccupant::Role role = MUCOccupant::Participant;
- MUCOccupant::Affiliation affiliation = MUCOccupant::NoAffiliation;
- if (!isImpromptu_) {
- role = occupant.getRole();
- affiliation = occupant.getAffiliation();
- }
- std::string groupName(roleToGroupName(role));
- roster_->addContact(jid, realJID, occupant.getNick(), groupName, avatarManager_->getAvatarPath(jid));
- roster_->applyOnItems(SetMUC(jid, role, affiliation));
- roster_->getGroup(groupName)->setManualSort(roleToSortName(role));
- if (joined_) {
- std::string joinString;
- if (role != MUCOccupant::NoRole && role != MUCOccupant::Participant) {
- joinString = str(format(QT_TRANSLATE_NOOP("", "%1% has entered the %3% as a %2%.")) % occupant.getNick() % roleToFriendlyName(role) % (isImpromptu_ ? QT_TRANSLATE_NOOP("", "chat") : QT_TRANSLATE_NOOP("", "room")));
- }
- else {
- joinString = str(format(QT_TRANSLATE_NOOP("", "%1% has entered the %2%.")) % occupant.getNick() % (isImpromptu_ ? QT_TRANSLATE_NOOP("", "chat") : QT_TRANSLATE_NOOP("", "room")));
- }
- if (shouldUpdateJoinParts()) {
- updateJoinParts();
- } else {
- addPresenceMessage(joinString);
- }
-
- if (isImpromptu_) {
- setImpromptuWindowTitle();
- onActivity("");
- }
- }
- if (avatarManager_ != NULL) {
- handleAvatarChanged(jid);
- }
+ if (nick_ != occupant.getNick()) {
+ completer_->addWord(occupant.getNick());
+ }
+ receivedActivity();
+ JID jid(nickToJID(occupant.getNick()));
+ JID realJID;
+ if (occupant.getRealJID()) {
+ realJID = occupant.getRealJID().get();
+ }
+ currentOccupants_.insert(occupant.getNick());
+ NickJoinPart event(occupant.getNick(), Join);
+ appendToJoinParts(joinParts_, event);
+ MUCOccupant::Role role = MUCOccupant::Participant;
+ MUCOccupant::Affiliation affiliation = MUCOccupant::NoAffiliation;
+ if (!isImpromptu_) {
+ role = occupant.getRole();
+ affiliation = occupant.getAffiliation();
+ }
+ std::string groupName(roleToGroupName(role));
+ roster_->addContact(jid, realJID, occupant.getNick(), groupName, avatarManager_->getAvatarPath(jid));
+ roster_->applyOnItems(SetMUC(jid, role, affiliation));
+ roster_->getGroup(groupName)->setManualSort(roleToSortName(role));
+ if (joined_) {
+ std::string joinString;
+ if (role != MUCOccupant::NoRole && role != MUCOccupant::Participant) {
+ joinString = str(format(QT_TRANSLATE_NOOP("", "%1% has entered the %3% as a %2%.")) % occupant.getNick() % roleToFriendlyName(role) % (isImpromptu_ ? QT_TRANSLATE_NOOP("", "chat") : QT_TRANSLATE_NOOP("", "room")));
+ }
+ else {
+ joinString = str(format(QT_TRANSLATE_NOOP("", "%1% has entered the %2%.")) % occupant.getNick() % (isImpromptu_ ? QT_TRANSLATE_NOOP("", "chat") : QT_TRANSLATE_NOOP("", "room")));
+ }
+ if (shouldUpdateJoinParts()) {
+ updateJoinParts();
+ } else {
+ addPresenceMessage(joinString);
+ }
+
+ if (isImpromptu_) {
+ setImpromptuWindowTitle();
+ onActivity("");
+ }
+ }
+ if (avatarManager_ != nullptr) {
+ handleAvatarChanged(jid);
+ }
}
void MUCController::addPresenceMessage(const std::string& message) {
- lastWasPresence_ = true;
- chatWindow_->addPresenceMessage(chatMessageParser_->parseMessageBody(message), ChatWindow::DefaultDirection);
+ lastWasPresence_ = true;
+ chatWindow_->addPresenceMessage(chatMessageParser_->parseMessageBody(message), ChatWindow::DefaultDirection);
}
void MUCController::setAvailableRoomActions(const MUCOccupant::Affiliation& affiliation, const MUCOccupant::Role& role)
{
- std::vector<ChatWindow::RoomAction> actions;
-
- if (role <= MUCOccupant::Participant) {
- actions.push_back(ChatWindow::ChangeSubject);
- }
- if (affiliation == MUCOccupant::Owner) {
- actions.push_back(ChatWindow::Configure);
- }
- if (affiliation <= MUCOccupant::Admin) {
- actions.push_back(ChatWindow::Affiliations);
- }
- if (affiliation == MUCOccupant::Owner) {
- actions.push_back(ChatWindow::Destroy);
- }
- if (role <= MUCOccupant::Visitor) {
- actions.push_back(ChatWindow::Invite);
- }
- chatWindow_->setAvailableRoomActions(actions);
+ std::vector<ChatWindow::RoomAction> actions;
+
+ if (role <= MUCOccupant::Participant) {
+ actions.push_back(ChatWindow::ChangeSubject);
+ }
+ if (affiliation == MUCOccupant::Owner) {
+ actions.push_back(ChatWindow::Configure);
+ }
+ if (affiliation <= MUCOccupant::Admin) {
+ actions.push_back(ChatWindow::Affiliations);
+ }
+ if (affiliation == MUCOccupant::Owner) {
+ actions.push_back(ChatWindow::Destroy);
+ }
+ if (role <= MUCOccupant::Visitor) {
+ actions.push_back(ChatWindow::Invite);
+ }
+ chatWindow_->setAvailableRoomActions(actions);
}
void MUCController::clearPresenceQueue() {
- lastWasPresence_ = false;
- joinParts_.clear();
+ lastWasPresence_ = false;
+ joinParts_.clear();
}
std::string MUCController::roleToFriendlyName(MUCOccupant::Role role) {
- switch (role) {
- case MUCOccupant::Moderator: return QT_TRANSLATE_NOOP("", "moderator");
- case MUCOccupant::Participant: return QT_TRANSLATE_NOOP("", "participant");
- case MUCOccupant::Visitor: return QT_TRANSLATE_NOOP("", "visitor");
- case MUCOccupant::NoRole: return "";
- }
- assert(false);
- return "";
+ switch (role) {
+ case MUCOccupant::Moderator: return QT_TRANSLATE_NOOP("", "moderator");
+ case MUCOccupant::Participant: return QT_TRANSLATE_NOOP("", "participant");
+ case MUCOccupant::Visitor: return QT_TRANSLATE_NOOP("", "visitor");
+ case MUCOccupant::NoRole: return "";
+ }
+ assert(false);
+ return "";
}
std::string MUCController::roleToSortName(MUCOccupant::Role role) {
- switch (role) {
- case MUCOccupant::Moderator: return "1";
- case MUCOccupant::Participant: return "2";
- case MUCOccupant::Visitor: return "3";
- case MUCOccupant::NoRole: return "4";
- }
- assert(false);
- return "5";
+ switch (role) {
+ case MUCOccupant::Moderator: return "1";
+ case MUCOccupant::Participant: return "2";
+ case MUCOccupant::Visitor: return "3";
+ case MUCOccupant::NoRole: return "4";
+ }
+ assert(false);
+ return "5";
}
JID MUCController::nickToJID(const std::string& nick) {
- return muc_->getJID().withResource(nick);
-}
-
-bool MUCController::messageTargetsMe(boost::shared_ptr<Message> message) {
- std::string stringRegexp(".*\\b" + boost::to_lower_copy(nick_) + "\\b.*");
- boost::regex myRegexp(stringRegexp);
- return boost::regex_match(boost::to_lower_copy(message->getBody().get_value_or("")), myRegexp);
-}
-
-void MUCController::preHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent) {
- if (messageEvent->getStanza()->getType() == Message::Groupchat) {
- lastActivity_ = boost::posix_time::microsec_clock::universal_time();
- }
- clearPresenceQueue();
- boost::shared_ptr<Message> message = messageEvent->getStanza();
- if (joined_ && messageEvent->getStanza()->getFrom().getResource() != nick_ && messageTargetsMe(message) && !message->getPayload<Delay>() && messageEvent->isReadable()) {
- chatWindow_->flash();
- }
- else {
- messageEvent->setTargetsMe(false);
- }
- if (messageEvent->isReadable() && isImpromptu_) {
- chatWindow_->flash(); /* behave like a regular char*/
- }
- if (joined_) {
- std::string nick = message->getFrom().getResource();
- if (nick != nick_ && currentOccupants_.find(nick) != currentOccupants_.end()) {
- completer_->addWord(nick);
- }
- }
- /*Buggy implementations never send the status code, so use an incoming message as a hint that joining's done (e.g. the old ejabberd on psi-im.org).*/
- receivedActivity();
- joined_ = true;
-
- if (message->hasSubject() && !message->getPayload<Body>() && !message->getPayload<Thread>()) {
- chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "The room subject is now: %1%")) % message->getSubject())), ChatWindow::DefaultDirection);
- chatWindow_->setSubject(message->getSubject());
- doneGettingHistory_ = true;
- }
-
- if (!doneGettingHistory_ && !message->getPayload<Delay>()) {
- doneGettingHistory_ = true;
- }
-
- if (!doneGettingHistory_) {
- checkDuplicates(message);
- messageEvent->conclude();
- }
-}
-
-void MUCController::addMessageHandleIncomingMessage(const JID& from, const std::string& message, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
- if (from.isBare()) {
- chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "%1%")) % message)), ChatWindow::DefaultDirection);
- }
- else {
- ChatControllerBase::addMessageHandleIncomingMessage(from, message, senderIsSelf, label, time, highlight);
- }
-}
-
-void MUCController::postHandleIncomingMessage(boost::shared_ptr<MessageEvent> messageEvent, const HighlightAction& highlight) {
- boost::shared_ptr<Message> message = messageEvent->getStanza();
- if (joined_ && messageEvent->getStanza()->getFrom().getResource() != nick_ && !message->getPayload<Delay>()) {
- if (messageTargetsMe(message) || isImpromptu_) {
- eventController_->handleIncomingEvent(messageEvent);
- }
- if (!messageEvent->getConcluded()) {
- highlighter_->handleHighlightAction(highlight);
- }
- }
+ return muc_->getJID().withResource(nick);
+}
+
+bool MUCController::messageTargetsMe(std::shared_ptr<Message> message) {
+ std::string stringRegexp(".*\\b" + boost::to_lower_copy(nick_) + "\\b.*");
+ boost::regex myRegexp(stringRegexp);
+ return boost::regex_match(boost::to_lower_copy(message->getBody().get_value_or("")), myRegexp);
+}
+
+void MUCController::preHandleIncomingMessage(std::shared_ptr<MessageEvent> messageEvent) {
+ if (messageEvent->getStanza()->getType() == Message::Groupchat) {
+ lastActivity_ = boost::posix_time::microsec_clock::universal_time();
+ }
+ clearPresenceQueue();
+ std::shared_ptr<Message> message = messageEvent->getStanza();
+ if (joined_ && messageEvent->getStanza()->getFrom().getResource() != nick_ && messageTargetsMe(message) && !message->getPayload<Delay>() && messageEvent->isReadable()) {
+ chatWindow_->flash();
+ }
+ else {
+ messageEvent->setTargetsMe(false);
+ }
+ if (messageEvent->isReadable() && isImpromptu_) {
+ chatWindow_->flash(); /* behave like a regular char*/
+ }
+ if (joined_) {
+ std::string nick = message->getFrom().getResource();
+ if (nick != nick_ && currentOccupants_.find(nick) != currentOccupants_.end()) {
+ completer_->addWord(nick);
+ }
+ }
+ /*Buggy implementations never send the status code, so use an incoming message as a hint that joining's done (e.g. the old ejabberd on psi-im.org).*/
+ receivedActivity();
+ joined_ = true;
+
+ if (message->hasSubject() && !message->getPayload<Body>() && !message->getPayload<Thread>()) {
+ chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "The room subject is now: %1%")) % message->getSubject())), ChatWindow::DefaultDirection);
+ chatWindow_->setSubject(message->getSubject());
+ doneGettingHistory_ = true;
+ }
+
+ if (!doneGettingHistory_ && !message->getPayload<Delay>()) {
+ doneGettingHistory_ = true;
+ }
+
+ if (!doneGettingHistory_) {
+ checkDuplicates(message);
+ messageEvent->conclude();
+ }
+}
+
+void MUCController::addMessageHandleIncomingMessage(const JID& from, const ChatWindow::ChatMessage& message, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& time) {
+ if (from.isBare()) {
+ chatWindow_->addSystemMessage(message, ChatWindow::DefaultDirection);
+ }
+ else {
+ ChatControllerBase::addMessageHandleIncomingMessage(from, message, senderIsSelf, label, time);
+ }
+}
+
+void MUCController::postHandleIncomingMessage(std::shared_ptr<MessageEvent> messageEvent, const ChatWindow::ChatMessage& chatMessage) {
+ std::shared_ptr<Message> message = messageEvent->getStanza();
+ if (joined_ && messageEvent->getStanza()->getFrom().getResource() != nick_ && !message->getPayload<Delay>()) {
+ if (messageTargetsMe(message) || isImpromptu_) {
+ eventController_->handleIncomingEvent(messageEvent);
+ }
+ if (!messageEvent->getConcluded()) {
+ handleHighlightActions(chatMessage);
+ }
+ }
}
void MUCController::handleOccupantRoleChanged(const std::string& nick, const MUCOccupant& occupant, const MUCOccupant::Role& oldRole) {
- clearPresenceQueue();
- receivedActivity();
- JID jid(nickToJID(nick));
- roster_->removeContactFromGroup(jid, roleToGroupName(oldRole));
- JID realJID;
- if (occupant.getRealJID()) {
- realJID = occupant.getRealJID().get();
- }
- std::string group(roleToGroupName(occupant.getRole()));
- roster_->addContact(jid, realJID, nick, group, avatarManager_->getAvatarPath(jid));
- roster_->getGroup(group)->setManualSort(roleToSortName(occupant.getRole()));
- roster_->applyOnItems(SetMUC(jid, occupant.getRole(), occupant.getAffiliation()));
- chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "%1% is now a %2%")) % nick % roleToFriendlyName(occupant.getRole()))), ChatWindow::DefaultDirection);
- if (nick == nick_) {
- setAvailableRoomActions(occupant.getAffiliation(), occupant.getRole());
- }
+ clearPresenceQueue();
+ receivedActivity();
+ JID jid(nickToJID(nick));
+ roster_->removeContactFromGroup(jid, roleToGroupName(oldRole));
+ JID realJID;
+ if (occupant.getRealJID()) {
+ realJID = occupant.getRealJID().get();
+ }
+ std::string group(roleToGroupName(occupant.getRole()));
+ roster_->addContact(jid, realJID, nick, group, avatarManager_->getAvatarPath(jid));
+ roster_->getGroup(group)->setManualSort(roleToSortName(occupant.getRole()));
+ roster_->applyOnItems(SetMUC(jid, occupant.getRole(), occupant.getAffiliation()));
+ chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "%1% is now a %2%")) % nick % roleToFriendlyName(occupant.getRole()))), ChatWindow::DefaultDirection);
+ if (nick == nick_) {
+ setAvailableRoomActions(occupant.getAffiliation(), occupant.getRole());
+ }
}
void MUCController::handleOccupantAffiliationChanged(const std::string& nick, const MUCOccupant::Affiliation& affiliation, const MUCOccupant::Affiliation& /*oldAffiliation*/)
{
- if (nick == nick_) {
- setAvailableRoomActions(affiliation, muc_->getOccupant(nick_).getRole());
- }
- JID jid(nickToJID(nick));
- MUCOccupant occupant = muc_->getOccupant(nick);
- roster_->applyOnItems(SetMUC(jid, occupant.getRole(), affiliation));
+ if (nick == nick_) {
+ setAvailableRoomActions(affiliation, muc_->getOccupant(nick_).getRole());
+ }
+ JID jid(nickToJID(nick));
+ MUCOccupant occupant = muc_->getOccupant(nick);
+ roster_->applyOnItems(SetMUC(jid, occupant.getRole(), affiliation));
}
std::string MUCController::roleToGroupName(MUCOccupant::Role role) {
- std::string result;
- switch (role) {
- case MUCOccupant::Moderator: result = QT_TRANSLATE_NOOP("", "Moderators"); break;
- case MUCOccupant::Participant: result = QT_TRANSLATE_NOOP("", "Participants"); break;
- case MUCOccupant::Visitor: result = QT_TRANSLATE_NOOP("", "Visitors"); break;
- case MUCOccupant::NoRole: result = QT_TRANSLATE_NOOP("", "Occupants"); break;
- }
- return result;
+ std::string result;
+ switch (role) {
+ case MUCOccupant::Moderator: result = QT_TRANSLATE_NOOP("", "Moderators"); break;
+ case MUCOccupant::Participant: result = QT_TRANSLATE_NOOP("", "Participants"); break;
+ case MUCOccupant::Visitor: result = QT_TRANSLATE_NOOP("", "Visitors"); break;
+ case MUCOccupant::NoRole: result = QT_TRANSLATE_NOOP("", "Occupants"); break;
+ }
+ return result;
}
void MUCController::setOnline(bool online) {
- ChatControllerBase::setOnline(online);
- if (!online) {
- muc_->part();
- parting_ = true;
- processUserPart();
- } else {
- if (shouldJoinOnReconnect_) {
- renameCounter_ = 0;
- boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList();
- if (blockList && blockList->isBlocked(muc_->getJID())) {
- handleBlockingStateChanged();
- lastJoinMessageUID_ = chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "You've blocked this room. To enter the room, first unblock it using the cog menu and try again")), ChatWindow::DefaultDirection);
- }
- else {
- if (isImpromptu_) {
- lastJoinMessageUID_ = chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "Trying to join chat")), ChatWindow::DefaultDirection);
- } else {
- lastJoinMessageUID_ = chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "Trying to enter room %1%")) % toJID_.toString())), ChatWindow::DefaultDirection);
- }
- if (loginCheckTimer_) {
- loginCheckTimer_->start();
- }
- setNick(desiredNick_);
- rejoin();
- }
- }
- }
+ ChatControllerBase::setOnline(online);
+ if (!online) {
+ muc_->part();
+ parting_ = true;
+ processUserPart();
+ } else {
+ if (shouldJoinOnReconnect_) {
+ renameCounter_ = 0;
+ std::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList();
+ if (blockList && blockList->isBlocked(muc_->getJID())) {
+ handleBlockingStateChanged();
+ lastJoinMessageUID_ = chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "You've blocked this room. To enter the room, first unblock it using the cog menu and try again")), ChatWindow::DefaultDirection);
+ }
+ else {
+ if (isImpromptu_) {
+ lastJoinMessageUID_ = chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "Trying to join chat")), ChatWindow::DefaultDirection);
+ } else {
+ lastJoinMessageUID_ = chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(str(format(QT_TRANSLATE_NOOP("", "Trying to enter room %1%")) % toJID_.toString())), ChatWindow::DefaultDirection);
+ }
+ if (loginCheckTimer_) {
+ loginCheckTimer_->start();
+ }
+ setNick(desiredNick_);
+ rejoin();
+ }
+ }
+ }
}
void MUCController::processUserPart() {
- roster_->removeAll();
- /* handleUserLeft won't throw a part back up unless this is called
- when it doesn't yet know we've left - which only happens on
- disconnect, so call with disconnect here so if the signal does
- bubble back up, it'll be with the right type.*/
- muc_->handleUserLeft(MUC::Disconnect);
- setEnabled(false);
+ roster_->removeAll();
+ /* handleUserLeft won't throw a part back up unless this is called
+ when it doesn't yet know we've left - which only happens on
+ disconnect, so call with disconnect here so if the signal does
+ bubble back up, it'll be with the right type.*/
+ muc_->handleUserLeft(MUC::Disconnect);
+ setEnabled(false);
}
bool MUCController::shouldUpdateJoinParts() {
- return lastWasPresence_;
+ return lastWasPresence_;
}
void MUCController::handleOccupantLeft(const MUCOccupant& occupant, MUC::LeavingType type, const std::string& reason) {
- NickJoinPart event(occupant.getNick(), Part);
- appendToJoinParts(joinParts_, event);
- currentOccupants_.erase(occupant.getNick());
- completer_->removeWord(occupant.getNick());
- std::string partMessage;
- bool clearAfter = false;
- if (occupant.getNick() != nick_) {
- std::string partType;
- switch (type) {
- case MUC::LeaveKick: clearPresenceQueue(); clearAfter = true; partType = " (kicked)"; break;
- case MUC::LeaveBan: clearPresenceQueue(); clearAfter = true; partType = " (banned)"; break;
- case MUC::LeaveNotMember: clearPresenceQueue(); clearAfter = true; partType = " (no longer a member)"; break;
- case MUC::LeaveDestroy:
- case MUC::Disconnect:
- case MUC::LeavePart: break;
- }
- if (isImpromptu_) {
- partMessage = str(format(QT_TRANSLATE_NOOP("", "%1% has left the chat%2%")) % occupant.getNick() % partType);
- } else {
- partMessage = str(format(QT_TRANSLATE_NOOP("", "%1% has left the room%2%")) % occupant.getNick() % partType);
- }
- }
- else if (isImpromptu_) {
- switch (type) {
- case MUC::LeaveKick:
- case MUC::LeaveBan: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You have been removed from this chat"); break;
- case MUC::LeaveNotMember: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You have been removed from this chat"); break;
- case MUC::LeaveDestroy: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "This chat has ended"); break;
- case MUC::Disconnect:
- case MUC::LeavePart: partMessage = QT_TRANSLATE_NOOP("", "You have left the chat");
- }
- }
- else {
- switch (type) {
- case MUC::LeaveKick: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You have been kicked out of the room"); break;
- case MUC::LeaveBan: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You have been banned from the room"); break;
- case MUC::LeaveNotMember: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You are no longer a member of the room and have been removed"); break;
- case MUC::LeaveDestroy: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "The room has been destroyed"); break;
- case MUC::Disconnect:
- case MUC::LeavePart: partMessage = QT_TRANSLATE_NOOP("", "You have left the room");
- }
- }
- if (!reason.empty()) {
- partMessage += " (" + reason + ")";
- }
- partMessage += ".";
-
- if (occupant.getNick() != nick_) {
- if (shouldUpdateJoinParts()) {
- updateJoinParts();
- } else {
- addPresenceMessage(partMessage);
- }
- roster_->removeContact(JID(toJID_.getNode(), toJID_.getDomain(), occupant.getNick()));
- } else {
- addPresenceMessage(partMessage);
- parting_ = true;
- processUserPart();
- }
- if (clearAfter) {
- clearPresenceQueue();
- }
-
- if (isImpromptu_) {
- setImpromptuWindowTitle();
- }
+ NickJoinPart event(occupant.getNick(), Part);
+ appendToJoinParts(joinParts_, event);
+ currentOccupants_.erase(occupant.getNick());
+ completer_->removeWord(occupant.getNick());
+ std::string partMessage;
+ bool clearAfter = false;
+ if (occupant.getNick() != nick_) {
+ std::string partType;
+ switch (type) {
+ case MUC::LeaveKick: clearPresenceQueue(); clearAfter = true; partType = " (kicked)"; break;
+ case MUC::LeaveBan: clearPresenceQueue(); clearAfter = true; partType = " (banned)"; break;
+ case MUC::LeaveNotMember: clearPresenceQueue(); clearAfter = true; partType = " (no longer a member)"; break;
+ case MUC::LeaveDestroy:
+ case MUC::Disconnect:
+ case MUC::LeavePart: break;
+ }
+ if (isImpromptu_) {
+ partMessage = str(format(QT_TRANSLATE_NOOP("", "%1% has left the chat%2%")) % occupant.getNick() % partType);
+ } else {
+ partMessage = str(format(QT_TRANSLATE_NOOP("", "%1% has left the room%2%")) % occupant.getNick() % partType);
+ }
+ }
+ else if (isImpromptu_) {
+ switch (type) {
+ case MUC::LeaveKick:
+ case MUC::LeaveBan: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You have been removed from this chat"); break;
+ case MUC::LeaveNotMember: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You have been removed from this chat"); break;
+ case MUC::LeaveDestroy: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "This chat has ended"); break;
+ case MUC::Disconnect:
+ case MUC::LeavePart: partMessage = QT_TRANSLATE_NOOP("", "You have left the chat");
+ }
+ }
+ else {
+ switch (type) {
+ case MUC::LeaveKick: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You have been kicked out of the room"); break;
+ case MUC::LeaveBan: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You have been banned from the room"); break;
+ case MUC::LeaveNotMember: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "You are no longer a member of the room and have been removed"); break;
+ case MUC::LeaveDestroy: clearPresenceQueue(); clearAfter = true; partMessage = QT_TRANSLATE_NOOP("", "The room has been destroyed"); break;
+ case MUC::Disconnect:
+ case MUC::LeavePart: partMessage = QT_TRANSLATE_NOOP("", "You have left the room");
+ }
+ }
+ if (!reason.empty()) {
+ partMessage += " (" + reason + ")";
+ }
+ partMessage += ".";
+
+ if (occupant.getNick() != nick_) {
+ if (shouldUpdateJoinParts()) {
+ updateJoinParts();
+ } else {
+ addPresenceMessage(partMessage);
+ }
+ roster_->removeContact(JID(toJID_.getNode(), toJID_.getDomain(), occupant.getNick()));
+ } else {
+ addPresenceMessage(partMessage);
+ parting_ = true;
+ processUserPart();
+ }
+ if (clearAfter) {
+ clearPresenceQueue();
+ }
+
+ if (isImpromptu_) {
+ setImpromptuWindowTitle();
+ }
}
void MUCController::handleOccupantNicknameChanged(const std::string& oldNickname, const std::string& newNickname) {
- addPresenceMessage(generateNicknameChangeString(oldNickname, newNickname));
- JID oldJID = muc_->getJID().withResource(oldNickname);
- JID newJID = muc_->getJID().withResource(newNickname);
+ addPresenceMessage(generateNicknameChangeString(oldNickname, newNickname));
+ JID oldJID = muc_->getJID().withResource(oldNickname);
+ JID newJID = muc_->getJID().withResource(newNickname);
- // adjust occupants
- currentOccupants_.erase(oldNickname);
- currentOccupants_.insert(newNickname);
+ // adjust occupants
+ currentOccupants_.erase(oldNickname);
+ currentOccupants_.insert(newNickname);
- // adjust completer
- completer_->removeWord(oldNickname);
- completer_->addWord(newNickname);
+ // adjust completer
+ completer_->removeWord(oldNickname);
+ completer_->addWord(newNickname);
- // update contact
- roster_->removeContact(oldJID);
- MUCOccupant occupant = muc_->getOccupant(newNickname);
+ // update contact
+ roster_->removeContact(oldJID);
+ MUCOccupant occupant = muc_->getOccupant(newNickname);
- JID realJID;
- if (occupant.getRealJID()) {
- realJID = occupant.getRealJID().get();
- }
- MUCOccupant::Role role = MUCOccupant::Participant;
- MUCOccupant::Affiliation affiliation = MUCOccupant::NoAffiliation;
- if (!isImpromptu_) {
- role = occupant.getRole();
- affiliation = occupant.getAffiliation();
- }
- std::string groupName(roleToGroupName(role));
- roster_->addContact(newJID, realJID, newNickname, groupName, avatarManager_->getAvatarPath(newJID));
- roster_->applyOnItems(SetMUC(newJID, role, affiliation));
- if (avatarManager_ != NULL) {
- handleAvatarChanged(newJID);
- }
+ JID realJID;
+ if (occupant.getRealJID()) {
+ realJID = occupant.getRealJID().get();
+ }
+ MUCOccupant::Role role = MUCOccupant::Participant;
+ MUCOccupant::Affiliation affiliation = MUCOccupant::NoAffiliation;
+ if (!isImpromptu_) {
+ role = occupant.getRole();
+ affiliation = occupant.getAffiliation();
+ }
+ std::string groupName(roleToGroupName(role));
+ roster_->addContact(newJID, realJID, newNickname, groupName, avatarManager_->getAvatarPath(newJID));
+ roster_->applyOnItems(SetMUC(newJID, role, affiliation));
+ if (avatarManager_ != nullptr) {
+ handleAvatarChanged(newJID);
+ }
- clearPresenceQueue();
- onUserNicknameChanged(oldNickname, newNickname);
+ clearPresenceQueue();
+ onUserNicknameChanged(oldNickname, newNickname);
}
-void MUCController::handleOccupantPresenceChange(boost::shared_ptr<Presence> presence) {
- receivedActivity();
- roster_->applyOnItems(SetPresence(presence, JID::WithResource));
+void MUCController::handleOccupantPresenceChange(std::shared_ptr<Presence> presence) {
+ receivedActivity();
+ roster_->applyOnItems(SetPresence(presence, JID::WithResource));
}
-bool MUCController::isIncomingMessageFromMe(boost::shared_ptr<Message> message) {
- JID from = message->getFrom();
- return nick_ == from.getResource();
+bool MUCController::isIncomingMessageFromMe(std::shared_ptr<Message> message) {
+ JID from = message->getFrom();
+ return nick_ == from.getResource();
}
std::string MUCController::senderHighlightNameFromMessage(const JID& from) {
- return from.getResource();
+ return from.getResource();
}
std::string MUCController::senderDisplayNameFromMessage(const JID& from) {
- return from.getResource();
+ return from.getResource();
}
-void MUCController::preSendMessageRequest(boost::shared_ptr<Message> message) {
- message->setType(Swift::Message::Groupchat);
+void MUCController::preSendMessageRequest(std::shared_ptr<Message> message) {
+ message->setType(Swift::Message::Groupchat);
}
-boost::optional<boost::posix_time::ptime> MUCController::getMessageTimestamp(boost::shared_ptr<Message> message) const {
- return message->getTimestampFrom(toJID_);
+boost::optional<boost::posix_time::ptime> MUCController::getMessageTimestamp(std::shared_ptr<Message> message) const {
+ return message->getTimestampFrom(toJID_);
}
void MUCController::updateJoinParts() {
- chatWindow_->replaceLastMessage(chatMessageParser_->parseMessageBody(generateJoinPartString(joinParts_, isImpromptu())), ChatWindow::UpdateTimestamp);
+ chatWindow_->replaceLastMessage(chatMessageParser_->parseMessageBody(generateJoinPartString(joinParts_, isImpromptu())), ChatWindow::UpdateTimestamp);
}
void MUCController::appendToJoinParts(std::vector<NickJoinPart>& joinParts, const NickJoinPart& newEvent) {
- std::vector<NickJoinPart>::iterator it = joinParts.begin();
- bool matched = false;
- for (; it != joinParts.end(); ++it) {
- if ((*it).nick == newEvent.nick) {
- matched = true;
- JoinPart type = (*it).type;
- switch (newEvent.type) {
- case Join: type = (type == Part) ? PartThenJoin : Join; break;
- case Part: type = (type == Join) ? JoinThenPart : Part; break;
- case PartThenJoin: break;
- case JoinThenPart: break;
- }
- (*it).type = type;
- break;
- }
- }
- if (!matched) {
- joinParts.push_back(newEvent);
- }
+ std::vector<NickJoinPart>::iterator it = joinParts.begin();
+ bool matched = false;
+ for (; it != joinParts.end(); ++it) {
+ if ((*it).nick == newEvent.nick) {
+ matched = true;
+ JoinPart type = (*it).type;
+ switch (newEvent.type) {
+ case Join: type = (type == Part) ? PartThenJoin : Join; break;
+ case Part: type = (type == Join) ? JoinThenPart : Part; break;
+ case PartThenJoin: break;
+ case JoinThenPart: break;
+ }
+ (*it).type = type;
+ break;
+ }
+ }
+ if (!matched) {
+ joinParts.push_back(newEvent);
+ }
}
std::string MUCController::concatenateListOfNames(const std::vector<NickJoinPart>& joinParts) {
- std::string result;
- for (size_t i = 0; i < joinParts.size(); i++) {
- if (i > 0) {
- if (i < joinParts.size() - 1) {
- result += ", ";
- } else {
- result += QT_TRANSLATE_NOOP("", " and ");
- }
- }
- NickJoinPart event = joinParts[i];
- result += event.nick;
- }
- return result;
+ std::string result;
+ for (size_t i = 0; i < joinParts.size(); i++) {
+ if (i > 0) {
+ if (i < joinParts.size() - 1) {
+ result += ", ";
+ } else {
+ result += QT_TRANSLATE_NOOP("", " and ");
+ }
+ }
+ NickJoinPart event = joinParts[i];
+ result += event.nick;
+ }
+ return result;
}
std::string MUCController::generateJoinPartString(const std::vector<NickJoinPart>& joinParts, bool isImpromptu) {
- std::vector<NickJoinPart> sorted[4];
- std::string eventStrings[4];
- foreach (NickJoinPart event, joinParts) {
- sorted[event.type].push_back(event);
- }
- std::string result;
- std::vector<JoinPart> populatedEvents;
- for (size_t i = 0; i < 4; i++) {
- std::string names = concatenateListOfNames(sorted[i]);
- if (!names.empty()) {
- std::string eventString;
- switch (i) {
- case Join:
- if (sorted[i].size() > 1) {
- eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have joined the chat") : QT_TRANSLATE_NOOP("", "%1% have entered the room"));
- }
- else {
- eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% has joined the chat") : QT_TRANSLATE_NOOP("", "%1% has entered the room"));
- }
- break;
- case Part:
- if (sorted[i].size() > 1) {
- eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have left the chat") : QT_TRANSLATE_NOOP("", "%1% have left the room"));
- }
- else {
- eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have left the chat") : QT_TRANSLATE_NOOP("", "%1% has left the room"));
- }
- break;
- case JoinThenPart:
- if (sorted[i].size() > 1) {
- eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have joined then left the chat") : QT_TRANSLATE_NOOP("", "%1% have entered then left the room"));
- }
- else {
- eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% has joined then left the chat") : QT_TRANSLATE_NOOP("", "%1% has entered then left the room"));
- }
- break;
- case PartThenJoin:
- if (sorted[i].size() > 1) {
- eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have left then returned to the chat") : QT_TRANSLATE_NOOP("", "%1% have left then returned to the room"));
- }
- else {
- eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% has left then returned to the chat") : QT_TRANSLATE_NOOP("", "%1% has left then returned to the room"));
- }
- break;
- }
- populatedEvents.push_back(static_cast<JoinPart>(i));
- eventStrings[i] = str(boost::format(eventString) % names);
- }
- }
- for (size_t i = 0; i < populatedEvents.size(); i++) {
- if (i > 0) {
- if (i < populatedEvents.size() - 1) {
- result += ", ";
- } else {
- result += QT_TRANSLATE_NOOP("", " and ");
- }
- }
- result += eventStrings[populatedEvents[i]];
- }
- return result;
+ std::vector<NickJoinPart> sorted[4];
+ std::string eventStrings[4];
+ for (const auto& event : joinParts) {
+ sorted[event.type].push_back(event);
+ }
+ std::string result;
+ std::vector<JoinPart> populatedEvents;
+ for (size_t i = 0; i < 4; i++) {
+ std::string names = concatenateListOfNames(sorted[i]);
+ if (!names.empty()) {
+ std::string eventString;
+ switch (i) {
+ case Join:
+ if (sorted[i].size() > 1) {
+ eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have joined the chat") : QT_TRANSLATE_NOOP("", "%1% have entered the room"));
+ }
+ else {
+ eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% has joined the chat") : QT_TRANSLATE_NOOP("", "%1% has entered the room"));
+ }
+ break;
+ case Part:
+ if (sorted[i].size() > 1) {
+ eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have left the chat") : QT_TRANSLATE_NOOP("", "%1% have left the room"));
+ }
+ else {
+ eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have left the chat") : QT_TRANSLATE_NOOP("", "%1% has left the room"));
+ }
+ break;
+ case JoinThenPart:
+ if (sorted[i].size() > 1) {
+ eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have joined then left the chat") : QT_TRANSLATE_NOOP("", "%1% have entered then left the room"));
+ }
+ else {
+ eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% has joined then left the chat") : QT_TRANSLATE_NOOP("", "%1% has entered then left the room"));
+ }
+ break;
+ case PartThenJoin:
+ if (sorted[i].size() > 1) {
+ eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% have left then returned to the chat") : QT_TRANSLATE_NOOP("", "%1% have left then returned to the room"));
+ }
+ else {
+ eventString = (isImpromptu ? QT_TRANSLATE_NOOP("", "%1% has left then returned to the chat") : QT_TRANSLATE_NOOP("", "%1% has left then returned to the room"));
+ }
+ break;
+ }
+ populatedEvents.push_back(static_cast<JoinPart>(i));
+ eventStrings[i] = str(boost::format(eventString) % names);
+ }
+ }
+ for (size_t i = 0; i < populatedEvents.size(); i++) {
+ if (i > 0) {
+ if (i < populatedEvents.size() - 1) {
+ result += ", ";
+ } else {
+ result += QT_TRANSLATE_NOOP("", " and ");
+ }
+ }
+ result += eventStrings[populatedEvents[i]];
+ }
+ return result;
}
std::string MUCController::generateNicknameChangeString(const std::string& oldNickname, const std::string& newNickname) {
- return str(boost::format(QT_TRANSLATE_NOOP("", "%1% is now known as %2%.")) % oldNickname % newNickname);
+ return str(boost::format(QT_TRANSLATE_NOOP("", "%1% is now known as %2%.")) % oldNickname % newNickname);
}
void MUCController::handleChangeSubjectRequest(const std::string& subject) {
- muc_->changeSubject(subject);
+ muc_->changeSubject(subject);
}
void MUCController::handleBookmarkRequest() {
- const JID jid = muc_->getJID();
+ const JID jid = muc_->getJID();
- // Prepare new bookmark for this room.
- MUCBookmark roomBookmark(jid, jid.toBare().toString());
- roomBookmark.setPassword(password_);
- roomBookmark.setNick(nick_);
+ // Prepare new bookmark for this room.
+ MUCBookmark roomBookmark(jid, jid.toBare().toString());
+ roomBookmark.setPassword(password_);
+ roomBookmark.setNick(nick_);
- // Check for existing bookmark for this room and, if it exists, use it instead.
- std::vector<MUCBookmark> bookmarks = mucBookmarkManager_->getBookmarks();
- foreach (const MUCBookmark& bookmark, bookmarks) {
- if (bookmark.getRoom() == jid.toBare()) {
- roomBookmark = bookmark;
- break;
- }
- }
+ // Check for existing bookmark for this room and, if it exists, use it instead.
+ std::vector<MUCBookmark> bookmarks = mucBookmarkManager_->getBookmarks();
+ for (const auto& bookmark : bookmarks) {
+ if (bookmark.getRoom() == jid.toBare()) {
+ roomBookmark = bookmark;
+ break;
+ }
+ }
- chatWindow_->showBookmarkWindow(roomBookmark);
+ chatWindow_->showBookmarkWindow(roomBookmark);
}
void MUCController::handleConfigureRequest(Form::ref form) {
- if (form) {
- muc_->configureRoom(form);
- }
- else {
- muc_->requestConfigurationForm();
- }
+ if (form) {
+ muc_->configureRoom(form);
+ }
+ else {
+ muc_->requestConfigurationForm();
+ }
}
void MUCController::handleConfigurationFailed(ErrorPayload::ref error) {
- std::string errorMessage = getErrorMessage(error);
- errorMessage = str(format(QT_TRANSLATE_NOOP("", "Room configuration failed: %1%.")) % errorMessage);
- chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage));
+ std::string errorMessage = getErrorMessage(error);
+ errorMessage = str(format(QT_TRANSLATE_NOOP("", "Room configuration failed: %1%.")) % errorMessage);
+ chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage));
}
void MUCController::handleOccupantRoleChangeFailed(ErrorPayload::ref error, const JID&, MUCOccupant::Role) {
- std::string errorMessage = getErrorMessage(error);
- errorMessage = str(format(QT_TRANSLATE_NOOP("", "Occupant role change failed: %1%.")) % errorMessage);
- chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage));
+ std::string errorMessage = getErrorMessage(error);
+ errorMessage = str(format(QT_TRANSLATE_NOOP("", "Occupant role change failed: %1%.")) % errorMessage);
+ chatWindow_->addErrorMessage(chatMessageParser_->parseMessageBody(errorMessage));
}
void MUCController::configureAsImpromptuRoom(Form::ref form) {
- muc_->configureRoom(buildImpromptuRoomConfiguration(form));
- isImpromptuAlreadyConfigured_ = true;
- onImpromptuConfigCompleted();
+ muc_->configureRoom(buildImpromptuRoomConfiguration(form));
+ isImpromptuAlreadyConfigured_ = true;
+ onImpromptuConfigCompleted();
}
void MUCController::handleConfigurationFormReceived(Form::ref form) {
- if (isImpromptu_) {
- if (!isImpromptuAlreadyConfigured_) {
- configureAsImpromptuRoom(form);
- }
- } else {
- chatWindow_->showRoomConfigurationForm(form);
- }
+ if (isImpromptu_) {
+ if (!isImpromptuAlreadyConfigured_) {
+ configureAsImpromptuRoom(form);
+ }
+ } else {
+ chatWindow_->showRoomConfigurationForm(form);
+ }
}
void MUCController::handleConfigurationCancelled() {
- muc_->cancelConfigureRoom();
+ muc_->cancelConfigureRoom();
}
void MUCController::handleDestroyRoomRequest() {
- muc_->destroyRoom();
+ muc_->destroyRoom();
}
void MUCController::handleInvitePersonToThisMUCRequest(const std::vector<JID>& jidsToInvite) {
- RequestInviteToMUCUIEvent::ImpromptuMode mode = isImpromptu_ ? RequestInviteToMUCUIEvent::Impromptu : RequestInviteToMUCUIEvent::NotImpromptu;
- boost::shared_ptr<UIEvent> event(new RequestInviteToMUCUIEvent(muc_->getJID(), jidsToInvite, mode));
- eventStream_->send(event);
+ RequestInviteToMUCUIEvent::ImpromptuMode mode = isImpromptu_ ? RequestInviteToMUCUIEvent::Impromptu : RequestInviteToMUCUIEvent::NotImpromptu;
+ eventStream_->send(std::make_shared<RequestInviteToMUCUIEvent>(getToJID(), jidsToInvite, mode));
}
-void MUCController::handleUIEvent(boost::shared_ptr<UIEvent> event) {
- boost::shared_ptr<InviteToMUCUIEvent> inviteEvent = boost::dynamic_pointer_cast<InviteToMUCUIEvent>(event);
- if (inviteEvent && inviteEvent->getRoom() == muc_->getJID()) {
- foreach (const JID& jid, inviteEvent->getInvites()) {
- muc_->invitePerson(jid, inviteEvent->getReason(), isImpromptu_);
- }
- }
+void MUCController::handleUIEvent(std::shared_ptr<UIEvent> event) {
+ std::shared_ptr<InviteToMUCUIEvent> inviteEvent = std::dynamic_pointer_cast<InviteToMUCUIEvent>(event);
+ if (inviteEvent && inviteEvent->getOriginator() == muc_->getJID()) {
+ for (const auto& jid : inviteEvent->getInvites()) {
+ muc_->invitePerson(jid, inviteEvent->getReason(), isImpromptu_);
+ }
+ }
}
void MUCController::handleGetAffiliationsRequest() {
- muc_->requestAffiliationList(MUCOccupant::Owner);
- muc_->requestAffiliationList(MUCOccupant::Admin);
- muc_->requestAffiliationList(MUCOccupant::Member);
- muc_->requestAffiliationList(MUCOccupant::Outcast);
+ muc_->requestAffiliationList(MUCOccupant::Owner);
+ muc_->requestAffiliationList(MUCOccupant::Admin);
+ muc_->requestAffiliationList(MUCOccupant::Member);
+ muc_->requestAffiliationList(MUCOccupant::Outcast);
}
-typedef std::pair<MUCOccupant::Affiliation, JID> AffiliationChangePair;
-
void MUCController::handleChangeAffiliationsRequest(const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& changes) {
- std::set<JID> addedJIDs;
- foreach (const AffiliationChangePair& change, changes) {
- if (change.first != MUCOccupant::NoAffiliation) {
- addedJIDs.insert(change.second);
- }
- }
- foreach (const AffiliationChangePair& change, changes) {
- if (change.first != MUCOccupant::NoAffiliation || addedJIDs.find(change.second) == addedJIDs.end()) {
- muc_->changeAffiliation(change.second, change.first);
- }
- }
+ std::set<JID> addedJIDs;
+ for (const auto& change : changes) {
+ if (change.first != MUCOccupant::NoAffiliation) {
+ addedJIDs.insert(change.second);
+ }
+ }
+ for (const auto& change : changes) {
+ if (change.first != MUCOccupant::NoAffiliation || addedJIDs.find(change.second) == addedJIDs.end()) {
+ muc_->changeAffiliation(change.second, change.first);
+ }
+ }
}
void MUCController::handleUnblockUserRequest() {
- eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Unblocked, muc_->getJID()));
+ eventStream_->send(std::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Unblocked, muc_->getJID()));
}
void MUCController::handleBlockingStateChanged() {
- boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList();
- if (blockList->getState() == BlockList::Available) {
- if (blockList->isBlocked(toJID_)) {
- if (!blockedContactAlert_) {
- blockedContactAlert_ = chatWindow_->addAlert(QT_TRANSLATE_NOOP("", "You've blocked this room. To enter the room, first unblock it using the cog menu and try again"));
- }
- chatWindow_->setBlockingState(ChatWindow::IsBlocked);
- } else {
- if (blockedContactAlert_) {
- chatWindow_->removeAlert(*blockedContactAlert_);
- blockedContactAlert_.reset();
- }
- chatWindow_->setBlockingState(ChatWindow::IsUnblocked);
- }
- }
+ std::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList();
+ if (blockList->getState() == BlockList::Available) {
+ if (blockList->isBlocked(toJID_)) {
+ if (!blockedContactAlert_) {
+ blockedContactAlert_ = chatWindow_->addAlert(QT_TRANSLATE_NOOP("", "You've blocked this room. To enter the room, first unblock it using the cog menu and try again"));
+ }
+ chatWindow_->setBlockingState(ChatWindow::IsBlocked);
+ } else {
+ if (blockedContactAlert_) {
+ chatWindow_->removeAlert(*blockedContactAlert_);
+ blockedContactAlert_.reset();
+ }
+ chatWindow_->setBlockingState(ChatWindow::IsUnblocked);
+ }
+ }
}
void MUCController::handleAffiliationListReceived(MUCOccupant::Affiliation affiliation, const std::vector<JID>& jids) {
- chatWindow_->setAffiliations(affiliation, jids);
+ chatWindow_->setAffiliations(affiliation, jids);
}
void MUCController::logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming) {
- // log only incoming messages
- if (isIncoming && historyController_) {
- historyController_->addMessage(message, fromJID, toJID, HistoryMessage::Groupchat, timeStamp);
- }
+ // log only incoming messages
+ if (isIncoming && historyController_) {
+ historyController_->addMessage(message, fromJID, toJID, HistoryMessage::Groupchat, timeStamp);
+ }
}
void MUCController::addRecentLogs() {
- if (!historyController_) {
- return;
- }
+ if (!historyController_) {
+ return;
+ }
- joinContext_ = historyController_->getMUCContext(selfJID_, toJID_, lastActivity_);
+ joinContext_ = historyController_->getMUCContext(selfJID_, toJID_, lastActivity_);
- foreach (const HistoryMessage& message, joinContext_) {
- bool senderIsSelf = nick_ == message.getFromJID().getResource();
+ for (const auto& message : joinContext_) {
+ bool senderIsSelf = nick_ == message.getFromJID().getResource();
- // the chatWindow uses utc timestamps
- addMessage(message.getMessage(), senderDisplayNameFromMessage(message.getFromJID()), senderIsSelf, boost::shared_ptr<SecurityLabel>(new SecurityLabel()), avatarManager_->getAvatarPath(message.getFromJID()), message.getTime() - boost::posix_time::hours(message.getOffset()), HighlightAction());
- }
+ // the chatWindow uses utc timestamps
+ addMessage(chatMessageParser_->parseMessageBody(message.getMessage()), senderDisplayNameFromMessage(message.getFromJID()), senderIsSelf, std::make_shared<SecurityLabel>(), avatarManager_->getAvatarPath(message.getFromJID()), message.getTime() - boost::posix_time::hours(message.getOffset()));
+ }
}
-void MUCController::checkDuplicates(boost::shared_ptr<Message> newMessage) {
- std::string body = newMessage->getBody().get_value_or("");
- JID jid = newMessage->getFrom();
- boost::optional<boost::posix_time::ptime> time = newMessage->getTimestamp();
+void MUCController::checkDuplicates(std::shared_ptr<Message> newMessage) {
+ std::string body = newMessage->getBody().get_value_or("");
+ JID jid = newMessage->getFrom();
+ boost::optional<boost::posix_time::ptime> time = newMessage->getTimestamp();
- reverse_foreach (const HistoryMessage& message, joinContext_) {
- boost::posix_time::ptime messageTime = message.getTime() - boost::posix_time::hours(message.getOffset());
- if (time && time < messageTime) {
- break;
- }
- if (time && time != messageTime) {
- continue;
- }
- if (message.getFromJID() != jid) {
- continue;
- }
- if (message.getMessage() != body) {
- continue;
- }
+ for (const auto& message : boost::adaptors::reverse(joinContext_)) {
+ boost::posix_time::ptime messageTime = message.getTime() - boost::posix_time::hours(message.getOffset());
+ if (time && time < messageTime) {
+ break;
+ }
+ if (time && time != messageTime) {
+ continue;
+ }
+ if (message.getFromJID() != jid) {
+ continue;
+ }
+ if (message.getMessage() != body) {
+ continue;
+ }
- // Mark the message as unreadable
- newMessage->setBody("");
- }
+ // Mark the message as unreadable
+ newMessage->setBody("");
+ }
}
void MUCController::setNick(const std::string& nick) {
- nick_ = nick;
- highlighter_->setNick(nick_);
+ nick_ = nick;
+ highlighter_->setNick(nick_);
}
Form::ref MUCController::buildImpromptuRoomConfiguration(Form::ref roomConfigurationForm) {
- Form::ref result = boost::make_shared<Form>(Form::SubmitType);
- std::string impromptuConfigs[] = { "muc#roomconfig_enablelogging", "muc#roomconfig_persistentroom", "muc#roomconfig_publicroom", "muc#roomconfig_whois"};
- std::set<std::string> impromptuConfigsMissing(impromptuConfigs, impromptuConfigs + 4);
- foreach (boost::shared_ptr<FormField> field, roomConfigurationForm->getFields()) {
- boost::shared_ptr<FormField> resultField;
- if (field->getName() == "muc#roomconfig_enablelogging") {
- resultField = boost::make_shared<FormField>(FormField::BooleanType, "0");
- }
- if (field->getName() == "muc#roomconfig_persistentroom") {
- resultField = boost::make_shared<FormField>(FormField::BooleanType, "0");
- }
- if (field->getName() == "muc#roomconfig_publicroom") {
- resultField = boost::make_shared<FormField>(FormField::BooleanType, "0");
- }
- if (field->getName() == "muc#roomconfig_whois") {
- resultField = boost::make_shared<FormField>(FormField::ListSingleType, "anyone");
- }
-
- if (field->getName() == "FORM_TYPE") {
- resultField = boost::make_shared<FormField>(FormField::HiddenType, "http://jabber.org/protocol/muc#roomconfig");
- }
-
- if (resultField) {
- impromptuConfigsMissing.erase(field->getName());
- resultField->setName(field->getName());
- result->addField(resultField);
- }
- }
-
- foreach (const std::string& config, impromptuConfigsMissing) {
- if (config == "muc#roomconfig_publicroom") {
- chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "This server doesn't support hiding your chat from other users.")), ChatWindow::DefaultDirection);
- } else if (config == "muc#roomconfig_whois") {
- chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "This server doesn't support sharing people's real identity in this chat.")), ChatWindow::DefaultDirection);
- }
- }
-
- return result;
+ Form::ref result = std::make_shared<Form>(Form::SubmitType);
+ std::string impromptuConfigs[] = { "muc#roomconfig_enablelogging", "muc#roomconfig_persistentroom", "muc#roomconfig_publicroom", "muc#roomconfig_whois"};
+ std::set<std::string> impromptuConfigsMissing(impromptuConfigs, impromptuConfigs + 4);
+ for (const auto& field : roomConfigurationForm->getFields()) {
+ std::shared_ptr<FormField> resultField;
+ if (field->getName() == "muc#roomconfig_enablelogging") {
+ resultField = std::make_shared<FormField>(FormField::BooleanType, "0");
+ }
+ if (field->getName() == "muc#roomconfig_persistentroom") {
+ resultField = std::make_shared<FormField>(FormField::BooleanType, "0");
+ }
+ if (field->getName() == "muc#roomconfig_publicroom") {
+ resultField = std::make_shared<FormField>(FormField::BooleanType, "0");
+ }
+ if (field->getName() == "muc#roomconfig_whois") {
+ resultField = std::make_shared<FormField>(FormField::ListSingleType, "anyone");
+ }
+
+ if (field->getName() == "FORM_TYPE") {
+ resultField = std::make_shared<FormField>(FormField::HiddenType, "http://jabber.org/protocol/muc#roomconfig");
+ }
+
+ if (resultField) {
+ impromptuConfigsMissing.erase(field->getName());
+ resultField->setName(field->getName());
+ result->addField(resultField);
+ }
+ }
+
+ for (const auto& config : impromptuConfigsMissing) {
+ if (config == "muc#roomconfig_publicroom") {
+ chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "This server doesn't support hiding your chat from other users.")), ChatWindow::DefaultDirection);
+ } else if (config == "muc#roomconfig_whois") {
+ chatWindow_->addSystemMessage(chatMessageParser_->parseMessageBody(QT_TRANSLATE_NOOP("", "This server doesn't support sharing people's real identity in this chat.")), ChatWindow::DefaultDirection);
+ }
+ }
+
+ return result;
}
void MUCController::setImpromptuWindowTitle() {
- std::string title;
- typedef std::pair<std::string, MUCOccupant> StringMUCOccupantPair;
- std::map<std::string, MUCOccupant> occupants = muc_->getOccupants();
- if (occupants.size() <= 1) {
- title = QT_TRANSLATE_NOOP("", "Empty Chat");
- } else {
- foreach (StringMUCOccupantPair pair, occupants) {
- if (pair.first != nick_) {
- title += (title.empty() ? "" : ", ") + pair.first;
- }
- }
- }
- chatWindow_->setName(title);
+ std::string title;
+ std::map<std::string, MUCOccupant> occupants = muc_->getOccupants();
+ if (occupants.size() <= 1) {
+ title = QT_TRANSLATE_NOOP("", "Empty Chat");
+ } else {
+ for (const auto& pair : occupants) {
+ if (pair.first != nick_) {
+ title += (title.empty() ? "" : ", ") + pair.first;
+ }
+ }
+ }
+ chatWindow_->setName(title);
}
void MUCController::handleRoomUnlocked() {
- // Handle buggy MUC implementations where the joined room already exists and is unlocked.
- // Configure the room again in this case.
- if (!isImpromptuAlreadyConfigured_) {
- if (isImpromptu_ && (muc_->getOccupant(nick_).getAffiliation() == MUCOccupant::Owner)) {
- muc_->requestConfigurationForm();
- } else if (isImpromptu_) {
- onImpromptuConfigCompleted();
- }
- }
+ // Handle buggy MUC implementations where the joined room already exists and is unlocked.
+ // Configure the room again in this case.
+ if (!isImpromptuAlreadyConfigured_) {
+ if (isImpromptu_ && (muc_->getOccupant(nick_).getAffiliation() == MUCOccupant::Owner)) {
+ muc_->requestConfigurationForm();
+ } else if (isImpromptu_) {
+ onImpromptuConfigCompleted();
+ }
+ }
}
-void MUCController::setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) {
- ChatControllerBase::setAvailableServerFeatures(info);
- if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::BlockingCommandFeature)) {
- boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList();
+void MUCController::setAvailableServerFeatures(std::shared_ptr<DiscoInfo> info) {
+ ChatControllerBase::setAvailableServerFeatures(info);
+ if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::BlockingCommandFeature)) {
+ std::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList();
- blockingOnStateChangedConnection_ = blockList->onStateChanged.connect(boost::bind(&MUCController::handleBlockingStateChanged, this));
- blockingOnItemAddedConnection_ = blockList->onItemAdded.connect(boost::bind(&MUCController::handleBlockingStateChanged, this));
- blockingOnItemRemovedConnection_ = blockList->onItemRemoved.connect(boost::bind(&MUCController::handleBlockingStateChanged, this));
+ blockingOnStateChangedConnection_ = blockList->onStateChanged.connect(boost::bind(&MUCController::handleBlockingStateChanged, this));
+ blockingOnItemAddedConnection_ = blockList->onItemAdded.connect(boost::bind(&MUCController::handleBlockingStateChanged, this));
+ blockingOnItemRemovedConnection_ = blockList->onItemRemoved.connect(boost::bind(&MUCController::handleBlockingStateChanged, this));
- handleBlockingStateChanged();
- }
+ handleBlockingStateChanged();
+ }
}
void MUCController::handleMUCBookmarkAdded(const MUCBookmark& bookmark) {
- if (bookmark.getRoom() == muc_->getJID()) {
- updateChatWindowBookmarkStatus(bookmark);
- }
+ if (bookmark.getRoom() == muc_->getJID()) {
+ updateChatWindowBookmarkStatus(bookmark);
+ }
}
void MUCController::handleMUCBookmarkRemoved(const MUCBookmark& bookmark) {
- if (bookmark.getRoom() == muc_->getJID()) {
- updateChatWindowBookmarkStatus(boost::optional<MUCBookmark>());
- }
+ if (bookmark.getRoom() == muc_->getJID()) {
+ updateChatWindowBookmarkStatus(boost::optional<MUCBookmark>());
+ }
}
void MUCController::updateChatWindowBookmarkStatus(const boost::optional<MUCBookmark>& bookmark) {
- assert(chatWindow_);
- if (bookmark) {
- if (bookmark->getAutojoin()) {
- chatWindow_->setBookmarkState(ChatWindow::RoomAutoJoined);
- }
- else {
- chatWindow_->setBookmarkState(ChatWindow::RoomBookmarked);
- }
- }
- else {
- chatWindow_->setBookmarkState(ChatWindow::RoomNotBookmarked);
- }
+ assert(chatWindow_);
+ if (bookmark) {
+ if (bookmark->getAutojoin()) {
+ chatWindow_->setBookmarkState(ChatWindow::RoomAutoJoined);
+ }
+ else {
+ chatWindow_->setBookmarkState(ChatWindow::RoomBookmarked);
+ }
+ }
+ else {
+ chatWindow_->setBookmarkState(ChatWindow::RoomNotBookmarked);
+ }
}
}
diff --git a/Swift/Controllers/Chat/MUCController.h b/Swift/Controllers/Chat/MUCController.h
index a08d541..e0ffd7e 100644
--- a/Swift/Controllers/Chat/MUCController.h
+++ b/Swift/Controllers/Chat/MUCController.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,14 +7,14 @@
#pragma once
#include <map>
+#include <memory>
#include <set>
#include <string>
-#include <boost/shared_ptr.hpp>
-#include <boost/signals/connection.hpp>
+#include <boost/signals2.hpp>
+#include <boost/signals2/connection.hpp>
#include <Swiften/Base/Override.h>
-#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Elements/DiscoInfo.h>
#include <Swiften/Elements/MUCOccupant.h>
#include <Swiften/Elements/Message.h>
@@ -27,159 +27,158 @@
#include <Swift/Controllers/UIInterfaces/ChatWindow.h>
namespace Swift {
- class StanzaChannel;
- class IQRouter;
- class ChatWindowFactory;
- class Roster;
- class AvatarManager;
- class UIEventStream;
- class TimerFactory;
- class TabComplete;
- class XMPPRoster;
- class HighlightManager;
- class UIEvent;
- class VCardManager;
- class RosterVCardProvider;
- class ClientBlockListManager;
- class MUCBookmarkManager;
- class MUCBookmark;
-
- enum JoinPart {Join, Part, JoinThenPart, PartThenJoin};
-
- struct NickJoinPart {
- NickJoinPart(const std::string& nick, JoinPart type) : nick(nick), type(type) {}
- std::string nick;
- JoinPart type;
- };
-
- class MUCController : public ChatControllerBase {
- public:
- MUCController(const JID& self, MUC::ref muc, const boost::optional<std::string>& password, const std::string &nick, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* events, bool useDelayForLatency, TimerFactory* timerFactory, EventController* eventController, EntityCapsProvider* entityCapsProvider, XMPPRoster* roster, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, boost::shared_ptr<ChatMessageParser> chatMessageParser, bool isImpromptu, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider, VCardManager* vcardManager, MUCBookmarkManager* mucBookmarkManager);
- virtual ~MUCController();
- boost::signal<void ()> onUserLeft;
- boost::signal<void ()> onUserJoined;
- boost::signal<void ()> onImpromptuConfigCompleted;
- boost::signal<void (const std::string&, const std::string& )> onUserNicknameChanged;
- virtual void setOnline(bool online) SWIFTEN_OVERRIDE;
- virtual void setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) SWIFTEN_OVERRIDE;
- void rejoin();
- static void appendToJoinParts(std::vector<NickJoinPart>& joinParts, const NickJoinPart& newEvent);
- static std::string generateJoinPartString(const std::vector<NickJoinPart>& joinParts, bool isImpromptu);
- static std::string concatenateListOfNames(const std::vector<NickJoinPart>& joinParts);
- static std::string generateNicknameChangeString(const std::string& oldNickname, const std::string& newNickname);
- bool isJoined();
- const std::string& getNick();
- const boost::optional<std::string> getPassword() const;
- bool isImpromptu() const;
- std::map<std::string, JID> getParticipantJIDs() const;
- void sendInvites(const std::vector<JID>& jids, const std::string& reason) const;
-
- protected:
- virtual void preSendMessageRequest(boost::shared_ptr<Message> message) SWIFTEN_OVERRIDE;
- virtual bool isIncomingMessageFromMe(boost::shared_ptr<Message> message) SWIFTEN_OVERRIDE;
- virtual std::string senderHighlightNameFromMessage(const JID& from) SWIFTEN_OVERRIDE;
- virtual std::string senderDisplayNameFromMessage(const JID& from) SWIFTEN_OVERRIDE;
- virtual boost::optional<boost::posix_time::ptime> getMessageTimestamp(boost::shared_ptr<Message> message) const SWIFTEN_OVERRIDE;
- virtual void preHandleIncomingMessage(boost::shared_ptr<MessageEvent>) SWIFTEN_OVERRIDE;
- virtual void addMessageHandleIncomingMessage(const JID& from, const std::string& message, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& time, const HighlightAction& highlight) SWIFTEN_OVERRIDE;
- virtual void postHandleIncomingMessage(boost::shared_ptr<MessageEvent>, const HighlightAction&) SWIFTEN_OVERRIDE;
- virtual void cancelReplaces() SWIFTEN_OVERRIDE;
- virtual void logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming) SWIFTEN_OVERRIDE;
-
- private:
- void setAvailableRoomActions(const MUCOccupant::Affiliation& affiliation, const MUCOccupant::Role& role);
- void clearPresenceQueue();
- void addPresenceMessage(const std::string& message);
- void handleWindowOccupantSelectionChanged(ContactRosterItem* item);
- void handleActionRequestedOnOccupant(ChatWindow::OccupantAction, ContactRosterItem* item);
- void handleWindowClosed();
- void handleAvatarChanged(const JID& jid);
- void handleOccupantJoined(const MUCOccupant& occupant);
- void handleOccupantNicknameChanged(const std::string& oldNickname, const std::string& newNickname);
- void handleOccupantLeft(const MUCOccupant& occupant, MUC::LeavingType type, const std::string& reason);
- void handleOccupantPresenceChange(boost::shared_ptr<Presence> presence);
- void handleOccupantRoleChanged(const std::string& nick, const MUCOccupant& occupant,const MUCOccupant::Role& oldRole);
- void handleOccupantAffiliationChanged(const std::string& nick, const MUCOccupant::Affiliation& affiliation,const MUCOccupant::Affiliation& oldAffiliation);
- void handleJoinComplete(const std::string& nick);
- void handleJoinFailed(boost::shared_ptr<ErrorPayload> error);
- void handleJoinTimeoutTick();
- void handleChangeSubjectRequest(const std::string&);
- void handleBookmarkRequest();
- std::string roleToGroupName(MUCOccupant::Role role);
- std::string roleToSortName(MUCOccupant::Role role);
- JID nickToJID(const std::string& nick);
- std::string roleToFriendlyName(MUCOccupant::Role role);
- void receivedActivity();
- bool messageTargetsMe(boost::shared_ptr<Message> message);
- void updateJoinParts();
- bool shouldUpdateJoinParts();
- virtual void dayTicked() SWIFTEN_OVERRIDE { clearPresenceQueue(); }
- void processUserPart();
- virtual void handleBareJIDCapsChanged(const JID& jid) SWIFTEN_OVERRIDE;
- void handleConfigureRequest(Form::ref);
- void handleConfigurationFailed(ErrorPayload::ref);
- void handleConfigurationFormReceived(Form::ref);
- void handleDestroyRoomRequest();
- void handleInvitePersonToThisMUCRequest(const std::vector<JID>& jidsToInvite);
- void handleConfigurationCancelled();
- void handleOccupantRoleChangeFailed(ErrorPayload::ref, const JID&, MUCOccupant::Role);
- void handleGetAffiliationsRequest();
- void handleAffiliationListReceived(MUCOccupant::Affiliation affiliation, const std::vector<JID>& jids);
- void handleChangeAffiliationsRequest(const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& changes);
- void handleInviteToMUCWindowDismissed();
- void handleInviteToMUCWindowCompleted();
- void handleUIEvent(boost::shared_ptr<UIEvent> event);
- void addRecentLogs();
- void checkDuplicates(boost::shared_ptr<Message> newMessage);
- void setNick(const std::string& nick);
- void setImpromptuWindowTitle();
- void handleRoomUnlocked();
- void configureAsImpromptuRoom(Form::ref form);
- Form::ref buildImpromptuRoomConfiguration(Form::ref roomConfigurationForm);
-
- void handleUnblockUserRequest();
- void handleBlockingStateChanged();
-
- void handleMUCBookmarkAdded(const MUCBookmark& bookmark);
- void handleMUCBookmarkRemoved(const MUCBookmark& bookmark);
- void updateChatWindowBookmarkStatus(const boost::optional<MUCBookmark>& bookmark);
-
- private:
- MUC::ref muc_;
- UIEventStream* events_;
- std::string nick_;
- std::string desiredNick_;
- Roster* roster_;
- TabComplete* completer_;
- bool parting_;
- bool joined_;
- bool lastWasPresence_;
- bool shouldJoinOnReconnect_;
- bool doneGettingHistory_;
- boost::bsignals::scoped_connection avatarChangedConnection_;
- boost::shared_ptr<Timer> loginCheckTimer_;
- std::set<std::string> currentOccupants_;
- std::vector<NickJoinPart> joinParts_;
- boost::posix_time::ptime lastActivity_;
- boost::optional<std::string> password_;
- XMPPRoster* xmppRoster_;
- std::vector<HistoryMessage> joinContext_;
- size_t renameCounter_;
- bool isImpromptu_;
- bool isImpromptuAlreadyConfigured_;
- RosterVCardProvider* rosterVCardProvider_;
- std::string lastJoinMessageUID_;
-
- ClientBlockListManager* clientBlockListManager_;
- boost::bsignals::scoped_connection blockingOnStateChangedConnection_;
- boost::bsignals::scoped_connection blockingOnItemAddedConnection_;
- boost::bsignals::scoped_connection blockingOnItemRemovedConnection_;
-
- boost::optional<ChatWindow::AlertID> blockedContactAlert_;
-
- MUCBookmarkManager* mucBookmarkManager_;
- boost::bsignals::scoped_connection mucBookmarkManagerBookmarkAddedConnection_;
- boost::bsignals::scoped_connection mucBookmarkManagerBookmarkRemovedConnection_;
- };
+ class StanzaChannel;
+ class IQRouter;
+ class ChatWindowFactory;
+ class Roster;
+ class AvatarManager;
+ class UIEventStream;
+ class TimerFactory;
+ class TabComplete;
+ class XMPPRoster;
+ class HighlightManager;
+ class UIEvent;
+ class VCardManager;
+ class RosterVCardProvider;
+ class ClientBlockListManager;
+ class MUCBookmarkManager;
+ class MUCBookmark;
+
+ enum JoinPart {Join, Part, JoinThenPart, PartThenJoin};
+
+ struct NickJoinPart {
+ NickJoinPart(const std::string& nick, JoinPart type) : nick(nick), type(type) {}
+ std::string nick;
+ JoinPart type;
+ };
+
+ class MUCController : public ChatControllerBase {
+ public:
+ MUCController(const JID& self, MUC::ref muc, const boost::optional<std::string>& password, const std::string &nick, StanzaChannel* stanzaChannel, IQRouter* iqRouter, ChatWindowFactory* chatWindowFactory, PresenceOracle* presenceOracle, AvatarManager* avatarManager, UIEventStream* events, bool useDelayForLatency, TimerFactory* timerFactory, EventController* eventController, EntityCapsProvider* entityCapsProvider, XMPPRoster* roster, HistoryController* historyController, MUCRegistry* mucRegistry, HighlightManager* highlightManager, ClientBlockListManager* clientBlockListManager, std::shared_ptr<ChatMessageParser> chatMessageParser, bool isImpromptu, AutoAcceptMUCInviteDecider* autoAcceptMUCInviteDecider, VCardManager* vcardManager, MUCBookmarkManager* mucBookmarkManager);
+ virtual ~MUCController();
+ boost::signals2::signal<void ()> onUserLeft;
+ boost::signals2::signal<void ()> onUserJoined;
+ boost::signals2::signal<void ()> onImpromptuConfigCompleted;
+ boost::signals2::signal<void (const std::string&, const std::string& )> onUserNicknameChanged;
+ virtual void setOnline(bool online) SWIFTEN_OVERRIDE;
+ virtual void setAvailableServerFeatures(std::shared_ptr<DiscoInfo> info) SWIFTEN_OVERRIDE;
+ void rejoin();
+ static void appendToJoinParts(std::vector<NickJoinPart>& joinParts, const NickJoinPart& newEvent);
+ static std::string generateJoinPartString(const std::vector<NickJoinPart>& joinParts, bool isImpromptu);
+ static std::string concatenateListOfNames(const std::vector<NickJoinPart>& joinParts);
+ static std::string generateNicknameChangeString(const std::string& oldNickname, const std::string& newNickname);
+ bool isJoined();
+ const std::string& getNick();
+ const boost::optional<std::string> getPassword() const;
+ bool isImpromptu() const;
+ std::map<std::string, JID> getParticipantJIDs() const;
+ void sendInvites(const std::vector<JID>& jids, const std::string& reason) const;
+
+ protected:
+ virtual void preSendMessageRequest(std::shared_ptr<Message> message) SWIFTEN_OVERRIDE;
+ virtual bool isIncomingMessageFromMe(std::shared_ptr<Message> message) SWIFTEN_OVERRIDE;
+ virtual std::string senderHighlightNameFromMessage(const JID& from) SWIFTEN_OVERRIDE;
+ virtual std::string senderDisplayNameFromMessage(const JID& from) SWIFTEN_OVERRIDE;
+ virtual boost::optional<boost::posix_time::ptime> getMessageTimestamp(std::shared_ptr<Message> message) const SWIFTEN_OVERRIDE;
+ virtual void preHandleIncomingMessage(std::shared_ptr<MessageEvent>) SWIFTEN_OVERRIDE;
+ virtual void addMessageHandleIncomingMessage(const JID& from, const ChatWindow::ChatMessage& message, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const boost::posix_time::ptime& time) SWIFTEN_OVERRIDE;
+ virtual void postHandleIncomingMessage(std::shared_ptr<MessageEvent>, const ChatWindow::ChatMessage& chatMessage) SWIFTEN_OVERRIDE;
+ virtual void cancelReplaces() SWIFTEN_OVERRIDE;
+ virtual void logMessage(const std::string& message, const JID& fromJID, const JID& toJID, const boost::posix_time::ptime& timeStamp, bool isIncoming) SWIFTEN_OVERRIDE;
+
+ private:
+ void setAvailableRoomActions(const MUCOccupant::Affiliation& affiliation, const MUCOccupant::Role& role);
+ void clearPresenceQueue();
+ void addPresenceMessage(const std::string& message);
+ void handleWindowOccupantSelectionChanged(ContactRosterItem* item);
+ void handleActionRequestedOnOccupant(ChatWindow::OccupantAction, ContactRosterItem* item);
+ void handleWindowClosed();
+ void handleAvatarChanged(const JID& jid);
+ void handleOccupantJoined(const MUCOccupant& occupant);
+ void handleOccupantNicknameChanged(const std::string& oldNickname, const std::string& newNickname);
+ void handleOccupantLeft(const MUCOccupant& occupant, MUC::LeavingType type, const std::string& reason);
+ void handleOccupantPresenceChange(std::shared_ptr<Presence> presence);
+ void handleOccupantRoleChanged(const std::string& nick, const MUCOccupant& occupant,const MUCOccupant::Role& oldRole);
+ void handleOccupantAffiliationChanged(const std::string& nick, const MUCOccupant::Affiliation& affiliation,const MUCOccupant::Affiliation& oldAffiliation);
+ void handleJoinComplete(const std::string& nick);
+ void handleJoinFailed(std::shared_ptr<ErrorPayload> error);
+ void handleJoinTimeoutTick();
+ void handleChangeSubjectRequest(const std::string&);
+ void handleBookmarkRequest();
+ std::string roleToGroupName(MUCOccupant::Role role);
+ std::string roleToSortName(MUCOccupant::Role role);
+ JID nickToJID(const std::string& nick);
+ std::string roleToFriendlyName(MUCOccupant::Role role);
+ void receivedActivity();
+ bool messageTargetsMe(std::shared_ptr<Message> message);
+ void updateJoinParts();
+ bool shouldUpdateJoinParts();
+ virtual void dayTicked() SWIFTEN_OVERRIDE { clearPresenceQueue(); }
+ void processUserPart();
+ virtual void handleBareJIDCapsChanged(const JID& jid) SWIFTEN_OVERRIDE;
+ void handleConfigureRequest(Form::ref);
+ void handleConfigurationFailed(ErrorPayload::ref);
+ void handleConfigurationFormReceived(Form::ref);
+ void handleDestroyRoomRequest();
+ void handleInvitePersonToThisMUCRequest(const std::vector<JID>& jidsToInvite);
+ void handleConfigurationCancelled();
+ void handleOccupantRoleChangeFailed(ErrorPayload::ref, const JID&, MUCOccupant::Role);
+ void handleGetAffiliationsRequest();
+ void handleAffiliationListReceived(MUCOccupant::Affiliation affiliation, const std::vector<JID>& jids);
+ void handleChangeAffiliationsRequest(const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& changes);
+ void handleInviteToMUCWindowDismissed();
+ void handleInviteToMUCWindowCompleted();
+ void handleUIEvent(std::shared_ptr<UIEvent> event);
+ void addRecentLogs();
+ void checkDuplicates(std::shared_ptr<Message> newMessage);
+ void setNick(const std::string& nick);
+ void setImpromptuWindowTitle();
+ void handleRoomUnlocked();
+ void configureAsImpromptuRoom(Form::ref form);
+ Form::ref buildImpromptuRoomConfiguration(Form::ref roomConfigurationForm);
+
+ void handleUnblockUserRequest();
+ void handleBlockingStateChanged();
+
+ void handleMUCBookmarkAdded(const MUCBookmark& bookmark);
+ void handleMUCBookmarkRemoved(const MUCBookmark& bookmark);
+ void updateChatWindowBookmarkStatus(const boost::optional<MUCBookmark>& bookmark);
+
+ private:
+ MUC::ref muc_;
+ UIEventStream* events_;
+ std::string nick_;
+ std::string desiredNick_;
+ Roster* roster_;
+ TabComplete* completer_;
+ bool parting_;
+ bool joined_;
+ bool shouldJoinOnReconnect_;
+ bool doneGettingHistory_;
+ boost::signals2::scoped_connection avatarChangedConnection_;
+ std::shared_ptr<Timer> loginCheckTimer_;
+ std::set<std::string> currentOccupants_;
+ std::vector<NickJoinPart> joinParts_;
+ boost::posix_time::ptime lastActivity_;
+ boost::optional<std::string> password_;
+ XMPPRoster* xmppRoster_;
+ std::vector<HistoryMessage> joinContext_;
+ size_t renameCounter_;
+ bool isImpromptu_;
+ bool isImpromptuAlreadyConfigured_;
+ RosterVCardProvider* rosterVCardProvider_;
+ std::string lastJoinMessageUID_;
+
+ ClientBlockListManager* clientBlockListManager_;
+ boost::signals2::scoped_connection blockingOnStateChangedConnection_;
+ boost::signals2::scoped_connection blockingOnItemAddedConnection_;
+ boost::signals2::scoped_connection blockingOnItemRemovedConnection_;
+
+ boost::optional<ChatWindow::AlertID> blockedContactAlert_;
+
+ MUCBookmarkManager* mucBookmarkManager_;
+ boost::signals2::scoped_connection mucBookmarkManagerBookmarkAddedConnection_;
+ boost::signals2::scoped_connection mucBookmarkManagerBookmarkRemovedConnection_;
+ };
}
diff --git a/Swift/Controllers/Chat/MUCSearchController.cpp b/Swift/Controllers/Chat/MUCSearchController.cpp
index d40f427..5db917a 100644
--- a/Swift/Controllers/Chat/MUCSearchController.cpp
+++ b/Swift/Controllers/Chat/MUCSearchController.cpp
@@ -1,183 +1,183 @@
/*
- * Copyright (c) 2010-2011 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/Controllers/Chat/MUCSearchController.h"
+#include <Swift/Controllers/Chat/MUCSearchController.h>
#include <iostream>
+#include <memory>
#include <boost/bind.hpp>
-#include <boost/shared_ptr.hpp>
-#include <Swiften/Base/foreach.h>
-#include <Swiften/Disco/GetDiscoItemsRequest.h>
#include <Swiften/Base/Log.h>
#include <Swiften/Base/String.h>
+#include <Swiften/Client/NickResolver.h>
+#include <Swiften/Disco/DiscoServiceWalker.h>
+#include <Swiften/Disco/GetDiscoItemsRequest.h>
+
#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h>
-#include <Swiften/Disco/DiscoServiceWalker.h>
-#include <Swiften/Client/NickResolver.h>
namespace Swift {
static const std::string SEARCHED_SERVICES = "searchedServices";
-MUCSearchController::MUCSearchController(const JID& jid, MUCSearchWindowFactory* factory, IQRouter* iqRouter, ProfileSettingsProvider* settings) : jid_(jid), factory_(factory), iqRouter_(iqRouter), settings_(settings), window_(NULL), walker_(NULL) {
- itemsInProgress_ = 0;
- loadSavedServices();
+MUCSearchController::MUCSearchController(const JID& jid, MUCSearchWindowFactory* factory, IQRouter* iqRouter, ProfileSettingsProvider* settings) : jid_(jid), factory_(factory), iqRouter_(iqRouter), settings_(settings), window_(nullptr), walker_(nullptr) {
+ itemsInProgress_ = 0;
+ loadSavedServices();
}
MUCSearchController::~MUCSearchController() {
- delete walker_;
- delete window_;
+ delete walker_;
+ delete window_;
}
void MUCSearchController::openSearchWindow() {
- if (!window_) {
- window_ = factory_->createMUCSearchWindow();
- window_->onSearchService.connect(boost::bind(&MUCSearchController::handleSearchService, this, _1));
- window_->onFinished.connect(boost::bind(&MUCSearchController::handleMUCSearchFinished, this, _1));
- window_->addSavedServices(savedServices_);
- }
- handleSearchService(JID(jid_.getDomain()));
- window_->show();
+ if (!window_) {
+ window_ = factory_->createMUCSearchWindow();
+ window_->onSearchService.connect(boost::bind(&MUCSearchController::handleSearchService, this, _1));
+ window_->onFinished.connect(boost::bind(&MUCSearchController::handleMUCSearchFinished, this, _1));
+ window_->addSavedServices(savedServices_);
+ }
+ handleSearchService(JID(jid_.getDomain()));
+ window_->show();
}
void MUCSearchController::loadSavedServices() {
- savedServices_.clear();
- foreach (std::string stringItem, String::split(settings_->getStringSetting(SEARCHED_SERVICES), '\n')) {
- savedServices_.push_back(JID(stringItem));
- }
+ savedServices_.clear();
+ for (auto&& stringItem : String::split(settings_->getStringSetting(SEARCHED_SERVICES), '\n')) {
+ savedServices_.push_back(JID(stringItem));
+ }
}
void MUCSearchController::addToSavedServices(const JID& jid) {
- savedServices_.erase(std::remove(savedServices_.begin(), savedServices_.end(), jid), savedServices_.end());
- savedServices_.push_front(jid);
-
- std::string collapsed;
- int i = 0;
- foreach (JID jidItem, savedServices_) {
- if (i >= 15) {
- break;
- }
- if (!collapsed.empty()) {
- collapsed += "\n";
- }
- collapsed += jidItem.toString();
- ++i;
- }
- settings_->storeString(SEARCHED_SERVICES, collapsed);
- window_->addSavedServices(savedServices_);
+ savedServices_.erase(std::remove(savedServices_.begin(), savedServices_.end(), jid), savedServices_.end());
+ savedServices_.push_front(jid);
+
+ std::string collapsed;
+ int i = 0;
+ for (auto&& jidItem : savedServices_) {
+ if (i >= 15) {
+ break;
+ }
+ if (!collapsed.empty()) {
+ collapsed += "\n";
+ }
+ collapsed += jidItem.toString();
+ ++i;
+ }
+ settings_->storeString(SEARCHED_SERVICES, collapsed);
+ window_->addSavedServices(savedServices_);
}
void MUCSearchController::handleSearchService(const JID& jid) {
- if (!jid.isValid()) {
- //Set Window to say error this isn't valid
- return;
- }
- addToSavedServices(jid);
-
- services_.clear();
- serviceDetails_.clear();
-
- window_->setSearchInProgress(true);
- refreshView();
-
- if (walker_) {
- walker_->endWalk();
- walker_->onServiceFound.disconnect(boost::bind(&MUCSearchController::handleDiscoServiceFound, this, _1, _2));
- walker_->onWalkComplete.disconnect(boost::bind(&MUCSearchController::handleDiscoWalkFinished, this));
- delete walker_;
- }
-
- SWIFT_LOG(debug) << "Starting walking MUC services" << std::endl;
- itemsInProgress_ = 0;
- walker_ = new DiscoServiceWalker(jid, iqRouter_);
- walker_->onServiceFound.connect(boost::bind(&MUCSearchController::handleDiscoServiceFound, this, _1, _2));
- walker_->onWalkComplete.connect(boost::bind(&MUCSearchController::handleDiscoWalkFinished, this));
- walker_->beginWalk();
+ if (!jid.isValid()) {
+ //Set Window to say error this isn't valid
+ return;
+ }
+ addToSavedServices(jid);
+
+ services_.clear();
+ serviceDetails_.clear();
+
+ window_->setSearchInProgress(true);
+ refreshView();
+
+ if (walker_) {
+ walker_->endWalk();
+ walker_->onServiceFound.disconnect(boost::bind(&MUCSearchController::handleDiscoServiceFound, this, _1, _2));
+ walker_->onWalkComplete.disconnect(boost::bind(&MUCSearchController::handleDiscoWalkFinished, this));
+ delete walker_;
+ }
+
+ SWIFT_LOG(debug) << "Starting walking MUC services" << std::endl;
+ itemsInProgress_ = 0;
+ walker_ = new DiscoServiceWalker(jid, iqRouter_);
+ walker_->onServiceFound.connect(boost::bind(&MUCSearchController::handleDiscoServiceFound, this, _1, _2));
+ walker_->onWalkComplete.connect(boost::bind(&MUCSearchController::handleDiscoWalkFinished, this));
+ walker_->beginWalk();
}
-void MUCSearchController::handleDiscoServiceFound(const JID& jid, boost::shared_ptr<DiscoInfo> info) {
- bool isMUC = false;
- std::string name;
- foreach (DiscoInfo::Identity identity, info->getIdentities()) {
- if ((identity.getCategory() == "directory"
- && identity.getType() == "chatroom")
- || (identity.getCategory() == "conference"
- && identity.getType() == "text")) {
- isMUC = true;
- name = identity.getName();
- }
- }
- if (isMUC) {
- SWIFT_LOG(debug) << "MUC Service found: " << jid << std::endl;
- services_.erase(std::remove(services_.begin(), services_.end(), jid), services_.end());
- services_.push_back(jid);
- serviceDetails_[jid].setName(name);
- serviceDetails_[jid].setJID(jid);
- serviceDetails_[jid].setComplete(false);
- itemsInProgress_++;
- SWIFT_LOG(debug) << "Requesting items of " << jid << " (" << itemsInProgress_ << " item requests in progress)" << std::endl;
- GetDiscoItemsRequest::ref discoItemsRequest = GetDiscoItemsRequest::create(jid, iqRouter_);
- discoItemsRequest->onResponse.connect(boost::bind(&MUCSearchController::handleRoomsItemsResponse, this, _1, _2, jid));
- discoItemsRequest->send();
- }
- else {
- removeService(jid);
- }
- refreshView();
+void MUCSearchController::handleDiscoServiceFound(const JID& jid, std::shared_ptr<DiscoInfo> info) {
+ bool isMUC = false;
+ std::string name;
+ for (auto&& identity : info->getIdentities()) {
+ if ((identity.getCategory() == "directory"
+ && identity.getType() == "chatroom")
+ || (identity.getCategory() == "conference"
+ && identity.getType() == "text")) {
+ isMUC = true;
+ name = identity.getName();
+ }
+ }
+ if (isMUC) {
+ SWIFT_LOG(debug) << "MUC Service found: " << jid << std::endl;
+ services_.erase(std::remove(services_.begin(), services_.end(), jid), services_.end());
+ services_.push_back(jid);
+ serviceDetails_[jid].setName(name);
+ serviceDetails_[jid].setJID(jid);
+ serviceDetails_[jid].setComplete(false);
+ itemsInProgress_++;
+ SWIFT_LOG(debug) << "Requesting items of " << jid << " (" << itemsInProgress_ << " item requests in progress)" << std::endl;
+ GetDiscoItemsRequest::ref discoItemsRequest = GetDiscoItemsRequest::create(jid, iqRouter_);
+ discoItemsRequest->onResponse.connect(boost::bind(&MUCSearchController::handleRoomsItemsResponse, this, _1, _2, jid));
+ discoItemsRequest->send();
+ }
+ else {
+ removeService(jid);
+ }
+ refreshView();
}
void MUCSearchController::handleDiscoWalkFinished() {
- SWIFT_LOG(debug) << "MUC Walk finished" << std::endl;
- updateInProgressness();
+ SWIFT_LOG(debug) << "MUC Walk finished" << std::endl;
+ updateInProgressness();
}
void MUCSearchController::removeService(const JID& jid) {
- serviceDetails_.erase(jid);
- services_.erase(std::remove(services_.begin(), services_.end(), jid), services_.end());
- refreshView();
+ serviceDetails_.erase(jid);
+ services_.erase(std::remove(services_.begin(), services_.end(), jid), services_.end());
+ refreshView();
}
-void MUCSearchController::handleRoomsItemsResponse(boost::shared_ptr<DiscoItems> items, ErrorPayload::ref error, const JID& jid) {
- itemsInProgress_--;
- SWIFT_LOG(debug) << "Items received for " << jid << " (" << itemsInProgress_ << " item requests in progress)" << std::endl;
- updateInProgressness();
- if (error) {
- handleDiscoError(jid, error);
- return;
- }
- serviceDetails_[jid].clearRooms();
- foreach (DiscoItems::Item item, items->getItems()) {
- serviceDetails_[jid].addRoom(MUCService::MUCRoom(item.getJID().getNode(), item.getName(), -1));
- }
- serviceDetails_[jid].setComplete(true);
- refreshView();
+void MUCSearchController::handleRoomsItemsResponse(std::shared_ptr<DiscoItems> items, ErrorPayload::ref error, const JID& jid) {
+ itemsInProgress_--;
+ SWIFT_LOG(debug) << "Items received for " << jid << " (" << itemsInProgress_ << " item requests in progress)" << std::endl;
+ updateInProgressness();
+ if (error) {
+ handleDiscoError(jid, error);
+ return;
+ }
+ serviceDetails_[jid].clearRooms();
+ for (auto&& item : items->getItems()) {
+ serviceDetails_[jid].addRoom(MUCService::MUCRoom(item.getJID().getNode(), item.getName(), -1));
+ }
+ serviceDetails_[jid].setComplete(true);
+ refreshView();
}
void MUCSearchController::handleDiscoError(const JID& jid, ErrorPayload::ref error) {
- serviceDetails_[jid].setComplete(true);
- serviceDetails_[jid].setError(error->getText());
+ serviceDetails_[jid].setComplete(true);
+ serviceDetails_[jid].setError(error->getText());
}
void MUCSearchController::refreshView() {
- window_->clearList();
- foreach (JID jid, services_) {
- window_->addService(serviceDetails_[jid]);
- }
+ window_->clearList();
+ for (auto&& jid : services_) {
+ window_->addService(serviceDetails_[jid]);
+ }
}
void MUCSearchController::updateInProgressness() {
- window_->setSearchInProgress((walker_ && walker_->isActive()) || itemsInProgress_ > 0);
+ window_->setSearchInProgress((walker_ && walker_->isActive()) || itemsInProgress_ > 0);
}
void MUCSearchController::handleMUCSearchFinished(const boost::optional<JID>& result) {
- if (result) {
- onMUCSelected(*result);
- }
+ if (result) {
+ onMUCSelected(*result);
+ }
}
}
diff --git a/Swift/Controllers/Chat/MUCSearchController.h b/Swift/Controllers/Chat/MUCSearchController.h
index 068c930..f853bcd 100644
--- a/Swift/Controllers/Chat/MUCSearchController.h
+++ b/Swift/Controllers/Chat/MUCSearchController.h
@@ -1,124 +1,124 @@
/*
- * Copyright (c) 2010-2011 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <vector>
#include <map>
+#include <memory>
+#include <string>
+#include <vector>
-#include <boost/shared_ptr.hpp>
-#include "Swiften/Base/boost_bsignals.h"
+#include <boost/signals2.hpp>
-#include <string>
-#include "Swiften/JID/JID.h"
+#include <Swiften/Elements/DiscoInfo.h>
+#include <Swiften/Elements/DiscoItems.h>
+#include <Swiften/Elements/ErrorPayload.h>
+#include <Swiften/JID/JID.h>
-#include "Swift/Controllers/UIEvents/UIEvent.h"
-#include "Swift/Controllers/ProfileSettingsProvider.h"
-#include "Swiften/Elements/DiscoInfo.h"
-#include "Swiften/Elements/DiscoItems.h"
-#include "Swiften/Elements/ErrorPayload.h"
+#include <Swift/Controllers/ProfileSettingsProvider.h>
+#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class UIEventStream;
- class MUCSearchWindow;
- class MUCSearchWindowFactory;
- class IQRouter;
- class DiscoServiceWalker;
- class NickResolver;
-
- class MUCService {
- public:
- class MUCRoom {
- public:
- MUCRoom(const std::string& node, const std::string& name, int occupants) : node_(node), name_(name), occupants_(occupants) {}
- std::string getNode() {return node_;}
- std::string getName() {return name_;}
- int getOccupantCount() {return occupants_;}
- private:
- std::string node_;
- std::string name_;
- int occupants_;
- };
-
- MUCService() {error_ = false; complete_ = false;}
-
- void setComplete(bool complete) {
- complete_ = complete;
- }
-
- void setName(const std::string& name) {
- name_ = name;
- }
-
- void setJID(const JID& jid) {
- jid_ = jid;
- }
-
- bool getComplete() const {
- return complete_;
- }
-
- JID getJID() const {
- return jid_;
- }
-
- std::string getName() const {
- return name_;
- }
-
- void setError(const std::string& errorText) {error_ = true; errorText_ = errorText;}
-
- void clearRooms() {rooms_.clear();}
-
- void addRoom(const MUCRoom& room) {rooms_.push_back(room);}
-
- std::vector<MUCRoom> getRooms() const {return rooms_;}
- private:
- std::string name_;
- JID jid_;
- std::vector<MUCRoom> rooms_;
- bool complete_;
- bool error_;
- std::string errorText_;
- };
-
- class MUCSearchController {
- public:
- MUCSearchController(const JID& jid, MUCSearchWindowFactory* mucSearchWindowFactory, IQRouter* iqRouter, ProfileSettingsProvider* settings);
- ~MUCSearchController();
-
- void openSearchWindow();
-
- public:
- boost::signal<void (const JID&)> onMUCSelected;
-
- private:
- void handleSearchService(const JID& jid);
- void handleRoomsItemsResponse(boost::shared_ptr<DiscoItems> items, ErrorPayload::ref error, const JID& jid);
- void handleDiscoError(const JID& jid, ErrorPayload::ref error);
- void handleDiscoServiceFound(const JID&, boost::shared_ptr<DiscoInfo>);
- void handleDiscoWalkFinished();
- void handleMUCSearchFinished(const boost::optional<JID>& result);
- void removeService(const JID& jid);
- void refreshView();
- void loadSavedServices();
- void addToSavedServices(const JID& jid);
- void updateInProgressness();
-
- private:
- JID jid_;
- MUCSearchWindowFactory* factory_;
- IQRouter* iqRouter_;
- ProfileSettingsProvider* settings_;
- MUCSearchWindow* window_;
- DiscoServiceWalker* walker_;
- std::list<JID> services_;
- std::list<JID> savedServices_;
- std::map<JID, MUCService> serviceDetails_;
- std::vector<DiscoServiceWalker*> walksInProgress_;
- int itemsInProgress_;
- };
+ class UIEventStream;
+ class MUCSearchWindow;
+ class MUCSearchWindowFactory;
+ class IQRouter;
+ class DiscoServiceWalker;
+ class NickResolver;
+
+ class MUCService {
+ public:
+ class MUCRoom {
+ public:
+ MUCRoom(const std::string& node, const std::string& name, int occupants) : node_(node), name_(name), occupants_(occupants) {}
+ std::string getNode() {return node_;}
+ std::string getName() {return name_;}
+ int getOccupantCount() {return occupants_;}
+ private:
+ std::string node_;
+ std::string name_;
+ int occupants_;
+ };
+
+ MUCService() {error_ = false; complete_ = false;}
+
+ void setComplete(bool complete) {
+ complete_ = complete;
+ }
+
+ void setName(const std::string& name) {
+ name_ = name;
+ }
+
+ void setJID(const JID& jid) {
+ jid_ = jid;
+ }
+
+ bool getComplete() const {
+ return complete_;
+ }
+
+ JID getJID() const {
+ return jid_;
+ }
+
+ std::string getName() const {
+ return name_;
+ }
+
+ void setError(const std::string& errorText) {error_ = true; errorText_ = errorText;}
+
+ void clearRooms() {rooms_.clear();}
+
+ void addRoom(const MUCRoom& room) {rooms_.push_back(room);}
+
+ std::vector<MUCRoom> getRooms() const {return rooms_;}
+ private:
+ std::string name_;
+ JID jid_;
+ std::vector<MUCRoom> rooms_;
+ bool complete_;
+ bool error_;
+ std::string errorText_;
+ };
+
+ class MUCSearchController {
+ public:
+ MUCSearchController(const JID& jid, MUCSearchWindowFactory* mucSearchWindowFactory, IQRouter* iqRouter, ProfileSettingsProvider* settings);
+ ~MUCSearchController();
+
+ void openSearchWindow();
+
+ public:
+ boost::signals2::signal<void (const JID&)> onMUCSelected;
+
+ private:
+ void handleSearchService(const JID& jid);
+ void handleRoomsItemsResponse(std::shared_ptr<DiscoItems> items, ErrorPayload::ref error, const JID& jid);
+ void handleDiscoError(const JID& jid, ErrorPayload::ref error);
+ void handleDiscoServiceFound(const JID&, std::shared_ptr<DiscoInfo>);
+ void handleDiscoWalkFinished();
+ void handleMUCSearchFinished(const boost::optional<JID>& result);
+ void removeService(const JID& jid);
+ void refreshView();
+ void loadSavedServices();
+ void addToSavedServices(const JID& jid);
+ void updateInProgressness();
+
+ private:
+ JID jid_;
+ MUCSearchWindowFactory* factory_;
+ IQRouter* iqRouter_;
+ ProfileSettingsProvider* settings_;
+ MUCSearchWindow* window_;
+ DiscoServiceWalker* walker_;
+ std::list<JID> services_;
+ std::list<JID> savedServices_;
+ std::map<JID, MUCService> serviceDetails_;
+ std::vector<DiscoServiceWalker*> walksInProgress_;
+ int itemsInProgress_;
+ };
}
diff --git a/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp
index 1b92bb6..bc72b33 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatMessageParserTest.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015 Isode Limited.
+ * Copyright (c) 2013-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -13,266 +13,269 @@
using namespace Swift;
class ChatMessageParserTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(ChatMessageParserTest);
- CPPUNIT_TEST(testFullBody);
- CPPUNIT_TEST(testOneEmoticon);
- CPPUNIT_TEST(testBareEmoticon);
- CPPUNIT_TEST(testHiddenEmoticon);
- CPPUNIT_TEST(testEndlineEmoticon);
- CPPUNIT_TEST(testBoundedEmoticons);
- CPPUNIT_TEST(testNoColourNoHighlight);
- CPPUNIT_TEST_SUITE_END();
-
+ CPPUNIT_TEST_SUITE(ChatMessageParserTest);
+ CPPUNIT_TEST(testFullBody);
+ CPPUNIT_TEST(testOneEmoticon);
+ CPPUNIT_TEST(testBareEmoticon);
+ CPPUNIT_TEST(testHiddenEmoticon);
+ CPPUNIT_TEST(testEndlineEmoticon);
+ CPPUNIT_TEST(testBoundedEmoticons);
+ CPPUNIT_TEST(testNoColourNoHighlight);
+ CPPUNIT_TEST_SUITE_END();
+
public:
- void setUp() {
- smile1_ = ":)";
- smile1Path_ = "/blah/smile1.png";
- smile2_ = ":(";
- smile2Path_ = "/blah/smile2.jpg";
- emoticons_[smile1_] = smile1Path_;
- emoticons_[smile2_] = smile2Path_;
- }
-
- void tearDown() {
- emoticons_.clear();
- }
-
- void assertText(const ChatWindow::ChatMessage& result, size_t index, const std::string& text) {
- boost::shared_ptr<ChatWindow::ChatTextMessagePart> part = boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(result.getParts()[index]);
- CPPUNIT_ASSERT_EQUAL(text, part->text);
- }
-
- void assertEmoticon(const ChatWindow::ChatMessage& result, size_t index, const std::string& text, const std::string& path) {
- boost::shared_ptr<ChatWindow::ChatEmoticonMessagePart> part = boost::dynamic_pointer_cast<ChatWindow::ChatEmoticonMessagePart>(result.getParts()[index]);
- CPPUNIT_ASSERT(!!part);
- CPPUNIT_ASSERT_EQUAL(text, part->alternativeText);
- CPPUNIT_ASSERT_EQUAL(path, part->imagePath);
- }
-
- void assertHighlight(const ChatWindow::ChatMessage& result, size_t index, const std::string& text) {
- boost::shared_ptr<ChatWindow::ChatHighlightingMessagePart> part = boost::dynamic_pointer_cast<ChatWindow::ChatHighlightingMessagePart>(result.getParts()[index]);
- CPPUNIT_ASSERT_EQUAL(text, part->text);
- }
-
- void assertURL(const ChatWindow::ChatMessage& result, size_t index, const std::string& text) {
- boost::shared_ptr<ChatWindow::ChatURIMessagePart> part = boost::dynamic_pointer_cast<ChatWindow::ChatURIMessagePart>(result.getParts()[index]);
- CPPUNIT_ASSERT_EQUAL(text, part->target);
- }
-
- static HighlightRule ruleFromKeyword(const std::string& keyword, bool matchCase, bool matchWholeWord)
- {
- HighlightRule rule;
- std::vector<std::string> keywords;
- keywords.push_back(keyword);
- rule.setKeywords(keywords);
- rule.setMatchCase(matchCase);
- rule.setMatchWholeWords(matchWholeWord);
- rule.setMatchChat(true);
- rule.getAction().setTextBackground("white");
- return rule;
- }
-
- static const HighlightRulesListPtr ruleListFromKeyword(const std::string& keyword, bool matchCase, bool matchWholeWord)
- {
- boost::shared_ptr<HighlightManager::HighlightRulesList> list = boost::make_shared<HighlightManager::HighlightRulesList>();
- list->addRule(ruleFromKeyword(keyword, matchCase, matchWholeWord));
- return list;
- }
-
- static const HighlightRulesListPtr ruleListFromKeywords(const HighlightRule &rule1, const HighlightRule &rule2)
- {
- boost::shared_ptr<HighlightManager::HighlightRulesList> list = boost::make_shared<HighlightManager::HighlightRulesList>();
- list->addRule(rule1);
- list->addRule(rule2);
- return list;
- }
-
- static HighlightRulesListPtr ruleListWithNickHighlight(bool withHighlightColour = true)
- {
- HighlightRule rule;
- rule.setMatchChat(true);
- rule.setNickIsKeyword(true);
- rule.setMatchCase(true);
- rule.setMatchWholeWords(true);
- if (withHighlightColour) {
- rule.getAction().setTextBackground("white");
- }
- boost::shared_ptr<HighlightManager::HighlightRulesList> list = boost::make_shared<HighlightManager::HighlightRulesList>();
- list->addRule(rule);
- return list;
- }
-
- void testFullBody() {
- const std::string no_special_message = "a message with no special content";
- ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>());
- ChatWindow::ChatMessage result = testling.parseMessageBody(no_special_message);
- assertText(result, 0, no_special_message);
-
- testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false));
- result = testling.parseMessageBody(":) shiny :( trigger :) http://wonderland.lit/blah http://denmark.lit boom boom");
- assertEmoticon(result, 0, smile1_, smile1Path_);
- assertText(result, 1, " shiny ");
- assertEmoticon(result, 2, smile2_, smile2Path_);
- assertText(result, 3, " ");
- assertHighlight(result, 4, "trigger");
- assertText(result, 5, " ");
- assertEmoticon(result, 6, smile1_, smile1Path_);
- assertText(result, 7, " ");
- assertURL(result, 8, "http://wonderland.lit/blah");
- assertText(result, 9, " ");
- assertURL(result, 10, "http://denmark.lit");
- assertText(result, 11, " boom boom");
-
- testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false));
- result = testling.parseMessageBody("testtriggermessage");
- assertText(result, 0, "test");
- assertHighlight(result, 1, "trigger");
- assertText(result, 2, "message");
-
- testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, true));
- result = testling.parseMessageBody("testtriggermessage");
- assertText(result, 0, "testtriggermessage");
-
- testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", true, false));
- result = testling.parseMessageBody("TrIgGeR");
- assertText(result, 0, "TrIgGeR");
-
- testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false));
- result = testling.parseMessageBody("TrIgGeR");
- assertHighlight(result, 0, "TrIgGeR");
-
- testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false));
- result = testling.parseMessageBody("partialTrIgGeRmatch");
- assertText(result, 0, "partial");
- assertHighlight(result, 1, "TrIgGeR");
- assertText(result, 2, "match");
-
- testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", false, false)));
- result = testling.parseMessageBody("zero one two three");
- assertText(result, 0, "zero ");
- assertHighlight(result, 1, "one");
- assertText(result, 2, " two ");
- assertHighlight(result, 3, "three");
-
- testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", false, false)));
- result = testling.parseMessageBody("zero oNe two tHrEe");
- assertText(result, 0, "zero ");
- assertHighlight(result, 1, "oNe");
- assertText(result, 2, " two ");
- assertHighlight(result, 3, "tHrEe");
-
- testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", true, false)));
- result = testling.parseMessageBody("zero oNe two tHrEe");
- assertText(result, 0, "zero ");
- assertHighlight(result, 1, "oNe");
- assertText(result, 2, " two tHrEe");
-
- testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", true, false), ruleFromKeyword("three", true, false)));
- result = testling.parseMessageBody("zero oNe two tHrEe");
- assertText(result, 0, "zero oNe two tHrEe");
-
- testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", false, false)));
- result = testling.parseMessageBody("zeroonetwothree");
- assertText(result, 0, "zero");
- assertHighlight(result, 1, "one");
- assertText(result, 2, "two");
- assertHighlight(result, 3, "three");
-
- testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", true, false), ruleFromKeyword("three", false, false)));
- result = testling.parseMessageBody("zeroOnEtwoThReE");
- assertText(result, 0, "zeroOnEtwo");
- assertHighlight(result, 1, "ThReE");
-
- testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, true), ruleFromKeyword("three", false, false)));
- result = testling.parseMessageBody("zeroonetwothree");
- assertText(result, 0, "zeroonetwo");
- assertHighlight(result, 1, "three");
-
- testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, true), ruleFromKeyword("three", false, true)));
- result = testling.parseMessageBody("zeroonetwothree");
- assertText(result, 0, "zeroonetwothree");
-
- testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
- result = testling.parseMessageBody("Alice", "Alice");
- assertHighlight(result, 0, "Alice");
-
- testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
- result = testling.parseMessageBody("TextAliceText", "Alice");
- assertText(result, 0, "TextAliceText");
-
- testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
- result = testling.parseMessageBody("Text Alice Text", "Alice");
- assertText(result, 0, "Text ");
- assertHighlight(result, 1, "Alice");
- assertText(result, 2, " Text");
-
- testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
- result = testling.parseMessageBody("Alice Text", "Alice");
- assertHighlight(result, 0, "Alice");
- assertText(result, 1, " Text");
-
- testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
- result = testling.parseMessageBody("Text Alice", "Alice");
- assertText(result, 0, "Text ");
- assertHighlight(result, 1, "Alice");
- }
-
- void testOneEmoticon() {
- ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>());
- ChatWindow::ChatMessage result = testling.parseMessageBody(" :) ");
- assertText(result, 0, " ");
- assertEmoticon(result, 1, smile1_, smile1Path_);
- assertText(result, 2, " ");
- }
-
-
- void testBareEmoticon() {
- ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>());
- ChatWindow::ChatMessage result = testling.parseMessageBody(":)");
- assertEmoticon(result, 0, smile1_, smile1Path_);
- }
-
- void testHiddenEmoticon() {
- ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>());
- ChatWindow::ChatMessage result = testling.parseMessageBody("b:)a");
- assertText(result, 0, "b:)a");
- }
-
- void testEndlineEmoticon() {
- ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>());
- ChatWindow::ChatMessage result = testling.parseMessageBody("Lazy:)");
- assertText(result, 0, "Lazy");
- assertEmoticon(result, 1, smile1_, smile1Path_);
- }
-
- void testBoundedEmoticons() {
- ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>());
- ChatWindow::ChatMessage result = testling.parseMessageBody(":)Lazy:(");
- assertEmoticon(result, 0, smile1_, smile1Path_);
- assertText(result, 1, "Lazy");
- assertEmoticon(result, 2, smile2_, smile2Path_);
- }
-
- void testEmoticonParenthesis() {
- ChatMessageParser testling(emoticons_, boost::make_shared<HighlightManager::HighlightRulesList>());
- ChatWindow::ChatMessage result = testling.parseMessageBody("(Like this :))");
- assertText(result, 0, "(Like this ");
- assertEmoticon(result, 1, smile1_, smile1Path_);
- assertText(result, 2, ")");
- }
-
- void testNoColourNoHighlight() {
- ChatMessageParser testling(emoticons_, ruleListWithNickHighlight(false));
- ChatWindow::ChatMessage result = testling.parseMessageBody("Alice", "Alice");
- assertText(result, 0, "Alice");
- }
+ void setUp() {
+ smile1_ = ":)";
+ smile1Path_ = "/blah/smile1.png";
+ smile2_ = ":(";
+ smile2Path_ = "/blah/smile2.jpg";
+ emoticons_[smile1_] = smile1Path_;
+ emoticons_[smile2_] = smile2Path_;
+ }
+
+ void tearDown() {
+ emoticons_.clear();
+ }
+
+ void assertText(const ChatWindow::ChatMessage& result, size_t index, const std::string& text) {
+ std::shared_ptr<ChatWindow::ChatTextMessagePart> part = std::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(result.getParts()[index]);
+ CPPUNIT_ASSERT_EQUAL(text, part->text);
+ }
+
+ void assertEmoticon(const ChatWindow::ChatMessage& result, size_t index, const std::string& text, const std::string& path) {
+ std::shared_ptr<ChatWindow::ChatEmoticonMessagePart> part = std::dynamic_pointer_cast<ChatWindow::ChatEmoticonMessagePart>(result.getParts()[index]);
+ CPPUNIT_ASSERT(!!part);
+ CPPUNIT_ASSERT_EQUAL(text, part->alternativeText);
+ CPPUNIT_ASSERT_EQUAL(path, part->imagePath);
+ }
+
+#define assertHighlight(RESULT, INDEX, TEXT, EXPECTED_HIGHLIGHT) \
+ { \
+ std::shared_ptr<ChatWindow::ChatHighlightingMessagePart> part = std::dynamic_pointer_cast<ChatWindow::ChatHighlightingMessagePart>(RESULT.getParts()[INDEX]); \
+ CPPUNIT_ASSERT_EQUAL(std::string(TEXT), part->text); \
+ CPPUNIT_ASSERT(EXPECTED_HIGHLIGHT == part->action); \
+ }
+
+ void assertURL(const ChatWindow::ChatMessage& result, size_t index, const std::string& text) {
+ std::shared_ptr<ChatWindow::ChatURIMessagePart> part = std::dynamic_pointer_cast<ChatWindow::ChatURIMessagePart>(result.getParts()[index]);
+ CPPUNIT_ASSERT_EQUAL(text, part->target);
+ }
+
+ static HighlightRule ruleFromKeyword(const std::string& keyword, bool matchCase, bool matchWholeWord)
+ {
+ HighlightRule rule;
+ std::vector<std::string> keywords;
+ keywords.push_back(keyword);
+ rule.setKeywords(keywords);
+ rule.setMatchCase(matchCase);
+ rule.setMatchWholeWords(matchWholeWord);
+ rule.setMatchChat(true);
+ rule.getAction().setTextBackground("white");
+ return rule;
+ }
+
+ static const HighlightRulesListPtr ruleListFromKeyword(const std::string& keyword, bool matchCase, bool matchWholeWord)
+ {
+ std::shared_ptr<HighlightManager::HighlightRulesList> list = std::make_shared<HighlightManager::HighlightRulesList>();
+ list->addRule(ruleFromKeyword(keyword, matchCase, matchWholeWord));
+ return list;
+ }
+
+ static const HighlightRulesListPtr ruleListFromKeywords(const HighlightRule &rule1, const HighlightRule &rule2)
+ {
+ std::shared_ptr<HighlightManager::HighlightRulesList> list = std::make_shared<HighlightManager::HighlightRulesList>();
+ list->addRule(rule1);
+ list->addRule(rule2);
+ return list;
+ }
+
+ static HighlightRulesListPtr ruleListWithNickHighlight(bool withHighlightColour = true)
+ {
+ HighlightRule rule;
+ rule.setMatchChat(true);
+ rule.setNickIsKeyword(true);
+ rule.setMatchCase(true);
+ rule.setMatchWholeWords(true);
+ if (withHighlightColour) {
+ rule.getAction().setTextBackground("white");
+ }
+ std::shared_ptr<HighlightManager::HighlightRulesList> list = std::make_shared<HighlightManager::HighlightRulesList>();
+ list->addRule(rule);
+ return list;
+ }
+
+ void testFullBody() {
+ const std::string no_special_message = "a message with no special content";
+ ChatMessageParser testling(emoticons_, std::make_shared<HighlightManager::HighlightRulesList>());
+ ChatWindow::ChatMessage result = testling.parseMessageBody(no_special_message);
+ assertText(result, 0, no_special_message);
+
+ HighlightRulesListPtr highlightRuleList = ruleListFromKeyword("trigger", false, false);
+ testling = ChatMessageParser(emoticons_, highlightRuleList);
+ result = testling.parseMessageBody(":) shiny :( trigger :) http://wonderland.lit/blah http://denmark.lit boom boom");
+ assertEmoticon(result, 0, smile1_, smile1Path_);
+ assertText(result, 1, " shiny ");
+ assertEmoticon(result, 2, smile2_, smile2Path_);
+ assertText(result, 3, " ");
+ assertHighlight(result, 4, "trigger", highlightRuleList->getRule(0).getAction());
+ assertText(result, 5, " ");
+ assertEmoticon(result, 6, smile1_, smile1Path_);
+ assertText(result, 7, " ");
+ assertURL(result, 8, "http://wonderland.lit/blah");
+ assertText(result, 9, " ");
+ assertURL(result, 10, "http://denmark.lit");
+ assertText(result, 11, " boom boom");
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false));
+ result = testling.parseMessageBody("testtriggermessage");
+ assertText(result, 0, "test");
+ assertHighlight(result, 1, "trigger", highlightRuleList->getRule(0).getAction());
+ assertText(result, 2, "message");
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, true));
+ result = testling.parseMessageBody("testtriggermessage");
+ assertText(result, 0, "testtriggermessage");
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", true, false));
+ result = testling.parseMessageBody("TrIgGeR");
+ assertText(result, 0, "TrIgGeR");
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false));
+ result = testling.parseMessageBody("TrIgGeR");
+ assertHighlight(result, 0, "TrIgGeR", highlightRuleList->getRule(0).getAction());
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeyword("trigger", false, false));
+ result = testling.parseMessageBody("partialTrIgGeRmatch");
+ assertText(result, 0, "partial");
+ assertHighlight(result, 1, "TrIgGeR", highlightRuleList->getRule(0).getAction());
+ assertText(result, 2, "match");
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", false, false)));
+ result = testling.parseMessageBody("zero one two three");
+ assertText(result, 0, "zero ");
+ assertHighlight(result, 1, "one", highlightRuleList->getRule(0).getAction());
+ assertText(result, 2, " two ");
+ assertHighlight(result, 3, "three", highlightRuleList->getRule(0).getAction());
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", false, false)));
+ result = testling.parseMessageBody("zero oNe two tHrEe");
+ assertText(result, 0, "zero ");
+ assertHighlight(result, 1, "oNe", highlightRuleList->getRule(0).getAction());
+ assertText(result, 2, " two ");
+ assertHighlight(result, 3, "tHrEe", highlightRuleList->getRule(0).getAction());
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", true, false)));
+ result = testling.parseMessageBody("zero oNe two tHrEe");
+ assertText(result, 0, "zero ");
+ assertHighlight(result, 1, "oNe", highlightRuleList->getRule(0).getAction());
+ assertText(result, 2, " two tHrEe");
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", true, false), ruleFromKeyword("three", true, false)));
+ result = testling.parseMessageBody("zero oNe two tHrEe");
+ assertText(result, 0, "zero oNe two tHrEe");
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, false), ruleFromKeyword("three", false, false)));
+ result = testling.parseMessageBody("zeroonetwothree");
+ assertText(result, 0, "zero");
+ assertHighlight(result, 1, "one", highlightRuleList->getRule(0).getAction());
+ assertText(result, 2, "two");
+ assertHighlight(result, 3, "three", highlightRuleList->getRule(0).getAction());
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", true, false), ruleFromKeyword("three", false, false)));
+ result = testling.parseMessageBody("zeroOnEtwoThReE");
+ assertText(result, 0, "zeroOnEtwo");
+ assertHighlight(result, 1, "ThReE", highlightRuleList->getRule(0).getAction());
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, true), ruleFromKeyword("three", false, false)));
+ result = testling.parseMessageBody("zeroonetwothree");
+ assertText(result, 0, "zeroonetwo");
+ assertHighlight(result, 1, "three", highlightRuleList->getRule(0).getAction());
+
+ testling = ChatMessageParser(emoticons_, ruleListFromKeywords(ruleFromKeyword("one", false, true), ruleFromKeyword("three", false, true)));
+ result = testling.parseMessageBody("zeroonetwothree");
+ assertText(result, 0, "zeroonetwothree");
+
+ testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
+ result = testling.parseMessageBody("Alice", "Alice");
+ assertHighlight(result, 0, "Alice", highlightRuleList->getRule(0).getAction());
+
+ testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
+ result = testling.parseMessageBody("TextAliceText", "Alice");
+ assertText(result, 0, "TextAliceText");
+
+ testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
+ result = testling.parseMessageBody("Text Alice Text", "Alice");
+ assertText(result, 0, "Text ");
+ assertHighlight(result, 1, "Alice", highlightRuleList->getRule(0).getAction());
+ assertText(result, 2, " Text");
+
+ testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
+ result = testling.parseMessageBody("Alice Text", "Alice");
+ assertHighlight(result, 0, "Alice", highlightRuleList->getRule(0).getAction());
+ assertText(result, 1, " Text");
+
+ testling = ChatMessageParser(emoticons_, ruleListWithNickHighlight());
+ result = testling.parseMessageBody("Text Alice", "Alice");
+ assertText(result, 0, "Text ");
+ assertHighlight(result, 1, "Alice", highlightRuleList->getRule(0).getAction());
+ }
+
+ void testOneEmoticon() {
+ ChatMessageParser testling(emoticons_, std::make_shared<HighlightManager::HighlightRulesList>());
+ ChatWindow::ChatMessage result = testling.parseMessageBody(" :) ");
+ assertText(result, 0, " ");
+ assertEmoticon(result, 1, smile1_, smile1Path_);
+ assertText(result, 2, " ");
+ }
+
+
+ void testBareEmoticon() {
+ ChatMessageParser testling(emoticons_, std::make_shared<HighlightManager::HighlightRulesList>());
+ ChatWindow::ChatMessage result = testling.parseMessageBody(":)");
+ assertEmoticon(result, 0, smile1_, smile1Path_);
+ }
+
+ void testHiddenEmoticon() {
+ ChatMessageParser testling(emoticons_, std::make_shared<HighlightManager::HighlightRulesList>());
+ ChatWindow::ChatMessage result = testling.parseMessageBody("b:)a");
+ assertText(result, 0, "b:)a");
+ }
+
+ void testEndlineEmoticon() {
+ ChatMessageParser testling(emoticons_, std::make_shared<HighlightManager::HighlightRulesList>());
+ ChatWindow::ChatMessage result = testling.parseMessageBody("Lazy:)");
+ assertText(result, 0, "Lazy");
+ assertEmoticon(result, 1, smile1_, smile1Path_);
+ }
+
+ void testBoundedEmoticons() {
+ ChatMessageParser testling(emoticons_, std::make_shared<HighlightManager::HighlightRulesList>());
+ ChatWindow::ChatMessage result = testling.parseMessageBody(":)Lazy:(");
+ assertEmoticon(result, 0, smile1_, smile1Path_);
+ assertText(result, 1, "Lazy");
+ assertEmoticon(result, 2, smile2_, smile2Path_);
+ }
+
+ void testEmoticonParenthesis() {
+ ChatMessageParser testling(emoticons_, std::make_shared<HighlightManager::HighlightRulesList>());
+ ChatWindow::ChatMessage result = testling.parseMessageBody("(Like this :))");
+ assertText(result, 0, "(Like this ");
+ assertEmoticon(result, 1, smile1_, smile1Path_);
+ assertText(result, 2, ")");
+ }
+
+ void testNoColourNoHighlight() {
+ ChatMessageParser testling(emoticons_, ruleListWithNickHighlight(false));
+ ChatWindow::ChatMessage result = testling.parseMessageBody("Alice", "Alice");
+ assertText(result, 0, "Alice");
+ }
private:
- std::map<std::string, std::string> emoticons_;
- std::string smile1_;
- std::string smile1Path_;
- std::string smile2_;
- std::string smile2Path_;
+ std::map<std::string, std::string> emoticons_;
+ std::string smile1_;
+ std::string smile1Path_;
+ std::string smile2_;
+ std::string smile2Path_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(ChatMessageParserTest);
diff --git a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
index 4f8cf5a..cff54f8 100644
--- a/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/ChatsManagerTest.cpp
@@ -4,6 +4,9 @@
* See the COPYING file for more information.
*/
+#include <map>
+#include <set>
+
#include <boost/bind.hpp>
#include <cppunit/extensions/HelperMacros.h>
@@ -20,8 +23,13 @@
#include <Swiften/Crypto/CryptoProvider.h>
#include <Swiften/Crypto/PlatformCryptoProvider.h>
#include <Swiften/Disco/DummyEntityCapsProvider.h>
+#include <Swiften/Elements/CarbonsReceived.h>
+#include <Swiften/Elements/CarbonsSent.h>
#include <Swiften/Elements/DeliveryReceipt.h>
#include <Swiften/Elements/DeliveryReceiptRequest.h>
+#include <Swiften/Elements/Forwarded.h>
+#include <Swiften/Elements/MUCInvitationPayload.h>
+#include <Swiften/Elements/MUCUserPayload.h>
#include <Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h>
#include <Swiften/Jingle/JingleSessionManager.h>
#include <Swiften/MUC/MUCManager.h>
@@ -58,723 +66,1124 @@
using namespace Swift;
class ChatsManagerTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(ChatsManagerTest);
- CPPUNIT_TEST(testFirstOpenWindowIncoming);
- CPPUNIT_TEST(testSecondOpenWindowIncoming);
- CPPUNIT_TEST(testFirstOpenWindowOutgoing);
- CPPUNIT_TEST(testFirstOpenWindowBareToFull);
- CPPUNIT_TEST(testSecondWindow);
- CPPUNIT_TEST(testUnbindRebind);
- CPPUNIT_TEST(testNoDuplicateUnbind);
- CPPUNIT_TEST(testThreeMUCWindows);
- CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnRemoveFromRoster);
- CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnAddToRoster);
- CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToBoth);
- CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToFrom);
- CPPUNIT_TEST(testChatControllerFullJIDBindingOnMessageAndNotReceipt);
- CPPUNIT_TEST(testChatControllerFullJIDBindingOnTypingAndNotActive);
- CPPUNIT_TEST(testChatControllerPMPresenceHandling);
- CPPUNIT_TEST(testLocalMUCServiceDiscoveryResetOnDisconnect);
- CPPUNIT_TEST_SUITE_END();
+ CPPUNIT_TEST_SUITE(ChatsManagerTest);
+ CPPUNIT_TEST(testFirstOpenWindowIncoming);
+ CPPUNIT_TEST(testSecondOpenWindowIncoming);
+ CPPUNIT_TEST(testFirstOpenWindowOutgoing);
+ CPPUNIT_TEST(testFirstOpenWindowBareToFull);
+ CPPUNIT_TEST(testSecondWindow);
+ CPPUNIT_TEST(testUnbindRebind);
+ CPPUNIT_TEST(testNoDuplicateUnbind);
+ CPPUNIT_TEST(testThreeMUCWindows);
+ CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnRemoveFromRoster);
+ CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnAddToRoster);
+ CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToBoth);
+ CPPUNIT_TEST(testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToFrom);
+ CPPUNIT_TEST(testChatControllerFullJIDBindingOnMessageAndNotReceipt);
+ CPPUNIT_TEST(testChatControllerFullJIDBindingOnTypingAndNotActive);
+ CPPUNIT_TEST(testLocalMUCServiceDiscoveryResetOnDisconnect);
+ CPPUNIT_TEST(testPresenceChangeDoesNotReplaceMUCInvite);
+
+ // MUC PM Tests
+ CPPUNIT_TEST(testChatControllerPMPresenceHandling);
+ CPPUNIT_TEST(testChatControllerMucPmUnavailableErrorHandling);
+
+ // Highlighting tests
+ CPPUNIT_TEST(testChatControllerHighlightingNotificationTesting);
+ CPPUNIT_TEST(testChatControllerHighlightingNotificationDeduplicateSounds);
+ CPPUNIT_TEST(testChatControllerMeMessageHandling);
+ CPPUNIT_TEST(testRestartingMUCComponentCrash);
+ CPPUNIT_TEST(testChatControllerMeMessageHandlingInMUC);
+
+ // Carbons tests
+ CPPUNIT_TEST(testCarbonsForwardedIncomingMessageToSecondResource);
+ CPPUNIT_TEST(testCarbonsForwardedOutgoingMessageFromSecondResource);
+
+ CPPUNIT_TEST_SUITE_END();
public:
- void setUp() {
- mocks_ = new MockRepository();
- jid_ = JID("test@test.com/resource");
- stanzaChannel_ = new DummyStanzaChannel();
- iqChannel_ = new DummyIQChannel();
- iqRouter_ = new IQRouter(iqChannel_);
-// capsProvider_ = new DummyCapsProvider();
- eventController_ = new EventController();
- chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>();
- joinMUCWindowFactory_ = mocks_->InterfaceMock<JoinMUCWindowFactory>();
- xmppRoster_ = new XMPPRosterImpl();
- mucRegistry_ = new MUCRegistry();
- nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL, mucRegistry_);
- presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_);
- serverDiscoInfo_ = boost::make_shared<DiscoInfo>();
- presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_);
- directedPresenceSender_ = new DirectedPresenceSender(presenceSender_);
- mucManager_ = new MUCManager(stanzaChannel_, iqRouter_, directedPresenceSender_, mucRegistry_);
- uiEventStream_ = new UIEventStream();
-// entityCapsManager_ = new EntityCapsManager(capsProvider_, stanzaChannel_);
- entityCapsProvider_ = new DummyEntityCapsProvider();
- chatListWindowFactory_ = mocks_->InterfaceMock<ChatListWindowFactory>();
- mucSearchWindowFactory_ = mocks_->InterfaceMock<MUCSearchWindowFactory>();
- settings_ = new DummySettingsProvider();
- profileSettings_ = new ProfileSettingsProvider("a", settings_);
- chatListWindow_ = new MockChatListWindow();
- ftManager_ = new DummyFileTransferManager();
- ftOverview_ = new FileTransferOverview(ftManager_);
- avatarManager_ = new NullAvatarManager();
- wbSessionManager_ = new WhiteboardSessionManager(iqRouter_, stanzaChannel_, presenceOracle_, entityCapsProvider_);
- wbManager_ = new WhiteboardManager(whiteboardWindowFactory_, uiEventStream_, nickResolver_, wbSessionManager_);
- highlightManager_ = new HighlightManager(settings_);
-
- crypto_ = PlatformCryptoProvider::create();
- vcardStorage_ = new VCardMemoryStorage(crypto_);
- vcardManager_ = new VCardManager(jid_, iqRouter_, vcardStorage_);
- mocks_->ExpectCall(chatListWindowFactory_, ChatListWindowFactory::createChatListWindow).With(uiEventStream_).Return(chatListWindow_);
- clientBlockListManager_ = new ClientBlockListManager(iqRouter_);
- manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, joinMUCWindowFactory_, nickResolver_, presenceOracle_, directedPresenceSender_, uiEventStream_, chatListWindowFactory_, true, NULL, mucRegistry_, entityCapsProvider_, mucManager_, mucSearchWindowFactory_, profileSettings_, ftOverview_, xmppRoster_, false, settings_, NULL, wbManager_, highlightManager_, clientBlockListManager_, emoticons_, vcardManager_);
-
- manager_->setAvatarManager(avatarManager_);
- }
-
- void tearDown() {
- delete highlightManager_;
- //delete chatListWindowFactory
- delete profileSettings_;
- delete avatarManager_;
- delete manager_;
- delete clientBlockListManager_;
- delete vcardManager_;
- delete vcardStorage_;
- delete crypto_;
- delete ftOverview_;
- delete ftManager_;
- delete wbSessionManager_;
- delete wbManager_;
- delete directedPresenceSender_;
- delete presenceSender_;
- delete presenceOracle_;
- delete nickResolver_;
- delete mucRegistry_;
- delete stanzaChannel_;
- delete eventController_;
- delete iqRouter_;
- delete iqChannel_;
- delete uiEventStream_;
- delete mucManager_;
- delete xmppRoster_;
- delete entityCapsProvider_;
- delete chatListWindow_;
- delete mocks_;
- delete settings_;
- }
-
- void testFirstOpenWindowIncoming() {
- JID messageJID("testling@test.com/resource1");
-
- MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
-
- boost::shared_ptr<Message> message(new Message());
- message->setFrom(messageJID);
- std::string body("This is a legible message. >HEH@)oeueu");
- message->setBody(body);
- manager_->handleIncomingMessage(message);
- CPPUNIT_ASSERT_EQUAL(body, window->lastMessageBody_);
- }
-
- void testSecondOpenWindowIncoming() {
- JID messageJID1("testling@test.com/resource1");
-
- MockChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID1, uiEventStream_).Return(window1);
-
- boost::shared_ptr<Message> message1(new Message());
- message1->setFrom(messageJID1);
- std::string body1("This is a legible message. >HEH@)oeueu");
- message1->setBody(body1);
- manager_->handleIncomingMessage(message1);
- CPPUNIT_ASSERT_EQUAL(body1, window1->lastMessageBody_);
-
- JID messageJID2("testling@test.com/resource2");
-
- //MockChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- //mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID2, uiEventStream_).Return(window2);
-
- boost::shared_ptr<Message> message2(new Message());
- message2->setFrom(messageJID2);
- std::string body2("This is a legible message. .cmaulm.chul");
- message2->setBody(body2);
- manager_->handleIncomingMessage(message2);
- CPPUNIT_ASSERT_EQUAL(body2, window1->lastMessageBody_);
- }
-
- void testFirstOpenWindowOutgoing() {
- std::string messageJIDString("testling@test.com");
-
- ChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString), uiEventStream_).Return(window);
-
- uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString))));
- }
-
-
- void testFirstOpenWindowBareToFull() {
- std::string bareJIDString("testling@test.com");
- std::string fullJIDString("testling@test.com/resource1");
-
- MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(bareJIDString), uiEventStream_).Return(window);
- uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(bareJIDString))));
-
- boost::shared_ptr<Message> message(new Message());
- message->setFrom(JID(fullJIDString));
- std::string body("This is a legible message. mjuga3089gm8G(*>M)@*(");
- message->setBody(body);
- manager_->handleIncomingMessage(message);
- CPPUNIT_ASSERT_EQUAL(body, window->lastMessageBody_);
- }
-
- void testSecondWindow() {
- std::string messageJIDString1("testling1@test.com");
- ChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString1), uiEventStream_).Return(window1);
- uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString1))));
-
- std::string messageJIDString2("testling2@test.com");
- ChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString2), uiEventStream_).Return(window2);
-
- uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString2))));
- }
-
- /** Complete cycle.
- Create unbound window.
- Bind it.
- Unbind it.
- Rebind it.
- */
- void testUnbindRebind() {
- std::string bareJIDString("testling@test.com");
- std::string fullJIDString1("testling@test.com/resource1");
- std::string fullJIDString2("testling@test.com/resource2");
-
- MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(bareJIDString), uiEventStream_).Return(window);
- uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(bareJIDString))));
-
- boost::shared_ptr<Message> message1(new Message());
- message1->setFrom(JID(fullJIDString1));
- std::string messageBody1("This is a legible message.");
- message1->setBody(messageBody1);
- manager_->handleIncomingMessage(message1);
- CPPUNIT_ASSERT_EQUAL(messageBody1, window->lastMessageBody_);
-
- boost::shared_ptr<Presence> jid1Online(new Presence());
- jid1Online->setFrom(JID(fullJIDString1));
- boost::shared_ptr<Presence> jid1Offline(new Presence());
- jid1Offline->setFrom(JID(fullJIDString1));
- jid1Offline->setType(Presence::Unavailable);
- presenceOracle_->onPresenceChange(jid1Offline);
-
- boost::shared_ptr<Message> message2(new Message());
- message2->setFrom(JID(fullJIDString2));
- std::string messageBody2("This is another legible message.");
- message2->setBody(messageBody2);
- manager_->handleIncomingMessage(message2);
- CPPUNIT_ASSERT_EQUAL(messageBody2, window->lastMessageBody_);
- }
-
- /**
- * Test that MUC PMs get opened in the right windows
- */
- void testThreeMUCWindows() {
- JID muc("testling@test.com");
- ChatWindow* mucWindow = new MockChatWindow();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(muc, uiEventStream_).Return(mucWindow);
- uiEventStream_->send(boost::make_shared<JoinMUCUIEvent>(muc, std::string("nick")));
-
-
- std::string messageJIDString1("testling@test.com/1");
- ChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString1), uiEventStream_).Return(window1);
- uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString1))));
-
- std::string messageJIDString2("testling@test.com/2");
- ChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString2), uiEventStream_).Return(window2);
-
- uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString2))));
-
- std::string messageJIDString3("testling@test.com/3");
- ChatWindow* window3 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString3), uiEventStream_).Return(window3);
-
- uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString3))));
-
- /* Refetch an earlier window */
- /* We do not expect a new window to be created */
- uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(messageJIDString1))));
-
- }
-
- /**
- Test that a second window isn't unbound where there's already an unbound one.
- Bind 1
- Bind 2
- Unbind 1
- Unbind 2 (but it doesn't)
- Sent to bound 2
- Rebind 1
- */
- void testNoDuplicateUnbind() {
- JID messageJID1("testling@test.com/resource1");
-
- MockChatWindow* window1 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID1, uiEventStream_).Return(window1);
-
- boost::shared_ptr<Message> message1(new Message());
- message1->setFrom(messageJID1);
- message1->setBody("This is a legible message1.");
- manager_->handleIncomingMessage(message1);
-
- JID messageJID2("testling@test.com/resource2");
-
- //MockChatWindow* window2 = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- //mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID2, uiEventStream_).Return(window2);
-
- boost::shared_ptr<Message> message2(new Message());
- message2->setFrom(messageJID2);
- message2->setBody("This is a legible message2.");
- manager_->handleIncomingMessage(message2);
-
- boost::shared_ptr<Presence> jid1Online(new Presence());
- jid1Online->setFrom(JID(messageJID1));
- boost::shared_ptr<Presence> jid1Offline(new Presence());
- jid1Offline->setFrom(JID(messageJID1));
- jid1Offline->setType(Presence::Unavailable);
- presenceOracle_->onPresenceChange(jid1Offline);
-
- boost::shared_ptr<Presence> jid2Online(new Presence());
- jid2Online->setFrom(JID(messageJID2));
- boost::shared_ptr<Presence> jid2Offline(new Presence());
- jid2Offline->setFrom(JID(messageJID2));
- jid2Offline->setType(Presence::Unavailable);
- presenceOracle_->onPresenceChange(jid2Offline);
-
- JID messageJID3("testling@test.com/resource3");
-
- boost::shared_ptr<Message> message3(new Message());
- message3->setFrom(messageJID3);
- std::string body3("This is a legible message3.");
- message3->setBody(body3);
- manager_->handleIncomingMessage(message3);
- CPPUNIT_ASSERT_EQUAL(body3, window1->lastMessageBody_);
-
- boost::shared_ptr<Message> message2b(new Message());
- message2b->setFrom(messageJID2);
- std::string body2b("This is a legible message2b.");
- message2b->setBody(body2b);
- manager_->handleIncomingMessage(message2b);
- CPPUNIT_ASSERT_EQUAL(body2b, window1->lastMessageBody_);
- }
-
- /**
- * Test that ChatController doesn't send receipts anymore after removal of the contact from the roster.
- */
- void testChatControllerPresenceAccessUpdatedOnRemoveFromRoster() {
- JID messageJID("testling@test.com/resource1");
- xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), RosterItemPayload::Both);
-
- MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
- settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true);
-
- boost::shared_ptr<Message> message = makeDeliveryReceiptTestMessage(messageJID, "1");
- manager_->handleIncomingMessage(message);
- Stanza::ref stanzaContactOnRoster = stanzaChannel_->getStanzaAtIndex<Stanza>(0);
- CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->sentStanzas.size());
- CPPUNIT_ASSERT(stanzaContactOnRoster->getPayload<DeliveryReceipt>() != 0);
-
- xmppRoster_->removeContact(messageJID);
-
- message->setID("2");
- manager_->handleIncomingMessage(message);
- CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->sentStanzas.size());
- }
-
- /**
- * Test that ChatController sends receipts after the contact has been added to the roster.
- */
- void testChatControllerPresenceAccessUpdatedOnAddToRoster() {
- JID messageJID("testling@test.com/resource1");
-
- MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
- settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true);
-
- boost::shared_ptr<Message> message = makeDeliveryReceiptTestMessage(messageJID, "1");
- manager_->handleIncomingMessage(message);
-
- CPPUNIT_ASSERT_EQUAL(st(0), stanzaChannel_->sentStanzas.size());
-
- xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), RosterItemPayload::Both);
- message->setID("2");
- manager_->handleIncomingMessage(message);
-
- CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->sentStanzas.size());
- Stanza::ref stanzaContactOnRoster = stanzaChannel_->getStanzaAtIndex<Stanza>(0);
- CPPUNIT_ASSERT(stanzaContactOnRoster->getPayload<DeliveryReceipt>() != 0);
- }
-
- /**
- * Test that ChatController sends receipts if requested after change from subscription state To to subscription state Both.
- */
- void testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToBoth() {
- testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::To, RosterItemPayload::Both);
- }
-
- /**
- * Test that ChatController sends receipts if requested after change from subscription state To to subscription state From.
- */
- void testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToFrom() {
- testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::To, RosterItemPayload::From);
- }
-
- void testChatControllerFullJIDBindingOnMessageAndNotReceipt() {
- JID ownJID("test@test.com/resource");
- JID sender("foo@test.com");
- std::vector<JID> senderResource;
- senderResource.push_back(sender.withResource("resourceA"));
- senderResource.push_back(sender.withResource("resourceB"));
-
- // We support delivery receipts.
- settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true);
-
- // Open chat window to a sender.
- MockChatWindow* window = new MockChatWindow();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(sender, uiEventStream_).Return(window);
-
- uiEventStream_->send(boost::make_shared<RequestChatUIEvent>(sender));
-
- foreach(const JID& senderJID, senderResource) {
- // The sender supports delivery receipts.
- DiscoInfo::ref disco = boost::make_shared<DiscoInfo>();
- disco->addFeature(DiscoInfo::MessageDeliveryReceiptsFeature);
- entityCapsProvider_->caps[senderJID] = disco;
-
- // The sender is online.
- Presence::ref senderPresence = boost::make_shared<Presence>();
- senderPresence->setFrom(senderJID);
- senderPresence->setTo(ownJID);
- stanzaChannel_->onPresenceReceived(senderPresence);
-
- entityCapsProvider_->onCapsChanged(senderJID);
- }
-
- // Send first message.
- window->onSendMessageRequest("hello there", false);
-
- // A bare message is send because no resources is bound.
- CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(0)->getTo());
- CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(0)->getPayload<DeliveryReceiptRequest>());
-
- // Two resources respond with message receipts.
- foreach(const JID& senderJID, senderResource) {
- Message::ref receiptReply = boost::make_shared<Message>();
- receiptReply->setFrom(senderJID);
- receiptReply->setTo(ownJID);
-
- boost::shared_ptr<DeliveryReceipt> receipt = boost::make_shared<DeliveryReceipt>();
- receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(0)->getID());
- receiptReply->addPayload(receipt);
- manager_->handleIncomingMessage(receiptReply);
- }
-
- // Send second message.
- window->onSendMessageRequest("how are you?", false);
-
- // A bare message is send because no resources is bound.
- CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(1)->getTo());
- CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(1)->getPayload<DeliveryReceiptRequest>());
-
- // Two resources respond with message receipts.
- foreach(const JID& senderJID, senderResource) {
- Message::ref receiptReply = boost::make_shared<Message>();
- receiptReply->setFrom(senderJID);
- receiptReply->setTo(ownJID);
-
- boost::shared_ptr<DeliveryReceipt> receipt = boost::make_shared<DeliveryReceipt>();
- receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(1)->getID());
- receiptReply->addPayload(receipt);
- manager_->handleIncomingMessage(receiptReply);
- }
-
- // Reply with a message including a body text.
- Message::ref reply = boost::make_shared<Message>();
- reply->setFrom(senderResource[0]);
- reply->setTo(ownJID);
- reply->setBody("fine.");
- manager_->handleIncomingMessage(reply);
-
- // Send third message.
- window->onSendMessageRequest("great to hear.", false);
-
- // The chat session is bound to the full JID of the first resource.
- CPPUNIT_ASSERT_EQUAL(senderResource[0], stanzaChannel_->getStanzaAtIndex<Message>(2)->getTo());
- CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(2)->getPayload<DeliveryReceiptRequest>());
-
- // Receive random receipt from second sender resource.
- reply = boost::make_shared<Message>();
- reply->setFrom(senderResource[1]);
- reply->setTo(ownJID);
-
- boost::shared_ptr<DeliveryReceipt> receipt = boost::make_shared<DeliveryReceipt>();
- receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(2)->getID());
- reply->addPayload(receipt);
- manager_->handleIncomingMessage(reply);
-
- // Send forth message.
- window->onSendMessageRequest("what else is new?", false);
-
- // The chat session is bound to the full JID of the first resource.
- CPPUNIT_ASSERT_EQUAL(senderResource[0], stanzaChannel_->getStanzaAtIndex<Message>(3)->getTo());
- CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(3)->getPayload<DeliveryReceiptRequest>());
-
- // Reply with a message including a body text from second resource.
- reply = boost::make_shared<Message>();
- reply->setFrom(senderResource[1]);
- reply->setTo(ownJID);
- reply->setBody("nothing.");
- manager_->handleIncomingMessage(reply);
-
- // Send fifth message.
- window->onSendMessageRequest("okay", false);
-
- // The chat session is now bound to the full JID of the second resource.
- CPPUNIT_ASSERT_EQUAL(senderResource[1], stanzaChannel_->getStanzaAtIndex<Message>(4)->getTo());
- CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(4)->getPayload<DeliveryReceiptRequest>());
- }
-
- void testChatControllerFullJIDBindingOnTypingAndNotActive() {
- JID ownJID("test@test.com/resource");
- JID sender("foo@test.com");
- std::vector<JID> senderResource;
- senderResource.push_back(sender.withResource("resourceA"));
- senderResource.push_back(sender.withResource("resourceB"));
-
- // We support delivery receipts.
- settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true);
-
- // Open chat window to a sender.
- MockChatWindow* window = new MockChatWindow();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(sender, uiEventStream_).Return(window);
-
- uiEventStream_->send(boost::make_shared<RequestChatUIEvent>(sender));
-
- foreach(const JID& senderJID, senderResource) {
- // The sender supports delivery receipts.
- DiscoInfo::ref disco = boost::make_shared<DiscoInfo>();
- disco->addFeature(DiscoInfo::MessageDeliveryReceiptsFeature);
- entityCapsProvider_->caps[senderJID] = disco;
-
- // The sender is online.
- Presence::ref senderPresence = boost::make_shared<Presence>();
- senderPresence->setFrom(senderJID);
- senderPresence->setTo(ownJID);
- stanzaChannel_->onPresenceReceived(senderPresence);
-
- entityCapsProvider_->onCapsChanged(senderJID);
- }
-
- // Send first message.
- window->onSendMessageRequest("hello there", false);
-
- // A bare message is send because no resources is bound.
- CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(0)->getTo());
- CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(0)->getPayload<DeliveryReceiptRequest>());
-
- // Two resources respond with message receipts.
- foreach(const JID& senderJID, senderResource) {
- Message::ref reply = boost::make_shared<Message>();
- reply->setFrom(senderJID);
- reply->setTo(ownJID);
-
- boost::shared_ptr<ChatState> csn = boost::make_shared<ChatState>();
- csn->setChatState(ChatState::Active);
- reply->addPayload(csn);
- manager_->handleIncomingMessage(reply);
- }
-
- // Send second message.
- window->onSendMessageRequest("how are you?", false);
-
- // A bare message is send because no resources is bound.
- CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(1)->getTo());
- CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(1)->getPayload<DeliveryReceiptRequest>());
-
- // Two resources respond with message receipts.
- foreach(const JID& senderJID, senderResource) {
- Message::ref receiptReply = boost::make_shared<Message>();
- receiptReply->setFrom(senderJID);
- receiptReply->setTo(ownJID);
-
- boost::shared_ptr<DeliveryReceipt> receipt = boost::make_shared<DeliveryReceipt>();
- receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(1)->getID());
- receiptReply->addPayload(receipt);
- manager_->handleIncomingMessage(receiptReply);
- }
-
- // Reply with a message including a CSN.
- Message::ref reply = boost::make_shared<Message>();
- reply->setFrom(senderResource[0]);
- reply->setTo(ownJID);
-
- boost::shared_ptr<ChatState> csn = boost::make_shared<ChatState>();
- csn->setChatState(ChatState::Composing);
- reply->addPayload(csn);
- manager_->handleIncomingMessage(reply);
-
- // Send third message.
- window->onSendMessageRequest("great to hear.", false);
-
- // The chat session is now bound to the full JID of the first resource due to its recent composing message.
- CPPUNIT_ASSERT_EQUAL(senderResource[0], stanzaChannel_->getStanzaAtIndex<Message>(2)->getTo());
- CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(2)->getPayload<DeliveryReceiptRequest>());
-
- // Reply with a message including a CSN from the other resource.
- reply = boost::make_shared<Message>();
- reply->setFrom(senderResource[1]);
- reply->setTo(ownJID);
-
- csn = boost::make_shared<ChatState>();
- csn->setChatState(ChatState::Composing);
- reply->addPayload(csn);
- manager_->handleIncomingMessage(reply);
-
- // Send third message.
- window->onSendMessageRequest("ping.", false);
-
- // The chat session is now bound to the full JID of the second resource due to its recent composing message.
- CPPUNIT_ASSERT_EQUAL(senderResource[1], stanzaChannel_->getStanzaAtIndex<Message>(3)->getTo());
- CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(3)->getPayload<DeliveryReceiptRequest>());
- }
-
- void testChatControllerPMPresenceHandling() {
- JID participantA = JID("test@rooms.test.com/participantA");
- JID participantB = JID("test@rooms.test.com/participantB");
-
- mucRegistry_->addMUC("test@rooms.test.com");
-
- MockChatWindow* window = new MockChatWindow();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(participantA, uiEventStream_).Return(window);
-
- uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(JID(participantA))));
-
- Presence::ref presence = Presence::create();
- presence->setFrom(participantA);
- presence->setShow(StatusShow::Online);
- stanzaChannel_->onPresenceReceived(presence);
- CPPUNIT_ASSERT_EQUAL(std::string("participantA has become available."), MockChatWindow::bodyFromMessage(window->lastAddedPresence_));
-
- presence = Presence::create();
- presence->setFrom(participantB);
- presence->setShow(StatusShow::Away);
- stanzaChannel_->onPresenceReceived(presence);
-
- presence = Presence::create();
- presence->setFrom(participantA);
- presence->setShow(StatusShow::None);
- presence->setType(Presence::Unavailable);
- stanzaChannel_->onPresenceReceived(presence);
- CPPUNIT_ASSERT_EQUAL(std::string("participantA has gone offline."), MockChatWindow::bodyFromMessage(window->lastReplacedMessage_));
- }
-
- void testLocalMUCServiceDiscoveryResetOnDisconnect() {
- JID ownJID("test@test.com/resource");
- JID sender("foo@test.com");
-
- manager_->setOnline(true);
-
- // Open chat window to a sender.
- MockChatWindow* window = new MockChatWindow();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(sender, uiEventStream_).Return(window);
-
- uiEventStream_->send(boost::make_shared<RequestChatUIEvent>(sender));
-
- CPPUNIT_ASSERT_EQUAL(false, window->impromptuMUCSupported_);
-
- boost::shared_ptr<IQ> infoRequest= iqChannel_->iqs_[1];
- boost::shared_ptr<IQ> infoResponse = IQ::createResult(infoRequest->getFrom(), infoRequest->getTo(), infoRequest->getID());
-
- DiscoInfo info;
- info.addIdentity(DiscoInfo::Identity("Shakespearean Chat Service", "conference", "text"));
- info.addFeature("http://jabber.org/protocol/muc");
- infoResponse->addPayload(boost::make_shared<DiscoInfo>(info));
- iqChannel_->onIQReceived(infoResponse);
-
- CPPUNIT_ASSERT_EQUAL(true, window->impromptuMUCSupported_);
- manager_->setOnline(false);
- CPPUNIT_ASSERT_EQUAL(false, window->impromptuMUCSupported_);
- }
-
- void testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::Subscription from, RosterItemPayload::Subscription to) {
- JID messageJID("testling@test.com/resource1");
- xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), from);
-
- MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
- settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true);
-
- boost::shared_ptr<Message> message = makeDeliveryReceiptTestMessage(messageJID, "1");
- manager_->handleIncomingMessage(message);
-
- CPPUNIT_ASSERT_EQUAL(st(0), stanzaChannel_->sentStanzas.size());
-
- xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), to);
- message->setID("2");
- manager_->handleIncomingMessage(message);
-
- CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->sentStanzas.size());
- Stanza::ref stanzaContactOnRoster = stanzaChannel_->getStanzaAtIndex<Stanza>(0);
- CPPUNIT_ASSERT(stanzaContactOnRoster->getPayload<DeliveryReceipt>() != 0);
- }
+ void setUp() {
+ mocks_ = new MockRepository();
+ jid_ = JID("test@test.com/resource");
+ stanzaChannel_ = new DummyStanzaChannel();
+ iqRouter_ = new IQRouter(stanzaChannel_);
+ eventController_ = new EventController();
+ chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>();
+ joinMUCWindowFactory_ = mocks_->InterfaceMock<JoinMUCWindowFactory>();
+ xmppRoster_ = new XMPPRosterImpl();
+ mucRegistry_ = new MUCRegistry();
+ nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, nullptr, mucRegistry_);
+ presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_);
+ serverDiscoInfo_ = std::make_shared<DiscoInfo>();
+ presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_);
+ directedPresenceSender_ = new DirectedPresenceSender(presenceSender_);
+ mucManager_ = new MUCManager(stanzaChannel_, iqRouter_, directedPresenceSender_, mucRegistry_);
+ uiEventStream_ = new UIEventStream();
+ entityCapsProvider_ = new DummyEntityCapsProvider();
+ chatListWindowFactory_ = mocks_->InterfaceMock<ChatListWindowFactory>();
+ mucSearchWindowFactory_ = mocks_->InterfaceMock<MUCSearchWindowFactory>();
+ settings_ = new DummySettingsProvider();
+ profileSettings_ = new ProfileSettingsProvider("a", settings_);
+ chatListWindow_ = new MockChatListWindow();
+ ftManager_ = new DummyFileTransferManager();
+ ftOverview_ = new FileTransferOverview(ftManager_);
+ avatarManager_ = new NullAvatarManager();
+ wbSessionManager_ = new WhiteboardSessionManager(iqRouter_, stanzaChannel_, presenceOracle_, entityCapsProvider_);
+ wbManager_ = new WhiteboardManager(whiteboardWindowFactory_, uiEventStream_, nickResolver_, wbSessionManager_);
+ highlightManager_ = new HighlightManager(settings_);
+ highlightManager_->resetToDefaultRulesList();
+ handledHighlightActions_ = 0;
+ soundsPlayed_.clear();
+ highlightManager_->onHighlight.connect(boost::bind(&ChatsManagerTest::handleHighlightAction, this, _1));
+
+ crypto_ = PlatformCryptoProvider::create();
+ vcardStorage_ = new VCardMemoryStorage(crypto_);
+ vcardManager_ = new VCardManager(jid_, iqRouter_, vcardStorage_);
+ mocks_->ExpectCall(chatListWindowFactory_, ChatListWindowFactory::createChatListWindow).With(uiEventStream_).Return(chatListWindow_);
+ clientBlockListManager_ = new ClientBlockListManager(iqRouter_);
+ manager_ = new ChatsManager(jid_, stanzaChannel_, iqRouter_, eventController_, chatWindowFactory_, joinMUCWindowFactory_, nickResolver_, presenceOracle_, directedPresenceSender_, uiEventStream_, chatListWindowFactory_, true, nullptr, mucRegistry_, entityCapsProvider_, mucManager_, mucSearchWindowFactory_, profileSettings_, ftOverview_, xmppRoster_, false, settings_, nullptr, wbManager_, highlightManager_, clientBlockListManager_, emoticons_, vcardManager_);
+
+ manager_->setAvatarManager(avatarManager_);
+ }
+
+ void tearDown() {
+ delete highlightManager_;
+ delete profileSettings_;
+ delete avatarManager_;
+ delete manager_;
+ delete clientBlockListManager_;
+ delete vcardManager_;
+ delete vcardStorage_;
+ delete crypto_;
+ delete ftOverview_;
+ delete ftManager_;
+ delete wbSessionManager_;
+ delete wbManager_;
+ delete directedPresenceSender_;
+ delete presenceSender_;
+ delete presenceOracle_;
+ delete nickResolver_;
+ delete mucRegistry_;
+ delete iqRouter_;
+ delete stanzaChannel_;
+ delete eventController_;
+ delete uiEventStream_;
+ delete mucManager_;
+ delete xmppRoster_;
+ delete entityCapsProvider_;
+ delete chatListWindow_;
+ delete mocks_;
+ delete settings_;
+ }
+
+ void testFirstOpenWindowIncoming() {
+ JID messageJID("testling@test.com/resource1");
+
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
+
+ std::shared_ptr<Message> message(new Message());
+ message->setFrom(messageJID);
+ std::string body("This is a legible message. >HEH@)oeueu");
+ message->setBody(body);
+ manager_->handleIncomingMessage(message);
+ CPPUNIT_ASSERT_EQUAL(body, MockChatWindow::bodyFromMessage(window->lastAddedMessage_));
+ }
+
+ void testSecondOpenWindowIncoming() {
+ JID messageJID1("testling@test.com/resource1");
+
+ MockChatWindow* window1 = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID1, uiEventStream_).Return(window1);
+
+ std::shared_ptr<Message> message1(new Message());
+ message1->setFrom(messageJID1);
+ std::string body1("This is a legible message. >HEH@)oeueu");
+ message1->setBody(body1);
+ manager_->handleIncomingMessage(message1);
+ CPPUNIT_ASSERT_EQUAL(body1, MockChatWindow::bodyFromMessage(window1->lastAddedMessage_));
+
+ JID messageJID2("testling@test.com/resource2");
+
+ std::shared_ptr<Message> message2(new Message());
+ message2->setFrom(messageJID2);
+ std::string body2("This is a legible message. .cmaulm.chul");
+ message2->setBody(body2);
+ manager_->handleIncomingMessage(message2);
+ CPPUNIT_ASSERT_EQUAL(body2, MockChatWindow::bodyFromMessage(window1->lastAddedMessage_));
+ }
+
+ void testFirstOpenWindowOutgoing() {
+ std::string messageJIDString("testling@test.com");
+
+ ChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString), uiEventStream_).Return(window);
+
+ uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(messageJIDString)));
+ }
+
+
+ void testFirstOpenWindowBareToFull() {
+ std::string bareJIDString("testling@test.com");
+ std::string fullJIDString("testling@test.com/resource1");
+
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(bareJIDString), uiEventStream_).Return(window);
+ uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(bareJIDString)));
+
+ std::shared_ptr<Message> message(new Message());
+ message->setFrom(JID(fullJIDString));
+ std::string body("This is a legible message. mjuga3089gm8G(*>M)@*(");
+ message->setBody(body);
+ manager_->handleIncomingMessage(message);
+ CPPUNIT_ASSERT_EQUAL(body, MockChatWindow::bodyFromMessage(window->lastAddedMessage_));
+ }
+
+ void testSecondWindow() {
+ std::string messageJIDString1("testling1@test.com");
+ ChatWindow* window1 = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString1), uiEventStream_).Return(window1);
+ uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(messageJIDString1)));
+
+ std::string messageJIDString2("testling2@test.com");
+ ChatWindow* window2 = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString2), uiEventStream_).Return(window2);
+
+ uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(messageJIDString2)));
+ }
+
+ /** Complete cycle.
+ Create unbound window.
+ Bind it.
+ Unbind it.
+ Rebind it.
+ */
+ void testUnbindRebind() {
+ std::string bareJIDString("testling@test.com");
+ std::string fullJIDString1("testling@test.com/resource1");
+ std::string fullJIDString2("testling@test.com/resource2");
+
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(bareJIDString), uiEventStream_).Return(window);
+ uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(bareJIDString)));
+
+ std::shared_ptr<Message> message1(new Message());
+ message1->setFrom(JID(fullJIDString1));
+ std::string messageBody1("This is a legible message.");
+ message1->setBody(messageBody1);
+ manager_->handleIncomingMessage(message1);
+ CPPUNIT_ASSERT_EQUAL(messageBody1, MockChatWindow::bodyFromMessage(window->lastAddedMessage_));
+
+ std::shared_ptr<Presence> jid1Online(new Presence());
+ jid1Online->setFrom(JID(fullJIDString1));
+ std::shared_ptr<Presence> jid1Offline(new Presence());
+ jid1Offline->setFrom(JID(fullJIDString1));
+ jid1Offline->setType(Presence::Unavailable);
+ presenceOracle_->onPresenceChange(jid1Offline);
+
+ std::shared_ptr<Message> message2(new Message());
+ message2->setFrom(JID(fullJIDString2));
+ std::string messageBody2("This is another legible message.");
+ message2->setBody(messageBody2);
+ manager_->handleIncomingMessage(message2);
+ CPPUNIT_ASSERT_EQUAL(messageBody2, MockChatWindow::bodyFromMessage(window->lastAddedMessage_));
+ }
+
+ /**
+ * Test that MUC PMs get opened in the right windows
+ */
+ void testThreeMUCWindows() {
+ JID muc("testling@test.com");
+ ChatWindow* mucWindow = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(muc, uiEventStream_).Return(mucWindow);
+ uiEventStream_->send(std::make_shared<JoinMUCUIEvent>(muc, std::string("nick")));
+
+
+ std::string messageJIDString1("testling@test.com/1");
+ ChatWindow* window1 = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString1), uiEventStream_).Return(window1);
+ uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(messageJIDString1)));
+
+ std::string messageJIDString2("testling@test.com/2");
+ ChatWindow* window2 = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString2), uiEventStream_).Return(window2);
+
+ uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(messageJIDString2)));
+
+ std::string messageJIDString3("testling@test.com/3");
+ ChatWindow* window3 = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(JID(messageJIDString3), uiEventStream_).Return(window3);
+
+ uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(messageJIDString3)));
+
+ /* Refetch an earlier window */
+ /* We do not expect a new window to be created */
+ uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(messageJIDString1)));
+
+ }
+
+ /**
+ Test that a second window isn't unbound where there's already an unbound one.
+ Bind 1
+ Bind 2
+ Unbind 1
+ Unbind 2 (but it doesn't)
+ Sent to bound 2
+ Rebind 1
+ */
+ void testNoDuplicateUnbind() {
+ JID messageJID1("testling@test.com/resource1");
+
+ MockChatWindow* window1 = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID1, uiEventStream_).Return(window1);
+
+ std::shared_ptr<Message> message1(new Message());
+ message1->setFrom(messageJID1);
+ message1->setBody("This is a legible message1.");
+ manager_->handleIncomingMessage(message1);
+
+ JID messageJID2("testling@test.com/resource2");
+
+ std::shared_ptr<Message> message2(new Message());
+ message2->setFrom(messageJID2);
+ message2->setBody("This is a legible message2.");
+ manager_->handleIncomingMessage(message2);
+
+ std::shared_ptr<Presence> jid1Online(new Presence());
+ jid1Online->setFrom(JID(messageJID1));
+ std::shared_ptr<Presence> jid1Offline(new Presence());
+ jid1Offline->setFrom(JID(messageJID1));
+ jid1Offline->setType(Presence::Unavailable);
+ presenceOracle_->onPresenceChange(jid1Offline);
+
+ std::shared_ptr<Presence> jid2Online(new Presence());
+ jid2Online->setFrom(JID(messageJID2));
+ std::shared_ptr<Presence> jid2Offline(new Presence());
+ jid2Offline->setFrom(JID(messageJID2));
+ jid2Offline->setType(Presence::Unavailable);
+ presenceOracle_->onPresenceChange(jid2Offline);
+
+ JID messageJID3("testling@test.com/resource3");
+
+ std::shared_ptr<Message> message3(new Message());
+ message3->setFrom(messageJID3);
+ std::string body3("This is a legible message3.");
+ message3->setBody(body3);
+ manager_->handleIncomingMessage(message3);
+ CPPUNIT_ASSERT_EQUAL(body3, MockChatWindow::bodyFromMessage(window1->lastAddedMessage_));
+
+ std::shared_ptr<Message> message2b(new Message());
+ message2b->setFrom(messageJID2);
+ std::string body2b("This is a legible message2b.");
+ message2b->setBody(body2b);
+ manager_->handleIncomingMessage(message2b);
+ CPPUNIT_ASSERT_EQUAL(body2b, MockChatWindow::bodyFromMessage(window1->lastAddedMessage_));
+ }
+
+ /**
+ * Test that ChatController doesn't send receipts anymore after removal of the contact from the roster.
+ */
+ void testChatControllerPresenceAccessUpdatedOnRemoveFromRoster() {
+ JID messageJID("testling@test.com/resource1");
+ xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), RosterItemPayload::Both);
+
+ MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
+ settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true);
+
+ std::shared_ptr<Message> message = makeDeliveryReceiptTestMessage(messageJID, "1");
+ manager_->handleIncomingMessage(message);
+ Stanza::ref stanzaContactOnRoster = stanzaChannel_->getStanzaAtIndex<Stanza>(1);
+ CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->countSentStanzaOfType<Message>());
+ CPPUNIT_ASSERT(stanzaContactOnRoster->getPayload<DeliveryReceipt>() != nullptr);
+
+ xmppRoster_->removeContact(messageJID);
+
+ message->setID("2");
+ manager_->handleIncomingMessage(message);
+ CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->countSentStanzaOfType<Message>());
+ }
+
+ /**
+ * Test that ChatController sends receipts after the contact has been added to the roster.
+ */
+ void testChatControllerPresenceAccessUpdatedOnAddToRoster() {
+ JID messageJID("testling@test.com/resource1");
+
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
+ settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true);
+
+ std::shared_ptr<Message> message = makeDeliveryReceiptTestMessage(messageJID, "1");
+ manager_->handleIncomingMessage(message);
+
+ CPPUNIT_ASSERT_EQUAL(st(0), stanzaChannel_->countSentStanzaOfType<Message>());
+
+ xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), RosterItemPayload::Both);
+ message->setID("2");
+ manager_->handleIncomingMessage(message);
+
+ CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->countSentStanzaOfType<Message>());
+ Stanza::ref stanzaContactOnRoster = stanzaChannel_->getStanzaAtIndex<Stanza>(1);
+ CPPUNIT_ASSERT(stanzaContactOnRoster->getPayload<DeliveryReceipt>() != nullptr);
+ }
+
+ /**
+ * Test that ChatController sends receipts if requested after change from subscription state To to subscription state Both.
+ */
+ void testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToBoth() {
+ testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::To, RosterItemPayload::Both);
+ }
+
+ /**
+ * Test that ChatController sends receipts if requested after change from subscription state To to subscription state From.
+ */
+ void testChatControllerPresenceAccessUpdatedOnSubscriptionChangeToFrom() {
+ testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::To, RosterItemPayload::From);
+ }
+
+ void testChatControllerFullJIDBindingOnMessageAndNotReceipt() {
+ JID ownJID("test@test.com/resource");
+ JID sender("foo@test.com");
+ std::vector<JID> senderResource;
+ senderResource.push_back(sender.withResource("resourceA"));
+ senderResource.push_back(sender.withResource("resourceB"));
+
+ // We support delivery receipts.
+ settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true);
+
+ // Open chat window to a sender.
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(sender, uiEventStream_).Return(window);
+
+ uiEventStream_->send(std::make_shared<RequestChatUIEvent>(sender));
+
+ for (const auto& senderJID : senderResource) {
+ // The sender supports delivery receipts.
+ DiscoInfo::ref disco = std::make_shared<DiscoInfo>();
+ disco->addFeature(DiscoInfo::MessageDeliveryReceiptsFeature);
+ entityCapsProvider_->caps[senderJID] = disco;
+
+ // The sender is online.
+ Presence::ref senderPresence = std::make_shared<Presence>();
+ senderPresence->setFrom(senderJID);
+ senderPresence->setTo(ownJID);
+ stanzaChannel_->onPresenceReceived(senderPresence);
+
+ entityCapsProvider_->onCapsChanged(senderJID);
+ }
+
+ // Send first message.
+ window->onSendMessageRequest("hello there", false);
+
+ // A bare message is send because no resources is bound.
+ CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(1)->getTo());
+ CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(1)->getPayload<DeliveryReceiptRequest>());
+
+ // Two resources respond with message receipts.
+ for (const auto& senderJID : senderResource) {
+ Message::ref receiptReply = std::make_shared<Message>();
+ receiptReply->setFrom(senderJID);
+ receiptReply->setTo(ownJID);
+
+ std::shared_ptr<DeliveryReceipt> receipt = std::make_shared<DeliveryReceipt>();
+ receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(1)->getID());
+ receiptReply->addPayload(receipt);
+ manager_->handleIncomingMessage(receiptReply);
+ }
+
+ // Send second message.
+ window->onSendMessageRequest("how are you?", false);
+
+ // A bare message is send because no resources is bound.
+ CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(1)->getTo());
+ CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(1)->getPayload<DeliveryReceiptRequest>());
+
+ // Two resources respond with message receipts.
+ for (const auto& senderJID : senderResource) {
+ Message::ref receiptReply = std::make_shared<Message>();
+ receiptReply->setFrom(senderJID);
+ receiptReply->setTo(ownJID);
+
+ std::shared_ptr<DeliveryReceipt> receipt = std::make_shared<DeliveryReceipt>();
+ receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(1)->getID());
+ receiptReply->addPayload(receipt);
+ manager_->handleIncomingMessage(receiptReply);
+ }
+
+ // Reply with a message including a body text.
+ Message::ref reply = std::make_shared<Message>();
+ reply->setFrom(senderResource[0]);
+ reply->setTo(ownJID);
+ reply->setBody("fine.");
+ manager_->handleIncomingMessage(reply);
+
+ // Send third message.
+ window->onSendMessageRequest("great to hear.", false);
+
+ // The chat session is bound to the full JID of the first resource.
+ CPPUNIT_ASSERT_EQUAL(senderResource[0], stanzaChannel_->getStanzaAtIndex<Message>(3)->getTo());
+ CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(2)->getPayload<DeliveryReceiptRequest>());
+
+ // Receive random receipt from second sender resource.
+ reply = std::make_shared<Message>();
+ reply->setFrom(senderResource[1]);
+ reply->setTo(ownJID);
+
+ std::shared_ptr<DeliveryReceipt> receipt = std::make_shared<DeliveryReceipt>();
+ receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(2)->getID());
+ reply->addPayload(receipt);
+ manager_->handleIncomingMessage(reply);
+
+ // Send forth message.
+ window->onSendMessageRequest("what else is new?", false);
+
+ // The chat session is bound to the full JID of the first resource.
+ CPPUNIT_ASSERT_EQUAL(senderResource[0], stanzaChannel_->getStanzaAtIndex<Message>(3)->getTo());
+ CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(3)->getPayload<DeliveryReceiptRequest>());
+
+ // Reply with a message including a body text from second resource.
+ reply = std::make_shared<Message>();
+ reply->setFrom(senderResource[1]);
+ reply->setTo(ownJID);
+ reply->setBody("nothing.");
+ manager_->handleIncomingMessage(reply);
+
+ // Send fifth message.
+ window->onSendMessageRequest("okay", false);
+
+ // The chat session is now bound to the full JID of the second resource.
+ CPPUNIT_ASSERT_EQUAL(senderResource[1], stanzaChannel_->getStanzaAtIndex<Message>(5)->getTo());
+ CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(5)->getPayload<DeliveryReceiptRequest>());
+ }
+
+ void testChatControllerFullJIDBindingOnTypingAndNotActive() {
+ JID ownJID("test@test.com/resource");
+ JID sender("foo@test.com");
+ std::vector<JID> senderResource;
+ senderResource.push_back(sender.withResource("resourceA"));
+ senderResource.push_back(sender.withResource("resourceB"));
+
+ // We support delivery receipts.
+ settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true);
+
+ // Open chat window to a sender.
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(sender, uiEventStream_).Return(window);
+
+ uiEventStream_->send(std::make_shared<RequestChatUIEvent>(sender));
+
+ for (const auto& senderJID : senderResource) {
+ // The sender supports delivery receipts.
+ DiscoInfo::ref disco = std::make_shared<DiscoInfo>();
+ disco->addFeature(DiscoInfo::MessageDeliveryReceiptsFeature);
+ entityCapsProvider_->caps[senderJID] = disco;
+
+ // The sender is online.
+ Presence::ref senderPresence = std::make_shared<Presence>();
+ senderPresence->setFrom(senderJID);
+ senderPresence->setTo(ownJID);
+ stanzaChannel_->onPresenceReceived(senderPresence);
+
+ entityCapsProvider_->onCapsChanged(senderJID);
+ }
+
+ // Send first message.
+ window->onSendMessageRequest("hello there", false);
+
+ // A bare message is send because no resources is bound.
+ CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(1)->getTo());
+ CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(1)->getPayload<DeliveryReceiptRequest>());
+
+ // Two resources respond with message receipts.
+ for (const auto& senderJID : senderResource) {
+ Message::ref reply = std::make_shared<Message>();
+ reply->setFrom(senderJID);
+ reply->setTo(ownJID);
+
+ std::shared_ptr<ChatState> csn = std::make_shared<ChatState>();
+ csn->setChatState(ChatState::Active);
+ reply->addPayload(csn);
+ manager_->handleIncomingMessage(reply);
+ }
+
+ // Send second message.
+ window->onSendMessageRequest("how are you?", false);
+
+ // A bare message is send because no resources is bound.
+ CPPUNIT_ASSERT_EQUAL(sender, stanzaChannel_->getStanzaAtIndex<Message>(1)->getTo());
+ CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(1)->getPayload<DeliveryReceiptRequest>());
+
+ // Two resources respond with message receipts.
+ for (const auto& senderJID : senderResource) {
+ Message::ref receiptReply = std::make_shared<Message>();
+ receiptReply->setFrom(senderJID);
+ receiptReply->setTo(ownJID);
+
+ std::shared_ptr<DeliveryReceipt> receipt = std::make_shared<DeliveryReceipt>();
+ receipt->setReceivedID(stanzaChannel_->getStanzaAtIndex<Message>(1)->getID());
+ receiptReply->addPayload(receipt);
+ manager_->handleIncomingMessage(receiptReply);
+ }
+
+ // Reply with a message including a CSN.
+ Message::ref reply = std::make_shared<Message>();
+ reply->setFrom(senderResource[0]);
+ reply->setTo(ownJID);
+
+ std::shared_ptr<ChatState> csn = std::make_shared<ChatState>();
+ csn->setChatState(ChatState::Composing);
+ reply->addPayload(csn);
+ manager_->handleIncomingMessage(reply);
+
+ // Send third message.
+ window->onSendMessageRequest("great to hear.", false);
+
+ // The chat session is now bound to the full JID of the first resource due to its recent composing message.
+ CPPUNIT_ASSERT_EQUAL(senderResource[0], stanzaChannel_->getStanzaAtIndex<Message>(3)->getTo());
+ CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(3)->getPayload<DeliveryReceiptRequest>());
+
+ // Reply with a message including a CSN from the other resource.
+ reply = std::make_shared<Message>();
+ reply->setFrom(senderResource[1]);
+ reply->setTo(ownJID);
+
+ csn = std::make_shared<ChatState>();
+ csn->setChatState(ChatState::Composing);
+ reply->addPayload(csn);
+ manager_->handleIncomingMessage(reply);
+
+ // Send third message.
+ window->onSendMessageRequest("ping.", false);
+
+ // The chat session is now bound to the full JID of the second resource due to its recent composing message.
+ CPPUNIT_ASSERT_EQUAL(senderResource[1], stanzaChannel_->getStanzaAtIndex<Message>(4)->getTo());
+ CPPUNIT_ASSERT(stanzaChannel_->getStanzaAtIndex<Message>(4)->getPayload<DeliveryReceiptRequest>());
+ }
+
+ void testChatControllerPMPresenceHandling() {
+ JID participantA = JID("test@rooms.test.com/participantA");
+ JID participantB = JID("test@rooms.test.com/participantB");
+
+ mucRegistry_->addMUC("test@rooms.test.com");
+
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(participantA, uiEventStream_).Return(window);
+
+ uiEventStream_->send(std::make_shared<RequestChatUIEvent>(JID(participantA)));
+
+ Presence::ref presence = Presence::create();
+ presence->setFrom(participantA);
+ presence->setShow(StatusShow::Online);
+ stanzaChannel_->onPresenceReceived(presence);
+ CPPUNIT_ASSERT_EQUAL(std::string("participantA has become available."), MockChatWindow::bodyFromMessage(window->lastAddedPresence_));
+
+ presence = Presence::create();
+ presence->setFrom(participantB);
+ presence->setShow(StatusShow::Away);
+ stanzaChannel_->onPresenceReceived(presence);
+
+ presence = Presence::create();
+ presence->setFrom(participantA);
+ presence->setShow(StatusShow::None);
+ presence->setType(Presence::Unavailable);
+ stanzaChannel_->onPresenceReceived(presence);
+ CPPUNIT_ASSERT_EQUAL(std::string("participantA has gone offline."), MockChatWindow::bodyFromMessage(window->lastReplacedMessage_));
+ }
+
+ void testChatControllerMucPmUnavailableErrorHandling() {
+ auto mucJID = JID("test@rooms.test.com");
+ auto participantA = mucJID.withResource("participantA");
+ auto participantB = mucJID.withResource("participantB");
+
+ auto mucWindow = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(mucJID, uiEventStream_).Return(mucWindow);
+ uiEventStream_->send(std::make_shared<JoinMUCUIEvent>(mucJID, participantB.getResource()));
+ CPPUNIT_ASSERT_EQUAL(true, mucWindow->mucType_.is_initialized());
+
+ auto window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(participantA, uiEventStream_).Return(window);
+ uiEventStream_->send(std::make_shared<RequestChatUIEvent>(participantA));
+ CPPUNIT_ASSERT_EQUAL(false, window->mucType_.is_initialized());
+
+ Presence::ref presence = Presence::create();
+ presence->setFrom(participantA);
+ presence->setShow(StatusShow::Online);
+ stanzaChannel_->onPresenceReceived(presence);
+ CPPUNIT_ASSERT_EQUAL(std::string("participantA has become available."), MockChatWindow::bodyFromMessage(window->lastAddedPresence_));
+
+ // send message to participantA
+ auto messageBody = std::string("message body to send");
+ window->onSendMessageRequest(messageBody, false);
+ auto sendMessageStanza = stanzaChannel_->getStanzaAtIndex<Message>(2);
+ CPPUNIT_ASSERT_EQUAL(messageBody, *sendMessageStanza->getBody());
+
+ // receive reply with error
+ auto messageErrorReply = std::make_shared<Message>();
+ messageErrorReply->setID(stanzaChannel_->getNewIQID());
+ messageErrorReply->setType(Message::Error);
+ messageErrorReply->setFrom(participantA);
+ messageErrorReply->setTo(jid_);
+ messageErrorReply->addPayload(std::make_shared<ErrorPayload>(ErrorPayload::ItemNotFound, ErrorPayload::Cancel, "Recipient not in room"));
+
+ auto lastMUCWindowErrorMessageBeforeError = MockChatWindow::bodyFromMessage(mucWindow->lastAddedErrorMessage_);
+ manager_->handleIncomingMessage(messageErrorReply);
+
+ // assert that error is not routed to MUC window
+ CPPUNIT_ASSERT_EQUAL(lastMUCWindowErrorMessageBeforeError, MockChatWindow::bodyFromMessage(mucWindow->lastAddedErrorMessage_));
+ // assert that error is routed to PM
+ CPPUNIT_ASSERT_EQUAL(std::string("This user could not be found in the room."), MockChatWindow::bodyFromMessage(window->lastAddedErrorMessage_));
+ }
+
+ void testLocalMUCServiceDiscoveryResetOnDisconnect() {
+ JID ownJID("test@test.com/resource");
+ JID sender("foo@test.com");
+
+ manager_->setOnline(true);
+
+ // Open chat window to a sender.
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(sender, uiEventStream_).Return(window);
+
+ uiEventStream_->send(std::make_shared<RequestChatUIEvent>(sender));
+
+ CPPUNIT_ASSERT_EQUAL(false, window->impromptuMUCSupported_);
+
+ std::shared_ptr<IQ> infoRequest = std::dynamic_pointer_cast<IQ>(stanzaChannel_->sentStanzas[1]);
+ std::shared_ptr<IQ> infoResponse = IQ::createResult(infoRequest->getFrom(), infoRequest->getTo(), infoRequest->getID());
+
+ DiscoInfo info;
+ info.addIdentity(DiscoInfo::Identity("Shakespearean Chat Service", "conference", "text"));
+ info.addFeature("http://jabber.org/protocol/muc");
+ infoResponse->addPayload(std::make_shared<DiscoInfo>(info));
+ stanzaChannel_->onIQReceived(infoResponse);
+
+ CPPUNIT_ASSERT_EQUAL(true, window->impromptuMUCSupported_);
+ manager_->setOnline(false);
+ CPPUNIT_ASSERT_EQUAL(false, window->impromptuMUCSupported_);
+ }
+
+ void testhelperChatControllerPresenceAccessUpdatedOnSubscriptionChangeReceiptsAllowed(RosterItemPayload::Subscription from, RosterItemPayload::Subscription to) {
+ JID messageJID("testling@test.com/resource1");
+ xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), from);
+
+ MockChatWindow* window = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
+ settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, true);
+
+ std::shared_ptr<Message> message = makeDeliveryReceiptTestMessage(messageJID, "1");
+ manager_->handleIncomingMessage(message);
+
+ CPPUNIT_ASSERT_EQUAL(st(0), stanzaChannel_->countSentStanzaOfType<Message>());
+
+ xmppRoster_->addContact(messageJID, "foo", std::vector<std::string>(), to);
+ message->setID("2");
+ manager_->handleIncomingMessage(message);
+
+ CPPUNIT_ASSERT_EQUAL(st(1), stanzaChannel_->countSentStanzaOfType<Message>());
+ Stanza::ref stanzaContactOnRoster = stanzaChannel_->getStanzaAtIndex<Stanza>(1);
+ CPPUNIT_ASSERT(stanzaContactOnRoster->getPayload<DeliveryReceipt>() != nullptr);
+ }
+
+ void testChatControllerHighlightingNotificationTesting() {
+ HighlightRule keywordRuleA;
+ keywordRuleA.setMatchChat(true);
+ std::vector<std::string> keywordsA;
+ keywordsA.push_back("Romeo");
+ keywordRuleA.setKeywords(keywordsA);
+ keywordRuleA.getAction().setTextColor("yellow");
+ keywordRuleA.getAction().setPlaySound(true);
+ highlightManager_->insertRule(0, keywordRuleA);
+
+ HighlightRule keywordRuleB;
+ keywordRuleB.setMatchChat(true);
+ std::vector<std::string> keywordsB;
+ keywordsB.push_back("Juliet");
+ keywordRuleB.setKeywords(keywordsB);
+ keywordRuleB.getAction().setTextColor("green");
+ keywordRuleB.getAction().setPlaySound(true);
+ keywordRuleB.getAction().setSoundFile("/tmp/someotherfile.wav");
+ highlightManager_->insertRule(0, keywordRuleB);
+
+ JID messageJID = JID("testling@test.com");
+
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
+
+ std::shared_ptr<Message> message(new Message());
+ message->setFrom(messageJID);
+ std::string body("This message should cause two sounds: Juliet and Romeo.");
+ message->setBody(body);
+ manager_->handleIncomingMessage(message);
+
+ CPPUNIT_ASSERT_EQUAL(2, handledHighlightActions_);
+ CPPUNIT_ASSERT(soundsPlayed_.find(keywordRuleA.getAction().getSoundFile()) != soundsPlayed_.end());
+ CPPUNIT_ASSERT(soundsPlayed_.find(keywordRuleB.getAction().getSoundFile()) != soundsPlayed_.end());
+ }
+
+ void testChatControllerHighlightingNotificationDeduplicateSounds() {
+ HighlightRule keywordRuleA;
+ keywordRuleA.setMatchChat(true);
+ std::vector<std::string> keywordsA;
+ keywordsA.push_back("Romeo");
+ keywordRuleA.setKeywords(keywordsA);
+ keywordRuleA.getAction().setTextColor("yellow");
+ keywordRuleA.getAction().setPlaySound(true);
+ highlightManager_->insertRule(0, keywordRuleA);
+
+ HighlightRule keywordRuleB;
+ keywordRuleB.setMatchChat(true);
+ std::vector<std::string> keywordsB;
+ keywordsB.push_back("Juliet");
+ keywordRuleB.setKeywords(keywordsB);
+ keywordRuleB.getAction().setTextColor("green");
+ keywordRuleB.getAction().setPlaySound(true);
+ highlightManager_->insertRule(0, keywordRuleB);
+
+ JID messageJID = JID("testling@test.com");
+
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
+
+ std::shared_ptr<Message> message(new Message());
+ message->setFrom(messageJID);
+ std::string body("This message should cause one sound, because both actions have the same sound: Juliet and Romeo.");
+ message->setBody(body);
+ manager_->handleIncomingMessage(message);
+
+ CPPUNIT_ASSERT_EQUAL(1, handledHighlightActions_);
+ CPPUNIT_ASSERT(soundsPlayed_.find(keywordRuleA.getAction().getSoundFile()) != soundsPlayed_.end());
+ CPPUNIT_ASSERT(soundsPlayed_.find(keywordRuleB.getAction().getSoundFile()) != soundsPlayed_.end());
+ }
+
+ void testChatControllerMeMessageHandling() {
+ JID messageJID("testling@test.com/resource1");
+
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
+
+ std::shared_ptr<Message> message(new Message());
+ message->setFrom(messageJID);
+ std::string body("/me is feeling delighted.");
+ message->setBody(body);
+ manager_->handleIncomingMessage(message);
+ CPPUNIT_ASSERT_EQUAL(std::string("is feeling delighted."), window->bodyFromMessage(window->lastAddedAction_));
+ }
+
+ void testRestartingMUCComponentCrash() {
+ JID mucJID = JID("teaparty@rooms.wonderland.lit");
+ JID self = JID("girl@wonderland.lit/rabbithole");
+ std::string nick = "aLiCe";
+
+ MockChatWindow* window;
+
+ auto genRemoteMUCPresence = [=]() {
+ auto presence = Presence::create();
+ presence->setFrom(mucJID.withResource(nick));
+ presence->setTo(self);
+ return presence;
+ };
+
+ // User rejoins.
+ window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(mucJID, uiEventStream_).Return(window);
+
+ // Join room
+ {
+ auto joinRoomEvent = std::make_shared<JoinMUCUIEvent>(mucJID, boost::optional<std::string>(), nick);
+ uiEventStream_->send(joinRoomEvent);
+ }
+
+ {
+ auto firstPresence = genRemoteMUCPresence();
+ firstPresence->setType(Presence::Unavailable);
+ auto userPayload = std::make_shared<MUCUserPayload>();
+ userPayload->addItem(MUCItem(MUCOccupant::Owner, MUCOccupant::NoRole));
+ firstPresence->addPayload(userPayload);
+ stanzaChannel_->onPresenceReceived(firstPresence);
+ }
+ CPPUNIT_ASSERT_EQUAL(std::string("Couldn't enter room: Unable to enter this room."), MockChatWindow::bodyFromMessage(window->lastAddedErrorMessage_));
+
+ {
+ auto presence = genRemoteMUCPresence();
+ presence->setType(Presence::Unavailable);
+ auto userPayload = std::make_shared<MUCUserPayload>();
+ userPayload->addStatusCode(303);
+ auto item = MUCItem(MUCOccupant::Owner, self, MUCOccupant::Moderator);
+ item.nick = nick;
+ userPayload->addItem(item);
+ userPayload->addStatusCode(110);
+ presence->addPayload(userPayload);
+ stanzaChannel_->onPresenceReceived(presence);
+ }
+ }
+
+ void testChatControllerMeMessageHandlingInMUC() {
+ JID mucJID("mucroom@rooms.test.com");
+ std::string nickname = "toodles";
+
+ // add highlight rule for 'foo'
+ HighlightRule fooHighlight;
+ fooHighlight.setKeywords({"foo"});
+ fooHighlight.setMatchMUC(true);
+ fooHighlight.getAction().setTextBackground("green");
+ highlightManager_->insertRule(0, fooHighlight);
+
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(mucJID, uiEventStream_).Return(window);
+
+ uiEventStream_->send(std::make_shared<JoinMUCUIEvent>(mucJID, boost::optional<std::string>(), nickname));
+
+ auto genRemoteMUCPresence = [=]() {
+ auto presence = Presence::create();
+ presence->setFrom(mucJID.withResource(nickname));
+ presence->setTo(jid_);
+ return presence;
+ };
+
+ {
+ auto presence = genRemoteMUCPresence();
+ auto userPayload = std::make_shared<MUCUserPayload>();
+ userPayload->addStatusCode(110);
+ userPayload->addItem(MUCItem(MUCOccupant::Owner, jid_, MUCOccupant::Moderator));
+ presence->addPayload(userPayload);
+ stanzaChannel_->onPresenceReceived(presence);
+ }
+
+ {
+ auto presence = genRemoteMUCPresence();
+ presence->setFrom(mucJID.withResource("someDifferentNickname"));
+ auto userPayload = std::make_shared<MUCUserPayload>();
+ userPayload->addItem(MUCItem(MUCOccupant::Member, JID("foo@bar.com"), MUCOccupant::Moderator));
+ presence->addPayload(userPayload);
+ stanzaChannel_->onPresenceReceived(presence);
+ }
+
+ window->onSendMessageRequest("/me sends a test message with foo", false);
+
+ window->resetLastMessages();
+ {
+ Message::ref mucMirrored = std::make_shared<Message>();
+ mucMirrored->setFrom(mucJID.withResource(nickname));
+ mucMirrored->setTo(jid_);
+ mucMirrored->setType(Message::Groupchat);
+ mucMirrored->setBody("/me sends a test message with foo");
+ manager_->handleIncomingMessage(mucMirrored);
+ }
+ CPPUNIT_ASSERT_EQUAL(std::string("sends a test message with foo"), window->bodyFromMessage(window->lastAddedAction_));
+
+ window->resetLastMessages();
+ {
+ Message::ref mucMirrored = std::make_shared<Message>();
+ mucMirrored->setFrom(mucJID.withResource("someDifferentNickname"));
+ mucMirrored->setTo(jid_);
+ mucMirrored->setType(Message::Groupchat);
+ mucMirrored->setBody("/me says hello with a test message with foo and foo");
+ manager_->handleIncomingMessage(mucMirrored);
+ }
+ CPPUNIT_ASSERT_EQUAL(std::string("says hello with a test message with foo and foo"), window->bodyFromMessage(window->lastAddedAction_));
+ }
+
+ void testPresenceChangeDoesNotReplaceMUCInvite() {
+ JID messageJID("testling@test.com/resource1");
+
+ auto generateIncomingPresence = [=](Presence::Type type) {
+ auto presence = std::make_shared<Presence>();
+ presence->setType(type);
+ presence->setFrom(messageJID);
+ presence->setTo(jid_);
+ return presence;
+ };
+
+ stanzaChannel_->onPresenceReceived(generateIncomingPresence(Presence::Available));
+
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
+
+ std::shared_ptr<Message> message(new Message());
+ message->setFrom(messageJID);
+ std::string body("This is a legible message. >HEH@)oeueu");
+ message->setBody(body);
+ manager_->handleIncomingMessage(message);
+ CPPUNIT_ASSERT_EQUAL(body, MockChatWindow::bodyFromMessage(window->lastAddedMessage_));
+
+ auto incomingMUCInvite = std::make_shared<Message>();
+ incomingMUCInvite->setFrom(messageJID);
+
+ auto invitePayload = std::make_shared<MUCInvitationPayload>();
+ invitePayload->setJID("room@muc.service.com");
+ incomingMUCInvite->addPayload(invitePayload);
+
+ stanzaChannel_->onPresenceReceived(generateIncomingPresence(Presence::Unavailable));
+ stanzaChannel_->onPresenceReceived(generateIncomingPresence(Presence::Available));
+
+ window->resetLastMessages();
+
+ manager_->handleIncomingMessage(incomingMUCInvite);
+ CPPUNIT_ASSERT_EQUAL(JID("room@muc.service.com"), window->lastMUCInvitationJID_);
+
+ stanzaChannel_->onPresenceReceived(generateIncomingPresence(Presence::Unavailable));
+ CPPUNIT_ASSERT_EQUAL(std::string(""), MockChatWindow::bodyFromMessage(window->lastReplacedMessage_));
+ CPPUNIT_ASSERT_EQUAL(std::string("testling@test.com has gone offline."), MockChatWindow::bodyFromMessage(window->lastAddedPresence_));
+ }
+
+ template <typename CarbonsType>
+ Message::ref createCarbonsMessage(std::shared_ptr<CarbonsType> carbons, std::shared_ptr<Message> forwardedMessage) {
+ auto messageWrapper = std::make_shared<Message>();
+ messageWrapper->setFrom(jid_.toBare());
+ messageWrapper->setTo(jid_);
+ messageWrapper->setType(Message::Chat);
+
+ messageWrapper->addPayload(carbons);
+ auto forwarded = std::make_shared<Forwarded>();
+ carbons->setForwarded(forwarded);
+ forwarded->setStanza(forwardedMessage);
+ return messageWrapper;
+ }
+
+ void testCarbonsForwardedIncomingMessageToSecondResource() {
+ JID messageJID("testling@test.com/resource1");
+ JID jid2 = jid_.toBare().withResource("someOtherResource");
+
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
+
+ std::shared_ptr<Message> message(new Message());
+ message->setFrom(messageJID);
+ std::string body("This is a legible message. >HEH@)oeueu");
+ message->setBody(body);
+ manager_->handleIncomingMessage(message);
+ CPPUNIT_ASSERT_EQUAL(body, MockChatWindow::bodyFromMessage(window->lastAddedMessage_));
+
+ // incoming carbons message from another resource
+ {
+ auto originalMessage = std::make_shared<Message>();
+ originalMessage->setFrom(messageJID);
+ originalMessage->setTo(jid2);
+ originalMessage->setType(Message::Chat);
+ std::string forwardedBody = "Some further text.";
+ originalMessage->setBody(forwardedBody);
+
+ auto messageWrapper = createCarbonsMessage(std::make_shared<CarbonsReceived>(), originalMessage);
+
+ manager_->handleIncomingMessage(messageWrapper);
+
+ CPPUNIT_ASSERT_EQUAL(forwardedBody, MockChatWindow::bodyFromMessage(window->lastAddedMessage_));
+ CPPUNIT_ASSERT_EQUAL(false, window->lastAddedMessageSenderIsSelf_);
+ }
+ }
+
+ void testCarbonsForwardedOutgoingMessageFromSecondResource() {
+ JID messageJID("testling@test.com/resource1");
+ JID jid2 = jid_.toBare().withResource("someOtherResource");
+
+ MockChatWindow* window = new MockChatWindow();
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(messageJID, uiEventStream_).Return(window);
+
+ std::shared_ptr<Message> message(new Message());
+ message->setFrom(messageJID);
+ std::string body("This is a legible message. >HEH@)oeueu");
+ message->setBody(body);
+ manager_->handleIncomingMessage(message);
+ CPPUNIT_ASSERT_EQUAL(body, MockChatWindow::bodyFromMessage(window->lastAddedMessage_));
+
+ // incoming carbons message from another resource
+ {
+ auto originalMessage = std::make_shared<Message>();
+ originalMessage->setFrom(jid2);
+ originalMessage->setTo(messageJID);
+ originalMessage->setType(Message::Chat);
+ originalMessage->setID("abcdefg123456");
+ std::string forwardedBody = "Some text my other resource sent.";
+ originalMessage->setBody(forwardedBody);
+ originalMessage->addPayload(std::make_shared<DeliveryReceiptRequest>());
+
+ auto messageWrapper = createCarbonsMessage(std::make_shared<CarbonsSent>(), originalMessage);
+
+ manager_->handleIncomingMessage(messageWrapper);
+
+ CPPUNIT_ASSERT_EQUAL(forwardedBody, MockChatWindow::bodyFromMessage(window->lastAddedMessage_));
+ CPPUNIT_ASSERT_EQUAL(true, window->lastAddedMessageSenderIsSelf_);
+ CPPUNIT_ASSERT_EQUAL(size_t(1), window->receiptChanges_.size());
+ CPPUNIT_ASSERT_EQUAL(ChatWindow::ReceiptRequested, window->receiptChanges_[0].second);
+ }
+
+ // incoming carbons message for the received delivery receipt to the other resource
+ {
+ auto originalMessage = std::make_shared<Message>();
+ originalMessage->setFrom(messageJID);
+ originalMessage->setTo(jid2);
+ originalMessage->setType(Message::Chat);
+ originalMessage->addPayload(std::make_shared<DeliveryReceipt>("abcdefg123456"));
+
+ auto messageWrapper = createCarbonsMessage(std::make_shared<CarbonsReceived>(), originalMessage);
+
+ manager_->handleIncomingMessage(messageWrapper);
+
+ CPPUNIT_ASSERT_EQUAL(size_t(2), window->receiptChanges_.size());
+ CPPUNIT_ASSERT_EQUAL(ChatWindow::ReceiptReceived, window->receiptChanges_[1].second);
+ }
+ }
private:
- boost::shared_ptr<Message> makeDeliveryReceiptTestMessage(const JID& from, const std::string& id) {
- boost::shared_ptr<Message> message = boost::make_shared<Message>();
- message->setFrom(from);
- message->setID(id);
- message->setBody("This will cause the window to open");
- message->addPayload(boost::make_shared<DeliveryReceiptRequest>());
- return message;
- }
-
- size_t st(int i) {
- return static_cast<size_t>(i);
- }
+ std::shared_ptr<Message> makeDeliveryReceiptTestMessage(const JID& from, const std::string& id) {
+ std::shared_ptr<Message> message = std::make_shared<Message>();
+ message->setFrom(from);
+ message->setID(id);
+ message->setBody("This will cause the window to open");
+ message->addPayload(std::make_shared<DeliveryReceiptRequest>());
+ return message;
+ }
+
+ size_t st(int i) {
+ return static_cast<size_t>(i);
+ }
+
+ void handleHighlightAction(const HighlightAction& action) {
+ handledHighlightActions_++;
+ if (action.playSound()) {
+ soundsPlayed_.insert(action.getSoundFile());
+ }
+ }
private:
- JID jid_;
- ChatsManager* manager_;
- DummyStanzaChannel* stanzaChannel_;
- DummyIQChannel* iqChannel_;
- IQRouter* iqRouter_;
- EventController* eventController_;
- ChatWindowFactory* chatWindowFactory_;
- JoinMUCWindowFactory* joinMUCWindowFactory_;
- NickResolver* nickResolver_;
- PresenceOracle* presenceOracle_;
- AvatarManager* avatarManager_;
- boost::shared_ptr<DiscoInfo> serverDiscoInfo_;
- XMPPRosterImpl* xmppRoster_;
- PresenceSender* presenceSender_;
- MockRepository* mocks_;
- UIEventStream* uiEventStream_;
- ChatListWindowFactory* chatListWindowFactory_;
- WhiteboardWindowFactory* whiteboardWindowFactory_;
- MUCSearchWindowFactory* mucSearchWindowFactory_;
- MUCRegistry* mucRegistry_;
- DirectedPresenceSender* directedPresenceSender_;
- DummyEntityCapsProvider* entityCapsProvider_;
- MUCManager* mucManager_;
- DummySettingsProvider* settings_;
- ProfileSettingsProvider* profileSettings_;
- ChatListWindow* chatListWindow_;
- FileTransferOverview* ftOverview_;
- FileTransferManager* ftManager_;
- WhiteboardSessionManager* wbSessionManager_;
- WhiteboardManager* wbManager_;
- HighlightManager* highlightManager_;
- ClientBlockListManager* clientBlockListManager_;
- VCardManager* vcardManager_;
- CryptoProvider* crypto_;
- VCardStorage* vcardStorage_;
- std::map<std::string, std::string> emoticons_;
+ JID jid_;
+ ChatsManager* manager_;
+ DummyStanzaChannel* stanzaChannel_;
+ IQRouter* iqRouter_;
+ EventController* eventController_;
+ ChatWindowFactory* chatWindowFactory_;
+ JoinMUCWindowFactory* joinMUCWindowFactory_;
+ NickResolver* nickResolver_;
+ PresenceOracle* presenceOracle_;
+ AvatarManager* avatarManager_;
+ std::shared_ptr<DiscoInfo> serverDiscoInfo_;
+ XMPPRosterImpl* xmppRoster_;
+ PresenceSender* presenceSender_;
+ MockRepository* mocks_;
+ UIEventStream* uiEventStream_;
+ ChatListWindowFactory* chatListWindowFactory_;
+ WhiteboardWindowFactory* whiteboardWindowFactory_;
+ MUCSearchWindowFactory* mucSearchWindowFactory_;
+ MUCRegistry* mucRegistry_;
+ DirectedPresenceSender* directedPresenceSender_;
+ DummyEntityCapsProvider* entityCapsProvider_;
+ MUCManager* mucManager_;
+ DummySettingsProvider* settings_;
+ ProfileSettingsProvider* profileSettings_;
+ ChatListWindow* chatListWindow_;
+ FileTransferOverview* ftOverview_;
+ FileTransferManager* ftManager_;
+ WhiteboardSessionManager* wbSessionManager_;
+ WhiteboardManager* wbManager_;
+ HighlightManager* highlightManager_;
+ ClientBlockListManager* clientBlockListManager_;
+ VCardManager* vcardManager_;
+ CryptoProvider* crypto_;
+ VCardStorage* vcardStorage_;
+ std::map<std::string, std::string> emoticons_;
+ int handledHighlightActions_;
+ std::set<std::string> soundsPlayed_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(ChatsManagerTest);
diff --git a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
index e8fc41d..32639f6 100644
--- a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
+++ b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp
@@ -11,7 +11,6 @@
#include <hippomocks.h>
#include <Swiften/Avatars/NullAvatarManager.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Client/ClientBlockListManager.h>
#include <Swiften/Client/DummyStanzaChannel.h>
#include <Swiften/Client/NickResolver.h>
@@ -48,509 +47,508 @@
using namespace Swift;
class MUCControllerTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(MUCControllerTest);
- CPPUNIT_TEST(testJoinPartStringContructionSimple);
- CPPUNIT_TEST(testJoinPartStringContructionMixed);
- CPPUNIT_TEST(testAppendToJoinParts);
- CPPUNIT_TEST(testAddressedToSelf);
- CPPUNIT_TEST(testNotAddressedToSelf);
- CPPUNIT_TEST(testAddressedToSelfBySelf);
- CPPUNIT_TEST(testMessageWithEmptyLabelItem);
- CPPUNIT_TEST(testMessageWithLabelItem);
- CPPUNIT_TEST(testCorrectMessageWithLabelItem);
- CPPUNIT_TEST(testRoleAffiliationStates);
- CPPUNIT_TEST(testSubjectChangeCorrect);
- CPPUNIT_TEST(testSubjectChangeIncorrectA);
- CPPUNIT_TEST(testSubjectChangeIncorrectB);
- CPPUNIT_TEST(testSubjectChangeIncorrectC);
- CPPUNIT_TEST_SUITE_END();
+ CPPUNIT_TEST_SUITE(MUCControllerTest);
+ CPPUNIT_TEST(testJoinPartStringContructionSimple);
+ CPPUNIT_TEST(testJoinPartStringContructionMixed);
+ CPPUNIT_TEST(testAppendToJoinParts);
+ CPPUNIT_TEST(testAddressedToSelf);
+ CPPUNIT_TEST(testNotAddressedToSelf);
+ CPPUNIT_TEST(testAddressedToSelfBySelf);
+ CPPUNIT_TEST(testMessageWithEmptyLabelItem);
+ CPPUNIT_TEST(testMessageWithLabelItem);
+ CPPUNIT_TEST(testCorrectMessageWithLabelItem);
+ CPPUNIT_TEST(testRoleAffiliationStates);
+ CPPUNIT_TEST(testSubjectChangeCorrect);
+ CPPUNIT_TEST(testSubjectChangeIncorrectA);
+ CPPUNIT_TEST(testSubjectChangeIncorrectB);
+ CPPUNIT_TEST(testSubjectChangeIncorrectC);
+ CPPUNIT_TEST_SUITE_END();
public:
- void setUp() {
- crypto_ = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());
- self_ = JID("girl@wonderland.lit/rabbithole");
- nick_ = "aLiCe";
- mucJID_ = JID("teaparty@rooms.wonderland.lit");
- mocks_ = new MockRepository();
- stanzaChannel_ = new DummyStanzaChannel();
- iqChannel_ = new DummyIQChannel();
- iqRouter_ = new IQRouter(iqChannel_);
- eventController_ = new EventController();
- chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>();
- userSearchWindowFactory_ = mocks_->InterfaceMock<UserSearchWindowFactory>();
- xmppRoster_ = new XMPPRosterImpl();
- presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_);
- presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_);
- directedPresenceSender_ = new DirectedPresenceSender(presenceSender_);
- uiEventStream_ = new UIEventStream();
- avatarManager_ = new NullAvatarManager();
- TimerFactory* timerFactory = NULL;
- window_ = new MockChatWindow();
- mucRegistry_ = new MUCRegistry();
- entityCapsProvider_ = new DummyEntityCapsProvider();
- settings_ = new DummySettingsProvider();
- highlightManager_ = new HighlightManager(settings_);
- muc_ = boost::make_shared<MockMUC>(mucJID_);
- mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(muc_->getJID(), uiEventStream_).Return(window_);
- chatMessageParser_ = boost::make_shared<ChatMessageParser>(std::map<std::string, std::string>(), highlightManager_->getRules(), true);
- vcardStorage_ = new VCardMemoryStorage(crypto_.get());
- vcardManager_ = new VCardManager(self_, iqRouter_, vcardStorage_);
- clientBlockListManager_ = new ClientBlockListManager(iqRouter_);
- mucBookmarkManager_ = new MUCBookmarkManager(iqRouter_);
- controller_ = new MUCController (self_, muc_, boost::optional<std::string>(), nick_, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory, eventController_, entityCapsProvider_, NULL, NULL, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser_, false, NULL, vcardManager_, mucBookmarkManager_);
- }
-
- void tearDown() {
- delete controller_;
- delete mucBookmarkManager_;
- delete clientBlockListManager_;
- delete vcardManager_;
- delete vcardStorage_;
- delete highlightManager_;
- delete settings_;
- delete entityCapsProvider_;
- delete eventController_;
- delete presenceOracle_;
- delete xmppRoster_;
- delete mocks_;
- delete uiEventStream_;
- delete stanzaChannel_;
- delete presenceSender_;
- delete directedPresenceSender_;
- delete iqRouter_;
- delete iqChannel_;
- delete mucRegistry_;
- delete avatarManager_;
- }
-
- void finishJoin() {
- Presence::ref presence(new Presence());
- presence->setFrom(JID(muc_->getJID().toString() + "/" + nick_));
- MUCUserPayload::ref status(new MUCUserPayload());
- MUCUserPayload::StatusCode code;
- code.code = 110;
- status->addStatusCode(code);
- presence->addPayload(status);
- stanzaChannel_->onPresenceReceived(presence);
- }
-
- void testAddressedToSelf() {
- finishJoin();
- Message::ref message(new Message());
-
- message = Message::ref(new Message());
- message->setFrom(JID(muc_->getJID().toString() + "/otherperson"));
- message->setBody("basic " + nick_ + " test.");
- message->setType(Message::Groupchat);
- controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
- CPPUNIT_ASSERT_EQUAL((size_t)1, eventController_->getEvents().size());
-
- message = Message::ref(new Message());
- message->setFrom(JID(muc_->getJID().toString() + "/otherperson"));
- message->setBody(nick_ + ": hi there");
- message->setType(Message::Groupchat);
- controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
- CPPUNIT_ASSERT_EQUAL((size_t)2, eventController_->getEvents().size());
-
- message->setFrom(JID(muc_->getJID().toString() + "/other"));
- message->setBody("Hi there " + nick_);
- message->setType(Message::Groupchat);
- controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
- CPPUNIT_ASSERT_EQUAL((size_t)3, eventController_->getEvents().size());
-
- message = Message::ref(new Message());
- message->setFrom(JID(muc_->getJID().toString() + "/other2"));
- message->setBody("Hi " + boost::to_lower_copy(nick_) + ".");
- message->setType(Message::Groupchat);
- controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
- CPPUNIT_ASSERT_EQUAL((size_t)4, eventController_->getEvents().size());
-
- message = Message::ref(new Message());
- message->setFrom(JID(muc_->getJID().toString() + "/other3"));
- message->setBody("Hi bert.");
- message->setType(Message::Groupchat);
- controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
- CPPUNIT_ASSERT_EQUAL((size_t)4, eventController_->getEvents().size());
-
- message = Message::ref(new Message());
- message->setFrom(JID(muc_->getJID().toString() + "/other2"));
- message->setBody("Hi " + boost::to_lower_copy(nick_) + "ie.");
- message->setType(Message::Groupchat);
- controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
- CPPUNIT_ASSERT_EQUAL((size_t)4, eventController_->getEvents().size());
- }
-
- void testNotAddressedToSelf() {
- finishJoin();
- Message::ref message(new Message());
- message->setFrom(JID(muc_->getJID().toString() + "/other3"));
- message->setBody("Hi there Hatter");
- message->setType(Message::Groupchat);
- controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
- CPPUNIT_ASSERT_EQUAL((size_t)0, eventController_->getEvents().size());
- }
-
- void testAddressedToSelfBySelf() {
- finishJoin();
- Message::ref message(new Message());
- message->setFrom(JID(muc_->getJID().toString() + "/" + nick_));
- message->setBody("Hi there " + nick_);
- message->setType(Message::Groupchat);
- controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
- CPPUNIT_ASSERT_EQUAL((size_t)0, eventController_->getEvents().size());
- }
-
- void testMessageWithEmptyLabelItem() {
- SecurityLabelsCatalog::Item label;
- label.setSelector("Bob");
- window_->label_ = label;
- boost::shared_ptr<DiscoInfo> features = boost::make_shared<DiscoInfo>();
- features->addFeature(DiscoInfo::SecurityLabelsCatalogFeature);
- controller_->setAvailableServerFeatures(features);
- IQ::ref iq = iqChannel_->iqs_[iqChannel_->iqs_.size() - 1];
- SecurityLabelsCatalog::ref labelPayload = boost::make_shared<SecurityLabelsCatalog>();
- labelPayload->addItem(label);
- IQ::ref result = IQ::createResult(self_, iq->getID(), labelPayload);
- iqChannel_->onIQReceived(result);
- std::string messageBody("agamemnon");
- window_->onSendMessageRequest(messageBody, false);
- boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
- Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza);
- CPPUNIT_ASSERT_EQUAL(iq->getTo(), result->getFrom());
- CPPUNIT_ASSERT(window_->labelsEnabled_);
- CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
- CPPUNIT_ASSERT(message);
- CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get());
- CPPUNIT_ASSERT(!message->getPayload<SecurityLabel>());
- }
-
- void testMessageWithLabelItem() {
- boost::shared_ptr<SecurityLabel> label = boost::make_shared<SecurityLabel>();
- label->setLabel("a");
- SecurityLabelsCatalog::Item labelItem;
- labelItem.setSelector("Bob");
- labelItem.setLabel(label);
- window_->label_ = labelItem;
- boost::shared_ptr<DiscoInfo> features = boost::make_shared<DiscoInfo>();
- features->addFeature(DiscoInfo::SecurityLabelsCatalogFeature);
- controller_->setAvailableServerFeatures(features);
- IQ::ref iq = iqChannel_->iqs_[iqChannel_->iqs_.size() - 1];
- SecurityLabelsCatalog::ref labelPayload = boost::make_shared<SecurityLabelsCatalog>();
- labelPayload->addItem(labelItem);
- IQ::ref result = IQ::createResult(self_, iq->getID(), labelPayload);
- iqChannel_->onIQReceived(result);
- std::string messageBody("agamemnon");
- window_->onSendMessageRequest(messageBody, false);
- boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
- Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza);
- CPPUNIT_ASSERT_EQUAL(iq->getTo(), result->getFrom());
- CPPUNIT_ASSERT(window_->labelsEnabled_);
- CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
- CPPUNIT_ASSERT(message);
- CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get());
- CPPUNIT_ASSERT_EQUAL(label, message->getPayload<SecurityLabel>());
- }
-
- void testCorrectMessageWithLabelItem() {
- boost::shared_ptr<SecurityLabel> label = boost::make_shared<SecurityLabel>();
- label->setLabel("a");
- SecurityLabelsCatalog::Item labelItem;
- labelItem.setSelector("Bob");
- labelItem.setLabel(label);
- boost::shared_ptr<SecurityLabel> label2 = boost::make_shared<SecurityLabel>();
- label->setLabel("b");
- SecurityLabelsCatalog::Item labelItem2;
- labelItem2.setSelector("Charlie");
- labelItem2.setLabel(label2);
- window_->label_ = labelItem;
- boost::shared_ptr<DiscoInfo> features = boost::make_shared<DiscoInfo>();
- features->addFeature(DiscoInfo::SecurityLabelsCatalogFeature);
- controller_->setAvailableServerFeatures(features);
- IQ::ref iq = iqChannel_->iqs_[iqChannel_->iqs_.size() - 1];
- SecurityLabelsCatalog::ref labelPayload = boost::make_shared<SecurityLabelsCatalog>();
- labelPayload->addItem(labelItem);
- IQ::ref result = IQ::createResult(self_, iq->getID(), labelPayload);
- iqChannel_->onIQReceived(result);
- std::string messageBody("agamemnon");
- window_->onSendMessageRequest(messageBody, false);
- boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
- Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza);
- CPPUNIT_ASSERT_EQUAL(iq->getTo(), result->getFrom());
- CPPUNIT_ASSERT(window_->labelsEnabled_);
- CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
- CPPUNIT_ASSERT(message);
- CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get());
- CPPUNIT_ASSERT_EQUAL(label, message->getPayload<SecurityLabel>());
- window_->label_ = labelItem2;
- window_->onSendMessageRequest(messageBody, true);
- rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
- message = boost::dynamic_pointer_cast<Message>(rawStanza);
- CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get());
- CPPUNIT_ASSERT_EQUAL(label, message->getPayload<SecurityLabel>());
- }
-
- void checkEqual(const std::vector<NickJoinPart>& expected, const std::vector<NickJoinPart>& actual) {
- CPPUNIT_ASSERT_EQUAL(expected.size(), actual.size());
- for (size_t i = 0; i < expected.size(); i++) {
- CPPUNIT_ASSERT_EQUAL(expected[i].nick, actual[i].nick);
- CPPUNIT_ASSERT_EQUAL(expected[i].type, actual[i].type);
- }
- }
-
- void testAppendToJoinParts() {
- std::vector<NickJoinPart> list;
- std::vector<NickJoinPart> gold;
- MUCController::appendToJoinParts(list, NickJoinPart("Kev", Join));
- gold.push_back(NickJoinPart("Kev", Join));
- checkEqual(gold, list);
- MUCController::appendToJoinParts(list, NickJoinPart("Remko", Join));
- gold.push_back(NickJoinPart("Remko", Join));
- checkEqual(gold, list);
- MUCController::appendToJoinParts(list, NickJoinPart("Bert", Join));
- gold.push_back(NickJoinPart("Bert", Join));
- checkEqual(gold, list);
- MUCController::appendToJoinParts(list, NickJoinPart("Bert", Part));
- gold[2].type = JoinThenPart;
- checkEqual(gold, list);
- MUCController::appendToJoinParts(list, NickJoinPart("Kev", Part));
- gold[0].type = JoinThenPart;
- checkEqual(gold, list);
- MUCController::appendToJoinParts(list, NickJoinPart("Remko", Part));
- gold[1].type = JoinThenPart;
- checkEqual(gold, list);
- MUCController::appendToJoinParts(list, NickJoinPart("Ernie", Part));
- gold.push_back(NickJoinPart("Ernie", Part));
- checkEqual(gold, list);
- MUCController::appendToJoinParts(list, NickJoinPart("Ernie", Join));
- gold[3].type = PartThenJoin;
- checkEqual(gold, list);
- MUCController::appendToJoinParts(list, NickJoinPart("Kev", Join));
- gold[0].type = Join;
- checkEqual(gold, list);
- MUCController::appendToJoinParts(list, NickJoinPart("Ernie", Part));
- gold[3].type = Part;
- checkEqual(gold, list);
-
- }
-
- void testJoinPartStringContructionSimple() {
- std::vector<NickJoinPart> list;
- list.push_back(NickJoinPart("Kev", Join));
- CPPUNIT_ASSERT_EQUAL(std::string("Kev has entered the room"), MUCController::generateJoinPartString(list, false));
- list.push_back(NickJoinPart("Remko", Part));
- CPPUNIT_ASSERT_EQUAL(std::string("Kev has entered the room and Remko has left the room"), MUCController::generateJoinPartString(list, false));
- list.push_back(NickJoinPart("Bert", Join));
- CPPUNIT_ASSERT_EQUAL(std::string("Kev and Bert have entered the room and Remko has left the room"), MUCController::generateJoinPartString(list, false));
- list.push_back(NickJoinPart("Ernie", Join));
- CPPUNIT_ASSERT_EQUAL(std::string("Kev, Bert and Ernie have entered the room and Remko has left the room"), MUCController::generateJoinPartString(list, false));
- }
-
- void testJoinPartStringContructionMixed() {
- std::vector<NickJoinPart> list;
- list.push_back(NickJoinPart("Kev", JoinThenPart));
- CPPUNIT_ASSERT_EQUAL(std::string("Kev has entered then left the room"), MUCController::generateJoinPartString(list, false));
- list.push_back(NickJoinPart("Remko", Part));
- CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room and Kev has entered then left the room"), MUCController::generateJoinPartString(list, false));
- list.push_back(NickJoinPart("Bert", PartThenJoin));
- CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room, Kev has entered then left the room and Bert has left then returned to the room"), MUCController::generateJoinPartString(list, false));
- list.push_back(NickJoinPart("Ernie", JoinThenPart));
- CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room, Kev and Ernie have entered then left the room and Bert has left then returned to the room"), MUCController::generateJoinPartString(list, false));
- }
-
- JID jidFromOccupant(const MUCOccupant& occupant) {
- return JID(mucJID_.toString()+"/"+occupant.getNick());
- }
-
- void testRoleAffiliationStates() {
-
- typedef std::map<std::string, MUCOccupant> occupant_map;
- occupant_map occupants;
- occupants.insert(occupant_map::value_type("Kev", MUCOccupant("Kev", MUCOccupant::Participant, MUCOccupant::Owner)));
- occupants.insert(occupant_map::value_type("Remko", MUCOccupant("Remko", MUCOccupant::Participant, MUCOccupant::Owner)));
- occupants.insert(occupant_map::value_type("Bert", MUCOccupant("Bert", MUCOccupant::Participant, MUCOccupant::Owner)));
- occupants.insert(occupant_map::value_type("Ernie", MUCOccupant("Ernie", MUCOccupant::Participant, MUCOccupant::Owner)));
-
- /* populate the MUC with fake users */
- typedef const std::pair<std::string,MUCOccupant> occupantIterator;
- foreach(occupantIterator &occupant, occupants) {
- muc_->insertOccupant(occupant.second);
- }
-
- std::vector<MUCOccupant> alterations;
- alterations.push_back(MUCOccupant("Kev", MUCOccupant::Visitor, MUCOccupant::Admin));
- alterations.push_back(MUCOccupant("Remko", MUCOccupant::Moderator, MUCOccupant::Member));
- alterations.push_back(MUCOccupant("Bert", MUCOccupant::Visitor, MUCOccupant::Outcast));
- alterations.push_back(MUCOccupant("Ernie", MUCOccupant::NoRole, MUCOccupant::Member));
- alterations.push_back(MUCOccupant("Bert", MUCOccupant::Moderator, MUCOccupant::Owner));
- alterations.push_back(MUCOccupant("Kev", MUCOccupant::Participant, MUCOccupant::Outcast));
- alterations.push_back(MUCOccupant("Bert", MUCOccupant::Visitor, MUCOccupant::NoAffiliation));
- alterations.push_back(MUCOccupant("Remko", MUCOccupant::NoRole, MUCOccupant::NoAffiliation));
- alterations.push_back(MUCOccupant("Ernie", MUCOccupant::Visitor, MUCOccupant::Outcast));
-
- foreach(const MUCOccupant& alteration, alterations) {
- /* perform an alteration to a user's role and affiliation */
- occupant_map::iterator occupant = occupants.find(alteration.getNick());
- CPPUNIT_ASSERT(occupant != occupants.end());
- const JID jid = jidFromOccupant(occupant->second);
- /* change the affiliation, leave the role in place */
- muc_->changeAffiliation(jid, alteration.getAffiliation());
- occupant->second = MUCOccupant(occupant->first, occupant->second.getRole(), alteration.getAffiliation());
- testRoleAffiliationStatesVerify(occupants);
- /* change the role, leave the affiliation in place */
- muc_->changeOccupantRole(jid, alteration.getRole());
- occupant->second = MUCOccupant(occupant->first, alteration.getRole(), occupant->second.getAffiliation());
- testRoleAffiliationStatesVerify(occupants);
- }
- }
-
- void testSubjectChangeCorrect() {
- std::string messageBody("test message");
- window_->onSendMessageRequest(messageBody, false);
- boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
- Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza);
- CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
- CPPUNIT_ASSERT(message);
- CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or(""));
-
- {
- Message::ref message = boost::make_shared<Message>();
- message->setType(Message::Groupchat);
- message->setTo(self_);
- message->setFrom(mucJID_.withResource("SomeNickname"));
- message->setID(iqChannel_->getNewIQID());
- message->setSubject("New Room Subject");
-
- controller_->handleIncomingMessage(boost::make_shared<MessageEvent>(message));
- CPPUNIT_ASSERT_EQUAL(std::string("The room subject is now: New Room Subject"), boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(window_->lastAddedSystemMessage_.getParts()[0])->text);
- }
- }
-
- /*
- * Test that message stanzas with subject element and non-empty body element do not cause a subject change.
- */
- void testSubjectChangeIncorrectA() {
- std::string messageBody("test message");
- window_->onSendMessageRequest(messageBody, false);
- boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
- Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza);
- CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
- CPPUNIT_ASSERT(message);
- CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or(""));
-
- {
- Message::ref message = boost::make_shared<Message>();
- message->setType(Message::Groupchat);
- message->setTo(self_);
- message->setFrom(mucJID_.withResource("SomeNickname"));
- message->setID(iqChannel_->getNewIQID());
- message->setSubject("New Room Subject");
- message->setBody("Some body text that prevents this stanza from being a subject change.");
-
- controller_->handleIncomingMessage(boost::make_shared<MessageEvent>(message));
- CPPUNIT_ASSERT_EQUAL(std::string("Trying to enter room teaparty@rooms.wonderland.lit"), boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(window_->lastAddedSystemMessage_.getParts()[0])->text);
- }
- }
-
- /*
- * Test that message stanzas with subject element and thread element do not cause a subject change.
- */
- void testSubjectChangeIncorrectB() {
- std::string messageBody("test message");
- window_->onSendMessageRequest(messageBody, false);
- boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
- Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza);
- CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
- CPPUNIT_ASSERT(message);
- CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or(""));
-
- {
- Message::ref message = boost::make_shared<Message>();
- message->setType(Message::Groupchat);
- message->setTo(self_);
- message->setFrom(mucJID_.withResource("SomeNickname"));
- message->setID(iqChannel_->getNewIQID());
- message->setSubject("New Room Subject");
- message->addPayload(boost::make_shared<Thread>("Thread that prevents the subject change."));
-
- controller_->handleIncomingMessage(boost::make_shared<MessageEvent>(message));
- CPPUNIT_ASSERT_EQUAL(std::string("Trying to enter room teaparty@rooms.wonderland.lit"), boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(window_->lastAddedSystemMessage_.getParts()[0])->text);
- }
- }
-
- /*
- * Test that message stanzas with subject element and empty body element do not cause a subject change.
- */
- void testSubjectChangeIncorrectC() {
- std::string messageBody("test message");
- window_->onSendMessageRequest(messageBody, false);
- boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
- Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza);
- CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
- CPPUNIT_ASSERT(message);
- CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or(""));
-
- {
- Message::ref message = boost::make_shared<Message>();
- message->setType(Message::Groupchat);
- message->setTo(self_);
- message->setFrom(mucJID_.withResource("SomeNickname"));
- message->setID(iqChannel_->getNewIQID());
- message->setSubject("New Room Subject");
- message->setBody("");
-
- controller_->handleIncomingMessage(boost::make_shared<MessageEvent>(message));
- CPPUNIT_ASSERT_EQUAL(std::string("Trying to enter room teaparty@rooms.wonderland.lit"), boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(window_->lastAddedSystemMessage_.getParts()[0])->text);
- }
- }
-
- void testRoleAffiliationStatesVerify(const std::map<std::string, MUCOccupant> &occupants) {
- /* verify that the roster is in sync */
- GroupRosterItem* group = window_->getRosterModel()->getRoot();
- foreach(RosterItem* rosterItem, group->getChildren()) {
- GroupRosterItem* child = dynamic_cast<GroupRosterItem*>(rosterItem);
- CPPUNIT_ASSERT(child);
- foreach(RosterItem* childItem, child->getChildren()) {
- ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(childItem);
- CPPUNIT_ASSERT(item);
- std::map<std::string, MUCOccupant>::const_iterator occupant = occupants.find(item->getJID().getResource());
- CPPUNIT_ASSERT(occupant != occupants.end());
- CPPUNIT_ASSERT(item->getMUCRole() == occupant->second.getRole());
- CPPUNIT_ASSERT(item->getMUCAffiliation() == occupant->second.getAffiliation());
- }
- }
- }
+ void setUp() {
+ crypto_ = std::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());
+ self_ = JID("girl@wonderland.lit/rabbithole");
+ nick_ = "aLiCe";
+ mucJID_ = JID("teaparty@rooms.wonderland.lit");
+ mocks_ = new MockRepository();
+ stanzaChannel_ = new DummyStanzaChannel();
+ iqChannel_ = new DummyIQChannel();
+ iqRouter_ = new IQRouter(iqChannel_);
+ eventController_ = new EventController();
+ chatWindowFactory_ = mocks_->InterfaceMock<ChatWindowFactory>();
+ userSearchWindowFactory_ = mocks_->InterfaceMock<UserSearchWindowFactory>();
+ xmppRoster_ = new XMPPRosterImpl();
+ presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_);
+ presenceSender_ = new StanzaChannelPresenceSender(stanzaChannel_);
+ directedPresenceSender_ = new DirectedPresenceSender(presenceSender_);
+ uiEventStream_ = new UIEventStream();
+ avatarManager_ = new NullAvatarManager();
+ TimerFactory* timerFactory = nullptr;
+ window_ = new MockChatWindow();
+ mucRegistry_ = new MUCRegistry();
+ entityCapsProvider_ = new DummyEntityCapsProvider();
+ settings_ = new DummySettingsProvider();
+ highlightManager_ = new HighlightManager(settings_);
+ muc_ = std::make_shared<MockMUC>(mucJID_);
+ mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(muc_->getJID(), uiEventStream_).Return(window_);
+ chatMessageParser_ = std::make_shared<ChatMessageParser>(std::map<std::string, std::string>(), highlightManager_->getRules(), true);
+ vcardStorage_ = new VCardMemoryStorage(crypto_.get());
+ vcardManager_ = new VCardManager(self_, iqRouter_, vcardStorage_);
+ clientBlockListManager_ = new ClientBlockListManager(iqRouter_);
+ mucBookmarkManager_ = new MUCBookmarkManager(iqRouter_);
+ controller_ = new MUCController (self_, muc_, boost::optional<std::string>(), nick_, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory, eventController_, entityCapsProvider_, nullptr, nullptr, mucRegistry_, highlightManager_, clientBlockListManager_, chatMessageParser_, false, nullptr, vcardManager_, mucBookmarkManager_);
+ }
+
+ void tearDown() {
+ delete controller_;
+ delete mucBookmarkManager_;
+ delete clientBlockListManager_;
+ delete vcardManager_;
+ delete vcardStorage_;
+ delete highlightManager_;
+ delete settings_;
+ delete entityCapsProvider_;
+ delete eventController_;
+ delete presenceOracle_;
+ delete xmppRoster_;
+ delete mocks_;
+ delete uiEventStream_;
+ delete stanzaChannel_;
+ delete presenceSender_;
+ delete directedPresenceSender_;
+ delete iqRouter_;
+ delete iqChannel_;
+ delete mucRegistry_;
+ delete avatarManager_;
+ }
+
+ void finishJoin() {
+ Presence::ref presence(new Presence());
+ presence->setFrom(JID(muc_->getJID().toString() + "/" + nick_));
+ MUCUserPayload::ref status(new MUCUserPayload());
+ MUCUserPayload::StatusCode code;
+ code.code = 110;
+ status->addStatusCode(code);
+ presence->addPayload(status);
+ stanzaChannel_->onPresenceReceived(presence);
+ }
+
+ void testAddressedToSelf() {
+ finishJoin();
+ Message::ref message(new Message());
+
+ message = Message::ref(new Message());
+ message->setFrom(JID(muc_->getJID().toString() + "/otherperson"));
+ message->setBody("basic " + nick_ + " test.");
+ message->setType(Message::Groupchat);
+ controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
+ CPPUNIT_ASSERT_EQUAL((size_t)1, eventController_->getEvents().size());
+
+ message = Message::ref(new Message());
+ message->setFrom(JID(muc_->getJID().toString() + "/otherperson"));
+ message->setBody(nick_ + ": hi there");
+ message->setType(Message::Groupchat);
+ controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
+ CPPUNIT_ASSERT_EQUAL((size_t)2, eventController_->getEvents().size());
+
+ message->setFrom(JID(muc_->getJID().toString() + "/other"));
+ message->setBody("Hi there " + nick_);
+ message->setType(Message::Groupchat);
+ controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
+ CPPUNIT_ASSERT_EQUAL((size_t)3, eventController_->getEvents().size());
+
+ message = Message::ref(new Message());
+ message->setFrom(JID(muc_->getJID().toString() + "/other2"));
+ message->setBody("Hi " + boost::to_lower_copy(nick_) + ".");
+ message->setType(Message::Groupchat);
+ controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
+ CPPUNIT_ASSERT_EQUAL((size_t)4, eventController_->getEvents().size());
+
+ message = Message::ref(new Message());
+ message->setFrom(JID(muc_->getJID().toString() + "/other3"));
+ message->setBody("Hi bert.");
+ message->setType(Message::Groupchat);
+ controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
+ CPPUNIT_ASSERT_EQUAL((size_t)4, eventController_->getEvents().size());
+
+ message = Message::ref(new Message());
+ message->setFrom(JID(muc_->getJID().toString() + "/other2"));
+ message->setBody("Hi " + boost::to_lower_copy(nick_) + "ie.");
+ message->setType(Message::Groupchat);
+ controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
+ CPPUNIT_ASSERT_EQUAL((size_t)4, eventController_->getEvents().size());
+ }
+
+ void testNotAddressedToSelf() {
+ finishJoin();
+ Message::ref message(new Message());
+ message->setFrom(JID(muc_->getJID().toString() + "/other3"));
+ message->setBody("Hi there Hatter");
+ message->setType(Message::Groupchat);
+ controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
+ CPPUNIT_ASSERT_EQUAL((size_t)0, eventController_->getEvents().size());
+ }
+
+ void testAddressedToSelfBySelf() {
+ finishJoin();
+ Message::ref message(new Message());
+ message->setFrom(JID(muc_->getJID().toString() + "/" + nick_));
+ message->setBody("Hi there " + nick_);
+ message->setType(Message::Groupchat);
+ controller_->handleIncomingMessage(MessageEvent::ref(new MessageEvent(message)));
+ CPPUNIT_ASSERT_EQUAL((size_t)0, eventController_->getEvents().size());
+ }
+
+ void testMessageWithEmptyLabelItem() {
+ SecurityLabelsCatalog::Item label;
+ label.setSelector("Bob");
+ window_->label_ = label;
+ std::shared_ptr<DiscoInfo> features = std::make_shared<DiscoInfo>();
+ features->addFeature(DiscoInfo::SecurityLabelsCatalogFeature);
+ controller_->setAvailableServerFeatures(features);
+ IQ::ref iq = iqChannel_->iqs_[iqChannel_->iqs_.size() - 1];
+ SecurityLabelsCatalog::ref labelPayload = std::make_shared<SecurityLabelsCatalog>();
+ labelPayload->addItem(label);
+ IQ::ref result = IQ::createResult(self_, iq->getID(), labelPayload);
+ iqChannel_->onIQReceived(result);
+ std::string messageBody("agamemnon");
+ window_->onSendMessageRequest(messageBody, false);
+ std::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
+ Message::ref message = std::dynamic_pointer_cast<Message>(rawStanza);
+ CPPUNIT_ASSERT_EQUAL(iq->getTo(), result->getFrom());
+ CPPUNIT_ASSERT(window_->labelsEnabled_);
+ CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
+ CPPUNIT_ASSERT(message);
+ CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get());
+ CPPUNIT_ASSERT(!message->getPayload<SecurityLabel>());
+ }
+
+ void testMessageWithLabelItem() {
+ std::shared_ptr<SecurityLabel> label = std::make_shared<SecurityLabel>();
+ label->setLabel("a");
+ SecurityLabelsCatalog::Item labelItem;
+ labelItem.setSelector("Bob");
+ labelItem.setLabel(label);
+ window_->label_ = labelItem;
+ std::shared_ptr<DiscoInfo> features = std::make_shared<DiscoInfo>();
+ features->addFeature(DiscoInfo::SecurityLabelsCatalogFeature);
+ controller_->setAvailableServerFeatures(features);
+ IQ::ref iq = iqChannel_->iqs_[iqChannel_->iqs_.size() - 1];
+ SecurityLabelsCatalog::ref labelPayload = std::make_shared<SecurityLabelsCatalog>();
+ labelPayload->addItem(labelItem);
+ IQ::ref result = IQ::createResult(self_, iq->getID(), labelPayload);
+ iqChannel_->onIQReceived(result);
+ std::string messageBody("agamemnon");
+ window_->onSendMessageRequest(messageBody, false);
+ std::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
+ Message::ref message = std::dynamic_pointer_cast<Message>(rawStanza);
+ CPPUNIT_ASSERT_EQUAL(iq->getTo(), result->getFrom());
+ CPPUNIT_ASSERT(window_->labelsEnabled_);
+ CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
+ CPPUNIT_ASSERT(message);
+ CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get());
+ CPPUNIT_ASSERT_EQUAL(label, message->getPayload<SecurityLabel>());
+ }
+
+ void testCorrectMessageWithLabelItem() {
+ std::shared_ptr<SecurityLabel> label = std::make_shared<SecurityLabel>();
+ label->setLabel("a");
+ SecurityLabelsCatalog::Item labelItem;
+ labelItem.setSelector("Bob");
+ labelItem.setLabel(label);
+ std::shared_ptr<SecurityLabel> label2 = std::make_shared<SecurityLabel>();
+ label->setLabel("b");
+ SecurityLabelsCatalog::Item labelItem2;
+ labelItem2.setSelector("Charlie");
+ labelItem2.setLabel(label2);
+ window_->label_ = labelItem;
+ std::shared_ptr<DiscoInfo> features = std::make_shared<DiscoInfo>();
+ features->addFeature(DiscoInfo::SecurityLabelsCatalogFeature);
+ controller_->setAvailableServerFeatures(features);
+ IQ::ref iq = iqChannel_->iqs_[iqChannel_->iqs_.size() - 1];
+ SecurityLabelsCatalog::ref labelPayload = std::make_shared<SecurityLabelsCatalog>();
+ labelPayload->addItem(labelItem);
+ IQ::ref result = IQ::createResult(self_, iq->getID(), labelPayload);
+ iqChannel_->onIQReceived(result);
+ std::string messageBody("agamemnon");
+ window_->onSendMessageRequest(messageBody, false);
+ std::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
+ Message::ref message = std::dynamic_pointer_cast<Message>(rawStanza);
+ CPPUNIT_ASSERT_EQUAL(iq->getTo(), result->getFrom());
+ CPPUNIT_ASSERT(window_->labelsEnabled_);
+ CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
+ CPPUNIT_ASSERT(message);
+ CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get());
+ CPPUNIT_ASSERT_EQUAL(label, message->getPayload<SecurityLabel>());
+ window_->label_ = labelItem2;
+ window_->onSendMessageRequest(messageBody, true);
+ rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
+ message = std::dynamic_pointer_cast<Message>(rawStanza);
+ CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get());
+ CPPUNIT_ASSERT_EQUAL(label, message->getPayload<SecurityLabel>());
+ }
+
+ void checkEqual(const std::vector<NickJoinPart>& expected, const std::vector<NickJoinPart>& actual) {
+ CPPUNIT_ASSERT_EQUAL(expected.size(), actual.size());
+ for (size_t i = 0; i < expected.size(); i++) {
+ CPPUNIT_ASSERT_EQUAL(expected[i].nick, actual[i].nick);
+ CPPUNIT_ASSERT_EQUAL(expected[i].type, actual[i].type);
+ }
+ }
+
+ void testAppendToJoinParts() {
+ std::vector<NickJoinPart> list;
+ std::vector<NickJoinPart> gold;
+ MUCController::appendToJoinParts(list, NickJoinPart("Kev", Join));
+ gold.push_back(NickJoinPart("Kev", Join));
+ checkEqual(gold, list);
+ MUCController::appendToJoinParts(list, NickJoinPart("Remko", Join));
+ gold.push_back(NickJoinPart("Remko", Join));
+ checkEqual(gold, list);
+ MUCController::appendToJoinParts(list, NickJoinPart("Bert", Join));
+ gold.push_back(NickJoinPart("Bert", Join));
+ checkEqual(gold, list);
+ MUCController::appendToJoinParts(list, NickJoinPart("Bert", Part));
+ gold[2].type = JoinThenPart;
+ checkEqual(gold, list);
+ MUCController::appendToJoinParts(list, NickJoinPart("Kev", Part));
+ gold[0].type = JoinThenPart;
+ checkEqual(gold, list);
+ MUCController::appendToJoinParts(list, NickJoinPart("Remko", Part));
+ gold[1].type = JoinThenPart;
+ checkEqual(gold, list);
+ MUCController::appendToJoinParts(list, NickJoinPart("Ernie", Part));
+ gold.push_back(NickJoinPart("Ernie", Part));
+ checkEqual(gold, list);
+ MUCController::appendToJoinParts(list, NickJoinPart("Ernie", Join));
+ gold[3].type = PartThenJoin;
+ checkEqual(gold, list);
+ MUCController::appendToJoinParts(list, NickJoinPart("Kev", Join));
+ gold[0].type = Join;
+ checkEqual(gold, list);
+ MUCController::appendToJoinParts(list, NickJoinPart("Ernie", Part));
+ gold[3].type = Part;
+ checkEqual(gold, list);
+
+ }
+
+ void testJoinPartStringContructionSimple() {
+ std::vector<NickJoinPart> list;
+ list.push_back(NickJoinPart("Kev", Join));
+ CPPUNIT_ASSERT_EQUAL(std::string("Kev has entered the room"), MUCController::generateJoinPartString(list, false));
+ list.push_back(NickJoinPart("Remko", Part));
+ CPPUNIT_ASSERT_EQUAL(std::string("Kev has entered the room and Remko has left the room"), MUCController::generateJoinPartString(list, false));
+ list.push_back(NickJoinPart("Bert", Join));
+ CPPUNIT_ASSERT_EQUAL(std::string("Kev and Bert have entered the room and Remko has left the room"), MUCController::generateJoinPartString(list, false));
+ list.push_back(NickJoinPart("Ernie", Join));
+ CPPUNIT_ASSERT_EQUAL(std::string("Kev, Bert and Ernie have entered the room and Remko has left the room"), MUCController::generateJoinPartString(list, false));
+ }
+
+ void testJoinPartStringContructionMixed() {
+ std::vector<NickJoinPart> list;
+ list.push_back(NickJoinPart("Kev", JoinThenPart));
+ CPPUNIT_ASSERT_EQUAL(std::string("Kev has entered then left the room"), MUCController::generateJoinPartString(list, false));
+ list.push_back(NickJoinPart("Remko", Part));
+ CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room and Kev has entered then left the room"), MUCController::generateJoinPartString(list, false));
+ list.push_back(NickJoinPart("Bert", PartThenJoin));
+ CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room, Kev has entered then left the room and Bert has left then returned to the room"), MUCController::generateJoinPartString(list, false));
+ list.push_back(NickJoinPart("Ernie", JoinThenPart));
+ CPPUNIT_ASSERT_EQUAL(std::string("Remko has left the room, Kev and Ernie have entered then left the room and Bert has left then returned to the room"), MUCController::generateJoinPartString(list, false));
+ }
+
+ JID jidFromOccupant(const MUCOccupant& occupant) {
+ return JID(mucJID_.toString()+"/"+occupant.getNick());
+ }
+
+ void testRoleAffiliationStates() {
+
+ typedef std::map<std::string, MUCOccupant> occupant_map;
+ occupant_map occupants;
+ occupants.insert(occupant_map::value_type("Kev", MUCOccupant("Kev", MUCOccupant::Participant, MUCOccupant::Owner)));
+ occupants.insert(occupant_map::value_type("Remko", MUCOccupant("Remko", MUCOccupant::Participant, MUCOccupant::Owner)));
+ occupants.insert(occupant_map::value_type("Bert", MUCOccupant("Bert", MUCOccupant::Participant, MUCOccupant::Owner)));
+ occupants.insert(occupant_map::value_type("Ernie", MUCOccupant("Ernie", MUCOccupant::Participant, MUCOccupant::Owner)));
+
+ /* populate the MUC with fake users */
+ for (auto&& occupant : occupants) {
+ muc_->insertOccupant(occupant.second);
+ }
+
+ std::vector<MUCOccupant> alterations;
+ alterations.push_back(MUCOccupant("Kev", MUCOccupant::Visitor, MUCOccupant::Admin));
+ alterations.push_back(MUCOccupant("Remko", MUCOccupant::Moderator, MUCOccupant::Member));
+ alterations.push_back(MUCOccupant("Bert", MUCOccupant::Visitor, MUCOccupant::Outcast));
+ alterations.push_back(MUCOccupant("Ernie", MUCOccupant::NoRole, MUCOccupant::Member));
+ alterations.push_back(MUCOccupant("Bert", MUCOccupant::Moderator, MUCOccupant::Owner));
+ alterations.push_back(MUCOccupant("Kev", MUCOccupant::Participant, MUCOccupant::Outcast));
+ alterations.push_back(MUCOccupant("Bert", MUCOccupant::Visitor, MUCOccupant::NoAffiliation));
+ alterations.push_back(MUCOccupant("Remko", MUCOccupant::NoRole, MUCOccupant::NoAffiliation));
+ alterations.push_back(MUCOccupant("Ernie", MUCOccupant::Visitor, MUCOccupant::Outcast));
+
+ for (const auto& alteration : alterations) {
+ /* perform an alteration to a user's role and affiliation */
+ occupant_map::iterator occupant = occupants.find(alteration.getNick());
+ CPPUNIT_ASSERT(occupant != occupants.end());
+ const JID jid = jidFromOccupant(occupant->second);
+ /* change the affiliation, leave the role in place */
+ muc_->changeAffiliation(jid, alteration.getAffiliation());
+ occupant->second = MUCOccupant(occupant->first, occupant->second.getRole(), alteration.getAffiliation());
+ testRoleAffiliationStatesVerify(occupants);
+ /* change the role, leave the affiliation in place */
+ muc_->changeOccupantRole(jid, alteration.getRole());
+ occupant->second = MUCOccupant(occupant->first, alteration.getRole(), occupant->second.getAffiliation());
+ testRoleAffiliationStatesVerify(occupants);
+ }
+ }
+
+ void testSubjectChangeCorrect() {
+ std::string messageBody("test message");
+ window_->onSendMessageRequest(messageBody, false);
+ std::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
+ Message::ref message = std::dynamic_pointer_cast<Message>(rawStanza);
+ CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
+ CPPUNIT_ASSERT(message);
+ CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or(""));
+
+ {
+ Message::ref message = std::make_shared<Message>();
+ message->setType(Message::Groupchat);
+ message->setTo(self_);
+ message->setFrom(mucJID_.withResource("SomeNickname"));
+ message->setID(iqChannel_->getNewIQID());
+ message->setSubject("New Room Subject");
+
+ controller_->handleIncomingMessage(std::make_shared<MessageEvent>(message));
+ CPPUNIT_ASSERT_EQUAL(std::string("The room subject is now: New Room Subject"), std::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(window_->lastAddedSystemMessage_.getParts()[0])->text);
+ }
+ }
+
+ /*
+ * Test that message stanzas with subject element and non-empty body element do not cause a subject change.
+ */
+ void testSubjectChangeIncorrectA() {
+ std::string messageBody("test message");
+ window_->onSendMessageRequest(messageBody, false);
+ std::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
+ Message::ref message = std::dynamic_pointer_cast<Message>(rawStanza);
+ CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
+ CPPUNIT_ASSERT(message);
+ CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or(""));
+
+ {
+ Message::ref message = std::make_shared<Message>();
+ message->setType(Message::Groupchat);
+ message->setTo(self_);
+ message->setFrom(mucJID_.withResource("SomeNickname"));
+ message->setID(iqChannel_->getNewIQID());
+ message->setSubject("New Room Subject");
+ message->setBody("Some body text that prevents this stanza from being a subject change.");
+
+ controller_->handleIncomingMessage(std::make_shared<MessageEvent>(message));
+ CPPUNIT_ASSERT_EQUAL(std::string("Trying to enter room teaparty@rooms.wonderland.lit"), std::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(window_->lastAddedSystemMessage_.getParts()[0])->text);
+ }
+ }
+
+ /*
+ * Test that message stanzas with subject element and thread element do not cause a subject change.
+ */
+ void testSubjectChangeIncorrectB() {
+ std::string messageBody("test message");
+ window_->onSendMessageRequest(messageBody, false);
+ std::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
+ Message::ref message = std::dynamic_pointer_cast<Message>(rawStanza);
+ CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
+ CPPUNIT_ASSERT(message);
+ CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or(""));
+
+ {
+ Message::ref message = std::make_shared<Message>();
+ message->setType(Message::Groupchat);
+ message->setTo(self_);
+ message->setFrom(mucJID_.withResource("SomeNickname"));
+ message->setID(iqChannel_->getNewIQID());
+ message->setSubject("New Room Subject");
+ message->addPayload(std::make_shared<Thread>("Thread that prevents the subject change."));
+
+ controller_->handleIncomingMessage(std::make_shared<MessageEvent>(message));
+ CPPUNIT_ASSERT_EQUAL(std::string("Trying to enter room teaparty@rooms.wonderland.lit"), std::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(window_->lastAddedSystemMessage_.getParts()[0])->text);
+ }
+ }
+
+ /*
+ * Test that message stanzas with subject element and empty body element do not cause a subject change.
+ */
+ void testSubjectChangeIncorrectC() {
+ std::string messageBody("test message");
+ window_->onSendMessageRequest(messageBody, false);
+ std::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1];
+ Message::ref message = std::dynamic_pointer_cast<Message>(rawStanza);
+ CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */
+ CPPUNIT_ASSERT(message);
+ CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody().get_value_or(""));
+
+ {
+ Message::ref message = std::make_shared<Message>();
+ message->setType(Message::Groupchat);
+ message->setTo(self_);
+ message->setFrom(mucJID_.withResource("SomeNickname"));
+ message->setID(iqChannel_->getNewIQID());
+ message->setSubject("New Room Subject");
+ message->setBody("");
+
+ controller_->handleIncomingMessage(std::make_shared<MessageEvent>(message));
+ CPPUNIT_ASSERT_EQUAL(std::string("Trying to enter room teaparty@rooms.wonderland.lit"), std::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(window_->lastAddedSystemMessage_.getParts()[0])->text);
+ }
+ }
+
+ void testRoleAffiliationStatesVerify(const std::map<std::string, MUCOccupant> &occupants) {
+ /* verify that the roster is in sync */
+ GroupRosterItem* group = window_->getRosterModel()->getRoot();
+ for (auto rosterItem : group->getChildren()) {
+ GroupRosterItem* child = dynamic_cast<GroupRosterItem*>(rosterItem);
+ CPPUNIT_ASSERT(child);
+ for (auto childItem : child->getChildren()) {
+ ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(childItem);
+ CPPUNIT_ASSERT(item);
+ std::map<std::string, MUCOccupant>::const_iterator occupant = occupants.find(item->getJID().getResource());
+ CPPUNIT_ASSERT(occupant != occupants.end());
+ CPPUNIT_ASSERT(item->getMUCRole() == occupant->second.getRole());
+ CPPUNIT_ASSERT(item->getMUCAffiliation() == occupant->second.getAffiliation());
+ }
+ }
+ }
private:
- JID self_;
- JID mucJID_;
- MockMUC::ref muc_;
- std::string nick_;
- DummyStanzaChannel* stanzaChannel_;
- DummyIQChannel* iqChannel_;
- IQRouter* iqRouter_;
- EventController* eventController_;
- ChatWindowFactory* chatWindowFactory_;
- UserSearchWindowFactory* userSearchWindowFactory_;
- MUCController* controller_;
-// NickResolver* nickResolver_;
- PresenceOracle* presenceOracle_;
- AvatarManager* avatarManager_;
- StanzaChannelPresenceSender* presenceSender_;
- DirectedPresenceSender* directedPresenceSender_;
- MockRepository* mocks_;
- UIEventStream* uiEventStream_;
- MockChatWindow* window_;
- MUCRegistry* mucRegistry_;
- DummyEntityCapsProvider* entityCapsProvider_;
- DummySettingsProvider* settings_;
- HighlightManager* highlightManager_;
- boost::shared_ptr<ChatMessageParser> chatMessageParser_;
- boost::shared_ptr<CryptoProvider> crypto_;
- VCardManager* vcardManager_;
- VCardMemoryStorage* vcardStorage_;
- ClientBlockListManager* clientBlockListManager_;
- MUCBookmarkManager* mucBookmarkManager_;
- XMPPRoster* xmppRoster_;
+ JID self_;
+ JID mucJID_;
+ MockMUC::ref muc_;
+ std::string nick_;
+ DummyStanzaChannel* stanzaChannel_;
+ DummyIQChannel* iqChannel_;
+ IQRouter* iqRouter_;
+ EventController* eventController_;
+ ChatWindowFactory* chatWindowFactory_;
+ UserSearchWindowFactory* userSearchWindowFactory_;
+ MUCController* controller_;
+// NickResolver* nickResolver_;
+ PresenceOracle* presenceOracle_;
+ AvatarManager* avatarManager_;
+ StanzaChannelPresenceSender* presenceSender_;
+ DirectedPresenceSender* directedPresenceSender_;
+ MockRepository* mocks_;
+ UIEventStream* uiEventStream_;
+ MockChatWindow* window_;
+ MUCRegistry* mucRegistry_;
+ DummyEntityCapsProvider* entityCapsProvider_;
+ DummySettingsProvider* settings_;
+ HighlightManager* highlightManager_;
+ std::shared_ptr<ChatMessageParser> chatMessageParser_;
+ std::shared_ptr<CryptoProvider> crypto_;
+ VCardManager* vcardManager_;
+ VCardMemoryStorage* vcardStorage_;
+ ClientBlockListManager* clientBlockListManager_;
+ MUCBookmarkManager* mucBookmarkManager_;
+ XMPPRoster* xmppRoster_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(MUCControllerTest);
diff --git a/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h b/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h
index c1410f3..395b050 100644
--- a/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h
+++ b/Swift/Controllers/Chat/UnitTest/MockChatListWindow.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2011-2014 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/UIInterfaces/ChatListWindow.h"
+#include <Swift/Controllers/UIInterfaces/ChatListWindow.h>
namespace Swift {
- class MockChatListWindow : public ChatListWindow {
- public:
- MockChatListWindow() {}
- virtual ~MockChatListWindow() {}
- void addMUCBookmark(const MUCBookmark& /*bookmark*/) {}
- void removeMUCBookmark(const MUCBookmark& /*bookmark*/) {}
- void addWhiteboardSession(const ChatListWindow::Chat& /*chat*/) {}
- void removeWhiteboardSession(const JID& /*jid*/) {}
- void setBookmarksEnabled(bool /*enabled*/) {}
- void setRecents(const std::list<ChatListWindow::Chat>& /*recents*/) {}
- void setUnreadCount(int /*unread*/) {}
- void clearBookmarks() {}
- void setOnline(bool /*isOnline*/) {}
- };
+ class MockChatListWindow : public ChatListWindow {
+ public:
+ MockChatListWindow() {}
+ virtual ~MockChatListWindow() {}
+ void addMUCBookmark(const MUCBookmark& /*bookmark*/) {}
+ void removeMUCBookmark(const MUCBookmark& /*bookmark*/) {}
+ void addWhiteboardSession(const ChatListWindow::Chat& /*chat*/) {}
+ void removeWhiteboardSession(const JID& /*jid*/) {}
+ void setBookmarksEnabled(bool /*enabled*/) {}
+ void setRecents(const std::list<ChatListWindow::Chat>& /*recents*/) {}
+ void setUnreadCount(int /*unread*/) {}
+ void clearBookmarks() {}
+ void setOnline(bool /*isOnline*/) {}
+ };
}
diff --git a/Swift/Controllers/Chat/UserSearchController.cpp b/Swift/Controllers/Chat/UserSearchController.cpp
index e08912a..91de670 100644
--- a/Swift/Controllers/Chat/UserSearchController.cpp
+++ b/Swift/Controllers/Chat/UserSearchController.cpp
@@ -1,18 +1,17 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/Chat/UserSearchController.h>
+#include <memory>
+
#include <boost/bind.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
#include <Swiften/Avatars/AvatarManager.h>
#include <Swiften/Base/String.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Disco/DiscoServiceWalker.h>
#include <Swiften/Disco/GetDiscoInfoRequest.h>
#include <Swiften/Disco/GetDiscoItemsRequest.h>
@@ -36,357 +35,359 @@ namespace Swift {
static const std::string SEARCHED_DIRECTORIES = "searchedDirectories";
UserSearchController::UserSearchController(Type type, const JID& jid, UIEventStream* uiEventStream, VCardManager* vcardManager, UserSearchWindowFactory* factory, IQRouter* iqRouter, RosterController* rosterController, ContactSuggester* contactSuggester, AvatarManager* avatarManager, PresenceOracle* presenceOracle, ProfileSettingsProvider* settings) : type_(type), jid_(jid), uiEventStream_(uiEventStream), vcardManager_(vcardManager), factory_(factory), iqRouter_(iqRouter), rosterController_(rosterController), contactSuggester_(contactSuggester), avatarManager_(avatarManager), presenceOracle_(presenceOracle), settings_(settings) {
- uiEventStream_->onUIEvent.connect(boost::bind(&UserSearchController::handleUIEvent, this, _1));
- vcardManager_->onVCardChanged.connect(boost::bind(&UserSearchController::handleVCardChanged, this, _1, _2));
- avatarManager_->onAvatarChanged.connect(boost::bind(&UserSearchController::handleAvatarChanged, this, _1));
- presenceOracle_->onPresenceChange.connect(boost::bind(&UserSearchController::handlePresenceChanged, this, _1));
- window_ = NULL;
- discoWalker_ = NULL;
- loadSavedDirectories();
+ uiEventStream_->onUIEvent.connect(boost::bind(&UserSearchController::handleUIEvent, this, _1));
+ vcardManager_->onVCardChanged.connect(boost::bind(&UserSearchController::handleVCardChanged, this, _1, _2));
+ avatarManager_->onAvatarChanged.connect(boost::bind(&UserSearchController::handleAvatarChanged, this, _1));
+ presenceOracle_->onPresenceChange.connect(boost::bind(&UserSearchController::handlePresenceChanged, this, _1));
+ window_ = nullptr;
+ discoWalker_ = nullptr;
+ loadSavedDirectories();
}
UserSearchController::~UserSearchController() {
- endDiscoWalker();
- delete discoWalker_;
- if (window_) {
- window_->onNameSuggestionRequested.disconnect(boost::bind(&UserSearchController::handleNameSuggestionRequest, this, _1));
- window_->onFormRequested.disconnect(boost::bind(&UserSearchController::handleFormRequested, this, _1));
- window_->onSearchRequested.disconnect(boost::bind(&UserSearchController::handleSearch, this, _1, _2));
- window_->onContactSuggestionsRequested.disconnect(boost::bind(&UserSearchController::handleContactSuggestionsRequested, this, _1));
- window_->onJIDUpdateRequested.disconnect(boost::bind(&UserSearchController::handleJIDUpdateRequested, this, _1));
- window_->onJIDAddRequested.disconnect(boost::bind(&UserSearchController::handleJIDAddRequested, this, _1));
- window_->onJIDEditFieldChanged.disconnect(boost::bind(&UserSearchController::handleJIDEditingFinished, this, _1));
- delete window_;
- }
- presenceOracle_->onPresenceChange.disconnect(boost::bind(&UserSearchController::handlePresenceChanged, this, _1));
- avatarManager_->onAvatarChanged.disconnect(boost::bind(&UserSearchController::handleAvatarChanged, this, _1));
- vcardManager_->onVCardChanged.disconnect(boost::bind(&UserSearchController::handleVCardChanged, this, _1, _2));
- uiEventStream_->onUIEvent.disconnect(boost::bind(&UserSearchController::handleUIEvent, this, _1));
+ endDiscoWalker();
+ delete discoWalker_;
+ if (window_) {
+ window_->onNameSuggestionRequested.disconnect(boost::bind(&UserSearchController::handleNameSuggestionRequest, this, _1));
+ window_->onFormRequested.disconnect(boost::bind(&UserSearchController::handleFormRequested, this, _1));
+ window_->onSearchRequested.disconnect(boost::bind(&UserSearchController::handleSearch, this, _1, _2));
+ window_->onContactSuggestionsRequested.disconnect(boost::bind(&UserSearchController::handleContactSuggestionsRequested, this, _1));
+ window_->onJIDUpdateRequested.disconnect(boost::bind(&UserSearchController::handleJIDUpdateRequested, this, _1));
+ window_->onJIDAddRequested.disconnect(boost::bind(&UserSearchController::handleJIDAddRequested, this, _1));
+ window_->onJIDEditFieldChanged.disconnect(boost::bind(&UserSearchController::handleJIDEditingFinished, this, _1));
+ delete window_;
+ }
+ presenceOracle_->onPresenceChange.disconnect(boost::bind(&UserSearchController::handlePresenceChanged, this, _1));
+ avatarManager_->onAvatarChanged.disconnect(boost::bind(&UserSearchController::handleAvatarChanged, this, _1));
+ vcardManager_->onVCardChanged.disconnect(boost::bind(&UserSearchController::handleVCardChanged, this, _1, _2));
+ uiEventStream_->onUIEvent.disconnect(boost::bind(&UserSearchController::handleUIEvent, this, _1));
}
UserSearchWindow* UserSearchController::getUserSearchWindow() {
- initializeUserWindow();
- assert(window_);
- return window_;
+ initializeUserWindow();
+ assert(window_);
+ return window_;
}
void UserSearchController::setCanInitiateImpromptuMUC(bool supportsImpromptu) {
- if (!window_) {
- initializeUserWindow();
- }
- if (window_) {
- window_->setCanStartImpromptuChats(supportsImpromptu);
- } // Else doesn't support search
+ if (!window_) {
+ initializeUserWindow();
+ }
+ if (window_) {
+ window_->setCanStartImpromptuChats(supportsImpromptu);
+ } // Else doesn't support search
}
-void UserSearchController::handleUIEvent(boost::shared_ptr<UIEvent> event) {
- bool handle = false;
- boost::shared_ptr<RequestAddUserDialogUIEvent> addUserRequest = boost::shared_ptr<RequestAddUserDialogUIEvent>();
- RequestInviteToMUCUIEvent::ref inviteToMUCRequest = RequestInviteToMUCUIEvent::ref();
- switch (type_) {
- case AddContact:
- if ((addUserRequest = boost::dynamic_pointer_cast<RequestAddUserDialogUIEvent>(event))) {
- handle = true;
- }
- break;
- case StartChat:
- if (boost::dynamic_pointer_cast<RequestChatWithUserDialogUIEvent>(event)) {
- handle = true;
- }
- break;
- case InviteToChat:
- if ((inviteToMUCRequest = boost::dynamic_pointer_cast<RequestInviteToMUCUIEvent>(event))) {
- handle = true;
- }
- break;
- }
- if (handle) {
- initializeUserWindow();
- window_->show();
- window_->addSavedServices(savedDirectories_);
- if (addUserRequest) {
- const std::string& name = addUserRequest->getPredefinedName();
- const JID& jid = addUserRequest->getPredefinedJID();
- if (!name.empty() && jid.isValid()) {
- window_->prepopulateJIDAndName(jid, name);
- }
- } else if (inviteToMUCRequest) {
- window_->setCanSupplyDescription(!inviteToMUCRequest->isImpromptu());
- window_->setJIDs(inviteToMUCRequest->getInvites());
- window_->setRoomJID(inviteToMUCRequest->getRoom());
- }
- return;
- }
+void UserSearchController::handleUIEvent(std::shared_ptr<UIEvent> event) {
+ bool handle = false;
+ std::shared_ptr<RequestAddUserDialogUIEvent> addUserRequest = std::shared_ptr<RequestAddUserDialogUIEvent>();
+ auto inviteToMUCRequest = RequestInviteToMUCUIEvent::ref();
+ switch (type_) {
+ case AddContact:
+ if ((addUserRequest = std::dynamic_pointer_cast<RequestAddUserDialogUIEvent>(event))) {
+ handle = true;
+ }
+ break;
+ case StartChat:
+ if (std::dynamic_pointer_cast<RequestChatWithUserDialogUIEvent>(event)) {
+ handle = true;
+ }
+ break;
+ case InviteToChat:
+ if ((inviteToMUCRequest = std::dynamic_pointer_cast<RequestInviteToMUCUIEvent>(event))) {
+ handle = true;
+ }
+ break;
+ }
+ if (handle) {
+ initializeUserWindow();
+ window_->show();
+ window_->addSavedServices(savedDirectories_);
+ if (addUserRequest) {
+ const std::string& name = addUserRequest->getPredefinedName();
+ const JID& jid = addUserRequest->getPredefinedJID();
+ if (!name.empty() && jid.isValid()) {
+ window_->prepopulateJIDAndName(jid, name);
+ }
+ }
+ else if (inviteToMUCRequest) {
+ window_->setCanSupplyDescription(!inviteToMUCRequest->isImpromptu());
+ window_->setJIDs(inviteToMUCRequest->getInvites());
+ window_->setOriginator(inviteToMUCRequest->getOriginator());
+ }
+ return;
+ }
}
void UserSearchController::handleFormRequested(const JID& service) {
- window_->setSearchError(false);
- window_->setServerSupportsSearch(true);
-
- //Abort a previous search if is active
- endDiscoWalker();
- delete discoWalker_;
- discoWalker_ = new DiscoServiceWalker(service, iqRouter_);
- discoWalker_->onServiceFound.connect(boost::bind(&UserSearchController::handleDiscoServiceFound, this, _1, _2));
- discoWalker_->onWalkComplete.connect(boost::bind(&UserSearchController::handleDiscoWalkFinished, this));
- discoWalker_->beginWalk();
+ window_->setSearchError(false);
+ window_->setServerSupportsSearch(true);
+
+ //Abort a previous search if is active
+ endDiscoWalker();
+ delete discoWalker_;
+ discoWalker_ = new DiscoServiceWalker(service, iqRouter_);
+ discoWalker_->onServiceFound.connect(boost::bind(&UserSearchController::handleDiscoServiceFound, this, _1, _2));
+ discoWalker_->onWalkComplete.connect(boost::bind(&UserSearchController::handleDiscoWalkFinished, this));
+ discoWalker_->beginWalk();
}
void UserSearchController::endDiscoWalker() {
- if (discoWalker_) {
- discoWalker_->endWalk();
- discoWalker_->onServiceFound.disconnect(boost::bind(&UserSearchController::handleDiscoServiceFound, this, _1, _2));
- discoWalker_->onWalkComplete.disconnect(boost::bind(&UserSearchController::handleDiscoWalkFinished, this));
- }
+ if (discoWalker_) {
+ discoWalker_->endWalk();
+ discoWalker_->onServiceFound.disconnect(boost::bind(&UserSearchController::handleDiscoServiceFound, this, _1, _2));
+ discoWalker_->onWalkComplete.disconnect(boost::bind(&UserSearchController::handleDiscoWalkFinished, this));
+ }
}
-void UserSearchController::handleDiscoServiceFound(const JID& jid, boost::shared_ptr<DiscoInfo> info) {
- //bool isUserDirectory = false;
- bool supports55 = false;
- foreach (DiscoInfo::Identity identity, info->getIdentities()) {
- if ((identity.getCategory() == "directory"
- && identity.getType() == "user")) {
- //isUserDirectory = true;
- }
- }
- std::vector<std::string> features = info->getFeatures();
- supports55 = std::find(features.begin(), features.end(), DiscoInfo::JabberSearchFeature) != features.end();
- if (/*isUserDirectory && */supports55) { //FIXME: once M-Link correctly advertises directoryness.
- /* Abort further searches.*/
- endDiscoWalker();
- boost::shared_ptr<GenericRequest<SearchPayload> > searchRequest(new GenericRequest<SearchPayload>(IQ::Get, jid, boost::make_shared<SearchPayload>(), iqRouter_));
- searchRequest->onResponse.connect(boost::bind(&UserSearchController::handleFormResponse, this, _1, _2));
- searchRequest->send();
- }
+void UserSearchController::handleDiscoServiceFound(const JID& jid, std::shared_ptr<DiscoInfo> info) {
+ //bool isUserDirectory = false;
+ bool supports55 = false;
+ // TODO: Cleanup code
+ for (const auto& identity : info->getIdentities()) {
+ if ((identity.getCategory() == "directory"
+ && identity.getType() == "user")) {
+ //isUserDirectory = true;
+ }
+ }
+ std::vector<std::string> features = info->getFeatures();
+ supports55 = std::find(features.begin(), features.end(), DiscoInfo::JabberSearchFeature) != features.end();
+ if (/*isUserDirectory && */supports55) { //FIXME: once M-Link correctly advertises directoryness.
+ /* Abort further searches.*/
+ endDiscoWalker();
+ std::shared_ptr<GenericRequest<SearchPayload> > searchRequest(new GenericRequest<SearchPayload>(IQ::Get, jid, std::make_shared<SearchPayload>(), iqRouter_));
+ searchRequest->onResponse.connect(boost::bind(&UserSearchController::handleFormResponse, this, _1, _2));
+ searchRequest->send();
+ }
}
-void UserSearchController::handleFormResponse(boost::shared_ptr<SearchPayload> fields, ErrorPayload::ref error) {
- if (error || !fields) {
- window_->setServerSupportsSearch(false);
- return;
- }
- window_->setSearchFields(fields);
+void UserSearchController::handleFormResponse(std::shared_ptr<SearchPayload> fields, ErrorPayload::ref error) {
+ if (error || !fields) {
+ window_->setServerSupportsSearch(false);
+ return;
+ }
+ window_->setSearchFields(fields);
}
-void UserSearchController::handleSearch(boost::shared_ptr<SearchPayload> fields, const JID& jid) {
- addToSavedDirectories(jid);
- boost::shared_ptr<GenericRequest<SearchPayload> > searchRequest(new GenericRequest<SearchPayload>(IQ::Set, jid, fields, iqRouter_));
- searchRequest->onResponse.connect(boost::bind(&UserSearchController::handleSearchResponse, this, _1, _2));
- searchRequest->send();
+void UserSearchController::handleSearch(std::shared_ptr<SearchPayload> fields, const JID& jid) {
+ addToSavedDirectories(jid);
+ std::shared_ptr<GenericRequest<SearchPayload> > searchRequest(new GenericRequest<SearchPayload>(IQ::Set, jid, fields, iqRouter_));
+ searchRequest->onResponse.connect(boost::bind(&UserSearchController::handleSearchResponse, this, _1, _2));
+ searchRequest->send();
}
-void UserSearchController::handleSearchResponse(boost::shared_ptr<SearchPayload> resultsPayload, ErrorPayload::ref error) {
- if (error || !resultsPayload) {
- window_->setSearchError(true);
- return;
- }
-
- std::vector<UserSearchResult> results;
-
- if (resultsPayload->getForm()) {
- window_->setResultsForm(resultsPayload->getForm());
- } else {
- foreach (SearchPayload::Item item, resultsPayload->getItems()) {
- JID jid(item.jid);
- std::map<std::string, std::string> fields;
- fields["first"] = item.first;
- fields["last"] = item.last;
- fields["nick"] = item.nick;
- fields["email"] = item.email;
- UserSearchResult result(jid, fields);
- results.push_back(result);
- }
- window_->setResults(results);
- }
+void UserSearchController::handleSearchResponse(std::shared_ptr<SearchPayload> resultsPayload, ErrorPayload::ref error) {
+ if (error || !resultsPayload) {
+ window_->setSearchError(true);
+ return;
+ }
+
+ std::vector<UserSearchResult> results;
+
+ if (resultsPayload->getForm()) {
+ window_->setResultsForm(resultsPayload->getForm());
+ } else {
+ for (auto&& item : resultsPayload->getItems()) {
+ JID jid(item.jid);
+ std::map<std::string, std::string> fields;
+ fields["first"] = item.first;
+ fields["last"] = item.last;
+ fields["nick"] = item.nick;
+ fields["email"] = item.email;
+ UserSearchResult result(jid, fields);
+ results.push_back(result);
+ }
+ window_->setResults(results);
+ }
}
void UserSearchController::handleNameSuggestionRequest(const JID &jid) {
- suggestionsJID_= jid;
- VCard::ref vcard = vcardManager_->getVCardAndRequestWhenNeeded(jid);
- if (vcard) {
- handleVCardChanged(jid, vcard);
- }
+ suggestionsJID_= jid;
+ VCard::ref vcard = vcardManager_->getVCardAndRequestWhenNeeded(jid);
+ if (vcard) {
+ handleVCardChanged(jid, vcard);
+ }
}
void UserSearchController::handleJIDEditingFinished(const JID& jid) {
- if (jid.isValid()) {
- if (rosterController_->getItem(jid)) {
- window_->setWarning(QT_TRANSLATE_NOOP("", "This contact is already on your contact list."));
- }
- else if (jid.getNode().empty()) {
- window_->setWarning(QT_TRANSLATE_NOOP("", "Part of the address you have entered is missing. An address has a structure of 'user@example.com'."));
- }
- else {
- window_->setWarning(boost::optional<std::string>());
- }
- }
- else {
- window_->setWarning(QT_TRANSLATE_NOOP("", "The address you have entered is invalid."));
- }
+ if (jid.isValid()) {
+ if (rosterController_->getItem(jid)) {
+ window_->setWarning(QT_TRANSLATE_NOOP("", "This contact is already on your contact list."));
+ }
+ else if (jid.getNode().empty()) {
+ window_->setWarning(QT_TRANSLATE_NOOP("", "Part of the address you have entered is missing. An address has a structure of 'user@example.com'."));
+ }
+ else {
+ window_->setWarning(boost::optional<std::string>());
+ }
+ }
+ else {
+ window_->setWarning(QT_TRANSLATE_NOOP("", "The address you have entered is invalid."));
+ }
}
void UserSearchController::handleContactSuggestionsRequested(std::string text) {
- const std::vector<JID> existingJIDs = window_->getJIDs();
- std::vector<Contact::ref> suggestions = contactSuggester_->getSuggestions(text, false);
- /* do not suggest contacts that have already been added to the chat list */
- std::vector<Contact::ref>::iterator i = suggestions.begin();
- while (i != suggestions.end()) {
- bool found = false;
- foreach (const JID& jid, existingJIDs) {
- if ((*i)->jid == jid) {
- found = true;
- break;
- }
- }
-
- // remove contact suggestions which are already on the contact list in add-contact-mode
- if (type_ == AddContact) {
- if (!found && !!rosterController_->getItem((*i)->jid)) {
- found = true;
- }
- }
-
- if (found) {
- i = suggestions.erase(i);
- } else {
- i++;
- }
- }
- window_->setContactSuggestions(suggestions);
+ const std::vector<JID> existingJIDs = window_->getJIDs();
+ std::vector<Contact::ref> suggestions = contactSuggester_->getSuggestions(text, false);
+ /* do not suggest contacts that have already been added to the chat list */
+ std::vector<Contact::ref>::iterator i = suggestions.begin();
+ while (i != suggestions.end()) {
+ bool found = false;
+ for (const auto& jid : existingJIDs) {
+ if ((*i)->jid == jid) {
+ found = true;
+ break;
+ }
+ }
+
+ // remove contact suggestions which are already on the contact list in add-contact-mode
+ if (type_ == AddContact) {
+ if (!found && !!rosterController_->getItem((*i)->jid)) {
+ found = true;
+ }
+ }
+
+ if (found) {
+ i = suggestions.erase(i);
+ } else {
+ i++;
+ }
+ }
+ window_->setContactSuggestions(suggestions);
}
void UserSearchController::handleVCardChanged(const JID& jid, VCard::ref vcard) {
- if (jid == suggestionsJID_) {
- window_->setNameSuggestions(ContactEditController::nameSuggestionsFromVCard(vcard));
- suggestionsJID_ = JID();
- }
- handleJIDUpdateRequested(std::vector<JID>(1, jid));
+ if (jid == suggestionsJID_) {
+ window_->setNameSuggestions(ContactEditController::nameSuggestionsFromVCard(vcard));
+ suggestionsJID_ = JID();
+ }
+ handleJIDUpdateRequested(std::vector<JID>(1, jid));
}
void UserSearchController::handleAvatarChanged(const JID& jid) {
- handleJIDUpdateRequested(std::vector<JID>(1, jid));
+ handleJIDUpdateRequested(std::vector<JID>(1, jid));
}
void UserSearchController::handlePresenceChanged(Presence::ref presence) {
- handleJIDUpdateRequested(std::vector<JID>(1, presence->getFrom().toBare()));
+ handleJIDUpdateRequested(std::vector<JID>(1, presence->getFrom().toBare()));
}
void UserSearchController::handleJIDUpdateRequested(const std::vector<JID>& jids) {
- if (window_) {
- std::vector<Contact::ref> updates;
- foreach(const JID& jid, jids) {
- updates.push_back(convertJIDtoContact(jid));
- }
- window_->updateContacts(updates);
- }
+ if (window_) {
+ std::vector<Contact::ref> updates;
+ for (const auto& jid : jids) {
+ updates.push_back(convertJIDtoContact(jid));
+ }
+ window_->updateContacts(updates);
+ }
}
void UserSearchController::handleJIDAddRequested(const std::vector<JID>& jids) {
- std::vector<Contact::ref> contacts;
- foreach(const JID& jid, jids) {
- contacts.push_back(convertJIDtoContact(jid));
- }
- window_->addContacts(contacts);
+ std::vector<Contact::ref> contacts;
+ for (const auto& jid : jids) {
+ contacts.push_back(convertJIDtoContact(jid));
+ }
+ window_->addContacts(contacts);
}
Contact::ref UserSearchController::convertJIDtoContact(const JID& jid) {
- Contact::ref contact = boost::make_shared<Contact>();
- contact->jid = jid;
-
- // name lookup
- boost::optional<XMPPRosterItem> rosterItem = rosterController_->getItem(jid);
- if (rosterItem && !rosterItem->getName().empty()) {
- contact->name = rosterItem->getName();
- } else {
- VCard::ref vcard = vcardManager_->getVCard(jid);
- if (vcard && !vcard->getFullName().empty()) {
- contact->name = vcard->getFullName();
- } else {
- contact->name = jid.toString();
- }
- }
-
- // presence lookup
- Presence::ref presence = presenceOracle_->getAccountPresence(jid);
- if (presence) {
- contact->statusType = presence->getShow();
- } else {
- contact->statusType = StatusShow::None;
- }
-
- // avatar lookup
- contact->avatarPath = avatarManager_->getAvatarPath(jid);
- return contact;
+ Contact::ref contact = std::make_shared<Contact>();
+ contact->jid = jid;
+
+ // name lookup
+ boost::optional<XMPPRosterItem> rosterItem = rosterController_->getItem(jid);
+ if (rosterItem && !rosterItem->getName().empty()) {
+ contact->name = rosterItem->getName();
+ } else {
+ VCard::ref vcard = vcardManager_->getVCard(jid);
+ if (vcard && !vcard->getFullName().empty()) {
+ contact->name = vcard->getFullName();
+ } else {
+ contact->name = jid.toString();
+ }
+ }
+
+ // presence lookup
+ Presence::ref presence = presenceOracle_->getAccountPresence(jid);
+ if (presence) {
+ contact->statusType = presence->getShow();
+ } else {
+ contact->statusType = StatusShow::None;
+ }
+
+ // avatar lookup
+ contact->avatarPath = avatarManager_->getAvatarPath(jid);
+ return contact;
}
void UserSearchController::handleDiscoWalkFinished() {
- window_->setServerSupportsSearch(false);
- endDiscoWalker();
+ window_->setServerSupportsSearch(false);
+ endDiscoWalker();
}
void UserSearchController::initializeUserWindow() {
- if (!window_) {
- UserSearchWindow::Type windowType = UserSearchWindow::AddContact;
- switch(type_) {
- case AddContact:
- windowType = UserSearchWindow::AddContact;
- break;
- case StartChat:
- windowType = UserSearchWindow::ChatToContact;
- break;
- case InviteToChat:
- windowType = UserSearchWindow::InviteToChat;
- break;
- }
-
- window_ = factory_->createUserSearchWindow(windowType, uiEventStream_, rosterController_->getGroups());
- if (!window_) {
- // UI Doesn't support user search
- return;
- }
- window_->onNameSuggestionRequested.connect(boost::bind(&UserSearchController::handleNameSuggestionRequest, this, _1));
- window_->onFormRequested.connect(boost::bind(&UserSearchController::handleFormRequested, this, _1));
- window_->onSearchRequested.connect(boost::bind(&UserSearchController::handleSearch, this, _1, _2));
- window_->onContactSuggestionsRequested.connect(boost::bind(&UserSearchController::handleContactSuggestionsRequested, this, _1));
- window_->onJIDUpdateRequested.connect(boost::bind(&UserSearchController::handleJIDUpdateRequested, this, _1));
- window_->onJIDAddRequested.connect(boost::bind(&UserSearchController::handleJIDAddRequested, this, _1));
- window_->onJIDEditFieldChanged.connect(boost::bind(&UserSearchController::handleJIDEditingFinished, this, _1));
- window_->setSelectedService(JID(jid_.getDomain()));
- window_->clear();
- }
+ if (!window_) {
+ UserSearchWindow::Type windowType = UserSearchWindow::AddContact;
+ switch(type_) {
+ case AddContact:
+ windowType = UserSearchWindow::AddContact;
+ break;
+ case StartChat:
+ windowType = UserSearchWindow::ChatToContact;
+ break;
+ case InviteToChat:
+ windowType = UserSearchWindow::InviteToChat;
+ break;
+ }
+
+ window_ = factory_->createUserSearchWindow(windowType, uiEventStream_, rosterController_->getGroups());
+ if (!window_) {
+ // UI Doesn't support user search
+ return;
+ }
+ window_->onNameSuggestionRequested.connect(boost::bind(&UserSearchController::handleNameSuggestionRequest, this, _1));
+ window_->onFormRequested.connect(boost::bind(&UserSearchController::handleFormRequested, this, _1));
+ window_->onSearchRequested.connect(boost::bind(&UserSearchController::handleSearch, this, _1, _2));
+ window_->onContactSuggestionsRequested.connect(boost::bind(&UserSearchController::handleContactSuggestionsRequested, this, _1));
+ window_->onJIDUpdateRequested.connect(boost::bind(&UserSearchController::handleJIDUpdateRequested, this, _1));
+ window_->onJIDAddRequested.connect(boost::bind(&UserSearchController::handleJIDAddRequested, this, _1));
+ window_->onJIDEditFieldChanged.connect(boost::bind(&UserSearchController::handleJIDEditingFinished, this, _1));
+ window_->setSelectedService(JID(jid_.getDomain()));
+ window_->clear();
+ }
}
void UserSearchController::loadSavedDirectories() {
- savedDirectories_.clear();
- foreach (std::string stringItem, String::split(settings_->getStringSetting(SEARCHED_DIRECTORIES), '\n')) {
- if(!stringItem.empty()) {
- savedDirectories_.push_back(JID(stringItem));
- }
- }
+ savedDirectories_.clear();
+ for (auto&& stringItem : String::split(settings_->getStringSetting(SEARCHED_DIRECTORIES), '\n')) {
+ if(!stringItem.empty()) {
+ savedDirectories_.push_back(JID(stringItem));
+ }
+ }
}
void UserSearchController::addToSavedDirectories(const JID& jid) {
- if (!jid.isValid()) {
- return;
- }
-
- savedDirectories_.erase(std::remove(savedDirectories_.begin(), savedDirectories_.end(), jid), savedDirectories_.end());
- savedDirectories_.insert(savedDirectories_.begin(), jid);
-
- std::string collapsed;
- int i = 0;
- foreach (JID jidItem, savedDirectories_) {
- if (i >= 15) {
- break;
- }
- if (!collapsed.empty()) {
- collapsed += "\n";
- }
- collapsed += jidItem.toString();
- ++i;
- }
- settings_->storeString(SEARCHED_DIRECTORIES, collapsed);
- window_->addSavedServices(savedDirectories_);
+ if (!jid.isValid()) {
+ return;
+ }
+
+ savedDirectories_.erase(std::remove(savedDirectories_.begin(), savedDirectories_.end(), jid), savedDirectories_.end());
+ savedDirectories_.insert(savedDirectories_.begin(), jid);
+
+ std::string collapsed;
+ int i = 0;
+ for (const auto& jidItem : savedDirectories_) {
+ if (i >= 15) {
+ break;
+ }
+ if (!collapsed.empty()) {
+ collapsed += "\n";
+ }
+ collapsed += jidItem.toString();
+ ++i;
+ }
+ settings_->storeString(SEARCHED_DIRECTORIES, collapsed);
+ window_->addSavedServices(savedDirectories_);
}
}
diff --git a/Swift/Controllers/Chat/UserSearchController.h b/Swift/Controllers/Chat/UserSearchController.h
index 0423a65..4658301 100644
--- a/Swift/Controllers/Chat/UserSearchController.h
+++ b/Swift/Controllers/Chat/UserSearchController.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,12 +7,12 @@
#pragma once
#include <map>
+#include <memory>
#include <string>
#include <vector>
-#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
-#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Elements/DiscoInfo.h>
#include <Swiften/Elements/DiscoItems.h>
#include <Swiften/Elements/ErrorPayload.h>
@@ -24,76 +24,76 @@
#include <Swift/Controllers/Contact.h>
namespace Swift {
- class UIEventStream;
- class UIEvent;
- class UserSearchWindow;
- class UserSearchWindowFactory;
- class IQRouter;
- class DiscoServiceWalker;
- class RosterController;
- class VCardManager;
- class ContactSuggester;
- class AvatarManager;
- class PresenceOracle;
- class ProfileSettingsProvider;
+ class UIEventStream;
+ class UIEvent;
+ class UserSearchWindow;
+ class UserSearchWindowFactory;
+ class IQRouter;
+ class DiscoServiceWalker;
+ class RosterController;
+ class VCardManager;
+ class ContactSuggester;
+ class AvatarManager;
+ class PresenceOracle;
+ class ProfileSettingsProvider;
- class UserSearchResult {
- public:
- UserSearchResult(const JID& jid, const std::map<std::string, std::string>& fields) : jid_(jid), fields_(fields) {}
- const JID& getJID() const {return jid_;}
- const std::map<std::string, std::string>& getFields() const {return fields_;}
- private:
- JID jid_;
- std::map<std::string, std::string> fields_;
- };
+ class UserSearchResult {
+ public:
+ UserSearchResult(const JID& jid, const std::map<std::string, std::string>& fields) : jid_(jid), fields_(fields) {}
+ const JID& getJID() const {return jid_;}
+ const std::map<std::string, std::string>& getFields() const {return fields_;}
+ private:
+ JID jid_;
+ std::map<std::string, std::string> fields_;
+ };
- class UserSearchController {
- public:
- enum Type {AddContact, StartChat, InviteToChat};
- UserSearchController(Type type, const JID& jid, UIEventStream* uiEventStream, VCardManager* vcardManager, UserSearchWindowFactory* userSearchWindowFactory, IQRouter* iqRouter, RosterController* rosterController, ContactSuggester* contactSuggester, AvatarManager* avatarManager, PresenceOracle* presenceOracle, ProfileSettingsProvider* settings);
- ~UserSearchController();
+ class UserSearchController {
+ public:
+ enum Type {AddContact, StartChat, InviteToChat};
+ UserSearchController(Type type, const JID& jid, UIEventStream* uiEventStream, VCardManager* vcardManager, UserSearchWindowFactory* userSearchWindowFactory, IQRouter* iqRouter, RosterController* rosterController, ContactSuggester* contactSuggester, AvatarManager* avatarManager, PresenceOracle* presenceOracle, ProfileSettingsProvider* settings);
+ ~UserSearchController();
- UserSearchWindow* getUserSearchWindow();
- void setCanInitiateImpromptuMUC(bool supportsImpromptu);
+ UserSearchWindow* getUserSearchWindow();
+ void setCanInitiateImpromptuMUC(bool supportsImpromptu);
- private:
- void handleUIEvent(boost::shared_ptr<UIEvent> event);
- void handleFormRequested(const JID& service);
- void handleDiscoServiceFound(const JID& jid, boost::shared_ptr<DiscoInfo> info);
- void handleDiscoWalkFinished();
- void handleFormResponse(boost::shared_ptr<SearchPayload> items, ErrorPayload::ref error);
- void handleSearch(boost::shared_ptr<SearchPayload> fields, const JID& jid);
- void handleSearchResponse(boost::shared_ptr<SearchPayload> results, ErrorPayload::ref error);
- void handleNameSuggestionRequest(const JID& jid);
- void handleContactSuggestionsRequested(std::string text);
- void handleVCardChanged(const JID& jid, VCard::ref vcard);
- void handleAvatarChanged(const JID& jid);
- void handlePresenceChanged(Presence::ref presence);
- void handleJIDUpdateRequested(const std::vector<JID>& jids);
- void handleJIDAddRequested(const std::vector<JID>& jids);
- void handleJIDEditingFinished(const JID& jid);
- Contact::ref convertJIDtoContact(const JID& jid);
- void endDiscoWalker();
- void initializeUserWindow();
+ private:
+ void handleUIEvent(std::shared_ptr<UIEvent> event);
+ void handleFormRequested(const JID& service);
+ void handleDiscoServiceFound(const JID& jid, std::shared_ptr<DiscoInfo> info);
+ void handleDiscoWalkFinished();
+ void handleFormResponse(std::shared_ptr<SearchPayload> items, ErrorPayload::ref error);
+ void handleSearch(std::shared_ptr<SearchPayload> fields, const JID& jid);
+ void handleSearchResponse(std::shared_ptr<SearchPayload> results, ErrorPayload::ref error);
+ void handleNameSuggestionRequest(const JID& jid);
+ void handleContactSuggestionsRequested(std::string text);
+ void handleVCardChanged(const JID& jid, VCard::ref vcard);
+ void handleAvatarChanged(const JID& jid);
+ void handlePresenceChanged(Presence::ref presence);
+ void handleJIDUpdateRequested(const std::vector<JID>& jids);
+ void handleJIDAddRequested(const std::vector<JID>& jids);
+ void handleJIDEditingFinished(const JID& jid);
+ Contact::ref convertJIDtoContact(const JID& jid);
+ void endDiscoWalker();
+ void initializeUserWindow();
- void loadSavedDirectories();
- void addToSavedDirectories(const JID& jid);
+ void loadSavedDirectories();
+ void addToSavedDirectories(const JID& jid);
- private:
- Type type_;
- JID jid_;
- JID suggestionsJID_;
- UIEventStream* uiEventStream_;
- VCardManager* vcardManager_;
- UserSearchWindowFactory* factory_;
- IQRouter* iqRouter_;
- RosterController* rosterController_;
- UserSearchWindow* window_;
- DiscoServiceWalker* discoWalker_;
- ContactSuggester* contactSuggester_;
- AvatarManager* avatarManager_;
- PresenceOracle* presenceOracle_;
- std::vector<JID> savedDirectories_;
- ProfileSettingsProvider* settings_;
- };
+ private:
+ Type type_;
+ JID jid_;
+ JID suggestionsJID_;
+ UIEventStream* uiEventStream_;
+ VCardManager* vcardManager_;
+ UserSearchWindowFactory* factory_;
+ IQRouter* iqRouter_;
+ RosterController* rosterController_;
+ UserSearchWindow* window_;
+ DiscoServiceWalker* discoWalker_;
+ ContactSuggester* contactSuggester_;
+ AvatarManager* avatarManager_;
+ PresenceOracle* presenceOracle_;
+ std::vector<JID> savedDirectories_;
+ ProfileSettingsProvider* settings_;
+ };
}
diff --git a/Swift/Controllers/ChatMessageSummarizer.cpp b/Swift/Controllers/ChatMessageSummarizer.cpp
index 34524ac..ac3d896 100644
--- a/Swift/Controllers/ChatMessageSummarizer.cpp
+++ b/Swift/Controllers/ChatMessageSummarizer.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2013 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,39 +7,39 @@
#include <Swift/Controllers/ChatMessageSummarizer.h>
#include <Swiften/Base/format.h>
+
#include <Swift/Controllers/Intl.h>
-#include <Swiften/Base/foreach.h>
using namespace Swift;
using namespace std;
string ChatMessageSummarizer::getSummary(const string& current, const vector<UnreadPair>& unreads) {
- vector<UnreadPair> others;
- int currentUnread = 0;
- int otherCount = 0;
- foreach (UnreadPair unread, unreads) {
- if (unread.first == current) {
- currentUnread += unread.second;
- } else {
- if (unread.second > 0) {
- otherCount += unread.second;
- others.push_back(unread);
- }
- }
- }
- string myString(current);
+ vector<UnreadPair> others;
+ int currentUnread = 0;
+ int otherCount = 0;
+ for (const auto& unread : unreads) {
+ if (unread.first == current) {
+ currentUnread += unread.second;
+ } else {
+ if (unread.second > 0) {
+ otherCount += unread.second;
+ others.push_back(unread);
+ }
+ }
+ }
+ string myString(current);
- if (currentUnread > 0) {
- string result(QT_TRANSLATE_NOOP("", "%1% (%2%)"));
- myString = str(format(result) % current % currentUnread);
- }
+ if (currentUnread > 0) {
+ string result(QT_TRANSLATE_NOOP("", "%1% (%2%)"));
+ myString = str(format(result) % current % currentUnread);
+ }
- if (others.size() > 1) {
- string result(QT_TRANSLATE_NOOP("", "%1% and %2% others (%3%)"));
- myString = str(format(result) % myString % others.size() % otherCount);
- } else if (!others.empty()) {
- string result(QT_TRANSLATE_NOOP("", "%1%; %2% (%3%)"));
- myString = str(format(result) % myString % others[0].first % otherCount);
- }
- return myString;
+ if (others.size() > 1) {
+ string result(QT_TRANSLATE_NOOP("", "%1% and %2% others (%3%)"));
+ myString = str(format(result) % myString % others.size() % otherCount);
+ } else if (!others.empty()) {
+ string result(QT_TRANSLATE_NOOP("", "%1%; %2% (%3%)"));
+ myString = str(format(result) % myString % others[0].first % otherCount);
+ }
+ return myString;
}
diff --git a/Swift/Controllers/ChatMessageSummarizer.h b/Swift/Controllers/ChatMessageSummarizer.h
index aab7bc6..0b4df21 100644
--- a/Swift/Controllers/ChatMessageSummarizer.h
+++ b/Swift/Controllers/ChatMessageSummarizer.h
@@ -1,20 +1,20 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <vector>
-#include <utility>
#include <string>
+#include <utility>
+#include <vector>
namespace Swift {
typedef std::pair<std::string, int> UnreadPair;
- class ChatMessageSummarizer {
- public:
- std::string getSummary(const std::string& current, const std::vector<UnreadPair>& unreads);
- };
+ class ChatMessageSummarizer {
+ public:
+ std::string getSummary(const std::string& current, const std::vector<UnreadPair>& unreads);
+ };
}
diff --git a/Swift/Controllers/ConnectionSettings.h b/Swift/Controllers/ConnectionSettings.h
index 6a2fded..7ce45cd 100644
--- a/Swift/Controllers/ConnectionSettings.h
+++ b/Swift/Controllers/ConnectionSettings.h
@@ -9,32 +9,32 @@
#include <string>
struct ConnectionSettings {
- enum Method {
- Automatic,
- Manual,
- BOSH
- };
- enum ProxyType {
- None,
- System,
- SOCKS5,
- HTTPConnect
- };
+ enum Method {
+ Automatic,
+ Manual,
+ BOSH
+ };
+ enum ProxyType {
+ None,
+ System,
+ SOCKS5,
+ HTTPConnect
+ };
- Method method;
- struct {
- bool useManualServer;
- std::string manualServerHostname;
- int manualServerPort;
- ProxyType proxyType;
- bool useManualProxy;
- std::string manualProxyHostname;
- int manualProxyPort;
- } manualSettings;
- struct {
- std::string boshURI;
- bool useManualProxy;
- std::string manualProxyHostname;
- int manualProxyPort;
- } boshSettings;
+ Method method;
+ struct {
+ bool useManualServer;
+ std::string manualServerHostname;
+ int manualServerPort;
+ ProxyType proxyType;
+ bool useManualProxy;
+ std::string manualProxyHostname;
+ int manualProxyPort;
+ } manualSettings;
+ struct {
+ std::string boshURI;
+ bool useManualProxy;
+ std::string manualProxyHostname;
+ int manualProxyPort;
+ } boshSettings;
};
diff --git a/Swift/Controllers/Contact.cpp b/Swift/Controllers/Contact.cpp
index b3e27f1..b9b98c3 100644
--- a/Swift/Controllers/Contact.cpp
+++ b/Swift/Controllers/Contact.cpp
@@ -4,9 +4,16 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/Controllers/Contact.h>
+
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/find.hpp>
-#include <Swift/Controllers/Contact.h>
namespace Swift {
@@ -17,54 +24,54 @@ Contact::Contact(const std::string& name, const JID& jid, StatusShow::Type statu
}
bool Contact::lexicographicalSortPredicate(const Contact::ref& a, const Contact::ref& b) {
- if (a->jid.isValid() && b->jid.isValid()) {
- return a->jid < b->jid;
- } else {
- return a->name < b->name;
- }
+ if (a->jid.isValid() && b->jid.isValid()) {
+ return a->jid < b->jid;
+ } else {
+ return a->name < b->name;
+ }
}
bool Contact::equalityPredicate(const Contact::ref& a, const Contact::ref& b) {
- if (a->jid.isValid() && b->jid.isValid()) {
- return a->jid == b->jid;
- } else {
- return a->name == b->name;
- }
+ if (a->jid.isValid() && b->jid.isValid()) {
+ return a->jid == b->jid;
+ } else {
+ return a->name == b->name;
+ }
}
bool Contact::sortPredicate(const Contact::ref& a, const Contact::ref& b, const std::string& search) {
- /* perform case insensitive comparisons */
- std::string aLower = a->name;
- boost::to_lower(aLower);
- std::string bLower = b->name;
- boost::to_lower(bLower);
- std::string searchLower = search;
- boost::to_lower(searchLower);
+ /* perform case insensitive comparisons */
+ std::string aLower = a->name;
+ boost::to_lower(aLower);
+ std::string bLower = b->name;
+ boost::to_lower(bLower);
+ std::string searchLower = search;
+ boost::to_lower(searchLower);
- /* name starts with the search term */
- if (aLower.find(searchLower) == 0 && bLower.find(searchLower) != 0) {
- return true;
- } else if (bLower.find(searchLower) == 0 && aLower.find(searchLower) != 0) {
- return false;
- }
+ /* name starts with the search term */
+ if (aLower.find(searchLower) == 0 && bLower.find(searchLower) != 0) {
+ return true;
+ } else if (bLower.find(searchLower) == 0 && aLower.find(searchLower) != 0) {
+ return false;
+ }
- /* name contains search term */
- if (aLower.find(searchLower) != std::string::npos && bLower.find(searchLower) == std::string::npos) {
- return true;
- } else if (bLower.find(searchLower) != std::string::npos && aLower.find(searchLower) == std::string::npos) {
- return false;
- }
+ /* name contains search term */
+ if (aLower.find(searchLower) != std::string::npos && bLower.find(searchLower) == std::string::npos) {
+ return true;
+ } else if (bLower.find(searchLower) != std::string::npos && aLower.find(searchLower) == std::string::npos) {
+ return false;
+ }
- /* Levenshtein should be done here */
- /* if edit distances are equal, fall through to the tests below */
+ /* Levenshtein should be done here */
+ /* if edit distances are equal, fall through to the tests below */
- /* lexicographical sort */
- if (a->statusType == b->statusType) {
- return aLower.compare(bLower) < 0;
- }
+ /* lexicographical sort */
+ if (a->statusType == b->statusType) {
+ return aLower.compare(bLower) < 0;
+ }
- /* online status */
- return a->statusType < b->statusType;
+ /* online status */
+ return a->statusType < b->statusType;
}
}
diff --git a/Swift/Controllers/Contact.h b/Swift/Controllers/Contact.h
index b03a118..47dda43 100644
--- a/Swift/Controllers/Contact.h
+++ b/Swift/Controllers/Contact.h
@@ -5,14 +5,15 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/enable_shared_from_this.hpp>
+#include <memory>
+
#include <boost/filesystem/path.hpp>
#include <Swiften/Elements/StatusShow.h>
@@ -20,22 +21,22 @@
namespace Swift {
-class Contact : public boost::enable_shared_from_this<Contact> {
- public:
- typedef boost::shared_ptr<Contact> ref;
+class Contact : public std::enable_shared_from_this<Contact> {
+ public:
+ typedef std::shared_ptr<Contact> ref;
- Contact();
- Contact(const std::string& name, const JID& jid, StatusShow::Type statusType, const boost::filesystem::path& path);
+ Contact();
+ Contact(const std::string& name, const JID& jid, StatusShow::Type statusType, const boost::filesystem::path& path);
- static bool lexicographicalSortPredicate(const Contact::ref& a, const Contact::ref& b);
- static bool equalityPredicate(const Contact::ref& a, const Contact::ref& b);
- static bool sortPredicate(const Contact::ref& a, const Contact::ref& b, const std::string& search);
+ static bool lexicographicalSortPredicate(const Contact::ref& a, const Contact::ref& b);
+ static bool equalityPredicate(const Contact::ref& a, const Contact::ref& b);
+ static bool sortPredicate(const Contact::ref& a, const Contact::ref& b, const std::string& search);
- public:
- std::string name;
- JID jid;
- StatusShow::Type statusType;
- boost::filesystem::path avatarPath;
+ public:
+ std::string name;
+ JID jid;
+ StatusShow::Type statusType;
+ boost::filesystem::path avatarPath;
};
}
diff --git a/Swift/Controllers/ContactEditController.cpp b/Swift/Controllers/ContactEditController.cpp
index 1163735..2ea1f7e 100644
--- a/Swift/Controllers/ContactEditController.cpp
+++ b/Swift/Controllers/ContactEditController.cpp
@@ -1,109 +1,110 @@
/*
- * Copyright (c) 2010-2012 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/ContactEditController.h>
+#include <memory>
+
#include <boost/algorithm/string.hpp>
#include <boost/bind.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <Swiften/VCards/VCardManager.h>
+
+#include <Swift/Controllers/Roster/RosterController.h>
+#include <Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestContactEditorUIEvent.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
-#include <Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h>
#include <Swift/Controllers/UIInterfaces/ContactEditWindowFactory.h>
-#include <Swift/Controllers/Roster/RosterController.h>
-#include <Swiften/VCards/VCardManager.h>
-
namespace Swift {
-ContactEditController::ContactEditController(RosterController* rosterController, VCardManager* vcardManager, ContactEditWindowFactory* contactEditWindowFactory, UIEventStream* uiEventStream) : rosterController(rosterController), vcardManager(vcardManager), contactEditWindowFactory(contactEditWindowFactory), uiEventStream(uiEventStream), contactEditWindow(NULL) {
- uiEventStream->onUIEvent.connect(boost::bind(&ContactEditController::handleUIEvent, this, _1));
- vcardManager->onVCardChanged.connect(boost::bind(&ContactEditController::handleVCardChanged, this, _1, _2));
+ContactEditController::ContactEditController(RosterController* rosterController, VCardManager* vcardManager, ContactEditWindowFactory* contactEditWindowFactory, UIEventStream* uiEventStream) : rosterController(rosterController), vcardManager(vcardManager), contactEditWindowFactory(contactEditWindowFactory), uiEventStream(uiEventStream), contactEditWindow(nullptr) {
+ uiEventStream->onUIEvent.connect(boost::bind(&ContactEditController::handleUIEvent, this, _1));
+ vcardManager->onVCardChanged.connect(boost::bind(&ContactEditController::handleVCardChanged, this, _1, _2));
}
ContactEditController::~ContactEditController() {
- if (contactEditWindow) {
- contactEditWindow->onChangeContactRequest.disconnect(boost::bind(&ContactEditController::handleChangeContactRequest, this, _1, _2));
- contactEditWindow->onRemoveContactRequest.disconnect(boost::bind(&ContactEditController::handleRemoveContactRequest, this));
- delete contactEditWindow;
- }
- uiEventStream->onUIEvent.disconnect(boost::bind(&ContactEditController::handleUIEvent, this, _1));
+ if (contactEditWindow) {
+ contactEditWindow->onChangeContactRequest.disconnect(boost::bind(&ContactEditController::handleChangeContactRequest, this, _1, _2));
+ contactEditWindow->onRemoveContactRequest.disconnect(boost::bind(&ContactEditController::handleRemoveContactRequest, this));
+ delete contactEditWindow;
+ }
+ uiEventStream->onUIEvent.disconnect(boost::bind(&ContactEditController::handleUIEvent, this, _1));
}
void ContactEditController::handleUIEvent(UIEvent::ref event) {
- RequestContactEditorUIEvent::ref editEvent = boost::dynamic_pointer_cast<RequestContactEditorUIEvent>(event);
- if (!editEvent) {
- return;
- }
-
- if (!contactEditWindow) {
- contactEditWindow = contactEditWindowFactory->createContactEditWindow();
- contactEditWindow->onRemoveContactRequest.connect(boost::bind(&ContactEditController::handleRemoveContactRequest, this));
- contactEditWindow->onChangeContactRequest.connect(boost::bind(&ContactEditController::handleChangeContactRequest, this, _1, _2));
- }
- currentContact = rosterController->getItem(editEvent->getJID());
- assert(currentContact);
- jid = rosterController->getItem(editEvent->getJID())->getJID();
- contactEditWindow->setContact(jid, currentContact->getName(), currentContact->getGroups(), rosterController->getGroups());
- contactEditWindow->show();
-
- if (vcardManager) {
- VCard::ref vcard = vcardManager->getVCardAndRequestWhenNeeded(jid);
- if (vcard) {
- handleVCardChanged(jid, vcard);
- }
- }
+ RequestContactEditorUIEvent::ref editEvent = std::dynamic_pointer_cast<RequestContactEditorUIEvent>(event);
+ if (!editEvent) {
+ return;
+ }
+
+ if (!contactEditWindow) {
+ contactEditWindow = contactEditWindowFactory->createContactEditWindow();
+ contactEditWindow->onRemoveContactRequest.connect(boost::bind(&ContactEditController::handleRemoveContactRequest, this));
+ contactEditWindow->onChangeContactRequest.connect(boost::bind(&ContactEditController::handleChangeContactRequest, this, _1, _2));
+ }
+ currentContact = rosterController->getItem(editEvent->getJID());
+ assert(currentContact);
+ jid = rosterController->getItem(editEvent->getJID())->getJID();
+ contactEditWindow->setContact(jid, currentContact->getName(), currentContact->getGroups(), rosterController->getGroups());
+ contactEditWindow->show();
+
+ if (vcardManager) {
+ VCard::ref vcard = vcardManager->getVCardAndRequestWhenNeeded(jid);
+ if (vcard) {
+ handleVCardChanged(jid, vcard);
+ }
+ }
}
void ContactEditController::handleVCardChanged(const JID &jid, VCard::ref vcard) {
- if (jid == this->jid) {
- contactEditWindow->setNameSuggestions(nameSuggestionsFromVCard(vcard));
- }
+ if (jid == this->jid) {
+ contactEditWindow->setNameSuggestions(nameSuggestionsFromVCard(vcard));
+ }
}
void ContactEditController::setAvailable(bool b) {
- if (contactEditWindow) {
- contactEditWindow->setEnabled(b);
- }
+ if (contactEditWindow) {
+ contactEditWindow->setEnabled(b);
+ }
}
std::vector<std::string> ContactEditController::nameSuggestionsFromVCard(VCard::ref vcard) {
- std::vector<std::string> suggestions;
- if (!vcard->getNickname().empty()) {
- suggestions.push_back(vcard->getNickname());
- }
- if (!vcard->getFullName().empty()) {
- suggestions.push_back(vcard->getFullName());
- }
- if (!vcard->getGivenName().empty()) {
- std::string suggestedName;
- suggestedName = vcard->getGivenName();
- boost::algorithm::trim(suggestedName);
- suggestions.push_back(suggestedName);
- }
- return suggestions;
+ std::vector<std::string> suggestions;
+ if (!vcard->getNickname().empty()) {
+ suggestions.push_back(vcard->getNickname());
+ }
+ if (!vcard->getFullName().empty()) {
+ suggestions.push_back(vcard->getFullName());
+ }
+ if (!vcard->getGivenName().empty()) {
+ std::string suggestedName;
+ suggestedName = vcard->getGivenName();
+ boost::algorithm::trim(suggestedName);
+ suggestions.push_back(suggestedName);
+ }
+ return suggestions;
}
void ContactEditController::handleRemoveContactRequest() {
- assert(currentContact);
- uiEventStream->send(boost::make_shared<RemoveRosterItemUIEvent>(currentContact->getJID()));
- contactEditWindow->hide();
+ assert(currentContact);
+ uiEventStream->send(std::make_shared<RemoveRosterItemUIEvent>(currentContact->getJID()));
+ contactEditWindow->hide();
}
void ContactEditController::handleChangeContactRequest(const std::string& name, const std::set<std::string>& newGroups) {
- std::vector<std::string> oldGroupsVector = currentContact->getGroups();
- std::set<std::string> oldGroups(oldGroupsVector.begin(), oldGroupsVector.end());
- if (oldGroups != newGroups || currentContact->getName() != name) {
- XMPPRosterItem newContact(*currentContact);
- newContact.setName(name);
- newContact.setGroups(std::vector<std::string>(newGroups.begin(), newGroups.end()));
- rosterController->updateItem(newContact);
- }
- contactEditWindow->hide();
+ std::vector<std::string> oldGroupsVector = currentContact->getGroups();
+ std::set<std::string> oldGroups(oldGroupsVector.begin(), oldGroupsVector.end());
+ if (oldGroups != newGroups || currentContact->getName() != name) {
+ XMPPRosterItem newContact(*currentContact);
+ newContact.setName(name);
+ newContact.setGroups(std::vector<std::string>(newGroups.begin(), newGroups.end()));
+ rosterController->updateItem(newContact);
+ }
+ contactEditWindow->hide();
}
}
diff --git a/Swift/Controllers/ContactEditController.h b/Swift/Controllers/ContactEditController.h
index 800da27..ab2b52e 100644
--- a/Swift/Controllers/ContactEditController.h
+++ b/Swift/Controllers/ContactEditController.h
@@ -1,54 +1,56 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <vector>
#include <set>
+#include <string>
+#include <vector>
+
#include <boost/optional.hpp>
-#include <Swiften/JID/JID.h>
-#include <string>
#include <Swiften/Elements/VCard.h>
-#include <Swift/Controllers/UIEvents/UIEvent.h>
+#include <Swiften/JID/JID.h>
#include <Swiften/Roster/XMPPRosterItem.h>
+#include <Swift/Controllers/UIEvents/UIEvent.h>
+
namespace Swift {
- class UIEventStream;
- class ContactEditWindowFactory;
- class ContactEditWindow;
- class RosterController;
- class VCardManager;
-
- class ContactEditController {
- public:
- ContactEditController(RosterController* rosterController, VCardManager* vcardManager, ContactEditWindowFactory* contactEditWindowFactory, UIEventStream* uiEventStream);
- ~ContactEditController();
-
- void setAvailable(bool b);
-
- public:
- static std::vector<std::string> nameSuggestionsFromVCard(VCard::ref vcard);
-
- private:
- void handleRemoveContactRequest();
- void handleChangeContactRequest(const std::string& name, const std::set<std::string>& groups);
-
- private:
- void handleUIEvent(UIEvent::ref event);
- void handleVCardChanged(const JID& jid, VCard::ref vcard);
-
- private:
- boost::optional<XMPPRosterItem> currentContact;
- RosterController* rosterController;
- VCardManager* vcardManager;
- ContactEditWindowFactory* contactEditWindowFactory;
- UIEventStream* uiEventStream;
- JID jid;
- ContactEditWindow* contactEditWindow;
- };
+ class UIEventStream;
+ class ContactEditWindowFactory;
+ class ContactEditWindow;
+ class RosterController;
+ class VCardManager;
+
+ class ContactEditController {
+ public:
+ ContactEditController(RosterController* rosterController, VCardManager* vcardManager, ContactEditWindowFactory* contactEditWindowFactory, UIEventStream* uiEventStream);
+ ~ContactEditController();
+
+ void setAvailable(bool b);
+
+ public:
+ static std::vector<std::string> nameSuggestionsFromVCard(VCard::ref vcard);
+
+ private:
+ void handleRemoveContactRequest();
+ void handleChangeContactRequest(const std::string& name, const std::set<std::string>& groups);
+
+ private:
+ void handleUIEvent(UIEvent::ref event);
+ void handleVCardChanged(const JID& jid, VCard::ref vcard);
+
+ private:
+ boost::optional<XMPPRosterItem> currentContact;
+ RosterController* rosterController;
+ VCardManager* vcardManager;
+ ContactEditWindowFactory* contactEditWindowFactory;
+ UIEventStream* uiEventStream;
+ JID jid;
+ ContactEditWindow* contactEditWindow;
+ };
}
diff --git a/Swift/Controllers/ContactProvider.h b/Swift/Controllers/ContactProvider.h
index 08812d5..423f8a3 100644
--- a/Swift/Controllers/ContactProvider.h
+++ b/Swift/Controllers/ContactProvider.h
@@ -19,9 +19,9 @@
namespace Swift {
class ContactProvider {
- public:
- virtual ~ContactProvider();
- virtual std::vector<Contact::ref> getContacts(bool withMUCNicks) = 0;
+ public:
+ virtual ~ContactProvider();
+ virtual std::vector<Contact::ref> getContacts(bool withMUCNicks) = 0;
};
}
diff --git a/Swift/Controllers/ContactSuggester.cpp b/Swift/Controllers/ContactSuggester.cpp
index 1f61286..eb27ed4 100644
--- a/Swift/Controllers/ContactSuggester.cpp
+++ b/Swift/Controllers/ContactSuggester.cpp
@@ -5,29 +5,28 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/ContactSuggester.h>
+#include <algorithm>
+#include <set>
+#include <vector>
+
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/find.hpp>
#include <boost/bind.hpp>
-#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
+#include <boost/lambda/lambda.hpp>
#include <Swiften/Base/Algorithm.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/JID/JID.h>
#include <Swift/Controllers/ContactProvider.h>
-#include <algorithm>
-#include <vector>
-#include <set>
-
namespace lambda = boost::lambda;
namespace Swift {
@@ -39,49 +38,49 @@ ContactSuggester::~ContactSuggester() {
}
void ContactSuggester::addContactProvider(ContactProvider* provider) {
- contactProviders_.push_back(provider);
+ contactProviders_.push_back(provider);
}
bool ContactSuggester::matchContact(const std::string& search, const Contact::ref& c) {
- if (fuzzyMatch(c->name, search)) {
- return true;
- }
- else if (c->jid.isValid()) {
- return fuzzyMatch(c->jid.toString(), search);
- }
- return false;
+ if (fuzzyMatch(c->name, search)) {
+ return true;
+ }
+ else if (c->jid.isValid()) {
+ return fuzzyMatch(c->jid.toString(), search);
+ }
+ return false;
}
std::vector<Contact::ref> ContactSuggester::getSuggestions(const std::string& search, bool withMUCNicks) const {
- std::vector<Contact::ref> results;
+ std::vector<Contact::ref> results;
- foreach(ContactProvider* provider, contactProviders_) {
- append(results, provider->getContacts(withMUCNicks));
- }
+ for (auto provider : contactProviders_) {
+ append(results, provider->getContacts(withMUCNicks));
+ }
- std::sort(results.begin(), results.end(), Contact::lexicographicalSortPredicate);
- results.erase(std::unique(results.begin(), results.end(), Contact::equalityPredicate), results.end());
- results.erase(std::remove_if(results.begin(), results.end(), !lambda::bind(&matchContact, search, lambda::_1)),
- results.end());
- std::sort(results.begin(), results.end(), boost::bind(&Contact::sortPredicate, _1, _2, search));
+ std::sort(results.begin(), results.end(), Contact::lexicographicalSortPredicate);
+ results.erase(std::unique(results.begin(), results.end(), Contact::equalityPredicate), results.end());
+ results.erase(std::remove_if(results.begin(), results.end(), !lambda::bind(&matchContact, search, lambda::_1)),
+ results.end());
+ std::sort(results.begin(), results.end(), boost::bind(&Contact::sortPredicate, _1, _2, search));
- return results;
+ return results;
}
bool ContactSuggester::fuzzyMatch(std::string text, std::string match) {
- std::string lowerText = text;
- boost::algorithm::to_lower(lowerText);
- std::string lowerMatch = match;
- boost::algorithm::to_lower(lowerMatch);
- size_t lastMatch = 0;
- for (size_t i = 0; i < lowerMatch.length(); ++i) {
- size_t where = lowerText.find_first_of(lowerMatch[i], lastMatch);
- if (where == std::string::npos) {
- return false;
- }
- lastMatch = where + 1;
- }
- return true;
+ std::string lowerText = text;
+ boost::algorithm::to_lower(lowerText);
+ std::string lowerMatch = match;
+ boost::algorithm::to_lower(lowerMatch);
+ size_t lastMatch = 0;
+ for (char i : lowerMatch) {
+ size_t where = lowerText.find_first_of(i, lastMatch);
+ if (where == std::string::npos) {
+ return false;
+ }
+ lastMatch = where + 1;
+ }
+ return true;
}
}
diff --git a/Swift/Controllers/ContactSuggester.h b/Swift/Controllers/ContactSuggester.h
index a57f638..f91879d 100644
--- a/Swift/Controllers/ContactSuggester.h
+++ b/Swift/Controllers/ContactSuggester.h
@@ -20,24 +20,24 @@
class ContactSuggesterTest;
namespace Swift {
- class ContactProvider;
-
- class ContactSuggester {
- public:
- ContactSuggester();
- ~ContactSuggester();
-
- void addContactProvider(ContactProvider* provider);
-
- std::vector<Contact::ref> getSuggestions(const std::string& search, bool withMUCNicks) const;
- public:
- static bool matchContact(const std::string& search, const Contact::ref& c);
- /**
- * Performs fuzzy matching on the string text. Matches when each character of match string is present in sequence in text string.
- */
- static bool fuzzyMatch(std::string text, std::string match);
-
- private:
- std::vector<ContactProvider*> contactProviders_;
- };
+ class ContactProvider;
+
+ class ContactSuggester {
+ public:
+ ContactSuggester();
+ ~ContactSuggester();
+
+ void addContactProvider(ContactProvider* provider);
+
+ std::vector<Contact::ref> getSuggestions(const std::string& search, bool withMUCNicks) const;
+ public:
+ static bool matchContact(const std::string& search, const Contact::ref& c);
+ /**
+ * Performs fuzzy matching on the string text. Matches when each character of match string is present in sequence in text string.
+ */
+ static bool fuzzyMatch(std::string text, std::string match);
+
+ private:
+ std::vector<ContactProvider*> contactProviders_;
+ };
}
diff --git a/Swift/Controllers/ContactsFromXMPPRoster.cpp b/Swift/Controllers/ContactsFromXMPPRoster.cpp
index 1cab9b1..1d1ccd4 100644
--- a/Swift/Controllers/ContactsFromXMPPRoster.cpp
+++ b/Swift/Controllers/ContactsFromXMPPRoster.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -13,7 +13,6 @@
#include <Swift/Controllers/ContactsFromXMPPRoster.h>
#include <Swiften/Avatars/AvatarManager.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Presence/PresenceOracle.h>
#include <Swiften/Roster/XMPPRoster.h>
#include <Swiften/Roster/XMPPRosterItem.h>
@@ -27,15 +26,15 @@ ContactsFromXMPPRoster::~ContactsFromXMPPRoster() {
}
std::vector<Contact::ref> ContactsFromXMPPRoster::getContacts(bool /*withMUCNicks*/) {
- std::vector<Contact::ref> results;
- std::vector<XMPPRosterItem> rosterItems = roster_->getItems();
- foreach(const XMPPRosterItem& rosterItem, rosterItems) {
- Contact::ref contact = boost::make_shared<Contact>(rosterItem.getName().empty() ? rosterItem.getJID().toString() : rosterItem.getName(), rosterItem.getJID(), StatusShow::None,"");
- contact->statusType = presenceOracle_->getAccountPresence(contact->jid) ? presenceOracle_->getAccountPresence(contact->jid)->getShow() : StatusShow::None;
- contact->avatarPath = avatarManager_->getAvatarPath(contact->jid);
- results.push_back(contact);
- }
- return results;
+ std::vector<Contact::ref> results;
+ std::vector<XMPPRosterItem> rosterItems = roster_->getItems();
+ for (const auto& rosterItem : rosterItems) {
+ Contact::ref contact = std::make_shared<Contact>(rosterItem.getName().empty() ? rosterItem.getJID().toString() : rosterItem.getName(), rosterItem.getJID(), StatusShow::None,"");
+ contact->statusType = presenceOracle_->getAccountPresence(contact->jid) ? presenceOracle_->getAccountPresence(contact->jid)->getShow() : StatusShow::None;
+ contact->avatarPath = avatarManager_->getAvatarPath(contact->jid);
+ results.push_back(contact);
+ }
+ return results;
}
}
diff --git a/Swift/Controllers/ContactsFromXMPPRoster.h b/Swift/Controllers/ContactsFromXMPPRoster.h
index 43d4985..2782dcc 100644
--- a/Swift/Controllers/ContactsFromXMPPRoster.h
+++ b/Swift/Controllers/ContactsFromXMPPRoster.h
@@ -21,15 +21,15 @@ class AvatarManager;
class XMPPRoster;
class ContactsFromXMPPRoster : public ContactProvider {
- public:
- ContactsFromXMPPRoster(XMPPRoster* roster, AvatarManager* avatarManager, PresenceOracle* presenceOracle);
- virtual ~ContactsFromXMPPRoster();
-
- virtual std::vector<Contact::ref> getContacts(bool withMUCNicks);
- private:
- XMPPRoster* roster_;
- AvatarManager* avatarManager_;
- PresenceOracle* presenceOracle_;
+ public:
+ ContactsFromXMPPRoster(XMPPRoster* roster, AvatarManager* avatarManager, PresenceOracle* presenceOracle);
+ virtual ~ContactsFromXMPPRoster();
+
+ virtual std::vector<Contact::ref> getContacts(bool withMUCNicks);
+ private:
+ XMPPRoster* roster_;
+ AvatarManager* avatarManager_;
+ PresenceOracle* presenceOracle_;
};
}
diff --git a/Swift/Controllers/DummySoundPlayer.h b/Swift/Controllers/DummySoundPlayer.h
index 2d99fb9..e297cae 100644
--- a/Swift/Controllers/DummySoundPlayer.h
+++ b/Swift/Controllers/DummySoundPlayer.h
@@ -9,8 +9,8 @@
#include <Swift/Controllers/SoundPlayer.h>
namespace Swift {
- class DummySoundPlayer : public SoundPlayer {
- public:
- void playSound(SoundEffect /*sound*/, const std::string& /*soundResource*/) {}
- };
+ class DummySoundPlayer : public SoundPlayer {
+ public:
+ void playSound(SoundEffect /*sound*/, const std::string& /*soundResource*/) {}
+ };
}
diff --git a/Swift/Controllers/DummySystemTray.h b/Swift/Controllers/DummySystemTray.h
index 10b7c33..b36ed28 100644
--- a/Swift/Controllers/DummySystemTray.h
+++ b/Swift/Controllers/DummySystemTray.h
@@ -1,18 +1,18 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/SystemTray.h"
+#include <Swift/Controllers/SystemTray.h>
namespace Swift {
- class DummySystemTray : public SystemTray {
- public:
- void setUnreadMessages(bool /*some*/) {}
- void setStatusType(StatusShow::Type /*type*/) {}
- void setConnecting() {}
- };
+ class DummySystemTray : public SystemTray {
+ public:
+ void setUnreadMessages(bool /*some*/) {}
+ void setStatusType(StatusShow::Type /*type*/) {}
+ void setConnecting() {}
+ };
}
diff --git a/Swift/Controllers/EventNotifier.cpp b/Swift/Controllers/EventNotifier.cpp
index 626fd40..6ea2ea5 100644
--- a/Swift/Controllers/EventNotifier.cpp
+++ b/Swift/Controllers/EventNotifier.cpp
@@ -10,71 +10,71 @@
#include <boost/bind.hpp>
#include <Swiften/Avatars/AvatarManager.h>
-#include <Swiften/Client/NickResolver.h>
-#include <Swiften/JID/JID.h>
#include <Swiften/Base/String.h>
#include <Swiften/Base/format.h>
+#include <Swiften/Client/NickResolver.h>
+#include <Swiften/JID/JID.h>
+#include <Swift/Controllers/Intl.h>
#include <Swift/Controllers/Settings/SettingsProvider.h>
#include <Swift/Controllers/XMPPEvents/ErrorEvent.h>
#include <Swift/Controllers/XMPPEvents/EventController.h>
#include <Swift/Controllers/XMPPEvents/MUCInviteEvent.h>
#include <Swift/Controllers/XMPPEvents/MessageEvent.h>
#include <Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h>
-#include <Swift/Controllers/Intl.h>
#include <SwifTools/Notifier/Notifier.h>
namespace Swift {
EventNotifier::EventNotifier(EventController* eventController, Notifier* notifier, AvatarManager* avatarManager, NickResolver* nickResolver) : eventController(eventController), notifier(notifier), avatarManager(avatarManager), nickResolver(nickResolver) {
- eventController->onEventQueueEventAdded.connect(boost::bind(&EventNotifier::handleEventAdded, this, _1));
+ eventController->onEventQueueEventAdded.connect(boost::bind(&EventNotifier::handleEventAdded, this, _1));
}
EventNotifier::~EventNotifier() {
- notifier->purgeCallbacks();
- eventController->onEventQueueEventAdded.disconnect(boost::bind(&EventNotifier::handleEventAdded, this, _1));
+ notifier->purgeCallbacks();
+ eventController->onEventQueueEventAdded.disconnect(boost::bind(&EventNotifier::handleEventAdded, this, _1));
}
-void EventNotifier::handleEventAdded(boost::shared_ptr<StanzaEvent> event) {
- if (event->getConcluded()) {
- return;
- }
- if (boost::shared_ptr<MessageEvent> messageEvent = boost::dynamic_pointer_cast<MessageEvent>(event)) {
- JID jid = messageEvent->getStanza()->getFrom();
- std::string title = nickResolver->jidToNick(jid);
- if (!messageEvent->getStanza()->isError() && !messageEvent->getStanza()->getBody().get_value_or("").empty()) {
- JID activationJID = jid;
- if (messageEvent->getStanza()->getType() == Message::Groupchat) {
- activationJID = jid.toBare();
- }
- std::string messageText = messageEvent->getStanza()->getBody().get_value_or("");
- if (boost::starts_with(messageText, "/me ")) {
- messageText = "*" + String::getSplittedAtFirst(messageText, ' ').second + "*";
- }
- notifier->showMessage(Notifier::IncomingMessage, title, messageText, avatarManager->getAvatarPath(jid), boost::bind(&EventNotifier::handleNotificationActivated, this, activationJID));
- }
- }
- else if(boost::shared_ptr<SubscriptionRequestEvent> subscriptionEvent = boost::dynamic_pointer_cast<SubscriptionRequestEvent>(event)) {
- JID jid = subscriptionEvent->getJID();
- std::string title = jid;
- std::string message = str(format(QT_TRANSLATE_NOOP("", "%1% wants to add you to his/her contact list")) % nickResolver->jidToNick(jid));
- notifier->showMessage(Notifier::SystemMessage, title, message, boost::filesystem::path(), boost::function<void()>());
- }
- else if(boost::shared_ptr<ErrorEvent> errorEvent = boost::dynamic_pointer_cast<ErrorEvent>(event)) {
- notifier->showMessage(Notifier::SystemMessage, QT_TRANSLATE_NOOP("", "Error"), errorEvent->getText(), boost::filesystem::path(), boost::function<void()>());
- }
- else if (boost::shared_ptr<MUCInviteEvent> mucInviteEvent = boost::dynamic_pointer_cast<MUCInviteEvent>(event)) {
- std::string title = mucInviteEvent->getInviter();
- std::string message = str(format(QT_TRANSLATE_NOOP("", "%1% has invited you to enter the %2% room")) % nickResolver->jidToNick(mucInviteEvent->getInviter()) % mucInviteEvent->getRoomJID());
- // FIXME: not show avatar or greyed out avatar for mediated invites
- notifier->showMessage(Notifier::SystemMessage, title, message, avatarManager->getAvatarPath(mucInviteEvent->getInviter()), boost::bind(&EventNotifier::handleNotificationActivated, this, mucInviteEvent->getInviter()));
- }
+void EventNotifier::handleEventAdded(std::shared_ptr<StanzaEvent> event) {
+ if (event->getConcluded()) {
+ return;
+ }
+ if (std::shared_ptr<MessageEvent> messageEvent = std::dynamic_pointer_cast<MessageEvent>(event)) {
+ JID jid = messageEvent->getStanza()->getFrom();
+ std::string title = nickResolver->jidToNick(jid);
+ if (!messageEvent->getStanza()->isError() && !messageEvent->getStanza()->getBody().get_value_or("").empty()) {
+ JID activationJID = jid;
+ if (messageEvent->getStanza()->getType() == Message::Groupchat) {
+ activationJID = jid.toBare();
+ }
+ std::string messageText = messageEvent->getStanza()->getBody().get_value_or("");
+ if (boost::starts_with(messageText, "/me ")) {
+ messageText = "*" + String::getSplittedAtFirst(messageText, ' ').second + "*";
+ }
+ notifier->showMessage(Notifier::IncomingMessage, title, messageText, avatarManager->getAvatarPath(jid), boost::bind(&EventNotifier::handleNotificationActivated, this, activationJID));
+ }
+ }
+ else if(std::shared_ptr<SubscriptionRequestEvent> subscriptionEvent = std::dynamic_pointer_cast<SubscriptionRequestEvent>(event)) {
+ JID jid = subscriptionEvent->getJID();
+ std::string title = jid;
+ std::string message = str(format(QT_TRANSLATE_NOOP("", "%1% wants to add you to his/her contact list")) % nickResolver->jidToNick(jid));
+ notifier->showMessage(Notifier::SystemMessage, title, message, boost::filesystem::path(), boost::function<void()>());
+ }
+ else if(std::shared_ptr<ErrorEvent> errorEvent = std::dynamic_pointer_cast<ErrorEvent>(event)) {
+ notifier->showMessage(Notifier::SystemMessage, QT_TRANSLATE_NOOP("", "Error"), errorEvent->getText(), boost::filesystem::path(), boost::function<void()>());
+ }
+ else if (std::shared_ptr<MUCInviteEvent> mucInviteEvent = std::dynamic_pointer_cast<MUCInviteEvent>(event)) {
+ std::string title = mucInviteEvent->getInviter();
+ std::string message = str(format(QT_TRANSLATE_NOOP("", "%1% has invited you to enter the %2% room")) % nickResolver->jidToNick(mucInviteEvent->getInviter()) % mucInviteEvent->getRoomJID());
+ // FIXME: not show avatar or greyed out avatar for mediated invites
+ notifier->showMessage(Notifier::SystemMessage, title, message, avatarManager->getAvatarPath(mucInviteEvent->getInviter()), boost::bind(&EventNotifier::handleNotificationActivated, this, mucInviteEvent->getInviter()));
+ }
}
void EventNotifier::handleNotificationActivated(JID jid) {
- onNotificationActivated(jid);
+ onNotificationActivated(jid);
}
}
diff --git a/Swift/Controllers/EventNotifier.h b/Swift/Controllers/EventNotifier.h
index 4f7c430..b44615d 100644
--- a/Swift/Controllers/EventNotifier.h
+++ b/Swift/Controllers/EventNotifier.h
@@ -1,42 +1,45 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
-#include "SwifTools/Notifier/Notifier.h"
-#include "Swiften/Base/boost_bsignals.h"
-#include "Swift/Controllers/XMPPEvents/StanzaEvent.h"
-#include "Swiften/JID/JID.h"
+#include <boost/signals2.hpp>
+
+#include <Swiften/JID/JID.h>
+
+#include <Swift/Controllers/XMPPEvents/StanzaEvent.h>
+
+#include <SwifTools/Notifier/Notifier.h>
namespace Swift {
- class EventController;
- class Notifier;
- class AvatarManager;
- class NickResolver;
- class JID;
- class UIEventStream;
- class SettingsProvider;
-
- class EventNotifier {
- public:
- EventNotifier(EventController* eventController, Notifier* notifier, AvatarManager* avatarManager, NickResolver* nickResolver);
- ~EventNotifier();
-
- boost::signal<void (const JID&)> onNotificationActivated;
-
- private:
- void handleEventAdded(boost::shared_ptr<StanzaEvent>);
- void handleNotificationActivated(JID jid);
-
- private:
- EventController* eventController;
- Notifier* notifier;
- AvatarManager* avatarManager;
- NickResolver* nickResolver;
- };
+ class EventController;
+ class Notifier;
+ class AvatarManager;
+ class NickResolver;
+ class JID;
+ class UIEventStream;
+ class SettingsProvider;
+
+ class EventNotifier {
+ public:
+ EventNotifier(EventController* eventController, Notifier* notifier, AvatarManager* avatarManager, NickResolver* nickResolver);
+ ~EventNotifier();
+
+ boost::signals2::signal<void (const JID&)> onNotificationActivated;
+
+ private:
+ void handleEventAdded(std::shared_ptr<StanzaEvent>);
+ void handleNotificationActivated(JID jid);
+
+ private:
+ EventController* eventController;
+ Notifier* notifier;
+ AvatarManager* avatarManager;
+ NickResolver* nickResolver;
+ };
}
diff --git a/Swift/Controllers/EventWindowController.cpp b/Swift/Controllers/EventWindowController.cpp
index 3acd7a5..412bb71 100644
--- a/Swift/Controllers/EventWindowController.cpp
+++ b/Swift/Controllers/EventWindowController.cpp
@@ -1,53 +1,54 @@
/*
- * Copyright (c) 2010-2012 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/EventWindowController.h>
+#include <boost/bind.hpp>
+
#include <Swift/Controllers/XMPPEvents/MessageEvent.h>
#include <Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h>
-#include <boost/bind.hpp>
namespace Swift {
EventWindowController::EventWindowController(EventController* eventController, EventWindowFactory* windowFactory) {
- eventController_ = eventController;
- windowFactory_ = windowFactory;
- window_ = windowFactory_->createEventWindow();
- eventAddedConnection_ = eventController_->onEventQueueEventAdded.connect(boost::bind(&EventWindowController::handleEventQueueEventAdded, this, _1));
+ eventController_ = eventController;
+ windowFactory_ = windowFactory;
+ window_ = windowFactory_->createEventWindow();
+ eventAddedConnection_ = eventController_->onEventQueueEventAdded.connect(boost::bind(&EventWindowController::handleEventQueueEventAdded, this, _1));
}
EventWindowController::~EventWindowController() {
- if (window_->canDelete()) {
- delete window_;
- }
+ if (window_->canDelete()) {
+ delete window_;
+ }
}
-void EventWindowController::handleEventQueueEventAdded(boost::shared_ptr<StanzaEvent> event) {
- if (event->getConcluded()) {
- handleEventConcluded(event);
- } else {
- boost::shared_ptr<MessageEvent> message = boost::dynamic_pointer_cast<MessageEvent>(event);
- if (!(message && message->isReadable())) {
- event->onConclusion.connect(boost::bind(&EventWindowController::handleEventConcluded, this, event));
- window_->addEvent(event, true);
- }
- }
+void EventWindowController::handleEventQueueEventAdded(std::shared_ptr<StanzaEvent> event) {
+ if (event->getConcluded()) {
+ handleEventConcluded(event);
+ } else {
+ std::shared_ptr<MessageEvent> message = std::dynamic_pointer_cast<MessageEvent>(event);
+ if (!(message && message->isReadable())) {
+ event->onConclusion.connect(boost::bind(&EventWindowController::handleEventConcluded, this, event));
+ window_->addEvent(event, true);
+ }
+ }
}
-void EventWindowController::handleEventConcluded(boost::shared_ptr<StanzaEvent> event) {
- window_->removeEvent(event);
- bool includeAsCompleted = true;
- /* Because subscription requests get duplicated, don't add them back */
- if (boost::dynamic_pointer_cast<SubscriptionRequestEvent>(event) || boost::dynamic_pointer_cast<MessageEvent>(event)) {
- includeAsCompleted = false;
- }
- if (includeAsCompleted) {
- window_->addEvent(event, false);
- }
- event->onConclusion.disconnect(boost::bind(&EventWindowController::handleEventConcluded, this, event));
+void EventWindowController::handleEventConcluded(std::shared_ptr<StanzaEvent> event) {
+ window_->removeEvent(event);
+ bool includeAsCompleted = true;
+ /* Because subscription requests get duplicated, don't add them back */
+ if (std::dynamic_pointer_cast<SubscriptionRequestEvent>(event) || std::dynamic_pointer_cast<MessageEvent>(event)) {
+ includeAsCompleted = false;
+ }
+ if (includeAsCompleted) {
+ window_->addEvent(event, false);
+ }
+ event->onConclusion.disconnect(boost::bind(&EventWindowController::handleEventConcluded, this, event));
}
}
diff --git a/Swift/Controllers/EventWindowController.h b/Swift/Controllers/EventWindowController.h
index f9477c5..aa730d0 100644
--- a/Swift/Controllers/EventWindowController.h
+++ b/Swift/Controllers/EventWindowController.h
@@ -1,30 +1,29 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/UIInterfaces/EventWindowFactory.h"
-#include "Swift/Controllers/UIInterfaces/EventWindow.h"
-#include "Swift/Controllers/XMPPEvents/EventController.h"
-
+#include <Swift/Controllers/UIInterfaces/EventWindow.h>
+#include <Swift/Controllers/UIInterfaces/EventWindowFactory.h>
+#include <Swift/Controllers/XMPPEvents/EventController.h>
namespace Swift {
- class EventWindowController {
- public:
- EventWindowController(EventController* eventController, EventWindowFactory* windowFactory);
- ~EventWindowController();
- private:
- void handleEventQueueEventAdded(boost::shared_ptr<StanzaEvent> event);
- void handleEventConcluded(boost::shared_ptr<StanzaEvent> event);
+ class EventWindowController {
+ public:
+ EventWindowController(EventController* eventController, EventWindowFactory* windowFactory);
+ ~EventWindowController();
+ private:
+ void handleEventQueueEventAdded(std::shared_ptr<StanzaEvent> event);
+ void handleEventConcluded(std::shared_ptr<StanzaEvent> event);
- EventController* eventController_;
- EventWindowFactory* windowFactory_;
- EventWindow* window_;
- boost::bsignals::scoped_connection eventAddedConnection_;
- };
+ EventController* eventController_;
+ EventWindowFactory* windowFactory_;
+ EventWindow* window_;
+ boost::signals2::scoped_connection eventAddedConnection_;
+ };
}
diff --git a/Swift/Controllers/FileTransfer/FileTransferController.cpp b/Swift/Controllers/FileTransfer/FileTransferController.cpp
index 89e9a91..65c2892 100644
--- a/Swift/Controllers/FileTransfer/FileTransferController.cpp
+++ b/Swift/Controllers/FileTransfer/FileTransferController.cpp
@@ -5,19 +5,20 @@
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/FileTransfer/FileTransferController.h>
+#include <memory>
+
#include <boost/bind.hpp>
#include <boost/filesystem.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <boost/signals2.hpp>
#include <Swiften/Base/Log.h>
-#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/FileTransfer/FileReadBytestream.h>
#include <Swiften/FileTransfer/FileTransferManager.h>
#include <Swiften/FileTransfer/OutgoingJingleFileTransfer.h>
@@ -28,135 +29,135 @@
namespace Swift {
FileTransferController::FileTransferController(const JID& receipient, const std::string& filename, FileTransferManager* fileTransferManager) :
- sending(true), otherParty(receipient), filename(filename), ftManager(fileTransferManager), ftProgressInfo(0), chatWindow(0), currentState(FileTransfer::State::WaitingForStart) {
-
+ sending(true), otherParty(receipient), filename(filename), ftManager(fileTransferManager), ftProgressInfo(nullptr), chatWindow(nullptr), currentState(FileTransfer::State::WaitingForStart) {
+
}
FileTransferController::FileTransferController(IncomingFileTransfer::ref transfer) :
- sending(false), otherParty(transfer->getSender()), filename(transfer->getFileName()), transfer(transfer), ftManager(0), ftProgressInfo(0), chatWindow(0), currentState(FileTransfer::State::WaitingForStart) {
- transfer->onStateChanged.connect(boost::bind(&FileTransferController::handleFileTransferStateChange, this, _1));
+ sending(false), otherParty(transfer->getSender()), filename(transfer->getFileName()), transfer(transfer), ftManager(nullptr), ftProgressInfo(nullptr), chatWindow(nullptr), currentState(FileTransfer::State::WaitingForStart) {
+ transfer->onStateChanged.connect(boost::bind(&FileTransferController::handleFileTransferStateChange, this, _1));
}
FileTransferController::~FileTransferController() {
- delete ftProgressInfo;
- transfer->onStateChanged.disconnect(boost::bind(&FileTransferController::handleFileTransferStateChange, this, _1));
+ delete ftProgressInfo;
+ transfer->onStateChanged.disconnect(boost::bind(&FileTransferController::handleFileTransferStateChange, this, _1));
}
const JID &FileTransferController::getOtherParty() const {
- return otherParty;
+ return otherParty;
}
std::string FileTransferController::setChatWindow(ChatWindow* wnd, std::string nickname) {
- chatWindow = wnd;
- if (sending) {
- uiID = wnd->addFileTransfer(QT_TRANSLATE_NOOP("", "me"), true, filename, boost::filesystem::file_size(boost::filesystem::path(filename)), "");
- } else {
- uiID = wnd->addFileTransfer(nickname, false, filename, transfer->getFileSizeInBytes(), transfer->getDescription());
- }
- return uiID;
+ chatWindow = wnd;
+ if (sending) {
+ uiID = wnd->addFileTransfer(QT_TRANSLATE_NOOP("", "me"), true, filename, boost::filesystem::file_size(boost::filesystem::path(filename)), "");
+ } else {
+ uiID = wnd->addFileTransfer(nickname, false, filename, transfer->getFileSizeInBytes(), transfer->getDescription());
+ }
+ return uiID;
}
void FileTransferController::setReceipient(const JID& receipient) {
- this->otherParty = receipient;
+ this->otherParty = receipient;
}
bool FileTransferController::isIncoming() const {
- return !sending;
+ return !sending;
}
FileTransfer::State FileTransferController::getState() const {
- return currentState;
+ return currentState;
}
int FileTransferController::getProgress() const {
- return ftProgressInfo ? ftProgressInfo->getPercentage() : 0;
+ return ftProgressInfo ? ftProgressInfo->getPercentage() : 0;
}
boost::uintmax_t FileTransferController::getSize() const {
- if (transfer) {
- return transfer->getFileSizeInBytes();
- } else {
- return 0;
- }
+ if (transfer) {
+ return transfer->getFileSizeInBytes();
+ } else {
+ return 0;
+ }
}
void FileTransferController::start(std::string& description) {
- SWIFT_LOG(debug) << "FileTransferController::start" << std::endl;
- fileReadStream = boost::make_shared<FileReadBytestream>(boost::filesystem::path(filename));
- OutgoingFileTransfer::ref outgoingTransfer = ftManager->createOutgoingFileTransfer(otherParty, boost::filesystem::path(filename), description, fileReadStream);
- if (outgoingTransfer) {
- ftProgressInfo = new FileTransferProgressInfo(outgoingTransfer->getFileSizeInBytes());
- ftProgressInfo->onProgressPercentage.connect(boost::bind(&FileTransferController::handleProgressPercentageChange, this, _1));
- outgoingTransfer->onStateChanged.connect(boost::bind(&FileTransferController::handleFileTransferStateChange, this, _1));
- outgoingTransfer->onProcessedBytes.connect(boost::bind(&FileTransferProgressInfo::setBytesProcessed, ftProgressInfo, _1));
- outgoingTransfer->start();
- transfer = outgoingTransfer;
- } else {
- std::cerr << "File transfer not supported!" << std::endl;
- }
+ SWIFT_LOG(debug) << "FileTransferController::start" << std::endl;
+ fileReadStream = std::make_shared<FileReadBytestream>(boost::filesystem::path(filename));
+ OutgoingFileTransfer::ref outgoingTransfer = ftManager->createOutgoingFileTransfer(otherParty, boost::filesystem::path(filename), description, fileReadStream);
+ if (outgoingTransfer) {
+ ftProgressInfo = new FileTransferProgressInfo(outgoingTransfer->getFileSizeInBytes());
+ ftProgressInfo->onProgressPercentage.connect(boost::bind(&FileTransferController::handleProgressPercentageChange, this, _1));
+ outgoingTransfer->onStateChanged.connect(boost::bind(&FileTransferController::handleFileTransferStateChange, this, _1));
+ outgoingTransfer->onProcessedBytes.connect(boost::bind(&FileTransferProgressInfo::setBytesProcessed, ftProgressInfo, _1));
+ outgoingTransfer->start();
+ transfer = outgoingTransfer;
+ } else {
+ std::cerr << "File transfer not supported!" << std::endl;
+ }
}
void FileTransferController::accept(std::string& file) {
- SWIFT_LOG(debug) << "FileTransferController::accept" << std::endl;
- IncomingFileTransfer::ref incomingTransfer = boost::dynamic_pointer_cast<IncomingFileTransfer>(transfer);
- if (incomingTransfer) {
- fileWriteStream = boost::make_shared<FileWriteBytestream>(boost::filesystem::path(file));
+ SWIFT_LOG(debug) << "FileTransferController::accept" << std::endl;
+ IncomingFileTransfer::ref incomingTransfer = std::dynamic_pointer_cast<IncomingFileTransfer>(transfer);
+ if (incomingTransfer) {
+ fileWriteStream = std::make_shared<FileWriteBytestream>(boost::filesystem::path(file));
- ftProgressInfo = new FileTransferProgressInfo(transfer->getFileSizeInBytes());
- ftProgressInfo->onProgressPercentage.connect(boost::bind(&FileTransferController::handleProgressPercentageChange, this, _1));
- transfer->onProcessedBytes.connect(boost::bind(&FileTransferProgressInfo::setBytesProcessed, ftProgressInfo, _1));
- incomingTransfer->accept(fileWriteStream);
- } else {
- std::cerr << "Expected an incoming transfer in this situation!" << std::endl;
- }
+ ftProgressInfo = new FileTransferProgressInfo(transfer->getFileSizeInBytes());
+ ftProgressInfo->onProgressPercentage.connect(boost::bind(&FileTransferController::handleProgressPercentageChange, this, _1));
+ transfer->onProcessedBytes.connect(boost::bind(&FileTransferProgressInfo::setBytesProcessed, ftProgressInfo, _1));
+ incomingTransfer->accept(fileWriteStream);
+ } else {
+ std::cerr << "Expected an incoming transfer in this situation!" << std::endl;
+ }
}
void FileTransferController::cancel() {
- if (transfer) {
- transfer->cancel();
- } else {
- chatWindow->setFileTransferStatus(uiID, ChatWindow::Canceled);
- }
+ if (transfer) {
+ transfer->cancel();
+ } else {
+ chatWindow->setFileTransferStatus(uiID, ChatWindow::Canceled);
+ }
}
void FileTransferController::handleFileTransferStateChange(FileTransfer::State state) {
- currentState = state;
- onStateChanged();
- switch(state.type) {
- case FileTransfer::State::Initial:
- assert(false);
- return;
- case FileTransfer::State::Negotiating:
- chatWindow->setFileTransferStatus(uiID, ChatWindow::Negotiating);
- return;
- case FileTransfer::State::Transferring:
- chatWindow->setFileTransferStatus(uiID, ChatWindow::Transferring);
- return;
- case FileTransfer::State::Canceled:
- chatWindow->setFileTransferStatus(uiID, ChatWindow::Canceled);
- return;
- case FileTransfer::State::Finished:
- chatWindow->setFileTransferStatus(uiID, ChatWindow::Finished);
- if (fileWriteStream) {
- fileWriteStream->close();
- }
- return;
- case FileTransfer::State::Failed:
- chatWindow->setFileTransferStatus(uiID, ChatWindow::FTFailed);
- return;
- case FileTransfer::State::WaitingForAccept:
- chatWindow->setFileTransferStatus(uiID, ChatWindow::WaitingForAccept);
- return;
- case FileTransfer::State::WaitingForStart:
- chatWindow->setFileTransferStatus(uiID, ChatWindow::Initialisation);
- return;
- }
- assert(false);
+ currentState = state;
+ onStateChanged();
+ switch(state.type) {
+ case FileTransfer::State::Initial:
+ assert(false);
+ return;
+ case FileTransfer::State::Negotiating:
+ chatWindow->setFileTransferStatus(uiID, ChatWindow::Negotiating);
+ return;
+ case FileTransfer::State::Transferring:
+ chatWindow->setFileTransferStatus(uiID, ChatWindow::Transferring);
+ return;
+ case FileTransfer::State::Canceled:
+ chatWindow->setFileTransferStatus(uiID, ChatWindow::Canceled);
+ return;
+ case FileTransfer::State::Finished:
+ chatWindow->setFileTransferStatus(uiID, ChatWindow::Finished);
+ if (fileWriteStream) {
+ fileWriteStream->close();
+ }
+ return;
+ case FileTransfer::State::Failed:
+ chatWindow->setFileTransferStatus(uiID, ChatWindow::FTFailed);
+ return;
+ case FileTransfer::State::WaitingForAccept:
+ chatWindow->setFileTransferStatus(uiID, ChatWindow::WaitingForAccept);
+ return;
+ case FileTransfer::State::WaitingForStart:
+ chatWindow->setFileTransferStatus(uiID, ChatWindow::Initialisation);
+ return;
+ }
+ assert(false);
}
void FileTransferController::handleProgressPercentageChange(int percentage) {
- onProgressChange();
- chatWindow->setFileTransferProgress(uiID, percentage);
+ onProgressChange();
+ chatWindow->setFileTransferProgress(uiID, percentage);
}
}
diff --git a/Swift/Controllers/FileTransfer/FileTransferController.h b/Swift/Controllers/FileTransfer/FileTransferController.h
index 490773d..38dde0e 100644
--- a/Swift/Controllers/FileTransfer/FileTransferController.h
+++ b/Swift/Controllers/FileTransfer/FileTransferController.h
@@ -5,17 +5,17 @@
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <memory>
#include <string>
#include <boost/cstdint.hpp>
-#include <boost/shared_ptr.hpp>
#include <Swiften/FileTransfer/FileReadBytestream.h>
#include <Swiften/FileTransfer/FileTransfer.h>
@@ -32,49 +32,49 @@ class ChatWindow;
class FileTransferController {
public:
- /**
- * For outgoing file transfers. It'll create a file transfer via FileTransferManager as soon as the descriptive information is available.
- */
- FileTransferController(const JID&, const std::string&, FileTransferManager*);
+ /**
+ * For outgoing file transfers. It'll create a file transfer via FileTransferManager as soon as the descriptive information is available.
+ */
+ FileTransferController(const JID&, const std::string&, FileTransferManager*);
- /**
- * For incoming file transfers.
- */
- FileTransferController(IncomingFileTransfer::ref transfer);
- ~FileTransferController();
+ /**
+ * For incoming file transfers.
+ */
+ FileTransferController(IncomingFileTransfer::ref transfer);
+ ~FileTransferController();
- std::string setChatWindow(ChatWindow*, std::string nickname);
- void setReceipient(const JID& otherParty);
+ std::string setChatWindow(ChatWindow*, std::string nickname);
+ void setReceipient(const JID& otherParty);
- void start(std::string& description);
- void accept(std::string& file);
- void cancel();
+ void start(std::string& description);
+ void accept(std::string& file);
+ void cancel();
- const JID &getOtherParty() const;
- bool isIncoming() const;
- FileTransfer::State getState() const;
- int getProgress() const;
- boost::uintmax_t getSize() const;
+ const JID &getOtherParty() const;
+ bool isIncoming() const;
+ FileTransfer::State getState() const;
+ int getProgress() const;
+ boost::uintmax_t getSize() const;
- boost::signal<void ()> onStateChanged;
- boost::signal<void ()> onProgressChange;
+ boost::signals2::signal<void ()> onStateChanged;
+ boost::signals2::signal<void ()> onProgressChange;
private:
- void handleFileTransferStateChange(FileTransfer::State);
- void handleProgressPercentageChange(int percentage);
+ void handleFileTransferStateChange(FileTransfer::State);
+ void handleProgressPercentageChange(int percentage);
private:
- bool sending;
- JID otherParty;
- std::string filename;
- FileTransfer::ref transfer;
- boost::shared_ptr<FileReadBytestream> fileReadStream;
- boost::shared_ptr<FileWriteBytestream> fileWriteStream;
- FileTransferManager* ftManager;
- FileTransferProgressInfo* ftProgressInfo;
- ChatWindow* chatWindow;
- std::string uiID;
- FileTransfer::State currentState;
+ bool sending;
+ JID otherParty;
+ std::string filename;
+ FileTransfer::ref transfer;
+ std::shared_ptr<FileReadBytestream> fileReadStream;
+ std::shared_ptr<FileWriteBytestream> fileWriteStream;
+ FileTransferManager* ftManager;
+ FileTransferProgressInfo* ftProgressInfo;
+ ChatWindow* chatWindow;
+ std::string uiID;
+ FileTransfer::State currentState;
};
}
diff --git a/Swift/Controllers/FileTransfer/FileTransferOverview.cpp b/Swift/Controllers/FileTransfer/FileTransferOverview.cpp
index b2afea9..fcc35e4 100644
--- a/Swift/Controllers/FileTransfer/FileTransferOverview.cpp
+++ b/Swift/Controllers/FileTransfer/FileTransferOverview.cpp
@@ -5,88 +5,87 @@
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "FileTransferOverview.h"
+#include <Swift/Controllers/FileTransfer/FileTransferOverview.h>
#include <boost/bind.hpp>
#include <boost/filesystem.hpp>
+#include <boost/signals2.hpp>
#include <Swiften/Base/Log.h>
-#include <Swiften/Base/boost_bsignals.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/FileTransfer/FileTransferManager.h>
namespace Swift {
FileTransferOverview::FileTransferOverview(FileTransferManager* ftm) : fileTransferManager(ftm) {
- fileTransferManager->onIncomingFileTransfer.connect(boost::bind(&FileTransferOverview::handleIncomingFileTransfer, this, _1));
- onNewFileTransferController.connect(boost::bind(&FileTransferOverview::handleNewFileTransferController, this, _1));
+ fileTransferManager->onIncomingFileTransfer.connect(boost::bind(&FileTransferOverview::handleIncomingFileTransfer, this, _1));
+ onNewFileTransferController.connect(boost::bind(&FileTransferOverview::handleNewFileTransferController, this, _1));
}
FileTransferOverview::~FileTransferOverview() {
- onNewFileTransferController.disconnect(boost::bind(&FileTransferOverview::handleNewFileTransferController, this, _1));
- fileTransferManager->onIncomingFileTransfer.disconnect(boost::bind(&FileTransferOverview::handleIncomingFileTransfer, this, _1));
- foreach(FileTransferController* controller, fileTransfers) {
- controller->onStateChanged.disconnect(boost::bind(&FileTransferOverview::handleFileTransferStateChanged, this));
- }
+ onNewFileTransferController.disconnect(boost::bind(&FileTransferOverview::handleNewFileTransferController, this, _1));
+ fileTransferManager->onIncomingFileTransfer.disconnect(boost::bind(&FileTransferOverview::handleIncomingFileTransfer, this, _1));
+ for (auto controller : fileTransfers) {
+ controller->onStateChanged.disconnect(boost::bind(&FileTransferOverview::handleFileTransferStateChanged, this));
+ }
}
-
+
void FileTransferOverview::sendFile(const JID& jid, const std::string& filename) {
- if (boost::filesystem::exists(filename) && boost::filesystem::file_size(filename) > 0) {
- FileTransferController* controller = new FileTransferController(jid, filename, fileTransferManager);
- onNewFileTransferController(controller);
- }
+ if (boost::filesystem::exists(filename) && boost::filesystem::file_size(filename) > 0) {
+ FileTransferController* controller = new FileTransferController(jid, filename, fileTransferManager);
+ onNewFileTransferController(controller);
+ }
}
void FileTransferOverview::handleIncomingFileTransfer(IncomingFileTransfer::ref transfer) {
- FileTransferController* controller = new FileTransferController(transfer);
- onNewFileTransferController(controller);
+ FileTransferController* controller = new FileTransferController(transfer);
+ onNewFileTransferController(controller);
}
void FileTransferOverview::handleNewFileTransferController(FileTransferController* controller) {
- fileTransfers.push_back(controller);
- controller->onStateChanged.connect(boost::bind(&FileTransferOverview::handleFileTransferStateChanged, this));
+ fileTransfers.push_back(controller);
+ controller->onStateChanged.connect(boost::bind(&FileTransferOverview::handleFileTransferStateChanged, this));
}
void FileTransferOverview::handleFileTransferStateChanged() {
- onFileTransferListChanged();
+ onFileTransferListChanged();
}
const std::vector<FileTransferController*>& FileTransferOverview::getFileTransfers() const {
- return fileTransfers;
+ return fileTransfers;
}
void FileTransferOverview::clearFinished() {
- for (std::vector<FileTransferController*>::iterator it = fileTransfers.begin(); it != fileTransfers.end(); ) {
- if((*it)->getState().type == FileTransfer::State::Finished
- || (*it)->getState().type == FileTransfer::State::Failed
- || (*it)->getState().type == FileTransfer::State::Canceled) {
- FileTransferController* controller = *it;
- it = fileTransfers.erase(it);
- controller->onStateChanged.disconnect(boost::bind(&FileTransferOverview::handleFileTransferStateChanged, this));
- delete controller;
- } else {
- ++it;
- }
- }
- onFileTransferListChanged();
+ for (std::vector<FileTransferController*>::iterator it = fileTransfers.begin(); it != fileTransfers.end(); ) {
+ if((*it)->getState().type == FileTransfer::State::Finished
+ || (*it)->getState().type == FileTransfer::State::Failed
+ || (*it)->getState().type == FileTransfer::State::Canceled) {
+ FileTransferController* controller = *it;
+ it = fileTransfers.erase(it);
+ controller->onStateChanged.disconnect(boost::bind(&FileTransferOverview::handleFileTransferStateChanged, this));
+ delete controller;
+ } else {
+ ++it;
+ }
+ }
+ onFileTransferListChanged();
}
bool FileTransferOverview::isClearable() const {
- bool isClearable = false;
- foreach (FileTransferController* controller, fileTransfers) {
- if(controller->getState().type == FileTransfer::State::Finished
- || controller->getState().type == FileTransfer::State::Failed
- || controller->getState().type == FileTransfer::State::Canceled) {
- isClearable = true;
- break;
- }
- }
- return isClearable;
+ bool isClearable = false;
+ for (auto controller : fileTransfers) {
+ if(controller->getState().type == FileTransfer::State::Finished
+ || controller->getState().type == FileTransfer::State::Failed
+ || controller->getState().type == FileTransfer::State::Canceled) {
+ isClearable = true;
+ break;
+ }
+ }
+ return isClearable;
}
}
diff --git a/Swift/Controllers/FileTransfer/FileTransferOverview.h b/Swift/Controllers/FileTransfer/FileTransferOverview.h
index e3cbf81..c311cb7 100644
--- a/Swift/Controllers/FileTransfer/FileTransferOverview.h
+++ b/Swift/Controllers/FileTransfer/FileTransferOverview.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -14,7 +14,7 @@
#include <vector>
-#include <Swiften/Base/boost_bsignals.h>
+#include <boost/signals2.hpp>
#include <Swift/Controllers/FileTransfer/FileTransferController.h>
@@ -25,25 +25,25 @@ class FileTransferManager;
class FileTransferOverview {
public:
- FileTransferOverview(FileTransferManager*);
- ~FileTransferOverview();
-
- void sendFile(const JID&, const std::string&);
- const std::vector<FileTransferController*>& getFileTransfers() const;
- void clearFinished();
- bool isClearable() const;
+ FileTransferOverview(FileTransferManager*);
+ ~FileTransferOverview();
- boost::signal<void (FileTransferController*)> onNewFileTransferController;
- boost::signal<void ()> onFileTransferListChanged;
+ void sendFile(const JID&, const std::string&);
+ const std::vector<FileTransferController*>& getFileTransfers() const;
+ void clearFinished();
+ bool isClearable() const;
+
+ boost::signals2::signal<void (FileTransferController*)> onNewFileTransferController;
+ boost::signals2::signal<void ()> onFileTransferListChanged;
private:
- void handleIncomingFileTransfer(IncomingFileTransfer::ref transfer);
- void handleNewFileTransferController(FileTransferController* controller);
- void handleFileTransferStateChanged();
+ void handleIncomingFileTransfer(IncomingFileTransfer::ref transfer);
+ void handleNewFileTransferController(FileTransferController* controller);
+ void handleFileTransferStateChanged();
private:
- std::vector<FileTransferController*> fileTransfers;
- FileTransferManager *fileTransferManager;
+ std::vector<FileTransferController*> fileTransfers;
+ FileTransferManager *fileTransferManager;
};
}
diff --git a/Swift/Controllers/FileTransfer/FileTransferProgressInfo.cpp b/Swift/Controllers/FileTransfer/FileTransferProgressInfo.cpp
index 3081f71..b073017 100644
--- a/Swift/Controllers/FileTransfer/FileTransferProgressInfo.cpp
+++ b/Swift/Controllers/FileTransfer/FileTransferProgressInfo.cpp
@@ -4,7 +4,13 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "FileTransferProgressInfo.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/Controllers/FileTransfer/FileTransferProgressInfo.h>
#include <boost/numeric/conversion/cast.hpp>
@@ -13,21 +19,21 @@
namespace Swift {
FileTransferProgressInfo::FileTransferProgressInfo(boost::uintmax_t completeBytes) : completeBytes(completeBytes), completedBytes(0), percentage(0) {
- onProgressPercentage(0);
+ onProgressPercentage(0);
}
void FileTransferProgressInfo::setBytesProcessed(int processedBytes) {
- int oldPercentage = int(double(completedBytes) / double(completeBytes) * 100.0);
- completedBytes += boost::numeric_cast<boost::uintmax_t>(processedBytes);
- int newPercentage = int(double(completedBytes) / double(completeBytes) * 100.0);
- if (oldPercentage != newPercentage) {
- onProgressPercentage(newPercentage);
- }
- percentage = newPercentage;
+ int oldPercentage = int(double(completedBytes) / double(completeBytes) * 100.0);
+ completedBytes += boost::numeric_cast<boost::uintmax_t>(processedBytes);
+ int newPercentage = int(double(completedBytes) / double(completeBytes) * 100.0);
+ if (oldPercentage != newPercentage) {
+ onProgressPercentage(newPercentage);
+ }
+ percentage = newPercentage;
}
int FileTransferProgressInfo::getPercentage() const {
- return percentage;
+ return percentage;
}
}
diff --git a/Swift/Controllers/FileTransfer/FileTransferProgressInfo.h b/Swift/Controllers/FileTransfer/FileTransferProgressInfo.h
index e324e33..5fb955c 100644
--- a/Swift/Controllers/FileTransfer/FileTransferProgressInfo.h
+++ b/Swift/Controllers/FileTransfer/FileTransferProgressInfo.h
@@ -4,27 +4,33 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
-#include <Swiften/Base/boost_bsignals.h>
#include <boost/cstdint.hpp>
+#include <boost/signals2.hpp>
namespace Swift {
class FileTransferProgressInfo {
public:
- FileTransferProgressInfo(boost::uintmax_t completeBytes);
+ FileTransferProgressInfo(boost::uintmax_t completeBytes);
public:
- void setBytesProcessed(int processedBytes);
+ void setBytesProcessed(int processedBytes);
- int getPercentage() const;
- boost::signal<void (int)> onProgressPercentage;
+ int getPercentage() const;
+ boost::signals2::signal<void (int)> onProgressPercentage;
private:
- boost::uintmax_t completeBytes;
- boost::uintmax_t completedBytes;
- int percentage;
+ boost::uintmax_t completeBytes;
+ boost::uintmax_t completedBytes;
+ int percentage;
};
}
diff --git a/Swift/Controllers/FileTransferListController.cpp b/Swift/Controllers/FileTransferListController.cpp
index 093a3c4..4f85b81 100644
--- a/Swift/Controllers/FileTransferListController.cpp
+++ b/Swift/Controllers/FileTransferListController.cpp
@@ -4,42 +4,48 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "Swift/Controllers/FileTransferListController.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/Controllers/FileTransferListController.h>
#include <boost/bind.hpp>
-#include "Swift/Controllers/UIInterfaces/FileTransferListWidgetFactory.h"
-#include "Swift/Controllers/UIEvents/RequestFileTransferListUIEvent.h"
+#include <Swift/Controllers/UIEvents/RequestFileTransferListUIEvent.h>
+#include <Swift/Controllers/UIInterfaces/FileTransferListWidgetFactory.h>
namespace Swift {
-FileTransferListController::FileTransferListController(UIEventStream* uiEventStream, FileTransferListWidgetFactory* fileTransferListWidgetFactory) : fileTransferListWidgetFactory(fileTransferListWidgetFactory), fileTransferListWidget(NULL), fileTransferOverview(0) {
- uiEventStream->onUIEvent.connect(boost::bind(&FileTransferListController::handleUIEvent, this, _1));
+FileTransferListController::FileTransferListController(UIEventStream* uiEventStream, FileTransferListWidgetFactory* fileTransferListWidgetFactory) : fileTransferListWidgetFactory(fileTransferListWidgetFactory), fileTransferListWidget(nullptr), fileTransferOverview(nullptr) {
+ uiEventStream->onUIEvent.connect(boost::bind(&FileTransferListController::handleUIEvent, this, _1));
}
FileTransferListController::~FileTransferListController() {
- delete fileTransferListWidget;
+ delete fileTransferListWidget;
}
void FileTransferListController::setFileTransferOverview(FileTransferOverview *overview) {
- fileTransferOverview = overview;
- if (fileTransferListWidget) {
- fileTransferListWidget->setFileTransferOverview(fileTransferOverview);
- }
+ fileTransferOverview = overview;
+ if (fileTransferListWidget) {
+ fileTransferListWidget->setFileTransferOverview(fileTransferOverview);
+ }
}
-void FileTransferListController::handleUIEvent(boost::shared_ptr<UIEvent> rawEvent) {
- boost::shared_ptr<RequestFileTransferListUIEvent> event = boost::dynamic_pointer_cast<RequestFileTransferListUIEvent>(rawEvent);
- if (event != NULL) {
- if (fileTransferListWidget == NULL) {
- fileTransferListWidget = fileTransferListWidgetFactory->createFileTransferListWidget();
- if (fileTransferOverview) {
- fileTransferListWidget->setFileTransferOverview(fileTransferOverview);
- }
- }
- fileTransferListWidget->show();
- fileTransferListWidget->activate();
- }
+void FileTransferListController::handleUIEvent(std::shared_ptr<UIEvent> rawEvent) {
+ std::shared_ptr<RequestFileTransferListUIEvent> event = std::dynamic_pointer_cast<RequestFileTransferListUIEvent>(rawEvent);
+ if (event != nullptr) {
+ if (fileTransferListWidget == nullptr) {
+ fileTransferListWidget = fileTransferListWidgetFactory->createFileTransferListWidget();
+ if (fileTransferOverview) {
+ fileTransferListWidget->setFileTransferOverview(fileTransferOverview);
+ }
+ }
+ fileTransferListWidget->show();
+ fileTransferListWidget->activate();
+ }
}
}
diff --git a/Swift/Controllers/FileTransferListController.h b/Swift/Controllers/FileTransferListController.h
index c5c8893..832a99c 100644
--- a/Swift/Controllers/FileTransferListController.h
+++ b/Swift/Controllers/FileTransferListController.h
@@ -4,11 +4,17 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
-#include "Swift/Controllers/UIEvents/UIEventStream.h"
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
namespace Swift {
@@ -18,18 +24,18 @@ class FileTransferOverview;
class FileTransferListController {
public:
- FileTransferListController(UIEventStream* uiEventStream, FileTransferListWidgetFactory* fileTransferListWidgetFactory);
- ~FileTransferListController();
+ FileTransferListController(UIEventStream* uiEventStream, FileTransferListWidgetFactory* fileTransferListWidgetFactory);
+ ~FileTransferListController();
- void setFileTransferOverview(FileTransferOverview* overview);
+ void setFileTransferOverview(FileTransferOverview* overview);
private:
- void handleUIEvent(boost::shared_ptr<UIEvent> event);
+ void handleUIEvent(std::shared_ptr<UIEvent> event);
private:
- FileTransferListWidgetFactory* fileTransferListWidgetFactory;
- FileTransferListWidget* fileTransferListWidget;
- FileTransferOverview* fileTransferOverview;
+ FileTransferListWidgetFactory* fileTransferListWidgetFactory;
+ FileTransferListWidget* fileTransferListWidget;
+ FileTransferOverview* fileTransferOverview;
};
}
diff --git a/Swift/Controllers/HighlightAction.cpp b/Swift/Controllers/HighlightAction.cpp
index 4603408..3ea2c86 100644
--- a/Swift/Controllers/HighlightAction.cpp
+++ b/Swift/Controllers/HighlightAction.cpp
@@ -16,47 +16,47 @@ namespace Swift {
void HighlightAction::setHighlightWholeMessage(bool highlightText)
{
- highlightWholeMessage_ = highlightText;
- if (!highlightWholeMessage_) {
- textColor_.clear();
- textBackground_.clear();
- }
+ highlightWholeMessage_ = highlightText;
+ if (!highlightWholeMessage_) {
+ textColor_.clear();
+ textBackground_.clear();
+ }
}
void HighlightAction::setPlaySound(bool playSound)
{
- playSound_ = playSound;
- if (!playSound_) {
- soundFile_.clear();
- }
+ playSound_ = playSound;
+ if (!playSound_) {
+ soundFile_.clear();
+ }
}
bool operator ==(HighlightAction const& a, HighlightAction const& b) {
- if (a.highlightWholeMessage() != b.highlightWholeMessage()) {
- return false;
- }
+ if (a.highlightWholeMessage() != b.highlightWholeMessage()) {
+ return false;
+ }
- if (a.getTextColor() != b.getTextColor()) {
- return false;
- }
+ if (a.getTextColor() != b.getTextColor()) {
+ return false;
+ }
- if (a.getTextBackground() != b.getTextBackground()) {
- return false;
- }
+ if (a.getTextBackground() != b.getTextBackground()) {
+ return false;
+ }
- if (a.playSound() != b.playSound()) {
- return false;
- }
+ if (a.playSound() != b.playSound()) {
+ return false;
+ }
- if (a.getSoundFile() != b.getSoundFile()) {
- return false;
- }
+ if (a.getSoundFile() != b.getSoundFile()) {
+ return false;
+ }
- return true;
+ return true;
}
bool operator !=(HighlightAction const& a, HighlightAction const& b) {
- return !(a == b);
+ return !(a == b);
}
}
diff --git a/Swift/Controllers/HighlightAction.h b/Swift/Controllers/HighlightAction.h
index 3930eee..b9d4539 100644
--- a/Swift/Controllers/HighlightAction.h
+++ b/Swift/Controllers/HighlightAction.h
@@ -19,64 +19,64 @@
namespace Swift {
- class HighlightRule;
-
- class HighlightAction {
- public:
- HighlightAction() : highlightWholeMessage_(false), playSound_(false) {}
-
- /**
- * Gets the flag that indicates the entire message should be highlighted.
- */
- bool highlightWholeMessage() const { return highlightWholeMessage_; }
- void setHighlightWholeMessage(bool highlightText);
-
- /**
- * Gets the foreground highlight color.
- */
- const std::string& getTextColor() const { return textColor_; }
- void setTextColor(const std::string& textColor) { textColor_ = textColor; }
-
- /**
- * Gets the background highlight color.
- */
- const std::string& getTextBackground() const { return textBackground_; }
- void setTextBackground(const std::string& textBackground) { textBackground_ = textBackground; }
-
- bool playSound() const { return playSound_; }
- void setPlaySound(bool playSound);
-
- /**
- * Gets the sound filename. If the string is empty, assume a default sound file.
- */
- const std::string& getSoundFile() const { return soundFile_; }
- void setSoundFile(const std::string& soundFile) { soundFile_ = soundFile; }
-
- bool isEmpty() const { return !highlightWholeMessage_ && !playSound_; }
-
- private:
- friend class boost::serialization::access;
- template<class Archive> void serialize(Archive & ar, const unsigned int version);
-
- bool highlightWholeMessage_;
- std::string textColor_;
- std::string textBackground_;
-
- bool playSound_;
- std::string soundFile_;
- };
-
- bool operator ==(HighlightAction const& a, HighlightAction const& b);
- bool operator !=(HighlightAction const& a, HighlightAction const& b);
-
- template<class Archive>
- void HighlightAction::serialize(Archive& ar, const unsigned int /*version*/)
- {
- ar & highlightWholeMessage_;
- ar & textColor_;
- ar & textBackground_;
- ar & playSound_;
- ar & soundFile_;
- }
+ class HighlightRule;
+
+ class HighlightAction {
+ public:
+ HighlightAction() : highlightWholeMessage_(false), playSound_(false) {}
+
+ /**
+ * Gets the flag that indicates the entire message should be highlighted.
+ */
+ bool highlightWholeMessage() const { return highlightWholeMessage_; }
+ void setHighlightWholeMessage(bool highlightText);
+
+ /**
+ * Gets the foreground highlight color.
+ */
+ const std::string& getTextColor() const { return textColor_; }
+ void setTextColor(const std::string& textColor) { textColor_ = textColor; }
+
+ /**
+ * Gets the background highlight color.
+ */
+ const std::string& getTextBackground() const { return textBackground_; }
+ void setTextBackground(const std::string& textBackground) { textBackground_ = textBackground; }
+
+ bool playSound() const { return playSound_; }
+ void setPlaySound(bool playSound);
+
+ /**
+ * Gets the sound filename. If the string is empty, assume a default sound file.
+ */
+ const std::string& getSoundFile() const { return soundFile_; }
+ void setSoundFile(const std::string& soundFile) { soundFile_ = soundFile; }
+
+ bool isEmpty() const { return !highlightWholeMessage_ && !playSound_; }
+
+ private:
+ friend class boost::serialization::access;
+ template<class Archive> void serialize(Archive & ar, const unsigned int version);
+
+ bool highlightWholeMessage_;
+ std::string textColor_;
+ std::string textBackground_;
+
+ bool playSound_;
+ std::string soundFile_;
+ };
+
+ bool operator ==(HighlightAction const& a, HighlightAction const& b);
+ bool operator !=(HighlightAction const& a, HighlightAction const& b);
+
+ template<class Archive>
+ void HighlightAction::serialize(Archive& ar, const unsigned int /*version*/)
+ {
+ ar & highlightWholeMessage_;
+ ar & textColor_;
+ ar & textBackground_;
+ ar & playSound_;
+ ar & soundFile_;
+ }
}
diff --git a/Swift/Controllers/HighlightEditorController.cpp b/Swift/Controllers/HighlightEditorController.cpp
index 35eb404..1f5f928 100644
--- a/Swift/Controllers/HighlightEditorController.cpp
+++ b/Swift/Controllers/HighlightEditorController.cpp
@@ -5,52 +5,53 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
+#include <Swift/Controllers/HighlightEditorController.h>
+
#include <boost/bind.hpp>
-#include <Swift/Controllers/HighlightEditorController.h>
+#include <Swift/Controllers/ContactSuggester.h>
#include <Swift/Controllers/UIEvents/RequestHighlightEditorUIEvent.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
-#include <Swift/Controllers/UIInterfaces/HighlightEditorWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/HighlightEditorWindow.h>
-#include <Swift/Controllers/ContactSuggester.h>
+#include <Swift/Controllers/UIInterfaces/HighlightEditorWindowFactory.h>
namespace Swift {
HighlightEditorController::HighlightEditorController(UIEventStream* uiEventStream, HighlightEditorWindowFactory* highlightEditorWindowFactory, HighlightManager* highlightManager)
-: highlightEditorWindowFactory_(highlightEditorWindowFactory), highlightEditorWindow_(NULL), highlightManager_(highlightManager), contactSuggester_(0)
+: highlightEditorWindowFactory_(highlightEditorWindowFactory), highlightEditorWindow_(nullptr), highlightManager_(highlightManager), contactSuggester_(nullptr)
{
- uiEventStream->onUIEvent.connect(boost::bind(&HighlightEditorController::handleUIEvent, this, _1));
+ uiEventStream->onUIEvent.connect(boost::bind(&HighlightEditorController::handleUIEvent, this, _1));
}
HighlightEditorController::~HighlightEditorController()
{
- delete highlightEditorWindow_;
- highlightEditorWindow_ = NULL;
+ delete highlightEditorWindow_;
+ highlightEditorWindow_ = nullptr;
}
-void HighlightEditorController::handleUIEvent(boost::shared_ptr<UIEvent> rawEvent)
+void HighlightEditorController::handleUIEvent(std::shared_ptr<UIEvent> rawEvent)
{
- boost::shared_ptr<RequestHighlightEditorUIEvent> event = boost::dynamic_pointer_cast<RequestHighlightEditorUIEvent>(rawEvent);
- if (event) {
- if (!highlightEditorWindow_) {
- highlightEditorWindow_ = highlightEditorWindowFactory_->createHighlightEditorWindow();
- highlightEditorWindow_->setHighlightManager(highlightManager_);
- highlightEditorWindow_->onContactSuggestionsRequested.connect(boost::bind(&HighlightEditorController::handleContactSuggestionsRequested, this, _1));
- }
- highlightEditorWindow_->show();
- }
+ std::shared_ptr<RequestHighlightEditorUIEvent> event = std::dynamic_pointer_cast<RequestHighlightEditorUIEvent>(rawEvent);
+ if (event) {
+ if (!highlightEditorWindow_) {
+ highlightEditorWindow_ = highlightEditorWindowFactory_->createHighlightEditorWindow();
+ highlightEditorWindow_->setHighlightManager(highlightManager_);
+ highlightEditorWindow_->onContactSuggestionsRequested.connect(boost::bind(&HighlightEditorController::handleContactSuggestionsRequested, this, _1));
+ }
+ highlightEditorWindow_->show();
+ }
}
void HighlightEditorController::handleContactSuggestionsRequested(const std::string& text)
{
- if (contactSuggester_) {
- highlightEditorWindow_->setContactSuggestions(contactSuggester_->getSuggestions(text, true));
- }
+ if (contactSuggester_) {
+ highlightEditorWindow_->setContactSuggestions(contactSuggester_->getSuggestions(text, true));
+ }
}
}
diff --git a/Swift/Controllers/HighlightEditorController.h b/Swift/Controllers/HighlightEditorController.h
index 52587c2..a699751 100644
--- a/Swift/Controllers/HighlightEditorController.h
+++ b/Swift/Controllers/HighlightEditorController.h
@@ -5,44 +5,45 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
+#include <string>
#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class UIEventStream;
+ class UIEventStream;
- class HighlightEditorWindowFactory;
- class HighlightEditorWindow;
+ class HighlightEditorWindowFactory;
+ class HighlightEditorWindow;
- class HighlightManager;
- class ContactSuggester;
+ class HighlightManager;
+ class ContactSuggester;
- class HighlightEditorController {
- public:
- HighlightEditorController(UIEventStream* uiEventStream, HighlightEditorWindowFactory* highlightEditorWindowFactory, HighlightManager* highlightManager);
- ~HighlightEditorController();
+ class HighlightEditorController {
+ public:
+ HighlightEditorController(UIEventStream* uiEventStream, HighlightEditorWindowFactory* highlightEditorWindowFactory, HighlightManager* highlightManager);
+ ~HighlightEditorController();
- HighlightManager* getHighlightManager() const { return highlightManager_; }
- void setContactSuggester(ContactSuggester *suggester) { contactSuggester_ = suggester; }
+ HighlightManager* getHighlightManager() const { return highlightManager_; }
+ void setContactSuggester(ContactSuggester *suggester) { contactSuggester_ = suggester; }
- private:
- void handleUIEvent(boost::shared_ptr<UIEvent> event);
- void handleContactSuggestionsRequested(const std::string& text);
+ private:
+ void handleUIEvent(std::shared_ptr<UIEvent> event);
+ void handleContactSuggestionsRequested(const std::string& text);
- private:
- HighlightEditorWindowFactory* highlightEditorWindowFactory_;
- HighlightEditorWindow* highlightEditorWindow_;
- HighlightManager* highlightManager_;
- ContactSuggester* contactSuggester_;
- };
+ private:
+ HighlightEditorWindowFactory* highlightEditorWindowFactory_;
+ HighlightEditorWindow* highlightEditorWindow_;
+ HighlightManager* highlightManager_;
+ ContactSuggester* contactSuggester_;
+ };
}
diff --git a/Swift/Controllers/HighlightManager.cpp b/Swift/Controllers/HighlightManager.cpp
index e5c8cef..9176301 100644
--- a/Swift/Controllers/HighlightManager.cpp
+++ b/Swift/Controllers/HighlightManager.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -13,6 +13,7 @@
#include <Swift/Controllers/HighlightManager.h>
#include <cassert>
+#include <sstream>
#include <boost/algorithm/string.hpp>
#include <boost/archive/text_iarchive.hpp>
@@ -22,8 +23,6 @@
#include <boost/regex.hpp>
#include <boost/serialization/vector.hpp>
-#include <Swiften/Base/foreach.h>
-
#include <Swift/Controllers/Highlighter.h>
#include <Swift/Controllers/SettingConstants.h>
#include <Swift/Controllers/Settings/SettingsProvider.h>
@@ -48,113 +47,102 @@
namespace Swift {
HighlightManager::HighlightManager(SettingsProvider* settings)
- : settings_(settings)
- , storingSettings_(false)
-{
- rules_ = boost::make_shared<HighlightRulesList>();
- loadSettings();
- handleSettingChangedConnection_ = settings_->onSettingChanged.connect(boost::bind(&HighlightManager::handleSettingChanged, this, _1));
+ : settings_(settings)
+ , storingSettings_(false) {
+ rules_ = std::make_shared<HighlightRulesList>();
+ loadSettings();
+ handleSettingChangedConnection_ = settings_->onSettingChanged.connect(boost::bind(&HighlightManager::handleSettingChanged, this, _1));
}
-void HighlightManager::handleSettingChanged(const std::string& settingPath)
-{
- if (!storingSettings_ && SettingConstants::HIGHLIGHT_RULES.getKey() == settingPath) {
- loadSettings();
- }
+void HighlightManager::handleSettingChanged(const std::string& settingPath) {
+ if (!storingSettings_ && SettingConstants::HIGHLIGHT_RULES.getKey() == settingPath) {
+ loadSettings();
+ }
}
-std::string HighlightManager::rulesToString() const
-{
- std::stringstream stream;
- boost::archive::text_oarchive archive(stream);
- archive << rules_->list_;
- return stream.str();
+std::string HighlightManager::rulesToString() const {
+ std::stringstream stream;
+ boost::archive::text_oarchive archive(stream);
+ archive & rules_->list_;
+ return stream.str();
}
-std::vector<HighlightRule> HighlightManager::getDefaultRules()
-{
- std::vector<HighlightRule> rules;
-
- HighlightRule chatNotificationRule;
- chatNotificationRule.setMatchChat(true);
- chatNotificationRule.getAction().setPlaySound(true);
- chatNotificationRule.setMatchWholeWords(true);
- rules.push_back(chatNotificationRule);
-
- HighlightRule selfMentionMUCRule;
- selfMentionMUCRule.setMatchMUC(true);
- selfMentionMUCRule.getAction().setPlaySound(true);
- selfMentionMUCRule.setNickIsKeyword(true);
- selfMentionMUCRule.setMatchCase(true);
- selfMentionMUCRule.setMatchWholeWords(true);
- rules.push_back(selfMentionMUCRule);
-
- return rules;
+std::vector<HighlightRule> HighlightManager::getDefaultRules() {
+ std::vector<HighlightRule> rules;
+
+ HighlightRule chatNotificationRule;
+ chatNotificationRule.setMatchChat(true);
+ chatNotificationRule.getAction().setPlaySound(true);
+ chatNotificationRule.setMatchWholeWords(true);
+ rules.push_back(chatNotificationRule);
+
+ HighlightRule selfMentionMUCRule;
+ selfMentionMUCRule.setMatchMUC(true);
+ selfMentionMUCRule.getAction().setPlaySound(true);
+ selfMentionMUCRule.setNickIsKeyword(true);
+ selfMentionMUCRule.setMatchCase(true);
+ selfMentionMUCRule.setMatchWholeWords(true);
+ rules.push_back(selfMentionMUCRule);
+
+ return rules;
}
-HighlightRule HighlightManager::getRule(int index) const
-{
- assert(index >= 0 && static_cast<size_t>(index) < rules_->getSize());
- return rules_->getRule(static_cast<size_t>(index));
+HighlightRule HighlightManager::getRule(int index) const {
+ assert(index >= 0 && static_cast<size_t>(index) < rules_->getSize());
+ return rules_->getRule(static_cast<size_t>(index));
}
-void HighlightManager::setRule(int index, const HighlightRule& rule)
-{
- assert(index >= 0 && static_cast<size_t>(index) < rules_->getSize());
- rules_->list_[static_cast<size_t>(index)] = rule;
+void HighlightManager::setRule(int index, const HighlightRule& rule) {
+ assert(index >= 0 && static_cast<size_t>(index) < rules_->getSize());
+ rules_->list_[static_cast<size_t>(index)] = rule;
}
-void HighlightManager::insertRule(int index, const HighlightRule& rule)
-{
- assert(index >= 0 && boost::numeric_cast<std::vector<std::string>::size_type>(index) <= rules_->getSize());
- rules_->list_.insert(rules_->list_.begin() + index, rule);
+void HighlightManager::insertRule(int index, const HighlightRule& rule) {
+ assert(index >= 0 && boost::numeric_cast<std::vector<std::string>::size_type>(index) <= rules_->getSize());
+ rules_->list_.insert(rules_->list_.begin() + index, rule);
}
-void HighlightManager::removeRule(int index)
-{
- assert(index >= 0 && boost::numeric_cast<std::vector<std::string>::size_type>(index) < rules_->getSize());
- rules_->list_.erase(rules_->list_.begin() + index);
+void HighlightManager::removeRule(int index) {
+ assert(index >= 0 && boost::numeric_cast<std::vector<std::string>::size_type>(index) < rules_->getSize());
+ rules_->list_.erase(rules_->list_.begin() + index);
}
void HighlightManager::swapRules(const size_t first, const size_t second) {
- assert(first < rules_->getSize());
- assert(second < rules_->getSize());
- const HighlightRule swap = rules_->getRule(first);
- rules_->setRule(first, rules_->getRule(second));
- rules_->setRule(second, swap);
+ assert(first < rules_->getSize());
+ assert(second < rules_->getSize());
+ const HighlightRule swap = rules_->getRule(first);
+ rules_->setRule(first, rules_->getRule(second));
+ rules_->setRule(second, swap);
}
-void HighlightManager::storeSettings()
-{
- storingSettings_ = true; // don't reload settings while saving
- settings_->storeSetting(SettingConstants::HIGHLIGHT_RULES, rulesToString());
- storingSettings_ = false;
+void HighlightManager::storeSettings() {
+ storingSettings_ = true; // don't reload settings while saving
+ settings_->storeSetting(SettingConstants::HIGHLIGHT_RULES, rulesToString());
+ storingSettings_ = false;
}
-void HighlightManager::loadSettings()
-{
- std::string rulesString = settings_->getSetting(SettingConstants::HIGHLIGHT_RULES);
- std::stringstream stream;
- stream << rulesString;
- try {
- boost::archive::text_iarchive archive(stream);
- archive >> rules_->list_;
- } catch (boost::archive::archive_exception&) {
- rules_->list_ = getDefaultRules();
- }
+void HighlightManager::loadSettings() {
+ std::string rulesString = settings_->getSetting(SettingConstants::HIGHLIGHT_RULES);
+ std::stringstream stream;
+ stream << rulesString;
+ try {
+ boost::archive::text_iarchive archive(stream);
+ archive >> rules_->list_;
+ } catch (boost::archive::archive_exception&) {
+ rules_->list_ = getDefaultRules();
+ }
}
-Highlighter* HighlightManager::createHighlighter()
-{
- return new Highlighter(this);
+Highlighter* HighlightManager::createHighlighter() {
+ return new Highlighter(this);
}
bool HighlightManager::isDefaultRulesList() const {
- return getDefaultRules() == rules_->list_;
+ return getDefaultRules() == rules_->list_;
}
void HighlightManager::resetToDefaultRulesList() {
- rules_->list_ = getDefaultRules();
+ rules_->list_ = getDefaultRules();
}
}
diff --git a/Swift/Controllers/HighlightManager.h b/Swift/Controllers/HighlightManager.h
index c55990b..a35e253 100644
--- a/Swift/Controllers/HighlightManager.h
+++ b/Swift/Controllers/HighlightManager.h
@@ -5,76 +5,77 @@
*/
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <vector>
#include <string>
+#include <vector>
+
+#include <boost/signals2.hpp>
-#include <Swiften/Base/boost_bsignals.h>
#include <Swift/Controllers/HighlightRule.h>
namespace Swift {
- class SettingsProvider;
- class Highlighter;
+ class SettingsProvider;
+ class Highlighter;
- class HighlightManager {
- public:
+ class HighlightManager {
+ public:
- class HighlightRulesList {
- public:
- friend class HighlightManager;
- size_t getSize() const { return list_.size(); }
- const HighlightRule& getRule(const size_t index) const { return list_[index]; }
- void addRule(const HighlightRule& rule) { list_.push_back(rule); }
- void combineRules(const HighlightRulesList& rhs) {
- list_.insert(list_.end(), rhs.list_.begin(), rhs.list_.end());
- }
- void setRule(const size_t index, const HighlightRule& rule) {
- list_[index] = rule;
- }
- private:
- std::vector<HighlightRule> list_;
- };
+ class HighlightRulesList {
+ public:
+ friend class HighlightManager;
+ size_t getSize() const { return list_.size(); }
+ const HighlightRule& getRule(const size_t index) const { return list_[index]; }
+ void addRule(const HighlightRule& rule) { list_.push_back(rule); }
+ void combineRules(const HighlightRulesList& rhs) {
+ list_.insert(list_.end(), rhs.list_.begin(), rhs.list_.end());
+ }
+ void setRule(const size_t index, const HighlightRule& rule) {
+ list_[index] = rule;
+ }
+ private:
+ std::vector<HighlightRule> list_;
+ };
- HighlightManager(SettingsProvider* settings);
+ HighlightManager(SettingsProvider* settings);
- Highlighter* createHighlighter();
+ Highlighter* createHighlighter();
- boost::shared_ptr<const HighlightManager::HighlightRulesList> getRules() const { return rules_; }
+ std::shared_ptr<const HighlightManager::HighlightRulesList> getRules() const { return rules_; }
- bool isDefaultRulesList() const;
- void resetToDefaultRulesList();
+ bool isDefaultRulesList() const;
+ void resetToDefaultRulesList();
- HighlightRule getRule(int index) const;
- void setRule(int index, const HighlightRule& rule);
- void insertRule(int index, const HighlightRule& rule);
- void removeRule(int index);
- void swapRules(const size_t first, const size_t second);
- void storeSettings();
- void loadSettings();
+ HighlightRule getRule(int index) const;
+ void setRule(int index, const HighlightRule& rule);
+ void insertRule(int index, const HighlightRule& rule);
+ void removeRule(int index);
+ void swapRules(const size_t first, const size_t second);
+ void storeSettings();
+ void loadSettings();
- boost::signal<void (const HighlightAction&)> onHighlight;
+ boost::signals2::signal<void (const HighlightAction&)> onHighlight;
- private:
- void handleSettingChanged(const std::string& settingPath);
+ private:
+ void handleSettingChanged(const std::string& settingPath);
- std::string rulesToString() const;
- static std::vector<HighlightRule> getDefaultRules();
+ std::string rulesToString() const;
+ static std::vector<HighlightRule> getDefaultRules();
- private:
- SettingsProvider* settings_;
- bool storingSettings_;
+ private:
+ SettingsProvider* settings_;
+ bool storingSettings_;
- boost::shared_ptr<HighlightManager::HighlightRulesList> rules_;
- boost::bsignals::scoped_connection handleSettingChangedConnection_;
- };
+ std::shared_ptr<HighlightManager::HighlightRulesList> rules_;
+ boost::signals2::scoped_connection handleSettingChangedConnection_;
+ };
- typedef boost::shared_ptr<const HighlightManager::HighlightRulesList> HighlightRulesListPtr;
+ typedef std::shared_ptr<const HighlightManager::HighlightRulesList> HighlightRulesListPtr;
}
diff --git a/Swift/Controllers/HighlightRule.cpp b/Swift/Controllers/HighlightRule.cpp
index 021e15d..a8cb7e4 100644
--- a/Swift/Controllers/HighlightRule.cpp
+++ b/Swift/Controllers/HighlightRule.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -18,184 +18,183 @@
#include <boost/lambda/lambda.hpp>
#include <Swiften/Base/Regex.h>
-#include <Swiften/Base/foreach.h>
namespace Swift {
HighlightRule::HighlightRule()
- : nickIsKeyword_(false)
- , matchCase_(false)
- , matchWholeWords_(false)
- , matchChat_(false)
- , matchMUC_(false)
+ : nickIsKeyword_(false)
+ , matchCase_(false)
+ , matchWholeWords_(false)
+ , matchChat_(false)
+ , matchMUC_(false)
{
}
boost::regex HighlightRule::regexFromString(const std::string & s) const
{
- std::string escaped = Regex::escape(s);
- std::string word = matchWholeWords_ ? "\\b" : "";
- boost::regex::flag_type flags = boost::regex::normal;
- if (!matchCase_) {
- flags |= boost::regex::icase;
- }
- return boost::regex(word + escaped + word, flags);
+ std::string escaped = Regex::escape(s);
+ std::string word = matchWholeWords_ ? "\\b" : "";
+ boost::regex::flag_type flags = boost::regex::normal;
+ if (!matchCase_) {
+ flags |= boost::regex::icase;
+ }
+ return boost::regex(word + escaped + word, flags);
}
void HighlightRule::updateRegex() const
{
- keywordRegex_.clear();
- foreach (const std::string & k, keywords_) {
- keywordRegex_.push_back(regexFromString(k));
- }
- senderRegex_.clear();
- foreach (const std::string & s, senders_) {
- senderRegex_.push_back(regexFromString(s));
- }
+ keywordRegex_.clear();
+ for (const auto& k : keywords_) {
+ keywordRegex_.push_back(regexFromString(k));
+ }
+ senderRegex_.clear();
+ for (const auto& s : senders_) {
+ senderRegex_.push_back(regexFromString(s));
+ }
}
std::string HighlightRule::boolToString(bool b)
{
- return b ? "1" : "0";
+ return b ? "1" : "0";
}
bool HighlightRule::boolFromString(const std::string& s)
{
- return s == "1";
+ return s == "1";
}
bool HighlightRule::isMatch(const std::string& body, const std::string& sender, const std::string& nick, MessageType messageType) const
{
- if ((messageType == HighlightRule::ChatMessage && matchChat_) || (messageType == HighlightRule::MUCMessage && matchMUC_)) {
-
- bool matchesKeyword = keywords_.empty() && (nick.empty() || !nickIsKeyword_);
- bool matchesSender = senders_.empty();
-
- if (!matchesKeyword) {
- // check if the nickname matches
- if (nickIsKeyword_ && !nick.empty() && boost::regex_search(body, regexFromString(nick))) {
- matchesKeyword = true;
- }
-
- // check if a keyword matches
- if (!matchesKeyword && !keywords_.empty()) {
- foreach (const boost::regex &keyword, keywordRegex_) {
- if (boost::regex_search(body, keyword)) {
- matchesKeyword = true;
- break;
- }
- }
- }
- }
-
- foreach (const boost::regex & rx, senderRegex_) {
- if (boost::regex_search(sender, rx)) {
- matchesSender = true;
- break;
- }
- }
-
- if (matchesKeyword && matchesSender) {
- return true;
- }
- }
-
- return false;
+ if ((messageType == HighlightRule::ChatMessage && matchChat_) || (messageType == HighlightRule::MUCMessage && matchMUC_)) {
+
+ bool matchesKeyword = keywords_.empty() && (nick.empty() || !nickIsKeyword_);
+ bool matchesSender = senders_.empty();
+
+ if (!matchesKeyword) {
+ // check if the nickname matches
+ if (nickIsKeyword_ && !nick.empty() && boost::regex_search(body, regexFromString(nick))) {
+ matchesKeyword = true;
+ }
+
+ // check if a keyword matches
+ if (!matchesKeyword && !keywords_.empty()) {
+ for (const auto& keyword : keywordRegex_) {
+ if (boost::regex_search(body, keyword)) {
+ matchesKeyword = true;
+ break;
+ }
+ }
+ }
+ }
+
+ for (const auto& rx : senderRegex_) {
+ if (boost::regex_search(sender, rx)) {
+ matchesSender = true;
+ break;
+ }
+ }
+
+ if (matchesKeyword && matchesSender) {
+ return true;
+ }
+ }
+
+ return false;
}
void HighlightRule::setSenders(const std::vector<std::string>& senders)
{
- senders_ = senders;
- updateRegex();
+ senders_ = senders;
+ updateRegex();
}
void HighlightRule::setKeywords(const std::vector<std::string>& keywords)
{
- keywords_ = keywords;
- updateRegex();
+ keywords_ = keywords;
+ updateRegex();
}
std::vector<boost::regex> HighlightRule::getKeywordRegex(const std::string& nick) const {
- if (nickIsKeyword_) {
- std::vector<boost::regex> regex;
- if (!nick.empty()) {
- regex.push_back(regexFromString(nick));
- }
- return regex;
- } else {
- return keywordRegex_;
- }
+ if (nickIsKeyword_) {
+ std::vector<boost::regex> regex;
+ if (!nick.empty()) {
+ regex.push_back(regexFromString(nick));
+ }
+ return regex;
+ } else {
+ return keywordRegex_;
+ }
}
void HighlightRule::setNickIsKeyword(bool nickIsKeyword)
{
- nickIsKeyword_ = nickIsKeyword;
- updateRegex();
+ nickIsKeyword_ = nickIsKeyword;
+ updateRegex();
}
void HighlightRule::setMatchCase(bool matchCase)
{
- matchCase_ = matchCase;
- updateRegex();
+ matchCase_ = matchCase;
+ updateRegex();
}
void HighlightRule::setMatchWholeWords(bool matchWholeWords)
{
- matchWholeWords_ = matchWholeWords;
- updateRegex();
+ matchWholeWords_ = matchWholeWords;
+ updateRegex();
}
void HighlightRule::setMatchChat(bool matchChat)
{
- matchChat_ = matchChat;
- updateRegex();
+ matchChat_ = matchChat;
+ updateRegex();
}
void HighlightRule::setMatchMUC(bool matchMUC)
{
- matchMUC_ = matchMUC;
- updateRegex();
+ matchMUC_ = matchMUC;
+ updateRegex();
}
bool HighlightRule::isEmpty() const
{
- return senders_.empty() && keywords_.empty() && !nickIsKeyword_ && !matchChat_ && !matchMUC_ && action_.isEmpty();
+ return senders_.empty() && keywords_.empty() && !nickIsKeyword_ && !matchChat_ && !matchMUC_ && action_.isEmpty();
}
bool operator ==(HighlightRule const& a, HighlightRule const& b) {
- if (a.getSenders() != b.getSenders()) {
- return false;
- }
+ if (a.getSenders() != b.getSenders()) {
+ return false;
+ }
- if (a.getKeywords() != b.getKeywords()) {
- return false;
- }
+ if (a.getKeywords() != b.getKeywords()) {
+ return false;
+ }
- if (a.getNickIsKeyword() != b.getNickIsKeyword()) {
- return false;
- }
+ if (a.getNickIsKeyword() != b.getNickIsKeyword()) {
+ return false;
+ }
- if (a.getMatchChat() != b.getMatchChat()) {
- return false;
- }
+ if (a.getMatchChat() != b.getMatchChat()) {
+ return false;
+ }
- if (a.getMatchMUC() != b.getMatchMUC()) {
- return false;
- }
+ if (a.getMatchMUC() != b.getMatchMUC()) {
+ return false;
+ }
- if (a.getMatchCase() != b.getMatchCase()) {
- return false;
- }
+ if (a.getMatchCase() != b.getMatchCase()) {
+ return false;
+ }
- if (a.getMatchWholeWords() != b.getMatchWholeWords()) {
- return false;
- }
+ if (a.getMatchWholeWords() != b.getMatchWholeWords()) {
+ return false;
+ }
- if (a.getAction() != b.getAction()) {
- return false;
- }
+ if (a.getAction() != b.getAction()) {
+ return false;
+ }
- return true;
+ return true;
}
}
diff --git a/Swift/Controllers/HighlightRule.h b/Swift/Controllers/HighlightRule.h
index 02b4864..bffdc41 100644
--- a/Swift/Controllers/HighlightRule.h
+++ b/Swift/Controllers/HighlightRule.h
@@ -5,99 +5,99 @@
*/
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <vector>
#include <string>
+#include <vector>
-#include <boost/regex.hpp>
-#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/regex.hpp>
#include <Swift/Controllers/HighlightAction.h>
namespace Swift {
- class HighlightRule {
- public:
- HighlightRule();
+ class HighlightRule {
+ public:
+ HighlightRule();
- enum MessageType { ChatMessage, MUCMessage };
+ enum MessageType { ChatMessage, MUCMessage };
- bool isMatch(const std::string& body, const std::string& sender, const std::string& nick, MessageType) const;
+ bool isMatch(const std::string& body, const std::string& sender, const std::string& nick, MessageType) const;
- const HighlightAction& getAction() const { return action_; }
- HighlightAction& getAction() { return action_; }
+ const HighlightAction& getAction() const { return action_; }
+ HighlightAction& getAction() { return action_; }
- const std::vector<std::string>& getSenders() const { return senders_; }
- void setSenders(const std::vector<std::string>&);
- const std::vector<boost::regex>& getSenderRegex() const { return senderRegex_; }
+ const std::vector<std::string>& getSenders() const { return senders_; }
+ void setSenders(const std::vector<std::string>&);
+ const std::vector<boost::regex>& getSenderRegex() const { return senderRegex_; }
- const std::vector<std::string>& getKeywords() const { return keywords_; }
- void setKeywords(const std::vector<std::string>&);
- std::vector<boost::regex> getKeywordRegex(const std::string& nick) const;
+ const std::vector<std::string>& getKeywords() const { return keywords_; }
+ void setKeywords(const std::vector<std::string>&);
+ std::vector<boost::regex> getKeywordRegex(const std::string& nick) const;
- bool getNickIsKeyword() const { return nickIsKeyword_; }
- void setNickIsKeyword(bool);
+ bool getNickIsKeyword() const { return nickIsKeyword_; }
+ void setNickIsKeyword(bool);
- bool getMatchCase() const { return matchCase_; }
- void setMatchCase(bool);
+ bool getMatchCase() const { return matchCase_; }
+ void setMatchCase(bool);
- bool getMatchWholeWords() const { return matchWholeWords_; }
- void setMatchWholeWords(bool);
+ bool getMatchWholeWords() const { return matchWholeWords_; }
+ void setMatchWholeWords(bool);
- bool getMatchChat() const { return matchChat_; }
- void setMatchChat(bool);
+ bool getMatchChat() const { return matchChat_; }
+ void setMatchChat(bool);
- bool getMatchMUC() const { return matchMUC_; }
- void setMatchMUC(bool);
+ bool getMatchMUC() const { return matchMUC_; }
+ void setMatchMUC(bool);
- bool isEmpty() const;
+ bool isEmpty() const;
- private:
- friend class boost::serialization::access;
- template<class Archive> void serialize(Archive & ar, const unsigned int version);
+ private:
+ friend class boost::serialization::access;
+ template<class Archive> void serialize(Archive & ar, const unsigned int version);
- static std::string boolToString(bool);
- static bool boolFromString(const std::string&);
+ static std::string boolToString(bool);
+ static bool boolFromString(const std::string&);
- std::vector<std::string> senders_;
- std::vector<std::string> keywords_;
- bool nickIsKeyword_;
+ std::vector<std::string> senders_;
+ std::vector<std::string> keywords_;
+ bool nickIsKeyword_;
- mutable std::vector<boost::regex> senderRegex_;
- mutable std::vector<boost::regex> keywordRegex_;
- void updateRegex() const;
- boost::regex regexFromString(const std::string&) const;
+ mutable std::vector<boost::regex> senderRegex_;
+ mutable std::vector<boost::regex> keywordRegex_;
+ void updateRegex() const;
+ boost::regex regexFromString(const std::string&) const;
- bool matchCase_;
- bool matchWholeWords_;
+ bool matchCase_;
+ bool matchWholeWords_;
- bool matchChat_;
- bool matchMUC_;
+ bool matchChat_;
+ bool matchMUC_;
- HighlightAction action_;
- };
+ HighlightAction action_;
+ };
- bool operator ==(HighlightRule const& a, HighlightRule const& b);
+ bool operator ==(HighlightRule const& a, HighlightRule const& b);
- template<class Archive>
- void HighlightRule::serialize(Archive& ar, const unsigned int /*version*/)
- {
- ar & senders_;
- ar & keywords_;
- ar & nickIsKeyword_;
- ar & matchChat_;
- ar & matchMUC_;
- ar & matchCase_;
- ar & matchWholeWords_;
- ar & action_;
- updateRegex();
- }
+ template<class Archive>
+ void HighlightRule::serialize(Archive& ar, const unsigned int /*version*/)
+ {
+ ar & senders_;
+ ar & keywords_;
+ ar & nickIsKeyword_;
+ ar & matchChat_;
+ ar & matchMUC_;
+ ar & matchCase_;
+ ar & matchWholeWords_;
+ ar & action_;
+ updateRegex();
+ }
}
diff --git a/Swift/Controllers/Highlighter.cpp b/Swift/Controllers/Highlighter.cpp
index 13ee951..cea077e 100644
--- a/Swift/Controllers/Highlighter.cpp
+++ b/Swift/Controllers/Highlighter.cpp
@@ -5,45 +5,47 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include <Swiften/Base/foreach.h>
#include <Swift/Controllers/Highlighter.h>
+
#include <Swift/Controllers/HighlightManager.h>
namespace Swift {
Highlighter::Highlighter(HighlightManager* manager)
- : manager_(manager)
+ : manager_(manager)
{
- setMode(ChatMode);
+ setMode(ChatMode);
}
void Highlighter::setMode(Mode mode)
{
- mode_ = mode;
- messageType_ = mode_ == ChatMode ? HighlightRule::ChatMessage : HighlightRule::MUCMessage;
+ mode_ = mode;
+ messageType_ = mode_ == ChatMode ? HighlightRule::ChatMessage : HighlightRule::MUCMessage;
}
-HighlightAction Highlighter::findAction(const std::string& body, const std::string& sender) const
+HighlightAction Highlighter::findFirstFullMessageMatchAction(const std::string& body, const std::string& sender) const
{
- HighlightRulesListPtr rules = manager_->getRules();
- for (size_t i = 0; i < rules->getSize(); ++i) {
- const HighlightRule& rule = rules->getRule(i);
- if (rule.isMatch(body, sender, nick_, messageType_)) {
- return rule.getAction();
- }
- }
-
- return HighlightAction();
+ HighlightAction match;
+ HighlightRulesListPtr rules = manager_->getRules();
+ for (size_t i = 0; i < rules->getSize(); ++i) {
+ const HighlightRule& rule = rules->getRule(i);
+ if (rule.isMatch(body, sender, nick_, messageType_) && rule.getAction().highlightWholeMessage()) {
+ match = rule.getAction();
+ break;
+ }
+ }
+
+ return match;
}
void Highlighter::handleHighlightAction(const HighlightAction& action)
{
- manager_->onHighlight(action);
+ manager_->onHighlight(action);
}
}
diff --git a/Swift/Controllers/Highlighter.h b/Swift/Controllers/Highlighter.h
index d5d846b..9ad3339 100644
--- a/Swift/Controllers/Highlighter.h
+++ b/Swift/Controllers/Highlighter.h
@@ -4,35 +4,42 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <string>
+#include <vector>
#include <Swift/Controllers/HighlightRule.h>
namespace Swift {
- class HighlightManager;
+ class HighlightManager;
- class Highlighter {
- public:
- Highlighter(HighlightManager* manager);
+ class Highlighter {
+ public:
+ Highlighter(HighlightManager* manager);
- enum Mode { ChatMode, MUCMode };
- void setMode(Mode mode);
+ enum Mode { ChatMode, MUCMode };
+ void setMode(Mode mode);
- void setNick(const std::string& nick) { nick_ = nick; }
- std::string getNick() const { return nick_; }
+ void setNick(const std::string& nick) { nick_ = nick; }
+ std::string getNick() const { return nick_; }
- HighlightAction findAction(const std::string& body, const std::string& sender) const;
+ HighlightAction findFirstFullMessageMatchAction(const std::string& body, const std::string& sender) const;
- void handleHighlightAction(const HighlightAction& action);
+ void handleHighlightAction(const HighlightAction& action);
- private:
- HighlightManager* manager_;
- Mode mode_;
- HighlightRule::MessageType messageType_;
- std::string nick_;
- };
+ private:
+ HighlightManager* manager_;
+ Mode mode_;
+ HighlightRule::MessageType messageType_;
+ std::string nick_;
+ };
}
diff --git a/Swift/Controllers/HistoryController.cpp b/Swift/Controllers/HistoryController.cpp
index f439429..1e5830c 100644
--- a/Swift/Controllers/HistoryController.cpp
+++ b/Swift/Controllers/HistoryController.cpp
@@ -28,39 +28,39 @@ HistoryController::~HistoryController() {
}
void HistoryController::addMessage(const std::string& message, const JID& fromJID, const JID& toJID, HistoryMessage::Type type, const boost::posix_time::ptime& timeStamp) {
- // note: using localtime timestamps
- boost::posix_time::ptime localTime = boost::date_time::c_local_adjustor<boost::posix_time::ptime>::utc_to_local(timeStamp);
- int offset = (localTime - timeStamp).hours();
+ // note: using localtime timestamps
+ boost::posix_time::ptime localTime = boost::date_time::c_local_adjustor<boost::posix_time::ptime>::utc_to_local(timeStamp);
+ int offset = (localTime - timeStamp).hours();
- HistoryMessage historyMessage(message, fromJID, toJID, type, localTime, offset);
+ HistoryMessage historyMessage(message, fromJID, toJID, type, localTime, offset);
- localHistory_->addMessage(historyMessage);
- onNewMessage(historyMessage);
+ localHistory_->addMessage(historyMessage);
+ onNewMessage(historyMessage);
}
std::vector<HistoryMessage> HistoryController::getMessagesFromDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const {
- return localHistory_->getMessagesFromDate(selfJID, contactJID, type, date);
+ return localHistory_->getMessagesFromDate(selfJID, contactJID, type, date);
}
std::vector<HistoryMessage> HistoryController::getMUCContext(const JID& selfJID, const JID& mucJID, const boost::posix_time::ptime& timeStamp) const {
- boost::posix_time::ptime localTime = boost::date_time::c_local_adjustor<boost::posix_time::ptime>::utc_to_local(timeStamp);
- return getMessagesFromDate(selfJID, mucJID, HistoryMessage::Groupchat, localTime.date());
+ boost::posix_time::ptime localTime = boost::date_time::c_local_adjustor<boost::posix_time::ptime>::utc_to_local(timeStamp);
+ return getMessagesFromDate(selfJID, mucJID, HistoryMessage::Groupchat, localTime.date());
}
std::vector<HistoryMessage> HistoryController::getMessagesFromPreviousDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const {
- return localHistory_->getMessagesFromPreviousDate(selfJID, contactJID, type, date);
+ return localHistory_->getMessagesFromPreviousDate(selfJID, contactJID, type, date);
}
std::vector<HistoryMessage> HistoryController::getMessagesFromNextDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const {
- return localHistory_->getMessagesFromNextDate(selfJID, contactJID, type, date);
+ return localHistory_->getMessagesFromNextDate(selfJID, contactJID, type, date);
}
ContactsMap HistoryController::getContacts(const JID& selfJID, HistoryMessage::Type type, const std::string& keyword) const {
- return localHistory_->getContacts(selfJID, type, keyword);
+ return localHistory_->getContacts(selfJID, type, keyword);
}
boost::posix_time::ptime HistoryController::getLastTimeStampFromMUC(const JID& selfJID, const JID& mucJID) {
- return localHistory_->getLastTimeStampFromMUC(selfJID, mucJID);
+ return localHistory_->getLastTimeStampFromMUC(selfJID, mucJID);
}
}
diff --git a/Swift/Controllers/HistoryController.h b/Swift/Controllers/HistoryController.h
index 0bdbb35..af70505 100644
--- a/Swift/Controllers/HistoryController.h
+++ b/Swift/Controllers/HistoryController.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -15,31 +15,31 @@
#include <vector>
#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/signals2.hpp>
-#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/History/HistoryMessage.h>
#include <Swiften/History/HistoryStorage.h>
namespace Swift {
- class JID;
+ class JID;
- class HistoryController {
- public:
- HistoryController(HistoryStorage* localHistoryStorage);
- ~HistoryController();
+ class HistoryController {
+ public:
+ HistoryController(HistoryStorage* localHistoryStorage);
+ ~HistoryController();
- void addMessage(const std::string& message, const JID& fromJID, const JID& toJID, HistoryMessage::Type type, const boost::posix_time::ptime& timeStamp);
- std::vector<HistoryMessage> getMessagesFromDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
- std::vector<HistoryMessage> getMessagesFromPreviousDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
- std::vector<HistoryMessage> getMessagesFromNextDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
- ContactsMap getContacts(const JID& selfJID, HistoryMessage::Type type, const std::string& keyword = std::string()) const;
- std::vector<HistoryMessage> getMUCContext(const JID& selfJID, const JID& mucJID, const boost::posix_time::ptime& timeStamp) const;
+ void addMessage(const std::string& message, const JID& fromJID, const JID& toJID, HistoryMessage::Type type, const boost::posix_time::ptime& timeStamp);
+ std::vector<HistoryMessage> getMessagesFromDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
+ std::vector<HistoryMessage> getMessagesFromPreviousDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
+ std::vector<HistoryMessage> getMessagesFromNextDate(const JID& selfJID, const JID& contactJID, HistoryMessage::Type type, const boost::gregorian::date& date) const;
+ ContactsMap getContacts(const JID& selfJID, HistoryMessage::Type type, const std::string& keyword = std::string()) const;
+ std::vector<HistoryMessage> getMUCContext(const JID& selfJID, const JID& mucJID, const boost::posix_time::ptime& timeStamp) const;
- boost::posix_time::ptime getLastTimeStampFromMUC(const JID& selfJID, const JID& mucJID);
+ boost::posix_time::ptime getLastTimeStampFromMUC(const JID& selfJID, const JID& mucJID);
- boost::signal<void (const HistoryMessage&)> onNewMessage;
+ boost::signals2::signal<void (const HistoryMessage&)> onNewMessage;
- private:
- HistoryStorage* localHistory_;
- };
+ private:
+ HistoryStorage* localHistory_;
+ };
}
diff --git a/Swift/Controllers/HistoryViewController.cpp b/Swift/Controllers/HistoryViewController.cpp
index 2d56b9e..669b002 100644
--- a/Swift/Controllers/HistoryViewController.cpp
+++ b/Swift/Controllers/HistoryViewController.cpp
@@ -5,16 +5,17 @@
*/
/*
- * Copyright (c) 2013 Isode Limited.
+ * Copyright (c) 2013-2016 Isode Limited.
* Licensed under the GNU General Public License.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/HistoryViewController.h>
+#include <boost/range/adaptor/reversed.hpp>
+
#include <Swiften/Avatars/AvatarManager.h>
#include <Swiften/Base/Path.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Client/NickResolver.h>
#include <Swiften/History/HistoryMessage.h>
@@ -25,335 +26,335 @@
#include <Swift/Controllers/UIInterfaces/HistoryWindowFactory.h>
namespace Swift {
- static const std::string category[] = { "Contacts", "MUC", "Contacts" };
+ static const std::string category[] = { "Contacts", "MUC", "Contacts" };
HistoryViewController::HistoryViewController(
- const JID& selfJID,
- UIEventStream* uiEventStream,
- HistoryController* historyController,
- NickResolver* nickResolver,
- AvatarManager* avatarManager,
- PresenceOracle* presenceOracle,
- HistoryWindowFactory* historyWindowFactory) :
- selfJID_(selfJID),
- uiEventStream_(uiEventStream),
- historyController_(historyController),
- nickResolver_(nickResolver),
- avatarManager_(avatarManager),
- presenceOracle_(presenceOracle),
- historyWindowFactory_(historyWindowFactory),
- historyWindow_(NULL),
- selectedItem_(NULL),
- currentResultDate_(boost::gregorian::not_a_date_time) {
- uiEventStream_->onUIEvent.connect(boost::bind(&HistoryViewController::handleUIEvent, this, _1));
-
- roster_ = new Roster(false, true);
+ const JID& selfJID,
+ UIEventStream* uiEventStream,
+ HistoryController* historyController,
+ NickResolver* nickResolver,
+ AvatarManager* avatarManager,
+ PresenceOracle* presenceOracle,
+ HistoryWindowFactory* historyWindowFactory) :
+ selfJID_(selfJID),
+ uiEventStream_(uiEventStream),
+ historyController_(historyController),
+ nickResolver_(nickResolver),
+ avatarManager_(avatarManager),
+ presenceOracle_(presenceOracle),
+ historyWindowFactory_(historyWindowFactory),
+ historyWindow_(nullptr),
+ selectedItem_(nullptr),
+ currentResultDate_(boost::gregorian::not_a_date_time) {
+ uiEventStream_->onUIEvent.connect(boost::bind(&HistoryViewController::handleUIEvent, this, _1));
+
+ roster_ = new Roster(false, true);
}
HistoryViewController::~HistoryViewController() {
- uiEventStream_->onUIEvent.disconnect(boost::bind(&HistoryViewController::handleUIEvent, this, _1));
- if (historyWindow_) {
- historyWindow_->onSelectedContactChanged.disconnect(boost::bind(&HistoryViewController::handleSelectedContactChanged, this, _1));
- historyWindow_->onReturnPressed.disconnect(boost::bind(&HistoryViewController::handleReturnPressed, this, _1));
- historyWindow_->onScrollReachedTop.disconnect(boost::bind(&HistoryViewController::handleScrollReachedTop, this, _1));
- historyWindow_->onScrollReachedBottom.disconnect(boost::bind(&HistoryViewController::handleScrollReachedBottom, this, _1));
- historyWindow_->onPreviousButtonClicked.disconnect(boost::bind(&HistoryViewController::handlePreviousButtonClicked, this));
- historyWindow_->onNextButtonClicked.disconnect(boost::bind(&HistoryViewController::handleNextButtonClicked, this));
- historyWindow_->onCalendarClicked.disconnect(boost::bind(&HistoryViewController::handleCalendarClicked, this, _1));
- historyController_->onNewMessage.disconnect(boost::bind(&HistoryViewController::handleNewMessage, this, _1));
-
- presenceOracle_->onPresenceChange.disconnect(boost::bind(&HistoryViewController::handlePresenceChanged, this, _1));
- avatarManager_->onAvatarChanged.disconnect(boost::bind(&HistoryViewController::handleAvatarChanged, this, _1));
-
- delete historyWindow_;
- }
- delete roster_;
+ uiEventStream_->onUIEvent.disconnect(boost::bind(&HistoryViewController::handleUIEvent, this, _1));
+ if (historyWindow_) {
+ historyWindow_->onSelectedContactChanged.disconnect(boost::bind(&HistoryViewController::handleSelectedContactChanged, this, _1));
+ historyWindow_->onReturnPressed.disconnect(boost::bind(&HistoryViewController::handleReturnPressed, this, _1));
+ historyWindow_->onScrollReachedTop.disconnect(boost::bind(&HistoryViewController::handleScrollReachedTop, this, _1));
+ historyWindow_->onScrollReachedBottom.disconnect(boost::bind(&HistoryViewController::handleScrollReachedBottom, this, _1));
+ historyWindow_->onPreviousButtonClicked.disconnect(boost::bind(&HistoryViewController::handlePreviousButtonClicked, this));
+ historyWindow_->onNextButtonClicked.disconnect(boost::bind(&HistoryViewController::handleNextButtonClicked, this));
+ historyWindow_->onCalendarClicked.disconnect(boost::bind(&HistoryViewController::handleCalendarClicked, this, _1));
+ historyController_->onNewMessage.disconnect(boost::bind(&HistoryViewController::handleNewMessage, this, _1));
+
+ presenceOracle_->onPresenceChange.disconnect(boost::bind(&HistoryViewController::handlePresenceChanged, this, _1));
+ avatarManager_->onAvatarChanged.disconnect(boost::bind(&HistoryViewController::handleAvatarChanged, this, _1));
+
+ delete historyWindow_;
+ }
+ delete roster_;
}
-void HistoryViewController::handleUIEvent(boost::shared_ptr<UIEvent> rawEvent) {
- boost::shared_ptr<RequestHistoryUIEvent> event = boost::dynamic_pointer_cast<RequestHistoryUIEvent>(rawEvent);
- if (event != NULL) {
- if (historyWindow_ == NULL) {
- historyWindow_ = historyWindowFactory_->createHistoryWindow(uiEventStream_);
- historyWindow_->onSelectedContactChanged.connect(boost::bind(&HistoryViewController::handleSelectedContactChanged, this, _1));
- historyWindow_->onReturnPressed.connect(boost::bind(&HistoryViewController::handleReturnPressed, this, _1));
- historyWindow_->onScrollReachedTop.connect(boost::bind(&HistoryViewController::handleScrollReachedTop, this, _1));
- historyWindow_->onScrollReachedBottom.connect(boost::bind(&HistoryViewController::handleScrollReachedBottom, this, _1));
- historyWindow_->onPreviousButtonClicked.connect(boost::bind(&HistoryViewController::handlePreviousButtonClicked, this));
- historyWindow_->onNextButtonClicked.connect(boost::bind(&HistoryViewController::handleNextButtonClicked, this));
- historyWindow_->onCalendarClicked.connect(boost::bind(&HistoryViewController::handleCalendarClicked, this, _1));
- historyController_->onNewMessage.connect(boost::bind(&HistoryViewController::handleNewMessage, this, _1));
-
- presenceOracle_->onPresenceChange.connect(boost::bind(&HistoryViewController::handlePresenceChanged, this, _1));
- avatarManager_->onAvatarChanged.connect(boost::bind(&HistoryViewController::handleAvatarChanged, this, _1));
-
- historyWindow_->setRosterModel(roster_);
- }
-
- // populate roster by doing an empty search
- handleReturnPressed(std::string());
-
- historyWindow_->activate();
- }
+void HistoryViewController::handleUIEvent(std::shared_ptr<UIEvent> rawEvent) {
+ std::shared_ptr<RequestHistoryUIEvent> event = std::dynamic_pointer_cast<RequestHistoryUIEvent>(rawEvent);
+ if (event != nullptr) {
+ if (historyWindow_ == nullptr) {
+ historyWindow_ = historyWindowFactory_->createHistoryWindow(uiEventStream_);
+ historyWindow_->onSelectedContactChanged.connect(boost::bind(&HistoryViewController::handleSelectedContactChanged, this, _1));
+ historyWindow_->onReturnPressed.connect(boost::bind(&HistoryViewController::handleReturnPressed, this, _1));
+ historyWindow_->onScrollReachedTop.connect(boost::bind(&HistoryViewController::handleScrollReachedTop, this, _1));
+ historyWindow_->onScrollReachedBottom.connect(boost::bind(&HistoryViewController::handleScrollReachedBottom, this, _1));
+ historyWindow_->onPreviousButtonClicked.connect(boost::bind(&HistoryViewController::handlePreviousButtonClicked, this));
+ historyWindow_->onNextButtonClicked.connect(boost::bind(&HistoryViewController::handleNextButtonClicked, this));
+ historyWindow_->onCalendarClicked.connect(boost::bind(&HistoryViewController::handleCalendarClicked, this, _1));
+ historyController_->onNewMessage.connect(boost::bind(&HistoryViewController::handleNewMessage, this, _1));
+
+ presenceOracle_->onPresenceChange.connect(boost::bind(&HistoryViewController::handlePresenceChanged, this, _1));
+ avatarManager_->onAvatarChanged.connect(boost::bind(&HistoryViewController::handleAvatarChanged, this, _1));
+
+ historyWindow_->setRosterModel(roster_);
+ }
+
+ // populate roster by doing an empty search
+ handleReturnPressed(std::string());
+
+ historyWindow_->activate();
+ }
}
void HistoryViewController::handleSelectedContactChanged(RosterItem* newContact) {
- // FIXME: signal is triggerd twice.
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(newContact);
-
- if (contact && selectedItem_ != contact) {
- selectedItem_ = contact;
- historyWindow_->resetConversationView();
- }
- else {
- return;
- }
-
- JID contactJID = contact->getJID();
-
- std::vector<HistoryMessage> messages;
- for (int it = HistoryMessage::Chat; it <= HistoryMessage::PrivateMessage; it++) {
- HistoryMessage::Type type = static_cast<HistoryMessage::Type>(it);
-
- if (contacts_[type].count(contactJID)) {
- currentResultDate_ = *contacts_[type][contactJID].rbegin();
- selectedItemType_ = type;
- messages = historyController_->getMessagesFromDate(selfJID_, contactJID, type, currentResultDate_);
- }
- }
-
- historyWindow_->setDate(currentResultDate_);
-
- foreach (const HistoryMessage& message, messages) {
- addNewMessage(message, false);
- }
+ // FIXME: signal is triggerd twice.
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(newContact);
+
+ if (contact && selectedItem_ != contact) {
+ selectedItem_ = contact;
+ historyWindow_->resetConversationView();
+ }
+ else {
+ return;
+ }
+
+ JID contactJID = contact->getJID();
+
+ std::vector<HistoryMessage> messages;
+ for (int it = HistoryMessage::Chat; it <= HistoryMessage::PrivateMessage; it++) {
+ HistoryMessage::Type type = static_cast<HistoryMessage::Type>(it);
+
+ if (contacts_[type].count(contactJID)) {
+ currentResultDate_ = *contacts_[type][contactJID].rbegin();
+ selectedItemType_ = type;
+ messages = historyController_->getMessagesFromDate(selfJID_, contactJID, type, currentResultDate_);
+ }
+ }
+
+ historyWindow_->setDate(currentResultDate_);
+
+ for (const auto& message : messages) {
+ addNewMessage(message, false);
+ }
}
void HistoryViewController::handleNewMessage(const HistoryMessage& message) {
- JID contactJID = message.getFromJID().toBare() == selfJID_ ? message.getToJID() : message.getFromJID();
-
- JID displayJID;
- if (message.getType() == HistoryMessage::PrivateMessage) {
- displayJID = contactJID;
- }
- else {
- displayJID = contactJID.toBare();
- }
-
- // check current conversation
- if (selectedItem_ && selectedItem_->getJID() == displayJID) {
- if (historyWindow_->getLastVisibleDate() == message.getTime().date()) {
- addNewMessage(message, false);
- }
- }
-
- // check if the new message matches the query
- if (message.getMessage().find(historyWindow_->getSearchBoxText()) == std::string::npos) {
- return;
- }
-
- // update contacts
- if (!contacts_[message.getType()].count(displayJID)) {
- roster_->addContact(displayJID, displayJID, nickResolver_->jidToNick(displayJID), category[message.getType()], avatarManager_->getAvatarPath(displayJID));
- }
-
- contacts_[message.getType()][displayJID].insert(message.getTime().date());
+ JID contactJID = message.getFromJID().toBare() == selfJID_ ? message.getToJID() : message.getFromJID();
+
+ JID displayJID;
+ if (message.getType() == HistoryMessage::PrivateMessage) {
+ displayJID = contactJID;
+ }
+ else {
+ displayJID = contactJID.toBare();
+ }
+
+ // check current conversation
+ if (selectedItem_ && selectedItem_->getJID() == displayJID) {
+ if (historyWindow_->getLastVisibleDate() == message.getTime().date()) {
+ addNewMessage(message, false);
+ }
+ }
+
+ // check if the new message matches the query
+ if (message.getMessage().find(historyWindow_->getSearchBoxText()) == std::string::npos) {
+ return;
+ }
+
+ // update contacts
+ if (!contacts_[message.getType()].count(displayJID)) {
+ roster_->addContact(displayJID, displayJID, nickResolver_->jidToNick(displayJID), category[message.getType()], avatarManager_->getAvatarPath(displayJID));
+ }
+
+ contacts_[message.getType()][displayJID].insert(message.getTime().date());
}
void HistoryViewController::addNewMessage(const HistoryMessage& message, bool addAtTheTop) {
- bool senderIsSelf = message.getFromJID().toBare() == selfJID_;
- std::string avatarPath = pathToString(avatarManager_->getAvatarPath(message.getFromJID()));
+ bool senderIsSelf = message.getFromJID().toBare() == selfJID_;
+ std::string avatarPath = pathToString(avatarManager_->getAvatarPath(message.getFromJID()));
- std::string nick = message.getType() != HistoryMessage::Groupchat ? nickResolver_->jidToNick(message.getFromJID()) : message.getFromJID().getResource();
- historyWindow_->addMessage(message.getMessage(), nick, senderIsSelf, avatarPath, message.getTime(), addAtTheTop);
+ std::string nick = message.getType() != HistoryMessage::Groupchat ? nickResolver_->jidToNick(message.getFromJID()) : message.getFromJID().getResource();
+ historyWindow_->addMessage(message.getMessage(), nick, senderIsSelf, avatarPath, message.getTime(), addAtTheTop);
}
void HistoryViewController::handleReturnPressed(const std::string& keyword) {
- reset();
-
- for (int it = HistoryMessage::Chat; it <= HistoryMessage::PrivateMessage; it++) {
- HistoryMessage::Type type = static_cast<HistoryMessage::Type>(it);
-
- contacts_[type] = historyController_->getContacts(selfJID_, type, keyword);
-
- for (ContactsMap::const_iterator contact = contacts_[type].begin(); contact != contacts_[type].end(); contact++) {
- const JID& jid = contact->first;
- std::string nick;
- if (type == HistoryMessage::PrivateMessage) {
- nick = jid.toString();
- }
- else {
- nick = nickResolver_->jidToNick(jid);
- }
- roster_->addContact(jid, jid, nick, category[type], avatarManager_->getAvatarPath(jid));
-
- Presence::ref presence = getPresence(jid, type == HistoryMessage::Groupchat);
-
- if (presence.get()) {
- roster_->applyOnItem(SetPresence(presence, JID::WithoutResource), jid);
- }
- }
- }
+ reset();
+
+ for (int it = HistoryMessage::Chat; it <= HistoryMessage::PrivateMessage; it++) {
+ HistoryMessage::Type type = static_cast<HistoryMessage::Type>(it);
+
+ contacts_[type] = historyController_->getContacts(selfJID_, type, keyword);
+
+ for (ContactsMap::const_iterator contact = contacts_[type].begin(); contact != contacts_[type].end(); contact++) {
+ const JID& jid = contact->first;
+ std::string nick;
+ if (type == HistoryMessage::PrivateMessage) {
+ nick = jid.toString();
+ }
+ else {
+ nick = nickResolver_->jidToNick(jid);
+ }
+ roster_->addContact(jid, jid, nick, category[type], avatarManager_->getAvatarPath(jid));
+
+ Presence::ref presence = getPresence(jid, type == HistoryMessage::Groupchat);
+
+ if (presence.get()) {
+ roster_->applyOnItem(SetPresence(presence, JID::WithoutResource), jid);
+ }
+ }
+ }
}
void HistoryViewController::handleScrollReachedTop(const boost::gregorian::date& date) {
- if (!selectedItem_) {
- return;
- }
+ if (!selectedItem_) {
+ return;
+ }
- std::vector<HistoryMessage> messages = historyController_->getMessagesFromPreviousDate(selfJID_, selectedItem_->getJID(), selectedItemType_, date);
+ std::vector<HistoryMessage> messages = historyController_->getMessagesFromPreviousDate(selfJID_, selectedItem_->getJID(), selectedItemType_, date);
- foreach (const HistoryMessage& message, messages) {
- addNewMessage(message, true);
- }
- historyWindow_->resetConversationViewTopInsertPoint();
+ for (const auto& message : messages) {
+ addNewMessage(message, true);
+ }
+ historyWindow_->resetConversationViewTopInsertPoint();
}
void HistoryViewController::handleScrollReachedBottom(const boost::gregorian::date& date) {
- if (!selectedItem_) {
- return;
- }
+ if (!selectedItem_) {
+ return;
+ }
- std::vector<HistoryMessage> messages = historyController_->getMessagesFromNextDate(selfJID_, selectedItem_->getJID(), selectedItemType_, date);
+ std::vector<HistoryMessage> messages = historyController_->getMessagesFromNextDate(selfJID_, selectedItem_->getJID(), selectedItemType_, date);
- foreach (const HistoryMessage& message, messages) {
- addNewMessage(message, false);
- }
+ for (const auto& message : messages) {
+ addNewMessage(message, false);
+ }
}
void HistoryViewController::handleNextButtonClicked() {
- if (!selectedItem_) {
- return;
- }
+ if (!selectedItem_) {
+ return;
+ }
- std::set<boost::gregorian::date>::iterator date = contacts_[selectedItemType_][selectedItem_->getJID()].find(currentResultDate_);
+ std::set<boost::gregorian::date>::iterator date = contacts_[selectedItemType_][selectedItem_->getJID()].find(currentResultDate_);
- if (*date == *contacts_[selectedItemType_][selectedItem_->getJID()].rbegin()) {
- return;
- }
+ if (*date == *contacts_[selectedItemType_][selectedItem_->getJID()].rbegin()) {
+ return;
+ }
- historyWindow_->resetConversationView();
- currentResultDate_ = *(++date);
- std::vector<HistoryMessage> messages = historyController_->getMessagesFromDate(selfJID_, selectedItem_->getJID(), selectedItemType_, currentResultDate_);
- historyWindow_->setDate(currentResultDate_);
+ historyWindow_->resetConversationView();
+ currentResultDate_ = *(++date);
+ std::vector<HistoryMessage> messages = historyController_->getMessagesFromDate(selfJID_, selectedItem_->getJID(), selectedItemType_, currentResultDate_);
+ historyWindow_->setDate(currentResultDate_);
- foreach (const HistoryMessage& message, messages) {
- addNewMessage(message, false);
- }
+ for (const auto& message : messages) {
+ addNewMessage(message, false);
+ }
}
void HistoryViewController::handlePreviousButtonClicked() {
- if (!selectedItem_) {
- return;
- }
+ if (!selectedItem_) {
+ return;
+ }
- std::set<boost::gregorian::date>::iterator date = contacts_[selectedItemType_][selectedItem_->getJID()].find(currentResultDate_);
+ std::set<boost::gregorian::date>::iterator date = contacts_[selectedItemType_][selectedItem_->getJID()].find(currentResultDate_);
- if (date == contacts_[selectedItemType_][selectedItem_->getJID()].begin()) {
- return;
- }
+ if (date == contacts_[selectedItemType_][selectedItem_->getJID()].begin()) {
+ return;
+ }
- historyWindow_->resetConversationView();
- currentResultDate_ = *(--date);
- std::vector<HistoryMessage> messages = historyController_->getMessagesFromDate(selfJID_, selectedItem_->getJID(), selectedItemType_, currentResultDate_);
- historyWindow_->setDate(currentResultDate_);
+ historyWindow_->resetConversationView();
+ currentResultDate_ = *(--date);
+ std::vector<HistoryMessage> messages = historyController_->getMessagesFromDate(selfJID_, selectedItem_->getJID(), selectedItemType_, currentResultDate_);
+ historyWindow_->setDate(currentResultDate_);
- foreach (const HistoryMessage& message, messages) {
- addNewMessage(message, false);
- }
+ for (const auto& message : messages) {
+ addNewMessage(message, false);
+ }
}
void HistoryViewController::reset() {
- roster_->removeAll();
- contacts_.clear();
- selectedItem_ = NULL;
- historyWindow_->resetConversationView();
+ roster_->removeAll();
+ contacts_.clear();
+ selectedItem_ = nullptr;
+ historyWindow_->resetConversationView();
}
void HistoryViewController::handleCalendarClicked(const boost::gregorian::date& date) {
- if (!selectedItem_) {
- return;
- }
-
- boost::gregorian::date newDate;
- if (contacts_[selectedItemType_][selectedItem_->getJID()].count(date)) {
- newDate = date;
- }
- else if (date < currentResultDate_) {
- foreach(const boost::gregorian::date& current, contacts_[selectedItemType_][selectedItem_->getJID()]) {
- if (current > date) {
- newDate = current;
- break;
- }
- }
- }
- else {
- reverse_foreach(const boost::gregorian::date& current, contacts_[selectedItemType_][selectedItem_->getJID()]) {
- if (current < date) {
- newDate = current;
- break;
- }
- }
- }
-
- historyWindow_->setDate(newDate);
- if (newDate == currentResultDate_) {
- return;
- }
- currentResultDate_ = newDate;
- historyWindow_->resetConversationView();
-
- std::vector<HistoryMessage> messages = historyController_->getMessagesFromDate(selfJID_, selectedItem_->getJID(), selectedItemType_, currentResultDate_);
- historyWindow_->setDate(currentResultDate_);
-
- foreach (const HistoryMessage& message, messages) {
- addNewMessage(message, false);
- }
+ if (!selectedItem_) {
+ return;
+ }
+
+ boost::gregorian::date newDate;
+ if (contacts_[selectedItemType_][selectedItem_->getJID()].count(date)) {
+ newDate = date;
+ }
+ else if (date < currentResultDate_) {
+ for (const auto& current : contacts_[selectedItemType_][selectedItem_->getJID()]) {
+ if (current > date) {
+ newDate = current;
+ break;
+ }
+ }
+ }
+ else {
+ for (const auto& current : boost::adaptors::reverse(contacts_[selectedItemType_][selectedItem_->getJID()])) {
+ if (current < date) {
+ newDate = current;
+ break;
+ }
+ }
+ }
+
+ historyWindow_->setDate(newDate);
+ if (newDate == currentResultDate_) {
+ return;
+ }
+ currentResultDate_ = newDate;
+ historyWindow_->resetConversationView();
+
+ std::vector<HistoryMessage> messages = historyController_->getMessagesFromDate(selfJID_, selectedItem_->getJID(), selectedItemType_, currentResultDate_);
+ historyWindow_->setDate(currentResultDate_);
+
+ for (const auto& message : messages) {
+ addNewMessage(message, false);
+ }
}
void HistoryViewController::handlePresenceChanged(Presence::ref presence) {
- JID jid = presence->getFrom();
-
- if (contacts_[HistoryMessage::Chat].count(jid.toBare())) {
- roster_->applyOnItems(SetPresence(presence, JID::WithoutResource));
- return;
- }
-
- if (contacts_[HistoryMessage::Groupchat].count(jid.toBare())) {
- Presence::ref availablePresence = boost::make_shared<Presence>(Presence());
- availablePresence->setFrom(jid.toBare());
- roster_->applyOnItems(SetPresence(availablePresence, JID::WithResource));
- }
-
- if (contacts_[HistoryMessage::PrivateMessage].count(jid)) {
- roster_->applyOnItems(SetPresence(presence, JID::WithResource));
- }
+ JID jid = presence->getFrom();
+
+ if (contacts_[HistoryMessage::Chat].count(jid.toBare())) {
+ roster_->applyOnItems(SetPresence(presence, JID::WithoutResource));
+ return;
+ }
+
+ if (contacts_[HistoryMessage::Groupchat].count(jid.toBare())) {
+ Presence::ref availablePresence = std::make_shared<Presence>(Presence());
+ availablePresence->setFrom(jid.toBare());
+ roster_->applyOnItems(SetPresence(availablePresence, JID::WithResource));
+ }
+
+ if (contacts_[HistoryMessage::PrivateMessage].count(jid)) {
+ roster_->applyOnItems(SetPresence(presence, JID::WithResource));
+ }
}
void HistoryViewController::handleAvatarChanged(const JID& jid) {
- roster_->applyOnItems(SetAvatar(jid, avatarManager_->getAvatarPath(jid)));
+ roster_->applyOnItems(SetAvatar(jid, avatarManager_->getAvatarPath(jid)));
}
Presence::ref HistoryViewController::getPresence(const JID& jid, bool isMUC) {
- if (jid.isBare() && !isMUC) {
- return presenceOracle_->getHighestPriorityPresence(jid);
- }
+ if (jid.isBare() && !isMUC) {
+ return presenceOracle_->getHighestPriorityPresence(jid);
+ }
- std::vector<Presence::ref> mucPresence = presenceOracle_->getAllPresence(jid.toBare());
+ std::vector<Presence::ref> mucPresence = presenceOracle_->getAllPresence(jid.toBare());
- if (isMUC && !mucPresence.empty()) {
- Presence::ref presence = boost::make_shared<Presence>(Presence());
- presence->setFrom(jid);
- return presence;
- }
+ if (isMUC && !mucPresence.empty()) {
+ Presence::ref presence = std::make_shared<Presence>(Presence());
+ presence->setFrom(jid);
+ return presence;
+ }
- foreach (Presence::ref presence, mucPresence) {
- if (presence.get() && presence->getFrom() == jid) {
- return presence;
- }
- }
+ for (auto&& presence : mucPresence) {
+ if (presence.get() && presence->getFrom() == jid) {
+ return presence;
+ }
+ }
- return Presence::create();
+ return Presence::create();
}
}
diff --git a/Swift/Controllers/HistoryViewController.h b/Swift/Controllers/HistoryViewController.h
index f44c968..75fc460 100644
--- a/Swift/Controllers/HistoryViewController.h
+++ b/Swift/Controllers/HistoryViewController.h
@@ -4,64 +4,72 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
-#include <Swiften/Base/boost_bsignals.h>
+#include <memory>
+#include <set>
+
#include <boost/bind.hpp>
-#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
-#include <Swift/Controllers/UIEvents/UIEventStream.h>
+#include <Swiften/History/HistoryStorage.h>
#include <Swiften/JID/JID.h>
#include <Swiften/Presence/PresenceOracle.h>
-#include <Swiften/History/HistoryStorage.h>
-#include <set>
+
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
namespace Swift {
- class HistoryWindowFactory;
- class HistoryWindow;
- class Roster;
- class RosterItem;
- class ContactRosterItem;
- class HistoryController;
- class NickResolver;
- class AvatarManager;
+ class HistoryWindowFactory;
+ class HistoryWindow;
+ class Roster;
+ class RosterItem;
+ class ContactRosterItem;
+ class HistoryController;
+ class NickResolver;
+ class AvatarManager;
- class HistoryViewController {
- public:
- HistoryViewController(const JID& selfJID, UIEventStream* uiEventStream, HistoryController* historyController, NickResolver* nickResolver, AvatarManager* avatarManager, PresenceOracle* presenceOracle, HistoryWindowFactory* historyWindowFactory);
- ~HistoryViewController();
+ class HistoryViewController {
+ public:
+ HistoryViewController(const JID& selfJID, UIEventStream* uiEventStream, HistoryController* historyController, NickResolver* nickResolver, AvatarManager* avatarManager, PresenceOracle* presenceOracle, HistoryWindowFactory* historyWindowFactory);
+ ~HistoryViewController();
- private:
- void handleUIEvent(boost::shared_ptr<UIEvent> event);
- void handleSelectedContactChanged(RosterItem* item);
- void handleNewMessage(const HistoryMessage& message);
- void handleReturnPressed(const std::string& keyword);
- void handleScrollReachedTop(const boost::gregorian::date& date);
- void handleScrollReachedBottom(const boost::gregorian::date& date);
- void handlePreviousButtonClicked();
- void handleNextButtonClicked();
- void handleCalendarClicked(const boost::gregorian::date& date);
- void handlePresenceChanged(Presence::ref presence);
- void handleAvatarChanged(const JID& jid);
+ private:
+ void handleUIEvent(std::shared_ptr<UIEvent> event);
+ void handleSelectedContactChanged(RosterItem* item);
+ void handleNewMessage(const HistoryMessage& message);
+ void handleReturnPressed(const std::string& keyword);
+ void handleScrollReachedTop(const boost::gregorian::date& date);
+ void handleScrollReachedBottom(const boost::gregorian::date& date);
+ void handlePreviousButtonClicked();
+ void handleNextButtonClicked();
+ void handleCalendarClicked(const boost::gregorian::date& date);
+ void handlePresenceChanged(Presence::ref presence);
+ void handleAvatarChanged(const JID& jid);
- void addNewMessage(const HistoryMessage& message, bool addAtTheTop);
- void reset();
- Presence::ref getPresence(const JID& jid, bool isMUC);
+ void addNewMessage(const HistoryMessage& message, bool addAtTheTop);
+ void reset();
+ Presence::ref getPresence(const JID& jid, bool isMUC);
- private:
- JID selfJID_;
- UIEventStream* uiEventStream_;
- HistoryController* historyController_;
- NickResolver* nickResolver_;
- AvatarManager* avatarManager_;
- PresenceOracle* presenceOracle_;
- HistoryWindowFactory* historyWindowFactory_;
- HistoryWindow* historyWindow_;
- Roster* roster_;
+ private:
+ JID selfJID_;
+ UIEventStream* uiEventStream_;
+ HistoryController* historyController_;
+ NickResolver* nickResolver_;
+ AvatarManager* avatarManager_;
+ PresenceOracle* presenceOracle_;
+ HistoryWindowFactory* historyWindowFactory_;
+ HistoryWindow* historyWindow_;
+ Roster* roster_;
- std::map<HistoryMessage::Type, ContactsMap> contacts_;
- ContactRosterItem* selectedItem_;
- HistoryMessage::Type selectedItemType_;
- boost::gregorian::date currentResultDate_;
- };
+ std::map<HistoryMessage::Type, ContactsMap> contacts_;
+ ContactRosterItem* selectedItem_;
+ HistoryMessage::Type selectedItemType_ = HistoryMessage::Chat;
+ boost::gregorian::date currentResultDate_;
+ };
}
diff --git a/Swift/Controllers/Intl.h b/Swift/Controllers/Intl.h
index 1c8204a..c599493 100644
--- a/Swift/Controllers/Intl.h
+++ b/Swift/Controllers/Intl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,6 +7,5 @@
#pragma once
#include <Swift/Controllers/Translator.h>
-
#define QT_TRANSLATE_NOOP(context, text) \
- Swift::Translator::getInstance()->translate(text, context)
+ Swift::Translator::getInstance()->translate(text, context)
diff --git a/Swift/Controllers/MainController.cpp b/Swift/Controllers/MainController.cpp
index 9f61b2b..0d9f1b8 100644
--- a/Swift/Controllers/MainController.cpp
+++ b/Swift/Controllers/MainController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,15 +7,14 @@
#include <Swift/Controllers/MainController.h>
#include <cstdlib>
+#include <memory>
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
#include <Swiften/Base/Algorithm.h>
+#include <Swiften/Base/Log.h>
#include <Swiften/Base/String.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Base/format.h>
#include <Swiften/Client/Client.h>
#include <Swiften/Client/ClientBlockListManager.h>
@@ -35,6 +34,7 @@
#include <Swiften/Network/NetworkFactories.h>
#include <Swiften/Network/TimerFactory.h>
#include <Swiften/Presence/PresenceSender.h>
+#include <Swiften/Queries/Requests/EnableCarbonsRequest.h>
#include <Swiften/StringCodecs/Base64.h>
#include <Swiften/StringCodecs/Hexify.h>
#include <Swiften/VCards/GetVCardRequest.h>
@@ -99,749 +99,766 @@ static const std::string CLIENT_NODE = "http://swift.im";
MainController::MainController(
- EventLoop* eventLoop,
- NetworkFactories* networkFactories,
- UIFactory* uiFactories,
- SettingsProvider* settings,
- SystemTray* systemTray,
- SoundPlayer* soundPlayer,
- StoragesFactory* storagesFactory,
- CertificateStorageFactory* certificateStorageFactory,
- Dock* dock,
- Notifier* notifier,
- URIHandler* uriHandler,
- IdleDetector* idleDetector,
- const std::map<std::string, std::string>& emoticons,
- bool useDelayForLatency) :
- eventLoop_(eventLoop),
- networkFactories_(networkFactories),
- uiFactory_(uiFactories),
- storagesFactory_(storagesFactory),
- certificateStorageFactory_(certificateStorageFactory),
- settings_(settings),
- uriHandler_(uriHandler),
- idleDetector_(idleDetector),
- loginWindow_(NULL) ,
- useDelayForLatency_(useDelayForLatency),
- ftOverview_(NULL),
- emoticons_(emoticons) {
- storages_ = NULL;
- certificateStorage_ = NULL;
- certificateTrustChecker_ = NULL;
- statusTracker_ = NULL;
- presenceNotifier_ = NULL;
- eventNotifier_ = NULL;
- rosterController_ = NULL;
- chatsManager_ = NULL;
- historyController_ = NULL;
- historyViewController_ = NULL;
- eventWindowController_ = NULL;
- profileController_ = NULL;
- blockListController_ = NULL;
- showProfileController_ = NULL;
- contactEditController_ = NULL;
- userSearchControllerChat_ = NULL;
- userSearchControllerAdd_ = NULL;
- userSearchControllerInvite_ = NULL;
- contactsFromRosterProvider_ = NULL;
- contactSuggesterWithoutRoster_ = NULL;
- contactSuggesterWithRoster_ = NULL;
- whiteboardManager_ = NULL;
- adHocManager_ = NULL;
- quitRequested_ = false;
- clientInitialized_ = false;
- offlineRequested_ = false;
-
- timeBeforeNextReconnect_ = -1;
- dock_ = dock;
- uiEventStream_ = new UIEventStream();
-
- notifier_ = new TogglableNotifier(notifier);
- notifier_->setPersistentEnabled(settings_->getSetting(SettingConstants::SHOW_NOTIFICATIONS));
- eventController_ = new EventController();
- eventController_->onEventQueueLengthChange.connect(boost::bind(&MainController::handleEventQueueLengthChange, this, _1));
-
- systemTrayController_ = new SystemTrayController(eventController_, systemTray);
- loginWindow_ = uiFactory_->createLoginWindow(uiEventStream_);
- loginWindow_->setShowNotificationToggle(!notifier->isExternallyConfigured());
-
- highlightManager_ = new HighlightManager(settings_);
- highlightEditorController_ = new HighlightEditorController(uiEventStream_, uiFactory_, highlightManager_);
-
- soundEventController_ = new SoundEventController(eventController_, soundPlayer, settings, highlightManager_);
-
- xmppURIController_ = new XMPPURIController(uriHandler_, uiEventStream_);
-
- std::string selectedLoginJID = settings_->getSetting(SettingConstants::LAST_LOGIN_JID);
- bool loginAutomatically = settings_->getSetting(SettingConstants::LOGIN_AUTOMATICALLY);
- std::string cachedPassword;
- std::string cachedCertificate;
- ClientOptions cachedOptions;
- bool eagle = settings_->getSetting(SettingConstants::FORGET_PASSWORDS);
- if (!eagle) {
- foreach (std::string profile, settings->getAvailableProfiles()) {
- ProfileSettingsProvider profileSettings(profile, settings);
- std::string password = profileSettings.getStringSetting("pass");
- std::string certificate = profileSettings.getStringSetting("certificate");
- std::string jid = profileSettings.getStringSetting("jid");
- ClientOptions clientOptions = parseClientOptions(profileSettings.getStringSetting("options"));
+ EventLoop* eventLoop,
+ NetworkFactories* networkFactories,
+ UIFactory* uiFactories,
+ SettingsProvider* settings,
+ SystemTray* systemTray,
+ SoundPlayer* soundPlayer,
+ StoragesFactory* storagesFactory,
+ CertificateStorageFactory* certificateStorageFactory,
+ Dock* dock,
+ Notifier* notifier,
+ URIHandler* uriHandler,
+ IdleDetector* idleDetector,
+ const std::map<std::string, std::string>& emoticons,
+ bool useDelayForLatency) :
+ eventLoop_(eventLoop),
+ networkFactories_(networkFactories),
+ uiFactory_(uiFactories),
+ storagesFactory_(storagesFactory),
+ certificateStorageFactory_(certificateStorageFactory),
+ settings_(settings),
+ uriHandler_(uriHandler),
+ idleDetector_(idleDetector),
+ loginWindow_(nullptr) ,
+ useDelayForLatency_(useDelayForLatency),
+ ftOverview_(nullptr),
+ emoticons_(emoticons) {
+ storages_ = nullptr;
+ certificateStorage_ = nullptr;
+ certificateTrustChecker_ = nullptr;
+ statusTracker_ = nullptr;
+ presenceNotifier_ = nullptr;
+ eventNotifier_ = nullptr;
+ rosterController_ = nullptr;
+ chatsManager_ = nullptr;
+ historyController_ = nullptr;
+ historyViewController_ = nullptr;
+ eventWindowController_ = nullptr;
+ profileController_ = nullptr;
+ blockListController_ = nullptr;
+ showProfileController_ = nullptr;
+ contactEditController_ = nullptr;
+ userSearchControllerChat_ = nullptr;
+ userSearchControllerAdd_ = nullptr;
+ userSearchControllerInvite_ = nullptr;
+ contactsFromRosterProvider_ = nullptr;
+ contactSuggesterWithoutRoster_ = nullptr;
+ contactSuggesterWithRoster_ = nullptr;
+ whiteboardManager_ = nullptr;
+ adHocManager_ = nullptr;
+ quitRequested_ = false;
+ clientInitialized_ = false;
+ offlineRequested_ = false;
+
+ timeBeforeNextReconnect_ = -1;
+ dock_ = dock;
+ uiEventStream_ = new UIEventStream();
+
+ notifier_ = new TogglableNotifier(notifier);
+ notifier_->setPersistentEnabled(settings_->getSetting(SettingConstants::SHOW_NOTIFICATIONS));
+ eventController_ = new EventController();
+ eventController_->onEventQueueLengthChange.connect(boost::bind(&MainController::handleEventQueueLengthChange, this, _1));
+
+ systemTrayController_ = new SystemTrayController(eventController_, systemTray);
+ loginWindow_ = uiFactory_->createLoginWindow(uiEventStream_);
+ loginWindow_->setShowNotificationToggle(!notifier->isExternallyConfigured());
+
+ highlightManager_ = new HighlightManager(settings_);
+ highlightEditorController_ = new HighlightEditorController(uiEventStream_, uiFactory_, highlightManager_);
+
+ soundEventController_ = new SoundEventController(eventController_, soundPlayer, settings, highlightManager_);
+
+ xmppURIController_ = new XMPPURIController(uriHandler_, uiEventStream_);
+
+ std::string selectedLoginJID = settings_->getSetting(SettingConstants::LAST_LOGIN_JID);
+ bool loginAutomatically = settings_->getSetting(SettingConstants::LOGIN_AUTOMATICALLY);
+ std::string cachedPassword;
+ std::string cachedCertificate;
+ ClientOptions cachedOptions;
+ bool eagle = settings_->getSetting(SettingConstants::FORGET_PASSWORDS);
+ if (!eagle) {
+ for (auto&& profile : settings->getAvailableProfiles()) {
+ ProfileSettingsProvider profileSettings(profile, settings);
+ std::string password = profileSettings.getStringSetting("pass");
+ std::string certificate = profileSettings.getStringSetting("certificate");
+ std::string jid = profileSettings.getStringSetting("jid");
+ ClientOptions clientOptions = parseClientOptions(profileSettings.getStringSetting("options"));
#ifdef SWIFTEN_PLATFORM_WIN32
- clientOptions.singleSignOn = settings_->getSetting(SettingConstants::SINGLE_SIGN_ON);
+ clientOptions.singleSignOn = settings_->getSetting(SettingConstants::SINGLE_SIGN_ON);
#endif
- loginWindow_->addAvailableAccount(jid, password, certificate, clientOptions);
- if (jid == selectedLoginJID) {
- cachedPassword = password;
- cachedCertificate = certificate;
- cachedOptions = clientOptions;
- }
- }
- loginWindow_->selectUser(selectedLoginJID);
- loginWindow_->setLoginAutomatically(loginAutomatically);
- }
+ loginWindow_->addAvailableAccount(jid, password, certificate, clientOptions);
+ if (jid == selectedLoginJID) {
+ cachedPassword = password;
+ cachedCertificate = certificate;
+ cachedOptions = clientOptions;
+ }
+ }
+ loginWindow_->selectUser(selectedLoginJID);
+ loginWindow_->setLoginAutomatically(loginAutomatically);
+ }
- loginWindow_->onLoginRequest.connect(boost::bind(&MainController::handleLoginRequest, this, _1, _2, _3, _4, _5, _6, _7));
- loginWindow_->onPurgeSavedLoginRequest.connect(boost::bind(&MainController::handlePurgeSavedLoginRequest, this, _1));
- loginWindow_->onCancelLoginRequest.connect(boost::bind(&MainController::handleCancelLoginRequest, this));
- loginWindow_->onQuitRequest.connect(boost::bind(&MainController::handleQuitRequest, this));
+ loginWindow_->onLoginRequest.connect(boost::bind(&MainController::handleLoginRequest, this, _1, _2, _3, _4, _5, _6, _7));
+ loginWindow_->onPurgeSavedLoginRequest.connect(boost::bind(&MainController::handlePurgeSavedLoginRequest, this, _1));
+ loginWindow_->onCancelLoginRequest.connect(boost::bind(&MainController::handleCancelLoginRequest, this));
+ loginWindow_->onQuitRequest.connect(boost::bind(&MainController::handleQuitRequest, this));
- idleDetector_->setIdleTimeSeconds(settings->getSetting(SettingConstants::IDLE_TIMEOUT));
- idleDetector_->onIdleChanged.connect(boost::bind(&MainController::handleInputIdleChanged, this, _1));
+ idleDetector_->setIdleTimeSeconds(settings->getSetting(SettingConstants::IDLE_TIMEOUT));
+ idleDetector_->onIdleChanged.connect(boost::bind(&MainController::handleInputIdleChanged, this, _1));
- xmlConsoleController_ = new XMLConsoleController(uiEventStream_, uiFactory_);
+ xmlConsoleController_ = new XMLConsoleController(uiEventStream_, uiFactory_);
- fileTransferListController_ = new FileTransferListController(uiEventStream_, uiFactory_);
+ fileTransferListController_ = new FileTransferListController(uiEventStream_, uiFactory_);
- settings_->onSettingChanged.connect(boost::bind(&MainController::handleSettingChanged, this, _1));
+ settings_->onSettingChanged.connect(boost::bind(&MainController::handleSettingChanged, this, _1));
- if (loginAutomatically) {
- profileSettings_ = new ProfileSettingsProvider(selectedLoginJID, settings_);
- /* FIXME: deal with autologin with a cert*/
- handleLoginRequest(selectedLoginJID, cachedPassword, cachedCertificate, CertificateWithKey::ref(), cachedOptions, true, true);
- } else {
- profileSettings_ = NULL;
- }
+ if (loginAutomatically) {
+ profileSettings_ = new ProfileSettingsProvider(selectedLoginJID, settings_);
+ /* FIXME: deal with autologin with a cert*/
+ handleLoginRequest(selectedLoginJID, cachedPassword, cachedCertificate, CertificateWithKey::ref(), cachedOptions, true, true);
+ } else {
+ profileSettings_ = nullptr;
+ }
}
MainController::~MainController() {
- idleDetector_->onIdleChanged.disconnect(boost::bind(&MainController::handleInputIdleChanged, this, _1));
-
- purgeCachedCredentials();
- //setManagersOffline();
- eventController_->disconnectAll();
-
- resetClient();
- delete highlightEditorController_;
- delete highlightManager_;
- delete fileTransferListController_;
- delete xmlConsoleController_;
- delete xmppURIController_;
- delete soundEventController_;
- delete systemTrayController_;
- delete eventController_;
- delete notifier_;
- delete uiEventStream_;
+ idleDetector_->onIdleChanged.disconnect(boost::bind(&MainController::handleInputIdleChanged, this, _1));
+
+ purgeCachedCredentials();
+ //setManagersOffline();
+ eventController_->disconnectAll();
+
+ resetClient();
+ delete highlightEditorController_;
+ delete highlightManager_;
+ delete fileTransferListController_;
+ delete xmlConsoleController_;
+ delete xmppURIController_;
+ delete soundEventController_;
+ delete systemTrayController_;
+ delete eventController_;
+ delete notifier_;
+ delete uiEventStream_;
}
void MainController::purgeCachedCredentials() {
- safeClear(password_);
+ safeClear(password_);
}
void MainController::resetClient() {
- purgeCachedCredentials();
- resetCurrentError();
- resetPendingReconnects();
- vCardPhotoHash_.clear();
- delete contactEditController_;
- contactEditController_ = NULL;
- delete profileController_;
- profileController_ = NULL;
- delete showProfileController_;
- showProfileController_ = NULL;
- delete eventWindowController_;
- eventWindowController_ = NULL;
- delete chatsManager_;
- chatsManager_ = NULL;
+ purgeCachedCredentials();
+ resetCurrentError();
+ resetPendingReconnects();
+ vCardPhotoHash_.clear();
+ delete contactEditController_;
+ contactEditController_ = nullptr;
+ delete profileController_;
+ profileController_ = nullptr;
+ delete showProfileController_;
+ showProfileController_ = nullptr;
+ delete eventWindowController_;
+ eventWindowController_ = nullptr;
+ delete chatsManager_;
+ chatsManager_ = nullptr;
#ifdef SWIFT_EXPERIMENTAL_HISTORY
- delete historyViewController_;
- historyViewController_ = NULL;
- delete historyController_;
- historyController_ = NULL;
+ delete historyViewController_;
+ historyViewController_ = nullptr;
+ delete historyController_;
+ historyController_ = nullptr;
#endif
- fileTransferListController_->setFileTransferOverview(NULL);
- delete ftOverview_;
- ftOverview_ = NULL;
- delete blockListController_;
- blockListController_ = NULL;
- delete rosterController_;
- rosterController_ = NULL;
- delete eventNotifier_;
- eventNotifier_ = NULL;
- delete presenceNotifier_;
- presenceNotifier_ = NULL;
- delete certificateTrustChecker_;
- certificateTrustChecker_ = NULL;
- delete certificateStorage_;
- certificateStorage_ = NULL;
- delete storages_;
- storages_ = NULL;
- delete statusTracker_;
- statusTracker_ = NULL;
- delete profileSettings_;
- profileSettings_ = NULL;
- delete userSearchControllerChat_;
- userSearchControllerChat_ = NULL;
- delete userSearchControllerAdd_;
- userSearchControllerAdd_ = NULL;
- delete userSearchControllerInvite_;
- userSearchControllerInvite_ = NULL;
- delete contactSuggesterWithoutRoster_;
- contactSuggesterWithoutRoster_ = NULL;
- delete contactSuggesterWithRoster_;
- contactSuggesterWithRoster_ = NULL;
- delete contactsFromRosterProvider_;
- contactsFromRosterProvider_ = NULL;
- delete adHocManager_;
- adHocManager_ = NULL;
- delete whiteboardManager_;
- whiteboardManager_ = NULL;
- clientInitialized_ = false;
+ fileTransferListController_->setFileTransferOverview(nullptr);
+ delete ftOverview_;
+ ftOverview_ = nullptr;
+ delete blockListController_;
+ blockListController_ = nullptr;
+ delete rosterController_;
+ rosterController_ = nullptr;
+ delete eventNotifier_;
+ eventNotifier_ = nullptr;
+ delete presenceNotifier_;
+ presenceNotifier_ = nullptr;
+ delete certificateTrustChecker_;
+ certificateTrustChecker_ = nullptr;
+ delete certificateStorage_;
+ certificateStorage_ = nullptr;
+ delete storages_;
+ storages_ = nullptr;
+ delete statusTracker_;
+ statusTracker_ = nullptr;
+ delete profileSettings_;
+ profileSettings_ = nullptr;
+ delete userSearchControllerChat_;
+ userSearchControllerChat_ = nullptr;
+ delete userSearchControllerAdd_;
+ userSearchControllerAdd_ = nullptr;
+ delete userSearchControllerInvite_;
+ userSearchControllerInvite_ = nullptr;
+ delete contactSuggesterWithoutRoster_;
+ contactSuggesterWithoutRoster_ = nullptr;
+ delete contactSuggesterWithRoster_;
+ contactSuggesterWithRoster_ = nullptr;
+ delete contactsFromRosterProvider_;
+ contactsFromRosterProvider_ = nullptr;
+ delete adHocManager_;
+ adHocManager_ = nullptr;
+ delete whiteboardManager_;
+ whiteboardManager_ = nullptr;
+ clientInitialized_ = false;
}
void MainController::handleSettingChanged(const std::string& settingPath) {
- if (settingPath == SettingConstants::SHOW_NOTIFICATIONS.getKey()) {
- notifier_->setPersistentEnabled(settings_->getSetting(SettingConstants::SHOW_NOTIFICATIONS));
- }
+ if (settingPath == SettingConstants::SHOW_NOTIFICATIONS.getKey()) {
+ notifier_->setPersistentEnabled(settings_->getSetting(SettingConstants::SHOW_NOTIFICATIONS));
+ }
}
void MainController::resetPendingReconnects() {
- timeBeforeNextReconnect_ = -1;
- if (reconnectTimer_) {
- reconnectTimer_->stop();
- reconnectTimer_.reset();
- }
- resetCurrentError();
+ timeBeforeNextReconnect_ = -1;
+ if (reconnectTimer_) {
+ reconnectTimer_->stop();
+ reconnectTimer_.reset();
+ }
+ resetCurrentError();
}
void MainController::resetCurrentError() {
- if (lastDisconnectError_) {
- lastDisconnectError_->conclude();
- lastDisconnectError_ = boost::shared_ptr<ErrorEvent>();
- }
+ if (lastDisconnectError_) {
+ lastDisconnectError_->conclude();
+ lastDisconnectError_ = std::shared_ptr<ErrorEvent>();
+ }
}
void MainController::handleConnected() {
- boundJID_ = client_->getJID();
- resetCurrentError();
- resetPendingReconnects();
-
- if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) {
- purgeCachedCredentials();
- }
-
- bool freshLogin = rosterController_ == NULL;
- myStatusLooksOnline_ = true;
- if (freshLogin) {
- profileController_ = new ProfileController(client_->getVCardManager(), uiFactory_, uiEventStream_);
- showProfileController_ = new ShowProfileController(client_->getVCardManager(), uiFactory_, uiEventStream_);
- ftOverview_ = new FileTransferOverview(client_->getFileTransferManager());
- fileTransferListController_->setFileTransferOverview(ftOverview_);
- rosterController_ = new RosterController(boundJID_, client_->getRoster(), client_->getAvatarManager(), uiFactory_, client_->getNickManager(), client_->getNickResolver(), client_->getPresenceOracle(), client_->getSubscriptionManager(), eventController_, uiEventStream_, client_->getIQRouter(), settings_, client_->getEntityCapsProvider(), ftOverview_, client_->getClientBlockListManager(), client_->getVCardManager());
- rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2));
- rosterController_->onSignOutRequest.connect(boost::bind(&MainController::signOut, this));
- rosterController_->getWindow()->onShowCertificateRequest.connect(boost::bind(&MainController::handleShowCertificateRequest, this));
-
- blockListController_ = new BlockListController(client_->getClientBlockListManager(), uiEventStream_, uiFactory_, eventController_);
-
- contactEditController_ = new ContactEditController(rosterController_, client_->getVCardManager(), uiFactory_, uiEventStream_);
- whiteboardManager_ = new WhiteboardManager(uiFactory_, uiEventStream_, client_->getNickResolver(), client_->getWhiteboardSessionManager());
-
- /* Doing this early as an ordering fix. Various things later will
- * want to have the user's nick available and this means it will
- * be before they receive stanzas that need it (e.g. bookmarks).*/
- client_->getVCardManager()->requestOwnVCard();
-
- contactSuggesterWithoutRoster_ = new ContactSuggester();
- contactSuggesterWithRoster_ = new ContactSuggester();
-
- userSearchControllerInvite_ = new UserSearchController(UserSearchController::InviteToChat, jid_, uiEventStream_, client_->getVCardManager(), uiFactory_, client_->getIQRouter(), rosterController_, contactSuggesterWithRoster_, client_->getAvatarManager(), client_->getPresenceOracle(), profileSettings_);
+ boundJID_ = client_->getJID();
+ resetCurrentError();
+ resetPendingReconnects();
+
+ if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) {
+ purgeCachedCredentials();
+ }
+
+ bool freshLogin = rosterController_ == nullptr;
+ myStatusLooksOnline_ = true;
+ if (freshLogin) {
+ profileController_ = new ProfileController(client_->getVCardManager(), uiFactory_, uiEventStream_);
+ showProfileController_ = new ShowProfileController(client_->getVCardManager(), uiFactory_, uiEventStream_);
+ ftOverview_ = new FileTransferOverview(client_->getFileTransferManager());
+ fileTransferListController_->setFileTransferOverview(ftOverview_);
+ rosterController_ = new RosterController(boundJID_, client_->getRoster(), client_->getAvatarManager(), uiFactory_, client_->getNickManager(), client_->getNickResolver(), client_->getPresenceOracle(), client_->getSubscriptionManager(), eventController_, uiEventStream_, client_->getIQRouter(), settings_, client_->getEntityCapsProvider(), client_->getClientBlockListManager(), client_->getVCardManager());
+ rosterController_->onChangeStatusRequest.connect(boost::bind(&MainController::handleChangeStatusRequest, this, _1, _2));
+ rosterController_->onSignOutRequest.connect(boost::bind(&MainController::signOut, this));
+ rosterController_->getWindow()->onShowCertificateRequest.connect(boost::bind(&MainController::handleShowCertificateRequest, this));
+
+ blockListController_ = new BlockListController(client_->getClientBlockListManager(), uiEventStream_, uiFactory_, eventController_);
+
+ contactEditController_ = new ContactEditController(rosterController_, client_->getVCardManager(), uiFactory_, uiEventStream_);
+ whiteboardManager_ = new WhiteboardManager(uiFactory_, uiEventStream_, client_->getNickResolver(), client_->getWhiteboardSessionManager());
+
+ /* Doing this early as an ordering fix. Various things later will
+ * want to have the user's nick available and this means it will
+ * be before they receive stanzas that need it (e.g. bookmarks).*/
+ client_->getVCardManager()->requestOwnVCard();
+
+ contactSuggesterWithoutRoster_ = new ContactSuggester();
+ contactSuggesterWithRoster_ = new ContactSuggester();
+
+ userSearchControllerInvite_ = new UserSearchController(UserSearchController::InviteToChat, jid_, uiEventStream_, client_->getVCardManager(), uiFactory_, client_->getIQRouter(), rosterController_, contactSuggesterWithRoster_, client_->getAvatarManager(), client_->getPresenceOracle(), profileSettings_);
#ifdef SWIFT_EXPERIMENTAL_HISTORY
- historyController_ = new HistoryController(storages_->getHistoryStorage());
- historyViewController_ = new HistoryViewController(jid_, uiEventStream_, historyController_, client_->getNickResolver(), client_->getAvatarManager(), client_->getPresenceOracle(), uiFactory_);
- chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, profileSettings_, ftOverview_, client_->getRoster(), !settings_->getSetting(SettingConstants::REMEMBER_RECENT_CHATS), settings_, historyController_, whiteboardManager_, highlightManager_, client_->getClientBlockListManager(), emoticons_, client_->getVCardManager());
+ historyController_ = new HistoryController(storages_->getHistoryStorage());
+ historyViewController_ = new HistoryViewController(jid_, uiEventStream_, historyController_, client_->getNickResolver(), client_->getAvatarManager(), client_->getPresenceOracle(), uiFactory_);
+ chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, profileSettings_, ftOverview_, client_->getRoster(), !settings_->getSetting(SettingConstants::REMEMBER_RECENT_CHATS), settings_, historyController_, whiteboardManager_, highlightManager_, client_->getClientBlockListManager(), emoticons_, client_->getVCardManager());
#else
- chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, profileSettings_, ftOverview_, client_->getRoster(), !settings_->getSetting(SettingConstants::REMEMBER_RECENT_CHATS), settings_, NULL, whiteboardManager_, highlightManager_, client_->getClientBlockListManager(), emoticons_, client_->getVCardManager());
+ chatsManager_ = new ChatsManager(jid_, client_->getStanzaChannel(), client_->getIQRouter(), eventController_, uiFactory_, uiFactory_, client_->getNickResolver(), client_->getPresenceOracle(), client_->getPresenceSender(), uiEventStream_, uiFactory_, useDelayForLatency_, networkFactories_->getTimerFactory(), client_->getMUCRegistry(), client_->getEntityCapsProvider(), client_->getMUCManager(), uiFactory_, profileSettings_, ftOverview_, client_->getRoster(), !settings_->getSetting(SettingConstants::REMEMBER_RECENT_CHATS), settings_, nullptr, whiteboardManager_, highlightManager_, client_->getClientBlockListManager(), emoticons_, client_->getVCardManager());
#endif
- contactsFromRosterProvider_ = new ContactsFromXMPPRoster(client_->getRoster(), client_->getAvatarManager(), client_->getPresenceOracle());
- contactSuggesterWithoutRoster_->addContactProvider(chatsManager_);
- contactSuggesterWithRoster_->addContactProvider(chatsManager_);
- contactSuggesterWithRoster_->addContactProvider(contactsFromRosterProvider_);
- highlightEditorController_->setContactSuggester(contactSuggesterWithoutRoster_);
+ contactsFromRosterProvider_ = new ContactsFromXMPPRoster(client_->getRoster(), client_->getAvatarManager(), client_->getPresenceOracle());
+ contactSuggesterWithoutRoster_->addContactProvider(chatsManager_);
+ contactSuggesterWithRoster_->addContactProvider(chatsManager_);
+ contactSuggesterWithRoster_->addContactProvider(contactsFromRosterProvider_);
+ highlightEditorController_->setContactSuggester(contactSuggesterWithoutRoster_);
- client_->onMessageReceived.connect(boost::bind(&ChatsManager::handleIncomingMessage, chatsManager_, _1));
- chatsManager_->setAvatarManager(client_->getAvatarManager());
+ client_->onMessageReceived.connect(boost::bind(&ChatsManager::handleIncomingMessage, chatsManager_, _1));
+ chatsManager_->setAvatarManager(client_->getAvatarManager());
- eventWindowController_ = new EventWindowController(eventController_, uiFactory_);
+ eventWindowController_ = new EventWindowController(eventController_, uiFactory_);
- loginWindow_->morphInto(rosterController_->getWindow());
+ loginWindow_->morphInto(rosterController_->getWindow());
- DiscoInfo discoInfo;
- discoInfo.addIdentity(DiscoInfo::Identity(CLIENT_NAME, "client", "pc"));
- discoInfo.addFeature(DiscoInfo::ChatStatesFeature);
- discoInfo.addFeature(DiscoInfo::SecurityLabelsFeature);
- discoInfo.addFeature(DiscoInfo::MessageCorrectionFeature);
+ DiscoInfo discoInfo;
+ discoInfo.addIdentity(DiscoInfo::Identity(CLIENT_NAME, "client", "pc"));
+ discoInfo.addFeature(DiscoInfo::ChatStatesFeature);
+ discoInfo.addFeature(DiscoInfo::SecurityLabelsFeature);
+ discoInfo.addFeature(DiscoInfo::MessageCorrectionFeature);
#ifdef SWIFT_EXPERIMENTAL_FT
- discoInfo.addFeature(DiscoInfo::JingleFeature);
- discoInfo.addFeature(DiscoInfo::JingleFTFeature);
- discoInfo.addFeature(DiscoInfo::JingleTransportsIBBFeature);
- discoInfo.addFeature(DiscoInfo::JingleTransportsS5BFeature);
+ discoInfo.addFeature(DiscoInfo::JingleFeature);
+ discoInfo.addFeature(DiscoInfo::JingleFTFeature);
+ discoInfo.addFeature(DiscoInfo::JingleTransportsIBBFeature);
+ discoInfo.addFeature(DiscoInfo::JingleTransportsS5BFeature);
#endif
#ifdef SWIFT_EXPERIMENTAL_WB
- discoInfo.addFeature(DiscoInfo::WhiteboardFeature);
+ discoInfo.addFeature(DiscoInfo::WhiteboardFeature);
#endif
- discoInfo.addFeature(DiscoInfo::MessageDeliveryReceiptsFeature);
- client_->getDiscoManager()->setCapsNode(CLIENT_NODE);
- client_->getDiscoManager()->setDiscoInfo(discoInfo);
-
- userSearchControllerChat_ = new UserSearchController(UserSearchController::StartChat, jid_, uiEventStream_, client_->getVCardManager(), uiFactory_, client_->getIQRouter(), rosterController_, contactSuggesterWithRoster_, client_->getAvatarManager(), client_->getPresenceOracle(), profileSettings_);
- userSearchControllerAdd_ = new UserSearchController(UserSearchController::AddContact, jid_, uiEventStream_, client_->getVCardManager(), uiFactory_, client_->getIQRouter(), rosterController_, contactSuggesterWithoutRoster_, client_->getAvatarManager(), client_->getPresenceOracle(), profileSettings_);
- adHocManager_ = new AdHocManager(JID(boundJID_.getDomain()), uiFactory_, client_->getIQRouter(), uiEventStream_, rosterController_->getWindow());
-
- chatsManager_->onImpromptuMUCServiceDiscovered.connect(boost::bind(&UserSearchController::setCanInitiateImpromptuMUC, userSearchControllerChat_, _1));
- }
- loginWindow_->setIsLoggingIn(false);
-
- client_->requestRoster();
-
- GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(JID(boundJID_.getDomain()), client_->getIQRouter());
- discoInfoRequest->onResponse.connect(boost::bind(&MainController::handleServerDiscoInfoResponse, this, _1, _2));
- discoInfoRequest->send();
-
- client_->getVCardManager()->requestOwnVCard();
-
- rosterController_->setJID(boundJID_);
- rosterController_->setEnabled(true);
- rosterController_->getWindow()->setStreamEncryptionStatus(client_->isStreamEncrypted());
- profileController_->setAvailable(true);
- contactEditController_->setAvailable(true);
- /* Send presence later to catch all the incoming presences. */
- sendPresence(statusTracker_->getNextPresence());
-
- /* Enable chats last of all, so rejoining MUCs has the right sent presence */
- assert(chatsManager_);
- chatsManager_->setOnline(true);
- adHocManager_->setOnline(true);
+ discoInfo.addFeature(DiscoInfo::MessageDeliveryReceiptsFeature);
+ client_->getDiscoManager()->setCapsNode(CLIENT_NODE);
+ client_->getDiscoManager()->setDiscoInfo(discoInfo);
+
+ userSearchControllerChat_ = new UserSearchController(UserSearchController::StartChat, jid_, uiEventStream_, client_->getVCardManager(), uiFactory_, client_->getIQRouter(), rosterController_, contactSuggesterWithRoster_, client_->getAvatarManager(), client_->getPresenceOracle(), profileSettings_);
+ userSearchControllerAdd_ = new UserSearchController(UserSearchController::AddContact, jid_, uiEventStream_, client_->getVCardManager(), uiFactory_, client_->getIQRouter(), rosterController_, contactSuggesterWithoutRoster_, client_->getAvatarManager(), client_->getPresenceOracle(), profileSettings_);
+ adHocManager_ = new AdHocManager(JID(boundJID_.getDomain()), uiFactory_, client_->getIQRouter(), uiEventStream_, rosterController_->getWindow());
+
+ chatsManager_->onImpromptuMUCServiceDiscovered.connect(boost::bind(&UserSearchController::setCanInitiateImpromptuMUC, userSearchControllerChat_, _1));
+ }
+ loginWindow_->setIsLoggingIn(false);
+
+ client_->requestRoster();
+
+ GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(JID(boundJID_.getDomain()), client_->getIQRouter());
+ discoInfoRequest->onResponse.connect(boost::bind(&MainController::handleServerDiscoInfoResponse, this, _1, _2));
+ discoInfoRequest->send();
+
+ client_->getVCardManager()->requestOwnVCard();
+
+ rosterController_->setJID(boundJID_);
+ rosterController_->setEnabled(true);
+ rosterController_->getWindow()->setStreamEncryptionStatus(client_->isStreamEncrypted());
+ profileController_->setAvailable(true);
+ contactEditController_->setAvailable(true);
+ /* Send presence later to catch all the incoming presences. */
+ sendPresence(statusTracker_->getNextPresence());
+
+ /* Enable chats last of all, so rejoining MUCs has the right sent presence */
+ assert(chatsManager_);
+ chatsManager_->setOnline(true);
+ adHocManager_->setOnline(true);
}
void MainController::handleEventQueueLengthChange(int count) {
- dock_->setNumberOfPendingMessages(count);
+ dock_->setNumberOfPendingMessages(count);
}
void MainController::reconnectAfterError() {
- if (reconnectTimer_) {
- reconnectTimer_->stop();
- }
- performLoginFromCachedCredentials();
+ if (reconnectTimer_) {
+ reconnectTimer_->stop();
+ }
+ performLoginFromCachedCredentials();
}
void MainController::handleChangeStatusRequest(StatusShow::Type show, const std::string &statusText) {
- boost::shared_ptr<Presence> presence(new Presence());
- if (show == StatusShow::None) {
- // Note: this is misleading, None doesn't mean unavailable on the wire.
- presence->setType(Presence::Unavailable);
- resetPendingReconnects();
- myStatusLooksOnline_ = false;
- offlineRequested_ = true;
- }
- else {
- offlineRequested_ = false;
- presence->setShow(show);
- }
- presence->setStatus(statusText);
- statusTracker_->setRequestedPresence(presence);
- if (presence->getType() != Presence::Unavailable) {
- profileSettings_->storeInt("lastShow", presence->getShow());
- profileSettings_->storeString("lastStatus", presence->getStatus());
- }
- if (presence->getType() != Presence::Unavailable && !client_->isAvailable()) {
- performLoginFromCachedCredentials();
- } else {
- sendPresence(presence);
- }
+ std::shared_ptr<Presence> presence(new Presence());
+ if (show == StatusShow::None) {
+ // Note: this is misleading, None doesn't mean unavailable on the wire.
+ presence->setType(Presence::Unavailable);
+ resetPendingReconnects();
+ myStatusLooksOnline_ = false;
+ offlineRequested_ = true;
+ }
+ else {
+ offlineRequested_ = false;
+ presence->setShow(show);
+ }
+ presence->setStatus(statusText);
+ statusTracker_->setRequestedPresence(presence);
+ if (presence->getType() != Presence::Unavailable) {
+ profileSettings_->storeInt("lastShow", presence->getShow());
+ profileSettings_->storeString("lastStatus", presence->getStatus());
+ }
+ if (presence->getType() != Presence::Unavailable && !client_->isAvailable()) {
+ performLoginFromCachedCredentials();
+ } else {
+ sendPresence(presence);
+ }
}
-void MainController::sendPresence(boost::shared_ptr<Presence> presence) {
- rosterController_->getWindow()->setMyStatusType(presence->getShow());
- rosterController_->getWindow()->setMyStatusText(presence->getStatus());
- systemTrayController_->setMyStatusType(presence->getShow());
- notifier_->setTemporarilyDisabled(presence->getShow() == StatusShow::DND);
-
- // Add information and send
- presence->updatePayload(boost::make_shared<VCardUpdate>(vCardPhotoHash_));
- client_->getPresenceSender()->sendPresence(presence);
- if (presence->getType() == Presence::Unavailable) {
- logout();
- }
+void MainController::sendPresence(std::shared_ptr<Presence> presence) {
+ rosterController_->getWindow()->setMyStatusType(presence->getShow());
+ rosterController_->getWindow()->setMyStatusText(presence->getStatus());
+ systemTrayController_->setMyStatusType(presence->getShow());
+ notifier_->setTemporarilyDisabled(presence->getShow() == StatusShow::DND);
+
+ // Add information and send
+ presence->updatePayload(std::make_shared<VCardUpdate>(vCardPhotoHash_));
+ client_->getPresenceSender()->sendPresence(presence);
+ if (presence->getType() == Presence::Unavailable) {
+ logout();
+ }
}
void MainController::handleInputIdleChanged(bool idle) {
- if (!statusTracker_) {
- //Haven't logged in yet.
- return;
- }
-
- if (settings_->getSetting(SettingConstants::IDLE_GOES_OFFLINE)) {
- if (idle) {
- logout();
- }
- }
- else {
- if (idle) {
- if (statusTracker_->goAutoAway(idleDetector_->getIdleTimeSeconds())) {
- if (client_ && client_->isAvailable()) {
- sendPresence(statusTracker_->getNextPresence());
- }
- }
- } else {
- if (statusTracker_->goAutoUnAway()) {
- if (client_ && client_->isAvailable()) {
- sendPresence(statusTracker_->getNextPresence());
- }
- }
- }
- }
+ if (!statusTracker_) {
+ //Haven't logged in yet.
+ return;
+ }
+
+ if (settings_->getSetting(SettingConstants::IDLE_GOES_OFFLINE)) {
+ if (idle) {
+ logout();
+ }
+ }
+ else {
+ if (idle) {
+ if (statusTracker_->goAutoAway(idleDetector_->getIdleTimeSeconds())) {
+ if (client_ && client_->isAvailable()) {
+ sendPresence(statusTracker_->getNextPresence());
+ }
+ }
+ } else {
+ if (statusTracker_->goAutoUnAway()) {
+ if (client_ && client_->isAvailable()) {
+ sendPresence(statusTracker_->getNextPresence());
+ }
+ }
+ }
+ }
}
void MainController::handleShowCertificateRequest() {
- std::vector<Certificate::ref> chain = client_->getStanzaChannel()->getPeerCertificateChain();
- rosterController_->getWindow()->openCertificateDialog(chain);
+ std::vector<Certificate::ref> chain = client_->getStanzaChannel()->getPeerCertificateChain();
+ rosterController_->getWindow()->openCertificateDialog(chain);
}
void MainController::handleLoginRequest(const std::string &username, const std::string &password, const std::string& certificatePath, CertificateWithKey::ref certificate, const ClientOptions& options, bool remember, bool loginAutomatically) {
- jid_ = JID(username);
- if (options.singleSignOn && (!jid_.isValid() || !jid_.getNode().empty())) {
- loginWindow_->setMessage(QT_TRANSLATE_NOOP("", "User address invalid. User address should be of the form 'wonderland.lit'"));
- loginWindow_->setIsLoggingIn(false);
- } else if (!options.singleSignOn && (!jid_.isValid() || jid_.getNode().empty())) {
- loginWindow_->setMessage(QT_TRANSLATE_NOOP("", "User address invalid. User address should be of the form 'alice@wonderland.lit'"));
- loginWindow_->setIsLoggingIn(false);
- } else {
+ jid_ = JID(username);
+ if (options.singleSignOn && (!jid_.isValid() || !jid_.getNode().empty())) {
+ loginWindow_->setMessage(QT_TRANSLATE_NOOP("", "User address invalid. User address should be of the form 'wonderland.lit'"));
+ loginWindow_->setIsLoggingIn(false);
+ } else if (!options.singleSignOn && (!jid_.isValid() || jid_.getNode().empty())) {
+ loginWindow_->setMessage(QT_TRANSLATE_NOOP("", "User address invalid. User address should be of the form 'alice@wonderland.lit'"));
+ loginWindow_->setIsLoggingIn(false);
+ } else {
#ifdef SWIFTEN_PLATFORM_WIN32
- if (options.singleSignOn) {
- std::string userName;
- std::string clientName;
- std::string serverName;
- boost::shared_ptr<boost::system::error_code> errorCode = getUserNameEx(userName, clientName, serverName);
-
- if (!errorCode) {
- /* Create JID using the Windows logon name and user provided domain name */
- jid_ = JID(clientName, username);
- }
- else {
- loginWindow_->setMessage(str(format(QT_TRANSLATE_NOOP("", "Error obtaining Windows user name (%1%)")) % errorCode->message()));
- loginWindow_->setIsLoggingIn(false);
- return;
- }
- }
+ if (options.singleSignOn) {
+ std::string userName;
+ std::string clientName;
+ std::string serverName;
+ std::shared_ptr<boost::system::error_code> errorCode = getUserNameEx(userName, clientName, serverName);
+
+ if (!errorCode) {
+ /* Create JID using the Windows logon name and user provided domain name */
+ jid_ = JID(clientName, username);
+ }
+ else {
+ loginWindow_->setMessage(str(format(QT_TRANSLATE_NOOP("", "Error obtaining Windows user name (%1%)")) % errorCode->message()));
+ loginWindow_->setIsLoggingIn(false);
+ return;
+ }
+ }
#endif
- loginWindow_->setMessage("");
- loginWindow_->setIsLoggingIn(true);
- profileSettings_ = new ProfileSettingsProvider(username, settings_);
- if (!settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) {
- profileSettings_->storeString("jid", username);
- profileSettings_->storeString("certificate", certificatePath);
- profileSettings_->storeString("pass", (remember || loginAutomatically) ? password : "");
- std::string optionString = serializeClientOptions(options);
- profileSettings_->storeString("options", optionString);
- settings_->storeSetting(SettingConstants::LAST_LOGIN_JID, username);
- settings_->storeSetting(SettingConstants::LOGIN_AUTOMATICALLY, loginAutomatically);
- loginWindow_->addAvailableAccount(profileSettings_->getStringSetting("jid"), profileSettings_->getStringSetting("pass"), profileSettings_->getStringSetting("certificate"), options);
- }
-
- password_ = password;
- certificate_ = certificate;
- clientOptions_ = options;
- performLoginFromCachedCredentials();
- }
+ loginWindow_->setMessage("");
+ loginWindow_->setIsLoggingIn(true);
+ profileSettings_ = new ProfileSettingsProvider(username, settings_);
+ if (!settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) {
+ profileSettings_->storeString("jid", username);
+ profileSettings_->storeString("certificate", certificatePath);
+ profileSettings_->storeString("pass", (remember || loginAutomatically) ? password : "");
+ std::string optionString = serializeClientOptions(options);
+ profileSettings_->storeString("options", optionString);
+ settings_->storeSetting(SettingConstants::LAST_LOGIN_JID, username);
+ settings_->storeSetting(SettingConstants::LOGIN_AUTOMATICALLY, loginAutomatically);
+ loginWindow_->addAvailableAccount(profileSettings_->getStringSetting("jid"), profileSettings_->getStringSetting("pass"), profileSettings_->getStringSetting("certificate"), options);
+ }
+
+ password_ = password;
+ certificate_ = certificate;
+ clientOptions_ = options;
+ performLoginFromCachedCredentials();
+ }
}
void MainController::handlePurgeSavedLoginRequest(const std::string& username) {
- settings_->removeProfile(username);
- loginWindow_->removeAvailableAccount(username);
+ settings_->removeProfile(username);
+ loginWindow_->removeAvailableAccount(username);
}
void MainController::performLoginFromCachedCredentials() {
- if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS) && password_.empty()) {
- /* Then we can't try to login again. */
- return;
- }
- /* If we logged in with a bare JID, and we have a full bound JID, re-login with the
- * bound JID to try and keep dynamically assigned resources */
- JID clientJID = jid_;
- if (boundJID_.isValid() && jid_.isBare() && boundJID_.toBare() == jid_) {
- clientJID = boundJID_;
- }
-
- if (!statusTracker_) {
- statusTracker_ = new StatusTracker();
- }
- if (!clientInitialized_) {
- storages_ = storagesFactory_->createStorages(jid_.toBare());
- certificateStorage_ = certificateStorageFactory_->createCertificateStorage(jid_.toBare());
- certificateTrustChecker_ = new CertificateStorageTrustChecker(certificateStorage_);
-
- client_ = boost::make_shared<Swift::Client>(clientJID, createSafeByteArray(password_.c_str()), networkFactories_, storages_);
- clientInitialized_ = true;
- client_->setCertificateTrustChecker(certificateTrustChecker_);
- client_->onDataRead.connect(boost::bind(&XMLConsoleController::handleDataRead, xmlConsoleController_, _1));
- client_->onDataWritten.connect(boost::bind(&XMLConsoleController::handleDataWritten, xmlConsoleController_, _1));
- client_->onDisconnected.connect(boost::bind(&MainController::handleDisconnected, this, _1));
- client_->onConnected.connect(boost::bind(&MainController::handleConnected, this));
-
- client_->setSoftwareVersion(CLIENT_NAME, buildVersion);
-
- client_->getVCardManager()->onVCardChanged.connect(boost::bind(&MainController::handleVCardReceived, this, _1, _2));
- presenceNotifier_ = new PresenceNotifier(client_->getStanzaChannel(), notifier_, client_->getMUCRegistry(), client_->getAvatarManager(), client_->getNickResolver(), client_->getPresenceOracle(), networkFactories_->getTimerFactory());
- presenceNotifier_->onNotificationActivated.connect(boost::bind(&MainController::handleNotificationClicked, this, _1));
- eventNotifier_ = new EventNotifier(eventController_, notifier_, client_->getAvatarManager(), client_->getNickResolver());
- eventNotifier_->onNotificationActivated.connect(boost::bind(&MainController::handleNotificationClicked, this, _1));
- if (certificate_) {
- client_->setCertificate(certificate_);
- }
- boost::shared_ptr<Presence> presence(new Presence());
- presence->setShow(static_cast<StatusShow::Type>(profileSettings_->getIntSetting("lastShow", StatusShow::Online)));
- presence->setStatus(profileSettings_->getStringSetting("lastStatus"));
- statusTracker_->setRequestedPresence(presence);
- } else {
- /* In case we're in the middle of another login, make sure they don't overlap */
- client_->disconnect();
- }
- systemTrayController_->setConnecting();
- if (rosterController_) {
- rosterController_->getWindow()->setConnecting();
- }
- ClientOptions clientOptions = clientOptions_;
- bool eagle = settings_->getSetting(SettingConstants::FORGET_PASSWORDS);
- clientOptions.forgetPassword = eagle;
- clientOptions.useTLS = eagle ? ClientOptions::RequireTLS : clientOptions_.useTLS;
- client_->connect(clientOptions);
+ if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS) && password_.empty()) {
+ /* Then we can't try to login again. */
+ return;
+ }
+ /* If we logged in with a bare JID, and we have a full bound JID, re-login with the
+ * bound JID to try and keep dynamically assigned resources */
+ JID clientJID = jid_;
+ if (boundJID_.isValid() && jid_.isBare() && boundJID_.toBare() == jid_) {
+ clientJID = boundJID_;
+ }
+
+ if (!statusTracker_) {
+ statusTracker_ = new StatusTracker();
+ }
+ if (!clientInitialized_) {
+ storages_ = storagesFactory_->createStorages(jid_.toBare());
+ certificateStorage_ = certificateStorageFactory_->createCertificateStorage(jid_.toBare());
+ certificateTrustChecker_ = new CertificateStorageTrustChecker(certificateStorage_);
+
+ client_ = std::make_shared<Swift::Client>(clientJID, createSafeByteArray(password_.c_str()), networkFactories_, storages_);
+ clientInitialized_ = true;
+ client_->setCertificateTrustChecker(certificateTrustChecker_);
+ client_->onDataRead.connect(boost::bind(&XMLConsoleController::handleDataRead, xmlConsoleController_, _1));
+ client_->onDataWritten.connect(boost::bind(&XMLConsoleController::handleDataWritten, xmlConsoleController_, _1));
+ client_->onDisconnected.connect(boost::bind(&MainController::handleDisconnected, this, _1));
+ client_->onConnected.connect(boost::bind(&MainController::handleConnected, this));
+
+ client_->setSoftwareVersion(CLIENT_NAME, buildVersion);
+
+ client_->getVCardManager()->onVCardChanged.connect(boost::bind(&MainController::handleVCardReceived, this, _1, _2));
+ presenceNotifier_ = new PresenceNotifier(client_->getStanzaChannel(), notifier_, client_->getMUCRegistry(), client_->getAvatarManager(), client_->getNickResolver(), client_->getPresenceOracle(), networkFactories_->getTimerFactory());
+ presenceNotifier_->onNotificationActivated.connect(boost::bind(&MainController::handleNotificationClicked, this, _1));
+ eventNotifier_ = new EventNotifier(eventController_, notifier_, client_->getAvatarManager(), client_->getNickResolver());
+ eventNotifier_->onNotificationActivated.connect(boost::bind(&MainController::handleNotificationClicked, this, _1));
+ if (certificate_) {
+ client_->setCertificate(certificate_);
+ }
+ std::shared_ptr<Presence> presence(new Presence());
+ presence->setShow(static_cast<StatusShow::Type>(profileSettings_->getIntSetting("lastShow", StatusShow::Online)));
+ presence->setStatus(profileSettings_->getStringSetting("lastStatus"));
+ statusTracker_->setRequestedPresence(presence);
+ } else {
+ /* In case we're in the middle of another login, make sure they don't overlap */
+ client_->disconnect();
+ }
+ systemTrayController_->setConnecting();
+ if (rosterController_) {
+ rosterController_->getWindow()->setConnecting();
+ }
+ ClientOptions clientOptions = clientOptions_;
+ bool eagle = settings_->getSetting(SettingConstants::FORGET_PASSWORDS);
+ clientOptions.forgetPassword = eagle;
+ clientOptions.useTLS = eagle ? ClientOptions::RequireTLS : clientOptions_.useTLS;
+ client_->connect(clientOptions);
}
void MainController::handleDisconnected(const boost::optional<ClientError>& error) {
- if (rosterController_) {
- rosterController_->getWindow()->setStreamEncryptionStatus(false);
- }
- if (adHocManager_) {
- adHocManager_->setOnline(false);
- }
- if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) {
- purgeCachedCredentials();
- }
- if (quitRequested_) {
- resetClient();
- loginWindow_->quit();
- }
- else if (error) {
- std::string message;
- std::string certificateErrorMessage;
- bool forceSignout = false;
- switch(error->getType()) {
- case ClientError::UnknownError: message = QT_TRANSLATE_NOOP("", "Unknown Error"); break;
- case ClientError::DomainNameResolveError: message = QT_TRANSLATE_NOOP("", "Unable to find server"); break;
- case ClientError::ConnectionError: message = QT_TRANSLATE_NOOP("", "Error connecting to server"); break;
- case ClientError::ConnectionReadError: message = QT_TRANSLATE_NOOP("", "Error while receiving server data"); break;
- case ClientError::ConnectionWriteError: message = QT_TRANSLATE_NOOP("", "Error while sending data to the server"); break;
- case ClientError::XMLError: message = QT_TRANSLATE_NOOP("", "Error parsing server data"); break;
- case ClientError::AuthenticationFailedError: message = QT_TRANSLATE_NOOP("", "Login/password invalid"); break;
- case ClientError::CompressionFailedError: message = QT_TRANSLATE_NOOP("", "Error while compressing stream"); break;
- case ClientError::ServerVerificationFailedError: message = QT_TRANSLATE_NOOP("", "Server verification failed"); break;
- case ClientError::NoSupportedAuthMechanismsError: message = QT_TRANSLATE_NOOP("", "Authentication mechanisms not supported"); break;
- case ClientError::UnexpectedElementError: message = QT_TRANSLATE_NOOP("", "Unexpected response"); break;
- case ClientError::ResourceBindError: message = QT_TRANSLATE_NOOP("", "Error binding resource"); break;
- case ClientError::SessionStartError: message = QT_TRANSLATE_NOOP("", "Error starting session"); break;
- case ClientError::StreamError: message = QT_TRANSLATE_NOOP("", "Stream error"); break;
- case ClientError::TLSError: message = QT_TRANSLATE_NOOP("", "Encryption error"); break;
- case ClientError::ClientCertificateLoadError: message = QT_TRANSLATE_NOOP("", "Error loading certificate (Invalid file or password?)"); break;
- case ClientError::ClientCertificateError: message = QT_TRANSLATE_NOOP("", "Certificate not authorized"); break;
- case ClientError::CertificateCardRemoved: message = QT_TRANSLATE_NOOP("", "Certificate card removed"); forceSignout = true; break;
-
- case ClientError::UnknownCertificateError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Unknown certificate"); break;
- case ClientError::CertificateExpiredError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate has expired"); break;
- case ClientError::CertificateNotYetValidError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate is not yet valid"); break;
- case ClientError::CertificateSelfSignedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate is self-signed"); break;
- case ClientError::CertificateRejectedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate has been rejected"); break;
- case ClientError::CertificateUntrustedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate is not trusted"); break;
- case ClientError::InvalidCertificatePurposeError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate cannot be used for encrypting your connection"); break;
- case ClientError::CertificatePathLengthExceededError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate path length constraint exceeded"); break;
- case ClientError::InvalidCertificateSignatureError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Invalid certificate signature"); break;
- case ClientError::InvalidCAError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Invalid Certificate Authority"); break;
- case ClientError::InvalidServerIdentityError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate does not match the host identity"); break;
- case ClientError::RevokedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate has been revoked"); break;
- case ClientError::RevocationCheckFailedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Unable to determine certificate revocation state"); break;
- }
- bool forceReconnectAfterCertificateTrust = false;
- if (!certificateErrorMessage.empty()) {
- std::vector<Certificate::ref> certificates = certificateTrustChecker_->getLastCertificateChain();
- if (!certificates.empty() && loginWindow_->askUserToTrustCertificatePermanently(certificateErrorMessage, certificates)) {
- certificateStorage_->addCertificate(certificates[0]);
- forceReconnectAfterCertificateTrust = true;
- }
- else {
- message = QT_TRANSLATE_NOOP("", "Certificate error");
- }
- }
-
- if (!message.empty() && error->getErrorCode()) {
- message = str(format(QT_TRANSLATE_NOOP("", "%1% (%2%)")) % message % error->getErrorCode()->message());
- }
-
- if (forceReconnectAfterCertificateTrust && settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) {
- forceReconnectAfterCertificateTrust = false;
- forceSignout = true;
- message = QT_TRANSLATE_NOOP("", "Re-enter credentials and retry");
- }
-
- if (forceReconnectAfterCertificateTrust) {
- performLoginFromCachedCredentials();
- }
- else if (forceSignout || !rosterController_) { //hasn't been logged in yet or permanent error
- signOut();
- loginWindow_->setMessage(message);
- loginWindow_->setIsLoggingIn(false);
- } else {
- logout();
- if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) {
- message = str(format(QT_TRANSLATE_NOOP("", "Disconnected from %1%: %2%. To reconnect, Sign Out and provide your password again.")) % jid_.getDomain() % message);
- } else {
- if (!offlineRequested_) {
- setReconnectTimer();
- }
- if (lastDisconnectError_) {
- message = str(format(QT_TRANSLATE_NOOP("", "Reconnect to %1% failed: %2%. Will retry in %3% seconds.")) % jid_.getDomain() % message % boost::lexical_cast<std::string>(timeBeforeNextReconnect_));
- lastDisconnectError_->conclude();
- } else {
- message = str(format(QT_TRANSLATE_NOOP("", "Disconnected from %1%: %2%.")) % jid_.getDomain() % message);
- }
- lastDisconnectError_ = boost::make_shared<ErrorEvent>(JID(jid_.getDomain()), message);
- eventController_->handleIncomingEvent(lastDisconnectError_);
- }
- }
- }
- else if (!rosterController_) { //hasn't been logged in yet
- loginWindow_->setIsLoggingIn(false);
- }
+ if (rosterController_) {
+ rosterController_->getWindow()->setStreamEncryptionStatus(false);
+ }
+ if (adHocManager_) {
+ adHocManager_->setOnline(false);
+ }
+ if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) {
+ purgeCachedCredentials();
+ }
+ if (quitRequested_) {
+ resetClient();
+ loginWindow_->quit();
+ }
+ else if (error) {
+ std::string message;
+ std::string certificateErrorMessage;
+ bool forceSignout = false;
+ switch(error->getType()) {
+ case ClientError::UnknownError: message = QT_TRANSLATE_NOOP("", "Unknown Error"); break;
+ case ClientError::DomainNameResolveError: message = QT_TRANSLATE_NOOP("", "Unable to find server"); break;
+ case ClientError::ConnectionError: message = QT_TRANSLATE_NOOP("", "Error connecting to server"); break;
+ case ClientError::ConnectionReadError: message = QT_TRANSLATE_NOOP("", "Error while receiving server data"); break;
+ case ClientError::ConnectionWriteError: message = QT_TRANSLATE_NOOP("", "Error while sending data to the server"); break;
+ case ClientError::XMLError: message = QT_TRANSLATE_NOOP("", "Error parsing server data"); break;
+ case ClientError::AuthenticationFailedError: message = QT_TRANSLATE_NOOP("", "Login/password invalid"); break;
+ case ClientError::CompressionFailedError: message = QT_TRANSLATE_NOOP("", "Error while compressing stream"); break;
+ case ClientError::ServerVerificationFailedError: message = QT_TRANSLATE_NOOP("", "Server verification failed"); break;
+ case ClientError::NoSupportedAuthMechanismsError: message = QT_TRANSLATE_NOOP("", "Authentication mechanisms not supported"); break;
+ case ClientError::UnexpectedElementError: message = QT_TRANSLATE_NOOP("", "Unexpected response"); break;
+ case ClientError::ResourceBindError: message = QT_TRANSLATE_NOOP("", "Error binding resource"); break;
+ case ClientError::SessionStartError: message = QT_TRANSLATE_NOOP("", "Error starting session"); break;
+ case ClientError::StreamError: message = QT_TRANSLATE_NOOP("", "Stream error"); break;
+ case ClientError::TLSError: message = QT_TRANSLATE_NOOP("", "Encryption error"); break;
+ case ClientError::ClientCertificateLoadError: message = QT_TRANSLATE_NOOP("", "Error loading certificate (Invalid file or password?)"); break;
+ case ClientError::ClientCertificateError: message = QT_TRANSLATE_NOOP("", "Certificate not authorized"); break;
+ case ClientError::CertificateCardRemoved: message = QT_TRANSLATE_NOOP("", "Certificate card removed"); forceSignout = true; break;
+
+ case ClientError::UnknownCertificateError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Unknown certificate"); break;
+ case ClientError::CertificateExpiredError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate has expired"); break;
+ case ClientError::CertificateNotYetValidError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate is not yet valid"); break;
+ case ClientError::CertificateSelfSignedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate is self-signed"); break;
+ case ClientError::CertificateRejectedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate has been rejected"); break;
+ case ClientError::CertificateUntrustedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate is not trusted"); break;
+ case ClientError::InvalidCertificatePurposeError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate cannot be used for encrypting your connection"); break;
+ case ClientError::CertificatePathLengthExceededError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate path length constraint exceeded"); break;
+ case ClientError::InvalidCertificateSignatureError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Invalid certificate signature"); break;
+ case ClientError::InvalidCAError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Invalid Certificate Authority"); break;
+ case ClientError::InvalidServerIdentityError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate does not match the host identity"); break;
+ case ClientError::RevokedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Certificate has been revoked"); break;
+ case ClientError::RevocationCheckFailedError: certificateErrorMessage = QT_TRANSLATE_NOOP("", "Unable to determine certificate revocation state"); break;
+ }
+ bool forceReconnectAfterCertificateTrust = false;
+ if (!certificateErrorMessage.empty()) {
+ std::vector<Certificate::ref> certificates = certificateTrustChecker_->getLastCertificateChain();
+ if (!certificates.empty() && loginWindow_->askUserToTrustCertificatePermanently(certificateErrorMessage, certificates)) {
+ certificateStorage_->addCertificate(certificates[0]);
+ forceReconnectAfterCertificateTrust = true;
+ }
+ else {
+ message = QT_TRANSLATE_NOOP("", "Certificate error");
+ }
+ }
+
+ if (!message.empty() && error->getErrorCode()) {
+ message = str(format(QT_TRANSLATE_NOOP("", "%1% (%2%)")) % message % error->getErrorCode()->message());
+ }
+
+ if (forceReconnectAfterCertificateTrust && settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) {
+ forceReconnectAfterCertificateTrust = false;
+ forceSignout = true;
+ message = QT_TRANSLATE_NOOP("", "Re-enter credentials and retry");
+ }
+
+ if (forceReconnectAfterCertificateTrust) {
+ performLoginFromCachedCredentials();
+ }
+ else if (forceSignout || !rosterController_) { //hasn't been logged in yet or permanent error
+ signOut();
+ loginWindow_->setMessage(message);
+ loginWindow_->setIsLoggingIn(false);
+ } else {
+ logout();
+ if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) {
+ message = str(format(QT_TRANSLATE_NOOP("", "Disconnected from %1%: %2%. To reconnect, Sign Out and provide your password again.")) % jid_.getDomain() % message);
+ } else {
+ if (!offlineRequested_) {
+ setReconnectTimer();
+ }
+ if (lastDisconnectError_) {
+ message = str(format(QT_TRANSLATE_NOOP("", "Reconnect to %1% failed: %2%. Will retry in %3% seconds.")) % jid_.getDomain() % message % boost::lexical_cast<std::string>(timeBeforeNextReconnect_));
+ lastDisconnectError_->conclude();
+ } else {
+ message = str(format(QT_TRANSLATE_NOOP("", "Disconnected from %1%: %2%.")) % jid_.getDomain() % message);
+ }
+ lastDisconnectError_ = std::make_shared<ErrorEvent>(JID(jid_.getDomain()), message);
+ eventController_->handleIncomingEvent(lastDisconnectError_);
+ }
+ }
+ }
+ else if (!rosterController_) { //hasn't been logged in yet
+ loginWindow_->setIsLoggingIn(false);
+ }
}
void MainController::setReconnectTimer() {
- if (timeBeforeNextReconnect_ < 0) {
- timeBeforeNextReconnect_ = 1;
- } else {
- timeBeforeNextReconnect_ = timeBeforeNextReconnect_ >= 150 ? 300 : timeBeforeNextReconnect_ * 2; // Randomly selected by roll of a die, as required by 3920bis
- }
- if (reconnectTimer_) {
- reconnectTimer_->stop();
- }
- reconnectTimer_ = networkFactories_->getTimerFactory()->createTimer(timeBeforeNextReconnect_ * 1000);
- reconnectTimer_->onTick.connect(boost::bind(&MainController::reconnectAfterError, this));
- reconnectTimer_->start();
+ if (timeBeforeNextReconnect_ < 0) {
+ timeBeforeNextReconnect_ = 1;
+ } else {
+ timeBeforeNextReconnect_ = timeBeforeNextReconnect_ >= 150 ? 300 : timeBeforeNextReconnect_ * 2; // Randomly selected by roll of a die, as required by 3920bis
+ }
+ if (reconnectTimer_) {
+ reconnectTimer_->stop();
+ }
+ reconnectTimer_ = networkFactories_->getTimerFactory()->createTimer(timeBeforeNextReconnect_ * 1000);
+ reconnectTimer_->onTick.connect(boost::bind(&MainController::reconnectAfterError, this));
+ reconnectTimer_->start();
}
void MainController::handleCancelLoginRequest() {
- signOut();
+ signOut();
}
void MainController::signOut() {
- if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) {
- purgeCachedCredentials();
- }
- eventController_->clear();
- logout();
- loginWindow_->loggedOut();
- resetClient();
+ if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) {
+ purgeCachedCredentials();
+ }
+ eventController_->clear();
+ logout();
+ loginWindow_->loggedOut();
+ resetClient();
}
void MainController::logout() {
- if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) {
- purgeCachedCredentials();
- }
- systemTrayController_->setMyStatusType(StatusShow::None);
- if (clientInitialized_ /*&& client_->isAvailable()*/) {
- client_->disconnect();
- }
- if (rosterController_ && myStatusLooksOnline_) {
- rosterController_->getWindow()->setMyStatusType(StatusShow::None);
- rosterController_->getWindow()->setMyStatusText("");
- myStatusLooksOnline_ = false;
- }
- setManagersOffline();
+ if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) {
+ purgeCachedCredentials();
+ }
+ systemTrayController_->setMyStatusType(StatusShow::None);
+ if (clientInitialized_ /*&& client_->isAvailable()*/) {
+ client_->disconnect();
+ }
+ if (rosterController_ && myStatusLooksOnline_) {
+ rosterController_->getWindow()->setMyStatusType(StatusShow::None);
+ rosterController_->getWindow()->setMyStatusText("");
+ myStatusLooksOnline_ = false;
+ }
+ setManagersOffline();
}
void MainController::setManagersOffline() {
- if (chatsManager_) {
- chatsManager_->setOnline(false);
- }
- if (rosterController_) {
- rosterController_->setEnabled(false);
- }
- if (profileController_) {
- profileController_->setAvailable(false);
- }
- if (contactEditController_) {
- contactEditController_->setAvailable(false);
- }
+ if (chatsManager_) {
+ chatsManager_->setOnline(false);
+ }
+ if (rosterController_) {
+ rosterController_->setEnabled(false);
+ }
+ if (profileController_) {
+ profileController_->setAvailable(false);
+ }
+ if (contactEditController_) {
+ contactEditController_->setAvailable(false);
+ }
}
-void MainController::handleServerDiscoInfoResponse(boost::shared_ptr<DiscoInfo> info, ErrorPayload::ref error) {
- if (!error) {
- chatsManager_->setServerDiscoInfo(info);
- adHocManager_->setServerDiscoInfo(info);
- if (info->hasFeature(DiscoInfo::BlockingCommandFeature)) {
- rosterController_->getWindow()->setBlockingCommandAvailable(true);
- rosterController_->initBlockingCommand();
- }
- }
+void MainController::handleServerDiscoInfoResponse(std::shared_ptr<DiscoInfo> info, ErrorPayload::ref error) {
+ if (!error) {
+ chatsManager_->setServerDiscoInfo(info);
+ adHocManager_->setServerDiscoInfo(info);
+ if (info->hasFeature(DiscoInfo::BlockingCommandFeature)) {
+ rosterController_->getWindow()->setBlockingCommandAvailable(true);
+ rosterController_->initBlockingCommand();
+ }
+ if (info->hasFeature(DiscoInfo::MessageCarbonsFeature)) {
+ enableMessageCarbons();
+ }
+ }
+}
+
+void MainController::enableMessageCarbons() {
+ auto enableCarbonsRequest = EnableCarbonsRequest::create(client_->getIQRouter());
+ enableCarbonsRequestHandlerConnection_ = enableCarbonsRequest->onResponse.connect([&](Payload::ref /*payload*/, ErrorPayload::ref error) {
+ if (error) {
+ SWIFT_LOG(warning) << "Failed to enable carbons." << std::endl;
+ }
+ else {
+ SWIFT_LOG(debug) << "Successfully enabled carbons." << std::endl;
+ }
+ enableCarbonsRequestHandlerConnection_.disconnect();
+ });
+ enableCarbonsRequest->send();
}
void MainController::handleVCardReceived(const JID& jid, VCard::ref vCard) {
- if (!jid.equals(jid_, JID::WithoutResource) || !vCard) {
- return;
- }
- std::string hash;
- if (!vCard->getPhoto().empty()) {
- hash = Hexify::hexify(networkFactories_->getCryptoProvider()->getSHA1Hash(vCard->getPhoto()));
- }
- if (hash != vCardPhotoHash_) {
- vCardPhotoHash_ = hash;
- if (client_ && client_->isAvailable()) {
- sendPresence(statusTracker_->getNextPresence());
- }
- }
+ if (!jid.equals(jid_, JID::WithoutResource) || !vCard) {
+ return;
+ }
+ std::string hash;
+ if (!vCard->getPhoto().empty()) {
+ hash = Hexify::hexify(networkFactories_->getCryptoProvider()->getSHA1Hash(vCard->getPhoto()));
+ }
+ if (hash != vCardPhotoHash_) {
+ vCardPhotoHash_ = hash;
+ if (client_ && client_->isAvailable()) {
+ sendPresence(statusTracker_->getNextPresence());
+ }
+ }
}
void MainController::handleNotificationClicked(const JID& jid) {
- assert(chatsManager_);
- if (clientInitialized_) {
- if (client_->getMUCRegistry()->isMUC(jid)) {
- uiEventStream_->send(boost::make_shared<JoinMUCUIEvent>(jid));
- }
- else {
- uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(jid)));
- }
- }
+ assert(chatsManager_);
+ if (clientInitialized_) {
+ if (client_->getMUCRegistry()->isMUC(jid)) {
+ uiEventStream_->send(std::make_shared<JoinMUCUIEvent>(jid));
+ }
+ else {
+ uiEventStream_->send(std::make_shared<RequestChatUIEvent>(jid));
+ }
+ }
}
void MainController::handleQuitRequest() {
- if (client_ && client_->isActive()) {
- quitRequested_ = true;
- client_->disconnect();
- }
- else {
- resetClient();
- loginWindow_->quit();
- }
+ if (client_ && client_->isActive()) {
+ quitRequested_ = true;
+ client_->disconnect();
+ }
+ else {
+ resetClient();
+ loginWindow_->quit();
+ }
}
#define SERIALIZE_BOOL(option) result += options.option ? "1" : "0"; result += ",";
@@ -851,34 +868,34 @@ void MainController::handleQuitRequest() {
#define SERIALIZE_URL(option) SERIALIZE_STRING(option.toString())
std::string MainController::serializeClientOptions(const ClientOptions& options) {
- std::string result;
- SERIALIZE_BOOL(useStreamCompression);
- switch (options.useTLS) {
- case ClientOptions::NeverUseTLS: result += "1";break;
- case ClientOptions::UseTLSWhenAvailable: result += "2";break;
- case ClientOptions::RequireTLS: result += "3";break;
- }
- result += ",";
- SERIALIZE_BOOL(allowPLAINWithoutTLS);
- SERIALIZE_BOOL(useStreamResumption);
- SERIALIZE_BOOL(useAcks);
- SERIALIZE_STRING(manualHostname);
- SERIALIZE_INT(manualPort);
- switch (options.proxyType) {
- case ClientOptions::NoProxy: result += "1";break;
- case ClientOptions::SystemConfiguredProxy: result += "2";break;
- case ClientOptions::SOCKS5Proxy: result += "3";break;
- case ClientOptions::HTTPConnectProxy: result += "4";break;
- }
- result += ",";
- SERIALIZE_STRING(manualProxyHostname);
- SERIALIZE_INT(manualProxyPort);
- SERIALIZE_URL(boshURL);
- SERIALIZE_URL(boshHTTPConnectProxyURL);
- SERIALIZE_SAFE_STRING(boshHTTPConnectProxyAuthID);
- SERIALIZE_SAFE_STRING(boshHTTPConnectProxyAuthPassword);
- SERIALIZE_BOOL(tlsOptions.schannelTLS1_0Workaround);
- return result;
+ std::string result;
+ SERIALIZE_BOOL(useStreamCompression);
+ switch (options.useTLS) {
+ case ClientOptions::NeverUseTLS: result += "1";break;
+ case ClientOptions::UseTLSWhenAvailable: result += "2";break;
+ case ClientOptions::RequireTLS: result += "3";break;
+ }
+ result += ",";
+ SERIALIZE_BOOL(allowPLAINWithoutTLS);
+ SERIALIZE_BOOL(useStreamResumption);
+ SERIALIZE_BOOL(useAcks);
+ SERIALIZE_STRING(manualHostname);
+ SERIALIZE_INT(manualPort);
+ switch (options.proxyType) {
+ case ClientOptions::NoProxy: result += "1";break;
+ case ClientOptions::SystemConfiguredProxy: result += "2";break;
+ case ClientOptions::SOCKS5Proxy: result += "3";break;
+ case ClientOptions::HTTPConnectProxy: result += "4";break;
+ }
+ result += ",";
+ SERIALIZE_STRING(manualProxyHostname);
+ SERIALIZE_INT(manualProxyPort);
+ SERIALIZE_URL(boshURL);
+ SERIALIZE_URL(boshHTTPConnectProxyURL);
+ SERIALIZE_SAFE_STRING(boshHTTPConnectProxyAuthID);
+ SERIALIZE_SAFE_STRING(boshHTTPConnectProxyAuthPassword);
+ SERIALIZE_BOOL(tlsOptions.schannelTLS1_0Workaround);
+ return result;
}
#define CHECK_PARSE_LENGTH if (i >= segments.size()) {return result;}
@@ -893,41 +910,41 @@ std::string MainController::serializeClientOptions(const ClientOptions& options)
ClientOptions MainController::parseClientOptions(const std::string& optionString) {
- ClientOptions result;
- size_t i = 0;
- int intVal = 0;
- std::string stringVal;
- std::vector<std::string> segments = String::split(optionString, ',');
-
- PARSE_BOOL(useStreamCompression, 1);
- PARSE_INT_RAW(-1);
- switch (intVal) {
- case 1: result.useTLS = ClientOptions::NeverUseTLS;break;
- case 2: result.useTLS = ClientOptions::UseTLSWhenAvailable;break;
- case 3: result.useTLS = ClientOptions::RequireTLS;break;
- default:;
- }
- PARSE_BOOL(allowPLAINWithoutTLS, 0);
- PARSE_BOOL(useStreamResumption, 0);
- PARSE_BOOL(useAcks, 1);
- PARSE_STRING(manualHostname);
- PARSE_INT(manualPort, -1);
- PARSE_INT_RAW(-1);
- switch (intVal) {
- case 1: result.proxyType = ClientOptions::NoProxy;break;
- case 2: result.proxyType = ClientOptions::SystemConfiguredProxy;break;
- case 3: result.proxyType = ClientOptions::SOCKS5Proxy;break;
- case 4: result.proxyType = ClientOptions::HTTPConnectProxy;break;
- }
- PARSE_STRING(manualProxyHostname);
- PARSE_INT(manualProxyPort, -1);
- PARSE_URL(boshURL);
- PARSE_URL(boshHTTPConnectProxyURL);
- PARSE_SAFE_STRING(boshHTTPConnectProxyAuthID);
- PARSE_SAFE_STRING(boshHTTPConnectProxyAuthPassword);
- PARSE_BOOL(tlsOptions.schannelTLS1_0Workaround, false);
-
- return result;
+ ClientOptions result;
+ size_t i = 0;
+ int intVal = 0;
+ std::string stringVal;
+ std::vector<std::string> segments = String::split(optionString, ',');
+
+ PARSE_BOOL(useStreamCompression, 1);
+ PARSE_INT_RAW(-1);
+ switch (intVal) {
+ case 1: result.useTLS = ClientOptions::NeverUseTLS;break;
+ case 2: result.useTLS = ClientOptions::UseTLSWhenAvailable;break;
+ case 3: result.useTLS = ClientOptions::RequireTLS;break;
+ default:;
+ }
+ PARSE_BOOL(allowPLAINWithoutTLS, 0);
+ PARSE_BOOL(useStreamResumption, 0);
+ PARSE_BOOL(useAcks, 1);
+ PARSE_STRING(manualHostname);
+ PARSE_INT(manualPort, -1);
+ PARSE_INT_RAW(-1);
+ switch (intVal) {
+ case 1: result.proxyType = ClientOptions::NoProxy;break;
+ case 2: result.proxyType = ClientOptions::SystemConfiguredProxy;break;
+ case 3: result.proxyType = ClientOptions::SOCKS5Proxy;break;
+ case 4: result.proxyType = ClientOptions::HTTPConnectProxy;break;
+ }
+ PARSE_STRING(manualProxyHostname);
+ PARSE_INT(manualProxyPort, -1);
+ PARSE_URL(boshURL);
+ PARSE_URL(boshHTTPConnectProxyURL);
+ PARSE_SAFE_STRING(boshHTTPConnectProxyAuthID);
+ PARSE_SAFE_STRING(boshHTTPConnectProxyAuthPassword);
+ PARSE_BOOL(tlsOptions.schannelTLS1_0Workaround, false);
+
+ return result;
}
}
diff --git a/Swift/Controllers/MainController.h b/Swift/Controllers/MainController.h
index cdf9436..cc3d45f 100644
--- a/Swift/Controllers/MainController.h
+++ b/Swift/Controllers/MainController.h
@@ -1,200 +1,201 @@
/*
- * Copyright (c) 2010-2013 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <vector>
#include <map>
+#include <memory>
#include <string>
+#include <vector>
-#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
-#include <Swiften/Base/boost_bsignals.h>
-#include <Swiften/Network/Timer.h>
#include <Swiften/Client/ClientError.h>
-#include <Swiften/JID/JID.h>
+#include <Swiften/Client/ClientXMLTracer.h>
+#include <Swiften/Elements/CapsInfo.h>
#include <Swiften/Elements/DiscoInfo.h>
-#include <Swiften/Elements/VCard.h>
#include <Swiften/Elements/ErrorPayload.h>
#include <Swiften/Elements/Presence.h>
-#include <Swiften/Elements/CapsInfo.h>
-#include <Swiften/Client/ClientXMLTracer.h>
+#include <Swiften/Elements/VCard.h>
+#include <Swiften/JID/JID.h>
+#include <Swiften/Network/Timer.h>
-#include <Swift/Controllers/Settings/SettingsProvider.h>
#include <Swift/Controllers/ProfileSettingsProvider.h>
-#include <Swift/Controllers/XMPPEvents/ErrorEvent.h>
+#include <Swift/Controllers/Settings/SettingsProvider.h>
#include <Swift/Controllers/UIEvents/UIEvent.h>
-
+#include <Swift/Controllers/XMPPEvents/ErrorEvent.h>
namespace Swift {
- class IdleDetector;
- class UIFactory;
- class EventLoop;
- class Client;
- class ChatController;
- class ChatsManager;
- class CertificateStorageFactory;
- class CertificateStorage;
- class CertificateStorageTrustChecker;
- class EventController;
- class MainWindow;
- class RosterController;
- class LoginWindow;
- class EventLoop;
- class MUCController;
- class Notifier;
- class ProfileController;
- class ShowProfileController;
- class ContactEditController;
- class TogglableNotifier;
- class PresenceNotifier;
- class EventNotifier;
- class SystemTray;
- class SystemTrayController;
- class SoundEventController;
- class SoundPlayer;
- class XMLConsoleController;
- class HistoryViewController;
- class HistoryController;
- class FileTransferListController;
- class UIEventStream;
- class EventWindowFactory;
- class EventWindowController;
- class MUCSearchController;
- class UserSearchController;
- class StatusTracker;
- class Dock;
- class Storages;
- class StoragesFactory;
- class NetworkFactories;
- class URIHandler;
- class XMPPURIController;
- class AdHocManager;
- class AdHocCommandWindowFactory;
- class FileTransferOverview;
- class WhiteboardManager;
- class HighlightManager;
- class HighlightEditorController;
- class BlockListController;
- class ContactSuggester;
- class ContactsFromXMPPRoster;
+ class IdleDetector;
+ class UIFactory;
+ class EventLoop;
+ class Client;
+ class ChatController;
+ class ChatsManager;
+ class CertificateStorageFactory;
+ class CertificateStorage;
+ class CertificateStorageTrustChecker;
+ class EventController;
+ class MainWindow;
+ class RosterController;
+ class LoginWindow;
+ class EventLoop;
+ class MUCController;
+ class Notifier;
+ class ProfileController;
+ class ShowProfileController;
+ class ContactEditController;
+ class TogglableNotifier;
+ class PresenceNotifier;
+ class EventNotifier;
+ class SystemTray;
+ class SystemTrayController;
+ class SoundEventController;
+ class SoundPlayer;
+ class XMLConsoleController;
+ class HistoryViewController;
+ class HistoryController;
+ class FileTransferListController;
+ class UIEventStream;
+ class EventWindowFactory;
+ class EventWindowController;
+ class MUCSearchController;
+ class UserSearchController;
+ class StatusTracker;
+ class Dock;
+ class Storages;
+ class StoragesFactory;
+ class NetworkFactories;
+ class URIHandler;
+ class XMPPURIController;
+ class AdHocManager;
+ class AdHocCommandWindowFactory;
+ class FileTransferOverview;
+ class WhiteboardManager;
+ class HighlightManager;
+ class HighlightEditorController;
+ class BlockListController;
+ class ContactSuggester;
+ class ContactsFromXMPPRoster;
+
+ class MainController {
+ public:
+ MainController(
+ EventLoop* eventLoop,
+ NetworkFactories* networkFactories,
+ UIFactory* uiFactories,
+ SettingsProvider *settings,
+ SystemTray* systemTray,
+ SoundPlayer* soundPlayer,
+ StoragesFactory* storagesFactory,
+ CertificateStorageFactory* certificateStorageFactory,
+ Dock* dock,
+ Notifier* notifier,
+ URIHandler* uriHandler,
+ IdleDetector* idleDetector,
+ const std::map<std::string, std::string>& emoticons,
+ bool useDelayForLatency);
+ ~MainController();
- class MainController {
- public:
- MainController(
- EventLoop* eventLoop,
- NetworkFactories* networkFactories,
- UIFactory* uiFactories,
- SettingsProvider *settings,
- SystemTray* systemTray,
- SoundPlayer* soundPlayer,
- StoragesFactory* storagesFactory,
- CertificateStorageFactory* certificateStorageFactory,
- Dock* dock,
- Notifier* notifier,
- URIHandler* uriHandler,
- IdleDetector* idleDetector,
- const std::map<std::string, std::string>& emoticons,
- bool useDelayForLatency);
- ~MainController();
+ private:
+ void resetClient();
+ void handleConnected();
+ void handleLoginRequest(const std::string& username, const std::string& password, const std::string& certificatePath, CertificateWithKey::ref certificate, const ClientOptions& options, bool remember, bool loginAutomatically);
+ void handleCancelLoginRequest();
+ void handleQuitRequest();
+ void handleChangeStatusRequest(StatusShow::Type show, const std::string &statusText);
+ void handleDisconnected(const boost::optional<ClientError>& error);
+ void handleServerDiscoInfoResponse(std::shared_ptr<DiscoInfo>, ErrorPayload::ref);
+ void handleEventQueueLengthChange(int count);
+ void handleVCardReceived(const JID& j, VCard::ref vCard);
+ void handleSettingChanged(const std::string& settingPath);
+ void handlePurgeSavedLoginRequest(const std::string& username);
+ void sendPresence(std::shared_ptr<Presence> presence);
+ void handleInputIdleChanged(bool);
+ void handleShowCertificateRequest();
+ void logout();
+ void signOut();
+ void setReconnectTimer();
+ void resetPendingReconnects();
+ void resetCurrentError();
+ void enableMessageCarbons();
- private:
- void resetClient();
- void handleConnected();
- void handleLoginRequest(const std::string& username, const std::string& password, const std::string& certificatePath, CertificateWithKey::ref certificate, const ClientOptions& options, bool remember, bool loginAutomatically);
- void handleCancelLoginRequest();
- void handleQuitRequest();
- void handleChangeStatusRequest(StatusShow::Type show, const std::string &statusText);
- void handleDisconnected(const boost::optional<ClientError>& error);
- void handleServerDiscoInfoResponse(boost::shared_ptr<DiscoInfo>, ErrorPayload::ref);
- void handleEventQueueLengthChange(int count);
- void handleVCardReceived(const JID& j, VCard::ref vCard);
- void handleSettingChanged(const std::string& settingPath);
- void handlePurgeSavedLoginRequest(const std::string& username);
- void sendPresence(boost::shared_ptr<Presence> presence);
- void handleInputIdleChanged(bool);
- void handleShowCertificateRequest();
- void logout();
- void signOut();
- void setReconnectTimer();
- void resetPendingReconnects();
- void resetCurrentError();
-
- void performLoginFromCachedCredentials();
- void reconnectAfterError();
- void setManagersOffline();
- void handleNotificationClicked(const JID& jid);
- void handleForceQuit();
- void purgeCachedCredentials();
- std::string serializeClientOptions(const ClientOptions& options);
- ClientOptions parseClientOptions(const std::string& optionString);
+ void performLoginFromCachedCredentials();
+ void reconnectAfterError();
+ void setManagersOffline();
+ void handleNotificationClicked(const JID& jid);
+ void handleForceQuit();
+ void purgeCachedCredentials();
+ std::string serializeClientOptions(const ClientOptions& options);
+ ClientOptions parseClientOptions(const std::string& optionString);
- private:
- EventLoop* eventLoop_;
- NetworkFactories* networkFactories_;
- UIFactory* uiFactory_;
- StoragesFactory* storagesFactory_;
- Storages* storages_;
- CertificateStorageFactory* certificateStorageFactory_;
- CertificateStorage* certificateStorage_;
- CertificateStorageTrustChecker* certificateTrustChecker_;
- bool clientInitialized_;
- boost::shared_ptr<Client> client_;
- SettingsProvider *settings_;
- ProfileSettingsProvider* profileSettings_;
- Dock* dock_;
- URIHandler* uriHandler_;
- IdleDetector* idleDetector_;
- TogglableNotifier* notifier_;
- PresenceNotifier* presenceNotifier_;
- EventNotifier* eventNotifier_;
- RosterController* rosterController_;
- EventController* eventController_;
- EventWindowController* eventWindowController_;
- AdHocManager* adHocManager_;
- LoginWindow* loginWindow_;
- UIEventStream* uiEventStream_;
- XMLConsoleController* xmlConsoleController_;
- HistoryViewController* historyViewController_;
- HistoryController* historyController_;
- FileTransferListController* fileTransferListController_;
- BlockListController* blockListController_;
- ChatsManager* chatsManager_;
- ProfileController* profileController_;
- ShowProfileController* showProfileController_;
- ContactEditController* contactEditController_;
- ContactsFromXMPPRoster* contactsFromRosterProvider_;
- ContactSuggester* contactSuggesterWithoutRoster_;
- ContactSuggester* contactSuggesterWithRoster_;
- JID jid_;
- JID boundJID_;
- SystemTrayController* systemTrayController_;
- SoundEventController* soundEventController_;
- XMPPURIController* xmppURIController_;
- std::string vCardPhotoHash_;
- std::string password_;
- CertificateWithKey::ref certificate_;
- ClientOptions clientOptions_;
- boost::shared_ptr<ErrorEvent> lastDisconnectError_;
- bool useDelayForLatency_;
- UserSearchController* userSearchControllerChat_;
- UserSearchController* userSearchControllerAdd_;
- UserSearchController* userSearchControllerInvite_;
- int timeBeforeNextReconnect_;
- Timer::ref reconnectTimer_;
- StatusTracker* statusTracker_;
- bool myStatusLooksOnline_;
- bool quitRequested_;
- bool offlineRequested_;
- static const int SecondsToWaitBeforeForceQuitting;
- FileTransferOverview* ftOverview_;
- WhiteboardManager* whiteboardManager_;
- HighlightManager* highlightManager_;
- HighlightEditorController* highlightEditorController_;
- std::map<std::string, std::string> emoticons_;
- };
+ private:
+ EventLoop* eventLoop_;
+ NetworkFactories* networkFactories_;
+ UIFactory* uiFactory_;
+ StoragesFactory* storagesFactory_;
+ Storages* storages_;
+ CertificateStorageFactory* certificateStorageFactory_;
+ CertificateStorage* certificateStorage_;
+ CertificateStorageTrustChecker* certificateTrustChecker_;
+ bool clientInitialized_;
+ std::shared_ptr<Client> client_;
+ SettingsProvider *settings_;
+ ProfileSettingsProvider* profileSettings_;
+ Dock* dock_;
+ URIHandler* uriHandler_;
+ IdleDetector* idleDetector_;
+ TogglableNotifier* notifier_;
+ PresenceNotifier* presenceNotifier_;
+ EventNotifier* eventNotifier_;
+ RosterController* rosterController_;
+ EventController* eventController_;
+ EventWindowController* eventWindowController_;
+ AdHocManager* adHocManager_;
+ LoginWindow* loginWindow_;
+ UIEventStream* uiEventStream_;
+ XMLConsoleController* xmlConsoleController_;
+ HistoryViewController* historyViewController_;
+ HistoryController* historyController_;
+ FileTransferListController* fileTransferListController_;
+ BlockListController* blockListController_;
+ ChatsManager* chatsManager_;
+ ProfileController* profileController_;
+ ShowProfileController* showProfileController_;
+ ContactEditController* contactEditController_;
+ ContactsFromXMPPRoster* contactsFromRosterProvider_;
+ ContactSuggester* contactSuggesterWithoutRoster_;
+ ContactSuggester* contactSuggesterWithRoster_;
+ JID jid_;
+ JID boundJID_;
+ SystemTrayController* systemTrayController_;
+ SoundEventController* soundEventController_;
+ XMPPURIController* xmppURIController_;
+ std::string vCardPhotoHash_;
+ std::string password_;
+ CertificateWithKey::ref certificate_;
+ ClientOptions clientOptions_;
+ std::shared_ptr<ErrorEvent> lastDisconnectError_;
+ bool useDelayForLatency_;
+ UserSearchController* userSearchControllerChat_;
+ UserSearchController* userSearchControllerAdd_;
+ UserSearchController* userSearchControllerInvite_;
+ int timeBeforeNextReconnect_;
+ Timer::ref reconnectTimer_;
+ StatusTracker* statusTracker_;
+ bool myStatusLooksOnline_ = false;
+ bool quitRequested_;
+ bool offlineRequested_;
+ static const int SecondsToWaitBeforeForceQuitting;
+ FileTransferOverview* ftOverview_;
+ WhiteboardManager* whiteboardManager_;
+ HighlightManager* highlightManager_;
+ HighlightEditorController* highlightEditorController_;
+ std::map<std::string, std::string> emoticons_;
+ boost::signals2::connection enableCarbonsRequestHandlerConnection_;
+ };
}
diff --git a/Swift/Controllers/PresenceNotifier.cpp b/Swift/Controllers/PresenceNotifier.cpp
index 0073720..91deae6 100644
--- a/Swift/Controllers/PresenceNotifier.cpp
+++ b/Swift/Controllers/PresenceNotifier.cpp
@@ -1,136 +1,137 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/Controllers/PresenceNotifier.h"
+#include <Swift/Controllers/PresenceNotifier.h>
#include <boost/bind.hpp>
-#include "Swiften/Client/StanzaChannel.h"
-#include "Swiften/Base/ByteArray.h"
-#include "Swiften/MUC/MUCRegistry.h"
-#include "Swiften/Roster/XMPPRoster.h"
-#include "Swiften/Presence/PresenceOracle.h"
-#include "Swiften/Network/TimerFactory.h"
-#include "Swiften/Client/NickResolver.h"
+#include <Swiften/Base/ByteArray.h>
+#include <Swiften/Client/NickResolver.h>
+#include <Swiften/Client/StanzaChannel.h>
+#include <Swiften/MUC/MUCRegistry.h>
+#include <Swiften/Network/TimerFactory.h>
+#include <Swiften/Presence/PresenceOracle.h>
+#include <Swiften/Roster/XMPPRoster.h>
+
#include <Swift/Controllers/StatusUtil.h>
namespace Swift {
PresenceNotifier::PresenceNotifier(StanzaChannel* stanzaChannel, Notifier* notifier, const MUCRegistry* mucRegistry, AvatarManager* avatarManager, NickResolver* nickResolver, const PresenceOracle* presenceOracle, TimerFactory* timerFactory) : stanzaChannel(stanzaChannel), notifier(notifier), mucRegistry(mucRegistry), avatarManager(avatarManager), nickResolver(nickResolver), presenceOracle(presenceOracle), timerFactory(timerFactory) {
- justInitialized = true;
- inQuietPeriod = false;
- stanzaChannel->onPresenceReceived.connect(boost::bind(&PresenceNotifier::handlePresenceReceived, this, _1));
- stanzaChannel->onAvailableChanged.connect(boost::bind(&PresenceNotifier::handleStanzaChannelAvailableChanged, this, _1));
- setInitialQuietPeriodMS(3000);
+ justInitialized = true;
+ inQuietPeriod = false;
+ stanzaChannel->onPresenceReceived.connect(boost::bind(&PresenceNotifier::handlePresenceReceived, this, _1));
+ stanzaChannel->onAvailableChanged.connect(boost::bind(&PresenceNotifier::handleStanzaChannelAvailableChanged, this, _1));
+ setInitialQuietPeriodMS(3000);
}
PresenceNotifier::~PresenceNotifier() {
- if (timer) {
- timer->stop();
- timer->onTick.disconnect(boost::bind(&PresenceNotifier::handleTimerTick, this));
- timer.reset();
- }
- stanzaChannel->onAvailableChanged.disconnect(boost::bind(&PresenceNotifier::handleStanzaChannelAvailableChanged, this, _1));
- stanzaChannel->onPresenceReceived.disconnect(boost::bind(&PresenceNotifier::handlePresenceReceived, this, _1));
+ if (timer) {
+ timer->stop();
+ timer->onTick.disconnect(boost::bind(&PresenceNotifier::handleTimerTick, this));
+ timer.reset();
+ }
+ stanzaChannel->onAvailableChanged.disconnect(boost::bind(&PresenceNotifier::handleStanzaChannelAvailableChanged, this, _1));
+ stanzaChannel->onPresenceReceived.disconnect(boost::bind(&PresenceNotifier::handlePresenceReceived, this, _1));
}
-void PresenceNotifier::handlePresenceReceived(boost::shared_ptr<Presence> presence) {
- JID from = presence->getFrom();
-
- if (mucRegistry->isMUC(from.toBare())) {
- return;
- }
-
- if (justInitialized) {
- justInitialized = false;
- if (timer) {
- inQuietPeriod = true;
- }
- }
-
- if (inQuietPeriod) {
- timer->stop();
- timer->start();
- return;
- }
-
- std::set<JID>::iterator i = availableUsers.find(from);
- if (presence->isAvailable()) {
- if (i != availableUsers.end()) {
- showNotification(from, Notifier::ContactStatusChange);
- }
- else {
- showNotification(from, Notifier::ContactAvailable);
- availableUsers.insert(from);
- }
- }
- else {
- if (i != availableUsers.end()) {
- showNotification(from, Notifier::ContactUnavailable);
- availableUsers.erase(i);
- }
- }
+void PresenceNotifier::handlePresenceReceived(std::shared_ptr<Presence> presence) {
+ JID from = presence->getFrom();
+
+ if (mucRegistry->isMUC(from.toBare())) {
+ return;
+ }
+
+ if (justInitialized) {
+ justInitialized = false;
+ if (timer) {
+ inQuietPeriod = true;
+ }
+ }
+
+ if (inQuietPeriod) {
+ timer->stop();
+ timer->start();
+ return;
+ }
+
+ std::set<JID>::iterator i = availableUsers.find(from);
+ if (presence->isAvailable()) {
+ if (i != availableUsers.end()) {
+ showNotification(from, Notifier::ContactStatusChange);
+ }
+ else {
+ showNotification(from, Notifier::ContactAvailable);
+ availableUsers.insert(from);
+ }
+ }
+ else {
+ if (i != availableUsers.end()) {
+ showNotification(from, Notifier::ContactUnavailable);
+ availableUsers.erase(i);
+ }
+ }
}
void PresenceNotifier::handleStanzaChannelAvailableChanged(bool available) {
- if (available) {
- availableUsers.clear();
- justInitialized = true;
- if (timer) {
- timer->stop();
- }
- }
+ if (available) {
+ availableUsers.clear();
+ justInitialized = true;
+ if (timer) {
+ timer->stop();
+ }
+ }
}
void PresenceNotifier::showNotification(const JID& jid, Notifier::Type type) {
- std::string name = nickResolver->jidToNick(jid);
- std::string title = name + " (" + getStatusType(jid) + ")";
- std::string message = getStatusMessage(jid);
- notifier->showMessage(type, title, message, avatarManager->getAvatarPath(jid), boost::bind(&PresenceNotifier::handleNotificationActivated, this, jid));
+ std::string name = nickResolver->jidToNick(jid);
+ std::string title = name + " (" + getStatusType(jid) + ")";
+ std::string message = getStatusMessage(jid);
+ notifier->showMessage(type, title, message, avatarManager->getAvatarPath(jid), boost::bind(&PresenceNotifier::handleNotificationActivated, this, jid));
}
void PresenceNotifier::handleNotificationActivated(JID jid) {
- onNotificationActivated(jid);
+ onNotificationActivated(jid);
}
std::string PresenceNotifier::getStatusType(const JID& jid) const {
- Presence::ref presence = presenceOracle->getLastPresence(jid);
- if (presence) {
- return statusShowTypeToFriendlyName(presence->getShow());
- }
- else {
- return "Unavailable";
- }
+ Presence::ref presence = presenceOracle->getLastPresence(jid);
+ if (presence) {
+ return statusShowTypeToFriendlyName(presence->getShow());
+ }
+ else {
+ return "Unavailable";
+ }
}
std::string PresenceNotifier::getStatusMessage(const JID& jid) const {
- Presence::ref presence = presenceOracle->getLastPresence(jid);
- if (presence) {
- return presence->getStatus();
- }
- else {
- return std::string();
- }
+ Presence::ref presence = presenceOracle->getLastPresence(jid);
+ if (presence) {
+ return presence->getStatus();
+ }
+ else {
+ return std::string();
+ }
}
void PresenceNotifier::setInitialQuietPeriodMS(int ms) {
- if (timer) {
- timer->stop();
- timer->onTick.disconnect(boost::bind(&PresenceNotifier::handleTimerTick, this));
- timer.reset();
- }
- if (ms > 0) {
- timer = timerFactory->createTimer(ms);
- timer->onTick.connect(boost::bind(&PresenceNotifier::handleTimerTick, this));
- }
+ if (timer) {
+ timer->stop();
+ timer->onTick.disconnect(boost::bind(&PresenceNotifier::handleTimerTick, this));
+ timer.reset();
+ }
+ if (ms > 0) {
+ timer = timerFactory->createTimer(ms);
+ timer->onTick.connect(boost::bind(&PresenceNotifier::handleTimerTick, this));
+ }
}
void PresenceNotifier::handleTimerTick() {
- inQuietPeriod = false;
- timer->stop();
+ inQuietPeriod = false;
+ timer->stop();
}
diff --git a/Swift/Controllers/PresenceNotifier.h b/Swift/Controllers/PresenceNotifier.h
index a1e1461..82678be 100644
--- a/Swift/Controllers/PresenceNotifier.h
+++ b/Swift/Controllers/PresenceNotifier.h
@@ -1,60 +1,62 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
#include <set>
-#include "Swiften/Base/boost_bsignals.h"
-#include "Swiften/Elements/Presence.h"
-#include "Swiften/JID/JID.h"
-#include "SwifTools/Notifier/Notifier.h"
-#include "Swiften/Avatars/AvatarManager.h"
-#include "Swiften/Network/Timer.h"
+#include <boost/signals2.hpp>
+
+#include <Swiften/Avatars/AvatarManager.h>
+#include <Swiften/Elements/Presence.h>
+#include <Swiften/JID/JID.h>
+#include <Swiften/Network/Timer.h>
+
+#include <SwifTools/Notifier/Notifier.h>
namespace Swift {
- class TimerFactory;
- class StanzaChannel;
- class MUCRegistry;
- class NickResolver;
- class PresenceOracle;
-
- class PresenceNotifier {
- public:
- PresenceNotifier(StanzaChannel* stanzaChannel, Notifier* notifier, const MUCRegistry* mucRegistry, AvatarManager* avatarManager, NickResolver* nickResolver, const PresenceOracle* presenceOracle, TimerFactory* timerFactory);
- ~PresenceNotifier();
-
- void setInitialQuietPeriodMS(int ms);
-
- boost::signal<void (const JID&)> onNotificationActivated;
-
- private:
- void handlePresenceReceived(boost::shared_ptr<Presence>);
- void handleStanzaChannelAvailableChanged(bool);
- void handleNotificationActivated(JID jid);
- void handleTimerTick();
- std::string getStatusType(const JID&) const;
- std::string getStatusMessage(const JID&) const;
-
- private:
- void showNotification(const JID& jid, Notifier::Type type);
-
- private:
- StanzaChannel* stanzaChannel;
- Notifier* notifier;
- const MUCRegistry* mucRegistry;
- AvatarManager* avatarManager;
- NickResolver* nickResolver;
- const PresenceOracle* presenceOracle;
- TimerFactory* timerFactory;
- boost::shared_ptr<Timer> timer;
- bool justInitialized;
- bool inQuietPeriod;
- std::set<JID> availableUsers;
- };
+ class TimerFactory;
+ class StanzaChannel;
+ class MUCRegistry;
+ class NickResolver;
+ class PresenceOracle;
+
+ class PresenceNotifier {
+ public:
+ PresenceNotifier(StanzaChannel* stanzaChannel, Notifier* notifier, const MUCRegistry* mucRegistry, AvatarManager* avatarManager, NickResolver* nickResolver, const PresenceOracle* presenceOracle, TimerFactory* timerFactory);
+ ~PresenceNotifier();
+
+ void setInitialQuietPeriodMS(int ms);
+
+ boost::signals2::signal<void (const JID&)> onNotificationActivated;
+
+ private:
+ void handlePresenceReceived(std::shared_ptr<Presence>);
+ void handleStanzaChannelAvailableChanged(bool);
+ void handleNotificationActivated(JID jid);
+ void handleTimerTick();
+ std::string getStatusType(const JID&) const;
+ std::string getStatusMessage(const JID&) const;
+
+ private:
+ void showNotification(const JID& jid, Notifier::Type type);
+
+ private:
+ StanzaChannel* stanzaChannel;
+ Notifier* notifier;
+ const MUCRegistry* mucRegistry;
+ AvatarManager* avatarManager;
+ NickResolver* nickResolver;
+ const PresenceOracle* presenceOracle;
+ TimerFactory* timerFactory;
+ std::shared_ptr<Timer> timer;
+ bool justInitialized;
+ bool inQuietPeriod;
+ std::set<JID> availableUsers;
+ };
}
diff --git a/Swift/Controllers/PreviousStatusStore.cpp b/Swift/Controllers/PreviousStatusStore.cpp
index 5886bdf..0b2d437 100644
--- a/Swift/Controllers/PreviousStatusStore.cpp
+++ b/Swift/Controllers/PreviousStatusStore.cpp
@@ -1,12 +1,10 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "PreviousStatusStore.h"
-
-#include "Swiften/Base/foreach.h"
+#include <Swift/Controllers/PreviousStatusStore.h>
namespace Swift {
@@ -19,35 +17,35 @@ PreviousStatusStore::~PreviousStatusStore() {
}
void PreviousStatusStore::addStatus(StatusShow::Type status, const std::string& message) {
- //FIXME: remove old entries
- store_.push_back(TypeStringPair(status, message));
+ //FIXME: remove old entries
+ store_.push_back(TypeStringPair(status, message));
}
std::vector<TypeStringPair> PreviousStatusStore::exactMatchSuggestions(StatusShow::Type status, const std::string& message) {
- std::vector<TypeStringPair> suggestions;
- suggestions.push_back(TypeStringPair(status, message));
- return suggestions;
+ std::vector<TypeStringPair> suggestions;
+ suggestions.push_back(TypeStringPair(status, message));
+ return suggestions;
}
std::vector<TypeStringPair> PreviousStatusStore::getSuggestions(const std::string& message) {
- std::vector<TypeStringPair> suggestions;
- foreach (TypeStringPair status, store_) {
- if (status.second == message) {
- suggestions.clear();
- suggestions.push_back(status);
- break;
- } else if (status.second.find(message) != std::string::npos) {
- suggestions.push_back(status);
- }
- }
- if (suggestions.empty()) {
- TypeStringPair suggestion(StatusShow::Online, message);
- suggestions.push_back(suggestion);
- }
- if (suggestions.size() == 1) {
- suggestions = exactMatchSuggestions(suggestions[0].first, suggestions[0].second);
- }
- return suggestions;
+ std::vector<TypeStringPair> suggestions;
+ for (auto&& status : store_) {
+ if (status.second == message) {
+ suggestions.clear();
+ suggestions.push_back(status);
+ break;
+ } else if (status.second.find(message) != std::string::npos) {
+ suggestions.push_back(status);
+ }
+ }
+ if (suggestions.empty()) {
+ TypeStringPair suggestion(StatusShow::Online, message);
+ suggestions.push_back(suggestion);
+ }
+ if (suggestions.size() == 1) {
+ suggestions = exactMatchSuggestions(suggestions[0].first, suggestions[0].second);
+ }
+ return suggestions;
}
}
diff --git a/Swift/Controllers/PreviousStatusStore.h b/Swift/Controllers/PreviousStatusStore.h
index 69531a5..b106445 100644
--- a/Swift/Controllers/PreviousStatusStore.h
+++ b/Swift/Controllers/PreviousStatusStore.h
@@ -1,28 +1,29 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <string>
#include <utility> /* std::pair */
#include <vector>
-#include <string>
-#include "Swiften/Elements/StatusShow.h"
+#include <Swiften/Elements/StatusShow.h>
namespace Swift {
- typedef std::pair<StatusShow::Type, std::string> TypeStringPair;
- class PreviousStatusStore {
- public:
- PreviousStatusStore();
- ~PreviousStatusStore();
- void addStatus(StatusShow::Type status, const std::string& message);
- std::vector<TypeStringPair> getSuggestions(const std::string& message);
+ typedef std::pair<StatusShow::Type, std::string> TypeStringPair;
+
+ class PreviousStatusStore {
+ public:
+ PreviousStatusStore();
+ ~PreviousStatusStore();
+ void addStatus(StatusShow::Type status, const std::string& message);
+ std::vector<TypeStringPair> getSuggestions(const std::string& message);
- private:
- std::vector<TypeStringPair> exactMatchSuggestions(StatusShow::Type status, const std::string& message);
- std::vector<TypeStringPair> store_;
- };
+ private:
+ std::vector<TypeStringPair> exactMatchSuggestions(StatusShow::Type status, const std::string& message);
+ std::vector<TypeStringPair> store_;
+ };
}
diff --git a/Swift/Controllers/ProfileController.cpp b/Swift/Controllers/ProfileController.cpp
index 49818b0..d000164 100644
--- a/Swift/Controllers/ProfileController.cpp
+++ b/Swift/Controllers/ProfileController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -17,87 +17,98 @@
namespace Swift {
-ProfileController::ProfileController(VCardManager* vcardManager, ProfileWindowFactory* profileWindowFactory, UIEventStream* uiEventStream) : vcardManager(vcardManager), profileWindowFactory(profileWindowFactory), uiEventStream(uiEventStream), available(true), profileWindow(NULL), gettingVCard(false) {
- uiEventStream->onUIEvent.connect(boost::bind(&ProfileController::handleUIEvent, this, _1));
+ProfileController::ProfileController(VCardManager* vcardManager, ProfileWindowFactory* profileWindowFactory, UIEventStream* uiEventStream) : vcardManager(vcardManager), profileWindowFactory(profileWindowFactory), uiEventStream(uiEventStream), available(true), profileWindow(nullptr), gettingVCard(false) {
+ uiEventStream->onUIEvent.connect(boost::bind(&ProfileController::handleUIEvent, this, _1));
}
ProfileController::~ProfileController() {
- if (profileWindow) {
- vcardManager->onOwnVCardChanged.disconnect(boost::bind(&ProfileController::handleOwnVCardChanged, this, _1));
- profileWindow->onVCardChangeRequest.disconnect(boost::bind(&ProfileController::handleVCardChangeRequest, this, _1));
- profileWindow->onWindowAboutToBeClosed.disconnect(boost::bind(&ProfileController::handleProfileWindowAboutToBeClosed, this, _1));
- }
- uiEventStream->onUIEvent.disconnect(boost::bind(&ProfileController::handleUIEvent, this, _1));
- delete profileWindow;
+ if (profileWindow) {
+ vcardManager->onOwnVCardChanged.disconnect(boost::bind(&ProfileController::handleOwnVCardChanged, this, _1));
+ vcardManager->onVCardRetrievalError.disconnect(boost::bind(&ProfileController::handleVCardRetrievalError, this, _1, _2));
+ profileWindow->onVCardChangeRequest.disconnect(boost::bind(&ProfileController::handleVCardChangeRequest, this, _1));
+ profileWindow->onWindowAboutToBeClosed.disconnect(boost::bind(&ProfileController::handleProfileWindowAboutToBeClosed, this, _1));
+ }
+ uiEventStream->onUIEvent.disconnect(boost::bind(&ProfileController::handleUIEvent, this, _1));
+ delete profileWindow;
}
void ProfileController::handleUIEvent(UIEvent::ref event) {
- if (!boost::dynamic_pointer_cast<RequestProfileEditorUIEvent>(event)) {
- return;
- }
-
- if (!profileWindow) {
- profileWindow = profileWindowFactory->createProfileWindow();
- profileWindow->setEditable(true);
- profileWindow->onVCardChangeRequest.connect(boost::bind(&ProfileController::handleVCardChangeRequest, this, _1));
- profileWindow->onWindowAboutToBeClosed.connect(boost::bind(&ProfileController::handleProfileWindowAboutToBeClosed, this, _1));
- vcardManager->onOwnVCardChanged.connect(boost::bind(&ProfileController::handleOwnVCardChanged, this, _1));
- }
- gettingVCard = true;
- updateDialogStatus();
- vcardManager->requestOwnVCard();
- profileWindow->show();
+ if (!std::dynamic_pointer_cast<RequestProfileEditorUIEvent>(event)) {
+ return;
+ }
+
+ if (!profileWindow) {
+ profileWindow = profileWindowFactory->createProfileWindow();
+ profileWindow->setEditable(true);
+ profileWindow->onVCardChangeRequest.connect(boost::bind(&ProfileController::handleVCardChangeRequest, this, _1));
+ profileWindow->onWindowAboutToBeClosed.connect(boost::bind(&ProfileController::handleProfileWindowAboutToBeClosed, this, _1));
+ vcardManager->onOwnVCardChanged.connect(boost::bind(&ProfileController::handleOwnVCardChanged, this, _1));
+ vcardManager->onVCardRetrievalError.connect(boost::bind(&ProfileController::handleVCardRetrievalError, this, _1, _2));
+ }
+ gettingVCard = true;
+ updateDialogStatus();
+ vcardManager->requestOwnVCard();
+ profileWindow->show();
}
void ProfileController::handleVCardChangeRequest(VCard::ref vcard) {
- assert(!pendingSetVCardRequest);
- profileWindow->setError("");
- pendingSetVCardRequest = vcardManager->createSetVCardRequest(vcard);
- pendingSetVCardRequest->onResponse.connect(boost::bind(&ProfileController::handleSetVCardResponse, this, _2));
- pendingSetVCardRequest->send();
- updateDialogStatus();
+ assert(!pendingSetVCardRequest);
+ profileWindow->setError("");
+ pendingSetVCardRequest = vcardManager->createSetVCardRequest(vcard);
+ pendingSetVCardRequest->onResponse.connect(boost::bind(&ProfileController::handleSetVCardResponse, this, _2));
+ pendingSetVCardRequest->send();
+ updateDialogStatus();
}
void ProfileController::handleSetVCardResponse(ErrorPayload::ref error) {
- pendingSetVCardRequest.reset();
- updateDialogStatus();
- if (error) {
- profileWindow->setVCard(vcardBeforeEdit);
- profileWindow->setError(QT_TRANSLATE_NOOP("", "There was an error publishing your profile data"));
- }
- else {
- profileWindow->setError("");
- profileWindow->hide();
- }
+ pendingSetVCardRequest.reset();
+ updateDialogStatus();
+ if (error) {
+ profileWindow->setVCard(vcardBeforeEdit);
+ profileWindow->setError(QT_TRANSLATE_NOOP("", "There was an error publishing your profile data"));
+ }
+ else {
+ profileWindow->setError("");
+ profileWindow->hide();
+ }
+}
+
+void ProfileController::handleVCardRetrievalError(const JID& jid, ErrorPayload::ref /* error */) {
+ if ((jid == JID()) && profileWindow) {
+ profileWindow->setProcessing(false);
+ profileWindow->setEnabled(false);
+ profileWindow->setVCard(std::make_shared<VCard>());
+ profileWindow->setError(QT_TRANSLATE_NOOP("", "There was an error fetching your current profile data"));
+ }
}
void ProfileController::handleOwnVCardChanged(VCard::ref vcard) {
- if (profileWindow) {
- profileWindow->setVCard(vcard);
- vcardBeforeEdit = vcard;
- gettingVCard = false;
- updateDialogStatus();
- }
+ if (profileWindow) {
+ profileWindow->setVCard(vcard);
+ vcardBeforeEdit = vcard;
+ gettingVCard = false;
+ updateDialogStatus();
+ }
}
void ProfileController::handleProfileWindowAboutToBeClosed(const JID&) {
- profileWindow = NULL;
+ profileWindow = nullptr;
}
void ProfileController::setAvailable(bool b) {
- available = b;
- if (!available) {
- pendingSetVCardRequest.reset();
- }
- updateDialogStatus();
+ available = b;
+ if (!available) {
+ pendingSetVCardRequest.reset();
+ }
+ updateDialogStatus();
}
void ProfileController::updateDialogStatus() {
- if (profileWindow) {
- profileWindow->setEnabled(available && !gettingVCard && !pendingSetVCardRequest);
- profileWindow->setProcessing(gettingVCard || pendingSetVCardRequest);
- }
+ if (profileWindow) {
+ profileWindow->setEnabled(available && !gettingVCard && !pendingSetVCardRequest);
+ profileWindow->setProcessing(gettingVCard || pendingSetVCardRequest);
+ }
}
}
diff --git a/Swift/Controllers/ProfileController.h b/Swift/Controllers/ProfileController.h
index c6f5420..3bb1fce 100644
--- a/Swift/Controllers/ProfileController.h
+++ b/Swift/Controllers/ProfileController.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -13,35 +13,36 @@
#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class UIEventStream;
- class ProfileWindowFactory;
- class ProfileWindow;
- class VCardManager;
-
- class ProfileController {
- public:
- ProfileController(VCardManager* vcardManager, ProfileWindowFactory* profileWindowFactory, UIEventStream* uiEventStream);
- ~ProfileController();
-
- void setAvailable(bool b);
-
- private:
- void handleUIEvent(UIEvent::ref event);
- void handleVCardChangeRequest(VCard::ref vcard);
- void handleSetVCardResponse(ErrorPayload::ref);
- void handleOwnVCardChanged(VCard::ref vcard);
- void handleProfileWindowAboutToBeClosed(const JID&);
- void updateDialogStatus();
-
- private:
- VCardManager* vcardManager;
- ProfileWindowFactory* profileWindowFactory;
- UIEventStream* uiEventStream;
- bool available;
- SetVCardRequest::ref pendingSetVCardRequest;
- ProfileWindow* profileWindow;
- bool gettingVCard;
- VCard::ref vcardBeforeEdit;
- };
+ class ProfileWindow;
+ class ProfileWindowFactory;
+ class UIEventStream;
+ class VCardManager;
+
+ class ProfileController {
+ public:
+ ProfileController(VCardManager* vcardManager, ProfileWindowFactory* profileWindowFactory, UIEventStream* uiEventStream);
+ ~ProfileController();
+
+ void setAvailable(bool b);
+
+ private:
+ void handleUIEvent(UIEvent::ref event);
+ void handleVCardChangeRequest(VCard::ref vcard);
+ void handleSetVCardResponse(ErrorPayload::ref);
+ void handleOwnVCardChanged(VCard::ref vcard);
+ void handleVCardRetrievalError(const JID& jid, ErrorPayload::ref error);
+ void handleProfileWindowAboutToBeClosed(const JID&);
+ void updateDialogStatus();
+
+ private:
+ VCardManager* vcardManager;
+ ProfileWindowFactory* profileWindowFactory;
+ UIEventStream* uiEventStream;
+ bool available;
+ SetVCardRequest::ref pendingSetVCardRequest;
+ ProfileWindow* profileWindow;
+ bool gettingVCard;
+ VCard::ref vcardBeforeEdit;
+ };
}
diff --git a/Swift/Controllers/ProfileSettingsProvider.cpp b/Swift/Controllers/ProfileSettingsProvider.cpp
index 180ffba..b979555 100644
--- a/Swift/Controllers/ProfileSettingsProvider.cpp
+++ b/Swift/Controllers/ProfileSettingsProvider.cpp
@@ -1,66 +1,68 @@
/*
- * Copyright (c) 2010-2012 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/Controllers/ProfileSettingsProvider.h"
+#include <Swift/Controllers/ProfileSettingsProvider.h>
+
+#include <Swift/Controllers/Settings/SettingsProvider.h>
namespace Swift {
ProfileSettingsProvider::ProfileSettingsProvider(const std::string& profile, SettingsProvider* provider) :
- profile_(profile) {
- provider_ = provider;
- bool found = false;
- foreach (std::string existingProfile, provider->getAvailableProfiles()) {
- if (existingProfile == profile) {
- found = true;
- }
- }
- if (!found) {
- provider_->createProfile(profile);
- }
+ profile_(profile) {
+ provider_ = provider;
+ bool found = false;
+ for (const auto& existingProfile : provider->getAvailableProfiles()) {
+ if (existingProfile == profile) {
+ found = true;
+ }
+ }
+ if (!found) {
+ provider_->createProfile(profile);
+ }
}
ProfileSettingsProvider::~ProfileSettingsProvider() {
}
std::string ProfileSettingsProvider::getStringSetting(const std::string &settingPath) {
- //FIXME: Remove shim
- SettingsProvider::Setting<std::string> setting(profileSettingPath(settingPath), "");
- return provider_->getSetting(setting);
+ //FIXME: Remove shim
+ SettingsProvider::Setting<std::string> setting(profileSettingPath(settingPath), "");
+ return provider_->getSetting(setting);
}
void ProfileSettingsProvider::storeString(const std::string &settingPath, const std::string &settingValue) {
- //FIXME: Remove shim
- if (!getIsSettingFinal(settingPath)) {
- SettingsProvider::Setting<std::string> setting(profileSettingPath(settingPath), "");
- provider_->storeSetting(setting, settingValue);
- }
+ //FIXME: Remove shim
+ if (!getIsSettingFinal(settingPath)) {
+ SettingsProvider::Setting<std::string> setting(profileSettingPath(settingPath), "");
+ provider_->storeSetting(setting, settingValue);
+ }
}
int ProfileSettingsProvider::getIntSetting(const std::string& settingPath, int defaultValue) {
- //FIXME: Remove shim
- SettingsProvider::Setting<int> setting(profileSettingPath(settingPath), defaultValue);
- return provider_->getSetting(setting);
+ //FIXME: Remove shim
+ SettingsProvider::Setting<int> setting(profileSettingPath(settingPath), defaultValue);
+ return provider_->getSetting(setting);
}
void ProfileSettingsProvider::storeInt(const std::string& settingPath, int settingValue) {
- //FIXME: Remove shim
- if (!getIsSettingFinal(settingPath)) {
- SettingsProvider::Setting<int> setting(profileSettingPath(settingPath), 0);
- provider_->storeSetting(setting, settingValue);
- }
+ //FIXME: Remove shim
+ if (!getIsSettingFinal(settingPath)) {
+ SettingsProvider::Setting<int> setting(profileSettingPath(settingPath), 0);
+ provider_->storeSetting(setting, settingValue);
+ }
}
bool ProfileSettingsProvider::getIsSettingFinal(const std::string& settingPath) {
- //FIXME: Remove shim
- SettingsProvider::Setting<int> setting(settingPath, 0);
- return provider_->getIsSettingFinal(setting);
+ //FIXME: Remove shim
+ SettingsProvider::Setting<int> setting(settingPath, 0);
+ return provider_->getIsSettingFinal(setting);
}
std::string ProfileSettingsProvider::profileSettingPath(const std::string &settingPath) {
- return profile_ + ":" + settingPath;
+ return profile_ + ":" + settingPath;
}
diff --git a/Swift/Controllers/ProfileSettingsProvider.h b/Swift/Controllers/ProfileSettingsProvider.h
index 02e1e81..e309c11 100644
--- a/Swift/Controllers/ProfileSettingsProvider.h
+++ b/Swift/Controllers/ProfileSettingsProvider.h
@@ -1,32 +1,34 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/foreach.h>
-
-#include <Swift/Controllers/Settings/SettingsProvider.h>
+#include <string>
namespace Swift {
+class SettingsProvider;
+
class ProfileSettingsProvider {
- public:
- ProfileSettingsProvider(const std::string& profile, SettingsProvider* provider);
- virtual ~ProfileSettingsProvider();
- virtual std::string getStringSetting(const std::string &settingPath);
- virtual void storeString(const std::string &settingPath, const std::string &settingValue);
- virtual int getIntSetting(const std::string& settingPath, int defaultValue);
- virtual void storeInt(const std::string& settingPath, int settingValue);
- /** See \ref SettingsProvider::getIsSettingFinal for discussion of what this means.*/
- virtual bool getIsSettingFinal(const std::string& settingPath);
-
- private:
- std::string profileSettingPath(const std::string &settingPath);
- SettingsProvider* provider_;
- std::string profile_;
+ public:
+ ProfileSettingsProvider(const std::string& profile, SettingsProvider* provider);
+ virtual ~ProfileSettingsProvider();
+ virtual std::string getStringSetting(const std::string &settingPath);
+ virtual void storeString(const std::string &settingPath, const std::string &settingValue);
+ virtual int getIntSetting(const std::string& settingPath, int defaultValue);
+ virtual void storeInt(const std::string& settingPath, int settingValue);
+ /** See \ref SettingsProvider::getIsSettingFinal for discussion of what this means.*/
+ virtual bool getIsSettingFinal(const std::string& settingPath);
+
+ private:
+ std::string profileSettingPath(const std::string &settingPath);
+
+ private:
+ SettingsProvider* provider_;
+ std::string profile_;
};
}
diff --git a/Swift/Controllers/Roster/ContactRosterItem.cpp b/Swift/Controllers/Roster/ContactRosterItem.cpp
index 3258fb5..8fdf183 100644
--- a/Swift/Controllers/Roster/ContactRosterItem.cpp
+++ b/Swift/Controllers/Roster/ContactRosterItem.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -9,8 +9,8 @@
#include <boost/date_time/posix_time/posix_time.hpp>
#include <Swiften/Base/DateTime.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Elements/Idle.h>
+#include <Swiften/Elements/Presence.h>
#include <Swift/Controllers/Intl.h>
#include <Swift/Controllers/Roster/GroupRosterItem.h>
@@ -27,149 +27,168 @@ ContactRosterItem::~ContactRosterItem() {
}
StatusShow::Type ContactRosterItem::getStatusShow() const {
- return presence_ ? presence_->getShow() : StatusShow::None;
+ return presence_ ? presence_->getShow() : StatusShow::None;
}
StatusShow::Type ContactRosterItem::getSimplifiedStatusShow() const {
- switch (presence_ ? presence_->getShow() : StatusShow::None) {
- case StatusShow::Online: return StatusShow::Online;
- case StatusShow::Away: return StatusShow::Away;
- case StatusShow::XA: return StatusShow::Away;
- case StatusShow::FFC: return StatusShow::Online;
- case StatusShow::DND: return StatusShow::DND;
- case StatusShow::None: return StatusShow::None;
- }
- assert(false);
- return StatusShow::None;
+ switch (presence_ ? presence_->getShow() : StatusShow::None) {
+ case StatusShow::Online: return StatusShow::Online;
+ case StatusShow::Away: return StatusShow::Away;
+ case StatusShow::XA: return StatusShow::Away;
+ case StatusShow::FFC: return StatusShow::Online;
+ case StatusShow::DND: return StatusShow::DND;
+ case StatusShow::None: return StatusShow::None;
+ }
+ assert(false);
+ return StatusShow::None;
}
std::string ContactRosterItem::getStatusText() const {
- return presence_ ? presence_->getStatus() : "";
+ return presence_ ? presence_->getStatus() : "";
}
std::string ContactRosterItem::getIdleText() const {
- Idle::ref idle = presence_ ? presence_->getPayload<Idle>() : Idle::ref();
- if (!idle || idle->getSince().is_not_a_date_time()) {
- return "";
- } else {
- return dateTimeToLocalString(idle->getSince());
- }
+ boost::posix_time::ptime idleTime = getIdle();
+ if (idleTime.is_not_a_date_time()) {
+ return "";
+ } else {
+ return dateTimeToLocalString(idleTime);
+ }
+}
+
+boost::posix_time::ptime ContactRosterItem::getIdle() const {
+ Idle::ref idle = presence_ ? presence_->getPayload<Idle>() : Idle::ref();
+ if (idle) {
+ return idle->getSince();
+ }
+ else {
+ return boost::posix_time::not_a_date_time;
+ }
}
std::string ContactRosterItem::getOfflineSinceText() const {
- if (presence_ && presence_->getType() == Presence::Unavailable) {
- boost::optional<boost::posix_time::ptime> delay = presence_->getTimestamp();
- if (delay) {
- return dateTimeToLocalString(*delay);
- }
- }
- return "";
+ boost::posix_time::ptime offlineSince = getOfflineSince();
+ if (!offlineSince.is_not_a_date_time()) {
+ return dateTimeToLocalString(offlineSince);
+ }
+ return "";
+}
+
+boost::posix_time::ptime ContactRosterItem::getOfflineSince() const {
+ boost::posix_time::ptime offlineSince = boost::posix_time::not_a_date_time;
+ if (presence_ && presence_->getType() == Presence::Unavailable) {
+ boost::optional<boost::posix_time::ptime> delay = presence_->getTimestamp();
+ if (delay) {
+ offlineSince = delay.get();
+ }
+ }
+ return offlineSince;
}
void ContactRosterItem::setAvatarPath(const boost::filesystem::path& path) {
- avatarPath_ = path;
- onDataChanged();
+ avatarPath_ = path;
+ onDataChanged();
}
const boost::filesystem::path& ContactRosterItem::getAvatarPath() const {
- return avatarPath_;
+ return avatarPath_;
}
const JID& ContactRosterItem::getJID() const {
- return jid_;
+ return jid_;
}
void ContactRosterItem::setDisplayJID(const JID& jid) {
- displayJID_ = jid;
+ displayJID_ = jid;
}
const JID& ContactRosterItem::getDisplayJID() const {
- return displayJID_;
+ return displayJID_;
}
-typedef std::pair<std::string, boost::shared_ptr<Presence> > StringPresencePair;
+typedef std::pair<std::string, std::shared_ptr<Presence> > StringPresencePair;
void ContactRosterItem::clearPresence() {
- presence_.reset();
- onDataChanged();
+ presence_.reset();
+ onDataChanged();
}
-void ContactRosterItem::applyPresence(boost::shared_ptr<Presence> presence) {
- presence_ = presence;
- onDataChanged();
+void ContactRosterItem::applyPresence(std::shared_ptr<Presence> presence) {
+ presence_ = presence;
+ onDataChanged();
}
const std::vector<std::string>& ContactRosterItem::getGroups() const {
- return groups_;
+ return groups_;
}
/** Only used so a contact can know about the groups it's in*/
void ContactRosterItem::addGroup(const std::string& group) {
- groups_.push_back(group);
+ groups_.push_back(group);
}
void ContactRosterItem::removeGroup(const std::string& group) {
- groups_.erase(std::remove(groups_.begin(), groups_.end(), group), groups_.end());
+ groups_.erase(std::remove(groups_.begin(), groups_.end(), group), groups_.end());
}
MUCOccupant::Role ContactRosterItem::getMUCRole() const
{
- return mucRole_;
+ return mucRole_;
}
void ContactRosterItem::setMUCRole(const MUCOccupant::Role& role)
{
- mucRole_ = role;
+ mucRole_ = role;
}
MUCOccupant::Affiliation ContactRosterItem::getMUCAffiliation() const
{
- return mucAffiliation_;
+ return mucAffiliation_;
}
void ContactRosterItem::setMUCAffiliation(const MUCOccupant::Affiliation& affiliation)
{
- mucAffiliation_ = affiliation;
+ mucAffiliation_ = affiliation;
}
std::string ContactRosterItem::getMUCAffiliationText() const
{
- std::string affiliationString;
- switch (mucAffiliation_) {
- case MUCOccupant::Owner: affiliationString = QT_TRANSLATE_NOOP("", "Owner"); break;
- case MUCOccupant::Admin: affiliationString = QT_TRANSLATE_NOOP("", "Admin"); break;
- case MUCOccupant::Member: affiliationString = QT_TRANSLATE_NOOP("", "Member"); break;
- case MUCOccupant::Outcast: affiliationString = QT_TRANSLATE_NOOP("", "Outcast"); break;
- case MUCOccupant::NoAffiliation: affiliationString = ""; break;
- }
+ std::string affiliationString;
+ switch (mucAffiliation_) {
+ case MUCOccupant::Owner: affiliationString = QT_TRANSLATE_NOOP("", "Owner"); break;
+ case MUCOccupant::Admin: affiliationString = QT_TRANSLATE_NOOP("", "Admin"); break;
+ case MUCOccupant::Member: affiliationString = QT_TRANSLATE_NOOP("", "Member"); break;
+ case MUCOccupant::Outcast: affiliationString = QT_TRANSLATE_NOOP("", "Outcast"); break;
+ case MUCOccupant::NoAffiliation: affiliationString = ""; break;
+ }
- return affiliationString;
+ return affiliationString;
}
void ContactRosterItem::setSupportedFeatures(const std::set<Feature>& features) {
- features_ = features;
- onDataChanged();
+ features_ = features;
+ onDataChanged();
}
bool ContactRosterItem::supportsFeature(const Feature feature) const {
- return features_.find(feature) != features_.end();
+ return features_.find(feature) != features_.end();
}
void ContactRosterItem::setBlockState(BlockState state) {
- blockState_ = state;
- onDataChanged();
+ blockState_ = state;
+ onDataChanged();
}
ContactRosterItem::BlockState ContactRosterItem::blockState() const {
- return blockState_;
+ return blockState_;
}
VCard::ref ContactRosterItem::getVCard() const {
- return vcard_;
+ return vcard_;
}
void ContactRosterItem::setVCard(VCard::ref vcard) {
- vcard_ = vcard;
- onDataChanged();
+ vcard_ = vcard;
+ onDataChanged();
}
}
diff --git a/Swift/Controllers/Roster/ContactRosterItem.h b/Swift/Controllers/Roster/ContactRosterItem.h
index d21935c..37c3840 100644
--- a/Swift/Controllers/Roster/ContactRosterItem.h
+++ b/Swift/Controllers/Roster/ContactRosterItem.h
@@ -1,11 +1,12 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -13,11 +14,9 @@
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/ptime.hpp>
#include <boost/filesystem/path.hpp>
-#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
-#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Elements/MUCOccupant.h>
-#include <Swiften/Elements/Presence.h>
#include <Swiften/Elements/StatusShow.h>
#include <Swiften/Elements/VCard.h>
#include <Swiften/JID/JID.h>
@@ -27,70 +26,73 @@
namespace Swift {
class GroupRosterItem;
+class Presence;
+
class ContactRosterItem : public RosterItem {
- public:
- enum Feature {
- FileTransferFeature,
- WhiteboardFeature
- };
-
- enum BlockState {
- BlockingNotSupported,
- IsBlocked,
- IsUnblocked,
- IsDomainBlocked
- };
-
- public:
- ContactRosterItem(const JID& jid, const JID& displayJID, const std::string& name, GroupRosterItem* parent);
- virtual ~ContactRosterItem();
-
- StatusShow::Type getStatusShow() const;
- StatusShow::Type getSimplifiedStatusShow() const;
- std::string getStatusText() const;
- std::string getIdleText() const;
- std::string getOfflineSinceText() const;
- void setAvatarPath(const boost::filesystem::path& path);
- const boost::filesystem::path& getAvatarPath() const;
- const JID& getJID() const;
- void setDisplayJID(const JID& jid);
- const JID& getDisplayJID() const;
- void applyPresence(boost::shared_ptr<Presence> presence);
- const std::vector<std::string>& getGroups() const;
- /** Only used so a contact can know about the groups it's in*/
- void addGroup(const std::string& group);
- void removeGroup(const std::string& group);
- void clearPresence();
-
- MUCOccupant::Role getMUCRole() const;
- void setMUCRole(const MUCOccupant::Role& role);
- MUCOccupant::Affiliation getMUCAffiliation() const;
- void setMUCAffiliation(const MUCOccupant::Affiliation& affiliation);
- std::string getMUCAffiliationText() const;
-
- void setSupportedFeatures(const std::set<Feature>& features);
- bool supportsFeature(Feature feature) const;
-
- void setBlockState(BlockState state);
- BlockState blockState() const;
-
- VCard::ref getVCard() const;
- void setVCard(VCard::ref vcard);
-
- boost::signal<void ()> onVCardRequested;
-
- private:
- JID jid_;
- JID displayJID_;
- boost::posix_time::ptime lastAvailableTime_;
- boost::filesystem::path avatarPath_;
- boost::shared_ptr<Presence> presence_;
- std::vector<std::string> groups_;
- MUCOccupant::Role mucRole_;
- MUCOccupant::Affiliation mucAffiliation_;
- std::set<Feature> features_;
- BlockState blockState_;
- VCard::ref vcard_;
+ public:
+ enum Feature {
+ FileTransferFeature,
+ WhiteboardFeature
+ };
+
+ enum BlockState {
+ BlockingNotSupported,
+ IsBlocked,
+ IsUnblocked,
+ IsDomainBlocked
+ };
+
+ public:
+ ContactRosterItem(const JID& jid, const JID& displayJID, const std::string& name, GroupRosterItem* parent);
+ virtual ~ContactRosterItem();
+
+ StatusShow::Type getStatusShow() const;
+ StatusShow::Type getSimplifiedStatusShow() const;
+ std::string getStatusText() const;
+ std::string getIdleText() const;
+ boost::posix_time::ptime getIdle() const;
+ std::string getOfflineSinceText() const;
+ boost::posix_time::ptime getOfflineSince() const;
+ void setAvatarPath(const boost::filesystem::path& path);
+ const boost::filesystem::path& getAvatarPath() const;
+ const JID& getJID() const;
+ void setDisplayJID(const JID& jid);
+ const JID& getDisplayJID() const;
+ void applyPresence(std::shared_ptr<Presence> presence);
+ const std::vector<std::string>& getGroups() const;
+ /** Only used so a contact can know about the groups it's in*/
+ void addGroup(const std::string& group);
+ void removeGroup(const std::string& group);
+ void clearPresence();
+
+ MUCOccupant::Role getMUCRole() const;
+ void setMUCRole(const MUCOccupant::Role& role);
+ MUCOccupant::Affiliation getMUCAffiliation() const;
+ void setMUCAffiliation(const MUCOccupant::Affiliation& affiliation);
+ std::string getMUCAffiliationText() const;
+
+ void setSupportedFeatures(const std::set<Feature>& features);
+ bool supportsFeature(Feature feature) const;
+
+ void setBlockState(BlockState state);
+ BlockState blockState() const;
+
+ VCard::ref getVCard() const;
+ void setVCard(VCard::ref vcard);
+
+ boost::signals2::signal<void ()> onVCardRequested;
+
+ private:
+ JID jid_;
+ JID displayJID_;
+ boost::filesystem::path avatarPath_;
+ std::shared_ptr<Presence> presence_;
+ std::vector<std::string> groups_;
+ MUCOccupant::Role mucRole_;
+ MUCOccupant::Affiliation mucAffiliation_;
+ std::set<Feature> features_;
+ BlockState blockState_;
+ VCard::ref vcard_;
};
}
diff --git a/Swift/Controllers/Roster/FuzzyRosterFilter.h b/Swift/Controllers/Roster/FuzzyRosterFilter.h
index 6710084..8c45935 100644
--- a/Swift/Controllers/Roster/FuzzyRosterFilter.h
+++ b/Swift/Controllers/Roster/FuzzyRosterFilter.h
@@ -4,33 +4,39 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <string>
#include <Swift/Controllers/ContactSuggester.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
-#include <Swift/Controllers/Roster/RosterItem.h>
#include <Swift/Controllers/Roster/RosterFilter.h>
+#include <Swift/Controllers/Roster/RosterItem.h>
namespace Swift {
class FuzzyRosterFilter : public RosterFilter {
- public:
- FuzzyRosterFilter(const std::string& query) : query_(query) { }
- virtual ~FuzzyRosterFilter() {}
- virtual bool operator() (RosterItem* item) const {
- ContactRosterItem *contactItem = dynamic_cast<ContactRosterItem*>(item);
- if (contactItem) {
- const bool itemMatched = ContactSuggester::fuzzyMatch(contactItem->getDisplayName(), query_) || ContactSuggester::fuzzyMatch(contactItem->getDisplayJID(), query_);
- return !itemMatched;
- } else {
- return false;
- }
- }
-
- private:
- std::string query_;
+ public:
+ FuzzyRosterFilter(const std::string& query) : query_(query) { }
+ virtual ~FuzzyRosterFilter() {}
+ virtual bool operator() (RosterItem* item) const {
+ ContactRosterItem *contactItem = dynamic_cast<ContactRosterItem*>(item);
+ if (contactItem) {
+ const bool itemMatched = ContactSuggester::fuzzyMatch(contactItem->getDisplayName(), query_) || ContactSuggester::fuzzyMatch(contactItem->getDisplayJID(), query_);
+ return !itemMatched;
+ } else {
+ return false;
+ }
+ }
+
+ private:
+ std::string query_;
};
}
diff --git a/Swift/Controllers/Roster/GroupRosterItem.cpp b/Swift/Controllers/Roster/GroupRosterItem.cpp
index a241dec..ac40afd 100644
--- a/Swift/Controllers/Roster/GroupRosterItem.cpp
+++ b/Swift/Controllers/Roster/GroupRosterItem.cpp
@@ -1,11 +1,10 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/Controllers/Roster/GroupRosterItem.h"
-
+#include <Swift/Controllers/Roster/GroupRosterItem.h>
#include <boost/bind.hpp>
//#include <boost/algorithm.hpp>
#include <iostream>
@@ -13,7 +12,7 @@
namespace Swift {
GroupRosterItem::GroupRosterItem(const std::string& name, GroupRosterItem* parent, bool sortByStatus) : RosterItem(name, parent), sortByStatus_(sortByStatus), manualSort_(false) {
- expanded_ = true;
+ expanded_ = true;
}
GroupRosterItem::~GroupRosterItem() {
@@ -21,77 +20,77 @@ GroupRosterItem::~GroupRosterItem() {
}
void GroupRosterItem::setManualSort(const std::string& manualSortValue) {
- manualSort_ = true;
- bool changed = manualSortValue_ != manualSortValue;
- manualSortValue_ = manualSortValue;
- if (changed) {
- onChildrenChanged();
- onDataChanged();
- }
+ manualSort_ = true;
+ bool changed = manualSortValue_ != manualSortValue;
+ manualSortValue_ = manualSortValue;
+ if (changed) {
+ onChildrenChanged();
+ onDataChanged();
+ }
}
const std::string& GroupRosterItem::getSortableDisplayName() const {
- return manualSort_ ? manualSortValue_ : RosterItem::getSortableDisplayName();
+ return manualSort_ ? manualSortValue_ : RosterItem::getSortableDisplayName();
}
bool GroupRosterItem::isExpanded() const {
- return expanded_;
+ return expanded_;
}
/**
- This has no effect, and is only used by the UI.
- If reTransmit is specified, dataChanged will be emitted on a change -
- This may be undesireable if called from the UI, so you can use reTransmit=false
- to avoid a loop in this case.
+ This has no effect, and is only used by the UI.
+ If reTransmit is specified, dataChanged will be emitted on a change -
+ This may be undesireable if called from the UI, so you can use reTransmit=false
+ to avoid a loop in this case.
*/
void GroupRosterItem::setExpanded(bool expanded) {
- bool old = expanded_;
- expanded_ = expanded;
- if (expanded != old) {
- onExpandedChanged(expanded);
- }
+ bool old = expanded_;
+ expanded_ = expanded;
+ if (expanded != old) {
+ onExpandedChanged(expanded);
+ }
}
const std::vector<RosterItem*>& GroupRosterItem::getChildren() const {
- return children_;
+ return children_;
}
const std::vector<RosterItem*>& GroupRosterItem::getDisplayedChildren() const {
- return displayedChildren_;
+ return displayedChildren_;
}
void GroupRosterItem::addChild(RosterItem* item) {
- children_.push_back(item);
- GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
- if (group) {
- group->onChildrenChanged.connect(boost::bind(&GroupRosterItem::handleChildrenChanged, this, group));
- } else {
- item->onDataChanged.connect(boost::bind(&GroupRosterItem::handleDataChanged, this, item));
- }
- onChildrenChanged();
- onDataChanged();
+ children_.push_back(item);
+ GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
+ if (group) {
+ group->onChildrenChanged.connect(boost::bind(&GroupRosterItem::handleChildrenChanged, this, group));
+ } else {
+ item->onDataChanged.connect(boost::bind(&GroupRosterItem::handleDataChanged, this, item));
+ }
+ onChildrenChanged();
+ onDataChanged();
}
/**
* Does not emit a changed signal.
*/
void GroupRosterItem::removeAll() {
- std::vector<RosterItem*>::iterator it = children_.begin();
- displayedChildren_.clear();
- while (it != children_.end()) {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(*it);
- if (contact) {
- delete contact;
- } else {
- GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it);
- if (group) {
- group->removeAll();
- delete group;
- }
- }
- ++it;
- }
- children_.clear();
+ std::vector<RosterItem*>::iterator it = children_.begin();
+ displayedChildren_.clear();
+ while (it != children_.end()) {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(*it);
+ if (contact) {
+ delete contact;
+ } else {
+ GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it);
+ if (group) {
+ group->removeAll();
+ delete group;
+ }
+ }
+ ++it;
+ }
+ children_.clear();
}
/**
@@ -99,136 +98,136 @@ void GroupRosterItem::removeAll() {
* the return result is undefined.
*/
ContactRosterItem* GroupRosterItem::removeChild(const JID& jid) {
- std::vector<RosterItem*>::iterator it = children_.begin();
- ContactRosterItem* removed = NULL;
- while (it != children_.end()) {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(*it);
- if (contact && contact->getJID() == jid) {
- displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), contact), displayedChildren_.end());
- removed = contact;
- delete contact;
- it = children_.erase(it);
- continue;
- }
- GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it);
- if (group) {
- ContactRosterItem* groupRemoved = group->removeChild(jid);
- if (groupRemoved) {
- removed = groupRemoved;
- }
- }
- ++it;
- }
- onChildrenChanged();
- onDataChanged();
- return removed;
+ std::vector<RosterItem*>::iterator it = children_.begin();
+ ContactRosterItem* removed = nullptr;
+ while (it != children_.end()) {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(*it);
+ if (contact && contact->getJID() == jid) {
+ displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), contact), displayedChildren_.end());
+ removed = contact;
+ delete contact;
+ it = children_.erase(it);
+ continue;
+ }
+ GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it);
+ if (group) {
+ ContactRosterItem* groupRemoved = group->removeChild(jid);
+ if (groupRemoved) {
+ removed = groupRemoved;
+ }
+ }
+ ++it;
+ }
+ onChildrenChanged();
+ onDataChanged();
+ return removed;
}
GroupRosterItem* GroupRosterItem::removeGroupChild(const std::string& groupName) {
- std::vector<RosterItem*>::iterator it = children_.begin();
- GroupRosterItem* removed = NULL;
- while (it != children_.end()) {
- GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it);
- if (group && group->getDisplayName() == groupName) {
- displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), group), displayedChildren_.end());
- removed = group;
- delete group;
- it = children_.erase(it);
- continue;
- }
- ++it;
- }
- onChildrenChanged();
- onDataChanged();
- return removed;
+ std::vector<RosterItem*>::iterator it = children_.begin();
+ GroupRosterItem* removed = nullptr;
+ while (it != children_.end()) {
+ GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it);
+ if (group && group->getDisplayName() == groupName) {
+ displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), group), displayedChildren_.end());
+ removed = group;
+ delete group;
+ it = children_.erase(it);
+ continue;
+ }
+ ++it;
+ }
+ onChildrenChanged();
+ onDataChanged();
+ return removed;
}
/**
* Returns false if the list didn't need a resort
*/
bool GroupRosterItem::sortDisplayed() {
- /* Not doing this until we import boost::algorithm*/
-// if (boost::is_sorted(displayedChildren_begin(), displayedChildren_.end(), itemLessThan)) {
-// return false;
-// }
- //Sholudn't need stable_sort here
- std::sort(displayedChildren_.begin(), displayedChildren_.end(), sortByStatus_? itemLessThanWithStatus : itemLessThanWithoutStatus);
- return true;
+ /* Not doing this until we import boost::algorithm*/
+// if (boost::is_sorted(displayedChildren_begin(), displayedChildren_.end(), itemLessThan)) {
+// return false;
+// }
+ //Sholudn't need stable_sort here
+ std::sort(displayedChildren_.begin(), displayedChildren_.end(), sortByStatus_? itemLessThanWithStatus : itemLessThanWithoutStatus);
+ return true;
}
bool GroupRosterItem::itemLessThanWithoutStatus(const RosterItem* left, const RosterItem* right) {
- return left->getSortableDisplayName() < right->getSortableDisplayName();
+ return left->getSortableDisplayName() < right->getSortableDisplayName();
}
bool GroupRosterItem::itemLessThanWithStatus(const RosterItem* left, const RosterItem* right) {
- const ContactRosterItem* leftContact = dynamic_cast<const ContactRosterItem*>(left);
- const ContactRosterItem* rightContact = dynamic_cast<const ContactRosterItem*>(right);
- if (leftContact) {
- if (!rightContact) {
- return false;
- }
- StatusShow::Type leftType = leftContact->getSimplifiedStatusShow();
- StatusShow::Type rightType = rightContact->getSimplifiedStatusShow();
- if (leftType == rightType) {
- return left->getSortableDisplayName() < right->getSortableDisplayName();
- } else {
- return leftType < rightType;
- }
- } else {
- if (rightContact) {
- return true;
- }
- return left->getSortableDisplayName() < right->getSortableDisplayName();
- }
+ const ContactRosterItem* leftContact = dynamic_cast<const ContactRosterItem*>(left);
+ const ContactRosterItem* rightContact = dynamic_cast<const ContactRosterItem*>(right);
+ if (leftContact) {
+ if (!rightContact) {
+ return false;
+ }
+ StatusShow::Type leftType = leftContact->getSimplifiedStatusShow();
+ StatusShow::Type rightType = rightContact->getSimplifiedStatusShow();
+ if (leftType == rightType) {
+ return left->getSortableDisplayName() < right->getSortableDisplayName();
+ } else {
+ return leftType < rightType;
+ }
+ } else {
+ if (rightContact) {
+ return true;
+ }
+ return left->getSortableDisplayName() < right->getSortableDisplayName();
+ }
}
void GroupRosterItem::setDisplayed(RosterItem* item, bool displayed) {
- bool found = false;
- for (size_t i = 0; i < displayedChildren_.size(); i++) {
- if (displayedChildren_[i] == item) {
- found = true;
- }
- }
- if (found == displayed) {
- return;
- }
- if (displayed) {
- displayedChildren_.push_back(item);
- sortDisplayed();
- } else {
- displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), item), displayedChildren_.end());
- }
- onChildrenChanged();
- onDataChanged();
+ bool found = false;
+ for (auto& i : displayedChildren_) {
+ if (i == item) {
+ found = true;
+ }
+ }
+ if (found == displayed) {
+ return;
+ }
+ if (displayed) {
+ displayedChildren_.push_back(item);
+ sortDisplayed();
+ } else {
+ displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), item), displayedChildren_.end());
+ }
+ onChildrenChanged();
+ onDataChanged();
}
void GroupRosterItem::handleDataChanged(RosterItem* /*item*/) {
- if (sortDisplayed()) {
- onChildrenChanged();
- }
+ if (sortDisplayed()) {
+ onChildrenChanged();
+ }
}
void GroupRosterItem::handleChildrenChanged(GroupRosterItem* group) {
- size_t oldSize = getDisplayedChildren().size();
- if (group->getDisplayedChildren().size() > 0) {
- bool found = false;
- for (size_t i = 0; i < displayedChildren_.size(); i++) {
- if (displayedChildren_[i] == group) {
- found = true;
- }
- }
- if (!found) {
- displayedChildren_.push_back(group);
- sortDisplayed();
- }
- } else {
- displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), group), displayedChildren_.end());
- }
-
- if (oldSize != getDisplayedChildren().size() || sortDisplayed()) {
- onChildrenChanged();
- onDataChanged();
- }
+ size_t oldSize = getDisplayedChildren().size();
+ if (group->getDisplayedChildren().size() > 0) {
+ bool found = false;
+ for (auto& i : displayedChildren_) {
+ if (i == group) {
+ found = true;
+ }
+ }
+ if (!found) {
+ displayedChildren_.push_back(group);
+ sortDisplayed();
+ }
+ } else {
+ displayedChildren_.erase(std::remove(displayedChildren_.begin(), displayedChildren_.end(), group), displayedChildren_.end());
+ }
+
+ if (oldSize != getDisplayedChildren().size() || sortDisplayed()) {
+ onChildrenChanged();
+ onDataChanged();
+ }
}
diff --git a/Swift/Controllers/Roster/GroupRosterItem.h b/Swift/Controllers/Roster/GroupRosterItem.h
index 90ba471..a4e008f 100644
--- a/Swift/Controllers/Roster/GroupRosterItem.h
+++ b/Swift/Controllers/Roster/GroupRosterItem.h
@@ -1,49 +1,49 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/Roster/RosterItem.h"
#include <string>
-#include "Swift/Controllers/Roster/ContactRosterItem.h"
-
#include <vector>
+#include <Swift/Controllers/Roster/ContactRosterItem.h>
+#include <Swift/Controllers/Roster/RosterItem.h>
+
namespace Swift {
class GroupRosterItem : public RosterItem {
- public:
- GroupRosterItem(const std::string& name, GroupRosterItem* parent, bool sortByStatus);
- virtual ~GroupRosterItem();
- const std::vector<RosterItem*>& getChildren() const;
- const std::vector<RosterItem*>& getDisplayedChildren() const;
- void addChild(RosterItem* item);
- ContactRosterItem* removeChild(const JID& jid);
- GroupRosterItem* removeGroupChild(const std::string& group);
- void removeAll();
- void setDisplayed(RosterItem* item, bool displayed);
- boost::signal<void ()> onChildrenChanged;
- static bool itemLessThanWithStatus(const RosterItem* left, const RosterItem* right);
- static bool itemLessThanWithoutStatus(const RosterItem* left, const RosterItem* right);
- void setExpanded(bool expanded);
- bool isExpanded() const;
- boost::signal<void (bool)> onExpandedChanged;
- void setManualSort(const std::string& manualSortValue);
- virtual const std::string& getSortableDisplayName() const;
- private:
- void handleChildrenChanged(GroupRosterItem* group);
- void handleDataChanged(RosterItem* item);
- bool sortDisplayed();
- std::string name_;
- bool expanded_;
- std::vector<RosterItem*> children_;
- std::vector<RosterItem*> displayedChildren_;
- bool sortByStatus_;
- bool manualSort_;
- std::string manualSortValue_;
+ public:
+ GroupRosterItem(const std::string& name, GroupRosterItem* parent, bool sortByStatus);
+ virtual ~GroupRosterItem();
+ const std::vector<RosterItem*>& getChildren() const;
+ const std::vector<RosterItem*>& getDisplayedChildren() const;
+ void addChild(RosterItem* item);
+ ContactRosterItem* removeChild(const JID& jid);
+ GroupRosterItem* removeGroupChild(const std::string& group);
+ void removeAll();
+ void setDisplayed(RosterItem* item, bool displayed);
+ boost::signals2::signal<void ()> onChildrenChanged;
+ static bool itemLessThanWithStatus(const RosterItem* left, const RosterItem* right);
+ static bool itemLessThanWithoutStatus(const RosterItem* left, const RosterItem* right);
+ void setExpanded(bool expanded);
+ bool isExpanded() const;
+ boost::signals2::signal<void (bool)> onExpandedChanged;
+ void setManualSort(const std::string& manualSortValue);
+ virtual const std::string& getSortableDisplayName() const;
+ private:
+ void handleChildrenChanged(GroupRosterItem* group);
+ void handleDataChanged(RosterItem* item);
+ bool sortDisplayed();
+ std::string name_;
+ bool expanded_;
+ std::vector<RosterItem*> children_;
+ std::vector<RosterItem*> displayedChildren_;
+ bool sortByStatus_;
+ bool manualSort_;
+ std::string manualSortValue_;
};
}
diff --git a/Swift/Controllers/Roster/ItemOperations/AppearOffline.h b/Swift/Controllers/Roster/ItemOperations/AppearOffline.h
index 6438a8e..c57974b 100644
--- a/Swift/Controllers/Roster/ItemOperations/AppearOffline.h
+++ b/Swift/Controllers/Roster/ItemOperations/AppearOffline.h
@@ -1,29 +1,29 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
+#include <Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h>
namespace Swift {
class RosterItem;
class AppearOffline : public RosterItemOperation {
- public:
- AppearOffline() {
- }
-
- virtual void operator() (RosterItem* item) const {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- if (contact) {
- contact->clearPresence();
- }
- }
+ public:
+ AppearOffline() {
+ }
+
+ virtual void operator() (RosterItem* item) const {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (contact) {
+ contact->clearPresence();
+ }
+ }
};
diff --git a/Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h b/Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h
index da81d2b..c633c20 100644
--- a/Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h
+++ b/Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h
@@ -1,30 +1,32 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/Roster/RosterItem.h"
+#include <Swiften/JID/JID.h>
+
+#include <Swift/Controllers/Roster/RosterItem.h>
namespace Swift {
class RosterItemOperation {
- public:
- RosterItemOperation(bool requiresLookup = false, const JID& lookupJID = JID()) : requiresLookup_(requiresLookup), lookupJID_(lookupJID) {}
- virtual ~RosterItemOperation() {}
- bool requiresLookup() const {return requiresLookup_;}
- const JID& lookupJID() const {return lookupJID_;}
- /**
- * This is called when iterating over possible subjects, so must check it's
- * applying to the right items - even if requiresLookup() is true an item
- * with the same bare JID but different full JID may be passed.
- */
- virtual void operator() (RosterItem*) const = 0;
- private:
- bool requiresLookup_;
- JID lookupJID_;
+ public:
+ RosterItemOperation(bool requiresLookup = false, const JID& lookupJID = JID()) : requiresLookup_(requiresLookup), lookupJID_(lookupJID) {}
+ virtual ~RosterItemOperation() {}
+ bool requiresLookup() const {return requiresLookup_;}
+ const JID& lookupJID() const {return lookupJID_;}
+ /**
+ * This is called when iterating over possible subjects, so must check it's
+ * applying to the right items - even if requiresLookup() is true an item
+ * with the same bare JID but different full JID may be passed.
+ */
+ virtual void operator() (RosterItem*) const = 0;
+ private:
+ bool requiresLookup_;
+ JID lookupJID_;
};
}
diff --git a/Swift/Controllers/Roster/ItemOperations/SetAvailableFeatures.h b/Swift/Controllers/Roster/ItemOperations/SetAvailableFeatures.h
index 620a1ae..29f9722 100644
--- a/Swift/Controllers/Roster/ItemOperations/SetAvailableFeatures.h
+++ b/Swift/Controllers/Roster/ItemOperations/SetAvailableFeatures.h
@@ -4,33 +4,39 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <Swiften/JID/JID.h>
-#include <Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
+#include <Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h>
namespace Swift {
class RosterItem;
class SetAvailableFeatures : public RosterItemOperation {
- public:
- SetAvailableFeatures(const JID& jid, const std::set<ContactRosterItem::Feature>& availableFeatures, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), jid_(jid), availableFeatures_(availableFeatures), compareType_(compareType) {
- }
-
- virtual void operator() (RosterItem* item) const {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- if (contact && contact->getJID().equals(jid_, compareType_)) {
- contact->setSupportedFeatures(availableFeatures_);
- }
- }
-
- private:
- JID jid_;
- std::set<ContactRosterItem::Feature> availableFeatures_;
- JID::CompareType compareType_;
+ public:
+ SetAvailableFeatures(const JID& jid, const std::set<ContactRosterItem::Feature>& availableFeatures, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), jid_(jid), availableFeatures_(availableFeatures), compareType_(compareType) {
+ }
+
+ virtual void operator() (RosterItem* item) const {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (contact && contact->getJID().equals(jid_, compareType_)) {
+ contact->setSupportedFeatures(availableFeatures_);
+ }
+ }
+
+ private:
+ JID jid_;
+ std::set<ContactRosterItem::Feature> availableFeatures_;
+ JID::CompareType compareType_;
};
}
diff --git a/Swift/Controllers/Roster/ItemOperations/SetAvatar.h b/Swift/Controllers/Roster/ItemOperations/SetAvatar.h
index 910a651..d47c921 100644
--- a/Swift/Controllers/Roster/ItemOperations/SetAvatar.h
+++ b/Swift/Controllers/Roster/ItemOperations/SetAvatar.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2013 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -11,29 +11,29 @@
#include <Swiften/Elements/Presence.h>
#include <Swiften/JID/JID.h>
-#include <Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
+#include <Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h>
namespace Swift {
class RosterItem;
class SetAvatar : public RosterItemOperation {
- public:
- SetAvatar(const JID& jid, const boost::filesystem::path& path, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), jid_(jid), path_(path), compareType_(compareType) {
- }
-
- virtual void operator() (RosterItem* item) const {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- if (contact && contact->getJID().equals(jid_, compareType_)) {
- contact->setAvatarPath(path_);
- }
- }
-
- private:
- JID jid_;
- boost::filesystem::path path_;
- JID::CompareType compareType_;
+ public:
+ SetAvatar(const JID& jid, const boost::filesystem::path& path, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), jid_(jid), path_(path), compareType_(compareType) {
+ }
+
+ virtual void operator() (RosterItem* item) const {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (contact && contact->getJID().equals(jid_, compareType_)) {
+ contact->setAvatarPath(path_);
+ }
+ }
+
+ private:
+ JID jid_;
+ boost::filesystem::path path_;
+ JID::CompareType compareType_;
};
}
diff --git a/Swift/Controllers/Roster/ItemOperations/SetBlockingState.h b/Swift/Controllers/Roster/ItemOperations/SetBlockingState.h
index ddb2c7a..818d9b4 100644
--- a/Swift/Controllers/Roster/ItemOperations/SetBlockingState.h
+++ b/Swift/Controllers/Roster/ItemOperations/SetBlockingState.h
@@ -4,42 +4,48 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <Swiften/JID/JID.h>
-#include <Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
+#include <Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h>
namespace Swift {
class RosterItem;
class SetBlockingState : public RosterItemOperation {
- public:
- SetBlockingState(const JID& jid, ContactRosterItem::BlockState state, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(!jid.getNode().empty(), jid), jid_(jid), state_(state), compareType_(compareType) {
- if (state_ == ContactRosterItem::IsBlocked && jid.getNode().empty()) {
- state_ = ContactRosterItem::IsDomainBlocked;
- }
- }
-
- virtual void operator() (RosterItem* item) const {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- if (jid_.getNode().empty()) {
- if (contact && contact->getJID().getDomain() == jid_.getDomain()) {
- contact->setBlockState(state_);
- }
- } else {
- if (contact && contact->getJID().equals(jid_, compareType_)) {
- contact->setBlockState(state_);
- }
- }
- }
-
- private:
- JID jid_;
- ContactRosterItem::BlockState state_;
- JID::CompareType compareType_;
+ public:
+ SetBlockingState(const JID& jid, ContactRosterItem::BlockState state, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(!jid.getNode().empty(), jid), jid_(jid), state_(state), compareType_(compareType) {
+ if (state_ == ContactRosterItem::IsBlocked && jid.getNode().empty()) {
+ state_ = ContactRosterItem::IsDomainBlocked;
+ }
+ }
+
+ virtual void operator() (RosterItem* item) const {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (jid_.getNode().empty()) {
+ if (contact && contact->getJID().getDomain() == jid_.getDomain()) {
+ contact->setBlockState(state_);
+ }
+ } else {
+ if (contact && contact->getJID().equals(jid_, compareType_)) {
+ contact->setBlockState(state_);
+ }
+ }
+ }
+
+ private:
+ JID jid_;
+ ContactRosterItem::BlockState state_;
+ JID::CompareType compareType_;
};
}
diff --git a/Swift/Controllers/Roster/ItemOperations/SetMUC.h b/Swift/Controllers/Roster/ItemOperations/SetMUC.h
index 5919144..7640c24 100644
--- a/Swift/Controllers/Roster/ItemOperations/SetMUC.h
+++ b/Swift/Controllers/Roster/ItemOperations/SetMUC.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2014 Isode Limited.
+ * Copyright (c) 2013-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,31 +8,31 @@
#include <Swiften/JID/JID.h>
-#include <Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
+#include <Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h>
namespace Swift {
class RosterItem;
class SetMUC : public RosterItemOperation {
- public:
- SetMUC(const JID& jid, const MUCOccupant::Role& role, const MUCOccupant::Affiliation& affiliation)
- : RosterItemOperation(true, jid), jid_(jid), mucRole_(role), mucAffiliation_(affiliation) {
- }
-
- virtual void operator() (RosterItem* item) const {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- if (contact && contact->getJID().equals(jid_, JID::WithResource)) {
- contact->setMUCRole(mucRole_);
- contact->setMUCAffiliation(mucAffiliation_);
- }
- }
-
- private:
- JID jid_;
- MUCOccupant::Role mucRole_;
- MUCOccupant::Affiliation mucAffiliation_;
+ public:
+ SetMUC(const JID& jid, const MUCOccupant::Role& role, const MUCOccupant::Affiliation& affiliation)
+ : RosterItemOperation(true, jid), jid_(jid), mucRole_(role), mucAffiliation_(affiliation) {
+ }
+
+ virtual void operator() (RosterItem* item) const {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (contact && contact->getJID().equals(jid_, JID::WithResource)) {
+ contact->setMUCRole(mucRole_);
+ contact->setMUCAffiliation(mucAffiliation_);
+ }
+ }
+
+ private:
+ JID jid_;
+ MUCOccupant::Role mucRole_;
+ MUCOccupant::Affiliation mucAffiliation_;
};
}
diff --git a/Swift/Controllers/Roster/ItemOperations/SetName.h b/Swift/Controllers/Roster/ItemOperations/SetName.h
index 5708740..fa0694d 100644
--- a/Swift/Controllers/Roster/ItemOperations/SetName.h
+++ b/Swift/Controllers/Roster/ItemOperations/SetName.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,29 +8,29 @@
#include <Swiften/JID/JID.h>
-#include <Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
+#include <Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h>
namespace Swift {
class RosterItem;
class SetName : public RosterItemOperation {
- public:
- SetName(const std::string& name, const JID& jid, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), name_(name), jid_(jid), compareType_(compareType) {
- }
-
- virtual void operator() (RosterItem* item) const {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- if (contact && contact->getJID().equals(jid_, compareType_)) {
- contact->setDisplayName(name_);
- }
- }
-
- private:
- std::string name_;
- JID jid_;
- JID::CompareType compareType_;
+ public:
+ SetName(const std::string& name, const JID& jid, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), name_(name), jid_(jid), compareType_(compareType) {
+ }
+
+ virtual void operator() (RosterItem* item) const {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (contact && contact->getJID().equals(jid_, compareType_)) {
+ contact->setDisplayName(name_);
+ }
+ }
+
+ private:
+ std::string name_;
+ JID jid_;
+ JID::CompareType compareType_;
};
}
diff --git a/Swift/Controllers/Roster/ItemOperations/SetPresence.h b/Swift/Controllers/Roster/ItemOperations/SetPresence.h
index 2b5bbbe..fc39e5c 100644
--- a/Swift/Controllers/Roster/ItemOperations/SetPresence.h
+++ b/Swift/Controllers/Roster/ItemOperations/SetPresence.h
@@ -17,20 +17,20 @@ namespace Swift {
class RosterItem;
class SetPresence : public RosterItemOperation {
- public:
- SetPresence(Presence::ref presence, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, compareType == JID::WithoutResource ? presence->getFrom().toBare() : presence->getFrom()), presence_(presence), compareType_(compareType) {
- }
-
- virtual void operator() (RosterItem* item) const {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- if (contact && contact->getJID().equals(presence_->getFrom(), compareType_)) {
- contact->applyPresence(presence_);
- }
- }
-
- private:
- Presence::ref presence_;
- JID::CompareType compareType_;
+ public:
+ SetPresence(Presence::ref presence, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, compareType == JID::WithoutResource ? presence->getFrom().toBare() : presence->getFrom()), presence_(presence), compareType_(compareType) {
+ }
+
+ virtual void operator() (RosterItem* item) const {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (contact && contact->getJID().equals(presence_->getFrom(), compareType_)) {
+ contact->applyPresence(presence_);
+ }
+ }
+
+ private:
+ Presence::ref presence_;
+ JID::CompareType compareType_;
};
}
diff --git a/Swift/Controllers/Roster/ItemOperations/SetVCard.h b/Swift/Controllers/Roster/ItemOperations/SetVCard.h
index 8ee73f9..278ae56 100644
--- a/Swift/Controllers/Roster/ItemOperations/SetVCard.h
+++ b/Swift/Controllers/Roster/ItemOperations/SetVCard.h
@@ -4,34 +4,40 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <Swiften/Elements/VCard.h>
#include <Swiften/JID/JID.h>
-#include <Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
+#include <Swift/Controllers/Roster/ItemOperations/RosterItemOperation.h>
namespace Swift {
class RosterItem;
class SetVCard : public RosterItemOperation {
- public:
- SetVCard(const JID& jid, VCard::ref vcard, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), jid_(jid), vcard_(vcard), compareType_(compareType) {
- }
-
- virtual void operator() (RosterItem* item) const {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- if (contact && contact->getJID().equals(jid_, compareType_)) {
- contact->setVCard(vcard_);
- }
- }
-
- private:
- JID jid_;
- VCard::ref vcard_;
- JID::CompareType compareType_;
+ public:
+ SetVCard(const JID& jid, VCard::ref vcard, JID::CompareType compareType = JID::WithoutResource) : RosterItemOperation(true, jid), jid_(jid), vcard_(vcard), compareType_(compareType) {
+ }
+
+ virtual void operator() (RosterItem* item) const {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (contact && contact->getJID().equals(jid_, compareType_)) {
+ contact->setVCard(vcard_);
+ }
+ }
+
+ private:
+ JID jid_;
+ VCard::ref vcard_;
+ JID::CompareType compareType_;
};
}
diff --git a/Swift/Controllers/Roster/LeastCommonSubsequence.h b/Swift/Controllers/Roster/LeastCommonSubsequence.h
index 0b5aa0a..8daa20c 100644
--- a/Swift/Controllers/Roster/LeastCommonSubsequence.h
+++ b/Swift/Controllers/Roster/LeastCommonSubsequence.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2013 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,101 +7,102 @@
#pragma once
#include <vector>
+
#include <boost/numeric/conversion/cast.hpp>
namespace Swift {
- using std::equal_to;
+ using std::equal_to;
- namespace Detail {
- template<typename XIt, typename YIt, typename Length, typename Predicate>
- void computeLeastCommonSubsequenceMatrix(XIt xBegin, XIt xEnd, YIt yBegin, YIt yEnd, std::vector<Length>& result) {
- size_t width = static_cast<size_t>(std::distance(xBegin, xEnd) + 1);
- size_t height = static_cast<size_t>(std::distance(yBegin, yEnd) + 1);
- result.resize(width * height);
+ namespace Detail {
+ template<typename XIt, typename YIt, typename Length, typename Predicate>
+ void computeLeastCommonSubsequenceMatrix(XIt xBegin, XIt xEnd, YIt yBegin, YIt yEnd, std::vector<Length>& result) {
+ size_t width = static_cast<size_t>(std::distance(xBegin, xEnd) + 1);
+ size_t height = static_cast<size_t>(std::distance(yBegin, yEnd) + 1);
+ result.resize(width * height);
- // Initialize first row & column
- for (size_t i = 0; i < width; ++i) {
- result[i] = 0;
- }
- for (size_t j = 0; j < height; ++j) {
- result[j*width] = 0;
- }
+ // Initialize first row & column
+ for (size_t i = 0; i < width; ++i) {
+ result[i] = 0;
+ }
+ for (size_t j = 0; j < height; ++j) {
+ result[j*width] = 0;
+ }
- // Compute the LCS lengths for subsets
- Predicate predicate;
- for (size_t i = 1; i < width; ++i) {
- for (size_t j = 1; j < height; ++j) {
- result[i + j*width] = predicate(*(xBegin + boost::numeric_cast<long long>(i)-1), *(yBegin + boost::numeric_cast<long long >(j)-1)) ? result[(i-1) + (j-1)*width] + 1 : std::max(result[i + (j-1)*width], result[i-1 + (j*width)]);
- }
- }
- }
- }
+ // Compute the LCS lengths for subsets
+ Predicate predicate;
+ for (size_t i = 1; i < width; ++i) {
+ for (size_t j = 1; j < height; ++j) {
+ result[i + j*width] = predicate(*(xBegin + boost::numeric_cast<long long>(i)-1), *(yBegin + boost::numeric_cast<long long >(j)-1)) ? result[(i-1) + (j-1)*width] + 1 : std::max(result[i + (j-1)*width], result[i-1 + (j*width)]);
+ }
+ }
+ }
+ }
- template<typename X, typename InsertRemovePredicate, typename UpdatePredicate>
- void computeIndexDiff(const std::vector<X>& x, const std::vector<X>& y, std::vector<size_t>& updates, std::vector<size_t>& postUpdates, std::vector<size_t>& removes, std::vector<size_t>& inserts) {
- InsertRemovePredicate insertRemovePredicate;
- UpdatePredicate updatePredicate;
+ template<typename X, typename InsertRemovePredicate, typename UpdatePredicate>
+ void computeIndexDiff(const std::vector<X>& x, const std::vector<X>& y, std::vector<size_t>& updates, std::vector<size_t>& postUpdates, std::vector<size_t>& removes, std::vector<size_t>& inserts) {
+ InsertRemovePredicate insertRemovePredicate;
+ UpdatePredicate updatePredicate;
- // Find & handle common prefix (Optimization to reduce LCS matrix size)
- typename std::vector<X>::const_iterator xBegin = x.begin();
- typename std::vector<X>::const_iterator yBegin = y.begin();
- while (xBegin < x.end() && yBegin < y.end() && insertRemovePredicate(*xBegin, *yBegin)) {
- if (updatePredicate(*xBegin, *yBegin)) {
- updates.push_back(static_cast<size_t>(std::distance(x.begin(), xBegin)));
- postUpdates.push_back(static_cast<size_t>(std::distance(y.begin(), yBegin)));
- }
- ++xBegin;
- ++yBegin;
- }
- size_t prefixLength = static_cast<size_t>(std::distance(x.begin(), xBegin));
+ // Find & handle common prefix (Optimization to reduce LCS matrix size)
+ typename std::vector<X>::const_iterator xBegin = x.begin();
+ typename std::vector<X>::const_iterator yBegin = y.begin();
+ while (xBegin < x.end() && yBegin < y.end() && insertRemovePredicate(*xBegin, *yBegin)) {
+ if (updatePredicate(*xBegin, *yBegin)) {
+ updates.push_back(static_cast<size_t>(std::distance(x.begin(), xBegin)));
+ postUpdates.push_back(static_cast<size_t>(std::distance(y.begin(), yBegin)));
+ }
+ ++xBegin;
+ ++yBegin;
+ }
+ size_t prefixLength = static_cast<size_t>(std::distance(x.begin(), xBegin));
- // Find & handle common suffix (Optimization to reduce LCS matrix size)
- typename std::vector<X>::const_reverse_iterator xEnd = x.rbegin();
- typename std::vector<X>::const_reverse_iterator yEnd = y.rbegin();
- while (xEnd.base() > xBegin && yEnd.base() > yBegin && insertRemovePredicate(*xEnd, *yEnd)) {
- if (updatePredicate(*xEnd, *yEnd)) {
- updates.push_back(static_cast<size_t>(std::distance(x.begin(), xEnd.base()) - 1));
- postUpdates.push_back(static_cast<size_t>(std::distance(y.begin(), yEnd.base()) - 1));
- }
- ++xEnd;
- ++yEnd;
- }
+ // Find & handle common suffix (Optimization to reduce LCS matrix size)
+ typename std::vector<X>::const_reverse_iterator xEnd = x.rbegin();
+ typename std::vector<X>::const_reverse_iterator yEnd = y.rbegin();
+ while (xEnd.base() > xBegin && yEnd.base() > yBegin && insertRemovePredicate(*xEnd, *yEnd)) {
+ if (updatePredicate(*xEnd, *yEnd)) {
+ updates.push_back(static_cast<size_t>(std::distance(x.begin(), xEnd.base()) - 1));
+ postUpdates.push_back(static_cast<size_t>(std::distance(y.begin(), yEnd.base()) - 1));
+ }
+ ++xEnd;
+ ++yEnd;
+ }
- // Compute lengths
- size_t xLength = static_cast<size_t>(std::distance(xBegin, xEnd.base()));
- size_t yLength = static_cast<size_t>(std::distance(yBegin, yEnd.base()));
+ // Compute lengths
+ size_t xLength = static_cast<size_t>(std::distance(xBegin, xEnd.base()));
+ size_t yLength = static_cast<size_t>(std::distance(yBegin, yEnd.base()));
- // Compute LCS matrix
- std::vector<unsigned int> lcs;
- Detail::computeLeastCommonSubsequenceMatrix<typename std::vector<X>::const_iterator, typename std::vector<X>::const_iterator, unsigned int, InsertRemovePredicate>(xBegin, xEnd.base(), yBegin, yEnd.base(), lcs);
+ // Compute LCS matrix
+ std::vector<unsigned int> lcs;
+ Detail::computeLeastCommonSubsequenceMatrix<typename std::vector<X>::const_iterator, typename std::vector<X>::const_iterator, unsigned int, InsertRemovePredicate>(xBegin, xEnd.base(), yBegin, yEnd.base(), lcs);
- // Process LCS matrix
- size_t i = xLength;
- size_t j = yLength;
- size_t width = xLength + 1;
- while (true) {
- if (i > 0 && j > 0 && insertRemovePredicate(x[prefixLength + i-1], y[prefixLength + j-1])) {
- // x[i-1] same
- if (updatePredicate(x[prefixLength + i - 1], y[prefixLength + j - 1])) {
- updates.push_back(prefixLength + i-1);
- postUpdates.push_back(prefixLength + j-1);
- }
- i -= 1;
- j -= 1;
- }
- else if (j > 0 && (i == 0 || lcs[i + (j-1)*width] >= lcs[i-1 + j*width])) {
- // y[j-1] added
- inserts.push_back(prefixLength + j-1);
- j -= 1;
- }
- else if (i > 0 && (j == 0 || lcs[i + (j-1)*width] < lcs[i-1 + j*width])) {
- // x[i-1] removed
- removes.push_back(prefixLength + i-1);
- i -= 1;
- }
- else {
- break;
- }
- }
- }
+ // Process LCS matrix
+ size_t i = xLength;
+ size_t j = yLength;
+ size_t width = xLength + 1;
+ while (true) {
+ if (i > 0 && j > 0 && insertRemovePredicate(x[prefixLength + i-1], y[prefixLength + j-1])) {
+ // x[i-1] same
+ if (updatePredicate(x[prefixLength + i - 1], y[prefixLength + j - 1])) {
+ updates.push_back(prefixLength + i-1);
+ postUpdates.push_back(prefixLength + j-1);
+ }
+ i -= 1;
+ j -= 1;
+ }
+ else if (j > 0 && (i == 0 || lcs[i + (j-1)*width] >= lcs[i-1 + j*width])) {
+ // y[j-1] added
+ inserts.push_back(prefixLength + j-1);
+ j -= 1;
+ }
+ else if (i > 0 && (j == 0 || lcs[i + (j-1)*width] < lcs[i-1 + j*width])) {
+ // x[i-1] removed
+ removes.push_back(prefixLength + i-1);
+ i -= 1;
+ }
+ else {
+ break;
+ }
+ }
+ }
}
diff --git a/Swift/Controllers/Roster/OfflineRosterFilter.h b/Swift/Controllers/Roster/OfflineRosterFilter.h
index 61ac3f4..033eecb 100644
--- a/Swift/Controllers/Roster/OfflineRosterFilter.h
+++ b/Swift/Controllers/Roster/OfflineRosterFilter.h
@@ -1,25 +1,26 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/Roster/ContactRosterItem.h"
-#include "Swift/Controllers/Roster/RosterItem.h"
-#include "Swift/Controllers/Roster/RosterFilter.h"
-#include "Swiften/Elements/StatusShow.h"
+#include <Swiften/Elements/StatusShow.h>
+
+#include <Swift/Controllers/Roster/ContactRosterItem.h>
+#include <Swift/Controllers/Roster/RosterFilter.h>
+#include <Swift/Controllers/Roster/RosterItem.h>
namespace Swift {
class OfflineRosterFilter : public RosterFilter {
- public:
- virtual ~OfflineRosterFilter() {}
- virtual bool operator() (RosterItem *item) const {
- ContactRosterItem *contactItem = dynamic_cast<ContactRosterItem*>(item);
- return contactItem && contactItem->getStatusShow() == StatusShow::None;
- }
+ public:
+ virtual ~OfflineRosterFilter() {}
+ virtual bool operator() (RosterItem *item) const {
+ ContactRosterItem *contactItem = dynamic_cast<ContactRosterItem*>(item);
+ return contactItem && contactItem->getStatusShow() == StatusShow::None;
+ }
};
}
diff --git a/Swift/Controllers/Roster/Roster.cpp b/Swift/Controllers/Roster/Roster.cpp
index 77d6b78..68297a4 100644
--- a/Swift/Controllers/Roster/Roster.cpp
+++ b/Swift/Controllers/Roster/Roster.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,12 +7,12 @@
#include <Swift/Controllers/Roster/Roster.h>
#include <deque>
+#include <memory>
#include <set>
#include <string>
#include <boost/bind.hpp>
-#include <Swiften/Base/foreach.h>
#include <Swiften/JID/JID.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
@@ -22,253 +22,250 @@
namespace Swift {
-Roster::Roster(bool sortByStatus, bool fullJIDMapping) : blockingSupported_(false) {
- sortByStatus_ = sortByStatus;
- fullJIDMapping_ = fullJIDMapping;
- root_ = new GroupRosterItem("Dummy-Root", NULL, sortByStatus_);
- root_->onChildrenChanged.connect(boost::bind(&Roster::handleChildrenChanged, this, root_));
+Roster::Roster(bool sortByStatus, bool fullJIDMapping) : fullJIDMapping_(fullJIDMapping), sortByStatus_(sortByStatus), root_(std::unique_ptr<GroupRosterItem>(new GroupRosterItem("Dummy-Root", nullptr, sortByStatus_))) {
+ root_->onChildrenChanged.connect(boost::bind(&Roster::handleChildrenChanged, this, root_.get()));
}
Roster::~Roster() {
- std::deque<RosterItem*> queue;
- queue.push_back(root_);
- while (!queue.empty()) {
- RosterItem* item = *queue.begin();
- queue.pop_front();
- GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
- if (group) {
- queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end());
- }
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- if (contact) {
- contact->onVCardRequested.disconnect(boost::bind(boost::ref(onVCardUpdateRequested), contact->getJID()));
- }
- delete item;
- }
+ std::deque<RosterItem*> queue;
+ while (!queue.empty()) {
+ RosterItem* item = *queue.begin();
+ queue.pop_front();
+ GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
+ if (group) {
+ queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end());
+ }
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (contact) {
+ contact->onVCardRequested.disconnect(boost::bind(boost::ref(onVCardUpdateRequested), contact->getJID()));
+ }
+ delete item;
+ }
}
GroupRosterItem* Roster::getRoot() const {
- return root_;
+ return root_.get();
}
std::set<JID> Roster::getJIDs() const {
- std::set<JID> jids;
-
- std::deque<RosterItem*> queue;
- queue.push_back(root_);
- while (!queue.empty()) {
- RosterItem* item = *queue.begin();
- queue.pop_front();
- GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
- ContactRosterItem *contact = dynamic_cast<ContactRosterItem*>(item);
- if (contact) {
- jids.insert(contact->getJID());
- jids.insert(contact->getDisplayJID());
- }
- else if (group) {
- queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end());
- }
- }
-
- return jids;
+ std::set<JID> jids;
+
+ std::deque<RosterItem*> queue;
+ queue.push_back(root_.get());
+ while (!queue.empty()) {
+ RosterItem* item = *queue.begin();
+ queue.pop_front();
+ GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
+ ContactRosterItem *contact = dynamic_cast<ContactRosterItem*>(item);
+ if (contact) {
+ jids.insert(contact->getJID());
+ jids.insert(contact->getDisplayJID());
+ }
+ else if (group) {
+ queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end());
+ }
+ }
+
+ return jids;
}
GroupRosterItem* Roster::getGroup(const std::string& groupName) {
- foreach (RosterItem *item, root_->getChildren()) {
- GroupRosterItem *group = dynamic_cast<GroupRosterItem*>(item);
- if (group && group->getDisplayName() == groupName) {
- return group;
- }
- }
- GroupRosterItem* group = new GroupRosterItem(groupName, root_, sortByStatus_);
- root_->addChild(group);
- group->onChildrenChanged.connect(boost::bind(&Roster::handleChildrenChanged, this, group));
- group->onDataChanged.connect(boost::bind(&Roster::handleDataChanged, this, group));
- return group;
+ for (auto* item : root_->getChildren()) {
+ GroupRosterItem *group = dynamic_cast<GroupRosterItem*>(item);
+ if (group && group->getDisplayName() == groupName) {
+ return group;
+ }
+ }
+ GroupRosterItem* group = new GroupRosterItem(groupName, root_.get(), sortByStatus_);
+ root_->addChild(group);
+ group->onChildrenChanged.connect(boost::bind(&Roster::handleChildrenChanged, this, group));
+ group->onDataChanged.connect(boost::bind(&Roster::handleDataChanged, this, group));
+ return group;
}
void Roster::setBlockingSupported(bool isSupported) {
- if (!blockingSupported_) {
- foreach(ItemMap::value_type i, itemMap_) {
- foreach(ContactRosterItem* item, i.second) {
- item->setBlockState(ContactRosterItem::IsUnblocked);
- }
- }
- }
- blockingSupported_ = isSupported;
+ if (!blockingSupported_) {
+ for (auto i : itemMap_) {
+ for (auto* item : i.second) {
+ item->setBlockState(ContactRosterItem::IsUnblocked);
+ }
+ }
+ }
+ blockingSupported_ = isSupported;
}
void Roster::removeGroup(const std::string& group) {
- root_->removeGroupChild(group);
+ root_->removeGroupChild(group);
}
void Roster::handleDataChanged(RosterItem* item) {
- onDataChanged(item);
+ onDataChanged(item);
}
void Roster::handleChildrenChanged(GroupRosterItem* item) {
- onChildrenChanged(item);
+ onChildrenChanged(item);
}
void Roster::addContact(const JID& jid, const JID& displayJID, const std::string& name, const std::string& groupName, const boost::filesystem::path& avatarPath) {
- GroupRosterItem* group(getGroup(groupName));
- ContactRosterItem *item = new ContactRosterItem(jid, displayJID, name, group);
- item->onVCardRequested.connect(boost::bind(boost::ref(onVCardUpdateRequested), jid));
- item->setAvatarPath(avatarPath);
- if (blockingSupported_) {
- item->setBlockState(ContactRosterItem::IsUnblocked);
- }
- group->addChild(item);
- ItemMap::iterator i = itemMap_.insert(std::make_pair(fullJIDMapping_ ? jid : jid.toBare(), std::vector<ContactRosterItem*>())).first;
- if (!i->second.empty()) {
- foreach (const std::string& existingGroup, i->second[0]->getGroups()) {
- item->addGroup(existingGroup);
- }
- }
- i->second.push_back(item);
- item->onDataChanged.connect(boost::bind(&Roster::handleDataChanged, this, item));
- filterContact(item, group);
-
- foreach (ContactRosterItem* item, i->second) {
- item->addGroup(groupName);
- }
+ GroupRosterItem* group(getGroup(groupName));
+ ContactRosterItem *item = new ContactRosterItem(jid, displayJID, name, group);
+ item->onVCardRequested.connect(boost::bind(boost::ref(onVCardUpdateRequested), jid));
+ item->setAvatarPath(avatarPath);
+ if (blockingSupported_) {
+ item->setBlockState(ContactRosterItem::IsUnblocked);
+ }
+ group->addChild(item);
+ ItemMap::iterator i = itemMap_.insert(std::make_pair(fullJIDMapping_ ? jid : jid.toBare(), std::vector<ContactRosterItem*>())).first;
+ if (!i->second.empty()) {
+ for (const auto& existingGroup : i->second[0]->getGroups()) {
+ item->addGroup(existingGroup);
+ }
+ }
+ i->second.push_back(item);
+ item->onDataChanged.connect(boost::bind(&Roster::handleDataChanged, this, item));
+ filterContact(item, group);
+
+ for (auto* item : i->second) {
+ item->addGroup(groupName);
+ }
}
struct JIDEqualsTo {
- JIDEqualsTo(const JID& jid) : jid(jid) {}
- bool operator()(ContactRosterItem* i) const { return jid == i->getJID(); }
- JID jid;
+ JIDEqualsTo(const JID& jid) : jid(jid) {}
+ bool operator()(ContactRosterItem* i) const { return jid == i->getJID(); }
+ JID jid;
};
void Roster::removeAll() {
- root_->removeAll();
- itemMap_.clear();
- onChildrenChanged(root_);
- onDataChanged(root_);
+ root_->removeAll();
+ itemMap_.clear();
+ onChildrenChanged(root_.get());
+ onDataChanged(root_.get());
}
void Roster::removeContact(const JID& jid) {
- ItemMap::iterator item = itemMap_.find(fullJIDMapping_ ? jid : jid.toBare());
- if (item != itemMap_.end()) {
- std::vector<ContactRosterItem*>& items = item->second;
- items.erase(std::remove_if(items.begin(), items.end(), JIDEqualsTo(jid)), items.end());
- if (items.empty()) {
- itemMap_.erase(item);
- }
- }
- //Causes the delete
- root_->removeChild(jid);
+ ItemMap::iterator item = itemMap_.find(fullJIDMapping_ ? jid : jid.toBare());
+ if (item != itemMap_.end()) {
+ std::vector<ContactRosterItem*>& items = item->second;
+ items.erase(std::remove_if(items.begin(), items.end(), JIDEqualsTo(jid)), items.end());
+ if (items.empty()) {
+ itemMap_.erase(item);
+ }
+ }
+ //Causes the delete
+ root_->removeChild(jid);
}
void Roster::removeContactFromGroup(const JID& jid, const std::string& groupName) {
- std::vector<RosterItem*> children = root_->getChildren();
- std::vector<RosterItem*>::iterator it = children.begin();
- ItemMap::iterator itemIt = itemMap_.find(fullJIDMapping_ ? jid : jid.toBare());
- while (it != children.end()) {
- GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it);
- if (group && group->getDisplayName() == groupName) {
- ContactRosterItem* deleted = group->removeChild(jid);
- if (itemIt != itemMap_.end()) {
- std::vector<ContactRosterItem*>& items = itemIt->second;
- items.erase(std::remove(items.begin(), items.end(), deleted), items.end());
- }
- }
- ++it;
- }
-
- if (itemIt != itemMap_.end()) {
- foreach (ContactRosterItem* item, itemIt->second) {
- item->removeGroup(groupName);
- }
- }
+ std::vector<RosterItem*> children = root_->getChildren();
+ std::vector<RosterItem*>::iterator it = children.begin();
+ ItemMap::iterator itemIt = itemMap_.find(fullJIDMapping_ ? jid : jid.toBare());
+ while (it != children.end()) {
+ GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(*it);
+ if (group && group->getDisplayName() == groupName) {
+ ContactRosterItem* deleted = group->removeChild(jid);
+ if (itemIt != itemMap_.end()) {
+ std::vector<ContactRosterItem*>& items = itemIt->second;
+ items.erase(std::remove(items.begin(), items.end(), deleted), items.end());
+ }
+ }
+ ++it;
+ }
+
+ if (itemIt != itemMap_.end()) {
+ for (auto* item : itemIt->second) {
+ item->removeGroup(groupName);
+ }
+ }
}
void Roster::applyOnItems(const RosterItemOperation& operation) {
- if (operation.requiresLookup()) {
- applyOnItem(operation, operation.lookupJID());
- } else {
- applyOnAllItems(operation);
- }
+ if (operation.requiresLookup()) {
+ applyOnItem(operation, operation.lookupJID());
+ }
+ else {
+ applyOnAllItems(operation);
+ }
}
void Roster::applyOnItem(const RosterItemOperation& operation, const JID& jid) {
- ItemMap::iterator i = itemMap_.find(fullJIDMapping_ ? jid : jid.toBare());
- if (i == itemMap_.end()) {
- return;
- }
- foreach (ContactRosterItem* item, i->second) {
- operation(item);
- filterContact(item, item->getParent());
- }
+ ItemMap::iterator i = itemMap_.find(fullJIDMapping_ ? jid : jid.toBare());
+ if (i == itemMap_.end()) {
+ return;
+ }
+ for (auto* item : i->second) {
+ operation(item);
+ filterContact(item, item->getParent());
+ }
}
void Roster::applyOnAllItems(const RosterItemOperation& operation) {
- std::deque<RosterItem*> queue;
- queue.push_back(root_);
- while (!queue.empty()) {
- RosterItem* item = *queue.begin();
- queue.pop_front();
- operation(item);
- GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
- if (group) {
- queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end());
- }
- }
- filterAll();
+ std::deque<RosterItem*> queue;
+ queue.push_back(root_.get());
+ while (!queue.empty()) {
+ RosterItem* item = *queue.begin();
+ queue.pop_front();
+ operation(item);
+ GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
+ if (group) {
+ queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end());
+ }
+ }
+ filterAll();
}
void Roster::addFilter(RosterFilter* filter) {
- filters_.push_back(filter);
- filterAll();
- onFilterAdded(filter);
+ filters_.push_back(filter);
+ filterAll();
+ onFilterAdded(filter);
}
void Roster::removeFilter(RosterFilter* filter) {
- for (unsigned int i = 0; i < filters_.size(); i++) {
- if (filters_[i] == filter) {
- filters_.erase(filters_.begin() + i);
- break;
- }
- }
- filterAll();
- onFilterRemoved(filter);
+ for (unsigned int i = 0; i < filters_.size(); i++) {
+ if (filters_[i] == filter) {
+ filters_.erase(filters_.begin() + i);
+ break;
+ }
+ }
+ filterAll();
+ onFilterRemoved(filter);
}
void Roster::filterContact(ContactRosterItem* contact, GroupRosterItem* group) {
- size_t oldDisplayedSize = group->getDisplayedChildren().size();
- bool hide = true;
- foreach (RosterFilter *filter, filters_) {
- hide &= (*filter)(contact);
- }
- group->setDisplayed(contact, filters_.empty() || !hide);
- size_t newDisplayedSize = group->getDisplayedChildren().size();
- if (oldDisplayedSize == 0 && newDisplayedSize > 0) {
- onGroupAdded(group);
- }
+ size_t oldDisplayedSize = group->getDisplayedChildren().size();
+ bool hide = true;
+ for (auto* filter : filters_) {
+ hide &= (*filter)(contact);
+ }
+ group->setDisplayed(contact, filters_.empty() || !hide);
+ size_t newDisplayedSize = group->getDisplayedChildren().size();
+ if (oldDisplayedSize == 0 && newDisplayedSize > 0) {
+ onGroupAdded(group);
+ }
}
void Roster::filterGroup(GroupRosterItem* group) {
- foreach (RosterItem* child, group->getChildren()) {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(child);
- if (contact) {
- filterContact(contact, group);
- }
- }
+ for (auto* child : group->getChildren()) {
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(child);
+ if (contact) {
+ filterContact(contact, group);
+ }
+ }
}
void Roster::filterAll() {
- std::deque<RosterItem*> queue;
- queue.push_back(root_);
- while (!queue.empty()) {
- RosterItem *item = *queue.begin();
- queue.pop_front();
- GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
- if (group) {
- queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end());
- filterGroup(group);
- }
- }
+ std::deque<RosterItem*> queue;
+ queue.push_back(root_.get());
+ while (!queue.empty()) {
+ RosterItem *item = *queue.begin();
+ queue.pop_front();
+ GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
+ if (group) {
+ queue.insert(queue.begin(), group->getChildren().begin(), group->getChildren().end());
+ filterGroup(group);
+ }
+ }
}
}
diff --git a/Swift/Controllers/Roster/Roster.h b/Swift/Controllers/Roster/Roster.h
index 269ec4d..d22b38d 100644
--- a/Swift/Controllers/Roster/Roster.h
+++ b/Swift/Controllers/Roster/Roster.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,13 +7,13 @@
#pragma once
#include <map>
+#include <memory>
#include <set>
#include <string>
#include <vector>
-#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
-#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/JID/JID.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
@@ -27,46 +27,48 @@ class GroupRosterItem;
class ContactRosterItem;
class Roster {
- public:
- Roster(bool sortByStatus = true, bool fullJIDMapping = false);
- ~Roster();
+ public:
+ Roster(bool sortByStatus = true, bool fullJIDMapping = false);
+ ~Roster();
- void addContact(const JID& jid, const JID& displayJID, const std::string& name, const std::string& group, const boost::filesystem::path& avatarPath);
- void removeContact(const JID& jid);
- void removeContactFromGroup(const JID& jid, const std::string& group);
- void removeGroup(const std::string& group);
- void removeAll();
- void applyOnItems(const RosterItemOperation& operation);
- void applyOnAllItems(const RosterItemOperation& operation);
- void applyOnItem(const RosterItemOperation& operation, const JID& jid);
- void addFilter(RosterFilter* filter);
- void removeFilter(RosterFilter* filter);
- GroupRosterItem* getRoot() const;
- std::set<JID> getJIDs() const;
+ void addContact(const JID& jid, const JID& displayJID, const std::string& name, const std::string& group, const boost::filesystem::path& avatarPath);
+ void removeContact(const JID& jid);
+ void removeContactFromGroup(const JID& jid, const std::string& group);
+ void removeGroup(const std::string& group);
+ void removeAll();
+ void applyOnItems(const RosterItemOperation& operation);
+ void applyOnAllItems(const RosterItemOperation& operation);
+ void applyOnItem(const RosterItemOperation& operation, const JID& jid);
+ void addFilter(RosterFilter* filter);
+ void removeFilter(RosterFilter* filter);
+ GroupRosterItem* getRoot() const;
+ std::set<JID> getJIDs() const;
- std::vector<RosterFilter*> getFilters() {return filters_;}
- boost::signal<void (GroupRosterItem*)> onChildrenChanged;
- boost::signal<void (GroupRosterItem*)> onGroupAdded;
- boost::signal<void (RosterItem*)> onDataChanged;
- boost::signal<void (JID&)> onVCardUpdateRequested;
- boost::signal<void (RosterFilter* filter)> onFilterAdded;
- boost::signal<void (RosterFilter* filter)> onFilterRemoved;
- GroupRosterItem* getGroup(const std::string& groupName);
- void setBlockingSupported(bool isSupported);
+ std::vector<RosterFilter*> getFilters() {return filters_;}
+ boost::signals2::signal<void (GroupRosterItem*)> onChildrenChanged;
+ boost::signals2::signal<void (GroupRosterItem*)> onGroupAdded;
+ boost::signals2::signal<void (RosterItem*)> onDataChanged;
+ boost::signals2::signal<void (JID&)> onVCardUpdateRequested;
+ boost::signals2::signal<void (RosterFilter* filter)> onFilterAdded;
+ boost::signals2::signal<void (RosterFilter* filter)> onFilterRemoved;
+ GroupRosterItem* getGroup(const std::string& groupName);
+ void setBlockingSupported(bool isSupported);
- private:
- void handleDataChanged(RosterItem* item);
- void handleChildrenChanged(GroupRosterItem* item);
- void filterGroup(GroupRosterItem* item);
- void filterContact(ContactRosterItem* contact, GroupRosterItem* group);
- void filterAll();
- GroupRosterItem* root_;
- std::vector<RosterFilter*> filters_;
- typedef std::map<JID, std::vector<ContactRosterItem*> > ItemMap;
- ItemMap itemMap_;
- bool fullJIDMapping_;
- bool sortByStatus_;
- bool blockingSupported_;
+ private:
+ void handleDataChanged(RosterItem* item);
+ void handleChildrenChanged(GroupRosterItem* item);
+ void filterGroup(GroupRosterItem* item);
+ void filterContact(ContactRosterItem* contact, GroupRosterItem* group);
+ void filterAll();
+
+ private:
+ std::vector<RosterFilter*> filters_;
+ typedef std::map<JID, std::vector<ContactRosterItem*> > ItemMap;
+ ItemMap itemMap_;
+ bool fullJIDMapping_;
+ bool sortByStatus_;
+ bool blockingSupported_ = false;
+ const std::unique_ptr<GroupRosterItem> root_;
};
}
diff --git a/Swift/Controllers/Roster/RosterController.cpp b/Swift/Controllers/Roster/RosterController.cpp
index 4fbdea4..1d20c4a 100644
--- a/Swift/Controllers/Roster/RosterController.cpp
+++ b/Swift/Controllers/Roster/RosterController.cpp
@@ -1,22 +1,23 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/Roster/RosterController.h>
+#include <memory>
+
#include <boost/bind.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
#include <Swiften/Avatars/AvatarManager.h>
#include <Swiften/Base/Path.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Base/format.h>
#include <Swiften/Client/ClientBlockListManager.h>
#include <Swiften/Client/NickManager.h>
#include <Swiften/Client/NickResolver.h>
#include <Swiften/Disco/EntityCapsManager.h>
+#include <Swiften/Disco/FeatureOracle.h>
#include <Swiften/Elements/DiscoInfo.h>
#include <Swiften/FileTransfer/FileTransferManager.h>
#include <Swiften/JID/JID.h>
@@ -30,7 +31,6 @@
#include <Swiften/Roster/XMPPRosterItem.h>
#include <Swiften/VCards/VCardManager.h>
-#include <Swift/Controllers/FileTransfer/FileTransferOverview.h>
#include <Swift/Controllers/Intl.h>
#include <Swift/Controllers/Roster/GroupRosterItem.h>
#include <Swift/Controllers/Roster/ItemOperations/AppearOffline.h>
@@ -49,7 +49,6 @@
#include <Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h>
#include <Swift/Controllers/UIEvents/RenameGroupUIEvent.h>
#include <Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h>
-#include <Swift/Controllers/UIEvents/SendFileUIEvent.h>
#include <Swift/Controllers/UIInterfaces/MainWindow.h>
#include <Swift/Controllers/UIInterfaces/MainWindowFactory.h>
#include <Swift/Controllers/XMPPEvents/ErrorEvent.h>
@@ -61,355 +60,347 @@ namespace Swift {
/**
* The controller does not gain ownership of these parameters.
*/
-RosterController::RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter, SettingsProvider* settings, EntityCapsProvider* entityCapsManager, FileTransferOverview* fileTransferOverview, ClientBlockListManager* clientBlockListManager, VCardManager* vcardManager)
- : myJID_(jid), xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), mainWindow_(mainWindowFactory_->createMainWindow(uiEventStream)), roster_(new Roster()), offlineFilter_(new OfflineRosterFilter()), vcardManager_(vcardManager), avatarManager_(avatarManager), nickManager_(nickManager), nickResolver_(nickResolver), presenceOracle_(presenceOracle), uiEventStream_(uiEventStream), entityCapsManager_(entityCapsManager), ftOverview_(fileTransferOverview), clientBlockListManager_(clientBlockListManager) {
- assert(fileTransferOverview);
- iqRouter_ = iqRouter;
- subscriptionManager_ = subscriptionManager;
- eventController_ = eventController;
- settings_ = settings;
- expandiness_ = new RosterGroupExpandinessPersister(roster_, settings);
- mainWindow_->setRosterModel(roster_);
- rosterVCardProvider_ = new RosterVCardProvider(roster_, vcardManager, JID::WithoutResource);
-
- changeStatusConnection_ = mainWindow_->onChangeStatusRequest.connect(boost::bind(&RosterController::handleChangeStatusRequest, this, _1, _2));
- signOutConnection_ = mainWindow_->onSignOutRequest.connect(boost::bind(boost::ref(onSignOutRequest)));
- xmppRoster_->onJIDAdded.connect(boost::bind(&RosterController::handleOnJIDAdded, this, _1));
- xmppRoster_->onJIDUpdated.connect(boost::bind(&RosterController::handleOnJIDUpdated, this, _1, _2, _3));
- xmppRoster_->onJIDRemoved.connect(boost::bind(&RosterController::handleOnJIDRemoved, this, _1));
- xmppRoster_->onRosterCleared.connect(boost::bind(&RosterController::handleRosterCleared, this));
- subscriptionManager_->onPresenceSubscriptionRequest.connect(boost::bind(&RosterController::handleSubscriptionRequest, this, _1, _2));
- uiEventConnection_ = uiEventStream->onUIEvent.connect(boost::bind(&RosterController::handleUIEvent, this, _1));
-
- vcardManager_->onOwnVCardChanged.connect(boost::bind(&RosterController::handleOwnVCardChanged, this, _1));
- avatarManager_->onAvatarChanged.connect(boost::bind(&RosterController::handleAvatarChanged, this, _1));
- presenceOracle_->onPresenceChange.connect(boost::bind(&RosterController::handlePresenceChanged, this, _1));
- mainWindow_->setMyAvatarPath(pathToString(avatarManager_->getAvatarPath(myJID_.toBare())));
-
- nickManager_->onOwnNickChanged.connect(boost::bind(&MainWindow::setMyNick, mainWindow_, _1));
- mainWindow_->setMyJID(jid);
- mainWindow_->setMyNick(nickManager_->getOwnNick());
-
- entityCapsManager_->onCapsChanged.connect(boost::bind(&RosterController::handleOnCapsChanged, this, _1));
-
- settings_->onSettingChanged.connect(boost::bind(&RosterController::handleSettingChanged, this, _1));
-
- handleShowOfflineToggled(settings_->getSetting(SettingConstants::SHOW_OFFLINE));
-
- ownContact_ = boost::make_shared<ContactRosterItem>(myJID_.toBare(), myJID_.toBare(), nickManager_->getOwnNick(), static_cast<GroupRosterItem*>(0));
- ownContact_->setVCard(vcardManager_->getVCard(myJID_.toBare()));
- ownContact_->setAvatarPath(pathToString(avatarManager_->getAvatarPath(myJID_.toBare())));
- mainWindow_->setMyContactRosterItem(ownContact_);
+RosterController::RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter, SettingsProvider* settings, EntityCapsProvider* entityCapsManager, ClientBlockListManager* clientBlockListManager, VCardManager* vcardManager)
+ : myJID_(jid), xmppRoster_(xmppRoster), mainWindowFactory_(mainWindowFactory), mainWindow_(mainWindowFactory_->createMainWindow(uiEventStream)), roster_(new Roster()), offlineFilter_(new OfflineRosterFilter()), vcardManager_(vcardManager), avatarManager_(avatarManager), nickManager_(nickManager), nickResolver_(nickResolver), presenceOracle_(presenceOracle), uiEventStream_(uiEventStream), entityCapsManager_(entityCapsManager), clientBlockListManager_(clientBlockListManager) {
+ iqRouter_ = iqRouter;
+ subscriptionManager_ = subscriptionManager;
+ eventController_ = eventController;
+ settings_ = settings;
+ expandiness_ = new RosterGroupExpandinessPersister(roster_, settings);
+ mainWindow_->setRosterModel(roster_);
+ rosterVCardProvider_ = new RosterVCardProvider(roster_, vcardManager, JID::WithoutResource);
+
+ changeStatusConnection_ = mainWindow_->onChangeStatusRequest.connect(boost::bind(&RosterController::handleChangeStatusRequest, this, _1, _2));
+ signOutConnection_ = mainWindow_->onSignOutRequest.connect(boost::bind(boost::ref(onSignOutRequest)));
+ xmppRoster_->onJIDAdded.connect(boost::bind(&RosterController::handleOnJIDAdded, this, _1));
+ xmppRoster_->onJIDUpdated.connect(boost::bind(&RosterController::handleOnJIDUpdated, this, _1, _2, _3));
+ xmppRoster_->onJIDRemoved.connect(boost::bind(&RosterController::handleOnJIDRemoved, this, _1));
+ xmppRoster_->onRosterCleared.connect(boost::bind(&RosterController::handleRosterCleared, this));
+ subscriptionManager_->onPresenceSubscriptionRequest.connect(boost::bind(&RosterController::handleSubscriptionRequest, this, _1, _2));
+ uiEventConnection_ = uiEventStream->onUIEvent.connect(boost::bind(&RosterController::handleUIEvent, this, _1));
+
+ featureOracle_ = std::unique_ptr<FeatureOracle>(new FeatureOracle(entityCapsManager_, presenceOracle_));
+
+ vcardManager_->onOwnVCardChanged.connect(boost::bind(&RosterController::handleOwnVCardChanged, this, _1));
+ avatarManager_->onAvatarChanged.connect(boost::bind(&RosterController::handleAvatarChanged, this, _1));
+ presenceOracle_->onPresenceChange.connect(boost::bind(&RosterController::handlePresenceChanged, this, _1));
+ mainWindow_->setMyAvatarPath(pathToString(avatarManager_->getAvatarPath(myJID_.toBare())));
+
+ nickManager_->onOwnNickChanged.connect(boost::bind(&MainWindow::setMyNick, mainWindow_, _1));
+ mainWindow_->setMyJID(jid);
+ mainWindow_->setMyNick(nickManager_->getOwnNick());
+
+ entityCapsManager_->onCapsChanged.connect(boost::bind(&RosterController::handleOnCapsChanged, this, _1));
+
+ settings_->onSettingChanged.connect(boost::bind(&RosterController::handleSettingChanged, this, _1));
+
+ handleShowOfflineToggled(settings_->getSetting(SettingConstants::SHOW_OFFLINE));
+
+ ownContact_ = std::make_shared<ContactRosterItem>(myJID_.toBare(), myJID_.toBare(), nickManager_->getOwnNick(), static_cast<GroupRosterItem*>(nullptr));
+ ownContact_->setVCard(vcardManager_->getVCard(myJID_.toBare()));
+ ownContact_->setAvatarPath(pathToString(avatarManager_->getAvatarPath(myJID_.toBare())));
+ mainWindow_->setMyContactRosterItem(ownContact_);
}
-RosterController::~RosterController() {
- settings_->onSettingChanged.disconnect(boost::bind(&RosterController::handleSettingChanged, this, _1));
- nickManager_->onOwnNickChanged.disconnect(boost::bind(&MainWindow::setMyNick, mainWindow_, _1));
-
- delete offlineFilter_;
- delete expandiness_;
+RosterController::~RosterController() {
+ settings_->onSettingChanged.disconnect(boost::bind(&RosterController::handleSettingChanged, this, _1));
+ nickManager_->onOwnNickChanged.disconnect(boost::bind(&MainWindow::setMyNick, mainWindow_, _1));
+
+ delete offlineFilter_;
+ delete expandiness_;
- mainWindow_->setRosterModel(NULL);
- if (mainWindow_->canDelete()) {
- delete mainWindow_;
- }
- delete rosterVCardProvider_;
- delete roster_;
+ mainWindow_->setRosterModel(nullptr);
+ if (mainWindow_->canDelete()) {
+ delete mainWindow_;
+ }
+ delete rosterVCardProvider_;
+ delete roster_;
}
void RosterController::setEnabled(bool enabled) {
- if (!enabled) {
- roster_->applyOnItems(AppearOffline());
- }
+ if (!enabled) {
+ roster_->applyOnItems(AppearOffline());
+ }
}
void RosterController::handleShowOfflineToggled(bool state) {
- if (state) {
- roster_->removeFilter(offlineFilter_);
- } else {
- roster_->addFilter(offlineFilter_);
- }
+ if (state) {
+ roster_->removeFilter(offlineFilter_);
+ } else {
+ roster_->addFilter(offlineFilter_);
+ }
}
void RosterController::handleChangeStatusRequest(StatusShow::Type show, const std::string &statusText) {
- onChangeStatusRequest(show, statusText);
+ onChangeStatusRequest(show, statusText);
}
void RosterController::handleOnJIDAdded(const JID& jid) {
- std::vector<std::string> groups = xmppRoster_->getGroupsForJID(jid);
- std::string name = nickResolver_->jidToNick(jid);
- if (!groups.empty()) {
- foreach(const std::string& group, groups) {
- roster_->addContact(jid, jid, name, group, avatarManager_->getAvatarPath(jid));
- }
- }
- else {
- roster_->addContact(jid, jid, name, QT_TRANSLATE_NOOP("", "Contacts"), avatarManager_->getAvatarPath(jid));
- }
- applyAllPresenceTo(jid);
+ std::vector<std::string> groups = xmppRoster_->getGroupsForJID(jid);
+ std::string name = nickResolver_->jidToNick(jid);
+ if (!groups.empty()) {
+ for (const auto& group : groups) {
+ roster_->addContact(jid, jid, name, group, avatarManager_->getAvatarPath(jid));
+ }
+ }
+ else {
+ roster_->addContact(jid, jid, name, QT_TRANSLATE_NOOP("", "Contacts"), avatarManager_->getAvatarPath(jid));
+ }
+ applyAllPresenceTo(jid);
}
void RosterController::applyAllPresenceTo(const JID& jid) {
- foreach (Presence::ref presence, presenceOracle_->getAllPresence(jid)) {
- roster_->applyOnItems(SetPresence(presence));
- }
+ for (auto&& presence : presenceOracle_->getAllPresence(jid)) {
+ roster_->applyOnItems(SetPresence(presence));
+ }
}
void RosterController::handleRosterCleared() {
- roster_->removeAll();
+ roster_->removeAll();
}
void RosterController::handleOnJIDRemoved(const JID& jid) {
- roster_->removeContact(jid);
+ roster_->removeContact(jid);
}
void RosterController::handleOnJIDUpdated(const JID& jid, const std::string& oldName, const std::vector<std::string>& passedOldGroups) {
- if (oldName != xmppRoster_->getNameForJID(jid)) {
- roster_->applyOnItems(SetName(nickResolver_->jidToNick(jid), jid));
- }
- std::vector<std::string> groups = xmppRoster_->getGroupsForJID(jid);
- std::vector<std::string> oldGroups = passedOldGroups;
- std::string name = nickResolver_->jidToNick(jid);
- std::string contactsGroup = QT_TRANSLATE_NOOP("", "Contacts");
- if (oldGroups.empty()) {
- oldGroups.push_back(contactsGroup);
- }
- if (groups.empty()) {
- groups.push_back(contactsGroup);
- }
- foreach(const std::string& group, groups) {
- if (std::find(oldGroups.begin(), oldGroups.end(), group) == oldGroups.end()) {
- roster_->addContact(jid, jid, name, group, avatarManager_->getAvatarPath(jid));
- }
- }
- foreach(const std::string& group, oldGroups) {
- if (std::find(groups.begin(), groups.end(), group) == groups.end()) {
- roster_->removeContactFromGroup(jid, group);
- if (roster_->getGroup(group)->getChildren().size() == 0) {
- roster_->removeGroup(group);
- }
- }
- }
- applyAllPresenceTo(jid);
+ if (oldName != xmppRoster_->getNameForJID(jid)) {
+ roster_->applyOnItems(SetName(nickResolver_->jidToNick(jid), jid));
+ }
+ std::vector<std::string> groups = xmppRoster_->getGroupsForJID(jid);
+ std::vector<std::string> oldGroups = passedOldGroups;
+ std::string name = nickResolver_->jidToNick(jid);
+ std::string contactsGroup = QT_TRANSLATE_NOOP("", "Contacts");
+ if (oldGroups.empty()) {
+ oldGroups.push_back(contactsGroup);
+ }
+ if (groups.empty()) {
+ groups.push_back(contactsGroup);
+ }
+ for (const auto& group : groups) {
+ if (std::find(oldGroups.begin(), oldGroups.end(), group) == oldGroups.end()) {
+ roster_->addContact(jid, jid, name, group, avatarManager_->getAvatarPath(jid));
+ }
+ }
+ for (const auto& group : oldGroups) {
+ if (std::find(groups.begin(), groups.end(), group) == groups.end()) {
+ roster_->removeContactFromGroup(jid, group);
+ if (roster_->getGroup(group)->getChildren().size() == 0) {
+ roster_->removeGroup(group);
+ }
+ }
+ }
+ applyAllPresenceTo(jid);
}
void RosterController::handleSettingChanged(const std::string& settingPath) {
- if (settingPath == SettingConstants::SHOW_OFFLINE.getKey()) {
- handleShowOfflineToggled(settings_->getSetting(SettingConstants::SHOW_OFFLINE));
- }
+ if (settingPath == SettingConstants::SHOW_OFFLINE.getKey()) {
+ handleShowOfflineToggled(settings_->getSetting(SettingConstants::SHOW_OFFLINE));
+ }
}
void RosterController::handleBlockingStateChanged() {
- if (clientBlockListManager_->getBlockList()->getState() == BlockList::Available) {
- foreach(const JID& jid, clientBlockListManager_->getBlockList()->getItems()) {
- roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsBlocked));
- }
- }
+ if (clientBlockListManager_->getBlockList()->getState() == BlockList::Available) {
+ for (const auto& jid : clientBlockListManager_->getBlockList()->getItems()) {
+ roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsBlocked));
+ }
+ }
}
void RosterController::handleBlockingItemAdded(const JID& jid) {
- roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsBlocked));
+ roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsBlocked));
}
void RosterController::handleBlockingItemRemoved(const JID& jid) {
- roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsUnblocked));
+ roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsUnblocked));
}
-void RosterController::handleUIEvent(boost::shared_ptr<UIEvent> event) {
- if (boost::shared_ptr<AddContactUIEvent> addContactEvent = boost::dynamic_pointer_cast<AddContactUIEvent>(event)) {
- RosterItemPayload item;
- item.setName(addContactEvent->getName());
- item.setJID(addContactEvent->getJID());
- item.setGroups(std::vector<std::string>(addContactEvent->getGroups().begin(), addContactEvent->getGroups().end()));
- boost::shared_ptr<RosterPayload> roster(new RosterPayload());
- roster->addItem(item);
- SetRosterRequest::ref request = SetRosterRequest::create(roster, iqRouter_);
- request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
- request->send();
- subscriptionManager_->requestSubscription(addContactEvent->getJID());
- }
- else if (boost::shared_ptr<RemoveRosterItemUIEvent> removeEvent = boost::dynamic_pointer_cast<RemoveRosterItemUIEvent>(event)) {
- RosterItemPayload item(removeEvent->getJID(), "", RosterItemPayload::Remove);
- boost::shared_ptr<RosterPayload> roster(new RosterPayload());
- roster->addItem(item);
- SetRosterRequest::ref request = SetRosterRequest::create(roster, iqRouter_);
- request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
- request->send();
-
- }
- else if (boost::shared_ptr<RenameRosterItemUIEvent> renameEvent = boost::dynamic_pointer_cast<RenameRosterItemUIEvent>(event)) {
- JID contact(renameEvent->getJID());
- RosterItemPayload item(contact, renameEvent->getNewName(), xmppRoster_->getSubscriptionStateForJID(contact));
- item.setGroups(xmppRoster_->getGroupsForJID(contact));
- boost::shared_ptr<RosterPayload> roster(new RosterPayload());
- roster->addItem(item);
- SetRosterRequest::ref request = SetRosterRequest::create(roster, iqRouter_);
- request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
- request->send();
- }
- else if (boost::shared_ptr<RenameGroupUIEvent> renameGroupEvent = boost::dynamic_pointer_cast<RenameGroupUIEvent>(event)) {
- std::vector<XMPPRosterItem> items = xmppRoster_->getItems();
- std::string group = renameGroupEvent->getGroup();
- // FIXME: We should handle contacts groups specially to avoid clashes
- if (group == QT_TRANSLATE_NOOP("", "Contacts")) {
- group = "";
- }
- foreach(XMPPRosterItem& item, items) {
- std::vector<std::string> groups = item.getGroups();
- if ( (group.empty() && groups.empty()) || std::find(groups.begin(), groups.end(), group) != groups.end()) {
- groups.erase(std::remove(groups.begin(), groups.end(), group), groups.end());
- if (std::find(groups.begin(), groups.end(), renameGroupEvent->getNewName()) == groups.end()) {
- groups.push_back(renameGroupEvent->getNewName());
- }
- item.setGroups(groups);
- updateItem(item);
- }
- }
- }
- else if (boost::shared_ptr<SendFileUIEvent> sendFileEvent = boost::dynamic_pointer_cast<SendFileUIEvent>(event)) {
- //TODO add send file dialog to ChatView of receipient jid
- ftOverview_->sendFile(sendFileEvent->getJID(), sendFileEvent->getFilename());
- }
+void RosterController::handleUIEvent(std::shared_ptr<UIEvent> event) {
+ if (std::shared_ptr<AddContactUIEvent> addContactEvent = std::dynamic_pointer_cast<AddContactUIEvent>(event)) {
+ RosterItemPayload item;
+ item.setName(addContactEvent->getName());
+ item.setJID(addContactEvent->getJID());
+ item.setGroups(std::vector<std::string>(addContactEvent->getGroups().begin(), addContactEvent->getGroups().end()));
+ std::shared_ptr<RosterPayload> roster(new RosterPayload());
+ roster->addItem(item);
+ SetRosterRequest::ref request = SetRosterRequest::create(roster, iqRouter_);
+ request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
+ request->send();
+ subscriptionManager_->requestSubscription(addContactEvent->getJID());
+ }
+ else if (std::shared_ptr<RemoveRosterItemUIEvent> removeEvent = std::dynamic_pointer_cast<RemoveRosterItemUIEvent>(event)) {
+ RosterItemPayload item(removeEvent->getJID(), "", RosterItemPayload::Remove);
+ std::shared_ptr<RosterPayload> roster(new RosterPayload());
+ roster->addItem(item);
+ SetRosterRequest::ref request = SetRosterRequest::create(roster, iqRouter_);
+ request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
+ request->send();
+
+ }
+ else if (std::shared_ptr<RenameRosterItemUIEvent> renameEvent = std::dynamic_pointer_cast<RenameRosterItemUIEvent>(event)) {
+ JID contact(renameEvent->getJID());
+ RosterItemPayload item(contact, renameEvent->getNewName(), xmppRoster_->getSubscriptionStateForJID(contact));
+ item.setGroups(xmppRoster_->getGroupsForJID(contact));
+ std::shared_ptr<RosterPayload> roster(new RosterPayload());
+ roster->addItem(item);
+ SetRosterRequest::ref request = SetRosterRequest::create(roster, iqRouter_);
+ request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
+ request->send();
+ }
+ else if (std::shared_ptr<RenameGroupUIEvent> renameGroupEvent = std::dynamic_pointer_cast<RenameGroupUIEvent>(event)) {
+ std::vector<XMPPRosterItem> items = xmppRoster_->getItems();
+ std::string group = renameGroupEvent->getGroup();
+ // FIXME: We should handle contacts groups specially to avoid clashes
+ if (group == QT_TRANSLATE_NOOP("", "Contacts")) {
+ group = "";
+ }
+ for (auto& item : items) {
+ std::vector<std::string> groups = item.getGroups();
+ if ( (group.empty() && groups.empty()) || std::find(groups.begin(), groups.end(), group) != groups.end()) {
+ groups.erase(std::remove(groups.begin(), groups.end(), group), groups.end());
+ if (std::find(groups.begin(), groups.end(), renameGroupEvent->getNewName()) == groups.end()) {
+ groups.push_back(renameGroupEvent->getNewName());
+ }
+ item.setGroups(groups);
+ updateItem(item);
+ }
+ }
+ }
}
void RosterController::setContactGroups(const JID& jid, const std::vector<std::string>& groups) {
- updateItem(XMPPRosterItem(jid, xmppRoster_->getNameForJID(jid), groups, xmppRoster_->getSubscriptionStateForJID(jid)));
+ updateItem(XMPPRosterItem(jid, xmppRoster_->getNameForJID(jid), groups, xmppRoster_->getSubscriptionStateForJID(jid)));
}
void RosterController::updateItem(const XMPPRosterItem& item) {
- RosterItemPayload itemPayload(item.getJID(), item.getName(), item.getSubscription());
- itemPayload.setGroups(item.getGroups());
+ RosterItemPayload itemPayload(item.getJID(), item.getName(), item.getSubscription());
+ itemPayload.setGroups(item.getGroups());
- RosterPayload::ref roster = boost::make_shared<RosterPayload>();
- roster->addItem(itemPayload);
+ RosterPayload::ref roster = std::make_shared<RosterPayload>();
+ roster->addItem(itemPayload);
- SetRosterRequest::ref request = SetRosterRequest::create(roster, iqRouter_);
- request->onResponse.connect(boost::bind(&RosterController::handleRosterItemUpdated, this, _1, roster));
- request->send();
+ SetRosterRequest::ref request = SetRosterRequest::create(roster, iqRouter_);
+ request->onResponse.connect(boost::bind(&RosterController::handleRosterItemUpdated, this, _1, roster));
+ request->send();
}
void RosterController::initBlockingCommand() {
- boost::shared_ptr<BlockList> blockList = clientBlockListManager_->requestBlockList();
-
- blockingOnStateChangedConnection_ = blockList->onStateChanged.connect(boost::bind(&RosterController::handleBlockingStateChanged, this));
- blockingOnItemAddedConnection_ = blockList->onItemAdded.connect(boost::bind(&RosterController::handleBlockingItemAdded, this, _1));
- blockingOnItemRemovedConnection_ = blockList->onItemRemoved.connect(boost::bind(&RosterController::handleBlockingItemRemoved, this, _1));
- roster_->setBlockingSupported(true);
- if (blockList->getState() == BlockList::Available) {
- foreach(const JID& jid, blockList->getItems()) {
- roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsBlocked));
- }
- }
+ std::shared_ptr<BlockList> blockList = clientBlockListManager_->requestBlockList();
+
+ blockingOnStateChangedConnection_ = blockList->onStateChanged.connect(boost::bind(&RosterController::handleBlockingStateChanged, this));
+ blockingOnItemAddedConnection_ = blockList->onItemAdded.connect(boost::bind(&RosterController::handleBlockingItemAdded, this, _1));
+ blockingOnItemRemovedConnection_ = blockList->onItemRemoved.connect(boost::bind(&RosterController::handleBlockingItemRemoved, this, _1));
+ roster_->setBlockingSupported(true);
+ if (blockList->getState() == BlockList::Available) {
+ for (const auto& jid : blockList->getItems()) {
+ roster_->applyOnItems(SetBlockingState(jid, ContactRosterItem::IsBlocked));
+ }
+ }
}
-void RosterController::handleRosterItemUpdated(ErrorPayload::ref error, boost::shared_ptr<RosterPayload> rosterPayload) {
- if (!!error) {
- handleRosterSetError(error, rosterPayload);
- }
- boost::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList();
- std::vector<RosterItemPayload> items = rosterPayload->getItems();
- if (blockList->getState() == BlockList::Available && items.size() > 0) {
- std::vector<JID> jids = blockList->getItems();
- if (std::find(jids.begin(), jids.end(), items[0].getJID()) != jids.end()) {
- roster_->applyOnItems(SetBlockingState(items[0].getJID(), ContactRosterItem::IsBlocked));
- }
- }
+void RosterController::handleRosterItemUpdated(ErrorPayload::ref error, std::shared_ptr<RosterPayload> rosterPayload) {
+ if (!!error) {
+ handleRosterSetError(error, rosterPayload);
+ }
+ std::shared_ptr<BlockList> blockList = clientBlockListManager_->getBlockList();
+ std::vector<RosterItemPayload> items = rosterPayload->getItems();
+ if (blockList->getState() == BlockList::Available && items.size() > 0) {
+ std::vector<JID> jids = blockList->getItems();
+ if (std::find(jids.begin(), jids.end(), items[0].getJID()) != jids.end()) {
+ roster_->applyOnItems(SetBlockingState(items[0].getJID(), ContactRosterItem::IsBlocked));
+ }
+ }
}
-void RosterController::handleRosterSetError(ErrorPayload::ref error, boost::shared_ptr<RosterPayload> rosterPayload) {
- if (!error) {
- return;
- }
- std::string text = str(format(QT_TRANSLATE_NOOP("", "Server %1% rejected contact list change to item '%2%'")) % myJID_.getDomain() % rosterPayload->getItems()[0].getJID().toString());
- if (!error->getText().empty()) {
- text += ": " + error->getText();
- }
- boost::shared_ptr<ErrorEvent> errorEvent(new ErrorEvent(JID(myJID_.getDomain()), text));
- eventController_->handleIncomingEvent(errorEvent);
+void RosterController::handleRosterSetError(ErrorPayload::ref error, std::shared_ptr<RosterPayload> rosterPayload) {
+ if (!error) {
+ return;
+ }
+ std::string text = str(format(QT_TRANSLATE_NOOP("", "Server %1% rejected contact list change to item '%2%'")) % myJID_.getDomain() % rosterPayload->getItems()[0].getJID().toString());
+ if (!error->getText().empty()) {
+ text += ": " + error->getText();
+ }
+ std::shared_ptr<ErrorEvent> errorEvent(new ErrorEvent(JID(myJID_.getDomain()), text));
+ eventController_->handleIncomingEvent(errorEvent);
}
void RosterController::handleIncomingPresence(Presence::ref newPresence) {
- if (newPresence->getType() == Presence::Error) {
- return;
- }
- Presence::ref accountPresence = presenceOracle_->getAccountPresence(newPresence->getFrom().toBare());
- if (!accountPresence) {
- accountPresence = Presence::create();
- accountPresence->setFrom(newPresence->getFrom());
- accountPresence->setType(Presence::Unavailable);
- }
- roster_->applyOnItems(SetPresence(accountPresence));
+ if (newPresence->getType() == Presence::Error) {
+ return;
+ }
+ Presence::ref accountPresence = presenceOracle_->getAccountPresence(newPresence->getFrom().toBare());
+ if (!accountPresence) {
+ accountPresence = Presence::create();
+ accountPresence->setFrom(newPresence->getFrom());
+ accountPresence->setType(Presence::Unavailable);
+ }
+ roster_->applyOnItems(SetPresence(accountPresence));
}
void RosterController::handleSubscriptionRequest(const JID& jid, const std::string& message) {
- if (xmppRoster_->containsJID(jid) && (xmppRoster_->getSubscriptionStateForJID(jid) == RosterItemPayload::To || xmppRoster_->getSubscriptionStateForJID(jid) == RosterItemPayload::Both)) {
- subscriptionManager_->confirmSubscription(jid);
- return;
- }
- SubscriptionRequestEvent* eventPointer = new SubscriptionRequestEvent(jid, message);
- eventPointer->onAccept.connect(boost::bind(&RosterController::handleSubscriptionRequestAccepted, this, eventPointer));
- eventPointer->onDecline.connect(boost::bind(&RosterController::handleSubscriptionRequestDeclined, this, eventPointer));
- boost::shared_ptr<StanzaEvent> event(eventPointer);
- eventController_->handleIncomingEvent(event);
+ if (xmppRoster_->containsJID(jid) && (xmppRoster_->getSubscriptionStateForJID(jid) == RosterItemPayload::To || xmppRoster_->getSubscriptionStateForJID(jid) == RosterItemPayload::Both)) {
+ subscriptionManager_->confirmSubscription(jid);
+ return;
+ }
+ SubscriptionRequestEvent* eventPointer = new SubscriptionRequestEvent(jid, message);
+ eventPointer->onAccept.connect(boost::bind(&RosterController::handleSubscriptionRequestAccepted, this, eventPointer));
+ eventPointer->onDecline.connect(boost::bind(&RosterController::handleSubscriptionRequestDeclined, this, eventPointer));
+ std::shared_ptr<StanzaEvent> event(eventPointer);
+ eventController_->handleIncomingEvent(event);
}
void RosterController::handleSubscriptionRequestAccepted(SubscriptionRequestEvent* event) {
- subscriptionManager_->confirmSubscription(event->getJID());
- if (!xmppRoster_->containsJID(event->getJID()) || xmppRoster_->getSubscriptionStateForJID(event->getJID()) == RosterItemPayload::None || xmppRoster_->getSubscriptionStateForJID(event->getJID()) == RosterItemPayload::From) {
- subscriptionManager_->requestSubscription(event->getJID());
- }
+ subscriptionManager_->confirmSubscription(event->getJID());
+ if (!xmppRoster_->containsJID(event->getJID()) || xmppRoster_->getSubscriptionStateForJID(event->getJID()) == RosterItemPayload::None || xmppRoster_->getSubscriptionStateForJID(event->getJID()) == RosterItemPayload::From) {
+ subscriptionManager_->requestSubscription(event->getJID());
+ }
}
void RosterController::handleSubscriptionRequestDeclined(SubscriptionRequestEvent* event) {
- subscriptionManager_->cancelSubscription(event->getJID());
+ subscriptionManager_->cancelSubscription(event->getJID());
}
void RosterController::handleOwnVCardChanged(VCard::ref vcard) {
- ownContact_->setVCard(vcard);
- mainWindow_->setMyContactRosterItem(ownContact_);
+ ownContact_->setVCard(vcard);
+ mainWindow_->setMyContactRosterItem(ownContact_);
}
void RosterController::handleAvatarChanged(const JID& jid) {
- boost::filesystem::path path = avatarManager_->getAvatarPath(jid);
- roster_->applyOnItems(SetAvatar(jid, path));
- if (jid.equals(myJID_, JID::WithoutResource)) {
- mainWindow_->setMyAvatarPath(pathToString(path));
- ownContact_->setAvatarPath(pathToString(path));
- mainWindow_->setMyContactRosterItem(ownContact_);
- }
+ boost::filesystem::path path = avatarManager_->getAvatarPath(jid);
+ roster_->applyOnItems(SetAvatar(jid, path));
+ if (jid.equals(myJID_, JID::WithoutResource)) {
+ mainWindow_->setMyAvatarPath(pathToString(path));
+ ownContact_->setAvatarPath(pathToString(path));
+ mainWindow_->setMyContactRosterItem(ownContact_);
+ }
}
void RosterController::handlePresenceChanged(Presence::ref presence) {
- if (presence->getFrom().equals(myJID_, JID::WithResource)) {
- ownContact_->applyPresence(presence);
- mainWindow_->setMyContactRosterItem(ownContact_);
- }
- else {
- handleIncomingPresence(presence);
- }
+ if (presence->getFrom().equals(myJID_, JID::WithResource)) {
+ ownContact_->applyPresence(presence);
+ mainWindow_->setMyContactRosterItem(ownContact_);
+ }
+ handleIncomingPresence(presence);
}
boost::optional<XMPPRosterItem> RosterController::getItem(const JID& jid) const {
- return xmppRoster_->getItem(jid);
+ return xmppRoster_->getItem(jid);
}
std::set<std::string> RosterController::getGroups() const {
- return xmppRoster_->getGroups();
+ return xmppRoster_->getGroups();
}
void RosterController::handleOnCapsChanged(const JID& jid) {
- DiscoInfo::ref info = entityCapsManager_->getCaps(jid);
- if (info) {
- std::set<ContactRosterItem::Feature> features;
- if (FileTransferManager::isSupportedBy(info)) {
- features.insert(ContactRosterItem::FileTransferFeature);
- }
- if (info->hasFeature(DiscoInfo::WhiteboardFeature)) {
- features.insert(ContactRosterItem::WhiteboardFeature);
- }
- roster_->applyOnItems(SetAvailableFeatures(jid, features));
- }
+ std::set<ContactRosterItem::Feature> features;
+ if (featureOracle_->isFileTransferSupported(jid.toBare()) == Tristate::Yes || featureOracle_->isFileTransferSupported(jid.toBare()) == Tristate::Maybe) {
+ features.insert(ContactRosterItem::FileTransferFeature);
+ }
+ if (featureOracle_->isWhiteboardSupported(jid.toBare()) == Tristate::Yes) {
+ features.insert(ContactRosterItem::WhiteboardFeature);
+ }
+ roster_->applyOnItems(SetAvailableFeatures(jid, features));
}
}
diff --git a/Swift/Controllers/Roster/RosterController.h b/Swift/Controllers/Roster/RosterController.h
index 545abfc..ca2ecdc 100644
--- a/Swift/Controllers/Roster/RosterController.h
+++ b/Swift/Controllers/Roster/RosterController.h
@@ -1,18 +1,18 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <memory>
#include <set>
#include <string>
-#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
#include <Swiften/Avatars/AvatarManager.h>
-#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Elements/ErrorPayload.h>
#include <Swiften/Elements/Presence.h>
#include <Swiften/Elements/RosterPayload.h>
@@ -23,104 +23,104 @@
#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class AvatarManager;
- class ClientBlockListManager;
- class EntityCapsProvider;
- class EventController;
- class FileTransferManager;
- class FileTransferOverview;
- class IQRouter;
- class MainWindow;
- class MainWindowFactory;
- class NickManager;
- class NickResolver;
- class OfflineRosterFilter;
- class PresenceOracle;
- class Roster;
- class RosterGroupExpandinessPersister;
- class RosterVCardProvider;
- class SettingsProvider;
- class SubscriptionManager;
- class SubscriptionRequestEvent;
- class UIEventStream;
- class VCardManager;
- class XMPPRoster;
- class XMPPRosterItem;
+ class AvatarManager;
+ class ClientBlockListManager;
+ class EntityCapsProvider;
+ class EventController;
+ class FeatureOracle;
+ class FileTransferManager;
+ class IQRouter;
+ class MainWindow;
+ class MainWindowFactory;
+ class NickManager;
+ class NickResolver;
+ class OfflineRosterFilter;
+ class PresenceOracle;
+ class Roster;
+ class RosterGroupExpandinessPersister;
+ class RosterVCardProvider;
+ class SettingsProvider;
+ class SubscriptionManager;
+ class SubscriptionRequestEvent;
+ class UIEventStream;
+ class VCardManager;
+ class XMPPRoster;
+ class XMPPRosterItem;
- class RosterController {
- public:
- RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter, SettingsProvider* settings, EntityCapsProvider* entityCapsProvider, FileTransferOverview* fileTransferOverview, ClientBlockListManager* clientBlockListManager, VCardManager* vcardManager);
- ~RosterController();
- void showRosterWindow();
- void setJID(const JID& jid) { myJID_ = jid; }
- MainWindow* getWindow() {return mainWindow_;}
- boost::signal<void (StatusShow::Type, const std::string&)> onChangeStatusRequest;
- boost::signal<void ()> onSignOutRequest;
- void handleOwnVCardChanged(VCard::ref vcard);
- void handleAvatarChanged(const JID& jid);
- void handlePresenceChanged(Presence::ref presence);
- void setEnabled(bool enabled);
+ class RosterController {
+ public:
+ RosterController(const JID& jid, XMPPRoster* xmppRoster, AvatarManager* avatarManager, MainWindowFactory* mainWindowFactory, NickManager* nickManager, NickResolver* nickResolver, PresenceOracle* presenceOracle, SubscriptionManager* subscriptionManager, EventController* eventController, UIEventStream* uiEventStream, IQRouter* iqRouter, SettingsProvider* settings, EntityCapsProvider* entityCapsProvider, ClientBlockListManager* clientBlockListManager, VCardManager* vcardManager);
+ ~RosterController();
+ void showRosterWindow();
+ void setJID(const JID& jid) { myJID_ = jid; }
+ MainWindow* getWindow() {return mainWindow_;}
+ boost::signals2::signal<void (StatusShow::Type, const std::string&)> onChangeStatusRequest;
+ boost::signals2::signal<void ()> onSignOutRequest;
+ void handleOwnVCardChanged(VCard::ref vcard);
+ void handleAvatarChanged(const JID& jid);
+ void handlePresenceChanged(Presence::ref presence);
+ void setEnabled(bool enabled);
- boost::optional<XMPPRosterItem> getItem(const JID&) const;
- std::set<std::string> getGroups() const;
+ boost::optional<XMPPRosterItem> getItem(const JID&) const;
+ std::set<std::string> getGroups() const;
- void setContactGroups(const JID& jid, const std::vector<std::string>& groups);
- void updateItem(const XMPPRosterItem&);
+ void setContactGroups(const JID& jid, const std::vector<std::string>& groups);
+ void updateItem(const XMPPRosterItem&);
- void initBlockingCommand();
+ void initBlockingCommand();
- private:
- void handleOnJIDAdded(const JID &jid);
- void handleRosterCleared();
- void handleOnJIDRemoved(const JID &jid);
- void handleOnJIDUpdated(const JID &jid, const std::string& oldName, const std::vector<std::string>& oldGroups);
- void handleStartChatRequest(const JID& contact);
- void handleChangeStatusRequest(StatusShow::Type show, const std::string &statusText);
- void handleShowOfflineToggled(bool state);
- void handleIncomingPresence(boost::shared_ptr<Presence> newPresence);
- void handleSubscriptionRequest(const JID& jid, const std::string& message);
- void handleSubscriptionRequestAccepted(SubscriptionRequestEvent* event);
- void handleSubscriptionRequestDeclined(SubscriptionRequestEvent* event);
- void handleUIEvent(boost::shared_ptr<UIEvent> event);
- void handleRosterItemUpdated(ErrorPayload::ref error, boost::shared_ptr<RosterPayload> rosterPayload);
- void handleRosterSetError(ErrorPayload::ref error, boost::shared_ptr<RosterPayload> rosterPayload);
- void applyAllPresenceTo(const JID& jid);
- void handleEditProfileRequest();
- void handleOnCapsChanged(const JID& jid);
- void handleSettingChanged(const std::string& settingPath);
+ private:
+ void handleOnJIDAdded(const JID &jid);
+ void handleRosterCleared();
+ void handleOnJIDRemoved(const JID &jid);
+ void handleOnJIDUpdated(const JID &jid, const std::string& oldName, const std::vector<std::string>& oldGroups);
+ void handleStartChatRequest(const JID& contact);
+ void handleChangeStatusRequest(StatusShow::Type show, const std::string &statusText);
+ void handleShowOfflineToggled(bool state);
+ void handleIncomingPresence(std::shared_ptr<Presence> newPresence);
+ void handleSubscriptionRequest(const JID& jid, const std::string& message);
+ void handleSubscriptionRequestAccepted(SubscriptionRequestEvent* event);
+ void handleSubscriptionRequestDeclined(SubscriptionRequestEvent* event);
+ void handleUIEvent(std::shared_ptr<UIEvent> event);
+ void handleRosterItemUpdated(ErrorPayload::ref error, std::shared_ptr<RosterPayload> rosterPayload);
+ void handleRosterSetError(ErrorPayload::ref error, std::shared_ptr<RosterPayload> rosterPayload);
+ void applyAllPresenceTo(const JID& jid);
+ void handleEditProfileRequest();
+ void handleOnCapsChanged(const JID& jid);
+ void handleSettingChanged(const std::string& settingPath);
- void handleBlockingStateChanged();
- void handleBlockingItemAdded(const JID& jid);
- void handleBlockingItemRemoved(const JID& jid);
+ void handleBlockingStateChanged();
+ void handleBlockingItemAdded(const JID& jid);
+ void handleBlockingItemRemoved(const JID& jid);
- JID myJID_;
- XMPPRoster* xmppRoster_;
- MainWindowFactory* mainWindowFactory_;
- MainWindow* mainWindow_;
- Roster* roster_;
- OfflineRosterFilter* offlineFilter_;
- VCardManager* vcardManager_;
- AvatarManager* avatarManager_;
- NickManager* nickManager_;
- NickResolver* nickResolver_;
- PresenceOracle* presenceOracle_;
- SubscriptionManager* subscriptionManager_;
- EventController* eventController_;
- RosterGroupExpandinessPersister* expandiness_;
- IQRouter* iqRouter_;
- SettingsProvider* settings_;
- UIEventStream* uiEventStream_;
- EntityCapsProvider* entityCapsManager_;
- FileTransferOverview* ftOverview_;
- ClientBlockListManager* clientBlockListManager_;
- RosterVCardProvider* rosterVCardProvider_;
- boost::shared_ptr<ContactRosterItem> ownContact_;
-
- boost::bsignals::scoped_connection blockingOnStateChangedConnection_;
- boost::bsignals::scoped_connection blockingOnItemAddedConnection_;
- boost::bsignals::scoped_connection blockingOnItemRemovedConnection_;
- boost::bsignals::scoped_connection changeStatusConnection_;
- boost::bsignals::scoped_connection signOutConnection_;
- boost::bsignals::scoped_connection uiEventConnection_;
- };
+ JID myJID_;
+ XMPPRoster* xmppRoster_;
+ MainWindowFactory* mainWindowFactory_;
+ MainWindow* mainWindow_;
+ Roster* roster_;
+ OfflineRosterFilter* offlineFilter_;
+ VCardManager* vcardManager_;
+ AvatarManager* avatarManager_;
+ NickManager* nickManager_;
+ NickResolver* nickResolver_;
+ PresenceOracle* presenceOracle_;
+ SubscriptionManager* subscriptionManager_;
+ EventController* eventController_;
+ RosterGroupExpandinessPersister* expandiness_;
+ IQRouter* iqRouter_;
+ SettingsProvider* settings_;
+ UIEventStream* uiEventStream_;
+ EntityCapsProvider* entityCapsManager_;
+ ClientBlockListManager* clientBlockListManager_;
+ RosterVCardProvider* rosterVCardProvider_;
+ std::shared_ptr<ContactRosterItem> ownContact_;
+ std::unique_ptr<FeatureOracle> featureOracle_;
+
+ boost::signals2::scoped_connection blockingOnStateChangedConnection_;
+ boost::signals2::scoped_connection blockingOnItemAddedConnection_;
+ boost::signals2::scoped_connection blockingOnItemRemovedConnection_;
+ boost::signals2::scoped_connection changeStatusConnection_;
+ boost::signals2::scoped_connection signOutConnection_;
+ boost::signals2::scoped_connection uiEventConnection_;
+ };
}
diff --git a/Swift/Controllers/Roster/RosterFilter.h b/Swift/Controllers/Roster/RosterFilter.h
index 8712569..6075c66 100644
--- a/Swift/Controllers/Roster/RosterFilter.h
+++ b/Swift/Controllers/Roster/RosterFilter.h
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/Roster/RosterItem.h"
+#include <Swift/Controllers/Roster/RosterItem.h>
namespace Swift {
class RosterFilter {
- public:
- virtual ~RosterFilter() {}
- virtual bool operator() (RosterItem* item) const = 0;
+ public:
+ virtual ~RosterFilter() {}
+ virtual bool operator() (RosterItem* item) const = 0;
};
}
diff --git a/Swift/Controllers/Roster/RosterGroupExpandinessPersister.cpp b/Swift/Controllers/Roster/RosterGroupExpandinessPersister.cpp
index 79ad812..0f07c0b 100644
--- a/Swift/Controllers/Roster/RosterGroupExpandinessPersister.cpp
+++ b/Swift/Controllers/Roster/RosterGroupExpandinessPersister.cpp
@@ -1,61 +1,62 @@
/*
- * Copyright (c) 2010-2012 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/Roster/RosterGroupExpandinessPersister.h>
-#include <boost/bind.hpp>
#include <vector>
-#include <Swiften/Base/foreach.h>
+#include <boost/bind.hpp>
+
#include <Swiften/Base/String.h>
+
#include <Swift/Controllers/Roster/GroupRosterItem.h>
#include <Swift/Controllers/SettingConstants.h>
namespace Swift {
RosterGroupExpandinessPersister::RosterGroupExpandinessPersister(Roster* roster, SettingsProvider* settings) : roster_(roster), settings_(settings) {
- load();
- roster_->onGroupAdded.connect(boost::bind(&RosterGroupExpandinessPersister::handleGroupAdded, this, _1));
+ load();
+ roster_->onGroupAdded.connect(boost::bind(&RosterGroupExpandinessPersister::handleGroupAdded, this, _1));
}
void RosterGroupExpandinessPersister::handleGroupAdded(GroupRosterItem* group) {
- if (collapsed_.find(group->getDisplayName()) != collapsed_.end()) {
- group->setExpanded(false);
- } else {
- group->setExpanded(true);
- }
- group->onExpandedChanged.connect(boost::bind(&RosterGroupExpandinessPersister::handleExpandedChanged, this, group, _1));
+ if (collapsed_.find(group->getDisplayName()) != collapsed_.end()) {
+ group->setExpanded(false);
+ } else {
+ group->setExpanded(true);
+ }
+ group->onExpandedChanged.connect(boost::bind(&RosterGroupExpandinessPersister::handleExpandedChanged, this, group, _1));
}
void RosterGroupExpandinessPersister::handleExpandedChanged(GroupRosterItem* group, bool expanded) {
- if (expanded) {
- std::string displayName = group->getDisplayName();
- //collapsed_.erase(std::remove(collapsed_.begin(), collapsed_.end(), displayName), collapsed_.end());
- collapsed_.erase(displayName);
- } else {
- collapsed_.insert(group->getDisplayName());
- }
- save();
+ if (expanded) {
+ std::string displayName = group->getDisplayName();
+ //collapsed_.erase(std::remove(collapsed_.begin(), collapsed_.end(), displayName), collapsed_.end());
+ collapsed_.erase(displayName);
+ } else {
+ collapsed_.insert(group->getDisplayName());
+ }
+ save();
}
void RosterGroupExpandinessPersister::save() {
- std::string setting;
- foreach (const std::string& group, collapsed_) {
- if (!setting.empty()) {
- setting += "\n";
- }
- setting += group;
- }
- settings_->storeSetting(SettingConstants::EXPANDED_ROSTER_GROUPS, setting);
+ std::string setting;
+ for (const auto& group : collapsed_) {
+ if (!setting.empty()) {
+ setting += "\n";
+ }
+ setting += group;
+ }
+ settings_->storeSetting(SettingConstants::EXPANDED_ROSTER_GROUPS, setting);
}
void RosterGroupExpandinessPersister::load() {
- std::string saved = settings_->getSetting(SettingConstants::EXPANDED_ROSTER_GROUPS);
- std::vector<std::string> collapsed = String::split(saved, '\n');
- collapsed_.insert(collapsed.begin(), collapsed.end());
+ std::string saved = settings_->getSetting(SettingConstants::EXPANDED_ROSTER_GROUPS);
+ std::vector<std::string> collapsed = String::split(saved, '\n');
+ collapsed_.insert(collapsed.begin(), collapsed.end());
}
diff --git a/Swift/Controllers/Roster/RosterGroupExpandinessPersister.h b/Swift/Controllers/Roster/RosterGroupExpandinessPersister.h
index 6addc81..4cc08a7 100644
--- a/Swift/Controllers/Roster/RosterGroupExpandinessPersister.h
+++ b/Swift/Controllers/Roster/RosterGroupExpandinessPersister.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2012 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,20 +7,21 @@
#pragma once
#include <set>
-#include "Swift/Controllers/Roster/Roster.h"
-#include "Swift/Controllers/Settings/SettingsProvider.h"
+
+#include <Swift/Controllers/Roster/Roster.h>
+#include <Swift/Controllers/Settings/SettingsProvider.h>
namespace Swift {
- class RosterGroupExpandinessPersister {
- public:
- RosterGroupExpandinessPersister(Roster* roster, SettingsProvider* settings);
- private:
- void handleExpandedChanged(GroupRosterItem* group, bool expanded);
- void handleGroupAdded(GroupRosterItem* group);
- void load();
- void save();
- std::set<std::string> collapsed_;
- Roster* roster_;
- SettingsProvider* settings_;
- };
+ class RosterGroupExpandinessPersister {
+ public:
+ RosterGroupExpandinessPersister(Roster* roster, SettingsProvider* settings);
+ private:
+ void handleExpandedChanged(GroupRosterItem* group, bool expanded);
+ void handleGroupAdded(GroupRosterItem* group);
+ void load();
+ void save();
+ std::set<std::string> collapsed_;
+ Roster* roster_;
+ SettingsProvider* settings_;
+ };
}
diff --git a/Swift/Controllers/Roster/RosterItem.cpp b/Swift/Controllers/Roster/RosterItem.cpp
index 7864fd9..685613f 100644
--- a/Swift/Controllers/Roster/RosterItem.cpp
+++ b/Swift/Controllers/Roster/RosterItem.cpp
@@ -1,22 +1,22 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/Controllers/Roster/RosterItem.h"
+#include <Swift/Controllers/Roster/RosterItem.h>
#include <boost/algorithm/string.hpp>
-#include "Swift/Controllers/Roster/GroupRosterItem.h"
+#include <Swift/Controllers/Roster/GroupRosterItem.h>
namespace Swift {
RosterItem::RosterItem(const std::string& name, GroupRosterItem* parent) : name_(name), sortableDisplayName_(boost::to_lower_copy(name_)), parent_(parent) {
- /* The following would be good, but because of C++'s inheritance not working in constructors, it's not going to work. */
- //if (parent) {
- // parent_->addChild(this);
- //}
+ /* The following would be good, but because of C++'s inheritance not working in constructors, it's not going to work. */
+ //if (parent) {
+ // parent_->addChild(this);
+ //}
}
RosterItem::~RosterItem() {
@@ -24,21 +24,21 @@ RosterItem::~RosterItem() {
}
GroupRosterItem* RosterItem::getParent() const {
- return parent_;
+ return parent_;
}
void RosterItem::setDisplayName(const std::string& name) {
- name_ = name;
- sortableDisplayName_ = boost::to_lower_copy(name_);
- onDataChanged();
+ name_ = name;
+ sortableDisplayName_ = boost::to_lower_copy(name_);
+ onDataChanged();
}
const std::string& RosterItem::getDisplayName() const {
- return name_;
+ return name_;
}
const std::string& RosterItem::getSortableDisplayName() const {
- return sortableDisplayName_;
+ return sortableDisplayName_;
}
diff --git a/Swift/Controllers/Roster/RosterItem.h b/Swift/Controllers/Roster/RosterItem.h
index 84cba2c..b834785 100644
--- a/Swift/Controllers/Roster/RosterItem.h
+++ b/Swift/Controllers/Roster/RosterItem.h
@@ -1,31 +1,31 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swiften/Base/boost_bsignals.h"
-#include <boost/shared_ptr.hpp>
-
+#include <memory>
#include <string>
+#include <boost/signals2.hpp>
+
namespace Swift {
class GroupRosterItem;
class RosterItem {
- public:
- RosterItem(const std::string& name, GroupRosterItem* parent);
- virtual ~RosterItem();
- boost::signal<void ()> onDataChanged;
- GroupRosterItem* getParent() const;
- void setDisplayName(const std::string& name);
- const std::string& getDisplayName() const;
- virtual const std::string& getSortableDisplayName() const;
- private:
- std::string name_;
- std::string sortableDisplayName_;
- GroupRosterItem* parent_;
+ public:
+ RosterItem(const std::string& name, GroupRosterItem* parent);
+ virtual ~RosterItem();
+ boost::signals2::signal<void ()> onDataChanged;
+ GroupRosterItem* getParent() const;
+ void setDisplayName(const std::string& name);
+ const std::string& getDisplayName() const;
+ virtual const std::string& getSortableDisplayName() const;
+ private:
+ std::string name_;
+ std::string sortableDisplayName_;
+ GroupRosterItem* parent_;
};
}
diff --git a/Swift/Controllers/Roster/RosterVCardProvider.cpp b/Swift/Controllers/Roster/RosterVCardProvider.cpp
index 954ac68..2aa82a9 100644
--- a/Swift/Controllers/Roster/RosterVCardProvider.cpp
+++ b/Swift/Controllers/Roster/RosterVCardProvider.cpp
@@ -4,32 +4,38 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#include <Swift/Controllers/Roster/RosterVCardProvider.h>
#include <Swiften/VCards/VCardManager.h>
-#include <Swift/Controllers/Roster/Roster.h>
#include <Swift/Controllers/Roster/ItemOperations/SetVCard.h>
+#include <Swift/Controllers/Roster/Roster.h>
namespace Swift {
RosterVCardProvider::RosterVCardProvider(Roster* roster, VCardManager* vcardManager, JID::CompareType compareType) : roster_(roster), vcardManager_(vcardManager), compareType_(compareType) {
- vcardUpdateRequestedConnection = roster_->onVCardUpdateRequested.connect(boost::bind(&RosterVCardProvider::handleVCardUpdateRequested, this, _1));
- vcardChangedConnection = vcardManager_->onVCardChanged.connect(boost::bind(&RosterVCardProvider::handleVCardChanged, this, _1, _2));
+ vcardUpdateRequestedConnection = roster_->onVCardUpdateRequested.connect(boost::bind(&RosterVCardProvider::handleVCardUpdateRequested, this, _1));
+ vcardChangedConnection = vcardManager_->onVCardChanged.connect(boost::bind(&RosterVCardProvider::handleVCardChanged, this, _1, _2));
}
RosterVCardProvider::~RosterVCardProvider() {
}
void RosterVCardProvider::handleVCardUpdateRequested(const JID& jid) {
- VCard::ref vcard = vcardManager_->getVCardAndRequestWhenNeeded(jid);
- if (vcard) {
- handleVCardChanged(jid, vcard);
- }
+ VCard::ref vcard = vcardManager_->getVCardAndRequestWhenNeeded(jid);
+ if (vcard) {
+ handleVCardChanged(jid, vcard);
+ }
}
void RosterVCardProvider::handleVCardChanged(const JID& jid, VCard::ref vcard) {
- roster_->applyOnItem(SetVCard(jid, vcard, compareType_), jid);
+ roster_->applyOnItem(SetVCard(jid, vcard, compareType_), jid);
}
diff --git a/Swift/Controllers/Roster/RosterVCardProvider.h b/Swift/Controllers/Roster/RosterVCardProvider.h
index da41298..337b0b2 100644
--- a/Swift/Controllers/Roster/RosterVCardProvider.h
+++ b/Swift/Controllers/Roster/RosterVCardProvider.h
@@ -4,11 +4,17 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
-#include <boost/signals/connection.hpp>
+#include <boost/signals2.hpp>
+#include <boost/signals2/connection.hpp>
-#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Elements/VCard.h>
#include <Swiften/JID/JID.h>
@@ -18,20 +24,20 @@ class Roster;
class VCardManager;
class RosterVCardProvider {
- public:
- RosterVCardProvider(Roster* roster, VCardManager* vcardManager, JID::CompareType compareType);
- ~RosterVCardProvider();
-
- private:
- void handleVCardUpdateRequested(const JID& jid);
- void handleVCardChanged(const JID& jid, VCard::ref vcard);
-
- private:
- Roster* roster_;
- VCardManager* vcardManager_;
- JID::CompareType compareType_;
- boost::bsignals::scoped_connection vcardUpdateRequestedConnection;
- boost::bsignals::scoped_connection vcardChangedConnection;
+ public:
+ RosterVCardProvider(Roster* roster, VCardManager* vcardManager, JID::CompareType compareType);
+ ~RosterVCardProvider();
+
+ private:
+ void handleVCardUpdateRequested(const JID& jid);
+ void handleVCardChanged(const JID& jid, VCard::ref vcard);
+
+ private:
+ Roster* roster_;
+ VCardManager* vcardManager_;
+ JID::CompareType compareType_;
+ boost::signals2::scoped_connection vcardUpdateRequestedConnection;
+ boost::signals2::scoped_connection vcardChangedConnection;
};
}
diff --git a/Swift/Controllers/Roster/TableRoster.cpp b/Swift/Controllers/Roster/TableRoster.cpp
index 9f3cd54..713f390 100644
--- a/Swift/Controllers/Roster/TableRoster.cpp
+++ b/Swift/Controllers/Roster/TableRoster.cpp
@@ -1,185 +1,186 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/Roster/TableRoster.h>
-#include <boost/cast.hpp>
-#include <cassert>
#include <algorithm>
+#include <cassert>
+
+#include <boost/cast.hpp>
#include <boost/numeric/conversion/cast.hpp>
-#include <Swiften/Base/foreach.h>
-#include <Swiften/Network/TimerFactory.h>
#include <Swiften/Network/Timer.h>
-#include <Swift/Controllers/Roster/Roster.h>
+#include <Swiften/Network/TimerFactory.h>
+
#include <Swift/Controllers/Roster/GroupRosterItem.h>
#include <Swift/Controllers/Roster/LeastCommonSubsequence.h>
+#include <Swift/Controllers/Roster/Roster.h>
namespace Swift {
- struct SectionNameEquals {
- bool operator()(const TableRoster::Section& s1, const TableRoster::Section& s2) const {
- return s1.name == s2.name;
- }
- };
-
- template<typename T>
- struct True {
- bool operator()(const T&, const T&) const {
- return true;
- }
- };
-
- struct ItemEquals {
- bool operator()(const TableRoster::Item& i1, const TableRoster::Item& i2) const {
- return i1.jid == i2.jid;
- }
- };
-
-
- struct ItemNeedsUpdate {
- bool operator()(const TableRoster::Item& i1, const TableRoster::Item& i2) const {
- return i1.status != i2.status || i1.description != i2.description || i1.name != i2.name || i1.avatarPath.empty() != i2.avatarPath.empty();
- }
- };
-
- struct CreateIndexForSection {
- CreateIndexForSection(size_t section) : section(section) {
- }
-
- TableRoster::Index operator()(size_t row) const {
- return TableRoster::Index(section, row);
- }
-
- size_t section;
- };
+ struct SectionNameEquals {
+ bool operator()(const TableRoster::Section& s1, const TableRoster::Section& s2) const {
+ return s1.name == s2.name;
+ }
+ };
+
+ template<typename T>
+ struct True {
+ bool operator()(const T&, const T&) const {
+ return true;
+ }
+ };
+
+ struct ItemEquals {
+ bool operator()(const TableRoster::Item& i1, const TableRoster::Item& i2) const {
+ return i1.jid == i2.jid;
+ }
+ };
+
+
+ struct ItemNeedsUpdate {
+ bool operator()(const TableRoster::Item& i1, const TableRoster::Item& i2) const {
+ return i1.status != i2.status || i1.description != i2.description || i1.name != i2.name || i1.avatarPath.empty() != i2.avatarPath.empty();
+ }
+ };
+
+ struct CreateIndexForSection {
+ CreateIndexForSection(size_t section) : section(section) {
+ }
+
+ TableRoster::Index operator()(size_t row) const {
+ return TableRoster::Index(section, row);
+ }
+
+ size_t section;
+ };
}
using namespace Swift;
TableRoster::TableRoster(Roster* model, TimerFactory* timerFactory, int updateDelay) : model(model), updatePending(false) {
- updateTimer = timerFactory->createTimer(updateDelay);
- updateTimer->onTick.connect(boost::bind(&TableRoster::handleUpdateTimerTick, this));
- if (model) {
- model->onChildrenChanged.connect(boost::bind(&TableRoster::scheduleUpdate, this));
- model->onGroupAdded.connect(boost::bind(&TableRoster::scheduleUpdate, this));
- model->onDataChanged.connect(boost::bind(&TableRoster::scheduleUpdate, this));
- }
+ updateTimer = timerFactory->createTimer(updateDelay);
+ updateTimer->onTick.connect(boost::bind(&TableRoster::handleUpdateTimerTick, this));
+ if (model) {
+ model->onChildrenChanged.connect(boost::bind(&TableRoster::scheduleUpdate, this));
+ model->onGroupAdded.connect(boost::bind(&TableRoster::scheduleUpdate, this));
+ model->onDataChanged.connect(boost::bind(&TableRoster::scheduleUpdate, this));
+ }
}
TableRoster::~TableRoster() {
- updateTimer->stop();
- updateTimer->onTick.disconnect(boost::bind(&TableRoster::handleUpdateTimerTick, this));
- if (model) {
- model->onDataChanged.disconnect(boost::bind(&TableRoster::scheduleUpdate, this));
- model->onGroupAdded.disconnect(boost::bind(&TableRoster::scheduleUpdate, this));
- model->onChildrenChanged.disconnect(boost::bind(&TableRoster::scheduleUpdate, this));
- }
+ updateTimer->stop();
+ updateTimer->onTick.disconnect(boost::bind(&TableRoster::handleUpdateTimerTick, this));
+ if (model) {
+ model->onDataChanged.disconnect(boost::bind(&TableRoster::scheduleUpdate, this));
+ model->onGroupAdded.disconnect(boost::bind(&TableRoster::scheduleUpdate, this));
+ model->onChildrenChanged.disconnect(boost::bind(&TableRoster::scheduleUpdate, this));
+ }
}
-
+
size_t TableRoster::getNumberOfSections() const {
- return sections.size();
+ return sections.size();
}
const std::string& TableRoster::getSectionTitle(size_t section) {
- return sections[section].name;
+ return sections[section].name;
}
size_t TableRoster::getNumberOfRowsInSection(size_t section) const {
- return sections[section].items.size();
+ return sections[section].items.size();
}
const TableRoster::Item& TableRoster::getItem(const Index& index) const {
- return sections[index.section].items[index.row];
+ return sections[index.section].items[index.row];
}
-
+
void TableRoster::handleUpdateTimerTick() {
- updateTimer->stop();
- updatePending = false;
-
- // Get a model for the new roster
- std::vector<Section> newSections;
- if (model) {
- foreach(RosterItem* item, model->getRoot()->getDisplayedChildren()) {
- if (GroupRosterItem* groupItem = boost::polymorphic_downcast<GroupRosterItem*>(item)) {
- //std::cerr << "* " << groupItem->getDisplayName() << std::endl;
- Section section(groupItem->getDisplayName());
- foreach(RosterItem* groupChildItem, groupItem->getDisplayedChildren()) {
- if (ContactRosterItem* contact = boost::polymorphic_downcast<ContactRosterItem*>(groupChildItem)) {
- //std::cerr << " - " << contact->getDisplayJID() << std::endl;
- section.items.push_back(Item(contact->getDisplayName(), contact->getStatusText(), contact->getDisplayJID(), contact->getStatusShow(), contact->getAvatarPath()));
- }
- }
- newSections.push_back(section);
- }
- }
- }
-
- // Do a diff with the previous roster
- Update update;
- std::vector<size_t> sectionUpdates;
- std::vector<size_t> sectionPostUpdates;
- computeIndexDiff<Section,SectionNameEquals,True<Section> >(sections, newSections, sectionUpdates, sectionPostUpdates, update.deletedSections, update.insertedSections);
- assert(sectionUpdates.size() == sectionPostUpdates.size());
- for (size_t i = 0; i < sectionUpdates.size(); ++i) {
- assert(sectionUpdates[i] < sections.size());
- assert(sectionPostUpdates[i] < newSections.size());
- std::vector<size_t> itemUpdates;
- std::vector<size_t> itemPostUpdates;
- std::vector<size_t> itemRemoves;
- std::vector<size_t> itemInserts;
- computeIndexDiff<Item, ItemEquals, ItemNeedsUpdate >(sections[sectionUpdates[i]].items, newSections[sectionPostUpdates[i]].items, itemUpdates, itemPostUpdates, itemRemoves, itemInserts);
- size_t end = update.insertedRows.size();
- update.insertedRows.resize(update.insertedRows.size() + itemInserts.size());
- std::transform(itemInserts.begin(), itemInserts.end(), update.insertedRows.begin() + boost::numeric_cast<long long>(end), CreateIndexForSection(sectionPostUpdates[i]));
- end = update.deletedRows.size();
- update.deletedRows.resize(update.deletedRows.size() + itemRemoves.size());
- std::transform(itemRemoves.begin(), itemRemoves.end(), update.deletedRows.begin() + boost::numeric_cast<long long>(end), CreateIndexForSection(sectionUpdates[i]));
- end = update.updatedRows.size();
- update.updatedRows.resize(update.updatedRows.size() + itemUpdates.size());
- std::transform(itemUpdates.begin(), itemUpdates.end(), update.updatedRows.begin() + boost::numeric_cast<long long>(end), CreateIndexForSection(sectionPostUpdates[i]));
- }
-
- // Switch the old model with the new
- sections.swap(newSections);
-
- /*
- std::cerr << "-S: ";
- for (size_t i = 0; i < update.deletedSections.size(); ++i) {
- std::cerr << update.deletedSections[i] << " ";
- }
- std::cerr << std::endl;
- std::cerr << "+S: ";
- for (size_t i = 0; i < update.insertedSections.size(); ++i) {
- std::cerr << update.insertedSections[i] << " ";
- }
- std::cerr << std::endl;
- std::cerr << "-R: ";
- for (size_t i = 0; i < update.deletedRows.size(); ++i) {
- std::cerr << update.deletedRows[i].section << "," << update.deletedRows[i].row << " ";
- }
- std::cerr << std::endl;
- std::cerr << "*R: ";
- for (size_t i = 0; i < update.updatedRows.size(); ++i) {
- std::cerr << update.updatedRows[i].section << "," << update.updatedRows[i].row << " ";
- }
- std::cerr << std::endl;
- std::cerr << "+R: ";
- for (size_t i = 0; i < update.insertedRows.size(); ++i) {
- std::cerr << update.insertedRows[i].section << "," << update.insertedRows[i].row << " ";
- }
- std::cerr << std::endl;
- */
-
- // Emit the update
- onUpdate(update);
+ updateTimer->stop();
+ updatePending = false;
+
+ // Get a model for the new roster
+ std::vector<Section> newSections;
+ if (model) {
+ for (auto item : model->getRoot()->getDisplayedChildren()) {
+ if (GroupRosterItem* groupItem = boost::polymorphic_downcast<GroupRosterItem*>(item)) {
+ //std::cerr << "* " << groupItem->getDisplayName() << std::endl;
+ Section section(groupItem->getDisplayName());
+ for (auto groupChildItem : groupItem->getDisplayedChildren()) {
+ if (ContactRosterItem* contact = boost::polymorphic_downcast<ContactRosterItem*>(groupChildItem)) {
+ //std::cerr << " - " << contact->getDisplayJID() << std::endl;
+ section.items.push_back(Item(contact->getDisplayName(), contact->getStatusText(), contact->getDisplayJID(), contact->getStatusShow(), contact->getAvatarPath()));
+ }
+ }
+ newSections.push_back(section);
+ }
+ }
+ }
+
+ // Do a diff with the previous roster
+ Update update;
+ std::vector<size_t> sectionUpdates;
+ std::vector<size_t> sectionPostUpdates;
+ computeIndexDiff<Section,SectionNameEquals,True<Section> >(sections, newSections, sectionUpdates, sectionPostUpdates, update.deletedSections, update.insertedSections);
+ assert(sectionUpdates.size() == sectionPostUpdates.size());
+ for (size_t i = 0; i < sectionUpdates.size(); ++i) {
+ assert(sectionUpdates[i] < sections.size());
+ assert(sectionPostUpdates[i] < newSections.size());
+ std::vector<size_t> itemUpdates;
+ std::vector<size_t> itemPostUpdates;
+ std::vector<size_t> itemRemoves;
+ std::vector<size_t> itemInserts;
+ computeIndexDiff<Item, ItemEquals, ItemNeedsUpdate >(sections[sectionUpdates[i]].items, newSections[sectionPostUpdates[i]].items, itemUpdates, itemPostUpdates, itemRemoves, itemInserts);
+ size_t end = update.insertedRows.size();
+ update.insertedRows.resize(update.insertedRows.size() + itemInserts.size());
+ std::transform(itemInserts.begin(), itemInserts.end(), update.insertedRows.begin() + boost::numeric_cast<long long>(end), CreateIndexForSection(sectionPostUpdates[i]));
+ end = update.deletedRows.size();
+ update.deletedRows.resize(update.deletedRows.size() + itemRemoves.size());
+ std::transform(itemRemoves.begin(), itemRemoves.end(), update.deletedRows.begin() + boost::numeric_cast<long long>(end), CreateIndexForSection(sectionUpdates[i]));
+ end = update.updatedRows.size();
+ update.updatedRows.resize(update.updatedRows.size() + itemUpdates.size());
+ std::transform(itemUpdates.begin(), itemUpdates.end(), update.updatedRows.begin() + boost::numeric_cast<long long>(end), CreateIndexForSection(sectionPostUpdates[i]));
+ }
+
+ // Switch the old model with the new
+ sections.swap(newSections);
+
+ /*
+ std::cerr << "-S: ";
+ for (size_t i = 0; i < update.deletedSections.size(); ++i) {
+ std::cerr << update.deletedSections[i] << " ";
+ }
+ std::cerr << std::endl;
+ std::cerr << "+S: ";
+ for (size_t i = 0; i < update.insertedSections.size(); ++i) {
+ std::cerr << update.insertedSections[i] << " ";
+ }
+ std::cerr << std::endl;
+ std::cerr << "-R: ";
+ for (size_t i = 0; i < update.deletedRows.size(); ++i) {
+ std::cerr << update.deletedRows[i].section << "," << update.deletedRows[i].row << " ";
+ }
+ std::cerr << std::endl;
+ std::cerr << "*R: ";
+ for (size_t i = 0; i < update.updatedRows.size(); ++i) {
+ std::cerr << update.updatedRows[i].section << "," << update.updatedRows[i].row << " ";
+ }
+ std::cerr << std::endl;
+ std::cerr << "+R: ";
+ for (size_t i = 0; i < update.insertedRows.size(); ++i) {
+ std::cerr << update.insertedRows[i].section << "," << update.insertedRows[i].row << " ";
+ }
+ std::cerr << std::endl;
+ */
+
+ // Emit the update
+ onUpdate(update);
}
void TableRoster::scheduleUpdate() {
- if (!updatePending) {
- updatePending = true;
- updateTimer->start();
- }
+ if (!updatePending) {
+ updatePending = true;
+ updateTimer->start();
+ }
}
diff --git a/Swift/Controllers/Roster/TableRoster.h b/Swift/Controllers/Roster/TableRoster.h
index f0010f5..22c9ca9 100644
--- a/Swift/Controllers/Roster/TableRoster.h
+++ b/Swift/Controllers/Roster/TableRoster.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,77 +8,78 @@
#include <string>
#include <vector>
-#include <Swiften/Base/boost_bsignals.h>
-#include <Swiften/JID/JID.h>
-#include <Swiften/Elements/StatusShow.h>
#include <boost/filesystem/path.hpp>
+#include <boost/signals2.hpp>
+
+#include <Swiften/Elements/StatusShow.h>
+#include <Swiften/JID/JID.h>
namespace Swift {
- class Roster;
- class TimerFactory;
- class Timer;
-
- class TableRoster {
- public:
- struct Item {
- Item(const std::string& name, const std::string& description, const JID& jid, StatusShow::Type status, const boost::filesystem::path& avatarPath) : name(name), description(description), jid(jid), status(status), avatarPath(avatarPath) {
- }
- std::string name;
- std::string description;
- JID jid;
- StatusShow::Type status;
- boost::filesystem::path avatarPath;
- };
-
- struct Index {
- Index(size_t section = 0, size_t row = 0) : section(section), row(row) {
- }
- size_t section;
- size_t row;
-
- bool operator==(const Index& o) const {
- return o.section == section && o.row == row;
- }
- };
-
- struct Update {
- std::vector<Index> updatedRows;
- std::vector<Index> insertedRows;
- std::vector<Index> deletedRows;
- std::vector<size_t> insertedSections;
- std::vector<size_t> deletedSections;
- };
-
- TableRoster(Roster* model, TimerFactory* timerFactory, int updateDelay);
- ~TableRoster();
-
- size_t getNumberOfSections() const;
- size_t getNumberOfRowsInSection(size_t section) const;
-
- const std::string& getSectionTitle(size_t);
-
- const Item& getItem(const Index&) const;
-
- boost::signal<void (const Update&)> onUpdate;
-
- private:
- void handleUpdateTimerTick();
- void scheduleUpdate();
-
- private:
- friend struct SectionNameEquals;
- struct Section {
- Section(const std::string& name) : name(name) {
- }
-
- std::string name;
- std::vector<Item> items;
- };
-
- Roster* model;
- std::vector<Section> sections;
- bool updatePending;
- boost::shared_ptr<Timer> updateTimer;
- };
+ class Roster;
+ class TimerFactory;
+ class Timer;
+
+ class TableRoster {
+ public:
+ struct Item {
+ Item(const std::string& name, const std::string& description, const JID& jid, StatusShow::Type status, const boost::filesystem::path& avatarPath) : name(name), description(description), jid(jid), status(status), avatarPath(avatarPath) {
+ }
+ std::string name;
+ std::string description;
+ JID jid;
+ StatusShow::Type status;
+ boost::filesystem::path avatarPath;
+ };
+
+ struct Index {
+ Index(size_t section = 0, size_t row = 0) : section(section), row(row) {
+ }
+ size_t section;
+ size_t row;
+
+ bool operator==(const Index& o) const {
+ return o.section == section && o.row == row;
+ }
+ };
+
+ struct Update {
+ std::vector<Index> updatedRows;
+ std::vector<Index> insertedRows;
+ std::vector<Index> deletedRows;
+ std::vector<size_t> insertedSections;
+ std::vector<size_t> deletedSections;
+ };
+
+ TableRoster(Roster* model, TimerFactory* timerFactory, int updateDelay);
+ ~TableRoster();
+
+ size_t getNumberOfSections() const;
+ size_t getNumberOfRowsInSection(size_t section) const;
+
+ const std::string& getSectionTitle(size_t);
+
+ const Item& getItem(const Index&) const;
+
+ boost::signals2::signal<void (const Update&)> onUpdate;
+
+ private:
+ void handleUpdateTimerTick();
+ void scheduleUpdate();
+
+ private:
+ friend struct SectionNameEquals;
+ struct Section {
+ Section(const std::string& name) : name(name) {
+ }
+
+ std::string name;
+ std::vector<Item> items;
+ };
+
+ Roster* model;
+ std::vector<Section> sections;
+ bool updatePending;
+ std::shared_ptr<Timer> updateTimer;
+ };
}
diff --git a/Swift/Controllers/Roster/UnitTest/LeastCommonSubsequenceTest.cpp b/Swift/Controllers/Roster/UnitTest/LeastCommonSubsequenceTest.cpp
index 996b460..5844ebe 100644
--- a/Swift/Controllers/Roster/UnitTest/LeastCommonSubsequenceTest.cpp
+++ b/Swift/Controllers/Roster/UnitTest/LeastCommonSubsequenceTest.cpp
@@ -1,308 +1,311 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include <boost/assign/list_of.hpp>
#include <functional>
+#include <boost/assign/list_of.hpp>
+
#include <QA/Checker/IO.h>
+
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
+
#include <Swift/Controllers/Roster/LeastCommonSubsequence.h>
using namespace Swift;
struct IsBOrC {
- bool operator()(char c, char c2) const {
- CPPUNIT_ASSERT_EQUAL(c, c2);
- return c == 'b' || c == 'c';
- }
+ bool operator()(char c, char c2) const {
+ CPPUNIT_ASSERT_EQUAL(c, c2);
+ return c == 'b' || c == 'c';
+ }
};
struct IsXOrY {
- bool operator()(char c, char c2) const {
- CPPUNIT_ASSERT_EQUAL(c, c2);
- return c == 'x' || c == 'y';
- }
+ bool operator()(char c, char c2) const {
+ CPPUNIT_ASSERT_EQUAL(c, c2);
+ return c == 'x' || c == 'y';
+ }
};
struct IsArizonaOrNewJersey {
- bool operator()(const std::string& s, const std::string& s2) const {
- CPPUNIT_ASSERT_EQUAL(s, s2);
- return s == "Arizona" || s == "New Jersey";
- }
+ bool operator()(const std::string& s, const std::string& s2) const {
+ CPPUNIT_ASSERT_EQUAL(s, s2);
+ return s == "Arizona" || s == "New Jersey";
+ }
};
class LeastCommonSubsequenceTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(LeastCommonSubsequenceTest);
- CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_1);
- CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_2);
- CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_Sequence1Empty);
- CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_Sequence2Empty);
- CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_BothSequencesEmpty);
- CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_NoCommonSequence);
- CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_SameSequences);
- CPPUNIT_TEST(testComputeIndexDiff_1);
- CPPUNIT_TEST(testComputeIndexDiff_2);
- CPPUNIT_TEST(testComputeIndexDiff_Sequence1Empty);
- CPPUNIT_TEST(testComputeIndexDiff_Sequence2Empty);
- CPPUNIT_TEST(testComputeIndexDiff_BothSequencesEmpty);
- CPPUNIT_TEST(testComputeIndexDiff_NoCommonSequence);
- CPPUNIT_TEST(testComputeIndexDiff_SameSequences);
- CPPUNIT_TEST(testComputeIndexDiff_CommonPrefixAndSuffix);
- CPPUNIT_TEST_SUITE_END();
-
- public:
- void testComputeLeastCommonSubsequenceMatrix_1() {
- std::vector<char> x = boost::assign::list_of('x')('m')('j')('y')('a')('u')('z');
- std::vector<char> y = boost::assign::list_of('m')('z')('j')('a')('w')('x')('u');
-
- std::vector<int> result;
- Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result);
-
- std::vector<int> expected = boost::assign::list_of
- (0)(0)(0)(0)(0)(0)(0)(0)
- (0)(0)(1)(1)(1)(1)(1)(1)
- (0)(0)(1)(1)(1)(1)(1)(2)
- (0)(0)(1)(2)(2)(2)(2)(2)
- (0)(0)(1)(2)(2)(3)(3)(3)
- (0)(0)(1)(2)(2)(3)(3)(3)
- (0)(1)(1)(2)(2)(3)(3)(3)
- (0)(1)(1)(2)(2)(3)(4)(4);
- CPPUNIT_ASSERT_EQUAL(expected, result);
- }
-
- void testComputeLeastCommonSubsequenceMatrix_2() {
- std::vector<char> x = boost::assign::list_of('x')('x')('x')('m')('j')('y')('a')('u')('z');
- std::vector<char> y = boost::assign::list_of('m')('z')('j')('a')('w')('x')('u');
-
- std::vector<int> result;
- Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result);
-
- std::vector<int> expected = boost::assign::list_of
- (0)(0)(0)(0)(0)(0)(0)(0)(0)(0)
- (0)(0)(0)(0)(1)(1)(1)(1)(1)(1)
- (0)(0)(0)(0)(1)(1)(1)(1)(1)(2)
- (0)(0)(0)(0)(1)(2)(2)(2)(2)(2)
- (0)(0)(0)(0)(1)(2)(2)(3)(3)(3)
- (0)(0)(0)(0)(1)(2)(2)(3)(3)(3)
- (0)(1)(1)(1)(1)(2)(2)(3)(3)(3)
- (0)(1)(1)(1)(1)(2)(2)(3)(4)(4);
- CPPUNIT_ASSERT_EQUAL(expected, result);
- }
-
- void testComputeLeastCommonSubsequenceMatrix_Sequence1Empty() {
- std::vector<char> x;
- std::vector<char> y = boost::assign::list_of('a')('b')('c');
-
- std::vector<int> result;
- Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result);
-
- std::vector<int> expected = boost::assign::list_of
- (0)
- (0)
- (0)
- (0);
- CPPUNIT_ASSERT_EQUAL(expected, result);
- }
-
- void testComputeLeastCommonSubsequenceMatrix_Sequence2Empty() {
- std::vector<char> x = boost::assign::list_of('a')('b')('c');
- std::vector<char> y;
-
- std::vector<int> result;
- Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result);
-
- std::vector<int> expected = boost::assign::list_of
- (0)(0)(0)(0);
- CPPUNIT_ASSERT_EQUAL(expected, result);
- }
-
- void testComputeLeastCommonSubsequenceMatrix_BothSequencesEmpty() {
- std::vector<char> x;
- std::vector<char> y;
-
- std::vector<int> result;
- Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result);
-
- std::vector<int> expected = boost::assign::list_of(0);
- CPPUNIT_ASSERT_EQUAL(expected, result);
- }
-
- void testComputeLeastCommonSubsequenceMatrix_NoCommonSequence() {
- std::vector<char> x = boost::assign::list_of('a')('b')('c');
- std::vector<char> y = boost::assign::list_of('d')('e')('f')('g');
-
- std::vector<int> result;
- Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result);
-
- std::vector<int> expected = boost::assign::list_of
- (0)(0)(0)(0)
- (0)(0)(0)(0)
- (0)(0)(0)(0)
- (0)(0)(0)(0)
- (0)(0)(0)(0);
- CPPUNIT_ASSERT_EQUAL(expected, result);
- }
-
- void testComputeLeastCommonSubsequenceMatrix_SameSequences() {
- std::vector<char> x = boost::assign::list_of('a')('b')('c');
- std::vector<char> y = boost::assign::list_of('a')('b')('c');
-
- std::vector<int> result;
- Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result);
-
- std::vector<int> expected = boost::assign::list_of
- (0)(0)(0)(0)
- (0)(1)(1)(1)
- (0)(1)(2)(2)
- (0)(1)(2)(3);
- CPPUNIT_ASSERT_EQUAL(expected, result);
- }
-
- void testComputeIndexDiff_1() {
- std::vector<std::string> x = boost::assign::list_of("Arizona")("California")("Delaware")("New Jersey")("Washington");
- std::vector<std::string> y = boost::assign::list_of("Alaska")("Arizona")("California")("Georgia")("New Jersey")("Virginia");
-
- std::vector<size_t> updates;
- std::vector<size_t> postUpdates;
- std::vector<size_t> removes;
- std::vector<size_t> inserts;
- computeIndexDiff<std::string, std::equal_to<std::string>, IsArizonaOrNewJersey >(x, y, updates, postUpdates, removes, inserts);
-
- std::vector<size_t> expectedUpdates = boost::assign::list_of(3)(0);
- std::vector<size_t> expectedPostUpdates = boost::assign::list_of(4)(1);
- std::vector<size_t> expectedRemoves = boost::assign::list_of(4)(2);
- std::vector<size_t> expectedInserts = boost::assign::list_of(5)(3)(0);
- CPPUNIT_ASSERT_EQUAL(expectedUpdates, updates);
- CPPUNIT_ASSERT_EQUAL(expectedPostUpdates, postUpdates);
- CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes);
- CPPUNIT_ASSERT_EQUAL(expectedInserts, inserts);
- }
-
- void testComputeIndexDiff_2() {
- std::vector<char> x = boost::assign::list_of('x')('y');
- std::vector<char> y = boost::assign::list_of('x');
-
- std::vector<size_t> updates;
- std::vector<size_t> postUpdates;
- std::vector<size_t> removes;
- std::vector<size_t> inserts;
- computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts);
-
- std::vector<size_t> expectedRemoves = boost::assign::list_of(1);
- CPPUNIT_ASSERT(updates.empty());
- CPPUNIT_ASSERT(postUpdates.empty());
- CPPUNIT_ASSERT(inserts.empty());
- CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes);
- }
-
- void testComputeIndexDiff_Sequence1Empty() {
- std::vector<char> x;
- std::vector<char> y = boost::assign::list_of('a')('b')('c');
-
- std::vector<size_t> updates;
- std::vector<size_t> postUpdates;
- std::vector<size_t> removes;
- std::vector<size_t> inserts;
- computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts);
-
- std::vector<size_t> expectedInserts = boost::assign::list_of(2)(1)(0);
- CPPUNIT_ASSERT(updates.empty());
- CPPUNIT_ASSERT(postUpdates.empty());
- CPPUNIT_ASSERT(removes.empty());
- CPPUNIT_ASSERT_EQUAL(expectedInserts, inserts);
- }
-
- void testComputeIndexDiff_Sequence2Empty() {
- std::vector<char> x = boost::assign::list_of('a')('b')('c');
- std::vector<char> y;
-
- std::vector<size_t> updates;
- std::vector<size_t> postUpdates;
- std::vector<size_t> removes;
- std::vector<size_t> inserts;
- computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts);
-
- std::vector<size_t> expectedRemoves = boost::assign::list_of(2)(1)(0);
- CPPUNIT_ASSERT(updates.empty());
- CPPUNIT_ASSERT(postUpdates.empty());
- CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes);
- CPPUNIT_ASSERT(inserts.empty());
- }
-
- void testComputeIndexDiff_BothSequencesEmpty() {
- std::vector<char> x;
- std::vector<char> y;
-
- std::vector<size_t> updates;
- std::vector<size_t> postUpdates;
- std::vector<size_t> removes;
- std::vector<size_t> inserts;
- computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts);
-
- CPPUNIT_ASSERT(updates.empty());
- CPPUNIT_ASSERT(postUpdates.empty());
- CPPUNIT_ASSERT(removes.empty());
- CPPUNIT_ASSERT(inserts.empty());
- }
-
- void testComputeIndexDiff_NoCommonSequence() {
- std::vector<char> x = boost::assign::list_of('a')('b')('c');
- std::vector<char> y = boost::assign::list_of('d')('e')('f')('g');
-
- std::vector<size_t> updates;
- std::vector<size_t> postUpdates;
- std::vector<size_t> removes;
- std::vector<size_t> inserts;
- computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts);
-
- std::vector<size_t> expectedRemoves = boost::assign::list_of(2)(1)(0);
- std::vector<size_t> expectedInserts = boost::assign::list_of(3)(2)(1)(0);
- CPPUNIT_ASSERT(updates.empty());
- CPPUNIT_ASSERT(postUpdates.empty());
- CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes);
- CPPUNIT_ASSERT_EQUAL(expectedInserts, inserts);
- }
-
- void testComputeIndexDiff_SameSequences() {
- std::vector<char> x = boost::assign::list_of('a')('b')('c');
- std::vector<char> y = boost::assign::list_of('a')('b')('c');
-
- std::vector<size_t> updates;
- std::vector<size_t> postUpdates;
- std::vector<size_t> removes;
- std::vector<size_t> inserts;
- computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts);
-
- std::vector<size_t> expectedUpdates = boost::assign::list_of(1)(2);
- CPPUNIT_ASSERT_EQUAL(expectedUpdates, updates);
- CPPUNIT_ASSERT_EQUAL(expectedUpdates, postUpdates);
- CPPUNIT_ASSERT(removes.empty());
- CPPUNIT_ASSERT(inserts.empty());
- }
-
- void testComputeIndexDiff_CommonPrefixAndSuffix() {
- std::vector<char> x = boost::assign::list_of('x')('x')('x')('x')('a')('b')('c')('d')('e')('y')('y')('y');
- std::vector<char> y = boost::assign::list_of('x')('x')('x')('x')('e')('a')('b')('f')('d')('g')('y')('y')('y');
-
- std::vector<size_t> updates;
- std::vector<size_t> postUpdates;
- std::vector<size_t> removes;
- std::vector<size_t> inserts;
- computeIndexDiff<char, std::equal_to<char>, IsXOrY >(x, y, updates, postUpdates, removes, inserts);
-
- std::vector<size_t> expectedUpdates = boost::assign::list_of(0)(1)(2)(3)(11)(10)(9);
- std::vector<size_t> expectedPostUpdates = boost::assign::list_of(0)(1)(2)(3)(12)(11)(10);
- std::vector<size_t> expectedRemoves = boost::assign::list_of(8)(6);
- std::vector<size_t> expectedInserts = boost::assign::list_of(9)(7)(4);
- CPPUNIT_ASSERT_EQUAL(expectedUpdates, updates);
- CPPUNIT_ASSERT_EQUAL(expectedPostUpdates, postUpdates);
- CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes);
- CPPUNIT_ASSERT_EQUAL(expectedInserts, inserts);
- }
+ CPPUNIT_TEST_SUITE(LeastCommonSubsequenceTest);
+ CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_1);
+ CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_2);
+ CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_Sequence1Empty);
+ CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_Sequence2Empty);
+ CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_BothSequencesEmpty);
+ CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_NoCommonSequence);
+ CPPUNIT_TEST(testComputeLeastCommonSubsequenceMatrix_SameSequences);
+ CPPUNIT_TEST(testComputeIndexDiff_1);
+ CPPUNIT_TEST(testComputeIndexDiff_2);
+ CPPUNIT_TEST(testComputeIndexDiff_Sequence1Empty);
+ CPPUNIT_TEST(testComputeIndexDiff_Sequence2Empty);
+ CPPUNIT_TEST(testComputeIndexDiff_BothSequencesEmpty);
+ CPPUNIT_TEST(testComputeIndexDiff_NoCommonSequence);
+ CPPUNIT_TEST(testComputeIndexDiff_SameSequences);
+ CPPUNIT_TEST(testComputeIndexDiff_CommonPrefixAndSuffix);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void testComputeLeastCommonSubsequenceMatrix_1() {
+ std::vector<char> x = boost::assign::list_of('x')('m')('j')('y')('a')('u')('z');
+ std::vector<char> y = boost::assign::list_of('m')('z')('j')('a')('w')('x')('u');
+
+ std::vector<int> result;
+ Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result);
+
+ std::vector<int> expected = boost::assign::list_of
+ (0)(0)(0)(0)(0)(0)(0)(0)
+ (0)(0)(1)(1)(1)(1)(1)(1)
+ (0)(0)(1)(1)(1)(1)(1)(2)
+ (0)(0)(1)(2)(2)(2)(2)(2)
+ (0)(0)(1)(2)(2)(3)(3)(3)
+ (0)(0)(1)(2)(2)(3)(3)(3)
+ (0)(1)(1)(2)(2)(3)(3)(3)
+ (0)(1)(1)(2)(2)(3)(4)(4);
+ CPPUNIT_ASSERT_EQUAL(expected, result);
+ }
+
+ void testComputeLeastCommonSubsequenceMatrix_2() {
+ std::vector<char> x = boost::assign::list_of('x')('x')('x')('m')('j')('y')('a')('u')('z');
+ std::vector<char> y = boost::assign::list_of('m')('z')('j')('a')('w')('x')('u');
+
+ std::vector<int> result;
+ Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result);
+
+ std::vector<int> expected = boost::assign::list_of
+ (0)(0)(0)(0)(0)(0)(0)(0)(0)(0)
+ (0)(0)(0)(0)(1)(1)(1)(1)(1)(1)
+ (0)(0)(0)(0)(1)(1)(1)(1)(1)(2)
+ (0)(0)(0)(0)(1)(2)(2)(2)(2)(2)
+ (0)(0)(0)(0)(1)(2)(2)(3)(3)(3)
+ (0)(0)(0)(0)(1)(2)(2)(3)(3)(3)
+ (0)(1)(1)(1)(1)(2)(2)(3)(3)(3)
+ (0)(1)(1)(1)(1)(2)(2)(3)(4)(4);
+ CPPUNIT_ASSERT_EQUAL(expected, result);
+ }
+
+ void testComputeLeastCommonSubsequenceMatrix_Sequence1Empty() {
+ std::vector<char> x;
+ std::vector<char> y = boost::assign::list_of('a')('b')('c');
+
+ std::vector<int> result;
+ Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result);
+
+ std::vector<int> expected = boost::assign::list_of
+ (0)
+ (0)
+ (0)
+ (0);
+ CPPUNIT_ASSERT_EQUAL(expected, result);
+ }
+
+ void testComputeLeastCommonSubsequenceMatrix_Sequence2Empty() {
+ std::vector<char> x = boost::assign::list_of('a')('b')('c');
+ std::vector<char> y;
+
+ std::vector<int> result;
+ Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result);
+
+ std::vector<int> expected = boost::assign::list_of
+ (0)(0)(0)(0);
+ CPPUNIT_ASSERT_EQUAL(expected, result);
+ }
+
+ void testComputeLeastCommonSubsequenceMatrix_BothSequencesEmpty() {
+ std::vector<char> x;
+ std::vector<char> y;
+
+ std::vector<int> result;
+ Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result);
+
+ std::vector<int> expected = boost::assign::list_of(0);
+ CPPUNIT_ASSERT_EQUAL(expected, result);
+ }
+
+ void testComputeLeastCommonSubsequenceMatrix_NoCommonSequence() {
+ std::vector<char> x = boost::assign::list_of('a')('b')('c');
+ std::vector<char> y = boost::assign::list_of('d')('e')('f')('g');
+
+ std::vector<int> result;
+ Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result);
+
+ std::vector<int> expected = boost::assign::list_of
+ (0)(0)(0)(0)
+ (0)(0)(0)(0)
+ (0)(0)(0)(0)
+ (0)(0)(0)(0)
+ (0)(0)(0)(0);
+ CPPUNIT_ASSERT_EQUAL(expected, result);
+ }
+
+ void testComputeLeastCommonSubsequenceMatrix_SameSequences() {
+ std::vector<char> x = boost::assign::list_of('a')('b')('c');
+ std::vector<char> y = boost::assign::list_of('a')('b')('c');
+
+ std::vector<int> result;
+ Detail::computeLeastCommonSubsequenceMatrix<std::vector<char>::const_iterator, std::vector<char>::const_iterator, int, std::equal_to<char> >(x.begin(), x.end(), y.begin(), y.end(), result);
+
+ std::vector<int> expected = boost::assign::list_of
+ (0)(0)(0)(0)
+ (0)(1)(1)(1)
+ (0)(1)(2)(2)
+ (0)(1)(2)(3);
+ CPPUNIT_ASSERT_EQUAL(expected, result);
+ }
+
+ void testComputeIndexDiff_1() {
+ std::vector<std::string> x = boost::assign::list_of("Arizona")("California")("Delaware")("New Jersey")("Washington");
+ std::vector<std::string> y = boost::assign::list_of("Alaska")("Arizona")("California")("Georgia")("New Jersey")("Virginia");
+
+ std::vector<size_t> updates;
+ std::vector<size_t> postUpdates;
+ std::vector<size_t> removes;
+ std::vector<size_t> inserts;
+ computeIndexDiff<std::string, std::equal_to<std::string>, IsArizonaOrNewJersey >(x, y, updates, postUpdates, removes, inserts);
+
+ std::vector<size_t> expectedUpdates = boost::assign::list_of(3)(0);
+ std::vector<size_t> expectedPostUpdates = boost::assign::list_of(4)(1);
+ std::vector<size_t> expectedRemoves = boost::assign::list_of(4)(2);
+ std::vector<size_t> expectedInserts = boost::assign::list_of(5)(3)(0);
+ CPPUNIT_ASSERT_EQUAL(expectedUpdates, updates);
+ CPPUNIT_ASSERT_EQUAL(expectedPostUpdates, postUpdates);
+ CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes);
+ CPPUNIT_ASSERT_EQUAL(expectedInserts, inserts);
+ }
+
+ void testComputeIndexDiff_2() {
+ std::vector<char> x = boost::assign::list_of('x')('y');
+ std::vector<char> y = boost::assign::list_of('x');
+
+ std::vector<size_t> updates;
+ std::vector<size_t> postUpdates;
+ std::vector<size_t> removes;
+ std::vector<size_t> inserts;
+ computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts);
+
+ std::vector<size_t> expectedRemoves = boost::assign::list_of(1);
+ CPPUNIT_ASSERT(updates.empty());
+ CPPUNIT_ASSERT(postUpdates.empty());
+ CPPUNIT_ASSERT(inserts.empty());
+ CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes);
+ }
+
+ void testComputeIndexDiff_Sequence1Empty() {
+ std::vector<char> x;
+ std::vector<char> y = boost::assign::list_of('a')('b')('c');
+
+ std::vector<size_t> updates;
+ std::vector<size_t> postUpdates;
+ std::vector<size_t> removes;
+ std::vector<size_t> inserts;
+ computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts);
+
+ std::vector<size_t> expectedInserts = boost::assign::list_of(2)(1)(0);
+ CPPUNIT_ASSERT(updates.empty());
+ CPPUNIT_ASSERT(postUpdates.empty());
+ CPPUNIT_ASSERT(removes.empty());
+ CPPUNIT_ASSERT_EQUAL(expectedInserts, inserts);
+ }
+
+ void testComputeIndexDiff_Sequence2Empty() {
+ std::vector<char> x = boost::assign::list_of('a')('b')('c');
+ std::vector<char> y;
+
+ std::vector<size_t> updates;
+ std::vector<size_t> postUpdates;
+ std::vector<size_t> removes;
+ std::vector<size_t> inserts;
+ computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts);
+
+ std::vector<size_t> expectedRemoves = boost::assign::list_of(2)(1)(0);
+ CPPUNIT_ASSERT(updates.empty());
+ CPPUNIT_ASSERT(postUpdates.empty());
+ CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes);
+ CPPUNIT_ASSERT(inserts.empty());
+ }
+
+ void testComputeIndexDiff_BothSequencesEmpty() {
+ std::vector<char> x;
+ std::vector<char> y;
+
+ std::vector<size_t> updates;
+ std::vector<size_t> postUpdates;
+ std::vector<size_t> removes;
+ std::vector<size_t> inserts;
+ computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts);
+
+ CPPUNIT_ASSERT(updates.empty());
+ CPPUNIT_ASSERT(postUpdates.empty());
+ CPPUNIT_ASSERT(removes.empty());
+ CPPUNIT_ASSERT(inserts.empty());
+ }
+
+ void testComputeIndexDiff_NoCommonSequence() {
+ std::vector<char> x = boost::assign::list_of('a')('b')('c');
+ std::vector<char> y = boost::assign::list_of('d')('e')('f')('g');
+
+ std::vector<size_t> updates;
+ std::vector<size_t> postUpdates;
+ std::vector<size_t> removes;
+ std::vector<size_t> inserts;
+ computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts);
+
+ std::vector<size_t> expectedRemoves = boost::assign::list_of(2)(1)(0);
+ std::vector<size_t> expectedInserts = boost::assign::list_of(3)(2)(1)(0);
+ CPPUNIT_ASSERT(updates.empty());
+ CPPUNIT_ASSERT(postUpdates.empty());
+ CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes);
+ CPPUNIT_ASSERT_EQUAL(expectedInserts, inserts);
+ }
+
+ void testComputeIndexDiff_SameSequences() {
+ std::vector<char> x = boost::assign::list_of('a')('b')('c');
+ std::vector<char> y = boost::assign::list_of('a')('b')('c');
+
+ std::vector<size_t> updates;
+ std::vector<size_t> postUpdates;
+ std::vector<size_t> removes;
+ std::vector<size_t> inserts;
+ computeIndexDiff<char, std::equal_to<char>, IsBOrC >(x, y, updates, postUpdates, removes, inserts);
+
+ std::vector<size_t> expectedUpdates = boost::assign::list_of(1)(2);
+ CPPUNIT_ASSERT_EQUAL(expectedUpdates, updates);
+ CPPUNIT_ASSERT_EQUAL(expectedUpdates, postUpdates);
+ CPPUNIT_ASSERT(removes.empty());
+ CPPUNIT_ASSERT(inserts.empty());
+ }
+
+ void testComputeIndexDiff_CommonPrefixAndSuffix() {
+ std::vector<char> x = boost::assign::list_of('x')('x')('x')('x')('a')('b')('c')('d')('e')('y')('y')('y');
+ std::vector<char> y = boost::assign::list_of('x')('x')('x')('x')('e')('a')('b')('f')('d')('g')('y')('y')('y');
+
+ std::vector<size_t> updates;
+ std::vector<size_t> postUpdates;
+ std::vector<size_t> removes;
+ std::vector<size_t> inserts;
+ computeIndexDiff<char, std::equal_to<char>, IsXOrY >(x, y, updates, postUpdates, removes, inserts);
+
+ std::vector<size_t> expectedUpdates = boost::assign::list_of(0)(1)(2)(3)(11)(10)(9);
+ std::vector<size_t> expectedPostUpdates = boost::assign::list_of(0)(1)(2)(3)(12)(11)(10);
+ std::vector<size_t> expectedRemoves = boost::assign::list_of(8)(6);
+ std::vector<size_t> expectedInserts = boost::assign::list_of(9)(7)(4);
+ CPPUNIT_ASSERT_EQUAL(expectedUpdates, updates);
+ CPPUNIT_ASSERT_EQUAL(expectedPostUpdates, postUpdates);
+ CPPUNIT_ASSERT_EQUAL(expectedRemoves, removes);
+ CPPUNIT_ASSERT_EQUAL(expectedInserts, inserts);
+ }
};
CPPUNIT_TEST_SUITE_REGISTRATION(LeastCommonSubsequenceTest);
diff --git a/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp b/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp
index d774e6d..ddbd7d3 100644
--- a/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp
+++ b/Swift/Controllers/Roster/UnitTest/RosterControllerTest.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -9,17 +9,19 @@
#include <Swiften/Avatars/NullAvatarManager.h>
#include <Swiften/Base/Algorithm.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Client/ClientBlockListManager.h>
#include <Swiften/Client/DummyNickManager.h>
#include <Swiften/Client/DummyStanzaChannel.h>
+#include <Swiften/Client/MemoryStorages.h>
#include <Swiften/Client/NickResolver.h>
#include <Swiften/Crypto/CryptoProvider.h>
#include <Swiften/Crypto/PlatformCryptoProvider.h>
+#include <Swiften/Disco/CapsInfoGenerator.h>
+#include <Swiften/Disco/CapsManager.h>
#include <Swiften/Disco/CapsProvider.h>
+#include <Swiften/Disco/ClientDiscoManager.h>
#include <Swiften/Disco/EntityCapsManager.h>
#include <Swiften/EventLoop/DummyEventLoop.h>
-#include <Swiften/FileTransfer/UnitTest/DummyFileTransferManager.h>
#include <Swiften/Jingle/JingleSessionManager.h>
#include <Swiften/MUC/MUCRegistry.h>
#include <Swiften/Presence/PresenceOracle.h>
@@ -30,7 +32,6 @@
#include <Swiften/VCards/VCardManager.h>
#include <Swiften/VCards/VCardMemoryStorage.h>
-#include <Swift/Controllers/FileTransfer/FileTransferOverview.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
#include <Swift/Controllers/Roster/GroupRosterItem.h>
#include <Swift/Controllers/Roster/Roster.h>
@@ -43,354 +44,438 @@
using namespace Swift;
-#define CHILDREN mainWindow_->roster->getRoot()->getChildren()
-
class DummyCapsProvider : public CapsProvider {
- DiscoInfo::ref getCaps(const std::string&) const {return DiscoInfo::ref(new DiscoInfo());}
+ DiscoInfo::ref getCaps(const std::string&) const {return DiscoInfo::ref(new DiscoInfo());}
};
class RosterControllerTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(RosterControllerTest);
- CPPUNIT_TEST(testAdd);
- CPPUNIT_TEST(testAddSubscription);
- CPPUNIT_TEST(testReceiveRename);
- CPPUNIT_TEST(testReceiveRegroup);
- CPPUNIT_TEST(testSendRename);
- CPPUNIT_TEST(testPresence);
- CPPUNIT_TEST(testHighestPresence);
- CPPUNIT_TEST(testNotHighestPresence);
- CPPUNIT_TEST(testUnavailablePresence);
- CPPUNIT_TEST(testRemoveResultsInUnavailablePresence);
- CPPUNIT_TEST_SUITE_END();
-
- public:
- void setUp() {
- jid_ = JID("testjid@swift.im/swift");
- xmppRoster_ = new XMPPRosterImpl();
- avatarManager_ = new NullAvatarManager();
- mainWindowFactory_ = new MockMainWindowFactory();
- mucRegistry_ = new MUCRegistry();
- nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, NULL, mucRegistry_);
- channel_ = new DummyIQChannel();
- router_ = new IQRouter(channel_);
- stanzaChannel_ = new DummyStanzaChannel();
- presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_);
- subscriptionManager_ = new SubscriptionManager(stanzaChannel_);
- eventController_ = new EventController();
- uiEventStream_ = new UIEventStream();
- settings_ = new DummySettingsProvider();
- nickManager_ = new DummyNickManager();
- capsProvider_ = new DummyCapsProvider();
- entityCapsManager_ = new EntityCapsManager(capsProvider_, stanzaChannel_);
- jingleSessionManager_ = new JingleSessionManager(router_);
-
- ftManager_ = new DummyFileTransferManager();
- ftOverview_ = new FileTransferOverview(ftManager_);
- clientBlockListManager_ = new ClientBlockListManager(router_);
- crypto_ = PlatformCryptoProvider::create();
- vcardStorage_ = new VCardMemoryStorage(crypto_);
- vcardManager_ = new VCardManager(jid_, router_, vcardStorage_);
- rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, nickManager_, nickResolver_, presenceOracle_, subscriptionManager_, eventController_, uiEventStream_, router_, settings_, entityCapsManager_, ftOverview_, clientBlockListManager_, vcardManager_);
- mainWindow_ = mainWindowFactory_->last;
- }
-
- void tearDown() {
- delete rosterController_;
- delete vcardManager_;
- delete vcardStorage_;
- delete crypto_;
- delete clientBlockListManager_;
- delete ftOverview_;
- delete ftManager_;
- delete jingleSessionManager_;
- delete entityCapsManager_;
- delete capsProvider_;
- delete nickManager_;
- delete nickResolver_;
- delete mucRegistry_;
- delete mainWindowFactory_;
- delete avatarManager_;
- delete router_;
- delete channel_;
- delete eventController_;
- delete subscriptionManager_;
- delete presenceOracle_;
- delete stanzaChannel_;
- delete uiEventStream_;
- delete settings_;
- delete xmppRoster_;
- }
-
- GroupRosterItem* groupChild(size_t i) {
- return dynamic_cast<GroupRosterItem*>(CHILDREN[i]);
- }
-
- JID withResource(const JID& jid, const std::string& resource) {
- return JID(jid.toBare().toString() + "/" + resource);
- }
-
- void testPresence() {
- std::vector<std::string> groups;
- groups.push_back("testGroup1");
- groups.push_back("testGroup2");
- JID from("test@testdomain.com");
- xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both);
- Presence::ref presence(new Presence());
- presence->setFrom(withResource(from, "bob"));
- presence->setPriority(2);
- presence->setStatus("So totally here");
- stanzaChannel_->onPresenceReceived(presence);
- ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[0])->getChildren()[0]);
- CPPUNIT_ASSERT(item);
- CPPUNIT_ASSERT_EQUAL(presence->getStatus(), item->getStatusText());
- ContactRosterItem* item2 = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[1])->getChildren()[0]);
- CPPUNIT_ASSERT(item2);
- CPPUNIT_ASSERT_EQUAL(presence->getStatus(), item2->getStatusText());
-
- }
-
- void testHighestPresence() {
- std::vector<std::string> groups;
- groups.push_back("testGroup1");
- JID from("test@testdomain.com");
- xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both);
- Presence::ref lowPresence(new Presence());
- lowPresence->setFrom(withResource(from, "bob"));
- lowPresence->setPriority(2);
- lowPresence->setStatus("Not here");
- Presence::ref highPresence(new Presence());
- highPresence->setFrom(withResource(from, "bert"));
- highPresence->setPriority(10);
- highPresence->setStatus("So totally here");
- stanzaChannel_->onPresenceReceived(lowPresence);
- stanzaChannel_->onPresenceReceived(highPresence);
- ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[0])->getChildren()[0]);
- CPPUNIT_ASSERT(item);
- CPPUNIT_ASSERT_EQUAL(highPresence->getStatus(), item->getStatusText());
- }
-
- void testNotHighestPresence() {
- std::vector<std::string> groups;
- groups.push_back("testGroup1");
- JID from("test@testdomain.com");
- xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both);
- Presence::ref lowPresence(new Presence());
- lowPresence->setFrom(withResource(from, "bob"));
- lowPresence->setPriority(2);
- lowPresence->setStatus("Not here");
- Presence::ref highPresence(new Presence());
- highPresence->setFrom(withResource(from, "bert"));
- highPresence->setPriority(10);
- highPresence->setStatus("So totally here");
- stanzaChannel_->onPresenceReceived(highPresence);
- stanzaChannel_->onPresenceReceived(lowPresence);
- ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[0])->getChildren()[0]);
- CPPUNIT_ASSERT(item);
- CPPUNIT_ASSERT_EQUAL(highPresence->getStatus(), item->getStatusText());
- }
-
- void testUnavailablePresence() {
- std::vector<std::string> groups;
- groups.push_back("testGroup1");
- JID from("test@testdomain.com");
- xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both);
-
- Presence::ref lowPresence(new Presence());
- lowPresence->setFrom(withResource(from, "bob"));
- lowPresence->setPriority(2);
- lowPresence->setShow(StatusShow::Away);
- lowPresence->setStatus("Not here");
- Presence::ref lowPresenceOffline(new Presence());
- lowPresenceOffline->setFrom(withResource(from, "bob"));
- lowPresenceOffline->setStatus("Signing out");
- lowPresenceOffline->setType(Presence::Unavailable);
-
- Presence::ref highPresence(new Presence());
- highPresence->setFrom(withResource(from, "bert"));
- highPresence->setPriority(10);
- highPresence->setStatus("So totally here");
- Presence::ref highPresenceOffline(new Presence());
- highPresenceOffline->setFrom(withResource(from, "bert"));
- highPresenceOffline->setType(Presence::Unavailable);
-
- stanzaChannel_->onPresenceReceived(lowPresence);
- Presence::ref accountPresence = presenceOracle_->getAccountPresence(from);
- CPPUNIT_ASSERT_EQUAL(StatusShow::Away, accountPresence->getShow());
-
- stanzaChannel_->onPresenceReceived(highPresence);
- accountPresence = presenceOracle_->getAccountPresence(from);
- CPPUNIT_ASSERT_EQUAL(StatusShow::Online, accountPresence->getShow());
-
- stanzaChannel_->onPresenceReceived(highPresenceOffline);
-
- // After this, the roster should show the low presence.
- ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[0])->getChildren()[0]);
- CPPUNIT_ASSERT(item);
-
- Presence::ref low = presenceOracle_->getAccountPresence(from);
-
- CPPUNIT_ASSERT_EQUAL(Presence::Available, low->getType());
- CPPUNIT_ASSERT_EQUAL(lowPresence->getStatus(), low->getStatus());
- CPPUNIT_ASSERT_EQUAL(lowPresence->getShow(), item->getStatusShow());
- CPPUNIT_ASSERT_EQUAL(lowPresence->getStatus(), item->getStatusText());
- stanzaChannel_->onPresenceReceived(lowPresenceOffline);
- item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(CHILDREN[0])->getChildren()[0]);
- CPPUNIT_ASSERT(item);
- /* A verification that if the test fails, it's the RosterController, not the PresenceOracle. */
- low = presenceOracle_->getHighestPriorityPresence(from);
- CPPUNIT_ASSERT_EQUAL(Presence::Unavailable, low->getType());
- CPPUNIT_ASSERT_EQUAL(lowPresenceOffline->getStatus(), low->getStatus());
- CPPUNIT_ASSERT_EQUAL(StatusShow::None, item->getStatusShow());
- CPPUNIT_ASSERT_EQUAL(lowPresenceOffline->getStatus(), item->getStatusText());
- }
-
- void testAdd() {
- std::vector<std::string> groups;
- groups.push_back("testGroup1");
- groups.push_back("testGroup2");
- xmppRoster_->addContact(JID("test@testdomain.com/bob"), "name", groups, RosterItemPayload::Both);
-
- CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(CHILDREN.size()));
- //CPPUNIT_ASSERT_EQUAL(std::string("Bob"), xmppRoster_->getNameForJID(JID("foo@bar.com")));
- }
-
- void testAddSubscription() {
- std::vector<std::string> groups;
- JID jid("test@testdomain.com");
- xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::None);
-
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(CHILDREN.size()));
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
- xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::To);
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(CHILDREN.size()));
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
-
- xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::Both);
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(CHILDREN.size()));
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
-
- }
-
- void testReceiveRename() {
- std::vector<std::string> groups;
- JID jid("test@testdomain.com");
- xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::Both);
-
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(CHILDREN.size()));
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
- CPPUNIT_ASSERT_EQUAL(std::string("name"), groupChild(0)->getChildren()[0]->getDisplayName());
- xmppRoster_->addContact(jid, "NewName", groups, RosterItemPayload::Both);
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(CHILDREN.size()));
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
- CPPUNIT_ASSERT_EQUAL(std::string("NewName"), groupChild(0)->getChildren()[0]->getDisplayName());
- }
-
- void testReceiveRegroup() {
- std::vector<std::string> oldGroups;
- std::vector<std::string> newGroups;
- newGroups.push_back("A Group");
- std::vector<std::string> newestGroups;
- newestGroups.push_back("Best Group");
- JID jid("test@testdomain.com");
- xmppRoster_->addContact(jid, "", oldGroups, RosterItemPayload::Both);
-
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(CHILDREN.size()));
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
- CPPUNIT_ASSERT_EQUAL(jid.toString(), groupChild(0)->getChildren()[0]->getDisplayName());
-
- xmppRoster_->addContact(jid, "new name", newGroups, RosterItemPayload::Both);
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(CHILDREN.size()));
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
- CPPUNIT_ASSERT_EQUAL(std::string("new name"), groupChild(0)->getChildren()[0]->getDisplayName());
- CPPUNIT_ASSERT_EQUAL(std::string("A Group"), groupChild(0)->getDisplayName());
-
- xmppRoster_->addContact(jid, "new name", newestGroups, RosterItemPayload::Both);
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(CHILDREN.size()));
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
- CPPUNIT_ASSERT_EQUAL(std::string("new name"), groupChild(0)->getChildren()[0]->getDisplayName());
- CPPUNIT_ASSERT_EQUAL(std::string("Best Group"), groupChild(0)->getDisplayName());
- }
-
- void testSendRename() {
- JID jid("testling@wonderland.lit");
- std::vector<std::string> groups;
- groups.push_back("Friends");
- groups.push_back("Enemies");
- xmppRoster_->addContact(jid, "Bob", groups, RosterItemPayload::From);
- CPPUNIT_ASSERT_EQUAL(groups.size(), xmppRoster_->getGroupsForJID(jid).size());
- uiEventStream_->send(boost::shared_ptr<UIEvent>(new RenameRosterItemUIEvent(jid, "Robert")));
- CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), channel_->iqs_.size());
- CPPUNIT_ASSERT_EQUAL(IQ::Set, channel_->iqs_[0]->getType());
- boost::shared_ptr<RosterPayload> payload = channel_->iqs_[0]->getPayload<RosterPayload>();
- CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), payload->getItems().size());
- RosterItemPayload item = payload->getItems()[0];
- CPPUNIT_ASSERT_EQUAL(jid, item.getJID());
- CPPUNIT_ASSERT_EQUAL(std::string("Robert"), item.getName());
-
- CPPUNIT_ASSERT_EQUAL(groups.size(), item.getGroups().size());
- assertVectorsEqual(groups, item.getGroups(), __LINE__);
- }
-
- void testRemoveResultsInUnavailablePresence() {
- std::vector<std::string> groups;
- groups.push_back("testGroup1");
- JID from("test@testdomain.com");
- xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both);
- Presence::ref lowPresence(new Presence());
- lowPresence->setFrom(withResource(from, "bob"));
- lowPresence->setPriority(2);
- lowPresence->setStatus("Not here");
- Presence::ref highPresence(new Presence());
- highPresence->setFrom(withResource(from, "bert"));
- highPresence->setPriority(10);
- highPresence->setStatus("So totally here");
- stanzaChannel_->onPresenceReceived(highPresence);
- stanzaChannel_->onPresenceReceived(lowPresence);
-
- CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), presenceOracle_->getAllPresence("test@testdomain.com").size());
-
- xmppRoster_->onJIDRemoved(JID("test@testdomain.com"));
- CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), presenceOracle_->getAllPresence("test@testdomain.com").size());
- CPPUNIT_ASSERT_EQUAL(Presence::Unavailable, presenceOracle_->getAllPresence("test@testdomain.com")[0]->getType());
- }
-
- void assertVectorsEqual(const std::vector<std::string>& v1, const std::vector<std::string>& v2, int line) {
- foreach (const std::string& entry, v1) {
- if (std::find(v2.begin(), v2.end(), entry) == v2.end()) {
- std::stringstream stream;
- stream << "Couldn't find " << entry << " in v2 (line " << line << ")";
- CPPUNIT_FAIL(stream.str());
- }
- }
- }
-
- private:
- JID jid_;
- XMPPRosterImpl* xmppRoster_;
- MUCRegistry* mucRegistry_;
- AvatarManager* avatarManager_;
- MockMainWindowFactory* mainWindowFactory_;
- NickManager* nickManager_;
- NickResolver* nickResolver_;
- RosterController* rosterController_;
- DummyIQChannel* channel_;
- DummyStanzaChannel* stanzaChannel_;
- IQRouter* router_;
- PresenceOracle* presenceOracle_;
- SubscriptionManager* subscriptionManager_;
- EventController* eventController_;
- UIEventStream* uiEventStream_;
- MockMainWindow* mainWindow_;
- DummySettingsProvider* settings_;
- DummyCapsProvider* capsProvider_;
- EntityCapsManager* entityCapsManager_;
- JingleSessionManager* jingleSessionManager_;
- FileTransferManager* ftManager_;
- FileTransferOverview* ftOverview_;
- ClientBlockListManager* clientBlockListManager_;
- CryptoProvider* crypto_;
- VCardStorage* vcardStorage_;
- VCardManager* vcardManager_;
+ CPPUNIT_TEST_SUITE(RosterControllerTest);
+ CPPUNIT_TEST(testAdd);
+ CPPUNIT_TEST(testAddSubscription);
+ CPPUNIT_TEST(testReceiveRename);
+ CPPUNIT_TEST(testReceiveRegroup);
+ CPPUNIT_TEST(testSendRename);
+ CPPUNIT_TEST(testPresence);
+ CPPUNIT_TEST(testHighestPresence);
+ CPPUNIT_TEST(testNotHighestPresence);
+ CPPUNIT_TEST(testUnavailablePresence);
+ CPPUNIT_TEST(testRemoveResultsInUnavailablePresence);
+ CPPUNIT_TEST(testOwnContactInRosterPresence);
+ CPPUNIT_TEST(testMultiResourceFileTransferFeature);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp() {
+ jid_ = JID("testjid@swift.im/swift");
+ xmppRoster_ = new XMPPRosterImpl();
+ avatarManager_ = new NullAvatarManager();
+ mainWindowFactory_ = new MockMainWindowFactory();
+ mucRegistry_ = new MUCRegistry();
+ crypto_ = PlatformCryptoProvider::create();
+ storages_ = std::unique_ptr<MemoryStorages>(new MemoryStorages(crypto_));
+ nickResolver_ = new NickResolver(jid_.toBare(), xmppRoster_, nullptr, mucRegistry_);
+ channel_ = new DummyIQChannel();
+ router_ = new IQRouter(channel_);
+ stanzaChannel_ = new DummyStanzaChannel();
+ presenceOracle_ = new PresenceOracle(stanzaChannel_, xmppRoster_);
+ subscriptionManager_ = new SubscriptionManager(stanzaChannel_);
+ eventController_ = new EventController();
+ uiEventStream_ = new UIEventStream();
+ settings_ = new DummySettingsProvider();
+ nickManager_ = new DummyNickManager();
+ capsManager_ = std::unique_ptr<CapsManager>(new CapsManager(storages_->getCapsStorage(), stanzaChannel_, router_, crypto_));
+ entityCapsManager_ = new EntityCapsManager(capsManager_.get(), stanzaChannel_);
+ jingleSessionManager_ = new JingleSessionManager(router_);
+
+ clientBlockListManager_ = new ClientBlockListManager(router_);
+ vcardStorage_ = new VCardMemoryStorage(crypto_);
+ vcardManager_ = new VCardManager(jid_, router_, vcardStorage_);
+ rosterController_ = new RosterController(jid_, xmppRoster_, avatarManager_, mainWindowFactory_, nickManager_, nickResolver_, presenceOracle_, subscriptionManager_, eventController_, uiEventStream_, router_, settings_, entityCapsManager_, clientBlockListManager_, vcardManager_);
+ mainWindow_ = mainWindowFactory_->last;
+ capsInfoGenerator_ = std::unique_ptr<CapsInfoGenerator>(new CapsInfoGenerator("", crypto_));
+ }
+
+ void tearDown() {
+ delete rosterController_;
+ delete vcardManager_;
+ delete vcardStorage_;
+ delete crypto_;
+ delete clientBlockListManager_;
+ delete jingleSessionManager_;
+ delete entityCapsManager_;
+ delete nickManager_;
+ delete nickResolver_;
+ delete mucRegistry_;
+ delete mainWindowFactory_;
+ delete avatarManager_;
+ delete router_;
+ delete channel_;
+ delete eventController_;
+ delete subscriptionManager_;
+ delete presenceOracle_;
+ delete stanzaChannel_;
+ delete uiEventStream_;
+ delete settings_;
+ delete xmppRoster_;
+ }
+
+ GroupRosterItem* groupChild(size_t i) {
+ return dynamic_cast<GroupRosterItem*>(getUIRosterChildren()[i]);
+ }
+
+ JID withResource(const JID& jid, const std::string& resource) {
+ return JID(jid.toBare().toString() + "/" + resource);
+ }
+
+ void testPresence() {
+ std::vector<std::string> groups;
+ groups.push_back("testGroup1");
+ groups.push_back("testGroup2");
+ JID from("test@testdomain.com");
+ xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both);
+ Presence::ref presence(new Presence());
+ presence->setFrom(withResource(from, "bob"));
+ presence->setPriority(2);
+ presence->setStatus("So totally here");
+ stanzaChannel_->onPresenceReceived(presence);
+ ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(getUIRosterChildren()[0])->getChildren()[0]);
+ CPPUNIT_ASSERT(item);
+ CPPUNIT_ASSERT_EQUAL(presence->getStatus(), item->getStatusText());
+ ContactRosterItem* item2 = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(getUIRosterChildren()[1])->getChildren()[0]);
+ CPPUNIT_ASSERT(item2);
+ CPPUNIT_ASSERT_EQUAL(presence->getStatus(), item2->getStatusText());
+ }
+
+ void testHighestPresence() {
+ std::vector<std::string> groups;
+ groups.push_back("testGroup1");
+ JID from("test@testdomain.com");
+ xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both);
+ Presence::ref lowPresence(new Presence());
+ lowPresence->setFrom(withResource(from, "bob"));
+ lowPresence->setPriority(2);
+ lowPresence->setStatus("Not here");
+ Presence::ref highPresence(new Presence());
+ highPresence->setFrom(withResource(from, "bert"));
+ highPresence->setPriority(10);
+ highPresence->setStatus("So totally here");
+ stanzaChannel_->onPresenceReceived(lowPresence);
+ stanzaChannel_->onPresenceReceived(highPresence);
+ ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(getUIRosterChildren()[0])->getChildren()[0]);
+ CPPUNIT_ASSERT(item);
+ CPPUNIT_ASSERT_EQUAL(highPresence->getStatus(), item->getStatusText());
+ }
+
+ void testNotHighestPresence() {
+ std::vector<std::string> groups;
+ groups.push_back("testGroup1");
+ JID from("test@testdomain.com");
+ xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both);
+ Presence::ref lowPresence(new Presence());
+ lowPresence->setFrom(withResource(from, "bob"));
+ lowPresence->setPriority(2);
+ lowPresence->setStatus("Not here");
+ Presence::ref highPresence(new Presence());
+ highPresence->setFrom(withResource(from, "bert"));
+ highPresence->setPriority(10);
+ highPresence->setStatus("So totally here");
+ stanzaChannel_->onPresenceReceived(highPresence);
+ stanzaChannel_->onPresenceReceived(lowPresence);
+ ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(getUIRosterChildren()[0])->getChildren()[0]);
+ CPPUNIT_ASSERT(item);
+ CPPUNIT_ASSERT_EQUAL(highPresence->getStatus(), item->getStatusText());
+ }
+
+ void testUnavailablePresence() {
+ std::vector<std::string> groups;
+ groups.push_back("testGroup1");
+ JID from("test@testdomain.com");
+ xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both);
+
+ Presence::ref lowPresence(new Presence());
+ lowPresence->setFrom(withResource(from, "bob"));
+ lowPresence->setPriority(2);
+ lowPresence->setShow(StatusShow::Away);
+ lowPresence->setStatus("Not here");
+ Presence::ref lowPresenceOffline(new Presence());
+ lowPresenceOffline->setFrom(withResource(from, "bob"));
+ lowPresenceOffline->setStatus("Signing out");
+ lowPresenceOffline->setType(Presence::Unavailable);
+
+ Presence::ref highPresence(new Presence());
+ highPresence->setFrom(withResource(from, "bert"));
+ highPresence->setPriority(10);
+ highPresence->setStatus("So totally here");
+ Presence::ref highPresenceOffline(new Presence());
+ highPresenceOffline->setFrom(withResource(from, "bert"));
+ highPresenceOffline->setType(Presence::Unavailable);
+
+ stanzaChannel_->onPresenceReceived(lowPresence);
+ Presence::ref accountPresence = presenceOracle_->getAccountPresence(from);
+ CPPUNIT_ASSERT_EQUAL(StatusShow::Away, accountPresence->getShow());
+
+ stanzaChannel_->onPresenceReceived(highPresence);
+ accountPresence = presenceOracle_->getAccountPresence(from);
+ CPPUNIT_ASSERT_EQUAL(StatusShow::Online, accountPresence->getShow());
+
+ stanzaChannel_->onPresenceReceived(highPresenceOffline);
+
+ // After this, the roster should show the low presence.
+ ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(getUIRosterChildren()[0])->getChildren()[0]);
+ CPPUNIT_ASSERT(item);
+
+ Presence::ref low = presenceOracle_->getAccountPresence(from);
+
+ CPPUNIT_ASSERT_EQUAL(Presence::Available, low->getType());
+ CPPUNIT_ASSERT_EQUAL(lowPresence->getStatus(), low->getStatus());
+ CPPUNIT_ASSERT_EQUAL(lowPresence->getShow(), item->getStatusShow());
+ CPPUNIT_ASSERT_EQUAL(lowPresence->getStatus(), item->getStatusText());
+ stanzaChannel_->onPresenceReceived(lowPresenceOffline);
+ item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(getUIRosterChildren()[0])->getChildren()[0]);
+ CPPUNIT_ASSERT(item);
+ /* A verification that if the test fails, it's the RosterController, not the PresenceOracle. */
+ low = presenceOracle_->getHighestPriorityPresence(from);
+ CPPUNIT_ASSERT_EQUAL(Presence::Unavailable, low->getType());
+ CPPUNIT_ASSERT_EQUAL(lowPresenceOffline->getStatus(), low->getStatus());
+ CPPUNIT_ASSERT_EQUAL(StatusShow::None, item->getStatusShow());
+ CPPUNIT_ASSERT_EQUAL(lowPresenceOffline->getStatus(), item->getStatusText());
+ }
+
+ void testAdd() {
+ std::vector<std::string> groups;
+ groups.push_back("testGroup1");
+ groups.push_back("testGroup2");
+ xmppRoster_->addContact(JID("test@testdomain.com/bob"), "name", groups, RosterItemPayload::Both);
+
+ CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(getUIRosterChildren().size()));
+ //CPPUNIT_ASSERT_EQUAL(std::string("Bob"), xmppRoster_->getNameForJID(JID("foo@bar.com")));
+ }
+
+ void testAddSubscription() {
+ std::vector<std::string> groups;
+ JID jid("test@testdomain.com");
+ xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::None);
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(getUIRosterChildren().size()));
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
+ xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::To);
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(getUIRosterChildren().size()));
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
+
+ xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::Both);
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(getUIRosterChildren().size()));
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
+
+ }
+
+ void testReceiveRename() {
+ std::vector<std::string> groups;
+ JID jid("test@testdomain.com");
+ xmppRoster_->addContact(jid, "name", groups, RosterItemPayload::Both);
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(getUIRosterChildren().size()));
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("name"), groupChild(0)->getChildren()[0]->getDisplayName());
+ xmppRoster_->addContact(jid, "NewName", groups, RosterItemPayload::Both);
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(getUIRosterChildren().size()));
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("NewName"), groupChild(0)->getChildren()[0]->getDisplayName());
+ }
+
+ void testReceiveRegroup() {
+ std::vector<std::string> oldGroups;
+ std::vector<std::string> newGroups;
+ newGroups.push_back("A Group");
+ std::vector<std::string> newestGroups;
+ newestGroups.push_back("Best Group");
+ JID jid("test@testdomain.com");
+ xmppRoster_->addContact(jid, "", oldGroups, RosterItemPayload::Both);
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(getUIRosterChildren().size()));
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
+ CPPUNIT_ASSERT_EQUAL(jid.toString(), groupChild(0)->getChildren()[0]->getDisplayName());
+
+ xmppRoster_->addContact(jid, "new name", newGroups, RosterItemPayload::Both);
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(getUIRosterChildren().size()));
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("new name"), groupChild(0)->getChildren()[0]->getDisplayName());
+ CPPUNIT_ASSERT_EQUAL(std::string("A Group"), groupChild(0)->getDisplayName());
+
+ xmppRoster_->addContact(jid, "new name", newestGroups, RosterItemPayload::Both);
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(getUIRosterChildren().size()));
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(groupChild(0)->getChildren().size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("new name"), groupChild(0)->getChildren()[0]->getDisplayName());
+ CPPUNIT_ASSERT_EQUAL(std::string("Best Group"), groupChild(0)->getDisplayName());
+ }
+
+ void testSendRename() {
+ JID jid("testling@wonderland.lit");
+ std::vector<std::string> groups;
+ groups.push_back("Friends");
+ groups.push_back("Enemies");
+ xmppRoster_->addContact(jid, "Bob", groups, RosterItemPayload::From);
+ CPPUNIT_ASSERT_EQUAL(groups.size(), xmppRoster_->getGroupsForJID(jid).size());
+ uiEventStream_->send(std::make_shared<RenameRosterItemUIEvent>(jid, "Robert"));
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), channel_->iqs_.size());
+ CPPUNIT_ASSERT_EQUAL(IQ::Set, channel_->iqs_[0]->getType());
+ std::shared_ptr<RosterPayload> payload = channel_->iqs_[0]->getPayload<RosterPayload>();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), payload->getItems().size());
+ RosterItemPayload item = payload->getItems()[0];
+ CPPUNIT_ASSERT_EQUAL(jid, item.getJID());
+ CPPUNIT_ASSERT_EQUAL(std::string("Robert"), item.getName());
+
+ CPPUNIT_ASSERT_EQUAL(groups.size(), item.getGroups().size());
+ assertVectorsEqual(groups, item.getGroups(), __LINE__);
+ }
+
+ void testRemoveResultsInUnavailablePresence() {
+ std::vector<std::string> groups;
+ groups.push_back("testGroup1");
+ JID from("test@testdomain.com");
+ xmppRoster_->addContact(from, "name", groups, RosterItemPayload::Both);
+ Presence::ref lowPresence(new Presence());
+ lowPresence->setFrom(withResource(from, "bob"));
+ lowPresence->setPriority(2);
+ lowPresence->setStatus("Not here");
+ Presence::ref highPresence(new Presence());
+ highPresence->setFrom(withResource(from, "bert"));
+ highPresence->setPriority(10);
+ highPresence->setStatus("So totally here");
+ stanzaChannel_->onPresenceReceived(highPresence);
+ stanzaChannel_->onPresenceReceived(lowPresence);
+
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), presenceOracle_->getAllPresence("test@testdomain.com").size());
+
+ xmppRoster_->onJIDRemoved(JID("test@testdomain.com"));
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), presenceOracle_->getAllPresence("test@testdomain.com").size());
+ CPPUNIT_ASSERT_EQUAL(Presence::Unavailable, presenceOracle_->getAllPresence("test@testdomain.com")[0]->getType());
+ }
+
+ void testOwnContactInRosterPresence() {
+ std::vector<std::string> groups;
+ groups.push_back("testGroup1");
+ groups.push_back("testGroup2");
+ JID from = jid_;
+ xmppRoster_->addContact(from.toBare(), "name", groups, RosterItemPayload::Both);
+ Presence::ref presence(new Presence());
+ presence->setFrom(from);
+ presence->setPriority(2);
+ presence->setStatus("So totally here");
+ stanzaChannel_->onPresenceReceived(presence);
+ ContactRosterItem* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(getUIRosterChildren()[0])->getChildren()[0]);
+ CPPUNIT_ASSERT(item);
+ CPPUNIT_ASSERT_EQUAL(presence->getStatus(), item->getStatusText());
+ ContactRosterItem* item2 = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(getUIRosterChildren()[1])->getChildren()[0]);
+ CPPUNIT_ASSERT(item2);
+ CPPUNIT_ASSERT_EQUAL(presence->getStatus(), item2->getStatusText());
+ }
+
+ // This tests a scenario of a contact having a resource supporting Jingle File Transfer and
+ // one resource not supporting it, and the contact features being set correctly.
+ void testMultiResourceFileTransferFeature() {
+ JID contact("test@testdomain.com");
+ xmppRoster_->addContact(contact, "Name", {}, RosterItemPayload::Both);
+
+ auto sendPresenceAndAnswerCaps = [=](const JID& from, const DiscoInfo& discoInfo) {
+ auto capsInfo = capsInfoGenerator_->generateCapsInfo(discoInfo);
+
+ auto ftClientPresence = std::make_shared<Presence>();
+ ftClientPresence->setFrom(from);
+ ftClientPresence->setPriority(0);
+ ftClientPresence->setShow(StatusShow::Online);
+ ftClientPresence->addPayload(std::make_shared<CapsInfo>(capsInfo));
+ stanzaChannel_->onPresenceReceived(ftClientPresence);
+
+ // disco reply
+ auto discoRequest = channel_->iqs_.back();
+ CPPUNIT_ASSERT(discoRequest);
+ auto discoReply = IQ::createResult(discoRequest->getFrom(), ftClientPresence->getFrom(), discoRequest->getID(), std::make_shared<DiscoInfo>(discoInfo));
+ channel_->onIQReceived(discoReply);
+ };
+
+ auto ftDiscoInfo = DiscoInfo();
+ ftDiscoInfo.addFeature(DiscoInfo::JingleFeature);
+ ftDiscoInfo.addFeature(DiscoInfo::JingleFTFeature);
+ ftDiscoInfo.addFeature(DiscoInfo::JingleTransportsIBBFeature);
+
+ sendPresenceAndAnswerCaps(contact.withResource("ft-supported"), ftDiscoInfo);
+
+ auto* item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(getUIRosterChildren()[0])->getChildren()[0]);
+ CPPUNIT_ASSERT(item);
+ CPPUNIT_ASSERT_EQUAL(contact, item->getJID());
+ CPPUNIT_ASSERT_EQUAL(true, item->supportsFeature(ContactRosterItem::FileTransferFeature));
+
+ sendPresenceAndAnswerCaps(contact.withResource("ft-unsupported"), DiscoInfo());
+
+ item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(getUIRosterChildren()[0])->getChildren()[0]);
+ CPPUNIT_ASSERT(item);
+ CPPUNIT_ASSERT_EQUAL(contact, item->getJID());
+ CPPUNIT_ASSERT_EQUAL(true, item->supportsFeature(ContactRosterItem::FileTransferFeature));
+
+ auto unavailablePresence = std::make_shared<Presence>();
+ unavailablePresence->setFrom(contact.withResource("ft-unsupported"));
+ unavailablePresence->setPriority(0);
+ unavailablePresence->setType(Presence::Unavailable);
+ stanzaChannel_->onPresenceReceived(unavailablePresence);
+
+ item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(getUIRosterChildren()[0])->getChildren()[0]);
+ CPPUNIT_ASSERT(item);
+ CPPUNIT_ASSERT_EQUAL(contact, item->getJID());
+ CPPUNIT_ASSERT_EQUAL(true, item->supportsFeature(ContactRosterItem::FileTransferFeature));
+
+ unavailablePresence = std::make_shared<Presence>();
+ unavailablePresence->setFrom(contact.withResource("ft-supported"));
+ unavailablePresence->setPriority(0);
+ unavailablePresence->setType(Presence::Unavailable);
+ stanzaChannel_->onPresenceReceived(unavailablePresence);
+
+ item = dynamic_cast<ContactRosterItem*>(dynamic_cast<GroupRosterItem*>(getUIRosterChildren()[0])->getChildren()[0]);
+ CPPUNIT_ASSERT(item);
+ CPPUNIT_ASSERT_EQUAL(contact, item->getJID());
+ CPPUNIT_ASSERT_EQUAL(false, item->supportsFeature(ContactRosterItem::FileTransferFeature));
+ }
+
+ void assertVectorsEqual(const std::vector<std::string>& v1, const std::vector<std::string>& v2, int line) {
+ for (const auto& entry : v1) {
+ if (std::find(v2.begin(), v2.end(), entry) == v2.end()) {
+ std::stringstream stream;
+ stream << "Couldn't find " << entry << " in v2 (line " << line << ")";
+ CPPUNIT_FAIL(stream.str());
+ }
+ }
+ }
+
+ const std::vector<RosterItem*>& getUIRosterChildren() const {
+ return mainWindow_->roster->getRoot()->getChildren();
+ }
+
+ private:
+ JID jid_;
+ std::unique_ptr<MemoryStorages> storages_;
+ XMPPRosterImpl* xmppRoster_;
+ MUCRegistry* mucRegistry_;
+ AvatarManager* avatarManager_;
+ MockMainWindowFactory* mainWindowFactory_;
+ NickManager* nickManager_;
+ NickResolver* nickResolver_;
+ RosterController* rosterController_;
+ DummyIQChannel* channel_;
+ DummyStanzaChannel* stanzaChannel_;
+ IQRouter* router_;
+ PresenceOracle* presenceOracle_;
+ SubscriptionManager* subscriptionManager_;
+ EventController* eventController_;
+ UIEventStream* uiEventStream_;
+ MockMainWindow* mainWindow_;
+ DummySettingsProvider* settings_;
+ std::unique_ptr<CapsManager> capsManager_;
+ EntityCapsManager* entityCapsManager_;
+ JingleSessionManager* jingleSessionManager_;
+ ClientBlockListManager* clientBlockListManager_;
+ CryptoProvider* crypto_;
+ VCardStorage* vcardStorage_;
+ VCardManager* vcardManager_;
+ std::unique_ptr<CapsInfoGenerator> capsInfoGenerator_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(RosterControllerTest);
diff --git a/Swift/Controllers/Roster/UnitTest/RosterTest.cpp b/Swift/Controllers/Roster/UnitTest/RosterTest.cpp
index d905d9f..5f500d4 100644
--- a/Swift/Controllers/Roster/UnitTest/RosterTest.cpp
+++ b/Swift/Controllers/Roster/UnitTest/RosterTest.cpp
@@ -1,145 +1,141 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
+#include <memory>
+
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
-#include <boost/shared_ptr.hpp>
-
-#include <Swift/Controllers/Roster/Roster.h>
#include <Swift/Controllers/Roster/GroupRosterItem.h>
#include <Swift/Controllers/Roster/ItemOperations/SetPresence.h>
+#include <Swift/Controllers/Roster/Roster.h>
using namespace Swift;
class RosterTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(RosterTest);
- CPPUNIT_TEST(testGetGroup);
- CPPUNIT_TEST(testRemoveContact);
- CPPUNIT_TEST(testRemoveSecondContact);
- CPPUNIT_TEST(testRemoveSecondContactSameBare);
- CPPUNIT_TEST(testApplyPresenceLikeMUC);
- CPPUNIT_TEST(testReSortLikeMUC);
- CPPUNIT_TEST_SUITE_END();
-
- public:
- void setUp() {
- jid1_ = JID("a@b.c");
- jid2_ = JID("b@c.d");
- jid3_ = JID("c@d.e");
- roster_ = new Roster();
- }
-
- void tearDown() {
- delete roster_;
- }
-
- void testGetGroup() {
- roster_->addContact(jid1_, JID(), "Bert", "group1", "");
- roster_->addContact(jid2_, JID(), "Ernie", "group2", "");
- roster_->addContact(jid3_, JID(), "Cookie", "group1", "");
-
- CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(roster_->getRoot()->getChildren().size()));
- CPPUNIT_ASSERT_EQUAL(std::string("group1"), roster_->getRoot()->getChildren()[0]->getDisplayName());
- CPPUNIT_ASSERT_EQUAL(std::string("group2"), roster_->getRoot()->getChildren()[1]->getDisplayName());
- CPPUNIT_ASSERT_EQUAL(std::string("Bert"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[0]->getDisplayName());
- CPPUNIT_ASSERT_EQUAL(std::string("Cookie"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[1]->getDisplayName());
- CPPUNIT_ASSERT_EQUAL(std::string("Ernie"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[1])->getChildren()[0]->getDisplayName());
-
- }
-
- void testRemoveContact() {
- roster_->addContact(jid1_, jid1_, "Bert", "group1", "");
- CPPUNIT_ASSERT_EQUAL(std::string("Bert"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[0]->getDisplayName());
-
- roster_->removeContact(jid1_);
- CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren().size()));
- }
-
- void testRemoveSecondContact() {
- roster_->addContact(jid1_, jid1_, "Bert", "group1", "");
- roster_->addContact(jid2_, jid2_, "Cookie", "group1", "");
- CPPUNIT_ASSERT_EQUAL(std::string("Cookie"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[1]->getDisplayName());
-
- roster_->removeContact(jid2_);
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren().size()));
- CPPUNIT_ASSERT_EQUAL(std::string("Bert"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[0]->getDisplayName());
- }
-
- void testRemoveSecondContactSameBare() {
- JID jid4a("a@b/c");
- JID jid4b("a@b/d");
- roster_->addContact(jid4a, JID(), "Bert", "group1", "");
- roster_->addContact(jid4b, JID(), "Cookie", "group1", "");
- CPPUNIT_ASSERT_EQUAL(std::string("Cookie"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[1]->getDisplayName());
-
- roster_->removeContact(jid4b);
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren().size()));
- CPPUNIT_ASSERT_EQUAL(std::string("Bert"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[0]->getDisplayName());
- }
-
- void testApplyPresenceLikeMUC() {
- JID jid4a("a@b/c");
- JID jid4b("a@b/d");
- JID jid4c("a@b/e");
- roster_->addContact(jid4a, JID(), "Bird", "group1", "");
- roster_->addContact(jid4b, JID(), "Cookie", "group1", "");
- roster_->removeContact(jid4b);
- roster_->addContact(jid4c, JID(), "Bert", "group1", "");
- roster_->addContact(jid4b, JID(), "Ernie", "group1", "");
- boost::shared_ptr<Presence> presence(new Presence());
- presence->setShow(StatusShow::DND);
- presence->setFrom(jid4a);
- roster_->applyOnItems(SetPresence(presence, JID::WithResource));
- presence->setFrom(jid4b);
- roster_->applyOnItems(SetPresence(presence, JID::WithResource));
- presence->setFrom(jid4c);
- roster_->applyOnItems(SetPresence(presence, JID::WithResource));
-
- presence = boost::make_shared<Presence>();
- presence->setFrom(jid4b);
- presence->setShow(StatusShow::Online);
- roster_->applyOnItems(SetPresence(presence, JID::WithResource));
- std::vector<RosterItem*> children = static_cast<GroupRosterItem*>(roster_->getRoot()->getDisplayedChildren()[0])->getDisplayedChildren();
- CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(children.size()));
-
- /* Check order */
- CPPUNIT_ASSERT_EQUAL(std::string("Ernie"), children[0]->getDisplayName());
- CPPUNIT_ASSERT_EQUAL(std::string("Bert"), children[1]->getDisplayName());
- CPPUNIT_ASSERT_EQUAL(std::string("Bird"), children[2]->getDisplayName());
-
- presence = boost::make_shared<Presence>();
- presence->setFrom(jid4c);
- presence->setType(Presence::Unavailable);
- roster_->removeContact(jid4c);
- roster_->applyOnItems(SetPresence(presence, JID::WithResource));
-
- }
-
- void testReSortLikeMUC() {
- JID jid4a("a@b/c");
- JID jid4b("a@b/d");
- JID jid4c("a@b/e");
- roster_->addContact(jid4a, JID(), "Bird", "group1", "");
- roster_->addContact(jid4b, JID(), "Cookie", "group2", "");
- roster_->addContact(jid4b, JID(), "Ernie", "group1", "");
- roster_->getGroup("group1")->setManualSort("2");
- roster_->getGroup("group2")->setManualSort("1");
- GroupRosterItem* root = roster_->getRoot();
- const std::vector<RosterItem*> kids = root->getDisplayedChildren();
- CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), kids.size());
- CPPUNIT_ASSERT_EQUAL(std::string("group2"), kids[0]->getDisplayName());
- CPPUNIT_ASSERT_EQUAL(std::string("group1"), kids[1]->getDisplayName());
- }
-
- private:
- Roster *roster_;
- JID jid1_;
- JID jid2_;
- JID jid3_;
+ CPPUNIT_TEST_SUITE(RosterTest);
+ CPPUNIT_TEST(testGetGroup);
+ CPPUNIT_TEST(testRemoveContact);
+ CPPUNIT_TEST(testRemoveSecondContact);
+ CPPUNIT_TEST(testRemoveSecondContactSameBare);
+ CPPUNIT_TEST(testApplyPresenceLikeMUC);
+ CPPUNIT_TEST(testReSortLikeMUC);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp() {
+ jid1_ = JID("a@b.c");
+ jid2_ = JID("b@c.d");
+ jid3_ = JID("c@d.e");
+ roster_ = std::unique_ptr<Roster>(new Roster());
+ }
+
+ void testGetGroup() {
+ roster_->addContact(jid1_, JID(), "Bert", "group1", "");
+ roster_->addContact(jid2_, JID(), "Ernie", "group2", "");
+ roster_->addContact(jid3_, JID(), "Cookie", "group1", "");
+
+ CPPUNIT_ASSERT_EQUAL(2, static_cast<int>(roster_->getRoot()->getChildren().size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("group1"), roster_->getRoot()->getChildren()[0]->getDisplayName());
+ CPPUNIT_ASSERT_EQUAL(std::string("group2"), roster_->getRoot()->getChildren()[1]->getDisplayName());
+ CPPUNIT_ASSERT_EQUAL(std::string("Bert"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[0]->getDisplayName());
+ CPPUNIT_ASSERT_EQUAL(std::string("Cookie"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[1]->getDisplayName());
+ CPPUNIT_ASSERT_EQUAL(std::string("Ernie"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[1])->getChildren()[0]->getDisplayName());
+
+ }
+
+ void testRemoveContact() {
+ roster_->addContact(jid1_, jid1_, "Bert", "group1", "");
+ CPPUNIT_ASSERT_EQUAL(std::string("Bert"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[0]->getDisplayName());
+
+ roster_->removeContact(jid1_);
+ CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren().size()));
+ }
+
+ void testRemoveSecondContact() {
+ roster_->addContact(jid1_, jid1_, "Bert", "group1", "");
+ roster_->addContact(jid2_, jid2_, "Cookie", "group1", "");
+ CPPUNIT_ASSERT_EQUAL(std::string("Cookie"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[1]->getDisplayName());
+
+ roster_->removeContact(jid2_);
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren().size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("Bert"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[0]->getDisplayName());
+ }
+
+ void testRemoveSecondContactSameBare() {
+ JID jid4a("a@b/c");
+ JID jid4b("a@b/d");
+ roster_->addContact(jid4a, JID(), "Bert", "group1", "");
+ roster_->addContact(jid4b, JID(), "Cookie", "group1", "");
+ CPPUNIT_ASSERT_EQUAL(std::string("Cookie"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[1]->getDisplayName());
+
+ roster_->removeContact(jid4b);
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren().size()));
+ CPPUNIT_ASSERT_EQUAL(std::string("Bert"), static_cast<GroupRosterItem*>(roster_->getRoot()->getChildren()[0])->getChildren()[0]->getDisplayName());
+ }
+
+ void testApplyPresenceLikeMUC() {
+ JID jid4a("a@b/c");
+ JID jid4b("a@b/d");
+ JID jid4c("a@b/e");
+ roster_->addContact(jid4a, JID(), "Bird", "group1", "");
+ roster_->addContact(jid4b, JID(), "Cookie", "group1", "");
+ roster_->removeContact(jid4b);
+ roster_->addContact(jid4c, JID(), "Bert", "group1", "");
+ roster_->addContact(jid4b, JID(), "Ernie", "group1", "");
+ std::shared_ptr<Presence> presence(new Presence());
+ presence->setShow(StatusShow::DND);
+ presence->setFrom(jid4a);
+ roster_->applyOnItems(SetPresence(presence, JID::WithResource));
+ presence->setFrom(jid4b);
+ roster_->applyOnItems(SetPresence(presence, JID::WithResource));
+ presence->setFrom(jid4c);
+ roster_->applyOnItems(SetPresence(presence, JID::WithResource));
+
+ presence = std::make_shared<Presence>();
+ presence->setFrom(jid4b);
+ presence->setShow(StatusShow::Online);
+ roster_->applyOnItems(SetPresence(presence, JID::WithResource));
+ std::vector<RosterItem*> children = static_cast<GroupRosterItem*>(roster_->getRoot()->getDisplayedChildren()[0])->getDisplayedChildren();
+ CPPUNIT_ASSERT_EQUAL(3, static_cast<int>(children.size()));
+
+ /* Check order */
+ CPPUNIT_ASSERT_EQUAL(std::string("Ernie"), children[0]->getDisplayName());
+ CPPUNIT_ASSERT_EQUAL(std::string("Bert"), children[1]->getDisplayName());
+ CPPUNIT_ASSERT_EQUAL(std::string("Bird"), children[2]->getDisplayName());
+
+ presence = std::make_shared<Presence>();
+ presence->setFrom(jid4c);
+ presence->setType(Presence::Unavailable);
+ roster_->removeContact(jid4c);
+ roster_->applyOnItems(SetPresence(presence, JID::WithResource));
+
+ }
+
+ void testReSortLikeMUC() {
+ JID jid4a("a@b/c");
+ JID jid4b("a@b/d");
+ JID jid4c("a@b/e");
+ roster_->addContact(jid4a, JID(), "Bird", "group1", "");
+ roster_->addContact(jid4b, JID(), "Cookie", "group2", "");
+ roster_->addContact(jid4b, JID(), "Ernie", "group1", "");
+ roster_->getGroup("group1")->setManualSort("2");
+ roster_->getGroup("group2")->setManualSort("1");
+ GroupRosterItem* root = roster_->getRoot();
+ const std::vector<RosterItem*> kids = root->getDisplayedChildren();
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), kids.size());
+ CPPUNIT_ASSERT_EQUAL(std::string("group2"), kids[0]->getDisplayName());
+ CPPUNIT_ASSERT_EQUAL(std::string("group1"), kids[1]->getDisplayName());
+ }
+
+ private:
+ std::unique_ptr<Roster> roster_;
+ JID jid1_;
+ JID jid2_;
+ JID jid3_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(RosterTest);
diff --git a/Swift/Controllers/Roster/UnitTest/TableRosterTest.cpp b/Swift/Controllers/Roster/UnitTest/TableRosterTest.cpp
index 10030ef..ddc8785 100644
--- a/Swift/Controllers/Roster/UnitTest/TableRosterTest.cpp
+++ b/Swift/Controllers/Roster/UnitTest/TableRosterTest.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -9,14 +9,15 @@
std::ostream& operator<<(std::ostream& os, const Swift::TableRoster::Index& i);
std::ostream& operator<<(std::ostream& os, const Swift::TableRoster::Index& i) {
- os << "(" << i.section << ", " << i.row << ")";
- return os;
+ os << "(" << i.section << ", " << i.row << ")";
+ return os;
}
+#include <memory>
+
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
-#include <boost/shared_ptr.hpp>
#include <boost/variant.hpp>
#include <Swiften/Network/DummyTimerFactory.h>
@@ -27,67 +28,62 @@ std::ostream& operator<<(std::ostream& os, const Swift::TableRoster::Index& i) {
using namespace Swift;
class TableRosterTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(TableRosterTest);
- CPPUNIT_TEST(testAddContact_EmptyRoster);
- CPPUNIT_TEST_SUITE_END();
-
- public:
- void setUp() {
- timerFactory = new DummyTimerFactory();
- roster = new Roster();
- jid1 = JID("jid1@example.com");
- jid2 = JID("jid2@example.com");
- }
-
- void tearDown() {
- delete roster;
- delete timerFactory;
- }
-
- void testAddContact_EmptyRoster() {
- /*
- boost::shared_ptr<TableRoster> tableRoster(createTestling());
-
- addContact(jid1, "1", "group1");
-
- CPPUNIT_ASSERT_EQUAL(4, static_cast<int>(events.size()));
- CPPUNIT_ASSERT(boost::get<BeginUpdatesEvent>(&events[0]));
- CPPUNIT_ASSERT(boost::get<SectionsInsertedEvent>(&events[1]));
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(boost::get<SectionsInsertedEvent>(events[1]).sections.size()));
- CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(boost::get<SectionsInsertedEvent>(events[1]).sections[0]));
- CPPUNIT_ASSERT(boost::get<RowsInsertedEvent>(&events[2]));
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(boost::get<RowsInsertedEvent>(events[2]).rows.size()));
- CPPUNIT_ASSERT_EQUAL(TableRoster::Index(0, 0), boost::get<RowsInsertedEvent>(events[2]).rows[0]);
- CPPUNIT_ASSERT(boost::get<EndUpdatesEvent>(&events[3]));
-
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(tableRoster->getNumberOfSections()));
- CPPUNIT_ASSERT_EQUAL(std::string("group1"), tableRoster->getSectionTitle(0));
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(tableRoster->getNumberOfRowsInSection(0)));
- CPPUNIT_ASSERT_EQUAL(jid1, tableRoster->getItem(TableRoster::Index(0, 0)).jid);
- */
- }
-
- private:
- void addContact(const JID& jid, const std::string& name, const std::string& group) {
- roster->addContact(jid, JID(), name, group, "");
- }
-
- TableRoster* createTestling() {
- TableRoster* result = new TableRoster(roster, timerFactory, 10);
- result->onUpdate.connect(boost::bind(&TableRosterTest::handleUpdate, this, _1));
- return result;
- }
-
- void handleUpdate(const TableRoster::Update& update) {
- updates.push_back(update);
- }
-
- private:
- DummyTimerFactory* timerFactory;
- Roster* roster;
- JID jid1;
- JID jid2;
- std::vector<TableRoster::Update> updates;
+ CPPUNIT_TEST_SUITE(TableRosterTest);
+ CPPUNIT_TEST(testAddContact_EmptyRoster);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp() {
+ timerFactory = std::unique_ptr<DummyTimerFactory>(new DummyTimerFactory());
+ roster = std::unique_ptr<Roster>(new Roster());
+ jid1 = JID("jid1@example.com");
+ jid2 = JID("jid2@example.com");
+ }
+
+ void testAddContact_EmptyRoster() {
+ /*
+ std::shared_ptr<TableRoster> tableRoster(createTestling());
+
+ addContact(jid1, "1", "group1");
+
+ CPPUNIT_ASSERT_EQUAL(4, static_cast<int>(events.size()));
+ CPPUNIT_ASSERT(boost::get<BeginUpdatesEvent>(&events[0]));
+ CPPUNIT_ASSERT(boost::get<SectionsInsertedEvent>(&events[1]));
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(boost::get<SectionsInsertedEvent>(events[1]).sections.size()));
+ CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(boost::get<SectionsInsertedEvent>(events[1]).sections[0]));
+ CPPUNIT_ASSERT(boost::get<RowsInsertedEvent>(&events[2]));
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(boost::get<RowsInsertedEvent>(events[2]).rows.size()));
+ CPPUNIT_ASSERT_EQUAL(TableRoster::Index(0, 0), boost::get<RowsInsertedEvent>(events[2]).rows[0]);
+ CPPUNIT_ASSERT(boost::get<EndUpdatesEvent>(&events[3]));
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(tableRoster->getNumberOfSections()));
+ CPPUNIT_ASSERT_EQUAL(std::string("group1"), tableRoster->getSectionTitle(0));
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(tableRoster->getNumberOfRowsInSection(0)));
+ CPPUNIT_ASSERT_EQUAL(jid1, tableRoster->getItem(TableRoster::Index(0, 0)).jid);
+ */
+ }
+
+ private:
+ void addContact(const JID& jid, const std::string& name, const std::string& group) {
+ roster->addContact(jid, JID(), name, group, "");
+ }
+
+ TableRoster* createTestling() {
+ TableRoster* result = new TableRoster(roster.get(), timerFactory.get(), 10);
+ result->onUpdate.connect(boost::bind(&TableRosterTest::handleUpdate, this, _1));
+ return result;
+ }
+
+ void handleUpdate(const TableRoster::Update& update) {
+ updates.push_back(update);
+ }
+
+ private:
+ std::unique_ptr<DummyTimerFactory> timerFactory;
+ std::unique_ptr<Roster> roster;
+ JID jid1;
+ JID jid2;
+ std::vector<TableRoster::Update> updates;
};
CPPUNIT_TEST_SUITE_REGISTRATION(TableRosterTest);
diff --git a/Swift/Controllers/SConscript b/Swift/Controllers/SConscript
index 5ebbdd3..105b44b 100644
--- a/Swift/Controllers/SConscript
+++ b/Swift/Controllers/SConscript
@@ -6,10 +6,10 @@ import Version
################################################################################
if env["SCONS_STAGE"] == "flags" :
- env["SWIFT_CONTROLLERS_FLAGS"] = {
- "LIBPATH": [Dir(".")],
- "LIBS": ["SwiftControllers"]
- }
+ env["SWIFT_CONTROLLERS_FLAGS"] = {
+ "LIBPATH": [Dir(".")],
+ "LIBS": ["SwiftControllers"]
+ }
################################################################################
@@ -17,95 +17,95 @@ if env["SCONS_STAGE"] == "flags" :
################################################################################
if env["SCONS_STAGE"] == "build" :
- myenv = env.Clone()
- myenv.BuildVersion("BuildVersion.h", project = "swift")
- myenv.UseFlags(env["SWIFTEN_FLAGS"])
- myenv.UseFlags(env["SWIFTEN_DEP_FLAGS"])
- myenv.StaticLibrary("SwiftControllers", [
- "Chat/ChatController.cpp",
- "Chat/ChatControllerBase.cpp",
- "Chat/ChatsManager.cpp",
- "Chat/MUCController.cpp",
- "Chat/MUCSearchController.cpp",
- "Chat/UserSearchController.cpp",
- "Chat/ChatMessageParser.cpp",
- "ContactSuggester.cpp",
- "MainController.cpp",
- "ProfileController.cpp",
- "ShowProfileController.cpp",
- "ContactEditController.cpp",
- "FileTransfer/FileTransferController.cpp",
- "FileTransfer/FileTransferOverview.cpp",
- "FileTransfer/FileTransferProgressInfo.cpp",
- "Roster/RosterController.cpp",
- "Roster/RosterGroupExpandinessPersister.cpp",
- "Roster/ContactRosterItem.cpp",
- "Roster/GroupRosterItem.cpp",
- "Roster/RosterItem.cpp",
- "Roster/Roster.cpp",
- "Roster/RosterVCardProvider.cpp",
- "Roster/TableRoster.cpp",
- "EventWindowController.cpp",
- "SoundEventController.cpp",
- "SystemTrayController.cpp",
- "XMLConsoleController.cpp",
- "HistoryViewController.cpp",
- "HistoryController.cpp",
- "FileTransferListController.cpp",
- "BlockListController.cpp",
- "StatusTracker.cpp",
- "PresenceNotifier.cpp",
- "EventNotifier.cpp",
- "AdHocManager.cpp",
- "AdHocController.cpp",
- "XMPPEvents/EventController.cpp",
- "UIEvents/UIEvent.cpp",
- "UIInterfaces/XMLConsoleWidget.cpp",
- "UIInterfaces/ChatListWindow.cpp",
- "UIInterfaces/HighlightEditorWindow.cpp",
- "PreviousStatusStore.cpp",
- "ProfileSettingsProvider.cpp",
- "Settings/SettingsProviderHierachy.cpp",
- "Settings/XMLSettingsProvider.cpp",
- "Storages/CertificateStorageFactory.cpp",
- "Storages/CertificateStorage.cpp",
- "Storages/CertificateFileStorage.cpp",
- "Storages/CertificateMemoryStorage.cpp",
- "Storages/AvatarFileStorage.cpp",
- "Storages/FileStorages.cpp",
- "Storages/RosterFileStorage.cpp",
- "Storages/CapsFileStorage.cpp",
- "Storages/VCardFileStorage.cpp",
- "StatusUtil.cpp",
- "Translator.cpp",
- "XMPPURIController.cpp",
- "ChatMessageSummarizer.cpp",
- "SettingConstants.cpp",
- "WhiteboardManager.cpp",
- "StatusCache.cpp",
- "HighlightAction.cpp",
- "HighlightEditorController.cpp",
- "HighlightManager.cpp",
- "HighlightRule.cpp",
- "Highlighter.cpp",
- "ContactsFromXMPPRoster.cpp",
- "ContactProvider.cpp",
- "Contact.cpp"
- ])
+ myenv = env.Clone()
+ myenv.BuildVersion("BuildVersion.h", project = "swift")
+ myenv.UseFlags(env["SWIFTEN_FLAGS"])
+ myenv.UseFlags(env["SWIFTEN_DEP_FLAGS"])
+ myenv.StaticLibrary("SwiftControllers", [
+ "Chat/ChatController.cpp",
+ "Chat/ChatControllerBase.cpp",
+ "Chat/ChatsManager.cpp",
+ "Chat/MUCController.cpp",
+ "Chat/MUCSearchController.cpp",
+ "Chat/UserSearchController.cpp",
+ "Chat/ChatMessageParser.cpp",
+ "ContactSuggester.cpp",
+ "MainController.cpp",
+ "ProfileController.cpp",
+ "ShowProfileController.cpp",
+ "ContactEditController.cpp",
+ "FileTransfer/FileTransferController.cpp",
+ "FileTransfer/FileTransferOverview.cpp",
+ "FileTransfer/FileTransferProgressInfo.cpp",
+ "Roster/RosterController.cpp",
+ "Roster/RosterGroupExpandinessPersister.cpp",
+ "Roster/ContactRosterItem.cpp",
+ "Roster/GroupRosterItem.cpp",
+ "Roster/RosterItem.cpp",
+ "Roster/Roster.cpp",
+ "Roster/RosterVCardProvider.cpp",
+ "Roster/TableRoster.cpp",
+ "EventWindowController.cpp",
+ "SoundEventController.cpp",
+ "SystemTrayController.cpp",
+ "XMLConsoleController.cpp",
+ "HistoryViewController.cpp",
+ "HistoryController.cpp",
+ "FileTransferListController.cpp",
+ "BlockListController.cpp",
+ "StatusTracker.cpp",
+ "PresenceNotifier.cpp",
+ "EventNotifier.cpp",
+ "AdHocManager.cpp",
+ "AdHocController.cpp",
+ "XMPPEvents/EventController.cpp",
+ "UIEvents/UIEvent.cpp",
+ "UIInterfaces/XMLConsoleWidget.cpp",
+ "UIInterfaces/ChatListWindow.cpp",
+ "UIInterfaces/HighlightEditorWindow.cpp",
+ "PreviousStatusStore.cpp",
+ "ProfileSettingsProvider.cpp",
+ "Settings/SettingsProviderHierachy.cpp",
+ "Settings/XMLSettingsProvider.cpp",
+ "Storages/CertificateStorageFactory.cpp",
+ "Storages/CertificateStorage.cpp",
+ "Storages/CertificateFileStorage.cpp",
+ "Storages/CertificateMemoryStorage.cpp",
+ "Storages/AvatarFileStorage.cpp",
+ "Storages/FileStorages.cpp",
+ "Storages/RosterFileStorage.cpp",
+ "Storages/CapsFileStorage.cpp",
+ "Storages/VCardFileStorage.cpp",
+ "StatusUtil.cpp",
+ "Translator.cpp",
+ "XMPPURIController.cpp",
+ "ChatMessageSummarizer.cpp",
+ "SettingConstants.cpp",
+ "WhiteboardManager.cpp",
+ "StatusCache.cpp",
+ "HighlightAction.cpp",
+ "HighlightEditorController.cpp",
+ "HighlightManager.cpp",
+ "HighlightRule.cpp",
+ "Highlighter.cpp",
+ "ContactsFromXMPPRoster.cpp",
+ "ContactProvider.cpp",
+ "Contact.cpp"
+ ])
- env.Append(UNITTEST_SOURCES = [
- File("Roster/UnitTest/RosterControllerTest.cpp"),
- File("Roster/UnitTest/RosterTest.cpp"),
- File("Roster/UnitTest/LeastCommonSubsequenceTest.cpp"),
- File("Roster/UnitTest/TableRosterTest.cpp"),
- File("UnitTest/PreviousStatusStoreTest.cpp"),
- File("UnitTest/PresenceNotifierTest.cpp"),
- File("Chat/UnitTest/ChatsManagerTest.cpp"),
- File("Chat/UnitTest/MUCControllerTest.cpp"),
- File("Chat/UnitTest/ChatMessageParserTest.cpp"),
- File("UnitTest/MockChatWindow.cpp"),
- File("UnitTest/ChatMessageSummarizerTest.cpp"),
- File("Settings/UnitTest/SettingsProviderHierachyTest.cpp"),
- File("UnitTest/HighlightRuleTest.cpp"),
- File("UnitTest/ContactSuggesterTest.cpp")
- ])
+ env.Append(UNITTEST_SOURCES = [
+ File("Roster/UnitTest/RosterControllerTest.cpp"),
+ File("Roster/UnitTest/RosterTest.cpp"),
+ File("Roster/UnitTest/LeastCommonSubsequenceTest.cpp"),
+ File("Roster/UnitTest/TableRosterTest.cpp"),
+ File("UnitTest/PreviousStatusStoreTest.cpp"),
+ File("UnitTest/PresenceNotifierTest.cpp"),
+ File("Chat/UnitTest/ChatsManagerTest.cpp"),
+ File("Chat/UnitTest/MUCControllerTest.cpp"),
+ File("Chat/UnitTest/ChatMessageParserTest.cpp"),
+ File("UnitTest/MockChatWindow.cpp"),
+ File("UnitTest/ChatMessageSummarizerTest.cpp"),
+ File("Settings/UnitTest/SettingsProviderHierachyTest.cpp"),
+ File("UnitTest/HighlightRuleTest.cpp"),
+ File("UnitTest/ContactSuggesterTest.cpp")
+ ])
diff --git a/Swift/Controllers/SettingConstants.cpp b/Swift/Controllers/SettingConstants.cpp
index 9807abc..dedf56b 100644
--- a/Swift/Controllers/SettingConstants.cpp
+++ b/Swift/Controllers/SettingConstants.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2015 Isode Limited.
+ * Copyright (c) 2012-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -20,13 +20,8 @@ const SettingsProvider::Setting<bool> SettingConstants::SHOW_OFFLINE("showOfflin
const SettingsProvider::Setting<std::string> SettingConstants::EXPANDED_ROSTER_GROUPS("GroupExpandiness", "");
const SettingsProvider::Setting<bool> SettingConstants::PLAY_SOUNDS("playSounds", true);
const SettingsProvider::Setting<std::string> SettingConstants::HIGHLIGHT_RULES("highlightRules", "@");
-const SettingsProvider::Setting<bool> SettingConstants::SPELL_CHECKER("spellChecker", false);
-const SettingsProvider::Setting<std::string> SettingConstants::DICT_PATH("dictPath", "/usr/share/myspell/dicts/");
-const SettingsProvider::Setting<std::string> SettingConstants::PERSONAL_DICT_PATH("personaldictPath", "/home/");
-const SettingsProvider::Setting<std::string> SettingConstants::DICT_FILE("dictFile", "en_US.dic");
const SettingsProvider::Setting<std::string> SettingConstants::INVITE_AUTO_ACCEPT_MODE("inviteAutoAcceptMode", "presence");
-const SettingsProvider::Setting<std::string> SettingConstants::TRELLIS_GRID_SIZE("trellisGridSize", "");
-const SettingsProvider::Setting<std::string> SettingConstants::TRELLIS_GRID_POSITIONS("trellisGridPositions", "");
const SettingsProvider::Setting<bool> SettingConstants::DISCONNECT_ON_CARD_REMOVAL("disconnectOnCardRemoval", true);
const SettingsProvider::Setting<bool> SettingConstants::SINGLE_SIGN_ON("singleSignOn", false);
+
}
diff --git a/Swift/Controllers/SettingConstants.h b/Swift/Controllers/SettingConstants.h
index c4ac4ad..3f15c44 100644
--- a/Swift/Controllers/SettingConstants.h
+++ b/Swift/Controllers/SettingConstants.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2015 Isode Limited.
+ * Copyright (c) 2012-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -9,100 +9,82 @@
#include <Swift/Controllers/Settings/SettingsProvider.h>
namespace Swift {
- /**
- * This class contains the major setting keys for Swift.
- */
- class SettingConstants {
- public:
- /**
- * The #IDLE_GOES_OFFLINE setting specifies whether to close the XMPP connection when
- * the user went idle.
- *
- * True for automatic close of the XMPP connection and false for only changing the presence on idle.
- */
- static const SettingsProvider::Setting<bool> IDLE_GOES_OFFLINE;
- /**
- * The #IDLE_TIMEOUT setting specifieds the seconds the user has to be inactive at the
- * desktop so the user is regarded as idle.
- */
- static const SettingsProvider::Setting<int> IDLE_TIMEOUT;
- static const SettingsProvider::Setting<bool> SHOW_NOTIFICATIONS;
- /**
- * The #REQUEST_DELIVERYRECEIPTS settings specifies whether to request delivery receipts
- * for messages to contacts that support message receipts.
- */
- static const SettingsProvider::Setting<bool> REQUEST_DELIVERYRECEIPTS;
- static const SettingsProvider::Setting<bool> FORGET_PASSWORDS;
- static const SettingsProvider::Setting<bool> REMEMBER_RECENT_CHATS;
- static const SettingsProvider::Setting<std::string> LAST_LOGIN_JID;
- static const SettingsProvider::Setting<bool> LOGIN_AUTOMATICALLY;
- /**
- * The #SHOW_OFFLINE setting specifies whether or not to show offline contacts in the
- * roster.
- *
- * If set true Swift will show offline contacts; else not.
- */
- static const SettingsProvider::Setting<bool> SHOW_OFFLINE;
- /**
- * The #EXPANDED_ROSTER_GROUPS setting specifies the list of groups that are expanded
- * in the roster UI.
- *
- * Its value is a string with group names seperated by newlines.
- */
- static const SettingsProvider::Setting<std::string> EXPANDED_ROSTER_GROUPS;
- static const SettingsProvider::Setting<bool> PLAY_SOUNDS;
- /**
- * The #HIGHLIGHT_RULES setting specifies the highlight rules and the associated actions.
- *
- * Its value is a Boost serialized representation.
- */
- static const SettingsProvider::Setting<std::string> HIGHLIGHT_RULES;
- static const SettingsProvider::Setting<bool> SPELL_CHECKER;
- static const SettingsProvider::Setting<std::string> DICT_PATH;
- static const SettingsProvider::Setting<std::string> PERSONAL_DICT_PATH;
- static const SettingsProvider::Setting<std::string> DICT_FILE;
- /**
- * The #INVITE_AUTO_ACCEPT_MODE setting specifies how to handle invites to chat rooms.
- *
- * Supported values are:
- * - "no" : It is up to the user whether to accept the invitation and enter a room or not.
- * - "presence" : The invitation is automatically accepted if it is from a contact that is
- * already allowed to see the user's presence status.
- * - "domain" : The invitation is automatically accepted if it is from a contact that is
- * already allowed to see the user's presence status or from a contact of user's domain.
- */
- static const SettingsProvider::Setting<std::string> INVITE_AUTO_ACCEPT_MODE;
- /**
- * The #TRELLIS_GRID_SIZE setting specifies the dimensions of the grid used for the trellis
- * layout.
- *
- * Its value is a Qt serialized representation.
- */
- static const SettingsProvider::Setting<std::string> TRELLIS_GRID_SIZE;
- /**
- * The #TRELLIS_GRID_POSITIONS setting specifies where conversations to contacts or rooms go
- * in the trellis grid.
- *
- * Its value is a Qt serialized representation.
- */
- static const SettingsProvider::Setting<std::string> TRELLIS_GRID_POSITIONS;
- /**
- * The #DISCONNECT_ON_CARD_REMOVAL setting
- * specifies whether or not to sign out the user when
- * the smartcard is removed.
- *
- * If set true Swift will sign out the user when the
- * smart card is removed; else not.
- */
- static const SettingsProvider::Setting<bool> DISCONNECT_ON_CARD_REMOVAL;
- /**
- * The #SINGLE_SIGN_ON setting
- * specifies whether to log in using Single Sign On.
- * This is currently supported on Windows.
- *
- * If set true Swift will use GSSAPI authentication to
- * log in the user; else not.
- */
- static const SettingsProvider::Setting<bool> SINGLE_SIGN_ON;
- };
+ /**
+ * This class contains the major setting keys for Swift.
+ */
+ class SettingConstants {
+ public:
+ /**
+ * The #IDLE_GOES_OFFLINE setting specifies whether to close the XMPP connection when
+ * the user went idle.
+ *
+ * True for automatic close of the XMPP connection and false for only changing the presence on idle.
+ */
+ static const SettingsProvider::Setting<bool> IDLE_GOES_OFFLINE;
+ /**
+ * The #IDLE_TIMEOUT setting specifieds the seconds the user has to be inactive at the
+ * desktop so the user is regarded as idle.
+ */
+ static const SettingsProvider::Setting<int> IDLE_TIMEOUT;
+ static const SettingsProvider::Setting<bool> SHOW_NOTIFICATIONS;
+ /**
+ * The #REQUEST_DELIVERYRECEIPTS settings specifies whether to request delivery receipts
+ * for messages to contacts that support message receipts.
+ */
+ static const SettingsProvider::Setting<bool> REQUEST_DELIVERYRECEIPTS;
+ static const SettingsProvider::Setting<bool> FORGET_PASSWORDS;
+ static const SettingsProvider::Setting<bool> REMEMBER_RECENT_CHATS;
+ static const SettingsProvider::Setting<std::string> LAST_LOGIN_JID;
+ static const SettingsProvider::Setting<bool> LOGIN_AUTOMATICALLY;
+ /**
+ * The #SHOW_OFFLINE setting specifies whether or not to show offline contacts in the
+ * roster.
+ *
+ * If set true Swift will show offline contacts; else not.
+ */
+ static const SettingsProvider::Setting<bool> SHOW_OFFLINE;
+ /**
+ * The #EXPANDED_ROSTER_GROUPS setting specifies the list of groups that are expanded
+ * in the roster UI.
+ *
+ * Its value is a string with group names seperated by newlines.
+ */
+ static const SettingsProvider::Setting<std::string> EXPANDED_ROSTER_GROUPS;
+ static const SettingsProvider::Setting<bool> PLAY_SOUNDS;
+ /**
+ * The #HIGHLIGHT_RULES setting specifies the highlight rules and the associated actions.
+ *
+ * Its value is a Boost serialized representation.
+ */
+ static const SettingsProvider::Setting<std::string> HIGHLIGHT_RULES;
+ /**
+ * The #INVITE_AUTO_ACCEPT_MODE setting specifies how to handle invites to chat rooms.
+ *
+ * Supported values are:
+ * - "no" : It is up to the user whether to accept the invitation and enter a room or not.
+ * - "presence" : The invitation is automatically accepted if it is from a contact that is
+ * already allowed to see the user's presence status.
+ * - "domain" : The invitation is automatically accepted if it is from a contact that is
+ * already allowed to see the user's presence status or from a contact of user's domain.
+ */
+ static const SettingsProvider::Setting<std::string> INVITE_AUTO_ACCEPT_MODE;
+ /**
+ * The #DISCONNECT_ON_CARD_REMOVAL setting
+ * specifies whether or not to sign out the user when
+ * the smartcard is removed.
+ *
+ * If set true Swift will sign out the user when the
+ * smart card is removed; else not.
+ */
+ static const SettingsProvider::Setting<bool> DISCONNECT_ON_CARD_REMOVAL;
+ /**
+ * The #SINGLE_SIGN_ON setting
+ * specifies whether to log in using Single Sign On.
+ * This is currently supported on Windows.
+ *
+ * If set true Swift will use GSSAPI authentication to
+ * log in the user; else not.
+ */
+ static const SettingsProvider::Setting<bool> SINGLE_SIGN_ON;
+ };
}
diff --git a/Swift/Controllers/Settings/DummySettingsProvider.h b/Swift/Controllers/Settings/DummySettingsProvider.h
index 340855a..134aadc 100644
--- a/Swift/Controllers/Settings/DummySettingsProvider.h
+++ b/Swift/Controllers/Settings/DummySettingsProvider.h
@@ -1,56 +1,58 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swift/Controllers/Settings/SettingsProvider.h>
-
#include <map>
+#include <set>
+#include <string>
+
+#include <Swift/Controllers/Settings/SettingsProvider.h>
namespace Swift {
class DummySettingsProvider : public SettingsProvider {
- public:
- virtual ~DummySettingsProvider() {}
- virtual std::string getSetting(const Setting<std::string>& setting) {
- return stringValues.find(setting.getKey()) != stringValues.end() ? stringValues[setting.getKey()] : setting.getDefaultValue();
- }
- virtual void storeSetting(const Setting<std::string>& setting, const std::string& value) {
- stringValues[setting.getKey()] = value;
- onSettingChanged(setting.getKey());
- }
- virtual bool getSetting(const Setting<bool>& setting) {
- return boolValues.find(setting.getKey()) != boolValues.end() ? boolValues[setting.getKey()] : setting.getDefaultValue();
- }
- virtual void storeSetting(const Setting<bool>& setting, const bool& value) {
- boolValues[setting.getKey()] = value;
- onSettingChanged(setting.getKey());
- }
- virtual int getSetting(const Setting<int>& setting) {
- return intValues.find(setting.getKey()) != intValues.end() ? intValues[setting.getKey()] : setting.getDefaultValue();
- }
- virtual void storeSetting(const Setting<int>& setting, const int& value) {
- intValues[setting.getKey()] = value;
- onSettingChanged(setting.getKey());
- }
- virtual std::vector<std::string> getAvailableProfiles() {return std::vector<std::string>();}
- virtual void createProfile(const std::string& ) {}
- virtual void removeProfile(const std::string& ) {}
- virtual bool getIsSettingFinal(const std::string& settingPath) {return finals.count(settingPath);}
- void setFinal(const std::string& settingPath) {
- finals.insert(settingPath);
- }
- virtual bool hasSetting(const std::string& key) {
- return stringValues.find(key) != stringValues.end() || intValues.find(key) != intValues.end() || boolValues.find(key) != boolValues.end();
- }
- private:
- std::map<std::string, std::string> stringValues;
- std::map<std::string, int> intValues;
- std::map<std::string, bool> boolValues;
- std::set<std::string> finals;
+ public:
+ virtual ~DummySettingsProvider() {}
+ virtual std::string getSetting(const Setting<std::string>& setting) {
+ return stringValues.find(setting.getKey()) != stringValues.end() ? stringValues[setting.getKey()] : setting.getDefaultValue();
+ }
+ virtual void storeSetting(const Setting<std::string>& setting, const std::string& value) {
+ stringValues[setting.getKey()] = value;
+ onSettingChanged(setting.getKey());
+ }
+ virtual bool getSetting(const Setting<bool>& setting) {
+ return boolValues.find(setting.getKey()) != boolValues.end() ? boolValues[setting.getKey()] : setting.getDefaultValue();
+ }
+ virtual void storeSetting(const Setting<bool>& setting, const bool& value) {
+ boolValues[setting.getKey()] = value;
+ onSettingChanged(setting.getKey());
+ }
+ virtual int getSetting(const Setting<int>& setting) {
+ return intValues.find(setting.getKey()) != intValues.end() ? intValues[setting.getKey()] : setting.getDefaultValue();
+ }
+ virtual void storeSetting(const Setting<int>& setting, const int& value) {
+ intValues[setting.getKey()] = value;
+ onSettingChanged(setting.getKey());
+ }
+ virtual std::vector<std::string> getAvailableProfiles() {return std::vector<std::string>();}
+ virtual void createProfile(const std::string& ) {}
+ virtual void removeProfile(const std::string& ) {}
+ virtual bool getIsSettingFinal(const std::string& settingPath) {return finals.count(settingPath);}
+ void setFinal(const std::string& settingPath) {
+ finals.insert(settingPath);
+ }
+ virtual bool hasSetting(const std::string& key) {
+ return stringValues.find(key) != stringValues.end() || intValues.find(key) != intValues.end() || boolValues.find(key) != boolValues.end();
+ }
+ private:
+ std::map<std::string, std::string> stringValues;
+ std::map<std::string, int> intValues;
+ std::map<std::string, bool> boolValues;
+ std::set<std::string> finals;
};
}
diff --git a/Swift/Controllers/Settings/SettingsProvider.h b/Swift/Controllers/Settings/SettingsProvider.h
index 1e62d2e..1e9805a 100644
--- a/Swift/Controllers/Settings/SettingsProvider.h
+++ b/Swift/Controllers/Settings/SettingsProvider.h
@@ -1,71 +1,71 @@
/*
- * Copyright (c) 2010-2012 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/boost_bsignals.h>
-
#include <string>
#include <vector>
+#include <boost/signals2.hpp>
+
namespace Swift {
class SettingsProvider {
- public:
- template <typename T>
- class Setting {
- public:
- Setting(const std::string& key, const T& defaultValue) : key(key), defaultValue(defaultValue) {
-
- }
-
- const std::string& getKey() const {
- return key;
- }
-
- const T& getDefaultValue() const {
- return defaultValue;
- }
-
- private:
- std::string key;
- T defaultValue;
- };
-
- public:
- virtual ~SettingsProvider() {}
- virtual std::string getSetting(const Setting<std::string>& setting) = 0;
- virtual void storeSetting(const Setting<std::string>& setting, const std::string& value) = 0;
- virtual bool getSetting(const Setting<bool>& setting) = 0;
- virtual void storeSetting(const Setting<bool>& setting, const bool& value) = 0;
- virtual int getSetting(const Setting<int>& setting) = 0;
- virtual void storeSetting(const Setting<int>& setting, const int& value) = 0;
-
- virtual std::vector<std::string> getAvailableProfiles() = 0;
- virtual void createProfile(const std::string& profile) = 0;
- virtual void removeProfile(const std::string& profile) = 0;
- /** A final setting is one that this settings provider says may not be overriden by lower priority profiles.
- * e.g. An Administrator-set configuration to disallow saving user passwords could not be overridden by the user.
- */
- template<typename T>
- bool getIsSettingFinal(const Setting<T>& setting) {
- return getIsSettingFinal(setting.getKey());
- }
- virtual bool hasSetting(const std::string& key) = 0;
-
- friend class SettingsProviderHierachy;
- protected:
- virtual bool getIsSettingFinal(const std::string& settingPath) = 0;
-
- public:
- /**
- * Emitted when a setting is changed.
- */
- boost::signal<void (const std::string& /*Setting's Path*/)> onSettingChanged;
+ public:
+ template <typename T>
+ class Setting {
+ public:
+ Setting(const std::string& key, const T& defaultValue) : key(key), defaultValue(defaultValue) {
+
+ }
+
+ const std::string& getKey() const {
+ return key;
+ }
+
+ const T& getDefaultValue() const {
+ return defaultValue;
+ }
+
+ private:
+ std::string key;
+ T defaultValue;
+ };
+
+ public:
+ virtual ~SettingsProvider() {}
+ virtual std::string getSetting(const Setting<std::string>& setting) = 0;
+ virtual void storeSetting(const Setting<std::string>& setting, const std::string& value) = 0;
+ virtual bool getSetting(const Setting<bool>& setting) = 0;
+ virtual void storeSetting(const Setting<bool>& setting, const bool& value) = 0;
+ virtual int getSetting(const Setting<int>& setting) = 0;
+ virtual void storeSetting(const Setting<int>& setting, const int& value) = 0;
+
+ virtual std::vector<std::string> getAvailableProfiles() = 0;
+ virtual void createProfile(const std::string& profile) = 0;
+ virtual void removeProfile(const std::string& profile) = 0;
+ /** A final setting is one that this settings provider says may not be overriden by lower priority profiles.
+ * e.g. An Administrator-set configuration to disallow saving user passwords could not be overridden by the user.
+ */
+ template<typename T>
+ bool getIsSettingFinal(const Setting<T>& setting) {
+ return getIsSettingFinal(setting.getKey());
+ }
+ virtual bool hasSetting(const std::string& key) = 0;
+
+ friend class SettingsProviderHierachy;
+ protected:
+ virtual bool getIsSettingFinal(const std::string& settingPath) = 0;
+
+ public:
+ /**
+ * Emitted when a setting is changed.
+ */
+ boost::signals2::signal<void (const std::string& /*Setting's Path*/)> onSettingChanged;
};
}
diff --git a/Swift/Controllers/Settings/SettingsProviderHierachy.cpp b/Swift/Controllers/Settings/SettingsProviderHierachy.cpp
index a349417..a05fabc 100644
--- a/Swift/Controllers/Settings/SettingsProviderHierachy.cpp
+++ b/Swift/Controllers/Settings/SettingsProviderHierachy.cpp
@@ -1,115 +1,115 @@
/*
- * Copyright (c) 2012 Isode Limited.
+ * Copyright (c) 2012-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/Settings/SettingsProviderHierachy.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Base/Log.h>
+
namespace Swift {
SettingsProviderHierachy::~SettingsProviderHierachy() {
}
bool SettingsProviderHierachy::hasSetting(const std::string& key) {
- foreach (SettingsProvider* provider, providers_) {
- if (provider->hasSetting(key)) {
- return true;
- }
- }
- return false;
+ for (auto provider : providers_) {
+ if (provider->hasSetting(key)) {
+ return true;
+ }
+ }
+ return false;
}
std::string SettingsProviderHierachy::getSetting(const Setting<std::string>& setting) {
- std::string value = setting.getDefaultValue();
- foreach (SettingsProvider* provider, providers_) {
- std::string providerSetting = provider->getSetting(setting);
- if (provider->hasSetting(setting.getKey())) {
- value = providerSetting;
- }
- if (provider->getIsSettingFinal(setting.getKey())) {
- return value;
- }
- }
- return value;
+ std::string value = setting.getDefaultValue();
+ for (auto provider : providers_) {
+ std::string providerSetting = provider->getSetting(setting);
+ if (provider->hasSetting(setting.getKey())) {
+ value = providerSetting;
+ }
+ if (provider->getIsSettingFinal(setting.getKey())) {
+ return value;
+ }
+ }
+ return value;
}
void SettingsProviderHierachy::storeSetting(const Setting<std::string>& setting, const std::string& settingValue) {
- if (!getIsSettingFinal(setting.getKey())) {
- getWritableProvider()->storeSetting(setting, settingValue);
- }
+ if (!getIsSettingFinal(setting.getKey())) {
+ getWritableProvider()->storeSetting(setting, settingValue);
+ }
}
bool SettingsProviderHierachy::getSetting(const Setting<bool>& setting) {
- bool value = setting.getDefaultValue();
- foreach (SettingsProvider* provider, providers_) {
- bool providerSetting = provider->getSetting(setting);
- if (provider->hasSetting(setting.getKey())) {
- value = providerSetting;
- if (provider->getIsSettingFinal(setting.getKey())) {
- return providerSetting;
- }
- }
- }
- return value;
+ bool value = setting.getDefaultValue();
+ for (auto provider : providers_) {
+ bool providerSetting = provider->getSetting(setting);
+ if (provider->hasSetting(setting.getKey())) {
+ value = providerSetting;
+ if (provider->getIsSettingFinal(setting.getKey())) {
+ return providerSetting;
+ }
+ }
+ }
+ return value;
}
void SettingsProviderHierachy::storeSetting(const Setting<bool>& setting, const bool& settingValue) {
- if (!getIsSettingFinal(setting.getKey())) {
- getWritableProvider()->storeSetting(setting, settingValue);
- }
+ if (!getIsSettingFinal(setting.getKey())) {
+ getWritableProvider()->storeSetting(setting, settingValue);
+ }
}
int SettingsProviderHierachy::getSetting(const Setting<int>& setting) {
- int value = setting.getDefaultValue();
- foreach (SettingsProvider* provider, providers_) {
- int providerSetting = provider->getSetting(setting);
- if (provider->hasSetting(setting.getKey())) {
- value = providerSetting;
- if (provider->getIsSettingFinal(setting.getKey())) {
- return providerSetting;
- }
- }
- }
- return value;
+ int value = setting.getDefaultValue();
+ for (auto provider : providers_) {
+ int providerSetting = provider->getSetting(setting);
+ if (provider->hasSetting(setting.getKey())) {
+ value = providerSetting;
+ if (provider->getIsSettingFinal(setting.getKey())) {
+ return providerSetting;
+ }
+ }
+ }
+ return value;
}
void SettingsProviderHierachy::storeSetting(const Setting<int>& setting, const int& settingValue) {
- if (!getIsSettingFinal(setting.getKey())) {
- getWritableProvider()->storeSetting(setting, settingValue);
- }
+ if (!getIsSettingFinal(setting.getKey())) {
+ getWritableProvider()->storeSetting(setting, settingValue);
+ }
}
std::vector<std::string> SettingsProviderHierachy::getAvailableProfiles() {
- /* Always pull profiles from the topmost */
- return getWritableProvider()->getAvailableProfiles();
+ /* Always pull profiles from the topmost */
+ return getWritableProvider()->getAvailableProfiles();
}
void SettingsProviderHierachy::createProfile(const std::string& profile) {
- return getWritableProvider()->createProfile(profile);
+ return getWritableProvider()->createProfile(profile);
}
void SettingsProviderHierachy::removeProfile(const std::string& profile) {
- return getWritableProvider()->removeProfile(profile);
+ return getWritableProvider()->removeProfile(profile);
}
bool SettingsProviderHierachy::getIsSettingFinal(const std::string& settingPath) {
- bool isFinal = false;
- foreach (SettingsProvider* provider, providers_) {
- isFinal |= provider->getIsSettingFinal(settingPath);
- }
- return isFinal;
+ bool isFinal = false;
+ for (auto provider : providers_) {
+ isFinal |= provider->getIsSettingFinal(settingPath);
+ }
+ return isFinal;
}
SettingsProvider* SettingsProviderHierachy::getWritableProvider() {
- return providers_.back();
+ return providers_.back();
}
void SettingsProviderHierachy::addProviderToTopOfStack(SettingsProvider* provider) {
- providers_.push_back(provider);
- provider->onSettingChanged.connect(onSettingChanged);
+ providers_.push_back(provider);
+ provider->onSettingChanged.connect(onSettingChanged);
}
}
diff --git a/Swift/Controllers/Settings/SettingsProviderHierachy.h b/Swift/Controllers/Settings/SettingsProviderHierachy.h
index 9efbdcb..a68ff36 100644
--- a/Swift/Controllers/Settings/SettingsProviderHierachy.h
+++ b/Swift/Controllers/Settings/SettingsProviderHierachy.h
@@ -11,34 +11,34 @@
namespace Swift {
class SettingsProviderHierachy : public SettingsProvider {
- public:
- virtual ~SettingsProviderHierachy();
- virtual std::string getSetting(const Setting<std::string>& setting);
- virtual void storeSetting(const Setting<std::string>& setting, const std::string& value);
- virtual bool getSetting(const Setting<bool>& setting);
- virtual void storeSetting(const Setting<bool>& setting, const bool& value);
- virtual int getSetting(const Setting<int>& setting);
- virtual void storeSetting(const Setting<int>& setting, const int& value);
- virtual std::vector<std::string> getAvailableProfiles();
- virtual void createProfile(const std::string& profile);
- virtual void removeProfile(const std::string& profile);
- virtual bool hasSetting(const std::string& key);
- protected:
- virtual bool getIsSettingFinal(const std::string& settingPath);
-
- public:
- /**
- * Adds a provider less significant than any already added.
- * This means that if an existing provider has a setting, this provider won't be asked.
- * Any settings will be pushed into the topmost (least significant) provider.
- * Does not take ownership of provider.
- */
- void addProviderToTopOfStack(SettingsProvider* provider);
- private:
- SettingsProvider* getWritableProvider();
- private:
- /* Start/Left is most significant (lowest), left overrides right.*/
- std::vector<SettingsProvider*> providers_;
+ public:
+ virtual ~SettingsProviderHierachy();
+ virtual std::string getSetting(const Setting<std::string>& setting);
+ virtual void storeSetting(const Setting<std::string>& setting, const std::string& value);
+ virtual bool getSetting(const Setting<bool>& setting);
+ virtual void storeSetting(const Setting<bool>& setting, const bool& value);
+ virtual int getSetting(const Setting<int>& setting);
+ virtual void storeSetting(const Setting<int>& setting, const int& value);
+ virtual std::vector<std::string> getAvailableProfiles();
+ virtual void createProfile(const std::string& profile);
+ virtual void removeProfile(const std::string& profile);
+ virtual bool hasSetting(const std::string& key);
+ protected:
+ virtual bool getIsSettingFinal(const std::string& settingPath);
+
+ public:
+ /**
+ * Adds a provider less significant than any already added.
+ * This means that if an existing provider has a setting, this provider won't be asked.
+ * Any settings will be pushed into the topmost (least significant) provider.
+ * Does not take ownership of provider.
+ */
+ void addProviderToTopOfStack(SettingsProvider* provider);
+ private:
+ SettingsProvider* getWritableProvider();
+ private:
+ /* Start/Left is most significant (lowest), left overrides right.*/
+ std::vector<SettingsProvider*> providers_;
};
}
diff --git a/Swift/Controllers/Settings/UnitTest/SettingsProviderHierachyTest.cpp b/Swift/Controllers/Settings/UnitTest/SettingsProviderHierachyTest.cpp
index dc9a92d..3cfebc7 100644
--- a/Swift/Controllers/Settings/UnitTest/SettingsProviderHierachyTest.cpp
+++ b/Swift/Controllers/Settings/UnitTest/SettingsProviderHierachyTest.cpp
@@ -1,91 +1,87 @@
/*
- * Copyright (c) 2012 Isode Limited.
+ * Copyright (c) 2012-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
+#include <memory>
+
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
-#include <Swift/Controllers/Settings/SettingsProviderHierachy.h>
#include <Swift/Controllers/Settings/DummySettingsProvider.h>
+#include <Swift/Controllers/Settings/SettingsProviderHierachy.h>
#include <Swift/Controllers/Settings/XMLSettingsProvider.h>
using namespace Swift;
using namespace std;
class SettingsProviderHierachyTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(SettingsProviderHierachyTest);
- CPPUNIT_TEST(testEmpty);
- CPPUNIT_TEST(testTop);
- CPPUNIT_TEST(testBottom);
- CPPUNIT_TEST(testBoth);
- CPPUNIT_TEST(testTopDefault);
- CPPUNIT_TEST(testBottomOverrides);
- CPPUNIT_TEST(testFinal);
- CPPUNIT_TEST_SUITE_END();
+ CPPUNIT_TEST_SUITE(SettingsProviderHierachyTest);
+ CPPUNIT_TEST(testEmpty);
+ CPPUNIT_TEST(testTop);
+ CPPUNIT_TEST(testBottom);
+ CPPUNIT_TEST(testBoth);
+ CPPUNIT_TEST(testTopDefault);
+ CPPUNIT_TEST(testBottomOverrides);
+ CPPUNIT_TEST(testFinal);
+ CPPUNIT_TEST_SUITE_END();
public:
- SettingsProviderHierachyTest() : setting1("somekey", 42) {}
-
- void setUp() {
- bottom = new DummySettingsProvider();
- top = new DummySettingsProvider();
- testling = new SettingsProviderHierachy();
- testling->addProviderToTopOfStack(bottom);
- testling->addProviderToTopOfStack(top);
- }
+ SettingsProviderHierachyTest() : setting1("somekey", 42) {}
- void tearDown() {
- delete testling;
- delete top;
- delete bottom;
- }
+ void setUp() {
+ bottom = std::unique_ptr<DummySettingsProvider>(new DummySettingsProvider());
+ top = std::unique_ptr<DummySettingsProvider>(new DummySettingsProvider());
+ testling = std::unique_ptr<SettingsProviderHierachy>(new SettingsProviderHierachy());
+ testling->addProviderToTopOfStack(bottom.get());
+ testling->addProviderToTopOfStack(top.get());
+ }
- void testEmpty() {
- CPPUNIT_ASSERT_EQUAL(42, testling->getSetting(setting1));
- }
+ void testEmpty() {
+ CPPUNIT_ASSERT_EQUAL(42, testling->getSetting(setting1));
+ }
- void testTop() {
- top->storeSetting(setting1, 37);
- CPPUNIT_ASSERT_EQUAL(37, testling->getSetting(setting1));
- }
+ void testTop() {
+ top->storeSetting(setting1, 37);
+ CPPUNIT_ASSERT_EQUAL(37, testling->getSetting(setting1));
+ }
- void testBottom() {
- bottom->storeSetting(setting1, 17);
- CPPUNIT_ASSERT_EQUAL(17, testling->getSetting(setting1));
- }
+ void testBottom() {
+ bottom->storeSetting(setting1, 17);
+ CPPUNIT_ASSERT_EQUAL(17, testling->getSetting(setting1));
+ }
- void testBoth() {
- bottom->storeSetting(setting1, 17);
- top->storeSetting(setting1, 37);
- CPPUNIT_ASSERT_EQUAL(37, testling->getSetting(setting1));
- }
+ void testBoth() {
+ bottom->storeSetting(setting1, 17);
+ top->storeSetting(setting1, 37);
+ CPPUNIT_ASSERT_EQUAL(37, testling->getSetting(setting1));
+ }
- void testTopDefault() {
- bottom->storeSetting(setting1, 17);
- top->storeSetting(setting1, 42);
- CPPUNIT_ASSERT_EQUAL(42, testling->getSetting(setting1));
- }
+ void testTopDefault() {
+ bottom->storeSetting(setting1, 17);
+ top->storeSetting(setting1, 42);
+ CPPUNIT_ASSERT_EQUAL(42, testling->getSetting(setting1));
+ }
- void testBottomOverrides() {
- bottom->storeSetting(setting1, 17);
- bottom->setFinal(setting1.getKey());
- top->storeSetting(setting1, 5);
- CPPUNIT_ASSERT_EQUAL(17, testling->getSetting(setting1));
- }
+ void testBottomOverrides() {
+ bottom->storeSetting(setting1, 17);
+ bottom->setFinal(setting1.getKey());
+ top->storeSetting(setting1, 5);
+ CPPUNIT_ASSERT_EQUAL(17, testling->getSetting(setting1));
+ }
- void testFinal() {
- bottom->storeSetting(setting1, 17);
- bottom->setFinal(setting1.getKey());
- testling->storeSetting(setting1, 5);
- CPPUNIT_ASSERT_EQUAL(17, testling->getSetting(setting1));
- }
+ void testFinal() {
+ bottom->storeSetting(setting1, 17);
+ bottom->setFinal(setting1.getKey());
+ testling->storeSetting(setting1, 5);
+ CPPUNIT_ASSERT_EQUAL(17, testling->getSetting(setting1));
+ }
private:
- SettingsProviderHierachy* testling;
- DummySettingsProvider* bottom;
- DummySettingsProvider* top;
- SettingsProvider::Setting<int> setting1;
+ std::unique_ptr<SettingsProviderHierachy> testling;
+ std::unique_ptr<DummySettingsProvider> bottom;
+ std::unique_ptr<DummySettingsProvider> top;
+ SettingsProvider::Setting<int> setting1;
};
CPPUNIT_TEST_SUITE_REGISTRATION(SettingsProviderHierachyTest);
diff --git a/Swift/Controllers/Settings/XMLSettingsProvider.cpp b/Swift/Controllers/Settings/XMLSettingsProvider.cpp
index d28947f..4dfb8bd 100644
--- a/Swift/Controllers/Settings/XMLSettingsProvider.cpp
+++ b/Swift/Controllers/Settings/XMLSettingsProvider.cpp
@@ -1,35 +1,35 @@
/*
- * Copyright (c) 2012 Isode Limited.
+ * Copyright (c) 2012-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/Settings/XMLSettingsProvider.h>
-#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
+#include <boost/lexical_cast.hpp>
+#include <Swiften/Base/Log.h>
#include <Swiften/Parser/PlatformXMLParserFactory.h>
#include <Swiften/Parser/XMLParser.h>
-#include <Swiften/Base/Log.h>
namespace Swift {
XMLSettingsProvider::XMLSettingsProvider(const std::string& xmlConfig) : level_(0) {
- if (!xmlConfig.empty()) {
- PlatformXMLParserFactory factory;
- XMLParser* parser = factory.createXMLParser(this);
- if (parser->parse(xmlConfig)) {
- SWIFT_LOG(debug) << "Found and parsed system config" << std::endl;
- }
- else {
- SWIFT_LOG(debug) << "Found invalid system config" << std::endl;
- }
- delete parser;
- }
- else {
- SWIFT_LOG(debug) << "No system config found" << std::endl;
- }
+ if (!xmlConfig.empty()) {
+ PlatformXMLParserFactory factory;
+ XMLParser* parser = factory.createXMLParser(this);
+ if (parser->parse(xmlConfig)) {
+ SWIFT_LOG(debug) << "Found and parsed system config" << std::endl;
+ }
+ else {
+ SWIFT_LOG(debug) << "Found invalid system config" << std::endl;
+ }
+ delete parser;
+ }
+ else {
+ SWIFT_LOG(debug) << "No system config found" << std::endl;
+ }
}
XMLSettingsProvider::~XMLSettingsProvider() {
@@ -37,89 +37,89 @@ XMLSettingsProvider::~XMLSettingsProvider() {
}
bool XMLSettingsProvider::hasSetting(const std::string& key) {
- return (values_.find(key) != values_.end());
+ return (values_.find(key) != values_.end());
}
std::string XMLSettingsProvider::getSetting(const Setting<std::string>& setting) {
- if (values_.find(setting.getKey()) != values_.end()) {
- std::string value = values_[setting.getKey()];
- return value;
- }
- return setting.getDefaultValue();
+ if (values_.find(setting.getKey()) != values_.end()) {
+ std::string value = values_[setting.getKey()];
+ return value;
+ }
+ return setting.getDefaultValue();
}
void XMLSettingsProvider::storeSetting(const Setting<std::string>& /*settingPath*/, const std::string& /*settingValue*/) {
- assert(false);
+ assert(false);
}
bool XMLSettingsProvider::getSetting(const Setting<bool>& setting) {
- if (values_.find(setting.getKey()) != values_.end()) {
- std::string value = values_[setting.getKey()];
- return boost::iequals(value, "true") || value == "1";
- }
- return setting.getDefaultValue();
+ if (values_.find(setting.getKey()) != values_.end()) {
+ std::string value = values_[setting.getKey()];
+ return boost::iequals(value, "true") || value == "1";
+ }
+ return setting.getDefaultValue();
}
void XMLSettingsProvider::storeSetting(const Setting<bool>& /*settingPath*/, const bool& /*settingValue*/) {
- assert(false);
+ assert(false);
}
int XMLSettingsProvider::getSetting(const Setting<int>& setting) {
- if (values_.find(setting.getKey()) != values_.end()) {
- std::string value = values_[setting.getKey()];
- try {
- return value.empty() ? setting.getDefaultValue() : boost::lexical_cast<int>(value);;
- }
- catch(boost::bad_lexical_cast &) {}
- }
- return setting.getDefaultValue();
+ if (values_.find(setting.getKey()) != values_.end()) {
+ std::string value = values_[setting.getKey()];
+ try {
+ return value.empty() ? setting.getDefaultValue() : boost::lexical_cast<int>(value);;
+ }
+ catch(boost::bad_lexical_cast &) {}
+ }
+ return setting.getDefaultValue();
}
void XMLSettingsProvider::storeSetting(const Setting<int>& /*settingPath*/, const int& /*settingValue*/) {
- assert(false);
+ assert(false);
}
std::vector<std::string> XMLSettingsProvider::getAvailableProfiles() {
- assert(false);
- return std::vector<std::string>();
+ assert(false);
+ return std::vector<std::string>();
}
void XMLSettingsProvider::createProfile(const std::string& /*profile*/) {
- assert(false);
+ assert(false);
}
void XMLSettingsProvider::removeProfile(const std::string& /*profile*/) {
- assert(false);
+ assert(false);
}
bool XMLSettingsProvider::getIsSettingFinal(const std::string& settingPath) {
- return finals_.count(settingPath);
+ return finals_.count(settingPath);
}
void XMLSettingsProvider::handleStartElement(const std::string& element, const std::string& /*ns*/, const AttributeMap& attributes) {
- level_++;
- if (level_ == SettingLevel) {
- if (attributes.getBoolAttribute("final", false)) {
- finals_.insert(element);
- }
- currentElement_ = element;
- currentText_ = "";
- }
+ level_++;
+ if (level_ == SettingLevel) {
+ if (attributes.getBoolAttribute("final", false)) {
+ finals_.insert(element);
+ }
+ currentElement_ = element;
+ currentText_ = "";
+ }
}
void XMLSettingsProvider::handleEndElement(const std::string& /*element*/, const std::string& /*ns*/) {
- if (level_ == SettingLevel) {
- values_[currentElement_] = currentText_;
- SWIFT_LOG(debug) << "Setting value of " << currentElement_ << " to " << currentText_ << std::endl;
- }
- level_--;
+ if (level_ == SettingLevel) {
+ values_[currentElement_] = currentText_;
+ SWIFT_LOG(debug) << "Setting value of " << currentElement_ << " to " << currentText_ << std::endl;
+ }
+ level_--;
}
void XMLSettingsProvider::handleCharacterData(const std::string& data) {
- if (level_ >= SettingLevel) {
- currentText_ += data;
- }
+ if (level_ >= SettingLevel) {
+ currentText_ += data;
+ }
}
diff --git a/Swift/Controllers/Settings/XMLSettingsProvider.h b/Swift/Controllers/Settings/XMLSettingsProvider.h
index 24689b7..5fd82cf 100644
--- a/Swift/Controllers/Settings/XMLSettingsProvider.h
+++ b/Swift/Controllers/Settings/XMLSettingsProvider.h
@@ -1,54 +1,55 @@
/*
- * Copyright (c) 2012 Isode Limited.
+ * Copyright (c) 2012-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swift/Controllers/Settings/SettingsProvider.h>
-#include <Swiften/Parser/XMLParserClient.h>
-
#include <map>
#include <set>
+#include <Swiften/Parser/XMLParserClient.h>
+
+#include <Swift/Controllers/Settings/SettingsProvider.h>
+
namespace Swift {
class XMLSettingsProvider : public SettingsProvider, public XMLParserClient {
- public:
- XMLSettingsProvider(const std::string& xmlConfig);
- virtual ~XMLSettingsProvider();
- virtual std::string getSetting(const Setting<std::string>& setting);
- virtual void storeSetting(const Setting<std::string>& setting, const std::string& value);
- virtual bool getSetting(const Setting<bool>& setting);
- virtual void storeSetting(const Setting<bool>& setting, const bool& value);
- virtual int getSetting(const Setting<int>& setting);
- virtual void storeSetting(const Setting<int>& setting, const int& value);
- virtual std::vector<std::string> getAvailableProfiles();
- virtual void createProfile(const std::string& profile);
- virtual void removeProfile(const std::string& profile);
- virtual bool hasSetting(const std::string& key);
-
-
- virtual void handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes);
- virtual void handleEndElement(const std::string& element, const std::string& ns);
- virtual void handleCharacterData(const std::string& data);
-
- protected:
- virtual bool getIsSettingFinal(const std::string& settingPath);
- private:
- std::map<std::string /*settingPath*/, std::string /*settingValue*/> values_;
- /* Settings that are final*/
- std::set<std::string /*settingPath*/> finals_;
-
- enum Level {
- TopLevel = 0,
- SettingLevel = 2
- };
-
- int level_;
- std::string currentElement_;
- std::string currentText_;
+ public:
+ XMLSettingsProvider(const std::string& xmlConfig);
+ virtual ~XMLSettingsProvider();
+ virtual std::string getSetting(const Setting<std::string>& setting);
+ virtual void storeSetting(const Setting<std::string>& setting, const std::string& value);
+ virtual bool getSetting(const Setting<bool>& setting);
+ virtual void storeSetting(const Setting<bool>& setting, const bool& value);
+ virtual int getSetting(const Setting<int>& setting);
+ virtual void storeSetting(const Setting<int>& setting, const int& value);
+ virtual std::vector<std::string> getAvailableProfiles();
+ virtual void createProfile(const std::string& profile);
+ virtual void removeProfile(const std::string& profile);
+ virtual bool hasSetting(const std::string& key);
+
+
+ virtual void handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes);
+ virtual void handleEndElement(const std::string& element, const std::string& ns);
+ virtual void handleCharacterData(const std::string& data);
+
+ protected:
+ virtual bool getIsSettingFinal(const std::string& settingPath);
+ private:
+ std::map<std::string /*settingPath*/, std::string /*settingValue*/> values_;
+ /* Settings that are final*/
+ std::set<std::string /*settingPath*/> finals_;
+
+ enum Level {
+ TopLevel = 0,
+ SettingLevel = 2
+ };
+
+ int level_;
+ std::string currentElement_;
+ std::string currentText_;
};
}
diff --git a/Swift/Controllers/ShowProfileController.cpp b/Swift/Controllers/ShowProfileController.cpp
index 88d6e69..b379141 100644
--- a/Swift/Controllers/ShowProfileController.cpp
+++ b/Swift/Controllers/ShowProfileController.cpp
@@ -5,17 +5,16 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "ShowProfileController.h"
+#include <Swift/Controllers/ShowProfileController.h>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
-#include <Swiften/Base/foreach.h>
#include <Swiften/VCards/VCardManager.h>
#include <Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h>
@@ -25,57 +24,56 @@
namespace Swift {
ShowProfileController::ShowProfileController(VCardManager* vcardManager, ProfileWindowFactory* profileWindowFactory, UIEventStream* uiEventStream) : vcardManager(vcardManager), profileWindowFactory(profileWindowFactory), uiEventStream(uiEventStream) {
- uiEventStream->onUIEvent.connect(boost::bind(&ShowProfileController::handleUIEvent, this, _1));
- vcardManager->onVCardChanged.connect(boost::bind(&ShowProfileController::handleVCardChanged, this, _1, _2));
+ uiEventStream->onUIEvent.connect(boost::bind(&ShowProfileController::handleUIEvent, this, _1));
+ vcardManager->onVCardChanged.connect(boost::bind(&ShowProfileController::handleVCardChanged, this, _1, _2));
}
ShowProfileController::~ShowProfileController() {
- typedef std::pair<JID, ProfileWindow*> JIDProfileWindowPair;
- foreach(const JIDProfileWindowPair& jidWndPair, openedProfileWindows) {
- jidWndPair.second->onWindowAboutToBeClosed.disconnect(boost::bind(&ShowProfileController::handleProfileWindowAboutToBeClosed, this, _1));
- delete jidWndPair.second;
- }
+ for (const auto& jidWndPair : openedProfileWindows) {
+ jidWndPair.second->onWindowAboutToBeClosed.disconnect(boost::bind(&ShowProfileController::handleProfileWindowAboutToBeClosed, this, _1));
+ delete jidWndPair.second;
+ }
- vcardManager->onVCardChanged.disconnect(boost::bind(&ShowProfileController::handleVCardChanged, this, _1, _2));
- uiEventStream->onUIEvent.disconnect(boost::bind(&ShowProfileController::handleUIEvent, this, _1));
+ vcardManager->onVCardChanged.disconnect(boost::bind(&ShowProfileController::handleVCardChanged, this, _1, _2));
+ uiEventStream->onUIEvent.disconnect(boost::bind(&ShowProfileController::handleUIEvent, this, _1));
}
void ShowProfileController::handleUIEvent(UIEvent::ref event) {
- ShowProfileForRosterItemUIEvent::ref showProfileEvent = boost::dynamic_pointer_cast<ShowProfileForRosterItemUIEvent>(event);
- if (!showProfileEvent) {
- return;
- }
+ ShowProfileForRosterItemUIEvent::ref showProfileEvent = std::dynamic_pointer_cast<ShowProfileForRosterItemUIEvent>(event);
+ if (!showProfileEvent) {
+ return;
+ }
- if (openedProfileWindows.find(showProfileEvent->getJID()) == openedProfileWindows.end()) {
- ProfileWindow* newProfileWindow = profileWindowFactory->createProfileWindow();
- newProfileWindow->setJID(showProfileEvent->getJID());
- newProfileWindow->onWindowAboutToBeClosed.connect(boost::bind(&ShowProfileController::handleProfileWindowAboutToBeClosed, this, _1));
- openedProfileWindows[showProfileEvent->getJID()] = newProfileWindow;
- VCard::ref vcard = vcardManager->getVCardAndRequestWhenNeeded(showProfileEvent->getJID(), boost::posix_time::minutes(5));
- if (vcard) {
- newProfileWindow->setVCard(vcard);
- } else {
- newProfileWindow->setProcessing(true);
- }
- newProfileWindow->show();
- } else {
- openedProfileWindows[showProfileEvent->getJID()]->show();
- }
+ if (openedProfileWindows.find(showProfileEvent->getJID()) == openedProfileWindows.end()) {
+ ProfileWindow* newProfileWindow = profileWindowFactory->createProfileWindow();
+ newProfileWindow->setJID(showProfileEvent->getJID());
+ newProfileWindow->onWindowAboutToBeClosed.connect(boost::bind(&ShowProfileController::handleProfileWindowAboutToBeClosed, this, _1));
+ openedProfileWindows[showProfileEvent->getJID()] = newProfileWindow;
+ VCard::ref vcard = vcardManager->getVCardAndRequestWhenNeeded(showProfileEvent->getJID(), boost::posix_time::minutes(5));
+ if (vcard) {
+ newProfileWindow->setVCard(vcard);
+ } else {
+ newProfileWindow->setProcessing(true);
+ }
+ newProfileWindow->show();
+ } else {
+ openedProfileWindows[showProfileEvent->getJID()]->show();
+ }
}
void ShowProfileController::handleVCardChanged(const JID& jid, VCard::ref vcard) {
- if (openedProfileWindows.find(jid) == openedProfileWindows.end()) {
- return;
- }
+ if (openedProfileWindows.find(jid) == openedProfileWindows.end()) {
+ return;
+ }
- ProfileWindow* profileWindow = openedProfileWindows[jid];
- profileWindow->setVCard(vcard);
- profileWindow->setProcessing(false);
- profileWindow->show();
+ ProfileWindow* profileWindow = openedProfileWindows[jid];
+ profileWindow->setVCard(vcard);
+ profileWindow->setProcessing(false);
+ profileWindow->show();
}
void ShowProfileController::handleProfileWindowAboutToBeClosed(const JID& profileJid) {
- openedProfileWindows.erase(profileJid);
+ openedProfileWindows.erase(profileJid);
}
}
diff --git a/Swift/Controllers/ShowProfileController.h b/Swift/Controllers/ShowProfileController.h
index 27a0cf4..4f23c19 100644
--- a/Swift/Controllers/ShowProfileController.h
+++ b/Swift/Controllers/ShowProfileController.h
@@ -4,33 +4,39 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
-#include <Swiften/JID/JID.h>
#include <Swiften/Elements/VCard.h>
+#include <Swiften/JID/JID.h>
#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class VCardManager;
- class ProfileWindow;
- class ProfileWindowFactory;
- class UIEventStream;
-
- class ShowProfileController {
- public:
- ShowProfileController(VCardManager* vcardManager, ProfileWindowFactory* profileWindowFactory, UIEventStream* uiEventStream);
- ~ShowProfileController();
-
- private:
- void handleUIEvent(UIEvent::ref event);
- void handleVCardChanged(const JID&, VCard::ref);
- void handleProfileWindowAboutToBeClosed(const JID& profileJid);
-
- private:
- VCardManager* vcardManager;
- ProfileWindowFactory* profileWindowFactory;
- UIEventStream* uiEventStream;
- std::map<JID, ProfileWindow*> openedProfileWindows;
- };
+ class VCardManager;
+ class ProfileWindow;
+ class ProfileWindowFactory;
+ class UIEventStream;
+
+ class ShowProfileController {
+ public:
+ ShowProfileController(VCardManager* vcardManager, ProfileWindowFactory* profileWindowFactory, UIEventStream* uiEventStream);
+ ~ShowProfileController();
+
+ private:
+ void handleUIEvent(UIEvent::ref event);
+ void handleVCardChanged(const JID&, VCard::ref);
+ void handleProfileWindowAboutToBeClosed(const JID& profileJid);
+
+ private:
+ VCardManager* vcardManager;
+ ProfileWindowFactory* profileWindowFactory;
+ UIEventStream* uiEventStream;
+ std::map<JID, ProfileWindow*> openedProfileWindows;
+ };
}
diff --git a/Swift/Controllers/SoundEventController.cpp b/Swift/Controllers/SoundEventController.cpp
index 43c8ed0..5c7568f 100644
--- a/Swift/Controllers/SoundEventController.cpp
+++ b/Swift/Controllers/SoundEventController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -18,39 +18,39 @@
namespace Swift {
SoundEventController::SoundEventController(EventController* eventController, SoundPlayer* soundPlayer, SettingsProvider* settings, HighlightManager* highlightManager) {
- settings_ = settings;
- eventController_ = eventController;
- soundPlayer_ = soundPlayer;
- eventController_->onEventQueueEventAdded.connect(boost::bind(&SoundEventController::handleEventQueueEventAdded, this, _1));
- highlightManager_ = highlightManager;
- highlightManager_->onHighlight.connect(boost::bind(&SoundEventController::handleHighlight, this, _1));
+ settings_ = settings;
+ eventController_ = eventController;
+ soundPlayer_ = soundPlayer;
+ eventController_->onEventQueueEventAdded.connect(boost::bind(&SoundEventController::handleEventQueueEventAdded, this, _1));
+ highlightManager_ = highlightManager;
+ highlightManager_->onHighlight.connect(boost::bind(&SoundEventController::handleHighlight, this, _1));
- settings_->onSettingChanged.connect(boost::bind(&SoundEventController::handleSettingChanged, this, _1));
+ settings_->onSettingChanged.connect(boost::bind(&SoundEventController::handleSettingChanged, this, _1));
- playSounds_ = settings->getSetting(SettingConstants::PLAY_SOUNDS);
+ playSounds_ = settings->getSetting(SettingConstants::PLAY_SOUNDS);
}
-void SoundEventController::handleEventQueueEventAdded(boost::shared_ptr<StanzaEvent> event) {
- if (playSounds_ && boost::dynamic_pointer_cast<IncomingFileTransferEvent>(event)) {
- soundPlayer_->playSound(SoundPlayer::MessageReceived, "");
- }
+void SoundEventController::handleEventQueueEventAdded(std::shared_ptr<StanzaEvent> event) {
+ if (playSounds_ && std::dynamic_pointer_cast<IncomingFileTransferEvent>(event)) {
+ soundPlayer_->playSound(SoundPlayer::MessageReceived, "");
+ }
}
void SoundEventController::handleHighlight(const HighlightAction& action) {
- if (playSounds_ && action.playSound()) {
- soundPlayer_->playSound(SoundPlayer::MessageReceived, action.getSoundFile());
- }
+ if (playSounds_ && action.playSound()) {
+ soundPlayer_->playSound(SoundPlayer::MessageReceived, action.getSoundFile());
+ }
}
void SoundEventController::setPlaySounds(bool playSounds) {
- playSounds_ = playSounds;
- settings_->storeSetting(SettingConstants::PLAY_SOUNDS, playSounds);
+ playSounds_ = playSounds;
+ settings_->storeSetting(SettingConstants::PLAY_SOUNDS, playSounds);
}
void SoundEventController::handleSettingChanged(const std::string& settingPath) {
- if (SettingConstants::PLAY_SOUNDS.getKey() == settingPath) {
- playSounds_ = settings_->getSetting(SettingConstants::PLAY_SOUNDS);
- }
+ if (SettingConstants::PLAY_SOUNDS.getKey() == settingPath) {
+ playSounds_ = settings_->getSetting(SettingConstants::PLAY_SOUNDS);
+ }
}
}
diff --git a/Swift/Controllers/SoundEventController.h b/Swift/Controllers/SoundEventController.h
index 17924cd..e5b43b4 100644
--- a/Swift/Controllers/SoundEventController.h
+++ b/Swift/Controllers/SoundEventController.h
@@ -1,34 +1,34 @@
/*
- * Copyright (c) 2010-2012 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
-#include <Swift/Controllers/XMPPEvents/StanzaEvent.h>
-#include <Swift/Controllers/Settings/SettingsProvider.h>
#include <Swift/Controllers/HighlightAction.h>
+#include <Swift/Controllers/Settings/SettingsProvider.h>
+#include <Swift/Controllers/XMPPEvents/StanzaEvent.h>
namespace Swift {
- class EventController;
- class SoundPlayer;
- class HighlightManager;
- class SoundEventController {
- public:
- SoundEventController(EventController* eventController, SoundPlayer* soundPlayer, SettingsProvider* settings, HighlightManager* highlightManager);
- void setPlaySounds(bool playSounds);
- bool getSoundEnabled() {return playSounds_;}
- private:
- void handleSettingChanged(const std::string& settingPath);
- void handleEventQueueEventAdded(boost::shared_ptr<StanzaEvent> event);
- void handleHighlight(const HighlightAction& action);
- EventController* eventController_;
- SoundPlayer* soundPlayer_;
- bool playSounds_;
- SettingsProvider* settings_;
- HighlightManager* highlightManager_;
- };
+ class EventController;
+ class SoundPlayer;
+ class HighlightManager;
+ class SoundEventController {
+ public:
+ SoundEventController(EventController* eventController, SoundPlayer* soundPlayer, SettingsProvider* settings, HighlightManager* highlightManager);
+ void setPlaySounds(bool playSounds);
+ bool getSoundEnabled() {return playSounds_;}
+ private:
+ void handleSettingChanged(const std::string& settingPath);
+ void handleEventQueueEventAdded(std::shared_ptr<StanzaEvent> event);
+ void handleHighlight(const HighlightAction& action);
+ EventController* eventController_;
+ SoundPlayer* soundPlayer_;
+ bool playSounds_;
+ SettingsProvider* settings_;
+ HighlightManager* highlightManager_;
+ };
}
diff --git a/Swift/Controllers/SoundPlayer.h b/Swift/Controllers/SoundPlayer.h
index e38cd7c..8525c6c 100644
--- a/Swift/Controllers/SoundPlayer.h
+++ b/Swift/Controllers/SoundPlayer.h
@@ -9,10 +9,10 @@
#include <string>
namespace Swift {
- class SoundPlayer {
- public:
- virtual ~SoundPlayer() {}
- enum SoundEffect{MessageReceived};
- virtual void playSound(SoundEffect sound, const std::string& soundResource) = 0;
- };
+ class SoundPlayer {
+ public:
+ virtual ~SoundPlayer() {}
+ enum SoundEffect{MessageReceived};
+ virtual void playSound(SoundEffect sound, const std::string& soundResource) = 0;
+ };
}
diff --git a/Swift/Controllers/StatusCache.cpp b/Swift/Controllers/StatusCache.cpp
index e40ac7f..3c6baed 100644
--- a/Swift/Controllers/StatusCache.cpp
+++ b/Swift/Controllers/StatusCache.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Isode Limited.
+ * Copyright (c) 2012-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,25 +7,22 @@
#include <Swift/Controllers/StatusCache.h>
#include <boost/algorithm/string.hpp>
-#include <boost/lexical_cast.hpp>
#include <boost/filesystem/fstream.hpp>
-#include <boost/lambda/lambda.hpp>
-#include <boost/lambda/bind.hpp>
+#include <boost/lexical_cast.hpp>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Base/ByteArray.h>
-#include <SwifTools/Application/ApplicationPathProvider.h>
+#include <Swiften/Base/Log.h>
-namespace lambda = boost::lambda;
+#include <SwifTools/Application/ApplicationPathProvider.h>
namespace Swift {
static const size_t MAX_ENTRIES = 200;
StatusCache::StatusCache(ApplicationPathProvider* paths) {
- paths_ = paths;
- path_ = paths_->getDataDir() / "StatusCache";
- loadRecents();
+ paths_ = paths;
+ path_ = paths_->getDataDir() / "StatusCache";
+ loadRecents();
}
StatusCache::~StatusCache() {
@@ -33,71 +30,78 @@ StatusCache::~StatusCache() {
}
std::vector<StatusCache::PreviousStatus> StatusCache::getMatches(const std::string& substring, size_t maxCount) const {
- std::vector<PreviousStatus> matches;
- foreach (const PreviousStatus& status, previousStatuses_) {
- if (substring.empty() || (boost::algorithm::ifind_first(status.first, substring) && substring != status.first)) {
- matches.push_back(status);
- if (matches.size() == maxCount) {
- break;
- }
- }
- }
- return matches;
+ std::vector<PreviousStatus> matches;
+ for (const auto& status : previousStatuses_) {
+ if (substring.empty() || (boost::algorithm::ifind_first(status.first, substring) && substring != status.first)) {
+ matches.push_back(status);
+ if (matches.size() == maxCount) {
+ break;
+ }
+ }
+ }
+ return matches;
}
void StatusCache::addRecent(const std::string& text, StatusShow::Type type) {
- if (text.empty()) {
- return;
- }
- previousStatuses_.remove_if(lambda::bind(&PreviousStatus::first, lambda::_1) == text && lambda::bind(&PreviousStatus::second, lambda::_1) == type);
- previousStatuses_.push_front(PreviousStatus(text, type));
- for (size_t i = previousStatuses_.size(); i > MAX_ENTRIES; i--) {
- previousStatuses_.pop_back();
- }
- saveRecents();
+ if (text.empty()) {
+ return;
+ }
+ previousStatuses_.remove_if([&](const PreviousStatus& previousStatus) {
+ return previousStatus.first == text && previousStatus.second == type;
+ });
+ previousStatuses_.push_front(PreviousStatus(text, type));
+ for (size_t i = previousStatuses_.size(); i > MAX_ENTRIES; i--) {
+ previousStatuses_.pop_back();
+ }
+ saveRecents();
}
void StatusCache::loadRecents() {
- try {
- if (boost::filesystem::exists(path_)) {
- ByteArray data;
- readByteArrayFromFile(data, path_);
- std::string stringData = byteArrayToString(data);
- std::vector<std::string> lines;
- boost::split(lines, stringData, boost::is_any_of("\n"));
- foreach (const std::string& line, lines) {
- std::vector<std::string> bits;
- boost::split(bits, line, boost::is_any_of("\t"));
- if (bits.size() < 2) {
- continue;
- }
- StatusShow::Type type;
- type = static_cast<StatusShow::Type>(boost::lexical_cast<size_t>(bits[0]));
- previousStatuses_.push_back(PreviousStatus(boost::trim_copy(bits[1]), type));
- }
- }
- }
- catch (const boost::filesystem::filesystem_error& e) {
- std::cerr << "ERROR: " << e.what() << std::endl;
- }
+ try {
+ if (boost::filesystem::exists(path_)) {
+ ByteArray data;
+ readByteArrayFromFile(data, path_);
+ std::string stringData = byteArrayToString(data);
+ std::vector<std::string> lines;
+ boost::split(lines, stringData, boost::is_any_of("\n"));
+ for (const auto& line : lines) {
+ std::vector<std::string> bits;
+ boost::split(bits, line, boost::is_any_of("\t"));
+ if (bits.size() < 2) {
+ continue;
+ }
+ StatusShow::Type type;
+ try {
+ type = static_cast<StatusShow::Type>(boost::lexical_cast<size_t>(bits[0]));
+ previousStatuses_.push_back(PreviousStatus(boost::trim_copy(bits[1]), type));
+ }
+ catch (const boost::bad_lexical_cast& e) {
+ SWIFT_LOG(error) << "Failed to load recent status cache entry: " << e.what() << std::endl;
+ }
+ }
+ }
+ }
+ catch (const boost::filesystem::filesystem_error& e) {
+ SWIFT_LOG(error) << "Failed to load recents: " << e.what() << std::endl;
+ }
}
void StatusCache::saveRecents() {
- try {
- if (!boost::filesystem::exists(path_.parent_path())) {
- boost::filesystem::create_directories(path_.parent_path());
- }
- boost::filesystem::ofstream file(path_);
- foreach (const PreviousStatus& recent, previousStatuses_) {
- std::string message = recent.first;
- boost::replace_all(message, "\t", " ");
- file << recent.second << "\t" << message << std::endl;
- }
- file.close();
- }
- catch (const boost::filesystem::filesystem_error& e) {
- std::cerr << "ERROR: " << e.what() << std::endl;
- }
+ try {
+ if (!boost::filesystem::exists(path_.parent_path())) {
+ boost::filesystem::create_directories(path_.parent_path());
+ }
+ boost::filesystem::ofstream file(path_);
+ for (const auto& recent : previousStatuses_) {
+ std::string message = recent.first;
+ boost::replace_all(message, "\t", " ");
+ file << recent.second << "\t" << message << std::endl;
+ }
+ file.close();
+ }
+ catch (const boost::filesystem::filesystem_error& e) {
+ SWIFT_LOG(error) << "Failed to save recents: " << e.what() << std::endl;
+ }
}
}
diff --git a/Swift/Controllers/StatusCache.h b/Swift/Controllers/StatusCache.h
index 94c8efc..83fd17a 100644
--- a/Swift/Controllers/StatusCache.h
+++ b/Swift/Controllers/StatusCache.h
@@ -1,40 +1,41 @@
/*
- * Copyright (c) 2012 Isode Limited.
+ * Copyright (c) 2012-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <list>
#include <string>
#include <utility>
-#include <vector>
-#include <list>
-#include <iostream>
#include <boost/filesystem/path.hpp>
#include <Swiften/Elements/StatusShow.h>
namespace Swift {
- class ApplicationPathProvider;
- class StatusCache {
- public:
- typedef std::pair<std::string, StatusShow::Type> PreviousStatus;
- public:
- StatusCache(ApplicationPathProvider* paths);
- ~StatusCache();
-
- std::vector<PreviousStatus> getMatches(const std::string& substring, size_t maxCount) const;
- void addRecent(const std::string& text, StatusShow::Type type);
- private:
- void saveRecents();
- void loadRecents();
- private:
- boost::filesystem::path path_;
- std::list<PreviousStatus> previousStatuses_;
- ApplicationPathProvider* paths_;
- };
+ class ApplicationPathProvider;
+
+ class StatusCache {
+ public:
+ typedef std::pair<std::string, StatusShow::Type> PreviousStatus;
+ public:
+ StatusCache(ApplicationPathProvider* paths);
+ ~StatusCache();
+
+ std::vector<PreviousStatus> getMatches(const std::string& substring, size_t maxCount) const;
+ void addRecent(const std::string& text, StatusShow::Type type);
+
+ private:
+ void saveRecents();
+ void loadRecents();
+
+ private:
+ boost::filesystem::path path_;
+ std::list<PreviousStatus> previousStatuses_;
+ ApplicationPathProvider* paths_;
+ };
}
diff --git a/Swift/Controllers/StatusTracker.cpp b/Swift/Controllers/StatusTracker.cpp
index 1f4f783..56cd27f 100644
--- a/Swift/Controllers/StatusTracker.cpp
+++ b/Swift/Controllers/StatusTracker.cpp
@@ -1,58 +1,58 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/Controllers/StatusTracker.h"
+#include <Swift/Controllers/StatusTracker.h>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
#include <Swiften/Elements/Idle.h>
namespace Swift {
StatusTracker::StatusTracker() {
- isAutoAway_ = false;
- queuedPresence_ = boost::make_shared<Presence>();
+ isAutoAway_ = false;
+ queuedPresence_ = std::make_shared<Presence>();
}
-boost::shared_ptr<Presence> StatusTracker::getNextPresence() {
- boost::shared_ptr<Presence> presence;
- if (isAutoAway_) {
- presence = boost::make_shared<Presence>();
- presence->setShow(StatusShow::Away);
- presence->setStatus(queuedPresence_->getStatus());
- presence->addPayload(boost::make_shared<Idle>(isAutoAwaySince_));
- } else {
- presence = queuedPresence_;
- }
- return presence;
+std::shared_ptr<Presence> StatusTracker::getNextPresence() {
+ std::shared_ptr<Presence> presence;
+ if (isAutoAway_) {
+ presence = std::make_shared<Presence>();
+ presence->setShow(StatusShow::Away);
+ presence->setStatus(queuedPresence_->getStatus());
+ presence->addPayload(std::make_shared<Idle>(isAutoAwaySince_));
+ } else {
+ presence = queuedPresence_;
+ }
+ return presence;
}
-void StatusTracker::setRequestedPresence(boost::shared_ptr<Presence> presence) {
- isAutoAway_ = false;
- queuedPresence_ = presence;
-// if (presence->getType() == Presence::Unavailable) {
-// queuedPresence_ = boost::make_shared<Presence>();
-// }
+void StatusTracker::setRequestedPresence(std::shared_ptr<Presence> presence) {
+ isAutoAway_ = false;
+ queuedPresence_ = presence;
+// if (presence->getType() == Presence::Unavailable) {
+// queuedPresence_ = std::make_shared<Presence>();
+// }
}
bool StatusTracker::goAutoAway(const int& seconds) {
- if (queuedPresence_->getShow() != StatusShow::Online) {
- return false;
- }
- isAutoAway_ = true;
- isAutoAwaySince_ = boost::posix_time::second_clock::universal_time() - boost::posix_time::seconds(seconds);
- return true;
+ if (queuedPresence_->getShow() != StatusShow::Online) {
+ return false;
+ }
+ isAutoAway_ = true;
+ isAutoAwaySince_ = boost::posix_time::second_clock::universal_time() - boost::posix_time::seconds(seconds);
+ return true;
}
bool StatusTracker::goAutoUnAway() {
- if (!isAutoAway_) {
- return false;
- }
- isAutoAway_ = false;
- return true;
+ if (!isAutoAway_) {
+ return false;
+ }
+ isAutoAway_ = false;
+ return true;
}
}
diff --git a/Swift/Controllers/StatusTracker.h b/Swift/Controllers/StatusTracker.h
index 472f30c..a74ab6e 100644
--- a/Swift/Controllers/StatusTracker.h
+++ b/Swift/Controllers/StatusTracker.h
@@ -1,29 +1,29 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
-
-#include "Swiften/Elements/Presence.h"
+#include <memory>
#include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <Swiften/Elements/Presence.h>
+
namespace Swift {
- class StatusTracker {
- public:
- StatusTracker();
- boost::shared_ptr<Presence> getNextPresence();
- void setRequestedPresence(boost::shared_ptr<Presence> presence);
- bool goAutoAway(const int& seconds);
- bool goAutoUnAway();
- private:
- boost::shared_ptr<Presence> queuedPresence_;
- bool isAutoAway_;
- boost::posix_time::ptime isAutoAwaySince_;
- };
+ class StatusTracker {
+ public:
+ StatusTracker();
+ std::shared_ptr<Presence> getNextPresence();
+ void setRequestedPresence(std::shared_ptr<Presence> presence);
+ bool goAutoAway(const int& seconds);
+ bool goAutoUnAway();
+ private:
+ std::shared_ptr<Presence> queuedPresence_;
+ bool isAutoAway_;
+ boost::posix_time::ptime isAutoAwaySince_;
+ };
}
diff --git a/Swift/Controllers/StatusUtil.cpp b/Swift/Controllers/StatusUtil.cpp
index 6c049a2..1034863 100644
--- a/Swift/Controllers/StatusUtil.cpp
+++ b/Swift/Controllers/StatusUtil.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,21 +7,22 @@
#include <Swift/Controllers/StatusUtil.h>
#include <cassert>
+
#include <Swift/Controllers/Intl.h>
namespace Swift {
std::string statusShowTypeToFriendlyName(StatusShow::Type type) {
- switch (type) {
- case StatusShow::Online: return QT_TRANSLATE_NOOP("", "Available");
- case StatusShow::FFC: return QT_TRANSLATE_NOOP("", "Available");
- case StatusShow::Away: return QT_TRANSLATE_NOOP("", "Away");
- case StatusShow::XA: return QT_TRANSLATE_NOOP("", "Away");
- case StatusShow::DND: return QT_TRANSLATE_NOOP("", "Busy");
- case StatusShow::None: return QT_TRANSLATE_NOOP("", "Offline");
- }
- assert(false);
- return "";
+ switch (type) {
+ case StatusShow::Online: return QT_TRANSLATE_NOOP("", "Available");
+ case StatusShow::FFC: return QT_TRANSLATE_NOOP("", "Available");
+ case StatusShow::Away: return QT_TRANSLATE_NOOP("", "Away");
+ case StatusShow::XA: return QT_TRANSLATE_NOOP("", "Away");
+ case StatusShow::DND: return QT_TRANSLATE_NOOP("", "Busy");
+ case StatusShow::None: return QT_TRANSLATE_NOOP("", "Offline");
+ }
+ assert(false);
+ return "";
}
}
diff --git a/Swift/Controllers/StatusUtil.h b/Swift/Controllers/StatusUtil.h
index 871ca0a..6872bf7 100644
--- a/Swift/Controllers/StatusUtil.h
+++ b/Swift/Controllers/StatusUtil.h
@@ -11,6 +11,6 @@
#include <Swiften/Elements/StatusShow.h>
namespace Swift {
- std::string statusShowTypeToFriendlyName(StatusShow::Type type);
+ std::string statusShowTypeToFriendlyName(StatusShow::Type type);
}
diff --git a/Swift/Controllers/Storages/AvatarFileStorage.cpp b/Swift/Controllers/Storages/AvatarFileStorage.cpp
index 39c3468..a103920 100644
--- a/Swift/Controllers/Storages/AvatarFileStorage.cpp
+++ b/Swift/Controllers/Storages/AvatarFileStorage.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2013 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,99 +7,99 @@
#include <Swift/Controllers/Storages/AvatarFileStorage.h>
#include <iostream>
-#include <boost/filesystem/fstream.hpp>
+
#include <boost/filesystem.hpp>
+#include <boost/filesystem/fstream.hpp>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Base/String.h>
-#include <Swiften/StringCodecs/Hexify.h>
#include <Swiften/Crypto/CryptoProvider.h>
+#include <Swiften/StringCodecs/Hexify.h>
namespace Swift {
AvatarFileStorage::AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile, CryptoProvider* crypto) : avatarsDir(avatarsDir), avatarsFile(avatarsFile), crypto(crypto) {
- if (boost::filesystem::exists(avatarsFile)) {
- try {
- boost::filesystem::ifstream file(avatarsFile);
- std::string line;
- if (file.is_open()) {
- while (!file.eof()) {
- getline(file, line);
- std::pair<std::string, std::string> r = String::getSplittedAtFirst(line, ' ');
- JID jid(r.second);
- if (jid.isValid()) {
- jidAvatars.insert(std::make_pair(jid, r.first));
- }
- else if (!r.first.empty() || !r.second.empty()) {
- std::cerr << "Invalid entry in avatars file: " << r.second << std::endl;
- }
- }
- }
- }
- catch (...) {
- std::cerr << "Error reading avatars file" << std::endl;
- }
- }
+ if (boost::filesystem::exists(avatarsFile)) {
+ try {
+ boost::filesystem::ifstream file(avatarsFile);
+ std::string line;
+ if (file.is_open()) {
+ while (!file.eof()) {
+ getline(file, line);
+ std::pair<std::string, std::string> r = String::getSplittedAtFirst(line, ' ');
+ JID jid(r.second);
+ if (jid.isValid()) {
+ jidAvatars.insert(std::make_pair(jid, r.first));
+ }
+ else if (!r.first.empty() || !r.second.empty()) {
+ std::cerr << "Invalid entry in avatars file: " << r.second << std::endl;
+ }
+ }
+ }
+ }
+ catch (...) {
+ std::cerr << "Error reading avatars file" << std::endl;
+ }
+ }
}
-bool AvatarFileStorage::hasAvatar(const std::string& hash) const {
- return boost::filesystem::exists(getAvatarPath(hash));
+bool AvatarFileStorage::hasAvatar(const std::string& hash) const {
+ return boost::filesystem::exists(getAvatarPath(hash));
}
void AvatarFileStorage::addAvatar(const std::string& hash, const ByteArray& avatar) {
- assert(Hexify::hexify(crypto->getSHA1Hash(avatar)) == hash);
+ assert(Hexify::hexify(crypto->getSHA1Hash(avatar)) == hash);
- boost::filesystem::path avatarPath = getAvatarPath(hash);
- if (!boost::filesystem::exists(avatarPath.parent_path())) {
- try {
- boost::filesystem::create_directories(avatarPath.parent_path());
- }
- catch (const boost::filesystem::filesystem_error& e) {
- std::cerr << "ERROR: " << e.what() << std::endl;
- }
- }
- boost::filesystem::ofstream file(avatarPath, boost::filesystem::ofstream::binary|boost::filesystem::ofstream::out);
- file.write(reinterpret_cast<const char*>(vecptr(avatar)), static_cast<std::streamsize>(avatar.size()));
- file.close();
+ boost::filesystem::path avatarPath = getAvatarPath(hash);
+ if (!boost::filesystem::exists(avatarPath.parent_path())) {
+ try {
+ boost::filesystem::create_directories(avatarPath.parent_path());
+ }
+ catch (const boost::filesystem::filesystem_error& e) {
+ std::cerr << "ERROR: " << e.what() << std::endl;
+ }
+ }
+ boost::filesystem::ofstream file(avatarPath, boost::filesystem::ofstream::binary|boost::filesystem::ofstream::out);
+ file.write(reinterpret_cast<const char*>(vecptr(avatar)), static_cast<std::streamsize>(avatar.size()));
+ file.close();
}
boost::filesystem::path AvatarFileStorage::getAvatarPath(const std::string& hash) const {
- return avatarsDir / hash;
+ return avatarsDir / hash;
}
ByteArray AvatarFileStorage::getAvatar(const std::string& hash) const {
- ByteArray data;
- readByteArrayFromFile(data, getAvatarPath(hash));
- return data;
+ ByteArray data;
+ readByteArrayFromFile(data, getAvatarPath(hash));
+ return data;
}
void AvatarFileStorage::setAvatarForJID(const JID& jid, const std::string& hash) {
- std::pair<JIDAvatarMap::iterator, bool> r = jidAvatars.insert(std::make_pair(jid, hash));
- if (r.second) {
- saveJIDAvatars();
- }
- else if (r.first->second != hash) {
- r.first->second = hash;
- saveJIDAvatars();
- }
+ std::pair<JIDAvatarMap::iterator, bool> r = jidAvatars.insert(std::make_pair(jid, hash));
+ if (r.second) {
+ saveJIDAvatars();
+ }
+ else if (r.first->second != hash) {
+ r.first->second = hash;
+ saveJIDAvatars();
+ }
}
std::string AvatarFileStorage::getAvatarForJID(const JID& jid) const {
- JIDAvatarMap::const_iterator i = jidAvatars.find(jid);
- return i == jidAvatars.end() ? "" : i->second;
+ JIDAvatarMap::const_iterator i = jidAvatars.find(jid);
+ return i == jidAvatars.end() ? "" : i->second;
}
void AvatarFileStorage::saveJIDAvatars() {
- try {
- boost::filesystem::ofstream file(avatarsFile);
- for (JIDAvatarMap::const_iterator i = jidAvatars.begin(); i != jidAvatars.end(); ++i) {
- file << i->second << " " << i->first.toString() << std::endl;
- }
- file.close();
- }
- catch (...) {
- std::cerr << "Error writing avatars file" << std::endl;
- }
+ try {
+ boost::filesystem::ofstream file(avatarsFile);
+ for (JIDAvatarMap::const_iterator i = jidAvatars.begin(); i != jidAvatars.end(); ++i) {
+ file << i->second << " " << i->first.toString() << std::endl;
+ }
+ file.close();
+ }
+ catch (...) {
+ std::cerr << "Error writing avatars file" << std::endl;
+ }
}
}
diff --git a/Swift/Controllers/Storages/AvatarFileStorage.h b/Swift/Controllers/Storages/AvatarFileStorage.h
index ecb9370..41c7106 100644
--- a/Swift/Controllers/Storages/AvatarFileStorage.h
+++ b/Swift/Controllers/Storages/AvatarFileStorage.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2013 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,37 +8,38 @@
#include <map>
#include <string>
+
#include <boost/filesystem/path.hpp>
+#include <Swiften/Avatars/AvatarStorage.h>
+#include <Swiften/Base/ByteArray.h>
#include <Swiften/JID/JID.h>
-#include "Swiften/Base/ByteArray.h"
-#include "Swiften/Avatars/AvatarStorage.h"
namespace Swift {
- class CryptoProvider;
+ class CryptoProvider;
- class AvatarFileStorage : public AvatarStorage {
- public:
- AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile, CryptoProvider* crypto);
+ class AvatarFileStorage : public AvatarStorage {
+ public:
+ AvatarFileStorage(const boost::filesystem::path& avatarsDir, const boost::filesystem::path& avatarsFile, CryptoProvider* crypto);
- virtual bool hasAvatar(const std::string& hash) const;
- virtual void addAvatar(const std::string& hash, const ByteArray& avatar);
- virtual ByteArray getAvatar(const std::string& hash) const;
+ virtual bool hasAvatar(const std::string& hash) const;
+ virtual void addAvatar(const std::string& hash, const ByteArray& avatar);
+ virtual ByteArray getAvatar(const std::string& hash) const;
- virtual boost::filesystem::path getAvatarPath(const std::string& hash) const;
+ virtual boost::filesystem::path getAvatarPath(const std::string& hash) const;
- virtual void setAvatarForJID(const JID& jid, const std::string& hash);
- virtual std::string getAvatarForJID(const JID& jid) const;
+ virtual void setAvatarForJID(const JID& jid, const std::string& hash);
+ virtual std::string getAvatarForJID(const JID& jid) const;
- private:
- void saveJIDAvatars();
+ private:
+ void saveJIDAvatars();
- private:
- boost::filesystem::path avatarsDir;
- boost::filesystem::path avatarsFile;
- CryptoProvider* crypto;
- typedef std::map<JID, std::string> JIDAvatarMap;
- JIDAvatarMap jidAvatars;
- };
+ private:
+ boost::filesystem::path avatarsDir;
+ boost::filesystem::path avatarsFile;
+ CryptoProvider* crypto;
+ typedef std::map<JID, std::string> JIDAvatarMap;
+ JIDAvatarMap jidAvatars;
+ };
}
diff --git a/Swift/Controllers/Storages/CapsFileStorage.cpp b/Swift/Controllers/Storages/CapsFileStorage.cpp
index f5d3a2e..21a99bc 100644
--- a/Swift/Controllers/Storages/CapsFileStorage.cpp
+++ b/Swift/Controllers/Storages/CapsFileStorage.cpp
@@ -1,16 +1,16 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/Controllers/Storages/CapsFileStorage.h"
+#include <Swift/Controllers/Storages/CapsFileStorage.h>
#include <Swiften/Entity/GenericPayloadPersister.h>
-#include "Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h"
-#include "Swiften/Parser/PayloadParsers/DiscoInfoParser.h"
-#include "Swiften/StringCodecs/Hexify.h"
-#include "Swiften/StringCodecs/Base64.h"
+#include <Swiften/Parser/PayloadParsers/DiscoInfoParser.h>
+#include <Swiften/Serializer/PayloadSerializers/DiscoInfoSerializer.h>
+#include <Swiften/StringCodecs/Base64.h>
+#include <Swiften/StringCodecs/Hexify.h>
using namespace Swift;
@@ -20,15 +20,15 @@ CapsFileStorage::CapsFileStorage(const boost::filesystem::path& path) : path(pat
}
DiscoInfo::ref CapsFileStorage::getDiscoInfo(const std::string& hash) const {
- return DiscoInfoPersister().loadPayloadGeneric(getCapsPath(hash));
+ return DiscoInfoPersister().loadPayloadGeneric(getCapsPath(hash));
}
void CapsFileStorage::setDiscoInfo(const std::string& hash, DiscoInfo::ref discoInfo) {
- DiscoInfo::ref bareDiscoInfo(new DiscoInfo(*discoInfo.get()));
- bareDiscoInfo->setNode("");
- DiscoInfoPersister().savePayload(bareDiscoInfo, getCapsPath(hash));
+ DiscoInfo::ref bareDiscoInfo(new DiscoInfo(*discoInfo.get()));
+ bareDiscoInfo->setNode("");
+ DiscoInfoPersister().savePayload(bareDiscoInfo, getCapsPath(hash));
}
boost::filesystem::path CapsFileStorage::getCapsPath(const std::string& hash) const {
- return path / (Hexify::hexify(Base64::decode(hash)) + ".xml");
+ return path / (Hexify::hexify(Base64::decode(hash)) + ".xml");
}
diff --git a/Swift/Controllers/Storages/CapsFileStorage.h b/Swift/Controllers/Storages/CapsFileStorage.h
index b8aaac2..7df23f1 100644
--- a/Swift/Controllers/Storages/CapsFileStorage.h
+++ b/Swift/Controllers/Storages/CapsFileStorage.h
@@ -1,28 +1,29 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <string>
+
#include <boost/filesystem/path.hpp>
-#include "Swiften/Disco/CapsStorage.h"
-#include <string>
+#include <Swiften/Disco/CapsStorage.h>
namespace Swift {
- class CapsFileStorage : public CapsStorage {
- public:
- CapsFileStorage(const boost::filesystem::path& path);
+ class CapsFileStorage : public CapsStorage {
+ public:
+ CapsFileStorage(const boost::filesystem::path& path);
- virtual DiscoInfo::ref getDiscoInfo(const std::string& hash) const;
- virtual void setDiscoInfo(const std::string& hash, DiscoInfo::ref discoInfo);
+ virtual DiscoInfo::ref getDiscoInfo(const std::string& hash) const;
+ virtual void setDiscoInfo(const std::string& hash, DiscoInfo::ref discoInfo);
- private:
- boost::filesystem::path getCapsPath(const std::string& hash) const;
+ private:
+ boost::filesystem::path getCapsPath(const std::string& hash) const;
- private:
- boost::filesystem::path path;
- };
+ private:
+ boost::filesystem::path path;
+ };
}
diff --git a/Swift/Controllers/Storages/CertificateFileStorage.cpp b/Swift/Controllers/Storages/CertificateFileStorage.cpp
index 52f4013..3fe6d54 100644
--- a/Swift/Controllers/Storages/CertificateFileStorage.cpp
+++ b/Swift/Controllers/Storages/CertificateFileStorage.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2013 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,13 +7,14 @@
#include <Swift/Controllers/Storages/CertificateFileStorage.h>
#include <iostream>
+
#include <boost/filesystem/fstream.hpp>
#include <boost/numeric/conversion/cast.hpp>
-#include <Swiften/StringCodecs/Hexify.h>
-#include <Swiften/TLS/CertificateFactory.h>
#include <Swiften/Base/Log.h>
#include <Swiften/Crypto/CryptoProvider.h>
+#include <Swiften/StringCodecs/Hexify.h>
+#include <Swiften/TLS/CertificateFactory.h>
namespace Swift {
@@ -21,42 +22,42 @@ CertificateFileStorage::CertificateFileStorage(const boost::filesystem::path& pa
}
bool CertificateFileStorage::hasCertificate(Certificate::ref certificate) const {
- boost::filesystem::path certificatePath = getCertificatePath(certificate);
- if (boost::filesystem::exists(certificatePath)) {
- ByteArray data;
- readByteArrayFromFile(data, certificatePath);
- Certificate::ref storedCertificate(certificateFactory->createCertificateFromDER(data));
- if (storedCertificate && storedCertificate->toDER() == certificate->toDER()) {
- return true;
- }
- else {
- SWIFT_LOG(warning) << "Stored certificate does not match received certificate" << std::endl;
- return false;
- }
- }
- else {
- return false;
- }
+ boost::filesystem::path certificatePath = getCertificatePath(certificate);
+ if (boost::filesystem::exists(certificatePath)) {
+ ByteArray data;
+ readByteArrayFromFile(data, certificatePath);
+ Certificate::ref storedCertificate(certificateFactory->createCertificateFromDER(data));
+ if (storedCertificate && storedCertificate->toDER() == certificate->toDER()) {
+ return true;
+ }
+ else {
+ SWIFT_LOG(warning) << "Stored certificate does not match received certificate" << std::endl;
+ return false;
+ }
+ }
+ else {
+ return false;
+ }
}
void CertificateFileStorage::addCertificate(Certificate::ref certificate) {
- boost::filesystem::path certificatePath = getCertificatePath(certificate);
- if (!boost::filesystem::exists(certificatePath.parent_path())) {
- try {
- boost::filesystem::create_directories(certificatePath.parent_path());
- }
- catch (const boost::filesystem::filesystem_error& e) {
- std::cerr << "ERROR: " << e.what() << std::endl;
- }
- }
- boost::filesystem::ofstream file(certificatePath, boost::filesystem::ofstream::binary|boost::filesystem::ofstream::out);
- ByteArray data = certificate->toDER();
- file.write(reinterpret_cast<const char*>(vecptr(data)), boost::numeric_cast<std::streamsize>(data.size()));
- file.close();
+ boost::filesystem::path certificatePath = getCertificatePath(certificate);
+ if (!boost::filesystem::exists(certificatePath.parent_path())) {
+ try {
+ boost::filesystem::create_directories(certificatePath.parent_path());
+ }
+ catch (const boost::filesystem::filesystem_error& e) {
+ std::cerr << "ERROR: " << e.what() << std::endl;
+ }
+ }
+ boost::filesystem::ofstream file(certificatePath, boost::filesystem::ofstream::binary|boost::filesystem::ofstream::out);
+ ByteArray data = certificate->toDER();
+ file.write(reinterpret_cast<const char*>(vecptr(data)), boost::numeric_cast<std::streamsize>(data.size()));
+ file.close();
}
boost::filesystem::path CertificateFileStorage::getCertificatePath(Certificate::ref certificate) const {
- return path / Hexify::hexify(crypto->getSHA1Hash(certificate->toDER()));
+ return path / Hexify::hexify(crypto->getSHA1Hash(certificate->toDER()));
}
}
diff --git a/Swift/Controllers/Storages/CertificateFileStorage.h b/Swift/Controllers/Storages/CertificateFileStorage.h
index e8d0fda..d2c228d 100644
--- a/Swift/Controllers/Storages/CertificateFileStorage.h
+++ b/Swift/Controllers/Storages/CertificateFileStorage.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2013 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,26 +8,26 @@
#include <boost/filesystem.hpp>
-#include "Swift/Controllers/Storages/CertificateStorage.h"
+#include <Swift/Controllers/Storages/CertificateStorage.h>
namespace Swift {
- class CertificateFactory;
- class CryptoProvider;
+ class CertificateFactory;
+ class CryptoProvider;
- class CertificateFileStorage : public CertificateStorage {
- public:
- CertificateFileStorage(const boost::filesystem::path& path, CertificateFactory* certificateFactory, CryptoProvider* crypto);
+ class CertificateFileStorage : public CertificateStorage {
+ public:
+ CertificateFileStorage(const boost::filesystem::path& path, CertificateFactory* certificateFactory, CryptoProvider* crypto);
- virtual bool hasCertificate(Certificate::ref certificate) const;
- virtual void addCertificate(Certificate::ref certificate);
+ virtual bool hasCertificate(Certificate::ref certificate) const;
+ virtual void addCertificate(Certificate::ref certificate);
- private:
- boost::filesystem::path getCertificatePath(Certificate::ref certificate) const;
+ private:
+ boost::filesystem::path getCertificatePath(Certificate::ref certificate) const;
- private:
- boost::filesystem::path path;
- CertificateFactory* certificateFactory;
- CryptoProvider* crypto;
- };
+ private:
+ boost::filesystem::path path;
+ CertificateFactory* certificateFactory;
+ CryptoProvider* crypto;
+ };
}
diff --git a/Swift/Controllers/Storages/CertificateFileStorageFactory.h b/Swift/Controllers/Storages/CertificateFileStorageFactory.h
index 43f0866..6f466dc 100644
--- a/Swift/Controllers/Storages/CertificateFileStorageFactory.h
+++ b/Swift/Controllers/Storages/CertificateFileStorageFactory.h
@@ -1,30 +1,32 @@
/*
- * Copyright (c) 2010-2013 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swift/Controllers/Storages/CertificateStorageFactory.h>
+#include <Swiften/JID/JID.h>
+
#include <Swift/Controllers/Storages/CertificateFileStorage.h>
+#include <Swift/Controllers/Storages/CertificateStorageFactory.h>
namespace Swift {
- class CertificateFactory;
- class CryptoProvider;
+ class CertificateFactory;
+ class CryptoProvider;
- class CertificateFileStorageFactory : public CertificateStorageFactory {
- public:
- CertificateFileStorageFactory(const boost::filesystem::path& basePath, CertificateFactory* certificateFactory, CryptoProvider* crypto) : basePath(basePath), certificateFactory(certificateFactory), crypto(crypto) {}
+ class CertificateFileStorageFactory : public CertificateStorageFactory {
+ public:
+ CertificateFileStorageFactory(const boost::filesystem::path& basePath, CertificateFactory* certificateFactory, CryptoProvider* crypto) : basePath(basePath), certificateFactory(certificateFactory), crypto(crypto) {}
- virtual CertificateStorage* createCertificateStorage(const JID& profile) const {
- boost::filesystem::path profilePath = basePath / profile.toString();
- return new CertificateFileStorage(profilePath / "certificates", certificateFactory, crypto);
- }
+ virtual CertificateStorage* createCertificateStorage(const JID& profile) const {
+ boost::filesystem::path profilePath = basePath / profile.toString();
+ return new CertificateFileStorage(profilePath / "certificates", certificateFactory, crypto);
+ }
- private:
- boost::filesystem::path basePath;
- CertificateFactory* certificateFactory;
- CryptoProvider* crypto;
- };
+ private:
+ boost::filesystem::path basePath;
+ CertificateFactory* certificateFactory;
+ CryptoProvider* crypto;
+ };
}
diff --git a/Swift/Controllers/Storages/CertificateMemoryStorage.cpp b/Swift/Controllers/Storages/CertificateMemoryStorage.cpp
index cd3c8fa..545ca65 100644
--- a/Swift/Controllers/Storages/CertificateMemoryStorage.cpp
+++ b/Swift/Controllers/Storages/CertificateMemoryStorage.cpp
@@ -1,27 +1,25 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/Storages/CertificateMemoryStorage.h>
-#include <Swiften/Base/foreach.h>
-
using namespace Swift;
CertificateMemoryStorage::CertificateMemoryStorage() {
}
bool CertificateMemoryStorage::hasCertificate(Certificate::ref certificate) const {
- foreach(Certificate::ref storedCert, certificates) {
- if (storedCert->toDER() == certificate->toDER()) {
- return true;
- }
- }
- return false;
+ for (auto&& storedCert : certificates) {
+ if (storedCert->toDER() == certificate->toDER()) {
+ return true;
+ }
+ }
+ return false;
}
void CertificateMemoryStorage::addCertificate(Certificate::ref certificate) {
- certificates.push_back(certificate);
+ certificates.push_back(certificate);
}
diff --git a/Swift/Controllers/Storages/CertificateMemoryStorage.h b/Swift/Controllers/Storages/CertificateMemoryStorage.h
index 8bf7986..4870385 100644
--- a/Swift/Controllers/Storages/CertificateMemoryStorage.h
+++ b/Swift/Controllers/Storages/CertificateMemoryStorage.h
@@ -11,15 +11,15 @@
#include <Swift/Controllers/Storages/CertificateStorage.h>
namespace Swift {
- class CertificateMemoryStorage : public CertificateStorage {
- public:
- CertificateMemoryStorage();
+ class CertificateMemoryStorage : public CertificateStorage {
+ public:
+ CertificateMemoryStorage();
- virtual bool hasCertificate(Certificate::ref certificate) const;
- virtual void addCertificate(Certificate::ref certificate);
+ virtual bool hasCertificate(Certificate::ref certificate) const;
+ virtual void addCertificate(Certificate::ref certificate);
- private:
- std::vector<Certificate::ref> certificates;
- };
+ private:
+ std::vector<Certificate::ref> certificates;
+ };
}
diff --git a/Swift/Controllers/Storages/CertificateStorage.cpp b/Swift/Controllers/Storages/CertificateStorage.cpp
index 041c5a1..38ed564 100644
--- a/Swift/Controllers/Storages/CertificateStorage.cpp
+++ b/Swift/Controllers/Storages/CertificateStorage.cpp
@@ -1,10 +1,10 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/Controllers/Storages/CertificateStorage.h"
+#include <Swift/Controllers/Storages/CertificateStorage.h>
namespace Swift {
diff --git a/Swift/Controllers/Storages/CertificateStorage.h b/Swift/Controllers/Storages/CertificateStorage.h
index 470b420..87a566b 100644
--- a/Swift/Controllers/Storages/CertificateStorage.h
+++ b/Swift/Controllers/Storages/CertificateStorage.h
@@ -11,12 +11,12 @@
#include <Swiften/TLS/Certificate.h>
namespace Swift {
- class CertificateStorage {
- public:
- virtual ~CertificateStorage();
+ class CertificateStorage {
+ public:
+ virtual ~CertificateStorage();
- virtual bool hasCertificate(Certificate::ref certificate) const = 0;
- virtual void addCertificate(Certificate::ref certificate) = 0;
- };
+ virtual bool hasCertificate(Certificate::ref certificate) const = 0;
+ virtual void addCertificate(Certificate::ref certificate) = 0;
+ };
}
diff --git a/Swift/Controllers/Storages/CertificateStorageFactory.h b/Swift/Controllers/Storages/CertificateStorageFactory.h
index 44605df..25fa232 100644
--- a/Swift/Controllers/Storages/CertificateStorageFactory.h
+++ b/Swift/Controllers/Storages/CertificateStorageFactory.h
@@ -7,13 +7,13 @@
#pragma once
namespace Swift {
- class CertificateStorage;
- class JID;
+ class CertificateStorage;
+ class JID;
- class CertificateStorageFactory {
- public:
- virtual ~CertificateStorageFactory();
+ class CertificateStorageFactory {
+ public:
+ virtual ~CertificateStorageFactory();
- virtual CertificateStorage* createCertificateStorage(const JID& profile) const = 0;
- };
+ virtual CertificateStorage* createCertificateStorage(const JID& profile) const = 0;
+ };
}
diff --git a/Swift/Controllers/Storages/CertificateStorageTrustChecker.h b/Swift/Controllers/Storages/CertificateStorageTrustChecker.h
index caf4d1f..3c708a3 100644
--- a/Swift/Controllers/Storages/CertificateStorageTrustChecker.h
+++ b/Swift/Controllers/Storages/CertificateStorageTrustChecker.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,28 +7,29 @@
#pragma once
#include <Swiften/TLS/CertificateTrustChecker.h>
+
#include <Swift/Controllers/Storages/CertificateStorage.h>
namespace Swift {
- /**
- * A certificate trust checker that trusts certificates in a certificate storage.
- */
- class CertificateStorageTrustChecker : public CertificateTrustChecker {
- public:
- CertificateStorageTrustChecker(CertificateStorage* storage) : storage(storage) {
- }
+ /**
+ * A certificate trust checker that trusts certificates in a certificate storage.
+ */
+ class CertificateStorageTrustChecker : public CertificateTrustChecker {
+ public:
+ CertificateStorageTrustChecker(CertificateStorage* storage) : storage(storage) {
+ }
- virtual bool isCertificateTrusted(const std::vector<Certificate::ref>& certificateChain) {
- lastCertificateChain = std::vector<Certificate::ref>(certificateChain.begin(), certificateChain.end());
- return certificateChain.empty() ? false : storage->hasCertificate(certificateChain[0]);
- }
+ virtual bool isCertificateTrusted(const std::vector<Certificate::ref>& certificateChain) {
+ lastCertificateChain = std::vector<Certificate::ref>(certificateChain.begin(), certificateChain.end());
+ return certificateChain.empty() ? false : storage->hasCertificate(certificateChain[0]);
+ }
- const std::vector<Certificate::ref>& getLastCertificateChain() const {
- return lastCertificateChain;
- }
+ const std::vector<Certificate::ref>& getLastCertificateChain() const {
+ return lastCertificateChain;
+ }
- private:
- CertificateStorage* storage;
- std::vector<Certificate::ref> lastCertificateChain;
- };
+ private:
+ CertificateStorage* storage;
+ std::vector<Certificate::ref> lastCertificateChain;
+ };
}
diff --git a/Swift/Controllers/Storages/FileStorages.cpp b/Swift/Controllers/Storages/FileStorages.cpp
index 4fb2034..49f9ecf 100644
--- a/Swift/Controllers/Storages/FileStorages.cpp
+++ b/Swift/Controllers/Storages/FileStorages.cpp
@@ -1,61 +1,63 @@
/*
- * Copyright (c) 2010-2013 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/Controllers/Storages/FileStorages.h"
-#include "Swift/Controllers/Storages/VCardFileStorage.h"
-#include "Swift/Controllers/Storages/AvatarFileStorage.h"
-#include "Swift/Controllers/Storages/CapsFileStorage.h"
-#include "Swift/Controllers/Storages/RosterFileStorage.h"
-#include <Swiften/History/SQLiteHistoryStorage.h>
+#include <Swift/Controllers/Storages/FileStorages.h>
+
#include <Swiften/Base/Path.h>
+#include <Swiften/History/SQLiteHistoryStorage.h>
+
+#include <Swift/Controllers/Storages/AvatarFileStorage.h>
+#include <Swift/Controllers/Storages/CapsFileStorage.h>
+#include <Swift/Controllers/Storages/RosterFileStorage.h>
+#include <Swift/Controllers/Storages/VCardFileStorage.h>
namespace Swift {
FileStorages::FileStorages(const boost::filesystem::path& baseDir, const JID& jid, CryptoProvider* crypto) {
- boost::filesystem::path profile = stringToPath(jid.toBare());
- vcardStorage = new VCardFileStorage(baseDir / profile / "vcards", crypto);
- capsStorage = new CapsFileStorage(baseDir / "caps");
- avatarStorage = new AvatarFileStorage(baseDir / "avatars", baseDir / profile / "avatars", crypto);
- rosterStorage = new RosterFileStorage(baseDir / profile / "roster.xml");
+ boost::filesystem::path profile = stringToPath(jid.toBare());
+ vcardStorage = new VCardFileStorage(baseDir / profile / "vcards", crypto);
+ capsStorage = new CapsFileStorage(baseDir / "caps");
+ avatarStorage = new AvatarFileStorage(baseDir / "avatars", baseDir / profile / "avatars", crypto);
+ rosterStorage = new RosterFileStorage(baseDir / profile / "roster.xml");
#ifdef SWIFT_EXPERIMENTAL_HISTORY
- historyStorage = new SQLiteHistoryStorage(baseDir / "history.db");
+ historyStorage = new SQLiteHistoryStorage(baseDir / "history.db");
#else
- historyStorage = NULL;
+ historyStorage = nullptr;
#endif
}
FileStorages::~FileStorages() {
- delete rosterStorage;
- delete avatarStorage;
- delete capsStorage;
- delete vcardStorage;
- delete historyStorage;
+ delete rosterStorage;
+ delete avatarStorage;
+ delete capsStorage;
+ delete vcardStorage;
+ delete historyStorage;
}
VCardStorage* FileStorages::getVCardStorage() const {
- return vcardStorage;
+ return vcardStorage;
}
CapsStorage* FileStorages::getCapsStorage() const {
- return capsStorage;
+ return capsStorage;
}
AvatarStorage* FileStorages::getAvatarStorage() const {
- return avatarStorage;
+ return avatarStorage;
}
RosterStorage* FileStorages::getRosterStorage() const {
- return rosterStorage;
+ return rosterStorage;
}
HistoryStorage* FileStorages::getHistoryStorage() const {
#ifdef SWIFT_EXPERIMENTAL_HISTORY
- return historyStorage;
+ return historyStorage;
#else
- return NULL;
+ return nullptr;
#endif
}
diff --git a/Swift/Controllers/Storages/FileStorages.h b/Swift/Controllers/Storages/FileStorages.h
index 195d0fa..e71d665 100644
--- a/Swift/Controllers/Storages/FileStorages.h
+++ b/Swift/Controllers/Storages/FileStorages.h
@@ -11,47 +11,47 @@
#include <Swiften/Client/Storages.h>
namespace Swift {
- class VCardFileStorage;
- class AvatarFileStorage;
- class CapsFileStorage;
- class RosterFileStorage;
- class HistoryStorage;
- class JID;
- class CryptoProvider;
+ class VCardFileStorage;
+ class AvatarFileStorage;
+ class CapsFileStorage;
+ class RosterFileStorage;
+ class HistoryStorage;
+ class JID;
+ class CryptoProvider;
- /**
- * A storages implementation that stores all controller data on disk.
- */
- class FileStorages : public Storages {
- public:
- /**
- * Creates the storages interface.
- *
- * All data will be stored relative to a base directory, and
- * for some controllers, in a subdirectory for the given profile.
- * The data is stored in the following places:
- * - Avatars: $basedir/avatars
- * - VCards: $basedir/$profile/vcards
- * - Entity capabilities: $basedir/caps
- *
- * \param baseDir the base dir to store data relative to
- * \param jid the subdir in which profile-specific data will be stored.
- * The bare JID will be used as the subdir name.
- */
- FileStorages(const boost::filesystem::path& baseDir, const JID& jid, CryptoProvider*);
- ~FileStorages();
+ /**
+ * A storages implementation that stores all controller data on disk.
+ */
+ class FileStorages : public Storages {
+ public:
+ /**
+ * Creates the storages interface.
+ *
+ * All data will be stored relative to a base directory, and
+ * for some controllers, in a subdirectory for the given profile.
+ * The data is stored in the following places:
+ * - Avatars: $basedir/avatars
+ * - VCards: $basedir/$profile/vcards
+ * - Entity capabilities: $basedir/caps
+ *
+ * \param baseDir the base dir to store data relative to
+ * \param jid the subdir in which profile-specific data will be stored.
+ * The bare JID will be used as the subdir name.
+ */
+ FileStorages(const boost::filesystem::path& baseDir, const JID& jid, CryptoProvider*);
+ ~FileStorages();
- virtual VCardStorage* getVCardStorage() const;
- virtual AvatarStorage* getAvatarStorage() const;
- virtual CapsStorage* getCapsStorage() const;
- virtual RosterStorage* getRosterStorage() const;
- virtual HistoryStorage* getHistoryStorage() const;
+ virtual VCardStorage* getVCardStorage() const;
+ virtual AvatarStorage* getAvatarStorage() const;
+ virtual CapsStorage* getCapsStorage() const;
+ virtual RosterStorage* getRosterStorage() const;
+ virtual HistoryStorage* getHistoryStorage() const;
- private:
- VCardFileStorage* vcardStorage;
- AvatarFileStorage* avatarStorage;
- CapsFileStorage* capsStorage;
- RosterFileStorage* rosterStorage;
- HistoryStorage* historyStorage;
- };
+ private:
+ VCardFileStorage* vcardStorage;
+ AvatarFileStorage* avatarStorage;
+ CapsFileStorage* capsStorage;
+ RosterFileStorage* rosterStorage;
+ HistoryStorage* historyStorage;
+ };
}
diff --git a/Swift/Controllers/Storages/FileStoragesFactory.h b/Swift/Controllers/Storages/FileStoragesFactory.h
index 7269810..ec0106e 100644
--- a/Swift/Controllers/Storages/FileStoragesFactory.h
+++ b/Swift/Controllers/Storages/FileStoragesFactory.h
@@ -1,27 +1,27 @@
/*
- * Copyright (c) 2010-2013 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/Storages/StoragesFactory.h"
-#include "Swift/Controllers/Storages/FileStorages.h"
+#include <Swift/Controllers/Storages/FileStorages.h>
+#include <Swift/Controllers/Storages/StoragesFactory.h>
namespace Swift {
- class CryptoProvider;
+ class CryptoProvider;
- class FileStoragesFactory : public StoragesFactory {
- public:
- FileStoragesFactory(const boost::filesystem::path& basePath, CryptoProvider* crypto) : basePath(basePath), crypto(crypto) {}
+ class FileStoragesFactory : public StoragesFactory {
+ public:
+ FileStoragesFactory(const boost::filesystem::path& basePath, CryptoProvider* crypto) : basePath(basePath), crypto(crypto) {}
- virtual Storages* createStorages(const JID& profile) const {
- return new FileStorages(basePath, profile, crypto);
- }
+ virtual Storages* createStorages(const JID& profile) const {
+ return new FileStorages(basePath, profile, crypto);
+ }
- private:
- boost::filesystem::path basePath;
- CryptoProvider* crypto;
- };
+ private:
+ boost::filesystem::path basePath;
+ CryptoProvider* crypto;
+ };
}
diff --git a/Swift/Controllers/Storages/MemoryStoragesFactory.h b/Swift/Controllers/Storages/MemoryStoragesFactory.h
index 8c68f19..28e9138 100644
--- a/Swift/Controllers/Storages/MemoryStoragesFactory.h
+++ b/Swift/Controllers/Storages/MemoryStoragesFactory.h
@@ -1,26 +1,27 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/Storages/StoragesFactory.h"
-#include "Swiften/Client/MemoryStorages.h"
+#include <Swiften/Client/MemoryStorages.h>
+
+#include <Swift/Controllers/Storages/StoragesFactory.h>
namespace Swift {
- class JID;
- class CryptoProvider;
+ class JID;
+ class CryptoProvider;
- class MemoryStoragesFactory : public StoragesFactory {
- public:
- MemoryStoragesFactory(CryptoProvider* cryptoProvider) : cryptoProvider_(cryptoProvider) {}
+ class MemoryStoragesFactory : public StoragesFactory {
+ public:
+ MemoryStoragesFactory(CryptoProvider* cryptoProvider) : cryptoProvider_(cryptoProvider) {}
- virtual Storages* createStorages(const JID& /*profile*/) const {
- return new MemoryStorages(cryptoProvider_);
- }
- private:
- CryptoProvider* cryptoProvider_;
- };
+ virtual Storages* createStorages(const JID& /*profile*/) const {
+ return new MemoryStorages(cryptoProvider_);
+ }
+ private:
+ CryptoProvider* cryptoProvider_;
+ };
}
diff --git a/Swift/Controllers/Storages/RosterFileStorage.cpp b/Swift/Controllers/Storages/RosterFileStorage.cpp
index a7f6810..1f0a90b 100644
--- a/Swift/Controllers/Storages/RosterFileStorage.cpp
+++ b/Swift/Controllers/Storages/RosterFileStorage.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,8 +7,8 @@
#include <Swift/Controllers/Storages/RosterFileStorage.h>
#include <Swiften/Entity/GenericPayloadPersister.h>
-#include <Swiften/Serializer/PayloadSerializers/RosterSerializer.h>
#include <Swiften/Parser/PayloadParsers/RosterParser.h>
+#include <Swiften/Serializer/PayloadSerializers/RosterSerializer.h>
using namespace Swift;
@@ -17,10 +17,10 @@ typedef GenericPayloadPersister<RosterPayload, RosterParser, RosterSerializer> R
RosterFileStorage::RosterFileStorage(const boost::filesystem::path& path) : path(path) {
}
-boost::shared_ptr<RosterPayload> RosterFileStorage::getRoster() const {
- return RosterPersister().loadPayloadGeneric(path);
+std::shared_ptr<RosterPayload> RosterFileStorage::getRoster() const {
+ return RosterPersister().loadPayloadGeneric(path);
}
-void RosterFileStorage::setRoster(boost::shared_ptr<RosterPayload> roster) {
- RosterPersister().savePayload(roster, path);
+void RosterFileStorage::setRoster(std::shared_ptr<RosterPayload> roster) {
+ RosterPersister().savePayload(roster, path);
}
diff --git a/Swift/Controllers/Storages/RosterFileStorage.h b/Swift/Controllers/Storages/RosterFileStorage.h
index d100793..38e26c9 100644
--- a/Swift/Controllers/Storages/RosterFileStorage.h
+++ b/Swift/Controllers/Storages/RosterFileStorage.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -11,14 +11,14 @@
#include <Swiften/Roster/RosterStorage.h>
namespace Swift {
- class RosterFileStorage : public RosterStorage {
- public:
- RosterFileStorage(const boost::filesystem::path& path);
+ class RosterFileStorage : public RosterStorage {
+ public:
+ RosterFileStorage(const boost::filesystem::path& path);
- virtual boost::shared_ptr<RosterPayload> getRoster() const;
- virtual void setRoster(boost::shared_ptr<RosterPayload>);
+ virtual std::shared_ptr<RosterPayload> getRoster() const;
+ virtual void setRoster(std::shared_ptr<RosterPayload>);
- private:
- boost::filesystem::path path;
- };
+ private:
+ boost::filesystem::path path;
+ };
}
diff --git a/Swift/Controllers/Storages/StoragesFactory.h b/Swift/Controllers/Storages/StoragesFactory.h
index 4eb991b..771230b 100644
--- a/Swift/Controllers/Storages/StoragesFactory.h
+++ b/Swift/Controllers/Storages/StoragesFactory.h
@@ -7,13 +7,13 @@
#pragma once
namespace Swift {
- class Storages;
- class JID;
+ class Storages;
+ class JID;
- class StoragesFactory {
- public:
- virtual ~StoragesFactory() {}
+ class StoragesFactory {
+ public:
+ virtual ~StoragesFactory() {}
- virtual Storages* createStorages(const JID& profile) const = 0;
- };
+ virtual Storages* createStorages(const JID& profile) const = 0;
+ };
}
diff --git a/Swift/Controllers/Storages/VCardFileStorage.cpp b/Swift/Controllers/Storages/VCardFileStorage.cpp
index 95f2575..2fdadf6 100644
--- a/Swift/Controllers/Storages/VCardFileStorage.cpp
+++ b/Swift/Controllers/Storages/VCardFileStorage.cpp
@@ -1,126 +1,126 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/Controllers/Storages/VCardFileStorage.h"
+#include <Swift/Controllers/Storages/VCardFileStorage.h>
-#include <boost/filesystem/fstream.hpp>
-#include <boost/filesystem.hpp>
#include <iostream>
-#include <Swiften/Entity/GenericPayloadPersister.h>
-#include <Swiften/Base/String.h>
-#include <Swiften/StringCodecs/Hexify.h>
-#include <Swiften/Base/foreach.h>
+#include <boost/filesystem.hpp>
+#include <boost/filesystem/fstream.hpp>
+
#include <Swiften/Base/Path.h>
+#include <Swiften/Base/String.h>
#include <Swiften/Crypto/CryptoProvider.h>
-#include "Swiften/JID/JID.h"
-#include "Swiften/Elements/VCard.h"
-#include "Swiften/Serializer/PayloadSerializers/VCardSerializer.h"
-#include "Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h"
-#include "Swiften/Parser/PayloadParsers/VCardParser.h"
+#include <Swiften/Elements/VCard.h>
+#include <Swiften/Entity/GenericPayloadPersister.h>
+#include <Swiften/JID/JID.h>
+#include <Swiften/Parser/PayloadParsers/UnitTest/PayloadParserTester.h>
+#include <Swiften/Parser/PayloadParsers/VCardParser.h>
+#include <Swiften/Serializer/PayloadSerializers/VCardSerializer.h>
+#include <Swiften/StringCodecs/Hexify.h>
using namespace Swift;
typedef GenericPayloadPersister<VCard, VCardParser, VCardSerializer> VCardPersister;
VCardFileStorage::VCardFileStorage(boost::filesystem::path dir, CryptoProvider* crypto) : VCardStorage(crypto), vcardsPath(dir), crypto(crypto) {
- cacheFile = vcardsPath / "phashes";
- if (boost::filesystem::exists(cacheFile)) {
- try {
- boost::filesystem::ifstream file(cacheFile);
- std::string line;
- if (file.is_open()) {
- while (!file.eof()) {
- getline(file, line);
- std::pair<std::string, std::string> r = String::getSplittedAtFirst(line, ' ');
- JID jid(r.second);
- if (jid.isValid()) {
- photoHashes.insert(std::make_pair(jid, r.first));
- }
- else if (!r.first.empty() || !r.second.empty()) {
- std::cerr << "Invalid entry in phashes file" << std::endl;
- }
- }
- }
- }
- catch (...) {
- std::cerr << "Error reading phashes file" << std::endl;
- }
- }
+ cacheFile = vcardsPath / "phashes";
+ if (boost::filesystem::exists(cacheFile)) {
+ try {
+ boost::filesystem::ifstream file(cacheFile);
+ std::string line;
+ if (file.is_open()) {
+ while (!file.eof()) {
+ getline(file, line);
+ std::pair<std::string, std::string> r = String::getSplittedAtFirst(line, ' ');
+ JID jid(r.second);
+ if (jid.isValid()) {
+ photoHashes.insert(std::make_pair(jid, r.first));
+ }
+ else if (!r.first.empty() || !r.second.empty()) {
+ std::cerr << "Invalid entry in phashes file" << std::endl;
+ }
+ }
+ }
+ }
+ catch (...) {
+ std::cerr << "Error reading phashes file" << std::endl;
+ }
+ }
}
-boost::shared_ptr<VCard> VCardFileStorage::getVCard(const JID& jid) const {
- boost::shared_ptr<VCard> result = VCardPersister().loadPayloadGeneric(getVCardPath(jid));
- getAndUpdatePhotoHash(jid, result);
- return result;
+std::shared_ptr<VCard> VCardFileStorage::getVCard(const JID& jid) const {
+ std::shared_ptr<VCard> result = VCardPersister().loadPayloadGeneric(getVCardPath(jid));
+ getAndUpdatePhotoHash(jid, result);
+ return result;
}
boost::posix_time::ptime VCardFileStorage::getVCardWriteTime(const JID& jid) const {
- if (vcardWriteTimes.find(jid) == vcardWriteTimes.end()) {
- return boost::posix_time::ptime();
- }
- else {
- return vcardWriteTimes.at(jid);
- }
+ if (vcardWriteTimes.find(jid) == vcardWriteTimes.end()) {
+ return boost::posix_time::ptime();
+ }
+ else {
+ return vcardWriteTimes.at(jid);
+ }
}
void VCardFileStorage::setVCard(const JID& jid, VCard::ref v) {
- vcardWriteTimes[jid] = boost::posix_time::second_clock::universal_time();
- VCardPersister().savePayload(v, getVCardPath(jid));
- getAndUpdatePhotoHash(jid, v);
+ vcardWriteTimes[jid] = boost::posix_time::second_clock::universal_time();
+ VCardPersister().savePayload(v, getVCardPath(jid));
+ getAndUpdatePhotoHash(jid, v);
}
boost::filesystem::path VCardFileStorage::getVCardPath(const JID& jid) const {
- try {
- std::string file(jid.toString());
- String::replaceAll(file, '/', "%2f");
- return boost::filesystem::path(vcardsPath / stringToPath(file + ".xml"));
- }
- catch (const boost::filesystem::filesystem_error& e) {
- std::cerr << "ERROR: " << e.what() << std::endl;
- return boost::filesystem::path();
- }
+ try {
+ std::string file(jid.toString());
+ String::replaceAll(file, '/', "%2f");
+ return boost::filesystem::path(vcardsPath / stringToPath(file + ".xml"));
+ }
+ catch (const boost::filesystem::filesystem_error& e) {
+ std::cerr << "ERROR: " << e.what() << std::endl;
+ return boost::filesystem::path();
+ }
}
std::string VCardFileStorage::getPhotoHash(const JID& jid) const {
- PhotoHashMap::const_iterator i = photoHashes.find(jid);
- if (i != photoHashes.end()) {
- return i->second;
- }
- else {
- VCard::ref vCard = getVCard(jid);
- return getAndUpdatePhotoHash(jid, vCard);
- }
+ PhotoHashMap::const_iterator i = photoHashes.find(jid);
+ if (i != photoHashes.end()) {
+ return i->second;
+ }
+ else {
+ VCard::ref vCard = getVCard(jid);
+ return getAndUpdatePhotoHash(jid, vCard);
+ }
}
std::string VCardFileStorage::getAndUpdatePhotoHash(const JID& jid, VCard::ref vCard) const {
- std::string hash;
- if (vCard && !vCard->getPhoto().empty()) {
- hash = Hexify::hexify(crypto->getSHA1Hash(vCard->getPhoto()));
- }
- std::pair<PhotoHashMap::iterator, bool> r = photoHashes.insert(std::make_pair(jid, hash));
- if (r.second) {
- savePhotoHashes();
- }
- else if (r.first->second != hash) {
- r.first->second = hash;
- savePhotoHashes();
- }
- return hash;
+ std::string hash;
+ if (vCard && !vCard->getPhoto().empty()) {
+ hash = Hexify::hexify(crypto->getSHA1Hash(vCard->getPhoto()));
+ }
+ std::pair<PhotoHashMap::iterator, bool> r = photoHashes.insert(std::make_pair(jid, hash));
+ if (r.second) {
+ savePhotoHashes();
+ }
+ else if (r.first->second != hash) {
+ r.first->second = hash;
+ savePhotoHashes();
+ }
+ return hash;
}
void VCardFileStorage::savePhotoHashes() const {
- try {
- boost::filesystem::ofstream file(cacheFile);
- for (PhotoHashMap::const_iterator i = photoHashes.begin(); i != photoHashes.end(); ++i) {
- file << i->second << " " << i->first.toString() << std::endl;
- }
- file.close();
- }
- catch (...) {
- std::cerr << "Error writing vcards file" << std::endl;
- }
+ try {
+ boost::filesystem::ofstream file(cacheFile);
+ for (PhotoHashMap::const_iterator i = photoHashes.begin(); i != photoHashes.end(); ++i) {
+ file << i->second << " " << i->first.toString() << std::endl;
+ }
+ file.close();
+ }
+ catch (...) {
+ std::cerr << "Error writing vcards file" << std::endl;
+ }
}
diff --git a/Swift/Controllers/Storages/VCardFileStorage.h b/Swift/Controllers/Storages/VCardFileStorage.h
index 85cf3fe..a91e914 100644
--- a/Swift/Controllers/Storages/VCardFileStorage.h
+++ b/Swift/Controllers/Storages/VCardFileStorage.h
@@ -1,43 +1,44 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
-#include <boost/filesystem/path.hpp>
-#include <string>
#include <map>
+#include <memory>
+#include <string>
+
+#include <boost/filesystem/path.hpp>
-#include "Swiften/VCards/VCardStorage.h"
+#include <Swiften/VCards/VCardStorage.h>
namespace Swift {
- class CryptoProvider;
+ class CryptoProvider;
- class VCardFileStorage : public VCardStorage {
- public:
- VCardFileStorage(boost::filesystem::path dir, CryptoProvider* crypto);
+ class VCardFileStorage : public VCardStorage {
+ public:
+ VCardFileStorage(boost::filesystem::path dir, CryptoProvider* crypto);
- virtual VCard::ref getVCard(const JID& jid) const;
- virtual boost::posix_time::ptime getVCardWriteTime(const JID& jid) const;
- virtual void setVCard(const JID& jid, VCard::ref v);
+ virtual VCard::ref getVCard(const JID& jid) const;
+ virtual boost::posix_time::ptime getVCardWriteTime(const JID& jid) const;
+ virtual void setVCard(const JID& jid, VCard::ref v);
- virtual std::string getPhotoHash(const JID&) const;
+ virtual std::string getPhotoHash(const JID&) const;
- private:
- boost::filesystem::path getVCardPath(const JID&) const;
+ private:
+ boost::filesystem::path getVCardPath(const JID&) const;
- std::string getAndUpdatePhotoHash(const JID& jid, VCard::ref vcard) const;
- void savePhotoHashes() const;
+ std::string getAndUpdatePhotoHash(const JID& jid, VCard::ref vcard) const;
+ void savePhotoHashes() const;
- private:
- boost::filesystem::path vcardsPath;
- CryptoProvider* crypto;
- boost::filesystem::path cacheFile;
- typedef std::map<JID, std::string> PhotoHashMap;
- mutable PhotoHashMap photoHashes;
- std::map<JID, boost::posix_time::ptime> vcardWriteTimes;
- };
+ private:
+ boost::filesystem::path vcardsPath;
+ CryptoProvider* crypto;
+ boost::filesystem::path cacheFile;
+ typedef std::map<JID, std::string> PhotoHashMap;
+ mutable PhotoHashMap photoHashes;
+ std::map<JID, boost::posix_time::ptime> vcardWriteTimes;
+ };
}
diff --git a/Swift/Controllers/SystemTray.h b/Swift/Controllers/SystemTray.h
index b85de99..094857f 100644
--- a/Swift/Controllers/SystemTray.h
+++ b/Swift/Controllers/SystemTray.h
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swiften/Elements/StatusShow.h"
+#include <Swiften/Elements/StatusShow.h>
namespace Swift {
- class SystemTray {
- public:
- virtual ~SystemTray(){}
- virtual void setUnreadMessages(bool some) = 0;
- virtual void setStatusType(StatusShow::Type type) = 0;
- virtual void setConnecting() = 0;
- };
+ class SystemTray {
+ public:
+ virtual ~SystemTray(){}
+ virtual void setUnreadMessages(bool some) = 0;
+ virtual void setStatusType(StatusShow::Type type) = 0;
+ virtual void setConnecting() = 0;
+ };
}
diff --git a/Swift/Controllers/SystemTrayController.cpp b/Swift/Controllers/SystemTrayController.cpp
index aa87537..8d4b2b7 100644
--- a/Swift/Controllers/SystemTrayController.cpp
+++ b/Swift/Controllers/SystemTrayController.cpp
@@ -1,42 +1,42 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/Controllers/SystemTrayController.h"
+#include <Swift/Controllers/SystemTrayController.h>
#include <boost/bind.hpp>
-#include "Swift/Controllers/XMPPEvents/EventController.h"
-#include "Swift/Controllers/SystemTray.h"
+#include <Swift/Controllers/SystemTray.h>
+#include <Swift/Controllers/XMPPEvents/EventController.h>
namespace Swift {
SystemTrayController::SystemTrayController(EventController* eventController, SystemTray* systemTray) {
- systemTray_ = systemTray;
- eventController_ = eventController;
- eventController_->onEventQueueLengthChange.connect(boost::bind(&SystemTrayController::handleEventQueueLengthChange, this, _1));
+ systemTray_ = systemTray;
+ eventController_ = eventController;
+ eventController_->onEventQueueLengthChange.connect(boost::bind(&SystemTrayController::handleEventQueueLengthChange, this, _1));
}
void SystemTrayController::handleEventQueueLengthChange(int /*length*/) {
- EventList events = eventController_->getEvents();
- bool found = false;
- for (EventList::iterator it = events.begin(); it != events.end(); ++it) {
- if (boost::dynamic_pointer_cast<MessageEvent>(*it)) {
- found = true;
- break;
- }
- }
- systemTray_->setUnreadMessages(found);
+ EventList events = eventController_->getEvents();
+ bool found = false;
+ for (auto& event : events) {
+ if (std::dynamic_pointer_cast<MessageEvent>(event)) {
+ found = true;
+ break;
+ }
+ }
+ systemTray_->setUnreadMessages(found);
}
void SystemTrayController::setMyStatusType(StatusShow::Type type) {
- systemTray_->setStatusType(type);
+ systemTray_->setStatusType(type);
}
void SystemTrayController::setConnecting() {
- systemTray_->setConnecting();
+ systemTray_->setConnecting();
}
}
diff --git a/Swift/Controllers/SystemTrayController.h b/Swift/Controllers/SystemTrayController.h
index 202e0ec..850ac71 100644
--- a/Swift/Controllers/SystemTrayController.h
+++ b/Swift/Controllers/SystemTrayController.h
@@ -1,27 +1,27 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swiften/Elements/StatusShow.h"
+#include <Swiften/Elements/StatusShow.h>
namespace Swift {
- class EventController;
- class SystemTray;
+ class EventController;
+ class SystemTray;
- class SystemTrayController {
- public:
- SystemTrayController(EventController* eventController, SystemTray* systemTray);
- void setMyStatusType(StatusShow::Type type);
- void setConnecting();
- private:
- void handleEventQueueLengthChange(int length);
+ class SystemTrayController {
+ public:
+ SystemTrayController(EventController* eventController, SystemTray* systemTray);
+ void setMyStatusType(StatusShow::Type type);
+ void setConnecting();
+ private:
+ void handleEventQueueLengthChange(int length);
- private:
- EventController* eventController_;
- SystemTray* systemTray_;
- };
+ private:
+ EventController* eventController_;
+ SystemTray* systemTray_;
+ };
}
diff --git a/Swift/Controllers/Translator.cpp b/Swift/Controllers/Translator.cpp
index 13230ab..f03c533 100644
--- a/Swift/Controllers/Translator.cpp
+++ b/Swift/Controllers/Translator.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,12 +8,18 @@
#include <cassert>
+#include <Swiften/Base/DateTime.h>
+
namespace Swift {
static struct DefaultTranslator : public Translator {
- virtual std::string translate(const std::string& text, const std::string&) {
- return text;
- }
+ virtual std::string translate(const std::string& text, const std::string&) {
+ return text;
+ }
+
+ virtual std::string ptimeToHumanReadableString(const boost::posix_time::ptime& time) {
+ return dateTimeToLocalString(time);
+ }
} defaultTranslator;
Translator* Translator::translator = &defaultTranslator;
@@ -22,7 +28,7 @@ Translator::~Translator() {
}
void Translator::setInstance(Translator* t) {
- translator = t;
+ translator = t;
}
}
diff --git a/Swift/Controllers/Translator.h b/Swift/Controllers/Translator.h
index 801e8b5..f37e059 100644
--- a/Swift/Controllers/Translator.h
+++ b/Swift/Controllers/Translator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,20 +8,24 @@
#include <string>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+
namespace Swift {
- class Translator {
- public:
- virtual ~Translator();
+ class Translator {
+ public:
+ virtual ~Translator();
+
+ virtual std::string translate(const std::string& text, const std::string& context) = 0;
- virtual std::string translate(const std::string& text, const std::string& context) = 0;
+ virtual std::string ptimeToHumanReadableString(const boost::posix_time::ptime& time) = 0;
- static void setInstance(Translator* translator);
+ static void setInstance(Translator* translator);
- static Translator* getInstance() {
- return translator;
- }
+ static Translator* getInstance() {
+ return translator;
+ }
- private:
- static Translator* translator;
- };
+ private:
+ static Translator* translator;
+ };
}
diff --git a/Swift/Controllers/UIEvents/AcceptWhiteboardSessionUIEvent.h b/Swift/Controllers/UIEvents/AcceptWhiteboardSessionUIEvent.h
index 93cad03..ac76ec4 100644
--- a/Swift/Controllers/UIEvents/AcceptWhiteboardSessionUIEvent.h
+++ b/Swift/Controllers/UIEvents/AcceptWhiteboardSessionUIEvent.h
@@ -4,21 +4,27 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
#include <Swiften/JID/JID.h>
#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class AcceptWhiteboardSessionUIEvent : public UIEvent {
- typedef boost::shared_ptr<AcceptWhiteboardSessionUIEvent> ref;
- public:
- AcceptWhiteboardSessionUIEvent(const JID& jid) : jid_(jid) {}
- const JID& getContact() const {return jid_;}
- private:
- JID jid_;
- };
+ class AcceptWhiteboardSessionUIEvent : public UIEvent {
+ typedef std::shared_ptr<AcceptWhiteboardSessionUIEvent> ref;
+ public:
+ AcceptWhiteboardSessionUIEvent(const JID& jid) : jid_(jid) {}
+ const JID& getContact() const {return jid_;}
+ private:
+ JID jid_;
+ };
}
diff --git a/Swift/Controllers/UIEvents/AddContactUIEvent.h b/Swift/Controllers/UIEvents/AddContactUIEvent.h
index 50a8761..df5bf36 100644
--- a/Swift/Controllers/UIEvents/AddContactUIEvent.h
+++ b/Swift/Controllers/UIEvents/AddContactUIEvent.h
@@ -1,36 +1,38 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <string>
#include <set>
+#include <string>
+
+#include <Swiften/JID/JID.h>
-#include "Swift/Controllers/UIEvents/UIEvent.h"
+#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class AddContactUIEvent : public UIEvent {
- public:
- AddContactUIEvent(const JID& jid, const std::string& name, const std::set<std::string>& groups) : jid_(jid), name_(name), groups_(groups) {}
-
- const std::string& getName() const {
- return name_;
- }
-
- const JID& getJID() const {
- return jid_;
- }
-
- const std::set<std::string>& getGroups() const {
- return groups_;
- }
-
- private:
- JID jid_;
- std::string name_;
- std::set<std::string> groups_;
- };
+ class AddContactUIEvent : public UIEvent {
+ public:
+ AddContactUIEvent(const JID& jid, const std::string& name, const std::set<std::string>& groups) : jid_(jid), name_(name), groups_(groups) {}
+
+ const std::string& getName() const {
+ return name_;
+ }
+
+ const JID& getJID() const {
+ return jid_;
+ }
+
+ const std::set<std::string>& getGroups() const {
+ return groups_;
+ }
+
+ private:
+ JID jid_;
+ std::string name_;
+ std::set<std::string> groups_;
+ };
}
diff --git a/Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h b/Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h
index 8523a78..e1d6744 100644
--- a/Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h
+++ b/Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h
@@ -1,23 +1,24 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
-#include "Swift/Controllers/UIEvents/UIEvent.h"
-#include "Swiften/MUC/MUCBookmark.h"
+#include <Swiften/MUC/MUCBookmark.h>
+
+#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class AddMUCBookmarkUIEvent : public UIEvent {
- public:
- AddMUCBookmarkUIEvent(const MUCBookmark& bookmark) : bookmark(bookmark) {}
- const MUCBookmark& getBookmark() { return bookmark; }
+ class AddMUCBookmarkUIEvent : public UIEvent {
+ public:
+ AddMUCBookmarkUIEvent(const MUCBookmark& bookmark) : bookmark(bookmark) {}
+ const MUCBookmark& getBookmark() { return bookmark; }
- private:
- MUCBookmark bookmark;
- };
+ private:
+ MUCBookmark bookmark;
+ };
}
diff --git a/Swift/Controllers/UIEvents/CancelWhiteboardSessionUIEvent.h b/Swift/Controllers/UIEvents/CancelWhiteboardSessionUIEvent.h
index f5c3b0e..1e9491f 100644
--- a/Swift/Controllers/UIEvents/CancelWhiteboardSessionUIEvent.h
+++ b/Swift/Controllers/UIEvents/CancelWhiteboardSessionUIEvent.h
@@ -4,21 +4,27 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
#include <Swiften/JID/JID.h>
#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class CancelWhiteboardSessionUIEvent : public UIEvent {
- typedef boost::shared_ptr<CancelWhiteboardSessionUIEvent> ref;
- public:
- CancelWhiteboardSessionUIEvent(const JID& jid) : jid_(jid) {}
- const JID& getContact() const {return jid_;}
- private:
- JID jid_;
- };
+ class CancelWhiteboardSessionUIEvent : public UIEvent {
+ typedef std::shared_ptr<CancelWhiteboardSessionUIEvent> ref;
+ public:
+ CancelWhiteboardSessionUIEvent(const JID& jid) : jid_(jid) {}
+ const JID& getContact() const {return jid_;}
+ private:
+ JID jid_;
+ };
}
diff --git a/Swift/Controllers/UIEvents/CreateImpromptuMUCUIEvent.h b/Swift/Controllers/UIEvents/CreateImpromptuMUCUIEvent.h
index 57e181d..e420bad 100644
--- a/Swift/Controllers/UIEvents/CreateImpromptuMUCUIEvent.h
+++ b/Swift/Controllers/UIEvents/CreateImpromptuMUCUIEvent.h
@@ -4,23 +4,44 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
+#include <string>
+#include <vector>
+
+#include <Swiften/JID/JID.h>
+
#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
class CreateImpromptuMUCUIEvent : public UIEvent {
- public:
- CreateImpromptuMUCUIEvent(const std::vector<JID>& jids, const JID& roomJID = JID(), const std::string reason = "") : jids_(jids), roomJID_(roomJID), reason_(reason) { }
-
- std::vector<JID> getJIDs() const { return jids_; }
- JID getRoomJID() const { return roomJID_; }
- std::string getReason() const { return reason_; }
- private:
- std::vector<JID> jids_;
- JID roomJID_;
- std::string reason_;
+ public:
+ /**
+ * @brief CreateImpromptuMUCUIEvent
+ * @param jids A vector of JIDs that are invited to the imprompto MUC.
+ * Useful when the event is used to recreate an old impromptu
+ * chat room.
+ * @param roomJID The full JID of the impromtu MUC. Useful when the event
+ * is used to recreate an old impromptu chat room.
+ * @param reason
+ */
+ CreateImpromptuMUCUIEvent(const std::vector<JID>& jids, const JID& roomJID = JID(), const std::string reason = "") : jids_(jids), roomJID_(roomJID), reason_(reason) { }
+
+ std::vector<JID> getJIDs() const { return jids_; }
+ JID getRoomJID() const { return roomJID_; }
+ std::string getReason() const { return reason_; }
+
+ private:
+ std::vector<JID> jids_;
+ JID roomJID_;
+ std::string reason_;
};
}
diff --git a/Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h b/Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h
index 01c59a3..33f38f2 100644
--- a/Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h
+++ b/Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h
@@ -1,26 +1,27 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
-#include "Swift/Controllers/UIEvents/UIEvent.h"
-#include "Swiften/MUC/MUCBookmark.h"
+#include <Swiften/MUC/MUCBookmark.h>
+
+#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class EditMUCBookmarkUIEvent : public UIEvent {
- public:
- EditMUCBookmarkUIEvent(const MUCBookmark& oldBookmark, const MUCBookmark& newBookmark) : oldBookmark(oldBookmark) , newBookmark(newBookmark) {}
+ class EditMUCBookmarkUIEvent : public UIEvent {
+ public:
+ EditMUCBookmarkUIEvent(const MUCBookmark& oldBookmark, const MUCBookmark& newBookmark) : oldBookmark(oldBookmark) , newBookmark(newBookmark) {}
- const MUCBookmark& getOldBookmark() {return oldBookmark;}
- const MUCBookmark& getNewBookmark() {return newBookmark;}
+ const MUCBookmark& getOldBookmark() {return oldBookmark;}
+ const MUCBookmark& getNewBookmark() {return newBookmark;}
- private:
- MUCBookmark oldBookmark;
- MUCBookmark newBookmark;
- };
+ private:
+ MUCBookmark oldBookmark;
+ MUCBookmark newBookmark;
+ };
}
diff --git a/Swift/Controllers/UIEvents/InviteToMUCUIEvent.h b/Swift/Controllers/UIEvents/InviteToMUCUIEvent.h
index cb9d20b..e38eab8 100644
--- a/Swift/Controllers/UIEvents/InviteToMUCUIEvent.h
+++ b/Swift/Controllers/UIEvents/InviteToMUCUIEvent.h
@@ -4,37 +4,44 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
#include <vector>
-#include <Swift/Controllers/UIEvents/UIEvent.h>
#include <Swiften/JID/JID.h>
+#include <Swift/Controllers/UIEvents/UIEvent.h>
+
namespace Swift {
- class InviteToMUCUIEvent : public UIEvent {
- public:
- typedef boost::shared_ptr<InviteToMUCUIEvent> ref;
-
- InviteToMUCUIEvent(const JID& room, const std::vector<JID>& JIDsToInvite, const std::string& reason) : room_(room), invite_(JIDsToInvite), reason_(reason) {
- }
-
- const JID& getRoom() const {
- return room_;
- }
-
- const std::vector<JID> getInvites() const {
- return invite_;
- }
-
- const std::string getReason() const {
- return reason_;
- }
-
- private:
- JID room_;
- std::vector<JID> invite_;
- std::string reason_;
- };
+ class InviteToMUCUIEvent : public UIEvent {
+ public:
+ typedef std::shared_ptr<InviteToMUCUIEvent> ref;
+
+ InviteToMUCUIEvent(const JID& originator, const std::vector<JID>& JIDsToInvite, const std::string& reason) : originator_(originator), invite_(JIDsToInvite), reason_(reason) {
+ }
+
+ const JID& getOriginator() const {
+ return originator_;
+ }
+
+ const std::vector<JID> getInvites() const {
+ return invite_;
+ }
+
+ const std::string getReason() const {
+ return reason_;
+ }
+
+ private:
+ JID originator_;
+ std::vector<JID> invite_;
+ std::string reason_;
+ };
}
diff --git a/Swift/Controllers/UIEvents/JoinMUCUIEvent.h b/Swift/Controllers/UIEvents/JoinMUCUIEvent.h
index a1f91f6..5d6df55 100644
--- a/Swift/Controllers/UIEvents/JoinMUCUIEvent.h
+++ b/Swift/Controllers/UIEvents/JoinMUCUIEvent.h
@@ -1,39 +1,40 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/optional.hpp>
-#include <boost/shared_ptr.hpp>
+#include <memory>
#include <string>
+#include <boost/optional.hpp>
+
#include <Swiften/JID/JID.h>
#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class JoinMUCUIEvent : public UIEvent {
- public:
- typedef boost::shared_ptr<JoinMUCUIEvent> ref;
- JoinMUCUIEvent(const JID& jid, const boost::optional<std::string>& password = boost::optional<std::string>(), const boost::optional<std::string>& nick = boost::optional<std::string>(), bool joinAutomaticallyInFuture = false, bool createAsReservedRoomIfNew = false, bool isImpromptu = false, bool isContinuation = false) : jid_(jid), nick_(nick), joinAutomatically_(joinAutomaticallyInFuture), createAsReservedRoomIfNew_(createAsReservedRoomIfNew), password_(password), isImpromptuMUC_(isImpromptu), isContinuation_(isContinuation) {}
- const boost::optional<std::string>& getNick() const {return nick_;}
- const JID& getJID() const {return jid_;}
- bool getShouldJoinAutomatically() const {return joinAutomatically_;}
- bool getCreateAsReservedRoomIfNew() const {return createAsReservedRoomIfNew_;}
- const boost::optional<std::string>& getPassword() const {return password_;}
- bool isImpromptu() const {return isImpromptuMUC_;}
- bool isContinuation() const {return isContinuation_;}
+ class JoinMUCUIEvent : public UIEvent {
+ public:
+ typedef std::shared_ptr<JoinMUCUIEvent> ref;
+ JoinMUCUIEvent(const JID& jid, const boost::optional<std::string>& password = boost::optional<std::string>(), const boost::optional<std::string>& nick = boost::optional<std::string>(), bool joinAutomaticallyInFuture = false, bool createAsReservedRoomIfNew = false, bool isImpromptu = false, bool isContinuation = false) : jid_(jid), nick_(nick), joinAutomatically_(joinAutomaticallyInFuture), createAsReservedRoomIfNew_(createAsReservedRoomIfNew), password_(password), isImpromptuMUC_(isImpromptu), isContinuation_(isContinuation) {}
+ const boost::optional<std::string>& getNick() const {return nick_;}
+ const JID& getJID() const {return jid_;}
+ bool getShouldJoinAutomatically() const {return joinAutomatically_;}
+ bool getCreateAsReservedRoomIfNew() const {return createAsReservedRoomIfNew_;}
+ const boost::optional<std::string>& getPassword() const {return password_;}
+ bool isImpromptu() const {return isImpromptuMUC_;}
+ bool isContinuation() const {return isContinuation_;}
- private:
- JID jid_;
- boost::optional<std::string> nick_;
- bool joinAutomatically_;
- bool createAsReservedRoomIfNew_;
- boost::optional<std::string> password_;
- bool isImpromptuMUC_;
- bool isContinuation_;
- };
+ private:
+ JID jid_;
+ boost::optional<std::string> nick_;
+ bool joinAutomatically_;
+ bool createAsReservedRoomIfNew_;
+ boost::optional<std::string> password_;
+ bool isImpromptuMUC_;
+ bool isContinuation_;
+ };
}
diff --git a/Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h b/Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h
index f253c2a..b73eda5 100644
--- a/Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h
+++ b/Swift/Controllers/UIEvents/RemoveMUCBookmarkUIEvent.h
@@ -1,23 +1,24 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
-#include "Swift/Controllers/UIEvents/UIEvent.h"
-#include "Swiften/MUC/MUCBookmark.h"
+#include <Swiften/MUC/MUCBookmark.h>
+
+#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class RemoveMUCBookmarkUIEvent : public UIEvent {
- public:
- RemoveMUCBookmarkUIEvent(const MUCBookmark& bookmark) : bookmark(bookmark) {}
- const MUCBookmark& getBookmark() { return bookmark; }
+ class RemoveMUCBookmarkUIEvent : public UIEvent {
+ public:
+ RemoveMUCBookmarkUIEvent(const MUCBookmark& bookmark) : bookmark(bookmark) {}
+ const MUCBookmark& getBookmark() { return bookmark; }
- private:
- MUCBookmark bookmark;
- };
+ private:
+ MUCBookmark bookmark;
+ };
}
diff --git a/Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h b/Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h
index 30c2c39..0f4a89d 100644
--- a/Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h
+++ b/Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h
@@ -1,23 +1,24 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swiften/JID/JID.h"
-#include "Swift/Controllers/UIEvents/UIEvent.h"
+#include <Swiften/JID/JID.h>
+
+#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
class RemoveRosterItemUIEvent : public UIEvent {
- public:
- RemoveRosterItemUIEvent(const JID& jid) : jid_(jid) {}
- virtual ~RemoveRosterItemUIEvent() {}
- JID getJID() {return jid_;}
- private:
- JID jid_;
+ public:
+ RemoveRosterItemUIEvent(const JID& jid) : jid_(jid) {}
+ virtual ~RemoveRosterItemUIEvent() {}
+ JID getJID() {return jid_;}
+ private:
+ JID jid_;
};
diff --git a/Swift/Controllers/UIEvents/RenameGroupUIEvent.h b/Swift/Controllers/UIEvents/RenameGroupUIEvent.h
index 13d2516..ea19efe 100644
--- a/Swift/Controllers/UIEvents/RenameGroupUIEvent.h
+++ b/Swift/Controllers/UIEvents/RenameGroupUIEvent.h
@@ -1,30 +1,31 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swift/Controllers/UIEvents/UIEvent.h>
#include <string>
+#include <Swift/Controllers/UIEvents/UIEvent.h>
+
namespace Swift {
- class RenameGroupUIEvent : public UIEvent {
- public:
- RenameGroupUIEvent(const std::string& group, const std::string& newName) : group(group), newName(newName) {
- }
+ class RenameGroupUIEvent : public UIEvent {
+ public:
+ RenameGroupUIEvent(const std::string& group, const std::string& newName) : group(group), newName(newName) {
+ }
- const std::string& getGroup() const {
- return group;
- }
+ const std::string& getGroup() const {
+ return group;
+ }
- const std::string& getNewName() const {
- return newName;
- }
+ const std::string& getNewName() const {
+ return newName;
+ }
- private:
- std::string group;
- std::string newName;
- };
+ private:
+ std::string group;
+ std::string newName;
+ };
}
diff --git a/Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h b/Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h
index b47575a..1a71cb4 100644
--- a/Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h
+++ b/Swift/Controllers/UIEvents/RenameRosterItemUIEvent.h
@@ -1,26 +1,27 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
-#include "Swift/Controllers/UIEvents/UIEvent.h"
-#include "Swiften/MUC/MUCBookmark.h"
+#include <Swiften/MUC/MUCBookmark.h>
+
+#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class RenameRosterItemUIEvent : public UIEvent {
- public:
- RenameRosterItemUIEvent(const JID& jid, const std::string& newName) : jid_(jid), newName_(newName) {}
+ class RenameRosterItemUIEvent : public UIEvent {
+ public:
+ RenameRosterItemUIEvent(const JID& jid, const std::string& newName) : jid_(jid), newName_(newName) {}
- const JID& getJID() const {return jid_;}
- const std::string& getNewName() const {return newName_;}
+ const JID& getJID() const {return jid_;}
+ const std::string& getNewName() const {return newName_;}
- private:
- JID jid_;
- std::string newName_;
- };
+ private:
+ JID jid_;
+ std::string newName_;
+ };
}
diff --git a/Swift/Controllers/UIEvents/RequestAdHocUIEvent.h b/Swift/Controllers/UIEvents/RequestAdHocUIEvent.h
index 284a1bd..f6fa1c7 100644
--- a/Swift/Controllers/UIEvents/RequestAdHocUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestAdHocUIEvent.h
@@ -1,21 +1,20 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swift/Controllers/UIInterfaces/MainWindow.h>
-
#include <Swift/Controllers/UIEvents/UIEvent.h>
+#include <Swift/Controllers/UIInterfaces/MainWindow.h>
namespace Swift {
- class RequestAdHocUIEvent : public UIEvent {
- public:
- RequestAdHocUIEvent(const DiscoItems::Item& command) : command_(command) {}
- const DiscoItems::Item& getCommand() const {return command_;}
- private:
- DiscoItems::Item command_;
- };
+ class RequestAdHocUIEvent : public UIEvent {
+ public:
+ RequestAdHocUIEvent(const DiscoItems::Item& command) : command_(command) {}
+ const DiscoItems::Item& getCommand() const {return command_;}
+ private:
+ DiscoItems::Item command_;
+ };
}
diff --git a/Swift/Controllers/UIEvents/RequestAdHocWithJIDUIEvent.h b/Swift/Controllers/UIEvents/RequestAdHocWithJIDUIEvent.h
index 2a01d47..6fe2342 100644
--- a/Swift/Controllers/UIEvents/RequestAdHocWithJIDUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestAdHocWithJIDUIEvent.h
@@ -1,21 +1,25 @@
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/UIEvents/UIEvent.h"
+#include <string>
+
+#include <Swiften/JID/JID.h>
+
+#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class RequestAdHocWithJIDUIEvent : public UIEvent {
- public:
- RequestAdHocWithJIDUIEvent(const JID& jid, const std::string& node) : jid_(jid), node_(node) {}
- JID getJID() const { return jid_; }
- std::string getNode() const { return node_; }
- private:
- JID jid_;
- std::string node_;
- };
+ class RequestAdHocWithJIDUIEvent : public UIEvent {
+ public:
+ RequestAdHocWithJIDUIEvent(const JID& jid, const std::string& node) : jid_(jid), node_(node) {}
+ JID getJID() const { return jid_; }
+ std::string getNode() const { return node_; }
+ private:
+ JID jid_;
+ std::string node_;
+ };
}
diff --git a/Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h b/Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h
index ba821a7..474d155 100644
--- a/Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestAddUserDialogUIEvent.h
@@ -1,29 +1,30 @@
/*
- * Copyright (c) 2010-2012 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/UIEvents/UIEvent.h"
#include <string>
+
#include <Swiften/JID/JID.h>
+#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class RequestAddUserDialogUIEvent : public UIEvent {
+ class RequestAddUserDialogUIEvent : public UIEvent {
- public:
- RequestAddUserDialogUIEvent(const JID& predefinedJID, const std::string& predefinedName) : preJID_(predefinedJID), preName_(predefinedName) {}
- RequestAddUserDialogUIEvent() : preJID_(), preName_() {}
+ public:
+ RequestAddUserDialogUIEvent(const JID& predefinedJID, const std::string& predefinedName) : preJID_(predefinedJID), preName_(predefinedName) {}
+ RequestAddUserDialogUIEvent() : preJID_(), preName_() {}
- const JID& getPredefinedJID() const { return preJID_; }
- const std::string& getPredefinedName() const { return preName_; }
+ const JID& getPredefinedJID() const { return preJID_; }
+ const std::string& getPredefinedName() const { return preName_; }
- private:
- JID preJID_;
- std::string preName_;
+ private:
+ JID preJID_;
+ std::string preName_;
- };
+ };
}
diff --git a/Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h b/Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h
index 9b7abcb..4dcf8be 100644
--- a/Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h
@@ -4,34 +4,40 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#pragma once
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
-#include <Swift/Controllers/UIEvents/UIEvent.h>
+#pragma once
#include <Swiften/JID/JID.h>
+#include <Swift/Controllers/UIEvents/UIEvent.h>
+
namespace Swift {
class RequestChangeBlockStateUIEvent : public UIEvent {
- public:
- enum BlockState {
- Blocked,
- Unblocked
- };
-
- public:
- RequestChangeBlockStateUIEvent(BlockState newState, const JID& contact) : state_(newState), contact_(contact) {}
-
- BlockState getBlockState() const {
- return state_;
- }
-
- JID getContact() const {
- return contact_;
- }
- private:
- BlockState state_;
- JID contact_;
+ public:
+ enum BlockState {
+ Blocked,
+ Unblocked
+ };
+
+ public:
+ RequestChangeBlockStateUIEvent(BlockState newState, const JID& contact) : state_(newState), contact_(contact) {}
+
+ BlockState getBlockState() const {
+ return state_;
+ }
+
+ JID getContact() const {
+ return contact_;
+ }
+ private:
+ BlockState state_;
+ JID contact_;
};
}
diff --git a/Swift/Controllers/UIEvents/RequestChatUIEvent.h b/Swift/Controllers/UIEvents/RequestChatUIEvent.h
index 9ed9863..4eca5d4 100644
--- a/Swift/Controllers/UIEvents/RequestChatUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestChatUIEvent.h
@@ -1,21 +1,21 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swiften/JID/JID.h"
+#include <Swiften/JID/JID.h>
-#include "Swift/Controllers/UIEvents/UIEvent.h"
+#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class RequestChatUIEvent : public UIEvent {
- public:
- RequestChatUIEvent(const JID& contact) : contact_(contact) {}
- JID getContact() {return contact_;}
- private:
- JID contact_;
- };
+ class RequestChatUIEvent : public UIEvent {
+ public:
+ RequestChatUIEvent(const JID& contact) : contact_(contact) {}
+ JID getContact() {return contact_;}
+ private:
+ JID contact_;
+ };
}
diff --git a/Swift/Controllers/UIEvents/RequestChatWithUserDialogUIEvent.h b/Swift/Controllers/UIEvents/RequestChatWithUserDialogUIEvent.h
index 758dabc..08804f4 100644
--- a/Swift/Controllers/UIEvents/RequestChatWithUserDialogUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestChatWithUserDialogUIEvent.h
@@ -1,15 +1,15 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/UIEvents/UIEvent.h"
+#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class RequestChatWithUserDialogUIEvent : public UIEvent {
+ class RequestChatWithUserDialogUIEvent : public UIEvent {
- };
+ };
}
diff --git a/Swift/Controllers/UIEvents/RequestContactEditorUIEvent.h b/Swift/Controllers/UIEvents/RequestContactEditorUIEvent.h
index ff67774..25a5e42 100644
--- a/Swift/Controllers/UIEvents/RequestContactEditorUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestContactEditorUIEvent.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,21 +7,22 @@
#pragma once
#include <Swiften/JID/JID.h>
+
#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class RequestContactEditorUIEvent : public UIEvent {
- public:
- typedef boost::shared_ptr<RequestContactEditorUIEvent> ref;
+ class RequestContactEditorUIEvent : public UIEvent {
+ public:
+ typedef std::shared_ptr<RequestContactEditorUIEvent> ref;
- RequestContactEditorUIEvent(const JID& jid) : jid(jid) {
- }
+ RequestContactEditorUIEvent(const JID& jid) : jid(jid) {
+ }
- const JID& getJID() const {
- return jid;
- }
+ const JID& getJID() const {
+ return jid;
+ }
- private:
- JID jid;
- };
+ private:
+ JID jid;
+ };
}
diff --git a/Swift/Controllers/UIEvents/RequestHighlightEditorUIEvent.h b/Swift/Controllers/UIEvents/RequestHighlightEditorUIEvent.h
index 42e22a2..0bfa458 100644
--- a/Swift/Controllers/UIEvents/RequestHighlightEditorUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestHighlightEditorUIEvent.h
@@ -10,7 +10,7 @@
namespace Swift {
- class RequestHighlightEditorUIEvent : public UIEvent {
- };
+ class RequestHighlightEditorUIEvent : public UIEvent {
+ };
}
diff --git a/Swift/Controllers/UIEvents/RequestHistoryUIEvent.h b/Swift/Controllers/UIEvents/RequestHistoryUIEvent.h
index 025e91f..8282204 100644
--- a/Swift/Controllers/UIEvents/RequestHistoryUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestHistoryUIEvent.h
@@ -9,6 +9,6 @@
#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class RequestHistoryUIEvent : public UIEvent {
- };
+ class RequestHistoryUIEvent : public UIEvent {
+ };
}
diff --git a/Swift/Controllers/UIEvents/RequestInviteToMUCUIEvent.h b/Swift/Controllers/UIEvents/RequestInviteToMUCUIEvent.h
index a6f8e7d..a8e4bb7 100644
--- a/Swift/Controllers/UIEvents/RequestInviteToMUCUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestInviteToMUCUIEvent.h
@@ -5,48 +5,59 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
#include <vector>
-#include <Swift/Controllers/UIEvents/UIEvent.h>
#include <Swiften/JID/JID.h>
+#include <Swift/Controllers/UIEvents/UIEvent.h>
+
namespace Swift {
- class RequestInviteToMUCUIEvent : public UIEvent {
- public:
- typedef boost::shared_ptr<RequestInviteToMUCUIEvent> ref;
-
- enum ImpromptuMode {
- Impromptu,
- NotImpromptu
- };
-
- RequestInviteToMUCUIEvent(const JID& room, const std::vector<JID>& JIDsToInvite, ImpromptuMode impromptu) : room_(room), invite_(JIDsToInvite) {
- isImpromptu_ = impromptu == Impromptu;
- }
-
- const JID& getRoom() const {
- return room_;
- }
-
- const std::vector<JID> getInvites() const {
- return invite_;
- }
-
- bool isImpromptu() const {
- return isImpromptu_;
- }
-
- private:
- JID room_;
- std::vector<JID> invite_;
- bool isImpromptu_;
- };
+ class RequestInviteToMUCUIEvent : public UIEvent {
+ public:
+ typedef std::shared_ptr<RequestInviteToMUCUIEvent> ref;
+
+ enum ImpromptuMode {
+ Impromptu,
+ NotImpromptu
+ };
+
+ /**
+ * @brief RequestInviteToMUCUIEvent
+ * @param originator This can be a MUC JID if the user wants to invite
+ * people to an existing MUC, or a contact JID if this is the
+ * start of an impromptu group chat.
+ * @param JIDsToInvite This is a std::vector of JIDs which are prefilled
+ * in the invite dialog.
+ * @param impromptu This flag indicates whether it is a normal MUC invite
+ * or an impromptu MUC invite.
+ */
+ RequestInviteToMUCUIEvent(const JID& originator, const std::vector<JID>& JIDsToInvite, ImpromptuMode impromptu) : originator_(originator), invite_(JIDsToInvite) {
+ isImpromptu_ = impromptu == Impromptu;
+ }
+
+ const JID& getOriginator() const {
+ return originator_;
+ }
+
+ const std::vector<JID> getInvites() const {
+ return invite_;
+ }
+
+ bool isImpromptu() const {
+ return isImpromptu_;
+ }
+
+ private:
+ JID originator_;
+ std::vector<JID> invite_;
+ bool isImpromptu_;
+ };
}
diff --git a/Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h b/Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h
index b592187..5e94290 100644
--- a/Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h
@@ -1,30 +1,31 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
#include <string>
-#include <Swift/Controllers/UIEvents/UIEvent.h>
#include <Swiften/JID/JID.h>
+#include <Swift/Controllers/UIEvents/UIEvent.h>
+
namespace Swift {
- class RequestJoinMUCUIEvent : public UIEvent {
- public:
- typedef boost::shared_ptr<RequestJoinMUCUIEvent> ref;
+ class RequestJoinMUCUIEvent : public UIEvent {
+ public:
+ typedef std::shared_ptr<RequestJoinMUCUIEvent> ref;
- RequestJoinMUCUIEvent(const JID& room = JID()) : room(room) {
- }
+ RequestJoinMUCUIEvent(const JID& room = JID()) : room(room) {
+ }
- const JID& getRoom() const {
- return room;
- }
+ const JID& getRoom() const {
+ return room;
+ }
- private:
- JID room;
- };
+ private:
+ JID room;
+ };
}
diff --git a/Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h b/Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h
index a9aedd5..1a02af4 100644
--- a/Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestProfileEditorUIEvent.h
@@ -1,16 +1,16 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/UIEvents/UIEvent.h"
+#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class RequestProfileEditorUIEvent : public UIEvent {
- public:
- RequestProfileEditorUIEvent() {}
- };
+ class RequestProfileEditorUIEvent : public UIEvent {
+ public:
+ RequestProfileEditorUIEvent() {}
+ };
}
diff --git a/Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h b/Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h
index 5c44da7..9c2b01d 100644
--- a/Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h
@@ -4,18 +4,24 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
-#include "Swiften/JID/JID.h"
+#include <Swiften/JID/JID.h>
-#include "Swift/Controllers/UIEvents/UIEvent.h"
+#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class RequestWhiteboardUIEvent : public UIEvent {
- public:
- RequestWhiteboardUIEvent(const JID& contact) : contact_(contact) {}
- const JID& getContact() const {return contact_;}
- private:
- JID contact_;
- };
+ class RequestWhiteboardUIEvent : public UIEvent {
+ public:
+ RequestWhiteboardUIEvent(const JID& contact) : contact_(contact) {}
+ const JID& getContact() const {return contact_;}
+ private:
+ JID contact_;
+ };
}
diff --git a/Swift/Controllers/UIEvents/RequestXMLConsoleUIEvent.h b/Swift/Controllers/UIEvents/RequestXMLConsoleUIEvent.h
index 12b8deb..4d780be 100644
--- a/Swift/Controllers/UIEvents/RequestXMLConsoleUIEvent.h
+++ b/Swift/Controllers/UIEvents/RequestXMLConsoleUIEvent.h
@@ -1,14 +1,14 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/UIEvents/UIEvent.h"
+#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class RequestXMLConsoleUIEvent : public UIEvent {
- };
+ class RequestXMLConsoleUIEvent : public UIEvent {
+ };
}
diff --git a/Swift/Controllers/UIEvents/SendFileUIEvent.h b/Swift/Controllers/UIEvents/SendFileUIEvent.h
index 3bfa69d..26e4940 100644
--- a/Swift/Controllers/UIEvents/SendFileUIEvent.h
+++ b/Swift/Controllers/UIEvents/SendFileUIEvent.h
@@ -4,31 +4,38 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <string>
#include <Swiften/JID/JID.h>
+
#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class SendFileUIEvent : public UIEvent {
- public:
- typedef boost::shared_ptr<SendFileUIEvent> ref;
-
- SendFileUIEvent(const JID& jid, const std::string& filename) : jid(jid), filename(filename) {
- }
-
- const JID& getJID() const {
- return jid;
- }
-
- const std::string& getFilename() const {
- return filename;
- }
-
- private:
- JID jid;
- std::string filename;
- };
+ class SendFileUIEvent : public UIEvent {
+ public:
+ typedef std::shared_ptr<SendFileUIEvent> ref;
+
+ SendFileUIEvent(const JID& jid, const std::string& filename) : jid(jid), filename(filename) {
+ }
+
+ const JID& getJID() const {
+ return jid;
+ }
+
+ const std::string& getFilename() const {
+ return filename;
+ }
+
+ private:
+ JID jid;
+ std::string filename;
+ };
}
diff --git a/Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h b/Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h
index 4a603ea..9b2f60f 100644
--- a/Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h
+++ b/Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h
@@ -4,22 +4,29 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <Swiften/JID/JID.h>
+
#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
class ShowProfileForRosterItemUIEvent : public UIEvent {
- public:
- typedef boost::shared_ptr<ShowProfileForRosterItemUIEvent> ref;
- public:
- ShowProfileForRosterItemUIEvent(const JID& jid) : jid_(jid) {}
- virtual ~ShowProfileForRosterItemUIEvent() {}
- JID getJID() const {return jid_;}
- private:
- JID jid_;
+ public:
+ typedef std::shared_ptr<ShowProfileForRosterItemUIEvent> ref;
+ public:
+ ShowProfileForRosterItemUIEvent(const JID& jid) : jid_(jid) {}
+ virtual ~ShowProfileForRosterItemUIEvent() {}
+ JID getJID() const {return jid_;}
+ private:
+ JID jid_;
};
}
diff --git a/Swift/Controllers/UIEvents/ShowWhiteboardUIEvent.h b/Swift/Controllers/UIEvents/ShowWhiteboardUIEvent.h
index bb72d9b..a1b6efb 100644
--- a/Swift/Controllers/UIEvents/ShowWhiteboardUIEvent.h
+++ b/Swift/Controllers/UIEvents/ShowWhiteboardUIEvent.h
@@ -4,19 +4,25 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
-#include "Swiften/JID/JID.h"
+#include <Swiften/JID/JID.h>
-#include "Swift/Controllers/UIEvents/UIEvent.h"
+#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class ShowWhiteboardUIEvent : public UIEvent {
- public:
- ShowWhiteboardUIEvent(const JID& contact) : contact_(contact) {}
- const JID& getContact() const {return contact_;}
- private:
- JID contact_;
- };
+ class ShowWhiteboardUIEvent : public UIEvent {
+ public:
+ ShowWhiteboardUIEvent(const JID& contact) : contact_(contact) {}
+ const JID& getContact() const {return contact_;}
+ private:
+ JID contact_;
+ };
}
diff --git a/Swift/Controllers/UIEvents/UIEvent.cpp b/Swift/Controllers/UIEvents/UIEvent.cpp
index 4827332..b1e870d 100644
--- a/Swift/Controllers/UIEvents/UIEvent.cpp
+++ b/Swift/Controllers/UIEvents/UIEvent.cpp
@@ -1,10 +1,10 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/Controllers/UIEvents/UIEvent.h"
+#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
UIEvent::~UIEvent() {
diff --git a/Swift/Controllers/UIEvents/UIEvent.h b/Swift/Controllers/UIEvents/UIEvent.h
index 548f356..5363a49 100644
--- a/Swift/Controllers/UIEvents/UIEvent.h
+++ b/Swift/Controllers/UIEvents/UIEvent.h
@@ -1,18 +1,18 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
namespace Swift {
- class UIEvent {
- public:
- typedef boost::shared_ptr<UIEvent> ref;
+ class UIEvent {
+ public:
+ typedef std::shared_ptr<UIEvent> ref;
- virtual ~UIEvent();
- };
+ virtual ~UIEvent();
+ };
}
diff --git a/Swift/Controllers/UIEvents/UIEventStream.h b/Swift/Controllers/UIEvents/UIEventStream.h
index 31a5f1c..e6e3f80 100644
--- a/Swift/Controllers/UIEvents/UIEventStream.h
+++ b/Swift/Controllers/UIEvents/UIEventStream.h
@@ -1,23 +1,24 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swiften/Base/boost_bsignals.h"
-#include <boost/shared_ptr.hpp>
+#include <memory>
-#include "Swift/Controllers/UIEvents/UIEvent.h"
+#include <boost/signals2.hpp>
+
+#include <Swift/Controllers/UIEvents/UIEvent.h>
namespace Swift {
- class UIEventStream {
- public:
- boost::signal<void (boost::shared_ptr<UIEvent>)> onUIEvent;
+ class UIEventStream {
+ public:
+ boost::signals2::signal<void (std::shared_ptr<UIEvent>)> onUIEvent;
- void send(boost::shared_ptr<UIEvent> event) {
- onUIEvent(event);
- }
- };
+ void send(std::shared_ptr<UIEvent> event) {
+ onUIEvent(event);
+ }
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/AdHocCommandWindow.h b/Swift/Controllers/UIInterfaces/AdHocCommandWindow.h
index e5d95fa..ceb1531 100644
--- a/Swift/Controllers/UIInterfaces/AdHocCommandWindow.h
+++ b/Swift/Controllers/UIInterfaces/AdHocCommandWindow.h
@@ -1,18 +1,18 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/boost_bsignals.h>
+#include <boost/signals2.hpp>
namespace Swift {
- class AdHocCommandWindow {
- public:
- virtual ~AdHocCommandWindow() {}
- virtual void setOnline(bool /*online*/) {}
- boost::signal<void ()> onClosing;
- };
+ class AdHocCommandWindow {
+ public:
+ virtual ~AdHocCommandWindow() {}
+ virtual void setOnline(bool /*online*/) {}
+ boost::signals2::signal<void ()> onClosing;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/AdHocCommandWindowFactory.h b/Swift/Controllers/UIInterfaces/AdHocCommandWindowFactory.h
index f6f37b3..7b9b6f7 100644
--- a/Swift/Controllers/UIInterfaces/AdHocCommandWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/AdHocCommandWindowFactory.h
@@ -1,19 +1,20 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swift/Controllers/UIInterfaces/AdHocCommandWindow.h>
#include <Swiften/AdHoc/OutgoingAdHocCommandSession.h>
+#include <Swift/Controllers/UIInterfaces/AdHocCommandWindow.h>
+
namespace Swift {
class AdHocCommandWindow;
- class AdHocCommandWindowFactory {
- public:
- virtual ~AdHocCommandWindowFactory() {}
- virtual AdHocCommandWindow* createAdHocCommandWindow(boost::shared_ptr<OutgoingAdHocCommandSession> command) = 0;
- };
+ class AdHocCommandWindowFactory {
+ public:
+ virtual ~AdHocCommandWindowFactory() {}
+ virtual AdHocCommandWindow* createAdHocCommandWindow(std::shared_ptr<OutgoingAdHocCommandSession> command) = 0;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/BlockListEditorWidget.h b/Swift/Controllers/UIInterfaces/BlockListEditorWidget.h
index dab5081..58b45d0 100644
--- a/Swift/Controllers/UIInterfaces/BlockListEditorWidget.h
+++ b/Swift/Controllers/UIInterfaces/BlockListEditorWidget.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -14,27 +14,28 @@
#include <vector>
+#include <boost/signals2.hpp>
+
#include <Swiften/JID/JID.h>
-#include <Swiften/Base/boost_bsignals.h>
namespace Swift {
- class ClientBlockListManager;
+ class ClientBlockListManager;
- class BlockListEditorWidget {
- public:
- virtual ~BlockListEditorWidget() {}
+ class BlockListEditorWidget {
+ public:
+ virtual ~BlockListEditorWidget() {}
- virtual void show() = 0;
- virtual void hide() = 0;
+ virtual void show() = 0;
+ virtual void hide() = 0;
- virtual void setCurrentBlockList(const std::vector<JID>& blockedJIDs) = 0;
- virtual void setBusy(bool isBusy) = 0;
- virtual void setError(const std::string&) = 0;
+ virtual void setCurrentBlockList(const std::vector<JID>& blockedJIDs) = 0;
+ virtual void setBusy(bool isBusy) = 0;
+ virtual void setError(const std::string&) = 0;
- virtual std::vector<JID> getCurrentBlockList() const = 0;
+ virtual std::vector<JID> getCurrentBlockList() const = 0;
- boost::signal<void (const std::vector<JID>& /* blockedJID */)> onSetNewBlockList;
- };
+ boost::signals2::signal<void (const std::vector<JID>& /* blockedJID */)> onSetNewBlockList;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/BlockListEditorWidgetFactory.h b/Swift/Controllers/UIInterfaces/BlockListEditorWidgetFactory.h
index eb91ac1..05e7f3a 100644
--- a/Swift/Controllers/UIInterfaces/BlockListEditorWidgetFactory.h
+++ b/Swift/Controllers/UIInterfaces/BlockListEditorWidgetFactory.h
@@ -8,13 +8,13 @@
namespace Swift {
- class BlockListEditorWidget;
+ class BlockListEditorWidget;
- class BlockListEditorWidgetFactory {
- public:
- virtual ~BlockListEditorWidgetFactory() {}
+ class BlockListEditorWidgetFactory {
+ public:
+ virtual ~BlockListEditorWidgetFactory() {}
- virtual BlockListEditorWidget* createBlockListEditorWidget() = 0;
- };
+ virtual BlockListEditorWidget* createBlockListEditorWidget() = 0;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/ChatListWindow.cpp b/Swift/Controllers/UIInterfaces/ChatListWindow.cpp
index 6391d32..5ad40fe 100644
--- a/Swift/Controllers/UIInterfaces/ChatListWindow.cpp
+++ b/Swift/Controllers/UIInterfaces/ChatListWindow.cpp
@@ -1,10 +1,10 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/Controllers/UIInterfaces/ChatListWindow.h"
+#include <Swift/Controllers/UIInterfaces/ChatListWindow.h>
namespace Swift {
diff --git a/Swift/Controllers/UIInterfaces/ChatListWindow.h b/Swift/Controllers/UIInterfaces/ChatListWindow.h
index 111c22c..dde596e 100644
--- a/Swift/Controllers/UIInterfaces/ChatListWindow.h
+++ b/Swift/Controllers/UIInterfaces/ChatListWindow.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,93 +7,93 @@
#pragma once
#include <list>
-#include <set>
#include <map>
-#include <boost/shared_ptr.hpp>
-#include <Swiften/MUC/MUCBookmark.h>
-#include <Swiften/Elements/StatusShow.h>
+#include <memory>
+#include <set>
+
#include <boost/filesystem/path.hpp>
-#include <Swiften/Base/foreach.h>
-#include <Swiften/Base/boost_bsignals.h>
+#include <boost/signals2.hpp>
+
+#include <Swiften/Elements/StatusShow.h>
+#include <Swiften/MUC/MUCBookmark.h>
namespace Swift {
- class ChatListWindow {
- public:
- class Chat {
- public:
- Chat() : statusType(StatusShow::None), isMUC(false), unreadCount(0), isPrivateMessage(false) {}
- Chat(const JID& jid, const std::string& chatName, const std::string& activity, int unreadCount, StatusShow::Type statusType, const boost::filesystem::path& avatarPath, bool isMUC, bool isPrivateMessage = false, const std::string& nick = "", const boost::optional<std::string> password = boost::optional<std::string>())
- : jid(jid), chatName(chatName), activity(activity), statusType(statusType), isMUC(isMUC), nick(nick), password(password), unreadCount(unreadCount), avatarPath(avatarPath), isPrivateMessage(isPrivateMessage) {}
- /** Assume that nicks and other transient features aren't important for equality */
- bool operator==(const Chat& other) const {
- if (impromptuJIDs.empty()) {
- return jid.toBare() == other.jid.toBare()
- && isMUC == other.isMUC;
- } else { /* compare the chat occupant lists */
- typedef std::map<std::string, JID> JIDMap;
- foreach (const JIDMap::value_type& jid, impromptuJIDs) {
- bool found = false;
- foreach (const JIDMap::value_type& otherJID, other.impromptuJIDs) {
- if (jid.second.toBare() == otherJID.second.toBare()) {
- found = true;
- break;
- }
- }
- if (!found) {
- return false;
- }
- }
- return true;
- }
- }
- void setUnreadCount(int unread) {
- unreadCount = unread;
- }
- void setStatusType(StatusShow::Type type) {
- statusType = type;
- }
- void setAvatarPath(const boost::filesystem::path& path) {
- avatarPath = path;
- }
- std::string getImpromptuTitle() const {
- typedef std::pair<std::string, JID> StringJIDPair;
- std::string title;
- foreach(StringJIDPair pair, impromptuJIDs) {
- if (title.empty()) {
- title += pair.first;
- } else {
- title += ", " + pair.first;
- }
- }
- return title;
- }
- JID jid;
- std::string chatName;
- std::string activity;
- StatusShow::Type statusType;
- bool isMUC;
- std::string nick;
- boost::optional<std::string> password;
- int unreadCount;
- boost::filesystem::path avatarPath;
- std::map<std::string, JID> impromptuJIDs;
- bool isPrivateMessage;
- };
- virtual ~ChatListWindow();
+ class ChatListWindow {
+ public:
+ class Chat {
+ public:
+ Chat() : statusType(StatusShow::None), isMUC(false), unreadCount(0), isPrivateMessage(false) {}
+ Chat(const JID& jid, const std::string& chatName, const std::string& activity, int unreadCount, StatusShow::Type statusType, const boost::filesystem::path& avatarPath, bool isMUC, bool isPrivateMessage = false, const std::string& nick = "", const boost::optional<std::string> password = boost::optional<std::string>())
+ : jid(jid), chatName(chatName), activity(activity), statusType(statusType), isMUC(isMUC), nick(nick), password(password), unreadCount(unreadCount), avatarPath(avatarPath), isPrivateMessage(isPrivateMessage) {}
+ /** Assume that nicks and other transient features aren't important for equality */
+ bool operator==(const Chat& other) const {
+ if (impromptuJIDs.empty()) {
+ return jid.toBare() == other.jid.toBare()
+ && isMUC == other.isMUC;
+ }
+ else { /* compare the chat occupant lists */
+ for (const auto& jid : impromptuJIDs) {
+ bool found = false;
+ for (const auto& otherJID : other.impromptuJIDs) {
+ if (jid.second.toBare() == otherJID.second.toBare()) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ return false;
+ }
+ }
+ return true;
+ }
+ }
+ void setUnreadCount(int unread) {
+ unreadCount = unread;
+ }
+ void setStatusType(StatusShow::Type type) {
+ statusType = type;
+ }
+ void setAvatarPath(const boost::filesystem::path& path) {
+ avatarPath = path;
+ }
+ std::string getImpromptuTitle() const {
+ std::string title;
+ for (auto& pair : impromptuJIDs) {
+ if (title.empty()) {
+ title += pair.first;
+ } else {
+ title += ", " + pair.first;
+ }
+ }
+ return title;
+ }
+ JID jid;
+ std::string chatName;
+ std::string activity;
+ StatusShow::Type statusType;
+ bool isMUC;
+ std::string nick;
+ boost::optional<std::string> password;
+ int unreadCount;
+ boost::filesystem::path avatarPath;
+ std::map<std::string, JID> impromptuJIDs;
+ bool isPrivateMessage;
+ };
+ virtual ~ChatListWindow();
- virtual void setBookmarksEnabled(bool enabled) = 0;
- virtual void addMUCBookmark(const MUCBookmark& bookmark) = 0;
- virtual void addWhiteboardSession(const ChatListWindow::Chat& chat) = 0;
- virtual void removeWhiteboardSession(const JID& jid) = 0;
- virtual void removeMUCBookmark(const MUCBookmark& bookmark) = 0;
- virtual void setRecents(const std::list<Chat>& recents) = 0;
- virtual void setUnreadCount(int unread) = 0;
- virtual void clearBookmarks() = 0;
- virtual void setOnline(bool isOnline) = 0;
+ virtual void setBookmarksEnabled(bool enabled) = 0;
+ virtual void addMUCBookmark(const MUCBookmark& bookmark) = 0;
+ virtual void addWhiteboardSession(const ChatListWindow::Chat& chat) = 0;
+ virtual void removeWhiteboardSession(const JID& jid) = 0;
+ virtual void removeMUCBookmark(const MUCBookmark& bookmark) = 0;
+ virtual void setRecents(const std::list<Chat>& recents) = 0;
+ virtual void setUnreadCount(int unread) = 0;
+ virtual void clearBookmarks() = 0;
+ virtual void setOnline(bool isOnline) = 0;
- boost::signal<void (const MUCBookmark&)> onMUCBookmarkActivated;
- boost::signal<void (const Chat&)> onRecentActivated;
- boost::signal<void (const JID&)> onWhiteboardActivated;
- boost::signal<void ()> onClearRecentsRequested;
- };
+ boost::signals2::signal<void (const MUCBookmark&)> onMUCBookmarkActivated;
+ boost::signals2::signal<void (const Chat&)> onRecentActivated;
+ boost::signals2::signal<void (const JID&)> onWhiteboardActivated;
+ boost::signals2::signal<void ()> onClearRecentsRequested;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/ChatListWindowFactory.h b/Swift/Controllers/UIInterfaces/ChatListWindowFactory.h
index 34dc7a9..3ae1ec6 100644
--- a/Swift/Controllers/UIInterfaces/ChatListWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/ChatListWindowFactory.h
@@ -1,18 +1,18 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/UIInterfaces/ChatListWindow.h"
+#include <Swift/Controllers/UIInterfaces/ChatListWindow.h>
namespace Swift {
- class UIEventStream;
- class ChatListWindowFactory {
- public:
- virtual ~ChatListWindowFactory() {}
- virtual ChatListWindow* createChatListWindow(UIEventStream* uiEventStream) = 0;
- };
+ class UIEventStream;
+ class ChatListWindowFactory {
+ public:
+ virtual ~ChatListWindowFactory() {}
+ virtual ChatListWindow* createChatListWindow(UIEventStream* uiEventStream) = 0;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/ChatWindow.h b/Swift/Controllers/UIInterfaces/ChatWindow.h
index 3a1acdf..8ee083d 100644
--- a/Swift/Controllers/UIInterfaces/ChatWindow.h
+++ b/Swift/Controllers/UIInterfaces/ChatWindow.h
@@ -1,21 +1,21 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <memory>
#include <string>
#include <vector>
+#include <boost/algorithm/string.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/make_shared.hpp>
#include <boost/optional.hpp>
-#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
#include <Swiften/Base/Tristate.h>
-#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Elements/ChatState.h>
#include <Swiften/Elements/Form.h>
#include <Swiften/Elements/MUCOccupant.h>
@@ -25,211 +25,234 @@
#include <Swift/Controllers/HighlightManager.h>
namespace Swift {
- class AvatarManager;
- class TreeWidget;
- class Roster;
- class TabComplete;
- class RosterItem;
- class ContactRosterItem;
- class FileTransferController;
- class UserSearchWindow;
-
-
- class ChatWindow {
- public:
- class ChatMessagePart {
- public:
- virtual ~ChatMessagePart() {}
- };
-
- class ChatMessage {
- public:
- ChatMessage() {}
- ChatMessage(const std::string& text) {
- append(boost::make_shared<ChatTextMessagePart>(text));
- }
- void append(const boost::shared_ptr<ChatMessagePart>& part) {
- parts_.push_back(part);
- }
-
- const std::vector<boost::shared_ptr<ChatMessagePart> >& getParts() const {
- return parts_;
- }
- private:
- std::vector<boost::shared_ptr<ChatMessagePart> > parts_;
- };
-
- class ChatTextMessagePart : public ChatMessagePart {
- public:
- ChatTextMessagePart(const std::string& text) : text(text) {}
- std::string text;
- };
-
- class ChatURIMessagePart : public ChatMessagePart {
- public:
- ChatURIMessagePart(const std::string& target) : target(target) {}
- std::string target;
- };
-
- class ChatEmoticonMessagePart : public ChatMessagePart {
- public:
- std::string imagePath;
- std::string alternativeText;
- };
-
- class ChatHighlightingMessagePart : public ChatMessagePart {
- public:
- std::string foregroundColor;
- std::string backgroundColor;
- std::string text;
- };
-
-
- enum AckState {Pending, Received, Failed};
- enum ReceiptState {ReceiptRequested, ReceiptReceived, ReceiptFailed};
- enum OccupantAction {Kick, Ban, MakeModerator, MakeParticipant, MakeVisitor, AddContact, ShowProfile};
- enum RoomAction {ChangeSubject, Configure, Affiliations, Destroy, Invite};
- enum FileTransferState {
- Initialisation, ///< Collecting information required for sending the request out.
- WaitingForAccept, ///< The file transfer request was send out.
- Negotiating, ///< The other party accepted the file transfer request and a suitable transfer method is negotiated.
- Transferring, ///< The negotiation was successful and the file is currently transferred.
- Canceled, ///< Someone actively canceled the transfer.
- Finished, ///< The file was transferred successfully.
- FTFailed ///< The negotiation, the transfer itself or the verification failed.
- };
- enum WhiteboardSessionState {WhiteboardAccepted, WhiteboardTerminated, WhiteboardRejected};
- enum BlockingState {BlockingUnsupported, IsBlocked, IsUnblocked};
- enum Direction { UnknownDirection, DefaultDirection };
- enum MUCType { StandardMUC, ImpromptuMUC };
- enum TimestampBehaviour { KeepTimestamp, UpdateTimestamp };
- enum RoomBookmarkState { RoomNotBookmarked, RoomBookmarked, RoomAutoJoined };
-
- ChatWindow() {}
- virtual ~ChatWindow() {}
-
- /** Add message to window.
- * @return id of added message (for acks).
- */
- virtual std::string addMessage(const ChatMessage& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) = 0;
- /** Adds action to window.
- * @return id of added message (for acks);
- */
- virtual std::string addAction(const ChatMessage& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) = 0;
-
- /** Adds system message to window
- * @return id of added message (for replacement)
- */
- virtual std::string addSystemMessage(const ChatMessage& message, Direction direction) = 0;
- virtual void addPresenceMessage(const ChatMessage& message, Direction direction) = 0;
-
- virtual void addErrorMessage(const ChatMessage& message) = 0;
- virtual void replaceMessage(const ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight) = 0;
- virtual void replaceSystemMessage(const ChatMessage& message, const std::string& id, const TimestampBehaviour timestampBehaviour) = 0;
- virtual void replaceWithAction(const ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight) = 0;
-
- // File transfer related stuff
- virtual std::string addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes, const std::string& description) = 0;
- virtual void setFileTransferProgress(std::string, const int percentageDone) = 0;
- virtual void setFileTransferStatus(std::string, const FileTransferState state, const std::string& msg = "") = 0;
- virtual void addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct = true, bool isImpromptu = false, bool isContinuation = false) = 0;
-
- virtual std::string addWhiteboardRequest(bool senderIsSelf) = 0;
- virtual void setWhiteboardSessionStatus(std::string id, const ChatWindow::WhiteboardSessionState state) = 0;
-
- // message receipts
- virtual void setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state) = 0;
-
- virtual void setContactChatState(ChatState::ChatStateType state) = 0;
- virtual void setName(const std::string& name) = 0;
- virtual void show() = 0;
- virtual bool isVisible() const = 0;
- virtual void activate() = 0;
- virtual void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels) = 0;
- virtual void setSecurityLabelsEnabled(bool enabled) = 0;
- virtual void setCorrectionEnabled(Tristate enabled) = 0;
- virtual void setFileTransferEnabled(Tristate enabled) = 0;
- virtual void setUnreadMessageCount(int count) = 0;
- virtual void convertToMUC(MUCType mucType) = 0;
-// virtual TreeWidget *getTreeWidget() = 0;
- virtual void setSecurityLabelsError() = 0;
- virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() = 0;
- virtual void setOnline(bool online) = 0;
- virtual void setRosterModel(Roster* model) = 0;
- virtual void setTabComplete(TabComplete* completer) = 0;
- virtual void replaceLastMessage(const ChatMessage& message, const TimestampBehaviour timestampBehaviour) = 0;
- virtual void setAckState(const std::string& id, AckState state) = 0;
- virtual void flash() = 0;
- virtual void setSubject(const std::string& subject) = 0;
- virtual void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>&) = 0;
- virtual void setAvailableRoomActions(const std::vector<RoomAction> &actions) = 0;
- virtual void setBlockingState(BlockingState state) = 0;
- virtual void setCanInitiateImpromptuChats(bool supportsImpromptu) = 0;
- virtual void showBookmarkWindow(const MUCBookmark& bookmark) = 0;
- virtual void setBookmarkState(RoomBookmarkState bookmarkState) = 0;
-
- /**
- * A handle that uniquely identities an alert message.
- */
- typedef int AlertID;
- /**
- * Set an alert on the window.
- * @param alertText Description of alert (required).
- * @param buttonText Button text to use (optional, no button is shown if empty).
- * @return A handle to the alert message.
- */
- virtual AlertID addAlert(const std::string& alertText) = 0;
- /**
- * Removes an alert.
- * @param id An alert ID previously returned from setAlert
- */
- virtual void removeAlert(const AlertID id) = 0;
-
- /**
- * Actions that can be performed on the selected occupant.
- */
- virtual void setAvailableOccupantActions(const std::vector<OccupantAction>& actions) = 0;
-
- /**
- * A room configuration has been requested, show the form.
- * If the form is cancelled, must emit onConfigurationFormCancelled().
- */
- virtual void showRoomConfigurationForm(Form::ref) = 0;
-
- boost::signal<void ()> onClosed;
- boost::signal<void ()> onAllMessagesRead;
- boost::signal<void (const std::string&, bool isCorrection)> onSendMessageRequest;
- boost::signal<void ()> onSendCorrectionMessageRequest;
- boost::signal<void ()> onUserTyping;
- boost::signal<void ()> onUserCancelsTyping;
- boost::signal<void ()> onAlertButtonClicked;
- boost::signal<void (ContactRosterItem*)> onOccupantSelectionChanged;
- boost::signal<void (ChatWindow::OccupantAction, ContactRosterItem*)> onOccupantActionSelected;
- boost::signal<void (const std::string&)> onChangeSubjectRequest;
- boost::signal<void ()> onBookmarkRequest;
- boost::signal<void (Form::ref)> onConfigureRequest;
- boost::signal<void ()> onDestroyRequest;
- boost::signal<void (const std::vector<JID>&)> onInviteToChat;
- boost::signal<void ()> onConfigurationFormCancelled;
- boost::signal<void ()> onGetAffiliationsRequest;
- boost::signal<void (MUCOccupant::Affiliation, const JID&)> onSetAffiliationRequest;
- boost::signal<void (const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& changes)> onChangeAffiliationsRequest;
- boost::signal<void ()> onLogCleared;
-
- // File transfer related
- boost::signal<void (std::string /* id */)> onFileTransferCancel;
- boost::signal<void (std::string /* id */, std::string /* description */)> onFileTransferStart;
- boost::signal<void (std::string /* id */, std::string /* path */)> onFileTransferAccept;
- boost::signal<void (std::string /* path */)> onSendFileRequest;
-
- //Whiteboard related
- boost::signal<void ()> onWhiteboardSessionAccept;
- boost::signal<void ()> onWhiteboardSessionCancel;
- boost::signal<void ()> onWhiteboardWindowShow;
-
- // Blocking Command related
- boost::signal<void ()> onBlockUserRequest;
- boost::signal<void ()> onUnblockUserRequest;
- };
+ class AvatarManager;
+ class TreeWidget;
+ class Roster;
+ class TabComplete;
+ class RosterItem;
+ class ContactRosterItem;
+ class FileTransferController;
+ class UserSearchWindow;
+
+
+ class ChatWindow {
+ public:
+ class ChatMessagePart {
+ public:
+ virtual ~ChatMessagePart() {}
+ };
+
+ class ChatMessage {
+ public:
+ ChatMessage() {}
+
+ ChatMessage(const std::string& text) {
+ append(std::make_shared<ChatTextMessagePart>(text));
+ }
+
+ void append(const std::shared_ptr<ChatMessagePart>& part) {
+ parts_.push_back(part);
+ }
+
+ const std::vector<std::shared_ptr<ChatMessagePart> >& getParts() const {
+ return parts_;
+ }
+
+ void setParts(const std::vector<std::shared_ptr<ChatMessagePart> >& parts) {
+ parts_ = parts;
+ }
+
+ void setFullMessageHighlightAction(const HighlightAction& action) {
+ fullMessageHighlightAction_ = action;
+ }
+
+ const HighlightAction& getFullMessageHighlightAction() const {
+ return fullMessageHighlightAction_;
+ }
+
+ bool isMeCommand() const {
+ return isMeCommand_;
+ }
+
+ void setIsMeCommand(bool isMeCommand) {
+ isMeCommand_ = isMeCommand;
+ }
+
+ private:
+ std::vector<std::shared_ptr<ChatMessagePart> > parts_;
+ HighlightAction fullMessageHighlightAction_;
+ bool isMeCommand_ = false;
+ };
+
+ class ChatTextMessagePart : public ChatMessagePart {
+ public:
+ ChatTextMessagePart(const std::string& text) : text(text) {}
+ std::string text;
+ };
+
+ class ChatURIMessagePart : public ChatMessagePart {
+ public:
+ ChatURIMessagePart(const std::string& target) : target(target) {}
+ std::string target;
+ };
+
+ class ChatEmoticonMessagePart : public ChatMessagePart {
+ public:
+ std::string imagePath;
+ std::string alternativeText;
+ };
+
+ class ChatHighlightingMessagePart : public ChatMessagePart {
+ public:
+ HighlightAction action;
+ std::string text;
+ };
+
+
+ enum AckState {Pending, Received, Failed};
+ enum ReceiptState {ReceiptRequested, ReceiptReceived, ReceiptFailed};
+ enum OccupantAction {Kick, Ban, MakeModerator, MakeParticipant, MakeVisitor, AddContact, ShowProfile};
+ enum RoomAction {ChangeSubject, Configure, Affiliations, Destroy, Invite};
+ enum FileTransferState {
+ Initialisation, ///< Collecting information required for sending the request out.
+ WaitingForAccept, ///< The file transfer request was send out.
+ Negotiating, ///< The other party accepted the file transfer request and a suitable transfer method is negotiated.
+ Transferring, ///< The negotiation was successful and the file is currently transferred.
+ Canceled, ///< Someone actively canceled the transfer.
+ Finished, ///< The file was transferred successfully.
+ FTFailed ///< The negotiation, the transfer itself or the verification failed.
+ };
+ enum WhiteboardSessionState {WhiteboardAccepted, WhiteboardTerminated, WhiteboardRejected};
+ enum BlockingState {BlockingUnsupported, IsBlocked, IsUnblocked};
+ enum Direction { UnknownDirection, DefaultDirection };
+ enum MUCType { StandardMUC, ImpromptuMUC };
+ enum TimestampBehaviour { KeepTimestamp, UpdateTimestamp };
+ enum RoomBookmarkState { RoomNotBookmarked, RoomBookmarked, RoomAutoJoined };
+
+ ChatWindow() {}
+ virtual ~ChatWindow() {}
+
+ /** Add message to window.
+ * @return id of added message (for acks).
+ */
+ virtual std::string addMessage(const ChatMessage& message, const std::string& senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) = 0;
+ /** Adds action to window.
+ * @return id of added message (for acks);
+ */
+ virtual std::string addAction(const ChatMessage& message, const std::string& senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) = 0;
+
+ /** Adds system message to window
+ * @return id of added message (for replacement)
+ */
+ virtual std::string addSystemMessage(const ChatMessage& message, Direction direction) = 0;
+ virtual void addPresenceMessage(const ChatMessage& message, Direction direction) = 0;
+
+ virtual void addErrorMessage(const ChatMessage& message) = 0;
+ virtual void replaceMessage(const ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time) = 0;
+ virtual void replaceSystemMessage(const ChatMessage& message, const std::string& id, const TimestampBehaviour timestampBehaviour) = 0;
+ virtual void replaceWithAction(const ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time) = 0;
+
+ // File transfer related stuff
+ virtual std::string addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes, const std::string& description) = 0;
+ virtual void setFileTransferProgress(std::string, const int percentageDone) = 0;
+ virtual void setFileTransferStatus(std::string, const FileTransferState state, const std::string& msg = "") = 0;
+ virtual void addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct = true, bool isImpromptu = false, bool isContinuation = false) = 0;
+
+ virtual std::string addWhiteboardRequest(bool senderIsSelf) = 0;
+ virtual void setWhiteboardSessionStatus(std::string id, const ChatWindow::WhiteboardSessionState state) = 0;
+
+ // message receipts
+ virtual void setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state) = 0;
+
+ virtual void setContactChatState(ChatState::ChatStateType state) = 0;
+ virtual void setName(const std::string& name) = 0;
+ virtual void show() = 0;
+ virtual bool isVisible() const = 0;
+ virtual void activate() = 0;
+ virtual void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels) = 0;
+ virtual void setSecurityLabelsEnabled(bool enabled) = 0;
+ virtual void setCorrectionEnabled(Tristate enabled) = 0;
+ virtual void setFileTransferEnabled(Tristate enabled) = 0;
+ virtual void setUnreadMessageCount(int count) = 0;
+ virtual void convertToMUC(MUCType mucType) = 0;
+// virtual TreeWidget *getTreeWidget() = 0;
+ virtual void setSecurityLabelsError() = 0;
+ virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() = 0;
+ virtual void setOnline(bool online) = 0;
+ virtual void setRosterModel(Roster* model) = 0;
+ virtual void setTabComplete(TabComplete* completer) = 0;
+ virtual void replaceLastMessage(const ChatMessage& message, const TimestampBehaviour timestampBehaviour) = 0;
+ virtual void setAckState(const std::string& id, AckState state) = 0;
+ virtual void flash() = 0;
+ virtual void setSubject(const std::string& subject) = 0;
+ virtual void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>&) = 0;
+ virtual void setAvailableRoomActions(const std::vector<RoomAction> &actions) = 0;
+ virtual void setBlockingState(BlockingState state) = 0;
+ virtual void setCanInitiateImpromptuChats(bool supportsImpromptu) = 0;
+ virtual void showBookmarkWindow(const MUCBookmark& bookmark) = 0;
+ virtual void setBookmarkState(RoomBookmarkState bookmarkState) = 0;
+
+ /**
+ * A handle that uniquely identities an alert message.
+ */
+ typedef int AlertID;
+ /**
+ * Set an alert on the window.
+ * @param alertText Description of alert (required).
+ * @return A handle to the alert message.
+ */
+ virtual AlertID addAlert(const std::string& alertText) = 0;
+ /**
+ * Removes an alert.
+ * @param id An alert ID previously returned from setAlert
+ */
+ virtual void removeAlert(const AlertID id) = 0;
+
+ /**
+ * Actions that can be performed on the selected occupant.
+ */
+ virtual void setAvailableOccupantActions(const std::vector<OccupantAction>& actions) = 0;
+
+ /**
+ * A room configuration has been requested, show the form.
+ * If the form is cancelled, must emit onConfigurationFormCancelled().
+ */
+ virtual void showRoomConfigurationForm(Form::ref) = 0;
+
+ boost::signals2::signal<void ()> onClosed;
+ boost::signals2::signal<void ()> onAllMessagesRead;
+ boost::signals2::signal<void (const std::string&, bool isCorrection)> onSendMessageRequest;
+ boost::signals2::signal<void ()> onSendCorrectionMessageRequest;
+ boost::signals2::signal<void ()> onUserTyping;
+ boost::signals2::signal<void ()> onUserCancelsTyping;
+ boost::signals2::signal<void ()> onAlertButtonClicked;
+ boost::signals2::signal<void (ContactRosterItem*)> onOccupantSelectionChanged;
+ boost::signals2::signal<void (ChatWindow::OccupantAction, ContactRosterItem*)> onOccupantActionSelected;
+ boost::signals2::signal<void (const std::string&)> onChangeSubjectRequest;
+ boost::signals2::signal<void ()> onBookmarkRequest;
+ boost::signals2::signal<void (Form::ref)> onConfigureRequest;
+ boost::signals2::signal<void ()> onDestroyRequest;
+ boost::signals2::signal<void (const std::vector<JID>&)> onInviteToChat;
+ boost::signals2::signal<void ()> onConfigurationFormCancelled;
+ boost::signals2::signal<void ()> onGetAffiliationsRequest;
+ boost::signals2::signal<void (MUCOccupant::Affiliation, const JID&)> onSetAffiliationRequest;
+ boost::signals2::signal<void (const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& changes)> onChangeAffiliationsRequest;
+ boost::signals2::signal<void ()> onLogCleared;
+
+ // File transfer related
+ boost::signals2::signal<void (std::string /* id */)> onFileTransferCancel;
+ boost::signals2::signal<void (std::string /* id */, std::string /* description */)> onFileTransferStart;
+ boost::signals2::signal<void (std::string /* id */, std::string /* path */)> onFileTransferAccept;
+ boost::signals2::signal<void (std::string /* path */)> onSendFileRequest;
+
+ //Whiteboard related
+ boost::signals2::signal<void ()> onWhiteboardSessionAccept;
+ boost::signals2::signal<void ()> onWhiteboardSessionCancel;
+ boost::signals2::signal<void ()> onWhiteboardWindowShow;
+
+ // Blocking Command related
+ boost::signals2::signal<void ()> onBlockUserRequest;
+ boost::signals2::signal<void ()> onUnblockUserRequest;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/ChatWindowFactory.h b/Swift/Controllers/UIInterfaces/ChatWindowFactory.h
index 7c47e2a..38706ab 100644
--- a/Swift/Controllers/UIInterfaces/ChatWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/ChatWindowFactory.h
@@ -10,17 +10,17 @@
#include "Swiften/JID/JID.h"
namespace Swift {
- class ChatWindow;
- class UIEventStream;
- class ChatWindowFactory {
- public:
- virtual ~ChatWindowFactory() {}
- /**
- * Transfers ownership of result.
- */
- virtual ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream) = 0;
+ class ChatWindow;
+ class UIEventStream;
+ class ChatWindowFactory {
+ public:
+ virtual ~ChatWindowFactory() {}
+ /**
+ * Transfers ownership of result.
+ */
+ virtual ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream) = 0;
- };
+ };
}
#endif
diff --git a/Swift/Controllers/UIInterfaces/ContactEditWindow.h b/Swift/Controllers/UIInterfaces/ContactEditWindow.h
index 2d15375..1e311c5 100644
--- a/Swift/Controllers/UIInterfaces/ContactEditWindow.h
+++ b/Swift/Controllers/UIInterfaces/ContactEditWindow.h
@@ -1,35 +1,35 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/boost_bsignals.h>
-#include <boost/shared_ptr.hpp>
+#include <memory>
#include <set>
+#include <string>
#include <vector>
-#include <string>
+#include <boost/signals2.hpp>
namespace Swift {
- class JID;
- class VCardManager;
+ class JID;
+ class VCardManager;
- class ContactEditWindow {
- public:
- virtual ~ContactEditWindow() {}
+ class ContactEditWindow {
+ public:
+ virtual ~ContactEditWindow() {}
- virtual void setEnabled(bool b) = 0;
+ virtual void setEnabled(bool b) = 0;
- virtual void setNameSuggestions(const std::vector<std::string>& suggestions) = 0;
- virtual void setContact(const JID& jid, const std::string& name, const std::vector<std::string>& groups, const std::set<std::string>& allGroups) = 0;
+ virtual void setNameSuggestions(const std::vector<std::string>& suggestions) = 0;
+ virtual void setContact(const JID& jid, const std::string& name, const std::vector<std::string>& groups, const std::set<std::string>& allGroups) = 0;
- virtual void show() = 0;
- virtual void hide() = 0;
+ virtual void show() = 0;
+ virtual void hide() = 0;
- boost::signal<void ()> onRemoveContactRequest;
- boost::signal<void (const std::string& /* name */, const std::set<std::string>& /* groups */)> onChangeContactRequest;
- };
+ boost::signals2::signal<void ()> onRemoveContactRequest;
+ boost::signals2::signal<void (const std::string& /* name */, const std::set<std::string>& /* groups */)> onChangeContactRequest;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/ContactEditWindowFactory.h b/Swift/Controllers/UIInterfaces/ContactEditWindowFactory.h
index 6955a69..f5a84d5 100644
--- a/Swift/Controllers/UIInterfaces/ContactEditWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/ContactEditWindowFactory.h
@@ -9,10 +9,10 @@
#include <Swift/Controllers/UIInterfaces/ContactEditWindow.h>
namespace Swift {
- class ContactEditWindowFactory {
- public:
- virtual ~ContactEditWindowFactory() {}
+ class ContactEditWindowFactory {
+ public:
+ virtual ~ContactEditWindowFactory() {}
- virtual ContactEditWindow* createContactEditWindow() = 0;
- };
+ virtual ContactEditWindow* createContactEditWindow() = 0;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/EventWindow.h b/Swift/Controllers/UIInterfaces/EventWindow.h
index 96ea4a1..c05976b 100644
--- a/Swift/Controllers/UIInterfaces/EventWindow.h
+++ b/Swift/Controllers/UIInterfaces/EventWindow.h
@@ -1,29 +1,29 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
-#include "Swift/Controllers/XMPPEvents/StanzaEvent.h"
+#include <Swift/Controllers/XMPPEvents/StanzaEvent.h>
namespace Swift {
- class EventWindow {
- public:
- EventWindow(bool candelete = true) : canDelete_(candelete) {}
+ class EventWindow {
+ public:
+ EventWindow(bool candelete = true) : canDelete_(candelete) {}
- bool canDelete() const {
- return canDelete_;
- }
+ bool canDelete() const {
+ return canDelete_;
+ }
- virtual ~EventWindow() {}
- virtual void addEvent(boost::shared_ptr<StanzaEvent> event, bool active) = 0;
- virtual void removeEvent(boost::shared_ptr<StanzaEvent> event) = 0;
+ virtual ~EventWindow() {}
+ virtual void addEvent(std::shared_ptr<StanzaEvent> event, bool active) = 0;
+ virtual void removeEvent(std::shared_ptr<StanzaEvent> event) = 0;
- private:
- bool canDelete_;
- };
+ private:
+ bool canDelete_;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/EventWindowFactory.h b/Swift/Controllers/UIInterfaces/EventWindowFactory.h
index 7c9c87d..76638da 100644
--- a/Swift/Controllers/UIInterfaces/EventWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/EventWindowFactory.h
@@ -7,17 +7,17 @@
#pragma once
namespace Swift {
- class EventWindow;
+ class EventWindow;
- class EventWindowFactory {
- public:
- virtual ~EventWindowFactory() {}
- /**
- * Transfers ownership of result.
- */
- virtual EventWindow* createEventWindow() = 0;
+ class EventWindowFactory {
+ public:
+ virtual ~EventWindowFactory() {}
+ /**
+ * Transfers ownership of result.
+ */
+ virtual EventWindow* createEventWindow() = 0;
- };
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/FileTransferListWidget.h b/Swift/Controllers/UIInterfaces/FileTransferListWidget.h
index 01dcfd3..5a9eaeb 100644
--- a/Swift/Controllers/UIInterfaces/FileTransferListWidget.h
+++ b/Swift/Controllers/UIInterfaces/FileTransferListWidget.h
@@ -12,12 +12,12 @@ class FileTransferOverview;
class FileTransferListWidget {
public:
- virtual ~FileTransferListWidget() {}
+ virtual ~FileTransferListWidget() {}
- virtual void show() = 0;
- virtual void activate() = 0;
+ virtual void show() = 0;
+ virtual void activate() = 0;
- virtual void setFileTransferOverview(FileTransferOverview*) = 0;
+ virtual void setFileTransferOverview(FileTransferOverview*) = 0;
};
}
diff --git a/Swift/Controllers/UIInterfaces/FileTransferListWidgetFactory.h b/Swift/Controllers/UIInterfaces/FileTransferListWidgetFactory.h
index 0b08fb3..da9fd37 100644
--- a/Swift/Controllers/UIInterfaces/FileTransferListWidgetFactory.h
+++ b/Swift/Controllers/UIInterfaces/FileTransferListWidgetFactory.h
@@ -4,17 +4,23 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
-#include "Swift/Controllers/UIInterfaces/FileTransferListWidget.h"
+#include <Swift/Controllers/UIInterfaces/FileTransferListWidget.h>
namespace Swift {
class FileTransferListWidgetFactory {
public:
- virtual ~FileTransferListWidgetFactory() {}
+ virtual ~FileTransferListWidgetFactory() {}
- virtual FileTransferListWidget* createFileTransferListWidget() = 0;
+ virtual FileTransferListWidget* createFileTransferListWidget() = 0;
};
}
diff --git a/Swift/Controllers/UIInterfaces/HighlightEditorWidget.h b/Swift/Controllers/UIInterfaces/HighlightEditorWidget.h
index 4745035..ff888e6 100644
--- a/Swift/Controllers/UIInterfaces/HighlightEditorWidget.h
+++ b/Swift/Controllers/UIInterfaces/HighlightEditorWidget.h
@@ -8,15 +8,15 @@
namespace Swift {
- class HighlightManager;
+ class HighlightManager;
- class HighlightEditorWidget {
- public:
- virtual ~HighlightEditorWidget() {}
+ class HighlightEditorWidget {
+ public:
+ virtual ~HighlightEditorWidget() {}
- virtual void show() = 0;
+ virtual void show() = 0;
- virtual void setHighlightManager(HighlightManager* highlightManager) = 0;
- };
+ virtual void setHighlightManager(HighlightManager* highlightManager) = 0;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/HighlightEditorWidgetFactory.h b/Swift/Controllers/UIInterfaces/HighlightEditorWidgetFactory.h
index ade575b..363e666 100644
--- a/Swift/Controllers/UIInterfaces/HighlightEditorWidgetFactory.h
+++ b/Swift/Controllers/UIInterfaces/HighlightEditorWidgetFactory.h
@@ -8,13 +8,13 @@
namespace Swift {
- class HighlightEditorWidget;
+ class HighlightEditorWidget;
- class HighlightEditorWidgetFactory {
- public:
- virtual ~HighlightEditorWidgetFactory() {}
+ class HighlightEditorWidgetFactory {
+ public:
+ virtual ~HighlightEditorWidgetFactory() {}
- virtual HighlightEditorWidget* createHighlightEditorWidget() = 0;
- };
+ virtual HighlightEditorWidget* createHighlightEditorWidget() = 0;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/HighlightEditorWindow.h b/Swift/Controllers/UIInterfaces/HighlightEditorWindow.h
index 12adb3d..cae54dc 100644
--- a/Swift/Controllers/UIInterfaces/HighlightEditorWindow.h
+++ b/Swift/Controllers/UIInterfaces/HighlightEditorWindow.h
@@ -1,11 +1,15 @@
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
+#pragma once
+
#include <vector>
-#include <Swiften/Base/boost_bsignals.h>
+
+#include <boost/signals2.hpp>
+
#include <Swift/Controllers/Contact.h>
namespace Swift {
@@ -14,14 +18,14 @@ class HighlightManager;
class HighlightEditorWindow {
public:
- HighlightEditorWindow();
- virtual ~HighlightEditorWindow();
- virtual void show() = 0;
- virtual void setHighlightManager(HighlightManager *highlightManager) = 0;
- virtual void setContactSuggestions(const std::vector<Contact::ref>& suggestions) = 0;
+ HighlightEditorWindow();
+ virtual ~HighlightEditorWindow();
+ virtual void show() = 0;
+ virtual void setHighlightManager(HighlightManager *highlightManager) = 0;
+ virtual void setContactSuggestions(const std::vector<Contact::ref>& suggestions) = 0;
public:
- boost::signal<void (const std::string&)> onContactSuggestionsRequested;
+ boost::signals2::signal<void (const std::string&)> onContactSuggestionsRequested;
};
}
diff --git a/Swift/Controllers/UIInterfaces/HighlightEditorWindowFactory.h b/Swift/Controllers/UIInterfaces/HighlightEditorWindowFactory.h
index 18fbeb7..ea05425 100644
--- a/Swift/Controllers/UIInterfaces/HighlightEditorWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/HighlightEditorWindowFactory.h
@@ -13,12 +13,12 @@
#pragma once
namespace Swift {
- class HighlightEditorWindow;
+ class HighlightEditorWindow;
- class HighlightEditorWindowFactory {
- public :
- virtual ~HighlightEditorWindowFactory() {}
+ class HighlightEditorWindowFactory {
+ public :
+ virtual ~HighlightEditorWindowFactory() {}
- virtual HighlightEditorWindow* createHighlightEditorWindow() = 0;
- };
+ virtual HighlightEditorWindow* createHighlightEditorWindow() = 0;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/HistoryWindow.h b/Swift/Controllers/UIInterfaces/HistoryWindow.h
index 6d50f4b..413d9d6 100644
--- a/Swift/Controllers/UIInterfaces/HistoryWindow.h
+++ b/Swift/Controllers/UIInterfaces/HistoryWindow.h
@@ -4,31 +4,37 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <Swift/Controllers/Roster/Roster.h>
namespace Swift {
- class HistoryWindow {
- public:
- virtual ~HistoryWindow() {}
+ class HistoryWindow {
+ public:
+ virtual ~HistoryWindow() {}
- virtual void activate() = 0;
- virtual void setRosterModel(Roster*) = 0;
- virtual void addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, const std::string& avatarPath, const boost::posix_time::ptime& time, bool addAtTheTop) = 0;
- virtual void resetConversationView() = 0;
- virtual void resetConversationViewTopInsertPoint() = 0; // this is a temporary fix used in adding messages at the top
- virtual void setDate(const boost::gregorian::date& date) = 0;
+ virtual void activate() = 0;
+ virtual void setRosterModel(Roster*) = 0;
+ virtual void addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, const std::string& avatarPath, const boost::posix_time::ptime& time, bool addAtTheTop) = 0;
+ virtual void resetConversationView() = 0;
+ virtual void resetConversationViewTopInsertPoint() = 0; // this is a temporary fix used in adding messages at the top
+ virtual void setDate(const boost::gregorian::date& date) = 0;
- virtual std::string getSearchBoxText() = 0;
- virtual boost::gregorian::date getLastVisibleDate() = 0;
+ virtual std::string getSearchBoxText() = 0;
+ virtual boost::gregorian::date getLastVisibleDate() = 0;
- boost::signal<void (RosterItem*)> onSelectedContactChanged;
- boost::signal<void (const std::string&)> onReturnPressed;
- boost::signal<void (const boost::gregorian::date&)> onScrollReachedTop;
- boost::signal<void (const boost::gregorian::date&)> onScrollReachedBottom;
- boost::signal<void ()> onPreviousButtonClicked;
- boost::signal<void ()> onNextButtonClicked;
- boost::signal<void (const boost::gregorian::date&)> onCalendarClicked;
- };
+ boost::signals2::signal<void (RosterItem*)> onSelectedContactChanged;
+ boost::signals2::signal<void (const std::string&)> onReturnPressed;
+ boost::signals2::signal<void (const boost::gregorian::date&)> onScrollReachedTop;
+ boost::signals2::signal<void (const boost::gregorian::date&)> onScrollReachedBottom;
+ boost::signals2::signal<void ()> onPreviousButtonClicked;
+ boost::signals2::signal<void ()> onNextButtonClicked;
+ boost::signals2::signal<void (const boost::gregorian::date&)> onCalendarClicked;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/HistoryWindowFactory.h b/Swift/Controllers/UIInterfaces/HistoryWindowFactory.h
index 807fec5..ab4cf0d 100644
--- a/Swift/Controllers/UIInterfaces/HistoryWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/HistoryWindowFactory.h
@@ -9,10 +9,10 @@
#include <Swift/Controllers/UIInterfaces/HistoryWindow.h>
namespace Swift {
- class UIEventStream;
- class HistoryWindowFactory {
- public:
- virtual ~HistoryWindowFactory() {}
- virtual HistoryWindow* createHistoryWindow(UIEventStream* eventStream) = 0;
- };
+ class UIEventStream;
+ class HistoryWindowFactory {
+ public:
+ virtual ~HistoryWindowFactory() {}
+ virtual HistoryWindow* createHistoryWindow(UIEventStream* eventStream) = 0;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/JoinMUCWindow.h b/Swift/Controllers/UIInterfaces/JoinMUCWindow.h
index 3fcf999..7a71195 100644
--- a/Swift/Controllers/UIInterfaces/JoinMUCWindow.h
+++ b/Swift/Controllers/UIInterfaces/JoinMUCWindow.h
@@ -1,26 +1,27 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <string>
#include <vector>
-#include <string>
-#include <Swiften/Base/boost_bsignals.h>
+#include <boost/signals2.hpp>
+
#include <Swiften/JID/JID.h>
namespace Swift {
- class JoinMUCWindow {
- public:
- virtual ~JoinMUCWindow() {}
+ class JoinMUCWindow {
+ public:
+ virtual ~JoinMUCWindow() {}
- virtual void setNick(const std::string& nick) = 0;
- virtual void setMUC(const std::string& nick) = 0;
- virtual void show() = 0;
+ virtual void setNick(const std::string& nick) = 0;
+ virtual void setMUC(const std::string& nick) = 0;
+ virtual void show() = 0;
- boost::signal<void ()> onSearchMUC;
- };
+ boost::signals2::signal<void ()> onSearchMUC;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h b/Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h
index a711294..5e8b1d0 100644
--- a/Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h
@@ -9,11 +9,11 @@
#include <Swift/Controllers/UIInterfaces/JoinMUCWindow.h>
namespace Swift {
- class UIEventStream;
- class JoinMUCWindowFactory {
- public:
- virtual ~JoinMUCWindowFactory() {}
+ class UIEventStream;
+ class JoinMUCWindowFactory {
+ public:
+ virtual ~JoinMUCWindowFactory() {}
- virtual JoinMUCWindow* createJoinMUCWindow(UIEventStream* uiEventStream) = 0;
- };
+ virtual JoinMUCWindow* createJoinMUCWindow(UIEventStream* uiEventStream) = 0;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/LoginWindow.h b/Swift/Controllers/UIInterfaces/LoginWindow.h
index 6baa5d8..d11aadb 100644
--- a/Swift/Controllers/UIInterfaces/LoginWindow.h
+++ b/Swift/Controllers/UIInterfaces/LoginWindow.h
@@ -1,41 +1,42 @@
/*
- * Copyright (c) 2010-2012 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/boost_bsignals.h>
-#include <boost/shared_ptr.hpp>
-
+#include <memory>
#include <string>
+
+#include <boost/signals2.hpp>
+
+#include <Swiften/Client/ClientOptions.h>
#include <Swiften/TLS/Certificate.h>
#include <Swiften/TLS/CertificateWithKey.h>
-#include <Swiften/Client/ClientOptions.h>
namespace Swift {
- class MainWindow;
- class LoginWindow {
- public:
- virtual ~LoginWindow() {}
- virtual void selectUser(const std::string&) = 0;
- virtual void morphInto(MainWindow *mainWindow) = 0;
- virtual void loggedOut() = 0;
- virtual void setShowNotificationToggle(bool) = 0;
- virtual void setMessage(const std::string&) = 0;
- virtual void setIsLoggingIn(bool loggingIn) = 0;
- virtual void addAvailableAccount(const std::string& defaultJID, const std::string& defaultPassword, const std::string& defaultCertificate, const ClientOptions& options) = 0;
- virtual void removeAvailableAccount(const std::string& jid) = 0;
- /** The certificate is what is used for login, the certificatePath is used for remembering paths to populate the loginwindow with*/
- boost::signal<void (const std::string&, const std::string&, const std::string& /*CertificatePath*/, CertificateWithKey::ref /* clientCertificate */, const ClientOptions& /*options*/, bool /* remember password*/, bool /* login automatically */)> onLoginRequest;
- virtual void setLoginAutomatically(bool loginAutomatically) = 0;
- virtual void quit() = 0;
- /** Blocking request whether a cert should be permanently trusted.*/
- virtual bool askUserToTrustCertificatePermanently(const std::string& message, const std::vector<Certificate::ref>& certificateChain) = 0;
+ class MainWindow;
+ class LoginWindow {
+ public:
+ virtual ~LoginWindow() {}
+ virtual void selectUser(const std::string&) = 0;
+ virtual void morphInto(MainWindow *mainWindow) = 0;
+ virtual void loggedOut() = 0;
+ virtual void setShowNotificationToggle(bool) = 0;
+ virtual void setMessage(const std::string&) = 0;
+ virtual void setIsLoggingIn(bool loggingIn) = 0;
+ virtual void addAvailableAccount(const std::string& defaultJID, const std::string& defaultPassword, const std::string& defaultCertificate, const ClientOptions& options) = 0;
+ virtual void removeAvailableAccount(const std::string& jid) = 0;
+ /** The certificate is what is used for login, the certificatePath is used for remembering paths to populate the loginwindow with*/
+ boost::signals2::signal<void (const std::string&, const std::string&, const std::string& /*CertificatePath*/, CertificateWithKey::ref /* clientCertificate */, const ClientOptions& /*options*/, bool /* remember password*/, bool /* login automatically */)> onLoginRequest;
+ virtual void setLoginAutomatically(bool loginAutomatically) = 0;
+ virtual void quit() = 0;
+ /** Blocking request whether a cert should be permanently trusted.*/
+ virtual bool askUserToTrustCertificatePermanently(const std::string& message, const std::vector<Certificate::ref>& certificateChain) = 0;
- boost::signal<void ()> onCancelLoginRequest;
- boost::signal<void ()> onQuitRequest;
- boost::signal<void (const std::string&)> onPurgeSavedLoginRequest;
- };
+ boost::signals2::signal<void ()> onCancelLoginRequest;
+ boost::signals2::signal<void ()> onQuitRequest;
+ boost::signals2::signal<void (const std::string&)> onPurgeSavedLoginRequest;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/LoginWindowFactory.h b/Swift/Controllers/UIInterfaces/LoginWindowFactory.h
index c040833..485f975 100644
--- a/Swift/Controllers/UIInterfaces/LoginWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/LoginWindowFactory.h
@@ -10,20 +10,20 @@
namespace Swift {
- class LoginWindow;
-
- class UIEventStream;
-
- class LoginWindowFactory {
- public:
- virtual ~LoginWindowFactory() {}
-
- /**
- * Transfers ownership of result.
- */
- virtual LoginWindow* createLoginWindow(UIEventStream* uiEventStream) = 0;
-
- };
+ class LoginWindow;
+
+ class UIEventStream;
+
+ class LoginWindowFactory {
+ public:
+ virtual ~LoginWindowFactory() {}
+
+ /**
+ * Transfers ownership of result.
+ */
+ virtual LoginWindow* createLoginWindow(UIEventStream* uiEventStream) = 0;
+
+ };
}
#endif
diff --git a/Swift/Controllers/UIInterfaces/MUCSearchWindow.h b/Swift/Controllers/UIInterfaces/MUCSearchWindow.h
index 9c3816e..045c2df 100644
--- a/Swift/Controllers/UIInterfaces/MUCSearchWindow.h
+++ b/Swift/Controllers/UIInterfaces/MUCSearchWindow.h
@@ -1,34 +1,35 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swiften/Base/boost_bsignals.h"
-
+#include <string>
#include <vector>
#include <boost/optional.hpp>
-#include <string>
-#include "Swiften/JID/JID.h"
+#include <boost/signals2.hpp>
+
+#include <Swiften/JID/JID.h>
+
#include <Swift/Controllers/Chat/MUCSearchController.h>
namespace Swift {
- class MUCSearchWindow {
- public:
- virtual ~MUCSearchWindow() {}
+ class MUCSearchWindow {
+ public:
+ virtual ~MUCSearchWindow() {}
- virtual void clearList() = 0;
- virtual void addService(const MUCService& service) = 0;
- virtual void addSavedServices(const std::list<JID>& services) = 0;
- virtual void setSearchInProgress(bool searching) = 0;
+ virtual void clearList() = 0;
+ virtual void addService(const MUCService& service) = 0;
+ virtual void addSavedServices(const std::list<JID>& services) = 0;
+ virtual void setSearchInProgress(bool searching) = 0;
- virtual void show() = 0;
+ virtual void show() = 0;
- boost::signal<void (const JID&)> onSearchService;
- boost::signal<void (const boost::optional<JID>&)> onFinished;
- };
+ boost::signals2::signal<void (const JID&)> onSearchService;
+ boost::signals2::signal<void (const boost::optional<JID>&)> onFinished;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h b/Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h
index 96d96b8..6e26ac3 100644
--- a/Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/UIInterfaces/MUCSearchWindow.h"
+#include <Swift/Controllers/UIInterfaces/MUCSearchWindow.h>
namespace Swift {
- class UIEventStream;
- class MUCSearchWindowFactory {
- public:
- virtual ~MUCSearchWindowFactory() {}
+ class UIEventStream;
+ class MUCSearchWindowFactory {
+ public:
+ virtual ~MUCSearchWindowFactory() {}
- virtual MUCSearchWindow* createMUCSearchWindow() = 0;
- };
+ virtual MUCSearchWindow* createMUCSearchWindow() = 0;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/MainWindow.h b/Swift/Controllers/UIInterfaces/MainWindow.h
index 8717021..bfd8c67 100644
--- a/Swift/Controllers/UIInterfaces/MainWindow.h
+++ b/Swift/Controllers/UIInterfaces/MainWindow.h
@@ -1,53 +1,54 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <memory>
#include <string>
-#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
-#include <Swiften/JID/JID.h>
-#include <Swiften/Elements/StatusShow.h>
#include <Swiften/Elements/DiscoItems.h>
+#include <Swiften/Elements/StatusShow.h>
+#include <Swiften/JID/JID.h>
#include <Swiften/TLS/Certificate.h>
-#include <Swiften/Base/boost_bsignals.h>
+
#include <Swift/Controllers/Roster/ContactRosterItem.h>
namespace Swift {
- class Roster;
-
- class MainWindow {
- public:
- MainWindow(bool candelete = true) : canDelete_(candelete) {}
- virtual ~MainWindow() {}
-
- bool canDelete() const {
- return canDelete_;
- }
-
- virtual void setMyNick(const std::string& name) = 0;
- virtual void setMyJID(const JID& jid) = 0;
- virtual void setMyAvatarPath(const std::string& path) = 0;
- virtual void setMyStatusText(const std::string& status) = 0;
- virtual void setMyStatusType(StatusShow::Type type) = 0;
- virtual void setMyContactRosterItem(boost::shared_ptr<ContactRosterItem> contact) = 0;
- /** Must be able to cope with NULL to clear the roster */
- virtual void setRosterModel(Roster* roster) = 0;
- virtual void setConnecting() = 0;
- virtual void setBlockingCommandAvailable(bool isAvailable) = 0;
- virtual void setAvailableAdHocCommands(const std::vector<DiscoItems::Item>& commands) = 0;
- virtual void setStreamEncryptionStatus(bool tlsInPlaceAndValid) = 0;
- virtual void openCertificateDialog(const std::vector<Certificate::ref>& chain) = 0;
-
- boost::signal<void (StatusShow::Type, const std::string&)> onChangeStatusRequest;
- boost::signal<void ()> onSignOutRequest;
- boost::signal<void ()> onShowCertificateRequest;
-
- private:
- bool canDelete_;
- };
+ class Roster;
+
+ class MainWindow {
+ public:
+ MainWindow(bool candelete = true) : canDelete_(candelete) {}
+ virtual ~MainWindow() {}
+
+ bool canDelete() const {
+ return canDelete_;
+ }
+
+ virtual void setMyNick(const std::string& name) = 0;
+ virtual void setMyJID(const JID& jid) = 0;
+ virtual void setMyAvatarPath(const std::string& path) = 0;
+ virtual void setMyStatusText(const std::string& status) = 0;
+ virtual void setMyStatusType(StatusShow::Type type) = 0;
+ virtual void setMyContactRosterItem(std::shared_ptr<ContactRosterItem> contact) = 0;
+ /** Must be able to cope with NULL to clear the roster */
+ virtual void setRosterModel(Roster* roster) = 0;
+ virtual void setConnecting() = 0;
+ virtual void setBlockingCommandAvailable(bool isAvailable) = 0;
+ virtual void setAvailableAdHocCommands(const std::vector<DiscoItems::Item>& commands) = 0;
+ virtual void setStreamEncryptionStatus(bool tlsInPlaceAndValid) = 0;
+ virtual void openCertificateDialog(const std::vector<Certificate::ref>& chain) = 0;
+
+ boost::signals2::signal<void (StatusShow::Type, const std::string&)> onChangeStatusRequest;
+ boost::signals2::signal<void ()> onSignOutRequest;
+ boost::signals2::signal<void ()> onShowCertificateRequest;
+
+ private:
+ bool canDelete_;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/MainWindowFactory.h b/Swift/Controllers/UIInterfaces/MainWindowFactory.h
index 5c24187..c0110cf 100644
--- a/Swift/Controllers/UIInterfaces/MainWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/MainWindowFactory.h
@@ -11,17 +11,17 @@
#include "Swift/Controllers/UIEvents/UIEventStream.h"
namespace Swift {
- class MainWindow;
+ class MainWindow;
- class MainWindowFactory {
- public:
- virtual ~MainWindowFactory() {}
- /**
- * Transfers ownership of result.
- */
- virtual MainWindow* createMainWindow(UIEventStream* eventStream) = 0;
+ class MainWindowFactory {
+ public:
+ virtual ~MainWindowFactory() {}
+ /**
+ * Transfers ownership of result.
+ */
+ virtual MainWindow* createMainWindow(UIEventStream* eventStream) = 0;
- };
+ };
}
#endif
diff --git a/Swift/Controllers/UIInterfaces/ProfileWindow.h b/Swift/Controllers/UIInterfaces/ProfileWindow.h
index e2c9da4..c2bcdae 100644
--- a/Swift/Controllers/UIInterfaces/ProfileWindow.h
+++ b/Swift/Controllers/UIInterfaces/ProfileWindow.h
@@ -1,35 +1,36 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/boost_bsignals.h>
-#include <boost/shared_ptr.hpp>
+#include <memory>
+
+#include <boost/signals2.hpp>
#include <Swiften/Elements/VCard.h>
namespace Swift {
- class JID;
+ class JID;
- class ProfileWindow {
- public:
- virtual ~ProfileWindow() {}
+ class ProfileWindow {
+ public:
+ virtual ~ProfileWindow() {}
- virtual void setJID(const JID& jid) = 0;
- virtual void setVCard(VCard::ref vcard) = 0;
+ virtual void setJID(const JID& jid) = 0;
+ virtual void setVCard(VCard::ref vcard) = 0;
- virtual void setEnabled(bool b) = 0;
- virtual void setProcessing(bool b) = 0;
- virtual void setError(const std::string&) = 0;
- virtual void setEditable(bool b) = 0;
+ virtual void setEnabled(bool b) = 0;
+ virtual void setProcessing(bool b) = 0;
+ virtual void setError(const std::string&) = 0;
+ virtual void setEditable(bool b) = 0;
- virtual void show() = 0;
- virtual void hide() = 0;
+ virtual void show() = 0;
+ virtual void hide() = 0;
- boost::signal<void (VCard::ref)> onVCardChangeRequest;
- boost::signal<void (const JID&)> onWindowAboutToBeClosed;
- };
+ boost::signals2::signal<void (VCard::ref)> onVCardChangeRequest;
+ boost::signals2::signal<void (const JID&)> onWindowAboutToBeClosed;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/ProfileWindowFactory.h b/Swift/Controllers/UIInterfaces/ProfileWindowFactory.h
index 5137151..6c2c6e5 100644
--- a/Swift/Controllers/UIInterfaces/ProfileWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/ProfileWindowFactory.h
@@ -9,10 +9,10 @@
#include <Swift/Controllers/UIInterfaces/ProfileWindow.h>
namespace Swift {
- class ProfileWindowFactory {
- public:
- virtual ~ProfileWindowFactory() {}
+ class ProfileWindowFactory {
+ public:
+ virtual ~ProfileWindowFactory() {}
- virtual ProfileWindow* createProfileWindow() = 0;
- };
+ virtual ProfileWindow* createProfileWindow() = 0;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/UIFactory.h b/Swift/Controllers/UIInterfaces/UIFactory.h
index 7e05657..a0976dc 100644
--- a/Swift/Controllers/UIInterfaces/UIFactory.h
+++ b/Swift/Controllers/UIInterfaces/UIFactory.h
@@ -1,49 +1,49 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <Swift/Controllers/UIInterfaces/AdHocCommandWindowFactory.h>
+#include <Swift/Controllers/UIInterfaces/BlockListEditorWidgetFactory.h>
#include <Swift/Controllers/UIInterfaces/ChatListWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/ChatWindowFactory.h>
-#include <Swift/Controllers/UIInterfaces/HistoryWindowFactory.h>
+#include <Swift/Controllers/UIInterfaces/ContactEditWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/EventWindowFactory.h>
+#include <Swift/Controllers/UIInterfaces/FileTransferListWidgetFactory.h>
+#include <Swift/Controllers/UIInterfaces/HighlightEditorWindowFactory.h>
+#include <Swift/Controllers/UIInterfaces/HistoryWindowFactory.h>
+#include <Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/LoginWindowFactory.h>
-#include <Swift/Controllers/UIInterfaces/MainWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/MUCSearchWindowFactory.h>
-#include <Swift/Controllers/UIInterfaces/JoinMUCWindowFactory.h>
-#include <Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h>
-#include <Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h>
+#include <Swift/Controllers/UIInterfaces/MainWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/ProfileWindowFactory.h>
-#include <Swift/Controllers/UIInterfaces/ContactEditWindowFactory.h>
-#include <Swift/Controllers/UIInterfaces/AdHocCommandWindowFactory.h>
-#include <Swift/Controllers/UIInterfaces/FileTransferListWidgetFactory.h>
+#include <Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h>
-#include <Swift/Controllers/UIInterfaces/HighlightEditorWindowFactory.h>
-#include <Swift/Controllers/UIInterfaces/BlockListEditorWidgetFactory.h>
+#include <Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h>
namespace Swift {
- class UIFactory :
- public ChatListWindowFactory,
- public ChatWindowFactory,
- public HistoryWindowFactory,
- public EventWindowFactory,
- public LoginWindowFactory,
- public MainWindowFactory,
- public MUCSearchWindowFactory,
- public XMLConsoleWidgetFactory,
- public UserSearchWindowFactory,
- public JoinMUCWindowFactory,
- public ProfileWindowFactory,
- public ContactEditWindowFactory,
- public AdHocCommandWindowFactory,
- public FileTransferListWidgetFactory,
- public WhiteboardWindowFactory,
- public HighlightEditorWindowFactory,
- public BlockListEditorWidgetFactory {
- public:
- virtual ~UIFactory() {}
- };
+ class UIFactory :
+ public ChatListWindowFactory,
+ public ChatWindowFactory,
+ public HistoryWindowFactory,
+ public EventWindowFactory,
+ public LoginWindowFactory,
+ public MainWindowFactory,
+ public MUCSearchWindowFactory,
+ public XMLConsoleWidgetFactory,
+ public UserSearchWindowFactory,
+ public JoinMUCWindowFactory,
+ public ProfileWindowFactory,
+ public ContactEditWindowFactory,
+ public AdHocCommandWindowFactory,
+ public FileTransferListWidgetFactory,
+ public WhiteboardWindowFactory,
+ public HighlightEditorWindowFactory,
+ public BlockListEditorWidgetFactory {
+ public:
+ virtual ~UIFactory() {}
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/UserSearchWindow.h b/Swift/Controllers/UIInterfaces/UserSearchWindow.h
index 9e17ba9..279f4f3 100644
--- a/Swift/Controllers/UIInterfaces/UserSearchWindow.h
+++ b/Swift/Controllers/UIInterfaces/UserSearchWindow.h
@@ -1,56 +1,58 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swiften/Base/boost_bsignals.h>
-
-#include <vector>
#include <string>
+#include <vector>
+
+#include <boost/signals2.hpp>
#include <Swiften/JID/JID.h>
+
#include <Swift/Controllers/Chat/UserSearchController.h>
#include <Swift/Controllers/Contact.h>
namespace Swift {
- class UserSearchWindow {
- public:
- enum Type {AddContact, ChatToContact, InviteToChat};
- virtual ~UserSearchWindow() {}
-
- virtual void clear() = 0;
- virtual void setResults(const std::vector<UserSearchResult>& results) = 0;
- virtual void setResultsForm(const Form::ref results) = 0;
- virtual void addSavedServices(const std::vector<JID>& services) = 0;
- virtual void setSelectedService(const JID& service) = 0;
- virtual void setServerSupportsSearch(bool support) = 0;
- virtual void setSearchError(bool support) = 0;
- virtual void setSearchFields(boost::shared_ptr<SearchPayload> fields) = 0;
- virtual void setNameSuggestions(const std::vector<std::string>& suggestions) = 0;
- virtual void prepopulateJIDAndName(const JID& jid, const std::string& name) = 0;
- virtual void setContactSuggestions(const std::vector<Contact::ref>& suggestions) = 0;
- virtual void setJIDs(const std::vector<JID>&) = 0;
- virtual void setRoomJID(const JID& roomJID) = 0;
- virtual std::string getReason() const = 0;
- virtual std::vector<JID> getJIDs() const = 0;
- virtual void setCanStartImpromptuChats(bool supportsImpromptu) = 0;
- virtual void updateContacts(const std::vector<Contact::ref>& contacts) = 0;
- virtual void addContacts(const std::vector<Contact::ref>& contacts) = 0;
- virtual void setCanSupplyDescription(bool allowed) = 0;
- virtual void setWarning(const boost::optional<std::string>& message) = 0;
-
- virtual void show() = 0;
-
- boost::signal<void (const JID&)> onFormRequested;
- boost::signal<void (boost::shared_ptr<SearchPayload>, const JID&)> onSearchRequested;
- boost::signal<void (const JID&)> onNameSuggestionRequested;
- boost::signal<void (const std::string&)> onContactSuggestionsRequested;
- boost::signal<void (const std::vector<JID>&)> onJIDUpdateRequested;
- boost::signal<void (const std::vector<JID>&)> onJIDAddRequested;
- boost::signal<void (const JID&)> onJIDEditFieldChanged;
- };
+ class UserSearchWindow {
+ public:
+ enum Type {AddContact, ChatToContact, InviteToChat};
+ virtual ~UserSearchWindow() {}
+
+ virtual void clear() = 0;
+ virtual void setResults(const std::vector<UserSearchResult>& results) = 0;
+ virtual void setResultsForm(const Form::ref results) = 0;
+ virtual void addSavedServices(const std::vector<JID>& services) = 0;
+ virtual void setSelectedService(const JID& service) = 0;
+ virtual void setServerSupportsSearch(bool support) = 0;
+ virtual void setSearchError(bool support) = 0;
+ virtual void setSearchFields(std::shared_ptr<SearchPayload> fields) = 0;
+ virtual void setNameSuggestions(const std::vector<std::string>& suggestions) = 0;
+ virtual void prepopulateJIDAndName(const JID& jid, const std::string& name) = 0;
+ virtual void setContactSuggestions(const std::vector<Contact::ref>& suggestions) = 0;
+ virtual void setJIDs(const std::vector<JID>&) = 0;
+ virtual void setOriginator(const JID& originator) = 0;
+ virtual void setRoomJID(const JID& roomJID) = 0;
+ virtual std::string getReason() const = 0;
+ virtual std::vector<JID> getJIDs() const = 0;
+ virtual void setCanStartImpromptuChats(bool supportsImpromptu) = 0;
+ virtual void updateContacts(const std::vector<Contact::ref>& contacts) = 0;
+ virtual void addContacts(const std::vector<Contact::ref>& contacts) = 0;
+ virtual void setCanSupplyDescription(bool allowed) = 0;
+ virtual void setWarning(const boost::optional<std::string>& message) = 0;
+
+ virtual void show() = 0;
+
+ boost::signals2::signal<void (const JID&)> onFormRequested;
+ boost::signals2::signal<void (std::shared_ptr<SearchPayload>, const JID&)> onSearchRequested;
+ boost::signals2::signal<void (const JID&)> onNameSuggestionRequested;
+ boost::signals2::signal<void (const std::string&)> onContactSuggestionsRequested;
+ boost::signals2::signal<void (const std::vector<JID>&)> onJIDUpdateRequested;
+ boost::signals2::signal<void (const std::vector<JID>&)> onJIDAddRequested;
+ boost::signals2::signal<void (const JID&)> onJIDEditFieldChanged;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h b/Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h
index b3a325e..d5d6135 100644
--- a/Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/UserSearchWindowFactory.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,14 +8,14 @@
#include <set>
-#include "Swift/Controllers/UIInterfaces/UserSearchWindow.h"
+#include <Swift/Controllers/UIInterfaces/UserSearchWindow.h>
namespace Swift {
- class UIEventStream;
- class UserSearchWindowFactory {
- public:
- virtual ~UserSearchWindowFactory() {}
+ class UIEventStream;
+ class UserSearchWindowFactory {
+ public:
+ virtual ~UserSearchWindowFactory() {}
- virtual UserSearchWindow* createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream, const std::set<std::string>& groups) = 0;
- };
+ virtual UserSearchWindow* createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream, const std::set<std::string>& groups) = 0;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/WhiteboardWindow.h b/Swift/Controllers/UIInterfaces/WhiteboardWindow.h
index a4a9ef0..a904ee1 100644
--- a/Swift/Controllers/UIInterfaces/WhiteboardWindow.h
+++ b/Swift/Controllers/UIInterfaces/WhiteboardWindow.h
@@ -4,23 +4,29 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#pragma once
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
-#include "Swiften/Base/boost_bsignals.h"
+#pragma once
#include <string>
+#include <boost/signals2.hpp>
+
namespace Swift {
- class WhiteboardSession;
- class WhiteboardElement;
+ class WhiteboardSession;
+ class WhiteboardElement;
- class WhiteboardWindow {
- public:
- virtual ~WhiteboardWindow() {}
+ class WhiteboardWindow {
+ public:
+ virtual ~WhiteboardWindow() {}
- virtual void show() = 0;
- virtual void setSession(boost::shared_ptr<WhiteboardSession> session) = 0;
- virtual void activateWindow() = 0;
- virtual void setName(const std::string& name) = 0;
- };
+ virtual void show() = 0;
+ virtual void setSession(std::shared_ptr<WhiteboardSession> session) = 0;
+ virtual void activateWindow() = 0;
+ virtual void setName(const std::string& name) = 0;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h b/Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h
index 2be0f9c..9868ceb 100644
--- a/Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h
+++ b/Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h
@@ -4,16 +4,24 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
+#include <memory>
+
namespace Swift {
- class WhiteboardSession;
- class WhiteboardWindow;
+ class WhiteboardSession;
+ class WhiteboardWindow;
- class WhiteboardWindowFactory {
- public :
- virtual ~WhiteboardWindowFactory() {}
+ class WhiteboardWindowFactory {
+ public :
+ virtual ~WhiteboardWindowFactory() {}
- virtual WhiteboardWindow* createWhiteboardWindow(boost::shared_ptr<WhiteboardSession> whiteboardSession) = 0;
- };
+ virtual WhiteboardWindow* createWhiteboardWindow(std::shared_ptr<WhiteboardSession> whiteboardSession) = 0;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/XMLConsoleWidget.cpp b/Swift/Controllers/UIInterfaces/XMLConsoleWidget.cpp
index 503cef8..0916d0b 100644
--- a/Swift/Controllers/UIInterfaces/XMLConsoleWidget.cpp
+++ b/Swift/Controllers/UIInterfaces/XMLConsoleWidget.cpp
@@ -1,10 +1,10 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/Controllers/UIInterfaces/XMLConsoleWidget.h"
+#include <Swift/Controllers/UIInterfaces/XMLConsoleWidget.h>
namespace Swift {
diff --git a/Swift/Controllers/UIInterfaces/XMLConsoleWidget.h b/Swift/Controllers/UIInterfaces/XMLConsoleWidget.h
index 7e477a9..872b9de 100644
--- a/Swift/Controllers/UIInterfaces/XMLConsoleWidget.h
+++ b/Swift/Controllers/UIInterfaces/XMLConsoleWidget.h
@@ -9,14 +9,14 @@
#include <Swiften/Base/SafeByteArray.h>
namespace Swift {
- class XMLConsoleWidget {
- public:
- virtual ~XMLConsoleWidget();
+ class XMLConsoleWidget {
+ public:
+ virtual ~XMLConsoleWidget();
- virtual void handleDataRead(const SafeByteArray& data) = 0;
- virtual void handleDataWritten(const SafeByteArray& data) = 0;
+ virtual void handleDataRead(const SafeByteArray& data) = 0;
+ virtual void handleDataWritten(const SafeByteArray& data) = 0;
- virtual void show() = 0;
- virtual void activate() = 0;
- };
+ virtual void show() = 0;
+ virtual void activate() = 0;
+ };
}
diff --git a/Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h b/Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h
index 33b577f..bbc055e 100644
--- a/Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h
+++ b/Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/UIInterfaces/XMLConsoleWidget.h"
+#include <Swift/Controllers/UIInterfaces/XMLConsoleWidget.h>
namespace Swift {
- class UIEventStream;
- class XMLConsoleWidgetFactory {
- public:
- virtual ~XMLConsoleWidgetFactory() {}
+ class UIEventStream;
+ class XMLConsoleWidgetFactory {
+ public:
+ virtual ~XMLConsoleWidgetFactory() {}
- virtual XMLConsoleWidget* createXMLConsoleWidget() = 0;
- };
+ virtual XMLConsoleWidget* createXMLConsoleWidget() = 0;
+ };
}
diff --git a/Swift/Controllers/UnitTest/ChatMessageSummarizerTest.cpp b/Swift/Controllers/UnitTest/ChatMessageSummarizerTest.cpp
index 2711034..59c57b9 100644
--- a/Swift/Controllers/UnitTest/ChatMessageSummarizerTest.cpp
+++ b/Swift/Controllers/UnitTest/ChatMessageSummarizerTest.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,115 +7,115 @@
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
-#include "Swift/Controllers/ChatMessageSummarizer.h"
+#include <Swift/Controllers/ChatMessageSummarizer.h>
using namespace Swift;
using namespace std;
class ChatMessageSummarizerTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(ChatMessageSummarizerTest);
- CPPUNIT_TEST(testEmpty);
- CPPUNIT_TEST(testCurrentNone);
- CPPUNIT_TEST(testCurrentCount);
- CPPUNIT_TEST(testCurrentCountOthersNone);
- CPPUNIT_TEST(testCurrentCountOtherCount);
- CPPUNIT_TEST(testCurrentNoneOtherCount);
- CPPUNIT_TEST(testCurrentCountOthersCount);
- CPPUNIT_TEST(testCurrentNoneOthersCount);
- CPPUNIT_TEST(testCurrentCountSomeOthersCount);
- CPPUNIT_TEST_SUITE_END();
+ CPPUNIT_TEST_SUITE(ChatMessageSummarizerTest);
+ CPPUNIT_TEST(testEmpty);
+ CPPUNIT_TEST(testCurrentNone);
+ CPPUNIT_TEST(testCurrentCount);
+ CPPUNIT_TEST(testCurrentCountOthersNone);
+ CPPUNIT_TEST(testCurrentCountOtherCount);
+ CPPUNIT_TEST(testCurrentNoneOtherCount);
+ CPPUNIT_TEST(testCurrentCountOthersCount);
+ CPPUNIT_TEST(testCurrentNoneOthersCount);
+ CPPUNIT_TEST(testCurrentCountSomeOthersCount);
+ CPPUNIT_TEST_SUITE_END();
public:
- ChatMessageSummarizerTest() {}
-
- void setUp() {
-
- }
-
- void testEmpty() {
- string current("");
- vector<UnreadPair> unreads;
- ChatMessageSummarizer summary;
- CPPUNIT_ASSERT_EQUAL(current, summary.getSummary(current, unreads));
- }
-
- void testCurrentNone() {
- string current("Bob");
- vector<UnreadPair> unreads;
- unreads.push_back(UnreadPair("Bob", 0));
- ChatMessageSummarizer summary;
- CPPUNIT_ASSERT_EQUAL(current, summary.getSummary(current, unreads));
- }
-
- void testCurrentCount() {
- string current("Bob");
- vector<UnreadPair> unreads;
- unreads.push_back(UnreadPair("Bob", 3));
- ChatMessageSummarizer summary;
- CPPUNIT_ASSERT_EQUAL(string("Bob (3)"), summary.getSummary(current, unreads));
- }
-
- void testCurrentCountOthersNone() {
- string current("Bob");
- vector<UnreadPair> unreads;
- unreads.push_back(UnreadPair("Bert", 0));
- unreads.push_back(UnreadPair("Bob", 3));
- unreads.push_back(UnreadPair("Betty", 0));
- ChatMessageSummarizer summary;
- CPPUNIT_ASSERT_EQUAL(string("Bob (3)"), summary.getSummary(current, unreads));
- }
-
- void testCurrentCountOtherCount() {
- string current("Bob");
- vector<UnreadPair> unreads;
- unreads.push_back(UnreadPair("Bert", 0));
- unreads.push_back(UnreadPair("Bob", 3));
- unreads.push_back(UnreadPair("Betty", 7));
- ChatMessageSummarizer summary;
- CPPUNIT_ASSERT_EQUAL(string("Bob (3); Betty (7)"), summary.getSummary(current, unreads));
- }
-
- void testCurrentNoneOtherCount() {
- string current("Bob");
- vector<UnreadPair> unreads;
- unreads.push_back(UnreadPair("Bert", 0));
- unreads.push_back(UnreadPair("Bob", 0));
- unreads.push_back(UnreadPair("Betty", 7));
- ChatMessageSummarizer summary;
- CPPUNIT_ASSERT_EQUAL(string("Bob; Betty (7)"), summary.getSummary(current, unreads));
- }
-
- void testCurrentNoneOthersCount() {
- string current("Bob");
- vector<UnreadPair> unreads;
- unreads.push_back(UnreadPair("Bert", 2));
- unreads.push_back(UnreadPair("Bob", 0));
- unreads.push_back(UnreadPair("Betty", 7));
- ChatMessageSummarizer summary;
- CPPUNIT_ASSERT_EQUAL(string("Bob and 2 others (9)"), summary.getSummary(current, unreads));
- }
-
- void testCurrentCountOthersCount() {
- string current("Bob");
- vector<UnreadPair> unreads;
- unreads.push_back(UnreadPair("Bert", 2));
- unreads.push_back(UnreadPair("Bob", 11));
- unreads.push_back(UnreadPair("Betty", 7));
- ChatMessageSummarizer summary;
- CPPUNIT_ASSERT_EQUAL(string("Bob (11) and 2 others (9)"), summary.getSummary(current, unreads));
- }
-
- void testCurrentCountSomeOthersCount() {
- string current("Bob");
- vector<UnreadPair> unreads;
- unreads.push_back(UnreadPair("Bert", 2));
- unreads.push_back(UnreadPair("Beverly", 0));
- unreads.push_back(UnreadPair("Bob", 11));
- unreads.push_back(UnreadPair("Beatrice", 0));
- unreads.push_back(UnreadPair("Betty", 7));
- ChatMessageSummarizer summary;
- CPPUNIT_ASSERT_EQUAL(string("Bob (11) and 2 others (9)"), summary.getSummary(current, unreads));
- }
+ ChatMessageSummarizerTest() {}
+
+ void setUp() {
+
+ }
+
+ void testEmpty() {
+ string current("");
+ vector<UnreadPair> unreads;
+ ChatMessageSummarizer summary;
+ CPPUNIT_ASSERT_EQUAL(current, summary.getSummary(current, unreads));
+ }
+
+ void testCurrentNone() {
+ string current("Bob");
+ vector<UnreadPair> unreads;
+ unreads.push_back(UnreadPair("Bob", 0));
+ ChatMessageSummarizer summary;
+ CPPUNIT_ASSERT_EQUAL(current, summary.getSummary(current, unreads));
+ }
+
+ void testCurrentCount() {
+ string current("Bob");
+ vector<UnreadPair> unreads;
+ unreads.push_back(UnreadPair("Bob", 3));
+ ChatMessageSummarizer summary;
+ CPPUNIT_ASSERT_EQUAL(string("Bob (3)"), summary.getSummary(current, unreads));
+ }
+
+ void testCurrentCountOthersNone() {
+ string current("Bob");
+ vector<UnreadPair> unreads;
+ unreads.push_back(UnreadPair("Bert", 0));
+ unreads.push_back(UnreadPair("Bob", 3));
+ unreads.push_back(UnreadPair("Betty", 0));
+ ChatMessageSummarizer summary;
+ CPPUNIT_ASSERT_EQUAL(string("Bob (3)"), summary.getSummary(current, unreads));
+ }
+
+ void testCurrentCountOtherCount() {
+ string current("Bob");
+ vector<UnreadPair> unreads;
+ unreads.push_back(UnreadPair("Bert", 0));
+ unreads.push_back(UnreadPair("Bob", 3));
+ unreads.push_back(UnreadPair("Betty", 7));
+ ChatMessageSummarizer summary;
+ CPPUNIT_ASSERT_EQUAL(string("Bob (3); Betty (7)"), summary.getSummary(current, unreads));
+ }
+
+ void testCurrentNoneOtherCount() {
+ string current("Bob");
+ vector<UnreadPair> unreads;
+ unreads.push_back(UnreadPair("Bert", 0));
+ unreads.push_back(UnreadPair("Bob", 0));
+ unreads.push_back(UnreadPair("Betty", 7));
+ ChatMessageSummarizer summary;
+ CPPUNIT_ASSERT_EQUAL(string("Bob; Betty (7)"), summary.getSummary(current, unreads));
+ }
+
+ void testCurrentNoneOthersCount() {
+ string current("Bob");
+ vector<UnreadPair> unreads;
+ unreads.push_back(UnreadPair("Bert", 2));
+ unreads.push_back(UnreadPair("Bob", 0));
+ unreads.push_back(UnreadPair("Betty", 7));
+ ChatMessageSummarizer summary;
+ CPPUNIT_ASSERT_EQUAL(string("Bob and 2 others (9)"), summary.getSummary(current, unreads));
+ }
+
+ void testCurrentCountOthersCount() {
+ string current("Bob");
+ vector<UnreadPair> unreads;
+ unreads.push_back(UnreadPair("Bert", 2));
+ unreads.push_back(UnreadPair("Bob", 11));
+ unreads.push_back(UnreadPair("Betty", 7));
+ ChatMessageSummarizer summary;
+ CPPUNIT_ASSERT_EQUAL(string("Bob (11) and 2 others (9)"), summary.getSummary(current, unreads));
+ }
+
+ void testCurrentCountSomeOthersCount() {
+ string current("Bob");
+ vector<UnreadPair> unreads;
+ unreads.push_back(UnreadPair("Bert", 2));
+ unreads.push_back(UnreadPair("Beverly", 0));
+ unreads.push_back(UnreadPair("Bob", 11));
+ unreads.push_back(UnreadPair("Beatrice", 0));
+ unreads.push_back(UnreadPair("Betty", 7));
+ ChatMessageSummarizer summary;
+ CPPUNIT_ASSERT_EQUAL(string("Bob (11) and 2 others (9)"), summary.getSummary(current, unreads));
+ }
};
diff --git a/Swift/Controllers/UnitTest/ContactSuggesterTest.cpp b/Swift/Controllers/UnitTest/ContactSuggesterTest.cpp
index b68fd43..6ac51b2 100644
--- a/Swift/Controllers/UnitTest/ContactSuggesterTest.cpp
+++ b/Swift/Controllers/UnitTest/ContactSuggesterTest.cpp
@@ -1,127 +1,127 @@
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/extensions/TestFactoryRegistry.h>
+#include <memory>
#include <boost/bind.hpp>
#include <boost/function.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-#include <Swiften/Base/foreach.h>
-#include "Swift/Controllers/ContactSuggester.h"
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/extensions/TestFactoryRegistry.h>
+
+#include <Swift/Controllers/ContactSuggester.h>
using namespace Swift;
class ContactSuggesterTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(ContactSuggesterTest);
- CPPUNIT_TEST(equalityTest);
- CPPUNIT_TEST(lexicographicalSortTest);
- CPPUNIT_TEST(sortTest);
- CPPUNIT_TEST_SUITE_END();
+ CPPUNIT_TEST_SUITE(ContactSuggesterTest);
+ CPPUNIT_TEST(equalityTest);
+ CPPUNIT_TEST(lexicographicalSortTest);
+ CPPUNIT_TEST(sortTest);
+ CPPUNIT_TEST_SUITE_END();
public:
- std::vector<std::string> wordList() {
- const std::string words[] = {
- "abc",
- "ab",
- "bc",
- "d"
- };
-
- return std::vector<std::string>(words, words+sizeof(words)/sizeof(*words));
- }
-
- std::vector<StatusShow::Type> statusList() {
- StatusShow::Type types[] = {
- StatusShow::Online,
- StatusShow::Away,
- StatusShow::FFC,
- StatusShow::XA,
- StatusShow::DND,
- StatusShow::None
- };
-
- return std::vector<StatusShow::Type>(types, types+sizeof(types)/sizeof(*types));
- }
-
- std::vector<Contact::ref> contactList() {
- std::vector<Contact::ref> contacts;
- std::vector<std::string> words = wordList();
- std::vector<StatusShow::Type> statuses = statusList();
- foreach (const std::string& name, words) {
- foreach (const std::string& jid, words) {
- foreach (const StatusShow::Type& status, statuses) {
- contacts.push_back(boost::make_shared<Contact>(name, jid, status, ""));
- }
- }
- }
- return contacts;
- }
-
- /* a = a */
- bool isReflexive(const boost::function<bool (const Contact::ref&, const Contact::ref&)>& comparitor) {
- std::vector<Contact::ref> contacts = contactList();
- foreach (const Contact::ref& a, contacts) {
- if (!comparitor(a, a)) {
- return false;
- }
- }
- return true;
- }
-
- /* a = b -> b = a */
- bool isSymmetric(const boost::function<bool (const Contact::ref&, const Contact::ref&)>& comparitor) {
- std::vector<Contact::ref> contacts = contactList();
- foreach (const Contact::ref& a, contacts) {
- foreach (const Contact::ref& b, contacts) {
- if (comparitor(a, b)) {
- if (!comparitor(b, a)) {
- return false;
- }
- }
- }
- }
- return true;
- }
-
- /* a = b && b = c -> a = c */
- bool isTransitive(const boost::function<bool (const Contact::ref&, const Contact::ref&)>& comparitor) {
- std::vector<Contact::ref> contacts = contactList();
- foreach (const Contact::ref& a, contacts) {
- foreach (const Contact::ref& b, contacts) {
- foreach (const Contact::ref& c, contacts) {
- if (comparitor(a, b) && comparitor(b, c)) {
- if (!comparitor(a, c)) {
- return false;
- }
- }
- }
- }
- }
- return true;
- }
-
- void equalityTest() {
- CPPUNIT_ASSERT(isReflexive(Contact::equalityPredicate));
- CPPUNIT_ASSERT(isSymmetric(Contact::equalityPredicate));
- CPPUNIT_ASSERT(isTransitive(Contact::equalityPredicate));
- }
-
- void lexicographicalSortTest() {
- CPPUNIT_ASSERT(isTransitive(Contact::lexicographicalSortPredicate));
- }
-
- void sortTest() {
- std::vector<std::string> words = wordList();
- foreach (const std::string& word, words) {
- CPPUNIT_ASSERT(isTransitive(boost::bind(Contact::sortPredicate, _1, _2, word)));
- }
- }
+ std::vector<std::string> wordList() {
+ const std::string words[] = {
+ "abc",
+ "ab",
+ "bc",
+ "d"
+ };
+
+ return std::vector<std::string>(words, words+sizeof(words)/sizeof(*words));
+ }
+
+ std::vector<StatusShow::Type> statusList() {
+ StatusShow::Type types[] = {
+ StatusShow::Online,
+ StatusShow::Away,
+ StatusShow::FFC,
+ StatusShow::XA,
+ StatusShow::DND,
+ StatusShow::None
+ };
+
+ return std::vector<StatusShow::Type>(types, types+sizeof(types)/sizeof(*types));
+ }
+
+ std::vector<Contact::ref> contactList() {
+ std::vector<Contact::ref> contacts;
+ std::vector<std::string> words = wordList();
+ std::vector<StatusShow::Type> statuses = statusList();
+ for (const auto& name : words) {
+ for (const auto& jid : words) {
+ for (const auto& status : statuses) {
+ contacts.push_back(std::make_shared<Contact>(name, jid, status, ""));
+ }
+ }
+ }
+ return contacts;
+ }
+
+ /* a = a */
+ bool isReflexive(const boost::function<bool (const Contact::ref&, const Contact::ref&)>& comparitor) {
+ std::vector<Contact::ref> contacts = contactList();
+ for (const auto& a : contacts) {
+ if (!comparitor(a, a)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /* a = b -> b = a */
+ bool isSymmetric(const boost::function<bool (const Contact::ref&, const Contact::ref&)>& comparitor) {
+ std::vector<Contact::ref> contacts = contactList();
+ for (const auto& a : contacts) {
+ for (const auto& b : contacts) {
+ if (comparitor(a, b)) {
+ if (!comparitor(b, a)) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ /* a = b && b = c -> a = c */
+ bool isTransitive(const boost::function<bool (const Contact::ref&, const Contact::ref&)>& comparitor) {
+ std::vector<Contact::ref> contacts = contactList();
+ for (const auto& a : contacts) {
+ for (const auto& b : contacts) {
+ for (const auto& c : contacts) {
+ if (comparitor(a, b) && comparitor(b, c)) {
+ if (!comparitor(a, c)) {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ void equalityTest() {
+ CPPUNIT_ASSERT(isReflexive(Contact::equalityPredicate));
+ CPPUNIT_ASSERT(isSymmetric(Contact::equalityPredicate));
+ CPPUNIT_ASSERT(isTransitive(Contact::equalityPredicate));
+ }
+
+ void lexicographicalSortTest() {
+ CPPUNIT_ASSERT(isTransitive(Contact::lexicographicalSortPredicate));
+ }
+
+ void sortTest() {
+ std::vector<std::string> words = wordList();
+ for (const auto& word : words) {
+ CPPUNIT_ASSERT(isTransitive(boost::bind(Contact::sortPredicate, _1, _2, word)));
+ }
+ }
};
diff --git a/Swift/Controllers/UnitTest/HighlightRuleTest.cpp b/Swift/Controllers/UnitTest/HighlightRuleTest.cpp
index 707524c..8d49d5d 100644
--- a/Swift/Controllers/UnitTest/HighlightRuleTest.cpp
+++ b/Swift/Controllers/UnitTest/HighlightRuleTest.cpp
@@ -5,13 +5,13 @@
*/
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include <vector>
#include <string>
+#include <vector>
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
@@ -21,304 +21,304 @@
using namespace Swift;
class HighlightRuleTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(HighlightRuleTest);
- CPPUNIT_TEST(testEmptyRuleNeverMatches);
- CPPUNIT_TEST(testKeyword);
- CPPUNIT_TEST(testNickKeyword);
- CPPUNIT_TEST(testNickWithoutOtherKeywords);
- CPPUNIT_TEST(testSender);
- CPPUNIT_TEST(testSenderAndKeyword);
- CPPUNIT_TEST(testWholeWords);
- CPPUNIT_TEST(testCase);
- CPPUNIT_TEST(testWholeWordsAndCase);
- CPPUNIT_TEST(testMUC);
- CPPUNIT_TEST_SUITE_END();
-
- public:
- void setUp() {
- std::vector<std::string> keywords;
- keywords.push_back("keyword1");
- keywords.push_back("KEYWORD2");
-
- std::vector<std::string> senders;
- senders.push_back("sender1");
- senders.push_back("SENDER2");
-
- emptyRule = new HighlightRule();
-
- keywordRule = new HighlightRule();
- keywordRule->setKeywords(keywords);
-
- keywordChatRule = new HighlightRule();
- keywordChatRule->setKeywords(keywords);
- keywordChatRule->setMatchChat(true);
-
- keywordNickChatRule = new HighlightRule();
- keywordNickChatRule->setKeywords(keywords);
- keywordNickChatRule->setNickIsKeyword(true);
- keywordNickChatRule->setMatchChat(true);
-
- nickChatRule = new HighlightRule();
- nickChatRule->setNickIsKeyword(true);
- nickChatRule->setMatchChat(true);
-
- nickRule = new HighlightRule();
- nickRule->setNickIsKeyword(true);
-
- senderRule = new HighlightRule();
- senderRule->setSenders(senders);
-
- senderChatRule = new HighlightRule();
- senderChatRule->setSenders(senders);
- senderChatRule->setMatchChat(true);
-
- senderKeywordChatRule = new HighlightRule();
- senderKeywordChatRule->setSenders(senders);
- senderKeywordChatRule->setKeywords(keywords);
- senderKeywordChatRule->setMatchChat(true);
-
- senderKeywordNickChatRule = new HighlightRule();
- senderKeywordNickChatRule->setSenders(senders);
- senderKeywordNickChatRule->setKeywords(keywords);
- senderKeywordNickChatRule->setNickIsKeyword(true);
- senderKeywordNickChatRule->setMatchChat(true);
-
- senderKeywordNickWordChatRule = new HighlightRule();
- senderKeywordNickWordChatRule->setSenders(senders);
- senderKeywordNickWordChatRule->setKeywords(keywords);
- senderKeywordNickWordChatRule->setNickIsKeyword(true);
- senderKeywordNickWordChatRule->setMatchWholeWords(true);
- senderKeywordNickWordChatRule->setMatchChat(true);
-
- senderKeywordNickCaseChatRule = new HighlightRule();
- senderKeywordNickCaseChatRule->setSenders(senders);
- senderKeywordNickCaseChatRule->setKeywords(keywords);
- senderKeywordNickCaseChatRule->setNickIsKeyword(true);
- senderKeywordNickCaseChatRule->setMatchCase(true);
- senderKeywordNickCaseChatRule->setMatchChat(true);
-
- senderKeywordNickCaseWordChatRule = new HighlightRule();
- senderKeywordNickCaseWordChatRule->setSenders(senders);
- senderKeywordNickCaseWordChatRule->setKeywords(keywords);
- senderKeywordNickCaseWordChatRule->setNickIsKeyword(true);
- senderKeywordNickCaseWordChatRule->setMatchCase(true);
- senderKeywordNickCaseWordChatRule->setMatchWholeWords(true);
- senderKeywordNickCaseWordChatRule->setMatchChat(true);
-
- senderKeywordNickMUCRule = new HighlightRule();
- senderKeywordNickMUCRule->setSenders(senders);
- senderKeywordNickMUCRule->setKeywords(keywords);
- senderKeywordNickMUCRule->setNickIsKeyword(true);
- senderKeywordNickMUCRule->setMatchMUC(true);
- }
+ CPPUNIT_TEST_SUITE(HighlightRuleTest);
+ CPPUNIT_TEST(testEmptyRuleNeverMatches);
+ CPPUNIT_TEST(testKeyword);
+ CPPUNIT_TEST(testNickKeyword);
+ CPPUNIT_TEST(testNickWithoutOtherKeywords);
+ CPPUNIT_TEST(testSender);
+ CPPUNIT_TEST(testSenderAndKeyword);
+ CPPUNIT_TEST(testWholeWords);
+ CPPUNIT_TEST(testCase);
+ CPPUNIT_TEST(testWholeWordsAndCase);
+ CPPUNIT_TEST(testMUC);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp() {
+ std::vector<std::string> keywords;
+ keywords.push_back("keyword1");
+ keywords.push_back("KEYWORD2");
+
+ std::vector<std::string> senders;
+ senders.push_back("sender1");
+ senders.push_back("SENDER2");
+
+ emptyRule = new HighlightRule();
+
+ keywordRule = new HighlightRule();
+ keywordRule->setKeywords(keywords);
+
+ keywordChatRule = new HighlightRule();
+ keywordChatRule->setKeywords(keywords);
+ keywordChatRule->setMatchChat(true);
+
+ keywordNickChatRule = new HighlightRule();
+ keywordNickChatRule->setKeywords(keywords);
+ keywordNickChatRule->setNickIsKeyword(true);
+ keywordNickChatRule->setMatchChat(true);
+
+ nickChatRule = new HighlightRule();
+ nickChatRule->setNickIsKeyword(true);
+ nickChatRule->setMatchChat(true);
+
+ nickRule = new HighlightRule();
+ nickRule->setNickIsKeyword(true);
+
+ senderRule = new HighlightRule();
+ senderRule->setSenders(senders);
+
+ senderChatRule = new HighlightRule();
+ senderChatRule->setSenders(senders);
+ senderChatRule->setMatchChat(true);
+
+ senderKeywordChatRule = new HighlightRule();
+ senderKeywordChatRule->setSenders(senders);
+ senderKeywordChatRule->setKeywords(keywords);
+ senderKeywordChatRule->setMatchChat(true);
+
+ senderKeywordNickChatRule = new HighlightRule();
+ senderKeywordNickChatRule->setSenders(senders);
+ senderKeywordNickChatRule->setKeywords(keywords);
+ senderKeywordNickChatRule->setNickIsKeyword(true);
+ senderKeywordNickChatRule->setMatchChat(true);
+
+ senderKeywordNickWordChatRule = new HighlightRule();
+ senderKeywordNickWordChatRule->setSenders(senders);
+ senderKeywordNickWordChatRule->setKeywords(keywords);
+ senderKeywordNickWordChatRule->setNickIsKeyword(true);
+ senderKeywordNickWordChatRule->setMatchWholeWords(true);
+ senderKeywordNickWordChatRule->setMatchChat(true);
+
+ senderKeywordNickCaseChatRule = new HighlightRule();
+ senderKeywordNickCaseChatRule->setSenders(senders);
+ senderKeywordNickCaseChatRule->setKeywords(keywords);
+ senderKeywordNickCaseChatRule->setNickIsKeyword(true);
+ senderKeywordNickCaseChatRule->setMatchCase(true);
+ senderKeywordNickCaseChatRule->setMatchChat(true);
+
+ senderKeywordNickCaseWordChatRule = new HighlightRule();
+ senderKeywordNickCaseWordChatRule->setSenders(senders);
+ senderKeywordNickCaseWordChatRule->setKeywords(keywords);
+ senderKeywordNickCaseWordChatRule->setNickIsKeyword(true);
+ senderKeywordNickCaseWordChatRule->setMatchCase(true);
+ senderKeywordNickCaseWordChatRule->setMatchWholeWords(true);
+ senderKeywordNickCaseWordChatRule->setMatchChat(true);
+
+ senderKeywordNickMUCRule = new HighlightRule();
+ senderKeywordNickMUCRule->setSenders(senders);
+ senderKeywordNickMUCRule->setKeywords(keywords);
+ senderKeywordNickMUCRule->setNickIsKeyword(true);
+ senderKeywordNickMUCRule->setMatchMUC(true);
+ }
- void tearDown() {
- delete emptyRule;
+ void tearDown() {
+ delete emptyRule;
- delete keywordRule;
- delete keywordChatRule;
- delete keywordNickChatRule;
- delete nickChatRule;
- delete nickRule;
-
- delete senderRule;
- delete senderChatRule;
- delete senderKeywordChatRule;
- delete senderKeywordNickChatRule;
+ delete keywordRule;
+ delete keywordChatRule;
+ delete keywordNickChatRule;
+ delete nickChatRule;
+ delete nickRule;
+
+ delete senderRule;
+ delete senderChatRule;
+ delete senderKeywordChatRule;
+ delete senderKeywordNickChatRule;
- delete senderKeywordNickWordChatRule;
- delete senderKeywordNickCaseChatRule;
- delete senderKeywordNickCaseWordChatRule;
+ delete senderKeywordNickWordChatRule;
+ delete senderKeywordNickCaseChatRule;
+ delete senderKeywordNickCaseWordChatRule;
- delete senderKeywordNickMUCRule;
- }
+ delete senderKeywordNickMUCRule;
+ }
- void testEmptyRuleNeverMatches() {
- CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "from", "nick", HighlightRule::MUCMessage), false);
+ void testEmptyRuleNeverMatches() {
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "from", "nick", HighlightRule::MUCMessage), false);
- CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "from", "", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "from", "", HighlightRule::MUCMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "from", "", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "from", "", HighlightRule::MUCMessage), false);
- CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "", "nick", HighlightRule::MUCMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "", "nick", HighlightRule::MUCMessage), false);
- CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "from", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "from", "nick", HighlightRule::MUCMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "from", "nick", HighlightRule::MUCMessage), false);
- CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "", "", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "", "", HighlightRule::MUCMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "", "", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("body", "", "", HighlightRule::MUCMessage), false);
- CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "from", "", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "from", "", HighlightRule::MUCMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "from", "", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "from", "", HighlightRule::MUCMessage), false);
- CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "", "nick", HighlightRule::MUCMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "", "nick", HighlightRule::MUCMessage), false);
- CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "", "", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "", "", HighlightRule::MUCMessage), false);
- }
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "", "", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(emptyRule->isMatch("", "", "", HighlightRule::MUCMessage), false);
+ }
- void testKeyword() {
- CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("body", "from", "nick", HighlightRule::MUCMessage), false);
+ void testKeyword() {
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("body", "from", "nick", HighlightRule::MUCMessage), false);
- CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("keyword1", "from", "nick", HighlightRule::MUCMessage), false);
- CPPUNIT_ASSERT_EQUAL(keywordRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("keyword1", "from", "nick", HighlightRule::MUCMessage), false);
+ CPPUNIT_ASSERT_EQUAL(keywordRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("body", "sender contains keyword1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("body", "sender contains keyword1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("abc keyword1 xyz", "from", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("abckeyword1xyz", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("abc keyword1 xyz", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("abckeyword1xyz", "from", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("KEYword1", "from", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("abc KEYword1 xyz", "from", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("abcKEYword1xyz", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("KEYword1", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("abc KEYword1 xyz", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("abcKEYword1xyz", "from", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("keyword2", "from", "nick", HighlightRule::ChatMessage), true);
- }
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("keyword2", "from", "nick", HighlightRule::ChatMessage), true);
+ }
- void testNickKeyword() {
- CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("body contains nick", "from", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("body contains nick", "from", "nick", HighlightRule::MUCMessage), false);
- CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("body contains nick", "from", "nick", HighlightRule::ChatMessage), false);
+ void testNickKeyword() {
+ CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("body contains nick", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("body contains nick", "from", "nick", HighlightRule::MUCMessage), false);
+ CPPUNIT_ASSERT_EQUAL(keywordChatRule->isMatch("body contains nick", "from", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("body", "sender contains nick", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("body", "sender contains nick", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("body contains mixed-case NiCk", "sender", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("body contains mixed-case NiCk", "sender", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("nickname", "from", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("NIckNAME", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("nickname", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("NIckNAME", "from", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("body", "from", "", HighlightRule::ChatMessage), false);
- }
+ CPPUNIT_ASSERT_EQUAL(keywordNickChatRule->isMatch("body", "from", "", HighlightRule::ChatMessage), false);
+ }
- void testNickWithoutOtherKeywords() {
- CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("body contains nick", "from", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("body contains nick", "from", "nick", HighlightRule::MUCMessage), false);
- CPPUNIT_ASSERT_EQUAL(nickRule->isMatch("body contains nick", "from", "nick", HighlightRule::ChatMessage), false);
+ void testNickWithoutOtherKeywords() {
+ CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("body contains nick", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("body contains nick", "from", "nick", HighlightRule::MUCMessage), false);
+ CPPUNIT_ASSERT_EQUAL(nickRule->isMatch("body contains nick", "from", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("body", "sender contains nick but it does't matter", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("body", "sender contains nick but it does't matter", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("body contains mixed-case NiCk", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("body contains mixed-case NiCk", "from", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("nickname", "from", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("NIckNAME", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("nickname", "from", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("NIckNAME", "from", "nick", HighlightRule::ChatMessage), true);
- // there are no keywords in this rule and empty nick is not treated as a keyword, so we don't check for keywords to get a match
- CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("body", "from", "", HighlightRule::ChatMessage), true);
- }
+ // there are no keywords in this rule and empty nick is not treated as a keyword, so we don't check for keywords to get a match
+ CPPUNIT_ASSERT_EQUAL(nickChatRule->isMatch("body", "from", "", HighlightRule::ChatMessage), true);
+ }
- void testSender() {
- CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "from", "nick", HighlightRule::MUCMessage), false);
+ void testSender() {
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "from", "nick", HighlightRule::MUCMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "sender1", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "sender1", "nick", HighlightRule::MUCMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderRule->isMatch("body", "sender1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "sender1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "sender1", "nick", HighlightRule::MUCMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderRule->isMatch("body", "sender1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderRule->isMatch("body contains sender1", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderRule->isMatch("body contains sender1", "from", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "abc sender1 xyz", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "abcsender1xyz", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "abc sender1 xyz", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "abcsender1xyz", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "SENDer1", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "abc SENDer1 xyz", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "abcSENDer1xyz", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "SENDer1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "abc SENDer1 xyz", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "abcSENDer1xyz", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "sender2", "nick", HighlightRule::ChatMessage), true);
- }
+ CPPUNIT_ASSERT_EQUAL(senderChatRule->isMatch("body", "sender2", "nick", HighlightRule::ChatMessage), true);
+ }
- void testSenderAndKeyword() {
- CPPUNIT_ASSERT_EQUAL(senderKeywordChatRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordChatRule->isMatch("body", "sender1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordChatRule->isMatch("keyword1", "sender1", "nick", HighlightRule::ChatMessage), true);
- }
+ void testSenderAndKeyword() {
+ CPPUNIT_ASSERT_EQUAL(senderKeywordChatRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordChatRule->isMatch("body", "sender1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordChatRule->isMatch("keyword1", "sender1", "nick", HighlightRule::ChatMessage), true);
+ }
- void testWholeWords() {
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("body", "sender1", "nick", HighlightRule::ChatMessage), false);
+ void testWholeWords() {
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("body", "sender1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("keyword1", "sender1", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("xkeyword1", "sender1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("keyword1", "xsender1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("keyword1", "sender1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("xkeyword1", "sender1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("keyword1", "xsender1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("body contains nick", "sender1", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("body contains xnick", "sender1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("body contains nick", "sender1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("body contains xnick", "sender1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("KEYword1", "SENDer1", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("body contains NiCk", "sender1", "nick", HighlightRule::ChatMessage), true);
- }
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("KEYword1", "SENDer1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickWordChatRule->isMatch("body contains NiCk", "sender1", "nick", HighlightRule::ChatMessage), true);
+ }
- void testCase() {
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("body", "sender1", "nick", HighlightRule::ChatMessage), false);
+ void testCase() {
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("body", "sender1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("keyword1", "sender1", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("xkeyword1", "xsender1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("keyword1", "sender1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("xkeyword1", "xsender1", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("body contains nick", "sender1", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("body contains xnick", "sender1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("body contains nick", "sender1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("body contains xnick", "sender1", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("KEYword1", "SENDer1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("keyword1", "SENDer1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("KEYword1", "sender1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("body contains NiCk", "sender1", "nick", HighlightRule::ChatMessage), false);
- }
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("KEYword1", "SENDer1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("keyword1", "SENDer1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("KEYword1", "sender1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseChatRule->isMatch("body contains NiCk", "sender1", "nick", HighlightRule::ChatMessage), false);
+ }
- void testWholeWordsAndCase() {
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("body", "sender1", "nick", HighlightRule::ChatMessage), false);
+ void testWholeWordsAndCase() {
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("keyword1", "from", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("body", "sender1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("keyword1", "sender1", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("xkeyword1", "sender1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("keyword1", "xsender1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("keyword1", "sender1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("xkeyword1", "sender1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("keyword1", "xsender1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("body contains nick", "sender1", "nick", HighlightRule::ChatMessage), true);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("body contains xnick", "sender1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("body contains nick", "sender1", "nick", HighlightRule::ChatMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("body contains xnick", "sender1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("KEYword1", "SENDer1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("keyword1", "SENDer1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("KEYword1", "sender1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("body contains NiCk", "sender1", "nick", HighlightRule::ChatMessage), false);
- }
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("KEYword1", "SENDer1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("keyword1", "SENDer1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("KEYword1", "sender1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickCaseWordChatRule->isMatch("body contains NiCk", "sender1", "nick", HighlightRule::ChatMessage), false);
+ }
- void testMUC() {
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickMUCRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
+ void testMUC() {
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickMUCRule->isMatch("body", "from", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickMUCRule->isMatch("keyword1", "sender1", "nick", HighlightRule::ChatMessage), false);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickMUCRule->isMatch("keyword1", "sender1", "nick", HighlightRule::MUCMessage), true);
- CPPUNIT_ASSERT_EQUAL(senderKeywordNickMUCRule->isMatch("body contains nick", "sender1", "nick", HighlightRule::MUCMessage), true);
- }
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickMUCRule->isMatch("keyword1", "sender1", "nick", HighlightRule::ChatMessage), false);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickMUCRule->isMatch("keyword1", "sender1", "nick", HighlightRule::MUCMessage), true);
+ CPPUNIT_ASSERT_EQUAL(senderKeywordNickMUCRule->isMatch("body contains nick", "sender1", "nick", HighlightRule::MUCMessage), true);
+ }
- private:
- HighlightRule* emptyRule;
+ private:
+ HighlightRule* emptyRule;
- HighlightRule* keywordRule;
- HighlightRule* keywordChatRule;
- HighlightRule* keywordNickChatRule;
- HighlightRule* nickChatRule;
- HighlightRule* nickRule;
+ HighlightRule* keywordRule;
+ HighlightRule* keywordChatRule;
+ HighlightRule* keywordNickChatRule;
+ HighlightRule* nickChatRule;
+ HighlightRule* nickRule;
- HighlightRule* senderRule;
- HighlightRule* senderChatRule;
- HighlightRule* senderKeywordChatRule;
- HighlightRule* senderKeywordNickChatRule;
+ HighlightRule* senderRule;
+ HighlightRule* senderChatRule;
+ HighlightRule* senderKeywordChatRule;
+ HighlightRule* senderKeywordNickChatRule;
- HighlightRule* senderKeywordNickWordChatRule;
- HighlightRule* senderKeywordNickCaseChatRule;
- HighlightRule* senderKeywordNickCaseWordChatRule;
+ HighlightRule* senderKeywordNickWordChatRule;
+ HighlightRule* senderKeywordNickCaseChatRule;
+ HighlightRule* senderKeywordNickCaseWordChatRule;
- HighlightRule* senderKeywordNickMUCRule;
+ HighlightRule* senderKeywordNickMUCRule;
};
CPPUNIT_TEST_SUITE_REGISTRATION(HighlightRuleTest);
diff --git a/Swift/Controllers/UnitTest/MockChatWindow.cpp b/Swift/Controllers/UnitTest/MockChatWindow.cpp
index d97d903..f0f666a 100644
--- a/Swift/Controllers/UnitTest/MockChatWindow.cpp
+++ b/Swift/Controllers/UnitTest/MockChatWindow.cpp
@@ -1,10 +1,10 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/Controllers/UnitTest/MockChatWindow.h"
+#include <Swift/Controllers/UnitTest/MockChatWindow.h>
namespace Swift {
MockChatWindow::~MockChatWindow() {
diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h
index dddea6c..76e5194 100644
--- a/Swift/Controllers/UnitTest/MockChatWindow.h
+++ b/Swift/Controllers/UnitTest/MockChatWindow.h
@@ -6,110 +6,149 @@
#pragma once
-#include <boost/shared_ptr.hpp>
-
-#include <Swiften/Base/foreach.h>
+#include <memory>
+#include <string>
#include <Swift/Controllers/UIInterfaces/ChatWindow.h>
namespace Swift {
- class MockChatWindow : public ChatWindow {
- public:
- MockChatWindow() : labelsEnabled_(false), impromptuMUCSupported_(false) {}
- virtual ~MockChatWindow();
-
- virtual std::string addMessage(const ChatMessage& message, const std::string& /*senderName*/, bool /*senderIsSelf*/, boost::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime& /*time*/, const HighlightAction& /*highlight*/) {
- lastMessageBody_ = bodyFromMessage(message);
- return "id";
- }
-
- virtual std::string addAction(const ChatMessage& /*message*/, const std::string& /*senderName*/, bool /*senderIsSelf*/, boost::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime& /*time*/, const HighlightAction& /*highlight*/) {return "id";}
-
- virtual std::string addSystemMessage(const ChatMessage& message, Direction /*direction*/) {
- lastAddedSystemMessage_ = message;
- return "id";
- }
-
- virtual void addPresenceMessage(const ChatMessage& message, Direction /*direction*/) {
- lastAddedPresence_ = message;
- }
-
- virtual void addErrorMessage(const ChatMessage& /*message*/) {}
- virtual void replaceMessage(const ChatMessage& /*message*/, const std::string& /*id*/, const boost::posix_time::ptime& /*time*/, const HighlightAction& /*highlight*/) {}
- virtual void replaceWithAction(const ChatMessage& /*message*/, const std::string& /*id*/, const boost::posix_time::ptime& /*time*/, const HighlightAction& /*highlight*/) {}
- virtual void replaceLastMessage(const ChatMessage& message, const TimestampBehaviour /*timestampBehaviour*/) {
- lastReplacedMessage_ = message;
- }
- virtual void replaceSystemMessage(const ChatMessage& /*message*/, const std::string& /*id*/, const TimestampBehaviour /*timestampBehaviour*/) {}
-
- // File transfer related stuff
- virtual std::string addFileTransfer(const std::string& /*senderName*/, bool /*senderIsSelf*/,const std::string& /*filename*/, const boost::uintmax_t /*sizeInBytes*/, const std::string& /*description*/) { return 0; }
- virtual void setFileTransferProgress(std::string /*id*/, const int /*alreadyTransferedBytes*/) { }
- virtual void setFileTransferStatus(std::string /*id*/, const FileTransferState /*state*/, const std::string& /*msg*/) { }
-
- virtual void setMessageReceiptState(const std::string &/* id */, ReceiptState /* state */) { }
-
- virtual void setContactChatState(ChatState::ChatStateType /*state*/) {}
- virtual void setName(const std::string& name) {name_ = name;}
- virtual void show() {}
- virtual bool isVisible() const { return true; }
- virtual void activate() {}
- virtual void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels) {labels_ = labels;}
- virtual void setSecurityLabelsEnabled(bool enabled) {labelsEnabled_ = enabled;}
- virtual void setUnreadMessageCount(int /*count*/) {}
- virtual void convertToMUC(MUCType /*mucType*/) {}
- virtual void setSecurityLabelsError() {}
- virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() {return label_;}
- virtual void setOnline(bool /*online*/) {}
- virtual void setRosterModel(Roster* roster) { roster_ = roster; }
- Roster* getRosterModel() { return roster_; }
- virtual void setTabComplete(TabComplete*) {}
-
- void setAckState(const std::string& /*id*/, AckState /*state*/) {}
- virtual void flash() {}
- virtual AlertID addAlert(const std::string& /*alertText*/) { return 0; }
- virtual void removeAlert(const AlertID /*id*/) {}
- virtual void setCorrectionEnabled(Tristate /*enabled*/) {}
- virtual void setFileTransferEnabled(Tristate /*enabled*/) {}
- void setAvailableOccupantActions(const std::vector<OccupantAction>&/* actions*/) {}
- void setSubject(const std::string& /*subject*/) {}
- virtual void showRoomConfigurationForm(Form::ref) {}
- virtual void addMUCInvitation(const std::string& /*senderName*/, const JID& /*jid*/, const std::string& /*reason*/, const std::string& /*password*/, bool = true, bool = false, bool = false) {}
-
- virtual std::string addWhiteboardRequest(bool) {return "";}
- virtual void setWhiteboardSessionStatus(std::string, const ChatWindow::WhiteboardSessionState){}
-
- virtual void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>&) {}
- virtual void setAvailableRoomActions(const std::vector<RoomAction> &) {}
-
- virtual void setBlockingState(BlockingState) {}
- virtual void setCanInitiateImpromptuChats(bool supportsImpromptu) {
- impromptuMUCSupported_ = supportsImpromptu;
- }
-
- virtual void showBookmarkWindow(const MUCBookmark& /*bookmark*/) {}
- virtual void setBookmarkState(RoomBookmarkState) {}
-
- static std::string bodyFromMessage(const ChatMessage& message) {
- boost::shared_ptr<ChatTextMessagePart> text;
- foreach (boost::shared_ptr<ChatMessagePart> part, message.getParts()) {
- if ((text = boost::dynamic_pointer_cast<ChatTextMessagePart>(part))) {
- return text->text;
- }
- }
- return "";
- }
-
- std::string name_;
- std::string lastMessageBody_;
- ChatMessage lastAddedPresence_;
- ChatMessage lastReplacedMessage_;
- ChatMessage lastAddedSystemMessage_;
- std::vector<SecurityLabelsCatalog::Item> labels_;
- bool labelsEnabled_;
- bool impromptuMUCSupported_;
- SecurityLabelsCatalog::Item label_;
- Roster* roster_;
- };
+ class MockChatWindow : public ChatWindow {
+ public:
+ MockChatWindow() {}
+ virtual ~MockChatWindow();
+
+ virtual std::string addMessage(const ChatMessage& message, const std::string& senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime& /*time*/) {
+ lastAddedMessage_ = message;
+ lastAddedMessageSenderName_ = senderName;
+ lastAddedMessageSenderIsSelf_ = senderIsSelf;
+ return "id";
+ }
+
+ virtual std::string addAction(const ChatMessage& message, const std::string& senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime& /*time*/) {
+ lastAddedAction_ = message;
+ lastAddedActionSenderName_ = senderName;
+ lastAddedActionSenderIsSelf_ = senderIsSelf;
+ return "id";
+ }
+
+ virtual std::string addSystemMessage(const ChatMessage& message, Direction /*direction*/) {
+ lastAddedSystemMessage_ = message;
+ return "id";
+ }
+
+ virtual void addPresenceMessage(const ChatMessage& message, Direction /*direction*/) {
+ lastAddedPresence_ = message;
+ }
+
+ virtual void addErrorMessage(const ChatMessage& message) {
+ lastAddedErrorMessage_ = message;
+ }
+ virtual void replaceMessage(const ChatMessage& /*message*/, const std::string& /*id*/, const boost::posix_time::ptime& /*time*/) {}
+ virtual void replaceWithAction(const ChatMessage& /*message*/, const std::string& /*id*/, const boost::posix_time::ptime& /*time*/) {}
+ virtual void replaceLastMessage(const ChatMessage& message, const TimestampBehaviour /*timestampBehaviour*/) {
+ lastReplacedMessage_ = message;
+ }
+ virtual void replaceSystemMessage(const ChatMessage& message, const std::string& /*id*/, const TimestampBehaviour /*timestampBehaviour*/) {
+ lastReplacedSystemMessage_ = message;
+ }
+
+ // File transfer related stuff
+ virtual std::string addFileTransfer(const std::string& /*senderName*/, bool /*senderIsSelf*/,const std::string& /*filename*/, const boost::uintmax_t /*sizeInBytes*/, const std::string& /*description*/) { return nullptr; }
+ virtual void setFileTransferProgress(std::string /*id*/, const int /*alreadyTransferedBytes*/) { }
+ virtual void setFileTransferStatus(std::string /*id*/, const FileTransferState /*state*/, const std::string& /*msg*/) { }
+
+ virtual void setMessageReceiptState(const std::string & id, ReceiptState state) {
+ receiptChanges_.emplace_back(id, state);
+ }
+
+ virtual void setContactChatState(ChatState::ChatStateType /*state*/) {}
+ virtual void setName(const std::string& name) {name_ = name;}
+ virtual void show() {}
+ virtual bool isVisible() const { return true; }
+ virtual void activate() {}
+ virtual void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels) {labels_ = labels;}
+ virtual void setSecurityLabelsEnabled(bool enabled) {labelsEnabled_ = enabled;}
+ virtual void setUnreadMessageCount(int /*count*/) {}
+
+ virtual void convertToMUC(MUCType mucType) {
+ mucType_ = mucType;
+ }
+
+ virtual void setSecurityLabelsError() {}
+ virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() {return label_;}
+ virtual void setOnline(bool /*online*/) {}
+ virtual void setRosterModel(Roster* roster) { roster_ = roster; }
+ Roster* getRosterModel() { return roster_; }
+ virtual void setTabComplete(TabComplete*) {}
+
+ void setAckState(const std::string& /*id*/, AckState /*state*/) {}
+ virtual void flash() {}
+ virtual AlertID addAlert(const std::string& /*alertText*/) { return 0; }
+ virtual void removeAlert(const AlertID /*id*/) {}
+ virtual void setCorrectionEnabled(Tristate /*enabled*/) {}
+ virtual void setFileTransferEnabled(Tristate /*enabled*/) {}
+ void setAvailableOccupantActions(const std::vector<OccupantAction>&/* actions*/) {}
+ void setSubject(const std::string& /*subject*/) {}
+ virtual void showRoomConfigurationForm(Form::ref) {}
+ virtual void addMUCInvitation(const std::string& /*senderName*/, const JID& jid, const std::string& /*reason*/, const std::string& /*password*/, bool = true, bool = false, bool = false) {
+ lastMUCInvitationJID_ = jid;
+ }
+
+ virtual std::string addWhiteboardRequest(bool) {return "";}
+ virtual void setWhiteboardSessionStatus(std::string, const ChatWindow::WhiteboardSessionState){}
+
+ virtual void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>&) {}
+ virtual void setAvailableRoomActions(const std::vector<RoomAction> &) {}
+
+ virtual void setBlockingState(BlockingState) {}
+ virtual void setCanInitiateImpromptuChats(bool supportsImpromptu) {
+ impromptuMUCSupported_ = supportsImpromptu;
+ }
+
+ virtual void showBookmarkWindow(const MUCBookmark& /*bookmark*/) {}
+ virtual void setBookmarkState(RoomBookmarkState) {}
+
+ static std::string bodyFromMessage(const ChatMessage& message) {
+ std::string body;
+ std::shared_ptr<ChatTextMessagePart> text;
+ std::shared_ptr<ChatHighlightingMessagePart> highlight;
+ for (auto &&part : message.getParts()) {
+ if ((text = std::dynamic_pointer_cast<ChatTextMessagePart>(part))) {
+ body += text->text;
+ }
+ else if ((highlight = std::dynamic_pointer_cast<ChatHighlightingMessagePart>(part))) {
+ body += highlight->text;
+ }
+ }
+ return body;
+ }
+
+ void resetLastMessages() {
+ lastAddedMessage_ = lastAddedAction_ = lastAddedPresence_ = lastReplacedMessage_ = lastAddedSystemMessage_ = lastReplacedSystemMessage_ = ChatMessage();
+ lastAddedMessageSenderName_ = lastAddedActionSenderName_ = "";
+ lastAddedMessageSenderIsSelf_ = lastAddedActionSenderIsSelf_ = false;
+ }
+
+ std::string name_;
+ ChatMessage lastAddedMessage_;
+ std::string lastAddedMessageSenderName_;
+ bool lastAddedMessageSenderIsSelf_ = false;
+ ChatMessage lastAddedAction_;
+ std::string lastAddedActionSenderName_;
+ bool lastAddedActionSenderIsSelf_ = false;
+ ChatMessage lastAddedPresence_;
+ ChatMessage lastReplacedMessage_;
+ ChatMessage lastAddedSystemMessage_;
+ ChatMessage lastReplacedSystemMessage_;
+ ChatMessage lastAddedErrorMessage_;
+ JID lastMUCInvitationJID_;
+ std::vector<SecurityLabelsCatalog::Item> labels_;
+ bool labelsEnabled_ = false;
+ bool impromptuMUCSupported_ = false;
+ SecurityLabelsCatalog::Item label_;
+ Roster* roster_ = nullptr;
+ std::vector<std::pair<std::string, ReceiptState>> receiptChanges_;
+ boost::optional<MUCType> mucType_;
+ };
}
diff --git a/Swift/Controllers/UnitTest/MockMainWindow.h b/Swift/Controllers/UnitTest/MockMainWindow.h
index af4267f..6ae2aa7 100644
--- a/Swift/Controllers/UnitTest/MockMainWindow.h
+++ b/Swift/Controllers/UnitTest/MockMainWindow.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -9,24 +9,24 @@
#include <Swift/Controllers/UIInterfaces/MainWindow.h>
namespace Swift {
- class Roster;
- class MockMainWindow : public MainWindow {
- public:
- MockMainWindow() : roster(NULL) {}
- virtual ~MockMainWindow() {}
- virtual void setRosterModel(Roster* roster) {this->roster = roster;}
- virtual void setMyNick(const std::string& /*name*/) {}
- virtual void setMyJID(const JID& /*jid*/) {}
- virtual void setMyAvatarPath(const std::string& /*path*/) {}
- virtual void setMyStatusText(const std::string& /*status*/) {}
- virtual void setMyStatusType(StatusShow::Type /*type*/) {}
- virtual void setMyContactRosterItem(boost::shared_ptr<ContactRosterItem> /*contact*/) {}
- virtual void setAvailableAdHocCommands(const std::vector<DiscoItems::Item>& /*commands*/) {}
- virtual void setConnecting() {}
- virtual void setStreamEncryptionStatus(bool /*tlsInPlaceAndValid*/) {}
- virtual void openCertificateDialog(const std::vector<Certificate::ref>& /*chain*/) {}
- virtual void setBlockingCommandAvailable(bool /*isAvailable*/) {}
- Roster* roster;
+ class Roster;
+ class MockMainWindow : public MainWindow {
+ public:
+ MockMainWindow() : roster(nullptr) {}
+ virtual ~MockMainWindow() {}
+ virtual void setRosterModel(Roster* roster) {this->roster = roster;}
+ virtual void setMyNick(const std::string& /*name*/) {}
+ virtual void setMyJID(const JID& /*jid*/) {}
+ virtual void setMyAvatarPath(const std::string& /*path*/) {}
+ virtual void setMyStatusText(const std::string& /*status*/) {}
+ virtual void setMyStatusType(StatusShow::Type /*type*/) {}
+ virtual void setMyContactRosterItem(std::shared_ptr<ContactRosterItem> /*contact*/) {}
+ virtual void setAvailableAdHocCommands(const std::vector<DiscoItems::Item>& /*commands*/) {}
+ virtual void setConnecting() {}
+ virtual void setStreamEncryptionStatus(bool /*tlsInPlaceAndValid*/) {}
+ virtual void openCertificateDialog(const std::vector<Certificate::ref>& /*chain*/) {}
+ virtual void setBlockingCommandAvailable(bool /*isAvailable*/) {}
+ Roster* roster;
- };
+ };
}
diff --git a/Swift/Controllers/UnitTest/MockMainWindowFactory.h b/Swift/Controllers/UnitTest/MockMainWindowFactory.h
index 5f9d590..adf4fdf 100644
--- a/Swift/Controllers/UnitTest/MockMainWindowFactory.h
+++ b/Swift/Controllers/UnitTest/MockMainWindowFactory.h
@@ -1,28 +1,28 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/UIInterfaces/MainWindowFactory.h"
-#include "Swift/Controllers/UnitTest/MockMainWindow.h"
+#include <Swift/Controllers/UIInterfaces/MainWindowFactory.h>
+#include <Swift/Controllers/UnitTest/MockMainWindow.h>
namespace Swift {
- class MockMainWindowFactory : public MainWindowFactory {
- public:
- MockMainWindowFactory() : last(NULL) {}
+ class MockMainWindowFactory : public MainWindowFactory {
+ public:
+ MockMainWindowFactory() : last(nullptr) {}
- virtual ~MockMainWindowFactory() {}
+ virtual ~MockMainWindowFactory() {}
- /**
- * Transfers ownership of result.
- */
- virtual MainWindow* createMainWindow(UIEventStream*) {last = new MockMainWindow();return last;}
- MockMainWindow* last;
- };
+ /**
+ * Transfers ownership of result.
+ */
+ virtual MainWindow* createMainWindow(UIEventStream*) {last = new MockMainWindow();return last;}
+ MockMainWindow* last;
+ };
}
diff --git a/Swift/Controllers/UnitTest/PresenceNotifierTest.cpp b/Swift/Controllers/UnitTest/PresenceNotifierTest.cpp
index 40530dc..1375475 100644
--- a/Swift/Controllers/UnitTest/PresenceNotifierTest.cpp
+++ b/Swift/Controllers/UnitTest/PresenceNotifierTest.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -26,297 +26,297 @@
using namespace Swift;
class PresenceNotifierTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(PresenceNotifierTest);
- CPPUNIT_TEST(testReceiveFirstPresenceCreatesAvailableNotification);
- CPPUNIT_TEST(testReceiveSecondPresenceCreatesStatusChangeNotification);
- CPPUNIT_TEST(testReceiveUnavailablePresenceAfterAvailablePresenceCreatesUnavailableNotification);
- CPPUNIT_TEST(testReceiveUnavailablePresenceWithoutAvailableDoesNotCreateNotification);
- CPPUNIT_TEST(testReceiveAvailablePresenceAfterUnavailableCreatesAvailableNotification);
- CPPUNIT_TEST(testReceiveAvailablePresenceAfterReconnectCreatesAvailableNotification);
- CPPUNIT_TEST(testReceiveAvailablePresenceFromMUCDoesNotCreateNotification);
- CPPUNIT_TEST(testNotificationSubjectContainsNameForJIDInRoster);
- CPPUNIT_TEST(testNotificationSubjectContainsJIDForJIDNotInRoster);
- CPPUNIT_TEST(testNotificationSubjectContainsStatus);
- CPPUNIT_TEST(testNotificationMessageContainsStatusMessage);
- CPPUNIT_TEST(testNotificationPicture);
- CPPUNIT_TEST(testNotificationActivationEmitsSignal);
- CPPUNIT_TEST(testReceiveFirstPresenceWithQuietPeriodDoesNotNotify);
- CPPUNIT_TEST(testReceiveFirstPresenceWithQuietPeriodDoesNotCountAsQuietPeriod);
- CPPUNIT_TEST(testReceivePresenceDuringQuietPeriodDoesNotNotify);
- CPPUNIT_TEST(testReceivePresenceDuringQuietPeriodResetsTimer);
- CPPUNIT_TEST(testReceivePresenceAfterQuietPeriodNotifies);
- CPPUNIT_TEST(testReceiveFirstPresenceAfterReconnectWithQuietPeriodDoesNotNotify);
- CPPUNIT_TEST_SUITE_END();
-
- public:
- void setUp() {
- stanzaChannel = new DummyStanzaChannel();
- notifier = new LoggingNotifier();
- mucRegistry = new MUCRegistry();
- user1 = JID("user1@bar.com/bla");
- user2 = JID("user2@foo.com/baz");
- avatarManager = new DummyAvatarManager();
- roster = new XMPPRosterImpl();
- nickResolver = new NickResolver(JID("foo@bar.com"), roster, NULL, mucRegistry);
- presenceOracle = new PresenceOracle(stanzaChannel, roster);
- timerFactory = new DummyTimerFactory();
- }
-
- void tearDown() {
- delete timerFactory;
- delete presenceOracle;
- delete nickResolver;
- delete roster;
- delete avatarManager;
- delete mucRegistry;
- delete notifier;
- delete stanzaChannel;
- }
-
- void testReceiveFirstPresenceCreatesAvailableNotification() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
-
- sendPresence(user1, StatusShow::Online);
-
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
- CPPUNIT_ASSERT_EQUAL(Notifier::ContactAvailable, notifier->notifications[0].type);
- }
-
- void testReceiveSecondPresenceCreatesStatusChangeNotification() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
- sendPresence(user1, StatusShow::Away);
- notifier->notifications.clear();
-
- sendPresence(user1, StatusShow::Online);
-
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
- CPPUNIT_ASSERT_EQUAL(Notifier::ContactStatusChange, notifier->notifications[0].type);
- }
-
- void testReceiveUnavailablePresenceAfterAvailablePresenceCreatesUnavailableNotification() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
- sendPresence(user1, StatusShow::Away);
- notifier->notifications.clear();
-
- sendUnavailablePresence(user1);
-
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
- CPPUNIT_ASSERT_EQUAL(Notifier::ContactUnavailable, notifier->notifications[0].type);
- }
-
- void testReceiveUnavailablePresenceWithoutAvailableDoesNotCreateNotification() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
-
- sendUnavailablePresence(user1);
-
- CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size()));
- }
-
- void testReceiveAvailablePresenceAfterUnavailableCreatesAvailableNotification() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
- sendPresence(user1, StatusShow::Away);
- sendUnavailablePresence(user1);
- notifier->notifications.clear();
-
- sendPresence(user1, StatusShow::Away);
-
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
- CPPUNIT_ASSERT_EQUAL(Notifier::ContactAvailable, notifier->notifications[0].type);
- }
-
- void testReceiveAvailablePresenceAfterReconnectCreatesAvailableNotification() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
- sendPresence(user1, StatusShow::Away);
- stanzaChannel->setAvailable(false);
- stanzaChannel->setAvailable(true);
- notifier->notifications.clear();
-
- sendPresence(user1, StatusShow::Away);
-
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
- CPPUNIT_ASSERT_EQUAL(Notifier::ContactAvailable, notifier->notifications[0].type);
- }
+ CPPUNIT_TEST_SUITE(PresenceNotifierTest);
+ CPPUNIT_TEST(testReceiveFirstPresenceCreatesAvailableNotification);
+ CPPUNIT_TEST(testReceiveSecondPresenceCreatesStatusChangeNotification);
+ CPPUNIT_TEST(testReceiveUnavailablePresenceAfterAvailablePresenceCreatesUnavailableNotification);
+ CPPUNIT_TEST(testReceiveUnavailablePresenceWithoutAvailableDoesNotCreateNotification);
+ CPPUNIT_TEST(testReceiveAvailablePresenceAfterUnavailableCreatesAvailableNotification);
+ CPPUNIT_TEST(testReceiveAvailablePresenceAfterReconnectCreatesAvailableNotification);
+ CPPUNIT_TEST(testReceiveAvailablePresenceFromMUCDoesNotCreateNotification);
+ CPPUNIT_TEST(testNotificationSubjectContainsNameForJIDInRoster);
+ CPPUNIT_TEST(testNotificationSubjectContainsJIDForJIDNotInRoster);
+ CPPUNIT_TEST(testNotificationSubjectContainsStatus);
+ CPPUNIT_TEST(testNotificationMessageContainsStatusMessage);
+ CPPUNIT_TEST(testNotificationPicture);
+ CPPUNIT_TEST(testNotificationActivationEmitsSignal);
+ CPPUNIT_TEST(testReceiveFirstPresenceWithQuietPeriodDoesNotNotify);
+ CPPUNIT_TEST(testReceiveFirstPresenceWithQuietPeriodDoesNotCountAsQuietPeriod);
+ CPPUNIT_TEST(testReceivePresenceDuringQuietPeriodDoesNotNotify);
+ CPPUNIT_TEST(testReceivePresenceDuringQuietPeriodResetsTimer);
+ CPPUNIT_TEST(testReceivePresenceAfterQuietPeriodNotifies);
+ CPPUNIT_TEST(testReceiveFirstPresenceAfterReconnectWithQuietPeriodDoesNotNotify);
+ CPPUNIT_TEST_SUITE_END();
+
+ public:
+ void setUp() {
+ stanzaChannel = new DummyStanzaChannel();
+ notifier = new LoggingNotifier();
+ mucRegistry = new MUCRegistry();
+ user1 = JID("user1@bar.com/bla");
+ user2 = JID("user2@foo.com/baz");
+ avatarManager = new DummyAvatarManager();
+ roster = new XMPPRosterImpl();
+ nickResolver = new NickResolver(JID("foo@bar.com"), roster, nullptr, mucRegistry);
+ presenceOracle = new PresenceOracle(stanzaChannel, roster);
+ timerFactory = new DummyTimerFactory();
+ }
+
+ void tearDown() {
+ delete timerFactory;
+ delete presenceOracle;
+ delete nickResolver;
+ delete roster;
+ delete avatarManager;
+ delete mucRegistry;
+ delete notifier;
+ delete stanzaChannel;
+ }
+
+ void testReceiveFirstPresenceCreatesAvailableNotification() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
+
+ sendPresence(user1, StatusShow::Online);
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
+ CPPUNIT_ASSERT_EQUAL(Notifier::ContactAvailable, notifier->notifications[0].type);
+ }
+
+ void testReceiveSecondPresenceCreatesStatusChangeNotification() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
+ sendPresence(user1, StatusShow::Away);
+ notifier->notifications.clear();
+
+ sendPresence(user1, StatusShow::Online);
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
+ CPPUNIT_ASSERT_EQUAL(Notifier::ContactStatusChange, notifier->notifications[0].type);
+ }
+
+ void testReceiveUnavailablePresenceAfterAvailablePresenceCreatesUnavailableNotification() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
+ sendPresence(user1, StatusShow::Away);
+ notifier->notifications.clear();
+
+ sendUnavailablePresence(user1);
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
+ CPPUNIT_ASSERT_EQUAL(Notifier::ContactUnavailable, notifier->notifications[0].type);
+ }
+
+ void testReceiveUnavailablePresenceWithoutAvailableDoesNotCreateNotification() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
+
+ sendUnavailablePresence(user1);
+
+ CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size()));
+ }
+
+ void testReceiveAvailablePresenceAfterUnavailableCreatesAvailableNotification() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
+ sendPresence(user1, StatusShow::Away);
+ sendUnavailablePresence(user1);
+ notifier->notifications.clear();
+
+ sendPresence(user1, StatusShow::Away);
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
+ CPPUNIT_ASSERT_EQUAL(Notifier::ContactAvailable, notifier->notifications[0].type);
+ }
+
+ void testReceiveAvailablePresenceAfterReconnectCreatesAvailableNotification() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
+ sendPresence(user1, StatusShow::Away);
+ stanzaChannel->setAvailable(false);
+ stanzaChannel->setAvailable(true);
+ notifier->notifications.clear();
+
+ sendPresence(user1, StatusShow::Away);
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
+ CPPUNIT_ASSERT_EQUAL(Notifier::ContactAvailable, notifier->notifications[0].type);
+ }
- void testReceiveAvailablePresenceFromMUCDoesNotCreateNotification() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
- mucRegistry->addMUC(JID("teaparty@wonderland.lit"));
+ void testReceiveAvailablePresenceFromMUCDoesNotCreateNotification() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
+ mucRegistry->addMUC(JID("teaparty@wonderland.lit"));
- sendPresence(JID("teaparty@wonderland.lit/Alice"), StatusShow::Away);
+ sendPresence(JID("teaparty@wonderland.lit/Alice"), StatusShow::Away);
- CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size()));
- }
+ CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size()));
+ }
- void testNotificationPicture() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
- avatarManager->avatars[user1] = createByteArray("abcdef");
+ void testNotificationPicture() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
+ avatarManager->avatars[user1] = createByteArray("abcdef");
- sendPresence(user1, StatusShow::Online);
+ sendPresence(user1, StatusShow::Online);
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
- CPPUNIT_ASSERT_EQUAL(boost::filesystem::path("/avatars/user1@bar.com/bla"), notifier->notifications[0].picture);
- }
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
+ CPPUNIT_ASSERT_EQUAL(boost::filesystem::path("/avatars/user1@bar.com/bla"), notifier->notifications[0].picture);
+ }
- void testNotificationActivationEmitsSignal() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
+ void testNotificationActivationEmitsSignal() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
- sendPresence(user1, StatusShow::Online);
- CPPUNIT_ASSERT(notifier->notifications[0].callback);
- notifier->notifications[0].callback();
+ sendPresence(user1, StatusShow::Online);
+ CPPUNIT_ASSERT(notifier->notifications[0].callback);
+ notifier->notifications[0].callback();
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(activatedNotifications.size()));
- CPPUNIT_ASSERT_EQUAL(user1, activatedNotifications[0]);
- }
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(activatedNotifications.size()));
+ CPPUNIT_ASSERT_EQUAL(user1, activatedNotifications[0]);
+ }
- void testNotificationSubjectContainsNameForJIDInRoster() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
- roster->addContact(user1.toBare(), "User 1", std::vector<std::string>(), RosterItemPayload::Both);
+ void testNotificationSubjectContainsNameForJIDInRoster() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
+ roster->addContact(user1.toBare(), "User 1", std::vector<std::string>(), RosterItemPayload::Both);
- sendPresence(user1, StatusShow::Online);
+ sendPresence(user1, StatusShow::Online);
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
- std::string subject = notifier->notifications[0].subject;
- CPPUNIT_ASSERT(subject.find("User 1") != std::string::npos);
- }
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
+ std::string subject = notifier->notifications[0].subject;
+ CPPUNIT_ASSERT(subject.find("User 1") != std::string::npos);
+ }
- void testNotificationSubjectContainsJIDForJIDNotInRoster() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
+ void testNotificationSubjectContainsJIDForJIDNotInRoster() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
- sendPresence(user1, StatusShow::Online);
+ sendPresence(user1, StatusShow::Online);
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
- std::string subject = notifier->notifications[0].subject;
- CPPUNIT_ASSERT(subject.find(user1.toBare().toString()) != std::string::npos);
- }
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
+ std::string subject = notifier->notifications[0].subject;
+ CPPUNIT_ASSERT(subject.find(user1.toBare().toString()) != std::string::npos);
+ }
- void testNotificationSubjectContainsStatus() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
+ void testNotificationSubjectContainsStatus() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
- sendPresence(user1, StatusShow::Away);
+ sendPresence(user1, StatusShow::Away);
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
- std::string subject = notifier->notifications[0].subject;
- CPPUNIT_ASSERT(subject.find("Away") != std::string::npos);
- }
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
+ std::string subject = notifier->notifications[0].subject;
+ CPPUNIT_ASSERT(subject.find("Away") != std::string::npos);
+ }
- void testNotificationMessageContainsStatusMessage() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
+ void testNotificationMessageContainsStatusMessage() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
- sendPresence(user1, StatusShow::Away);
+ sendPresence(user1, StatusShow::Away);
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
- CPPUNIT_ASSERT(notifier->notifications[0].description.find("Status Message") != std::string::npos);
- }
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
+ CPPUNIT_ASSERT(notifier->notifications[0].description.find("Status Message") != std::string::npos);
+ }
- void testReceiveFirstPresenceWithQuietPeriodDoesNotNotify() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
- testling->setInitialQuietPeriodMS(10);
+ void testReceiveFirstPresenceWithQuietPeriodDoesNotNotify() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
+ testling->setInitialQuietPeriodMS(10);
- sendPresence(user1, StatusShow::Online);
+ sendPresence(user1, StatusShow::Online);
- CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size()));
- }
+ CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size()));
+ }
- void testReceivePresenceDuringQuietPeriodDoesNotNotify() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
- testling->setInitialQuietPeriodMS(10);
+ void testReceivePresenceDuringQuietPeriodDoesNotNotify() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
+ testling->setInitialQuietPeriodMS(10);
- sendPresence(user1, StatusShow::Online);
- timerFactory->setTime(1);
- sendPresence(user2, StatusShow::Away);
+ sendPresence(user1, StatusShow::Online);
+ timerFactory->setTime(1);
+ sendPresence(user2, StatusShow::Away);
- CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size()));
- }
+ CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size()));
+ }
- void testReceivePresenceDuringQuietPeriodResetsTimer() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
- testling->setInitialQuietPeriodMS(10);
+ void testReceivePresenceDuringQuietPeriodResetsTimer() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
+ testling->setInitialQuietPeriodMS(10);
- sendPresence(user1, StatusShow::Online);
- timerFactory->setTime(9);
- sendPresence(user2, StatusShow::Away);
- timerFactory->setTime(18);
- sendPresence(user1, StatusShow::Away);
+ sendPresence(user1, StatusShow::Online);
+ timerFactory->setTime(9);
+ sendPresence(user2, StatusShow::Away);
+ timerFactory->setTime(18);
+ sendPresence(user1, StatusShow::Away);
- CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size()));
- }
+ CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size()));
+ }
- void testReceivePresenceAfterQuietPeriodNotifies() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
- testling->setInitialQuietPeriodMS(10);
-
- sendPresence(user1, StatusShow::Online);
- timerFactory->setTime(11);
- sendPresence(user2, StatusShow::Away);
-
- CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
- }
-
- void testReceiveFirstPresenceWithQuietPeriodDoesNotCountAsQuietPeriod() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
- testling->setInitialQuietPeriodMS(10);
-
- timerFactory->setTime(11);
- sendPresence(user1, StatusShow::Away);
-
- CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size()));
- }
-
- void testReceiveFirstPresenceAfterReconnectWithQuietPeriodDoesNotNotify() {
- boost::shared_ptr<PresenceNotifier> testling = createNotifier();
- testling->setInitialQuietPeriodMS(10);
- sendPresence(user1, StatusShow::Online);
- timerFactory->setTime(15);
- notifier->notifications.clear();
-
- stanzaChannel->setAvailable(false);
- stanzaChannel->setAvailable(true);
- sendPresence(user1, StatusShow::Online);
- timerFactory->setTime(21);
- sendPresence(user2, StatusShow::Online);
-
- CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size()));
- }
-
-
- private:
- boost::shared_ptr<PresenceNotifier> createNotifier() {
- boost::shared_ptr<PresenceNotifier> result(new PresenceNotifier(stanzaChannel, notifier, mucRegistry, avatarManager, nickResolver, presenceOracle, timerFactory));
- result->onNotificationActivated.connect(boost::bind(&PresenceNotifierTest::handleNotificationActivated, this, _1));
- result->setInitialQuietPeriodMS(0);
- return result;
- }
-
- void sendPresence(const JID& jid, StatusShow::Type type) {
- boost::shared_ptr<Presence> presence(new Presence());
- presence->setFrom(jid);
- presence->setShow(type);
- presence->setStatus("Status Message");
- stanzaChannel->onPresenceReceived(presence);
- }
-
- void sendUnavailablePresence(const JID& jid) {
- boost::shared_ptr<Presence> presence(new Presence());
- presence->setType(Presence::Unavailable);
- presence->setFrom(jid);
- stanzaChannel->onPresenceReceived(presence);
- }
-
- void handleNotificationActivated(const JID& j) {
- activatedNotifications.push_back(j);
- }
-
- private:
- DummyStanzaChannel* stanzaChannel;
- LoggingNotifier* notifier;
- MUCRegistry* mucRegistry;
- DummyAvatarManager* avatarManager;
- XMPPRosterImpl* roster;
- NickResolver* nickResolver;
- PresenceOracle* presenceOracle;
- DummyTimerFactory* timerFactory;
- JID user1;
- JID user2;
- std::vector<JID> activatedNotifications;
+ void testReceivePresenceAfterQuietPeriodNotifies() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
+ testling->setInitialQuietPeriodMS(10);
+
+ sendPresence(user1, StatusShow::Online);
+ timerFactory->setTime(11);
+ sendPresence(user2, StatusShow::Away);
+
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(notifier->notifications.size()));
+ }
+
+ void testReceiveFirstPresenceWithQuietPeriodDoesNotCountAsQuietPeriod() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
+ testling->setInitialQuietPeriodMS(10);
+
+ timerFactory->setTime(11);
+ sendPresence(user1, StatusShow::Away);
+
+ CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size()));
+ }
+
+ void testReceiveFirstPresenceAfterReconnectWithQuietPeriodDoesNotNotify() {
+ std::shared_ptr<PresenceNotifier> testling = createNotifier();
+ testling->setInitialQuietPeriodMS(10);
+ sendPresence(user1, StatusShow::Online);
+ timerFactory->setTime(15);
+ notifier->notifications.clear();
+
+ stanzaChannel->setAvailable(false);
+ stanzaChannel->setAvailable(true);
+ sendPresence(user1, StatusShow::Online);
+ timerFactory->setTime(21);
+ sendPresence(user2, StatusShow::Online);
+
+ CPPUNIT_ASSERT_EQUAL(0, static_cast<int>(notifier->notifications.size()));
+ }
+
+
+ private:
+ std::shared_ptr<PresenceNotifier> createNotifier() {
+ std::shared_ptr<PresenceNotifier> result(new PresenceNotifier(stanzaChannel, notifier, mucRegistry, avatarManager, nickResolver, presenceOracle, timerFactory));
+ result->onNotificationActivated.connect(boost::bind(&PresenceNotifierTest::handleNotificationActivated, this, _1));
+ result->setInitialQuietPeriodMS(0);
+ return result;
+ }
+
+ void sendPresence(const JID& jid, StatusShow::Type type) {
+ std::shared_ptr<Presence> presence(new Presence());
+ presence->setFrom(jid);
+ presence->setShow(type);
+ presence->setStatus("Status Message");
+ stanzaChannel->onPresenceReceived(presence);
+ }
+
+ void sendUnavailablePresence(const JID& jid) {
+ std::shared_ptr<Presence> presence(new Presence());
+ presence->setType(Presence::Unavailable);
+ presence->setFrom(jid);
+ stanzaChannel->onPresenceReceived(presence);
+ }
+
+ void handleNotificationActivated(const JID& j) {
+ activatedNotifications.push_back(j);
+ }
+
+ private:
+ DummyStanzaChannel* stanzaChannel;
+ LoggingNotifier* notifier;
+ MUCRegistry* mucRegistry;
+ DummyAvatarManager* avatarManager;
+ XMPPRosterImpl* roster;
+ NickResolver* nickResolver;
+ PresenceOracle* presenceOracle;
+ DummyTimerFactory* timerFactory;
+ JID user1;
+ JID user2;
+ std::vector<JID> activatedNotifications;
};
CPPUNIT_TEST_SUITE_REGISTRATION(PresenceNotifierTest);
diff --git a/Swift/Controllers/UnitTest/PreviousStatusStoreTest.cpp b/Swift/Controllers/UnitTest/PreviousStatusStoreTest.cpp
index 4c9941d..be35468 100644
--- a/Swift/Controllers/UnitTest/PreviousStatusStoreTest.cpp
+++ b/Swift/Controllers/UnitTest/PreviousStatusStoreTest.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,38 +7,38 @@
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
-#include "Swift/Controllers/PreviousStatusStore.h"
+#include <Swift/Controllers/PreviousStatusStore.h>
using namespace Swift;
class PreviousStatusStoreTest : public CppUnit::TestFixture {
- CPPUNIT_TEST_SUITE(PreviousStatusStoreTest);
- CPPUNIT_TEST(testGetAll);
- //CPPUNIT_TEST(testGetAllLimited);
- //CPPUNIT_TEST(testGetSuggestionsInexact);
- //CPPUNIT_TEST(testGetSuggestionsExact);
- CPPUNIT_TEST_SUITE_END();
+ CPPUNIT_TEST_SUITE(PreviousStatusStoreTest);
+ CPPUNIT_TEST(testGetAll);
+ //CPPUNIT_TEST(testGetAllLimited);
+ //CPPUNIT_TEST(testGetSuggestionsInexact);
+ //CPPUNIT_TEST(testGetSuggestionsExact);
+ CPPUNIT_TEST_SUITE_END();
public:
- void setUp() {
- store_ = new PreviousStatusStore();
- store_->addStatus(StatusShow::Online, "At home in the study");
- store_->addStatus(StatusShow::DND, "In a meeting");
- store_->addStatus(StatusShow::DND, "With a client");
- store_->addStatus(StatusShow::Away, "Walking the elephant");
- store_->addStatus(StatusShow::Online, "In the office, at my desk");
- }
+ void setUp() {
+ store_ = new PreviousStatusStore();
+ store_->addStatus(StatusShow::Online, "At home in the study");
+ store_->addStatus(StatusShow::DND, "In a meeting");
+ store_->addStatus(StatusShow::DND, "With a client");
+ store_->addStatus(StatusShow::Away, "Walking the elephant");
+ store_->addStatus(StatusShow::Online, "In the office, at my desk");
+ }
- void tearDown() {
- delete store_;
- }
+ void tearDown() {
+ delete store_;
+ }
- void testGetAll() {
+ void testGetAll() {
- }
+ }
private:
- PreviousStatusStore* store_;
+ PreviousStatusStore* store_;
};
CPPUNIT_TEST_SUITE_REGISTRATION(PreviousStatusStoreTest);
diff --git a/Swift/Controllers/WhiteboardManager.cpp b/Swift/Controllers/WhiteboardManager.cpp
index d8d89eb..37fe8e3 100644
--- a/Swift/Controllers/WhiteboardManager.cpp
+++ b/Swift/Controllers/WhiteboardManager.cpp
@@ -4,135 +4,139 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#include <Swift/Controllers/WhiteboardManager.h>
#include <boost/bind.hpp>
-#include <Swiften/Base/foreach.h>
-#include <Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h>
+#include <Swiften/Client/NickResolver.h>
+#include <Swiften/Client/StanzaChannel.h>
+#include <Swiften/Whiteboard/WhiteboardSessionManager.h>
+
#include <Swift/Controllers/UIEvents/AcceptWhiteboardSessionUIEvent.h>
#include <Swift/Controllers/UIEvents/CancelWhiteboardSessionUIEvent.h>
+#include <Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h>
#include <Swift/Controllers/UIEvents/ShowWhiteboardUIEvent.h>
-#include "Swiften/Client/NickResolver.h"
-#include <Swiften/Client/StanzaChannel.h>
-#include <Swiften/Whiteboard/WhiteboardSessionManager.h>
namespace Swift {
- typedef std::pair<JID, WhiteboardWindow*> JIDWhiteboardWindowPair;
-
- WhiteboardManager::WhiteboardManager(WhiteboardWindowFactory* whiteboardWindowFactory, UIEventStream* uiEventStream, NickResolver* nickResolver, WhiteboardSessionManager* whiteboardSessionManager) : whiteboardWindowFactory_(whiteboardWindowFactory), uiEventStream_(uiEventStream), nickResolver_(nickResolver), whiteboardSessionManager_(whiteboardSessionManager) {
+ WhiteboardManager::WhiteboardManager(WhiteboardWindowFactory* whiteboardWindowFactory, UIEventStream* uiEventStream, NickResolver* nickResolver, WhiteboardSessionManager* whiteboardSessionManager) : whiteboardWindowFactory_(whiteboardWindowFactory), uiEventStream_(uiEventStream), nickResolver_(nickResolver), whiteboardSessionManager_(whiteboardSessionManager) {
#ifdef SWIFT_EXPERIMENTAL_WB
- whiteboardSessionManager_->onSessionRequest.connect(boost::bind(&WhiteboardManager::handleIncomingSession, this, _1));
+ whiteboardSessionManager_->onSessionRequest.connect(boost::bind(&WhiteboardManager::handleIncomingSession, this, _1));
#endif
- uiEventConnection_ = uiEventStream_->onUIEvent.connect(boost::bind(&WhiteboardManager::handleUIEvent, this, _1));
- }
-
- WhiteboardManager::~WhiteboardManager() {
- foreach (JIDWhiteboardWindowPair whiteboardWindowPair, whiteboardWindows_) {
- delete whiteboardWindowPair.second;
- }
- }
-
- WhiteboardWindow* WhiteboardManager::createNewWhiteboardWindow(const JID& contact, WhiteboardSession::ref session) {
- WhiteboardWindow *window = whiteboardWindowFactory_->createWhiteboardWindow(session);
- window->setName(nickResolver_->jidToNick(contact));
- whiteboardWindows_[contact.toBare()] = window;
- return window;
- }
-
- WhiteboardWindow* WhiteboardManager::findWhiteboardWindow(const JID& contact) {
- if (whiteboardWindows_.find(contact.toBare()) == whiteboardWindows_.end()) {
- return NULL;
- }
- return whiteboardWindows_[contact.toBare()];
- }
-
- void WhiteboardManager::handleUIEvent(boost::shared_ptr<UIEvent> event) {
- boost::shared_ptr<RequestWhiteboardUIEvent> requestWhiteboardEvent = boost::dynamic_pointer_cast<RequestWhiteboardUIEvent>(event);
- if (requestWhiteboardEvent) {
- requestSession(requestWhiteboardEvent->getContact());
- }
- boost::shared_ptr<AcceptWhiteboardSessionUIEvent> sessionAcceptEvent = boost::dynamic_pointer_cast<AcceptWhiteboardSessionUIEvent>(event);
- if (sessionAcceptEvent) {
- acceptSession(sessionAcceptEvent->getContact());
- }
- boost::shared_ptr<CancelWhiteboardSessionUIEvent> sessionCancelEvent = boost::dynamic_pointer_cast<CancelWhiteboardSessionUIEvent>(event);
- if (sessionCancelEvent) {
- cancelSession(sessionCancelEvent->getContact());
- }
- boost::shared_ptr<ShowWhiteboardUIEvent> showWindowEvent = boost::dynamic_pointer_cast<ShowWhiteboardUIEvent>(event);
- if (showWindowEvent) {
- WhiteboardWindow* window = findWhiteboardWindow(showWindowEvent->getContact());
- if (window != NULL) {
- window->activateWindow();
- }
- }
- }
-
- void WhiteboardManager::acceptSession(const JID& from) {
- IncomingWhiteboardSession::ref session = boost::dynamic_pointer_cast<IncomingWhiteboardSession>(whiteboardSessionManager_->getSession(from));
- WhiteboardWindow* window = findWhiteboardWindow(from);
- if (session && window) {
- session->accept();
- window->show();
- }
- }
-
- void WhiteboardManager::requestSession(const JID& contact) {
- WhiteboardSession::ref session = whiteboardSessionManager_->requestSession(contact);
- session->onSessionTerminated.connect(boost::bind(&WhiteboardManager::handleSessionTerminate, this, _1));
- session->onRequestAccepted.connect(boost::bind(&WhiteboardManager::handleSessionAccept, this, _1));
- session->onRequestRejected.connect(boost::bind(&WhiteboardManager::handleRequestReject, this, _1));
-
- WhiteboardWindow* window = findWhiteboardWindow(contact);
- if (window == NULL) {
- createNewWhiteboardWindow(contact, session);
- } else {
- window->setSession(session);
- }
- onSessionRequest(session->getTo(), true);
- }
-
- void WhiteboardManager::cancelSession(const JID& from) {
- WhiteboardSession::ref session = whiteboardSessionManager_->getSession(from);
- if (session) {
- session->cancel();
- }
- }
-
- void WhiteboardManager::handleIncomingSession(IncomingWhiteboardSession::ref session) {
- session->onSessionTerminated.connect(boost::bind(&WhiteboardManager::handleSessionTerminate, this, _1));
- session->onRequestAccepted.connect(boost::bind(&WhiteboardManager::handleSessionAccept, this, _1));
-
- WhiteboardWindow* window = findWhiteboardWindow(session->getTo());
- if (window == NULL) {
- createNewWhiteboardWindow(session->getTo(), session);
- } else {
- window->setSession(session);
- }
-
- onSessionRequest(session->getTo(), false);
- }
-
- void WhiteboardManager::handleSessionTerminate(const JID& contact) {
- onSessionTerminate(contact);
- }
-
- void WhiteboardManager::handleSessionCancel(const JID& contact) {
- onSessionTerminate(contact);
- }
-
- void WhiteboardManager::handleSessionAccept(const JID& contact) {
- WhiteboardWindow* window = findWhiteboardWindow(contact);
- if (window != NULL) {
- window->show();
- }
- onRequestAccepted(contact);
- }
-
- void WhiteboardManager::handleRequestReject(const JID& contact) {
- onRequestRejected(contact);
- }
+ uiEventConnection_ = uiEventStream_->onUIEvent.connect(boost::bind(&WhiteboardManager::handleUIEvent, this, _1));
+ }
+
+ WhiteboardManager::~WhiteboardManager() {
+ for (auto&& whiteboardWindowPair : whiteboardWindows_) {
+ delete whiteboardWindowPair.second;
+ }
+ }
+
+ WhiteboardWindow* WhiteboardManager::createNewWhiteboardWindow(const JID& contact, WhiteboardSession::ref session) {
+ WhiteboardWindow *window = whiteboardWindowFactory_->createWhiteboardWindow(session);
+ window->setName(nickResolver_->jidToNick(contact));
+ whiteboardWindows_[contact.toBare()] = window;
+ return window;
+ }
+
+ WhiteboardWindow* WhiteboardManager::findWhiteboardWindow(const JID& contact) {
+ if (whiteboardWindows_.find(contact.toBare()) == whiteboardWindows_.end()) {
+ return nullptr;
+ }
+ return whiteboardWindows_[contact.toBare()];
+ }
+
+ void WhiteboardManager::handleUIEvent(std::shared_ptr<UIEvent> event) {
+ std::shared_ptr<RequestWhiteboardUIEvent> requestWhiteboardEvent = std::dynamic_pointer_cast<RequestWhiteboardUIEvent>(event);
+ if (requestWhiteboardEvent) {
+ requestSession(requestWhiteboardEvent->getContact());
+ }
+ std::shared_ptr<AcceptWhiteboardSessionUIEvent> sessionAcceptEvent = std::dynamic_pointer_cast<AcceptWhiteboardSessionUIEvent>(event);
+ if (sessionAcceptEvent) {
+ acceptSession(sessionAcceptEvent->getContact());
+ }
+ std::shared_ptr<CancelWhiteboardSessionUIEvent> sessionCancelEvent = std::dynamic_pointer_cast<CancelWhiteboardSessionUIEvent>(event);
+ if (sessionCancelEvent) {
+ cancelSession(sessionCancelEvent->getContact());
+ }
+ std::shared_ptr<ShowWhiteboardUIEvent> showWindowEvent = std::dynamic_pointer_cast<ShowWhiteboardUIEvent>(event);
+ if (showWindowEvent) {
+ WhiteboardWindow* window = findWhiteboardWindow(showWindowEvent->getContact());
+ if (window != nullptr) {
+ window->activateWindow();
+ }
+ }
+ }
+
+ void WhiteboardManager::acceptSession(const JID& from) {
+ IncomingWhiteboardSession::ref session = std::dynamic_pointer_cast<IncomingWhiteboardSession>(whiteboardSessionManager_->getSession(from));
+ WhiteboardWindow* window = findWhiteboardWindow(from);
+ if (session && window) {
+ session->accept();
+ window->show();
+ }
+ }
+
+ void WhiteboardManager::requestSession(const JID& contact) {
+ WhiteboardSession::ref session = whiteboardSessionManager_->requestSession(contact);
+ session->onSessionTerminated.connect(boost::bind(&WhiteboardManager::handleSessionTerminate, this, _1));
+ session->onRequestAccepted.connect(boost::bind(&WhiteboardManager::handleSessionAccept, this, _1));
+ session->onRequestRejected.connect(boost::bind(&WhiteboardManager::handleRequestReject, this, _1));
+
+ WhiteboardWindow* window = findWhiteboardWindow(contact);
+ if (window == nullptr) {
+ createNewWhiteboardWindow(contact, session);
+ } else {
+ window->setSession(session);
+ }
+ onSessionRequest(session->getTo(), true);
+ }
+
+ void WhiteboardManager::cancelSession(const JID& from) {
+ WhiteboardSession::ref session = whiteboardSessionManager_->getSession(from);
+ if (session) {
+ session->cancel();
+ }
+ }
+
+ void WhiteboardManager::handleIncomingSession(IncomingWhiteboardSession::ref session) {
+ session->onSessionTerminated.connect(boost::bind(&WhiteboardManager::handleSessionTerminate, this, _1));
+ session->onRequestAccepted.connect(boost::bind(&WhiteboardManager::handleSessionAccept, this, _1));
+
+ WhiteboardWindow* window = findWhiteboardWindow(session->getTo());
+ if (window == nullptr) {
+ createNewWhiteboardWindow(session->getTo(), session);
+ } else {
+ window->setSession(session);
+ }
+
+ onSessionRequest(session->getTo(), false);
+ }
+
+ void WhiteboardManager::handleSessionTerminate(const JID& contact) {
+ onSessionTerminate(contact);
+ }
+
+ void WhiteboardManager::handleSessionCancel(const JID& contact) {
+ onSessionTerminate(contact);
+ }
+
+ void WhiteboardManager::handleSessionAccept(const JID& contact) {
+ WhiteboardWindow* window = findWhiteboardWindow(contact);
+ if (window != nullptr) {
+ window->show();
+ }
+ onRequestAccepted(contact);
+ }
+
+ void WhiteboardManager::handleRequestReject(const JID& contact) {
+ onRequestRejected(contact);
+ }
}
diff --git a/Swift/Controllers/WhiteboardManager.h b/Swift/Controllers/WhiteboardManager.h
index 2f5767b..3ef14ab 100644
--- a/Swift/Controllers/WhiteboardManager.h
+++ b/Swift/Controllers/WhiteboardManager.h
@@ -4,56 +4,61 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <map>
-
-#include <boost/shared_ptr.hpp>
+#include <memory>
#include <Swiften/JID/JID.h>
+#include <Swiften/Whiteboard/IncomingWhiteboardSession.h>
+#include <Swiften/Whiteboard/WhiteboardSession.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
-#include <Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h>
#include <Swift/Controllers/UIInterfaces/WhiteboardWindow.h>
-#include <Swiften/Whiteboard/WhiteboardSession.h>
-#include <Swiften/Whiteboard/IncomingWhiteboardSession.h>
+#include <Swift/Controllers/UIInterfaces/WhiteboardWindowFactory.h>
namespace Swift {
- class WhiteboardSessionManager;
- class NickResolver;
-
- class WhiteboardManager {
- public:
- WhiteboardManager(WhiteboardWindowFactory* whiteboardWindowFactory, UIEventStream* uiEventStream, NickResolver* nickResolver, WhiteboardSessionManager* whiteboardSessionManager);
- ~WhiteboardManager();
-
- WhiteboardWindow* createNewWhiteboardWindow(const JID& contact, WhiteboardSession::ref session);
-
- public:
- boost::signal< void (const JID&, bool senderIsSelf)> onSessionRequest;
- boost::signal< void (const JID&)> onSessionTerminate;
- boost::signal< void (const JID&)> onRequestAccepted;
- boost::signal< void (const JID&)> onRequestRejected;
-
- private:
- void handleUIEvent(boost::shared_ptr<UIEvent> event);
- void handleSessionTerminate(const JID& contact);
- void handleSessionCancel(const JID& contact);
- void handleSessionAccept(const JID& contact);
- void handleRequestReject(const JID& contact);
- void handleIncomingSession(IncomingWhiteboardSession::ref session);
- void acceptSession(const JID& from);
- void requestSession(const JID& contact);
- void cancelSession(const JID& from);
- WhiteboardWindow* findWhiteboardWindow(const JID& contact);
-
- private:
- std::map<JID, WhiteboardWindow*> whiteboardWindows_;
- WhiteboardWindowFactory* whiteboardWindowFactory_;
- UIEventStream* uiEventStream_;
- NickResolver* nickResolver_;
- boost::bsignals::scoped_connection uiEventConnection_;
- WhiteboardSessionManager* whiteboardSessionManager_;
- };
+ class WhiteboardSessionManager;
+ class NickResolver;
+
+ class WhiteboardManager {
+ public:
+ WhiteboardManager(WhiteboardWindowFactory* whiteboardWindowFactory, UIEventStream* uiEventStream, NickResolver* nickResolver, WhiteboardSessionManager* whiteboardSessionManager);
+ ~WhiteboardManager();
+
+ WhiteboardWindow* createNewWhiteboardWindow(const JID& contact, WhiteboardSession::ref session);
+
+ public:
+ boost::signals2::signal< void (const JID&, bool senderIsSelf)> onSessionRequest;
+ boost::signals2::signal< void (const JID&)> onSessionTerminate;
+ boost::signals2::signal< void (const JID&)> onRequestAccepted;
+ boost::signals2::signal< void (const JID&)> onRequestRejected;
+
+ private:
+ void handleUIEvent(std::shared_ptr<UIEvent> event);
+ void handleSessionTerminate(const JID& contact);
+ void handleSessionCancel(const JID& contact);
+ void handleSessionAccept(const JID& contact);
+ void handleRequestReject(const JID& contact);
+ void handleIncomingSession(IncomingWhiteboardSession::ref session);
+ void acceptSession(const JID& from);
+ void requestSession(const JID& contact);
+ void cancelSession(const JID& from);
+ WhiteboardWindow* findWhiteboardWindow(const JID& contact);
+
+ private:
+ std::map<JID, WhiteboardWindow*> whiteboardWindows_;
+ WhiteboardWindowFactory* whiteboardWindowFactory_;
+ UIEventStream* uiEventStream_;
+ NickResolver* nickResolver_;
+ boost::signals2::scoped_connection uiEventConnection_;
+ WhiteboardSessionManager* whiteboardSessionManager_;
+ };
}
diff --git a/Swift/Controllers/XMLConsoleController.cpp b/Swift/Controllers/XMLConsoleController.cpp
index b9edcb8..b72fde3 100644
--- a/Swift/Controllers/XMLConsoleController.cpp
+++ b/Swift/Controllers/XMLConsoleController.cpp
@@ -1,45 +1,45 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/Controllers/XMLConsoleController.h"
+#include <Swift/Controllers/XMLConsoleController.h>
-#include "Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h"
-#include "Swift/Controllers/UIEvents/RequestXMLConsoleUIEvent.h"
+#include <Swift/Controllers/UIEvents/RequestXMLConsoleUIEvent.h>
+#include <Swift/Controllers/UIInterfaces/XMLConsoleWidgetFactory.h>
namespace Swift {
-XMLConsoleController::XMLConsoleController(UIEventStream* uiEventStream, XMLConsoleWidgetFactory* xmlConsoleWidgetFactory) : xmlConsoleWidgetFactory(xmlConsoleWidgetFactory), xmlConsoleWidget(NULL) {
- uiEventStream->onUIEvent.connect(boost::bind(&XMLConsoleController::handleUIEvent, this, _1));
+XMLConsoleController::XMLConsoleController(UIEventStream* uiEventStream, XMLConsoleWidgetFactory* xmlConsoleWidgetFactory) : xmlConsoleWidgetFactory(xmlConsoleWidgetFactory), xmlConsoleWidget(nullptr) {
+ uiEventStream->onUIEvent.connect(boost::bind(&XMLConsoleController::handleUIEvent, this, _1));
}
XMLConsoleController::~XMLConsoleController() {
- delete xmlConsoleWidget;
+ delete xmlConsoleWidget;
}
-void XMLConsoleController::handleUIEvent(boost::shared_ptr<UIEvent> rawEvent) {
- boost::shared_ptr<RequestXMLConsoleUIEvent> event = boost::dynamic_pointer_cast<RequestXMLConsoleUIEvent>(rawEvent);
- if (event != NULL) {
- if (xmlConsoleWidget == NULL) {
- xmlConsoleWidget = xmlConsoleWidgetFactory->createXMLConsoleWidget();
- }
- xmlConsoleWidget->show();
- xmlConsoleWidget->activate();
- }
+void XMLConsoleController::handleUIEvent(std::shared_ptr<UIEvent> rawEvent) {
+ std::shared_ptr<RequestXMLConsoleUIEvent> event = std::dynamic_pointer_cast<RequestXMLConsoleUIEvent>(rawEvent);
+ if (event != nullptr) {
+ if (xmlConsoleWidget == nullptr) {
+ xmlConsoleWidget = xmlConsoleWidgetFactory->createXMLConsoleWidget();
+ }
+ xmlConsoleWidget->show();
+ xmlConsoleWidget->activate();
+ }
}
void XMLConsoleController::handleDataRead(const SafeByteArray& data) {
- if (xmlConsoleWidget) {
- xmlConsoleWidget->handleDataRead(data);
- }
+ if (xmlConsoleWidget) {
+ xmlConsoleWidget->handleDataRead(data);
+ }
}
void XMLConsoleController::handleDataWritten(const SafeByteArray& data) {
- if (xmlConsoleWidget) {
- xmlConsoleWidget->handleDataWritten(data);
- }
+ if (xmlConsoleWidget) {
+ xmlConsoleWidget->handleDataWritten(data);
+ }
}
}
diff --git a/Swift/Controllers/XMLConsoleController.h b/Swift/Controllers/XMLConsoleController.h
index 7a11577..56202b4 100644
--- a/Swift/Controllers/XMLConsoleController.h
+++ b/Swift/Controllers/XMLConsoleController.h
@@ -1,37 +1,39 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swiften/Base/boost_bsignals.h"
+#include <memory>
+
#include <boost/bind.hpp>
-#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
-#include "Swift/Controllers/UIEvents/UIEventStream.h"
#include <Swiften/Base/SafeByteArray.h>
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
+
namespace Swift {
-
- class XMLConsoleWidgetFactory;
- class XMLConsoleWidget;
-
- class XMLConsoleController {
- public:
- XMLConsoleController(UIEventStream* uiEventStream, XMLConsoleWidgetFactory* xmlConsoleWidgetFactory);
- ~XMLConsoleController();
-
- public:
- void handleDataRead(const SafeByteArray& data);
- void handleDataWritten(const SafeByteArray& data);
-
- private:
- void handleUIEvent(boost::shared_ptr<UIEvent> event);
-
- private:
- XMLConsoleWidgetFactory* xmlConsoleWidgetFactory;
- XMLConsoleWidget* xmlConsoleWidget;
- };
+
+ class XMLConsoleWidgetFactory;
+ class XMLConsoleWidget;
+
+ class XMLConsoleController {
+ public:
+ XMLConsoleController(UIEventStream* uiEventStream, XMLConsoleWidgetFactory* xmlConsoleWidgetFactory);
+ ~XMLConsoleController();
+
+ public:
+ void handleDataRead(const SafeByteArray& data);
+ void handleDataWritten(const SafeByteArray& data);
+
+ private:
+ void handleUIEvent(std::shared_ptr<UIEvent> event);
+
+ private:
+ XMLConsoleWidgetFactory* xmlConsoleWidgetFactory;
+ XMLConsoleWidget* xmlConsoleWidget;
+ };
}
diff --git a/Swift/Controllers/XMPPEvents/ErrorEvent.h b/Swift/Controllers/XMPPEvents/ErrorEvent.h
index ee0284e..c0b5e52 100644
--- a/Swift/Controllers/XMPPEvents/ErrorEvent.h
+++ b/Swift/Controllers/XMPPEvents/ErrorEvent.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,25 +7,26 @@
#pragma once
#include <cassert>
+#include <memory>
+#include <string>
-#include "Swiften/Base/boost_bsignals.h"
-#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
-#include "Swift/Controllers/XMPPEvents/StanzaEvent.h"
-#include <string>
-#include "Swiften/JID/JID.h"
+#include <Swiften/JID/JID.h>
+
+#include <Swift/Controllers/XMPPEvents/StanzaEvent.h>
namespace Swift {
- class ErrorEvent : public StanzaEvent {
- public:
- ErrorEvent(const JID& jid, const std::string& text) : jid_(jid), text_(text){}
- virtual ~ErrorEvent(){}
- const JID& getJID() const {return jid_;}
- const std::string& getText() const {return text_;}
-
- private:
- JID jid_;
- std::string text_;
- };
+ class ErrorEvent : public StanzaEvent {
+ public:
+ ErrorEvent(const JID& jid, const std::string& text) : jid_(jid), text_(text){}
+ virtual ~ErrorEvent(){}
+ const JID& getJID() const {return jid_;}
+ const std::string& getText() const {return text_;}
+
+ private:
+ JID jid_;
+ std::string text_;
+ };
}
diff --git a/Swift/Controllers/XMPPEvents/EventController.cpp b/Swift/Controllers/XMPPEvents/EventController.cpp
index bbe7356..f8fb192 100644
--- a/Swift/Controllers/XMPPEvents/EventController.cpp
+++ b/Swift/Controllers/XMPPEvents/EventController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -11,8 +11,6 @@
#include <boost/bind.hpp>
#include <boost/numeric/conversion/cast.hpp>
-#include <Swiften/Base/foreach.h>
-
#include <Swift/Controllers/XMPPEvents/ErrorEvent.h>
#include <Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h>
#include <Swift/Controllers/XMPPEvents/MUCInviteEvent.h>
@@ -25,56 +23,56 @@ EventController::EventController() {
}
EventController::~EventController() {
- foreach(boost::shared_ptr<StanzaEvent> event, events_) {
- event->onConclusion.disconnect(boost::bind(&EventController::handleEventConcluded, this, event));
- }
+ for (auto&& event : events_) {
+ event->onConclusion.disconnect(boost::bind(&EventController::handleEventConcluded, this, event));
+ }
}
-void EventController::handleIncomingEvent(boost::shared_ptr<StanzaEvent> sourceEvent) {
- boost::shared_ptr<MessageEvent> messageEvent = boost::dynamic_pointer_cast<MessageEvent>(sourceEvent);
- boost::shared_ptr<SubscriptionRequestEvent> subscriptionEvent = boost::dynamic_pointer_cast<SubscriptionRequestEvent>(sourceEvent);
- boost::shared_ptr<ErrorEvent> errorEvent = boost::dynamic_pointer_cast<ErrorEvent>(sourceEvent);
- boost::shared_ptr<MUCInviteEvent> mucInviteEvent = boost::dynamic_pointer_cast<MUCInviteEvent>(sourceEvent);
- boost::shared_ptr<IncomingFileTransferEvent> incomingFileTransferEvent = boost::dynamic_pointer_cast<IncomingFileTransferEvent>(sourceEvent);
+void EventController::handleIncomingEvent(std::shared_ptr<StanzaEvent> sourceEvent) {
+ std::shared_ptr<MessageEvent> messageEvent = std::dynamic_pointer_cast<MessageEvent>(sourceEvent);
+ std::shared_ptr<SubscriptionRequestEvent> subscriptionEvent = std::dynamic_pointer_cast<SubscriptionRequestEvent>(sourceEvent);
+ std::shared_ptr<ErrorEvent> errorEvent = std::dynamic_pointer_cast<ErrorEvent>(sourceEvent);
+ std::shared_ptr<MUCInviteEvent> mucInviteEvent = std::dynamic_pointer_cast<MUCInviteEvent>(sourceEvent);
+ std::shared_ptr<IncomingFileTransferEvent> incomingFileTransferEvent = std::dynamic_pointer_cast<IncomingFileTransferEvent>(sourceEvent);
- /* If it's a duplicate subscription request, remove the previous request first */
- if (subscriptionEvent) {
- EventList existingEvents(events_);
- foreach(boost::shared_ptr<StanzaEvent> existingEvent, existingEvents) {
- boost::shared_ptr<SubscriptionRequestEvent> existingSubscriptionEvent = boost::dynamic_pointer_cast<SubscriptionRequestEvent>(existingEvent);
- if (existingSubscriptionEvent) {
- if (existingSubscriptionEvent->getJID() == subscriptionEvent->getJID()) {
- existingEvent->conclude();
- }
- }
- }
- }
+ /* If it's a duplicate subscription request, remove the previous request first */
+ if (subscriptionEvent) {
+ EventList existingEvents(events_);
+ for (auto&& existingEvent : existingEvents) {
+ std::shared_ptr<SubscriptionRequestEvent> existingSubscriptionEvent = std::dynamic_pointer_cast<SubscriptionRequestEvent>(existingEvent);
+ if (existingSubscriptionEvent) {
+ if (existingSubscriptionEvent->getJID() == subscriptionEvent->getJID()) {
+ existingEvent->conclude();
+ }
+ }
+ }
+ }
- if ((messageEvent && messageEvent->isReadable()) || subscriptionEvent || errorEvent || mucInviteEvent || incomingFileTransferEvent) {
- events_.push_back(sourceEvent);
- sourceEvent->onConclusion.connect(boost::bind(&EventController::handleEventConcluded, this, sourceEvent));
- onEventQueueLengthChange(boost::numeric_cast<int>(events_.size()));
- onEventQueueEventAdded(sourceEvent);
- if (sourceEvent->getConcluded()) {
- handleEventConcluded(sourceEvent);
- }
- }
+ if ((messageEvent && messageEvent->isReadable()) || subscriptionEvent || errorEvent || mucInviteEvent || incomingFileTransferEvent) {
+ events_.push_back(sourceEvent);
+ sourceEvent->onConclusion.connect(boost::bind(&EventController::handleEventConcluded, this, sourceEvent));
+ onEventQueueLengthChange(boost::numeric_cast<int>(events_.size()));
+ onEventQueueEventAdded(sourceEvent);
+ if (sourceEvent->getConcluded()) {
+ handleEventConcluded(sourceEvent);
+ }
+ }
}
-void EventController::handleEventConcluded(boost::shared_ptr<StanzaEvent> event) {
- event->onConclusion.disconnect(boost::bind(&EventController::handleEventConcluded, this, event));
- events_.erase(std::remove(events_.begin(), events_.end(), event), events_.end());
- onEventQueueLengthChange(boost::numeric_cast<int>(events_.size()));
+void EventController::handleEventConcluded(std::shared_ptr<StanzaEvent> event) {
+ event->onConclusion.disconnect(boost::bind(&EventController::handleEventConcluded, this, event));
+ events_.erase(std::remove(events_.begin(), events_.end(), event), events_.end());
+ onEventQueueLengthChange(boost::numeric_cast<int>(events_.size()));
}
void EventController::disconnectAll() {
- onEventQueueLengthChange.disconnect_all_slots();
- onEventQueueEventAdded.disconnect_all_slots();
+ onEventQueueLengthChange.disconnect_all_slots();
+ onEventQueueEventAdded.disconnect_all_slots();
}
void EventController::clear() {
- events_.clear();
- onEventQueueLengthChange(0);
+ events_.clear();
+ onEventQueueLengthChange(0);
}
}
diff --git a/Swift/Controllers/XMPPEvents/EventController.h b/Swift/Controllers/XMPPEvents/EventController.h
index 35938ac..8a095d9 100644
--- a/Swift/Controllers/XMPPEvents/EventController.h
+++ b/Swift/Controllers/XMPPEvents/EventController.h
@@ -1,36 +1,35 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <memory>
#include <vector>
-#include <boost/shared_ptr.hpp>
-
-#include <Swiften/Base/boost_bsignals.h>
+#include <boost/signals2.hpp>
#include <Swift/Controllers/XMPPEvents/MessageEvent.h>
#include <Swift/Controllers/XMPPEvents/StanzaEvent.h>
namespace Swift {
- typedef std::vector<boost::shared_ptr<StanzaEvent> > EventList;
- class EventController {
- public:
- EventController();
- ~EventController();
-
- void handleIncomingEvent(boost::shared_ptr<StanzaEvent> sourceEvent);
- boost::signal<void (int)> onEventQueueLengthChange;
- boost::signal<void (boost::shared_ptr<StanzaEvent>)> onEventQueueEventAdded;
- const EventList& getEvents() const {return events_;}
- void disconnectAll();
- void clear();
-
- private:
- void handleEventConcluded(boost::shared_ptr<StanzaEvent> event);
- EventList events_;
- };
+ typedef std::vector<std::shared_ptr<StanzaEvent> > EventList;
+ class EventController {
+ public:
+ EventController();
+ ~EventController();
+
+ void handleIncomingEvent(std::shared_ptr<StanzaEvent> sourceEvent);
+ boost::signals2::signal<void (int)> onEventQueueLengthChange;
+ boost::signals2::signal<void (std::shared_ptr<StanzaEvent>)> onEventQueueEventAdded;
+ const EventList& getEvents() const {return events_;}
+ void disconnectAll();
+ void clear();
+
+ private:
+ void handleEventConcluded(std::shared_ptr<StanzaEvent> event);
+ EventList events_;
+ };
}
diff --git a/Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h b/Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h
index 24af640..3d4303d 100644
--- a/Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h
+++ b/Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h
@@ -1,30 +1,30 @@
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
#include <Swiften/JID/JID.h>
#include <Swift/Controllers/XMPPEvents/StanzaEvent.h>
namespace Swift {
- class IncomingFileTransferEvent : public StanzaEvent {
- public:
- typedef boost::shared_ptr<IncomingFileTransferEvent> ref;
+ class IncomingFileTransferEvent : public StanzaEvent {
+ public:
+ typedef std::shared_ptr<IncomingFileTransferEvent> ref;
- IncomingFileTransferEvent(const JID& sender) : sender_(sender) {}
+ IncomingFileTransferEvent(const JID& sender) : sender_(sender) {}
- const JID& getSender() const {
- return sender_;
- }
+ const JID& getSender() const {
+ return sender_;
+ }
- private:
- JID sender_;
- };
+ private:
+ JID sender_;
+ };
}
diff --git a/Swift/Controllers/XMPPEvents/MUCInviteEvent.h b/Swift/Controllers/XMPPEvents/MUCInviteEvent.h
index 1ae9891..4cdbbff 100644
--- a/Swift/Controllers/XMPPEvents/MUCInviteEvent.h
+++ b/Swift/Controllers/XMPPEvents/MUCInviteEvent.h
@@ -5,43 +5,42 @@
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <memory>
#include <string>
-#include <boost/shared_ptr.hpp>
-
#include <Swiften/JID/JID.h>
#include <Swift/Controllers/XMPPEvents/StanzaEvent.h>
namespace Swift {
- class MUCInviteEvent : public StanzaEvent {
- public:
- typedef boost::shared_ptr<MUCInviteEvent> ref;
-
- public:
- MUCInviteEvent(const JID& inviter, const JID& roomJID, const std::string& reason, const std::string& password, bool direct, bool impromptu) : inviter_(inviter), roomJID_(roomJID), reason_(reason), password_(password), direct_(direct), impromptu_(impromptu) {}
-
- const JID& getInviter() const { return inviter_; }
- const JID& getRoomJID() const { return roomJID_; }
- const std::string& getReason() const { return reason_; }
- const std::string& getPassword() const { return password_; }
- bool getDirect() const { return direct_; }
- bool getImpromptu() const { return impromptu_; }
-
- private:
- JID inviter_;
- JID roomJID_;
- std::string reason_;
- std::string password_;
- bool direct_;
- bool impromptu_;
- };
+ class MUCInviteEvent : public StanzaEvent {
+ public:
+ typedef std::shared_ptr<MUCInviteEvent> ref;
+
+ public:
+ MUCInviteEvent(const JID& inviter, const JID& roomJID, const std::string& reason, const std::string& password, bool direct, bool impromptu) : inviter_(inviter), roomJID_(roomJID), reason_(reason), password_(password), direct_(direct), impromptu_(impromptu) {}
+
+ const JID& getInviter() const { return inviter_; }
+ const JID& getRoomJID() const { return roomJID_; }
+ const std::string& getReason() const { return reason_; }
+ const std::string& getPassword() const { return password_; }
+ bool getDirect() const { return direct_; }
+ bool getImpromptu() const { return impromptu_; }
+
+ private:
+ JID inviter_;
+ JID roomJID_;
+ std::string reason_;
+ std::string password_;
+ bool direct_;
+ bool impromptu_;
+ };
}
diff --git a/Swift/Controllers/XMPPEvents/MessageEvent.h b/Swift/Controllers/XMPPEvents/MessageEvent.h
index b5b1215..7af2be6 100644
--- a/Swift/Controllers/XMPPEvents/MessageEvent.h
+++ b/Swift/Controllers/XMPPEvents/MessageEvent.h
@@ -4,45 +4,44 @@
* See the COPYING file for more information.
*/
-#pragma once
+#pragma once
#include <cassert>
-
-#include <boost/shared_ptr.hpp>
+#include <memory>
#include <Swiften/Elements/Message.h>
#include <Swift/Controllers/XMPPEvents/StanzaEvent.h>
namespace Swift {
- class MessageEvent : public StanzaEvent {
- public:
- typedef boost::shared_ptr<MessageEvent> ref;
+ class MessageEvent : public StanzaEvent {
+ public:
+ typedef std::shared_ptr<MessageEvent> ref;
- MessageEvent(boost::shared_ptr<Message> stanza) : stanza_(stanza), targetsMe_(true) {}
+ MessageEvent(std::shared_ptr<Message> stanza) : stanza_(stanza), targetsMe_(true) {}
- boost::shared_ptr<Message> getStanza() {return stanza_;}
+ std::shared_ptr<Message> getStanza() {return stanza_;}
- bool isReadable() {
- return getStanza()->isError() || !getStanza()->getBody().get_value_or("").empty();
- }
+ bool isReadable() {
+ return getStanza()->isError() || !getStanza()->getBody().get_value_or("").empty();
+ }
- void read() {
- assert (isReadable());
- conclude();
- }
+ void read() {
+ assert (isReadable());
+ conclude();
+ }
- void setTargetsMe(bool targetsMe) {
- targetsMe_ = targetsMe;
- }
+ void setTargetsMe(bool targetsMe) {
+ targetsMe_ = targetsMe;
+ }
- bool targetsMe() const {
- return targetsMe_;
- }
+ bool targetsMe() const {
+ return targetsMe_;
+ }
- private:
- boost::shared_ptr<Message> stanza_;
- bool targetsMe_;
- };
+ private:
+ std::shared_ptr<Message> stanza_;
+ bool targetsMe_;
+ };
}
diff --git a/Swift/Controllers/XMPPEvents/StanzaEvent.h b/Swift/Controllers/XMPPEvents/StanzaEvent.h
index a16aac9..56c4ea3 100644
--- a/Swift/Controllers/XMPPEvents/StanzaEvent.h
+++ b/Swift/Controllers/XMPPEvents/StanzaEvent.h
@@ -1,29 +1,29 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
-#include <boost/date_time/posix_time/posix_time.hpp>
+#include <memory>
-#include "Swiften/Base/boost_bsignals.h"
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/signals2.hpp>
namespace Swift {
- class StanzaEvent {
- public:
- StanzaEvent() : time_(boost::posix_time::microsec_clock::universal_time()) {concluded_ = false;}
- virtual ~StanzaEvent() {}
- void conclude() {concluded_ = true; onConclusion();}
- /** Do not call this directly from outside the class.
- * If you connect to this signal, you *must* disconnect from it manually. */
- boost::signal<void()> onConclusion;
- bool getConcluded() {return concluded_;}
- boost::posix_time::ptime getTime() {return time_;}
- private:
- bool concluded_;
- boost::posix_time::ptime time_;
- };
+ class StanzaEvent {
+ public:
+ StanzaEvent() : time_(boost::posix_time::microsec_clock::universal_time()) {concluded_ = false;}
+ virtual ~StanzaEvent() {}
+ void conclude() {concluded_ = true; onConclusion();}
+ /** Do not call this directly from outside the class.
+ * If you connect to this signal, you *must* disconnect from it manually. */
+ boost::signals2::signal<void()> onConclusion;
+ bool getConcluded() {return concluded_;}
+ boost::posix_time::ptime getTime() {return time_;}
+ private:
+ bool concluded_;
+ boost::posix_time::ptime time_;
+ };
}
diff --git a/Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h b/Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h
index 1eb9cb1..8e3fd32 100644
--- a/Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h
+++ b/Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,40 +7,41 @@
#pragma once
#include <cassert>
+#include <memory>
+#include <string>
-#include "Swiften/Base/boost_bsignals.h"
-#include <boost/shared_ptr.hpp>
+#include <boost/signals2.hpp>
-#include "Swift/Controllers/XMPPEvents/StanzaEvent.h"
-#include <string>
-#include "Swiften/JID/JID.h"
+#include <Swiften/JID/JID.h>
+
+#include <Swift/Controllers/XMPPEvents/StanzaEvent.h>
namespace Swift {
- class SubscriptionRequestEvent : public StanzaEvent {
- public:
- SubscriptionRequestEvent(const JID& jid, const std::string& reason) : jid_(jid), reason_(reason){}
- virtual ~SubscriptionRequestEvent(){}
- const JID& getJID() const {return jid_;}
- const std::string& getReason() const {return reason_;}
- boost::signal<void()> onAccept;
- boost::signal<void()> onDecline;
- void accept() {
- onAccept();
- conclude();
- }
-
- void decline() {
- onDecline();
- conclude();
- }
-
- void defer() {
- conclude();
- }
-
- private:
- JID jid_;
- std::string reason_;
- };
+ class SubscriptionRequestEvent : public StanzaEvent {
+ public:
+ SubscriptionRequestEvent(const JID& jid, const std::string& reason) : jid_(jid), reason_(reason){}
+ virtual ~SubscriptionRequestEvent(){}
+ const JID& getJID() const {return jid_;}
+ const std::string& getReason() const {return reason_;}
+ boost::signals2::signal<void()> onAccept;
+ boost::signals2::signal<void()> onDecline;
+ void accept() {
+ onAccept();
+ conclude();
+ }
+
+ void decline() {
+ onDecline();
+ conclude();
+ }
+
+ void defer() {
+ conclude();
+ }
+
+ private:
+ JID jid_;
+ std::string reason_;
+ };
}
diff --git a/Swift/Controllers/XMPPURIController.cpp b/Swift/Controllers/XMPPURIController.cpp
index 06062e6..aaebd56 100644
--- a/Swift/Controllers/XMPPURIController.cpp
+++ b/Swift/Controllers/XMPPURIController.cpp
@@ -1,38 +1,40 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/Controllers/XMPPURIController.h>
+#include <memory>
+
#include <boost/bind.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+
+#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>
+#include <Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h>
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <SwifTools/URIHandler/URIHandler.h>
#include <SwifTools/URIHandler/XMPPURI.h>
-#include <Swift/Controllers/UIEvents/UIEventStream.h>
-#include <Swift/Controllers/UIEvents/RequestJoinMUCUIEvent.h>
-#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>
using namespace Swift;
XMPPURIController::XMPPURIController(URIHandler* uriHandler, UIEventStream* uiEventStream) : uriHandler(uriHandler), uiEventStream(uiEventStream) {
- uriHandler->onURI.connect(boost::bind(&XMPPURIController::handleURI, this, _1));
+ uriHandler->onURI.connect(boost::bind(&XMPPURIController::handleURI, this, _1));
}
XMPPURIController::~XMPPURIController() {
- uriHandler->onURI.disconnect(boost::bind(&XMPPURIController::handleURI, this, _1));
+ uriHandler->onURI.disconnect(boost::bind(&XMPPURIController::handleURI, this, _1));
}
void XMPPURIController::handleURI(const std::string& s) {
- XMPPURI uri = XMPPURI::fromString(s);
- if (!uri.isNull()) {
- if (uri.getQueryType() == "join") {
- uiEventStream->send(boost::make_shared<RequestJoinMUCUIEvent>(uri.getPath()));
- }
- else {
- uiEventStream->send(boost::make_shared<RequestChatUIEvent>(uri.getPath()));
- }
- }
+ XMPPURI uri = XMPPURI::fromString(s);
+ if (!uri.isNull()) {
+ if (uri.getQueryType() == "join") {
+ uiEventStream->send(std::make_shared<RequestJoinMUCUIEvent>(uri.getPath()));
+ }
+ else {
+ uiEventStream->send(std::make_shared<RequestChatUIEvent>(uri.getPath()));
+ }
+ }
}
diff --git a/Swift/Controllers/XMPPURIController.h b/Swift/Controllers/XMPPURIController.h
index b8a64de..941441f 100644
--- a/Swift/Controllers/XMPPURIController.h
+++ b/Swift/Controllers/XMPPURIController.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,26 +7,27 @@
#pragma once
#include <string>
-#include <Swiften/Base/boost_bsignals.h>
+
+#include <boost/signals2.hpp>
namespace Swift {
- class URIHandler;
- class JID;
- class UIEventStream;
+ class URIHandler;
+ class JID;
+ class UIEventStream;
- class XMPPURIController {
- public:
- XMPPURIController(URIHandler* uriHandler, UIEventStream* uiEventStream);
- ~XMPPURIController();
+ class XMPPURIController {
+ public:
+ XMPPURIController(URIHandler* uriHandler, UIEventStream* uiEventStream);
+ ~XMPPURIController();
- boost::signal<void (const JID&)> onStartChat;
- boost::signal<void (const JID&)> onJoinMUC;
+ boost::signals2::signal<void (const JID&)> onStartChat;
+ boost::signals2::signal<void (const JID&)> onJoinMUC;
- private:
- void handleURI(const std::string&);
+ private:
+ void handleURI(const std::string&);
- private:
- URIHandler* uriHandler;
- UIEventStream* uiEventStream;
- };
+ private:
+ URIHandler* uriHandler;
+ UIEventStream* uiEventStream;
+ };
}
diff --git a/Swift/Packaging/Debian/debian/control.in b/Swift/Packaging/Debian/debian/control.in
index 8583ebf..68a52de 100644
--- a/Swift/Packaging/Debian/debian/control.in
+++ b/Swift/Packaging/Debian/debian/control.in
@@ -3,7 +3,7 @@ Section: net
Priority: optional
Maintainer: Swift Package Maintainer <packages@swift.im>
Uploaders: Remko Tronçon <dev@el-tramo.be>, Kevin Smith <kevin@kismith.co.uk>
-Build-Depends: debhelper (>= 9), scons (>= 1.2.0), libssl-dev (>= 0.9.8g), qtbase5-dev (>= 5.0.0), qtchooser, qtbase5-dev-tools (>= 5.0.0), libqt5x11extras5-dev (>= 5.0.0), libqt5webkit5-dev (>= 5.0.0), qtmultimedia5-dev (>=5.0.0), qttools5-dev-tools (>=5.0.0), libxml2-dev (>= 2.7.6), libxss-dev (>= 1.2.0), libboost-dev (>= 1.34.1), libboost-filesystem-dev (>= 1.34.1), libboost-program-options-dev (>= 1.34.1), libboost-regex-dev (>= 1.34.1), libboost-signals-dev (>= 1.34.1), libboost-system-dev (>= 1.34.1), libboost-thread-dev (>= 1.34.1), libboost-date-time-dev (>= 1.34.1), libidn11-dev (>= 1.10), docbook-xsl (>= 1.75.0), docbook-xml (>= 4.5), xsltproc, libxml2-utils, libnatpmp-dev, libminiupnpc-dev, libsqlite3-dev, zlib1g-dev
+Build-Depends: debhelper (>= 9), scons (>= 1.2.0), libssl-dev (>= 0.9.8g), qtbase5-dev (>= 5.0.0), qtchooser, qtbase5-dev-tools (>= 5.0.0), libqt5x11extras5-dev (>= 5.0.0), libqt5webkit5-dev (>= 5.0.0), qtmultimedia5-dev (>=5.0.0), qttools5-dev-tools (>=5.0.0), qt5-image-formats-plugins (>=5.0.0), libqt5svg5 (>=5.0.0), libxml2-dev (>= 2.7.6), libxss-dev (>= 1.2.0), libboost-dev (>= 1.34.1), libboost-filesystem-dev (>= 1.34.1), libboost-program-options-dev (>= 1.34.1), libboost-regex-dev (>= 1.34.1), libboost-signals-dev (>= 1.34.1), libboost-system-dev (>= 1.34.1), libboost-thread-dev (>= 1.34.1), libboost-date-time-dev (>= 1.34.1), libidn11-dev (>= 1.10), docbook-xsl (>= 1.75.0), docbook-xml (>= 4.5), xsltproc, libxml2-utils, libnatpmp-dev, libminiupnpc-dev, libsqlite3-dev, libhunspell-dev, zlib1g-dev
Standards-Version: 3.9.8
Vcs-Git: git://swift.im/swift
Vcs-Browser: http://swift.im/git/swift
diff --git a/Swift/Packaging/Debian/package_all_platforms.sh b/Swift/Packaging/Debian/package_all_platforms.sh
index 1773515..4d1ef3c 100755
--- a/Swift/Packaging/Debian/package_all_platforms.sh
+++ b/Swift/Packaging/Debian/package_all_platforms.sh
@@ -24,7 +24,7 @@ export SWIFT_FORCE_LUCID="yep"
unset SWIFT_FORCE_LUCID
./package.sh
-for distro in trusty wily jessie sid; do
+for distro in trusty xenial jessie sid; do
for arch in amd64; do
pbuilder-dist $distro $arch build *.dsc
done
diff --git a/Swift/Packaging/MacOSX/Swift.dmg.gz b/Swift/Packaging/MacOSX/Swift.dmg.gz
index ba8ccf7..ca2b520 100644
--- a/Swift/Packaging/MacOSX/Swift.dmg.gz
+++ b/Swift/Packaging/MacOSX/Swift.dmg.gz
Binary files differ
diff --git a/Swift/Packaging/MacOSX/package.sh b/Swift/Packaging/MacOSX/package.sh
index a13a03c..7a63237 100755
--- a/Swift/Packaging/MacOSX/package.sh
+++ b/Swift/Packaging/MacOSX/package.sh
@@ -4,6 +4,7 @@ APP=$1
TEMPLATE=$2
TARGET=$3
QTDIR=$4
+CODESIGN_IDENTITY=$5
if [[ ! -f "$TEMPLATE" || ! -d "$APP" || ! -d "$QTDIR" || -z "$TARGET" ]]; then
echo "Error"
@@ -30,6 +31,11 @@ rm "$WC_DIR"/`basename $APP`/Contents/PlugIns/bearer/*.dylib
# Remove debugging symbols from the application bundle
rm -rf "$WC_DIR"/`basename $APP`/Contents/MacOS/*.dSYM
+# Codesign the app bundle if requested by caller
+if [ ! -z "$CODESIGN_IDENTITY" ]; then
+ codesign --verbose --force --deep --sign "$CODESIGN_IDENTITY" "$WC_DIR"/`basename $APP`
+fi
+
hdiutil detach "$WC_DIR" -quiet -force
rm -f $TARGET
hdiutil convert "$WC_DMG" -quiet -format UDZO -imagekey zlib-level=9 -o "$TARGET"
diff --git a/Swift/Packaging/Source/package.sh b/Swift/Packaging/Source/package.sh
index 16a9a1f..3872b35 100755
--- a/Swift/Packaging/Source/package.sh
+++ b/Swift/Packaging/Source/package.sh
@@ -3,9 +3,13 @@
## For a Swiften-only tarball, try
## EXCLUDE_FOLDERS="Swift Sluift Limber Slimber" ./package.sh
+## This script will require GPG and a suitable signing key by default.
+## To disable tarball signature generation, pass the --nosign parameter to package.sh.
+
export PYTHONPATH=../../../BuildTools/SCons
VERSION=`../../../BuildTools/GetBuildVersion.py swift`
DIRNAME=swift-$VERSION
+FIRST_ARGUMENT=$1
if [ -z "$VERSION" ]; then
echo "Unable to determine version"
@@ -40,3 +44,20 @@ done
echo "Creating tarball ..."
$TAR -czf $DIRNAME.tar.gz --owner=swift --group=swift $DIRNAME
+
+if [ "$FIRST_ARGUMENT" != "--nosign" ]; then
+ echo "Creating armored GPG signature ..."
+ which gpg
+ if [ $? -eq 0 ]; then
+ gpg --list-keys packages@swift.im
+ if [ $? -eq 0 ]; then
+ gpg --armor --default-key packages@swift.im --detach-sign $DIRNAME.tar.gz
+ else
+ echo "Key for packages@swift.im missing. Not signing tar archive."
+ exit 1
+ fi
+ else
+ echo "GPG not found. Not signing tar archive."
+ exit 1
+ fi
+fi \ No newline at end of file
diff --git a/Swift/QtUI/ApplicationTest/main.cpp b/Swift/QtUI/ApplicationTest/main.cpp
index abaddf6..782bbf1 100644
--- a/Swift/QtUI/ApplicationTest/main.cpp
+++ b/Swift/QtUI/ApplicationTest/main.cpp
@@ -1,45 +1,48 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
+#include <string>
+
#include <QApplication>
-#include <QWidget>
-#include <QVBoxLayout>
#include <QLineEdit>
-#include "../QtSwiftUtil.h"
-#include <string>
-#include "SwifTools/Application/Platform/PlatformApplication.h"
+#include <QVBoxLayout>
+#include <QWidget>
+
+#include <SwifTools/Application/Platform/PlatformApplication.h>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
using namespace Swift;
class MyWidget : public QWidget {
- Q_OBJECT
-
- public:
- MyWidget() : application_("MyApplication") {
- QVBoxLayout *layout = new QVBoxLayout(this);
- input_ = new QLineEdit(this);
- layout->addWidget(input_);
- connect(input_, SIGNAL(returnPressed()), SLOT(handleReturnPressed()));
- }
-
- private slots:
- void handleReturnPressed() {
- application_.getApplicationMessageDisplay()->setMessage(Q2PSTRING(input_->text()));
- }
-
- private:
- PlatformApplication application_;
- QLineEdit* input_;
+ Q_OBJECT
+
+ public:
+ MyWidget() : application_("MyApplication") {
+ QVBoxLayout *layout = new QVBoxLayout(this);
+ input_ = new QLineEdit(this);
+ layout->addWidget(input_);
+ connect(input_, SIGNAL(returnPressed()), SLOT(handleReturnPressed()));
+ }
+
+ private slots:
+ void handleReturnPressed() {
+ application_.getApplicationMessageDisplay()->setMessage(Q2PSTRING(input_->text()));
+ }
+
+ private:
+ PlatformApplication application_;
+ QLineEdit* input_;
};
int main(int argc, char* argv[]) {
- QApplication app(argc, argv);
- MyWidget widget;
- widget.show();
- return app.exec();
+ QApplication app(argc, argv);
+ MyWidget widget;
+ widget.show();
+ return app.exec();
}
#include "main.moc"
diff --git a/Swift/QtUI/CAPICertificateSelector.cpp b/Swift/QtUI/CAPICertificateSelector.cpp
index 953051b..36d8c54 100644
--- a/Swift/QtUI/CAPICertificateSelector.cpp
+++ b/Swift/QtUI/CAPICertificateSelector.cpp
@@ -23,94 +23,94 @@
namespace Swift {
/////Hmm, maybe we should not exlude the "location" column
-#define exclude_columns CRYPTUI_SELECT_LOCATION_COLUMN | CRYPTUI_SELECT_INTENDEDUSE_COLUMN
+#define exclude_columns CRYPTUI_SELECT_LOCATION_COLUMN | CRYPTUI_SELECT_INTENDEDUSE_COLUMN
#define SHA1_HASH_LENGTH 20
static std::string getCertUri(PCCERT_CONTEXT cert, const char * cert_store_name) {
- DWORD cbHash = SHA1_HASH_LENGTH;
- BYTE aHash[SHA1_HASH_LENGTH];
- std::string result("certstore:");
+ DWORD cbHash = SHA1_HASH_LENGTH;
+ BYTE aHash[SHA1_HASH_LENGTH];
+ std::string result("certstore:");
- result += cert_store_name;
- result += ":sha1:";
+ result += cert_store_name;
+ result += ":sha1:";
- if (CertGetCertificateContextProperty(cert, CERT_HASH_PROP_ID, aHash, &cbHash) == FALSE ) {
- return "";
- }
+ if (CertGetCertificateContextProperty(cert, CERT_HASH_PROP_ID, aHash, &cbHash) == FALSE ) {
+ return "";
+ }
- ByteArray byteArray = createByteArray((char *)(&aHash[0]), cbHash);
- result += Hexify::hexify(byteArray);
+ ByteArray byteArray = createByteArray((char *)(&aHash[0]), cbHash);
+ result += Hexify::hexify(byteArray);
- return result;
+ return result;
}
std::string selectCAPICertificate() {
- const char* certStoreName = "MY";
+ const char* certStoreName = "MY";
- DWORD storeFlags = CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_CURRENT_USER;
+ DWORD storeFlags = CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG | CERT_SYSTEM_STORE_CURRENT_USER;
- HCERTSTORE hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0, storeFlags, certStoreName);
- if (!hstore) {
- return "";
- }
+ HCERTSTORE hstore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0, storeFlags, certStoreName);
+ if (!hstore) {
+ return "";
+ }
- HWND hwnd = GetForegroundWindow();
- if (!hwnd) {
- hwnd = GetActiveWindow();
- }
+ HWND hwnd = GetForegroundWindow();
+ if (!hwnd) {
+ hwnd = GetActiveWindow();
+ }
- std::string certificateDialogTitle = QT_TRANSLATE_NOOP("", "TLS Client Certificate Selection");
- std::string certificateDialogPrompt = QT_TRANSLATE_NOOP("", "Select a certificate to use for authentication");
+ std::string certificateDialogTitle = QT_TRANSLATE_NOOP("", "TLS Client Certificate Selection");
+ std::string certificateDialogPrompt = QT_TRANSLATE_NOOP("", "Select a certificate to use for authentication");
- int titleLength = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, certificateDialogTitle.c_str(), -1, NULL, 0);
- int promptLength = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, certificateDialogPrompt.c_str(), -1, NULL, 0);
+ int titleLength = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, certificateDialogTitle.c_str(), -1, NULL, 0);
+ int promptLength = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, certificateDialogPrompt.c_str(), -1, NULL, 0);
- wchar_t* titleChars = new wchar_t[titleLength];
- wchar_t* promptChars = new wchar_t[promptLength];
+ wchar_t* titleChars = new wchar_t[titleLength];
+ wchar_t* promptChars = new wchar_t[promptLength];
- //titleChars[titleLength] = '\0';
- //promptChars[promptLength] = '\0';
+ //titleChars[titleLength] = '\0';
+ //promptChars[promptLength] = '\0';
- titleLength = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, certificateDialogTitle.c_str(), -1, titleChars, titleLength);
- promptLength = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, certificateDialogPrompt.c_str(), -1, promptChars, promptLength);
+ titleLength = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, certificateDialogTitle.c_str(), -1, titleChars, titleLength);
+ promptLength = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, certificateDialogPrompt.c_str(), -1, promptChars, promptLength);
- if (titleLength == 0 || promptLength == 0) {
- int error = GetLastError();
- switch (error) {
- case ERROR_INSUFFICIENT_BUFFER: SWIFT_LOG(error) << "Insufficient buffer for rendering cert dialog" << std::endl;break;
- case ERROR_INVALID_FLAGS: SWIFT_LOG(error) << "Invalid flags for rendering cert dialog" << std::endl;break;
- case ERROR_INVALID_PARAMETER: SWIFT_LOG(error) << "Invalid parameter for rendering cert dialog" << std::endl;break;
- case ERROR_NO_UNICODE_TRANSLATION: SWIFT_LOG(error) << "Invalid unicode for rendering cert dialog" << std::endl;break;
- default: SWIFT_LOG(error) << "Unexpected multibyte conversion errorcode" << std::endl;
+ if (titleLength == 0 || promptLength == 0) {
+ int error = GetLastError();
+ switch (error) {
+ case ERROR_INSUFFICIENT_BUFFER: SWIFT_LOG(error) << "Insufficient buffer for rendering cert dialog" << std::endl;break;
+ case ERROR_INVALID_FLAGS: SWIFT_LOG(error) << "Invalid flags for rendering cert dialog" << std::endl;break;
+ case ERROR_INVALID_PARAMETER: SWIFT_LOG(error) << "Invalid parameter for rendering cert dialog" << std::endl;break;
+ case ERROR_NO_UNICODE_TRANSLATION: SWIFT_LOG(error) << "Invalid unicode for rendering cert dialog" << std::endl;break;
+ default: SWIFT_LOG(error) << "Unexpected multibyte conversion errorcode" << std::endl;
- }
- }
+ }
+ }
-
- /* Call Windows dialog to select a suitable certificate */
- PCCERT_CONTEXT cert = CryptUIDlgSelectCertificateFromStore(hstore, hwnd, titleChars, promptChars, exclude_columns, 0, NULL);
- delete[] titleChars;
- delete[] promptChars;
+ /* Call Windows dialog to select a suitable certificate */
+ PCCERT_CONTEXT cert = CryptUIDlgSelectCertificateFromStore(hstore, hwnd, titleChars, promptChars, exclude_columns, 0, NULL);
- if (hstore) {
- CertCloseStore(hstore, 0);
- }
+ delete[] titleChars;
+ delete[] promptChars;
- std::string result;
+ if (hstore) {
+ CertCloseStore(hstore, 0);
+ }
- if (cert) {
- result = getCertUri(cert, certStoreName);
- CertFreeCertificateContext(cert);
- }
+ std::string result;
- return result;
+ if (cert) {
+ result = getCertUri(cert, certStoreName);
+ CertFreeCertificateContext(cert);
+ }
+
+ return result;
}
bool isCAPIURI(std::string uri) {
- return (boost::iequals(uri.substr(0, 10), "certstore:"));
+ return (boost::iequals(uri.substr(0, 10), "certstore:"));
}
}
diff --git a/Swift/QtUI/CAPICertificateSelector.h b/Swift/QtUI/CAPICertificateSelector.h
index 714f1c5..8273c78 100644
--- a/Swift/QtUI/CAPICertificateSelector.h
+++ b/Swift/QtUI/CAPICertificateSelector.h
@@ -9,6 +9,6 @@
#include <string>
namespace Swift {
- std::string selectCAPICertificate();
- bool isCAPIURI(std::string uri);
+ std::string selectCAPICertificate();
+ bool isCAPIURI(std::string uri);
}
diff --git a/Swift/QtUI/ChatList/ChatListDelegate.cpp b/Swift/QtUI/ChatList/ChatListDelegate.cpp
index 5fa4e23..f818e50 100644
--- a/Swift/QtUI/ChatList/ChatListDelegate.cpp
+++ b/Swift/QtUI/ChatList/ChatListDelegate.cpp
@@ -1,11 +1,12 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/ChatList/ChatListDelegate.h>
+#include <QColor>
#include <QPainter>
#include <QPen>
@@ -18,126 +19,130 @@
namespace Swift {
+namespace {
+ const QColor secondLineColor = QColor(160,160,160);
+}
+
ChatListDelegate::ChatListDelegate(bool compact) : compact_(compact) {
- groupDelegate_ = new GroupItemDelegate();
+ groupDelegate_ = new GroupItemDelegate();
}
ChatListDelegate::~ChatListDelegate() {
- delete groupDelegate_;
+ delete groupDelegate_;
}
void ChatListDelegate::setCompact(bool compact) {
- compact_ = compact;
- emit sizeHintChanged(QModelIndex());
+ compact_ = compact;
+ emit sizeHintChanged(QModelIndex());
}
QSize ChatListDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index ) const {
- ChatListItem* item = static_cast<ChatListItem*>(index.internalPointer());
- if (item && dynamic_cast<ChatListMUCItem*>(item)) {
- return mucSizeHint(option, index);
- }
- else if (item && dynamic_cast<ChatListRecentItem*>(item)) {
- return common_.contactSizeHint(option, index, compact_);
- }
- else if (item && dynamic_cast<ChatListGroupItem*>(item)) {
- return groupDelegate_->sizeHint(option, index);
- }
- else if (item && dynamic_cast<ChatListWhiteboardItem*>(item)) {
- return common_.contactSizeHint(option, index, compact_);
- }
- return QStyledItemDelegate::sizeHint(option, index);
+ ChatListItem* item = static_cast<ChatListItem*>(index.internalPointer());
+ if (item && dynamic_cast<ChatListMUCItem*>(item)) {
+ return mucSizeHint(option, index);
+ }
+ else if (item && dynamic_cast<ChatListRecentItem*>(item)) {
+ return common_.contactSizeHint(option, index, compact_);
+ }
+ else if (item && dynamic_cast<ChatListGroupItem*>(item)) {
+ return groupDelegate_->sizeHint(option, index);
+ }
+ else if (item && dynamic_cast<ChatListWhiteboardItem*>(item)) {
+ return common_.contactSizeHint(option, index, compact_);
+ }
+ return QStyledItemDelegate::sizeHint(option, index);
}
QSize ChatListDelegate::mucSizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/ ) const {
- QFontMetrics nameMetrics(common_.nameFont);
- QFontMetrics statusMetrics(common_.detailFont);
- int sizeByText = 2 * common_.verticalMargin + nameMetrics.height() + statusMetrics.height();
- return QSize(150, sizeByText);
+ QFontMetrics nameMetrics(common_.nameFont);
+ QFontMetrics statusMetrics(common_.detailFont);
+ int sizeByText = 2 * common_.verticalMargin + nameMetrics.height() + statusMetrics.height();
+ return QSize(150, sizeByText);
}
QSize ChatListDelegate::recentSizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const {
- return mucSizeHint(option, index);
+ return mucSizeHint(option, index);
}
void ChatListDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
- ChatListItem* item = static_cast<ChatListItem*>(index.internalPointer());
- if (item && dynamic_cast<ChatListMUCItem*>(item)) {
- paintMUC(painter, option, dynamic_cast<ChatListMUCItem*>(item));
- }
- else if (item && dynamic_cast<ChatListRecentItem*>(item)) {
- paintRecent(painter, option, dynamic_cast<ChatListRecentItem*>(item));
- }
- else if (item && dynamic_cast<ChatListGroupItem*>(item)) {
- ChatListGroupItem* group = dynamic_cast<ChatListGroupItem*>(item);
- groupDelegate_->paint(painter, option, group->data(Qt::DisplayRole).toString(), group->rowCount(), option.state & QStyle::State_Open);
- }
- else if (item && dynamic_cast<ChatListWhiteboardItem*>(item)) {
- paintWhiteboard(painter, option, dynamic_cast<ChatListWhiteboardItem*>(item));
- }
- else {
- QStyledItemDelegate::paint(painter, option, index);
- }
+ ChatListItem* item = static_cast<ChatListItem*>(index.internalPointer());
+ if (item && dynamic_cast<ChatListMUCItem*>(item)) {
+ paintMUC(painter, option, dynamic_cast<ChatListMUCItem*>(item));
+ }
+ else if (item && dynamic_cast<ChatListRecentItem*>(item)) {
+ paintRecent(painter, option, dynamic_cast<ChatListRecentItem*>(item));
+ }
+ else if (item && dynamic_cast<ChatListGroupItem*>(item)) {
+ ChatListGroupItem* group = dynamic_cast<ChatListGroupItem*>(item);
+ groupDelegate_->paint(painter, option, group->data(Qt::DisplayRole).toString(), group->rowCount(), option.state & QStyle::State_Open);
+ }
+ else if (item && dynamic_cast<ChatListWhiteboardItem*>(item)) {
+ paintWhiteboard(painter, option, dynamic_cast<ChatListWhiteboardItem*>(item));
+ }
+ else {
+ QStyledItemDelegate::paint(painter, option, index);
+ }
}
void ChatListDelegate::paintMUC(QPainter* painter, const QStyleOptionViewItem& option, ChatListMUCItem* item) const {
- painter->save();
- QRect fullRegion(option.rect);
- if ( option.state & QStyle::State_Selected ) {
- painter->fillRect(fullRegion, option.palette.highlight());
- painter->setPen(option.palette.highlightedText().color());
- } else {
- QColor nameColor = item->data(Qt::TextColorRole).value<QColor>();
- painter->setPen(QPen(nameColor));
- }
-
- QFontMetrics nameMetrics(common_.nameFont);
- painter->setFont(common_.nameFont);
- int extraFontWidth = nameMetrics.width("H");
- int leftOffset = common_.horizontalMargin * 2 + extraFontWidth / 2;
- QRect textRegion(fullRegion.adjusted(leftOffset, 0, 0, 0));
-
- int nameHeight = nameMetrics.height() + common_.verticalMargin;
- QRect nameRegion(textRegion.adjusted(0, common_.verticalMargin, 0, 0));
-
- DelegateCommons::drawElidedText(painter, nameRegion, item->data(Qt::DisplayRole).toString());
-
- painter->setFont(common_.detailFont);
- painter->setPen(QPen(QColor(160,160,160)));
-
- QRect detailRegion(textRegion.adjusted(0, nameHeight, 0, 0));
- DelegateCommons::drawElidedText(painter, detailRegion, item->data(ChatListMUCItem::DetailTextRole).toString());
-
- painter->restore();
+ painter->save();
+ QRect fullRegion(option.rect);
+ if ( option.state & QStyle::State_Selected ) {
+ painter->fillRect(fullRegion, option.palette.highlight());
+ painter->setPen(option.palette.highlightedText().color());
+ } else {
+ QColor nameColor = item->data(Qt::TextColorRole).value<QColor>();
+ painter->setPen(QPen(nameColor));
+ }
+
+ QFontMetrics nameMetrics(common_.nameFont);
+ painter->setFont(common_.nameFont);
+ int extraFontWidth = nameMetrics.width("H");
+ int leftOffset = common_.horizontalMargin * 2 + extraFontWidth / 2;
+ QRect textRegion(fullRegion.adjusted(leftOffset, 0, 0, 0));
+
+ int nameHeight = nameMetrics.height() + common_.verticalMargin;
+ QRect nameRegion(textRegion.adjusted(0, common_.verticalMargin, 0, 0));
+
+ DelegateCommons::drawElidedText(painter, nameRegion, item->data(Qt::DisplayRole).toString());
+
+ painter->setFont(common_.detailFont);
+ painter->setPen(QPen(secondLineColor));
+
+ QRect detailRegion(textRegion.adjusted(0, nameHeight, 0, 0));
+ DelegateCommons::drawElidedText(painter, detailRegion, item->data(ChatListMUCItem::DetailTextRole).toString());
+
+ painter->restore();
}
void ChatListDelegate::paintRecent(QPainter* painter, const QStyleOptionViewItem& option, ChatListRecentItem* item) const {
- QColor nameColor = item->data(Qt::TextColorRole).value<QColor>();
- QString avatarPath;
- if (item->data(ChatListRecentItem::AvatarRole).isValid() && !item->data(ChatListRecentItem::AvatarRole).value<QString>().isNull()) {
- avatarPath = item->data(ChatListRecentItem::AvatarRole).value<QString>();
- }
- QIcon presenceIcon = item->data(ChatListRecentItem::PresenceIconRole).isValid() && !item->data(ChatListRecentItem::PresenceIconRole).value<QIcon>().isNull()
- ? item->data(ChatListRecentItem::PresenceIconRole).value<QIcon>()
- : QIcon(":/icons/offline.png");
- QString name = item->data(Qt::DisplayRole).toString();
- //qDebug() << "Avatar for " << name << " = " << avatarPath;
- QString statusText = item->data(ChatListRecentItem::DetailTextRole).toString();
- common_.paintContact(painter, option, nameColor, avatarPath, presenceIcon, name, statusText, false, item->getChat().unreadCount, compact_);
+ QColor nameColor = item->data(Qt::TextColorRole).value<QColor>();
+ QString avatarPath;
+ if (item->data(ChatListRecentItem::AvatarRole).isValid() && !item->data(ChatListRecentItem::AvatarRole).value<QString>().isNull()) {
+ avatarPath = item->data(ChatListRecentItem::AvatarRole).value<QString>();
+ }
+ QIcon presenceIcon = item->data(ChatListRecentItem::PresenceIconRole).isValid() && !item->data(ChatListRecentItem::PresenceIconRole).value<QIcon>().isNull()
+ ? item->data(ChatListRecentItem::PresenceIconRole).value<QIcon>()
+ : QIcon(":/icons/offline.png");
+ QString name = item->data(Qt::DisplayRole).toString();
+ //qDebug() << "Avatar for " << name << " = " << avatarPath;
+ QString statusText = item->data(ChatListRecentItem::DetailTextRole).toString();
+ common_.paintContact(painter, option, nameColor, avatarPath, presenceIcon, name, statusText, false, item->getChat().unreadCount, compact_);
}
void ChatListDelegate::paintWhiteboard(QPainter* painter, const QStyleOptionViewItem& option, ChatListWhiteboardItem* item) const {
- QColor nameColor = item->data(Qt::TextColorRole).value<QColor>();
- QString avatarPath;
- if (item->data(ChatListWhiteboardItem::AvatarRole).isValid() && !item->data(ChatListWhiteboardItem::AvatarRole).value<QString>().isNull()) {
- avatarPath = item->data(ChatListWhiteboardItem::AvatarRole).value<QString>();
- }
- QIcon presenceIcon;/* = item->data(ChatListWhiteboardItem::PresenceIconRole).isValid() && !item->data(ChatListWhiteboardItem::PresenceIconRole).value<QIcon>().isNull()
- ? item->data(ChatListWhiteboardItem::PresenceIconRole).value<QIcon>()
- : QIcon(":/icons/offline.png");*/
- QString name = item->data(Qt::DisplayRole).toString();
- //qDebug() << "Avatar for " << name << " = " << avatarPath;
- QString statusText = item->data(ChatListWhiteboardItem::DetailTextRole).toString();
- common_.paintContact(painter, option, nameColor, avatarPath, presenceIcon, name, statusText, false, item->getChat().unreadCount, compact_);
+ QColor nameColor = item->data(Qt::TextColorRole).value<QColor>();
+ QString avatarPath;
+ if (item->data(ChatListWhiteboardItem::AvatarRole).isValid() && !item->data(ChatListWhiteboardItem::AvatarRole).value<QString>().isNull()) {
+ avatarPath = item->data(ChatListWhiteboardItem::AvatarRole).value<QString>();
+ }
+ QIcon presenceIcon;/* = item->data(ChatListWhiteboardItem::PresenceIconRole).isValid() && !item->data(ChatListWhiteboardItem::PresenceIconRole).value<QIcon>().isNull()
+ ? item->data(ChatListWhiteboardItem::PresenceIconRole).value<QIcon>()
+ : QIcon(":/icons/offline.png");*/
+ QString name = item->data(Qt::DisplayRole).toString();
+ //qDebug() << "Avatar for " << name << " = " << avatarPath;
+ QString statusText = item->data(ChatListWhiteboardItem::DetailTextRole).toString();
+ common_.paintContact(painter, option, nameColor, avatarPath, presenceIcon, name, statusText, false, item->getChat().unreadCount, compact_);
}
diff --git a/Swift/QtUI/ChatList/ChatListDelegate.h b/Swift/QtUI/ChatList/ChatListDelegate.h
index eca22d8..44ca947 100644
--- a/Swift/QtUI/ChatList/ChatListDelegate.h
+++ b/Swift/QtUI/ChatList/ChatListDelegate.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2011 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,31 +8,31 @@
#include <QStyledItemDelegate>
-#include "Swift/QtUI/Roster/GroupItemDelegate.h"
+#include <Swift/QtUI/Roster/GroupItemDelegate.h>
namespace Swift {
- class ChatListMUCItem;
- class ChatListRecentItem;
- class ChatListWhiteboardItem;
- class ChatListDelegate : public QStyledItemDelegate {
- public:
- ChatListDelegate(bool compact);
- ~ChatListDelegate();
- QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
- void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
- public slots:
- void setCompact(bool compact);
- private:
- void paintMUC(QPainter* painter, const QStyleOptionViewItem& option, ChatListMUCItem* item) const;
- void paintRecent(QPainter* painter, const QStyleOptionViewItem& option, ChatListRecentItem* item) const;
- void paintWhiteboard(QPainter* painter, const QStyleOptionViewItem& option, ChatListWhiteboardItem* item) const;
- QSize mucSizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/ ) const;
- QSize recentSizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/ ) const;
+ class ChatListMUCItem;
+ class ChatListRecentItem;
+ class ChatListWhiteboardItem;
+ class ChatListDelegate : public QStyledItemDelegate {
+ public:
+ ChatListDelegate(bool compact);
+ ~ChatListDelegate();
+ QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ public slots:
+ void setCompact(bool compact);
+ private:
+ void paintMUC(QPainter* painter, const QStyleOptionViewItem& option, ChatListMUCItem* item) const;
+ void paintRecent(QPainter* painter, const QStyleOptionViewItem& option, ChatListRecentItem* item) const;
+ void paintWhiteboard(QPainter* painter, const QStyleOptionViewItem& option, ChatListWhiteboardItem* item) const;
+ QSize mucSizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/ ) const;
+ QSize recentSizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/ ) const;
- bool compact_;
- DelegateCommons common_;
- GroupItemDelegate* groupDelegate_;
- };
+ bool compact_;
+ DelegateCommons common_;
+ GroupItemDelegate* groupDelegate_;
+ };
}
diff --git a/Swift/QtUI/ChatList/ChatListGroupItem.h b/Swift/QtUI/ChatList/ChatListGroupItem.h
index 2b6534a..a9bb9b1 100644
--- a/Swift/QtUI/ChatList/ChatListGroupItem.h
+++ b/Swift/QtUI/ChatList/ChatListGroupItem.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,38 +8,35 @@
#include <QList>
-#include <Swiften/Base/foreach.h>
-
-#include "Swift/QtUI/ChatList/ChatListItem.h"
+#include <Swift/QtUI/ChatList/ChatListItem.h>
namespace Swift {
- class ChatListGroupItem : public ChatListItem {
- public:
- ChatListGroupItem(const QString& name, ChatListGroupItem* parent, bool sorted = true) : ChatListItem(parent), name_(name), sorted_(sorted) {}
- virtual ~ChatListGroupItem() {clear();}
- void addItem(ChatListItem* item) {items_.push_back(item); if (sorted_) {qStableSort(items_.begin(), items_.end(), pointerItemLessThan);}}
- void remove(int index) {items_.removeAt(index);}
- int rowCount() {return items_.size();}
- ChatListItem* item(int i) {return items_[i];}
- int row(ChatListItem* item) {return items_.indexOf(item);}
- QVariant data(int role) const {return (role == Qt::DisplayRole) ? name_ : QVariant();}
- void clear() {
- foreach (ChatListItem* item, items_) {
- delete item;
- }
- items_.clear();
- }
-
-
- private:
- static bool pointerItemLessThan(const ChatListItem* first, const ChatListItem* second) {
- QString myName = first->data(Qt::DisplayRole).toString().toLower();
- QString theirName = second->data(Qt::DisplayRole).toString().toLower();
- return myName < theirName;
- }
-
- QString name_;
- QList<ChatListItem*> items_;
- bool sorted_;
- };
+ class ChatListGroupItem : public ChatListItem {
+ public:
+ ChatListGroupItem(const QString& name, ChatListGroupItem* parent, bool sorted = true) : ChatListItem(parent), name_(name), sorted_(sorted) {}
+ virtual ~ChatListGroupItem() {clear();}
+ void addItem(ChatListItem* item) {items_.push_back(item); if (sorted_) {qStableSort(items_.begin(), items_.end(), pointerItemLessThan);}}
+ void remove(int index) {items_.removeAt(index);}
+ int rowCount() {return items_.size();}
+ ChatListItem* item(int i) {return items_[i];}
+ int row(ChatListItem* item) {return items_.indexOf(item);}
+ QVariant data(int role) const {return (role == Qt::DisplayRole) ? name_ : QVariant();}
+ void clear() {
+ for (auto item : items_) {
+ delete item;
+ }
+ items_.clear();
+ }
+
+ private:
+ static bool pointerItemLessThan(const ChatListItem* first, const ChatListItem* second) {
+ QString myName = first->data(Qt::DisplayRole).toString().toLower();
+ QString theirName = second->data(Qt::DisplayRole).toString().toLower();
+ return myName < theirName;
+ }
+
+ QString name_;
+ QList<ChatListItem*> items_;
+ bool sorted_;
+ };
}
diff --git a/Swift/QtUI/ChatList/ChatListItem.h b/Swift/QtUI/ChatList/ChatListItem.h
index 423e0ec..c6fd762 100644
--- a/Swift/QtUI/ChatList/ChatListItem.h
+++ b/Swift/QtUI/ChatList/ChatListItem.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,19 +7,20 @@
#pragma once
#include <QVariant>
+
#include <qdebug.h>
namespace Swift {
- class ChatListGroupItem;
- class ChatListItem {
- public:
- ChatListItem(ChatListGroupItem* parent) {parent_ = parent;}
- virtual ~ChatListItem() {}
+ class ChatListGroupItem;
+ class ChatListItem {
+ public:
+ ChatListItem(ChatListGroupItem* parent) {parent_ = parent;}
+ virtual ~ChatListItem() {}
- ChatListGroupItem* parent() {return parent_;}
- virtual QVariant data(int role) const = 0;
+ ChatListGroupItem* parent() {return parent_;}
+ virtual QVariant data(int role) const = 0;
- private:
- ChatListGroupItem* parent_;
- };
+ private:
+ ChatListGroupItem* parent_;
+ };
}
diff --git a/Swift/QtUI/ChatList/ChatListMUCItem.cpp b/Swift/QtUI/ChatList/ChatListMUCItem.cpp
index 1eb614b..e701ddc 100644
--- a/Swift/QtUI/ChatList/ChatListMUCItem.cpp
+++ b/Swift/QtUI/ChatList/ChatListMUCItem.cpp
@@ -1,12 +1,14 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/QtUI/ChatList/ChatListMUCItem.h"
+#include <Swift/QtUI/ChatList/ChatListMUCItem.h>
-#include "Swift/QtUI/QtSwiftUtil.h"
+#include <QColor>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
ChatListMUCItem::ChatListMUCItem(const MUCBookmark& bookmark, ChatListGroupItem* parent) : ChatListItem(parent), bookmark_(bookmark) {
@@ -14,21 +16,21 @@ ChatListMUCItem::ChatListMUCItem(const MUCBookmark& bookmark, ChatListGroupItem*
}
const MUCBookmark& ChatListMUCItem::getBookmark() const {
- return bookmark_;
+ return bookmark_;
}
QVariant ChatListMUCItem::data(int role) const {
- switch (role) {
- case Qt::DisplayRole: return P2QSTRING(bookmark_.getName());
- case DetailTextRole: return P2QSTRING(bookmark_.getRoom().toString());
- /*case Qt::TextColorRole: return textColor_;
- case Qt::BackgroundColorRole: return backgroundColor_;
- case Qt::ToolTipRole: return isContact() ? toolTipString() : QVariant();
- case StatusTextRole: return statusText_;
- case AvatarRole: return avatar_;
- case PresenceIconRole: return getPresenceIcon();*/
- default: return QVariant();
- }
+ switch (role) {
+ case Qt::DisplayRole: return P2QSTRING(bookmark_.getName());
+ case DetailTextRole: return P2QSTRING(bookmark_.getRoom().toString());
+ case Qt::TextColorRole: return QColor(89,89,89);
+ /*case Qt::BackgroundColorRole: return backgroundColor_;
+ case Qt::ToolTipRole: return isContact() ? toolTipString() : QVariant();
+ case StatusTextRole: return statusText_;
+ case AvatarRole: return avatar_;
+ case PresenceIconRole: return getPresenceIcon();*/
+ default: return QVariant();
+ }
}
}
diff --git a/Swift/QtUI/ChatList/ChatListMUCItem.h b/Swift/QtUI/ChatList/ChatListMUCItem.h
index 7e9177a..c77c284 100644
--- a/Swift/QtUI/ChatList/ChatListMUCItem.h
+++ b/Swift/QtUI/ChatList/ChatListMUCItem.h
@@ -1,33 +1,33 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <QList>
+#include <memory>
-#include <boost/shared_ptr.hpp>
+#include <QList>
-#include "Swiften/MUC/MUCBookmark.h"
+#include <Swiften/MUC/MUCBookmark.h>
-#include "Swift/QtUI/ChatList/ChatListItem.h"
+#include <Swift/QtUI/ChatList/ChatListItem.h>
namespace Swift {
- class ChatListMUCItem : public ChatListItem {
- public:
- enum MUCItemRoles {
- DetailTextRole = Qt::UserRole/*,
- AvatarRole = Qt::UserRole + 1,
- PresenceIconRole = Qt::UserRole + 2,
- StatusShowTypeRole = Qt::UserRole + 3*/
- };
- ChatListMUCItem(const MUCBookmark& bookmark, ChatListGroupItem* parent);
- const MUCBookmark& getBookmark() const;
- QVariant data(int role) const;
- private:
- MUCBookmark bookmark_;
- QList<ChatListItem*> items_;
- };
+ class ChatListMUCItem : public ChatListItem {
+ public:
+ enum MUCItemRoles {
+ DetailTextRole = Qt::UserRole/*,
+ AvatarRole = Qt::UserRole + 1,
+ PresenceIconRole = Qt::UserRole + 2,
+ StatusShowTypeRole = Qt::UserRole + 3*/
+ };
+ ChatListMUCItem(const MUCBookmark& bookmark, ChatListGroupItem* parent);
+ const MUCBookmark& getBookmark() const;
+ QVariant data(int role) const;
+ private:
+ MUCBookmark bookmark_;
+ QList<ChatListItem*> items_;
+ };
}
diff --git a/Swift/QtUI/ChatList/ChatListModel.cpp b/Swift/QtUI/ChatList/ChatListModel.cpp
index 2447aa1..416b786 100644
--- a/Swift/QtUI/ChatList/ChatListModel.cpp
+++ b/Swift/QtUI/ChatList/ChatListModel.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -16,173 +16,172 @@
namespace Swift {
-ChatListModel::ChatListModel() : whiteboards_(NULL) {
- root_ = new ChatListGroupItem("", NULL, false);
- mucBookmarks_ = new ChatListGroupItem(tr("Bookmarked Rooms"), root_);
- recents_ = new ChatListGroupItem(tr("Recent Chats"), root_, false);
+ChatListModel::ChatListModel() : whiteboards_(nullptr) {
+ root_ = new ChatListGroupItem("", nullptr, false);
+ mucBookmarks_ = new ChatListGroupItem(tr("Bookmarked Rooms"), root_);
+ recents_ = new ChatListGroupItem(tr("Recent Chats"), root_, false);
#ifdef SWIFT_EXPERIMENTAL_WB
- whiteboards_ = new ChatListGroupItem(tr("Opened Whiteboards"), root_, false);
- root_->addItem(whiteboards_);
+ whiteboards_ = new ChatListGroupItem(tr("Opened Whiteboards"), root_, false);
+ root_->addItem(whiteboards_);
#endif
- root_->addItem(recents_);
- root_->addItem(mucBookmarks_);
+ root_->addItem(recents_);
+ root_->addItem(mucBookmarks_);
- QModelIndex idx = index(0, 0, QModelIndex());
- while (idx.isValid()) {
- if (idx.internalPointer() == mucBookmarks_) {
- mucBookmarksIndex_ = idx;
- } else if (idx.internalPointer() == recents_) {
- recentsIndex_ = idx;
- } else if (idx.internalPointer() == whiteboards_) {
- whiteboardsIndex_ = idx;
- }
- idx = index(idx.row() + 1, 0, QModelIndex());
- }
+ QModelIndex idx = index(0, 0, QModelIndex());
+ while (idx.isValid()) {
+ if (idx.internalPointer() == mucBookmarks_) {
+ mucBookmarksIndex_ = idx;
+ } else if (idx.internalPointer() == recents_) {
+ recentsIndex_ = idx;
+ } else if (idx.internalPointer() == whiteboards_) {
+ whiteboardsIndex_ = idx;
+ }
+ idx = index(idx.row() + 1, 0, QModelIndex());
+ }
}
Qt::ItemFlags ChatListModel::flags(const QModelIndex& index) const {
- Qt::ItemFlags flags = QAbstractItemModel::flags(index);
- if (dynamic_cast<ChatListRecentItem*>(getItemForIndex(index))) {
- flags |= Qt::ItemIsDragEnabled;
- }
- return flags;
+ Qt::ItemFlags flags = QAbstractItemModel::flags(index);
+ if (dynamic_cast<ChatListRecentItem*>(getItemForIndex(index))) {
+ flags |= Qt::ItemIsDragEnabled;
+ }
+ return flags;
}
void ChatListModel::clearBookmarks() {
- beginRemoveRows(mucBookmarksIndex_, 0, mucBookmarks_->rowCount());
- mucBookmarks_->clear();
- endRemoveRows();
+ beginRemoveRows(mucBookmarksIndex_, 0, mucBookmarks_->rowCount());
+ mucBookmarks_->clear();
+ endRemoveRows();
}
void ChatListModel::addMUCBookmark(const Swift::MUCBookmark& bookmark) {
- beginInsertRows(mucBookmarksIndex_, 0, mucBookmarks_->rowCount());
- mucBookmarks_->addItem(new ChatListMUCItem(bookmark, mucBookmarks_));
- endInsertRows();
+ beginInsertRows(mucBookmarksIndex_, 0, mucBookmarks_->rowCount());
+ mucBookmarks_->addItem(new ChatListMUCItem(bookmark, mucBookmarks_));
+ endInsertRows();
}
void ChatListModel::removeMUCBookmark(const Swift::MUCBookmark& bookmark) {
- for (int i = 0; i < mucBookmarks_->rowCount(); i++) {
- ChatListMUCItem* item = dynamic_cast<ChatListMUCItem*>(mucBookmarks_->item(i));
- if (item->getBookmark() == bookmark) {
- beginRemoveRows(mucBookmarksIndex_, i, i+1);
- mucBookmarks_->remove(i);
- endRemoveRows();
- break;
- }
- }
+ for (int i = 0; i < mucBookmarks_->rowCount(); i++) {
+ ChatListMUCItem* item = dynamic_cast<ChatListMUCItem*>(mucBookmarks_->item(i));
+ if (item->getBookmark() == bookmark) {
+ beginRemoveRows(mucBookmarksIndex_, i, i+1);
+ mucBookmarks_->remove(i);
+ endRemoveRows();
+ break;
+ }
+ }
}
void ChatListModel::addWhiteboardSession(const ChatListWindow::Chat& chat) {
- beginInsertRows(whiteboardsIndex_, 0, whiteboards_->rowCount());
- whiteboards_->addItem(new ChatListWhiteboardItem(chat, whiteboards_));
- endInsertRows();
+ beginInsertRows(whiteboardsIndex_, 0, whiteboards_->rowCount());
+ whiteboards_->addItem(new ChatListWhiteboardItem(chat, whiteboards_));
+ endInsertRows();
}
void ChatListModel::removeWhiteboardSession(const JID& jid) {
- for (int i = 0; i < whiteboards_->rowCount(); i++) {
- ChatListWhiteboardItem* item = dynamic_cast<ChatListWhiteboardItem*>(whiteboards_->item(i));
- if (item->getChat().jid == jid) {
- beginRemoveRows(whiteboardsIndex_, i, i+1);
- whiteboards_->remove(i);
- endRemoveRows();
- break;
- }
- }
+ for (int i = 0; i < whiteboards_->rowCount(); i++) {
+ ChatListWhiteboardItem* item = dynamic_cast<ChatListWhiteboardItem*>(whiteboards_->item(i));
+ if (item->getChat().jid == jid) {
+ beginRemoveRows(whiteboardsIndex_, i, i+1);
+ whiteboards_->remove(i);
+ endRemoveRows();
+ break;
+ }
+ }
}
void ChatListModel::setRecents(const std::list<ChatListWindow::Chat>& recents) {
- beginRemoveRows(recentsIndex_, 0, recents_->rowCount());
- recents_->clear();
- endRemoveRows();
- beginInsertRows(recentsIndex_, 0, recents.size());
- foreach (const ChatListWindow::Chat chat, recents) {
- recents_->addItem(new ChatListRecentItem(chat, recents_));
+ beginRemoveRows(recentsIndex_, 0, recents_->rowCount());
+ recents_->clear();
+ endRemoveRows();
+ beginInsertRows(recentsIndex_, 0, recents.size());
+ for (const auto& chat : recents) {
+ recents_->addItem(new ChatListRecentItem(chat, recents_));
//whiteboards_->addItem(new ChatListRecentItem(chat, whiteboards_));
- }
- endInsertRows();
+ }
+ endInsertRows();
}
QMimeData* ChatListModel::mimeData(const QModelIndexList& indexes) const {
- QMimeData* data = QAbstractItemModel::mimeData(indexes);
- ChatListRecentItem *item = dynamic_cast<ChatListRecentItem*>(getItemForIndex(indexes.first()));
- if (item == NULL) {
- return data;
- }
-
- QByteArray itemData;
- QDataStream dataStream(&itemData, QIODevice::WriteOnly);
- const ChatListWindow::Chat& chat = item->getChat();
-
- QString mimeType = "application/vnd.swift.contact-jid-list";
- if (!chat.impromptuJIDs.size()) {
- if (chat.isMUC) {
- mimeType = "application/vnd.swift.contact-jid-muc";
- }
- dataStream << P2QSTRING(chat.jid.toString());
- } else {
- typedef std::map<std::string, JID> JIDMap;
- foreach (const JIDMap::value_type& jid, chat.impromptuJIDs) {
- dataStream << P2QSTRING(jid.second.toString());
- }
- }
-
- data->setData(mimeType, itemData);
- return data;
+ QMimeData* data = QAbstractItemModel::mimeData(indexes);
+ ChatListRecentItem *item = dynamic_cast<ChatListRecentItem*>(getItemForIndex(indexes.first()));
+ if (item == nullptr) {
+ return data;
+ }
+
+ QByteArray itemData;
+ QDataStream dataStream(&itemData, QIODevice::WriteOnly);
+ const ChatListWindow::Chat& chat = item->getChat();
+
+ QString mimeType = "application/vnd.swift.contact-jid-list";
+ if (!chat.impromptuJIDs.size()) {
+ if (chat.isMUC) {
+ mimeType = "application/vnd.swift.contact-jid-muc";
+ }
+ dataStream << P2QSTRING(chat.jid.toString());
+ } else {
+ for (const auto& jid : chat.impromptuJIDs) {
+ dataStream << P2QSTRING(jid.second.toString());
+ }
+ }
+
+ data->setData(mimeType, itemData);
+ return data;
}
const ChatListMUCItem* ChatListModel::getChatListMUCItem(const JID& roomJID) const {
- const ChatListMUCItem* mucItem = NULL;
- for (int i = 0; i < mucBookmarks_->rowCount(); i++) {
- ChatListMUCItem* item = dynamic_cast<ChatListMUCItem*>(mucBookmarks_->item(i));
- if (item->getBookmark().getRoom() == roomJID) {
- mucItem = item;
- break;
- }
- }
- return mucItem;
+ const ChatListMUCItem* mucItem = nullptr;
+ for (int i = 0; i < mucBookmarks_->rowCount(); i++) {
+ ChatListMUCItem* item = dynamic_cast<ChatListMUCItem*>(mucBookmarks_->item(i));
+ if (item->getBookmark().getRoom() == roomJID) {
+ mucItem = item;
+ break;
+ }
+ }
+ return mucItem;
}
int ChatListModel::columnCount(const QModelIndex& /*parent*/) const {
- return 1;
+ return 1;
}
ChatListItem* ChatListModel::getItemForIndex(const QModelIndex& index) const {
- return index.isValid() ? static_cast<ChatListItem*>(index.internalPointer()) : NULL;
+ return index.isValid() ? static_cast<ChatListItem*>(index.internalPointer()) : nullptr;
}
QVariant ChatListModel::data(const QModelIndex& index, int role) const {
- ChatListItem* item = getItemForIndex(index);
- return item ? item->data(role) : QVariant();
+ ChatListItem* item = getItemForIndex(index);
+ return item ? item->data(role) : QVariant();
}
QModelIndex ChatListModel::index(int row, int column, const QModelIndex & parent) const {
- if (!hasIndex(row, column, parent)) {
- return QModelIndex();
- }
+ if (!hasIndex(row, column, parent)) {
+ return QModelIndex();
+ }
- ChatListGroupItem *parentItem = parent.isValid() ? static_cast<ChatListGroupItem*>(parent.internalPointer()) : root_;
+ ChatListGroupItem *parentItem = parent.isValid() ? static_cast<ChatListGroupItem*>(parent.internalPointer()) : root_;
- return row < parentItem->rowCount() ? createIndex(row, column, parentItem->item(row)) : QModelIndex();
+ return row < parentItem->rowCount() ? createIndex(row, column, parentItem->item(row)) : QModelIndex();
}
QModelIndex ChatListModel::parent(const QModelIndex& index) const {
- if (!index.isValid()) {
- return QModelIndex();
- }
- ChatListGroupItem* parent = static_cast<ChatListGroupItem*>(index.internalPointer())->parent();
- return (parent == root_) ? QModelIndex() : createIndex(parent->parent()->row(parent), 0, parent);
+ if (!index.isValid()) {
+ return QModelIndex();
+ }
+ ChatListGroupItem* parent = static_cast<ChatListGroupItem*>(index.internalPointer())->parent();
+ return (parent == root_) ? QModelIndex() : createIndex(parent->parent()->row(parent), 0, parent);
}
int ChatListModel::rowCount(const QModelIndex& parentIndex) const {
- ChatListGroupItem* parent = NULL;
- if (parentIndex.isValid()) {
- parent = dynamic_cast<ChatListGroupItem*>(static_cast<ChatListItem*>(parentIndex.internalPointer()));
- } else {
- parent = root_;
- }
- int count = (parent ? parent->rowCount() : 0);
- return count;
+ ChatListGroupItem* parent = nullptr;
+ if (parentIndex.isValid()) {
+ parent = dynamic_cast<ChatListGroupItem*>(static_cast<ChatListItem*>(parentIndex.internalPointer()));
+ } else {
+ parent = root_;
+ }
+ int count = (parent ? parent->rowCount() : 0);
+ return count;
}
}
diff --git a/Swift/QtUI/ChatList/ChatListModel.h b/Swift/QtUI/ChatList/ChatListModel.h
index ea85efb..363b2e6 100644
--- a/Swift/QtUI/ChatList/ChatListModel.h
+++ b/Swift/QtUI/ChatList/ChatListModel.h
@@ -16,38 +16,38 @@
#include <Swift/QtUI/ChatList/ChatListGroupItem.h>
namespace Swift {
- class ChatListMUCItem;
-
- class ChatListModel : public QAbstractItemModel {
- Q_OBJECT
- public:
- ChatListModel();
- Qt::ItemFlags flags(const QModelIndex& index) const;
- void addMUCBookmark(const MUCBookmark& bookmark);
- void removeMUCBookmark(const MUCBookmark& bookmark);
- void addWhiteboardSession(const ChatListWindow::Chat& chat);
- void removeWhiteboardSession(const JID& jid);
- int columnCount(const QModelIndex& parent = QModelIndex()) const;
- QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
- QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
- QModelIndex parent(const QModelIndex& index) const;
- int rowCount(const QModelIndex& parent = QModelIndex()) const;
- ChatListItem* getItemForIndex(const QModelIndex& index) const;
- void clearBookmarks();
- void setRecents(const std::list<ChatListWindow::Chat>& recents);
- QMimeData* mimeData(const QModelIndexList& indexes) const;
-
- const ChatListMUCItem* getChatListMUCItem(const JID& roomJID) const;
-
- private:
- ChatListGroupItem* mucBookmarks_;
- ChatListGroupItem* recents_;
- ChatListGroupItem* whiteboards_;
- ChatListGroupItem* root_;
-
- QPersistentModelIndex mucBookmarksIndex_;
- QPersistentModelIndex recentsIndex_;
- QPersistentModelIndex whiteboardsIndex_;
- };
+ class ChatListMUCItem;
+
+ class ChatListModel : public QAbstractItemModel {
+ Q_OBJECT
+ public:
+ ChatListModel();
+ Qt::ItemFlags flags(const QModelIndex& index) const;
+ void addMUCBookmark(const MUCBookmark& bookmark);
+ void removeMUCBookmark(const MUCBookmark& bookmark);
+ void addWhiteboardSession(const ChatListWindow::Chat& chat);
+ void removeWhiteboardSession(const JID& jid);
+ int columnCount(const QModelIndex& parent = QModelIndex()) const;
+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
+ QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex& index) const;
+ int rowCount(const QModelIndex& parent = QModelIndex()) const;
+ ChatListItem* getItemForIndex(const QModelIndex& index) const;
+ void clearBookmarks();
+ void setRecents(const std::list<ChatListWindow::Chat>& recents);
+ QMimeData* mimeData(const QModelIndexList& indexes) const;
+
+ const ChatListMUCItem* getChatListMUCItem(const JID& roomJID) const;
+
+ private:
+ ChatListGroupItem* mucBookmarks_;
+ ChatListGroupItem* recents_;
+ ChatListGroupItem* whiteboards_;
+ ChatListGroupItem* root_;
+
+ QPersistentModelIndex mucBookmarksIndex_;
+ QPersistentModelIndex recentsIndex_;
+ QPersistentModelIndex whiteboardsIndex_;
+ };
}
diff --git a/Swift/QtUI/ChatList/ChatListRecentItem.cpp b/Swift/QtUI/ChatList/ChatListRecentItem.cpp
index a1446e3..faac937 100644
--- a/Swift/QtUI/ChatList/ChatListRecentItem.cpp
+++ b/Swift/QtUI/ChatList/ChatListRecentItem.cpp
@@ -1,12 +1,13 @@
/*
- * Copyright (c) 2011-2013 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
+#include <Swift/QtUI/ChatList/ChatListRecentItem.h>
+
#include <Swiften/Base/Path.h>
-#include <Swift/QtUI/ChatList/ChatListRecentItem.h>
#include <Swift/QtUI/QtResourceHelper.h>
#include <Swift/QtUI/QtSwiftUtil.h>
@@ -16,25 +17,25 @@ ChatListRecentItem::ChatListRecentItem(const ChatListWindow::Chat& chat, ChatLis
}
const ChatListWindow::Chat& ChatListRecentItem::getChat() const {
- return chat_;
+ return chat_;
}
QVariant ChatListRecentItem::data(int role) const {
- switch (role) {
- case Qt::DisplayRole: return chat_.impromptuJIDs.empty() ? P2QSTRING(chat_.chatName) : P2QSTRING(chat_.getImpromptuTitle());
- case DetailTextRole: return P2QSTRING(chat_.activity);
- /*case Qt::TextColorRole: return textColor_;
- case Qt::BackgroundColorRole: return backgroundColor_;
- case Qt::ToolTipRole: return isContact() ? toolTipString() : QVariant();
- case StatusTextRole: return statusText_;*/
- case AvatarRole: return QVariant(P2QSTRING(pathToString(chat_.avatarPath)));
- case PresenceIconRole: return getPresenceIcon();
- default: return QVariant();
- }
+ switch (role) {
+ case Qt::DisplayRole: return chat_.impromptuJIDs.empty() ? P2QSTRING(chat_.chatName) : P2QSTRING(chat_.getImpromptuTitle());
+ case DetailTextRole: return P2QSTRING(chat_.activity);
+ case Qt::TextColorRole: return QColor(89,89,89);
+ /*case Qt::BackgroundColorRole: return backgroundColor_;
+ case Qt::ToolTipRole: return isContact() ? toolTipString() : QVariant();
+ case StatusTextRole: return statusText_;*/
+ case AvatarRole: return QVariant(P2QSTRING(pathToString(chat_.avatarPath)));
+ case PresenceIconRole: return getPresenceIcon();
+ default: return QVariant();
+ }
}
QIcon ChatListRecentItem::getPresenceIcon() const {
- return QIcon(statusShowTypeToIconPath(chat_.statusType));
+ return QIcon(statusShowTypeToIconPath(chat_.statusType));
}
}
diff --git a/Swift/QtUI/ChatList/ChatListRecentItem.h b/Swift/QtUI/ChatList/ChatListRecentItem.h
index 74c8024..3c9635b 100644
--- a/Swift/QtUI/ChatList/ChatListRecentItem.h
+++ b/Swift/QtUI/ChatList/ChatListRecentItem.h
@@ -1,36 +1,37 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <QList>
-#include <QIcon>
+#include <memory>
-#include <boost/shared_ptr.hpp>
+#include <QIcon>
+#include <QList>
#include <Swiften/MUC/MUCBookmark.h>
+
#include <Swift/Controllers/UIInterfaces/ChatListWindow.h>
#include <Swift/QtUI/ChatList/ChatListItem.h>
namespace Swift {
- class ChatListRecentItem : public ChatListItem {
- public:
- enum RecentItemRoles {
- DetailTextRole = Qt::UserRole,
- AvatarRole = Qt::UserRole + 1,
- PresenceIconRole = Qt::UserRole + 2/*,
- StatusShowTypeRole = Qt::UserRole + 3,
- IdleRole = Qt::UserRole + 4*/
- };
- ChatListRecentItem(const ChatListWindow::Chat& chat, ChatListGroupItem* parent);
- const ChatListWindow::Chat& getChat() const;
- QVariant data(int role) const;
- private:
- QIcon getPresenceIcon() const;
- ChatListWindow::Chat chat_;
- };
+ class ChatListRecentItem : public ChatListItem {
+ public:
+ enum RecentItemRoles {
+ DetailTextRole = Qt::UserRole,
+ AvatarRole = Qt::UserRole + 1,
+ PresenceIconRole = Qt::UserRole + 2/*,
+ StatusShowTypeRole = Qt::UserRole + 3,
+ IdleRole = Qt::UserRole + 4*/
+ };
+ ChatListRecentItem(const ChatListWindow::Chat& chat, ChatListGroupItem* parent);
+ const ChatListWindow::Chat& getChat() const;
+ QVariant data(int role) const;
+ private:
+ QIcon getPresenceIcon() const;
+ ChatListWindow::Chat chat_;
+ };
}
diff --git a/Swift/QtUI/ChatList/ChatListWhiteboardItem.cpp b/Swift/QtUI/ChatList/ChatListWhiteboardItem.cpp
index 287ccaf..8a4447e 100644
--- a/Swift/QtUI/ChatList/ChatListWhiteboardItem.cpp
+++ b/Swift/QtUI/ChatList/ChatListWhiteboardItem.cpp
@@ -5,42 +5,46 @@
*/
/*
- * Copyright (c) 2013 Isode Limited.
+ * Copyright (c) 2013-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
+#include <Swift/QtUI/ChatList/ChatListWhiteboardItem.h>
+
+#include <QColor>
+
#include <Swiften/Base/Path.h>
-#include <Swift/QtUI/ChatList/ChatListWhiteboardItem.h>
-#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swift/QtUI/QtResourceHelper.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
- ChatListWhiteboardItem::ChatListWhiteboardItem(const ChatListWindow::Chat& chat, ChatListGroupItem* parent) : ChatListItem(parent), chat_(chat) {
-
- }
-
- const ChatListWindow::Chat& ChatListWhiteboardItem::getChat() const {
- return chat_;
- }
-
- QVariant ChatListWhiteboardItem::data(int role) const {
- switch (role) {
- case Qt::DisplayRole: return P2QSTRING(chat_.chatName);
- case DetailTextRole: return P2QSTRING(chat_.activity);
- /*case Qt::TextColorRole: return textColor_;
- case Qt::BackgroundColorRole: return backgroundColor_;
- case Qt::ToolTipRole: return isContact() ? toolTipString() : QVariant();
- case StatusTextRole: return statusText_;*/
- case AvatarRole: return QVariant(P2QSTRING(pathToString(chat_.avatarPath)));
- case PresenceIconRole: return getPresenceIcon();
- default: return QVariant();
- }
- }
-
- QIcon ChatListWhiteboardItem::getPresenceIcon() const {
- return QIcon(statusShowTypeToIconPath(chat_.statusType));
- }
+ ChatListWhiteboardItem::ChatListWhiteboardItem(const ChatListWindow::Chat& chat, ChatListGroupItem* parent) : ChatListItem(parent), chat_(chat) {
+
+ }
+
+ const ChatListWindow::Chat& ChatListWhiteboardItem::getChat() const {
+ return chat_;
+ }
+
+ QVariant ChatListWhiteboardItem::data(int role) const {
+ switch (role) {
+ case Qt::DisplayRole: return P2QSTRING(chat_.chatName);
+ case DetailTextRole: return P2QSTRING(chat_.activity);
+ case Qt::TextColorRole: return QColor(89,89,89);
+ /*case Qt::TextColorRole: return textColor_;
+ case Qt::BackgroundColorRole: return backgroundColor_;
+ case Qt::ToolTipRole: return isContact() ? toolTipString() : QVariant();
+ case StatusTextRole: return statusText_;*/
+ case AvatarRole: return QVariant(P2QSTRING(pathToString(chat_.avatarPath)));
+ case PresenceIconRole: return getPresenceIcon();
+ default: return QVariant();
+ }
+ }
+
+ QIcon ChatListWhiteboardItem::getPresenceIcon() const {
+ return QIcon(statusShowTypeToIconPath(chat_.statusType));
+ }
}
diff --git a/Swift/QtUI/ChatList/ChatListWhiteboardItem.h b/Swift/QtUI/ChatList/ChatListWhiteboardItem.h
index 0281cb0..6dbc5f6 100644
--- a/Swift/QtUI/ChatList/ChatListWhiteboardItem.h
+++ b/Swift/QtUI/ChatList/ChatListWhiteboardItem.h
@@ -1,35 +1,36 @@
/*
- * Copyright (c) 2012 Isode Limited.
+ * Copyright (c) 2012-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <QList>
-#include <QIcon>
+#include <memory>
-#include <boost/shared_ptr.hpp>
+#include <QIcon>
+#include <QList>
#include <Swiften/MUC/MUCBookmark.h>
+
#include <Swift/Controllers/UIInterfaces/ChatListWindow.h>
#include <Swift/QtUI/ChatList/ChatListItem.h>
namespace Swift {
- class ChatListWhiteboardItem : public ChatListItem {
- public:
- enum RecentItemRoles {
- DetailTextRole = Qt::UserRole,
- AvatarRole = Qt::UserRole + 1,
- PresenceIconRole = Qt::UserRole + 2/*,
- StatusShowTypeRole = Qt::UserRole + 3*/
- };
- ChatListWhiteboardItem(const ChatListWindow::Chat& chat, ChatListGroupItem* parent);
- const ChatListWindow::Chat& getChat() const;
- QVariant data(int role) const;
- private:
- QIcon getPresenceIcon() const;
- ChatListWindow::Chat chat_;
- };
+ class ChatListWhiteboardItem : public ChatListItem {
+ public:
+ enum RecentItemRoles {
+ DetailTextRole = Qt::UserRole,
+ AvatarRole = Qt::UserRole + 1,
+ PresenceIconRole = Qt::UserRole + 2/*,
+ StatusShowTypeRole = Qt::UserRole + 3*/
+ };
+ ChatListWhiteboardItem(const ChatListWindow::Chat& chat, ChatListGroupItem* parent);
+ const ChatListWindow::Chat& getChat() const;
+ QVariant data(int role) const;
+ private:
+ QIcon getPresenceIcon() const;
+ ChatListWindow::Chat chat_;
+ };
}
diff --git a/Swift/QtUI/ChatList/QtChatListWindow.cpp b/Swift/QtUI/ChatList/QtChatListWindow.cpp
index b990b84..3caed57 100644
--- a/Swift/QtUI/ChatList/QtChatListWindow.cpp
+++ b/Swift/QtUI/ChatList/QtChatListWindow.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -31,197 +31,197 @@
namespace Swift {
QtChatListWindow::QtChatListWindow(UIEventStream *uiEventStream, SettingsProvider* settings, QWidget* parent) : QTreeView(parent), isOnline_(false) {
- eventStream_ = uiEventStream;
- settings_ = settings;
- bookmarksEnabled_ = false;
- model_ = new ChatListModel();
- setModel(model_);
- delegate_ = new ChatListDelegate(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
- setItemDelegate(delegate_);
- setHeaderHidden(true);
+ eventStream_ = uiEventStream;
+ settings_ = settings;
+ bookmarksEnabled_ = false;
+ model_ = new ChatListModel();
+ setModel(model_);
+ delegate_ = new ChatListDelegate(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
+ setItemDelegate(delegate_);
+ setHeaderHidden(true);
#ifdef SWIFT_PLATFORM_MACOSX
- setAlternatingRowColors(true);
+ setAlternatingRowColors(true);
#endif
- expandAll();
- setAnimated(true);
- setIndentation(0);
- setDragEnabled(true);
- setRootIsDecorated(true);
- setupContextMenus();
- connect(this, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleItemActivated(const QModelIndex&)));
- connect(this, SIGNAL(clicked(const QModelIndex&)), this, SLOT(handleClicked(const QModelIndex&)));
+ expandAll();
+ setAnimated(true);
+ setIndentation(0);
+ setDragEnabled(true);
+ setRootIsDecorated(true);
+ setupContextMenus();
+ connect(this, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleItemActivated(const QModelIndex&)));
+ connect(this, SIGNAL(clicked(const QModelIndex&)), this, SLOT(handleClicked(const QModelIndex&)));
- settings_->onSettingChanged.connect(boost::bind(&QtChatListWindow::handleSettingChanged, this, _1));
+ settings_->onSettingChanged.connect(boost::bind(&QtChatListWindow::handleSettingChanged, this, _1));
}
QtChatListWindow::~QtChatListWindow() {
- settings_->onSettingChanged.disconnect(boost::bind(&QtChatListWindow::handleSettingChanged, this, _1));
- delete model_;
- delete delegate_;
- delete mucMenu_;
- delete emptyMenu_;
+ settings_->onSettingChanged.disconnect(boost::bind(&QtChatListWindow::handleSettingChanged, this, _1));
+ delete model_;
+ delete delegate_;
+ delete mucMenu_;
+ delete emptyMenu_;
}
void QtChatListWindow::handleSettingChanged(const std::string& setting) {
- if (setting == QtUISettingConstants::COMPACT_ROSTER.getKey()) {
- delegate_->setCompact(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
- repaint();
- }
+ if (setting == QtUISettingConstants::COMPACT_ROSTER.getKey()) {
+ delegate_->setCompact(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
+ repaint();
+ }
}
void QtChatListWindow::handleClearRecentsRequested() {
- onClearRecentsRequested();
+ onClearRecentsRequested();
}
void QtChatListWindow::setBookmarksEnabled(bool enabled) {
- bookmarksEnabled_ = enabled;
+ bookmarksEnabled_ = enabled;
}
void QtChatListWindow::handleClicked(const QModelIndex& index) {
- ChatListGroupItem* item = dynamic_cast<ChatListGroupItem*>(static_cast<ChatListItem*>(index.internalPointer()));
- if (item) {
- setExpanded(index, !isExpanded(index));
- }
+ ChatListGroupItem* item = dynamic_cast<ChatListGroupItem*>(static_cast<ChatListItem*>(index.internalPointer()));
+ if (item) {
+ setExpanded(index, !isExpanded(index));
+ }
}
void QtChatListWindow::setupContextMenus() {
- mucMenu_ = new QMenu();
- onlineOnlyActions_ << mucMenu_->addAction(tr("Add New Bookmark"), this, SLOT(handleAddBookmark()));
- onlineOnlyActions_ << mucMenu_->addAction(tr("Edit Bookmark"), this, SLOT(handleEditBookmark()));
- onlineOnlyActions_ << mucMenu_->addAction(tr("Remove Bookmark"), this, SLOT(handleRemoveBookmark()));
- emptyMenu_ = new QMenu();
- onlineOnlyActions_ << emptyMenu_->addAction(tr("Add New Bookmark"), this, SLOT(handleAddBookmark()));
+ mucMenu_ = new QMenu();
+ onlineOnlyActions_ << mucMenu_->addAction(tr("Add New Bookmark"), this, SLOT(handleAddBookmark()));
+ onlineOnlyActions_ << mucMenu_->addAction(tr("Edit Bookmark"), this, SLOT(handleEditBookmark()));
+ onlineOnlyActions_ << mucMenu_->addAction(tr("Remove Bookmark"), this, SLOT(handleRemoveBookmark()));
+ emptyMenu_ = new QMenu();
+ onlineOnlyActions_ << emptyMenu_->addAction(tr("Add New Bookmark"), this, SLOT(handleAddBookmark()));
}
void QtChatListWindow::handleItemActivated(const QModelIndex& index) {
- ChatListItem* item = model_->getItemForIndex(index);
- if (ChatListMUCItem* mucItem = dynamic_cast<ChatListMUCItem*>(item)) {
- onMUCBookmarkActivated(mucItem->getBookmark());
- }
- else if (ChatListRecentItem* recentItem = dynamic_cast<ChatListRecentItem*>(item)) {
- onRecentActivated(recentItem->getChat());
- }
- else if (ChatListWhiteboardItem* whiteboardItem = dynamic_cast<ChatListWhiteboardItem*>(item)) {
- if (!whiteboardItem->getChat().isMUC || bookmarksEnabled_) {
- eventStream_->send(boost::make_shared<ShowWhiteboardUIEvent>(whiteboardItem->getChat().jid));
- }
- }
+ ChatListItem* item = model_->getItemForIndex(index);
+ if (ChatListMUCItem* mucItem = dynamic_cast<ChatListMUCItem*>(item)) {
+ onMUCBookmarkActivated(mucItem->getBookmark());
+ }
+ else if (ChatListRecentItem* recentItem = dynamic_cast<ChatListRecentItem*>(item)) {
+ onRecentActivated(recentItem->getChat());
+ }
+ else if (ChatListWhiteboardItem* whiteboardItem = dynamic_cast<ChatListWhiteboardItem*>(item)) {
+ if (!whiteboardItem->getChat().isMUC || bookmarksEnabled_) {
+ eventStream_->send(std::make_shared<ShowWhiteboardUIEvent>(whiteboardItem->getChat().jid));
+ }
+ }
}
void QtChatListWindow::clearBookmarks() {
- model_->clearBookmarks();
+ model_->clearBookmarks();
}
void QtChatListWindow::addMUCBookmark(const MUCBookmark& bookmark) {
- model_->addMUCBookmark(bookmark);
+ model_->addMUCBookmark(bookmark);
}
void QtChatListWindow::removeMUCBookmark(const MUCBookmark& bookmark) {
- model_->removeMUCBookmark(bookmark);
+ model_->removeMUCBookmark(bookmark);
}
void QtChatListWindow::addWhiteboardSession(const ChatListWindow::Chat& chat) {
- model_->addWhiteboardSession(chat);
+ model_->addWhiteboardSession(chat);
}
void QtChatListWindow::removeWhiteboardSession(const JID& jid) {
- model_->removeWhiteboardSession(jid);
+ model_->removeWhiteboardSession(jid);
}
void QtChatListWindow::setRecents(const std::list<ChatListWindow::Chat>& recents) {
- model_->setRecents(recents);
+ model_->setRecents(recents);
}
void QtChatListWindow::setUnreadCount(int unread) {
- emit onCountUpdated(unread);
+ emit onCountUpdated(unread);
}
void QtChatListWindow::setOnline(bool isOnline) {
- isOnline_ = isOnline;
+ isOnline_ = isOnline;
}
void QtChatListWindow::handleRemoveBookmark() {
- const ChatListMUCItem* mucItem = dynamic_cast<const ChatListMUCItem*>(contextMenuItem_);
- if (!mucItem) return;
- eventStream_->send(boost::shared_ptr<UIEvent>(new RemoveMUCBookmarkUIEvent(mucItem->getBookmark())));
+ const ChatListMUCItem* mucItem = dynamic_cast<const ChatListMUCItem*>(contextMenuItem_);
+ if (!mucItem) return;
+ eventStream_->send(std::make_shared<RemoveMUCBookmarkUIEvent>(mucItem->getBookmark()));
}
void QtChatListWindow::handleAddBookmarkFromRecents() {
- const ChatListRecentItem* item = dynamic_cast<const ChatListRecentItem*>(contextMenuItem_);
- if (item) {
- const ChatListWindow::Chat& chat = item->getChat();
- MUCBookmark bookmark(chat.jid, chat.jid.toBare().toString());
- bookmark.setNick(chat.nick);
- bookmark.setPassword(chat.password);
- eventStream_->send(boost::shared_ptr<UIEvent>(new AddMUCBookmarkUIEvent(bookmark)));
- }
+ const ChatListRecentItem* item = dynamic_cast<const ChatListRecentItem*>(contextMenuItem_);
+ if (item) {
+ const ChatListWindow::Chat& chat = item->getChat();
+ MUCBookmark bookmark(chat.jid, chat.jid.toBare().toString());
+ bookmark.setNick(chat.nick);
+ bookmark.setPassword(chat.password);
+ eventStream_->send(std::make_shared<AddMUCBookmarkUIEvent>(bookmark));
+ }
}
void QtChatListWindow::handleAddBookmark() {
- (new QtAddBookmarkWindow(eventStream_))->show();
+ (new QtAddBookmarkWindow(eventStream_))->show();
}
void QtChatListWindow::handleEditBookmark() {
- const ChatListMUCItem* mucItem = dynamic_cast<const ChatListMUCItem*>(contextMenuItem_);
- if (!mucItem) return;
- QtEditBookmarkWindow* window = new QtEditBookmarkWindow(eventStream_, mucItem->getBookmark());
- window->show();
+ const ChatListMUCItem* mucItem = dynamic_cast<const ChatListMUCItem*>(contextMenuItem_);
+ if (!mucItem) return;
+ QtEditBookmarkWindow* window = new QtEditBookmarkWindow(eventStream_, mucItem->getBookmark());
+ window->show();
}
void QtChatListWindow::dragEnterEvent(QDragEnterEvent *event) {
- if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) {
- event->acceptProposedAction();
- }
+ if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) {
+ event->acceptProposedAction();
+ }
}
void QtChatListWindow::contextMenuEvent(QContextMenuEvent* event) {
- QModelIndex index = indexAt(event->pos());
- ChatListItem* baseItem = index.isValid() ? static_cast<ChatListItem*>(index.internalPointer()) : NULL;
- contextMenuItem_ = baseItem;
-
- foreach(QAction* action, onlineOnlyActions_) {
- action->setEnabled(isOnline_);
- }
-
- if (!baseItem) {
- emptyMenu_->exec(QCursor::pos());
- return;
- }
-
- ChatListMUCItem* mucItem = dynamic_cast<ChatListMUCItem*>(baseItem);
- if (mucItem) {
- if (!bookmarksEnabled_) {
- return;
- }
- mucMenu_->exec(QCursor::pos());
- return;
- }
-
- ChatListRecentItem* recentItem = dynamic_cast<ChatListRecentItem*>(baseItem);
- if (recentItem) {
- const ChatListWindow::Chat& chat = recentItem->getChat();
- if (chat.isMUC) {
- QMenu mucRecentsMenu;
- QAction* bookmarkAction = NULL;
- const ChatListMUCItem* mucItem = model_->getChatListMUCItem(chat.jid);
- if (mucItem) {
- contextMenuItem_ = mucItem;
- bookmarkAction = mucRecentsMenu.addAction(tr("Edit Bookmark"), this, SLOT(handleEditBookmark()));
- }
- else {
- bookmarkAction = mucRecentsMenu.addAction(tr("Add to Bookmarks"), this, SLOT(handleAddBookmarkFromRecents()));
- }
- bookmarkAction->setEnabled(isOnline_);
- mucRecentsMenu.addAction(tr("Clear recents"), this, SLOT(handleClearRecentsRequested()));
- mucRecentsMenu.exec(QCursor::pos());
- return;
- }
- }
-
- QMenu menu;
- menu.addAction(tr("Clear recents"), this, SLOT(handleClearRecentsRequested()));
- menu.exec(event->globalPos());
+ QModelIndex index = indexAt(event->pos());
+ ChatListItem* baseItem = index.isValid() ? static_cast<ChatListItem*>(index.internalPointer()) : nullptr;
+ contextMenuItem_ = baseItem;
+
+ for (auto action : onlineOnlyActions_) {
+ action->setEnabled(isOnline_);
+ }
+
+ if (!baseItem) {
+ emptyMenu_->exec(QCursor::pos());
+ return;
+ }
+
+ ChatListMUCItem* mucItem = dynamic_cast<ChatListMUCItem*>(baseItem);
+ if (mucItem) {
+ if (!bookmarksEnabled_) {
+ return;
+ }
+ mucMenu_->exec(QCursor::pos());
+ return;
+ }
+
+ ChatListRecentItem* recentItem = dynamic_cast<ChatListRecentItem*>(baseItem);
+ if (recentItem) {
+ const ChatListWindow::Chat& chat = recentItem->getChat();
+ if (chat.isMUC) {
+ QMenu mucRecentsMenu;
+ QAction* bookmarkAction = nullptr;
+ const ChatListMUCItem* mucItem = model_->getChatListMUCItem(chat.jid);
+ if (mucItem) {
+ contextMenuItem_ = mucItem;
+ bookmarkAction = mucRecentsMenu.addAction(tr("Edit Bookmark"), this, SLOT(handleEditBookmark()));
+ }
+ else {
+ bookmarkAction = mucRecentsMenu.addAction(tr("Add to Bookmarks"), this, SLOT(handleAddBookmarkFromRecents()));
+ }
+ bookmarkAction->setEnabled(isOnline_);
+ mucRecentsMenu.addAction(tr("Clear recents"), this, SLOT(handleClearRecentsRequested()));
+ mucRecentsMenu.exec(QCursor::pos());
+ return;
+ }
+ }
+
+ QMenu menu;
+ menu.addAction(tr("Clear recents"), this, SLOT(handleClearRecentsRequested()));
+ menu.exec(event->globalPos());
}
}
diff --git a/Swift/QtUI/ChatList/QtChatListWindow.h b/Swift/QtUI/ChatList/QtChatListWindow.h
index 627dcd4..834e318 100644
--- a/Swift/QtUI/ChatList/QtChatListWindow.h
+++ b/Swift/QtUI/ChatList/QtChatListWindow.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -15,50 +15,50 @@
#include <Swift/QtUI/ChatList/ChatListModel.h>
namespace Swift {
- class SettingsProvider;
- class QtChatListWindow : public QTreeView, public ChatListWindow {
- Q_OBJECT
- public:
- QtChatListWindow(UIEventStream *uiEventStream, SettingsProvider* settings, QWidget* parent = NULL);
- virtual ~QtChatListWindow();
- void addMUCBookmark(const MUCBookmark& bookmark);
- void removeMUCBookmark(const MUCBookmark& bookmark);
- void addWhiteboardSession(const ChatListWindow::Chat& chat);
- void removeWhiteboardSession(const JID& jid);
- void setBookmarksEnabled(bool enabled);
- void setRecents(const std::list<ChatListWindow::Chat>& recents);
- void setUnreadCount(int unread);
- void clearBookmarks();
- virtual void setOnline(bool isOnline);
+ class SettingsProvider;
+ class QtChatListWindow : public QTreeView, public ChatListWindow {
+ Q_OBJECT
+ public:
+ QtChatListWindow(UIEventStream *uiEventStream, SettingsProvider* settings, QWidget* parent = nullptr);
+ virtual ~QtChatListWindow();
+ void addMUCBookmark(const MUCBookmark& bookmark);
+ void removeMUCBookmark(const MUCBookmark& bookmark);
+ void addWhiteboardSession(const ChatListWindow::Chat& chat);
+ void removeWhiteboardSession(const JID& jid);
+ void setBookmarksEnabled(bool enabled);
+ void setRecents(const std::list<ChatListWindow::Chat>& recents);
+ void setUnreadCount(int unread);
+ void clearBookmarks();
+ virtual void setOnline(bool isOnline);
- signals:
- void onCountUpdated(int count);
- private slots:
- void handleItemActivated(const QModelIndex&);
- void handleAddBookmark();
- void handleEditBookmark();
- void handleRemoveBookmark();
- void handleAddBookmarkFromRecents();
- void handleClicked(const QModelIndex& index);
- void handleSettingChanged(const std::string& setting);
- void handleClearRecentsRequested();
+ signals:
+ void onCountUpdated(int count);
+ private slots:
+ void handleItemActivated(const QModelIndex&);
+ void handleAddBookmark();
+ void handleEditBookmark();
+ void handleRemoveBookmark();
+ void handleAddBookmarkFromRecents();
+ void handleClicked(const QModelIndex& index);
+ void handleSettingChanged(const std::string& setting);
+ void handleClearRecentsRequested();
- protected:
- void dragEnterEvent(QDragEnterEvent* event);
- void contextMenuEvent(QContextMenuEvent* event);
+ protected:
+ void dragEnterEvent(QDragEnterEvent* event);
+ void contextMenuEvent(QContextMenuEvent* event);
- private:
- void setupContextMenus();
- bool bookmarksEnabled_;
- UIEventStream* eventStream_;
- ChatListModel* model_;
- ChatListDelegate* delegate_;
- QMenu* mucMenu_;
- QMenu* emptyMenu_;
- const ChatListItem* contextMenuItem_;
- SettingsProvider* settings_;
- QList<QAction*> onlineOnlyActions_;
- bool isOnline_;
- };
+ private:
+ void setupContextMenus();
+ bool bookmarksEnabled_;
+ UIEventStream* eventStream_;
+ ChatListModel* model_;
+ ChatListDelegate* delegate_;
+ QMenu* mucMenu_;
+ QMenu* emptyMenu_;
+ const ChatListItem* contextMenuItem_;
+ SettingsProvider* settings_;
+ QList<QAction*> onlineOnlyActions_;
+ bool isOnline_;
+ };
}
diff --git a/Swift/QtUI/ChatSnippet.cpp b/Swift/QtUI/ChatSnippet.cpp
index d8b64c1..87dfac2 100644
--- a/Swift/QtUI/ChatSnippet.cpp
+++ b/Swift/QtUI/ChatSnippet.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2013 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -19,79 +19,79 @@ ChatSnippet::~ChatSnippet() {
}
QString ChatSnippet::timeToEscapedString(const QDateTime& time) {
- QDate now(QDate::currentDate());
- QString date = "";
- if (time.date().daysTo(now) > 0) {
- date = "ddd ";
- }
- if (time.date().month() != now.month()) {
- date = date + "MMMM ";
- }
- if (time.date().daysTo(now) > 6) {
- date = date + "d ";
- }
- if (time.date().year() != now.year()) {
- date = date + "yy ";
- }
- date += "h:mm";
- return escape(time.toString(date));
+ QDate now(QDate::currentDate());
+ QString date = "";
+ if (time.date().daysTo(now) > 0) {
+ date = "ddd ";
+ }
+ if (time.date().month() != now.month()) {
+ date = date + "MMMM ";
+ }
+ if (time.date().daysTo(now) > 6) {
+ date = date + "d ";
+ }
+ if (time.date().year() != now.year()) {
+ date = date + "yy ";
+ }
+ date += "h:mm";
+ return escape(time.toString(date));
}
QString ChatSnippet::wrapResizable(const QString& text) {
- return "<span class='swift_resizable'>" + text + "</span>";
+ return "<span class='swift_resizable'>" + text + "</span>";
}
QString ChatSnippet::directionToCSS(Direction direction) {
- return direction == RTL ? QString("rtl") : QString("ltr");
+ return direction == RTL ? QString("rtl") : QString("ltr");
}
ChatSnippet::Direction ChatSnippet::getDirection(const ChatWindow::ChatMessage& message) {
- boost::shared_ptr<ChatWindow::ChatTextMessagePart> textPart;
- std::string text = "";
- foreach (boost::shared_ptr<ChatWindow::ChatMessagePart> part, message.getParts()) {
- if ((textPart = boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(part))) {
- text = textPart->text;
- break;
- }
- }
- return getDirection(text);
+ std::shared_ptr<ChatWindow::ChatTextMessagePart> textPart;
+ std::string text = "";
+ for (auto&& part : message.getParts()) {
+ if ((textPart = std::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(part))) {
+ text = textPart->text;
+ break;
+ }
+ }
+ return getDirection(text);
}
ChatSnippet::Direction ChatSnippet::getDirection(const std::string& message) {
- return getDirection(P2QSTRING(message));
+ return getDirection(P2QSTRING(message));
}
ChatSnippet::Direction ChatSnippet::getDirection(const QString& message) {
- /*
- for (int i = 0; i < message.size(); ++i) {
- switch (message.at(i).direction()) {
- case QChar::DirL:
- case QChar::DirLRE:
- case QChar::DirLRO:
- return ChatSnippet::LTR;
- case QChar::DirR:
- case QChar::DirAL:
- case QChar::DirRLE:
- case QChar::DirRLO:
- return ChatSnippet::RTL;
- case QChar::DirEN:
- case QChar::DirES:
- case QChar::DirET:
- case QChar::DirAN:
- case QChar::DirCS:
- case QChar::DirB:
- case QChar::DirWS:
- case QChar::DirON:
- case QChar::DirS:
- case QChar::DirPDF:
- case QChar::DirNSM:
- case QChar::DirBN:
- break;
- }
- }
- return ChatSnippet::LTR;
- */
- return message.isRightToLeft() ? ChatSnippet::RTL : ChatSnippet::LTR;
+ /*
+ for (int i = 0; i < message.size(); ++i) {
+ switch (message.at(i).direction()) {
+ case QChar::DirL:
+ case QChar::DirLRE:
+ case QChar::DirLRO:
+ return ChatSnippet::LTR;
+ case QChar::DirR:
+ case QChar::DirAL:
+ case QChar::DirRLE:
+ case QChar::DirRLO:
+ return ChatSnippet::RTL;
+ case QChar::DirEN:
+ case QChar::DirES:
+ case QChar::DirET:
+ case QChar::DirAN:
+ case QChar::DirCS:
+ case QChar::DirB:
+ case QChar::DirWS:
+ case QChar::DirON:
+ case QChar::DirS:
+ case QChar::DirPDF:
+ case QChar::DirNSM:
+ case QChar::DirBN:
+ break;
+ }
+ }
+ return ChatSnippet::LTR;
+ */
+ return message.isRightToLeft() ? ChatSnippet::RTL : ChatSnippet::LTR;
}
diff --git a/Swift/QtUI/ChatSnippet.h b/Swift/QtUI/ChatSnippet.h
index 5d94917..d8bc209 100644
--- a/Swift/QtUI/ChatSnippet.h
+++ b/Swift/QtUI/ChatSnippet.h
@@ -1,70 +1,70 @@
/*
- * Copyright (c) 2010-2013 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
-#include <QString>
#include <QDateTime>
+#include <QString>
-#include <Swiften/Base/foreach.h>
#include <Swift/Controllers/UIInterfaces/ChatWindow.h>
-#include <Swift/QtUI/QtChatTheme.h>
+#include <Swift/QtUI/QtChatTheme.h>
namespace Swift {
- class ChatSnippet {
- public:
- enum Direction {
- RTL,
- LTR
- };
-
- ChatSnippet(bool appendToPrevious);
- virtual ~ChatSnippet();
-
- virtual const QString& getContent() const = 0;
- virtual QString getContinuationElementID() const { return ""; }
-
- boost::shared_ptr<ChatSnippet> getContinuationFallbackSnippet() const {return continuationFallback_;}
-
- bool getAppendToPrevious() const {
- return appendToPrevious_;
- }
-
- static QString escape(const QString& original) {
- QString result(original);
- result.replace("%message%", "&#37;message&#37;");
- result.replace("%sender%", "&#37;sender&#37;");
- result.replace("%wrapped_sender%", "&#37;wrapped_sender&#37;");
- result.replace("%time%", "%&#37;time&#37;");
- result.replace("%shortTime%", "%&#37;shortTime&#37;");
- result.replace("%userIconPath%", "&#37;userIconPath&#37;");
- result.replace("\t", " ");
- result.replace(" ", "&nbsp;&nbsp;");
- return result;
- }
-
- static QString timeToEscapedString(const QDateTime& time);
-
- static Direction getDirection(const std::string& message);
- static Direction getDirection(const ChatWindow::ChatMessage& message);
- static Direction getDirection(const QString& message);
-
- protected:
- static QString directionToCSS(Direction direction);
-
- QString wrapResizable(const QString& text);
- void setContinuationFallbackSnippet(boost::shared_ptr<ChatSnippet> continuationFallback) {
- continuationFallback_ = continuationFallback;
- }
- private:
- bool appendToPrevious_;
- boost::shared_ptr<ChatSnippet> continuationFallback_;
- };
+ class ChatSnippet {
+ public:
+ enum Direction {
+ RTL,
+ LTR
+ };
+
+ ChatSnippet(bool appendToPrevious);
+ virtual ~ChatSnippet();
+
+ virtual const QString& getContent() const = 0;
+ virtual QString getContinuationElementID() const { return ""; }
+
+ std::shared_ptr<ChatSnippet> getContinuationFallbackSnippet() const {return continuationFallback_;}
+
+ bool getAppendToPrevious() const {
+ return appendToPrevious_;
+ }
+
+ static QString escape(const QString& original) {
+ QString result(original);
+ result.replace("%message%", "&#37;message&#37;");
+ result.replace("%sender%", "&#37;sender&#37;");
+ result.replace("%wrapped_sender%", "&#37;wrapped_sender&#37;");
+ result.replace("%time%", "%&#37;time&#37;");
+ result.replace("%shortTime%", "%&#37;shortTime&#37;");
+ result.replace("%userIconPath%", "&#37;userIconPath&#37;");
+ result.replace("%id%", "&#37;id&#37;");
+ result.replace("\t", " ");
+ result.replace(" ", "&nbsp;&nbsp;");
+ return result;
+ }
+
+ static QString timeToEscapedString(const QDateTime& time);
+
+ static Direction getDirection(const std::string& message);
+ static Direction getDirection(const ChatWindow::ChatMessage& message);
+ static Direction getDirection(const QString& message);
+
+ protected:
+ static QString directionToCSS(Direction direction);
+
+ QString wrapResizable(const QString& text);
+ void setContinuationFallbackSnippet(std::shared_ptr<ChatSnippet> continuationFallback) {
+ continuationFallback_ = continuationFallback;
+ }
+ private:
+ bool appendToPrevious_;
+ std::shared_ptr<ChatSnippet> continuationFallback_;
+ };
}
diff --git a/Swift/QtUI/ChatView/main.cpp b/Swift/QtUI/ChatView/main.cpp
index d845958..aa3255e 100644
--- a/Swift/QtUI/ChatView/main.cpp
+++ b/Swift/QtUI/ChatView/main.cpp
@@ -1,178 +1,180 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include <QtDebug>
-#include <QApplication>
#include <iostream>
-#include <QWidget>
-#include <QFile>
+
+#include <QApplication>
#include <QDateTime>
+#include <QFile>
#include <QLineEdit>
+#include <QNetworkAccessManager>
+#include <QNetworkReply>
+#include <QNetworkRequest>
#include <QVBoxLayout>
-#include <QWebView>
#include <QWebFrame>
-#include <QNetworkRequest>
-#include <QNetworkReply>
-#include <QNetworkAccessManager>
-#include "../QtChatView.h"
-#include "../MessageSnippet.h"
-#include "../SystemMessageSnippet.h"
+#include <QWebView>
+#include <QWidget>
+#include <QtDebug>
+
+#include <Swift/QtUI/MessageSnippet.h>
+#include <Swift/QtUI/QtChatView.h>
+#include <Swift/QtUI/SystemMessageSnippet.h>
using namespace Swift;
/*
class MyNetworkReply : public QNetworkReply {
- public:
- MyNetworkReply() {
- }
-
- qint64 readData(char*, qint64) {
- return 0;
- }
-
- virtual void abort() {
- }
+ public:
+ MyNetworkReply() {
+ }
+
+ qint64 readData(char*, qint64) {
+ return 0;
+ }
+
+ virtual void abort() {
+ }
};
class MyNetworkAccessManager : public QNetworkAccessManager {
- public:
- MyNetworkAccessManager() {
- }
-
- QNetworkReply * createRequest (Operation op, const QNetworkRequest& request, QIODevice* outgoingData = 0) {
- assert(op == QNetworkAccessManager::GetOperation);
- qDebug() << "Requesting: " << request.url();
- return QNetworkAccessManager::createRequest(op, request, outgoingData);
- //return new MyNetworkReply();
- }
+ public:
+ MyNetworkAccessManager() {
+ }
+
+ QNetworkReply * createRequest (Operation op, const QNetworkRequest& request, QIODevice* outgoingData = 0) {
+ assert(op == QNetworkAccessManager::GetOperation);
+ qDebug() << "Requesting: " << request.url();
+ return QNetworkAccessManager::createRequest(op, request, outgoingData);
+ //return new MyNetworkReply();
+ }
};
- QVBoxLayout* mainLayout = new QVBoxLayout(this);
- webView_ = new QWebView(this);
-
- QFile file(":/themes/Stockholm/Contents/Resources/Incoming/Content.html");
- file.open(QIODevice::ReadOnly);
- QString content = QString::fromUtf8(file.readAll());
-
- webPage_ = new QWebPage(this);
- webPage_->setNetworkAccessManager(new MyNetworkAccessManager());
- webView_->setPage(webPage_);
- QString pagehtml =
- "<head>"
- //"<base href=\"file:///Users/remko/src/swift/resources/themes/Stockholm/Contents/Resources/\"/>"
- "<base href=\"file:///Users/remko/src/swift/resources/themes/Stockholm/Contents/Resources/\"/>"
- "<link rel=\"stylesheet\" type=\"text/css\" href=\"main.css\"/>"
- "<link rel=\"stylesheet\" type=\"text/css\" href=\"Variants/Alt Blue - Blue.css\"/>"
- "</head><body>" + content + "</body>";
- qDebug() << pagehtml;
- webPage_->mainFrame()->setHtml(pagehtml);
+ QVBoxLayout* mainLayout = new QVBoxLayout(this);
+ webView_ = new QWebView(this);
+
+ QFile file(":/themes/Stockholm/Contents/Resources/Incoming/Content.html");
+ file.open(QIODevice::ReadOnly);
+ QString content = QString::fromUtf8(file.readAll());
+
+ webPage_ = new QWebPage(this);
+ webPage_->setNetworkAccessManager(new MyNetworkAccessManager());
+ webView_->setPage(webPage_);
+ QString pagehtml =
+ "<head>"
+ //"<base href=\"file:///Users/remko/src/swift/resources/themes/Stockholm/Contents/Resources/\"/>"
+ "<base href=\"file:///Users/remko/src/swift/resources/themes/Stockholm/Contents/Resources/\"/>"
+ "<link rel=\"stylesheet\" type=\"text/css\" href=\"main.css\"/>"
+ "<link rel=\"stylesheet\" type=\"text/css\" href=\"Variants/Alt Blue - Blue.css\"/>"
+ "</head><body>" + content + "</body>";
+ qDebug() << pagehtml;
+ webPage_->mainFrame()->setHtml(pagehtml);
*/
/*
class ChatView : public QWidget {
- public:
- ChatView(QWidget* parent) : QWidget(parent) {
- setFocusPolicy(Qt::NoFocus);
-
- QVBoxLayout* mainLayout = new QVBoxLayout(this);
- mainLayout->setSpacing(0);
- mainLayout->setContentsMargins(0,0,0,0);
-
- webView_ = new QWebView(this);
- webView_->setFocusPolicy(Qt::NoFocus);
- mainLayout->addWidget(webView_);
-
- webPage_ = new QWebPage(this);
- webPage_->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
- webView_->setPage(webPage_);
- connect(webPage_, SIGNAL(selectionChanged()), SLOT(copySelectionToClipboard()));
-
- QString pageHTML = "<head></head><body><div id=\"chat\"></div></body>";
- webPage_->mainFrame()->setHtml(pageHTML);
- }
-
- void appendHTML(const QString& html) {
- webPage_->mainFrame()->evaluateJavaScript(
- "newNode = document.createElement(\"div\");"
- "newNode.innerHTML = \"" + html + "\";"
- "chatElement = document.getElementById(\"chat\");"
- "chatElement.appendChild(newNode);");
- webPage_->mainFrame()->setScrollBarValue(Qt::Vertical, webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical));
- }
-
- private:
- QWebView* webView_;
- QWebPage* webPage_;
+ public:
+ ChatView(QWidget* parent) : QWidget(parent) {
+ setFocusPolicy(Qt::NoFocus);
+
+ QVBoxLayout* mainLayout = new QVBoxLayout(this);
+ mainLayout->setSpacing(0);
+ mainLayout->setContentsMargins(0,0,0,0);
+
+ webView_ = new QWebView(this);
+ webView_->setFocusPolicy(Qt::NoFocus);
+ mainLayout->addWidget(webView_);
+
+ webPage_ = new QWebPage(this);
+ webPage_->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
+ webView_->setPage(webPage_);
+ connect(webPage_, SIGNAL(selectionChanged()), SLOT(copySelectionToClipboard()));
+
+ QString pageHTML = "<head></head><body><div id=\"chat\"></div></body>";
+ webPage_->mainFrame()->setHtml(pageHTML);
+ }
+
+ void appendHTML(const QString& html) {
+ webPage_->mainFrame()->evaluateJavaScript(
+ "newNode = document.createElement(\"div\");"
+ "newNode.innerHTML = \"" + html + "\";"
+ "chatElement = document.getElementById(\"chat\");"
+ "chatElement.appendChild(newNode);");
+ webPage_->mainFrame()->setScrollBarValue(Qt::Vertical, webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical));
+ }
+
+ private:
+ QWebView* webView_;
+ QWebPage* webPage_;
};
*/
class MyWidget : public QWidget {
- Q_OBJECT
-
- public:
- MyWidget() : previousWasIncoming_(false), previousWasOutgoing_(false), previousWasSystem_(false) {
- QVBoxLayout* mainLayout = new QVBoxLayout(this);
- chatView_ = new QtChatView(this);
- mainLayout->addWidget(chatView_);
- input1_ = new QLineEdit(this);
- connect(input1_, SIGNAL(returnPressed()), SLOT(addIncoming()));
- mainLayout->addWidget(input1_);
- input2_ = new QLineEdit(this);
- connect(input2_, SIGNAL(returnPressed()), SLOT(addOutgoing()));
- mainLayout->addWidget(input2_);
- input3_ = new QLineEdit(this);
- connect(input3_, SIGNAL(returnPressed()), SLOT(addSystem()));
- mainLayout->addWidget(input3_);
-
- resize(300,200);
- }
-
- public slots:
- void addIncoming() {
- chatView_->addMessage(MessageSnippet(input1_->text(), "Me", QDateTime::currentDateTime(), "qrc:/icons/avatar.png", true, previousWasIncoming_));
- previousWasIncoming_ = true;
- previousWasOutgoing_ = false;
- previousWasSystem_ = false;
- input1_->clear();
- }
-
- void addOutgoing() {
- chatView_->addMessage(MessageSnippet(input2_->text(), "You", QDateTime::currentDateTime(), "qrc:/icons/avatar.png", false, previousWasOutgoing_));
- previousWasIncoming_ = false;
- previousWasOutgoing_ = true;
- previousWasSystem_ = false;
- input2_->clear();
- }
-
- void addSystem() {
- chatView_->addMessage(SystemMessageSnippet(input3_->text(), QDateTime::currentDateTime(), previousWasSystem_));
- previousWasIncoming_ = false;
- previousWasOutgoing_ = false;
- previousWasSystem_ = true;
- input3_->clear();
- }
-
- private:
- bool previousWasIncoming_;
- bool previousWasOutgoing_;
- bool previousWasSystem_;
- QtChatView* chatView_;
- QLineEdit* input1_;
- QLineEdit* input2_;
- QLineEdit* input3_;
+ Q_OBJECT
+
+ public:
+ MyWidget() : previousWasIncoming_(false), previousWasOutgoing_(false), previousWasSystem_(false) {
+ QVBoxLayout* mainLayout = new QVBoxLayout(this);
+ chatView_ = new QtChatView(this);
+ mainLayout->addWidget(chatView_);
+ input1_ = new QLineEdit(this);
+ connect(input1_, SIGNAL(returnPressed()), SLOT(addIncoming()));
+ mainLayout->addWidget(input1_);
+ input2_ = new QLineEdit(this);
+ connect(input2_, SIGNAL(returnPressed()), SLOT(addOutgoing()));
+ mainLayout->addWidget(input2_);
+ input3_ = new QLineEdit(this);
+ connect(input3_, SIGNAL(returnPressed()), SLOT(addSystem()));
+ mainLayout->addWidget(input3_);
+
+ resize(300,200);
+ }
+
+ public slots:
+ void addIncoming() {
+ chatView_->addMessage(MessageSnippet(input1_->text(), "Me", QDateTime::currentDateTime(), "qrc:/icons/avatar.png", true, previousWasIncoming_));
+ previousWasIncoming_ = true;
+ previousWasOutgoing_ = false;
+ previousWasSystem_ = false;
+ input1_->clear();
+ }
+
+ void addOutgoing() {
+ chatView_->addMessage(MessageSnippet(input2_->text(), "You", QDateTime::currentDateTime(), "qrc:/icons/avatar.png", false, previousWasOutgoing_));
+ previousWasIncoming_ = false;
+ previousWasOutgoing_ = true;
+ previousWasSystem_ = false;
+ input2_->clear();
+ }
+
+ void addSystem() {
+ chatView_->addMessage(SystemMessageSnippet(input3_->text(), QDateTime::currentDateTime(), previousWasSystem_));
+ previousWasIncoming_ = false;
+ previousWasOutgoing_ = false;
+ previousWasSystem_ = true;
+ input3_->clear();
+ }
+
+ private:
+ bool previousWasIncoming_;
+ bool previousWasOutgoing_;
+ bool previousWasSystem_;
+ QtChatView* chatView_;
+ QLineEdit* input1_;
+ QLineEdit* input2_;
+ QLineEdit* input3_;
};
-
+
int main(int argc, char* argv[]) {
- QApplication app(argc, argv);
- MyWidget w;
- w.show();
- return app.exec();
+ QApplication app(argc, argv);
+ MyWidget w;
+ w.show();
+ return app.exec();
}
#include "main.moc"
diff --git a/Swift/QtUI/CocoaApplicationActivateHelper.h b/Swift/QtUI/CocoaApplicationActivateHelper.h
index 2b166e2..83fa886 100644
--- a/Swift/QtUI/CocoaApplicationActivateHelper.h
+++ b/Swift/QtUI/CocoaApplicationActivateHelper.h
@@ -1,28 +1,30 @@
/*
- * Copyright (c) 2012 Isode Limited.
+ * Copyright (c) 2012-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <memory>
+
#include <QObject>
namespace Swift {
- /**
- * This class is here as a workaround for a bug in Qt.
- * See Case #501.
- */
- class CocoaApplicationActivateHelper : public QObject {
- public:
- CocoaApplicationActivateHelper();
- virtual ~CocoaApplicationActivateHelper();
+ /**
+ * This class is here as a workaround for a bug in Qt.
+ * See Case #501.
+ */
+ class CocoaApplicationActivateHelper : public QObject {
+ public:
+ CocoaApplicationActivateHelper();
+ virtual ~CocoaApplicationActivateHelper();
- private:
- bool eventFilter(QObject* o, QEvent* e);
+ private:
+ bool eventFilter(QObject* o, QEvent* e);
- private:
- struct Private;
- Private* p;
- };
+ private:
+ struct Private;
+ const std::unique_ptr<Private> p;
+ };
}
diff --git a/Swift/QtUI/CocoaApplicationActivateHelper.mm b/Swift/QtUI/CocoaApplicationActivateHelper.mm
index 9f12fba..2bd985a 100644
--- a/Swift/QtUI/CocoaApplicationActivateHelper.mm
+++ b/Swift/QtUI/CocoaApplicationActivateHelper.mm
@@ -1,15 +1,19 @@
/*
- * Copyright (c) 2012 Isode Limited.
+ * Copyright (c) 2012-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include <Cocoa/Cocoa.h>
-#include "CocoaApplicationActivateHelper.h"
+#include <Swift/QtUI/CocoaApplicationActivateHelper.h>
+
+#include <memory>
#include <boost/function.hpp>
+
#include <QApplication>
+#include <Cocoa/Cocoa.h>
+
@interface CocoaApplicationActivateHelperDelegate : NSObject {
}
- (void) handleActivate: (NSAppleEventDescriptor*) event withReply: (NSAppleEventDescriptor*) reply;
@@ -17,37 +21,35 @@
@implementation CocoaApplicationActivateHelperDelegate
- (void) handleActivate: (NSAppleEventDescriptor*) event withReply: (NSAppleEventDescriptor*) reply {
- (void) event; (void) reply;
- QApplication::postEvent(qApp, new QEvent(QEvent::ApplicationActivate));
+ (void) event; (void) reply;
+ QApplication::postEvent(qApp, new QEvent(QEvent::ApplicationActivate));
}
@end
namespace Swift {
struct CocoaApplicationActivateHelper::Private {
- CocoaApplicationActivateHelperDelegate* delegate;
- bool initialized;
+ CocoaApplicationActivateHelperDelegate* delegate;
+ bool initialized;
};
-CocoaApplicationActivateHelper::CocoaApplicationActivateHelper() {
- p = new Private();
- p->delegate = [[CocoaApplicationActivateHelperDelegate alloc] init];
- p->initialized = false;
- qApp->installEventFilter(this);
+CocoaApplicationActivateHelper::CocoaApplicationActivateHelper() : p(new Private()) {
+ p->delegate = [[CocoaApplicationActivateHelperDelegate alloc] init];
+ p->initialized = false;
+ qApp->installEventFilter(this);
}
CocoaApplicationActivateHelper::~CocoaApplicationActivateHelper() {
- [[NSAppleEventManager sharedAppleEventManager] removeEventHandlerForEventClass:kCoreEventClass andEventID:kAEReopenApplication];
- [p->delegate release];
- delete p;
+ [[NSAppleEventManager sharedAppleEventManager] removeEventHandlerForEventClass:kCoreEventClass andEventID:kAEReopenApplication];
+ [p->delegate release];
}
bool CocoaApplicationActivateHelper::eventFilter(QObject* object, QEvent* event) {
- if (object == qApp && event->type() == QEvent::ApplicationActivate && !p->initialized) {
- [[NSAppleEventManager sharedAppleEventManager] setEventHandler:p->delegate andSelector:@selector(handleActivate:withReply:) forEventClass:kCoreEventClass andEventID:kAEReopenApplication];
- p->initialized = true;
- }
- return QObject::eventFilter(object, event);
+ if (object == qApp && event->type() == QEvent::ApplicationActivate && !p->initialized) {
+ [[NSAppleEventManager sharedAppleEventManager] setEventHandler:p->delegate andSelector:@selector(handleActivate:withReply:) forEventClass:kCoreEventClass andEventID:kAEReopenApplication];
+ p->initialized = true;
+ }
+ return QObject::eventFilter(object, event);
}
diff --git a/Swift/QtUI/CocoaUIHelpers.h b/Swift/QtUI/CocoaUIHelpers.h
index 25da0e3..8d96bd9 100644
--- a/Swift/QtUI/CocoaUIHelpers.h
+++ b/Swift/QtUI/CocoaUIHelpers.h
@@ -4,16 +4,24 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
-#include <Swiften/TLS/Certificate.h>
#include <QWidget>
+#include <Swiften/TLS/Certificate.h>
+
namespace Swift {
class CocoaUIHelpers {
public:
- static void displayCertificateChainAsSheet(QWidget* parent, const std::vector<Certificate::ref>& chain);
+ static void displayCertificateChainAsSheet(QWidget* parent, const std::vector<Certificate::ref>& chain);
+ static void sendCocoaApplicationWillTerminateNotification();
};
}
diff --git a/Swift/QtUI/CocoaUIHelpers.mm b/Swift/QtUI/CocoaUIHelpers.mm
index 3cb62f3..1f4ffc1 100644
--- a/Swift/QtUI/CocoaUIHelpers.mm
+++ b/Swift/QtUI/CocoaUIHelpers.mm
@@ -4,9 +4,16 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#include "CocoaUIHelpers.h"
-#include <boost/shared_ptr.hpp>
+#include <memory>
+
#include <boost/type_traits.hpp>
#include <Cocoa/Cocoa.h>
@@ -14,30 +21,31 @@
#include <Security/Security.h>
#include <SecurityInterface/SFCertificatePanel.h>
-#include <Swiften/Base/foreach.h>
-
#pragma GCC diagnostic ignored "-Wold-style-cast"
namespace Swift {
void CocoaUIHelpers::displayCertificateChainAsSheet(QWidget* parent, const std::vector<Certificate::ref>& chain) {
- NSWindow* parentWindow = [((NSView*)parent->winId()) window];
- NSMutableArray* certificates = [[NSMutableArray alloc] init];
- foreach(Certificate::ref cert, chain) {
- // convert chain to SecCertificateRef
- ByteArray certAsDER = cert->toDER();
- boost::shared_ptr<boost::remove_pointer<CFDataRef>::type> certData(CFDataCreate(NULL, certAsDER.data(), certAsDER.size()), CFRelease);
- boost::shared_ptr<OpaqueSecCertificateRef> macCert(SecCertificateCreateWithData(NULL, certData.get()), CFRelease);
-
- // add to NSMutable array
- [certificates addObject: (id)macCert.get()];
- }
-
-
- SFCertificatePanel* panel = [[SFCertificatePanel alloc] init];
- //[panel setPolicies:(id)policies.get()];
- [panel beginSheetForWindow:parentWindow modalDelegate:nil didEndSelector:NULL contextInfo:NULL certificates:certificates showGroup:YES];
- [certificates release];
+ NSWindow* parentWindow = [((NSView*)parent->winId()) window];
+ NSMutableArray* certificates = [[NSMutableArray alloc] init];
+ for (auto&& cert : chain) {
+ // convert chain to SecCertificateRef
+ ByteArray certAsDER = cert->toDER();
+ std::shared_ptr<boost::remove_pointer<CFDataRef>::type> certData(CFDataCreate(nullptr, certAsDER.data(), certAsDER.size()), CFRelease);
+ std::shared_ptr<OpaqueSecCertificateRef> macCert(SecCertificateCreateWithData(nullptr, certData.get()), CFRelease);
+
+ // add to NSMutable array
+ [certificates addObject: (id)macCert.get()];
+ }
+
+ SFCertificatePanel* panel = [[SFCertificatePanel alloc] init];
+ //[panel setPolicies:(id)policies.get()];
+ [panel beginSheetForWindow:parentWindow modalDelegate:nil didEndSelector:nullptr contextInfo:nullptr certificates:certificates showGroup:YES];
+ [certificates release];
+}
+
+void CocoaUIHelpers::sendCocoaApplicationWillTerminateNotification() {
+ [[NSNotificationCenter defaultCenter] postNotificationName:@"NSApplicationWillTerminateNotification" object:nil];
}
}
diff --git a/Swift/QtUI/EventViewer/EventDelegate.cpp b/Swift/QtUI/EventViewer/EventDelegate.cpp
index cd657b8..1c3ed7f 100644
--- a/Swift/QtUI/EventViewer/EventDelegate.cpp
+++ b/Swift/QtUI/EventViewer/EventDelegate.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -17,69 +17,69 @@
namespace Swift {
EventDelegate::EventDelegate() : QStyledItemDelegate(),
- messageDelegate_(QtEvent::SenderRole, Qt::DisplayRole, false),
- subscriptionDelegate_(QtEvent::SenderRole, Qt::DisplayRole, true),
- errorDelegate_(QtEvent::SenderRole, Qt::DisplayRole, true),
- mucInviteDelegate_(QtEvent::SenderRole, Qt::DisplayRole, false),
- incomingFileTransferDelegate_(QtEvent::SenderRole, Qt::DisplayRole, false) {
+ messageDelegate_(QtEvent::SenderRole, Qt::DisplayRole, false),
+ subscriptionDelegate_(QtEvent::SenderRole, Qt::DisplayRole, true),
+ errorDelegate_(QtEvent::SenderRole, Qt::DisplayRole, true),
+ mucInviteDelegate_(QtEvent::SenderRole, Qt::DisplayRole, false),
+ incomingFileTransferDelegate_(QtEvent::SenderRole, Qt::DisplayRole, false) {
}
QSize EventDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index ) const {
- QtEvent* item = static_cast<QtEvent*>(index.internalPointer());
- if (!item) {
- return QStyledItemDelegate::sizeHint(option, index);
- }
- switch (getEventType(item->getEvent())) {
- case MessageEventType: return messageDelegate_.sizeHint(option, item);
- case SubscriptionEventType: return subscriptionDelegate_.sizeHint(option, item);
- case ErrorEventType: return errorDelegate_.sizeHint(option, item);
- case MUCInviteEventType: return mucInviteDelegate_.sizeHint(option, item);
- case IncomingFileTransferEventType: return incomingFileTransferDelegate_.sizeHint(option, item);
- }
- assert(false);
- return QSize();
+ QtEvent* item = static_cast<QtEvent*>(index.internalPointer());
+ if (!item) {
+ return QStyledItemDelegate::sizeHint(option, index);
+ }
+ switch (getEventType(item->getEvent())) {
+ case MessageEventType: return messageDelegate_.sizeHint(option, item);
+ case SubscriptionEventType: return subscriptionDelegate_.sizeHint(option, item);
+ case ErrorEventType: return errorDelegate_.sizeHint(option, item);
+ case MUCInviteEventType: return mucInviteDelegate_.sizeHint(option, item);
+ case IncomingFileTransferEventType: return incomingFileTransferDelegate_.sizeHint(option, item);
+ }
+ assert(false);
+ return QSize();
}
void EventDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
- QtEvent* item = static_cast<QtEvent*>(index.internalPointer());
- if (!item) {
- QStyledItemDelegate::paint(painter, option, index);
- return;
- }
- switch (getEventType(item->getEvent())) {
- case MessageEventType: messageDelegate_.paint(painter, option, item);break;
- case SubscriptionEventType: subscriptionDelegate_.paint(painter, option, item);break;
- case ErrorEventType: errorDelegate_.paint(painter, option, item);break;
- case MUCInviteEventType: mucInviteDelegate_.paint(painter, option, item);break;
- case IncomingFileTransferEventType: incomingFileTransferDelegate_.paint(painter, option, item);break;
- }
+ QtEvent* item = static_cast<QtEvent*>(index.internalPointer());
+ if (!item) {
+ QStyledItemDelegate::paint(painter, option, index);
+ return;
+ }
+ switch (getEventType(item->getEvent())) {
+ case MessageEventType: messageDelegate_.paint(painter, option, item);break;
+ case SubscriptionEventType: subscriptionDelegate_.paint(painter, option, item);break;
+ case ErrorEventType: errorDelegate_.paint(painter, option, item);break;
+ case MUCInviteEventType: mucInviteDelegate_.paint(painter, option, item);break;
+ case IncomingFileTransferEventType: incomingFileTransferDelegate_.paint(painter, option, item);break;
+ }
}
-EventType EventDelegate::getEventType(boost::shared_ptr<StanzaEvent> event) const {
- boost::shared_ptr<MessageEvent> messageEvent = boost::dynamic_pointer_cast<MessageEvent>(event);
- if (messageEvent) {
- return MessageEventType;
- }
- boost::shared_ptr<SubscriptionRequestEvent> subscriptionEvent = boost::dynamic_pointer_cast<SubscriptionRequestEvent>(event);
- if (subscriptionEvent) {
- return SubscriptionEventType;
- }
- boost::shared_ptr<ErrorEvent> errorEvent = boost::dynamic_pointer_cast<ErrorEvent>(event);
- if (errorEvent) {
- return ErrorEventType;
- }
- boost::shared_ptr<MUCInviteEvent> mucInviteEvent = boost::dynamic_pointer_cast<MUCInviteEvent>(event);
- if (mucInviteEvent) {
- return MUCInviteEventType;
- }
- boost::shared_ptr<IncomingFileTransferEvent> incomingFileTransferEvent = boost::dynamic_pointer_cast<IncomingFileTransferEvent>(event);
- if (incomingFileTransferEvent) {
- return IncomingFileTransferEventType;
- }
- //I don't know what this is.
- assert(false);
- return MessageEventType;
+EventType EventDelegate::getEventType(std::shared_ptr<StanzaEvent> event) const {
+ std::shared_ptr<MessageEvent> messageEvent = std::dynamic_pointer_cast<MessageEvent>(event);
+ if (messageEvent) {
+ return MessageEventType;
+ }
+ std::shared_ptr<SubscriptionRequestEvent> subscriptionEvent = std::dynamic_pointer_cast<SubscriptionRequestEvent>(event);
+ if (subscriptionEvent) {
+ return SubscriptionEventType;
+ }
+ std::shared_ptr<ErrorEvent> errorEvent = std::dynamic_pointer_cast<ErrorEvent>(event);
+ if (errorEvent) {
+ return ErrorEventType;
+ }
+ std::shared_ptr<MUCInviteEvent> mucInviteEvent = std::dynamic_pointer_cast<MUCInviteEvent>(event);
+ if (mucInviteEvent) {
+ return MUCInviteEventType;
+ }
+ std::shared_ptr<IncomingFileTransferEvent> incomingFileTransferEvent = std::dynamic_pointer_cast<IncomingFileTransferEvent>(event);
+ if (incomingFileTransferEvent) {
+ return IncomingFileTransferEventType;
+ }
+ //I don't know what this is.
+ assert(false);
+ return MessageEventType;
}
}
diff --git a/Swift/QtUI/EventViewer/EventDelegate.h b/Swift/QtUI/EventViewer/EventDelegate.h
index 6ab96e4..79ee8ed 100644
--- a/Swift/QtUI/EventViewer/EventDelegate.h
+++ b/Swift/QtUI/EventViewer/EventDelegate.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -12,21 +12,21 @@
#include <Swift/QtUI/Roster/DelegateCommons.h>
namespace Swift {
- enum EventType {MessageEventType, SubscriptionEventType, ErrorEventType, MUCInviteEventType, IncomingFileTransferEventType};
- class EventDelegate : public QStyledItemDelegate {
- Q_OBJECT
- public:
- EventDelegate();
- QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
- void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
- private:
- EventType getEventType(boost::shared_ptr<StanzaEvent> event) const;
- DelegateCommons common_;
- TwoLineDelegate messageDelegate_;
- TwoLineDelegate subscriptionDelegate_;
- TwoLineDelegate errorDelegate_;
- TwoLineDelegate mucInviteDelegate_;
- TwoLineDelegate incomingFileTransferDelegate_;
- };
+ enum EventType {MessageEventType, SubscriptionEventType, ErrorEventType, MUCInviteEventType, IncomingFileTransferEventType};
+ class EventDelegate : public QStyledItemDelegate {
+ Q_OBJECT
+ public:
+ EventDelegate();
+ QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ private:
+ EventType getEventType(std::shared_ptr<StanzaEvent> event) const;
+ DelegateCommons common_;
+ TwoLineDelegate messageDelegate_;
+ TwoLineDelegate subscriptionDelegate_;
+ TwoLineDelegate errorDelegate_;
+ TwoLineDelegate mucInviteDelegate_;
+ TwoLineDelegate incomingFileTransferDelegate_;
+ };
}
diff --git a/Swift/QtUI/EventViewer/EventModel.cpp b/Swift/QtUI/EventViewer/EventModel.cpp
index 889bcac..5b97b3e 100644
--- a/Swift/QtUI/EventViewer/EventModel.cpp
+++ b/Swift/QtUI/EventViewer/EventModel.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -11,100 +11,100 @@
namespace Swift {
namespace {
- const int inactiveEventsLimit = 50;
+ const int inactiveEventsLimit = 50;
}
EventModel::EventModel() {
-
+
}
EventModel::~EventModel() {
- foreach (QtEvent* event, activeEvents_) {
- delete event;
- }
- foreach (QtEvent* event, inactiveEvents_) {
- delete event;
- }
+ for (auto event : activeEvents_) {
+ delete event;
+ }
+ for (auto event : inactiveEvents_) {
+ delete event;
+ }
}
QtEvent* EventModel::getItem(int row) const {
- QtEvent* event = NULL;
- if (row < activeEvents_.size()) {
- event = activeEvents_[row];
- }
- else {
- int inactiveRow = row - activeEvents_.size();
- if (inactiveRow < inactiveEvents_.size()) {
- event = inactiveEvents_[inactiveRow];
- }
- else {
- SWIFT_LOG(error) << "Misbehaving EventModel requests row index outside of range";
- }
- }
- return event;
+ QtEvent* event = nullptr;
+ if (row < activeEvents_.size()) {
+ event = activeEvents_[row];
+ }
+ else {
+ int inactiveRow = row - activeEvents_.size();
+ if (inactiveRow < inactiveEvents_.size()) {
+ event = inactiveEvents_[inactiveRow];
+ }
+ else {
+ SWIFT_LOG(error) << "Misbehaving EventModel requests row index outside of range";
+ }
+ }
+ return event;
}
int EventModel::getNewEventCount() {
- return activeEvents_.size();
+ return activeEvents_.size();
}
QVariant EventModel::data(const QModelIndex& index, int role) const {
- if (!index.isValid()) {
- return QVariant();
- }
- QtEvent* item = getItem(index.row());
- QVariant result = item ? item->data(role) : QVariant();
- return result;
+ if (!index.isValid()) {
+ return QVariant();
+ }
+ QtEvent* item = getItem(index.row());
+ QVariant result = item ? item->data(role) : QVariant();
+ return result;
}
/*
* We only reimplement this to get the pointers inside the indices.
*/
QModelIndex EventModel::index(int row, int column, const QModelIndex & parent) const {
- if (!hasIndex(row, column, parent) || parent.isValid()) {
- return QModelIndex();
- }
+ if (!hasIndex(row, column, parent) || parent.isValid()) {
+ return QModelIndex();
+ }
- return row < rowCount() ? createIndex(row, column, getItem(row)) : QModelIndex();
+ return row < rowCount() ? createIndex(row, column, getItem(row)) : QModelIndex();
}
int EventModel::rowCount(const QModelIndex& parent) const {
- /* Invalid parent = root, valid parent = child, and we're a list not a tree.*/
- int count = parent.isValid() ? 0 : activeEvents_.size() + inactiveEvents_.size();
- return count;
+ /* Invalid parent = root, valid parent = child, and we're a list not a tree.*/
+ int count = parent.isValid() ? 0 : activeEvents_.size() + inactiveEvents_.size();
+ return count;
}
-void EventModel::addEvent(boost::shared_ptr<StanzaEvent> event, bool active) {
- beginResetModel();
- if (active) {
- activeEvents_.push_front(new QtEvent(event, active));
- } else {
- inactiveEvents_.push_front(new QtEvent(event, active));
- if (inactiveEvents_.size() > inactiveEventsLimit) {
- removeEvent(inactiveEvents_[inactiveEventsLimit]->getEvent());
- }
- }
- endResetModel();
+void EventModel::addEvent(std::shared_ptr<StanzaEvent> event, bool active) {
+ beginResetModel();
+ if (active) {
+ activeEvents_.push_front(new QtEvent(event, active));
+ } else {
+ inactiveEvents_.push_front(new QtEvent(event, active));
+ if (inactiveEvents_.size() > inactiveEventsLimit) {
+ removeEvent(inactiveEvents_[inactiveEventsLimit]->getEvent());
+ }
+ }
+ endResetModel();
}
-void EventModel::removeEvent(boost::shared_ptr<StanzaEvent> event) {
- beginResetModel();
- for (int i = inactiveEvents_.size() - 1; i >= 0; i--) {
- if (event == inactiveEvents_[i]->getEvent()) {
- inactiveEvents_.removeAt(i);
- endResetModel();
- return;
- }
- }
-
- for (int i = 0; i < activeEvents_.size(); i++) {
- if (event == activeEvents_[i]->getEvent()) {
- activeEvents_.removeAt(i);
- endResetModel();
- return;
- }
- }
- endResetModel();
+void EventModel::removeEvent(std::shared_ptr<StanzaEvent> event) {
+ beginResetModel();
+ for (int i = inactiveEvents_.size() - 1; i >= 0; i--) {
+ if (event == inactiveEvents_[i]->getEvent()) {
+ inactiveEvents_.removeAt(i);
+ endResetModel();
+ return;
+ }
+ }
+
+ for (int i = 0; i < activeEvents_.size(); i++) {
+ if (event == activeEvents_[i]->getEvent()) {
+ activeEvents_.removeAt(i);
+ endResetModel();
+ return;
+ }
+ }
+ endResetModel();
}
}
diff --git a/Swift/QtUI/EventViewer/EventModel.h b/Swift/QtUI/EventViewer/EventModel.h
index cf259f2..de72c1b 100644
--- a/Swift/QtUI/EventViewer/EventModel.h
+++ b/Swift/QtUI/EventViewer/EventModel.h
@@ -1,37 +1,37 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
#include <QAbstractListModel>
#include <QList>
-#include "Swift/Controllers/XMPPEvents/StanzaEvent.h"
+#include <Swift/Controllers/XMPPEvents/StanzaEvent.h>
-#include "Swift/QtUI/EventViewer/QtEvent.h"
+#include <Swift/QtUI/EventViewer/QtEvent.h>
namespace Swift {
class EventModel : public QAbstractListModel {
- Q_OBJECT
- public:
- EventModel();
- virtual ~EventModel();
- void addEvent(boost::shared_ptr<StanzaEvent> event, bool active);
- void removeEvent(boost::shared_ptr<StanzaEvent> event);
- QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
- int rowCount(const QModelIndex& parent = QModelIndex()) const;
- QtEvent* getItem(int row) const;
- int getNewEventCount();
- protected:
- QModelIndex index(int row, int column = 0, const QModelIndex & parent = QModelIndex()) const;
- private:
- QList<QtEvent*> activeEvents_;
- QList<QtEvent*> inactiveEvents_;
+ Q_OBJECT
+ public:
+ EventModel();
+ virtual ~EventModel();
+ void addEvent(std::shared_ptr<StanzaEvent> event, bool active);
+ void removeEvent(std::shared_ptr<StanzaEvent> event);
+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
+ int rowCount(const QModelIndex& parent = QModelIndex()) const;
+ QtEvent* getItem(int row) const;
+ int getNewEventCount();
+ protected:
+ QModelIndex index(int row, int column = 0, const QModelIndex & parent = QModelIndex()) const;
+ private:
+ QList<QtEvent*> activeEvents_;
+ QList<QtEvent*> inactiveEvents_;
};
}
diff --git a/Swift/QtUI/EventViewer/EventView.cpp b/Swift/QtUI/EventViewer/EventView.cpp
index 7e89f04..4d56548 100644
--- a/Swift/QtUI/EventViewer/EventView.cpp
+++ b/Swift/QtUI/EventViewer/EventView.cpp
@@ -1,14 +1,14 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/QtUI/EventViewer/EventView.h"
+#include <Swift/QtUI/EventViewer/EventView.h>
namespace Swift {
EventView::EventView(QWidget* parent) : QListView(parent) {
-
+
}
}
diff --git a/Swift/QtUI/EventViewer/EventView.h b/Swift/QtUI/EventViewer/EventView.h
index 36c67f3..83898bd 100644
--- a/Swift/QtUI/EventViewer/EventView.h
+++ b/Swift/QtUI/EventViewer/EventView.h
@@ -9,9 +9,9 @@
#include <QListView>
namespace Swift {
- class EventView : public QListView {
- Q_OBJECT
- public:
- EventView(QWidget* parent);
- };
+ class EventView : public QListView {
+ Q_OBJECT
+ public:
+ EventView(QWidget* parent);
+ };
}
diff --git a/Swift/QtUI/EventViewer/QtEvent.cpp b/Swift/QtUI/EventViewer/QtEvent.cpp
index 4830aec..5bd0fad 100644
--- a/Swift/QtUI/EventViewer/QtEvent.cpp
+++ b/Swift/QtUI/EventViewer/QtEvent.cpp
@@ -15,84 +15,84 @@
#include <Swift/Controllers/XMPPEvents/MessageEvent.h>
#include <Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h>
-#include "Swift/QtUI/QtSwiftUtil.h"
+#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
-QtEvent::QtEvent(boost::shared_ptr<StanzaEvent> event, bool active) : event_(event) {
- active_ = active;
+QtEvent::QtEvent(std::shared_ptr<StanzaEvent> event, bool active) : event_(event) {
+ active_ = active;
}
QVariant QtEvent::data(int role) {
- switch (role) {
- case Qt::ToolTipRole: return QVariant(text()).toString() + "\n" + B2QDATE(event_->getTime()).toString();
- case Qt::DisplayRole: return QVariant(text());
- case Qt::TextColorRole: return QColor(active_ ? Qt::black : Qt::darkGray);
- case Qt::BackgroundColorRole: return QColor(active_ ? Qt::white : Qt::lightGray);
- case SenderRole: return QVariant(sender());
- /*case StatusTextRole: return statusText_;
- case AvatarRole: return avatar_;
- case PresenceIconRole: return getPresenceIcon();*/
- default: return QVariant();
- }
+ switch (role) {
+ case Qt::ToolTipRole: return QVariant(text()).toString() + "\n" + B2QDATE(event_->getTime()).toString();
+ case Qt::DisplayRole: return QVariant(text());
+ case Qt::TextColorRole: return QColor(active_ ? Qt::black : Qt::darkGray);
+ case Qt::BackgroundColorRole: return QColor(active_ ? Qt::white : Qt::lightGray);
+ case SenderRole: return QVariant(sender());
+ /*case StatusTextRole: return statusText_;
+ case AvatarRole: return avatar_;
+ case PresenceIconRole: return getPresenceIcon();*/
+ default: return QVariant();
+ }
}
QString QtEvent::sender() {
- boost::shared_ptr<MessageEvent> messageEvent = boost::dynamic_pointer_cast<MessageEvent>(event_);
- if (messageEvent) {
- return P2QSTRING(messageEvent->getStanza()->getFrom().toString());
- }
- boost::shared_ptr<SubscriptionRequestEvent> subscriptionRequestEvent = boost::dynamic_pointer_cast<SubscriptionRequestEvent>(event_);
- if (subscriptionRequestEvent) {
- return P2QSTRING(subscriptionRequestEvent->getJID().toBare().toString());
- }
- boost::shared_ptr<ErrorEvent> errorEvent = boost::dynamic_pointer_cast<ErrorEvent>(event_);
- if (errorEvent) {
- return P2QSTRING(errorEvent->getJID().toBare().toString());
- }
- boost::shared_ptr<MUCInviteEvent> mucInviteEvent = boost::dynamic_pointer_cast<MUCInviteEvent>(event_);
- if (mucInviteEvent) {
- return P2QSTRING(mucInviteEvent->getInviter().toString());
- }
- boost::shared_ptr<IncomingFileTransferEvent> incomingFTEvent = boost::dynamic_pointer_cast<IncomingFileTransferEvent>(event_);
- if (incomingFTEvent) {
- return P2QSTRING(incomingFTEvent->getSender().toString());
- }
- return "";
+ std::shared_ptr<MessageEvent> messageEvent = std::dynamic_pointer_cast<MessageEvent>(event_);
+ if (messageEvent) {
+ return P2QSTRING(messageEvent->getStanza()->getFrom().toString());
+ }
+ std::shared_ptr<SubscriptionRequestEvent> subscriptionRequestEvent = std::dynamic_pointer_cast<SubscriptionRequestEvent>(event_);
+ if (subscriptionRequestEvent) {
+ return P2QSTRING(subscriptionRequestEvent->getJID().toBare().toString());
+ }
+ std::shared_ptr<ErrorEvent> errorEvent = std::dynamic_pointer_cast<ErrorEvent>(event_);
+ if (errorEvent) {
+ return P2QSTRING(errorEvent->getJID().toBare().toString());
+ }
+ std::shared_ptr<MUCInviteEvent> mucInviteEvent = std::dynamic_pointer_cast<MUCInviteEvent>(event_);
+ if (mucInviteEvent) {
+ return P2QSTRING(mucInviteEvent->getInviter().toString());
+ }
+ std::shared_ptr<IncomingFileTransferEvent> incomingFTEvent = std::dynamic_pointer_cast<IncomingFileTransferEvent>(event_);
+ if (incomingFTEvent) {
+ return P2QSTRING(incomingFTEvent->getSender().toString());
+ }
+ return "";
}
QString QtEvent::text() {
- boost::shared_ptr<MessageEvent> messageEvent = boost::dynamic_pointer_cast<MessageEvent>(event_);
- if (messageEvent) {
- return P2QSTRING(messageEvent->getStanza()->getBody().get_value_or(""));
- }
- boost::shared_ptr<SubscriptionRequestEvent> subscriptionRequestEvent = boost::dynamic_pointer_cast<SubscriptionRequestEvent>(event_);
- if (subscriptionRequestEvent) {
- std::string reason = subscriptionRequestEvent->getReason();
- QString message;
- if (reason.empty()) {
- message = QString(QObject::tr("%1 would like to add you to their contact list.")).arg(subscriptionRequestEvent->getJID().toBare().toString().c_str());
- }
- else {
- message = QString(QObject::tr("%1 would like to add you to their contact list, saying '%2'")).arg(subscriptionRequestEvent->getJID().toBare().toString().c_str()).arg(reason.c_str());
- }
- return message;
- }
- boost::shared_ptr<ErrorEvent> errorEvent = boost::dynamic_pointer_cast<ErrorEvent>(event_);
- if (errorEvent) {
- return P2QSTRING(errorEvent->getText());
- }
- boost::shared_ptr<MUCInviteEvent> mucInviteEvent = boost::dynamic_pointer_cast<MUCInviteEvent>(event_);
- if (mucInviteEvent) {
- QString message = QString(QObject::tr("%1 has invited you to enter the %2 room.")).arg(P2QSTRING(mucInviteEvent->getInviter().toBare().toString())).arg(P2QSTRING(mucInviteEvent->getRoomJID().toString()));
- return message;
- }
- boost::shared_ptr<IncomingFileTransferEvent> incomingFTEvent = boost::dynamic_pointer_cast<IncomingFileTransferEvent>(event_);
- if (incomingFTEvent) {
- QString message = QString(QObject::tr("%1 would like to send a file to you.")).arg(P2QSTRING(incomingFTEvent->getSender().toBare().toString()));
- return message;
- }
- return "";
+ std::shared_ptr<MessageEvent> messageEvent = std::dynamic_pointer_cast<MessageEvent>(event_);
+ if (messageEvent) {
+ return P2QSTRING(messageEvent->getStanza()->getBody().get_value_or(""));
+ }
+ std::shared_ptr<SubscriptionRequestEvent> subscriptionRequestEvent = std::dynamic_pointer_cast<SubscriptionRequestEvent>(event_);
+ if (subscriptionRequestEvent) {
+ std::string reason = subscriptionRequestEvent->getReason();
+ QString message;
+ if (reason.empty()) {
+ message = QString(QObject::tr("%1 would like to add you to their contact list.")).arg(subscriptionRequestEvent->getJID().toBare().toString().c_str());
+ }
+ else {
+ message = QString(QObject::tr("%1 would like to add you to their contact list, saying '%2'")).arg(subscriptionRequestEvent->getJID().toBare().toString().c_str()).arg(reason.c_str());
+ }
+ return message;
+ }
+ std::shared_ptr<ErrorEvent> errorEvent = std::dynamic_pointer_cast<ErrorEvent>(event_);
+ if (errorEvent) {
+ return P2QSTRING(errorEvent->getText());
+ }
+ std::shared_ptr<MUCInviteEvent> mucInviteEvent = std::dynamic_pointer_cast<MUCInviteEvent>(event_);
+ if (mucInviteEvent) {
+ QString message = QString(QObject::tr("%1 has invited you to enter the %2 room.")).arg(P2QSTRING(mucInviteEvent->getInviter().toBare().toString())).arg(P2QSTRING(mucInviteEvent->getRoomJID().toString()));
+ return message;
+ }
+ std::shared_ptr<IncomingFileTransferEvent> incomingFTEvent = std::dynamic_pointer_cast<IncomingFileTransferEvent>(event_);
+ if (incomingFTEvent) {
+ QString message = QString(QObject::tr("%1 would like to send a file to you.")).arg(P2QSTRING(incomingFTEvent->getSender().toBare().toString()));
+ return message;
+ }
+ return "";
}
}
diff --git a/Swift/QtUI/EventViewer/QtEvent.h b/Swift/QtUI/EventViewer/QtEvent.h
index 8959452..cb78b00 100644
--- a/Swift/QtUI/EventViewer/QtEvent.h
+++ b/Swift/QtUI/EventViewer/QtEvent.h
@@ -1,32 +1,32 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
#include <QVariant>
-#include "Swift/Controllers/XMPPEvents/StanzaEvent.h"
+#include <Swift/Controllers/XMPPEvents/StanzaEvent.h>
namespace Swift {
- class QtEvent {
- public:
- QtEvent(boost::shared_ptr<StanzaEvent> event, bool active);
- QVariant data(int role);
- boost::shared_ptr<StanzaEvent> getEvent() { return event_; }
- enum EventRoles {
- SenderRole = Qt::UserRole
+ class QtEvent {
+ public:
+ QtEvent(std::shared_ptr<StanzaEvent> event, bool active);
+ QVariant data(int role);
+ std::shared_ptr<StanzaEvent> getEvent() { return event_; }
+ enum EventRoles {
+ SenderRole = Qt::UserRole
- };
+ };
- private:
- QString text();
- QString sender();
- boost::shared_ptr<StanzaEvent> event_;
- bool active_;
- };
+ private:
+ QString text();
+ QString sender();
+ std::shared_ptr<StanzaEvent> event_;
+ bool active_;
+ };
}
diff --git a/Swift/QtUI/EventViewer/QtEventWindow.cpp b/Swift/QtUI/EventViewer/QtEventWindow.cpp
index f92cd07..c8d1f0c 100644
--- a/Swift/QtUI/EventViewer/QtEventWindow.cpp
+++ b/Swift/QtUI/EventViewer/QtEventWindow.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -9,12 +9,13 @@
#include <QBoxLayout>
#include <QMessageBox>
#include <QPushButton>
-#include <QtDebug>
+#include <QTreeView>
#include <Swiften/Base/Platform.h>
#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
#include <Swift/Controllers/XMPPEvents/ErrorEvent.h>
#include <Swift/Controllers/XMPPEvents/IncomingFileTransferEvent.h>
#include <Swift/Controllers/XMPPEvents/MUCInviteEvent.h>
@@ -26,97 +27,97 @@
namespace Swift {
QtEventWindow::QtEventWindow(UIEventStream* eventStream) : EventWindow(false) {
- QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom, this);
- layout->setContentsMargins(0,0,0,0);
- layout->setSpacing(0);
-
- view_ = new QTreeView(this);
- layout->addWidget(view_);
- eventStream_ = eventStream;
- model_ = new EventModel();
- view_->setModel(model_);
- delegate_ = new EventDelegate();
- view_->setItemDelegate(delegate_);
- view_->setHeaderHidden(true);
+ QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom, this);
+ layout->setContentsMargins(0,0,0,0);
+ layout->setSpacing(0);
+
+ view_ = new QTreeView(this);
+ layout->addWidget(view_);
+ eventStream_ = eventStream;
+ model_ = new EventModel();
+ view_->setModel(model_);
+ delegate_ = new EventDelegate();
+ view_->setItemDelegate(delegate_);
+ view_->setHeaderHidden(true);
#ifdef SWIFT_PLATFORM_MACOSX
- view_->setAlternatingRowColors(true);
+ view_->setAlternatingRowColors(true);
#endif
- view_->setAnimated(true);
- view_->setIndentation(0);
- view_->setRootIsDecorated(true);
-
- readButton_ = new QPushButton(tr("Display Notice"), this);
- layout->addWidget(readButton_);
- readButton_->setEnabled(false);
- connect(readButton_, SIGNAL(clicked()), this, SLOT(handleReadClicked()));
- connect(view_, SIGNAL(clicked(const QModelIndex&)), this, SLOT(handleItemClicked(const QModelIndex&)));
- connect(view_, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleItemActivated(const QModelIndex&)));
+ view_->setAnimated(true);
+ view_->setIndentation(0);
+ view_->setRootIsDecorated(true);
+
+ readButton_ = new QPushButton(tr("Display Notice"), this);
+ layout->addWidget(readButton_);
+ readButton_->setEnabled(false);
+ connect(readButton_, SIGNAL(clicked()), this, SLOT(handleReadClicked()));
+ connect(view_, SIGNAL(clicked(const QModelIndex&)), this, SLOT(handleItemClicked(const QModelIndex&)));
+ connect(view_, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleItemActivated(const QModelIndex&)));
}
QtEventWindow::~QtEventWindow() {
- delete model_;
- delete delegate_;
- /* Not view_ because this is the parent */
+ delete model_;
+ delete delegate_;
+ /* Not view_ because this is the parent */
}
void QtEventWindow::handleItemClicked(const QModelIndex&) {
- readButton_->setEnabled(true);
+ readButton_->setEnabled(true);
}
void QtEventWindow::handleReadClicked() {
- QModelIndex index = view_->currentIndex();
- if (!index.isValid()) {
- return;
- }
- handleItemActivated(index);
+ QModelIndex index = view_->currentIndex();
+ if (!index.isValid()) {
+ return;
+ }
+ handleItemActivated(index);
}
void QtEventWindow::handleItemActivated(const QModelIndex& item) {
- QtEvent* event = model_->getItem(item.row());
- boost::shared_ptr<MessageEvent> messageEvent = boost::dynamic_pointer_cast<MessageEvent>(event->getEvent());
- boost::shared_ptr<SubscriptionRequestEvent> subscriptionEvent = boost::dynamic_pointer_cast<SubscriptionRequestEvent>(event->getEvent());
- boost::shared_ptr<MUCInviteEvent> mucInviteEvent = boost::dynamic_pointer_cast<MUCInviteEvent>(event->getEvent());
- boost::shared_ptr<IncomingFileTransferEvent> incomingFTEvent = boost::dynamic_pointer_cast<IncomingFileTransferEvent>(event->getEvent());
- boost::shared_ptr<ErrorEvent> errorEvent = boost::dynamic_pointer_cast<ErrorEvent>(event->getEvent());
-
- if (messageEvent) {
- if (messageEvent->getStanza()->getType() == Message::Groupchat) {
- eventStream_->send(boost::shared_ptr<UIEvent>(new JoinMUCUIEvent(messageEvent->getStanza()->getFrom().toBare(), messageEvent->getStanza()->getTo().getResource())));
- } else {
- eventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(messageEvent->getStanza()->getFrom())));
- }
- } else if (subscriptionEvent) {
- QtSubscriptionRequestWindow* window = QtSubscriptionRequestWindow::getWindow(subscriptionEvent, this);
- window->show();
- } else if (mucInviteEvent) {
- eventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(mucInviteEvent->getInviter())));
- mucInviteEvent->conclude();
- } else if (incomingFTEvent) {
- eventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(incomingFTEvent->getSender())));
- incomingFTEvent->conclude();
- } else {
- if (errorEvent) {
- errorEvent->conclude();
- }
- QMessageBox msgBox;
- msgBox.setText(model_->data(item, Qt::DisplayRole).toString());
- msgBox.exec();
- }
+ QtEvent* event = model_->getItem(item.row());
+ std::shared_ptr<MessageEvent> messageEvent = std::dynamic_pointer_cast<MessageEvent>(event->getEvent());
+ std::shared_ptr<SubscriptionRequestEvent> subscriptionEvent = std::dynamic_pointer_cast<SubscriptionRequestEvent>(event->getEvent());
+ std::shared_ptr<MUCInviteEvent> mucInviteEvent = std::dynamic_pointer_cast<MUCInviteEvent>(event->getEvent());
+ std::shared_ptr<IncomingFileTransferEvent> incomingFTEvent = std::dynamic_pointer_cast<IncomingFileTransferEvent>(event->getEvent());
+ std::shared_ptr<ErrorEvent> errorEvent = std::dynamic_pointer_cast<ErrorEvent>(event->getEvent());
+
+ if (messageEvent) {
+ if (messageEvent->getStanza()->getType() == Message::Groupchat) {
+ eventStream_->send(std::make_shared<JoinMUCUIEvent>(messageEvent->getStanza()->getFrom().toBare(), messageEvent->getStanza()->getTo().getResource()));
+ } else {
+ eventStream_->send(std::make_shared<RequestChatUIEvent>(messageEvent->getStanza()->getFrom()));
+ }
+ } else if (subscriptionEvent) {
+ QtSubscriptionRequestWindow* window = QtSubscriptionRequestWindow::getWindow(subscriptionEvent, this);
+ window->show();
+ } else if (mucInviteEvent) {
+ eventStream_->send(std::make_shared<RequestChatUIEvent>(mucInviteEvent->getInviter()));
+ mucInviteEvent->conclude();
+ } else if (incomingFTEvent) {
+ eventStream_->send(std::make_shared<RequestChatUIEvent>(incomingFTEvent->getSender()));
+ incomingFTEvent->conclude();
+ } else {
+ if (errorEvent) {
+ errorEvent->conclude();
+ }
+ QMessageBox msgBox;
+ msgBox.setText(event->data(Qt::DisplayRole).toString());
+ msgBox.exec();
+ }
}
-void QtEventWindow::addEvent(boost::shared_ptr<StanzaEvent> event, bool active) {
- view_->clearSelection();
- model_->addEvent(event, active);
- emit onNewEventCountUpdated(model_->getNewEventCount());
- readButton_->setEnabled(model_->rowCount() > 0);
+void QtEventWindow::addEvent(std::shared_ptr<StanzaEvent> event, bool active) {
+ view_->clearSelection();
+ model_->addEvent(event, active);
+ emit onNewEventCountUpdated(model_->getNewEventCount());
+ readButton_->setEnabled(model_->rowCount() > 0);
}
-void QtEventWindow::removeEvent(boost::shared_ptr<StanzaEvent> event) {
- view_->clearSelection();
- model_->removeEvent(event);
- emit onNewEventCountUpdated(model_->getNewEventCount());
- readButton_->setEnabled(model_->rowCount() > 0);
+void QtEventWindow::removeEvent(std::shared_ptr<StanzaEvent> event) {
+ view_->clearSelection();
+ model_->removeEvent(event);
+ emit onNewEventCountUpdated(model_->getNewEventCount());
+ readButton_->setEnabled(model_->rowCount() > 0);
}
}
diff --git a/Swift/QtUI/EventViewer/QtEventWindow.h b/Swift/QtUI/EventViewer/QtEventWindow.h
index 68c3456..7ae33ec 100644
--- a/Swift/QtUI/EventViewer/QtEventWindow.h
+++ b/Swift/QtUI/EventViewer/QtEventWindow.h
@@ -1,44 +1,48 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
-#include <QTreeView>
+#include <Swift/Controllers/UIInterfaces/EventWindow.h>
-#include "Swift/Controllers/UIInterfaces/EventWindow.h"
-#include "Swift/Controllers/UIEvents/UIEventStream.h"
-#include "Swift/QtUI/EventViewer/EventView.h"
-#include "Swift/QtUI/EventViewer/EventModel.h"
-#include "Swift/QtUI/EventViewer/EventDelegate.h"
+#include <Swift/QtUI/EventViewer/EventDelegate.h>
+#include <Swift/QtUI/EventViewer/EventModel.h>
+#include <Swift/QtUI/EventViewer/EventView.h>
class QPushButton;
+class QTreeView;
namespace Swift {
- class QtEventWindow : public QWidget, public EventWindow {
- Q_OBJECT
- public:
- QtEventWindow(UIEventStream* eventStream);
- ~QtEventWindow();
- void addEvent(boost::shared_ptr<StanzaEvent> event, bool active);
- void removeEvent(boost::shared_ptr<StanzaEvent> event);
- signals:
- void onNewEventCountUpdated(int count);
- private slots:
- void handleItemActivated(const QModelIndex& item);
- void handleItemClicked(const QModelIndex& item);
- void handleReadClicked();
- private:
- EventModel* model_;
- EventDelegate* delegate_;
- UIEventStream* eventStream_;
- QTreeView* view_;
- QPushButton* readButton_;
- };
-
+ class UIEventStream;
+
+ class QtEventWindow : public QWidget, public EventWindow {
+ Q_OBJECT
+ public:
+ QtEventWindow(UIEventStream* eventStream);
+ ~QtEventWindow();
+ void addEvent(std::shared_ptr<StanzaEvent> event, bool active);
+ void removeEvent(std::shared_ptr<StanzaEvent> event);
+
+ signals:
+ void onNewEventCountUpdated(int count);
+
+ private slots:
+ void handleItemActivated(const QModelIndex& item);
+ void handleItemClicked(const QModelIndex& item);
+ void handleReadClicked();
+
+ private:
+ EventModel* model_;
+ EventDelegate* delegate_;
+ UIEventStream* eventStream_;
+ QTreeView* view_;
+ QPushButton* readButton_;
+ };
+
}
diff --git a/Swift/QtUI/EventViewer/TwoLineDelegate.cpp b/Swift/QtUI/EventViewer/TwoLineDelegate.cpp
index 662f5f8..5ba24ec 100644
--- a/Swift/QtUI/EventViewer/TwoLineDelegate.cpp
+++ b/Swift/QtUI/EventViewer/TwoLineDelegate.cpp
@@ -1,20 +1,25 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "TwoLineDelegate.h"
+#include <Swift/QtUI/EventViewer/TwoLineDelegate.h>
-#include <QPen>
+#include <QColor>
#include <QPainter>
-#include <QDebug>
+#include <QPen>
namespace Swift {
+
+namespace {
+ const QColor secondLineColor = QColor(160,160,160);
+}
+
TwoLineDelegate::TwoLineDelegate(int firstRole, int secondRole, bool wrap) {
- firstRole_ = firstRole;
- secondRole_ = secondRole;
- wrap_ = wrap;
+ firstRole_ = firstRole;
+ secondRole_ = secondRole;
+ wrap_ = wrap;
}
TwoLineDelegate::~TwoLineDelegate() {
@@ -22,41 +27,41 @@ TwoLineDelegate::~TwoLineDelegate() {
}
QSize TwoLineDelegate::sizeHint(const QStyleOptionViewItem& /*option*/, QtEvent* /*event*/ ) const {
- QFontMetrics nameMetrics(common_.nameFont);
- QFontMetrics statusMetrics(common_.detailFont);
- int sizeByText = 2 * common_.verticalMargin + nameMetrics.height() + statusMetrics.height();
- return QSize(150, sizeByText);
+ QFontMetrics nameMetrics(common_.nameFont);
+ QFontMetrics statusMetrics(common_.detailFont);
+ int sizeByText = 2 * common_.verticalMargin + nameMetrics.height() + statusMetrics.height();
+ return QSize(150, sizeByText);
}
void TwoLineDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, QtEvent* event) const {
- painter->save();
- QRect fullRegion(option.rect);
- if ( option.state & QStyle::State_Selected ) {
- painter->fillRect(fullRegion, option.palette.highlight());
- painter->setPen(option.palette.highlightedText().color());
- } else {
- QColor nameColor = event->data(Qt::TextColorRole).value<QColor>();
- painter->setPen(QPen(nameColor));
- }
-
- QFontMetrics nameMetrics(common_.nameFont);
- painter->setFont(common_.nameFont);
- int extraFontWidth = nameMetrics.width("H");
- int leftOffset = common_.horizontalMargin * 2 + extraFontWidth / 2;
- QRect textRegion(fullRegion.adjusted(leftOffset, 0, 0, 0));
-
- int nameHeight = nameMetrics.height() + common_.verticalMargin;
- QRect nameRegion(textRegion.adjusted(0, common_.verticalMargin, 0, 0));
-
- DelegateCommons::drawElidedText(painter, nameRegion, event->data(firstRole_).toString());
-
- painter->setFont(common_.detailFont);
- painter->setPen(QPen(QColor(160,160,160)));
-
- QRect detailRegion(textRegion.adjusted(0, nameHeight, 0, 0));
- DelegateCommons::drawElidedText(painter, detailRegion, event->data(secondRole_).toString());
-
- painter->restore();
+ painter->save();
+ QRect fullRegion(option.rect);
+ if ( option.state & QStyle::State_Selected ) {
+ painter->fillRect(fullRegion, option.palette.highlight());
+ painter->setPen(option.palette.highlightedText().color());
+ } else {
+ QColor nameColor = event->data(Qt::TextColorRole).value<QColor>();
+ painter->setPen(QPen(nameColor));
+ }
+
+ QFontMetrics nameMetrics(common_.nameFont);
+ painter->setFont(common_.nameFont);
+ int extraFontWidth = nameMetrics.width("H");
+ int leftOffset = common_.horizontalMargin * 2 + extraFontWidth / 2;
+ QRect textRegion(fullRegion.adjusted(leftOffset, 0, 0, 0));
+
+ int nameHeight = nameMetrics.height() + common_.verticalMargin;
+ QRect nameRegion(textRegion.adjusted(0, common_.verticalMargin, 0, 0));
+
+ DelegateCommons::drawElidedText(painter, nameRegion, event->data(firstRole_).toString());
+
+ painter->setFont(common_.detailFont);
+ painter->setPen(QPen(secondLineColor));
+
+ QRect detailRegion(textRegion.adjusted(0, nameHeight, 0, 0));
+ DelegateCommons::drawElidedText(painter, detailRegion, event->data(secondRole_).toString());
+
+ painter->restore();
}
}
diff --git a/Swift/QtUI/EventViewer/TwoLineDelegate.h b/Swift/QtUI/EventViewer/TwoLineDelegate.h
index e1e3c7a..089f97a 100644
--- a/Swift/QtUI/EventViewer/TwoLineDelegate.h
+++ b/Swift/QtUI/EventViewer/TwoLineDelegate.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,22 +8,22 @@
#include <QStyledItemDelegate>
-#include "Swift/QtUI/Roster/DelegateCommons.h"
-#include "QtEvent.h"
+#include <Swift/QtUI/EventViewer/QtEvent.h>
+#include <Swift/QtUI/Roster/DelegateCommons.h>
namespace Swift {
- class TwoLineDelegate {
- public:
- TwoLineDelegate(int firstRole, int secondRole, bool wrap);
- ~TwoLineDelegate();
- QSize sizeHint(const QStyleOptionViewItem& option, QtEvent* event) const;
- void paint(QPainter* painter, const QStyleOptionViewItem& option, QtEvent* event) const;
- private:
- DelegateCommons common_;
- int firstRole_;
- int secondRole_;
- bool wrap_;
- };
+ class TwoLineDelegate {
+ public:
+ TwoLineDelegate(int firstRole, int secondRole, bool wrap);
+ ~TwoLineDelegate();
+ QSize sizeHint(const QStyleOptionViewItem& option, QtEvent* event) const;
+ void paint(QPainter* painter, const QStyleOptionViewItem& option, QtEvent* event) const;
+ private:
+ DelegateCommons common_;
+ int firstRole_;
+ int secondRole_;
+ bool wrap_;
+ };
}
diff --git a/Swift/QtUI/EventViewer/main.cpp b/Swift/QtUI/EventViewer/main.cpp
index 278dfa8..492599e 100644
--- a/Swift/QtUI/EventViewer/main.cpp
+++ b/Swift/QtUI/EventViewer/main.cpp
@@ -1,31 +1,33 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <QtGui>
-#include "EventView.h"
-#include "EventModel.h"
-#include "QtEventWindow.h"
-#include "Swiften/Events/MessageEvent.h"
-#include "Swiften/Events/ErrorEvent.h"
-#include "Swiften/JID/JID.h"
+#include <EventModel.h>
+#include <EventView.h>
+
+#include <Swiften/Events/ErrorEvent.h>
+#include <Swiften/Events/MessageEvent.h>
+#include <Swiften/JID/JID.h>
+
+#include <Swift/QtUI/EventViewer/QtEventWindow.h>
int main(int argc, char *argv[])
{
- QApplication app(argc, argv);
- Swift::UIEventStream eventStream;
- Swift::QtEventWindow* viewer = new Swift::QtEventWindow(&eventStream);
- viewer->show();
- boost::shared_ptr<Swift::Message> message1(new Swift::Message());
- message1->setBody("Oooh, shiny");
- boost::shared_ptr<Swift::MessageEvent> event1(new Swift::MessageEvent(message1));
- viewer->addEvent(boost::dynamic_pointer_cast<Swift::StanzaEvent>(event1), true);
- for (int i = 0; i < 100; i++) {
- viewer->addEvent(boost::dynamic_pointer_cast<Swift::StanzaEvent>(event1), false);
- }
- viewer->addEvent(boost::dynamic_pointer_cast<Swift::StanzaEvent>(boost::make_shared<Swift::ErrorEvent>(Swift::JID("me@example.com"), "Something bad did happen to you.")), true);
- return app.exec();
+ QApplication app(argc, argv);
+ Swift::UIEventStream eventStream;
+ Swift::QtEventWindow* viewer = new Swift::QtEventWindow(&eventStream);
+ viewer->show();
+ std::shared_ptr<Swift::Message> message1(new Swift::Message());
+ message1->setBody("Oooh, shiny");
+ std::shared_ptr<Swift::MessageEvent> event1(new Swift::MessageEvent(message1));
+ viewer->addEvent(std::dynamic_pointer_cast<Swift::StanzaEvent>(event1), true);
+ for (int i = 0; i < 100; i++) {
+ viewer->addEvent(std::dynamic_pointer_cast<Swift::StanzaEvent>(event1), false);
+ }
+ viewer->addEvent(std::dynamic_pointer_cast<Swift::StanzaEvent>(std::make_shared<Swift::ErrorEvent>(Swift::JID("me@example.com"), "Something bad did happen to you.")), true);
+ return app.exec();
}
diff --git a/Swift/QtUI/FreeDesktopNotifier.cpp b/Swift/QtUI/FreeDesktopNotifier.cpp
index 54e0ccc..16f6a11 100644
--- a/Swift/QtUI/FreeDesktopNotifier.cpp
+++ b/Swift/QtUI/FreeDesktopNotifier.cpp
@@ -23,37 +23,37 @@ FreeDesktopNotifier::FreeDesktopNotifier(const std::string& name) : applicationN
}
void FreeDesktopNotifier::showMessage(Type type, const std::string& subject, const std::string& description, const boost::filesystem::path& picture, boost::function<void()>) {
- QDBusConnection bus = QDBusConnection::sessionBus();
- if (!bus.isConnected()) {
- return;
- }
- std::vector<Notifier::Type> defaultTypes = getDefaultTypes();
- if (std::find(defaultTypes.begin(), defaultTypes.end(), type) == defaultTypes.end()) {
- return;
- }
-
- QString body = description.c_str();
- body = body.replace("&", "&amp;");
- body = body.replace("<", "&lt;");
- body = body.replace(">", "&gt;");
-
- int timeout = (type == IncomingMessage || type == SystemMessage) ? DEFAULT_MESSAGE_NOTIFICATION_TIMEOUT_SECONDS : DEFAULT_STATUS_NOTIFICATION_TIMEOUT_SECONDS;
-
- QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "", "Notify");
-
- QStringList actions;
- QMap<QString, QVariant> hints;
- hints["x-canonical-append"] = QString("allowed");
- msg << applicationName.c_str();
- msg << quint32(0); // ID of previous notification to replace
- msg << P2QSTRING(pathToString(imageScaler.getScaledImage(picture, 48))); // Icon to display
- msg << subject.c_str(); // Summary / Header of the message to display
- msg << body; // Body of the message to display
- msg << actions; // Actions from which the user may choose
- msg << hints; // Hints to the server displaying the message
- msg << qint32(timeout*1000); // Timeout in milliseconds
-
- bus.asyncCall(msg);
+ QDBusConnection bus = QDBusConnection::sessionBus();
+ if (!bus.isConnected()) {
+ return;
+ }
+ std::vector<Notifier::Type> defaultTypes = getDefaultTypes();
+ if (std::find(defaultTypes.begin(), defaultTypes.end(), type) == defaultTypes.end()) {
+ return;
+ }
+
+ QString body = description.c_str();
+ body = body.replace("&", "&amp;");
+ body = body.replace("<", "&lt;");
+ body = body.replace(">", "&gt;");
+
+ int timeout = (type == IncomingMessage || type == SystemMessage) ? DEFAULT_MESSAGE_NOTIFICATION_TIMEOUT_SECONDS : DEFAULT_STATUS_NOTIFICATION_TIMEOUT_SECONDS;
+
+ QDBusMessage msg = QDBusMessage::createMethodCall("org.freedesktop.Notifications", "/org/freedesktop/Notifications", "", "Notify");
+
+ QStringList actions;
+ QMap<QString, QVariant> hints;
+ hints["x-canonical-append"] = QString("allowed");
+ msg << applicationName.c_str();
+ msg << quint32(0); // ID of previous notification to replace
+ msg << P2QSTRING(pathToString(imageScaler.getScaledImage(picture, 48))); // Icon to display
+ msg << subject.c_str(); // Summary / Header of the message to display
+ msg << body; // Body of the message to display
+ msg << actions; // Actions from which the user may choose
+ msg << hints; // Hints to the server displaying the message
+ msg << qint32(timeout*1000); // Timeout in milliseconds
+
+ bus.asyncCall(msg);
}
}
diff --git a/Swift/QtUI/FreeDesktopNotifier.h b/Swift/QtUI/FreeDesktopNotifier.h
index aebe405..dab7e73 100644
--- a/Swift/QtUI/FreeDesktopNotifier.h
+++ b/Swift/QtUI/FreeDesktopNotifier.h
@@ -1,24 +1,25 @@
/*
- * Copyright (c) 2010 -2012 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "SwifTools/Notifier/Notifier.h"
-#include "QtCachedImageScaler.h"
+#include <SwifTools/Notifier/Notifier.h>
+
+#include <Swift/QtUI/QtCachedImageScaler.h>
namespace Swift {
- class FreeDesktopNotifier : public Notifier {
- public:
- FreeDesktopNotifier(const std::string& name);
+ class FreeDesktopNotifier : public Notifier {
+ public:
+ FreeDesktopNotifier(const std::string& name);
- virtual void showMessage(Type type, const std::string& subject, const std::string& description, const boost::filesystem::path& picture, boost::function<void()> callback);
- virtual void purgeCallbacks() {}
+ virtual void showMessage(Type type, const std::string& subject, const std::string& description, const boost::filesystem::path& picture, boost::function<void()> callback);
+ virtual void purgeCallbacks() {}
- private:
- std::string applicationName;
- QtCachedImageScaler imageScaler;
- };
+ private:
+ std::string applicationName;
+ QtCachedImageScaler imageScaler;
+ };
}
diff --git a/Swift/QtUI/MUCSearch/MUCSearchDelegate.cpp b/Swift/QtUI/MUCSearch/MUCSearchDelegate.cpp
index 828b89a..0163e03 100644
--- a/Swift/QtUI/MUCSearch/MUCSearchDelegate.cpp
+++ b/Swift/QtUI/MUCSearch/MUCSearchDelegate.cpp
@@ -1,17 +1,18 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include <QPen>
+#include <Swift/QtUI/MUCSearch/MUCSearchDelegate.h>
+
#include <QPainter>
+#include <QPen>
-#include "Swift/QtUI/MUCSearch/MUCSearchDelegate.h"
-#include "Swift/QtUI/Roster/GroupItemDelegate.h"
-#include "Swift/QtUI/MUCSearch/MUCSearchItem.h"
-#include "Swift/QtUI/MUCSearch/MUCSearchRoomItem.h"
-#include "Swift/QtUI/MUCSearch/MUCSearchServiceItem.h"
+#include <Swift/QtUI/MUCSearch/MUCSearchItem.h>
+#include <Swift/QtUI/MUCSearch/MUCSearchRoomItem.h>
+#include <Swift/QtUI/MUCSearch/MUCSearchServiceItem.h>
+#include <Swift/QtUI/Roster/GroupItemDelegate.h>
namespace Swift {
@@ -24,63 +25,63 @@ MUCSearchDelegate::~MUCSearchDelegate() {
}
// QSize MUCSearchDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index ) const {
-// // MUCSearchItem* item = static_cast<MUCSearchItem*>(index.internalPointer());
-// // if (item && dynamic_cast<MUCSearchMUCItem*>(item)) {
-// // return mucSizeHint(option, index);
-// // } else if (item && dynamic_cast<MUCSearchGroupItem*>(item)) {
-// // return groupDelegate_->sizeHint(option, index);
-// // }
-// return QStyledItemDelegate::sizeHint(option, index);
+// // MUCSearchItem* item = static_cast<MUCSearchItem*>(index.internalPointer());
+// // if (item && dynamic_cast<MUCSearchMUCItem*>(item)) {
+// // return mucSizeHint(option, index);
+// // } else if (item && dynamic_cast<MUCSearchGroupItem*>(item)) {
+// // return groupDelegate_->sizeHint(option, index);
+// // }
+// return QStyledItemDelegate::sizeHint(option, index);
// }
// QSize MUCSearchDelegate::mucSizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/ ) const {
-// QFontMetrics nameMetrics(common_.nameFont);
-// QFontMetrics statusMetrics(common_.detailFont);
-// int sizeByText = 2 * common_.verticalMargin + nameMetrics.height() + statusMetrics.height();
-// return QSize(150, sizeByText);
+// QFontMetrics nameMetrics(common_.nameFont);
+// QFontMetrics statusMetrics(common_.detailFont);
+// int sizeByText = 2 * common_.verticalMargin + nameMetrics.height() + statusMetrics.height();
+// return QSize(150, sizeByText);
// }
// void MUCSearchDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
-// MUCSearchItem* item = static_cast<MUCSearchItem*>(index.internalPointer());
-// if (item && dynamic_cast<MUCSearchMUCItem*>(item)) {
-// paintMUC(painter, option, dynamic_cast<MUCSearchMUCItem*>(item));
-// } else if (item && dynamic_cast<MUCSearchGroupItem*>(item)) {
-// MUCSearchGroupItem* group = dynamic_cast<MUCSearchGroupItem*>(item);
-// groupDelegate_->paint(painter, option, group->data(Qt::DisplayRole).toString(), group->rowCount(), option.state & QStyle::State_Open);
-// } else {
-// QStyledItemDelegate::paint(painter, option, index);
-// }
+// MUCSearchItem* item = static_cast<MUCSearchItem*>(index.internalPointer());
+// if (item && dynamic_cast<MUCSearchMUCItem*>(item)) {
+// paintMUC(painter, option, dynamic_cast<MUCSearchMUCItem*>(item));
+// } else if (item && dynamic_cast<MUCSearchGroupItem*>(item)) {
+// MUCSearchGroupItem* group = dynamic_cast<MUCSearchGroupItem*>(item);
+// groupDelegate_->paint(painter, option, group->data(Qt::DisplayRole).toString(), group->rowCount(), option.state & QStyle::State_Open);
+// } else {
+// QStyledItemDelegate::paint(painter, option, index);
+// }
// }
// void MUCSearchDelegate::paintMUC(QPainter* painter, const QStyleOptionViewItem& option, MUCSearchMUCItem* item) const {
-// painter->save();
-// QRect fullRegion(option.rect);
-// if ( option.state & QStyle::State_Selected ) {
-// painter->fillRect(fullRegion, option.palette.highlight());
-// painter->setPen(option.palette.highlightedText().color());
-// } else {
-// QColor nameColor = item->data(Qt::TextColorRole).value<QColor>();
-// painter->setPen(QPen(nameColor));
-// }
-
-// QFontMetrics nameMetrics(common_.nameFont);
-// painter->setFont(common_.nameFont);
-// int extraFontWidth = nameMetrics.width("H");
-// int leftOffset = common_.horizontalMargin * 2 + extraFontWidth / 2;
-// QRect textRegion(fullRegion.adjusted(leftOffset, 0, 0, 0));
-
-// int nameHeight = nameMetrics.height() + common_.verticalMargin;
-// QRect nameRegion(textRegion.adjusted(0, common_.verticalMargin, 0, 0));
-
-// painter->drawText(nameRegion, Qt::AlignTop, item->data(Qt::DisplayRole).toString());
-
-// painter->setFont(common_.detailFont);
-// painter->setPen(QPen(QColor(160,160,160)));
-
-// QRect detailRegion(textRegion.adjusted(0, nameHeight, 0, 0));
-// painter->drawText(detailRegion, Qt::AlignTop, item->data(DetailTextRole).toString());
-
-// painter->restore();
+// painter->save();
+// QRect fullRegion(option.rect);
+// if ( option.state & QStyle::State_Selected ) {
+// painter->fillRect(fullRegion, option.palette.highlight());
+// painter->setPen(option.palette.highlightedText().color());
+// } else {
+// QColor nameColor = item->data(Qt::TextColorRole).value<QColor>();
+// painter->setPen(QPen(nameColor));
+// }
+
+// QFontMetrics nameMetrics(common_.nameFont);
+// painter->setFont(common_.nameFont);
+// int extraFontWidth = nameMetrics.width("H");
+// int leftOffset = common_.horizontalMargin * 2 + extraFontWidth / 2;
+// QRect textRegion(fullRegion.adjusted(leftOffset, 0, 0, 0));
+
+// int nameHeight = nameMetrics.height() + common_.verticalMargin;
+// QRect nameRegion(textRegion.adjusted(0, common_.verticalMargin, 0, 0));
+
+// painter->drawText(nameRegion, Qt::AlignTop, item->data(Qt::DisplayRole).toString());
+
+// painter->setFont(common_.detailFont);
+// painter->setPen(QPen(QColor(160,160,160)));
+
+// QRect detailRegion(textRegion.adjusted(0, nameHeight, 0, 0));
+// painter->drawText(detailRegion, Qt::AlignTop, item->data(DetailTextRole).toString());
+
+// painter->restore();
// }
}
diff --git a/Swift/QtUI/MUCSearch/MUCSearchDelegate.h b/Swift/QtUI/MUCSearch/MUCSearchDelegate.h
index 57dcaee..5bf9646 100644
--- a/Swift/QtUI/MUCSearch/MUCSearchDelegate.h
+++ b/Swift/QtUI/MUCSearch/MUCSearchDelegate.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,21 +8,21 @@
#include <QStyledItemDelegate>
-#include "Swift/QtUI/Roster/DelegateCommons.h"
+#include <Swift/QtUI/Roster/DelegateCommons.h>
namespace Swift {
- class MUCSearchDelegate : public QStyledItemDelegate {
- public:
- MUCSearchDelegate();
- ~MUCSearchDelegate();
- /* QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; */
- /* void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; */
- private:
-// void paintMUC(QPainter* painter, const QStyleOptionViewItem& option, MUCSearchMUCItem* item) const;
-// QSize mucSizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/ ) const;
+ class MUCSearchDelegate : public QStyledItemDelegate {
+ public:
+ MUCSearchDelegate();
+ ~MUCSearchDelegate();
+ /* QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; */
+ /* void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; */
+ private:
+// void paintMUC(QPainter* painter, const QStyleOptionViewItem& option, MUCSearchMUCItem* item) const;
+// QSize mucSizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/ ) const;
- DelegateCommons common_;
- };
+ DelegateCommons common_;
+ };
}
diff --git a/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.cpp b/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.cpp
index 492971a..3a3b841 100644
--- a/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.cpp
+++ b/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.cpp
@@ -1,38 +1,44 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h>
-#include <Swift/QtUI/MUCSearch/MUCSearchServiceItem.h>
-#include <QFont>
+#include <memory>
+
#include <QColor>
+#include <QFont>
+
+#include <Swift/QtUI/MUCSearch/MUCSearchServiceItem.h>
namespace Swift {
-MUCSearchEmptyItem::MUCSearchEmptyItem(MUCSearchServiceItem* parent) : parent(parent) {
- parent->addRoom(this);
+MUCSearchEmptyItem::MUCSearchEmptyItem() {
+}
+
+void MUCSearchEmptyItem::setParent(std::weak_ptr<MUCSearchServiceItem> parent) {
+ parent_ = parent;
}
-MUCSearchServiceItem* MUCSearchEmptyItem::getParent() {
- return parent;
+std::shared_ptr<MUCSearchServiceItem> MUCSearchEmptyItem::getParent() {
+ return parent_.lock();
}
QVariant MUCSearchEmptyItem::data(int role) {
- switch (role) {
- case Qt::DisplayRole:
- return QVariant(QObject::tr("No rooms found"));
- case Qt::FontRole: {
- QFont font;
- font.setItalic(true);
- return font;
- }
- case Qt::ForegroundRole:
- return QColor(Qt::gray);
- default:
- return QVariant();
- }
+ switch (role) {
+ case Qt::DisplayRole:
+ return QVariant(QObject::tr("No rooms found"));
+ case Qt::FontRole: {
+ QFont font;
+ font.setItalic(true);
+ return font;
+ }
+ case Qt::ForegroundRole:
+ return QColor(Qt::gray);
+ default:
+ return QVariant();
+ }
}
}
diff --git a/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h b/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h
index 74e0154..8a5bb06 100644
--- a/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h
+++ b/Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h
@@ -1,25 +1,28 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <memory>
+
#include <Swift/QtUI/MUCSearch/MUCSearchItem.h>
namespace Swift {
- class MUCSearchServiceItem;
+ class MUCSearchServiceItem;
- class MUCSearchEmptyItem : public MUCSearchItem {
- public:
- MUCSearchEmptyItem(MUCSearchServiceItem* parent);
+ class MUCSearchEmptyItem : public MUCSearchItem {
+ public:
+ MUCSearchEmptyItem();
- MUCSearchServiceItem* getParent();
+ void setParent(std::weak_ptr<MUCSearchServiceItem> parent);
+ std::shared_ptr<MUCSearchServiceItem> getParent();
- QVariant data(int role);
+ QVariant data(int role);
- private:
- MUCSearchServiceItem* parent;
- };
+ private:
+ std::weak_ptr<MUCSearchServiceItem> parent_;
+ };
}
diff --git a/Swift/QtUI/MUCSearch/MUCSearchItem.h b/Swift/QtUI/MUCSearch/MUCSearchItem.h
index d2a2c2d..08daa21 100644
--- a/Swift/QtUI/MUCSearch/MUCSearchItem.h
+++ b/Swift/QtUI/MUCSearch/MUCSearchItem.h
@@ -1,17 +1,23 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <memory>
+
#include <QVariant>
namespace Swift {
- class MUCSearchItem {
- public:
- virtual ~MUCSearchItem() {}
- virtual QVariant data(int role) = 0;
- };
+
+class MUCSearchServiceItem;
+
+class MUCSearchItem {
+ public:
+ virtual ~MUCSearchItem() {}
+ virtual void setParent(std::weak_ptr<MUCSearchServiceItem>) { }
+ virtual QVariant data(int role) = 0;
+ };
}
diff --git a/Swift/QtUI/MUCSearch/MUCSearchModel.cpp b/Swift/QtUI/MUCSearch/MUCSearchModel.cpp
index adb2a11..cc36f5f 100644
--- a/Swift/QtUI/MUCSearch/MUCSearchModel.cpp
+++ b/Swift/QtUI/MUCSearch/MUCSearchModel.cpp
@@ -1,11 +1,14 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/QtUI/MUCSearch/MUCSearchModel.h"
-#include "Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h"
+#include <Swift/QtUI/MUCSearch/MUCSearchModel.h>
+
+#include <memory>
+
+#include <Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h>
namespace Swift {
@@ -13,78 +16,91 @@ MUCSearchModel::MUCSearchModel() {
}
void MUCSearchModel::clear() {
- emit layoutAboutToBeChanged();
- services_.clear();
- emit layoutChanged();
+ // We need to reset the model, so that model indices containing raw pointers
+ // to MUCSearchServiceItems are invalaidated before we delete the
+ // MUCSearchServiceItems.
+ emit beginResetModel();
+ services_.clear();
+ emit endResetModel();
}
-void MUCSearchModel::addService(MUCSearchServiceItem* service) {
- emit layoutAboutToBeChanged();
- services_.push_back(service);
- emit layoutChanged();
+void MUCSearchModel::addService(std::shared_ptr<MUCSearchServiceItem> service) {
+ emit layoutAboutToBeChanged();
+ if (sortOrder_) {
+ service->setSorting(*sortOrder_);
+ }
+ services_.push_back(service);
+ emit layoutChanged();
}
int MUCSearchModel::columnCount(const QModelIndex& /*parent*/) const {
- return 1;
+ return 1;
}
QVariant MUCSearchModel::data(const QModelIndex& index, int role) const {
- return index.isValid() ? static_cast<MUCSearchItem*>(index.internalPointer())->data(role) : QVariant();
+ return index.isValid() ? static_cast<MUCSearchItem*>(index.internalPointer())->data(role) : QVariant();
}
QModelIndex MUCSearchModel::index(int row, int column, const QModelIndex & parent) const {
- if (!hasIndex(row, column, parent)) {
- return QModelIndex();
- }
-
- if (parent.isValid()) {
- MUCSearchServiceItem* parentItem = static_cast<MUCSearchServiceItem*>(parent.internalPointer());
- return row < parentItem->rowCount() ? createIndex(row, column, parentItem->getItem(row)) : QModelIndex();
- } else {
- return row < services_.size() ? createIndex(row, column, services_[row]) : QModelIndex();
- }
-
+ if (!hasIndex(row, column, parent)) {
+ return QModelIndex();
+ }
+ if (parent.isValid()) {
+ MUCSearchServiceItem* parentItem = static_cast<MUCSearchServiceItem*>(parent.internalPointer());
+ return row < parentItem->rowCount() ? createIndex(row, column, parentItem->getItem(row)) : QModelIndex();
+ } else {
+ return row < services_.size() ? createIndex(row, column, services_[row].get()) : QModelIndex();
+ }
}
QModelIndex MUCSearchModel::parent(const QModelIndex& index) const {
- if (!index.isValid()) {
- return QModelIndex();
- }
- MUCSearchItem* item = static_cast<MUCSearchItem*>(index.internalPointer());
- if (!item) {
- return QModelIndex();
- }
- else if (dynamic_cast<MUCSearchServiceItem*>(item)) {
- return QModelIndex();
- }
-
- MUCSearchServiceItem* parent = NULL;
- if (MUCSearchRoomItem* roomItem = dynamic_cast<MUCSearchRoomItem*>(item)) {
- parent = roomItem->getParent();
- }
- else if (MUCSearchEmptyItem* emptyItem = dynamic_cast<MUCSearchEmptyItem*>(item)) {
- parent = emptyItem->getParent();
- }
- if (parent) {
- int row = services_.indexOf(parent);
- return createIndex(row, 1, parent);
- }
- else {
- return QModelIndex();
- }
+ if (!index.isValid()) {
+ return QModelIndex();
+ }
+ MUCSearchItem* item = static_cast<MUCSearchItem*>(index.internalPointer());
+ if (!item) {
+ return QModelIndex();
+ }
+ else if (dynamic_cast<MUCSearchServiceItem*>(item)) {
+ return QModelIndex();
+ }
+
+ std::shared_ptr<MUCSearchServiceItem> parent;
+ if (MUCSearchRoomItem* roomItem = dynamic_cast<MUCSearchRoomItem*>(item)) {
+ parent = roomItem->getParent();
+ }
+ else if (MUCSearchEmptyItem* emptyItem = dynamic_cast<MUCSearchEmptyItem*>(item)) {
+ parent = emptyItem->getParent();
+ }
+ if (parent) {
+ int row = services_.indexOf(parent);
+ return createIndex(row, 1, parent.get());
+ }
+ else {
+ return QModelIndex();
+ }
}
int MUCSearchModel::rowCount(const QModelIndex& parentIndex) const {
- if (!parentIndex.isValid()) {
- return services_.size();
- }
- if (dynamic_cast<MUCSearchServiceItem*>(static_cast<MUCSearchItem*>(parentIndex.internalPointer()))) {
- return services_[parentIndex.row()]->rowCount();
- }
- else {
- return 0;
- }
+ if (!parentIndex.isValid()) {
+ return services_.size();
+ }
+ if (dynamic_cast<MUCSearchServiceItem*>(static_cast<MUCSearchItem*>(parentIndex.internalPointer()))) {
+ return services_[parentIndex.row()]->rowCount();
+ }
+ else {
+ return 0;
+ }
+}
+
+void MUCSearchModel::sort(int column, Qt::SortOrder order) {
+ sortOrder_ = order;
+ if (column == 0) {
+ for (auto&& serviceItem : services_) {
+ serviceItem->setSorting(*sortOrder_);
+ }
+ }
}
}
diff --git a/Swift/QtUI/MUCSearch/MUCSearchModel.h b/Swift/QtUI/MUCSearch/MUCSearchModel.h
index e18a1c0..f36d147 100644
--- a/Swift/QtUI/MUCSearch/MUCSearchModel.h
+++ b/Swift/QtUI/MUCSearch/MUCSearchModel.h
@@ -1,35 +1,37 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
+
+#include <boost/optional.hpp>
#include <QAbstractItemModel>
-#include <QList>
+#include <QVector>
-#include "Swift/QtUI/MUCSearch/MUCSearchServiceItem.h"
+#include <Swift/QtUI/MUCSearch/MUCSearchServiceItem.h>
namespace Swift {
- class MUCSearchModel : public QAbstractItemModel {
- Q_OBJECT
- public:
- MUCSearchModel();
- void clear();
- void addService(MUCSearchServiceItem* service);
- int columnCount(const QModelIndex& parent = QModelIndex()) const;
- QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
- QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
- QModelIndex parent(const QModelIndex& index) const;
- int rowCount(const QModelIndex& parent = QModelIndex()) const;
-// ChatListItem* getItemForIndex(const QModelIndex& index) const;
- private:
-// ChatListGroupItem* mucBookmarks_;
-// ChatListGroupItem* root_;
- QList<MUCSearchServiceItem*> services_;
- };
+ class MUCSearchModel : public QAbstractItemModel {
+ Q_OBJECT
+ public:
+ MUCSearchModel();
+ void clear();
+ void addService(std::shared_ptr<MUCSearchServiceItem> service);
+ int columnCount(const QModelIndex& parent = QModelIndex()) const;
+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
+ QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex& index) const;
+ int rowCount(const QModelIndex& parent = QModelIndex()) const;
+ virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
+
+ private:
+ QVector<std::shared_ptr<MUCSearchServiceItem>> services_;
+ boost::optional<Qt::SortOrder> sortOrder_;
+ };
}
diff --git a/Swift/QtUI/MUCSearch/MUCSearchRoomItem.cpp b/Swift/QtUI/MUCSearch/MUCSearchRoomItem.cpp
index a8c7bbe..9c3ef2c 100644
--- a/Swift/QtUI/MUCSearch/MUCSearchRoomItem.cpp
+++ b/Swift/QtUI/MUCSearch/MUCSearchRoomItem.cpp
@@ -1,26 +1,34 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/QtUI/MUCSearch/MUCSearchRoomItem.h"
+#include <Swift/QtUI/MUCSearch/MUCSearchRoomItem.h>
-#include "Swift/QtUI/MUCSearch/MUCSearchServiceItem.h"
+#include <memory>
+
+#include <Swift/QtUI/MUCSearch/MUCSearchServiceItem.h>
namespace Swift {
-MUCSearchRoomItem::MUCSearchRoomItem(const QString& node, MUCSearchServiceItem* parent) : parent_(parent), node_(node) {
- parent_->addRoom(this);
+
+MUCSearchRoomItem::MUCSearchRoomItem(const QString& node) : node_(node) {
+
}
-MUCSearchServiceItem* MUCSearchRoomItem::getParent() {
- return parent_;
+void MUCSearchRoomItem::setParent(std::weak_ptr<MUCSearchServiceItem> parent) {
+ parent_ = parent;
}
+
+std::shared_ptr<MUCSearchServiceItem> MUCSearchRoomItem::getParent() {
+ return parent_.lock();
+}
+
QVariant MUCSearchRoomItem::data(int role) {
- switch (role) {
- case Qt::DisplayRole: return QVariant(node_);
- default: return QVariant();
- }
+ switch (role) {
+ case Qt::DisplayRole: return QVariant(node_);
+ default: return QVariant();
+ }
}
}
diff --git a/Swift/QtUI/MUCSearch/MUCSearchRoomItem.h b/Swift/QtUI/MUCSearch/MUCSearchRoomItem.h
index d0f8daa..5ecb7d7 100644
--- a/Swift/QtUI/MUCSearch/MUCSearchRoomItem.h
+++ b/Swift/QtUI/MUCSearch/MUCSearchRoomItem.h
@@ -1,23 +1,27 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/QtUI/MUCSearch/MUCSearchItem.h"
+#include <memory>
+
+#include <Swift/QtUI/MUCSearch/MUCSearchItem.h>
namespace Swift {
- class MUCSearchServiceItem;
- class MUCSearchRoomItem : public MUCSearchItem {
- public:
- MUCSearchRoomItem(const QString& node, MUCSearchServiceItem* parent);
- MUCSearchServiceItem* getParent();
- QVariant data(int role);
- QString getNode() const {return node_;}
- private:
- MUCSearchServiceItem* parent_;
- QString node_;
- };
+ class MUCSearchServiceItem;
+ class MUCSearchRoomItem : public MUCSearchItem {
+ public:
+ MUCSearchRoomItem(const QString& node);
+ void setParent(std::weak_ptr<MUCSearchServiceItem> parent);
+ std::shared_ptr<MUCSearchServiceItem> getParent();
+ QVariant data(int role);
+ QString getNode() const {return node_;}
+
+ private:
+ std::weak_ptr<MUCSearchServiceItem> parent_;
+ QString node_;
+ };
}
diff --git a/Swift/QtUI/MUCSearch/MUCSearchServiceItem.cpp b/Swift/QtUI/MUCSearch/MUCSearchServiceItem.cpp
new file mode 100644
index 0000000..57d5aac
--- /dev/null
+++ b/Swift/QtUI/MUCSearch/MUCSearchServiceItem.cpp
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/MUCSearch/MUCSearchServiceItem.h>
+
+#include <memory>
+
+#include <QString>
+#include <QVector>
+#include <QtAlgorithms>
+
+namespace Swift {
+
+MUCSearchServiceItem::MUCSearchServiceItem(const QString& jidString) : jidString_(jidString) {
+
+}
+
+void MUCSearchServiceItem::addRoom(std::shared_ptr<MUCSearchItem> room) {
+ room->setParent(shared_from_this());
+ rooms_.push_back(room);
+ if (sortOrder_) {
+ sort();
+ }
+}
+
+void MUCSearchServiceItem::addRooms(const std::vector<std::shared_ptr<MUCSearchItem> >& rooms) {
+ for (auto&& room: rooms) {
+ room->setParent(shared_from_this());
+ rooms_.push_back(room);
+ }
+ if (sortOrder_) {
+ sort();
+ }
+}
+
+int MUCSearchServiceItem::rowCount() {
+ return rooms_.count();
+}
+
+MUCSearchItem* MUCSearchServiceItem::getItem(int i) {
+ return rooms_[i].get();
+}
+
+QVariant MUCSearchServiceItem::data(int role) {
+ switch (role) {
+ case Qt::DisplayRole:
+ return QVariant(jidString_);
+ default:
+ return QVariant();
+ }
+}
+
+QString MUCSearchServiceItem::getHost() const {
+ return jidString_;
+}
+
+void MUCSearchServiceItem::setSorting(Qt::SortOrder sortOrder) {
+ sortOrder_ = sortOrder;
+ sort();
+}
+
+void MUCSearchServiceItem::sort() {
+ if (*sortOrder_ == Qt::AscendingOrder) {
+ qStableSort(rooms_.begin(), rooms_.end(), [](const std::shared_ptr<MUCSearchItem>& item1, const std::shared_ptr<MUCSearchItem>& item2) -> bool {
+ return QString::localeAwareCompare(item1->data(Qt::DisplayRole).toString(), item2->data(Qt::DisplayRole).toString()) < 0;
+ });
+ }
+ else {
+ qStableSort(rooms_.begin(), rooms_.end(), [](const std::shared_ptr<MUCSearchItem>& item1, const std::shared_ptr<MUCSearchItem>& item2) -> bool {
+ return QString::localeAwareCompare(item1->data(Qt::DisplayRole).toString(), item2->data(Qt::DisplayRole).toString()) > 0;
+ });
+ }
+}
+
+}
diff --git a/Swift/QtUI/MUCSearch/MUCSearchServiceItem.h b/Swift/QtUI/MUCSearch/MUCSearchServiceItem.h
index 306e85a..9f5e000 100644
--- a/Swift/QtUI/MUCSearch/MUCSearchServiceItem.h
+++ b/Swift/QtUI/MUCSearch/MUCSearchServiceItem.h
@@ -1,32 +1,39 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <QList>
+#include <memory>
+
+#include <boost/optional.hpp>
+
#include <QString>
+#include <QVector>
-#include "Swift/QtUI/MUCSearch/MUCSearchRoomItem.h"
+#include <Swift/QtUI/MUCSearch/MUCSearchRoomItem.h>
namespace Swift {
- class MUCSearchServiceItem : public MUCSearchItem {
- public:
- MUCSearchServiceItem(const QString& jidString) : jidString_(jidString) {}
- void addRoom(MUCSearchItem* room) {rooms_.push_back(room);}
- int rowCount() {return rooms_.count();}
- MUCSearchItem* getItem(int i) {return rooms_[i];}
- QVariant data(int role) {
- switch (role) {
- case Qt::DisplayRole: return QVariant(jidString_);
- default: return QVariant();
- }
- }
- QString getHost() const {return jidString_;}
- private:
- QList<MUCSearchItem*> rooms_;
- QString jidString_;
- };
+ class MUCSearchServiceItem : public MUCSearchItem, public std::enable_shared_from_this<MUCSearchServiceItem> {
+ public:
+ MUCSearchServiceItem(const QString& jidString);
+
+ void addRoom(std::shared_ptr<MUCSearchItem> room);
+ void addRooms(const std::vector<std::shared_ptr<MUCSearchItem>>& rooms);
+ int rowCount();
+ MUCSearchItem* getItem(int i);
+ QVariant data(int role);
+ QString getHost() const;
+ void setSorting(Qt::SortOrder sortOrder);
+
+ private:
+ void sort();
+
+ private:
+ QVector<std::shared_ptr<MUCSearchItem>> rooms_;
+ QString jidString_;
+ boost::optional<Qt::SortOrder> sortOrder_;
+ };
}
diff --git a/Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.cpp b/Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.cpp
new file mode 100644
index 0000000..b8cf15a
--- /dev/null
+++ b/Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.cpp
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.h>
+
+namespace Swift {
+
+QtLeafSortFilterProxyModel::QtLeafSortFilterProxyModel(QObject* parent) : QSortFilterProxyModel(parent) {
+
+}
+
+QtLeafSortFilterProxyModel::~QtLeafSortFilterProxyModel() {
+
+}
+
+bool QtLeafSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const {
+ if (!sourceModel()->hasChildren(sourceModel()->index(source_row, 0, source_parent))) {
+ return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
+ }
+ else {
+ return true;
+ }
+}
+
+}
diff --git a/Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.h b/Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.h
new file mode 100644
index 0000000..b4be622
--- /dev/null
+++ b/Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <QSortFilterProxyModel>
+
+namespace Swift {
+
+/**
+ * @brief The QtLeafSortFilterProxyModel class is similar to the QSortFilterProxyModel
+ * class. While the basic QSortFilterProxyModel class filters all hierarchical items,
+ * the QtLeafSortFilterProxyModel class will only filter on items without children.
+ */
+class QtLeafSortFilterProxyModel : public QSortFilterProxyModel {
+ Q_OBJECT
+
+public:
+ QtLeafSortFilterProxyModel(QObject* parent = nullptr);
+ virtual ~QtLeafSortFilterProxyModel();
+
+protected:
+ virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
+};
+
+}
diff --git a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp
index bafb958..f69da41 100644
--- a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp
+++ b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.cpp
@@ -1,58 +1,68 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/QtUI/MUCSearch/QtMUCSearchWindow.h"
+#include <Swift/QtUI/MUCSearch/QtMUCSearchWindow.h>
+
+#include <memory>
+#include <vector>
-#include <qdebug.h>
#include <QMovie>
+#include <QPushButton>
#include <QScrollBar>
+#include <QSortFilterProxyModel>
#include <QTimer>
-#include <QPushButton>
-#include "Swift/Controllers/UIEvents/JoinMUCUIEvent.h"
-#include "Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h"
-#include "Swift/QtUI/MUCSearch/MUCSearchModel.h"
-#include "Swift/QtUI/MUCSearch/MUCSearchDelegate.h"
-#include "Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h"
-#include "Swift/QtUI/QtSwiftUtil.h"
+#include <Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h>
+#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h>
+
+#include <Swift/QtUI/MUCSearch/MUCSearchDelegate.h>
+#include <Swift/QtUI/MUCSearch/MUCSearchEmptyItem.h>
+#include <Swift/QtUI/MUCSearch/MUCSearchModel.h>
+#include <Swift/QtUI/MUCSearch/QtLeafSortFilterProxyModel.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
QtMUCSearchWindow::QtMUCSearchWindow() {
- ui_.setupUi(this);
+ ui_.setupUi(this);
#ifndef Q_OS_MAC
- setWindowIcon(QIcon(":/logo-icon-16.png"));
+ setWindowIcon(QIcon(":/logo-icon-16.png"));
#endif
- setModal(true);
- ui_.filter_->hide();
- model_ = new MUCSearchModel();
- delegate_ = new MUCSearchDelegate();
- ui_.results_->setModel(model_);
- ui_.results_->setItemDelegate(delegate_);
- ui_.results_->setHeaderHidden(true);
- ui_.results_->setRootIsDecorated(true);
- ui_.results_->setAnimated(true);
- ui_.results_->setAlternatingRowColors(true);
- connect(ui_.searchButton, SIGNAL(clicked()), this, SLOT(handleSearch()));
- connect(ui_.service_, SIGNAL(activated(const QString&)), this, SLOT(handleSearch(const QString&)));
- connect(ui_.results_->selectionModel(), SIGNAL(selectionChanged (const QItemSelection&, const QItemSelection&)), this, SLOT(handleSelectionChanged (const QItemSelection&, const QItemSelection&)));
- connect(ui_.results_, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleActivated(const QModelIndex&)));
- connect(ui_.results_, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleActivated(const QModelIndex&)));
- // Not using a button box, because i can't seem to be able to make the ok button non-default (on mac)
- connect(ui_.okButton, SIGNAL(clicked()), this, SLOT(accept()));
- ui_.okButton->setEnabled(false);
- connect(ui_.cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
-
- throbber_ = new QLabel(tr("Searching"), ui_.results_);
- throbber_->setMovie(new QMovie(":/icons/throbber.gif", QByteArray(), throbber_));
- throbber_->setToolTip(tr("Searching"));
-
- hasHadScrollBars_ = false;
- updateThrobberPosition();
- setSearchInProgress(false);
+ setModal(true);
+ model_ = new MUCSearchModel();
+ sortFilterProxyModel_ = new QtLeafSortFilterProxyModel(this);
+ sortFilterProxyModel_->setSourceModel(model_);
+ sortFilterProxyModel_->setDynamicSortFilter(true);
+ delegate_ = new MUCSearchDelegate();
+ ui_.results_->setModel(sortFilterProxyModel_);
+ ui_.results_->setItemDelegate(delegate_);
+ ui_.results_->setHeaderHidden(true);
+ ui_.results_->setRootIsDecorated(true);
+ ui_.results_->setAnimated(true);
+ ui_.results_->setAlternatingRowColors(true);
+ ui_.results_->setSortingEnabled(true);
+ ui_.results_->sortByColumn(0, Qt::AscendingOrder);
+ connect(ui_.searchButton_, SIGNAL(clicked()), this, SLOT(handleSearch()));
+ connect(ui_.service_, SIGNAL(activated(const QString&)), this, SLOT(handleSearch(const QString&)));
+ connect(ui_.results_->selectionModel(), SIGNAL(selectionChanged (const QItemSelection&, const QItemSelection&)), this, SLOT(handleSelectionChanged (const QItemSelection&, const QItemSelection&)));
+ connect(ui_.results_, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleActivated(const QModelIndex&)));
+ connect(ui_.results_, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleActivated(const QModelIndex&)));
+ // Not using a button box, because i can't seem to be able to make the ok button non-default (on mac)
+ connect(ui_.okButton, SIGNAL(clicked()), this, SLOT(accept()));
+ ui_.okButton->setEnabled(false);
+ connect(ui_.cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
+ connect(ui_.filter_, SIGNAL(textChanged(const QString&)), this, SLOT(handleFilterStringChanged(const QString&)));
+
+ throbber_ = new QLabel(tr("Searching"), ui_.results_);
+ throbber_->setMovie(new QMovie(":/icons/throbber.gif", QByteArray(), throbber_));
+ throbber_->setToolTip(tr("Searching"));
+
+ hasHadScrollBars_ = false;
+ updateThrobberPosition();
+ setSearchInProgress(false);
}
QtMUCSearchWindow::~QtMUCSearchWindow() {
@@ -60,136 +70,145 @@ QtMUCSearchWindow::~QtMUCSearchWindow() {
}
void QtMUCSearchWindow::resizeEvent(QResizeEvent* /*event*/) {
- updateThrobberPosition();
+ updateThrobberPosition();
}
void QtMUCSearchWindow::updateThrobberPosition() {
- bool isShown = throbber_->isVisible();
- int resultWidth = ui_.results_->width();
- int resultHeight = ui_.results_->height();
- //throbberWidth = throbber_->movie()->scaledSize().width();
- //throbberHeight = throbber_->movie()->scaledSize().height();
- int throbberWidth = 16; /* This is nasty, but the above doesn't work! */
- int throbberHeight = 16;
- /* It's difficult (or I spent a while trying) to work out whether the scrollbars are currently shown and their appropriate size,
- * because if you listen for the expanded/collapsed signals, you seem to get them before the scrollbars are updated.
- * This seems an acceptable workaround.
- */
- hasHadScrollBars_ |= ui_.results_->verticalScrollBar()->isVisible();
- int hMargin = hasHadScrollBars_ ? ui_.results_->verticalScrollBar()->width() + 2 : 2;
- int vMargin = 2; /* We don't get horizontal scrollbars */
- throbber_->setGeometry(QRect(resultWidth - throbberWidth - hMargin, resultHeight - throbberHeight - vMargin, throbberWidth, throbberHeight)); /* include margins */
- throbber_->setVisible(isShown);
+ bool isShown = throbber_->isVisible();
+ int resultWidth = ui_.results_->width();
+ int resultHeight = ui_.results_->height();
+ //throbberWidth = throbber_->movie()->scaledSize().width();
+ //throbberHeight = throbber_->movie()->scaledSize().height();
+ int throbberWidth = 16; /* This is nasty, but the above doesn't work! */
+ int throbberHeight = 16;
+ /* It's difficult (or I spent a while trying) to work out whether the scrollbars are currently shown and their appropriate size,
+ * because if you listen for the expanded/collapsed signals, you seem to get them before the scrollbars are updated.
+ * This seems an acceptable workaround.
+ */
+ hasHadScrollBars_ |= ui_.results_->verticalScrollBar()->isVisible();
+ int hMargin = hasHadScrollBars_ ? ui_.results_->verticalScrollBar()->width() + 2 : 2;
+ int vMargin = 2; /* We don't get horizontal scrollbars */
+ throbber_->setGeometry(QRect(resultWidth - throbberWidth - hMargin, resultHeight - throbberHeight - vMargin, throbberWidth, throbberHeight)); /* include margins */
+ throbber_->setVisible(isShown);
}
void QtMUCSearchWindow::addSavedServices(const std::list<JID>& services) {
- ui_.service_->clear();
- foreach (const JID& jid, services) {
- ui_.service_->addItem(P2QSTRING(jid.toString()));
- }
- if (!services.empty()) {
- ui_.service_->setEditText(P2QSTRING(services.begin()->toString()));
- }
- else {
- ui_.service_->clearEditText();
- }
+ ui_.service_->clear();
+ for (const auto& jid : services) {
+ ui_.service_->addItem(P2QSTRING(jid.toString()));
+ }
+ if (!services.empty()) {
+ ui_.service_->setEditText(P2QSTRING(services.begin()->toString()));
+ }
+ else {
+ ui_.service_->clearEditText();
+ }
}
void QtMUCSearchWindow::handleActivated(const QModelIndex& index) {
- if (!index.isValid()) {
- return;
- }
- if (dynamic_cast<MUCSearchRoomItem*>(static_cast<MUCSearchItem*>(index.internalPointer()))) {
- accept();
- }
+ if (!index.isValid()) {
+ return;
+ }
+ if (dynamic_cast<MUCSearchRoomItem*>(static_cast<MUCSearchItem*>(sortFilterProxyModel_->mapToSource(index).internalPointer()))) {
+ accept();
+ }
}
void QtMUCSearchWindow::handleSearch() {
- handleSearch(ui_.service_->currentText());
+ handleSearch(ui_.service_->currentText());
}
void QtMUCSearchWindow::handleSearch(const QString& service) {
- if (!service.isEmpty()) {
- onSearchService(JID(Q2PSTRING(service)));
- }
+ if (!service.isEmpty()) {
+ onSearchService(JID(Q2PSTRING(service)));
+ }
+}
+
+void QtMUCSearchWindow::handleFilterStringChanged(const QString& filterString) {
+ sortFilterProxyModel_->setFilterRegExp(filterString);
}
void QtMUCSearchWindow::show() {
- QWidget::show();
- QWidget::activateWindow();
+ ui_.filter_->clear();
+ QWidget::show();
+ QWidget::activateWindow();
}
void QtMUCSearchWindow::clearList() {
- model_->clear();
+ model_->clear();
}
void QtMUCSearchWindow::addService(const MUCService& service) {
- updateThrobberPosition();
- MUCSearchServiceItem* serviceItem = new MUCSearchServiceItem(P2QSTRING(service.getJID().toString()));
- if (service.getRooms().size() > 0) {
- foreach (MUCService::MUCRoom room, service.getRooms()) {
- new MUCSearchRoomItem(P2QSTRING(room.getNode()), serviceItem);
- }
- }
- else {
- new MUCSearchEmptyItem(serviceItem);
- }
- model_->addService(serviceItem);
- ui_.results_->expandAll();
+ updateThrobberPosition();
+ auto serviceItem = std::make_shared<MUCSearchServiceItem>(P2QSTRING(service.getJID().toString()));
+ if (service.getRooms().size() > 0) {
+ std::vector<std::shared_ptr<MUCSearchItem>> rooms;
+ for (auto&& room : service.getRooms()) {
+ if (!room.getNode().empty()) {
+ rooms.push_back(std::make_shared<MUCSearchRoomItem>(P2QSTRING(room.getNode())));
+ }
+ }
+ serviceItem->addRooms(rooms);
+ }
+ else {
+ serviceItem->addRoom(std::make_shared<MUCSearchEmptyItem>());
+ }
+ model_->addService(serviceItem);
+ ui_.results_->expandAll();
}
void QtMUCSearchWindow::setSearchInProgress(bool searching) {
- if (searching) {
- throbber_->movie()->start();
- } else {
- throbber_->movie()->stop();
- }
- throbber_->setVisible(searching);
+ if (searching) {
+ throbber_->movie()->start();
+ } else {
+ throbber_->movie()->stop();
+ }
+ throbber_->setVisible(searching);
}
void QtMUCSearchWindow::accept() {
- MUCSearchRoomItem* room = getSelectedRoom();
- if (room) {
- onFinished(JID(Q2PSTRING(room->getNode()), Q2PSTRING(room->getParent()->getHost())));
- }
- else {
- onFinished(boost::optional<JID>());
- }
- QDialog::accept();
+ MUCSearchRoomItem* room = getSelectedRoom();
+ if (room) {
+ onFinished(JID(Q2PSTRING(room->getNode()), Q2PSTRING(room->getParent()->getHost())));
+ }
+ else {
+ onFinished(boost::optional<JID>());
+ }
+ QDialog::accept();
}
void QtMUCSearchWindow::reject() {
- onFinished(boost::optional<JID>());
- QDialog::reject();
+ onFinished(boost::optional<JID>());
+ QDialog::reject();
}
void QtMUCSearchWindow::handleSelectionChanged(const QItemSelection&, const QItemSelection&) {
- ui_.okButton->setEnabled(getSelectedRoom());
+ ui_.okButton->setEnabled(getSelectedRoom());
}
MUCSearchRoomItem* QtMUCSearchWindow::getSelectedRoom() const {
- // Not using selectedIndexes(), because this seems to cause a crash in Qt (4.7.0) in the
- // QModelIndexList destructor.
- // This is a workaround posted in http://www.qtcentre.org/threads/16933 (although this case
- // was resolved by linking against the debug libs, ours isn't, and we're not alone)
- QItemSelection ranges = ui_.results_->selectionModel()->selection();
- QModelIndexList lstIndex;
- for (int i = 0; i < ranges.count(); ++i) {
- QModelIndex parent = ranges.at(i).parent();
- int right = ranges.at(i).model()->columnCount(parent) - 1;
- if (ranges.at(i).left() == 0 && ranges.at(i).right() == right) {
- for (int r = ranges.at(i).top(); r <= ranges.at(i).bottom(); ++r) {
- lstIndex.append(ranges.at(i).model()->index(r, 0, parent));
- }
- }
- }
- if (lstIndex.isEmpty()) {
- return NULL;
- }
- else {
- return dynamic_cast<MUCSearchRoomItem*>(static_cast<MUCSearchItem*>(lstIndex.first().internalPointer()));
- }
+ // Not using selectedIndexes(), because this seems to cause a crash in Qt (4.7.0) in the
+ // QModelIndexList destructor.
+ // This is a workaround posted in http://www.qtcentre.org/threads/16933 (although this case
+ // was resolved by linking against the debug libs, ours isn't, and we're not alone)
+ QItemSelection ranges = ui_.results_->selectionModel()->selection();
+ QModelIndexList lstIndex;
+ for (int i = 0; i < ranges.count(); ++i) {
+ QModelIndex parent = ranges.at(i).parent();
+ int right = ranges.at(i).model()->columnCount(parent) - 1;
+ if (ranges.at(i).left() == 0 && ranges.at(i).right() == right) {
+ for (int r = ranges.at(i).top(); r <= ranges.at(i).bottom(); ++r) {
+ lstIndex.append(ranges.at(i).model()->index(r, 0, parent));
+ }
+ }
+ }
+ if (lstIndex.isEmpty()) {
+ return nullptr;
+ }
+ else {
+ return dynamic_cast<MUCSearchRoomItem*>(static_cast<MUCSearchItem*>(sortFilterProxyModel_->mapToSource(lstIndex.first()).internalPointer()));
+ }
}
}
diff --git a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.h b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.h
index bc9fb43..6f38533 100644
--- a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.h
+++ b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.h
@@ -1,51 +1,55 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/QtUI/MUCSearch/ui_QtMUCSearchWindow.h"
+#include <Swift/Controllers/UIInterfaces/MUCSearchWindow.h>
-#include "Swift/Controllers/UIInterfaces/MUCSearchWindow.h"
+#include <Swift/QtUI/MUCSearch/ui_QtMUCSearchWindow.h>
+
+class QSortFilterProxyModel;
namespace Swift {
- class MUCSearchModel;
- class MUCSearchDelegate;
- class MUCSearchRoomItem;
-
- class QtMUCSearchWindow : public QDialog, public MUCSearchWindow {
- Q_OBJECT
- public:
- QtMUCSearchWindow();
- virtual ~QtMUCSearchWindow();
-
- virtual void clearList();
- virtual void addService(const MUCService& service);
- virtual void addSavedServices(const std::list<JID>& services);
- virtual void setSearchInProgress(bool searching);
-
- virtual void show();
- virtual void accept();
- virtual void reject();
-
- protected:
- virtual void resizeEvent(QResizeEvent* event);
-
- private slots:
- void handleSearch();
- void handleSearch(const QString&);
- void handleActivated(const QModelIndex& index);
- void updateThrobberPosition();
- void handleSelectionChanged (const QItemSelection&, const QItemSelection&);
- MUCSearchRoomItem* getSelectedRoom() const;
-
- private:
- Ui::QtMUCSearchWindow ui_;
- MUCSearchModel* model_;
- MUCSearchDelegate* delegate_;
- QLabel* throbber_;
- bool hasHadScrollBars_;
- };
+ class MUCSearchModel;
+ class MUCSearchDelegate;
+ class MUCSearchRoomItem;
+
+ class QtMUCSearchWindow : public QDialog, public MUCSearchWindow {
+ Q_OBJECT
+ public:
+ QtMUCSearchWindow();
+ virtual ~QtMUCSearchWindow();
+
+ virtual void clearList();
+ virtual void addService(const MUCService& service);
+ virtual void addSavedServices(const std::list<JID>& services);
+ virtual void setSearchInProgress(bool searching);
+
+ virtual void show();
+ virtual void accept();
+ virtual void reject();
+
+ protected:
+ virtual void resizeEvent(QResizeEvent* event);
+
+ private slots:
+ void handleSearch();
+ void handleSearch(const QString&);
+ void handleFilterStringChanged(const QString&);
+ void handleActivated(const QModelIndex& index);
+ void updateThrobberPosition();
+ void handleSelectionChanged (const QItemSelection&, const QItemSelection&);
+ MUCSearchRoomItem* getSelectedRoom() const;
+
+ private:
+ Ui::QtMUCSearchWindow ui_;
+ MUCSearchModel* model_;
+ MUCSearchDelegate* delegate_;
+ QLabel* throbber_;
+ bool hasHadScrollBars_;
+ QSortFilterProxyModel* sortFilterProxyModel_ = nullptr;
+ };
}
diff --git a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui
index 49460ab..52714c4 100644
--- a/Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui
+++ b/Swift/QtUI/MUCSearch/QtMUCSearchWindow.ui
@@ -6,21 +6,14 @@
<rect>
<x>0</x>
<y>0</y>
- <width>523</width>
- <height>368</height>
+ <width>566</width>
+ <height>264</height>
</rect>
</property>
<property name="windowTitle">
<string>Search Room</string>
</property>
<layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Service:</string>
- </property>
- </widget>
- </item>
<item row="0" column="1">
<widget class="QComboBox" name="service_">
<property name="sizePolicy">
@@ -34,26 +27,14 @@
</property>
</widget>
</item>
- <item row="0" column="3">
- <widget class="QLineEdit" name="filter_">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>1</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
+ <item row="0" column="0">
+ <widget class="QLabel" name="serviceLabel_">
<property name="text">
- <string/>
- </property>
- <property name="frame">
- <bool>true</bool>
+ <string>Service:</string>
</property>
</widget>
</item>
- <item row="1" column="0" colspan="4">
- <widget class="QTreeView" name="results_"/>
- </item>
- <item row="2" column="0" colspan="4">
+ <item row="2" column="0" colspan="5">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
@@ -90,13 +71,42 @@
</item>
</layout>
</item>
+ <item row="0" column="4">
+ <widget class="QLineEdit" name="filter_">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>1</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string/>
+ </property>
+ <property name="frame">
+ <bool>true</bool>
+ </property>
+ <property name="placeholderText">
+ <string/>
+ </property>
+ </widget>
+ </item>
<item row="0" column="2">
- <widget class="QToolButton" name="searchButton">
+ <widget class="QToolButton" name="searchButton_">
<property name="text">
<string>List rooms</string>
</property>
</widget>
</item>
+ <item row="1" column="0" colspan="5">
+ <widget class="QTreeView" name="results_"/>
+ </item>
+ <item row="0" column="3">
+ <widget class="QLabel" name="filterLabel_">
+ <property name="text">
+ <string>Search for</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
<resources/>
diff --git a/Swift/QtUI/MessageSnippet.cpp b/Swift/QtUI/MessageSnippet.cpp
index f76212e..4682365 100644
--- a/Swift/QtUI/MessageSnippet.cpp
+++ b/Swift/QtUI/MessageSnippet.cpp
@@ -1,45 +1,43 @@
/*
- * Copyright (c) 2010-2013 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "MessageSnippet.h"
+#include <Swift/QtUI/MessageSnippet.h>
-#include <QtDebug>
#include <QDateTime>
namespace Swift {
MessageSnippet::MessageSnippet(const QString& message, const QString& sender, const QDateTime& time, const QString& iconURI, bool isIncoming, bool appendToPrevious, QtChatTheme* theme, const QString& id, Direction direction) : ChatSnippet(appendToPrevious) {
- if (appendToPrevious) {
- setContinuationFallbackSnippet(boost::shared_ptr<ChatSnippet>(new MessageSnippet(message, sender, time, iconURI, isIncoming, false, theme, id, direction)));
- }
- if (isIncoming) {
- if (appendToPrevious) {
- content_ = theme->getIncomingNextContent();
- }
- else {
- content_ = theme->getIncomingContent();
- }
- }
- else {
- if (appendToPrevious) {
- content_ = theme->getOutgoingNextContent();
- }
- else {
- content_ = theme->getOutgoingContent();
- }
- }
-
- content_.replace("%direction%", directionToCSS(direction));
- content_.replace("%message%", wrapResizable("<span class='swift_message'>" + escape(message) + "</span><span class='swift_ack'></span><span class='swift_receipt'></span>"));
- content_.replace("%wrapped_sender%", wrapResizable(escape(sender)));
- content_.replace("%sender%", escape(sender));
- content_.replace("%time%", wrapResizable("<span class='swift_time'>" + timeToEscapedString(time) + "</span>"));
- content_.replace("%userIconPath%", escape(iconURI));
- content_ = QString("<div id='%1'>%2</div>").arg(id).arg(content_);
- content_ = "<span class='date" + time.date().toString(Qt::ISODate) + "'>" + content_ + "</span>";
+ if (appendToPrevious) {
+ setContinuationFallbackSnippet(std::make_shared<MessageSnippet>(message, sender, time, iconURI, isIncoming, false, theme, id, direction));
+ }
+ if (isIncoming) {
+ if (appendToPrevious) {
+ content_ = theme->getIncomingNextContent();
+ }
+ else {
+ content_ = theme->getIncomingContent();
+ }
+ }
+ else {
+ if (appendToPrevious) {
+ content_ = theme->getOutgoingNextContent();
+ }
+ else {
+ content_ = theme->getOutgoingContent();
+ }
+ }
+
+ content_.replace("%direction%", directionToCSS(direction));
+ content_.replace("%message%", wrapResizable("<span class='swift_message'>" + escape(message) + "</span>"));
+ content_.replace("%wrapped_sender%", wrapResizable(escape(sender)));
+ content_.replace("%sender%", escape(sender));
+ content_.replace("%time%", wrapResizable("<span class='swift_time'>" + timeToEscapedString(time) + "</span>"));
+ content_.replace("%userIconPath%", escape(iconURI));
+ content_.replace("%id%", id);
}
MessageSnippet::~MessageSnippet() {
diff --git a/Swift/QtUI/MessageSnippet.h b/Swift/QtUI/MessageSnippet.h
index 4e51b1d..302785f 100644
--- a/Swift/QtUI/MessageSnippet.h
+++ b/Swift/QtUI/MessageSnippet.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2013 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,24 +8,24 @@
#include <QString>
-#include "ChatSnippet.h"
+#include <Swift/QtUI/ChatSnippet.h>
class QDateTime;
namespace Swift {
- class MessageSnippet : public ChatSnippet {
- public:
- MessageSnippet(const QString& message, const QString& sender, const QDateTime& time, const QString& iconURI, bool isIncoming, bool appendToPrevious, QtChatTheme* theme, const QString& id, Direction direction);
- virtual ~MessageSnippet();
- const QString& getContent() const {
- return content_;
- }
+ class MessageSnippet : public ChatSnippet {
+ public:
+ MessageSnippet(const QString& message, const QString& sender, const QDateTime& time, const QString& iconURI, bool isIncoming, bool appendToPrevious, QtChatTheme* theme, const QString& id, Direction direction);
+ virtual ~MessageSnippet();
+ const QString& getContent() const {
+ return content_;
+ }
- QString getContinuationElementID() const {
- return "insert";
- }
+ QString getContinuationElementID() const {
+ return "insert";
+ }
- private:
- QString content_;
- };
+ private:
+ QString content_;
+ };
}
diff --git a/Swift/QtUI/NotifierTest/NotifierTest.cpp b/Swift/QtUI/NotifierTest/NotifierTest.cpp
index bae670d..8d2e467 100644
--- a/Swift/QtUI/NotifierTest/NotifierTest.cpp
+++ b/Swift/QtUI/NotifierTest/NotifierTest.cpp
@@ -1,26 +1,28 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <iostream>
+#include <string>
+
#include <boost/bind.hpp>
-#include <string>
-#include "Swiften/Base/ByteArray.h"
-#include "Swiften/Notifier/GrowlNotifier.h"
#include <QApplication>
+#include <Swiften/Base/ByteArray.h>
+#include <Swiften/Notifier/GrowlNotifier.h>
+
using namespace Swift;
void notificationClicked(const std::string& message) {
- std::cout << "Notification clicked: " << message << std::endl;
+ std::cout << "Notification clicked: " << message << std::endl;
}
int main(int argc, char* argv[]) {
- QApplication app(argc, argv);
- GrowlNotifier notifier("Swift-NotifierTest");
- notifier.showMessage(Notifier::ContactAvailable, "Contact is available", "The contact has become available", ByteArray(), boost::bind(&notificationClicked, "Message 1"));
- return app.exec();
+ QApplication app(argc, argv);
+ GrowlNotifier notifier("Swift-NotifierTest");
+ notifier.showMessage(Notifier::ContactAvailable, "Contact is available", "The contact has become available", ByteArray(), boost::bind(&notificationClicked, "Message 1"));
+ return app.exec();
}
diff --git a/Swift/QtUI/QtAboutWidget.cpp b/Swift/QtUI/QtAboutWidget.cpp
index 9fb07ed..9047525 100644
--- a/Swift/QtUI/QtAboutWidget.cpp
+++ b/Swift/QtUI/QtAboutWidget.cpp
@@ -16,73 +16,148 @@
#include <QVBoxLayout>
#include <QtGlobal>
+#include <Swiften/Base/Log.h>
#include <Swiften/Base/Platform.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/QtUISettingConstants.h>
+#include <Swift/QtUI/QtUpdateFeedSelectionDialog.h>
+#include <Swift/QtUI/SwiftUpdateFeeds.h>
+
namespace Swift {
-QtAboutWidget::QtAboutWidget() : QDialog() {
+QtAboutWidget::QtAboutWidget(SettingsProvider* settingsProvider) : QDialog(), settingsProvider_(settingsProvider) {
#ifndef Q_OS_MAC
- setWindowTitle(QString(tr("About %1")).arg("Swift"));
+ setWindowTitle(QString(tr("About %1")).arg("Swift"));
#endif
- setWindowIcon(QIcon(":/logo-icon-16.png"));
-
- resize(180, 240);
- QVBoxLayout *mainLayout = new QVBoxLayout(this);
- mainLayout->setAlignment(Qt::AlignHCenter);
- setLayout(mainLayout);
-
- QLabel* iconLabel = new QLabel(this);
- iconLabel->setPixmap(QIcon(":/logo-shaded-text.256.png").pixmap(90, 90));
- iconLabel->setAlignment(Qt::AlignHCenter);
- mainLayout->addWidget(iconLabel);
-
- QLabel* appNameLabel = new QLabel("<center><font size='+1'><b>" + QCoreApplication::applicationName() + "</b></font></center>", this);
- mainLayout->addWidget(appNameLabel);
-
- QLabel* versionLabel = new QLabel((QString("<center><font size='-1'>") + tr("Version %1") + "</font></center><center><font size='-1'><br/>" + QString(tr("Built with Qt %2")) + QString("<br/>") + QString(tr("Running with Qt %3")) + "</font></center>").arg(QCoreApplication::applicationVersion()).arg(QT_VERSION_STR).arg(qVersion()));
- versionLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
- mainLayout->addWidget(versionLabel);
-
- if (QCoreApplication::translate("TRANSLATION_INFO", "TRANSLATION_AUTHOR") != "TRANSLATION_AUTHOR") {
- mainLayout->addWidget(new QLabel(QString("<center><font size='-1'>") + QString(tr("Using the English translation by\n%1")).arg(QCoreApplication::translate("TRANSLATION_INFO", "TRANSLATION_AUTHOR")).replace("\n", "<br/>") + "</font></center>", this));
- }
- QCoreApplication::translate("TRANSLATION_INFO", "TRANSLATION_LICENSE", "This string contains the license under which this translation is licensed. We ask you to license the translation under the BSD license. Please read http://www.opensource.org/licenses/bsd-license.php, and if you agree to release your translation under this license, use the following (untranslated) text: 'This translation is licensed under the BSD License. See http://www.opensource.org/licenses/bsd-license.php'");
+ setWindowIcon(QIcon(":/logo-icon-16.png"));
+
+ resize(180, 240);
+ QVBoxLayout *mainLayout = new QVBoxLayout(this);
+ mainLayout->setAlignment(Qt::AlignHCenter);
+ setLayout(mainLayout);
+
+ QLabel* iconLabel = new QLabel(this);
+ iconLabel->setPixmap(QIcon(":/logo-shaded-text.256.png").pixmap(90, 90));
+ iconLabel->setAlignment(Qt::AlignHCenter);
+ mainLayout->addWidget(iconLabel);
+
+ QLabel* appNameLabel = new QLabel("<center><font size='+1'><b>" + QCoreApplication::applicationName() + "</b></font></center>", this);
+ mainLayout->addWidget(appNameLabel);
+
+ QLabel* versionLabel = new QLabel((QString("<center><font size='-1'>") + tr("Version %1") + "</font></center><center><font size='-1'><br/>" + QString(tr("Built with Qt %2")) + QString("<br/>") + QString(tr("Running with Qt %3")) + "</font></center>").arg(QCoreApplication::applicationVersion()).arg(QT_VERSION_STR).arg(qVersion()));
+ versionLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
+ mainLayout->addWidget(versionLabel);
+
+ settingsChangedConnection_ = settingsProvider_->onSettingChanged.connect([&](const std::string& path) {
+ if (path == QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL.getKey() || path == QtUISettingConstants::ENABLE_SOFTWARE_UPDATES.getKey()) {
+ updateUpdateInfoLabel();
+ }
+ });
+
+ updateInfoLabel_ = new QLabel("", this);
+ updateInfoLabel_->setTextInteractionFlags(Qt::LinksAccessibleByKeyboard | Qt::LinksAccessibleByMouse);
+ connect(updateInfoLabel_, SIGNAL(linkActivated(const QString &)), this, SLOT(handleChangeUpdateChannelClicked()));
+ mainLayout->addWidget(updateInfoLabel_);
+
+ updateUpdateInfoLabel();
+
+ if (QCoreApplication::translate("TRANSLATION_INFO", "TRANSLATION_AUTHOR") != "TRANSLATION_AUTHOR") {
+ mainLayout->addWidget(new QLabel(QString("<center><font size='-1'>") + QString(tr("Using the English translation by\n%1")).arg(QCoreApplication::translate("TRANSLATION_INFO", "TRANSLATION_AUTHOR")).replace("\n", "<br/>") + "</font></center>", this));
+ }
+ QCoreApplication::translate("TRANSLATION_INFO", "TRANSLATION_LICENSE", "This string contains the license under which this translation is licensed. We ask you to license the translation under the BSD license. Please read http://www.opensource.org/licenses/bsd-license.php, and if you agree to release your translation under this license, use the following (untranslated) text: 'This translation is licensed under the BSD License. See http://www.opensource.org/licenses/bsd-license.php'");
#if defined(SWIFTEN_PLATFORM_WINDOWS) || defined(SWIFTEN_PLATFORM_MACOSX)
- QPushButton* licenseButton = new QPushButton(tr("View License"), this);
- mainLayout->addWidget(licenseButton);
- connect(licenseButton, SIGNAL(clicked()), this, SLOT(handleLicenseClicked()));
+ QPushButton* licenseButton = new QPushButton(tr("View License"), this);
+ mainLayout->addWidget(licenseButton);
+ connect(licenseButton, SIGNAL(clicked()), this, SLOT(handleLicenseClicked()));
+
+ QPushButton* changelogButton = new QPushButton(tr("View Changes"), this);
+ mainLayout->addWidget(changelogButton);
+ connect(changelogButton, SIGNAL(clicked()), this, SLOT(handleChangelogClicked()));
#else
- // Some Linux desktops have dialog window decorations without close window buttons.
- // This code adds a dedicated button to close the about window dialog.
- QHBoxLayout* buttonLayout = new QHBoxLayout();
- mainLayout->addLayout(buttonLayout);
+ // Some Linux desktops have dialog window decorations without close window buttons.
+ // This code adds a dedicated button to close the about window dialog.
+ QHBoxLayout* buttonLayout = new QHBoxLayout();
+ mainLayout->addLayout(buttonLayout);
- QPushButton* licenseButton = new QPushButton(tr("View License"), this);
- buttonLayout->addWidget(licenseButton);
- connect(licenseButton, SIGNAL(clicked()), this, SLOT(handleLicenseClicked()));
+ QPushButton* licenseButton = new QPushButton(tr("View License"), this);
+ buttonLayout->addWidget(licenseButton);
+ connect(licenseButton, SIGNAL(clicked()), this, SLOT(handleLicenseClicked()));
- buttonLayout->addItem(new QSpacerItem(20,20));
+ QPushButton* changelogButton = new QPushButton(tr("View Changes"), this);
+ buttonLayout->addWidget(changelogButton);
+ connect(changelogButton, SIGNAL(clicked()), this, SLOT(handleChangelogClicked()));
- QPushButton* closeButton = new QPushButton(tr("Close"), this);
- buttonLayout->addWidget(closeButton);
- connect(closeButton, SIGNAL(clicked()), this, SLOT(accept()));
+ buttonLayout->addItem(new QSpacerItem(20,20));
+
+ QPushButton* closeButton = new QPushButton(tr("Close"), this);
+ buttonLayout->addWidget(closeButton);
+ connect(closeButton, SIGNAL(clicked()), this, SLOT(accept()));
#endif
- setFixedSize(minimumSizeHint());
+ setFixedSize(minimumSizeHint());
}
void QtAboutWidget::handleLicenseClicked() {
- QTextEdit* text = new QTextEdit();
- text->setAttribute(Qt::WA_DeleteOnClose);
- text->setReadOnly(true);
- QFile file(":/COPYING");
- file.open(QIODevice::ReadOnly);
- QTextStream in(&file);
- in.setCodec("UTF-8");
- text->setPlainText(in.readAll());
- file.close();
- text->resize(500, 600);
- text->show();
- text->activateWindow();
+ openPlainTextWindow(":/COPYING");
+}
+
+void QtAboutWidget::handleChangelogClicked() {
+ openPlainTextWindow(":/ChangeLog.md");
+}
+
+void QtAboutWidget::handleChangeUpdateChannelClicked() {
+ auto feedSelectionDialog = new QtUpdateFeedSelectionDialog(settingsProvider_);
+ feedSelectionDialog->show();
+}
+
+void QtAboutWidget::openPlainTextWindow(const QString& path) {
+ QTextEdit* text = new QTextEdit();
+ text->setAttribute(Qt::WA_DeleteOnClose);
+ text->setReadOnly(true);
+ QFile file(path);
+ if (file.open(QIODevice::ReadOnly)) {
+ QTextStream in(&file);
+ in.setCodec("UTF-8");
+ text->setPlainText(in.readAll());
+ file.close();
+ text->resize(500, 600);
+ text->show();
+ text->activateWindow();
+ }
+ else {
+ SWIFT_LOG(error) << "Failed to open " << Q2PSTRING(path) << "." << std::endl;
+ }
+}
+
+void QtAboutWidget::updateUpdateInfoLabel() {
+ if (settingsProvider_->getSetting(QtUISettingConstants::ENABLE_SOFTWARE_UPDATES)) {
+ if (!settingsProvider_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL).empty()) {
+ QString updateFeedDescription;
+ auto addUpdateFeedDialogLink = false;
+ if (settingsProvider_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL) == UpdateFeeds::StableChannel) {
+ updateFeedDescription = tr("You are receiving updates from the Stable update channel.");
+ addUpdateFeedDialogLink = true;
+ }
+ else if (settingsProvider_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL) == UpdateFeeds::DevelopmentChannel) {
+ updateFeedDescription = tr("You are receiving updates from the Development update channel.");
+ addUpdateFeedDialogLink = true;
+ }
+ else if (settingsProvider_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL) == UpdateFeeds::TestingChannel) {
+ updateFeedDescription = tr("You are receiving updates from the Testing update channel.");
+ addUpdateFeedDialogLink = true;
+ }
+ auto updateFeedDialogLink = QString( addUpdateFeedDialogLink ? "<a href=\"#\">%1</a>" : "" ).arg(tr("Change the update channel."));
+ updateInfoLabel_->setText(QString("<center><font size='-1'>%1<br/>%2</font></center>").arg(updateFeedDescription, updateFeedDialogLink));
+ updateInfoLabel_->show();
+ }
+ else {
+ updateInfoLabel_->hide();
+ }
+ }
+ else {
+ updateInfoLabel_->hide();
+ }
+
}
}
diff --git a/Swift/QtUI/QtAboutWidget.h b/Swift/QtUI/QtAboutWidget.h
index d09010b..fb54c6e 100644
--- a/Swift/QtUI/QtAboutWidget.h
+++ b/Swift/QtUI/QtAboutWidget.h
@@ -1,21 +1,38 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <boost/signals2/connection.hpp>
+
#include <QDialog>
+class QLabel;
+
namespace Swift {
- class QtAboutWidget : public QDialog {
- Q_OBJECT
+ class SettingsProvider;
+
+ class QtAboutWidget : public QDialog {
+ Q_OBJECT
+
+ public:
+ QtAboutWidget(SettingsProvider* settings);
+
+ private slots:
+ void handleLicenseClicked();
+ void handleChangelogClicked();
+ void handleChangeUpdateChannelClicked();
- public:
- QtAboutWidget();
+ private:
+ void openPlainTextWindow(const QString& path);
+ void updateUpdateInfoLabel();
- private slots:
- void handleLicenseClicked();
- };
+ private:
+ SettingsProvider* settingsProvider_;
+ QLabel* updateInfoLabel_ = nullptr;
+ boost::signals2::scoped_connection settingsChangedConnection_;
+ };
}
diff --git a/Swift/QtUI/QtAdHocCommandWindow.cpp b/Swift/QtUI/QtAdHocCommandWindow.cpp
index ef397f4..65dac91 100644
--- a/Swift/QtUI/QtAdHocCommandWindow.cpp
+++ b/Swift/QtUI/QtAdHocCommandWindow.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -19,156 +19,156 @@
const int FormLayoutIndex = 1;
namespace Swift {
-QtAdHocCommandWindow::QtAdHocCommandWindow(boost::shared_ptr<OutgoingAdHocCommandSession> command) : command_(command) {
- formWidget_ = NULL;
-
- setAttribute(Qt::WA_DeleteOnClose);
- command->onNextStageReceived.connect(boost::bind(&QtAdHocCommandWindow::handleNextStageReceived, this, _1));
- command->onError.connect(boost::bind(&QtAdHocCommandWindow::handleError, this, _1));
- command->start();
-
- layout_ = new QBoxLayout(QBoxLayout::TopToBottom, this);
- layout_->setContentsMargins(0,0,0,0);
- layout_->setSpacing(2);
- label_ = new QLabel(this);
- label_->setTextFormat(Qt::PlainText);
- layout_->addWidget(label_);
-
- errorLabel_ = new QLabel(this);
- errorLabel_->setText(QString("<b>%1</b>").arg(tr("Unable to complete the command because you have been disconnected")));
- errorLabel_->setVisible(false);
- errorLabel_->setFrameStyle(QFrame::Box|QFrame::Sunken);
- layout_->addWidget(errorLabel_);
-
- dialogButtons_ = new QDialogButtonBox(this);
- layout_->addWidget(dialogButtons_);
-
- dialogButtons_->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
- okButton_ = dialogButtons_->button(QDialogButtonBox::Ok);
- connect(okButton_, SIGNAL(clicked()), this, SLOT(close()));
- cancelButton_ = dialogButtons_->button(QDialogButtonBox::Cancel);
- connect(cancelButton_, SIGNAL(clicked()), this, SLOT(handleCancelClicked()));
- // Buttons appear next to the Ok button, right of Cancel with YesRole
- completeButton_ = dialogButtons_->addButton(tr("Complete"), QDialogButtonBox::YesRole);
- connect(completeButton_, SIGNAL(clicked()), this, SLOT(handleCompleteClicked()));
- nextButton_ = dialogButtons_->addButton(tr("Next"), QDialogButtonBox::YesRole);
- connect(nextButton_, SIGNAL(clicked()), this, SLOT(handleNextClicked()));
- backButton_ = dialogButtons_->addButton(tr("Back"), QDialogButtonBox::YesRole);
- connect(backButton_, SIGNAL(clicked()), this, SLOT(handlePrevClicked()));
-
- okButton_->setEnabled(false);
- okButton_->hide();
-
- nextButton_->setEnabled(false);
- backButton_->setEnabled(false);
- completeButton_->setEnabled(false);
-
- actions_[Command::Next] = nextButton_;
- actions_[Command::Prev] = backButton_;
- actions_[Command::Complete] = completeButton_;
- actions_[Command::Cancel] = cancelButton_;
+QtAdHocCommandWindow::QtAdHocCommandWindow(std::shared_ptr<OutgoingAdHocCommandSession> command) : command_(command) {
+ formWidget_ = nullptr;
+
+ setAttribute(Qt::WA_DeleteOnClose);
+ command->onNextStageReceived.connect(boost::bind(&QtAdHocCommandWindow::handleNextStageReceived, this, _1));
+ command->onError.connect(boost::bind(&QtAdHocCommandWindow::handleError, this, _1));
+ command->start();
+
+ layout_ = new QBoxLayout(QBoxLayout::TopToBottom, this);
+ layout_->setContentsMargins(0,0,0,0);
+ layout_->setSpacing(2);
+ label_ = new QLabel(this);
+ label_->setTextFormat(Qt::PlainText);
+ layout_->addWidget(label_);
+
+ errorLabel_ = new QLabel(this);
+ errorLabel_->setText(QString("<b>%1</b>").arg(tr("Unable to complete the command because you have been disconnected")));
+ errorLabel_->setVisible(false);
+ errorLabel_->setFrameStyle(QFrame::Box|QFrame::Sunken);
+ layout_->addWidget(errorLabel_);
+
+ dialogButtons_ = new QDialogButtonBox(this);
+ layout_->addWidget(dialogButtons_);
+
+ dialogButtons_->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Ok);
+ okButton_ = dialogButtons_->button(QDialogButtonBox::Ok);
+ connect(okButton_, SIGNAL(clicked()), this, SLOT(close()));
+ cancelButton_ = dialogButtons_->button(QDialogButtonBox::Cancel);
+ connect(cancelButton_, SIGNAL(clicked()), this, SLOT(handleCancelClicked()));
+ // Buttons appear next to the Ok button, right of Cancel with YesRole
+ completeButton_ = dialogButtons_->addButton(tr("Complete"), QDialogButtonBox::YesRole);
+ connect(completeButton_, SIGNAL(clicked()), this, SLOT(handleCompleteClicked()));
+ nextButton_ = dialogButtons_->addButton(tr("Next"), QDialogButtonBox::YesRole);
+ connect(nextButton_, SIGNAL(clicked()), this, SLOT(handleNextClicked()));
+ backButton_ = dialogButtons_->addButton(tr("Back"), QDialogButtonBox::YesRole);
+ connect(backButton_, SIGNAL(clicked()), this, SLOT(handlePrevClicked()));
+
+ okButton_->setEnabled(false);
+ okButton_->hide();
+
+ nextButton_->setEnabled(false);
+ backButton_->setEnabled(false);
+ completeButton_->setEnabled(false);
+
+ actions_[Command::Next] = nextButton_;
+ actions_[Command::Prev] = backButton_;
+ actions_[Command::Complete] = completeButton_;
+ actions_[Command::Cancel] = cancelButton_;
}
QtAdHocCommandWindow::~QtAdHocCommandWindow() {
}
void QtAdHocCommandWindow::setOnline(bool online) {
- if (!online) {
- nextButton_->setEnabled(false);
- backButton_->setEnabled(false);
- completeButton_->setEnabled(false);
- errorLabel_->setVisible(true);
- }
+ if (!online) {
+ nextButton_->setEnabled(false);
+ backButton_->setEnabled(false);
+ completeButton_->setEnabled(false);
+ errorLabel_->setVisible(true);
+ }
}
void QtAdHocCommandWindow::closeEvent(QCloseEvent*) {
- onClosing();
+ onClosing();
}
void QtAdHocCommandWindow::handleCancelClicked() {
- command_->cancel();
- close();
+ command_->cancel();
+ close();
}
void QtAdHocCommandWindow::handlePrevClicked() {
- command_->goBack();
+ command_->goBack();
}
void QtAdHocCommandWindow::handleNextClicked() {
- command_->goNext(formWidget_ ? formWidget_->getCompletedForm() : Form::ref());
+ command_->goNext(formWidget_ ? formWidget_->getCompletedForm() : Form::ref());
}
void QtAdHocCommandWindow::handleCompleteClicked() {
- command_->complete(formWidget_ ? formWidget_->getCompletedForm() : Form::ref());
+ command_->complete(formWidget_ ? formWidget_->getCompletedForm() : Form::ref());
}
void QtAdHocCommandWindow::handleNextStageReceived(Command::ref command) {
- QString notes;
- foreach (Command::Note note, command->getNotes()) {
- if (!notes.isEmpty()) {
- notes += "\n";
- }
- QString qNote(P2QSTRING(note.note));
- switch (note.type) {
- case Command::Note::Error: notes += tr("Error: %1").arg(qNote); break;
- case Command::Note::Warn: notes += tr("Warning: %1").arg(qNote); break;
- case Command::Note::Info: notes += qNote; break;
- }
- }
- label_->setText(notes);
- if (command->getForm()) {
- setForm(command->getForm());
- } else {
- setNoForm(notes.isEmpty());
- }
- setAvailableActions(command);
+ QString notes;
+ for (const auto& note : command->getNotes()) {
+ if (!notes.isEmpty()) {
+ notes += "\n";
+ }
+ QString qNote(P2QSTRING(note.note));
+ switch (note.type) {
+ case Command::Note::Error: notes += tr("Error: %1").arg(qNote); break;
+ case Command::Note::Warn: notes += tr("Warning: %1").arg(qNote); break;
+ case Command::Note::Info: notes += qNote; break;
+ }
+ }
+ label_->setText(notes);
+ if (command->getForm()) {
+ setForm(command->getForm());
+ } else {
+ setNoForm(notes.isEmpty());
+ }
+ setAvailableActions(command);
}
void QtAdHocCommandWindow::handleError(ErrorPayload::ref /*error*/) {
- nextButton_->setEnabled(false);
- backButton_->setEnabled(false);
- completeButton_->setEnabled(false);
- label_->setText(tr("Error executing command"));
+ nextButton_->setEnabled(false);
+ backButton_->setEnabled(false);
+ completeButton_->setEnabled(false);
+ label_->setText(tr("Error executing command"));
}
void QtAdHocCommandWindow::setForm(Form::ref form) {
- form_ = form;
- delete formWidget_;
- formWidget_ = new QtFormWidget(form, this);
- layout_->insertWidget(FormLayoutIndex, formWidget_);
- show();
+ form_ = form;
+ delete formWidget_;
+ formWidget_ = new QtFormWidget(form, this);
+ layout_->insertWidget(FormLayoutIndex, formWidget_);
+ show();
}
void QtAdHocCommandWindow::setNoForm(bool andHide) {
- form_.reset();
- delete formWidget_;
- formWidget_ = NULL;
- resize(minimumSize());
- setVisible(!andHide);
+ form_.reset();
+ delete formWidget_;
+ formWidget_ = nullptr;
+ resize(minimumSize());
+ setVisible(!andHide);
}
typedef std::pair<Command::Action, QPushButton*> ActionButton;
void QtAdHocCommandWindow::setAvailableActions(Command::ref /*commandResult*/) {
- okButton_->show();
- okButton_->setEnabled(true);
- foreach (ActionButton pair, actions_) {
- OutgoingAdHocCommandSession::ActionState state = command_->getActionState(pair.first);
- if (state & OutgoingAdHocCommandSession::Present) {
- okButton_->hide();
- okButton_->setEnabled(false);
- pair.second->show();
- }
- else {
- pair.second->hide();
- }
- if (state & OutgoingAdHocCommandSession::Enabled) {
- pair.second->setEnabled(true);
- }
- else {
- pair.second->setEnabled(false);
- }
- }
+ okButton_->show();
+ okButton_->setEnabled(true);
+ for (auto&& pair : actions_) {
+ OutgoingAdHocCommandSession::ActionState state = command_->getActionState(pair.first);
+ if (state & OutgoingAdHocCommandSession::Present) {
+ okButton_->hide();
+ okButton_->setEnabled(false);
+ pair.second->show();
+ }
+ else {
+ pair.second->hide();
+ }
+ if (state & OutgoingAdHocCommandSession::Enabled) {
+ pair.second->setEnabled(true);
+ }
+ else {
+ pair.second->setEnabled(false);
+ }
+ }
}
}
diff --git a/Swift/QtUI/QtAdHocCommandWindow.h b/Swift/QtUI/QtAdHocCommandWindow.h
index c8d493c..1135ef9 100644
--- a/Swift/QtUI/QtAdHocCommandWindow.h
+++ b/Swift/QtUI/QtAdHocCommandWindow.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -18,41 +18,41 @@
class QBoxLayout;
namespace Swift {
- class QtFormWidget;
- class QtAdHocCommandWindow : public QWidget, public AdHocCommandWindow {
- Q_OBJECT
- public:
- QtAdHocCommandWindow(boost::shared_ptr<OutgoingAdHocCommandSession> command);
- virtual ~QtAdHocCommandWindow();
- virtual void setOnline(bool online);
-
- private:
- void closeEvent(QCloseEvent* event);
- void handleNextStageReceived(Command::ref command);
- void handleError(ErrorPayload::ref error);
- void setForm(Form::ref);
- void setNoForm(bool andHide);
- void setAvailableActions(Command::ref commandResult);
-
- private slots:
- void handleCancelClicked();
- void handlePrevClicked();
- void handleNextClicked();
- void handleCompleteClicked();
-
- private:
- boost::shared_ptr<OutgoingAdHocCommandSession> command_;
- QtFormWidget* formWidget_;
- Form::ref form_;
- QLabel* label_;
- QLabel* errorLabel_;
- QPushButton* backButton_;
- QPushButton* nextButton_;
- QPushButton* completeButton_;
- QPushButton* cancelButton_;
- QPushButton* okButton_;
- std::map<Command::Action, QPushButton*> actions_;
- QDialogButtonBox* dialogButtons_;
- QBoxLayout* layout_;
- };
+ class QtFormWidget;
+ class QtAdHocCommandWindow : public QWidget, public AdHocCommandWindow {
+ Q_OBJECT
+ public:
+ QtAdHocCommandWindow(std::shared_ptr<OutgoingAdHocCommandSession> command);
+ virtual ~QtAdHocCommandWindow();
+ virtual void setOnline(bool online);
+
+ private:
+ void closeEvent(QCloseEvent* event);
+ void handleNextStageReceived(Command::ref command);
+ void handleError(ErrorPayload::ref error);
+ void setForm(Form::ref);
+ void setNoForm(bool andHide);
+ void setAvailableActions(Command::ref commandResult);
+
+ private slots:
+ void handleCancelClicked();
+ void handlePrevClicked();
+ void handleNextClicked();
+ void handleCompleteClicked();
+
+ private:
+ std::shared_ptr<OutgoingAdHocCommandSession> command_;
+ QtFormWidget* formWidget_;
+ Form::ref form_;
+ QLabel* label_;
+ QLabel* errorLabel_;
+ QPushButton* backButton_;
+ QPushButton* nextButton_;
+ QPushButton* completeButton_;
+ QPushButton* cancelButton_;
+ QPushButton* okButton_;
+ std::map<Command::Action, QPushButton*> actions_;
+ QDialogButtonBox* dialogButtons_;
+ QBoxLayout* layout_;
+ };
}
diff --git a/Swift/QtUI/QtAdHocCommandWithJIDWindow.cpp b/Swift/QtUI/QtAdHocCommandWithJIDWindow.cpp
index ac2a603..1b114d9 100644
--- a/Swift/QtUI/QtAdHocCommandWithJIDWindow.cpp
+++ b/Swift/QtUI/QtAdHocCommandWithJIDWindow.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -23,42 +23,42 @@
namespace Swift {
QtAdHocCommandWithJIDWindow::QtAdHocCommandWithJIDWindow(UIEventStream* uiEventStream) : uiEventStream_(uiEventStream) {
- QVBoxLayout* hlayout = new QVBoxLayout(this);
+ QVBoxLayout* hlayout = new QVBoxLayout(this);
- QLabel* jidLabel = new QLabel("JID:", this);
- hlayout->addWidget(jidLabel);
- jid_ = new QLineEdit(this);
- hlayout->addWidget(jid_);
+ QLabel* jidLabel = new QLabel("JID:", this);
+ hlayout->addWidget(jidLabel);
+ jid_ = new QLineEdit(this);
+ hlayout->addWidget(jid_);
- QLabel* commandLabel = new QLabel("Command:", this);
- hlayout->addWidget(commandLabel);
- node_ = new QLineEdit(this);
- hlayout->addWidget(node_);
+ QLabel* commandLabel = new QLabel("Command:", this);
+ hlayout->addWidget(commandLabel);
+ node_ = new QLineEdit(this);
+ hlayout->addWidget(node_);
- QDialogButtonBox* buttonBox = new QDialogButtonBox(this);
- QPushButton* rejectButton = buttonBox->addButton("Cancel", QDialogButtonBox::RejectRole);
- connect(rejectButton, SIGNAL(clicked()), this, SLOT(handleRejectClick()));
- QPushButton* acceptButton = buttonBox->addButton("Complete", QDialogButtonBox::AcceptRole);
- connect(acceptButton, SIGNAL(clicked()), this, SLOT(handleAcceptClick()));
- hlayout->addWidget(buttonBox);
+ QDialogButtonBox* buttonBox = new QDialogButtonBox(this);
+ QPushButton* rejectButton = buttonBox->addButton("Cancel", QDialogButtonBox::RejectRole);
+ connect(rejectButton, SIGNAL(clicked()), this, SLOT(handleRejectClick()));
+ QPushButton* acceptButton = buttonBox->addButton("Complete", QDialogButtonBox::AcceptRole);
+ connect(acceptButton, SIGNAL(clicked()), this, SLOT(handleAcceptClick()));
+ hlayout->addWidget(buttonBox);
- setLayout(hlayout);
- show();
+ setLayout(hlayout);
+ show();
}
QtAdHocCommandWithJIDWindow::~QtAdHocCommandWithJIDWindow() {
}
void QtAdHocCommandWithJIDWindow::handleAcceptClick() {
- const JID jid = JID(Q2PSTRING(jid_->text()));
- const std::string node = Q2PSTRING(node_->text());
- boost::shared_ptr<UIEvent> event(new RequestAdHocWithJIDUIEvent(jid, node));
- uiEventStream_->send(event);
- accept();
+ const JID jid = JID(Q2PSTRING(jid_->text()));
+ const std::string node = Q2PSTRING(node_->text());
+ std::shared_ptr<UIEvent> event(new RequestAdHocWithJIDUIEvent(jid, node));
+ uiEventStream_->send(event);
+ accept();
}
void QtAdHocCommandWithJIDWindow::handleRejectClick() {
- reject();
+ reject();
}
}
diff --git a/Swift/QtUI/QtAdHocCommandWithJIDWindow.h b/Swift/QtUI/QtAdHocCommandWithJIDWindow.h
index e1f7a9c..0e83555 100644
--- a/Swift/QtUI/QtAdHocCommandWithJIDWindow.h
+++ b/Swift/QtUI/QtAdHocCommandWithJIDWindow.h
@@ -14,19 +14,19 @@
class QBoxLayout;
namespace Swift {
- class UIEventStream;
- class QtFormWidget;
- class QtAdHocCommandWithJIDWindow : public QDialog {
- Q_OBJECT
- public:
- QtAdHocCommandWithJIDWindow(UIEventStream* eventStream);
- virtual ~QtAdHocCommandWithJIDWindow();
- public slots:
- void handleAcceptClick();
- void handleRejectClick();
- private:
- UIEventStream* uiEventStream_;
- QLineEdit* jid_;
- QLineEdit* node_;
- };
+ class UIEventStream;
+ class QtFormWidget;
+ class QtAdHocCommandWithJIDWindow : public QDialog {
+ Q_OBJECT
+ public:
+ QtAdHocCommandWithJIDWindow(UIEventStream* eventStream);
+ virtual ~QtAdHocCommandWithJIDWindow();
+ public slots:
+ void handleAcceptClick();
+ void handleRejectClick();
+ private:
+ UIEventStream* uiEventStream_;
+ QLineEdit* jid_;
+ QLineEdit* node_;
+ };
}
diff --git a/Swift/QtUI/QtAddBookmarkWindow.cpp b/Swift/QtUI/QtAddBookmarkWindow.cpp
index 3596657..8c5d662 100644
--- a/Swift/QtUI/QtAddBookmarkWindow.cpp
+++ b/Swift/QtUI/QtAddBookmarkWindow.cpp
@@ -1,30 +1,30 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtAddBookmarkWindow.h"
+#include <Swift/QtUI/QtAddBookmarkWindow.h>
namespace Swift {
QtAddBookmarkWindow::QtAddBookmarkWindow(UIEventStream* eventStream) : eventStream_(eventStream) {
- setWindowTitle(tr("Add Bookmark Details"));
+ setWindowTitle(tr("Add Bookmark Details"));
}
QtAddBookmarkWindow::QtAddBookmarkWindow(UIEventStream* eventStream, const MUCBookmark& bookmark) : eventStream_(eventStream) {
- createFormFromBookmark(bookmark);
- setWindowTitle(tr("Add Bookmark Details"));
+ createFormFromBookmark(bookmark);
+ setWindowTitle(tr("Add Bookmark Details"));
}
bool QtAddBookmarkWindow::commit() {
- boost::optional<MUCBookmark> bookmark = createBookmarkFromForm();
- if (bookmark) {
- eventStream_->send(boost::shared_ptr<UIEvent>(new AddMUCBookmarkUIEvent(*bookmark)));
- return true;
- }
- else {
- return false;
- }
+ boost::optional<MUCBookmark> bookmark = createBookmarkFromForm();
+ if (bookmark) {
+ eventStream_->send(std::make_shared<AddMUCBookmarkUIEvent>(*bookmark));
+ return true;
+ }
+ else {
+ return false;
+ }
}
}
diff --git a/Swift/QtUI/QtAddBookmarkWindow.h b/Swift/QtUI/QtAddBookmarkWindow.h
index 0152fb3..607f647 100644
--- a/Swift/QtUI/QtAddBookmarkWindow.h
+++ b/Swift/QtUI/QtAddBookmarkWindow.h
@@ -1,24 +1,24 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "QtBookmarkDetailWindow.h"
+#include <Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h>
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
-#include "Swift/Controllers/UIEvents/UIEventStream.h"
-#include "Swift/Controllers/UIEvents/AddMUCBookmarkUIEvent.h"
+#include <Swift/QtUI/QtBookmarkDetailWindow.h>
namespace Swift {
- class QtAddBookmarkWindow : public QtBookmarkDetailWindow {
- Q_OBJECT
- public:
- QtAddBookmarkWindow(UIEventStream* eventStream);
- QtAddBookmarkWindow(UIEventStream* eventStream, const MUCBookmark& bookmark);
- bool commit();
- private:
- UIEventStream* eventStream_;
- };
+ class QtAddBookmarkWindow : public QtBookmarkDetailWindow {
+ Q_OBJECT
+ public:
+ QtAddBookmarkWindow(UIEventStream* eventStream);
+ QtAddBookmarkWindow(UIEventStream* eventStream, const MUCBookmark& bookmark);
+ bool commit();
+ private:
+ UIEventStream* eventStream_;
+ };
}
diff --git a/Swift/QtUI/QtAffiliationEditor.cpp b/Swift/QtUI/QtAffiliationEditor.cpp
index debf024..92b6aff 100644
--- a/Swift/QtUI/QtAffiliationEditor.cpp
+++ b/Swift/QtUI/QtAffiliationEditor.cpp
@@ -1,79 +1,78 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtAffiliationEditor.h"
+#include <Swift/QtUI/QtAffiliationEditor.h>
-#include <QListWidgetItem>
#include <QInputDialog>
+#include <QListWidgetItem>
-#include "QtSwiftUtil.h"
-
+#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
QtAffiliationEditor::QtAffiliationEditor(QWidget* parent) : QDialog(parent){
- ui_.setupUi(this);
- setAttribute(Qt::WA_DeleteOnClose);
- connect(ui_.affiliation, SIGNAL(currentIndexChanged(int)), this, SLOT(handleCurrentIndexChanged(int)));
- connect(ui_.addJID, SIGNAL(clicked()), this, SLOT(handleAddClicked()));
- connect(ui_.removeJID, SIGNAL(clicked()), this, SLOT(handleRemoveClicked()));
+ ui_.setupUi(this);
+ setAttribute(Qt::WA_DeleteOnClose);
+ connect(ui_.affiliation, SIGNAL(currentIndexChanged(int)), this, SLOT(handleCurrentIndexChanged(int)));
+ connect(ui_.addJID, SIGNAL(clicked()), this, SLOT(handleAddClicked()));
+ connect(ui_.removeJID, SIGNAL(clicked()), this, SLOT(handleRemoveClicked()));
}
QtAffiliationEditor::~QtAffiliationEditor() {
-
+
}
void QtAffiliationEditor::setAffiliations(MUCOccupant::Affiliation affiliation, const std::vector<JID>& jids) {
- affiliations_[affiliation] = jids;
- if (affiliationFromIndex(ui_.affiliation->currentIndex()) == affiliation) {
- handleCurrentIndexChanged(ui_.affiliation->currentIndex());
- }
+ affiliations_[affiliation] = jids;
+ if (affiliationFromIndex(ui_.affiliation->currentIndex()) == affiliation) {
+ handleCurrentIndexChanged(ui_.affiliation->currentIndex());
+ }
}
const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& QtAffiliationEditor::getChanges() const {
- return changes_;
+ return changes_;
}
void QtAffiliationEditor::handleCurrentIndexChanged(int index) {
- ui_.list->clear();
- foreach (const JID& jid, affiliations_[affiliationFromIndex(index)]) {
- ui_.list->addItem(P2QSTRING(jid.toString()));
- }
+ ui_.list->clear();
+ for (const auto& jid : affiliations_[affiliationFromIndex(index)]) {
+ ui_.list->addItem(P2QSTRING(jid.toString()));
+ }
}
void QtAffiliationEditor::handleAddClicked() {
- bool ok = false;
- JID jid = JID(Q2PSTRING(QInputDialog::getText(this, tr("Add User"), tr("Added User's Address:"), QLineEdit::Normal, "", &ok)));
- if (ok && jid.isValid()) {
- //FIXME: validation
- MUCOccupant::Affiliation affiliation = affiliationFromIndex(ui_.affiliation->currentIndex());
- changes_.push_back(ChangePair(affiliation, jid));
- ui_.list->addItem(P2QSTRING(jid.toString()));
- affiliations_[affiliation].push_back(jid);
- }
+ bool ok = false;
+ JID jid = JID(Q2PSTRING(QInputDialog::getText(this, tr("Add User"), tr("Added User's Address:"), QLineEdit::Normal, "", &ok)));
+ if (ok && jid.isValid()) {
+ //FIXME: validation
+ MUCOccupant::Affiliation affiliation = affiliationFromIndex(ui_.affiliation->currentIndex());
+ changes_.push_back(ChangePair(affiliation, jid));
+ ui_.list->addItem(P2QSTRING(jid.toString()));
+ affiliations_[affiliation].push_back(jid);
+ }
}
void QtAffiliationEditor::handleRemoveClicked() {
- QListWidgetItem* item = ui_.list->currentItem();
- if (item) {
- JID jid(Q2PSTRING(item->text()));
- changes_.push_back(ChangePair(MUCOccupant::NoAffiliation, jid));
- std::vector<JID>& jids = affiliations_[affiliationFromIndex(ui_.affiliation->currentIndex())];
- jids.erase(std::remove(jids.begin(), jids.end(), jid), jids.end());
- handleCurrentIndexChanged(ui_.affiliation->currentIndex());
- }
+ QListWidgetItem* item = ui_.list->currentItem();
+ if (item) {
+ JID jid(Q2PSTRING(item->text()));
+ changes_.push_back(ChangePair(MUCOccupant::NoAffiliation, jid));
+ std::vector<JID>& jids = affiliations_[affiliationFromIndex(ui_.affiliation->currentIndex())];
+ jids.erase(std::remove(jids.begin(), jids.end(), jid), jids.end());
+ handleCurrentIndexChanged(ui_.affiliation->currentIndex());
+ }
}
MUCOccupant::Affiliation QtAffiliationEditor::affiliationFromIndex(int affiliation) {
- switch (affiliation) {
- case 0: return MUCOccupant::Owner;
- case 1: return MUCOccupant::Admin;
- case 2: return MUCOccupant::Member;
- case 3: return MUCOccupant::Outcast;
- default: return MUCOccupant::Outcast;
- }
+ switch (affiliation) {
+ case 0: return MUCOccupant::Owner;
+ case 1: return MUCOccupant::Admin;
+ case 2: return MUCOccupant::Member;
+ case 3: return MUCOccupant::Outcast;
+ default: return MUCOccupant::Outcast;
+ }
}
}
diff --git a/Swift/QtUI/QtAffiliationEditor.h b/Swift/QtUI/QtAffiliationEditor.h
index 7064684..58e2497 100644
--- a/Swift/QtUI/QtAffiliationEditor.h
+++ b/Swift/QtUI/QtAffiliationEditor.h
@@ -1,37 +1,38 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <vector>
#include <map>
+#include <vector>
#include <QDialog>
-#include <Swift/QtUI/ui_QtAffiliationEditor.h>
-#include <Swiften/JID/JID.h>
#include <Swiften/Elements/MUCOccupant.h>
+#include <Swiften/JID/JID.h>
+
+#include <Swift/QtUI/ui_QtAffiliationEditor.h>
namespace Swift {
- class QtAffiliationEditor : public QDialog {
- Q_OBJECT
- public:
- QtAffiliationEditor(QWidget* parent = NULL);
- ~QtAffiliationEditor();
- void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>& jids);
- const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& getChanges() const;
- private slots:
- void handleCurrentIndexChanged(int);
- void handleAddClicked();
- void handleRemoveClicked();
- private:
- typedef std::pair<MUCOccupant::Affiliation, JID> ChangePair;
- MUCOccupant::Affiliation affiliationFromIndex(int affiliation);
- Ui::QtAffiliationEditor ui_;
- std::map<MUCOccupant::Affiliation, std::vector<JID> > affiliations_;
- std::vector<ChangePair> changes_;
- };
+ class QtAffiliationEditor : public QDialog {
+ Q_OBJECT
+ public:
+ QtAffiliationEditor(QWidget* parent = nullptr);
+ ~QtAffiliationEditor();
+ void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>& jids);
+ const std::vector<std::pair<MUCOccupant::Affiliation, JID> >& getChanges() const;
+ private slots:
+ void handleCurrentIndexChanged(int);
+ void handleAddClicked();
+ void handleRemoveClicked();
+ private:
+ typedef std::pair<MUCOccupant::Affiliation, JID> ChangePair;
+ MUCOccupant::Affiliation affiliationFromIndex(int affiliation);
+ Ui::QtAffiliationEditor ui_;
+ std::map<MUCOccupant::Affiliation, std::vector<JID> > affiliations_;
+ std::vector<ChangePair> changes_;
+ };
}
diff --git a/Swift/QtUI/QtAvatarWidget.cpp b/Swift/QtUI/QtAvatarWidget.cpp
index ca7e22f..7f6e275 100644
--- a/Swift/QtUI/QtAvatarWidget.cpp
+++ b/Swift/QtUI/QtAvatarWidget.cpp
@@ -1,110 +1,111 @@
/*
- * Copyright (c) 2011-2014 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtAvatarWidget.h"
+#include <Swift/QtUI/QtAvatarWidget.h>
-#include <QLabel>
-#include <QVBoxLayout>
-#include <QPixmap>
-#include <QMenu>
#include <QAction>
-#include <QMouseEvent>
+#include <QBuffer>
#include <QFileDialog>
#include <QImageReader>
-#include <QBuffer>
+#include <QLabel>
+#include <QMenu>
#include <QMessageBox>
+#include <QMouseEvent>
#include <QPainter>
+#include <QPixmap>
+#include <QVBoxLayout>
-#include <QtSwiftUtil.h>
#include <Swiften/Base/Path.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
+
namespace Swift {
QtAvatarWidget::QtAvatarWidget(QWidget* parent) : QWidget(parent), editable(false) {
- QVBoxLayout* layout = new QVBoxLayout(this);
- layout->setContentsMargins(0,0,0,0);
-
- QSizePolicy sp(QSizePolicy::Fixed, QSizePolicy::Fixed);
- sp.setHorizontalStretch(0);
- sp.setVerticalStretch(0);
- setSizePolicy(sp);
- setMinimumSize(QSize(96, 96));
- setMaximumSize(QSize(96, 96));
-
- label = new QLabel(this);
- label->setWordWrap(true);
- label->setSizePolicy(sp);
- label->setMinimumSize(QSize(96, 96));
- label->setMaximumSize(QSize(96, 96));
- label->setAlignment(Qt::AlignCenter);
- layout->addWidget(label);
+ QVBoxLayout* layout = new QVBoxLayout(this);
+ layout->setContentsMargins(0,0,0,0);
+
+ QSizePolicy sp(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ sp.setHorizontalStretch(0);
+ sp.setVerticalStretch(0);
+ setSizePolicy(sp);
+ setMinimumSize(QSize(96, 96));
+ setMaximumSize(QSize(96, 96));
+
+ label = new QLabel(this);
+ label->setWordWrap(true);
+ label->setSizePolicy(sp);
+ label->setMinimumSize(QSize(96, 96));
+ label->setMaximumSize(QSize(96, 96));
+ label->setAlignment(Qt::AlignCenter);
+ layout->addWidget(label);
}
void QtAvatarWidget::setAvatar(const ByteArray& data, const std::string& type) {
- this->data = data;
- this->type = type;
-
- QImage image;
- if (!data.empty()) {
- image.loadFromData(reinterpret_cast<const uchar*>(vecptr(data)), data.size());
- }
-
- if (image.isNull()) {
- image = QImage(":/icons/no-avatar.png");
- QPainter painter(&image);
- painter.setPen(Qt::gray);
- QFont font = painter.font();
- font.setPointSize(14);
- painter.setFont(font);
- painter.drawText(0, 0, image.height(), image.width(), Qt::AlignHCenter | Qt::AlignVCenter, tr("No picture"));
- }
-
- if (image.height() > label->height() || image.width() > label->width()) {
- image = image.scaled(label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
- }
- label->setPixmap(QPixmap::fromImage(image));
+ this->data = data;
+ this->type = type;
+
+ QImage image;
+ if (!data.empty()) {
+ image.loadFromData(reinterpret_cast<const uchar*>(vecptr(data)), data.size());
+ }
+
+ if (image.isNull()) {
+ image = QImage(":/icons/no-avatar.png");
+ QPainter painter(&image);
+ painter.setPen(Qt::gray);
+ QFont font = painter.font();
+ font.setPointSize(14);
+ painter.setFont(font);
+ painter.drawText(0, 0, image.height(), image.width(), Qt::AlignHCenter | Qt::AlignVCenter, tr("No picture"));
+ }
+
+ if (image.height() > label->height() || image.width() > label->width()) {
+ image = image.scaled(label->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ }
+ label->setPixmap(QPixmap::fromImage(image));
}
void QtAvatarWidget::mousePressEvent(QMouseEvent* event) {
- if (!editable) {
- return;
- }
- QMenu menu;
-
- QAction* selectPicture = new QAction(tr("Select picture ..."), this);
- menu.addAction(selectPicture);
-
- QAction* clearPicture = new QAction(tr("Clear picture"), this);
- menu.addAction(clearPicture);
-
- QAction* result = menu.exec(event->globalPos());
- if (result == selectPicture) {
- QString fileName = QFileDialog::getOpenFileName(this, tr("Select picture"), "", tr("Image Files (*.png *.jpg *.jpeg *.gif)"));
- if (!fileName.isEmpty()) {
- ByteArray data;
- readByteArrayFromFile(data, stringToPath(Q2PSTRING(fileName)));
-
- QBuffer buffer;
- buffer.setData(reinterpret_cast<const char*>(vecptr(data)), data.size());
- buffer.open(QIODevice::ReadOnly);
- QString type = QImageReader::imageFormat(&buffer).toLower();
- if (!type.isEmpty()) {
- type = "image/" + type;
- setAvatar(data, Q2PSTRING(type));
- }
- else {
- QMessageBox::critical(this, tr("Error"), tr("The selected picture is in an unrecognized format"));
- }
- }
- }
- else if (result == clearPicture) {
- setAvatar(ByteArray(), "");
- }
+ if (!editable) {
+ return;
+ }
+ QMenu menu;
+
+ QAction* selectPicture = new QAction(tr("Select picture ..."), this);
+ menu.addAction(selectPicture);
+
+ QAction* clearPicture = new QAction(tr("Clear picture"), this);
+ menu.addAction(clearPicture);
+
+ QAction* result = menu.exec(event->globalPos());
+ if (result == selectPicture) {
+ QString fileName = QFileDialog::getOpenFileName(this, tr("Select picture"), "", tr("Image Files (*.png *.jpg *.jpeg *.gif)"));
+ if (!fileName.isEmpty()) {
+ ByteArray data;
+ readByteArrayFromFile(data, stringToPath(Q2PSTRING(fileName)));
+
+ QBuffer buffer;
+ buffer.setData(reinterpret_cast<const char*>(vecptr(data)), data.size());
+ buffer.open(QIODevice::ReadOnly);
+ QString type = QImageReader::imageFormat(&buffer).toLower();
+ if (!type.isEmpty()) {
+ type = "image/" + type;
+ setAvatar(data, Q2PSTRING(type));
+ }
+ else {
+ QMessageBox::critical(this, tr("Error"), tr("The selected picture is in an unrecognized format"));
+ }
+ }
+ }
+ else if (result == clearPicture) {
+ setAvatar(ByteArray(), "");
+ }
}
diff --git a/Swift/QtUI/QtAvatarWidget.h b/Swift/QtUI/QtAvatarWidget.h
index ed89e37..612c79b 100644
--- a/Swift/QtUI/QtAvatarWidget.h
+++ b/Swift/QtUI/QtAvatarWidget.h
@@ -1,48 +1,49 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <QWidget>
#include <QImage>
+#include <QWidget>
+
#include <Swiften/Base/ByteArray.h>
class QLabel;
namespace Swift {
- class QtAvatarWidget : public QWidget {
- Q_OBJECT
- Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
- public:
- QtAvatarWidget(QWidget* parent);
-
- void setAvatar(const ByteArray& data, const std::string& type);
-
- const ByteArray& getAvatarData() const {
- return data;
- }
-
- const std::string& getAvatarType() const {
- return type;
- }
-
- void setEditable(bool b) {
- editable = b;
- }
-
- bool isEditable() const {
- return editable;
- }
-
- void mousePressEvent(QMouseEvent* event);
-
- private:
- bool editable;
- ByteArray data;
- std::string type;
- QLabel* label;
- };
+ class QtAvatarWidget : public QWidget {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+ public:
+ QtAvatarWidget(QWidget* parent);
+
+ void setAvatar(const ByteArray& data, const std::string& type);
+
+ const ByteArray& getAvatarData() const {
+ return data;
+ }
+
+ const std::string& getAvatarType() const {
+ return type;
+ }
+
+ void setEditable(bool b) {
+ editable = b;
+ }
+
+ bool isEditable() const {
+ return editable;
+ }
+
+ void mousePressEvent(QMouseEvent* event);
+
+ private:
+ bool editable;
+ ByteArray data;
+ std::string type;
+ QLabel* label;
+ };
}
diff --git a/Swift/QtUI/QtBlockListEditorWindow.cpp b/Swift/QtUI/QtBlockListEditorWindow.cpp
index 48bac26..30c939f 100644
--- a/Swift/QtUI/QtBlockListEditorWindow.cpp
+++ b/Swift/QtUI/QtBlockListEditorWindow.cpp
@@ -5,13 +5,12 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include <QtBlockListEditorWindow.h>
-#include <ui_QtBlockListEditorWindow.h>
+#include <Swift/QtUI/QtBlockListEditorWindow.h>
#include <boost/bind.hpp>
@@ -21,206 +20,207 @@
#include <QStyledItemDelegate>
#include <QValidator>
-#include <Swift/QtUI/QtSwiftUtil.h>
-#include <Swift/QtUI/QtUtilities.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Client/ClientBlockListManager.h>
#include <Swiften/JID/JID.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/QtUtilities.h>
+#include <Swift/QtUI/ui_QtBlockListEditorWindow.h>
+
namespace Swift {
class QtJIDValidator : public QValidator {
- public:
- QtJIDValidator(QObject* parent) : QValidator(parent) {}
- virtual ~QtJIDValidator() {}
- virtual QValidator::State validate(QString& input, int&) const {
- return JID(Q2PSTRING(input)).isValid() ? Acceptable : Intermediate;
- }
+ public:
+ QtJIDValidator(QObject* parent) : QValidator(parent) {}
+ virtual ~QtJIDValidator() {}
+ virtual QValidator::State validate(QString& input, int&) const {
+ return JID(Q2PSTRING(input)).isValid() ? Acceptable : Intermediate;
+ }
};
class QtJIDValidatedItemDelegate : public QItemDelegate {
- public:
- QtJIDValidatedItemDelegate(QObject* parent) : QItemDelegate(parent) {}
- virtual ~QtJIDValidatedItemDelegate() {}
-
- virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem&, const QModelIndex&) const {
- QLineEdit *editor = new QLineEdit(parent);
- editor->setValidator(new QtJIDValidator(editor));
- return editor;
- }
-
- void setEditorData(QWidget *editor, const QModelIndex &index) const {
- QString value = index.model()->data(index, Qt::EditRole).toString();
-
- QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
- lineEdit->setText(value);
- }
-
- void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {
- QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
- QString currentValue = lineEdit->text();
- int pos = 0;
- if (lineEdit->validator()->validate(currentValue, pos) == QValidator::Acceptable) {
- model->setData(index, lineEdit->text(), Qt::EditRole);
- } else {
- model->setData(index, QString(), Qt::EditRole);
- }
- }
-
- void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const {
- editor->setGeometry(option.rect);
- }
+ public:
+ QtJIDValidatedItemDelegate(QObject* parent) : QItemDelegate(parent) {}
+ virtual ~QtJIDValidatedItemDelegate() {}
+
+ virtual QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem&, const QModelIndex&) const {
+ QLineEdit *editor = new QLineEdit(parent);
+ editor->setValidator(new QtJIDValidator(editor));
+ return editor;
+ }
+
+ void setEditorData(QWidget *editor, const QModelIndex &index) const {
+ QString value = index.model()->data(index, Qt::EditRole).toString();
+
+ QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
+ lineEdit->setText(value);
+ }
+
+ void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {
+ QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
+ QString currentValue = lineEdit->text();
+ int pos = 0;
+ if (lineEdit->validator()->validate(currentValue, pos) == QValidator::Acceptable) {
+ model->setData(index, lineEdit->text(), Qt::EditRole);
+ } else {
+ model->setData(index, QString(), Qt::EditRole);
+ }
+ }
+
+ void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const {
+ editor->setGeometry(option.rect);
+ }
};
-QtBlockListEditorWindow::QtBlockListEditorWindow() : QWidget(), ui(new Ui::QtBlockListEditorWindow), removeItemDelegate(0), editItemDelegate(0) {
- ui->setupUi(this);
+QtBlockListEditorWindow::QtBlockListEditorWindow() : QWidget(), ui(new Ui::QtBlockListEditorWindow), removeItemDelegate(nullptr), editItemDelegate(nullptr) {
+ ui->setupUi(this);
- freshBlockListTemplate = tr("Double-click to add contact");
+ freshBlockListTemplate = tr("Double-click to add contact");
- new QShortcut(QKeySequence::Close, this, SLOT(close()));
- ui->throbberLabel->setMovie(new QMovie(":/icons/throbber.gif", QByteArray(), this));
+ new QShortcut(QKeySequence::Close, this, SLOT(close()));
+ ui->throbberLabel->setMovie(new QMovie(":/icons/throbber.gif", QByteArray(), this));
- removeItemDelegate = new QtRemovableItemDelegate(style());
- editItemDelegate = new QtJIDValidatedItemDelegate(this);
+ removeItemDelegate = new QtRemovableItemDelegate(style());
+ editItemDelegate = new QtJIDValidatedItemDelegate(this);
- connect(ui->savePushButton, SIGNAL(clicked()), SLOT(applyChanges()));
+ connect(ui->savePushButton, SIGNAL(clicked()), SLOT(applyChanges()));
- ui->blockListTreeWidget->setColumnCount(2);
- ui->blockListTreeWidget->header()->setStretchLastSection(false);
- ui->blockListTreeWidget->header()->resizeSection(1, removeItemDelegate->sizeHint(QStyleOptionViewItem(), QModelIndex()).width());
+ ui->blockListTreeWidget->setColumnCount(2);
+ ui->blockListTreeWidget->header()->setStretchLastSection(false);
+ ui->blockListTreeWidget->header()->resizeSection(1, removeItemDelegate->sizeHint(QStyleOptionViewItem(), QModelIndex()).width());
#if QT_VERSION >= 0x050000
- ui->blockListTreeWidget->header()->setSectionResizeMode(0, QHeaderView::Stretch);
+ ui->blockListTreeWidget->header()->setSectionResizeMode(0, QHeaderView::Stretch);
#else
- ui->blockListTreeWidget->header()->setResizeMode(0, QHeaderView::Stretch);
+ ui->blockListTreeWidget->header()->setResizeMode(0, QHeaderView::Stretch);
#endif
- ui->blockListTreeWidget->setHeaderHidden(true);
- ui->blockListTreeWidget->setRootIsDecorated(false);
- ui->blockListTreeWidget->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked | QAbstractItemView::EditKeyPressed);
- ui->blockListTreeWidget->setItemDelegateForColumn(0, editItemDelegate);
- ui->blockListTreeWidget->setItemDelegateForColumn(1, removeItemDelegate);
- connect(ui->blockListTreeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)), SLOT(handleItemChanged(QTreeWidgetItem*,int)));
- ui->blockListTreeWidget->installEventFilter(this);
-
- QTreeWidgetItem* item = new QTreeWidgetItem(QStringList(freshBlockListTemplate) << "x");
- item->setFlags(item->flags() | Qt::ItemIsEditable);
- ui->blockListTreeWidget->addTopLevelItem(item);
+ ui->blockListTreeWidget->setHeaderHidden(true);
+ ui->blockListTreeWidget->setRootIsDecorated(false);
+ ui->blockListTreeWidget->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::SelectedClicked | QAbstractItemView::EditKeyPressed);
+ ui->blockListTreeWidget->setItemDelegateForColumn(0, editItemDelegate);
+ ui->blockListTreeWidget->setItemDelegateForColumn(1, removeItemDelegate);
+ connect(ui->blockListTreeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)), SLOT(handleItemChanged(QTreeWidgetItem*,int)));
+ ui->blockListTreeWidget->installEventFilter(this);
+
+ QTreeWidgetItem* item = new QTreeWidgetItem(QStringList(freshBlockListTemplate) << "x");
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+ ui->blockListTreeWidget->addTopLevelItem(item);
}
QtBlockListEditorWindow::~QtBlockListEditorWindow() {
}
void QtBlockListEditorWindow::show() {
- QWidget::showNormal();
- QWidget::activateWindow();
- QWidget::raise();
+ QWidget::showNormal();
+ QWidget::activateWindow();
+ QWidget::raise();
}
void QtBlockListEditorWindow::hide() {
- QWidget::hide();
+ QWidget::hide();
}
void QtBlockListEditorWindow::handleItemChanged(QTreeWidgetItem *item, int) {
- // check whether changed item contains a valid JID and make it removable
- if (item && item->text(0) != freshBlockListTemplate) {
- item->setText(1, "");
- }
-
- // check for empty rows and add an empty one so the user can add items
- bool hasEmptyRow = false;
- for( int i = 0; i < ui->blockListTreeWidget->topLevelItemCount(); ++i ) {
- QTreeWidgetItem* row = ui->blockListTreeWidget->topLevelItem(i);
- if (row->text(0) == freshBlockListTemplate) {
- hasEmptyRow = true;
- }
- else if (row->text(0).isEmpty()) {
- ui->blockListTreeWidget->removeItemWidget(row, 0);
- }
- }
-
- if (!hasEmptyRow) {
- QTreeWidgetItem* item = new QTreeWidgetItem(QStringList(freshBlockListTemplate) << "x");
- item->setFlags(item->flags() | Qt::ItemIsEditable);
- ui->blockListTreeWidget->addTopLevelItem(item);
- }
-
- if (!item) {
- ui->blockListTreeWidget->setCurrentItem(ui->blockListTreeWidget->topLevelItem(0));
- }
+ // check whether changed item contains a valid JID and make it removable
+ if (item && item->text(0) != freshBlockListTemplate) {
+ item->setText(1, "");
+ }
+
+ // check for empty rows and add an empty one so the user can add items
+ bool hasEmptyRow = false;
+ for( int i = 0; i < ui->blockListTreeWidget->topLevelItemCount(); ++i ) {
+ QTreeWidgetItem* row = ui->blockListTreeWidget->topLevelItem(i);
+ if (row->text(0) == freshBlockListTemplate) {
+ hasEmptyRow = true;
+ }
+ else if (row->text(0).isEmpty()) {
+ ui->blockListTreeWidget->removeItemWidget(row, 0);
+ }
+ }
+
+ if (!hasEmptyRow) {
+ QTreeWidgetItem* item = new QTreeWidgetItem(QStringList(freshBlockListTemplate) << "x");
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+ ui->blockListTreeWidget->addTopLevelItem(item);
+ }
+
+ if (!item) {
+ ui->blockListTreeWidget->setCurrentItem(ui->blockListTreeWidget->topLevelItem(0));
+ }
}
void QtBlockListEditorWindow::applyChanges() {
- onSetNewBlockList(getCurrentBlockList());
+ onSetNewBlockList(getCurrentBlockList());
}
void QtBlockListEditorWindow::setCurrentBlockList(const std::vector<JID> &blockedJIDs) {
- ui->blockListTreeWidget->clear();
-
- foreach(const JID& jid, blockedJIDs) {
- QTreeWidgetItem* item = new QTreeWidgetItem(QStringList(P2QSTRING(jid.toString())) << "");
- item->setFlags(item->flags() | Qt::ItemIsEditable);
- ui->blockListTreeWidget->addTopLevelItem(item);
- }
- handleItemChanged(0,0);
+ ui->blockListTreeWidget->clear();
+
+ for (const auto& jid : blockedJIDs) {
+ QTreeWidgetItem* item = new QTreeWidgetItem(QStringList(P2QSTRING(jid.toString())) << "");
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+ ui->blockListTreeWidget->addTopLevelItem(item);
+ }
+ handleItemChanged(nullptr,0);
}
void QtBlockListEditorWindow::setBusy(bool isBusy) {
- if (isBusy) {
- ui->throbberLabel->movie()->start();
- ui->throbberLabel->show();
- ui->blockListTreeWidget->setEnabled(false);
- ui->savePushButton->setEnabled(false);
- } else {
- ui->throbberLabel->movie()->stop();
- ui->throbberLabel->hide();
- ui->blockListTreeWidget->setEnabled(true);
- ui->savePushButton->setEnabled(true);
- }
+ if (isBusy) {
+ ui->throbberLabel->movie()->start();
+ ui->throbberLabel->show();
+ ui->blockListTreeWidget->setEnabled(false);
+ ui->savePushButton->setEnabled(false);
+ } else {
+ ui->throbberLabel->movie()->stop();
+ ui->throbberLabel->hide();
+ ui->blockListTreeWidget->setEnabled(true);
+ ui->savePushButton->setEnabled(true);
+ }
}
void QtBlockListEditorWindow::setError(const std::string& error) {
- if (!error.empty()) {
- ui->errorLabel->setText("<font color='red'>" + QtUtilities::htmlEscape(P2QSTRING(error)) + "</font>");
- }
- else {
- ui->errorLabel->setText("");
- }
+ if (!error.empty()) {
+ ui->errorLabel->setText("<font color='red'>" + QtUtilities::htmlEscape(P2QSTRING(error)) + "</font>");
+ }
+ else {
+ ui->errorLabel->setText("");
+ }
}
std::vector<JID> Swift::QtBlockListEditorWindow::getCurrentBlockList() const {
- std::vector<JID> futureBlockedJIDs;
-
- for(int i=0; i < ui->blockListTreeWidget->topLevelItemCount(); ++i) {
- QTreeWidgetItem* row = ui->blockListTreeWidget->topLevelItem(i);
- JID jid = JID(Q2PSTRING(row->text(0)));
- if (!jid.toString().empty() && jid.isValid()) {
- futureBlockedJIDs.push_back(jid);
- }
- }
- return futureBlockedJIDs;
+ std::vector<JID> futureBlockedJIDs;
+
+ for(int i=0; i < ui->blockListTreeWidget->topLevelItemCount(); ++i) {
+ QTreeWidgetItem* row = ui->blockListTreeWidget->topLevelItem(i);
+ JID jid = JID(Q2PSTRING(row->text(0)));
+ if (!jid.toString().empty() && jid.isValid()) {
+ futureBlockedJIDs.push_back(jid);
+ }
+ }
+ return futureBlockedJIDs;
}
bool QtBlockListEditorWindow::eventFilter(QObject* target, QEvent* event) {
- if (target == ui->blockListTreeWidget) {
- if (event->type() == QEvent::KeyPress) {
- QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
- if (keyEvent->key() == Qt::Key_Backspace) {
- // remove currently selected item
- QTreeWidgetItem* currentItem = ui->blockListTreeWidget->currentItem();
- if (currentItem->text(0) != freshBlockListTemplate) {
- ui->blockListTreeWidget->takeTopLevelItem(ui->blockListTreeWidget->indexOfTopLevelItem(currentItem));
- return true;
- }
- }
- else if (keyEvent->key() == Qt::Key_Return) {
- // open editor for return key d
- ui->blockListTreeWidget->editItem(ui->blockListTreeWidget->currentItem(), 0);
- return true;
- }
- }
- }
- return QWidget::eventFilter(target, event);
+ if (target == ui->blockListTreeWidget) {
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
+ if (keyEvent->key() == Qt::Key_Backspace) {
+ // remove currently selected item
+ QTreeWidgetItem* currentItem = ui->blockListTreeWidget->currentItem();
+ if (currentItem->text(0) != freshBlockListTemplate) {
+ ui->blockListTreeWidget->takeTopLevelItem(ui->blockListTreeWidget->indexOfTopLevelItem(currentItem));
+ return true;
+ }
+ }
+ else if (keyEvent->key() == Qt::Key_Return) {
+ // open editor for return key d
+ ui->blockListTreeWidget->editItem(ui->blockListTreeWidget->currentItem(), 0);
+ return true;
+ }
+ }
+ }
+ return QWidget::eventFilter(target, event);
}
}
diff --git a/Swift/QtUI/QtBlockListEditorWindow.h b/Swift/QtUI/QtBlockListEditorWindow.h
index e5288ca..dc900ab 100644
--- a/Swift/QtUI/QtBlockListEditorWindow.h
+++ b/Swift/QtUI/QtBlockListEditorWindow.h
@@ -5,21 +5,22 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <QTreeWidgetItem>
+#include <QWidget>
+
#include <Swift/Controllers/UIInterfaces/BlockListEditorWidget.h>
-#include <Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h>
-#include <QWidget>
-#include <QTreeWidgetItem>
+#include <Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h>
namespace Ui {
- class QtBlockListEditorWindow;
+ class QtBlockListEditorWindow;
}
namespace Swift {
@@ -27,29 +28,29 @@ namespace Swift {
class QtJIDValidatedItemDelegate;
class QtBlockListEditorWindow : public QWidget, public BlockListEditorWidget {
- Q_OBJECT
-
- public:
- QtBlockListEditorWindow();
- virtual ~QtBlockListEditorWindow();
-
- virtual void show();
- virtual void hide();
- virtual void setCurrentBlockList(const std::vector<JID>& blockedJIDs);
- virtual void setBusy(bool isBusy);
- virtual void setError(const std::string& error);
- virtual std::vector<JID> getCurrentBlockList() const;
- virtual bool eventFilter(QObject* target, QEvent* event);
-
- private slots:
- void handleItemChanged(QTreeWidgetItem*, int);
- void applyChanges();
-
- private:
- Ui::QtBlockListEditorWindow* ui;
- QtRemovableItemDelegate* removeItemDelegate;
- QtJIDValidatedItemDelegate* editItemDelegate;
- QString freshBlockListTemplate;
+ Q_OBJECT
+
+ public:
+ QtBlockListEditorWindow();
+ virtual ~QtBlockListEditorWindow();
+
+ virtual void show();
+ virtual void hide();
+ virtual void setCurrentBlockList(const std::vector<JID>& blockedJIDs);
+ virtual void setBusy(bool isBusy);
+ virtual void setError(const std::string& error);
+ virtual std::vector<JID> getCurrentBlockList() const;
+ virtual bool eventFilter(QObject* target, QEvent* event);
+
+ private slots:
+ void handleItemChanged(QTreeWidgetItem*, int);
+ void applyChanges();
+
+ private:
+ Ui::QtBlockListEditorWindow* ui;
+ QtRemovableItemDelegate* removeItemDelegate;
+ QtJIDValidatedItemDelegate* editItemDelegate;
+ QString freshBlockListTemplate;
};
}
diff --git a/Swift/QtUI/QtBookmarkDetailWindow.cpp b/Swift/QtUI/QtBookmarkDetailWindow.cpp
index 0210305..920e94e 100644
--- a/Swift/QtUI/QtBookmarkDetailWindow.cpp
+++ b/Swift/QtUI/QtBookmarkDetailWindow.cpp
@@ -1,77 +1,79 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtBookmarkDetailWindow.h"
-#include "QtSwiftUtil.h"
+#include <Swift/QtUI/QtBookmarkDetailWindow.h>
+
#include <QMessageBox>
+#include <Swift/QtUI/QtSwiftUtil.h>
+
namespace Swift {
QtBookmarkDetailWindow::QtBookmarkDetailWindow(QWidget* parent) : QDialog(parent) {
- setupUi(this);
- setAttribute(Qt::WA_DeleteOnClose, true);
- //connect(buttons_, SIGNAL(accepted()), SLOT(accept()));
- //connect(buttons_, SIGNAL(rejected()), SLOT(reject()));
- setFixedHeight(sizeHint().height());
+ setupUi(this);
+ setAttribute(Qt::WA_DeleteOnClose, true);
+ //connect(buttons_, SIGNAL(accepted()), SLOT(accept()));
+ //connect(buttons_, SIGNAL(rejected()), SLOT(reject()));
+ setFixedHeight(sizeHint().height());
}
void QtBookmarkDetailWindow::accept() {
- if (commit()) {
- QDialog::accept();
- }
+ if (commit()) {
+ QDialog::accept();
+ }
}
boost::optional<MUCBookmark> QtBookmarkDetailWindow::createBookmarkFromForm() {
- //check room
- //check bookmarkName
- JID room(Q2PSTRING(room_->text()));
- if (!room.isValid() || room.getNode().empty() || !room.getResource().empty()) {
- QMessageBox::warning(this, tr("Bookmark not valid"), tr("You must specify a valid room address (e.g. someroom@rooms.example.com)."));
- return boost::optional<MUCBookmark>();
- }
- std::string name(Q2PSTRING(name_->text()));
- if (name.empty()) {
- name = room.toString();
- }
+ //check room
+ //check bookmarkName
+ JID room(Q2PSTRING(room_->text()));
+ if (!room.isValid() || room.getNode().empty() || !room.getResource().empty()) {
+ QMessageBox::warning(this, tr("Bookmark not valid"), tr("You must specify a valid room address (e.g. someroom@rooms.example.com)."));
+ return boost::optional<MUCBookmark>();
+ }
+ std::string name(Q2PSTRING(name_->text()));
+ if (name.empty()) {
+ name = room.toString();
+ }
- MUCBookmark bookmark(room, name);
- std::string nick(Q2PSTRING(nick_->text()));
- std::string password(Q2PSTRING(password_->text()));
- bookmark.setAutojoin(autojoin_->isChecked());
- if (!nick.empty()) {
- bookmark.setNick(nick);
- }
- if (!password.empty()) {
- bookmark.setPassword(password);
- }
- return bookmark;
+ MUCBookmark bookmark(room, name);
+ std::string nick(Q2PSTRING(nick_->text()));
+ std::string password(Q2PSTRING(password_->text()));
+ bookmark.setAutojoin(autojoin_->isChecked());
+ if (!nick.empty()) {
+ bookmark.setNick(nick);
+ }
+ if (!password.empty()) {
+ bookmark.setPassword(password);
+ }
+ return bookmark;
}
void QtBookmarkDetailWindow::createFormFromBookmark(const MUCBookmark& bookmark) {
- if (bookmark.getRoom().isValid()) {
- room_->setText(P2QSTRING(bookmark.getRoom().toString()));
- }
+ if (bookmark.getRoom().isValid()) {
+ room_->setText(P2QSTRING(bookmark.getRoom().toString()));
+ }
- if (!bookmark.getName().empty()) {
- name_->setText(P2QSTRING(bookmark.getName()));
- }
+ if (!bookmark.getName().empty()) {
+ name_->setText(P2QSTRING(bookmark.getName()));
+ }
- if (bookmark.getNick()) {
- nick_->setText(P2QSTRING((*bookmark.getNick())));
- }
+ if (bookmark.getNick()) {
+ nick_->setText(P2QSTRING((*bookmark.getNick())));
+ }
- if (bookmark.getPassword()) {
- password_->setText(P2QSTRING((*bookmark.getPassword())));
- }
+ if (bookmark.getPassword()) {
+ password_->setText(P2QSTRING((*bookmark.getPassword())));
+ }
- if (bookmark.getAutojoin()) {
- autojoin_->setCheckState(Qt::Checked);
- } else {
- autojoin_->setCheckState(Qt::Unchecked);
- }
+ if (bookmark.getAutojoin()) {
+ autojoin_->setCheckState(Qt::Checked);
+ } else {
+ autojoin_->setCheckState(Qt::Unchecked);
+ }
}
}
diff --git a/Swift/QtUI/QtBookmarkDetailWindow.h b/Swift/QtUI/QtBookmarkDetailWindow.h
index e465007..82e757d 100644
--- a/Swift/QtUI/QtBookmarkDetailWindow.h
+++ b/Swift/QtUI/QtBookmarkDetailWindow.h
@@ -1,32 +1,32 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "ui_QtBookmarkDetailWindow.h"
-
#include <boost/optional.hpp>
#include <QDialog>
-#include "Swiften/MUC/MUCBookmark.h"
+#include <Swiften/MUC/MUCBookmark.h>
+
+#include <Swift/QtUI/ui_QtBookmarkDetailWindow.h>
namespace Swift {
- class QtBookmarkDetailWindow : public QDialog, protected Ui::QtBookmarkDetailWindow {
- Q_OBJECT
- public:
- QtBookmarkDetailWindow(QWidget* parent = NULL);
- virtual bool commit() = 0;
- boost::optional<MUCBookmark> createBookmarkFromForm();
-
- protected:
- void createFormFromBookmark(const MUCBookmark& bookmark);
-
- public slots:
- void accept();
- };
+ class QtBookmarkDetailWindow : public QDialog, protected Ui::QtBookmarkDetailWindow {
+ Q_OBJECT
+ public:
+ QtBookmarkDetailWindow(QWidget* parent = nullptr);
+ virtual bool commit() = 0;
+ boost::optional<MUCBookmark> createBookmarkFromForm();
+
+ protected:
+ void createFormFromBookmark(const MUCBookmark& bookmark);
+
+ public slots:
+ void accept();
+ };
}
diff --git a/Swift/QtUI/QtCachedImageScaler.cpp b/Swift/QtUI/QtCachedImageScaler.cpp
index 8675bb2..e1f540b 100644
--- a/Swift/QtUI/QtCachedImageScaler.cpp
+++ b/Swift/QtUI/QtCachedImageScaler.cpp
@@ -1,14 +1,17 @@
/*
- * Copyright (c) 2010-2013 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtCachedImageScaler.h"
+#include <Swift/QtUI/QtCachedImageScaler.h>
-#include <QImage>
#include <boost/lexical_cast.hpp>
+
+#include <QImage>
+
#include <Swiften/Base/Path.h>
+
#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
@@ -17,25 +20,25 @@ QtCachedImageScaler::QtCachedImageScaler() {
}
boost::filesystem::path QtCachedImageScaler::getScaledImage(const boost::filesystem::path& imagePath, int size) {
- boost::filesystem::path scaledImagePath(imagePath);
- std::string suffix = "." + boost::lexical_cast<std::string>(size);
- scaledImagePath = stringToPath(pathToString(scaledImagePath) + suffix);
- if (!boost::filesystem::exists(scaledImagePath)) {
- QImage image(P2QSTRING(pathToString(imagePath)));
- if (!image.isNull()) {
- if (image.width() > size || image.height() > size) {
- QImage scaledImage = image.scaled(size, size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
- scaledImage.save(P2QSTRING(pathToString(scaledImagePath)), "PNG");
- }
- else {
- image.save(P2QSTRING(pathToString(scaledImagePath)), "PNG");
- }
- }
- else {
- return imagePath;
- }
- }
- return scaledImagePath;
+ boost::filesystem::path scaledImagePath(imagePath);
+ std::string suffix = "." + boost::lexical_cast<std::string>(size);
+ scaledImagePath = stringToPath(pathToString(scaledImagePath) + suffix);
+ if (!boost::filesystem::exists(scaledImagePath)) {
+ QImage image(P2QSTRING(pathToString(imagePath)));
+ if (!image.isNull()) {
+ if (image.width() > size || image.height() > size) {
+ QImage scaledImage = image.scaled(size, size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ scaledImage.save(P2QSTRING(pathToString(scaledImagePath)), "PNG");
+ }
+ else {
+ image.save(P2QSTRING(pathToString(scaledImagePath)), "PNG");
+ }
+ }
+ else {
+ return imagePath;
+ }
+ }
+ return scaledImagePath;
}
diff --git a/Swift/QtUI/QtCachedImageScaler.h b/Swift/QtUI/QtCachedImageScaler.h
index fcc2a2d..15d868e 100644
--- a/Swift/QtUI/QtCachedImageScaler.h
+++ b/Swift/QtUI/QtCachedImageScaler.h
@@ -9,11 +9,11 @@
#include <boost/filesystem.hpp>
namespace Swift {
- class QtCachedImageScaler {
- public:
- QtCachedImageScaler();
+ class QtCachedImageScaler {
+ public:
+ QtCachedImageScaler();
- boost::filesystem::path getScaledImage(const boost::filesystem::path& image, int size);
- };
+ boost::filesystem::path getScaledImage(const boost::filesystem::path& image, int size);
+ };
}
diff --git a/Swift/QtUI/QtCertificateViewerDialog.cpp b/Swift/QtUI/QtCertificateViewerDialog.cpp
index 8108978..6454d82 100644
--- a/Swift/QtUI/QtCertificateViewerDialog.cpp
+++ b/Swift/QtUI/QtCertificateViewerDialog.cpp
@@ -5,15 +5,12 @@
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtCertificateViewerDialog.h"
-#include "ui_QtCertificateViewerDialog.h"
-
-#include <Swiften/Base/foreach.h>
+#include <Swift/QtUI/QtCertificateViewerDialog.h>
#include <QDateTime>
#include <QLabel>
@@ -21,129 +18,131 @@
#include <QStringList>
#include <QTreeWidgetItem>
+#include <Swift/QtUI/ui_QtCertificateViewerDialog.h>
+
namespace Swift {
QtCertificateViewerDialog::QtCertificateViewerDialog(QWidget* parent) : QDialog(parent), ui(new Ui::QtCertificateViewerDialog) {
- ui->setupUi(this);
- connect(ui->certChainTreeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), SLOT(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
+ ui->setupUi(this);
+ connect(ui->certChainTreeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), SLOT(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)));
- setAttribute(Qt::WA_DeleteOnClose);
+ setAttribute(Qt::WA_DeleteOnClose);
}
QtCertificateViewerDialog::~QtCertificateViewerDialog() {
- delete ui;
+ delete ui;
}
void QtCertificateViewerDialog::setCertificateChain(const std::vector<Certificate::ref>& chain) {
- // clean widgets
- ui->certChainTreeWidget->clear();
-
- if (chain.empty()) return;
-
- // convert Swift certificate chain to qt certificate chain (root goes first)
- currentChain.clear();
- foreach(Certificate::ref cert, chain) {
- ByteArray certAsDer = cert->toDER();
- QByteArray dataArray(reinterpret_cast<const char*>(certAsDer.data()), certAsDer.size());
- currentChain.push_front(QSslCertificate(dataArray, QSsl::Der));
- }
-
- // fill treeWidget
- QTreeWidgetItem* root = new QTreeWidgetItem(ui->certChainTreeWidget, QStringList(currentChain.at(0).subjectInfo(QSslCertificate::CommonName)));
- root->setData(0, Qt::UserRole, QVariant(0));
- root->setExpanded(true);
- ui->certChainTreeWidget->addTopLevelItem(root);
- if (currentChain.size() > 1) {
- QTreeWidgetItem* parent = root;
- for (int n = 1; n < currentChain.size(); n++) {
- QTreeWidgetItem* link = new QTreeWidgetItem(parent, QStringList(QString("↳ ") + (QStringList(currentChain.at(n).subjectInfo(QSslCertificate::CommonName)).join(", "))));
- link->setExpanded(true);
- link->setData(0, Qt::UserRole, QVariant(n));
- parent = link;
- }
- ui->certChainTreeWidget->setCurrentItem(parent);
- } else {
- ui->certChainTreeWidget->setCurrentItem(root);
- }
+ // clean widgets
+ ui->certChainTreeWidget->clear();
+
+ if (chain.empty()) return;
+
+ // convert Swift certificate chain to qt certificate chain (root goes first)
+ currentChain.clear();
+ for (auto&& cert : chain) {
+ ByteArray certAsDer = cert->toDER();
+ QByteArray dataArray(reinterpret_cast<const char*>(certAsDer.data()), certAsDer.size());
+ currentChain.push_front(QSslCertificate(dataArray, QSsl::Der));
+ }
+
+ // fill treeWidget
+ QTreeWidgetItem* root = new QTreeWidgetItem(ui->certChainTreeWidget, QStringList(currentChain.at(0).subjectInfo(QSslCertificate::CommonName)));
+ root->setData(0, Qt::UserRole, QVariant(0));
+ root->setExpanded(true);
+ ui->certChainTreeWidget->addTopLevelItem(root);
+ if (currentChain.size() > 1) {
+ QTreeWidgetItem* parent = root;
+ for (int n = 1; n < currentChain.size(); n++) {
+ QTreeWidgetItem* link = new QTreeWidgetItem(parent, QStringList(QString("↳ ") + (QStringList(currentChain.at(n).subjectInfo(QSslCertificate::CommonName)).join(", "))));
+ link->setExpanded(true);
+ link->setData(0, Qt::UserRole, QVariant(n));
+ parent = link;
+ }
+ ui->certChainTreeWidget->setCurrentItem(parent);
+ } else {
+ ui->certChainTreeWidget->setCurrentItem(root);
+ }
}
void QtCertificateViewerDialog::displayCertificateChainAsSheet(QWidget* parent, const std::vector<Certificate::ref>& chain) {
- QtCertificateViewerDialog* dialog = new QtCertificateViewerDialog(parent);
- dialog->setCertificateChain(chain);
- dialog->show();
+ QtCertificateViewerDialog* dialog = new QtCertificateViewerDialog(parent);
+ dialog->setCertificateChain(chain);
+ dialog->show();
}
void QtCertificateViewerDialog::currentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem*) {
- setCertificateDetails(currentChain.at(current->data(0, Qt::UserRole).toInt()));
+ setCertificateDetails(currentChain.at(current->data(0, Qt::UserRole).toInt()));
}
#define ADD_SECTION( TITLE ) \
- ui->certGridLayout->addWidget(new QLabel("<strong>" + TITLE + "</strong>"), rowCount++, 0, 1, 2);
+ ui->certGridLayout->addWidget(new QLabel("<strong>" + TITLE + "</strong>"), rowCount++, 0, 1, 2);
#define ADD_FIELD( TITLE, VALUE) \
- ui->certGridLayout->addWidget(new QLabel(TITLE), rowCount, 0, 1, 1, Qt::AlignRight); \
- valueLabel = new QLabel(); \
- valueLabel->setText(QStringList(VALUE).join(", ")); \
- valueLabel->setTextFormat(Qt::PlainText); \
- valueLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard); \
- ui->certGridLayout->addWidget(valueLabel, rowCount++, 1, 1, 1, Qt::AlignLeft);
+ ui->certGridLayout->addWidget(new QLabel(TITLE), rowCount, 0, 1, 1, Qt::AlignRight); \
+ valueLabel = new QLabel(); \
+ valueLabel->setText(QStringList(VALUE).join(", ")); \
+ valueLabel->setTextFormat(Qt::PlainText); \
+ valueLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard); \
+ ui->certGridLayout->addWidget(valueLabel, rowCount++, 1, 1, 1, Qt::AlignLeft);
void QtCertificateViewerDialog::setCertificateDetails(const QSslCertificate& cert) {
- QLayoutItem* item;
- while ((item = ui->certGridLayout->takeAt(0)) != NULL ) {
- delete item->widget();
- delete item;
- }
+ QLayoutItem* item;
+ while ((item = ui->certGridLayout->takeAt(0)) != NULL ) {
+ delete item->widget();
+ delete item;
+ }
- int rowCount = 0;
+ int rowCount = 0;
- ui->certGridLayout->setColumnStretch(2, 1);
+ ui->certGridLayout->setColumnStretch(2, 1);
- QLabel* valueLabel = 0;
+ QLabel* valueLabel = 0;
- ADD_SECTION(tr("General"));
- ADD_FIELD(tr("Valid From"), cert.effectiveDate().toString(Qt::TextDate));
- ADD_FIELD(tr("Valid To"), cert.expiryDate().toString(Qt::TextDate));
- ADD_FIELD(tr("Serial Number"), QString(cert.serialNumber().toHex()));
- ADD_FIELD(tr("Version"), QString(cert.version()));
+ ADD_SECTION(tr("General"));
+ ADD_FIELD(tr("Valid From"), cert.effectiveDate().toString(Qt::TextDate));
+ ADD_FIELD(tr("Valid To"), cert.expiryDate().toString(Qt::TextDate));
+ ADD_FIELD(tr("Serial Number"), QString(cert.serialNumber().toHex()));
+ ADD_FIELD(tr("Version"), QString(cert.version()));
- ADD_SECTION(tr("Subject"));
- ADD_FIELD(tr("Organization"), cert.subjectInfo(QSslCertificate::Organization));
- ADD_FIELD(tr("Common Name"), cert.subjectInfo(QSslCertificate::CommonName));
- ADD_FIELD(tr("Locality"), cert.subjectInfo(QSslCertificate::LocalityName));
- ADD_FIELD(tr("Organizational Unit"), cert.subjectInfo(QSslCertificate::OrganizationalUnitName));
- ADD_FIELD(tr("Country"), cert.subjectInfo(QSslCertificate::CountryName));
- ADD_FIELD(tr("State"), cert.subjectInfo(QSslCertificate::StateOrProvinceName));
+ ADD_SECTION(tr("Subject"));
+ ADD_FIELD(tr("Organization"), cert.subjectInfo(QSslCertificate::Organization));
+ ADD_FIELD(tr("Common Name"), cert.subjectInfo(QSslCertificate::CommonName));
+ ADD_FIELD(tr("Locality"), cert.subjectInfo(QSslCertificate::LocalityName));
+ ADD_FIELD(tr("Organizational Unit"), cert.subjectInfo(QSslCertificate::OrganizationalUnitName));
+ ADD_FIELD(tr("Country"), cert.subjectInfo(QSslCertificate::CountryName));
+ ADD_FIELD(tr("State"), cert.subjectInfo(QSslCertificate::StateOrProvinceName));
#if QT_VERSION < 0x050000
- QMultiMap<QSsl::AlternateNameEntryType, QString> altNames = cert.alternateSubjectNames();
+ QMultiMap<QSsl::AlternateNameEntryType, QString> altNames = cert.alternateSubjectNames();
#define SANTYPE QSsl::AlternateNameEntryType
#else
- QMultiMap<QSsl::AlternativeNameEntryType, QString> altNames = cert.subjectAlternativeNames();
+ QMultiMap<QSsl::AlternativeNameEntryType, QString> altNames = cert.subjectAlternativeNames();
#define SANTYPE QSsl::AlternativeNameEntryType
#endif
- if (!altNames.empty()) {
- ADD_SECTION(tr("Alternate Subject Names"));
- foreach (const SANTYPE &type, altNames.uniqueKeys()) {
- foreach (QString name, altNames.values(type)) {
- if (type == QSsl::EmailEntry) {
- ADD_FIELD(tr("E-mail Address"), name);
- } else {
- ADD_FIELD(tr("DNS Name"), name);
- }
- }
- }
- }
-
- ADD_SECTION(tr("Issuer"));
- ADD_FIELD(tr("Organization"), cert.issuerInfo(QSslCertificate::Organization));
- ADD_FIELD(tr("Common Name"), cert.issuerInfo(QSslCertificate::CommonName));
- ADD_FIELD(tr("Locality"), cert.issuerInfo(QSslCertificate::LocalityName));
- ADD_FIELD(tr("Organizational Unit"), cert.issuerInfo(QSslCertificate::OrganizationalUnitName));
- ADD_FIELD(tr("Country"), cert.issuerInfo(QSslCertificate::CountryName));
- ADD_FIELD(tr("State"), cert.issuerInfo(QSslCertificate::StateOrProvinceName));
-
- ui->certGridLayout->setRowStretch(rowCount + 1, 1);
+ if (!altNames.empty()) {
+ ADD_SECTION(tr("Alternate Subject Names"));
+ for (const auto& type : altNames.uniqueKeys()) {
+ for (auto&& name : altNames.values(type)) {
+ if (type == QSsl::EmailEntry) {
+ ADD_FIELD(tr("E-mail Address"), name);
+ } else {
+ ADD_FIELD(tr("DNS Name"), name);
+ }
+ }
+ }
+ }
+
+ ADD_SECTION(tr("Issuer"));
+ ADD_FIELD(tr("Organization"), cert.issuerInfo(QSslCertificate::Organization));
+ ADD_FIELD(tr("Common Name"), cert.issuerInfo(QSslCertificate::CommonName));
+ ADD_FIELD(tr("Locality"), cert.issuerInfo(QSslCertificate::LocalityName));
+ ADD_FIELD(tr("Organizational Unit"), cert.issuerInfo(QSslCertificate::OrganizationalUnitName));
+ ADD_FIELD(tr("Country"), cert.issuerInfo(QSslCertificate::CountryName));
+ ADD_FIELD(tr("State"), cert.issuerInfo(QSslCertificate::StateOrProvinceName));
+
+ ui->certGridLayout->setRowStretch(rowCount + 1, 1);
}
}
diff --git a/Swift/QtUI/QtCertificateViewerDialog.h b/Swift/QtUI/QtCertificateViewerDialog.h
index 9475a83..7b72f1d 100644
--- a/Swift/QtUI/QtCertificateViewerDialog.h
+++ b/Swift/QtUI/QtCertificateViewerDialog.h
@@ -20,25 +20,25 @@ class QtCertificateViewerDialog;
namespace Swift {
class QtCertificateViewerDialog : public QDialog {
- Q_OBJECT
-
- public:
- explicit QtCertificateViewerDialog(QWidget* parent = 0);
- ~QtCertificateViewerDialog();
+ Q_OBJECT
- void setCertificateChain(const std::vector<Certificate::ref>& chain);
+ public:
+ explicit QtCertificateViewerDialog(QWidget* parent = 0);
+ ~QtCertificateViewerDialog();
- static void displayCertificateChainAsSheet(QWidget* parent, const std::vector<Certificate::ref>& chain);
+ void setCertificateChain(const std::vector<Certificate::ref>& chain);
- private slots:
- void currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*);
+ static void displayCertificateChainAsSheet(QWidget* parent, const std::vector<Certificate::ref>& chain);
- private:
- void setCertificateDetails(const QSslCertificate& cert);
+ private slots:
+ void currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*);
- private:
- Ui::QtCertificateViewerDialog *ui;
- QList<QSslCertificate> currentChain;
+ private:
+ void setCertificateDetails(const QSslCertificate& cert);
+
+ private:
+ Ui::QtCertificateViewerDialog *ui;
+ QList<QSslCertificate> currentChain;
};
}
diff --git a/Swift/QtUI/QtChatTabs.cpp b/Swift/QtUI/QtChatTabs.cpp
index 9ecf093..3241858 100644
--- a/Swift/QtUI/QtChatTabs.cpp
+++ b/Swift/QtUI/QtChatTabs.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -9,17 +9,6 @@
#include <algorithm>
#include <vector>
-#include <Swiften/Base/Log.h>
-
-#include <Swift/Controllers/ChatMessageSummarizer.h>
-#include <Swift/Controllers/SettingConstants.h>
-#include <Swift/Controllers/Settings/SettingsProvider.h>
-#include <Swift/QtUI/QtSwiftUtil.h>
-#include <Swift/QtUI/QtTabWidget.h>
-#include <Swift/QtUI/QtTabbable.h>
-#include <Swift/QtUI/Trellis/QtDynamicGridLayout.h>
-#include <Swift/QtUI/Trellis/QtGridSelectionDialog.h>
-
#include <QAction>
#include <QApplication>
#include <QCloseEvent>
@@ -31,392 +20,403 @@
#include <QTabWidget>
#include <QtGlobal>
+#include <Swiften/Base/Log.h>
+
+#include <Swift/Controllers/ChatMessageSummarizer.h>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/QtTabWidget.h>
+#include <Swift/QtUI/QtTabbable.h>
+#include <Swift/QtUI/QtUISettingConstants.h>
+#include <Swift/QtUI/Trellis/QtDynamicGridLayout.h>
+#include <Swift/QtUI/Trellis/QtGridSelectionDialog.h>
+
namespace Swift {
-QtChatTabs::QtChatTabs(bool singleWindow, SettingsProvider* settingsProvider, bool trellisMode) : QWidget(), singleWindow_(singleWindow), settingsProvider_(settingsProvider), trellisMode_(trellisMode), dynamicGrid_(NULL), gridSelectionDialog_(NULL) {
+QtChatTabs::QtChatTabs(bool singleWindow, SettingsProvider* settingsProvider, bool trellisMode) : QWidget(), singleWindow_(singleWindow), settingsProvider_(settingsProvider), trellisMode_(trellisMode), dynamicGrid_(nullptr), gridSelectionDialog_(nullptr) {
#ifndef Q_OS_MAC
- setWindowIcon(QIcon(":/logo-chat-16.png"));
+ setWindowIcon(QIcon(":/logo-chat-16.png"));
#else
- setAttribute(Qt::WA_ShowWithoutActivating);
+ setAttribute(Qt::WA_ShowWithoutActivating);
#endif
- dynamicGrid_ = new QtDynamicGridLayout(this, trellisMode);
- connect(dynamicGrid_, SIGNAL(tabCloseRequested(int)), this, SLOT(handleTabCloseRequested(int)));
- connect(dynamicGrid_, SIGNAL(onCurrentIndexChanged(int)), this, SLOT(handleCurrentTabIndexChanged(int)));
-
- QVBoxLayout *layout = new QVBoxLayout;
- layout->setSpacing(0);
- layout->setContentsMargins(0, 0, 0, 0);
- layout->addWidget(dynamicGrid_);
- setLayout(layout);
-
- if (trellisMode) {
- // restore size
- std::string gridSizeString = settingsProvider->getSetting(SettingConstants::TRELLIS_GRID_SIZE);
- if (!gridSizeString.empty()) {
- QByteArray gridSizeData = QByteArray::fromBase64(P2QSTRING(gridSizeString).toUtf8());
- QDataStream dataStreamGridSize(&gridSizeData, QIODevice::ReadWrite);
- QSize gridSize(1,1);
- dataStreamGridSize >> gridSize;
- dynamicGrid_->setDimensions(gridSize);
- }
-
- // restore positions
- std::string tabPositionsString = settingsProvider->getSetting(SettingConstants::TRELLIS_GRID_POSITIONS);
- if (!tabPositionsString.empty()) {
- QByteArray tabPositionsData = QByteArray::fromBase64(P2QSTRING(tabPositionsString).toUtf8());
- QDataStream inTabPositions(&tabPositionsData, QIODevice::ReadWrite);
- QHash<QString, QPoint> tabPositions;
- inTabPositions >> tabPositions;
- dynamicGrid_->setTabPositions(tabPositions);
- }
- }
-
- gridSelectionDialog_ = new QtGridSelectionDialog();
-
- // setup shortcuts
- shortcuts_ << new QShortcut(QKeySequence(tr("CTRL+W", "Close chat tab.")), window(), SLOT(handleCloseTabShortcut()));
- shortcuts_ << new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_PageUp), window(), SLOT(handleRequestedPreviousTab()));
- shortcuts_ << new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_PageDown), window(), SLOT(handleRequestedNextTab()));
- shortcuts_ << new QShortcut(QKeySequence(Qt::ALT + Qt::Key_A), window(), SLOT(handleRequestedActiveTab()));
+ dynamicGrid_ = new QtDynamicGridLayout(this, trellisMode);
+ connect(dynamicGrid_, SIGNAL(tabCloseRequested(int)), this, SLOT(handleTabCloseRequested(int)));
+ connect(dynamicGrid_, SIGNAL(onCurrentIndexChanged(int)), this, SLOT(handleCurrentTabIndexChanged(int)));
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->setSpacing(0);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->addWidget(dynamicGrid_);
+ setLayout(layout);
+
+ if (trellisMode) {
+ // restore size
+ std::string gridSizeString = settingsProvider->getSetting(QtUISettingConstants::TRELLIS_GRID_SIZE);
+ if (!gridSizeString.empty()) {
+ QByteArray gridSizeData = QByteArray::fromBase64(P2QSTRING(gridSizeString).toUtf8());
+ QDataStream dataStreamGridSize(&gridSizeData, QIODevice::ReadWrite);
+ QSize gridSize(1,1);
+ dataStreamGridSize >> gridSize;
+ dynamicGrid_->setDimensions(gridSize);
+ }
+
+ // restore positions
+ std::string tabPositionsString = settingsProvider->getSetting(QtUISettingConstants::TRELLIS_GRID_POSITIONS);
+ if (!tabPositionsString.empty()) {
+ QByteArray tabPositionsData = QByteArray::fromBase64(P2QSTRING(tabPositionsString).toUtf8());
+ QDataStream inTabPositions(&tabPositionsData, QIODevice::ReadWrite);
+ QHash<QString, QPoint> tabPositions;
+ inTabPositions >> tabPositions;
+ dynamicGrid_->setTabPositions(tabPositions);
+ }
+ }
+
+ gridSelectionDialog_ = new QtGridSelectionDialog();
+
+ // setup shortcuts
+ shortcuts_ << new QShortcut(QKeySequence(tr("CTRL+W", "Close chat tab.")), window(), SLOT(handleCloseTabShortcut()));
+ shortcuts_ << new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_PageUp), window(), SLOT(handleRequestedPreviousTab()));
+ shortcuts_ << new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_PageDown), window(), SLOT(handleRequestedNextTab()));
+ shortcuts_ << new QShortcut(QKeySequence(Qt::ALT + Qt::Key_A), window(), SLOT(handleRequestedActiveTab()));
}
QtChatTabs::~QtChatTabs() {
- foreach (QShortcut* shortcut, shortcuts_) {
- delete shortcut;
- }
-
- if (trellisMode_) {
- storeTabPositions();
- }
- delete gridSelectionDialog_;
+ for (auto shortcut : shortcuts_) {
+ delete shortcut;
+ }
+
+ if (trellisMode_) {
+ storeTabPositions();
+ }
+ delete gridSelectionDialog_;
}
void QtChatTabs::closeEvent(QCloseEvent* event) {
- //Hide first to prevent flickering as each tab is removed.
- hide();
- if (trellisMode_) {
- storeTabPositions();
- }
-
- for (int i = dynamicGrid_->count() - 1; i >= 0; i--) {
- dynamicGrid_->widget(i)->close();
- }
- event->accept();
+ //Hide first to prevent flickering as each tab is removed.
+ hide();
+ if (trellisMode_) {
+ storeTabPositions();
+ }
+
+ for (int i = dynamicGrid_->count() - 1; i >= 0; i--) {
+ dynamicGrid_->widget(i)->close();
+ }
+ event->accept();
}
QtTabbable* QtChatTabs::getCurrentTab() {
- return qobject_cast<QtTabbable*>(dynamicGrid_->currentWidget());
+ return qobject_cast<QtTabbable*>(dynamicGrid_->currentWidget());
}
void QtChatTabs::setViewMenu(QMenu* viewMenu) {
- if (trellisMode_) {
- viewMenu->addSeparator();
- QAction* action = new QAction(tr("Change &layout"), this);
- action->setShortcutContext(Qt::ApplicationShortcut);
- action->setShortcut(QKeySequence(tr("Ctrl+Alt+L")));
- connect(action, SIGNAL(triggered()), this, SLOT(handleOpenLayoutChangeDialog()));
- viewMenu->addAction(action);
-
- action = new QAction(tr("Move Tab right"), this);
- action->setShortcutContext(Qt::ApplicationShortcut);
- action->setShortcut(QKeySequence(tr("Ctrl+Shift+PgDown")));
- connect(action, SIGNAL(triggered()), dynamicGrid_, SLOT(moveCurrentTabRight()));
- viewMenu->addAction(action);
-
- action = new QAction(tr("Move Tab left"), this);
- action->setShortcutContext(Qt::ApplicationShortcut);
- action->setShortcut(QKeySequence(tr("Ctrl+Shift+PgUp")));
- connect(action, SIGNAL(triggered()), dynamicGrid_, SLOT(moveCurrentTabLeft()));
- viewMenu->addAction(action);
-
- action = new QAction(tr("Move Tab to next group"), this);
- action->setShortcutContext(Qt::ApplicationShortcut);
- action->setShortcut(QKeySequence(tr("Ctrl+Alt+PgDown")));
- connect(action, SIGNAL(triggered()), dynamicGrid_, SLOT(moveCurrentTabToNextGroup()));
- viewMenu->addAction(action);
-
- action = new QAction(tr("Move Tab to previous group"), this);
- action->setShortcutContext(Qt::ApplicationShortcut);
- action->setShortcut(QKeySequence(tr("Ctrl+Alt+PgUp")));
- connect(action, SIGNAL(triggered()), dynamicGrid_, SLOT(moveCurrentTabToPreviousGroup()));
- viewMenu->addAction(action);
- }
+ if (trellisMode_) {
+ viewMenu->addSeparator();
+ QAction* action = new QAction(tr("Change &layout"), this);
+ action->setShortcutContext(Qt::ApplicationShortcut);
+ action->setShortcut(QKeySequence(tr("Ctrl+Alt+L")));
+ connect(action, SIGNAL(triggered()), this, SLOT(handleOpenLayoutChangeDialog()));
+ viewMenu->addAction(action);
+
+ action = new QAction(tr("Move Tab right"), this);
+ action->setShortcutContext(Qt::ApplicationShortcut);
+ action->setShortcut(QKeySequence(tr("Ctrl+Shift+PgDown")));
+ connect(action, SIGNAL(triggered()), dynamicGrid_, SLOT(moveCurrentTabRight()));
+ viewMenu->addAction(action);
+
+ action = new QAction(tr("Move Tab left"), this);
+ action->setShortcutContext(Qt::ApplicationShortcut);
+ action->setShortcut(QKeySequence(tr("Ctrl+Shift+PgUp")));
+ connect(action, SIGNAL(triggered()), dynamicGrid_, SLOT(moveCurrentTabLeft()));
+ viewMenu->addAction(action);
+
+ action = new QAction(tr("Move Tab to next group"), this);
+ action->setShortcutContext(Qt::ApplicationShortcut);
+ action->setShortcut(QKeySequence(tr("Ctrl+Alt+PgDown")));
+ connect(action, SIGNAL(triggered()), dynamicGrid_, SLOT(moveCurrentTabToNextGroup()));
+ viewMenu->addAction(action);
+
+ action = new QAction(tr("Move Tab to previous group"), this);
+ action->setShortcutContext(Qt::ApplicationShortcut);
+ action->setShortcut(QKeySequence(tr("Ctrl+Alt+PgUp")));
+ connect(action, SIGNAL(triggered()), dynamicGrid_, SLOT(moveCurrentTabToPreviousGroup()));
+ viewMenu->addAction(action);
+ }
}
void QtChatTabs::addTab(QtTabbable* tab) {
- QSizePolicy policy = sizePolicy();
- /* Chat windows like to grow - don't let them */
- setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
- dynamicGrid_->addTab(tab, tab->windowTitle());
- connect(tab, SIGNAL(titleUpdated()), this, SLOT(handleTabTitleUpdated()), Qt::UniqueConnection);
- connect(tab, SIGNAL(countUpdated()), this, SLOT(handleTabTitleUpdated()), Qt::UniqueConnection);
- connect(tab, SIGNAL(windowClosing()), this, SLOT(handleTabClosing()), Qt::UniqueConnection);
- connect(tab, SIGNAL(windowOpening()), this, SLOT(handleWidgetShown()), Qt::UniqueConnection);
- connect(tab, SIGNAL(wantsToActivate()), this, SLOT(handleWantsToActivate()), Qt::UniqueConnection);
- connect(tab, SIGNAL(requestNextTab()), this, SLOT(handleRequestedNextTab()), Qt::UniqueConnection);
- connect(tab, SIGNAL(requestActiveTab()), this, SLOT(handleRequestedActiveTab()), Qt::UniqueConnection);
- connect(tab, SIGNAL(requestPreviousTab()), this, SLOT(handleRequestedPreviousTab()), Qt::UniqueConnection);
- connect(tab, SIGNAL(requestFlash()), this, SLOT(flash()), Qt::UniqueConnection);
- setSizePolicy(policy);
+ QSizePolicy policy = sizePolicy();
+ /* Chat windows like to grow - don't let them */
+ setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
+ dynamicGrid_->addTab(tab, tab->windowTitle());
+ connect(tab, SIGNAL(titleUpdated()), this, SLOT(handleTabTitleUpdated()), Qt::UniqueConnection);
+ connect(tab, SIGNAL(countUpdated()), this, SLOT(handleTabTitleUpdated()), Qt::UniqueConnection);
+ connect(tab, SIGNAL(windowClosing()), this, SLOT(handleTabClosing()), Qt::UniqueConnection);
+ connect(tab, SIGNAL(windowOpening()), this, SLOT(handleWidgetShown()), Qt::UniqueConnection);
+ connect(tab, SIGNAL(wantsToActivate()), this, SLOT(handleWantsToActivate()), Qt::UniqueConnection);
+ connect(tab, SIGNAL(requestNextTab()), this, SLOT(handleRequestedNextTab()), Qt::UniqueConnection);
+ connect(tab, SIGNAL(requestActiveTab()), this, SLOT(handleRequestedActiveTab()), Qt::UniqueConnection);
+ connect(tab, SIGNAL(requestPreviousTab()), this, SLOT(handleRequestedPreviousTab()), Qt::UniqueConnection);
+ connect(tab, SIGNAL(requestFlash()), this, SLOT(flash()), Qt::UniqueConnection);
+ setSizePolicy(policy);
}
void QtChatTabs::handleWidgetShown() {
- QtTabbable* widget = qobject_cast<QtTabbable*>(sender());
- if (!widget) {
- return;
- }
- checkForFirstShow();
- if (dynamicGrid_->indexOf(widget) >= 0) {
- handleTabTitleUpdated(widget);
- return;
- }
- widget->blockSignals(true);
- addTab(widget);
- widget->blockSignals(false);
- show();
+ QtTabbable* widget = qobject_cast<QtTabbable*>(sender());
+ if (!widget) {
+ return;
+ }
+ checkForFirstShow();
+ if (dynamicGrid_->indexOf(widget) >= 0) {
+ handleTabTitleUpdated(widget);
+ return;
+ }
+ widget->blockSignals(true);
+ addTab(widget);
+ widget->blockSignals(false);
+ show();
}
void QtChatTabs::handleCurrentTabIndexChanged(int newIndex) {
- handleTabTitleUpdated(dynamicGrid_->widget(newIndex));
+ handleTabTitleUpdated(dynamicGrid_->widget(newIndex));
}
void QtChatTabs::handleWantsToActivate() {
- QtTabbable* widget = qobject_cast<QtTabbable*>(sender());
- Q_ASSERT(widget);
- //Un-minimize and bring to front.
- setWindowState(windowState() & ~Qt::WindowMinimized);
- setWindowState(windowState() | Qt::WindowActive);
- show();
- widget->show();
- dynamicGrid_->setCurrentWidget(widget);
- handleTabTitleUpdated(widget);
- widget->setFocus();
- raise();
- activateWindow();
+ QtTabbable* widget = qobject_cast<QtTabbable*>(sender());
+ Q_ASSERT(widget);
+ //Un-minimize and bring to front.
+ setWindowState(windowState() & ~Qt::WindowMinimized);
+ setWindowState(windowState() | Qt::WindowActive);
+ show();
+ widget->show();
+ dynamicGrid_->setCurrentWidget(widget);
+ handleTabTitleUpdated(widget);
+ widget->setFocus();
+ raise();
+ activateWindow();
}
void QtChatTabs::handleTabClosing() {
- QWidget* widget = qobject_cast<QWidget*>(sender());
- int index;
- if (widget && ((index = dynamicGrid_->indexOf(widget)) >= 0)) {
- dynamicGrid_->removeTab(index);
- if (dynamicGrid_->count() == 0) {
- if (!singleWindow_) {
- hide();
- }
- else {
- setWindowTitle("");
- onTitleChanged("");
- }
- }
- else {
- handleTabTitleUpdated(dynamicGrid_->currentWidget());
- }
- }
+ QWidget* widget = qobject_cast<QWidget*>(sender());
+ int index;
+ if (widget && ((index = dynamicGrid_->indexOf(widget)) >= 0)) {
+ dynamicGrid_->removeTab(index);
+ if (dynamicGrid_->count() == 0) {
+ if (!singleWindow_) {
+ hide();
+ }
+ else {
+ setWindowTitle("");
+ onTitleChanged("");
+ }
+ }
+ else {
+ handleTabTitleUpdated(dynamicGrid_->currentWidget());
+ }
+ }
}
void QtChatTabs::handleRequestedPreviousTab() {
- int newIndex = dynamicGrid_->currentIndex() - 1;
- dynamicGrid_->setCurrentIndex(newIndex >= 0 ? newIndex : dynamicGrid_->count() - 1);
+ int newIndex = dynamicGrid_->currentIndex() - 1;
+ dynamicGrid_->setCurrentIndex(newIndex >= 0 ? newIndex : dynamicGrid_->count() - 1);
}
void QtChatTabs::handleRequestedNextTab() {
- int newIndex = dynamicGrid_->currentIndex() + 1;
- dynamicGrid_->setCurrentIndex(newIndex < dynamicGrid_->count() ? newIndex : 0);
+ int newIndex = dynamicGrid_->currentIndex() + 1;
+ dynamicGrid_->setCurrentIndex(newIndex < dynamicGrid_->count() ? newIndex : 0);
}
void QtChatTabs::handleRequestedActiveTab() {
- QtTabbable::AlertType types[] = {QtTabbable::WaitingActivity, QtTabbable::ImpendingActivity};
- bool finished = false;
- for (int j = 0; j < 2; j++) {
- bool looped = false;
- for (int i = dynamicGrid_->currentIndex() + 1; !finished && i != dynamicGrid_->currentIndex(); i++) {
- if (i >= dynamicGrid_->count()) {
- if (looped) {
- break;
- }
- looped = true;
- i = 0;
- }
- if (qobject_cast<QtTabbable*>(dynamicGrid_->widget(i))->getWidgetAlertState() == types[j]) {
- dynamicGrid_->setCurrentIndex(i);
- finished = true;
- break;
- }
- }
- }
+ QtTabbable::AlertType types[] = {QtTabbable::WaitingActivity, QtTabbable::ImpendingActivity};
+ bool finished = false;
+ for (auto& type : types) {
+ bool looped = false;
+ for (int i = dynamicGrid_->currentIndex() + 1; !finished && i != dynamicGrid_->currentIndex(); i++) {
+ if (i >= dynamicGrid_->count()) {
+ if (looped) {
+ break;
+ }
+ looped = true;
+ i = 0;
+ }
+ if (qobject_cast<QtTabbable*>(dynamicGrid_->widget(i))->getWidgetAlertState() == type) {
+ dynamicGrid_->setCurrentIndex(i);
+ finished = true;
+ break;
+ }
+ }
+ }
}
void QtChatTabs::handleCloseTabShortcut() {
- QWidget* currentWidget = dynamicGrid_->currentWidget();
- if (currentWidget) {
- currentWidget->close();
- }
+ QWidget* currentWidget = dynamicGrid_->currentWidget();
+ if (currentWidget) {
+ currentWidget->close();
+ }
}
void QtChatTabs::handleTabCloseRequested(int index) {
- if (trellisMode_) {
- storeTabPositions();
- }
-
- assert(index < dynamicGrid_->count());
- QWidget* widget = dynamicGrid_->widget(index);
- assert(widget);
- widget->close();
+ if (trellisMode_) {
+ storeTabPositions();
+ }
+
+ assert(index < dynamicGrid_->count());
+ QWidget* widget = dynamicGrid_->widget(index);
+ assert(widget);
+ widget->close();
}
void QtChatTabs::handleTabTitleUpdated() {
- QWidget* widget = qobject_cast<QWidget*>(sender());
- handleTabTitleUpdated(widget);
+ QWidget* widget = qobject_cast<QWidget*>(sender());
+ handleTabTitleUpdated(widget);
}
void QtChatTabs::handleTabTitleUpdated(QWidget* widget) {
- if (!widget) {
- return;
- }
- QtTabbable* tabbable = qobject_cast<QtTabbable*>(widget);
- int index = dynamicGrid_->indexOf(widget);
- if (index < 0) {
- return;
- }
-
- QString tabText = tabbable->windowTitle().simplified();
- // look for spectrum-generated and other long JID localparts, and
- // try to abbreviate the resulting long tab texts
- QRegExp hasTrailingGarbage("^(.[-\\w\\s,&]+)([^\\s\\,w].*)$");
- if (hasTrailingGarbage.exactMatch(tabText) &&
- hasTrailingGarbage.cap(1).simplified().length() >= 2 &&
- hasTrailingGarbage.cap(2).length() >= 7) {
- // there may be some trailing garbage, and it's long
- // enough to be worth removing, and we'd leave at
- // least a couple of characters.
- tabText = hasTrailingGarbage.cap(1).simplified();
- }
- // QTabBar interprets &, so escape that
- tabText.replace("&", "&&");
- // see which alt[a-z] keys other tabs use
- bool accelsTaken[26];
- int i = 0;
- while (i < 26) {
- accelsTaken[i] = (i == 0); //A is used for 'switch to active tab'
- i++;
- }
-
- int other = dynamicGrid_->count();
- while (other >= 0) {
- other--;
- if (other != index) {
- int tabIndex = -1;
- QtTabWidget* tabWidget = dynamicGrid_->indexToTabWidget(other, tabIndex);
- QString t = tabWidget->tabBar()->tabText(tabIndex).toLower();
- int r = t.indexOf('&');
- if (r >= 0 && t[r+1] >= 'a' && t[r+1] <= 'z') {
- accelsTaken[t[r+1].unicode()-'a'] = true;
- }
- }
- }
- // then look to see which letters in tabText may be used
- i = 0;
- int accelPos = -1;
- while (i < tabText.length() && accelPos < 0) {
- if (tabText[i] >= 'A' && tabText[i] <= 'Z' &&
- !accelsTaken[tabText[i].unicode()-'A']) {
- accelPos = i;
- }
- if (tabText[i] >= 'a' && tabText[i] <= 'z' &&
- !accelsTaken[tabText[i].unicode()-'a']) {
- accelPos = i;
- }
- ++i;
- }
- if (accelPos >= 0) {
- tabText = tabText.mid(0, accelPos) + "&" + tabText.mid(accelPos);
- }
- // this could be improved on some european keyboards, such as
- // the German one (where alt-Sz-Ligature is available) and basically
- // doesn't work on Arabic/Indic keyboards (where Latin letters
- // aren't available), but I don't care to deal with those.
-
- int tabIndex = -1;
- QtTabWidget* tabWidget = dynamicGrid_->indexToTabWidget(index, tabIndex);
- tabWidget->setTabText(tabIndex, tabbable->getCount() > 0 ? QString("(%1) %2").arg(tabbable->getCount()).arg(tabText) : tabText);
- QColor tabTextColor;
- switch (tabbable->getWidgetAlertState()) {
- case QtTabbable::WaitingActivity : tabTextColor = QColor(217, 20, 43); break;
- case QtTabbable::ImpendingActivity : tabTextColor = QColor(27, 171, 32); break;
- case QtTabbable::NoActivity : tabTextColor = QColor(); break;
- }
- tabWidget->tabBar()->setTabTextColor(tabIndex, tabTextColor);
-
- std::vector<std::pair<std::string, int> > unreads;
- for (int i = 0; i < dynamicGrid_->count(); i++) {
- QtTabbable* tab = qobject_cast<QtTabbable*>(dynamicGrid_->widget(i));
- if (tab) {
- unreads.push_back(std::pair<std::string, int>(Q2PSTRING(tab->windowTitle()), tab->getCount()));
- }
- }
-
- std::string current(Q2PSTRING(qobject_cast<QtTabbable*>(dynamicGrid_->currentWidget())->windowTitle()));
- ChatMessageSummarizer summary;
- QString title = summary.getSummary(current, unreads).c_str();
- setWindowTitle(title);
- emit onTitleChanged(title);
+ if (!widget) {
+ return;
+ }
+ QtTabbable* tabbable = qobject_cast<QtTabbable*>(widget);
+ int index = dynamicGrid_->indexOf(widget);
+ if (index < 0) {
+ return;
+ }
+
+ QString tabText = tabbable->windowTitle().simplified();
+ // look for spectrum-generated and other long JID localparts, and
+ // try to abbreviate the resulting long tab texts
+ QRegExp hasTrailingGarbage("^(.[-\\w\\s,&]+)([^\\s\\,w].*)$");
+ if (hasTrailingGarbage.exactMatch(tabText) &&
+ hasTrailingGarbage.cap(1).simplified().length() >= 2 &&
+ hasTrailingGarbage.cap(2).length() >= 7) {
+ // there may be some trailing garbage, and it's long
+ // enough to be worth removing, and we'd leave at
+ // least a couple of characters.
+ tabText = hasTrailingGarbage.cap(1).simplified();
+ }
+ // QTabBar interprets &, so escape that
+ tabText.replace("&", "&&");
+ // see which alt[a-z] keys other tabs use
+ bool accelsTaken[26];
+ int i = 0;
+ while (i < 26) {
+ accelsTaken[i] = (i == 0); //A is used for 'switch to active tab'
+ i++;
+ }
+
+ int other = dynamicGrid_->count();
+ while (other >= 0) {
+ other--;
+ if (other != index) {
+ int tabIndex = -1;
+ QtTabWidget* tabWidget = dynamicGrid_->indexToTabWidget(other, tabIndex);
+ QString t = tabWidget->tabBar()->tabText(tabIndex).toLower();
+ int r = t.indexOf('&');
+ if (r >= 0 && t[r+1] >= 'a' && t[r+1] <= 'z') {
+ accelsTaken[t[r+1].unicode()-'a'] = true;
+ }
+ }
+ }
+ // then look to see which letters in tabText may be used
+ i = 0;
+ int accelPos = -1;
+ while (i < tabText.length() && accelPos < 0) {
+ if (tabText[i] >= 'A' && tabText[i] <= 'Z' &&
+ !accelsTaken[tabText[i].unicode()-'A']) {
+ accelPos = i;
+ }
+ if (tabText[i] >= 'a' && tabText[i] <= 'z' &&
+ !accelsTaken[tabText[i].unicode()-'a']) {
+ accelPos = i;
+ }
+ ++i;
+ }
+ if (accelPos >= 0) {
+ tabText = tabText.mid(0, accelPos) + "&" + tabText.mid(accelPos);
+ }
+ // this could be improved on some european keyboards, such as
+ // the German one (where alt-Sz-Ligature is available) and basically
+ // doesn't work on Arabic/Indic keyboards (where Latin letters
+ // aren't available), but I don't care to deal with those.
+
+ int tabIndex = -1;
+ QtTabWidget* tabWidget = dynamicGrid_->indexToTabWidget(index, tabIndex);
+ tabWidget->setTabText(tabIndex, tabbable->getCount() > 0 ? QString("(%1) %2").arg(tabbable->getCount()).arg(tabText) : tabText);
+ QColor tabTextColor;
+ switch (tabbable->getWidgetAlertState()) {
+ case QtTabbable::WaitingActivity : tabTextColor = QColor(217, 20, 43); break;
+ case QtTabbable::ImpendingActivity : tabTextColor = QColor(27, 171, 32); break;
+ case QtTabbable::NoActivity : tabTextColor = QColor(); break;
+ }
+ tabWidget->tabBar()->setTabTextColor(tabIndex, tabTextColor);
+
+ std::vector<std::pair<std::string, int> > unreads;
+ for (int i = 0; i < dynamicGrid_->count(); i++) {
+ QtTabbable* tab = qobject_cast<QtTabbable*>(dynamicGrid_->widget(i));
+ if (tab) {
+ unreads.push_back(std::pair<std::string, int>(Q2PSTRING(tab->windowTitle()), tab->getCount()));
+ }
+ }
+
+ std::string current(Q2PSTRING(qobject_cast<QtTabbable*>(dynamicGrid_->currentWidget())->windowTitle()));
+ ChatMessageSummarizer summary;
+ QString title = summary.getSummary(current, unreads).c_str();
+ setWindowTitle(title);
+ emit onTitleChanged(title);
}
void QtChatTabs::flash() {
#ifndef SWIFTEN_PLATFORM_MACOSX
- QApplication::alert(this, 0);
+ QApplication::alert(this, 0);
#endif
}
void QtChatTabs::handleOpenLayoutChangeDialog() {
- disconnect(gridSelectionDialog_, SIGNAL(currentGridSizeChanged(QSize)), dynamicGrid_, SLOT(setDimensions(QSize)));
- gridSelectionDialog_->setCurrentGridSize(dynamicGrid_->getDimension());
- gridSelectionDialog_->move(QCursor::pos());
- connect(gridSelectionDialog_, SIGNAL(currentGridSizeChanged(QSize)), dynamicGrid_, SLOT(setDimensions(QSize)));
- gridSelectionDialog_->show();
+ disconnect(gridSelectionDialog_, SIGNAL(currentGridSizeChanged(QSize)), dynamicGrid_, SLOT(setDimensions(QSize)));
+ gridSelectionDialog_->setCurrentGridSize(dynamicGrid_->getDimension());
+ gridSelectionDialog_->move(QCursor::pos());
+ connect(gridSelectionDialog_, SIGNAL(currentGridSizeChanged(QSize)), dynamicGrid_, SLOT(setDimensions(QSize)));
+ gridSelectionDialog_->show();
}
void QtChatTabs::storeTabPositions() {
- // save size
- QByteArray gridSizeData;
- QDataStream dataStreamGridSize(&gridSizeData, QIODevice::ReadWrite);
- dataStreamGridSize << dynamicGrid_->getDimension();
- settingsProvider_->storeSetting(SettingConstants::TRELLIS_GRID_SIZE, Q2PSTRING(QString(gridSizeData.toBase64())));
-
- // save positions
- QByteArray tabPositionsData;
- QDataStream dataStreamTabPositions(&tabPositionsData, QIODevice::ReadWrite);
- dynamicGrid_->updateTabPositions();
- dataStreamTabPositions << dynamicGrid_->getTabPositions();
- settingsProvider_->storeSetting(SettingConstants::TRELLIS_GRID_POSITIONS, Q2PSTRING(QString(tabPositionsData.toBase64())));
+ // save size
+ QByteArray gridSizeData;
+ QDataStream dataStreamGridSize(&gridSizeData, QIODevice::ReadWrite);
+ dataStreamGridSize << dynamicGrid_->getDimension();
+ settingsProvider_->storeSetting(QtUISettingConstants::TRELLIS_GRID_SIZE, Q2PSTRING(QString(gridSizeData.toBase64())));
+
+ // save positions
+ QByteArray tabPositionsData;
+ QDataStream dataStreamTabPositions(&tabPositionsData, QIODevice::ReadWrite);
+ dynamicGrid_->updateTabPositions();
+ dataStreamTabPositions << dynamicGrid_->getTabPositions();
+ settingsProvider_->storeSetting(QtUISettingConstants::TRELLIS_GRID_POSITIONS, Q2PSTRING(QString(tabPositionsData.toBase64())));
}
void QtChatTabs::resizeEvent(QResizeEvent*) {
- emit geometryChanged();
+ emit geometryChanged();
}
void QtChatTabs::moveEvent(QMoveEvent*) {
- emit geometryChanged();
+ emit geometryChanged();
}
void QtChatTabs::checkForFirstShow() {
- if (!isVisible()) {
+ if (!isVisible()) {
#ifndef Q_OS_MAC
- showMinimized();
+ showMinimized();
#else
- /* https://bugreports.qt-project.org/browse/QTBUG-19194
- * ^ When the above is fixed we can swap the below for just show();
- * WA_ShowWithoutActivating seems to helpfully not work, so... */
-
- QWidget* currentWindow = QApplication::activeWindow(); /* Remember who had focus if we're the current application*/
- show();
- QCoreApplication::processEvents(); /* Run through the eventloop to clear the show() */
- if (currentWindow) {
- currentWindow->activateWindow(); /* Set focus back */
- }
+ /* https://bugreports.qt-project.org/browse/QTBUG-19194
+ * ^ When the above is fixed we can swap the below for just show();
+ * WA_ShowWithoutActivating seems to helpfully not work, so... */
+
+ QWidget* currentWindow = QApplication::activeWindow(); /* Remember who had focus if we're the current application*/
+ show();
+ QCoreApplication::processEvents(); /* Run through the eventloop to clear the show() */
+ if (currentWindow) {
+ currentWindow->activateWindow(); /* Set focus back */
+ }
#endif
- }
+ }
}
}
diff --git a/Swift/QtUI/QtChatTabs.h b/Swift/QtUI/QtChatTabs.h
index 71d4ddc..0c12d96 100644
--- a/Swift/QtUI/QtChatTabs.h
+++ b/Swift/QtUI/QtChatTabs.h
@@ -1,14 +1,14 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <QWidget>
#include <QRect>
#include <QShortcut>
+#include <QWidget>
#include <Swift/QtUI/QtChatTabsBase.h>
@@ -16,62 +16,62 @@ class QTabWidget;
class QMenu;
namespace Swift {
- class SettingsProvider;
-
- class QtTabbable;
- class QtTabWidget;
- class QtDynamicGridLayout;
- class QtGridSelectionDialog;
-
- class QtChatTabs : public QWidget, public QtChatTabsBase {
- Q_OBJECT
- public:
- QtChatTabs(bool singleWindow, SettingsProvider* settingsProvider, bool trellisMode);
- virtual ~QtChatTabs();
-
- virtual void addTab(QtTabbable* tab);
- void minimise();
- QtTabbable* getCurrentTab();
- void setViewMenu(QMenu* viewMenu);
-
- signals:
- void geometryChanged();
- void onTitleChanged(const QString& title);
-
- protected slots:
- void closeEvent(QCloseEvent* event);
- void resizeEvent(QResizeEvent* event);
- void moveEvent(QMoveEvent* event);
-
- private slots:
- void handleCurrentTabIndexChanged(int newIndex);
- void handleTabClosing();
- void handleTabTitleUpdated();
- void handleTabTitleUpdated(QWidget* widget);
- void handleTabCloseRequested(int index);
- void handleWidgetShown();
- void handleWantsToActivate();
- void handleRequestedPreviousTab();
- void handleRequestedNextTab();
- void handleRequestedActiveTab();
- void flash();
-
- void handleOpenLayoutChangeDialog();
-
- void handleCloseTabShortcut();
-
- private:
- void storeTabPositions();
- void checkForFirstShow();
-
- private:
- bool singleWindow_;
- SettingsProvider* settingsProvider_;
- bool trellisMode_;
- QtDynamicGridLayout* dynamicGrid_;
- QtGridSelectionDialog* gridSelectionDialog_;
-
- QList<QShortcut*> shortcuts_;
- };
+ class SettingsProvider;
+
+ class QtTabbable;
+ class QtTabWidget;
+ class QtDynamicGridLayout;
+ class QtGridSelectionDialog;
+
+ class QtChatTabs : public QWidget, public QtChatTabsBase {
+ Q_OBJECT
+ public:
+ QtChatTabs(bool singleWindow, SettingsProvider* settingsProvider, bool trellisMode);
+ virtual ~QtChatTabs();
+
+ virtual void addTab(QtTabbable* tab);
+ void minimise();
+ QtTabbable* getCurrentTab();
+ void setViewMenu(QMenu* viewMenu);
+
+ signals:
+ void geometryChanged();
+ void onTitleChanged(const QString& title);
+
+ protected slots:
+ void closeEvent(QCloseEvent* event);
+ void resizeEvent(QResizeEvent* event);
+ void moveEvent(QMoveEvent* event);
+
+ private slots:
+ void handleCurrentTabIndexChanged(int newIndex);
+ void handleTabClosing();
+ void handleTabTitleUpdated();
+ void handleTabTitleUpdated(QWidget* widget);
+ void handleTabCloseRequested(int index);
+ void handleWidgetShown();
+ void handleWantsToActivate();
+ void handleRequestedPreviousTab();
+ void handleRequestedNextTab();
+ void handleRequestedActiveTab();
+ void flash();
+
+ void handleOpenLayoutChangeDialog();
+
+ void handleCloseTabShortcut();
+
+ private:
+ void storeTabPositions();
+ void checkForFirstShow();
+
+ private:
+ bool singleWindow_;
+ SettingsProvider* settingsProvider_;
+ bool trellisMode_;
+ QtDynamicGridLayout* dynamicGrid_;
+ QtGridSelectionDialog* gridSelectionDialog_;
+
+ QList<QShortcut*> shortcuts_;
+ };
}
diff --git a/Swift/QtUI/QtChatTabsBase.h b/Swift/QtUI/QtChatTabsBase.h
index 753b706..b49bb10 100644
--- a/Swift/QtUI/QtChatTabsBase.h
+++ b/Swift/QtUI/QtChatTabsBase.h
@@ -11,11 +11,11 @@ namespace Swift {
class QtTabbable;
class QtChatTabsBase {
- public:
- QtChatTabsBase();
- virtual ~QtChatTabsBase();
+ public:
+ QtChatTabsBase();
+ virtual ~QtChatTabsBase();
- virtual void addTab(QtTabbable* tab) = 0;
+ virtual void addTab(QtTabbable* tab) = 0;
};
}
diff --git a/Swift/QtUI/QtChatTabsShortcutOnlySubstitute.cpp b/Swift/QtUI/QtChatTabsShortcutOnlySubstitute.cpp
index 7f44177..40ab17f 100644
--- a/Swift/QtUI/QtChatTabsShortcutOnlySubstitute.cpp
+++ b/Swift/QtUI/QtChatTabsShortcutOnlySubstitute.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -12,7 +12,6 @@
#include <QShortcut>
#include <Swiften/Base/Log.h>
-#include <Swiften/Base/foreach.h>
#include <Swift/QtUI/QtTabbable.h>
@@ -27,82 +26,82 @@ QtChatTabsShortcutOnlySubstitute::~QtChatTabsShortcutOnlySubstitute() {
}
void QtChatTabsShortcutOnlySubstitute::addTab(QtTabbable* tab) {
- connect(tab, SIGNAL(requestNextTab()), this, SLOT(handleRequestedNextTab()), Qt::UniqueConnection);
- connect(tab, SIGNAL(requestActiveTab()), this, SLOT(handleRequestedActiveTab()), Qt::UniqueConnection);
- connect(tab, SIGNAL(requestPreviousTab()), this, SLOT(handleRequestedPreviousTab()), Qt::UniqueConnection);
-
- connect(new QShortcut(QKeySequence(tr("CTRL+W", "Close chat tab.")), tab), SIGNAL(activated()), this, SLOT(handleCloseTabShortcut()));
- connect(new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_PageUp), tab), SIGNAL(activated()), tab, SIGNAL(requestPreviousTab()));
- connect(new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_PageDown), tab), SIGNAL(activated()), tab, SIGNAL(requestNextTab()));
- connect(new QShortcut(QKeySequence(Qt::ALT + Qt::Key_A), tab), SIGNAL(activated()), tab, SIGNAL(requestActiveTab()));
+ connect(tab, SIGNAL(requestNextTab()), this, SLOT(handleRequestedNextTab()), Qt::UniqueConnection);
+ connect(tab, SIGNAL(requestActiveTab()), this, SLOT(handleRequestedActiveTab()), Qt::UniqueConnection);
+ connect(tab, SIGNAL(requestPreviousTab()), this, SLOT(handleRequestedPreviousTab()), Qt::UniqueConnection);
+
+ connect(new QShortcut(QKeySequence(tr("CTRL+W", "Close chat tab.")), tab), SIGNAL(activated()), this, SLOT(handleCloseTabShortcut()));
+ connect(new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_PageUp), tab), SIGNAL(activated()), tab, SIGNAL(requestPreviousTab()));
+ connect(new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_PageDown), tab), SIGNAL(activated()), tab, SIGNAL(requestNextTab()));
+ connect(new QShortcut(QKeySequence(Qt::ALT + Qt::Key_A), tab), SIGNAL(activated()), tab, SIGNAL(requestActiveTab()));
}
void QtChatTabsShortcutOnlySubstitute::handleCloseTabShortcut() {
- QtTabbable* senderTab = dynamic_cast<QtTabbable*>(sender()->parent());
- SWIFT_LOG_ASSERT(senderTab, debug) << "No window to close." << std::endl;
- if (senderTab) {
- senderTab->close();
- }
+ QtTabbable* senderTab = dynamic_cast<QtTabbable*>(sender()->parent());
+ SWIFT_LOG_ASSERT(senderTab, debug) << "No window to close." << std::endl;
+ if (senderTab) {
+ senderTab->close();
+ }
}
void QtChatTabsShortcutOnlySubstitute::handleRequestedNextTab() {
- QtTabbable* senderTab = dynamic_cast<QtTabbable*>(sender());
+ QtTabbable* senderTab = dynamic_cast<QtTabbable*>(sender());
- QList<QtTabbable*> tabs = tabbableWindows();
+ QList<QtTabbable*> tabs = tabbableWindows();
- int currentIndex = tabs.indexOf(senderTab);
- assert(currentIndex >= 0);
+ int currentIndex = tabs.indexOf(senderTab);
+ assert(currentIndex >= 0);
- QtTabbable* nextTab = tabs.at((currentIndex + 1) % tabs.size());
- nextTab->activateWindow();
+ QtTabbable* nextTab = tabs.at((currentIndex + 1) % tabs.size());
+ nextTab->activateWindow();
}
void QtChatTabsShortcutOnlySubstitute::handleRequestedActiveTab() {
- QtTabbable* senderTab = dynamic_cast<QtTabbable*>(sender());
+ QtTabbable* senderTab = dynamic_cast<QtTabbable*>(sender());
- QtTabbable::AlertType types[] = {QtTabbable::WaitingActivity, QtTabbable::ImpendingActivity};
+ QtTabbable::AlertType types[] = {QtTabbable::WaitingActivity, QtTabbable::ImpendingActivity};
- QList<QtTabbable*> tabs = tabbableWindows();
+ QList<QtTabbable*> tabs = tabbableWindows();
- for (int j = 0; j < 2; j++) {
- int startIndex = tabs.indexOf(senderTab);
- int currentIndex = startIndex;
+ for (auto& type : types) {
+ int startIndex = tabs.indexOf(senderTab);
+ int currentIndex = startIndex;
- do {
- currentIndex = (currentIndex + 1) % tabs.size();
- QtTabbable* currentTab = tabs.at(currentIndex);
- if (currentTab->getWidgetAlertState() == types[j]) {
- currentTab->activateWindow();
- return;
- }
- } while (startIndex != currentIndex);
- }
+ do {
+ currentIndex = (currentIndex + 1) % tabs.size();
+ QtTabbable* currentTab = tabs.at(currentIndex);
+ if (currentTab->getWidgetAlertState() == type) {
+ currentTab->activateWindow();
+ return;
+ }
+ } while (startIndex != currentIndex);
+ }
}
void QtChatTabsShortcutOnlySubstitute::handleRequestedPreviousTab() {
- QtTabbable* senderTab = dynamic_cast<QtTabbable*>(sender());
+ QtTabbable* senderTab = dynamic_cast<QtTabbable*>(sender());
- QList<QtTabbable*> tabs = tabbableWindows();
+ QList<QtTabbable*> tabs = tabbableWindows();
- int currentIndex = tabs.indexOf(senderTab);
- assert(currentIndex >= 0);
+ int currentIndex = tabs.indexOf(senderTab);
+ assert(currentIndex >= 0);
- QtTabbable* previousTab = tabs.at((currentIndex + tabs.size() - 1) % tabs.size());
- previousTab->activateWindow();
+ QtTabbable* previousTab = tabs.at((currentIndex + tabs.size() - 1) % tabs.size());
+ previousTab->activateWindow();
}
QList<QtTabbable*> QtChatTabsShortcutOnlySubstitute::tabbableWindows() const {
- QList<QWidget*> windows = qApp->topLevelWidgets();
+ QList<QWidget*> windows = qApp->topLevelWidgets();
- QList<QtTabbable*> tabbables;
- foreach(QWidget* topLevelWidget, windows) {
- QtTabbable* tabbable = dynamic_cast<QtTabbable*>(topLevelWidget);
- if (tabbable) {
- tabbables << tabbable;
- }
- }
+ QList<QtTabbable*> tabbables;
+ for (auto topLevelWidget : windows) {
+ QtTabbable* tabbable = dynamic_cast<QtTabbable*>(topLevelWidget);
+ if (tabbable) {
+ tabbables << tabbable;
+ }
+ }
- return tabbables;
+ return tabbables;
}
}
diff --git a/Swift/QtUI/QtChatTabsShortcutOnlySubstitute.h b/Swift/QtUI/QtChatTabsShortcutOnlySubstitute.h
index 069bb0b..b330fe7 100644
--- a/Swift/QtUI/QtChatTabsShortcutOnlySubstitute.h
+++ b/Swift/QtUI/QtChatTabsShortcutOnlySubstitute.h
@@ -1,13 +1,13 @@
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <QWidget>
#include <QList>
+#include <QWidget>
#include <Swift/QtUI/QtChatTabsBase.h>
@@ -16,25 +16,25 @@ class QShortcut;
namespace Swift {
class QtChatTabsShortcutOnlySubstitute : public QWidget, public QtChatTabsBase {
- Q_OBJECT
+ Q_OBJECT
- public:
- QtChatTabsShortcutOnlySubstitute();
- virtual ~QtChatTabsShortcutOnlySubstitute();
+ public:
+ QtChatTabsShortcutOnlySubstitute();
+ virtual ~QtChatTabsShortcutOnlySubstitute();
- virtual void addTab(QtTabbable* tab);
+ virtual void addTab(QtTabbable* tab);
- private slots:
- void handleCloseTabShortcut();
- void handleRequestedNextTab();
- void handleRequestedActiveTab();
- void handleRequestedPreviousTab();
+ private slots:
+ void handleCloseTabShortcut();
+ void handleRequestedNextTab();
+ void handleRequestedActiveTab();
+ void handleRequestedPreviousTab();
- private:
- QList<QtTabbable*> tabbableWindows() const;
+ private:
+ QList<QtTabbable*> tabbableWindows() const;
- private:
- QList<QShortcut*> shortcuts_;
+ private:
+ QList<QShortcut*> shortcuts_;
};
}
diff --git a/Swift/QtUI/QtChatTheme.cpp b/Swift/QtUI/QtChatTheme.cpp
index 5a9bc44..e73f8ac 100644
--- a/Swift/QtUI/QtChatTheme.cpp
+++ b/Swift/QtUI/QtChatTheme.cpp
@@ -1,67 +1,71 @@
/*
- * Copyright (c) 2010 Isode Limited..
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtChatTheme.h"
+#include <Swift/QtUI/QtChatTheme.h>
#include <QFile>
-#include <qdebug.h>
namespace Swift {
/**
* Load Adium themes, as http://trac.adium.im/wiki/CreatingMessageStyles
*/
-QtChatTheme::QtChatTheme(const QString& themePath) : qrc_(themePath.isEmpty()), themePath_(qrc_ ? ":/themes/Default/" : themePath + "/Contents/Resources/") {
- QString fileNames[EndMarker];
- fileNames[Header] = "Header.html";
- fileNames[Footer] = "Footer.html";
- fileNames[Content] = "Content.html";
- fileNames[Status] = "Status.html";
- fileNames[Topic] = "Topic.html";
- fileNames[FileTransferRequest] = "FileTransferRequest.html";
- fileNames[IncomingContent] = "Incoming/Content.html";
- fileNames[IncomingNextContent] = "Incoming/NextContent.html";
- fileNames[IncomingContext] = "Incoming/Context.html";
- fileNames[IncomingNextContext] = "Incoming/NextContext.html";
- fileNames[OutgoingContent] = "Outgoing/Content.html";
- fileNames[OutgoingNextContent] = "Outgoing/NextContent.html";
- fileNames[OutgoingContext] = "Outgoing/Context.html";
- fileNames[OutgoingNextContext] = "Outgoing/NextContext.html";
- fileNames[Template] = "Template.html";
- fileNames[MainCSS] = "main.css";
- fileNames[TemplateDefault] = ":/themes/Template.html";
- for (int i = 0; i < EndMarker; i++) {
- QString source;
- QFile sourceFile((i != TemplateDefault ? themePath_ : "") + fileNames[i]);
- if (sourceFile.exists() && sourceFile.open(QIODevice::ReadOnly)) {
- source = sourceFile.readAll();
- sourceFile.close();
- } else {
- //qWarning() << "Couldn't load file " << sourceFile.fileName();
- }
- fileContents_.append(source);
- }
+QtChatTheme::QtChatTheme(const QString& themePath) : qrc_(themePath[0] == ':'), themePath_(qrc_ ? themePath : themePath + "/Contents/Resources/") {
+ QString fileNames[EndMarker];
+ fileNames[Header] = "Header.html";
+ fileNames[Footer] = "Footer.html";
+ fileNames[Content] = "Content.html";
+ fileNames[Status] = "Status.html";
+ fileNames[Topic] = "Topic.html";
+ fileNames[FileTransferRequest] = "FileTransferRequest.html";
+ fileNames[IncomingContent] = "Incoming/Content.html";
+ fileNames[IncomingNextContent] = "Incoming/NextContent.html";
+ fileNames[IncomingContext] = "Incoming/Context.html";
+ fileNames[IncomingNextContext] = "Incoming/NextContext.html";
+ fileNames[OutgoingContent] = "Outgoing/Content.html";
+ fileNames[OutgoingNextContent] = "Outgoing/NextContent.html";
+ fileNames[OutgoingContext] = "Outgoing/Context.html";
+ fileNames[OutgoingNextContext] = "Outgoing/NextContext.html";
+ fileNames[Template] = "Template.html";
+ fileNames[MainCSS] = "main.css";
+ fileNames[Unread] = "Unread.html";
+ fileNames[TemplateDefault] = ":/themes/Template.html";
+ for (int i = 0; i < EndMarker; i++) {
+ QString source;
+ QFile sourceFile((i != TemplateDefault ? themePath_ : "") + fileNames[i]);
+ if (sourceFile.exists() && sourceFile.open(QIODevice::ReadOnly)) {
+ source = sourceFile.readAll();
+ sourceFile.close();
+ } else {
+ //qWarning() << "Couldn't load file " << sourceFile.fileName();
+ }
+ fileContents_.append(source);
+ }
- /* Fallbacks */
- if (fileContents_[Template].isEmpty()) fileContents_[Template] = fileContents_[TemplateDefault];
- if (fileContents_[Status].isEmpty()) fileContents_[Status] = fileContents_[Content];
- if (fileContents_[IncomingContent].isEmpty()) fileContents_[IncomingContent] = fileContents_[Content];
- if (fileContents_[IncomingNextContent].isEmpty()) fileContents_[IncomingNextContent] = fileContents_[IncomingContent];
- if (fileContents_[FileTransferRequest].isEmpty()) fileContents_[FileTransferRequest] = fileContents_[Status];
- if (fileContents_[IncomingContext].isEmpty()) fileContents_[IncomingContext] = fileContents_[IncomingContent];
- if (fileContents_[IncomingNextContext].isEmpty()) fileContents_[IncomingNextContext] = fileContents_[IncomingNextContent];
- if (fileContents_[OutgoingContent].isEmpty()) fileContents_[OutgoingContent] = fileContents_[IncomingContent];
- if (fileContents_[OutgoingContext].isEmpty()) fileContents_[OutgoingContext] = fileContents_[OutgoingContent];
- if (fileContents_[OutgoingNextContent].isEmpty()) fileContents_[OutgoingNextContent] = fileContents_[OutgoingContent];
- if (fileContents_[OutgoingNextContext].isEmpty()) fileContents_[OutgoingNextContext] = fileContents_[OutgoingNextContent];
+ /* Fallbacks */
+ if (fileContents_[Template].isEmpty()) fileContents_[Template] = fileContents_[TemplateDefault];
+ if (fileContents_[Status].isEmpty()) fileContents_[Status] = fileContents_[Content];
+ if (fileContents_[IncomingContent].isEmpty()) fileContents_[IncomingContent] = fileContents_[Content];
+ if (fileContents_[IncomingNextContent].isEmpty()) fileContents_[IncomingNextContent] = fileContents_[IncomingContent];
+ if (fileContents_[FileTransferRequest].isEmpty()) fileContents_[FileTransferRequest] = fileContents_[Status];
+ if (fileContents_[IncomingContext].isEmpty()) fileContents_[IncomingContext] = fileContents_[IncomingContent];
+ if (fileContents_[IncomingNextContext].isEmpty()) fileContents_[IncomingNextContext] = fileContents_[IncomingNextContent];
+ if (fileContents_[OutgoingContent].isEmpty()) fileContents_[OutgoingContent] = fileContents_[IncomingContent];
+ if (fileContents_[OutgoingContext].isEmpty()) fileContents_[OutgoingContext] = fileContents_[OutgoingContent];
+ if (fileContents_[OutgoingNextContent].isEmpty()) fileContents_[OutgoingNextContent] = fileContents_[OutgoingContent];
+ if (fileContents_[OutgoingNextContext].isEmpty()) fileContents_[OutgoingNextContext] = fileContents_[OutgoingNextContent];
}
QString QtChatTheme::getBase() const {
- return qrc_ ? "qrc" + themePath_ : "file://" + themePath_;
+ return qrc_ ? "qrc" + themePath_ : "file://" + themePath_;
+}
+
+QString QtChatTheme::getUnread() const {
+ return fileContents_[Unread].isEmpty() ? "<hr/>" : fileContents_[Unread];
}
}
diff --git a/Swift/QtUI/QtChatTheme.h b/Swift/QtUI/QtChatTheme.h
index bc5b0be..8db662f 100644
--- a/Swift/QtUI/QtChatTheme.h
+++ b/Swift/QtUI/QtChatTheme.h
@@ -1,40 +1,41 @@
/*
- * Copyright (c) 2010 Isode Limited..
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <QString>
#include <QList>
+#include <QString>
namespace Swift {
- class QtChatTheme {
- public:
- QtChatTheme(const QString& themePath);
- QString getHeader() const {return fileContents_[Header];}
- QString getFooter() const {return fileContents_[Footer];}
- QString getContent() const {return fileContents_[Content];}
- QString getStatus() const {return fileContents_[Status];}
- QString getTopic() const {return fileContents_[Topic];}
- QString getFileTransferRequest() const {return fileContents_[FileTransferRequest];}
- QString getIncomingContent() const {return fileContents_[IncomingContent];}
- QString getIncomingNextContent() const {return fileContents_[IncomingNextContent];}
- QString getIncomingContext() const {return fileContents_[IncomingContext];}
- QString getIncomingNextContext() const {return fileContents_[IncomingNextContext];}
- QString getOutgoingContent() const {return fileContents_[OutgoingContent];}
- QString getOutgoingNextContent() const {return fileContents_[OutgoingNextContent];}
- QString getOutgoingContext() const {return fileContents_[OutgoingContext];}
- QString getOutgoingNextContext() const {return fileContents_[OutgoingNextContext];}
- QString getTemplate() const {return fileContents_[Template];}
- QString getMainCSS() const {return fileContents_[MainCSS];}
- QString getBase() const;
+ class QtChatTheme {
+ public:
+ QtChatTheme(const QString& themePath);
+ QString getHeader() const {return fileContents_[Header];}
+ QString getFooter() const {return fileContents_[Footer];}
+ QString getContent() const {return fileContents_[Content];}
+ QString getStatus() const {return fileContents_[Status];}
+ QString getTopic() const {return fileContents_[Topic];}
+ QString getFileTransferRequest() const {return fileContents_[FileTransferRequest];}
+ QString getIncomingContent() const {return fileContents_[IncomingContent];}
+ QString getIncomingNextContent() const {return fileContents_[IncomingNextContent];}
+ QString getIncomingContext() const {return fileContents_[IncomingContext];}
+ QString getIncomingNextContext() const {return fileContents_[IncomingNextContext];}
+ QString getOutgoingContent() const {return fileContents_[OutgoingContent];}
+ QString getOutgoingNextContent() const {return fileContents_[OutgoingNextContent];}
+ QString getOutgoingContext() const {return fileContents_[OutgoingContext];}
+ QString getOutgoingNextContext() const {return fileContents_[OutgoingNextContext];}
+ QString getTemplate() const {return fileContents_[Template];}
+ QString getMainCSS() const {return fileContents_[MainCSS];}
+ QString getBase() const;
+ QString getUnread() const;
- private:
- enum files {Header = 0, Footer, Content, Status, Topic, FileTransferRequest, IncomingContent, IncomingNextContent, IncomingContext, IncomingNextContext, OutgoingContent, OutgoingNextContent, OutgoingContext, OutgoingNextContext, Template, MainCSS, TemplateDefault, EndMarker};
- bool qrc_;
- QList<QString> fileContents_;
- QString themePath_;
- };
+ private:
+ enum files {Header = 0, Footer, Content, Status, Topic, FileTransferRequest, IncomingContent, IncomingNextContent, IncomingContext, IncomingNextContext, OutgoingContent, OutgoingNextContent, OutgoingContext, OutgoingNextContext, Template, MainCSS, TemplateDefault, Unread, /*Must be last!*/EndMarker};
+ bool qrc_;
+ QList<QString> fileContents_;
+ QString themePath_;
+ };
}
diff --git a/Swift/QtUI/QtChatView.cpp b/Swift/QtUI/QtChatView.cpp
index 9946114..6d9a17d 100644
--- a/Swift/QtUI/QtChatView.cpp
+++ b/Swift/QtUI/QtChatView.cpp
@@ -1,12 +1,11 @@
/*
- * Copyright (c) 2013 Isode Limited.
+ * Copyright (c) 2013-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/QtChatView.h>
-
namespace Swift {
QtChatView::QtChatView(QWidget* parent) : QWidget(parent) {
@@ -14,7 +13,7 @@ QtChatView::QtChatView(QWidget* parent) : QWidget(parent) {
}
QtChatView::~QtChatView() {
-
+
}
}
diff --git a/Swift/QtUI/QtChatView.h b/Swift/QtUI/QtChatView.h
index e1d2e1a..fd13cc2 100644
--- a/Swift/QtUI/QtChatView.h
+++ b/Swift/QtUI/QtChatView.h
@@ -1,64 +1,64 @@
/*
- * Copyright (c) 2013-2015 Isode Limited.
+ * Copyright (c) 2013-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <memory>
#include <string>
#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/shared_ptr.hpp>
#include <QWidget>
#include <Swift/Controllers/UIInterfaces/ChatWindow.h>
namespace Swift {
- class HighlightAction;
- class SecurityLabel;
+ class HighlightAction;
+ class SecurityLabel;
- class QtChatView : public QWidget {
- Q_OBJECT
- public:
- QtChatView(QWidget* parent);
- virtual ~QtChatView();
+ class QtChatView : public QWidget {
+ Q_OBJECT
+ public:
+ QtChatView(QWidget* parent);
+ virtual ~QtChatView();
- /** Add message to window.
- * @return id of added message (for acks).
- */
- virtual std::string addMessage(const ChatWindow::ChatMessage& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) = 0;
- /** Adds action to window.
- * @return id of added message (for acks);
- */
- virtual std::string addAction(const ChatWindow::ChatMessage& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) = 0;
+ /** Add message to window.
+ * @return id of added message (for acks).
+ */
+ virtual std::string addMessage(const ChatWindow::ChatMessage& message, const std::string& senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) = 0;
+ /** Adds action to window.
+ * @return id of added message (for acks);
+ */
+ virtual std::string addAction(const ChatWindow::ChatMessage& message, const std::string& senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) = 0;
- virtual std::string addSystemMessage(const ChatWindow::ChatMessage& message, ChatWindow::Direction direction) = 0;
- virtual void addPresenceMessage(const ChatWindow::ChatMessage& message, ChatWindow::Direction direction) = 0;
+ virtual std::string addSystemMessage(const ChatWindow::ChatMessage& message, ChatWindow::Direction direction) = 0;
+ virtual void addPresenceMessage(const ChatWindow::ChatMessage& message, ChatWindow::Direction direction) = 0;
- virtual void addErrorMessage(const ChatWindow::ChatMessage& message) = 0;
- virtual void replaceMessage(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight) = 0;
- virtual void replaceSystemMessage(const ChatWindow::ChatMessage& message, const std::string& id, const ChatWindow::TimestampBehaviour /*timestampBehaviour*/) = 0;
- virtual void replaceWithAction(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight) = 0;
- virtual void replaceLastMessage(const ChatWindow::ChatMessage& message, const ChatWindow::TimestampBehaviour /*timestampBehaviour*/) = 0;
- virtual void setAckState(const std::string& id, ChatWindow::AckState state) = 0;
-
- virtual std::string addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes, const std::string& description) = 0;
- virtual void setFileTransferProgress(std::string, const int percentageDone) = 0;
- virtual void setFileTransferStatus(std::string, const ChatWindow::FileTransferState state, const std::string& msg = "") = 0;
- virtual void addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct, bool isImpromptu, bool isContinuation) = 0;
- virtual std::string addWhiteboardRequest(const QString& contact, bool senderIsSelf) = 0;
- virtual void setWhiteboardSessionStatus(const std::string& id, const ChatWindow::WhiteboardSessionState state) = 0;
- virtual void setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state) = 0;
+ virtual void addErrorMessage(const ChatWindow::ChatMessage& message) = 0;
+ virtual void replaceMessage(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time) = 0;
+ virtual void replaceSystemMessage(const ChatWindow::ChatMessage& message, const std::string& id, const ChatWindow::TimestampBehaviour /*timestampBehaviour*/) = 0;
+ virtual void replaceWithAction(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time) = 0;
+ virtual void replaceLastMessage(const ChatWindow::ChatMessage& message, const ChatWindow::TimestampBehaviour /*timestampBehaviour*/) = 0;
+ virtual void setAckState(const std::string& id, ChatWindow::AckState state) = 0;
- virtual void showEmoticons(bool show) = 0;
- virtual void addLastSeenLine() = 0;
+ virtual std::string addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes, const std::string& description) = 0;
+ virtual void setFileTransferProgress(std::string, const int percentageDone) = 0;
+ virtual void setFileTransferStatus(std::string, const ChatWindow::FileTransferState state, const std::string& msg = "") = 0;
+ virtual void addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct, bool isImpromptu, bool isContinuation) = 0;
+ virtual std::string addWhiteboardRequest(const QString& contact, bool senderIsSelf) = 0;
+ virtual void setWhiteboardSessionStatus(const std::string& id, const ChatWindow::WhiteboardSessionState state) = 0;
+ virtual void setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state) = 0;
- public slots:
- virtual void resizeFont(int fontSizeSteps) = 0;
- virtual void scrollToBottom() = 0;
- virtual void handleKeyPressEvent(QKeyEvent* event) = 0;
+ virtual void showEmoticons(bool show) = 0;
+ virtual void addLastSeenLine() = 0;
- };
+ public slots:
+ virtual void resizeFont(int fontSizeSteps) = 0;
+ virtual void scrollToBottom() = 0;
+ virtual void handleKeyPressEvent(QKeyEvent* event) = 0;
+
+ };
}
diff --git a/Swift/QtUI/QtChatWindow.cpp b/Swift/QtUI/QtChatWindow.cpp
index a9bc2b5..d799e19 100644
--- a/Swift/QtUI/QtChatWindow.cpp
+++ b/Swift/QtUI/QtChatWindow.cpp
@@ -6,9 +6,10 @@
#include <Swift/QtUI/QtChatWindow.h>
+#include <memory>
+
#include <boost/cstdint.hpp>
#include <boost/lexical_cast.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
#include <QApplication>
#include <QBoxLayout>
@@ -62,883 +63,886 @@
namespace Swift {
QtChatWindow::QtChatWindow(const QString& contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings, const std::map<std::string, std::string>& emoticons) : QtTabbable(), id_(Q2PSTRING(contact)), contact_(contact), nextAlertId_(0), eventStream_(eventStream), blockingState_(BlockingUnsupported), isMUC_(false), supportsImpromptuChat_(false), roomBookmarkState_(RoomNotBookmarked) {
- settings_ = settings;
- unreadCount_ = 0;
- isOnline_ = true;
- completer_ = NULL;
- affiliationEditor_ = NULL;
- theme_ = theme;
- isCorrection_ = false;
- labelModel_ = NULL;
- correctionEnabled_ = Maybe;
- fileTransferEnabled_ = Maybe;
- updateTitleWithUnreadCount();
- assert(settings);
- setAcceptDrops(true);
-
- alertStyleSheet_ = "background: rgb(255, 255, 153); color: black";
-
- QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, this);
- layout->setContentsMargins(0,0,0,0);
- layout->setSpacing(2);
-
- alertLayout_ = new QVBoxLayout();
- layout->addLayout(alertLayout_);
-
- subjectLayout_ = new QBoxLayout(QBoxLayout::LeftToRight);
- subject_ = new QLineEdit(this);
- subjectLayout_->addWidget(subject_);
- setSubject("");
- subject_->setReadOnly(true);
-
- QPushButton* actionButton_ = new QPushButton(this);
- actionButton_->setIcon(QIcon(":/icons/actions.png"));
- connect(actionButton_, SIGNAL(clicked()), this, SLOT(handleActionButtonClicked()));
- subject_->hide();
-
- layout->addLayout(subjectLayout_);
-
- logRosterSplitter_ = new QSplitter(this);
- logRosterSplitter_->setAutoFillBackground(true);
- layout->addWidget(logRosterSplitter_);
- if (settings_->getSetting(QtUISettingConstants::USE_PLAIN_CHATS) || settings_->getSetting(QtUISettingConstants::USE_SCREENREADER)) {
- messageLog_ = new QtPlainChatView(this, eventStream_);
- }
- else {
- messageLog_ = new QtWebKitChatView(this, eventStream_, theme, this); // I accept that passing the ChatWindow in so that the view can call the signals is somewhat inelegant, but it saves a lot of boilerplate. This patch is unpleasant enough already. So let's fix this soon (it at least needs fixing by the time history is sorted), but not now.
- }
- logRosterSplitter_->addWidget(messageLog_);
-
- treeWidget_ = new QtOccupantListWidget(eventStream_, settings_, QtTreeWidget::MessageDefaultJID, this);
- treeWidget_->hide();
- logRosterSplitter_->addWidget(treeWidget_);
- logRosterSplitter_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
- connect(logRosterSplitter_, SIGNAL(splitterMoved(int, int)), this, SLOT(handleSplitterMoved(int, int)));
-
- midBar_ = new QWidget(this);
- //layout->addWidget(midBar);
- midBar_->setAutoFillBackground(true);
- QHBoxLayout *midBarLayout = new QHBoxLayout(midBar_);
- midBarLayout->setContentsMargins(0,0,0,0);
- midBarLayout->setSpacing(2);
- //midBarLayout->addStretch();
-
- labelsWidget_ = new QComboBox(this);
- labelsWidget_->setFocusPolicy(Qt::NoFocus);
- labelsWidget_->hide();
- labelsWidget_->setSizeAdjustPolicy(QComboBox::AdjustToContents);
- midBarLayout->addWidget(labelsWidget_,0);
- connect(labelsWidget_, SIGNAL(currentIndexChanged(int)), this, SLOT(handleCurrentLabelChanged(int)));
- defaultLabelsPalette_ = labelsWidget_->palette();
-
- QHBoxLayout* inputBarLayout = new QHBoxLayout();
- inputBarLayout->setContentsMargins(0,0,0,0);
- inputBarLayout->setSpacing(2);
- input_ = new QtTextEdit(settings_, this);
- input_->setAcceptRichText(false);
- inputBarLayout->addWidget(midBar_);
- inputBarLayout->addWidget(input_);
- correctingLabel_ = new QLabel(tr("Correcting"), this);
- inputBarLayout->addWidget(correctingLabel_);
- correctingLabel_->hide();
-
- connect(input_, SIGNAL(receivedFocus()), this, SLOT(handleTextInputReceivedFocus()));
- connect(input_, SIGNAL(lostFocus()), this, SLOT(handleTextInputLostFocus()));
- QPushButton* emoticonsButton_ = new QPushButton(this);
- emoticonsButton_->setIcon(QIcon(":/emoticons/smile.png"));
- connect(emoticonsButton_, SIGNAL(clicked()), this, SLOT(handleEmoticonsButtonClicked()));
-
- emoticonsMenu_ = new QMenu(this);
- QtEmoticonsGrid* emoticonsGrid = new QtEmoticonsGrid(emoticons, emoticonsMenu_);
- connect(emoticonsGrid, SIGNAL(emoticonClicked(QString)), this, SLOT(handleEmoticonClicked(QString)));
-
- // using an extra layout to work around Qt margin glitches on OS X
- QHBoxLayout* actionLayout = new QHBoxLayout();
- actionLayout->addWidget(emoticonsButton_);
- actionLayout->addWidget(actionButton_);
-
- inputBarLayout->addLayout(actionLayout);
- layout->addLayout(inputBarLayout);
-
- inputClearing_ = false;
- contactIsTyping_ = false;
- tabCompletion_ = false;
-
- connect(input_, SIGNAL(unhandledKeyPressEvent(QKeyEvent*)), this, SLOT(handleKeyPressEvent(QKeyEvent*)));
- connect(input_, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
- connect(input_, SIGNAL(textChanged()), this, SLOT(handleInputChanged()));
- connect(input_, SIGNAL(cursorPositionChanged()), this, SLOT(handleCursorPositionChanged()));
- setFocusProxy(input_);
- logRosterSplitter_->setFocusProxy(input_);
- midBar_->setFocusProxy(input_);
- messageLog_->setFocusProxy(input_);
- connect(messageLog_, SIGNAL(gotFocus()), input_, SLOT(setFocus()));
- resize(400,300);
- connect(messageLog_, SIGNAL(fontResized(int)), this, SIGNAL(fontResized(int)));
- connect(messageLog_, SIGNAL(logCleared()), this, SLOT(handleLogCleared()));
-
- treeWidget_->onSomethingSelectedChanged.connect(boost::bind(&QtChatWindow::handleOccupantSelectionChanged, this, _1));
- treeWidget_->onOccupantActionSelected.connect(boost::bind(boost::ref(onOccupantActionSelected), _1, _2));
-
- settings_->onSettingChanged.connect(boost::bind(&QtChatWindow::handleSettingChanged, this, _1));
- messageLog_->showEmoticons(settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS));
- setMinimumSize(100, 100);
+ settings_ = settings;
+ unreadCount_ = 0;
+ isOnline_ = true;
+ completer_ = nullptr;
+ affiliationEditor_ = nullptr;
+ theme_ = theme;
+ isCorrection_ = false;
+ labelModel_ = nullptr;
+ correctionEnabled_ = Maybe;
+ fileTransferEnabled_ = Maybe;
+ updateTitleWithUnreadCount();
+ assert(settings);
+ setAcceptDrops(true);
+
+ alertStyleSheet_ = ".QWidget, QTextEdit { background: rgb(255, 255, 153); color: black }";
+
+ QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, this);
+ layout->setContentsMargins(0,0,0,0);
+ layout->setSpacing(2);
+
+ alertLayout_ = new QVBoxLayout();
+ layout->addLayout(alertLayout_);
+
+ subjectLayout_ = new QBoxLayout(QBoxLayout::LeftToRight);
+ subject_ = new QLineEdit(this);
+ subjectLayout_->addWidget(subject_);
+ setSubject("");
+ subject_->setReadOnly(true);
+
+ QPushButton* actionButton_ = new QPushButton(this);
+ actionButton_->setIcon(QIcon(":/icons/actions.png"));
+ connect(actionButton_, SIGNAL(clicked()), this, SLOT(handleActionButtonClicked()));
+ subject_->hide();
+
+ layout->addLayout(subjectLayout_);
+
+ logRosterSplitter_ = new QSplitter(this);
+ logRosterSplitter_->setAutoFillBackground(true);
+ layout->addWidget(logRosterSplitter_);
+ if (settings_->getSetting(QtUISettingConstants::USE_PLAIN_CHATS) || settings_->getSetting(QtUISettingConstants::USE_SCREENREADER)) {
+ messageLog_ = new QtPlainChatView(this, eventStream_);
+ }
+ else {
+ messageLog_ = new QtWebKitChatView(this, eventStream_, theme, this); // I accept that passing the ChatWindow in so that the view can call the signals is somewhat inelegant, but it saves a lot of boilerplate. This patch is unpleasant enough already. So let's fix this soon (it at least needs fixing by the time history is sorted), but not now.
+ }
+ logRosterSplitter_->addWidget(messageLog_);
+
+ treeWidget_ = new QtOccupantListWidget(eventStream_, settings_, QtTreeWidget::MessageDefaultJID, this);
+ treeWidget_->hide();
+ logRosterSplitter_->addWidget(treeWidget_);
+ logRosterSplitter_->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ connect(logRosterSplitter_, SIGNAL(splitterMoved(int, int)), this, SLOT(handleSplitterMoved(int, int)));
+
+ midBar_ = new QWidget(this);
+ //layout->addWidget(midBar);
+ midBar_->setAutoFillBackground(true);
+ QHBoxLayout *midBarLayout = new QHBoxLayout(midBar_);
+ midBarLayout->setContentsMargins(0,0,0,0);
+ midBarLayout->setSpacing(2);
+ //midBarLayout->addStretch();
+
+ labelsWidget_ = new QComboBox(this);
+ labelsWidget_->setFocusPolicy(Qt::NoFocus);
+ labelsWidget_->hide();
+ labelsWidget_->setSizeAdjustPolicy(QComboBox::AdjustToContents);
+ midBarLayout->addWidget(labelsWidget_,0);
+ connect(labelsWidget_, SIGNAL(currentIndexChanged(int)), this, SLOT(handleCurrentLabelChanged(int)));
+ defaultLabelsPalette_ = labelsWidget_->palette();
+
+ QHBoxLayout* inputBarLayout = new QHBoxLayout();
+ inputBarLayout->setContentsMargins(0,0,0,0);
+ inputBarLayout->setSpacing(2);
+ input_ = new QtTextEdit(settings_, this);
+ input_->setAcceptRichText(false);
+ inputBarLayout->addWidget(midBar_);
+ inputBarLayout->addWidget(input_);
+ correctingLabel_ = new QLabel(tr("Correcting"), this);
+ inputBarLayout->addWidget(correctingLabel_);
+ correctingLabel_->hide();
+
+ connect(input_, SIGNAL(receivedFocus()), this, SLOT(handleTextInputReceivedFocus()));
+ connect(input_, SIGNAL(lostFocus()), this, SLOT(handleTextInputLostFocus()));
+ QPushButton* emoticonsButton_ = new QPushButton(this);
+ emoticonsButton_->setIcon(QIcon(":/emoticons/smile.png"));
+ connect(emoticonsButton_, SIGNAL(clicked()), this, SLOT(handleEmoticonsButtonClicked()));
+
+ emoticonsMenu_ = new QMenu(this);
+ QtEmoticonsGrid* emoticonsGrid = new QtEmoticonsGrid(emoticons, emoticonsMenu_);
+ connect(emoticonsGrid, SIGNAL(emoticonClicked(QString)), this, SLOT(handleEmoticonClicked(QString)));
+
+ // using an extra layout to work around Qt margin glitches on OS X
+ QHBoxLayout* actionLayout = new QHBoxLayout();
+ actionLayout->addWidget(emoticonsButton_);
+ actionLayout->addWidget(actionButton_);
+
+ inputBarLayout->addLayout(actionLayout);
+ layout->addLayout(inputBarLayout);
+
+ inputClearing_ = false;
+ contactIsTyping_ = false;
+ tabCompletion_ = false;
+
+ connect(input_, SIGNAL(unhandledKeyPressEvent(QKeyEvent*)), this, SLOT(handleKeyPressEvent(QKeyEvent*)));
+ connect(input_, SIGNAL(returnPressed()), this, SLOT(returnPressed()));
+ connect(input_, SIGNAL(textChanged()), this, SLOT(handleInputChanged()));
+ connect(input_, SIGNAL(cursorPositionChanged()), this, SLOT(handleCursorPositionChanged()));
+ setFocusProxy(input_);
+ logRosterSplitter_->setFocusProxy(input_);
+ midBar_->setFocusProxy(input_);
+ messageLog_->setFocusProxy(input_);
+ connect(messageLog_, SIGNAL(gotFocus()), input_, SLOT(setFocus()));
+ resize(400,300);
+ connect(messageLog_, SIGNAL(fontResized(int)), this, SIGNAL(fontResized(int)));
+ connect(messageLog_, SIGNAL(logCleared()), this, SLOT(handleLogCleared()));
+
+ treeWidget_->onSomethingSelectedChanged.connect(boost::bind(&QtChatWindow::handleOccupantSelectionChanged, this, _1));
+ treeWidget_->onOccupantActionSelected.connect(boost::bind(boost::ref(onOccupantActionSelected), _1, _2));
+
+ settings_->onSettingChanged.connect(boost::bind(&QtChatWindow::handleSettingChanged, this, _1));
+ messageLog_->showEmoticons(settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS));
+ setMinimumSize(100, 100);
}
QtChatWindow::~QtChatWindow() {
- settings_->onSettingChanged.disconnect(boost::bind(&QtChatWindow::handleSettingChanged, this, _1));
- if (mucConfigurationWindow_) {
- delete mucConfigurationWindow_.data();
- }
+ settings_->onSettingChanged.disconnect(boost::bind(&QtChatWindow::handleSettingChanged, this, _1));
+ if (mucConfigurationWindow_) {
+ delete mucConfigurationWindow_.data();
+ }
}
void QtChatWindow::handleSettingChanged(const std::string& setting) {
- if (setting == QtUISettingConstants::SHOW_EMOTICONS.getKey()) {
- bool showEmoticons = settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS);
- messageLog_->showEmoticons(showEmoticons);
- }
+ if (setting == QtUISettingConstants::SHOW_EMOTICONS.getKey()) {
+ bool showEmoticons = settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS);
+ messageLog_->showEmoticons(showEmoticons);
+ }
}
void QtChatWindow::handleLogCleared() {
- onLogCleared();
+ onLogCleared();
}
void QtChatWindow::handleOccupantSelectionChanged(RosterItem* item) {
- onOccupantSelectionChanged(dynamic_cast<ContactRosterItem*>(item));
+ onOccupantSelectionChanged(dynamic_cast<ContactRosterItem*>(item));
}
void QtChatWindow::handleFontResized(int fontSizeSteps) {
- messageLog_->resizeFont(fontSizeSteps);
+ messageLog_->resizeFont(fontSizeSteps);
}
void QtChatWindow::handleAlertButtonClicked() {
- const QObject* alertWidget = QObject::sender()->parent();
- std::map<AlertID, QWidget*>::const_iterator i = alertWidgets_.begin();
- for ( ; i != alertWidgets_.end(); ++i) {
- if (i->second == alertWidget) {
- removeAlert(i->first);
- break;
- }
- }
+ const QObject* alertWidget = QObject::sender()->parent();
+ std::map<AlertID, QWidget*>::const_iterator i = alertWidgets_.begin();
+ for ( ; i != alertWidgets_.end(); ++i) {
+ if (i->second == alertWidget) {
+ removeAlert(i->first);
+ break;
+ }
+ }
}
QtChatWindow::AlertID QtChatWindow::addAlert(const std::string& alertText) {
- QWidget* alertWidget = new QWidget(this);
- QHBoxLayout* alertLayout = new QHBoxLayout(alertWidget);
- alertLayout_->addWidget(alertWidget);
- QLabel* alertLabel = new QLabel(this);
- alertLabel->setText(alertText.c_str());
- alertLayout->addWidget(alertLabel);
-
- QToolButton* closeButton = new QToolButton(alertWidget);
- closeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton));
- closeButton->setIconSize(QSize(16,16));
- closeButton->setCursor(Qt::ArrowCursor);
- closeButton->setStyleSheet("QToolButton { border: none; padding: 0px; }");
- connect (closeButton, SIGNAL(clicked()), this, SLOT(handleAlertButtonClicked()));
-
- alertLayout->addWidget(closeButton);
- QPalette palette = alertWidget->palette();
- palette.setColor(QPalette::Window, QColor(Qt::yellow));
- palette.setColor(QPalette::WindowText, QColor(Qt::black));
- alertWidget->setStyleSheet(alertStyleSheet_);
- alertLabel->setStyleSheet(alertStyleSheet_);
-
- AlertID id = nextAlertId_++;
- alertWidgets_[id] = alertWidget;
- return id;
+ QWidget* alertWidget = new QWidget(this);
+ QHBoxLayout* alertLayout = new QHBoxLayout(alertWidget);
+ alertLayout_->addWidget(alertWidget);
+ QLabel* alertLabel = new QLabel(this);
+ alertLabel->setText(alertText.c_str());
+ alertLayout->addWidget(alertLabel);
+
+ QToolButton* closeButton = new QToolButton(alertWidget);
+ closeButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton));
+ closeButton->setIconSize(QSize(16,16));
+ closeButton->setCursor(Qt::ArrowCursor);
+ closeButton->setStyleSheet("QToolButton { border: none; padding: 0px; }");
+ connect (closeButton, SIGNAL(clicked()), this, SLOT(handleAlertButtonClicked()));
+
+ alertLayout->addWidget(closeButton);
+ QPalette palette = alertWidget->palette();
+ palette.setColor(QPalette::Window, QColor(Qt::yellow));
+ palette.setColor(QPalette::WindowText, QColor(Qt::black));
+ alertWidget->setStyleSheet(alertStyleSheet_);
+ alertLabel->setStyleSheet(alertStyleSheet_);
+
+ AlertID id = nextAlertId_++;
+ alertWidgets_[id] = alertWidget;
+ return id;
}
void QtChatWindow::removeAlert(const AlertID id) {
- std::map<AlertID, QWidget*>::iterator i = alertWidgets_.find(id);
- if (i != alertWidgets_.end()) {
- alertLayout_->removeWidget(i->second);
- delete i->second;
- alertWidgets_.erase(i);
- }
+ std::map<AlertID, QWidget*>::iterator i = alertWidgets_.find(id);
+ if (i != alertWidgets_.end()) {
+ alertLayout_->removeWidget(i->second);
+ delete i->second;
+ alertWidgets_.erase(i);
+ }
}
void QtChatWindow::setTabComplete(TabComplete* completer) {
- completer_ = completer;
+ completer_ = completer;
}
void QtChatWindow::handleKeyPressEvent(QKeyEvent* event) {
- event->ignore();
- if (event->isAccepted()) {
- return;
- }
- event->accept();
-
- int key = event->key();
- if (key == Qt::Key_Tab) {
- tabComplete();
- }
- else if ((key == Qt::Key_Up) && input_->toPlainText().isEmpty() && !(lastSentMessage_.isEmpty())) {
- beginCorrection();
- }
- else if (key == Qt::Key_Down && isCorrection_ && input_->textCursor().atBlockEnd()) {
- cancelCorrection();
- }
- else if (key == Qt::Key_Down || key == Qt::Key_Up) {
- event->ignore();
- }
- else {
- messageLog_->handleKeyPressEvent(event);
- }
+ event->ignore();
+ if (event->isAccepted()) {
+ return;
+ }
+ event->accept();
+
+ int key = event->key();
+ if (key == Qt::Key_Tab) {
+ tabComplete();
+ }
+ else if ((key == Qt::Key_Up) && input_->toPlainText().isEmpty() && !(lastSentMessage_.isEmpty())) {
+ beginCorrection();
+ }
+ else if (key == Qt::Key_Down && isCorrection_ && input_->textCursor().atBlockEnd()) {
+ cancelCorrection();
+ }
+ else if (key == Qt::Key_Down || key == Qt::Key_Up) {
+ event->ignore();
+ }
+ else {
+ messageLog_->handleKeyPressEvent(event);
+ }
}
void QtChatWindow::beginCorrection() {
- boost::optional<AlertID> newCorrectingAlert;
- if (correctionEnabled_ == Maybe) {
- newCorrectingAlert = addAlert(Q2PSTRING(tr("This chat may not support message correction. If you send a correction anyway, it may appear as a duplicate message")));
- }
- else if (correctionEnabled_ == No) {
- newCorrectingAlert = addAlert(Q2PSTRING(tr("This chat does not support message correction. If you send a correction anyway, it will appear as a duplicate message")));
- }
-
- if (newCorrectingAlert) {
- if (correctingAlert_) {
- removeAlert(*correctingAlert_);
- }
- correctingAlert_ = newCorrectingAlert;
- }
-
- QTextCursor cursor = input_->textCursor();
- cursor.select(QTextCursor::Document);
- cursor.beginEditBlock();
- cursor.insertText(QString(lastSentMessage_));
- cursor.endEditBlock();
- isCorrection_ = true;
- correctingLabel_->show();
- input_->setStyleSheet(alertStyleSheet_);
- labelsWidget_->setEnabled(false);
+ boost::optional<AlertID> newCorrectingAlert;
+ if (correctionEnabled_ == Maybe) {
+ newCorrectingAlert = addAlert(Q2PSTRING(tr("This chat may not support message correction. If you send a correction anyway, it may appear as a duplicate message")));
+ }
+ else if (correctionEnabled_ == No) {
+ newCorrectingAlert = addAlert(Q2PSTRING(tr("This chat does not support message correction. If you send a correction anyway, it will appear as a duplicate message")));
+ }
+
+ if (newCorrectingAlert) {
+ if (correctingAlert_) {
+ removeAlert(*correctingAlert_);
+ }
+ correctingAlert_ = newCorrectingAlert;
+ }
+
+ QTextCursor cursor = input_->textCursor();
+ cursor.select(QTextCursor::Document);
+ cursor.beginEditBlock();
+ cursor.insertText(QString(lastSentMessage_));
+ cursor.endEditBlock();
+ isCorrection_ = true;
+ correctingLabel_->show();
+ input_->setCorrectionHighlight(true);
+ labelsWidget_->setEnabled(false);
}
void QtChatWindow::cancelCorrection() {
- if (correctingAlert_) {
- removeAlert(*correctingAlert_);
- correctingAlert_.reset();
- }
- QTextCursor cursor = input_->textCursor();
- cursor.select(QTextCursor::Document);
- cursor.removeSelectedText();
- isCorrection_ = false;
- correctingLabel_->hide();
- input_->setStyleSheet(qApp->styleSheet());
- labelsWidget_->setEnabled(true);
+ if (correctingAlert_) {
+ removeAlert(*correctingAlert_);
+ correctingAlert_.reset();
+ }
+ QTextCursor cursor = input_->textCursor();
+ cursor.select(QTextCursor::Document);
+ cursor.removeSelectedText();
+ isCorrection_ = false;
+ correctingLabel_->hide();
+ input_->setCorrectionHighlight(false);
+ labelsWidget_->setEnabled(true);
}
QByteArray QtChatWindow::getSplitterState() {
- return logRosterSplitter_->saveState();
+ return logRosterSplitter_->saveState();
}
void QtChatWindow::handleChangeSplitterState(QByteArray state) {
- logRosterSplitter_->restoreState(state);
+ logRosterSplitter_->restoreState(state);
}
void QtChatWindow::handleSplitterMoved(int, int) {
- emit splitterMoved();
+ emit splitterMoved();
}
void QtChatWindow::tabComplete() {
- if (!completer_) {
- return;
- }
-
- QTextCursor cursor;
- if (tabCompleteCursor_.hasSelection()) {
- cursor = tabCompleteCursor_;
- }
- else {
- cursor = input_->textCursor();
- while(cursor.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor) && cursor.document()->characterAt(cursor.position() - 1) != ' ') { }
- }
- QString root = cursor.selectedText();
- if (root.isEmpty()) {
- return;
- }
- QString suggestion = P2QSTRING(completer_->completeWord(Q2PSTRING(root)));
- if (root == suggestion) {
- return;
- }
- tabCompletion_ = true;
- cursor.beginEditBlock();
- cursor.removeSelectedText();
- int oldPosition = cursor.position();
-
- cursor.insertText(suggestion);
- tabCompleteCursor_ = cursor;
- tabCompleteCursor_.setPosition(oldPosition, QTextCursor::KeepAnchor);
-
- cursor.endEditBlock();
- tabCompletion_ = false;
+ if (!completer_) {
+ return;
+ }
+
+ QTextCursor cursor;
+ if (tabCompleteCursor_.hasSelection()) {
+ cursor = tabCompleteCursor_;
+ }
+ else {
+ cursor = input_->textCursor();
+ while(cursor.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor) && cursor.document()->characterAt(cursor.position() - 1) != ' ') { }
+ }
+ QString root = cursor.selectedText();
+ if (root.isEmpty()) {
+ return;
+ }
+ QString suggestion = P2QSTRING(completer_->completeWord(Q2PSTRING(root)));
+ if (root == suggestion) {
+ return;
+ }
+ tabCompletion_ = true;
+ cursor.beginEditBlock();
+ cursor.removeSelectedText();
+ int oldPosition = cursor.position();
+
+ cursor.insertText(suggestion);
+ tabCompleteCursor_ = cursor;
+ tabCompleteCursor_.setPosition(oldPosition, QTextCursor::KeepAnchor);
+
+ cursor.endEditBlock();
+ tabCompletion_ = false;
}
void QtChatWindow::setRosterModel(Roster* roster) {
- treeWidget_->setRosterModel(roster);
+ treeWidget_->setRosterModel(roster);
}
void QtChatWindow::setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels) {
- delete labelModel_;
- labelModel_ = new LabelModel();
- labelModel_->availableLabels_ = labels;
- int i = 0;
- int defaultIndex = 0;
- labelsWidget_->setModel(labelModel_);
- foreach (SecurityLabelsCatalog::Item label, labels) {
- if (label.getIsDefault()) {
- defaultIndex = i;
- break;
- }
- i++;
- }
- labelsWidget_->setCurrentIndex(defaultIndex);
+ delete labelModel_;
+ labelModel_ = new LabelModel();
+ labelModel_->availableLabels_ = labels;
+ int i = 0;
+ int defaultIndex = 0;
+ labelsWidget_->setModel(labelModel_);
+ for (const auto& label : labels) {
+ if (label.getIsDefault()) {
+ defaultIndex = i;
+ break;
+ }
+ i++;
+ }
+ labelsWidget_->setCurrentIndex(defaultIndex);
}
void QtChatWindow::handleCurrentLabelChanged(int index) {
- if (static_cast<size_t>(index) >= labelModel_->availableLabels_.size()) {
- SWIFT_LOG(debug) << "User selected a label that doesn't exist";
- return;
- }
- const SecurityLabelsCatalog::Item& label = labelModel_->availableLabels_[index];
- if (label.getLabel()) {
- QPalette palette = labelsWidget_->palette();
- //palette.setColor(QPalette::Base, P2QSTRING(label.getLabel()->getBackgroundColor()));
- palette.setColor(labelsWidget_->backgroundRole(), P2QSTRING(label.getLabel()->getBackgroundColor()));
- palette.setColor(labelsWidget_->foregroundRole(), P2QSTRING(label.getLabel()->getForegroundColor()));
- labelsWidget_->setPalette(palette);
- midBar_->setPalette(palette);
- labelsWidget_->setAutoFillBackground(true);
- }
- else {
- labelsWidget_->setAutoFillBackground(false);
- labelsWidget_->setPalette(defaultLabelsPalette_);
- midBar_->setPalette(defaultLabelsPalette_);
- }
+ if (static_cast<size_t>(index) >= labelModel_->availableLabels_.size()) {
+ SWIFT_LOG(debug) << "User selected a label that doesn't exist";
+ return;
+ }
+ const SecurityLabelsCatalog::Item& label = labelModel_->availableLabels_[index];
+ if (label.getLabel()) {
+ QPalette palette = labelsWidget_->palette();
+ //palette.setColor(QPalette::Base, P2QSTRING(label.getLabel()->getBackgroundColor()));
+ palette.setColor(labelsWidget_->backgroundRole(), P2QSTRING(label.getLabel()->getBackgroundColor()));
+ palette.setColor(labelsWidget_->foregroundRole(), P2QSTRING(label.getLabel()->getForegroundColor()));
+ labelsWidget_->setPalette(palette);
+ midBar_->setPalette(palette);
+ labelsWidget_->setAutoFillBackground(true);
+ }
+ else {
+ labelsWidget_->setAutoFillBackground(false);
+ labelsWidget_->setPalette(defaultLabelsPalette_);
+ midBar_->setPalette(defaultLabelsPalette_);
+ }
}
void QtChatWindow::setSecurityLabelsError() {
- labelsWidget_->setEnabled(false);
+ labelsWidget_->setEnabled(false);
}
void QtChatWindow::setSecurityLabelsEnabled(bool enabled) {
- if (enabled) {
- labelsWidget_->setEnabled(true);
- labelsWidget_->show();
- }
- else {
- labelsWidget_->hide();
- }
+ if (enabled) {
+ labelsWidget_->setEnabled(true);
+ labelsWidget_->show();
+ }
+ else {
+ labelsWidget_->hide();
+ }
}
void QtChatWindow::setCorrectionEnabled(Tristate enabled) {
- correctionEnabled_ = enabled;
+ correctionEnabled_ = enabled;
}
void QtChatWindow::setFileTransferEnabled(Tristate enabled) {
- fileTransferEnabled_ = enabled;
+ fileTransferEnabled_ = enabled;
}
SecurityLabelsCatalog::Item QtChatWindow::getSelectedSecurityLabel() {
- assert(labelsWidget_->isEnabled());
- assert(labelsWidget_->currentIndex() >= 0 && static_cast<size_t>(labelsWidget_->currentIndex()) < labelModel_->availableLabels_.size());
- return labelModel_->availableLabels_[labelsWidget_->currentIndex()];
+ assert(labelsWidget_->isEnabled());
+ assert(labelsWidget_->currentIndex() >= 0 && static_cast<size_t>(labelsWidget_->currentIndex()) < labelModel_->availableLabels_.size());
+ return labelModel_->availableLabels_[labelsWidget_->currentIndex()];
}
void QtChatWindow::closeEvent(QCloseEvent* event) {
- event->accept();
- emit windowClosing();
- onClosed();
+ event->accept();
+ emit windowClosing();
+ onClosed();
}
void QtChatWindow::convertToMUC(MUCType mucType) {
- impromptu_ = (mucType == ImpromptuMUC);
- treeWidget_->setMessageTarget(impromptu_ ? QtTreeWidget::MessageDisplayJID : QtTreeWidget::MessageDefaultJID);
- isMUC_ = true;
- treeWidget_->show();
- subject_->setVisible(!impromptu_);
+ impromptu_ = (mucType == ImpromptuMUC);
+ treeWidget_->setMessageTarget(impromptu_ ? QtTreeWidget::MessageDisplayJID : QtTreeWidget::MessageDefaultJID);
+ isMUC_ = true;
+ treeWidget_->show();
+ subject_->setVisible(!impromptu_);
}
void QtChatWindow::setOnline(bool online) {
- isOnline_ = online;
- if (!online) {
- if (mucConfigurationWindow_) {
- delete mucConfigurationWindow_.data();
- }
- if (affiliationEditor_) {
- delete affiliationEditor_.data();
- }
- }
+ isOnline_ = online;
+ if (!online) {
+ if (mucConfigurationWindow_) {
+ delete mucConfigurationWindow_.data();
+ }
+ if (affiliationEditor_) {
+ delete affiliationEditor_.data();
+ }
+ }
}
void QtChatWindow::showEvent(QShowEvent* event) {
- emit windowOpening();
- QWidget::showEvent(event);
+ emit windowOpening();
+ QWidget::showEvent(event);
}
void QtChatWindow::setUnreadMessageCount(int count) {
- if (unreadCount_ != count) {
- unreadCount_ = count;
- updateTitleWithUnreadCount();
- emit countUpdated();
- }
+ if (unreadCount_ != count) {
+ unreadCount_ = count;
+ updateTitleWithUnreadCount();
+ emit countUpdated();
+ }
}
void QtChatWindow::setContactChatState(ChatState::ChatStateType state) {
- contactIsTyping_ = (state == ChatState::Composing);
- emit titleUpdated();
+ contactIsTyping_ = (state == ChatState::Composing);
+ emit titleUpdated();
}
QtTabbable::AlertType QtChatWindow::getWidgetAlertState() {
- if (contactIsTyping_) {
- return ImpendingActivity;
- }
- if (unreadCount_ > 0) {
- return WaitingActivity;
- }
- return NoActivity;
+ if (contactIsTyping_) {
+ return ImpendingActivity;
+ }
+ if (unreadCount_ > 0) {
+ return WaitingActivity;
+ }
+ return NoActivity;
}
void QtChatWindow::setName(const std::string& name) {
- contact_ = P2QSTRING(name);
- updateTitleWithUnreadCount();
+ contact_ = P2QSTRING(name);
+ updateTitleWithUnreadCount();
}
void QtChatWindow::updateTitleWithUnreadCount() {
- if (isWindow()) {
- setWindowTitle(unreadCount_ > 0 ? QString("(%1) %2").arg(unreadCount_).arg(contact_) : contact_);
- }
- else {
- setWindowTitle(contact_);
- }
- emit titleUpdated();
+ if (isWindow()) {
+ setWindowTitle(unreadCount_ > 0 ? QString("(%1) %2").arg(unreadCount_).arg(contact_) : contact_);
+ }
+ else {
+ setWindowTitle(contact_);
+ }
+ emit titleUpdated();
}
void QtChatWindow::flash() {
- emit requestFlash();
+ emit requestFlash();
}
int QtChatWindow::getCount() {
- return unreadCount_;
+ return unreadCount_;
}
void QtChatWindow::replaceSystemMessage(const ChatWindow::ChatMessage& message, const std::string& id, const ChatWindow::TimestampBehaviour timestampBehaviour) {
- messageLog_->replaceSystemMessage(message, id, timestampBehaviour);
+ messageLog_->replaceSystemMessage(message, id, timestampBehaviour);
}
void QtChatWindow::returnPressed() {
- if (!isOnline_ || (blockingState_ == IsBlocked)) {
- return;
- }
- messageLog_->scrollToBottom();
- lastSentMessage_ = QString(input_->toPlainText());
- onSendMessageRequest(Q2PSTRING(input_->toPlainText()), isCorrection_);
- inputClearing_ = true;
- input_->clear();
- cancelCorrection();
- inputClearing_ = false;
+ if (!isOnline_ || (blockingState_ == IsBlocked)) {
+ return;
+ }
+ messageLog_->scrollToBottom();
+ lastSentMessage_ = QString(input_->toPlainText());
+ onSendMessageRequest(Q2PSTRING(input_->toPlainText()), isCorrection_);
+ inputClearing_ = true;
+ input_->clear();
+ cancelCorrection();
+ inputClearing_ = false;
}
void QtChatWindow::handleInputChanged() {
- if (inputClearing_) {
- return;
- }
- if (input_->toPlainText().isEmpty()) {
- onUserCancelsTyping();
- }
- else {
- onUserTyping();
- }
+ if (inputClearing_) {
+ return;
+ }
+ if (input_->toPlainText().isEmpty()) {
+ onUserCancelsTyping();
+ }
+ else {
+ onUserTyping();
+ }
}
void QtChatWindow::handleCursorPositionChanged() {
- if (tabCompletion_) {
- return;
- }
- tabCompleteCursor_.clearSelection();
+ if (tabCompletion_) {
+ return;
+ }
+ tabCompleteCursor_.clearSelection();
}
void QtChatWindow::show() {
- if (parentWidget() == NULL) {
- QWidget::show();
- }
- emit windowOpening();
+ if (parentWidget() == nullptr) {
+ QWidget::show();
+ }
+ emit windowOpening();
}
bool QtChatWindow::isVisible() const {
- return QWidget::isVisible();
+ return QWidget::isVisible();
}
void QtChatWindow::activate() {
- if (isWindow()) {
- QWidget::show();
- }
- emit wantsToActivate();
- input_->setFocus();
+ if (isWindow()) {
+ QWidget::show();
+ }
+ emit wantsToActivate();
+ input_->setFocus();
}
void QtChatWindow::resizeEvent(QResizeEvent*) {
- emit geometryChanged();
+ emit geometryChanged();
}
void QtChatWindow::moveEvent(QMoveEvent*) {
- emit geometryChanged();
+ emit geometryChanged();
}
void QtChatWindow::dragEnterEvent(QDragEnterEvent *event) {
- if (isOnline_ && (blockingState_ != IsBlocked)) {
- if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) {
- if (!isMUC_ && fileTransferEnabled_ == Yes) {
- event->acceptProposedAction();
- }
- }
- else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")) {
- if (isMUC_ || supportsImpromptuChat_) {
- // Prevent invitations or impromptu initializations for contacts that you are already chatting to.
- std::vector<JID> droppedJIDs =jidListFromQByteArray(event->mimeData()->data("application/vnd.swift.contact-jid-list"));
- std::set<JID> conversationJIDs;
- if (isMUC_) {
- conversationJIDs = treeWidget_->getRoster()->getJIDs();
- }
-
- for (std::vector<JID>::iterator i = droppedJIDs.begin(); i != droppedJIDs.end(); ) {
- const JID& droppedJID = *i;
- if (conversationJIDs.find(droppedJID) != conversationJIDs.end()) {
- i = droppedJIDs.erase(i);
- }
- else {
- ++i;
- }
- }
-
- if (droppedJIDs.empty()) {
- event->ignore();
- }
- else {
- event->acceptProposedAction();
- }
- }
- }
- }
+ if (isOnline_ && (blockingState_ != IsBlocked)) {
+ if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) {
+ if (!isMUC_ && fileTransferEnabled_ == Yes) {
+ event->acceptProposedAction();
+ }
+ }
+ else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")) {
+ if (isMUC_ || supportsImpromptuChat_) {
+ // Prevent invitations or impromptu initializations for contacts that you are already chatting to.
+ std::vector<JID> droppedJIDs =jidListFromQByteArray(event->mimeData()->data("application/vnd.swift.contact-jid-list"));
+ std::set<JID> conversationJIDs;
+ if (isMUC_) {
+ conversationJIDs = treeWidget_->getRoster()->getJIDs();
+ }
+
+ for (std::vector<JID>::iterator i = droppedJIDs.begin(); i != droppedJIDs.end(); ) {
+ const JID& droppedJID = *i;
+ if (conversationJIDs.find(droppedJID) != conversationJIDs.end()) {
+ i = droppedJIDs.erase(i);
+ }
+ else {
+ ++i;
+ }
+ }
+
+ if (droppedJIDs.empty()) {
+ event->ignore();
+ }
+ else {
+ event->acceptProposedAction();
+ }
+ }
+ }
+ }
}
void QtChatWindow::dropEvent(QDropEvent *event) {
- if (fileTransferEnabled_ == Yes && event->mimeData()->hasUrls()) {
- if (event->mimeData()->urls().size() == 1) {
- onSendFileRequest(Q2PSTRING(event->mimeData()->urls().at(0).toLocalFile()));
- }
- else {
- std::string messageText(Q2PSTRING(tr("Sending of multiple files at once isn't supported at this time.")));
- ChatMessage message;
- message.append(boost::make_shared<ChatTextMessagePart>(messageText));
- addSystemMessage(message, DefaultDirection);
- }
- }
- else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")) {
- std::vector<JID> invites = jidListFromQByteArray(event->mimeData()->data("application/vnd.swift.contact-jid-list"));
- onInviteToChat(invites);
- }
+ if (fileTransferEnabled_ == Yes && event->mimeData()->hasUrls()) {
+ if (event->mimeData()->urls().size() == 1) {
+ onSendFileRequest(Q2PSTRING(event->mimeData()->urls().at(0).toLocalFile()));
+ }
+ else {
+ std::string messageText(Q2PSTRING(tr("Sending of multiple files at once isn't supported at this time.")));
+ ChatMessage message;
+ message.append(std::make_shared<ChatTextMessagePart>(messageText));
+ addSystemMessage(message, DefaultDirection);
+ }
+ }
+ else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")) {
+ std::vector<JID> invites = jidListFromQByteArray(event->mimeData()->data("application/vnd.swift.contact-jid-list"));
+ onInviteToChat(invites);
+ }
}
std::vector<JID> QtChatWindow::jidListFromQByteArray(const QByteArray& dataBytes) {
- QDataStream dataStream(dataBytes);
- std::vector<JID> invites;
- while (!dataStream.atEnd()) {
- QString jidString;
- dataStream >> jidString;
- invites.push_back(Q2PSTRING(jidString));
- }
- return invites;
+ QDataStream dataStream(dataBytes);
+ std::vector<JID> invites;
+ while (!dataStream.atEnd()) {
+ QString jidString;
+ dataStream >> jidString;
+ invites.push_back(Q2PSTRING(jidString));
+ }
+ return invites;
}
void QtChatWindow::setAvailableOccupantActions(const std::vector<OccupantAction>& actions) {
- treeWidget_->setAvailableOccupantActions(actions);
+ treeWidget_->setAvailableOccupantActions(actions);
}
void QtChatWindow::setSubject(const std::string& subject) {
- //subject_->setVisible(!subject.empty());
- subject_->setText(P2QSTRING(subject));
- subject_->setToolTip(P2QSTRING(subject));
- subject_->setCursorPosition(0);
+ //subject_->setVisible(!subject.empty());
+ subject_->setText(P2QSTRING(subject));
+ subject_->setToolTip(P2QSTRING(subject));
+ subject_->setCursorPosition(0);
}
void QtChatWindow::handleEmoticonsButtonClicked() {
- emoticonsMenu_->adjustSize();
- QSize menuSize = emoticonsMenu_->size();
- emoticonsMenu_->exec(QPoint(QCursor::pos().x() - menuSize.width(), QCursor::pos().y() - menuSize.height()));
+ emoticonsMenu_->adjustSize();
+ QSize menuSize = emoticonsMenu_->size();
+ emoticonsMenu_->exec(QPoint(QCursor::pos().x() - menuSize.width(), QCursor::pos().y() - menuSize.height()));
}
void QtChatWindow::handleEmoticonClicked(QString emoticonAsText) {
- input_->textCursor().insertText(emoticonAsText);
- input_->setFocus();
+ input_->textCursor().insertText(emoticonAsText);
+ input_->setFocus();
}
void QtChatWindow::handleTextInputReceivedFocus() {
- lastLineTracker_.setHasFocus(true);
- input_->setFocus();
- onAllMessagesRead();
+ lastLineTracker_.setHasFocus(true);
+ input_->setFocus();
+ onAllMessagesRead();
}
void QtChatWindow::handleTextInputLostFocus() {
- lastLineTracker_.setHasFocus(false);
+ lastLineTracker_.setHasFocus(false);
}
void QtChatWindow::handleActionButtonClicked() {
- QMenu contextMenu;
- QAction* changeSubject = NULL;
- QAction* configure = NULL;
- QAction* affiliations = NULL;
- QAction* destroy = NULL;
- QAction* invite = NULL;
-
- QAction* block = NULL;
- QAction* unblock = NULL;
-
- if (availableRoomActions_.empty()) {
- if (blockingState_ == IsBlocked) {
- unblock = contextMenu.addAction(tr("Unblock"));
- unblock->setEnabled(isOnline_);
- }
- else if (!isMUC_ && blockingState_ == IsUnblocked) {
- block = contextMenu.addAction(tr("Block"));
- block->setEnabled(isOnline_);
- }
-
- if (supportsImpromptuChat_) {
- invite = contextMenu.addAction(tr("Invite person to this chat…"));
- invite->setEnabled(isOnline_ && (blockingState_ != IsBlocked));
- }
-
- }
- else {
- foreach(ChatWindow::RoomAction availableAction, availableRoomActions_)
- {
- if (impromptu_) {
- // hide options we don't need in impromptu chats
- if (availableAction == ChatWindow::ChangeSubject ||
- availableAction == ChatWindow::Configure ||
- availableAction == ChatWindow::Affiliations ||
- availableAction == ChatWindow::Destroy) {
- continue;
- }
- }
- switch(availableAction)
- {
- case ChatWindow::ChangeSubject:
- changeSubject = contextMenu.addAction(tr("Change subject…"));
- changeSubject->setEnabled(isOnline_);
- break;
- case ChatWindow::Configure:
- configure = contextMenu.addAction(tr("Configure room…"));
- configure->setEnabled(isOnline_);
- break;
- case ChatWindow::Affiliations:
- affiliations = contextMenu.addAction(tr("Edit affiliations…"));
- affiliations->setEnabled(isOnline_);
- break;
- case ChatWindow::Destroy:
- destroy = contextMenu.addAction(tr("Destroy room"));
- destroy->setEnabled(isOnline_);
- break;
- case ChatWindow::Invite:
- invite = contextMenu.addAction(tr("Invite person to this room…"));
- invite->setEnabled(isOnline_);
- break;
- }
- }
- }
-
- QAction* bookmark = NULL;
- if (isMUC_) {
- if (roomBookmarkState_ == RoomNotBookmarked) {
- bookmark = contextMenu.addAction(tr("Bookmark this room..."));
- }
- else {
- bookmark = contextMenu.addAction(tr("Edit bookmark..."));
- }
- bookmark->setEnabled(isOnline_);
- }
-
- QAction* result = contextMenu.exec(QCursor::pos());
- if (result == NULL) {
- /* Skip processing. Note that otherwise, because the actions could be null they could match */
- }
- else if (result == changeSubject) {
- bool ok;
- QString subject = QInputDialog::getText(this, tr("Change room subject"), tr("New subject:"), QLineEdit::Normal, subject_->text(), &ok);
- if (ok) {
- onChangeSubjectRequest(Q2PSTRING(subject));
- }
- }
- else if (result == configure) {
- onConfigureRequest(Form::ref());
- }
- else if (result == affiliations) {
- if (!affiliationEditor_) {
- onGetAffiliationsRequest();
- affiliationEditor_ = new QtAffiliationEditor(this);
- connect(affiliationEditor_, SIGNAL(accepted()), this, SLOT(handleAffiliationEditorAccepted()));
- }
- affiliationEditor_->show();
- }
- else if (result == destroy) {
- QMessageBox msgBox;
- msgBox.setWindowTitle(tr("Confirm room destruction"));
- msgBox.setText(tr("Are you sure you want to destroy the room?"));
- msgBox.setInformativeText(tr("This will destroy the room."));
- msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
- msgBox.setDefaultButton(QMessageBox::No);
- if (msgBox.exec() == QMessageBox::Yes) {
- onDestroyRequest();
- }
- }
- else if (result == invite) {
- onInviteToChat(std::vector<JID>());
- }
- else if (result == block) {
- onBlockUserRequest();
- }
- else if (result == unblock) {
- onUnblockUserRequest();
- }
- else if (result == bookmark) {
- onBookmarkRequest();
- }
+ QMenu contextMenu;
+ QAction* changeSubject = nullptr;
+ QAction* configure = nullptr;
+ QAction* affiliations = nullptr;
+ QAction* destroy = nullptr;
+ QAction* invite = nullptr;
+
+ QAction* block = nullptr;
+ QAction* unblock = nullptr;
+
+ if (availableRoomActions_.empty()) {
+ if (blockingState_ == IsBlocked) {
+ unblock = contextMenu.addAction(tr("Unblock"));
+ unblock->setEnabled(isOnline_);
+ }
+ else if (!isMUC_ && blockingState_ == IsUnblocked) {
+ block = contextMenu.addAction(tr("Block"));
+ block->setEnabled(isOnline_);
+ }
+
+ if (supportsImpromptuChat_) {
+ invite = contextMenu.addAction(tr("Invite person to this chat…"));
+ invite->setEnabled(isOnline_ && (blockingState_ != IsBlocked));
+ }
+
+ }
+ else {
+ for (auto&& availableAction : availableRoomActions_) {
+ if (impromptu_) {
+ // hide options we don't need in impromptu chats
+ if (availableAction == ChatWindow::ChangeSubject ||
+ availableAction == ChatWindow::Configure ||
+ availableAction == ChatWindow::Affiliations ||
+ availableAction == ChatWindow::Destroy) {
+ continue;
+ }
+ }
+ switch(availableAction)
+ {
+ case ChatWindow::ChangeSubject:
+ changeSubject = contextMenu.addAction(tr("Change subject…"));
+ changeSubject->setEnabled(isOnline_);
+ break;
+ case ChatWindow::Configure:
+ configure = contextMenu.addAction(tr("Configure room…"));
+ configure->setEnabled(isOnline_);
+ break;
+ case ChatWindow::Affiliations:
+ affiliations = contextMenu.addAction(tr("Edit affiliations…"));
+ affiliations->setEnabled(isOnline_);
+ break;
+ case ChatWindow::Destroy:
+ destroy = contextMenu.addAction(tr("Destroy room"));
+ destroy->setEnabled(isOnline_);
+ break;
+ case ChatWindow::Invite:
+ invite = contextMenu.addAction(tr("Invite person to this room…"));
+ invite->setEnabled(isOnline_);
+ break;
+ }
+ }
+ }
+
+ QAction* bookmark = nullptr;
+ if (isMUC_) {
+ if (roomBookmarkState_ == RoomNotBookmarked) {
+ bookmark = contextMenu.addAction(tr("Bookmark this room..."));
+ }
+ else {
+ bookmark = contextMenu.addAction(tr("Edit bookmark..."));
+ }
+ bookmark->setEnabled(isOnline_);
+ }
+
+ QAction* result = contextMenu.exec(QCursor::pos());
+ if (result == nullptr) {
+ /* Skip processing. Note that otherwise, because the actions could be null they could match */
+ }
+ else if (result == changeSubject) {
+ bool ok;
+ QString subject = QInputDialog::getText(this, tr("Change room subject"), tr("New subject:"), QLineEdit::Normal, subject_->text(), &ok);
+ if (ok) {
+ onChangeSubjectRequest(Q2PSTRING(subject));
+ }
+ }
+ else if (result == configure) {
+ onConfigureRequest(Form::ref());
+ }
+ else if (result == affiliations) {
+ if (!affiliationEditor_) {
+ onGetAffiliationsRequest();
+ affiliationEditor_ = new QtAffiliationEditor(this);
+ connect(affiliationEditor_, SIGNAL(accepted()), this, SLOT(handleAffiliationEditorAccepted()));
+ }
+ affiliationEditor_->show();
+ }
+ else if (result == destroy) {
+ QMessageBox msgBox;
+ msgBox.setWindowTitle(tr("Confirm room destruction"));
+ msgBox.setText(tr("Are you sure you want to destroy the room?"));
+ msgBox.setInformativeText(tr("This will destroy the room."));
+ msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+ msgBox.setDefaultButton(QMessageBox::No);
+ if (msgBox.exec() == QMessageBox::Yes) {
+ onDestroyRequest();
+ }
+ }
+ else if (result == invite) {
+ onInviteToChat(std::vector<JID>());
+ }
+ else if (result == block) {
+ onBlockUserRequest();
+ }
+ else if (result == unblock) {
+ onUnblockUserRequest();
+ }
+ else if (result == bookmark) {
+ onBookmarkRequest();
+ }
}
void QtChatWindow::handleAffiliationEditorAccepted() {
- onChangeAffiliationsRequest(affiliationEditor_->getChanges());
+ onChangeAffiliationsRequest(affiliationEditor_->getChanges());
}
void QtChatWindow::setAffiliations(MUCOccupant::Affiliation affiliation, const std::vector<JID>& jids) {
- if (!affiliationEditor_) return;
- affiliationEditor_->setAffiliations(affiliation, jids);
+ if (!affiliationEditor_) return;
+ affiliationEditor_->setAffiliations(affiliation, jids);
}
void QtChatWindow::setAvailableRoomActions(const std::vector<RoomAction>& actions) {
- availableRoomActions_ = actions;
+ availableRoomActions_ = actions;
}
void QtChatWindow::setBlockingState(BlockingState state) {
- blockingState_ = state;
+ blockingState_ = state;
}
void QtChatWindow::setCanInitiateImpromptuChats(bool supportsImpromptu) {
- supportsImpromptuChat_ = supportsImpromptu;
+ supportsImpromptuChat_ = supportsImpromptu;
}
void QtChatWindow::showBookmarkWindow(const MUCBookmark& bookmark) {
- if (roomBookmarkState_ == RoomNotBookmarked) {
- QtAddBookmarkWindow* window = new QtAddBookmarkWindow(eventStream_, bookmark);
- window->show();
- }
- else {
- QtEditBookmarkWindow* window = new QtEditBookmarkWindow(eventStream_, bookmark);
- window->show();
- }
+ if (roomBookmarkState_ == RoomNotBookmarked) {
+ QtAddBookmarkWindow* window = new QtAddBookmarkWindow(eventStream_, bookmark);
+ window->show();
+ }
+ else {
+ QtEditBookmarkWindow* window = new QtEditBookmarkWindow(eventStream_, bookmark);
+ window->show();
+ }
}
std::string QtChatWindow::getID() const {
- return id_;
+ return id_;
+}
+
+void QtChatWindow::setEmphasiseFocus(bool emphasise) {
+ input_->setEmphasiseFocus(emphasise);
}
void QtChatWindow::showRoomConfigurationForm(Form::ref form) {
- if (mucConfigurationWindow_) {
- delete mucConfigurationWindow_.data();
- }
- mucConfigurationWindow_ = new QtMUCConfigurationWindow(form);
- mucConfigurationWindow_->onFormComplete.connect(boost::bind(boost::ref(onConfigureRequest), _1));
- mucConfigurationWindow_->onFormCancelled.connect(boost::bind(boost::ref(onConfigurationFormCancelled)));
+ if (mucConfigurationWindow_) {
+ delete mucConfigurationWindow_.data();
+ }
+ mucConfigurationWindow_ = new QtMUCConfigurationWindow(form);
+ mucConfigurationWindow_->onFormComplete.connect(boost::bind(boost::ref(onConfigureRequest), _1));
+ mucConfigurationWindow_->onFormCancelled.connect(boost::bind(boost::ref(onConfigurationFormCancelled)));
}
void QtChatWindow::handleAppendedToLog() {
- if (lastLineTracker_.getShouldMoveLastLine()) {
- /* should this be queued? */
- messageLog_->addLastSeenLine();
- }
- if (isWidgetSelected()) {
- onAllMessagesRead();
- }
+ if (lastLineTracker_.getShouldMoveLastLine()) {
+ /* should this be queued? */
+ messageLog_->addLastSeenLine();
+ }
+ if (isWidgetSelected()) {
+ onAllMessagesRead();
+ }
}
void QtChatWindow::addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct, bool isImpromptu, bool isContinuation) {
- handleAppendedToLog();
- messageLog_->addMUCInvitation(senderName, jid, reason, password, direct, isImpromptu, isContinuation);
+ handleAppendedToLog();
+ messageLog_->addMUCInvitation(senderName, jid, reason, password, direct, isImpromptu, isContinuation);
}
-std::string QtChatWindow::addMessage(const ChatMessage& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
- handleAppendedToLog();
- return messageLog_->addMessage(message, senderName, senderIsSelf, label, avatarPath, time, highlight);
+std::string QtChatWindow::addMessage(const ChatMessage& message, const std::string& senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) {
+ handleAppendedToLog();
+ return messageLog_->addMessage(message, senderName, senderIsSelf, label, avatarPath, time);
}
-std::string QtChatWindow::addAction(const ChatMessage& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
- handleAppendedToLog();
- return messageLog_->addAction(message, senderName, senderIsSelf, label, avatarPath, time, highlight);
+std::string QtChatWindow::addAction(const ChatMessage& message, const std::string& senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) {
+ handleAppendedToLog();
+ return messageLog_->addAction(message, senderName, senderIsSelf, label, avatarPath, time);
}
std::string QtChatWindow::addSystemMessage(const ChatMessage& message, Direction direction) {
- handleAppendedToLog();
- return messageLog_->addSystemMessage(message, direction);
+ handleAppendedToLog();
+ return messageLog_->addSystemMessage(message, direction);
}
void QtChatWindow::addPresenceMessage(const ChatMessage& message, Direction direction) {
- handleAppendedToLog();
- messageLog_->addPresenceMessage(message, direction);
+ handleAppendedToLog();
+ messageLog_->addPresenceMessage(message, direction);
}
void QtChatWindow::addErrorMessage(const ChatMessage& message) {
- handleAppendedToLog();
- messageLog_->addErrorMessage(message);
+ handleAppendedToLog();
+ messageLog_->addErrorMessage(message);
}
-void QtChatWindow::replaceMessage(const ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
- handleAppendedToLog();
- messageLog_->replaceMessage(message, id, time, highlight);
+void QtChatWindow::replaceMessage(const ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time) {
+ handleAppendedToLog();
+ messageLog_->replaceMessage(message, id, time);
}
-void QtChatWindow::replaceWithAction(const ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
- handleAppendedToLog();
- messageLog_->replaceWithAction(message, id, time, highlight);
+void QtChatWindow::replaceWithAction(const ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time) {
+ handleAppendedToLog();
+ messageLog_->replaceWithAction(message, id, time);
}
std::string QtChatWindow::addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes, const std::string& description) {
- handleAppendedToLog();
- return messageLog_->addFileTransfer(senderName, senderIsSelf, filename, sizeInBytes, description);
+ handleAppendedToLog();
+ return messageLog_->addFileTransfer(senderName, senderIsSelf, filename, sizeInBytes, description);
}
void QtChatWindow::setFileTransferProgress(std::string id, const int percentageDone) {
- messageLog_->setFileTransferProgress(id, percentageDone);
+ messageLog_->setFileTransferProgress(id, percentageDone);
}
void QtChatWindow::setFileTransferStatus(std::string id, const FileTransferState state, const std::string& msg) {
- messageLog_->setFileTransferStatus(id, state, msg);
+ messageLog_->setFileTransferStatus(id, state, msg);
}
std::string QtChatWindow::addWhiteboardRequest(bool senderIsSelf) {
- handleAppendedToLog();
- return messageLog_->addWhiteboardRequest(contact_, senderIsSelf);
+ handleAppendedToLog();
+ return messageLog_->addWhiteboardRequest(contact_, senderIsSelf);
}
void QtChatWindow::setWhiteboardSessionStatus(std::string id, const ChatWindow::WhiteboardSessionState state) {
- messageLog_->setWhiteboardSessionStatus(id, state);
+ messageLog_->setWhiteboardSessionStatus(id, state);
}
void QtChatWindow::replaceLastMessage(const ChatMessage& message, const TimestampBehaviour timestampBehaviour) {
- messageLog_->replaceLastMessage(message, timestampBehaviour);
+ messageLog_->replaceLastMessage(message, timestampBehaviour);
}
void QtChatWindow::setAckState(const std::string& id, AckState state) {
- messageLog_->setAckState(id, state);
+ messageLog_->setAckState(id, state);
}
void QtChatWindow::setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state) {
- messageLog_->setMessageReceiptState(id, state);
+ messageLog_->setMessageReceiptState(id, state);
}
void QtChatWindow::setBookmarkState(RoomBookmarkState bookmarkState) {
- roomBookmarkState_ = bookmarkState;
+ roomBookmarkState_ = bookmarkState;
}
}
diff --git a/Swift/QtUI/QtChatWindow.h b/Swift/QtUI/QtChatWindow.h
index 121192a..08ad7ad 100644
--- a/Swift/QtUI/QtChatWindow.h
+++ b/Swift/QtUI/QtChatWindow.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -32,203 +32,204 @@ class QSplitter;
class QPushButton;
namespace Swift {
- class QtChatView;
- class QtOccupantListWidget;
- class QtChatTheme;
- class TreeWidget;
- class QtTextEdit;
- class UIEventStream;
- class QtChatWindowJSBridge;
- class SettingsProvider;
- class QtEmoticonsGrid;
-
- class LabelModel : public QAbstractListModel {
- Q_OBJECT
- public:
- LabelModel(QObject* parent = NULL) : QAbstractListModel(parent) {}
-
- virtual int rowCount(const QModelIndex& /*index*/) const {
- return static_cast<int>(availableLabels_.size());
- }
-
- virtual QVariant data(const QModelIndex& index, int role) const {
- if (!index.isValid()) {
- return QVariant();
- }
- boost::shared_ptr<SecurityLabel> label = availableLabels_[index.row()].getLabel();
- if (label && role == Qt::TextColorRole) {
- return P2QSTRING(label->getForegroundColor());
- }
- if (label && role == Qt::TextColorRole) {
- return P2QSTRING(label->getBackgroundColor());
- }
- if (role == Qt::DisplayRole) {
- std::string selector = availableLabels_[index.row()].getSelector();
- std::string displayMarking = label ? label->getDisplayMarking() : "";
- QString labelName = selector.empty() ? displayMarking.c_str() : selector.c_str();
- return labelName;
- }
- return QVariant();
- }
-
- std::vector<SecurityLabelsCatalog::Item> availableLabels_;
- };
-
- class QtChatWindow : public QtTabbable, public ChatWindow {
- Q_OBJECT
-
- public:
- QtChatWindow(const QString& contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings, const std::map<std::string, std::string>& emoticons);
- virtual ~QtChatWindow();
- std::string addMessage(const ChatMessage& message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight);
- std::string addAction(const ChatMessage& message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight);
-
- std::string addSystemMessage(const ChatMessage& message, Direction direction);
- void addPresenceMessage(const ChatMessage& message, Direction direction);
- void addErrorMessage(const ChatMessage& message);
-
- void replaceMessage(const ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight);
- void replaceWithAction(const ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight);
- // File transfer related stuff
- std::string addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes, const std::string& description);
- void setFileTransferProgress(std::string id, const int percentageDone);
- void setFileTransferStatus(std::string id, const FileTransferState state, const std::string& msg);
-
- std::string addWhiteboardRequest(bool senderIsSelf);
- void setWhiteboardSessionStatus(std::string id, const ChatWindow::WhiteboardSessionState state);
-
- void show();
- bool isVisible() const;
- void activate();
- void setUnreadMessageCount(int count);
- void convertToMUC(MUCType mucType);
-// TreeWidget *getTreeWidget();
- void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels);
- void setSecurityLabelsEnabled(bool enabled);
- void setSecurityLabelsError();
- SecurityLabelsCatalog::Item getSelectedSecurityLabel();
- void setName(const std::string& name);
- void setOnline(bool online);
- QtTabbable::AlertType getWidgetAlertState();
- void setContactChatState(ChatState::ChatStateType state);
- void setRosterModel(Roster* roster);
- void setTabComplete(TabComplete* completer);
- int getCount();
- virtual void replaceSystemMessage(const ChatMessage& message, const std::string& id, const TimestampBehaviour timestampBehaviour);
- void replaceLastMessage(const ChatMessage& message, const TimestampBehaviour timestampBehaviour);
- void setAckState(const std::string& id, AckState state);
-
- // message receipts
- void setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state);
-
- void flash();
- QByteArray getSplitterState();
- virtual void setAvailableOccupantActions(const std::vector<OccupantAction>& actions);
- void setSubject(const std::string& subject);
- void showRoomConfigurationForm(Form::ref);
- void addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct = true, bool isImpromptu = false, bool isContinuation = false);
- void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>&);
- void setAvailableRoomActions(const std::vector<RoomAction>& actions);
- void setBlockingState(BlockingState state);
- virtual void setCanInitiateImpromptuChats(bool supportsImpromptu);
- virtual void showBookmarkWindow(const MUCBookmark& bookmark);
- virtual void setBookmarkState(RoomBookmarkState bookmarkState);
- virtual std::string getID() const;
-
- public slots:
- void handleChangeSplitterState(QByteArray state);
- void handleFontResized(int fontSizeSteps);
- AlertID addAlert(const std::string& alertText);
- void removeAlert(const AlertID id);
- void setCorrectionEnabled(Tristate enabled);
- void setFileTransferEnabled(Tristate enabled);
-
- signals:
- void geometryChanged();
- void splitterMoved();
- void fontResized(int);
-
- protected slots:
- void closeEvent(QCloseEvent* event);
- void resizeEvent(QResizeEvent* event);
- void moveEvent(QMoveEvent* event);
-
- void dragEnterEvent(QDragEnterEvent *event);
- void dropEvent(QDropEvent *event);
-
- protected:
- void showEvent(QShowEvent* event);
-
- private slots:
- void handleLogCleared();
- void returnPressed();
- void handleInputChanged();
- void handleCursorPositionChanged();
- void handleKeyPressEvent(QKeyEvent* event);
- void handleSplitterMoved(int pos, int index);
- void handleAlertButtonClicked();
- void handleActionButtonClicked();
- void handleAffiliationEditorAccepted();
- void handleCurrentLabelChanged(int);
- void handleEmoticonsButtonClicked();
- void handleEmoticonClicked(QString emoticonAsText);
- void handleTextInputReceivedFocus();
- void handleTextInputLostFocus();
-
- private:
- void updateTitleWithUnreadCount();
- void tabComplete();
- void beginCorrection();
- void cancelCorrection();
- void handleSettingChanged(const std::string& setting);
-
- void handleOccupantSelectionChanged(RosterItem* item);
- void handleAppendedToLog();
-
- static std::vector<JID> jidListFromQByteArray(const QByteArray& dataBytes);
-
- private:
- int unreadCount_;
- bool contactIsTyping_;
- LastLineTracker lastLineTracker_;
- std::string id_;
- QString contact_;
- QString lastSentMessage_;
- QTextCursor tabCompleteCursor_;
- QtChatView* messageLog_;
- QtChatTheme* theme_;
- QtTextEdit* input_;
- QWidget* midBar_;
- QBoxLayout* subjectLayout_;
- QComboBox* labelsWidget_;
- QtOccupantListWidget* treeWidget_;
- QLabel* correctingLabel_;
- boost::optional<AlertID> correctingAlert_;
- QVBoxLayout* alertLayout_;
- std::map<AlertID, QWidget*> alertWidgets_;
- AlertID nextAlertId_;
- TabComplete* completer_;
- QLineEdit* subject_;
- bool isCorrection_;
- bool inputClearing_;
- bool tabCompletion_;
- UIEventStream* eventStream_;
- bool isOnline_;
- QSplitter *logRosterSplitter_;
- Tristate correctionEnabled_;
- Tristate fileTransferEnabled_;
- QString alertStyleSheet_;
- QPointer<QtMUCConfigurationWindow> mucConfigurationWindow_;
- QPointer<QtAffiliationEditor> affiliationEditor_;
- SettingsProvider* settings_;
- std::vector<ChatWindow::RoomAction> availableRoomActions_;
- QPalette defaultLabelsPalette_;
- LabelModel* labelModel_;
- BlockingState blockingState_;
- bool impromptu_;
- bool isMUC_;
- bool supportsImpromptuChat_;
- RoomBookmarkState roomBookmarkState_;
- QMenu* emoticonsMenu_;
- };
+ class QtChatView;
+ class QtOccupantListWidget;
+ class QtChatTheme;
+ class TreeWidget;
+ class QtTextEdit;
+ class UIEventStream;
+ class QtChatWindowJSBridge;
+ class SettingsProvider;
+ class QtEmoticonsGrid;
+
+ class LabelModel : public QAbstractListModel {
+ Q_OBJECT
+ public:
+ LabelModel(QObject* parent = nullptr) : QAbstractListModel(parent) {}
+
+ virtual int rowCount(const QModelIndex& /*index*/) const {
+ return static_cast<int>(availableLabels_.size());
+ }
+
+ virtual QVariant data(const QModelIndex& index, int role) const {
+ if (!index.isValid()) {
+ return QVariant();
+ }
+ std::shared_ptr<SecurityLabel> label = availableLabels_[index.row()].getLabel();
+ if (label && role == Qt::TextColorRole) {
+ return P2QSTRING(label->getForegroundColor());
+ }
+ if (label && role == Qt::TextColorRole) {
+ return P2QSTRING(label->getBackgroundColor());
+ }
+ if (role == Qt::DisplayRole) {
+ std::string selector = availableLabels_[index.row()].getSelector();
+ std::string displayMarking = label ? label->getDisplayMarking() : "";
+ QString labelName = selector.empty() ? displayMarking.c_str() : selector.c_str();
+ return labelName;
+ }
+ return QVariant();
+ }
+
+ std::vector<SecurityLabelsCatalog::Item> availableLabels_;
+ };
+
+ class QtChatWindow : public QtTabbable, public ChatWindow {
+ Q_OBJECT
+
+ public:
+ QtChatWindow(const QString& contact, QtChatTheme* theme, UIEventStream* eventStream, SettingsProvider* settings, const std::map<std::string, std::string>& emoticons);
+ virtual ~QtChatWindow();
+ std::string addMessage(const ChatMessage& message, const std::string &senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time);
+ std::string addAction(const ChatMessage& message, const std::string &senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time);
+
+ std::string addSystemMessage(const ChatMessage& message, Direction direction);
+ void addPresenceMessage(const ChatMessage& message, Direction direction);
+ void addErrorMessage(const ChatMessage& message);
+
+ void replaceMessage(const ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time);
+ void replaceWithAction(const ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time);
+ // File transfer related stuff
+ std::string addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes, const std::string& description);
+ void setFileTransferProgress(std::string id, const int percentageDone);
+ void setFileTransferStatus(std::string id, const FileTransferState state, const std::string& msg);
+
+ std::string addWhiteboardRequest(bool senderIsSelf);
+ void setWhiteboardSessionStatus(std::string id, const ChatWindow::WhiteboardSessionState state);
+
+ void show();
+ bool isVisible() const;
+ void activate();
+ void setUnreadMessageCount(int count);
+ void convertToMUC(MUCType mucType);
+// TreeWidget *getTreeWidget();
+ void setAvailableSecurityLabels(const std::vector<SecurityLabelsCatalog::Item>& labels);
+ void setSecurityLabelsEnabled(bool enabled);
+ void setSecurityLabelsError();
+ SecurityLabelsCatalog::Item getSelectedSecurityLabel();
+ void setName(const std::string& name);
+ void setOnline(bool online);
+ QtTabbable::AlertType getWidgetAlertState();
+ void setContactChatState(ChatState::ChatStateType state);
+ void setRosterModel(Roster* roster);
+ void setTabComplete(TabComplete* completer);
+ int getCount();
+ virtual void replaceSystemMessage(const ChatMessage& message, const std::string& id, const TimestampBehaviour timestampBehaviour);
+ void replaceLastMessage(const ChatMessage& message, const TimestampBehaviour timestampBehaviour);
+ void setAckState(const std::string& id, AckState state);
+
+ // message receipts
+ void setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state);
+
+ void flash();
+ QByteArray getSplitterState();
+ virtual void setAvailableOccupantActions(const std::vector<OccupantAction>& actions);
+ void setSubject(const std::string& subject);
+ void showRoomConfigurationForm(Form::ref);
+ void addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct = true, bool isImpromptu = false, bool isContinuation = false);
+ void setAffiliations(MUCOccupant::Affiliation, const std::vector<JID>&);
+ void setAvailableRoomActions(const std::vector<RoomAction>& actions);
+ void setBlockingState(BlockingState state);
+ virtual void setCanInitiateImpromptuChats(bool supportsImpromptu);
+ virtual void showBookmarkWindow(const MUCBookmark& bookmark);
+ virtual void setBookmarkState(RoomBookmarkState bookmarkState);
+ virtual std::string getID() const;
+ virtual void setEmphasiseFocus(bool emphasise);
+
+ public slots:
+ void handleChangeSplitterState(QByteArray state);
+ void handleFontResized(int fontSizeSteps);
+ AlertID addAlert(const std::string& alertText);
+ void removeAlert(const AlertID id);
+ void setCorrectionEnabled(Tristate enabled);
+ void setFileTransferEnabled(Tristate enabled);
+
+ signals:
+ void geometryChanged();
+ void splitterMoved();
+ void fontResized(int);
+
+ protected slots:
+ void closeEvent(QCloseEvent* event);
+ void resizeEvent(QResizeEvent* event);
+ void moveEvent(QMoveEvent* event);
+
+ void dragEnterEvent(QDragEnterEvent *event);
+ void dropEvent(QDropEvent *event);
+
+ protected:
+ void showEvent(QShowEvent* event);
+
+ private slots:
+ void handleLogCleared();
+ void returnPressed();
+ void handleInputChanged();
+ void handleCursorPositionChanged();
+ void handleKeyPressEvent(QKeyEvent* event);
+ void handleSplitterMoved(int pos, int index);
+ void handleAlertButtonClicked();
+ void handleActionButtonClicked();
+ void handleAffiliationEditorAccepted();
+ void handleCurrentLabelChanged(int);
+ void handleEmoticonsButtonClicked();
+ void handleEmoticonClicked(QString emoticonAsText);
+ void handleTextInputReceivedFocus();
+ void handleTextInputLostFocus();
+
+ private:
+ void updateTitleWithUnreadCount();
+ void tabComplete();
+ void beginCorrection();
+ void cancelCorrection();
+ void handleSettingChanged(const std::string& setting);
+
+ void handleOccupantSelectionChanged(RosterItem* item);
+ void handleAppendedToLog();
+
+ static std::vector<JID> jidListFromQByteArray(const QByteArray& dataBytes);
+
+ private:
+ int unreadCount_;
+ bool contactIsTyping_;
+ LastLineTracker lastLineTracker_;
+ std::string id_;
+ QString contact_;
+ QString lastSentMessage_;
+ QTextCursor tabCompleteCursor_;
+ QtChatView* messageLog_;
+ QtChatTheme* theme_;
+ QtTextEdit* input_;
+ QWidget* midBar_;
+ QBoxLayout* subjectLayout_;
+ QComboBox* labelsWidget_;
+ QtOccupantListWidget* treeWidget_;
+ QLabel* correctingLabel_;
+ boost::optional<AlertID> correctingAlert_;
+ QVBoxLayout* alertLayout_;
+ std::map<AlertID, QWidget*> alertWidgets_;
+ AlertID nextAlertId_;
+ TabComplete* completer_;
+ QLineEdit* subject_;
+ bool isCorrection_;
+ bool inputClearing_;
+ bool tabCompletion_;
+ UIEventStream* eventStream_;
+ bool isOnline_;
+ QSplitter *logRosterSplitter_;
+ Tristate correctionEnabled_;
+ Tristate fileTransferEnabled_;
+ QString alertStyleSheet_;
+ QPointer<QtMUCConfigurationWindow> mucConfigurationWindow_;
+ QPointer<QtAffiliationEditor> affiliationEditor_;
+ SettingsProvider* settings_;
+ std::vector<ChatWindow::RoomAction> availableRoomActions_;
+ QPalette defaultLabelsPalette_;
+ LabelModel* labelModel_;
+ BlockingState blockingState_;
+ bool impromptu_;
+ bool isMUC_;
+ bool supportsImpromptuChat_;
+ RoomBookmarkState roomBookmarkState_;
+ QMenu* emoticonsMenu_;
+ };
}
diff --git a/Swift/QtUI/QtChatWindowFactory.cpp b/Swift/QtUI/QtChatWindowFactory.cpp
index b9ba89d..9c59e9a 100644
--- a/Swift/QtUI/QtChatWindowFactory.cpp
+++ b/Swift/QtUI/QtChatWindowFactory.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,15 +7,15 @@
#include <Swift/QtUI/QtChatWindowFactory.h>
#include <QDesktopWidget>
+
#include <qdebug.h>
#include <Swift/QtUI/QtChatTabs.h>
#include <Swift/QtUI/QtChatTabsBase.h>
-#include <Swift/QtUI/QtChatWindow.h>
-#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swift/QtUI/QtChatTheme.h>
+#include <Swift/QtUI/QtChatWindow.h>
#include <Swift/QtUI/QtSingleWindow.h>
-
+#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
@@ -23,65 +23,65 @@ static const QString SPLITTER_STATE = "mucSplitterState";
static const QString CHAT_TABS_GEOMETRY = "chatTabsGeometry";
QtChatWindowFactory::QtChatWindowFactory(QtSingleWindow* splitter, SettingsProvider* settings, QtSettingsProvider* qtSettings, QtChatTabsBase* tabs, const QString& themePath, const std::map<std::string, std::string>& emoticons) : themePath_(themePath), emoticons_(emoticons) {
- qtOnlySettings_ = qtSettings;
- settings_ = settings;
- tabs_ = tabs;
- theme_ = NULL;
- QtChatTabs* fullTabs = dynamic_cast<QtChatTabs*>(tabs_);
- if (splitter) {
- assert(fullTabs && "Netbook mode and no-tabs interface is not supported!");
- splitter->addWidget(fullTabs);
- } else if (fullTabs) {
- QVariant chatTabsGeometryVariant = qtOnlySettings_->getQSettings()->value(CHAT_TABS_GEOMETRY);
- if (chatTabsGeometryVariant.isValid()) {
- fullTabs->restoreGeometry(chatTabsGeometryVariant.toByteArray());
- }
- connect(fullTabs, SIGNAL(geometryChanged()), this, SLOT(handleWindowGeometryChanged()));
- }
+ qtOnlySettings_ = qtSettings;
+ settings_ = settings;
+ tabs_ = tabs;
+ theme_ = nullptr;
+ QtChatTabs* fullTabs = dynamic_cast<QtChatTabs*>(tabs_);
+ if (splitter) {
+ assert(fullTabs && "Netbook mode and no-tabs interface is not supported!");
+ splitter->addWidget(fullTabs);
+ } else if (fullTabs) {
+ QVariant chatTabsGeometryVariant = qtOnlySettings_->getQSettings()->value(CHAT_TABS_GEOMETRY);
+ if (chatTabsGeometryVariant.isValid()) {
+ fullTabs->restoreGeometry(chatTabsGeometryVariant.toByteArray());
+ }
+ connect(fullTabs, SIGNAL(geometryChanged()), this, SLOT(handleWindowGeometryChanged()));
+ }
}
QtChatWindowFactory::~QtChatWindowFactory() {
- delete theme_;
+ delete theme_;
}
ChatWindow* QtChatWindowFactory::createChatWindow(const JID &contact,UIEventStream* eventStream) {
- if (!theme_) {
- theme_ = new QtChatTheme(themePath_);
- if (theme_->getIncomingContent().isEmpty()) {
- delete theme_;
- theme_ = new QtChatTheme(""); /* Use the inbuilt theme */
- }
- }
+ if (!theme_) {
+ theme_ = new QtChatTheme(themePath_);
+ if (theme_->getIncomingContent().isEmpty()) {
+ delete theme_;
+ theme_ = new QtChatTheme(":/themes/Default/"); /* Use the inbuilt theme */
+ }
+ }
- QtChatWindow* chatWindow = new QtChatWindow(P2QSTRING(contact.toString()), theme_, eventStream, settings_, emoticons_);
- connect(chatWindow, SIGNAL(splitterMoved()), this, SLOT(handleSplitterMoved()));
- connect(this, SIGNAL(changeSplitterState(QByteArray)), chatWindow, SLOT(handleChangeSplitterState(QByteArray)));
+ QtChatWindow* chatWindow = new QtChatWindow(P2QSTRING(contact.toString()), theme_, eventStream, settings_, emoticons_);
+ connect(chatWindow, SIGNAL(splitterMoved()), this, SLOT(handleSplitterMoved()));
+ connect(this, SIGNAL(changeSplitterState(QByteArray)), chatWindow, SLOT(handleChangeSplitterState(QByteArray)));
- QVariant splitterState = qtOnlySettings_->getQSettings()->value(SPLITTER_STATE);
- if(splitterState.isValid()) {
- chatWindow->handleChangeSplitterState(splitterState.toByteArray());
- }
+ QVariant splitterState = qtOnlySettings_->getQSettings()->value(SPLITTER_STATE);
+ if(splitterState.isValid()) {
+ chatWindow->handleChangeSplitterState(splitterState.toByteArray());
+ }
- if (tabs_) {
- tabs_->addTab(chatWindow);
- } else {
- QVariant chatGeometryVariant = qtOnlySettings_->getQSettings()->value(CHAT_TABS_GEOMETRY);
- if (chatGeometryVariant.isValid()) {
- chatWindow->restoreGeometry(chatGeometryVariant.toByteArray());
- }
- connect(chatWindow, SIGNAL(geometryChanged()), this, SLOT(handleWindowGeometryChanged()));
- }
- return chatWindow;
+ if (tabs_) {
+ tabs_->addTab(chatWindow);
+ } else {
+ QVariant chatGeometryVariant = qtOnlySettings_->getQSettings()->value(CHAT_TABS_GEOMETRY);
+ if (chatGeometryVariant.isValid()) {
+ chatWindow->restoreGeometry(chatGeometryVariant.toByteArray());
+ }
+ connect(chatWindow, SIGNAL(geometryChanged()), this, SLOT(handleWindowGeometryChanged()));
+ }
+ return chatWindow;
}
void QtChatWindowFactory::handleWindowGeometryChanged() {
- qtOnlySettings_->getQSettings()->setValue(CHAT_TABS_GEOMETRY, qobject_cast<QWidget*>(sender())->saveGeometry());
+ qtOnlySettings_->getQSettings()->setValue(CHAT_TABS_GEOMETRY, qobject_cast<QWidget*>(sender())->saveGeometry());
}
void QtChatWindowFactory::handleSplitterMoved() {
- QByteArray splitterState = qobject_cast<QtChatWindow*>(sender())->getSplitterState();
- qtOnlySettings_->getQSettings()->setValue(SPLITTER_STATE, QVariant(splitterState));
- emit changeSplitterState(splitterState);
+ QByteArray splitterState = qobject_cast<QtChatWindow*>(sender())->getSplitterState();
+ qtOnlySettings_->getQSettings()->setValue(SPLITTER_STATE, QVariant(splitterState));
+ emit changeSplitterState(splitterState);
}
}
diff --git a/Swift/QtUI/QtChatWindowFactory.h b/Swift/QtUI/QtChatWindowFactory.h
index 6b1f0a1..29bc5bc 100644
--- a/Swift/QtUI/QtChatWindowFactory.h
+++ b/Swift/QtUI/QtChatWindowFactory.h
@@ -19,29 +19,29 @@
#include <Swift/QtUI/QtSettingsProvider.h>
namespace Swift {
- class QtChatTabsBase;
- class QtChatTheme;
- class UIEventStream;
- class QtUIPreferences;
- class QtSingleWindow;
- class QtChatWindowFactory : public QObject, public ChatWindowFactory {
- Q_OBJECT
- public:
- QtChatWindowFactory(QtSingleWindow* splitter, SettingsProvider* settings, QtSettingsProvider* qtSettings, QtChatTabsBase* tabs, const QString& themePath, const std::map<std::string, std::string>& emoticons);
- ~QtChatWindowFactory();
- ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream);
- signals:
- void changeSplitterState(QByteArray);
- private slots:
- void handleWindowGeometryChanged();
- void handleSplitterMoved();
- private:
- QString themePath_;
- SettingsProvider* settings_;
- QtSettingsProvider* qtOnlySettings_;
- QtChatTabsBase* tabs_;
- QtChatTheme* theme_;
- std::map<std::string, std::string> emoticons_;
- };
+ class QtChatTabsBase;
+ class QtChatTheme;
+ class UIEventStream;
+ class QtUIPreferences;
+ class QtSingleWindow;
+ class QtChatWindowFactory : public QObject, public ChatWindowFactory {
+ Q_OBJECT
+ public:
+ QtChatWindowFactory(QtSingleWindow* splitter, SettingsProvider* settings, QtSettingsProvider* qtSettings, QtChatTabsBase* tabs, const QString& themePath, const std::map<std::string, std::string>& emoticons);
+ ~QtChatWindowFactory();
+ ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream);
+ signals:
+ void changeSplitterState(QByteArray);
+ private slots:
+ void handleWindowGeometryChanged();
+ void handleSplitterMoved();
+ private:
+ QString themePath_;
+ SettingsProvider* settings_;
+ QtSettingsProvider* qtOnlySettings_;
+ QtChatTabsBase* tabs_;
+ QtChatTheme* theme_;
+ std::map<std::string, std::string> emoticons_;
+ };
}
diff --git a/Swift/QtUI/QtChatWindowJSBridge.cpp b/Swift/QtUI/QtChatWindowJSBridge.cpp
index db67d79..3030689 100644
--- a/Swift/QtUI/QtChatWindowJSBridge.cpp
+++ b/Swift/QtUI/QtChatWindowJSBridge.cpp
@@ -4,16 +4,22 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "QtChatWindowJSBridge.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtChatWindowJSBridge.h>
namespace Swift {
QtChatWindowJSBridge::QtChatWindowJSBridge() {
-
+
}
QtChatWindowJSBridge::~QtChatWindowJSBridge() {
-
+
}
}
diff --git a/Swift/QtUI/QtChatWindowJSBridge.h b/Swift/QtUI/QtChatWindowJSBridge.h
index 5a26302..553e929 100644
--- a/Swift/QtUI/QtChatWindowJSBridge.h
+++ b/Swift/QtUI/QtChatWindowJSBridge.h
@@ -4,23 +4,30 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#pragma once
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
-#include <QObject>
+#pragma once
#include <map>
+#include <QObject>
+
namespace Swift {
class FileTransferController;
class QtChatWindowJSBridge : public QObject {
- Q_OBJECT
+ Q_OBJECT
public:
- QtChatWindowJSBridge();
- virtual ~QtChatWindowJSBridge();
+ QtChatWindowJSBridge();
+ virtual ~QtChatWindowJSBridge();
signals:
- void buttonClicked(QString id, QString arg1, QString arg2, QString arg3, QString arg4, QString arg5);
+ void buttonClicked(QString id, QString arg1, QString arg2, QString arg3, QString arg4, QString arg5);
+ void verticalScrollBarPositionChanged(double scrollbarPosition);
};
}
diff --git a/Swift/QtUI/QtClickableLabel.cpp b/Swift/QtUI/QtClickableLabel.cpp
index d944ec8..7ce3325 100644
--- a/Swift/QtUI/QtClickableLabel.cpp
+++ b/Swift/QtUI/QtClickableLabel.cpp
@@ -1,10 +1,10 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtClickableLabel.h"
+#include <Swift/QtUI/QtClickableLabel.h>
namespace Swift {
@@ -12,7 +12,7 @@ QtClickableLabel::QtClickableLabel(QWidget* parent) : QLabel(parent) {
}
void QtClickableLabel::mousePressEvent(QMouseEvent*) {
- emit clicked();
+ emit clicked();
}
}
diff --git a/Swift/QtUI/QtClickableLabel.h b/Swift/QtUI/QtClickableLabel.h
index deaf646..83ed3f1 100644
--- a/Swift/QtUI/QtClickableLabel.h
+++ b/Swift/QtUI/QtClickableLabel.h
@@ -9,14 +9,14 @@
#include <QLabel>
namespace Swift {
- class QtClickableLabel : public QLabel {
- Q_OBJECT
- public:
- QtClickableLabel(QWidget* parent);
+ class QtClickableLabel : public QLabel {
+ Q_OBJECT
+ public:
+ QtClickableLabel(QWidget* parent);
- void mousePressEvent(QMouseEvent* event);
+ void mousePressEvent(QMouseEvent* event);
- signals:
- void clicked();
- };
+ signals:
+ void clicked();
+ };
}
diff --git a/Swift/QtUI/QtClosableLineEdit.cpp b/Swift/QtUI/QtClosableLineEdit.cpp
index 414463a..033db78 100644
--- a/Swift/QtUI/QtClosableLineEdit.cpp
+++ b/Swift/QtUI/QtClosableLineEdit.cpp
@@ -27,40 +27,40 @@ namespace Swift {
const int QtClosableLineEdit::clearButtonPadding = 2;
QtClosableLineEdit::QtClosableLineEdit(QWidget *parent) : QLineEdit(parent) {
- clearButton = new QToolButton(this);
- clearButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton));
- clearButton->setIconSize(QSize(16,16));
- clearButton->setCursor(Qt::ArrowCursor);
- clearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }");
- clearButton->hide();
- connect(clearButton, SIGNAL(clicked()), this, SLOT(handleCloseButtonClicked()));
- connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateCloseButton(const QString&)));
- int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
- setStyleSheet(QString("QLineEdit { padding-right: %1px; } ").arg(clearButton->sizeHint().width() + frameWidth + 1));
- QSize minimumSize = minimumSizeHint();
- setMinimumSize(qMax(minimumSize.width(), clearButton->sizeHint().width() + frameWidth * 2 + clearButtonPadding),
- qMax(minimumSize.height(), clearButton->sizeHint().height() + frameWidth * 2 + clearButtonPadding));
+ clearButton = new QToolButton(this);
+ clearButton->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton));
+ clearButton->setIconSize(QSize(16,16));
+ clearButton->setCursor(Qt::ArrowCursor);
+ clearButton->setStyleSheet("QToolButton { border: none; padding: 0px; }");
+ clearButton->hide();
+ connect(clearButton, SIGNAL(clicked()), this, SLOT(handleCloseButtonClicked()));
+ connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(updateCloseButton(const QString&)));
+ int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
+ setStyleSheet(QString("QLineEdit { padding-right: %1px; } ").arg(clearButton->sizeHint().width() + frameWidth + 1));
+ QSize minimumSize = minimumSizeHint();
+ setMinimumSize(qMax(minimumSize.width(), clearButton->sizeHint().width() + frameWidth * 2 + clearButtonPadding),
+ qMax(minimumSize.height(), clearButton->sizeHint().height() + frameWidth * 2 + clearButtonPadding));
}
void QtClosableLineEdit::resizeEvent(QResizeEvent *) {
- QSize size = clearButton->sizeHint();
- int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
- int verticalAdjustment = 1;
+ QSize size = clearButton->sizeHint();
+ int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
+ int verticalAdjustment = 1;
#if defined(Q_OS_WIN32)
- // This vertical adjustment is required on Windows so the close button is vertically centered in the line edit.
- verticalAdjustment += 2;
-#endif
- clearButton->move(rect().right() - frameWidth - size.width(), (rect().bottom() + verticalAdjustment - size.height())/2);
+ // This vertical adjustment is required on Windows so the close button is vertically centered in the line edit.
+ verticalAdjustment += 2;
+#endif
+ clearButton->move(rect().right() - frameWidth - size.width(), (rect().bottom() + verticalAdjustment - size.height())/2);
}
void QtClosableLineEdit::updateCloseButton(const QString& text) {
- clearButton->setVisible(!text.isEmpty());
+ clearButton->setVisible(!text.isEmpty());
}
void QtClosableLineEdit::handleCloseButtonClicked() {
- clear();
- QApplication::postEvent(this, new QKeyEvent(QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier));
- QApplication::postEvent(this, new QKeyEvent(QEvent::KeyRelease, Qt::Key_Escape, Qt::NoModifier));
+ clear();
+ QApplication::postEvent(this, new QKeyEvent(QEvent::KeyPress, Qt::Key_Escape, Qt::NoModifier));
+ QApplication::postEvent(this, new QKeyEvent(QEvent::KeyRelease, Qt::Key_Escape, Qt::NoModifier));
}
}
diff --git a/Swift/QtUI/QtClosableLineEdit.h b/Swift/QtUI/QtClosableLineEdit.h
index da9f5a8..0b195dd 100644
--- a/Swift/QtUI/QtClosableLineEdit.h
+++ b/Swift/QtUI/QtClosableLineEdit.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -24,20 +24,20 @@ namespace Swift {
class QtClosableLineEdit : public QLineEdit
{
- Q_OBJECT
- public:
- QtClosableLineEdit(QWidget *parent = 0);
+ Q_OBJECT
+ public:
+ QtClosableLineEdit(QWidget *parent = nullptr);
- protected:
- void resizeEvent(QResizeEvent *);
+ protected:
+ void resizeEvent(QResizeEvent *);
- private slots:
- void updateCloseButton(const QString &text);
- void handleCloseButtonClicked();
+ private slots:
+ void updateCloseButton(const QString &text);
+ void handleCloseButtonClicked();
- private:
- static const int clearButtonPadding;
- QToolButton *clearButton;
+ private:
+ static const int clearButtonPadding;
+ QToolButton *clearButton;
};
}
diff --git a/Swift/QtUI/QtColorToolButton.cpp b/Swift/QtUI/QtColorToolButton.cpp
index 1d379a3..b349a47 100644
--- a/Swift/QtUI/QtColorToolButton.cpp
+++ b/Swift/QtUI/QtColorToolButton.cpp
@@ -4,42 +4,48 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include <QColorDialog>
-#include <QPainter>
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
#include <Swift/QtUI/QtColorToolButton.h>
+#include <QColorDialog>
+#include <QPainter>
+
namespace Swift {
QtColorToolButton::QtColorToolButton(QWidget* parent) :
- QToolButton(parent)
+ QToolButton(parent)
{
- connect(this, SIGNAL(clicked()), SLOT(onClicked()));
- setColorIcon(Qt::transparent);
+ connect(this, SIGNAL(clicked()), SLOT(onClicked()));
+ setColorIcon(Qt::transparent);
}
void QtColorToolButton::setColor(const QColor& color)
{
- if (color.isValid() != color_.isValid() || (color.isValid() && color != color_)) {
- color_ = color;
- setColorIcon(color_);
- emit colorChanged(color_);
- }
+ if (color.isValid() != color_.isValid() || (color.isValid() && color != color_)) {
+ color_ = color;
+ setColorIcon(color_);
+ emit colorChanged(color_);
+ }
}
void QtColorToolButton::onClicked()
{
- QColor c = QColorDialog::getColor(color_, this);
- if (c.isValid()) {
- setColor(c);
- }
+ QColor c = QColorDialog::getColor(color_, this);
+ if (c.isValid()) {
+ setColor(c);
+ }
}
void QtColorToolButton::setColorIcon(const QColor& color)
{
- QPixmap pix(iconSize());
- pix.fill(color.isValid() ? color : Qt::transparent);
- setIcon(pix);
+ QPixmap pix(iconSize());
+ pix.fill(color.isValid() ? color : Qt::transparent);
+ setIcon(pix);
}
}
diff --git a/Swift/QtUI/QtColorToolButton.h b/Swift/QtUI/QtColorToolButton.h
index 33d195d..babafc5 100644
--- a/Swift/QtUI/QtColorToolButton.h
+++ b/Swift/QtUI/QtColorToolButton.h
@@ -4,29 +4,35 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <QToolButton>
namespace Swift {
- class QtColorToolButton : public QToolButton {
- Q_OBJECT
- Q_PROPERTY(QColor color READ getColor WRITE setColor NOTIFY colorChanged)
- public:
- explicit QtColorToolButton(QWidget* parent = NULL);
- void setColor(const QColor& color);
- const QColor& getColor() const { return color_; }
+ class QtColorToolButton : public QToolButton {
+ Q_OBJECT
+ Q_PROPERTY(QColor color READ getColor WRITE setColor NOTIFY colorChanged)
+ public:
+ explicit QtColorToolButton(QWidget* parent = nullptr);
+ void setColor(const QColor& color);
+ const QColor& getColor() const { return color_; }
- signals:
- void colorChanged(const QColor&);
+ signals:
+ void colorChanged(const QColor&);
- private slots:
- void onClicked();
+ private slots:
+ void onClicked();
- private:
- void setColorIcon(const QColor& color);
- QColor color_;
- };
+ private:
+ void setColorIcon(const QColor& color);
+ QColor color_;
+ };
}
diff --git a/Swift/QtUI/QtConnectionSettingsWindow.cpp b/Swift/QtUI/QtConnectionSettingsWindow.cpp
index 7b5003a..a58bc5c 100644
--- a/Swift/QtUI/QtConnectionSettingsWindow.cpp
+++ b/Swift/QtUI/QtConnectionSettingsWindow.cpp
@@ -1,23 +1,23 @@
/*
- * Copyright (c) 2012-2015 Isode Limited.
+ * Copyright (c) 2012-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/QtUI/QtConnectionSettingsWindow.h"
+#include <Swift/QtUI/QtConnectionSettingsWindow.h>
#include <boost/lexical_cast.hpp>
#include <QCoreApplication>
+#include <QFile>
#include <QIcon>
#include <QLabel>
-#include <QVBoxLayout>
-#include <QtGlobal>
+#include <QMessageBox>
#include <QPushButton>
#include <QTextEdit>
-#include <QFile>
#include <QTextStream>
-#include <QMessageBox>
+#include <QVBoxLayout>
+#include <QtGlobal>
#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swift/QtUI/QtURLValidator.h>
@@ -25,147 +25,147 @@
namespace Swift {
QtConnectionSettingsWindow::QtConnectionSettingsWindow(const ClientOptions& options) : QDialog() {
- ui.setupUi(this);
-
- connect(ui.connectionMethod, SIGNAL(currentIndexChanged(int)), ui.stackedWidget, SLOT(setCurrentIndex(int)));
-
- connect(ui.manual_manualHost, SIGNAL(toggled(bool)), ui.manual_manualHostNameLabel, SLOT(setEnabled(bool)));
- connect(ui.manual_manualHost, SIGNAL(toggled(bool)), ui.manual_manualHostName, SLOT(setEnabled(bool)));
- connect(ui.manual_manualHost, SIGNAL(toggled(bool)), ui.manual_manualHostPortLabel, SLOT(setEnabled(bool)));
- connect(ui.manual_manualHost, SIGNAL(toggled(bool)), ui.manual_manualHostPort, SLOT(setEnabled(bool)));
-
- connect(ui.manual_manualProxy, SIGNAL(toggled(bool)), ui.manual_manualProxyHostLabel, SLOT(setEnabled(bool)));
- connect(ui.manual_manualProxy, SIGNAL(toggled(bool)), ui.manual_manualProxyHost, SLOT(setEnabled(bool)));
- connect(ui.manual_manualProxy, SIGNAL(toggled(bool)), ui.manual_manualProxyPortLabel, SLOT(setEnabled(bool)));
- connect(ui.manual_manualProxy, SIGNAL(toggled(bool)), ui.manual_manualProxyPort, SLOT(setEnabled(bool)));
-
- connect(ui.bosh_manualProxy, SIGNAL(toggled(bool)), ui.bosh_manualProxyHostLabel, SLOT(setEnabled(bool)));
- connect(ui.bosh_manualProxy, SIGNAL(toggled(bool)), ui.bosh_manualProxyHost, SLOT(setEnabled(bool)));
- connect(ui.bosh_manualProxy, SIGNAL(toggled(bool)), ui.bosh_manualProxyPortLabel, SLOT(setEnabled(bool)));
- connect(ui.bosh_manualProxy, SIGNAL(toggled(bool)), ui.bosh_manualProxyPort, SLOT(setEnabled(bool)));
-
- connect(ui.manual_proxyType, SIGNAL(currentIndexChanged(int)), SLOT(handleProxyTypeChanged(int)));
-
- connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(handleAcceptRequested()));
-
- QtURLValidator* urlValidator = new QtURLValidator(this);
- ui.bosh_uri->setValidator(urlValidator);
-
- ui.manual_useTLS->setCurrentIndex(2);
-
- ui.manual_proxyType->setCurrentIndex(0);
-
- ClientOptions defaults;
- if (options.boshURL.isEmpty()) {
- bool isDefault = options.useStreamCompression == defaults.useStreamCompression;
- isDefault &= options.useTLS == defaults.useTLS;
- isDefault &= options.allowPLAINWithoutTLS == defaults.allowPLAINWithoutTLS;
- isDefault &= options.useStreamCompression == defaults.useStreamCompression;
- isDefault &= options.useAcks == defaults.useAcks;
- isDefault &= options.manualHostname == defaults.manualHostname;
- isDefault &= options.manualPort == defaults.manualPort;
- isDefault &= options.proxyType == defaults.proxyType;
- isDefault &= options.manualProxyHostname == defaults.manualProxyHostname;
- isDefault &= options.manualProxyPort == defaults.manualProxyPort;
- isDefault &= options.tlsOptions.schannelTLS1_0Workaround == defaults.tlsOptions.schannelTLS1_0Workaround;
- if (isDefault) {
- ui.connectionMethod->setCurrentIndex(0);
- }
- else {
- ui.connectionMethod->setCurrentIndex(1);
- ui.manual_useTLS->setCurrentIndex(options.useTLS);
- ui.manual_allowPLAINWithoutTLS->setChecked(options.allowPLAINWithoutTLS);
- ui.manual_allowCompression->setChecked(options.useStreamCompression);
- if (!options.manualHostname.empty()) {
- ui.manual_manualHost->setChecked(true);
- ui.manual_manualHostName->setText(P2QSTRING(options.manualHostname));
- if (options.manualPort >=0) {
- ui.manual_manualHostPort->setText(P2QSTRING(boost::lexical_cast<std::string>(options.manualPort)));
- }
- }
- ui.manual_proxyType->setCurrentIndex(options.proxyType);
- if (!options.manualProxyHostname.empty()) {
- ui.manual_manualProxy->setChecked(true);
- ui.manual_manualProxyHost->setText(P2QSTRING(options.manualProxyHostname));
- ui.manual_manualProxyPort->setText(P2QSTRING(boost::lexical_cast<std::string>(options.manualProxyPort)));
- }
- ui.manual_forceTLS1_0->setChecked(options.tlsOptions.schannelTLS1_0Workaround);
- }
- } else {
- ui.connectionMethod->setCurrentIndex(2);
- ui.bosh_uri->setText(P2QSTRING(options.boshURL.toString()));
- if (!options.boshHTTPConnectProxyURL.isEmpty()) {
- ui.bosh_manualProxy->setChecked(true);
- ui.bosh_manualProxyHost->setText(P2QSTRING(options.boshHTTPConnectProxyURL.getHost()));
- if (options.boshHTTPConnectProxyURL.getPort()) {
- ui.bosh_manualProxyPort->setText(P2QSTRING(boost::lexical_cast<std::string>(*options.boshHTTPConnectProxyURL.getPort())));
- }
- }
- }
+ ui.setupUi(this);
+
+ connect(ui.connectionMethod, SIGNAL(currentIndexChanged(int)), ui.stackedWidget, SLOT(setCurrentIndex(int)));
+
+ connect(ui.manual_manualHost, SIGNAL(toggled(bool)), ui.manual_manualHostNameLabel, SLOT(setEnabled(bool)));
+ connect(ui.manual_manualHost, SIGNAL(toggled(bool)), ui.manual_manualHostName, SLOT(setEnabled(bool)));
+ connect(ui.manual_manualHost, SIGNAL(toggled(bool)), ui.manual_manualHostPortLabel, SLOT(setEnabled(bool)));
+ connect(ui.manual_manualHost, SIGNAL(toggled(bool)), ui.manual_manualHostPort, SLOT(setEnabled(bool)));
+
+ connect(ui.manual_manualProxy, SIGNAL(toggled(bool)), ui.manual_manualProxyHostLabel, SLOT(setEnabled(bool)));
+ connect(ui.manual_manualProxy, SIGNAL(toggled(bool)), ui.manual_manualProxyHost, SLOT(setEnabled(bool)));
+ connect(ui.manual_manualProxy, SIGNAL(toggled(bool)), ui.manual_manualProxyPortLabel, SLOT(setEnabled(bool)));
+ connect(ui.manual_manualProxy, SIGNAL(toggled(bool)), ui.manual_manualProxyPort, SLOT(setEnabled(bool)));
+
+ connect(ui.bosh_manualProxy, SIGNAL(toggled(bool)), ui.bosh_manualProxyHostLabel, SLOT(setEnabled(bool)));
+ connect(ui.bosh_manualProxy, SIGNAL(toggled(bool)), ui.bosh_manualProxyHost, SLOT(setEnabled(bool)));
+ connect(ui.bosh_manualProxy, SIGNAL(toggled(bool)), ui.bosh_manualProxyPortLabel, SLOT(setEnabled(bool)));
+ connect(ui.bosh_manualProxy, SIGNAL(toggled(bool)), ui.bosh_manualProxyPort, SLOT(setEnabled(bool)));
+
+ connect(ui.manual_proxyType, SIGNAL(currentIndexChanged(int)), SLOT(handleProxyTypeChanged(int)));
+
+ connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(handleAcceptRequested()));
+
+ QtURLValidator* urlValidator = new QtURLValidator(this);
+ ui.bosh_uri->setValidator(urlValidator);
+
+ ui.manual_useTLS->setCurrentIndex(2);
+
+ ui.manual_proxyType->setCurrentIndex(0);
+
+ ClientOptions defaults;
+ if (options.boshURL.isEmpty()) {
+ bool isDefault = options.useStreamCompression == defaults.useStreamCompression;
+ isDefault &= options.useTLS == defaults.useTLS;
+ isDefault &= options.allowPLAINWithoutTLS == defaults.allowPLAINWithoutTLS;
+ isDefault &= options.useStreamCompression == defaults.useStreamCompression;
+ isDefault &= options.useAcks == defaults.useAcks;
+ isDefault &= options.manualHostname == defaults.manualHostname;
+ isDefault &= options.manualPort == defaults.manualPort;
+ isDefault &= options.proxyType == defaults.proxyType;
+ isDefault &= options.manualProxyHostname == defaults.manualProxyHostname;
+ isDefault &= options.manualProxyPort == defaults.manualProxyPort;
+ isDefault &= options.tlsOptions.schannelTLS1_0Workaround == defaults.tlsOptions.schannelTLS1_0Workaround;
+ if (isDefault) {
+ ui.connectionMethod->setCurrentIndex(0);
+ }
+ else {
+ ui.connectionMethod->setCurrentIndex(1);
+ ui.manual_useTLS->setCurrentIndex(options.useTLS);
+ ui.manual_allowPLAINWithoutTLS->setChecked(options.allowPLAINWithoutTLS);
+ ui.manual_allowCompression->setChecked(options.useStreamCompression);
+ if (!options.manualHostname.empty()) {
+ ui.manual_manualHost->setChecked(true);
+ ui.manual_manualHostName->setText(P2QSTRING(options.manualHostname));
+ if (options.manualPort >=0) {
+ ui.manual_manualHostPort->setText(P2QSTRING(boost::lexical_cast<std::string>(options.manualPort)));
+ }
+ }
+ ui.manual_proxyType->setCurrentIndex(options.proxyType);
+ if (!options.manualProxyHostname.empty()) {
+ ui.manual_manualProxy->setChecked(true);
+ ui.manual_manualProxyHost->setText(P2QSTRING(options.manualProxyHostname));
+ ui.manual_manualProxyPort->setText(P2QSTRING(boost::lexical_cast<std::string>(options.manualProxyPort)));
+ }
+ ui.manual_forceTLS1_0->setChecked(options.tlsOptions.schannelTLS1_0Workaround);
+ }
+ } else {
+ ui.connectionMethod->setCurrentIndex(2);
+ ui.bosh_uri->setText(P2QSTRING(options.boshURL.toString()));
+ if (!options.boshHTTPConnectProxyURL.isEmpty()) {
+ ui.bosh_manualProxy->setChecked(true);
+ ui.bosh_manualProxyHost->setText(P2QSTRING(options.boshHTTPConnectProxyURL.getHost()));
+ if (options.boshHTTPConnectProxyURL.getPort()) {
+ ui.bosh_manualProxyPort->setText(P2QSTRING(boost::lexical_cast<std::string>(*options.boshHTTPConnectProxyURL.getPort())));
+ }
+ }
+ }
#ifndef HAVE_SCHANNEL
- ui.manual_forceTLS1_0->hide();
+ ui.manual_forceTLS1_0->hide();
#endif
}
void QtConnectionSettingsWindow::handleProxyTypeChanged(int index) {
- bool proxySettingsVisible = index != NoProxy && index != SystemProxy;
- ui.manual_manualProxy->setVisible(proxySettingsVisible);
- ui.manual_manualProxyHostLabel->setVisible(proxySettingsVisible);
- ui.manual_manualProxyHost->setVisible(proxySettingsVisible);
- ui.manual_manualProxyPortLabel->setVisible(proxySettingsVisible);
- ui.manual_manualProxyPort->setVisible(proxySettingsVisible);
+ bool proxySettingsVisible = index != NoProxy && index != SystemProxy;
+ ui.manual_manualProxy->setVisible(proxySettingsVisible);
+ ui.manual_manualProxyHostLabel->setVisible(proxySettingsVisible);
+ ui.manual_manualProxyHost->setVisible(proxySettingsVisible);
+ ui.manual_manualProxyPortLabel->setVisible(proxySettingsVisible);
+ ui.manual_manualProxyPort->setVisible(proxySettingsVisible);
}
void QtConnectionSettingsWindow::handleAcceptRequested() {
- if (ui.connectionMethod->currentIndex() != 2 || ui.bosh_uri->hasAcceptableInput()) {
- accept();
- }
- else {
- QMessageBox::critical(this, tr("Configuration invalid"), tr("The provided BOSH URL is not valid."));
- }
+ if (ui.connectionMethod->currentIndex() != 2 || ui.bosh_uri->hasAcceptableInput()) {
+ accept();
+ }
+ else {
+ QMessageBox::critical(this, tr("Configuration invalid"), tr("The provided BOSH URL is not valid."));
+ }
}
ClientOptions QtConnectionSettingsWindow::getOptions() {
- ClientOptions options;
- if (ui.connectionMethod->currentIndex() > 0) {
- /* Not automatic */
- if (ui.connectionMethod->currentIndex() == 1) {
- /* Manual */
- options.useTLS = static_cast<ClientOptions::UseTLS>(ui.manual_useTLS->currentIndex());
- options.useStreamCompression = ui.manual_allowCompression->isChecked();
- options.allowPLAINWithoutTLS = ui.manual_allowPLAINWithoutTLS->isChecked();
- options.tlsOptions.schannelTLS1_0Workaround = ui.manual_forceTLS1_0->isChecked();
- if (ui.manual_manualHost->isChecked()) {
- options.manualHostname = Q2PSTRING(ui.manual_manualHostName->text());
- try {
- options.manualPort = boost::lexical_cast<int>(Q2PSTRING(ui.manual_manualHostPort->text()));
- } catch (const boost::bad_lexical_cast&) {
- options.manualPort = -1;
- }
- }
- options.proxyType = static_cast<ClientOptions::ProxyType>(ui.manual_proxyType->currentIndex());
- if (ui.manual_manualProxy->isChecked()) {
- options.manualProxyHostname = Q2PSTRING(ui.manual_manualProxyHost->text());
- try {
- options.manualProxyPort = boost::lexical_cast<int>(Q2PSTRING(ui.manual_manualProxyPort->text()));
- } catch (const boost::bad_lexical_cast&) {}
- }
- }
- else {
- /* BOSH */
- options.boshURL = URL::fromString(Q2PSTRING(ui.bosh_uri->text()));
- if (ui.bosh_manualProxy->isChecked()) {
- std::string host = Q2PSTRING(ui.bosh_manualProxyHost->text());
- try {
- int port = boost::lexical_cast<int>(Q2PSTRING(ui.bosh_manualProxyPort->text()));
- options.boshHTTPConnectProxyURL = URL("http", host, port, "");
- } catch (const boost::bad_lexical_cast&) {
- options.boshHTTPConnectProxyURL = URL("http", host, "");
- }
- }
- }
- }
- return options;
+ ClientOptions options;
+ if (ui.connectionMethod->currentIndex() > 0) {
+ /* Not automatic */
+ if (ui.connectionMethod->currentIndex() == 1) {
+ /* Manual */
+ options.useTLS = static_cast<ClientOptions::UseTLS>(ui.manual_useTLS->currentIndex());
+ options.useStreamCompression = ui.manual_allowCompression->isChecked();
+ options.allowPLAINWithoutTLS = ui.manual_allowPLAINWithoutTLS->isChecked();
+ options.tlsOptions.schannelTLS1_0Workaround = ui.manual_forceTLS1_0->isChecked();
+ if (ui.manual_manualHost->isChecked()) {
+ options.manualHostname = Q2PSTRING(ui.manual_manualHostName->text());
+ try {
+ options.manualPort = boost::lexical_cast<int>(Q2PSTRING(ui.manual_manualHostPort->text()));
+ } catch (const boost::bad_lexical_cast&) {
+ options.manualPort = -1;
+ }
+ }
+ options.proxyType = static_cast<ClientOptions::ProxyType>(ui.manual_proxyType->currentIndex());
+ if (ui.manual_manualProxy->isChecked()) {
+ options.manualProxyHostname = Q2PSTRING(ui.manual_manualProxyHost->text());
+ try {
+ options.manualProxyPort = boost::lexical_cast<int>(Q2PSTRING(ui.manual_manualProxyPort->text()));
+ } catch (const boost::bad_lexical_cast&) {}
+ }
+ }
+ else {
+ /* BOSH */
+ options.boshURL = URL::fromString(Q2PSTRING(ui.bosh_uri->text()));
+ if (ui.bosh_manualProxy->isChecked()) {
+ std::string host = Q2PSTRING(ui.bosh_manualProxyHost->text());
+ try {
+ int port = boost::lexical_cast<int>(Q2PSTRING(ui.bosh_manualProxyPort->text()));
+ options.boshHTTPConnectProxyURL = URL("http", host, port, "");
+ } catch (const boost::bad_lexical_cast&) {
+ options.boshHTTPConnectProxyURL = URL("http", host, "");
+ }
+ }
+ }
+ }
+ return options;
}
}
diff --git a/Swift/QtUI/QtConnectionSettingsWindow.h b/Swift/QtUI/QtConnectionSettingsWindow.h
index b86f841..f9fad84 100644
--- a/Swift/QtUI/QtConnectionSettingsWindow.h
+++ b/Swift/QtUI/QtConnectionSettingsWindow.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Isode Limited.
+ * Copyright (c) 2012-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,30 +8,30 @@
#include <QDialog>
-#include "ui_QtConnectionSettings.h"
-
#include <Swiften/Client/ClientOptions.h>
+#include <Swift/QtUI/ui_QtConnectionSettings.h>
+
namespace Swift {
- class QtConnectionSettingsWindow : public QDialog {
- Q_OBJECT
-
- public:
- QtConnectionSettingsWindow(const ClientOptions& options);
-
- ClientOptions getOptions();
-
- private slots:
- void handleProxyTypeChanged(int);
- void handleAcceptRequested();
-
- private:
- enum {
- NoProxy = 0,
- SystemProxy = 1,
- SOCKS5Proxy = 2,
- HTTPProxy = 3
- };
- Ui::QtConnectionSettings ui;
- };
+ class QtConnectionSettingsWindow : public QDialog {
+ Q_OBJECT
+
+ public:
+ QtConnectionSettingsWindow(const ClientOptions& options);
+
+ ClientOptions getOptions();
+
+ private slots:
+ void handleProxyTypeChanged(int);
+ void handleAcceptRequested();
+
+ private:
+ enum {
+ NoProxy = 0,
+ SystemProxy = 1,
+ SOCKS5Proxy = 2,
+ HTTPProxy = 3
+ };
+ Ui::QtConnectionSettings ui;
+ };
}
diff --git a/Swift/QtUI/QtContactEditWidget.cpp b/Swift/QtUI/QtContactEditWidget.cpp
index 478f8ce..17f5ccf 100644
--- a/Swift/QtUI/QtContactEditWidget.cpp
+++ b/Swift/QtUI/QtContactEditWidget.cpp
@@ -1,10 +1,10 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtContactEditWidget.h"
+#include <Swift/QtUI/QtContactEditWidget.h>
#include <algorithm>
@@ -13,163 +13,163 @@
#include <QLabel>
#include <QLineEdit>
#include <QMovie>
-#include <QScrollArea>
#include <QRadioButton>
+#include <QScrollArea>
-#include "Swift/QtUI/QtSwiftUtil.h"
+#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
-QtContactEditWidget::QtContactEditWidget(const std::set<std::string>& allGroups, QWidget* parent) : QWidget(parent), nameRadioButton_(NULL), groups_(NULL) {
- QBoxLayout* layout = new QVBoxLayout(this);
- setContentsMargins(0,0,0,0);
- layout->setContentsMargins(0,0,0,0);
-
- nameLayout_ = new QHBoxLayout();
- suggestionsLayout_ = new QHBoxLayout();
- nameLayout_->addLayout(suggestionsLayout_);
-
- name_ = new QLineEdit(this);
- nameLayout_->addWidget(name_);
-
- throbberLabel_ = new QLabel(this);
- throbberLabel_->setMovie(new QMovie(":/icons/throbber.gif", QByteArray(), this));
- throbberLabel_->movie()->start();
- nameLayout_->addWidget(throbberLabel_);
-
- layout->addLayout(nameLayout_);
-
- layout->addWidget(new QLabel(tr("Groups:"), this));
-
- QScrollArea* groupsArea = new QScrollArea(this);
- layout->addWidget(groupsArea);
- groupsArea->setWidgetResizable(true);
- groupsArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
- groupsArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
-
- QWidget* groups = new QWidget(groupsArea);
- groupsArea->setWidget(groups);
- QVBoxLayout* scrollLayout = new QVBoxLayout(groups);
-
- foreach (std::string group, allGroups) {
- QString groupName = doubleAmpersand(group);
- QCheckBox* check = new QCheckBox(groups);
- check->setText(groupName);
- check->setCheckState(Qt::Unchecked);
- checkBoxes_[group] = check;
- scrollLayout->addWidget(check);
- }
-
- QHBoxLayout* newGroupLayout = new QHBoxLayout();
- newGroup_ = new QCheckBox(groups);
- newGroup_->setText(tr("New Group:"));
- newGroup_->setCheckState(Qt::Unchecked);
- newGroupLayout->addWidget(newGroup_);
- newGroupName_ = new QLineEdit(groups);
- newGroupLayout->addWidget(newGroupName_);
- scrollLayout->addLayout(newGroupLayout);
-
- scrollLayout->addItem(new QSpacerItem(20, 73, QSizePolicy::Minimum, QSizePolicy::Expanding));
+QtContactEditWidget::QtContactEditWidget(const std::set<std::string>& allGroups, QWidget* parent) : QWidget(parent), nameRadioButton_(nullptr), groups_(nullptr) {
+ QBoxLayout* layout = new QVBoxLayout(this);
+ setContentsMargins(0,0,0,0);
+ layout->setContentsMargins(0,0,0,0);
+
+ nameLayout_ = new QHBoxLayout();
+ suggestionsLayout_ = new QHBoxLayout();
+ nameLayout_->addLayout(suggestionsLayout_);
+
+ name_ = new QLineEdit(this);
+ nameLayout_->addWidget(name_);
+
+ throbberLabel_ = new QLabel(this);
+ throbberLabel_->setMovie(new QMovie(":/icons/throbber.gif", QByteArray(), this));
+ throbberLabel_->movie()->start();
+ nameLayout_->addWidget(throbberLabel_);
+
+ layout->addLayout(nameLayout_);
+
+ layout->addWidget(new QLabel(tr("Groups:"), this));
+
+ QScrollArea* groupsArea = new QScrollArea(this);
+ layout->addWidget(groupsArea);
+ groupsArea->setWidgetResizable(true);
+ groupsArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ groupsArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+
+ QWidget* groups = new QWidget(groupsArea);
+ groupsArea->setWidget(groups);
+ QVBoxLayout* scrollLayout = new QVBoxLayout(groups);
+
+ for (const auto& group : allGroups) {
+ QString groupName = doubleAmpersand(group);
+ QCheckBox* check = new QCheckBox(groups);
+ check->setText(groupName);
+ check->setCheckState(Qt::Unchecked);
+ checkBoxes_[group] = check;
+ scrollLayout->addWidget(check);
+ }
+
+ QHBoxLayout* newGroupLayout = new QHBoxLayout();
+ newGroup_ = new QCheckBox(groups);
+ newGroup_->setText(tr("New Group:"));
+ newGroup_->setCheckState(Qt::Unchecked);
+ newGroupLayout->addWidget(newGroup_);
+ newGroupName_ = new QLineEdit(groups);
+ newGroupLayout->addWidget(newGroupName_);
+ scrollLayout->addLayout(newGroupLayout);
+
+ scrollLayout->addItem(new QSpacerItem(20, 73, QSizePolicy::Minimum, QSizePolicy::Expanding));
}
void QtContactEditWidget::setName(const std::string& name) {
- name_->setText(P2QSTRING(name));
+ name_->setText(P2QSTRING(name));
}
std::string QtContactEditWidget::getName() const {
- std::string name = Q2PSTRING(name_->text());
- QList<QRadioButton*> buttons = findChildren<QRadioButton*>();
- foreach(const QRadioButton* button, buttons) {
- if (button->isChecked()) {
- if (button == nameRadioButton_) {
- name = Q2PSTRING(name_->text());
- } else {
- name = singleAmpersand(button->text());
- }
- break;
- }
- }
- return name;
+ std::string name = Q2PSTRING(name_->text());
+ QList<QRadioButton*> buttons = findChildren<QRadioButton*>();
+ for (const auto button : buttons) {
+ if (button->isChecked()) {
+ if (button == nameRadioButton_) {
+ name = Q2PSTRING(name_->text());
+ } else {
+ name = singleAmpersand(button->text());
+ }
+ break;
+ }
+ }
+ return name;
}
void QtContactEditWidget::setSelectedGroups(const std::vector<std::string>& groups) {
- foreach (std::string group, groups) {
- checkBoxes_[group]->setCheckState(Qt::Checked);
- }
+ for (auto&& group : groups) {
+ checkBoxes_[group]->setCheckState(Qt::Checked);
+ }
}
std::set<std::string> QtContactEditWidget::getSelectedGroups() const {
- std::set<std::string> groups;
- foreach(const CheckBoxMap::value_type& group, checkBoxes_) {
- if (group.second->checkState() == Qt::Checked) {
- groups.insert(group.first);
- }
- }
- if (newGroup_->checkState() == Qt::Checked && !newGroupName_->text().isEmpty()) {
- groups.insert(Q2PSTRING(newGroupName_->text()));
- }
- return groups;
+ std::set<std::string> groups;
+ for (const auto& group : checkBoxes_) {
+ if (group.second->checkState() == Qt::Checked) {
+ groups.insert(group.first);
+ }
+ }
+ if (newGroup_->checkState() == Qt::Checked && !newGroupName_->text().isEmpty()) {
+ groups.insert(Q2PSTRING(newGroupName_->text()));
+ }
+ return groups;
}
void QtContactEditWidget::setNameSuggestions(const std::vector<std::string>& suggestions) {
- throbberLabel_->movie()->stop();
- throbberLabel_->hide();
-
- // remove old suggestions except for the user input text field
- QLayoutItem* suggestionItem = NULL;
- while ((suggestionItem = suggestionsLayout_->itemAt(0)) && suggestionItem->widget() != name_) {
- QWidget* suggestionWidget = suggestionItem->widget();
- suggestionsLayout_->removeWidget(suggestionWidget);
- delete suggestionWidget;
- }
-
- // populate new suggestions
- foreach(const std::string& name, suggestions) {
- suggestionsLayout_->insertWidget(nameLayout_->count() - 2, new QRadioButton(doubleAmpersand(name), this));
- }
-
- nameRadioButton_ = new QRadioButton(tr("Name:"), this);
- suggestionsLayout_->insertWidget(nameLayout_->count(), nameRadioButton_);
-
- QRadioButton* suggestedRadioButton = 0;
- QList<QRadioButton*> radioButtons = findChildren<QRadioButton*>();
- foreach (QRadioButton* candidate, radioButtons) {
- if (candidate->text() == name_->text()) {
- suggestedRadioButton = candidate;
- break;
- }
- }
- if (suggestedRadioButton) {
- suggestedRadioButton->setChecked(true);
- } else {
- nameRadioButton_->setChecked(true);
- }
+ throbberLabel_->movie()->stop();
+ throbberLabel_->hide();
+
+ // remove old suggestions except for the user input text field
+ QLayoutItem* suggestionItem = nullptr;
+ while ((suggestionItem = suggestionsLayout_->itemAt(0)) && suggestionItem->widget() != name_) {
+ QWidget* suggestionWidget = suggestionItem->widget();
+ suggestionsLayout_->removeWidget(suggestionWidget);
+ delete suggestionWidget;
+ }
+
+ // populate new suggestions
+ for (const auto& name : suggestions) {
+ suggestionsLayout_->insertWidget(nameLayout_->count() - 2, new QRadioButton(doubleAmpersand(name), this));
+ }
+
+ nameRadioButton_ = new QRadioButton(tr("Name:"), this);
+ suggestionsLayout_->insertWidget(nameLayout_->count(), nameRadioButton_);
+
+ QRadioButton* suggestedRadioButton = nullptr;
+ QList<QRadioButton*> radioButtons = findChildren<QRadioButton*>();
+ for (auto candidate : radioButtons) {
+ if (candidate->text() == name_->text()) {
+ suggestedRadioButton = candidate;
+ break;
+ }
+ }
+ if (suggestedRadioButton) {
+ suggestedRadioButton->setChecked(true);
+ } else {
+ nameRadioButton_->setChecked(true);
+ }
}
QString QtContactEditWidget::doubleAmpersand(const std::string& name) const {
- return P2QSTRING(name).replace("&", "&&");
+ return P2QSTRING(name).replace("&", "&&");
}
std::string QtContactEditWidget::singleAmpersand(const QString& name) const {
- return Q2PSTRING(QString(name).replace("&&", "&"));
+ return Q2PSTRING(QString(name).replace("&&", "&"));
}
void QtContactEditWidget::clear() {
- name_->clear();
- setSelectedGroups(std::vector<std::string>());
- newGroup_->setChecked(false);
- newGroupName_->clear();
- throbberLabel_->movie()->start();
- throbberLabel_->show();
-
- // clear suggestions
- while(suggestionsLayout_->count() != 0) {
- QLayoutItem *layoutItem = suggestionsLayout_->takeAt(0);
- delete layoutItem->widget();
- delete layoutItem;
- }
- nameRadioButton_ = NULL;
+ name_->clear();
+ setSelectedGroups(std::vector<std::string>());
+ newGroup_->setChecked(false);
+ newGroupName_->clear();
+ throbberLabel_->movie()->start();
+ throbberLabel_->show();
+
+ // clear suggestions
+ while(suggestionsLayout_->count() != 0) {
+ QLayoutItem *layoutItem = suggestionsLayout_->takeAt(0);
+ delete layoutItem->widget();
+ delete layoutItem;
+ }
+ nameRadioButton_ = nullptr;
}
}
diff --git a/Swift/QtUI/QtContactEditWidget.h b/Swift/QtUI/QtContactEditWidget.h
index 4a2d056..0718fee 100644
--- a/Swift/QtUI/QtContactEditWidget.h
+++ b/Swift/QtUI/QtContactEditWidget.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,14 +7,13 @@
#pragma once
#include <map>
+#include <memory>
#include <set>
-#include <boost/shared_ptr.hpp>
+#include <string>
+#include <vector>
#include <QWidget>
-#include <vector>
-#include <string>
-
class QLabel;
class QLineEdit;
class QCheckBox;
@@ -22,37 +21,37 @@ class QHBoxLayout;
class QRadioButton;
namespace Swift {
- class QtContactEditWidget : public QWidget {
- Q_OBJECT
-
- public:
- QtContactEditWidget(const std::set<std::string>& allGroups, QWidget* parent);
-
- void setName(const std::string&);
- std::string getName() const;
-
- void setSelectedGroups(const std::vector<std::string>& groups);
- std::set<std::string> getSelectedGroups() const;
-
- void setNameSuggestions(const std::vector<std::string>& suggestions);
-
- void clear();
-
-
- private:
- QString doubleAmpersand(const std::string& name) const;
- std::string singleAmpersand(const QString& name) const;
- private:
- typedef std::map<std::string, QCheckBox*> CheckBoxMap;
- CheckBoxMap checkBoxes_;
- QHBoxLayout* nameLayout_;
- QHBoxLayout* suggestionsLayout_;
- QRadioButton* nameRadioButton_;
- QLineEdit* name_;
- QWidget* groups_;
- QCheckBox* newGroup_;
- QLineEdit* newGroupName_;
- QLabel* throbberLabel_;
- };
+ class QtContactEditWidget : public QWidget {
+ Q_OBJECT
+
+ public:
+ QtContactEditWidget(const std::set<std::string>& allGroups, QWidget* parent);
+
+ void setName(const std::string&);
+ std::string getName() const;
+
+ void setSelectedGroups(const std::vector<std::string>& groups);
+ std::set<std::string> getSelectedGroups() const;
+
+ void setNameSuggestions(const std::vector<std::string>& suggestions);
+
+ void clear();
+
+
+ private:
+ QString doubleAmpersand(const std::string& name) const;
+ std::string singleAmpersand(const QString& name) const;
+
+ private:
+ std::map<std::string, QCheckBox*> checkBoxes_;
+ QHBoxLayout* nameLayout_;
+ QHBoxLayout* suggestionsLayout_;
+ QRadioButton* nameRadioButton_;
+ QLineEdit* name_;
+ QWidget* groups_;
+ QCheckBox* newGroup_;
+ QLineEdit* newGroupName_;
+ QLabel* throbberLabel_;
+ };
}
diff --git a/Swift/QtUI/QtContactEditWindow.cpp b/Swift/QtUI/QtContactEditWindow.cpp
index 5f69b52..138a356 100644
--- a/Swift/QtUI/QtContactEditWindow.cpp
+++ b/Swift/QtUI/QtContactEditWindow.cpp
@@ -1,107 +1,107 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtContactEditWindow.h"
+#include <Swift/QtUI/QtContactEditWindow.h>
#include <algorithm>
#include <boost/bind.hpp>
-#include <QScrollArea>
#include <QBoxLayout>
-#include <QLabel>
#include <QCheckBox>
+#include <QLabel>
#include <QLineEdit>
#include <QMessageBox>
#include <QPushButton>
+#include <QScrollArea>
-#include "Swift/QtUI/QtSwiftUtil.h"
-#include "QtContactEditWidget.h"
+#include <Swift/QtUI/QtContactEditWidget.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
-QtContactEditWindow::QtContactEditWindow() : contactEditWidget_(NULL) {
- resize(400,300);
- setWindowTitle(tr("Edit contact"));
- setContentsMargins(0,0,0,0);
-
- QBoxLayout* layout = new QVBoxLayout(this);
-
- jidLabel_ = new QLabel(this);
- jidLabel_->setAlignment(Qt::AlignHCenter);
- layout->addWidget(jidLabel_);
-
- groupsLayout_ = new QVBoxLayout();
- groupsLayout_->setContentsMargins(0,0,0,0);
- layout->addLayout(groupsLayout_);
-
- QHBoxLayout* buttonLayout = new QHBoxLayout();
- layout->addLayout(buttonLayout);
- QPushButton* removeButton = new QPushButton(tr("Remove contact"), this);
- connect(removeButton, SIGNAL(clicked()), this, SLOT(handleRemoveContact()));
- buttonLayout->addWidget(removeButton);
- QPushButton* okButton = new QPushButton(tr("OK"), this);
- okButton->setDefault( true );
- connect(okButton, SIGNAL(clicked()), this, SLOT(handleUpdateContact()));
- buttonLayout->addStretch();
- buttonLayout->addWidget(okButton);
+QtContactEditWindow::QtContactEditWindow() : contactEditWidget_(nullptr) {
+ resize(400,300);
+ setWindowTitle(tr("Edit contact"));
+ setContentsMargins(0,0,0,0);
+
+ QBoxLayout* layout = new QVBoxLayout(this);
+
+ jidLabel_ = new QLabel(this);
+ jidLabel_->setAlignment(Qt::AlignHCenter);
+ layout->addWidget(jidLabel_);
+
+ groupsLayout_ = new QVBoxLayout();
+ groupsLayout_->setContentsMargins(0,0,0,0);
+ layout->addLayout(groupsLayout_);
+
+ QHBoxLayout* buttonLayout = new QHBoxLayout();
+ layout->addLayout(buttonLayout);
+ QPushButton* removeButton = new QPushButton(tr("Remove contact"), this);
+ connect(removeButton, SIGNAL(clicked()), this, SLOT(handleRemoveContact()));
+ buttonLayout->addWidget(removeButton);
+ QPushButton* okButton = new QPushButton(tr("OK"), this);
+ okButton->setDefault( true );
+ connect(okButton, SIGNAL(clicked()), this, SLOT(handleUpdateContact()));
+ buttonLayout->addStretch();
+ buttonLayout->addWidget(okButton);
}
QtContactEditWindow::~QtContactEditWindow() {
}
void QtContactEditWindow::setNameSuggestions(const std::vector<std::string>& nameSuggestions) {
- if (contactEditWidget_) {
- contactEditWidget_->setNameSuggestions(nameSuggestions);
- }
+ if (contactEditWidget_) {
+ contactEditWidget_->setNameSuggestions(nameSuggestions);
+ }
}
void QtContactEditWindow::setContact(const JID& jid, const std::string& name, const std::vector<std::string>& groups, const std::set<std::string>& allGroups) {
- delete contactEditWidget_;
- jid_ = jid;
- jidLabel_->setText("<b>" + P2QSTRING(jid.toString()) + "</b>");
-
- contactEditWidget_ = new QtContactEditWidget(allGroups, this);
- groupsLayout_->addWidget(contactEditWidget_);
- contactEditWidget_->setName(name);
- contactEditWidget_->setSelectedGroups(groups);
+ delete contactEditWidget_;
+ jid_ = jid;
+ jidLabel_->setText("<b>" + P2QSTRING(jid.toString()) + "</b>");
+
+ contactEditWidget_ = new QtContactEditWidget(allGroups, this);
+ groupsLayout_->addWidget(contactEditWidget_);
+ contactEditWidget_->setName(name);
+ contactEditWidget_->setSelectedGroups(groups);
}
void QtContactEditWindow::setEnabled(bool b) {
- QWidget::setEnabled(b);
+ QWidget::setEnabled(b);
}
void QtContactEditWindow::show() {
- QWidget::showNormal();
- QWidget::activateWindow();
- QWidget::raise();
+ QWidget::showNormal();
+ QWidget::activateWindow();
+ QWidget::raise();
}
void QtContactEditWindow::hide() {
- QWidget::hide();
+ QWidget::hide();
}
void QtContactEditWindow::handleRemoveContact() {
- if (confirmContactDeletion(jid_)) {
- onRemoveContactRequest();
- }
+ if (confirmContactDeletion(jid_)) {
+ onRemoveContactRequest();
+ }
}
bool QtContactEditWindow::confirmContactDeletion(const JID& jid) {
- QMessageBox msgBox;
- msgBox.setWindowTitle(tr("Confirm contact deletion"));
- msgBox.setText(tr("Are you sure you want to delete this contact?"));
- msgBox.setInformativeText(QString(tr("This will remove the contact '%1' from all groups they may be in.")).arg(P2QSTRING(jid.toString())));
- msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
- msgBox.setDefaultButton(QMessageBox::Yes);
- return msgBox.exec() == QMessageBox::Yes;
+ QMessageBox msgBox;
+ msgBox.setWindowTitle(tr("Confirm contact deletion"));
+ msgBox.setText(tr("Are you sure you want to delete this contact?"));
+ msgBox.setInformativeText(QString(tr("This will remove the contact '%1' from all groups they may be in.")).arg(P2QSTRING(jid.toString())));
+ msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+ msgBox.setDefaultButton(QMessageBox::Yes);
+ return msgBox.exec() == QMessageBox::Yes;
}
void QtContactEditWindow::handleUpdateContact() {
- onChangeContactRequest(contactEditWidget_->getName(), contactEditWidget_->getSelectedGroups());
+ onChangeContactRequest(contactEditWidget_->getName(), contactEditWidget_->getSelectedGroups());
}
}
diff --git a/Swift/QtUI/QtContactEditWindow.h b/Swift/QtUI/QtContactEditWindow.h
index 1e9b07c..655fbb4 100644
--- a/Swift/QtUI/QtContactEditWindow.h
+++ b/Swift/QtUI/QtContactEditWindow.h
@@ -1,49 +1,51 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <string>
+
#include <QWidget>
-#include <Swift/Controllers/UIInterfaces/ContactEditWindow.h>
-#include <string>
-#include <Swiften/JID/JID.h>
#include <Swiften/Elements/VCard.h>
+#include <Swiften/JID/JID.h>
+
+#include <Swift/Controllers/UIInterfaces/ContactEditWindow.h>
class QLabel;
class QVBoxLayout;
namespace Swift {
- class QtContactEditWidget;
+ class QtContactEditWidget;
- class QtContactEditWindow : public QWidget, public ContactEditWindow {
- Q_OBJECT
+ class QtContactEditWindow : public QWidget, public ContactEditWindow {
+ Q_OBJECT
- public:
- QtContactEditWindow();
- virtual ~QtContactEditWindow();
+ public:
+ QtContactEditWindow();
+ virtual ~QtContactEditWindow();
- virtual void setNameSuggestions(const std::vector<std::string>& nameSuggestions);
- virtual void setContact(const JID& jid, const std::string& name, const std::vector<std::string>& groups, const std::set<std::string>& allGroups);
+ virtual void setNameSuggestions(const std::vector<std::string>& nameSuggestions);
+ virtual void setContact(const JID& jid, const std::string& name, const std::vector<std::string>& groups, const std::set<std::string>& allGroups);
- void setEnabled(bool);
- void show();
- void hide();
+ void setEnabled(bool);
+ void show();
+ void hide();
- static bool confirmContactDeletion(const JID& jid);
+ static bool confirmContactDeletion(const JID& jid);
- private slots:
- void handleRemoveContact();
- void handleUpdateContact();
+ private slots:
+ void handleRemoveContact();
+ void handleUpdateContact();
- private:
- JID jid_;
- QVBoxLayout* groupsLayout_;
- QLabel* jidLabel_;
- QtContactEditWidget* contactEditWidget_;
- };
+ private:
+ JID jid_;
+ QVBoxLayout* groupsLayout_;
+ QLabel* jidLabel_;
+ QtContactEditWidget* contactEditWidget_;
+ };
}
diff --git a/Swift/QtUI/QtDBUSURIHandler.cpp b/Swift/QtUI/QtDBUSURIHandler.cpp
index f71e16e..c873676 100644
--- a/Swift/QtUI/QtDBUSURIHandler.cpp
+++ b/Swift/QtUI/QtDBUSURIHandler.cpp
@@ -1,41 +1,41 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtDBUSURIHandler.h"
+#include <Swift/QtUI/QtDBUSURIHandler.h>
#include <QDBusAbstractAdaptor>
#include <QDBusConnection>
-#include "QtSwiftUtil.h"
+#include <Swift/QtUI/QtSwiftUtil.h>
using namespace Swift;
namespace {
- class DBUSAdaptor: public QDBusAbstractAdaptor {
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "im.swift.Swift.URIHandler");
- public:
- DBUSAdaptor(QtDBUSURIHandler* uriHandler) : QDBusAbstractAdaptor(uriHandler), uriHandler(uriHandler) {
- }
-
- public slots:
- void openURI(const QString& uri) {
- uriHandler->onURI(Q2PSTRING(uri));
- }
-
- private:
- QtDBUSURIHandler* uriHandler;
- };
+ class DBUSAdaptor: public QDBusAbstractAdaptor {
+ Q_OBJECT
+ Q_CLASSINFO("D-Bus Interface", "im.swift.Swift.URIHandler");
+ public:
+ DBUSAdaptor(QtDBUSURIHandler* uriHandler) : QDBusAbstractAdaptor(uriHandler), uriHandler(uriHandler) {
+ }
+
+ public slots:
+ void openURI(const QString& uri) {
+ uriHandler->onURI(Q2PSTRING(uri));
+ }
+
+ private:
+ QtDBUSURIHandler* uriHandler;
+ };
}
QtDBUSURIHandler::QtDBUSURIHandler() {
- new DBUSAdaptor(this);
- QDBusConnection connection = QDBusConnection::sessionBus();
- connection.registerService("im.swift.Swift.URIHandler");
- connection.registerObject("/", this);
+ new DBUSAdaptor(this);
+ QDBusConnection connection = QDBusConnection::sessionBus();
+ connection.registerService("im.swift.Swift.URIHandler");
+ connection.registerObject("/", this);
}
#include "QtDBUSURIHandler.moc"
diff --git a/Swift/QtUI/QtDBUSURIHandler.h b/Swift/QtUI/QtDBUSURIHandler.h
index 05c1558..3cd12f7 100644
--- a/Swift/QtUI/QtDBUSURIHandler.h
+++ b/Swift/QtUI/QtDBUSURIHandler.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,11 +7,12 @@
#pragma once
#include <QObject>
+
#include <SwifTools/URIHandler/URIHandler.h>
namespace Swift {
- class QtDBUSURIHandler : public QObject, public URIHandler {
- public:
- QtDBUSURIHandler();
- };
+ class QtDBUSURIHandler : public QObject, public URIHandler {
+ public:
+ QtDBUSURIHandler();
+ };
}
diff --git a/Swift/QtUI/QtEditBookmarkWindow.cpp b/Swift/QtUI/QtEditBookmarkWindow.cpp
index 9a7ad64..1d6b467 100644
--- a/Swift/QtUI/QtEditBookmarkWindow.cpp
+++ b/Swift/QtUI/QtEditBookmarkWindow.cpp
@@ -1,29 +1,29 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtEditBookmarkWindow.h"
+#include <Swift/QtUI/QtEditBookmarkWindow.h>
-#include "QtSwiftUtil.h"
+#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
QtEditBookmarkWindow::QtEditBookmarkWindow(UIEventStream* eventStream, const MUCBookmark& bookmark) : eventStream_(eventStream), bookmark_(bookmark) {
- name_->setText(P2QSTRING(bookmark.getName()));
- room_->setText(P2QSTRING(bookmark.getRoom().toString()));
- autojoin_->setChecked(bookmark.getAutojoin());
- nick_->setText(bookmark.getNick() ? P2QSTRING(bookmark.getNick().get()) : "");
- password_->setText(bookmark.getPassword() ? P2QSTRING(bookmark.getPassword().get()) : "");
+ name_->setText(P2QSTRING(bookmark.getName()));
+ room_->setText(P2QSTRING(bookmark.getRoom().toString()));
+ autojoin_->setChecked(bookmark.getAutojoin());
+ nick_->setText(bookmark.getNick() ? P2QSTRING(bookmark.getNick().get()) : "");
+ password_->setText(bookmark.getPassword() ? P2QSTRING(bookmark.getPassword().get()) : "");
}
bool QtEditBookmarkWindow::commit() {
- boost::optional<MUCBookmark> bookmark = createBookmarkFromForm();
- if (!bookmark) {
- return false;
- }
- eventStream_->send(boost::shared_ptr<UIEvent>(new EditMUCBookmarkUIEvent(bookmark_, *bookmark)));
- return true;
+ boost::optional<MUCBookmark> bookmark = createBookmarkFromForm();
+ if (!bookmark) {
+ return false;
+ }
+ eventStream_->send(std::make_shared<EditMUCBookmarkUIEvent>(bookmark_, *bookmark));
+ return true;
}
}
diff --git a/Swift/QtUI/QtEditBookmarkWindow.h b/Swift/QtUI/QtEditBookmarkWindow.h
index 63c5f2c..337ba1f 100644
--- a/Swift/QtUI/QtEditBookmarkWindow.h
+++ b/Swift/QtUI/QtEditBookmarkWindow.h
@@ -1,24 +1,25 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "QtBookmarkDetailWindow.h"
-#include "Swift/Controllers/UIEvents/UIEventStream.h"
-#include "Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h"
+#include <Swift/Controllers/UIEvents/EditMUCBookmarkUIEvent.h>
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
+
+#include <Swift/QtUI/QtBookmarkDetailWindow.h>
namespace Swift {
- class QtEditBookmarkWindow : public QtBookmarkDetailWindow {
- Q_OBJECT
- public:
- QtEditBookmarkWindow(UIEventStream* eventStream, const MUCBookmark& bookmark);
- bool commit();
-
- private:
- UIEventStream* eventStream_;
- MUCBookmark bookmark_;
- };
+ class QtEditBookmarkWindow : public QtBookmarkDetailWindow {
+ Q_OBJECT
+ public:
+ QtEditBookmarkWindow(UIEventStream* eventStream, const MUCBookmark& bookmark);
+ bool commit();
+
+ private:
+ UIEventStream* eventStream_;
+ MUCBookmark bookmark_;
+ };
}
diff --git a/Swift/QtUI/QtElidingLabel.cpp b/Swift/QtUI/QtElidingLabel.cpp
index f5a39f0..4707f9f 100644
--- a/Swift/QtUI/QtElidingLabel.cpp
+++ b/Swift/QtUI/QtElidingLabel.cpp
@@ -8,17 +8,17 @@
namespace Swift {
QtElidingLabel::QtElidingLabel(QWidget* parent, Qt::WindowFlags f) : QLabel(parent, f) {
- fullText_ = "";
- dirty_ = true;
- setSizes();
- setTextFormat(Qt::PlainText);
+ fullText_ = "";
+ dirty_ = true;
+ setSizes();
+ setTextFormat(Qt::PlainText);
}
QtElidingLabel::QtElidingLabel(const QString& text, QWidget* parent, Qt::WindowFlags f) : QLabel(text, parent, f) {
- fullText_ = text;
- dirty_ = true;
- setSizes();
- setTextFormat(Qt::PlainText);
+ fullText_ = text;
+ dirty_ = true;
+ setSizes();
+ setTextFormat(Qt::PlainText);
}
QtElidingLabel::~QtElidingLabel() {
@@ -26,35 +26,35 @@ QtElidingLabel::~QtElidingLabel() {
}
QSize QtElidingLabel::sizeHint() const {
- return sizeHint_;
+ return sizeHint_;
}
void QtElidingLabel::setSizes() {
- setMinimumSize(1, minimumHeight());
+ setMinimumSize(1, minimumHeight());
}
void QtElidingLabel::setText(const QString& text) {
- fullText_ = text;
- QLabel::setText(text);
- sizeHint_ = QLabel::sizeHint();
- dirty_ = true;
+ fullText_ = text;
+ QLabel::setText(text);
+ sizeHint_ = QLabel::sizeHint();
+ dirty_ = true;
}
void QtElidingLabel::paintEvent(QPaintEvent* event) {
- QRect rect = contentsRect();
- dirty_ = dirty_ || rect != lastRect_;
- if (dirty_) {
- lastRect_ = rect;
- int fontWidth = fontMetrics().width(fullText_);
- if (fontWidth > rect.width()) {
- QString elidedText(fontMetrics().elidedText(fullText_, Qt::ElideRight, rect.width(), Qt::TextShowMnemonic));
- QLabel::setText(elidedText);
- } else {
- QLabel::setText(fullText_);
- }
- dirty_ = false;
- }
- QLabel::paintEvent(event);
+ QRect rect = contentsRect();
+ dirty_ = dirty_ || rect != lastRect_;
+ if (dirty_) {
+ lastRect_ = rect;
+ int fontWidth = fontMetrics().width(fullText_);
+ if (fontWidth > rect.width()) {
+ QString elidedText(fontMetrics().elidedText(fullText_, Qt::ElideRight, rect.width(), Qt::TextShowMnemonic));
+ QLabel::setText(elidedText);
+ } else {
+ QLabel::setText(fullText_);
+ }
+ dirty_ = false;
+ }
+ QLabel::paintEvent(event);
}
}
diff --git a/Swift/QtUI/QtElidingLabel.h b/Swift/QtUI/QtElidingLabel.h
index 84fa00f..e10c39c 100644
--- a/Swift/QtUI/QtElidingLabel.h
+++ b/Swift/QtUI/QtElidingLabel.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -9,23 +9,23 @@
#include <QLabel>
namespace Swift {
- class QtElidingLabel : public QLabel {
- Q_OBJECT
- public:
- QtElidingLabel(QWidget* parent = NULL, Qt::WindowFlags f = 0);
- QtElidingLabel(const QString &text, QWidget* parent = NULL, Qt::WindowFlags f = 0);
- void setText(const QString& text);
- virtual ~QtElidingLabel();
-
- virtual QSize sizeHint() const;
+ class QtElidingLabel : public QLabel {
+ Q_OBJECT
+ public:
+ QtElidingLabel(QWidget* parent = nullptr, Qt::WindowFlags f = Qt::Widget);
+ QtElidingLabel(const QString &text, QWidget* parent = nullptr, Qt::WindowFlags f = Qt::Widget);
+ void setText(const QString& text);
+ virtual ~QtElidingLabel();
- virtual void paintEvent(QPaintEvent* event);
+ virtual QSize sizeHint() const;
- private:
- void setSizes();
- bool dirty_;
- QString fullText_;
- QRect lastRect_;
- QSize sizeHint_;
- };
+ virtual void paintEvent(QPaintEvent* event);
+
+ private:
+ void setSizes();
+ bool dirty_;
+ QString fullText_;
+ QRect lastRect_;
+ QSize sizeHint_;
+ };
}
diff --git a/Swift/QtUI/QtEmoticonCell.cpp b/Swift/QtUI/QtEmoticonCell.cpp
index 1c1f6ed..fe580aa 100644
--- a/Swift/QtUI/QtEmoticonCell.cpp
+++ b/Swift/QtUI/QtEmoticonCell.cpp
@@ -4,16 +4,22 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "QtEmoticonCell.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtEmoticonCell.h>
namespace Swift {
QtEmoticonCell::QtEmoticonCell(const QString emoticonAsText, QString filePath, QWidget* parent) : QLabel(parent), emoticonAsText_(emoticonAsText) {
- if (filePath.startsWith("qrc:/")) {
- filePath.remove(0, 3);
- }
- setPixmap(QPixmap(filePath));
- setToolTip(emoticonAsText_);
+ if (filePath.startsWith("qrc:/")) {
+ filePath.remove(0, 3);
+ }
+ setPixmap(QPixmap(filePath));
+ setToolTip(emoticonAsText_);
}
QtEmoticonCell::~QtEmoticonCell() {
@@ -21,8 +27,8 @@ QtEmoticonCell::~QtEmoticonCell() {
}
void QtEmoticonCell::mousePressEvent (QMouseEvent* event) {
- emit emoticonClicked(emoticonAsText_);
- QLabel::mousePressEvent(event);
+ emit emoticonClicked(emoticonAsText_);
+ QLabel::mousePressEvent(event);
}
}
diff --git a/Swift/QtUI/QtEmoticonCell.h b/Swift/QtUI/QtEmoticonCell.h
index 379f5d6..669d1ed 100644
--- a/Swift/QtUI/QtEmoticonCell.h
+++ b/Swift/QtUI/QtEmoticonCell.h
@@ -4,6 +4,12 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <map>
@@ -18,17 +24,17 @@ class QMouseEvent;
namespace Swift {
- class QtEmoticonCell : public QLabel {
- Q_OBJECT
- public:
- QtEmoticonCell(const QString emoticonAsText, QString filePath, QWidget* parent = 0);
- ~QtEmoticonCell();
- virtual void mousePressEvent(QMouseEvent* event);
+ class QtEmoticonCell : public QLabel {
+ Q_OBJECT
+ public:
+ QtEmoticonCell(const QString emoticonAsText, QString filePath, QWidget* parent = nullptr);
+ ~QtEmoticonCell();
+ virtual void mousePressEvent(QMouseEvent* event);
- signals:
- void emoticonClicked(QString emoticonAsText);
+ signals:
+ void emoticonClicked(QString emoticonAsText);
- private:
- QString emoticonAsText_;
- };
+ private:
+ QString emoticonAsText_;
+ };
}
diff --git a/Swift/QtUI/QtEmoticonsGrid.cpp b/Swift/QtUI/QtEmoticonsGrid.cpp
index 4a599ea..4c8c024 100644
--- a/Swift/QtUI/QtEmoticonsGrid.cpp
+++ b/Swift/QtUI/QtEmoticonsGrid.cpp
@@ -4,38 +4,42 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "QtEmoticonsGrid.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtEmoticonsGrid.h>
#include <set>
-#include <QPushButton>
+#include <boost/range/adaptor/reversed.hpp>
-#include <Swiften/Base/foreach.h>
+#include <QPushButton>
#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
-typedef std::map<std::string, std::string> EmoticonsMap; // Without this typedef compiler complains when using foreach
-
QtEmoticonsGrid::QtEmoticonsGrid(const std::map<std::string, std::string>& emoticons, QWidget* parent) : QGridLayout(parent) {
- makeUniqueEmoticonsMap(emoticons);
-
- // Create grid: 3 columns, [uniqueEmoticons_.size()/3] rows
- int row = 0;
- int column = 0;
-
- foreach(EmoticonsMap::value_type emoticon, uniqueEmoticons_) {
- QtEmoticonCell* newCell = new QtEmoticonCell(P2QSTRING(emoticon.first), P2QSTRING(emoticon.second));
- addWidget(newCell, row, column);
- connect(newCell, SIGNAL(emoticonClicked(QString)), this, SLOT(emoticonClickedSlot(QString)));
-
- column++;
- if (column >= 3) {
- column = 0;
- row++;
- }
- }
+ makeUniqueEmoticonsMap(emoticons);
+
+ // Create grid: 3 columns, [uniqueEmoticons_.size()/3] rows
+ int row = 0;
+ int column = 0;
+
+ for (auto&& emoticon : uniqueEmoticons_) {
+ QtEmoticonCell* newCell = new QtEmoticonCell(P2QSTRING(emoticon.first), P2QSTRING(emoticon.second));
+ addWidget(newCell, row, column);
+ connect(newCell, SIGNAL(emoticonClicked(QString)), this, SLOT(emoticonClickedSlot(QString)));
+
+ column++;
+ if (column >= 3) {
+ column = 0;
+ row++;
+ }
+ }
}
QtEmoticonsGrid::~QtEmoticonsGrid() {
@@ -43,17 +47,17 @@ QtEmoticonsGrid::~QtEmoticonsGrid() {
}
void QtEmoticonsGrid::makeUniqueEmoticonsMap(const std::map<std::string, std::string>& emoticons) {
- std::set<std::string> paths;
- reverse_foreach(EmoticonsMap::value_type emoticon, emoticons) {
- if (paths.find(emoticon.second) == paths.end()) {
- uniqueEmoticons_.insert(emoticon);
- paths.insert(emoticon.second);
- }
- }
+ std::set<std::string> paths;
+ for (auto&& emoticon : boost::adaptors::reverse(emoticons)) {
+ if (paths.find(emoticon.second) == paths.end()) {
+ uniqueEmoticons_.insert(emoticon);
+ paths.insert(emoticon.second);
+ }
+ }
}
void QtEmoticonsGrid::emoticonClickedSlot(QString emoticonAsText) {
- emit emoticonClicked(emoticonAsText);
+ emit emoticonClicked(emoticonAsText);
}
}
diff --git a/Swift/QtUI/QtEmoticonsGrid.h b/Swift/QtUI/QtEmoticonsGrid.h
index b045b26..b3b8ac3 100644
--- a/Swift/QtUI/QtEmoticonsGrid.h
+++ b/Swift/QtUI/QtEmoticonsGrid.h
@@ -4,6 +4,12 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <map>
@@ -20,21 +26,21 @@ class QWidget;
namespace Swift {
- class QtEmoticonsGrid : public QGridLayout {
- Q_OBJECT
- public:
- explicit QtEmoticonsGrid(const std::map<std::string, std::string>& emoticons, QWidget* parent = 0);
- virtual ~QtEmoticonsGrid();
+ class QtEmoticonsGrid : public QGridLayout {
+ Q_OBJECT
+ public:
+ explicit QtEmoticonsGrid(const std::map<std::string, std::string>& emoticons, QWidget* parent = nullptr);
+ virtual ~QtEmoticonsGrid();
- signals:
- void emoticonClicked(QString emoticonAsText);
+ signals:
+ void emoticonClicked(QString emoticonAsText);
- public slots:
- void emoticonClickedSlot(QString emoticonAsText);
+ public slots:
+ void emoticonClickedSlot(QString emoticonAsText);
- private:
- void makeUniqueEmoticonsMap(const std::map<std::string, std::string>& emoticons);
+ private:
+ void makeUniqueEmoticonsMap(const std::map<std::string, std::string>& emoticons);
- std::map<std::string, std::string> uniqueEmoticons_;
- };
+ std::map<std::string, std::string> uniqueEmoticons_;
+ };
}
diff --git a/Swift/QtUI/QtFileTransferListItemModel.cpp b/Swift/QtUI/QtFileTransferListItemModel.cpp
index ef73f4f..24d6dd1 100644
--- a/Swift/QtUI/QtFileTransferListItemModel.cpp
+++ b/Swift/QtUI/QtFileTransferListItemModel.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -14,9 +14,9 @@
#include <boost/bind.hpp>
#include <boost/cstdint.hpp>
+#include <boost/signals2.hpp>
#include <Swiften/Base/FileSize.h>
-#include <Swiften/Base/boost_bsignals.h>
#include <Swift/Controllers/FileTransfer/FileTransferController.h>
#include <Swift/Controllers/FileTransfer/FileTransferOverview.h>
@@ -25,119 +25,119 @@
namespace Swift {
-QtFileTransferListItemModel::QtFileTransferListItemModel(QObject *parent) : QAbstractItemModel(parent), fileTransferOverview(0) {
+QtFileTransferListItemModel::QtFileTransferListItemModel(QObject *parent) : QAbstractItemModel(parent), fileTransferOverview(nullptr) {
}
QtFileTransferListItemModel::~QtFileTransferListItemModel() {
- if (fileTransferOverview) {
- fileTransferOverview->onNewFileTransferController.disconnect(boost::bind(&QtFileTransferListItemModel::handleNewFileTransferController, this, _1));
- fileTransferOverview->onFileTransferListChanged.disconnect(boost::bind(&QtFileTransferListItemModel::handleFileTransferListChanged, this));
- }
+ if (fileTransferOverview) {
+ fileTransferOverview->onNewFileTransferController.disconnect(boost::bind(&QtFileTransferListItemModel::handleNewFileTransferController, this, _1));
+ fileTransferOverview->onFileTransferListChanged.disconnect(boost::bind(&QtFileTransferListItemModel::handleFileTransferListChanged, this));
+ }
}
void QtFileTransferListItemModel::setFileTransferOverview(FileTransferOverview *overview) {
- if (fileTransferOverview) {
- fileTransferOverview->onNewFileTransferController.disconnect(boost::bind(&QtFileTransferListItemModel::handleNewFileTransferController, this, _1));
- fileTransferOverview->onFileTransferListChanged.disconnect(boost::bind(&QtFileTransferListItemModel::handleFileTransferListChanged, this));
- }
- fileTransferOverview = overview;
- if (fileTransferOverview) {
- fileTransferOverview->onNewFileTransferController.connect(boost::bind(&QtFileTransferListItemModel::handleNewFileTransferController, this, _1));
- fileTransferOverview->onFileTransferListChanged.connect(boost::bind(&QtFileTransferListItemModel::handleFileTransferListChanged, this));
- }
- emit layoutAboutToBeChanged();
- emit layoutChanged();
+ if (fileTransferOverview) {
+ fileTransferOverview->onNewFileTransferController.disconnect(boost::bind(&QtFileTransferListItemModel::handleNewFileTransferController, this, _1));
+ fileTransferOverview->onFileTransferListChanged.disconnect(boost::bind(&QtFileTransferListItemModel::handleFileTransferListChanged, this));
+ }
+ fileTransferOverview = overview;
+ if (fileTransferOverview) {
+ fileTransferOverview->onNewFileTransferController.connect(boost::bind(&QtFileTransferListItemModel::handleNewFileTransferController, this, _1));
+ fileTransferOverview->onFileTransferListChanged.connect(boost::bind(&QtFileTransferListItemModel::handleFileTransferListChanged, this));
+ }
+ emit layoutAboutToBeChanged();
+ emit layoutChanged();
}
void QtFileTransferListItemModel::handleNewFileTransferController(FileTransferController* newController) {
- emit layoutAboutToBeChanged();
- emit layoutChanged();
- dataChanged(createIndex(0,0), createIndex(fileTransferOverview->getFileTransfers().size(),4));
- newController->onStateChanged.connect(boost::bind(&QtFileTransferListItemModel::handleStateChange, this, fileTransferOverview->getFileTransfers().size() - 1));
- newController->onProgressChange.connect(boost::bind(&QtFileTransferListItemModel::handleProgressChange, this, fileTransferOverview->getFileTransfers().size() - 1));
+ emit layoutAboutToBeChanged();
+ emit layoutChanged();
+ dataChanged(createIndex(0,0), createIndex(fileTransferOverview->getFileTransfers().size(),4));
+ newController->onStateChanged.connect(boost::bind(&QtFileTransferListItemModel::handleStateChange, this, fileTransferOverview->getFileTransfers().size() - 1));
+ newController->onProgressChange.connect(boost::bind(&QtFileTransferListItemModel::handleProgressChange, this, fileTransferOverview->getFileTransfers().size() - 1));
}
void QtFileTransferListItemModel::handleFileTransferListChanged() {
- emit layoutAboutToBeChanged();
- emit layoutChanged();
+ emit layoutAboutToBeChanged();
+ emit layoutChanged();
}
void QtFileTransferListItemModel::handleStateChange(int index) {
- emit dataChanged(createIndex(index, 2), createIndex(index, 2));
+ emit dataChanged(createIndex(index, 2), createIndex(index, 2));
}
void QtFileTransferListItemModel::handleProgressChange(int index) {
- emit dataChanged(createIndex(index, 3), createIndex(index, 3));
+ emit dataChanged(createIndex(index, 3), createIndex(index, 3));
}
QVariant QtFileTransferListItemModel::headerData(int section, Qt::Orientation /* orientation */, int role) const {
- if (role != Qt::DisplayRole) return QVariant();
- if (section == Direction) return QVariant(QObject::tr("Direction"));
- if (section == OtherParty) return QVariant(QObject::tr("Other Party"));
- if (section == State) return QVariant(QObject::tr("State"));
- if (section == Progress) return QVariant(QObject::tr("Progress"));
- if (section == OverallSize) return QVariant(QObject::tr("Size"));
- return QVariant();
+ if (role != Qt::DisplayRole) return QVariant();
+ if (section == Direction) return QVariant(QObject::tr("Direction"));
+ if (section == OtherParty) return QVariant(QObject::tr("Other Party"));
+ if (section == State) return QVariant(QObject::tr("State"));
+ if (section == Progress) return QVariant(QObject::tr("Progress"));
+ if (section == OverallSize) return QVariant(QObject::tr("Size"));
+ return QVariant();
}
int QtFileTransferListItemModel::columnCount(const QModelIndex& /* parent */) const {
- return NoOfColumns;
+ return NoOfColumns;
}
QVariant QtFileTransferListItemModel::data(const QModelIndex &index, int role) const {
- if (role != Qt::DisplayRole || !index.isValid() ||
- !fileTransferOverview || static_cast<size_t>(index.row()) >= fileTransferOverview->getFileTransfers().size()) {
- return QVariant();
- }
- FileTransferController* controller = fileTransferOverview->getFileTransfers().at(index.row());
- if (index.column() == Direction) {
- return controller->isIncoming() ? QVariant(QObject::tr("Incoming")) : QVariant(QObject::tr("Outgoing"));
- }
- if (index.column() == OtherParty) {
- return QVariant(P2QSTRING(controller->getOtherParty().toString()));
- }
- if (index.column() == State) {
- FileTransfer::State state = controller->getState();
- switch(state.type) {
- case FileTransfer::State::Initial:
- assert(false);
- return QVariant("");
- case FileTransfer::State::WaitingForStart:
- return QVariant(QObject::tr("Waiting for start"));
- case FileTransfer::State::WaitingForAccept:
- return QVariant(QObject::tr("Waiting for other side to accept"));
- case FileTransfer::State::Negotiating:
- return QVariant(QObject::tr("Negotiating"));
- case FileTransfer::State::Transferring:
- return QVariant(QObject::tr("Transferring"));
- case FileTransfer::State::Finished:
- return QVariant(QObject::tr("Finished"));
- case FileTransfer::State::Failed:
- return QVariant(QObject::tr("Failed"));
- case FileTransfer::State::Canceled:
- return QVariant(QObject::tr("Canceled"));
- }
- }
-
- if (index.column() == Progress) {
- return QVariant(QString::number(controller->getProgress()));
- }
- if (index.column() == OverallSize) {
- return QVariant(P2QSTRING(formatSize((controller->getSize()))));
- }
- return QVariant();
+ if (role != Qt::DisplayRole || !index.isValid() ||
+ !fileTransferOverview || static_cast<size_t>(index.row()) >= fileTransferOverview->getFileTransfers().size()) {
+ return QVariant();
+ }
+ FileTransferController* controller = fileTransferOverview->getFileTransfers().at(index.row());
+ if (index.column() == Direction) {
+ return controller->isIncoming() ? QVariant(QObject::tr("Incoming")) : QVariant(QObject::tr("Outgoing"));
+ }
+ if (index.column() == OtherParty) {
+ return QVariant(P2QSTRING(controller->getOtherParty().toString()));
+ }
+ if (index.column() == State) {
+ FileTransfer::State state = controller->getState();
+ switch(state.type) {
+ case FileTransfer::State::Initial:
+ assert(false);
+ return QVariant("");
+ case FileTransfer::State::WaitingForStart:
+ return QVariant(QObject::tr("Waiting for start"));
+ case FileTransfer::State::WaitingForAccept:
+ return QVariant(QObject::tr("Waiting for other side to accept"));
+ case FileTransfer::State::Negotiating:
+ return QVariant(QObject::tr("Negotiating"));
+ case FileTransfer::State::Transferring:
+ return QVariant(QObject::tr("Transferring"));
+ case FileTransfer::State::Finished:
+ return QVariant(QObject::tr("Finished"));
+ case FileTransfer::State::Failed:
+ return QVariant(QObject::tr("Failed"));
+ case FileTransfer::State::Canceled:
+ return QVariant(QObject::tr("Canceled"));
+ }
+ }
+
+ if (index.column() == Progress) {
+ return QVariant(QString::number(controller->getProgress()));
+ }
+ if (index.column() == OverallSize) {
+ return QVariant(P2QSTRING(formatSize((controller->getSize()))));
+ }
+ return QVariant();
}
QModelIndex QtFileTransferListItemModel::parent(const QModelIndex& /* child */) const {
- return createIndex(0,0);
+ return createIndex(0,0);
}
int QtFileTransferListItemModel::rowCount(const QModelIndex& /* parent */) const {
- return fileTransferOverview ? fileTransferOverview->getFileTransfers().size() : 0;
+ return fileTransferOverview ? fileTransferOverview->getFileTransfers().size() : 0;
}
QModelIndex QtFileTransferListItemModel::index(int row, int column, const QModelIndex& /* parent */) const {
- return createIndex(row, column, static_cast<void*>(0));
+ return createIndex(row, column, static_cast<void*>(nullptr));
}
}
diff --git a/Swift/QtUI/QtFileTransferListItemModel.h b/Swift/QtUI/QtFileTransferListItemModel.h
index 64cdca4..4d1e48b 100644
--- a/Swift/QtUI/QtFileTransferListItemModel.h
+++ b/Swift/QtUI/QtFileTransferListItemModel.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -20,42 +20,42 @@ class FileTransferController;
class FileTransferOverview;
class QtFileTransferListItemModel : public QAbstractItemModel {
- Q_OBJECT
+ Q_OBJECT
public:
- explicit QtFileTransferListItemModel(QObject *parent = 0);
- virtual ~QtFileTransferListItemModel();
+ explicit QtFileTransferListItemModel(QObject *parent = nullptr);
+ virtual ~QtFileTransferListItemModel();
- void setFileTransferOverview(FileTransferOverview*);
+ void setFileTransferOverview(FileTransferOverview*);
- QVariant headerData(int section, Qt::Orientation orientation, int role) const;
- int columnCount(const QModelIndex &parent) const;
- QVariant data(const QModelIndex &index, int role) const;
- QModelIndex parent(const QModelIndex &child) const;
- int rowCount(const QModelIndex &parent) const;
- QModelIndex index(int row, int column, const QModelIndex &parent) const;
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+ int columnCount(const QModelIndex &parent) const;
+ QVariant data(const QModelIndex &index, int role) const;
+ QModelIndex parent(const QModelIndex &child) const;
+ int rowCount(const QModelIndex &parent) const;
+ QModelIndex index(int row, int column, const QModelIndex &parent) const;
private:
- enum Columns {
- Direction = 0,
- OtherParty,
- State,
- Progress,
- OverallSize,
- NoOfColumns
- };
+ enum Columns {
+ Direction = 0,
+ OtherParty,
+ State,
+ Progress,
+ OverallSize,
+ NoOfColumns
+ };
private:
- void handleNewFileTransferController(FileTransferController*);
- void handleFileTransferListChanged();
- void handleStateChange(int index);
- void handleProgressChange(int index);
+ void handleNewFileTransferController(FileTransferController*);
+ void handleFileTransferListChanged();
+ void handleStateChange(int index);
+ void handleProgressChange(int index);
signals:
public slots:
private:
- FileTransferOverview *fileTransferOverview;
+ FileTransferOverview *fileTransferOverview;
};
diff --git a/Swift/QtUI/QtFileTransferListWidget.cpp b/Swift/QtUI/QtFileTransferListWidget.cpp
index d95cd06..8b855b0 100644
--- a/Swift/QtUI/QtFileTransferListWidget.cpp
+++ b/Swift/QtUI/QtFileTransferListWidget.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -25,87 +25,87 @@
namespace Swift {
-QtFileTransferListWidget::QtFileTransferListWidget() : fileTransferOverview(0) {
- QVBoxLayout* layout = new QVBoxLayout(this);
- layout->setSpacing(0);
- layout->setContentsMargins(0,0,0,0);
+QtFileTransferListWidget::QtFileTransferListWidget() : fileTransferOverview(nullptr) {
+ QVBoxLayout* layout = new QVBoxLayout(this);
+ layout->setSpacing(0);
+ layout->setContentsMargins(0,0,0,0);
- treeView = new QTreeView(this);
- treeView->setRootIsDecorated(false);
- treeView->setItemsExpandable(false);
- layout->addWidget(treeView);
+ treeView = new QTreeView(this);
+ treeView->setRootIsDecorated(false);
+ treeView->setItemsExpandable(false);
+ layout->addWidget(treeView);
- itemModel = new QtFileTransferListItemModel();
- treeView->setModel(itemModel);
+ itemModel = new QtFileTransferListItemModel();
+ treeView->setModel(itemModel);
- QWidget* bottom = new QWidget(this);
- layout->addWidget(bottom);
- bottom->setAutoFillBackground(true);
+ QWidget* bottom = new QWidget(this);
+ layout->addWidget(bottom);
+ bottom->setAutoFillBackground(true);
- QHBoxLayout* buttonLayout = new QHBoxLayout(bottom);
- buttonLayout->setContentsMargins(10,0,20,0);
- buttonLayout->setSpacing(0);
+ QHBoxLayout* buttonLayout = new QHBoxLayout(bottom);
+ buttonLayout->setContentsMargins(10,0,20,0);
+ buttonLayout->setSpacing(0);
- clearFinished = new QPushButton(tr("Clear all"), bottom);
- clearFinished->setEnabled(false);
- connect(clearFinished, SIGNAL(clicked()), this, SLOT(clearInactiveTransfers()));
- buttonLayout->addWidget(clearFinished);
+ clearFinished = new QPushButton(tr("Clear all"), bottom);
+ clearFinished->setEnabled(false);
+ connect(clearFinished, SIGNAL(clicked()), this, SLOT(clearInactiveTransfers()));
+ buttonLayout->addWidget(clearFinished);
- setWindowTitle(tr("File Transfer List"));
- emit titleUpdated();
+ setWindowTitle(tr("File Transfer List"));
+ emit titleUpdated();
}
QtFileTransferListWidget::~QtFileTransferListWidget() {
- if (fileTransferOverview) {
- fileTransferOverview->onFileTransferListChanged.disconnect(boost::bind(&QtFileTransferListWidget::handleFileTransferListChanged, this));
- fileTransferOverview = NULL;
- }
- delete itemModel;
+ if (fileTransferOverview) {
+ fileTransferOverview->onFileTransferListChanged.disconnect(boost::bind(&QtFileTransferListWidget::handleFileTransferListChanged, this));
+ fileTransferOverview = nullptr;
+ }
+ delete itemModel;
}
void QtFileTransferListWidget::showEvent(QShowEvent* event) {
- emit windowOpening();
- emit titleUpdated(); /* This just needs to be somewhere after construction */
- QWidget::showEvent(event);
+ emit windowOpening();
+ emit titleUpdated(); /* This just needs to be somewhere after construction */
+ QWidget::showEvent(event);
}
void QtFileTransferListWidget::handleFileTransferListChanged() {
- clearFinished->setEnabled(fileTransferOverview->isClearable());
+ clearFinished->setEnabled(fileTransferOverview->isClearable());
}
void QtFileTransferListWidget::clearInactiveTransfers() {
- fileTransferOverview->clearFinished();
+ fileTransferOverview->clearFinished();
}
void QtFileTransferListWidget::show() {
- QWidget::show();
- emit windowOpening();
+ QWidget::show();
+ emit windowOpening();
}
void QtFileTransferListWidget::activate() {
- emit wantsToActivate();
+ emit wantsToActivate();
}
void QtFileTransferListWidget::setFileTransferOverview(FileTransferOverview *overview) {
- if (fileTransferOverview) {
- fileTransferOverview->onFileTransferListChanged.disconnect(boost::bind(&QtFileTransferListWidget::handleFileTransferListChanged, this));
- fileTransferOverview = NULL;
- }
- if (overview) {
- fileTransferOverview = overview;
- fileTransferOverview->onFileTransferListChanged.connect(boost::bind(&QtFileTransferListWidget::handleFileTransferListChanged, this));
- clearFinished->setEnabled(fileTransferOverview->isClearable());
- }
- itemModel->setFileTransferOverview(overview);
+ if (fileTransferOverview) {
+ fileTransferOverview->onFileTransferListChanged.disconnect(boost::bind(&QtFileTransferListWidget::handleFileTransferListChanged, this));
+ fileTransferOverview = nullptr;
+ }
+ if (overview) {
+ fileTransferOverview = overview;
+ fileTransferOverview->onFileTransferListChanged.connect(boost::bind(&QtFileTransferListWidget::handleFileTransferListChanged, this));
+ clearFinished->setEnabled(fileTransferOverview->isClearable());
+ }
+ itemModel->setFileTransferOverview(overview);
}
std::string QtFileTransferListWidget::getID() const {
- return "QtFileTransferListWidget";
+ return "QtFileTransferListWidget";
}
void QtFileTransferListWidget::closeEvent(QCloseEvent* event) {
- emit windowClosing();
- event->accept();
+ emit windowClosing();
+ event->accept();
}
}
diff --git a/Swift/QtUI/QtFileTransferListWidget.h b/Swift/QtUI/QtFileTransferListWidget.h
index 740eb15..cfc7dd2 100644
--- a/Swift/QtUI/QtFileTransferListWidget.h
+++ b/Swift/QtUI/QtFileTransferListWidget.h
@@ -27,33 +27,33 @@ class FileTransferOverview;
class QtFileTransferListItemModel;
class QtFileTransferListWidget : public QtTabbable, public FileTransferListWidget {
- Q_OBJECT
+ Q_OBJECT
public:
- QtFileTransferListWidget();
- virtual ~QtFileTransferListWidget();
+ QtFileTransferListWidget();
+ virtual ~QtFileTransferListWidget();
- void show();
- void activate();
+ void show();
+ void activate();
- void setFileTransferOverview(FileTransferOverview *);
+ void setFileTransferOverview(FileTransferOverview *);
- virtual std::string getID() const;
+ virtual std::string getID() const;
private:
- virtual void closeEvent(QCloseEvent* event);
- virtual void showEvent(QShowEvent* event);
- void handleFileTransferListChanged();
+ virtual void closeEvent(QCloseEvent* event);
+ virtual void showEvent(QShowEvent* event);
+ void handleFileTransferListChanged();
private slots:
- void clearInactiveTransfers();
+ void clearInactiveTransfers();
private:
- QTreeView* treeView;
+ QTreeView* treeView;
- QtFileTransferListItemModel* itemModel;
- FileTransferOverview* fileTransferOverview;
- QPushButton* clearFinished;
+ QtFileTransferListItemModel* itemModel;
+ FileTransferOverview* fileTransferOverview;
+ QPushButton* clearFinished;
};
}
diff --git a/Swift/QtUI/QtFormResultItemModel.cpp b/Swift/QtUI/QtFormResultItemModel.cpp
index b0b0749..b35bb4f 100644
--- a/Swift/QtUI/QtFormResultItemModel.cpp
+++ b/Swift/QtUI/QtFormResultItemModel.cpp
@@ -5,17 +5,16 @@
*/
/*
- * Copyright (c) 2013 Isode Limited.
+ * Copyright (c) 2013-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtFormResultItemModel.h"
+#include <Swift/QtUI/QtFormResultItemModel.h>
#include <boost/algorithm/string/join.hpp>
#include <Swift/QtUI/QtSwiftUtil.h>
-#include <Swiften/Base/foreach.h>
namespace Swift {
@@ -28,67 +27,67 @@ QtFormResultItemModel::QtFormResultItemModel(QObject* parent, Form::ref formResu
}
void QtFormResultItemModel::setForm(Form::ref formResult) {
- emit layoutAboutToBeChanged();
- formResult_ = formResult;
- emit layoutChanged();
+ emit layoutAboutToBeChanged();
+ formResult_ = formResult;
+ emit layoutChanged();
}
const Form::ref QtFormResultItemModel::getForm() const {
- return formResult_;
+ return formResult_;
}
QVariant QtFormResultItemModel::headerData(int section, Qt::Orientation /*orientation*/, int role) const {
- if (!formResult_) return QVariant();
- if (role != Qt::DisplayRole) return QVariant();
- if (static_cast<size_t>(section) >= formResult_->getReportedFields().size()) return QVariant();
- return QVariant(P2QSTRING(formResult_->getReportedFields().at(section)->getLabel()));
+ if (!formResult_) return QVariant();
+ if (role != Qt::DisplayRole) return QVariant();
+ if (static_cast<size_t>(section) >= formResult_->getReportedFields().size()) return QVariant();
+ return QVariant(P2QSTRING(formResult_->getReportedFields().at(section)->getLabel()));
}
int QtFormResultItemModel::rowCount(const QModelIndex &/*parent*/) const {
- if (!formResult_) return 0;
- return formResult_->getItems().size();
+ if (!formResult_) return 0;
+ return formResult_->getItems().size();
}
int QtFormResultItemModel::columnCount(const QModelIndex &/*parent*/) const {
- if (!formResult_) return 0;
- return formResult_->getReportedFields().size();
+ if (!formResult_) return 0;
+ return formResult_->getReportedFields().size();
}
QVariant QtFormResultItemModel::data(const QModelIndex &index, int role) const {
- if (!formResult_) return QVariant();
- if (role != Qt::DisplayRole || !index.isValid()) {
- return QVariant();
- }
+ if (!formResult_) return QVariant();
+ if (role != Qt::DisplayRole || !index.isValid()) {
+ return QVariant();
+ }
- if (static_cast<size_t>(index.row()) >= formResult_->getItems().size()) return QVariant();
- if (static_cast<size_t>(index.column()) >= formResult_->getReportedFields().size()) return QVariant();
+ if (static_cast<size_t>(index.row()) >= formResult_->getItems().size()) return QVariant();
+ if (static_cast<size_t>(index.column()) >= formResult_->getReportedFields().size()) return QVariant();
- Form::FormItem item = formResult_->getItems().at(index.row());
+ Form::FormItem item = formResult_->getItems().at(index.row());
- return QVariant(P2QSTRING(getFieldValue(item, index.column())));
+ return QVariant(P2QSTRING(getFieldValue(item, index.column())));
}
const std::string QtFormResultItemModel::getFieldValue(const Form::FormItem& item, const int column) const {
- // determine field name
- std::string name = formResult_->getReportedFields().at(column)->getName();
-
- foreach(FormField::ref field, item) {
- if (field->getName() == name) {
- std::string delimiter = "";
- if (field->getType() == FormField::TextMultiType) {
- delimiter = "\n";
- }
- else if (field->getType() == FormField::JIDMultiType) {
- delimiter = ", ";
- }
- else if (field->getType() == FormField::ListMultiType) {
- delimiter = ", ";
- }
- return boost::algorithm::join(field->getValues(), delimiter);
- }
- }
-
- return "";
+ // determine field name
+ std::string name = formResult_->getReportedFields().at(column)->getName();
+
+ for (auto&& field : item) {
+ if (field->getName() == name) {
+ std::string delimiter = "";
+ if (field->getType() == FormField::TextMultiType) {
+ delimiter = "\n";
+ }
+ else if (field->getType() == FormField::JIDMultiType) {
+ delimiter = ", ";
+ }
+ else if (field->getType() == FormField::ListMultiType) {
+ delimiter = ", ";
+ }
+ return boost::algorithm::join(field->getValues(), delimiter);
+ }
+ }
+
+ return "";
}
}
diff --git a/Swift/QtUI/QtFormResultItemModel.h b/Swift/QtUI/QtFormResultItemModel.h
index f383f74..47f3549 100644
--- a/Swift/QtUI/QtFormResultItemModel.h
+++ b/Swift/QtUI/QtFormResultItemModel.h
@@ -13,24 +13,24 @@
namespace Swift {
class QtFormResultItemModel : public QAbstractTableModel {
- Q_OBJECT
- public:
- QtFormResultItemModel(QObject* parent);
- QtFormResultItemModel(QObject* parent, Form::ref formResult);
+ Q_OBJECT
+ public:
+ QtFormResultItemModel(QObject* parent);
+ QtFormResultItemModel(QObject* parent, Form::ref formResult);
- void setForm(Form::ref formResult);
- const Form::ref getForm() const;
+ void setForm(Form::ref formResult);
+ const Form::ref getForm() const;
- virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
- virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
- virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
- virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const;
+ virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
- private:
- const std::string getFieldValue(const Form::FormItem& item, const int column) const;
+ private:
+ const std::string getFieldValue(const Form::FormItem& item, const int column) const;
- private:
- Form::ref formResult_;
+ private:
+ Form::ref formResult_;
};
}
diff --git a/Swift/QtUI/QtFormWidget.cpp b/Swift/QtUI/QtFormWidget.cpp
index 58af2cd..96c2da0 100644
--- a/Swift/QtUI/QtFormWidget.cpp
+++ b/Swift/QtUI/QtFormWidget.cpp
@@ -1,68 +1,70 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/QtFormWidget.h>
+#include <memory>
+
+#include <boost/algorithm/string/join.hpp>
+
+#include <QCheckBox>
#include <QGridLayout>
#include <QLabel>
-#include <QListWidget>
#include <QLineEdit>
-#include <QTextEdit>
-#include <QCheckBox>
+#include <QListWidget>
#include <QScrollArea>
+#include <QTextEdit>
+
#include <qdebug.h>
#include <Swift/QtUI/QtSwiftUtil.h>
-#include <Swiften/Base/foreach.h>
-#include <boost/algorithm/string/join.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
namespace Swift {
QtFormWidget::QtFormWidget(Form::ref form, QWidget* parent) : QWidget(parent), form_(form) {
- QGridLayout* thisLayout = new QGridLayout(this);
- int row = 0;
- if (!form->getTitle().empty()) {
- QLabel* instructions = new QLabel(("<b>" + form->getTitle() + "</b>").c_str(), this);
- thisLayout->addWidget(instructions, row++, 0, 1, 2);
- }
- if (!form->getInstructions().empty()) {
- QLabel* instructions = new QLabel(form->getInstructions().c_str(), this);
- thisLayout->addWidget(instructions, row++, 0, 1, 2);
- }
- QScrollArea* scrollArea = new QScrollArea(this);
- thisLayout->addWidget(scrollArea);
- QWidget* scroll = new QWidget(this);
- QGridLayout* layout = new QGridLayout(scroll);
- const std::vector<Form::FormItem> items = form->getItems();
- if (items.empty()) { /* single item forms */
- foreach (FormField::ref field, form->getFields()) {
- QWidget* widget = createWidget(field, field->getType(), 0);
- if (widget) {
- layout->addWidget(new QLabel(field->getLabel().c_str(), this), row, 0);
- layout->addWidget(widget, row++, 1);
- }
- }
- } else { /* multi-item forms */
- const Form::FormItem& headers = form->getFields();
- for (size_t i = 0; i < items.size(); ++i) {
- const Form::FormItem& item = items[i];
- assert(item.size() == headers.size());
- for (size_t j = 0; j < item.size(); ++j) {
- QWidget* widget = createWidget(item[j], headers[j]->getType(), i);
- if (widget) {
- layout->addWidget(new QLabel(item[j]->getLabel().c_str(), this), row, 0);
- layout->addWidget(widget, row++, 1);
- }
- }
- }
- }
- scrollArea->setWidget(scroll);
- scrollArea->setWidgetResizable(true);
- setEditable(form->getType() != Form::CancelType && form->getType() != Form::ResultType);
+ QGridLayout* thisLayout = new QGridLayout(this);
+ int row = 0;
+ if (!form->getTitle().empty()) {
+ QLabel* instructions = new QLabel(("<b>" + form->getTitle() + "</b>").c_str(), this);
+ thisLayout->addWidget(instructions, row++, 0, 1, 2);
+ }
+ if (!form->getInstructions().empty()) {
+ QLabel* instructions = new QLabel(form->getInstructions().c_str(), this);
+ thisLayout->addWidget(instructions, row++, 0, 1, 2);
+ }
+ QScrollArea* scrollArea = new QScrollArea(this);
+ thisLayout->addWidget(scrollArea);
+ QWidget* scroll = new QWidget(this);
+ QGridLayout* layout = new QGridLayout(scroll);
+ const std::vector<Form::FormItem> items = form->getItems();
+ if (items.empty()) { /* single item forms */
+ for (auto&& field : form->getFields()) {
+ QWidget* widget = createWidget(field, field->getType(), 0);
+ if (widget) {
+ layout->addWidget(new QLabel(field->getLabel().c_str(), this), row, 0);
+ layout->addWidget(widget, row++, 1);
+ }
+ }
+ } else { /* multi-item forms */
+ const Form::FormItem& headers = form->getFields();
+ for (size_t i = 0; i < items.size(); ++i) {
+ const Form::FormItem& item = items[i];
+ assert(item.size() == headers.size());
+ for (size_t j = 0; j < item.size(); ++j) {
+ QWidget* widget = createWidget(item[j], headers[j]->getType(), i);
+ if (widget) {
+ layout->addWidget(new QLabel(item[j]->getLabel().c_str(), this), row, 0);
+ layout->addWidget(widget, row++, 1);
+ }
+ }
+ }
+ }
+ scrollArea->setWidget(scroll);
+ scrollArea->setWidgetResizable(true);
+ setEditable(form->getType() != Form::CancelType && form->getType() != Form::ResultType);
}
QtFormWidget::~QtFormWidget() {
@@ -70,168 +72,168 @@ QtFormWidget::~QtFormWidget() {
}
QListWidget* QtFormWidget::createList(FormField::ref field) {
- QListWidget* listWidget = new QListWidget(this);
- listWidget->setSortingEnabled(false);
- listWidget->setSelectionMode(field->getType() == FormField::ListMultiType ? QAbstractItemView::MultiSelection : QAbstractItemView::SingleSelection);
- std::vector<bool> selected;
- /* if this is an editable form, use the 'options' list, otherwise use the 'values' list */
- if (form_->getType() != Form::FormType) {
- foreach (const std::string& value, field->getValues()) {
- listWidget->addItem(P2QSTRING(value));
- selected.push_back(false);
- }
- } else {
- foreach (FormField::Option option, field->getOptions()) {
- listWidget->addItem(option.label.c_str());
- if (field->getType() == FormField::ListSingleType) {
- selected.push_back(!field->getValues().empty() && option.value == field->getValues()[0]);
- }
- else if (field->getType() == FormField::ListMultiType) {
- std::string text = option.value;
- selected.push_back(std::find(field->getValues().begin(), field->getValues().end(), text) != field->getValues().end());
- }
- }
- }
- for (int i = 0; i < listWidget->count(); i++) {
- QListWidgetItem* item = listWidget->item(i);
- item->setSelected(selected[i]);
- }
- return listWidget;
+ QListWidget* listWidget = new QListWidget(this);
+ listWidget->setSortingEnabled(false);
+ listWidget->setSelectionMode(field->getType() == FormField::ListMultiType ? QAbstractItemView::MultiSelection : QAbstractItemView::SingleSelection);
+ std::vector<bool> selected;
+ /* if this is an editable form, use the 'options' list, otherwise use the 'values' list */
+ if (form_->getType() != Form::FormType) {
+ for (const auto& value : field->getValues()) {
+ listWidget->addItem(P2QSTRING(value));
+ selected.push_back(false);
+ }
+ } else {
+ for (auto&& option : field->getOptions()) {
+ listWidget->addItem(option.label.c_str());
+ if (field->getType() == FormField::ListSingleType) {
+ selected.push_back(!field->getValues().empty() && option.value == field->getValues()[0]);
+ }
+ else if (field->getType() == FormField::ListMultiType) {
+ std::string text = option.value;
+ selected.push_back(std::find(field->getValues().begin(), field->getValues().end(), text) != field->getValues().end());
+ }
+ }
+ }
+ for (int i = 0; i < listWidget->count(); i++) {
+ QListWidgetItem* item = listWidget->item(i);
+ item->setSelected(selected[i]);
+ }
+ return listWidget;
}
QWidget* QtFormWidget::createWidget(FormField::ref field, const FormField::Type type, const size_t index) {
- QWidget* widget = NULL;
- if (type == FormField::BooleanType) {
- QCheckBox* checkWidget = new QCheckBox(this);
- checkWidget->setCheckState(field->getBoolValue() ? Qt::Checked : Qt::Unchecked);
- widget = checkWidget;
- }
- if (type == FormField::FixedType) {
- QString value = field->getFixedValue().c_str();
- widget = new QLabel(value, this);
- }
- if (type == FormField::ListSingleType) {
- widget = createList(field);
- }
- if (type == FormField::TextMultiType) {
- QString value = field->getTextMultiValue().c_str();
- QTextEdit* textWidget = new QTextEdit(this);
- textWidget->setPlainText(value);
- widget = textWidget;
- }
- if (type == FormField::TextPrivateType) {
- QString value = field->getTextPrivateValue().c_str();
- QLineEdit* lineWidget = new QLineEdit(value, this);
- lineWidget->setEchoMode(QLineEdit::Password);
- widget = lineWidget;
- }
- if (type == FormField::TextSingleType) {
- QString value = field->getTextSingleValue().c_str();
- widget = new QLineEdit(value, this);
- }
- if (type == FormField::JIDSingleType) {
- QString value = field->getJIDSingleValue().toString().c_str();
- widget = new QLineEdit(value, this);
- }
- if (type == FormField::JIDMultiType) {
- QString text = boost::join(field->getValues(), "\n").c_str();
- QTextEdit* textWidget = new QTextEdit(this);
- textWidget->setPlainText(text);
- widget = textWidget;
- }
- if (type == FormField::ListMultiType) {
- widget = createList(field);
- }
- std::string indexString;
- if (index) {
- /* for multi-item forms we need to distinguish between the different rows */
- indexString = boost::lexical_cast<std::string>(index);
- }
- fields_[field->getName() + indexString] = widget;
- return widget;
+ QWidget* widget = nullptr;
+ if (type == FormField::BooleanType) {
+ QCheckBox* checkWidget = new QCheckBox(this);
+ checkWidget->setCheckState(field->getBoolValue() ? Qt::Checked : Qt::Unchecked);
+ widget = checkWidget;
+ }
+ if (type == FormField::FixedType) {
+ QString value = field->getFixedValue().c_str();
+ widget = new QLabel(value, this);
+ }
+ if (type == FormField::ListSingleType) {
+ widget = createList(field);
+ }
+ if (type == FormField::TextMultiType) {
+ QString value = field->getTextMultiValue().c_str();
+ QTextEdit* textWidget = new QTextEdit(this);
+ textWidget->setPlainText(value);
+ widget = textWidget;
+ }
+ if (type == FormField::TextPrivateType) {
+ QString value = field->getTextPrivateValue().c_str();
+ QLineEdit* lineWidget = new QLineEdit(value, this);
+ lineWidget->setEchoMode(QLineEdit::Password);
+ widget = lineWidget;
+ }
+ if (type == FormField::TextSingleType) {
+ QString value = field->getTextSingleValue().c_str();
+ widget = new QLineEdit(value, this);
+ }
+ if (type == FormField::JIDSingleType) {
+ QString value = field->getJIDSingleValue().toString().c_str();
+ widget = new QLineEdit(value, this);
+ }
+ if (type == FormField::JIDMultiType) {
+ QString text = boost::join(field->getValues(), "\n").c_str();
+ QTextEdit* textWidget = new QTextEdit(this);
+ textWidget->setPlainText(text);
+ widget = textWidget;
+ }
+ if (type == FormField::ListMultiType) {
+ widget = createList(field);
+ }
+ std::string indexString;
+ if (index) {
+ /* for multi-item forms we need to distinguish between the different rows */
+ indexString = boost::lexical_cast<std::string>(index);
+ }
+ fields_[field->getName() + indexString] = widget;
+ return widget;
}
Form::ref QtFormWidget::getCompletedForm() {
- Form::ref result(new Form(Form::SubmitType));
- foreach (boost::shared_ptr<FormField> field, form_->getFields()) {
- boost::shared_ptr<FormField> resultField = boost::make_shared<FormField>(field->getType());
- if (field->getType() == FormField::BooleanType) {
- resultField->setBoolValue(qobject_cast<QCheckBox*>(fields_[field->getName()])->checkState() == Qt::Checked);
- }
- if (field->getType() == FormField::FixedType || field->getType() == FormField::HiddenType) {
- resultField->addValue(field->getValues().empty() ? "" : field->getValues()[0]);
- }
- if (field->getType() == FormField::ListSingleType) {
- QListWidget* listWidget = qobject_cast<QListWidget*>(fields_[field->getName()]);
- if (listWidget->selectedItems().size() > 0) {
- int i = listWidget->row(listWidget->selectedItems()[0]);
- resultField->addValue(field->getOptions()[i].value);
- }
- }
- if (field->getType() == FormField::TextMultiType) {
- QTextEdit* widget = qobject_cast<QTextEdit*>(fields_[field->getName()]);
- QString string = widget->toPlainText();
- if (!string.isEmpty()) {
- resultField->setTextMultiValue(Q2PSTRING(string));
- }
- }
- if (field->getType() == FormField::TextPrivateType || field->getType() == FormField::TextSingleType || field->getType() == FormField::JIDSingleType) {
- QLineEdit* widget = qobject_cast<QLineEdit*>(fields_[field->getName()]);
- QString string = widget->text();
- if (!string.isEmpty()) {
- resultField->addValue(Q2PSTRING(string));
- }
- }
- if (field->getType() == FormField::JIDMultiType) {
- QTextEdit* widget = qobject_cast<QTextEdit*>(fields_[field->getName()]);
- QString string = widget->toPlainText();
- if (!string.isEmpty()) {
- QStringList lines = string.split("\n");
- foreach (QString line, lines) {
- resultField->addValue(Q2PSTRING(line));
- }
- }
- }
- if (field->getType() == FormField::ListMultiType) {
- QListWidget* listWidget = qobject_cast<QListWidget*>(fields_[field->getName()]);
- foreach (QListWidgetItem* item, listWidget->selectedItems()) {
- resultField->addValue(field->getOptions()[listWidget->row(item)].value);
- }
- }
- resultField->setName(field->getName());
- result->addField(resultField);
- }
- return result;
+ Form::ref result(new Form(Form::SubmitType));
+ for (auto&& field : form_->getFields()) {
+ std::shared_ptr<FormField> resultField = std::make_shared<FormField>(field->getType());
+ if (field->getType() == FormField::BooleanType) {
+ resultField->setBoolValue(qobject_cast<QCheckBox*>(fields_[field->getName()])->checkState() == Qt::Checked);
+ }
+ if (field->getType() == FormField::FixedType || field->getType() == FormField::HiddenType) {
+ resultField->addValue(field->getValues().empty() ? "" : field->getValues()[0]);
+ }
+ if (field->getType() == FormField::ListSingleType) {
+ QListWidget* listWidget = qobject_cast<QListWidget*>(fields_[field->getName()]);
+ if (listWidget->selectedItems().size() > 0) {
+ int i = listWidget->row(listWidget->selectedItems()[0]);
+ resultField->addValue(field->getOptions()[i].value);
+ }
+ }
+ if (field->getType() == FormField::TextMultiType) {
+ QTextEdit* widget = qobject_cast<QTextEdit*>(fields_[field->getName()]);
+ QString string = widget->toPlainText();
+ if (!string.isEmpty()) {
+ resultField->setTextMultiValue(Q2PSTRING(string));
+ }
+ }
+ if (field->getType() == FormField::TextPrivateType || field->getType() == FormField::TextSingleType || field->getType() == FormField::JIDSingleType) {
+ QLineEdit* widget = qobject_cast<QLineEdit*>(fields_[field->getName()]);
+ QString string = widget->text();
+ if (!string.isEmpty()) {
+ resultField->addValue(Q2PSTRING(string));
+ }
+ }
+ if (field->getType() == FormField::JIDMultiType) {
+ QTextEdit* widget = qobject_cast<QTextEdit*>(fields_[field->getName()]);
+ QString string = widget->toPlainText();
+ if (!string.isEmpty()) {
+ QStringList lines = string.split("\n");
+ for (auto&& line : lines) {
+ resultField->addValue(Q2PSTRING(line));
+ }
+ }
+ }
+ if (field->getType() == FormField::ListMultiType) {
+ QListWidget* listWidget = qobject_cast<QListWidget*>(fields_[field->getName()]);
+ for (auto item : listWidget->selectedItems()) {
+ resultField->addValue(field->getOptions()[listWidget->row(item)].value);
+ }
+ }
+ resultField->setName(field->getName());
+ result->addField(resultField);
+ }
+ return result;
}
template<class T> void QtFormWidget::setEnabled(QWidget* rawWidget, bool editable) {
- T* widget = qobject_cast<T*>(rawWidget);
- if (widget) {
- widget->setEnabled(editable);
- }
+ T* widget = qobject_cast<T*>(rawWidget);
+ if (widget) {
+ widget->setEnabled(editable);
+ }
}
template<class T> void QtFormWidget::setEditable(QWidget* rawWidget, bool editable) {
- T* widget = qobject_cast<T*>(rawWidget);
- if (widget) {
- widget->setReadOnly(!editable);
- }
+ T* widget = qobject_cast<T*>(rawWidget);
+ if (widget) {
+ widget->setReadOnly(!editable);
+ }
}
void QtFormWidget::setEditable(bool editable) {
- if (!form_) {
- return;
- }
- foreach (boost::shared_ptr<FormField> field, form_->getFields()) {
- QWidget* widget = NULL;
- if (field) {
- widget = fields_[field->getName()];
- }
- setEnabled<QCheckBox>(widget, editable);
- setEnabled<QListWidget>(widget, editable);
- setEditable<QTextEdit>(widget, editable);
- setEditable<QLineEdit>(widget, editable);
- }
+ if (!form_) {
+ return;
+ }
+ for (auto&& field : form_->getFields()) {
+ QWidget* widget = nullptr;
+ if (field) {
+ widget = fields_[field->getName()];
+ }
+ setEnabled<QCheckBox>(widget, editable);
+ setEnabled<QListWidget>(widget, editable);
+ setEditable<QTextEdit>(widget, editable);
+ setEditable<QLineEdit>(widget, editable);
+ }
}
}
diff --git a/Swift/QtUI/QtFormWidget.h b/Swift/QtUI/QtFormWidget.h
index 9c01983..f228ccb 100644
--- a/Swift/QtUI/QtFormWidget.h
+++ b/Swift/QtUI/QtFormWidget.h
@@ -1,14 +1,15 @@
/*
- * Copyright (c) 2011-2014 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <map>
+
#include <QWidget>
-#include <map>
#include <Swiften/Elements/Form.h>
class QListWidget;
@@ -16,19 +17,19 @@ class QListWidget;
namespace Swift {
class QtFormWidget : public QWidget {
- Q_OBJECT
- public:
- QtFormWidget(Form::ref form, QWidget* parent = NULL);
- virtual ~QtFormWidget();
- Form::ref getCompletedForm();
- void setEditable(bool editable);
- private:
- QWidget* createWidget(FormField::ref field, const FormField::Type type, const size_t index);
- QListWidget* createList(FormField::ref field);
- template<class T> void setEnabled(QWidget* rawWidget, bool editable);
- template<class T> void setEditable(QWidget* rawWidget, bool editable);
- std::map<std::string, QWidget*> fields_;
- Form::ref form_;
+ Q_OBJECT
+ public:
+ QtFormWidget(Form::ref form, QWidget* parent = nullptr);
+ virtual ~QtFormWidget();
+ Form::ref getCompletedForm();
+ void setEditable(bool editable);
+ private:
+ QWidget* createWidget(FormField::ref field, const FormField::Type type, const size_t index);
+ QListWidget* createList(FormField::ref field);
+ template<class T> void setEnabled(QWidget* rawWidget, bool editable);
+ template<class T> void setEditable(QWidget* rawWidget, bool editable);
+ std::map<std::string, QWidget*> fields_;
+ Form::ref form_;
};
}
diff --git a/Swift/QtUI/QtHighlightEditor.cpp b/Swift/QtUI/QtHighlightEditor.cpp
index 1d47c4e..dd95941 100644
--- a/Swift/QtUI/QtHighlightEditor.cpp
+++ b/Swift/QtUI/QtHighlightEditor.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -29,540 +29,540 @@
namespace Swift {
QtHighlightEditor::QtHighlightEditor(QtSettingsProvider* settings, QWidget* parent)
- : QWidget(parent), settings_(settings), previousRow_(-1)
+ : QWidget(parent), settings_(settings), previousRow_(-1)
{
- ui_.setupUi(this);
+ ui_.setupUi(this);
- connect(ui_.listWidget, SIGNAL(currentRowChanged(int)), SLOT(onCurrentRowChanged(int)));
+ connect(ui_.listWidget, SIGNAL(currentRowChanged(int)), SLOT(onCurrentRowChanged(int)));
- connect(ui_.newButton, SIGNAL(clicked()), SLOT(onNewButtonClicked()));
- connect(ui_.deleteButton, SIGNAL(clicked()), SLOT(onDeleteButtonClicked()));
+ connect(ui_.newButton, SIGNAL(clicked()), SLOT(onNewButtonClicked()));
+ connect(ui_.deleteButton, SIGNAL(clicked()), SLOT(onDeleteButtonClicked()));
- connect(ui_.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), SLOT(onApplyButtonClick()));
- connect(ui_.buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), SLOT(onCancelButtonClick()));
- connect(ui_.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), SLOT(onOkButtonClick()));
- connect(ui_.buttonBox->button(QDialogButtonBox::RestoreDefaults), SIGNAL(clicked()), SLOT(onResetToDefaultRulesClicked()));
+ connect(ui_.buttonBox->button(QDialogButtonBox::Apply), SIGNAL(clicked()), SLOT(onApplyButtonClick()));
+ connect(ui_.buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), SLOT(onCancelButtonClick()));
+ connect(ui_.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), SLOT(onOkButtonClick()));
+ connect(ui_.buttonBox->button(QDialogButtonBox::RestoreDefaults), SIGNAL(clicked()), SLOT(onResetToDefaultRulesClicked()));
- connect(ui_.noColorRadio, SIGNAL(clicked()), SLOT(colorOtherSelect()));
- connect(ui_.customColorRadio, SIGNAL(clicked()), SLOT(colorCustomSelect()));
+ connect(ui_.noColorRadio, SIGNAL(clicked()), SLOT(colorOtherSelect()));
+ connect(ui_.customColorRadio, SIGNAL(clicked()), SLOT(colorCustomSelect()));
- connect(ui_.noSoundRadio, SIGNAL(clicked()), SLOT(soundOtherSelect()));
- connect(ui_.defaultSoundRadio, SIGNAL(clicked()), SLOT(soundOtherSelect()));
- connect(ui_.customSoundRadio, SIGNAL(clicked()), SLOT(soundCustomSelect()));
+ connect(ui_.noSoundRadio, SIGNAL(clicked()), SLOT(soundOtherSelect()));
+ connect(ui_.defaultSoundRadio, SIGNAL(clicked()), SLOT(soundOtherSelect()));
+ connect(ui_.customSoundRadio, SIGNAL(clicked()), SLOT(soundCustomSelect()));
- /* replace the static line-edit control with the roster autocompleter */
- ui_.dummySenderName->setVisible(false);
- jid_ = new QtSuggestingJIDInput(this, settings);
- ui_.senderName->addWidget(jid_);
- jid_->onUserSelected.connect(boost::bind(&QtHighlightEditor::handleOnUserSelected, this, _1));
+ /* replace the static line-edit control with the roster autocompleter */
+ ui_.dummySenderName->setVisible(false);
+ jid_ = new QtSuggestingJIDInput(this, settings);
+ ui_.senderName->addWidget(jid_);
+ jid_->onUserSelected.connect(boost::bind(&QtHighlightEditor::handleOnUserSelected, this, _1));
- /* handle autocomplete */
- connect(jid_, SIGNAL(textEdited(QString)), SLOT(handleContactSuggestionRequested(QString)));
+ /* handle autocomplete */
+ connect(jid_, SIGNAL(textEdited(QString)), SLOT(handleContactSuggestionRequested(QString)));
- /* we need to be notified if any of the state changes so that we can update our textual rule description */
- connect(ui_.chatRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.roomRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.nickIsKeyword, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.allMsgRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.senderRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(jid_, SIGNAL(textChanged(const QString&)), SLOT(widgetClick()));
- connect(ui_.keywordRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.keyword, SIGNAL(textChanged(const QString&)), SLOT(widgetClick()));
- connect(ui_.matchPartialWords, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.matchCase, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.noColorRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.customColorRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.noSoundRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.defaultSoundRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- connect(ui_.customSoundRadio, SIGNAL(clicked()), SLOT(widgetClick()));
+ /* we need to be notified if any of the state changes so that we can update our textual rule description */
+ connect(ui_.chatRadio, SIGNAL(clicked()), SLOT(widgetClick()));
+ connect(ui_.roomRadio, SIGNAL(clicked()), SLOT(widgetClick()));
+ connect(ui_.nickIsKeyword, SIGNAL(clicked()), SLOT(widgetClick()));
+ connect(ui_.allMsgRadio, SIGNAL(clicked()), SLOT(widgetClick()));
+ connect(ui_.senderRadio, SIGNAL(clicked()), SLOT(widgetClick()));
+ connect(jid_, SIGNAL(textChanged(const QString&)), SLOT(widgetClick()));
+ connect(ui_.keywordRadio, SIGNAL(clicked()), SLOT(widgetClick()));
+ connect(ui_.keyword, SIGNAL(textChanged(const QString&)), SLOT(widgetClick()));
+ connect(ui_.matchPartialWords, SIGNAL(clicked()), SLOT(widgetClick()));
+ connect(ui_.matchCase, SIGNAL(clicked()), SLOT(widgetClick()));
+ connect(ui_.noColorRadio, SIGNAL(clicked()), SLOT(widgetClick()));
+ connect(ui_.customColorRadio, SIGNAL(clicked()), SLOT(widgetClick()));
+ connect(ui_.noSoundRadio, SIGNAL(clicked()), SLOT(widgetClick()));
+ connect(ui_.defaultSoundRadio, SIGNAL(clicked()), SLOT(widgetClick()));
+ connect(ui_.customSoundRadio, SIGNAL(clicked()), SLOT(widgetClick()));
- /* allow selection of a custom sound file */
- connect(ui_.soundFileButton, SIGNAL(clicked()), SLOT(selectSoundFile()));
+ /* allow selection of a custom sound file */
+ connect(ui_.soundFileButton, SIGNAL(clicked()), SLOT(selectSoundFile()));
- /* allowing reordering items */
- connect(ui_.moveUpButton, SIGNAL(clicked()), this, SLOT(onUpButtonClicked()));
- connect(ui_.moveDownButton, SIGNAL(clicked()), this, SLOT(onDownButtonClicked()));
+ /* allowing reordering items */
+ connect(ui_.moveUpButton, SIGNAL(clicked()), this, SLOT(onUpButtonClicked()));
+ connect(ui_.moveDownButton, SIGNAL(clicked()), this, SLOT(onDownButtonClicked()));
- setWindowTitle(tr("Highlight Rules"));
+ setWindowTitle(tr("Highlight Rules"));
}
QtHighlightEditor::~QtHighlightEditor()
{
}
-std::string formatShortDescription(const HighlightRule &rule)
+QString QtHighlightEditor::formatShortDescription(const HighlightRule &rule)
{
- const std::string chatOrRoom = (rule.getMatchChat() ? "chat" : "room");
+ const QString chatOrRoom = (rule.getMatchChat() ? tr("chat") : tr("room"));
- std::vector<std::string> senders = rule.getSenders();
- std::vector<std::string> keywords = rule.getKeywords();
+ std::vector<std::string> senders = rule.getSenders();
+ std::vector<std::string> keywords = rule.getKeywords();
- if (senders.empty() && keywords.empty() && !rule.getNickIsKeyword()) {
- return std::string("All ") + chatOrRoom + " messages.";
- }
+ if (senders.empty() && keywords.empty() && !rule.getNickIsKeyword()) {
+ return tr("All %1 messages.").arg(chatOrRoom);
+ }
- if (rule.getNickIsKeyword()) {
- return std::string("All ") + chatOrRoom + " messages that mention my name.";
- }
+ if (rule.getNickIsKeyword()) {
+ return tr("All %1 messages that mention my name.").arg(chatOrRoom);
+ }
- if (!senders.empty()) {
- return std::string("All ") + chatOrRoom + " messages from " + senders[0] + ".";
- }
+ if (!senders.empty()) {
+ return tr("All %1 messages from %2.").arg(chatOrRoom, P2QSTRING(senders[0]));
+ }
- if (!keywords.empty()) {
- return std::string("All ") + chatOrRoom + " messages mentioning the keyword '" + keywords[0] + "'.";
- }
+ if (!keywords.empty()) {
+ return tr("All %1 messages mentioning the keyword '%2'.").arg(chatOrRoom, P2QSTRING(keywords[0]));
+ }
- return "Unknown Rule";
+ return tr("Unknown Rule");
}
void QtHighlightEditor::show()
{
- highlightManager_->loadSettings();
+ highlightManager_->loadSettings();
- populateList();
+ populateList();
- if (ui_.listWidget->count()) {
- selectRow(0);
- }
+ if (ui_.listWidget->count()) {
+ selectRow(0);
+ }
- updateResetToDefaultRulesVisibility();
+ updateResetToDefaultRulesVisibility();
- /* prepare default states */
- widgetClick();
+ /* prepare default states */
+ widgetClick();
- QWidget::show();
- QWidget::activateWindow();
+ QWidget::show();
+ QWidget::activateWindow();
}
void QtHighlightEditor::setHighlightManager(HighlightManager* highlightManager)
{
- highlightManager_ = highlightManager;
+ highlightManager_ = highlightManager;
}
void QtHighlightEditor::setContactSuggestions(const std::vector<Contact::ref>& suggestions)
{
- jid_->setSuggestions(suggestions);
+ jid_->setSuggestions(suggestions);
}
void QtHighlightEditor::colorOtherSelect()
{
- ui_.foregroundColor->setEnabled(false);
- ui_.backgroundColor->setEnabled(false);
+ ui_.foregroundColor->setEnabled(false);
+ ui_.backgroundColor->setEnabled(false);
}
void QtHighlightEditor::colorCustomSelect()
{
- ui_.foregroundColor->setEnabled(true);
- ui_.backgroundColor->setEnabled(true);
+ ui_.foregroundColor->setEnabled(true);
+ ui_.backgroundColor->setEnabled(true);
}
void QtHighlightEditor::soundOtherSelect()
{
- ui_.soundFile->setEnabled(false);
- ui_.soundFileButton->setEnabled(false);
+ ui_.soundFile->setEnabled(false);
+ ui_.soundFileButton->setEnabled(false);
}
void QtHighlightEditor::soundCustomSelect()
{
- ui_.soundFile->setEnabled(true);
- ui_.soundFileButton->setEnabled(true);
+ ui_.soundFile->setEnabled(true);
+ ui_.soundFileButton->setEnabled(true);
}
void QtHighlightEditor::onNewButtonClicked()
{
- int row = getSelectedRow() + 1;
- populateList();
- HighlightRule newRule;
- newRule.setMatchMUC(true);
- highlightManager_->insertRule(row, newRule);
- QListWidgetItem *item = new QListWidgetItem();
- item->setText(P2QSTRING(formatShortDescription(newRule)));
- QFont font;
- font.setItalic(true);
- item->setFont(font);
- ui_.listWidget->insertItem(row, item);
- selectRow(row);
+ int row = getSelectedRow() + 1;
+ populateList();
+ HighlightRule newRule;
+ newRule.setMatchMUC(true);
+ highlightManager_->insertRule(row, newRule);
+ QListWidgetItem *item = new QListWidgetItem();
+ item->setText(formatShortDescription(newRule));
+ QFont font;
+ font.setItalic(true);
+ item->setFont(font);
+ ui_.listWidget->insertItem(row, item);
+ selectRow(row);
}
void QtHighlightEditor::onDeleteButtonClicked()
{
- int selectedRow = getSelectedRow();
- assert(selectedRow>=0 && selectedRow<ui_.listWidget->count());
- delete ui_.listWidget->takeItem(selectedRow);
- highlightManager_->removeRule(selectedRow);
-
- if (!ui_.listWidget->count()) {
- disableDialog();
- ui_.deleteButton->setEnabled(false);
- } else {
- if (selectedRow == ui_.listWidget->count()) {
- selectRow(ui_.listWidget->count() - 1);
- } else {
- selectRow(selectedRow);
- }
- }
+ int selectedRow = getSelectedRow();
+ assert(selectedRow>=0 && selectedRow<ui_.listWidget->count());
+ delete ui_.listWidget->takeItem(selectedRow);
+ highlightManager_->removeRule(selectedRow);
+
+ if (!ui_.listWidget->count()) {
+ disableDialog();
+ ui_.deleteButton->setEnabled(false);
+ } else {
+ if (selectedRow == ui_.listWidget->count()) {
+ selectRow(ui_.listWidget->count() - 1);
+ } else {
+ selectRow(selectedRow);
+ }
+ }
}
void QtHighlightEditor::moveRowFromTo(int fromRow, int toRow) {
- int verticalScrollAreaPosition = ui_.scrollArea->verticalScrollBar()->value();
- highlightManager_->swapRules(fromRow, toRow);
- populateList();
- selectRow(toRow);
- ui_.scrollArea->verticalScrollBar()->setValue(verticalScrollAreaPosition);
+ int verticalScrollAreaPosition = ui_.scrollArea->verticalScrollBar()->value();
+ highlightManager_->swapRules(fromRow, toRow);
+ populateList();
+ selectRow(toRow);
+ ui_.scrollArea->verticalScrollBar()->setValue(verticalScrollAreaPosition);
}
void QtHighlightEditor::onUpButtonClicked() {
- const size_t moveFrom = ui_.listWidget->currentRow();
- const size_t moveTo = moveFrom - 1;
- moveRowFromTo(moveFrom, moveTo);
+ const size_t moveFrom = ui_.listWidget->currentRow();
+ const size_t moveTo = moveFrom - 1;
+ moveRowFromTo(moveFrom, moveTo);
}
void QtHighlightEditor::onDownButtonClicked() {
- const size_t moveFrom = ui_.listWidget->currentRow();
- const size_t moveTo = moveFrom + 1;
- moveRowFromTo(moveFrom, moveTo);
+ const size_t moveFrom = ui_.listWidget->currentRow();
+ const size_t moveTo = moveFrom + 1;
+ moveRowFromTo(moveFrom, moveTo);
}
void QtHighlightEditor::onCurrentRowChanged(int currentRow)
{
- ui_.deleteButton->setEnabled(currentRow != -1);
- ui_.moveUpButton->setEnabled(currentRow != -1 && currentRow != 0);
- ui_.moveDownButton->setEnabled(currentRow != -1 && currentRow != (ui_.listWidget->count()-1));
-
- if (previousRow_ != -1) {
- if (ui_.listWidget->count() > previousRow_) {
- QFont font;
- font.setItalic(false);
- ui_.listWidget->item(previousRow_)->setFont(font);
- highlightManager_->setRule(previousRow_, ruleFromDialog());
- }
- }
-
- if (currentRow != -1) {
- HighlightRule rule = highlightManager_->getRule(currentRow);
- ruleToDialog(rule);
- if (ui_.listWidget->currentItem()) {
- QFont font;
- font.setItalic(true);
- ui_.listWidget->currentItem()->setFont(font);
- ui_.listWidget->currentItem()->setText(P2QSTRING(formatShortDescription(rule)));
- }
- }
-
- /* grey the dialog if we have nothing selected */
- if (currentRow == -1) {
- disableDialog();
- }
-
- previousRow_ = currentRow;
-
- updateResetToDefaultRulesVisibility();
+ ui_.deleteButton->setEnabled(currentRow != -1);
+ ui_.moveUpButton->setEnabled(currentRow != -1 && currentRow != 0);
+ ui_.moveDownButton->setEnabled(currentRow != -1 && currentRow != (ui_.listWidget->count()-1));
+
+ if (previousRow_ != -1) {
+ if (ui_.listWidget->count() > previousRow_) {
+ QFont font;
+ font.setItalic(false);
+ ui_.listWidget->item(previousRow_)->setFont(font);
+ highlightManager_->setRule(previousRow_, ruleFromDialog());
+ }
+ }
+
+ if (currentRow != -1) {
+ HighlightRule rule = highlightManager_->getRule(currentRow);
+ ruleToDialog(rule);
+ if (ui_.listWidget->currentItem()) {
+ QFont font;
+ font.setItalic(true);
+ ui_.listWidget->currentItem()->setFont(font);
+ ui_.listWidget->currentItem()->setText(formatShortDescription(rule));
+ }
+ }
+
+ /* grey the dialog if we have nothing selected */
+ if (currentRow == -1) {
+ disableDialog();
+ }
+
+ previousRow_ = currentRow;
+
+ updateResetToDefaultRulesVisibility();
}
void QtHighlightEditor::onApplyButtonClick()
{
- selectRow(getSelectedRow()); /* force save */
- highlightManager_->storeSettings();
+ selectRow(getSelectedRow()); /* force save */
+ highlightManager_->storeSettings();
}
void QtHighlightEditor::onCancelButtonClick()
{
- close();
+ close();
}
void QtHighlightEditor::onOkButtonClick()
{
- onApplyButtonClick();
- close();
+ onApplyButtonClick();
+ close();
}
void QtHighlightEditor::setChildWidgetStates()
{
- /* disable appropriate radio button child widgets */
-
- if (ui_.chatRadio->isChecked()) {
- if (ui_.nickIsKeyword->isChecked()) {
- /* switch to another choice before we disable this button */
- ui_.allMsgRadio->setChecked(true);
- }
- ui_.nickIsKeyword->setEnabled(false);
- } else if (ui_.roomRadio->isChecked()) {
- ui_.nickIsKeyword->setEnabled(true);
- } else { /* chats and rooms */
- ui_.nickIsKeyword->setEnabled(true);
- }
-
- if (ui_.senderRadio->isChecked()) {
- jid_->setEnabled(true);
- } else {
- jid_->setEnabled(false);
- }
-
- if (ui_.keywordRadio->isChecked()) {
- ui_.keyword->setEnabled(true);
- ui_.matchPartialWords->setEnabled(true);
- ui_.matchCase->setEnabled(true);
- } else {
- ui_.keyword->setEnabled(false);
- ui_.matchPartialWords->setEnabled(false);
- ui_.matchCase->setEnabled(false);
- }
-
- if (ui_.chatRadio->isChecked()) {
- ui_.allMsgRadio->setText(tr("Apply to all chat messages"));
- } else {
- ui_.allMsgRadio->setText(tr("Apply to all room messages"));
- }
+ /* disable appropriate radio button child widgets */
+
+ if (ui_.chatRadio->isChecked()) {
+ if (ui_.nickIsKeyword->isChecked()) {
+ /* switch to another choice before we disable this button */
+ ui_.allMsgRadio->setChecked(true);
+ }
+ ui_.nickIsKeyword->setEnabled(false);
+ } else if (ui_.roomRadio->isChecked()) {
+ ui_.nickIsKeyword->setEnabled(true);
+ } else { /* chats and rooms */
+ ui_.nickIsKeyword->setEnabled(true);
+ }
+
+ if (ui_.senderRadio->isChecked()) {
+ jid_->setEnabled(true);
+ } else {
+ jid_->setEnabled(false);
+ }
+
+ if (ui_.keywordRadio->isChecked()) {
+ ui_.keyword->setEnabled(true);
+ ui_.matchPartialWords->setEnabled(true);
+ ui_.matchCase->setEnabled(true);
+ } else {
+ ui_.keyword->setEnabled(false);
+ ui_.matchPartialWords->setEnabled(false);
+ ui_.matchCase->setEnabled(false);
+ }
+
+ if (ui_.chatRadio->isChecked()) {
+ ui_.allMsgRadio->setText(tr("Apply to all chat messages"));
+ } else {
+ ui_.allMsgRadio->setText(tr("Apply to all room messages"));
+ }
}
void QtHighlightEditor::widgetClick()
{
- setChildWidgetStates();
+ setChildWidgetStates();
- HighlightRule rule = ruleFromDialog();
+ HighlightRule rule = ruleFromDialog();
- if (ui_.listWidget->currentItem()) {
- ui_.listWidget->currentItem()->setText(P2QSTRING(formatShortDescription(rule)));
- }
+ if (ui_.listWidget->currentItem()) {
+ ui_.listWidget->currentItem()->setText(formatShortDescription(rule));
+ }
}
void QtHighlightEditor::disableDialog()
{
- ui_.chatRadio->setEnabled(false);
- ui_.roomRadio->setEnabled(false);
- ui_.allMsgRadio->setEnabled(false);
- ui_.nickIsKeyword->setEnabled(false);
- ui_.senderRadio->setEnabled(false);
- ui_.dummySenderName->setEnabled(false);
- ui_.keywordRadio->setEnabled(false);
- ui_.keyword->setEnabled(false);
- ui_.matchPartialWords->setEnabled(false);
- ui_.matchCase->setEnabled(false);
- ui_.noColorRadio->setEnabled(false);
- ui_.customColorRadio->setEnabled(false);
- ui_.foregroundColor->setEnabled(false);
- ui_.backgroundColor->setEnabled(false);
- ui_.noSoundRadio->setEnabled(false);
- ui_.defaultSoundRadio->setEnabled(false);
- ui_.customSoundRadio->setEnabled(false);
- ui_.soundFile->setEnabled(false);
- ui_.soundFileButton->setEnabled(false);
+ ui_.chatRadio->setEnabled(false);
+ ui_.roomRadio->setEnabled(false);
+ ui_.allMsgRadio->setEnabled(false);
+ ui_.nickIsKeyword->setEnabled(false);
+ ui_.senderRadio->setEnabled(false);
+ ui_.dummySenderName->setEnabled(false);
+ ui_.keywordRadio->setEnabled(false);
+ ui_.keyword->setEnabled(false);
+ ui_.matchPartialWords->setEnabled(false);
+ ui_.matchCase->setEnabled(false);
+ ui_.noColorRadio->setEnabled(false);
+ ui_.customColorRadio->setEnabled(false);
+ ui_.foregroundColor->setEnabled(false);
+ ui_.backgroundColor->setEnabled(false);
+ ui_.noSoundRadio->setEnabled(false);
+ ui_.defaultSoundRadio->setEnabled(false);
+ ui_.customSoundRadio->setEnabled(false);
+ ui_.soundFile->setEnabled(false);
+ ui_.soundFileButton->setEnabled(false);
}
void QtHighlightEditor::handleContactSuggestionRequested(const QString& text)
{
- std::string stdText = Q2PSTRING(text);
- onContactSuggestionsRequested(stdText);
+ std::string stdText = Q2PSTRING(text);
+ onContactSuggestionsRequested(stdText);
}
void QtHighlightEditor::selectSoundFile()
{
- QString path = QFileDialog::getOpenFileName(this, tr("Select sound file..."), QString(), "Sounds (*.wav)");
- ui_.soundFile->setText(path);
+ QString path = QFileDialog::getOpenFileName(this, tr("Select sound file..."), QString(), tr("Sounds (*.wav)"));
+ ui_.soundFile->setText(path);
}
void QtHighlightEditor::onResetToDefaultRulesClicked() {
- highlightManager_->resetToDefaultRulesList();
- populateList();
- updateResetToDefaultRulesVisibility();
+ highlightManager_->resetToDefaultRulesList();
+ populateList();
+ updateResetToDefaultRulesVisibility();
}
void QtHighlightEditor::handleOnUserSelected(const Contact::ref& contact) {
- /* this might seem like it should be standard behaviour for the suggesting input box, but is not desirable in all cases */
- if (contact->jid.isValid()) {
- jid_->setText(P2QSTRING(contact->jid.toString()));
- } else {
- jid_->setText(P2QSTRING(contact->name));
- }
+ /* this might seem like it should be standard behaviour for the suggesting input box, but is not desirable in all cases */
+ if (contact->jid.isValid()) {
+ jid_->setText(P2QSTRING(contact->jid.toString()));
+ } else {
+ jid_->setText(P2QSTRING(contact->name));
+ }
}
void QtHighlightEditor::populateList()
{
- previousRow_ = -1;
- ui_.listWidget->clear();
- HighlightRulesListPtr rules = highlightManager_->getRules();
- for (size_t i = 0; i < rules->getSize(); ++i) {
- const HighlightRule& rule = rules->getRule(i);
- QListWidgetItem *item = new QListWidgetItem();
- item->setText(P2QSTRING(formatShortDescription(rule)));
- ui_.listWidget->addItem(item);
- }
+ previousRow_ = -1;
+ ui_.listWidget->clear();
+ HighlightRulesListPtr rules = highlightManager_->getRules();
+ for (size_t i = 0; i < rules->getSize(); ++i) {
+ const HighlightRule& rule = rules->getRule(i);
+ QListWidgetItem *item = new QListWidgetItem();
+ item->setText(formatShortDescription(rule));
+ ui_.listWidget->addItem(item);
+ }
}
void QtHighlightEditor::selectRow(int row)
{
- for (int i = 0; i < ui_.listWidget->count(); ++i) {
- if (i == row) {
- ui_.listWidget->item(i)->setSelected(true);
- onCurrentRowChanged(i);
- } else {
- ui_.listWidget->item(i)->setSelected(false);
- }
- }
- ui_.listWidget->setCurrentRow(row);
+ for (int i = 0; i < ui_.listWidget->count(); ++i) {
+ if (i == row) {
+ ui_.listWidget->item(i)->setSelected(true);
+ onCurrentRowChanged(i);
+ } else {
+ ui_.listWidget->item(i)->setSelected(false);
+ }
+ }
+ ui_.listWidget->setCurrentRow(row);
}
int QtHighlightEditor::getSelectedRow() const
{
- for (int i = 0; i < ui_.listWidget->count(); ++i) {
- if (ui_.listWidget->item(i)->isSelected()) {
- return i;
- }
- }
- return -1;
+ for (int i = 0; i < ui_.listWidget->count(); ++i) {
+ if (ui_.listWidget->item(i)->isSelected()) {
+ return i;
+ }
+ }
+ return -1;
}
HighlightRule QtHighlightEditor::ruleFromDialog()
{
- HighlightRule rule;
- HighlightAction& action = rule.getAction();
-
- if (ui_.chatRadio->isChecked()) {
- rule.setMatchChat(true);
- rule.setMatchMUC(false);
- } else {
- rule.setMatchChat(false);
- rule.setMatchMUC(true);
- }
-
- if (ui_.allMsgRadio->isChecked()) {
- action.setHighlightWholeMessage(true);
- }
-
- if (ui_.senderRadio->isChecked()) {
- QString senderName = jid_->text();
- if (!senderName.isEmpty()) {
- std::vector<std::string> senders;
- senders.push_back(Q2PSTRING(senderName));
- rule.setSenders(senders);
- action.setHighlightWholeMessage(true);
- }
- }
-
- if (ui_.keywordRadio->isChecked()) {
- QString keywordString = ui_.keyword->text();
- if (!keywordString.isEmpty()) {
- std::vector<std::string> keywords;
- keywords.push_back(Q2PSTRING(keywordString));
- rule.setKeywords(keywords);
- }
- }
-
- if (ui_.nickIsKeyword->isChecked()) {
- rule.setNickIsKeyword(true);
- rule.setMatchWholeWords(true);
- rule.setMatchCase(true);
- } else {
- rule.setMatchWholeWords(!ui_.matchPartialWords->isChecked());
- rule.setMatchCase(ui_.matchCase->isChecked());
- }
-
- if (ui_.noColorRadio->isChecked()) {
- action.setTextColor("");
- action.setTextBackground("");
- } else {
- action.setTextColor(Q2PSTRING(ui_.foregroundColor->getColor().name()));
- action.setTextBackground(Q2PSTRING(ui_.backgroundColor->getColor().name()));
- }
-
- if (ui_.noSoundRadio->isChecked()) {
- action.setPlaySound(false);
- } else if (ui_.defaultSoundRadio->isChecked()) {
- action.setPlaySound(true);
- action.setSoundFile("");
- } else {
- action.setPlaySound(true);
- action.setSoundFile(Q2PSTRING(ui_.soundFile->text()));
- }
-
- return rule;
+ HighlightRule rule;
+ HighlightAction& action = rule.getAction();
+
+ if (ui_.chatRadio->isChecked()) {
+ rule.setMatchChat(true);
+ rule.setMatchMUC(false);
+ } else {
+ rule.setMatchChat(false);
+ rule.setMatchMUC(true);
+ }
+
+ if (ui_.allMsgRadio->isChecked()) {
+ action.setHighlightWholeMessage(true);
+ }
+
+ if (ui_.senderRadio->isChecked()) {
+ QString senderName = jid_->text();
+ if (!senderName.isEmpty()) {
+ std::vector<std::string> senders;
+ senders.push_back(Q2PSTRING(senderName));
+ rule.setSenders(senders);
+ action.setHighlightWholeMessage(true);
+ }
+ }
+
+ if (ui_.keywordRadio->isChecked()) {
+ QString keywordString = ui_.keyword->text();
+ if (!keywordString.isEmpty()) {
+ std::vector<std::string> keywords;
+ keywords.push_back(Q2PSTRING(keywordString));
+ rule.setKeywords(keywords);
+ }
+ }
+
+ if (ui_.nickIsKeyword->isChecked()) {
+ rule.setNickIsKeyword(true);
+ rule.setMatchWholeWords(true);
+ rule.setMatchCase(true);
+ } else {
+ rule.setMatchWholeWords(!ui_.matchPartialWords->isChecked());
+ rule.setMatchCase(ui_.matchCase->isChecked());
+ }
+
+ if (ui_.noColorRadio->isChecked()) {
+ action.setTextColor("");
+ action.setTextBackground("");
+ } else {
+ action.setTextColor(Q2PSTRING(ui_.foregroundColor->getColor().name()));
+ action.setTextBackground(Q2PSTRING(ui_.backgroundColor->getColor().name()));
+ }
+
+ if (ui_.noSoundRadio->isChecked()) {
+ action.setPlaySound(false);
+ } else if (ui_.defaultSoundRadio->isChecked()) {
+ action.setPlaySound(true);
+ action.setSoundFile("");
+ } else {
+ action.setPlaySound(true);
+ action.setSoundFile(Q2PSTRING(ui_.soundFile->text()));
+ }
+
+ return rule;
}
void QtHighlightEditor::ruleToDialog(const HighlightRule& rule)
{
- ui_.chatRadio->setEnabled(true);
- ui_.roomRadio->setEnabled(true);
-
- if (rule.getMatchMUC()) {
- ui_.chatRadio->setChecked(false);
- ui_.roomRadio->setChecked(true);
- } else {
- ui_.chatRadio->setChecked(true);
- ui_.roomRadio->setChecked(false);
- }
-
- ui_.allMsgRadio->setEnabled(true);
- ui_.allMsgRadio->setChecked(true); /* this is the default radio button */
- jid_->setText("");
- ui_.keyword->setText("");
- ui_.matchPartialWords->setChecked(false);
- ui_.matchCase->setChecked(false);
-
- ui_.nickIsKeyword->setEnabled(true);
- if (rule.getNickIsKeyword()) {
- ui_.nickIsKeyword->setChecked(true);
- }
-
- ui_.senderRadio->setEnabled(true);
- std::vector<std::string> senders = rule.getSenders();
- if (!senders.empty()) {
- ui_.senderRadio->setChecked(true);
- jid_->setText(P2QSTRING(senders[0]));
- }
-
- ui_.keywordRadio->setEnabled(true);
- std::vector<std::string> keywords = rule.getKeywords();
- if (!keywords.empty()) {
- ui_.keywordRadio->setChecked(true);
- ui_.keyword->setText(P2QSTRING(keywords[0]));
- ui_.matchPartialWords->setChecked(!rule.getMatchWholeWords());
- ui_.matchCase->setChecked(rule.getMatchCase());
- }
-
- const HighlightAction& action = rule.getAction();
-
- ui_.noColorRadio->setEnabled(true);
- ui_.customColorRadio->setEnabled(true);
- if (action.getTextColor().empty() && action.getTextBackground().empty()) {
- ui_.noColorRadio->setChecked(true);
- ui_.foregroundColor->setEnabled(false);
- ui_.backgroundColor->setEnabled(false);
- } else {
- ui_.foregroundColor->setEnabled(true);
- ui_.backgroundColor->setEnabled(true);
- QColor foregroundColor(P2QSTRING(action.getTextColor()));
- ui_.foregroundColor->setColor(foregroundColor);
- QColor backgroundColor(P2QSTRING(action.getTextBackground()));
- ui_.backgroundColor->setColor(backgroundColor);
- ui_.customColorRadio->setChecked(true);
- }
-
- ui_.noSoundRadio->setEnabled(true);
- ui_.defaultSoundRadio->setEnabled(true);
- ui_.customSoundRadio->setEnabled(true);
- ui_.soundFile->setText("");
- ui_.soundFile->setEnabled(false);
- ui_.soundFileButton->setEnabled(false);
- if (action.playSound()) {
- if (action.getSoundFile().empty()) {
- ui_.defaultSoundRadio->setChecked(true);
- } else {
- ui_.customSoundRadio->setChecked(true);
- ui_.soundFile->setText(P2QSTRING(action.getSoundFile()));
- ui_.soundFile->setEnabled(true);
- ui_.soundFileButton->setEnabled(true);
- }
- } else {
- ui_.noSoundRadio->setChecked(true);
- }
-
- /* set radio button child option states */
- setChildWidgetStates();
+ ui_.chatRadio->setEnabled(true);
+ ui_.roomRadio->setEnabled(true);
+
+ if (rule.getMatchMUC()) {
+ ui_.chatRadio->setChecked(false);
+ ui_.roomRadio->setChecked(true);
+ } else {
+ ui_.chatRadio->setChecked(true);
+ ui_.roomRadio->setChecked(false);
+ }
+
+ ui_.allMsgRadio->setEnabled(true);
+ ui_.allMsgRadio->setChecked(true); /* this is the default radio button */
+ jid_->setText("");
+ ui_.keyword->setText("");
+ ui_.matchPartialWords->setChecked(false);
+ ui_.matchCase->setChecked(false);
+
+ ui_.nickIsKeyword->setEnabled(true);
+ if (rule.getNickIsKeyword()) {
+ ui_.nickIsKeyword->setChecked(true);
+ }
+
+ ui_.senderRadio->setEnabled(true);
+ std::vector<std::string> senders = rule.getSenders();
+ if (!senders.empty()) {
+ ui_.senderRadio->setChecked(true);
+ jid_->setText(P2QSTRING(senders[0]));
+ }
+
+ ui_.keywordRadio->setEnabled(true);
+ std::vector<std::string> keywords = rule.getKeywords();
+ if (!keywords.empty()) {
+ ui_.keywordRadio->setChecked(true);
+ ui_.keyword->setText(P2QSTRING(keywords[0]));
+ ui_.matchPartialWords->setChecked(!rule.getMatchWholeWords());
+ ui_.matchCase->setChecked(rule.getMatchCase());
+ }
+
+ const HighlightAction& action = rule.getAction();
+
+ ui_.noColorRadio->setEnabled(true);
+ ui_.customColorRadio->setEnabled(true);
+ if (action.getTextColor().empty() && action.getTextBackground().empty()) {
+ ui_.noColorRadio->setChecked(true);
+ ui_.foregroundColor->setEnabled(false);
+ ui_.backgroundColor->setEnabled(false);
+ } else {
+ ui_.foregroundColor->setEnabled(true);
+ ui_.backgroundColor->setEnabled(true);
+ QColor foregroundColor(P2QSTRING(action.getTextColor()));
+ ui_.foregroundColor->setColor(foregroundColor);
+ QColor backgroundColor(P2QSTRING(action.getTextBackground()));
+ ui_.backgroundColor->setColor(backgroundColor);
+ ui_.customColorRadio->setChecked(true);
+ }
+
+ ui_.noSoundRadio->setEnabled(true);
+ ui_.defaultSoundRadio->setEnabled(true);
+ ui_.customSoundRadio->setEnabled(true);
+ ui_.soundFile->setText("");
+ ui_.soundFile->setEnabled(false);
+ ui_.soundFileButton->setEnabled(false);
+ if (action.playSound()) {
+ if (action.getSoundFile().empty()) {
+ ui_.defaultSoundRadio->setChecked(true);
+ } else {
+ ui_.customSoundRadio->setChecked(true);
+ ui_.soundFile->setText(P2QSTRING(action.getSoundFile()));
+ ui_.soundFile->setEnabled(true);
+ ui_.soundFileButton->setEnabled(true);
+ }
+ } else {
+ ui_.noSoundRadio->setChecked(true);
+ }
+
+ /* set radio button child option states */
+ setChildWidgetStates();
}
void QtHighlightEditor::updateResetToDefaultRulesVisibility() {
- ui_.buttonBox->button(QDialogButtonBox::RestoreDefaults)->setVisible(!highlightManager_->isDefaultRulesList());
+ ui_.buttonBox->button(QDialogButtonBox::RestoreDefaults)->setVisible(!highlightManager_->isDefaultRulesList());
}
}
diff --git a/Swift/QtUI/QtHighlightEditor.h b/Swift/QtUI/QtHighlightEditor.h
index eb6a52b..c4a12e2 100644
--- a/Swift/QtUI/QtHighlightEditor.h
+++ b/Swift/QtUI/QtHighlightEditor.h
@@ -5,70 +5,72 @@
*/
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swift/QtUI/ui_QtHighlightEditor.h>
-
#include <Swift/Controllers/HighlightRule.h>
#include <Swift/Controllers/UIInterfaces/HighlightEditorWindow.h>
+#include <Swift/QtUI/ui_QtHighlightEditor.h>
+
namespace Swift {
- class QtSettingsProvider;
- class QtSuggestingJIDInput;
- class QtWebKitChatView;
+ class QtSettingsProvider;
+ class QtSuggestingJIDInput;
+ class QtWebKitChatView;
- class QtHighlightEditor : public QWidget, public HighlightEditorWindow {
- Q_OBJECT
+ class QtHighlightEditor : public QWidget, public HighlightEditorWindow {
+ Q_OBJECT
- public:
- QtHighlightEditor(QtSettingsProvider* settings, QWidget* parent = NULL);
- virtual ~QtHighlightEditor();
+ public:
+ QtHighlightEditor(QtSettingsProvider* settings, QWidget* parent = nullptr);
+ virtual ~QtHighlightEditor();
- virtual void show();
- virtual void setHighlightManager(HighlightManager* highlightManager);
- virtual void setContactSuggestions(const std::vector<Contact::ref>& suggestions);
+ virtual void show();
+ virtual void setHighlightManager(HighlightManager* highlightManager);
+ virtual void setContactSuggestions(const std::vector<Contact::ref>& suggestions);
- private slots:
- void colorOtherSelect();
- void colorCustomSelect();
- void soundOtherSelect();
- void soundCustomSelect();
- void onNewButtonClicked();
- void onDeleteButtonClicked();
- void onUpButtonClicked();
- void onDownButtonClicked();
- void onCurrentRowChanged(int currentRow);
- void onApplyButtonClick();
- void onCancelButtonClick();
- void onOkButtonClick();
- void setChildWidgetStates();
- void widgetClick();
- void disableDialog();
- void handleContactSuggestionRequested(const QString& text);
- void selectSoundFile();
- void onResetToDefaultRulesClicked();
+ private slots:
+ void colorOtherSelect();
+ void colorCustomSelect();
+ void soundOtherSelect();
+ void soundCustomSelect();
+ void onNewButtonClicked();
+ void onDeleteButtonClicked();
+ void onUpButtonClicked();
+ void onDownButtonClicked();
+ void onCurrentRowChanged(int currentRow);
+ void onApplyButtonClick();
+ void onCancelButtonClick();
+ void onOkButtonClick();
+ void setChildWidgetStates();
+ void widgetClick();
+ void disableDialog();
+ void handleContactSuggestionRequested(const QString& text);
+ void selectSoundFile();
+ void onResetToDefaultRulesClicked();
- private:
- void handleOnUserSelected(const Contact::ref& contact);
- void populateList();
- void selectRow(int row);
- int getSelectedRow() const;
- HighlightRule ruleFromDialog();
- void ruleToDialog(const HighlightRule& rule);
- void updateResetToDefaultRulesVisibility();
- void moveRowFromTo(int fromRow, int toRow);
+ private:
+ QString formatShortDescription(const HighlightRule &rule);
+ void handleOnUserSelected(const Contact::ref& contact);
+ void populateList();
+ void selectRow(int row);
+ int getSelectedRow() const;
+ HighlightRule ruleFromDialog();
+ void ruleToDialog(const HighlightRule& rule);
+ void updateResetToDefaultRulesVisibility();
+ void moveRowFromTo(int fromRow, int toRow);
- Ui::QtHighlightEditor ui_;
- QtSettingsProvider* settings_;
- HighlightManager* highlightManager_;
- QtSuggestingJIDInput* jid_;
- int previousRow_;
- };
+ private:
+ Ui::QtHighlightEditor ui_;
+ QtSettingsProvider* settings_;
+ HighlightManager* highlightManager_ = nullptr;
+ QtSuggestingJIDInput* jid_;
+ int previousRow_;
+ };
}
diff --git a/Swift/QtUI/QtHighlightEditorWidget.cpp b/Swift/QtUI/QtHighlightEditorWidget.cpp
deleted file mode 100644
index 7ff094e..0000000
--- a/Swift/QtUI/QtHighlightEditorWidget.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/*
- * Copyright (c) 2012 Maciej Niedzielski
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#include <cassert>
-
-#include <Swift/QtUI/QtHighlightEditorWidget.h>
-#include <Swift/QtUI/QtHighlightRulesItemModel.h>
-
-namespace Swift {
-
-QtHighlightEditorWidget::QtHighlightEditorWidget(QWidget* parent)
- : QWidget(parent)
-{
- ui_.setupUi(this);
-
- itemModel_ = new QtHighlightRulesItemModel(this);
- ui_.treeView->setModel(itemModel_);
- ui_.ruleWidget->setModel(itemModel_);
-
- for (int i = 0; i < QtHighlightRulesItemModel::NumberOfColumns; ++i) {
- switch (i) {
- case QtHighlightRulesItemModel::ApplyTo:
- case QtHighlightRulesItemModel::Sender:
- case QtHighlightRulesItemModel::Keyword:
- case QtHighlightRulesItemModel::Action:
- ui_.treeView->showColumn(i);
- break;
- default:
- ui_.treeView->hideColumn(i);
- break;
- }
- }
-
- setHighlightManager(NULL); // setup buttons for empty rules list
-
- connect(ui_.treeView->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), SLOT(onCurrentRowChanged(QModelIndex)));
-
- connect(ui_.newButton, SIGNAL(clicked()), SLOT(onNewButtonClicked()));
- connect(ui_.deleteButton, SIGNAL(clicked()), SLOT(onDeleteButtonClicked()));
-
- connect(ui_.moveUpButton, SIGNAL(clicked()), SLOT(onMoveUpButtonClicked()));
- connect(ui_.moveDownButton, SIGNAL(clicked()), SLOT(onMoveDownButtonClicked()));
-
- connect(ui_.closeButton, SIGNAL(clicked()), SLOT(close()));
-
- setWindowTitle(tr("Highlight Rules"));
-}
-
-QtHighlightEditorWidget::~QtHighlightEditorWidget()
-{
-}
-
-void QtHighlightEditorWidget::show()
-{
- if (itemModel_->rowCount(QModelIndex())) {
- selectRow(0);
- }
- QWidget::show();
- QWidget::activateWindow();
-}
-
-void QtHighlightEditorWidget::setHighlightManager(HighlightManager* highlightManager)
-{
- itemModel_->setHighlightManager(highlightManager);
- ui_.newButton->setEnabled(highlightManager != NULL);
-
- ui_.ruleWidget->setEnabled(false);
- ui_.deleteButton->setEnabled(false);
- ui_.moveUpButton->setEnabled(false);
- ui_.moveDownButton->setEnabled(false);
-}
-
-void QtHighlightEditorWidget::closeEvent(QCloseEvent* event) {
- ui_.ruleWidget->save();
- event->accept();
-}
-
-void QtHighlightEditorWidget::onNewButtonClicked()
-{
- int row = getSelectedRow() + 1;
- itemModel_->insertRow(row, QModelIndex());
- selectRow(row);
-}
-
-void QtHighlightEditorWidget::onDeleteButtonClicked()
-{
- int row = getSelectedRow();
- assert(row >= 0);
-
- itemModel_->removeRow(row, QModelIndex());
- if (row == itemModel_->rowCount(QModelIndex())) {
- --row;
- }
- selectRow(row);
-}
-
-void QtHighlightEditorWidget::onMoveUpButtonClicked()
-{
- int row = getSelectedRow();
- assert(row > 0);
-
- ui_.ruleWidget->save();
- ui_.ruleWidget->setActiveIndex(QModelIndex());
- itemModel_->swapRows(row, row - 1);
- selectRow(row - 1);
-}
-
-void QtHighlightEditorWidget::onMoveDownButtonClicked()
-{
- int row = getSelectedRow();
- assert(row < itemModel_->rowCount(QModelIndex()) - 1);
-
- ui_.ruleWidget->save();
- ui_.ruleWidget->setActiveIndex(QModelIndex());
- if (itemModel_->swapRows(row, row + 1)) {
- selectRow(row + 1);
- }
-}
-
-void QtHighlightEditorWidget::onCurrentRowChanged(const QModelIndex& index)
-{
- ui_.ruleWidget->save();
- ui_.ruleWidget->setActiveIndex(index);
-
- ui_.ruleWidget->setEnabled(index.isValid());
-
- ui_.deleteButton->setEnabled(index.isValid());
-
- ui_.moveUpButton->setEnabled(index.isValid() && index.row() != 0);
- ui_.moveDownButton->setEnabled(index.isValid() && index.row() != itemModel_->rowCount(QModelIndex()) - 1);
-}
-
-void QtHighlightEditorWidget::selectRow(int row)
-{
- QModelIndex index = itemModel_->index(row, 0, QModelIndex());
- ui_.treeView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
-}
-
-/** Return index of selected row or -1 if none is selected */
-int QtHighlightEditorWidget::getSelectedRow() const
-{
- QModelIndexList rows = ui_.treeView->selectionModel()->selectedRows();
- return rows.isEmpty() ? -1 : rows[0].row();
-}
-
-}
diff --git a/Swift/QtUI/QtHighlightEditorWidget.h b/Swift/QtUI/QtHighlightEditorWidget.h
deleted file mode 100644
index 1293c87..0000000
--- a/Swift/QtUI/QtHighlightEditorWidget.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2012 Maciej Niedzielski
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#pragma once
-
-#include <Swift/Controllers/UIInterfaces/HighlightEditorWidget.h>
-#include <Swift/QtUI/ui_QtHighlightEditorWidget.h>
-
-namespace Swift {
-
- class QtHighlightRulesItemModel;
-
- class QtHighlightEditorWidget : public QWidget, public HighlightEditorWidget {
- Q_OBJECT
-
- public:
- QtHighlightEditorWidget(QWidget* parent = NULL);
- virtual ~QtHighlightEditorWidget();
-
- void show();
-
- void setHighlightManager(HighlightManager* highlightManager);
-
- private slots:
- void onNewButtonClicked();
- void onDeleteButtonClicked();
- void onMoveUpButtonClicked();
- void onMoveDownButtonClicked();
- void onCurrentRowChanged(const QModelIndex&);
-
- private:
- virtual void closeEvent(QCloseEvent* event);
-
- void selectRow(int row);
- int getSelectedRow() const;
-
- Ui::QtHighlightEditorWidget ui_;
- QtHighlightRulesItemModel* itemModel_;
- };
-
-}
diff --git a/Swift/QtUI/QtHighlightEditorWidget.ui b/Swift/QtUI/QtHighlightEditorWidget.ui
deleted file mode 100644
index 0f39168..0000000
--- a/Swift/QtUI/QtHighlightEditorWidget.ui
+++ /dev/null
@@ -1,124 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>QtHighlightEditorWidget</class>
- <widget class="QWidget" name="QtHighlightEditorWidget">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>419</width>
- <height>373</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>Form</string>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Incoming messages are checked against the following rules. First rule that matches will be executed.</string>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QTreeView" name="treeView">
- <property name="rootIsDecorated">
- <bool>false</bool>
- </property>
- <property name="itemsExpandable">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="Swift::QtHighlightRuleWidget" name="ruleWidget" native="true"/>
- </item>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <widget class="QPushButton" name="newButton">
- <property name="text">
- <string>New</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="deleteButton">
- <property name="text">
- <string>Delete</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeType">
- <enum>QSizePolicy::Fixed</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="moveUpButton">
- <property name="text">
- <string>Move up</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="moveDownButton">
- <property name="text">
- <string>Move down</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer_3">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QPushButton" name="closeButton">
- <property name="text">
- <string>Close</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>Swift::QtHighlightRuleWidget</class>
- <extends>QWidget</extends>
- <header>QtHighlightRuleWidget.h</header>
- <container>1</container>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
diff --git a/Swift/QtUI/QtHighlightRulesItemModel.cpp b/Swift/QtUI/QtHighlightRulesItemModel.cpp
deleted file mode 100644
index fcbaddc..0000000
--- a/Swift/QtUI/QtHighlightRulesItemModel.cpp
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Copyright (c) 2012 Maciej Niedzielski
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#include <boost/algorithm/string.hpp>
-#include <boost/lambda/lambda.hpp>
-#include <boost/numeric/conversion/cast.hpp>
-
-#include <QStringList>
-#include <QColor>
-
-#include <Swift/Controllers/HighlightManager.h>
-#include <Swift/QtUI/QtHighlightRulesItemModel.h>
-#include <Swift/QtUI/QtSwiftUtil.h>
-
-namespace Swift {
-
-QtHighlightRulesItemModel::QtHighlightRulesItemModel(QObject* parent) : QAbstractItemModel(parent), highlightManager_(NULL)
-{
-}
-
-void QtHighlightRulesItemModel::setHighlightManager(HighlightManager* highlightManager)
-{
- emit layoutAboutToBeChanged();
- highlightManager_ = highlightManager;
- emit layoutChanged();
-}
-
-QVariant QtHighlightRulesItemModel::headerData(int section, Qt::Orientation /* orientation */, int role) const
-{
- if (role == Qt::DisplayRole) {
- switch (section) {
- case ApplyTo: return QVariant(tr("Apply to"));
- case Sender: return QVariant(tr("Sender"));
- case Keyword: return QVariant(tr("Keyword"));
- case Action: return QVariant(tr("Action"));
- case NickIsKeyword: return QVariant(tr("Nick Is Keyword"));
- case MatchCase: return QVariant(tr("Match Case"));
- case MatchWholeWords: return QVariant(tr("Match Whole Words"));
- case HighlightText: return QVariant(tr("Highlight Text"));
- case TextColor: return QVariant(tr("Text Color"));
- case TextBackground: return QVariant(tr("Text Background"));
- case PlaySound: return QVariant(tr("Play Sounds"));
- case SoundFile: return QVariant(tr("Sound File"));
- }
- }
-
- return QVariant();
-}
-
-int QtHighlightRulesItemModel::columnCount(const QModelIndex& /* parent */) const
-{
- return NumberOfColumns;
-}
-
-QVariant QtHighlightRulesItemModel::data(const QModelIndex &index, int role) const
-{
- if (index.isValid() && highlightManager_ && (role == Qt::DisplayRole || role == Qt::EditRole)) {
-
- const char* separator = (role == Qt::DisplayRole) ? " ; " : "\n";
-
- if (boost::numeric_cast<std::vector<std::string>::size_type>(index.row()) < highlightManager_->getRules().size()) {
- const HighlightRule& r = highlightManager_->getRules()[index.row()];
- switch (index.column()) {
- case ApplyTo: {
- int applyTo = 0;
- if (r.getMatchChat() && r.getMatchMUC()) {
- applyTo = 1;
- } else if (r.getMatchChat()) {
- applyTo = 2;
- } else if (r.getMatchMUC()) {
- applyTo = 3;
- }
-
- if (role == Qt::DisplayRole) {
- return QVariant(getApplyToString(applyTo));
- } else {
- return QVariant(applyTo);
- }
- }
- case Sender: {
- std::string s = boost::join(r.getSenders(), separator);
- return QVariant(P2QSTRING(s));
- }
- case Keyword: {
- std::string s = boost::join(r.getKeywords(), separator);
- QString qs(P2QSTRING(s));
- if (role == Qt::DisplayRole && r.getNickIsKeyword()) {
- qs = tr("<nick>") + (qs.isEmpty() ? "" : separator + qs);
- }
- return QVariant(qs);
- }
- case Action: {
- std::vector<std::string> v;
- const HighlightAction & action = r.getAction();
- if (action.highlightText()) {
- v.push_back(Q2PSTRING(tr("Highlight text")));
- }
- if (action.playSound()) {
- v.push_back(Q2PSTRING(tr("Play sound")));
- }
- std::string s = boost::join(v, separator);
- return QVariant(P2QSTRING(s));
- }
- case NickIsKeyword: {
- return QVariant(r.getNickIsKeyword());
- }
- case MatchCase: {
- return QVariant(r.getMatchCase());
- }
- case MatchWholeWords: {
- return QVariant(r.getMatchWholeWords());
- }
- case HighlightText: {
- return QVariant(r.getAction().highlightText());
- }
- case TextColor: {
- return QVariant(QColor(P2QSTRING(r.getAction().getTextColor())));
- }
- case TextBackground: {
- return QVariant(QColor(P2QSTRING(r.getAction().getTextBackground())));
- }
- case PlaySound: {
- return QVariant(r.getAction().playSound());
- }
- case SoundFile: {
- return QVariant(P2QSTRING(r.getAction().getSoundFile()));
- }
- }
- }
- }
- return QVariant();
-}
-
-bool QtHighlightRulesItemModel::setData(const QModelIndex &index, const QVariant &value, int role)
-{
- if (index.isValid() && highlightManager_ && role == Qt::EditRole) {
- if (boost::numeric_cast<std::vector<std::string>::size_type>(index.row()) < highlightManager_->getRules().size()) {
- HighlightRule r = highlightManager_->getRule(index.row());
- std::vector<int> changedColumns;
- switch (index.column()) {
- case ApplyTo: {
- bool ok = false;
- int applyTo = value.toInt(&ok);
- if (!ok) {
- return false;
- }
- r.setMatchChat(applyTo == ApplyToAll || applyTo == ApplyToChat);
- r.setMatchMUC(applyTo == ApplyToAll || applyTo == ApplyToMUC);
- break;
- }
- case Sender:
- case Keyword: {
- std::string s = Q2PSTRING(value.toString());
- std::vector<std::string> v;
- boost::split(v, s, boost::is_any_of("\n"));
- v.erase(std::remove_if(v.begin(), v.end(), boost::lambda::_1 == ""), v.end());
- if (index.column() == Sender) {
- r.setSenders(v);
- } else {
- r.setKeywords(v);
- }
- break;
- }
- case NickIsKeyword: {
- r.setNickIsKeyword(value.toBool());
- changedColumns.push_back(Keyword); // "<nick>"
- break;
- }
- case MatchCase: {
- r.setMatchCase(value.toBool());
- break;
- }
- case MatchWholeWords: {
- r.setMatchWholeWords(value.toBool());
- break;
- }
- case HighlightText: {
- r.getAction().setHighlightText(value.toBool());
- changedColumns.push_back(Action);
- break;
- }
- case TextColor: {
- QColor c = value.value<QColor>();
- r.getAction().setTextColor(c.isValid() ? Q2PSTRING(c.name()) : "");
- break;
- }
- case TextBackground: {
- QColor c = value.value<QColor>();
- r.getAction().setTextBackground(c.isValid() ? Q2PSTRING(c.name()) : "");
- break;
- }
- case PlaySound: {
- r.getAction().setPlaySound(value.toBool());
- changedColumns.push_back(Action);
- break;
- }
- case SoundFile: {
- r.getAction().setSoundFile(Q2PSTRING(value.toString()));
- break;
- }
- }
-
- highlightManager_->setRule(index.row(), r);
- emit dataChanged(index, index);
- foreach (int column, changedColumns) {
- QModelIndex i = createIndex(index.row(), column, static_cast<void*>(0));
- emit dataChanged(i, i);
- }
- }
- }
-
- return false;
-}
-
-QModelIndex QtHighlightRulesItemModel::parent(const QModelIndex& /* child */) const
-{
- return QModelIndex();
-}
-
-int QtHighlightRulesItemModel::rowCount(const QModelIndex& /* parent */) const
-{
- return highlightManager_ ? highlightManager_->getRules().size() : 0;
-}
-
-QModelIndex QtHighlightRulesItemModel::index(int row, int column, const QModelIndex& /* parent */) const
-{
- return createIndex(row, column, static_cast<void*>(0));
-}
-
-bool QtHighlightRulesItemModel::insertRows(int row, int count, const QModelIndex& /* parent */)
-{
- if (highlightManager_) {
- beginInsertRows(QModelIndex(), row, row + count);
- while (count--) {
- highlightManager_->insertRule(row, HighlightRule());
- }
- endInsertRows();
- return true;
- }
- return false;
-}
-
-bool QtHighlightRulesItemModel::removeRows(int row, int count, const QModelIndex& /* parent */)
-{
- if (highlightManager_) {
- beginRemoveRows(QModelIndex(), row, row + count);
- while (count--) {
- highlightManager_->removeRule(row);
- }
- endRemoveRows();
- return true;
- }
- return false;
-}
-
-bool QtHighlightRulesItemModel::swapRows(int row1, int row2)
-{
- if (highlightManager_) {
- assert(row1 >= 0 && row2 >= 0 && boost::numeric_cast<std::vector<std::string>::size_type>(row1) < highlightManager_->getRules().size() && boost::numeric_cast<std::vector<std::string>::size_type>(row2) < highlightManager_->getRules().size());
- HighlightRule r = highlightManager_->getRule(row1);
- highlightManager_->setRule(row1, highlightManager_->getRule(row2));
- highlightManager_->setRule(row2, r);
- emit dataChanged(index(row1, 0, QModelIndex()), index(row1, 0, QModelIndex()));
- emit dataChanged(index(row2, 0, QModelIndex()), index(row2, 0, QModelIndex()));
- return true;
- }
- return false;
-}
-
-QString QtHighlightRulesItemModel::getApplyToString(int applyTo)
-{
- switch (applyTo) {
- case ApplyToNone: return tr("None");
- case ApplyToAll: return tr("Chat or MUC");
- case ApplyToChat: return tr("Chat");
- case ApplyToMUC: return tr("MUC");
- default: return "";
- }
-}
-
-}
diff --git a/Swift/QtUI/QtHighlightRulesItemModel.h b/Swift/QtUI/QtHighlightRulesItemModel.h
deleted file mode 100644
index ac85628..0000000
--- a/Swift/QtUI/QtHighlightRulesItemModel.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2012 Maciej Niedzielski
- * Licensed under the simplified BSD license.
- * See Documentation/Licenses/BSD-simplified.txt for more information.
- */
-
-#pragma once
-
-#include <QAbstractItemModel>
-
-namespace Swift {
-
- class HighlightManager;
-
- class QtHighlightRulesItemModel : public QAbstractItemModel {
- Q_OBJECT
-
- public:
- QtHighlightRulesItemModel(QObject* parent = NULL);
-
- void setHighlightManager(HighlightManager* highlightManager);
-
- QVariant headerData(int section, Qt::Orientation orientation, int role) const;
- int columnCount(const QModelIndex& parent) const;
- QVariant data(const QModelIndex& index, int role) const;
- bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
- QModelIndex parent(const QModelIndex& child) const;
- int rowCount(const QModelIndex& parent) const;
- QModelIndex index(int row, int column, const QModelIndex& parent) const;
- bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex());
- bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex());
- bool swapRows(int row1, int row2);
-
- static QString getApplyToString(int);
-
- enum Columns {
- ApplyTo = 0,
- Sender,
- Keyword,
- Action,
- NickIsKeyword,
- MatchCase,
- MatchWholeWords,
- HighlightText,
- TextColor,
- TextBackground,
- PlaySound,
- SoundFile,
- NumberOfColumns // end of list marker
- };
-
- enum ApplyToValues {
- ApplyToNone = 0,
- ApplyToAll,
- ApplyToChat,
- ApplyToMUC,
- ApplyToEOL // end of list marker
- };
-
- private:
- HighlightManager* highlightManager_;
- };
-
-}
diff --git a/Swift/QtUI/QtHistoryWindow.cpp b/Swift/QtUI/QtHistoryWindow.cpp
index f07c9b2..77a7f12 100644
--- a/Swift/QtUI/QtHistoryWindow.cpp
+++ b/Swift/QtUI/QtHistoryWindow.cpp
@@ -5,264 +5,263 @@
*/
/*
- * Copyright (c) 2013 Isode Limited.
+ * Copyright (c) 2013-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include <QtHistoryWindow.h>
+#include <Swift/QtUI/QtHistoryWindow.h>
+#include <memory>
#include <string>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/numeric/conversion/cast.hpp>
-#include <boost/shared_ptr.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
-#include <QTime>
-#include <QUrl>
-#include <QMenu>
-#include <QTextDocument>
#include <QDateTime>
#include <QLineEdit>
+#include <QMenu>
+#include <QTextDocument>
+#include <QTime>
+#include <QUrl>
#include <Swiften/History/HistoryMessage.h>
#include <Swift/Controllers/Settings/SettingsProvider.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
-#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/ChatSnippet.h>
#include <Swift/QtUI/MessageSnippet.h>
#include <Swift/QtUI/QtScaledAvatarCache.h>
-#include <Swift/QtUI/ChatSnippet.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swift/QtUI/QtUtilities.h>
-#include <Swift/QtUI/Roster/QtTreeWidget.h>
#include <Swift/QtUI/QtWebKitChatView.h>
+#include <Swift/QtUI/Roster/QtTreeWidget.h>
namespace Swift {
QtHistoryWindow::QtHistoryWindow(SettingsProvider* settings, UIEventStream* eventStream) :
- previousTopMessageWasSelf_(false),
- previousBottomMessageWasSelf_(false) {
- ui_.setupUi(this);
-
- theme_ = new QtChatTheme("");
- idCounter_ = 0;
-
- delete ui_.conversation_;
- conversation_ = new QtWebKitChatView(NULL, NULL, theme_, this, true); // Horrible unsafe. Do not do this. FIXME
- QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
- sizePolicy.setHorizontalStretch(80);
- sizePolicy.setVerticalStretch(0);
- conversation_->setSizePolicy(sizePolicy);
-
- ui_.conversation_ = conversation_;
- ui_.bottomLayout_->addWidget(conversation_);
-
- delete ui_.conversationRoster_;
- conversationRoster_ = new QtTreeWidget(eventStream, settings, QtTreeWidget::MessageDefaultJID, this);
- QSizePolicy sizePolicy2(QSizePolicy::Preferred, QSizePolicy::Expanding);
- sizePolicy2.setVerticalStretch(80);
- conversationRoster_->setSizePolicy(sizePolicy2);
- ui_.conversationRoster_ = conversationRoster_;
- ui_.bottomLeftLayout_->setDirection(QBoxLayout::BottomToTop);
- ui_.bottomLeftLayout_->addWidget(conversationRoster_);
-
- setWindowTitle(tr("History"));
-
- conversationRoster_->onSomethingSelectedChanged.connect(boost::bind(&QtHistoryWindow::handleSomethingSelectedChanged, this, _1));
- connect(conversation_, SIGNAL(scrollRequested(int)), this, SLOT(handleScrollRequested(int)));
- connect(conversation_, SIGNAL(scrollReachedTop()), this, SLOT(handleScrollReachedTop()));
- connect(conversation_, SIGNAL(scrollReachedBottom()), this, SLOT(handleScrollReachedBottom()));
- connect(conversation_, SIGNAL(fontResized(int)), this, SLOT(handleFontResized(int)));
- connect(ui_.searchBox_->lineEdit(), SIGNAL(returnPressed()), this, SLOT(handleReturnPressed()));
- connect(ui_.calendarWidget_, SIGNAL(clicked(const QDate&)), this, SLOT(handleCalendarClicked(const QDate&)));
- connect(ui_.calendarWidget_, SIGNAL(activated(const QDate&)), this, SLOT(handleCalendarClicked(const QDate&)));
- connect(ui_.previousButton_, SIGNAL(clicked(bool)), this, SLOT(handlePreviousButtonClicked()));
- connect(ui_.nextButton_, SIGNAL(clicked(bool)), this, SLOT(handleNextButtonClicked()));
+ previousTopMessageWasSelf_(false),
+ previousBottomMessageWasSelf_(false) {
+ ui_.setupUi(this);
+
+ theme_ = new QtChatTheme("");
+ idCounter_ = 0;
+
+ delete ui_.conversation_;
+ conversation_ = new QtWebKitChatView(nullptr, nullptr, theme_, this, true); // Horrible unsafe. Do not do this. FIXME
+ QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ sizePolicy.setHorizontalStretch(80);
+ sizePolicy.setVerticalStretch(0);
+ conversation_->setSizePolicy(sizePolicy);
+
+ ui_.conversation_ = conversation_;
+ ui_.bottomLayout_->addWidget(conversation_);
+
+ delete ui_.conversationRoster_;
+ conversationRoster_ = new QtTreeWidget(eventStream, settings, QtTreeWidget::MessageDefaultJID, this);
+ QSizePolicy sizePolicy2(QSizePolicy::Preferred, QSizePolicy::Expanding);
+ sizePolicy2.setVerticalStretch(80);
+ conversationRoster_->setSizePolicy(sizePolicy2);
+ ui_.conversationRoster_ = conversationRoster_;
+ ui_.bottomLeftLayout_->setDirection(QBoxLayout::BottomToTop);
+ ui_.bottomLeftLayout_->addWidget(conversationRoster_);
+
+ setWindowTitle(tr("History"));
+
+ conversationRoster_->onSomethingSelectedChanged.connect(boost::bind(&QtHistoryWindow::handleSomethingSelectedChanged, this, _1));
+ connect(conversation_, SIGNAL(scrollRequested(int)), this, SLOT(handleScrollRequested(int)));
+ connect(conversation_, SIGNAL(scrollReachedTop()), this, SLOT(handleScrollReachedTop()));
+ connect(conversation_, SIGNAL(scrollReachedBottom()), this, SLOT(handleScrollReachedBottom()));
+ connect(conversation_, SIGNAL(fontResized(int)), this, SLOT(handleFontResized(int)));
+ connect(ui_.searchBox_->lineEdit(), SIGNAL(returnPressed()), this, SLOT(handleReturnPressed()));
+ connect(ui_.calendarWidget_, SIGNAL(clicked(const QDate&)), this, SLOT(handleCalendarClicked(const QDate&)));
+ connect(ui_.calendarWidget_, SIGNAL(activated(const QDate&)), this, SLOT(handleCalendarClicked(const QDate&)));
+ connect(ui_.previousButton_, SIGNAL(clicked(bool)), this, SLOT(handlePreviousButtonClicked()));
+ connect(ui_.nextButton_, SIGNAL(clicked(bool)), this, SLOT(handleNextButtonClicked()));
}
QtHistoryWindow::~QtHistoryWindow() {
- disconnect(conversation_, SIGNAL(scrollRequested(int)), this, SLOT(handleScrollRequested(int)));
- disconnect(conversation_, SIGNAL(scrollReachedTop()), this, SLOT(handleScrollReachedTop()));
- disconnect(conversation_, SIGNAL(scrollReachedBottom()), this, SLOT(handleScrollReachedBottom()));
- disconnect(conversation_, SIGNAL(fontResized(int)), this, SLOT(handleFontResized(int)));
- disconnect(ui_.searchBox_->lineEdit(), SIGNAL(returnPressed()), this, SLOT(handleReturnPressed()));
- disconnect(ui_.calendarWidget_, SIGNAL(clicked(const QDate&)), this, SLOT(handleCalendarClicked(const QDate&)));
- disconnect(ui_.calendarWidget_, SIGNAL(activated(const QDate&)), this, SLOT(handleCalendarClicked(const QDate&)));
- disconnect(ui_.previousButton_, SIGNAL(clicked(bool)), this, SLOT(handlePreviousButtonClicked()));
- disconnect(ui_.nextButton_, SIGNAL(clicked(bool)), this, SLOT(handleNextButtonClicked()));
-
- delete theme_;
- delete conversation_;
- // TODO: delete ui_
+ disconnect(conversation_, SIGNAL(scrollRequested(int)), this, SLOT(handleScrollRequested(int)));
+ disconnect(conversation_, SIGNAL(scrollReachedTop()), this, SLOT(handleScrollReachedTop()));
+ disconnect(conversation_, SIGNAL(scrollReachedBottom()), this, SLOT(handleScrollReachedBottom()));
+ disconnect(conversation_, SIGNAL(fontResized(int)), this, SLOT(handleFontResized(int)));
+ disconnect(ui_.searchBox_->lineEdit(), SIGNAL(returnPressed()), this, SLOT(handleReturnPressed()));
+ disconnect(ui_.calendarWidget_, SIGNAL(clicked(const QDate&)), this, SLOT(handleCalendarClicked(const QDate&)));
+ disconnect(ui_.calendarWidget_, SIGNAL(activated(const QDate&)), this, SLOT(handleCalendarClicked(const QDate&)));
+ disconnect(ui_.previousButton_, SIGNAL(clicked(bool)), this, SLOT(handlePreviousButtonClicked()));
+ disconnect(ui_.nextButton_, SIGNAL(clicked(bool)), this, SLOT(handleNextButtonClicked()));
+
+ delete theme_;
+ delete conversation_;
+ // TODO: delete ui_
}
void QtHistoryWindow::activate() {
- emit wantsToActivate();
+ emit wantsToActivate();
}
void QtHistoryWindow::showEvent(QShowEvent* event) {
- emit windowOpening();
- emit titleUpdated();
- QWidget::showEvent(event);
+ emit windowOpening();
+ emit titleUpdated();
+ QWidget::showEvent(event);
}
void QtHistoryWindow::closeEvent(QCloseEvent* event) {
- emit windowClosing();
- event->accept();
+ emit windowClosing();
+ event->accept();
}
void QtHistoryWindow::setRosterModel(Roster* model) {
- conversationRoster_->setRosterModel(model);
+ conversationRoster_->setRosterModel(model);
}
void QtHistoryWindow::addMessage(const std::string &message, const std::string &senderName, bool senderIsSelf, const std::string& avatarPath, const boost::posix_time::ptime& time, bool addAtTheTop) {
- QString scaledAvatarPath = QtScaledAvatarCache(32).getScaledAvatarPath(avatarPath.c_str());
-
- QString messageHTML(P2QSTRING(message));
- messageHTML = QtUtilities::htmlEscape(messageHTML);
- QString searchTerm = ui_.searchBox_->lineEdit()->text();
- if (searchTerm.length()) {
- messageHTML.replace(searchTerm, "<span style='background-color: yellow'>" + searchTerm + "</span>");
- }
-
- // note: time uses localtime
- QDate date = QDate(time.date().year(), time.date().month(), time.date().day());
- QTime dayTime = QTime(time.time_of_day().hours(), time.time_of_day().minutes(), time.time_of_day().seconds());
- QDateTime qTime = QDateTime(date, dayTime);
-
- std::string id = "id" + boost::lexical_cast<std::string>(idCounter_++);
-
- QString qAvatarPath = scaledAvatarPath.isEmpty() ? "qrc:/icons/avatar.png" : QUrl::fromLocalFile(scaledAvatarPath).toEncoded();
-
- if (addAtTheTop) {
- bool appendToPrevious = ((senderIsSelf && previousTopMessageWasSelf_) || (!senderIsSelf && !previousTopMessageWasSelf_&& previousTopSenderName_ == P2QSTRING(senderName)));
- conversation_->addMessageTop(boost::shared_ptr<ChatSnippet>(new MessageSnippet(messageHTML, QtUtilities::htmlEscape(P2QSTRING(senderName)), qTime, qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id), ChatSnippet::getDirection(message))));
-
- previousTopMessageWasSelf_ = senderIsSelf;
- previousTopSenderName_ = P2QSTRING(senderName);
- }
- else {
- bool appendToPrevious = ((senderIsSelf && previousBottomMessageWasSelf_) || (!senderIsSelf && !previousBottomMessageWasSelf_&& previousBottomSenderName_ == P2QSTRING(senderName)));
- conversation_->addMessageBottom(boost::make_shared<MessageSnippet>(messageHTML, QtUtilities::htmlEscape(P2QSTRING(senderName)), qTime, qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id), ChatSnippet::getDirection(message)));
- previousBottomMessageWasSelf_ = senderIsSelf;
- previousBottomSenderName_ = P2QSTRING(senderName);
- }
-
- // keep track of the days viewable in the chatView
- if (!dates_.count(date)) {
- dates_.insert(date);
- }
+ QString scaledAvatarPath = QtScaledAvatarCache(32).getScaledAvatarPath(avatarPath.c_str());
+
+ QString messageHTML(P2QSTRING(message));
+ messageHTML = QtUtilities::htmlEscape(messageHTML);
+ QString searchTerm = ui_.searchBox_->lineEdit()->text();
+ if (searchTerm.length()) {
+ messageHTML.replace(searchTerm, "<span style='background-color: yellow'>" + searchTerm + "</span>");
+ }
+
+ // note: time uses localtime
+ QDate date = QDate(time.date().year(), time.date().month(), time.date().day());
+ QTime dayTime = QTime(time.time_of_day().hours(), time.time_of_day().minutes(), time.time_of_day().seconds());
+ QDateTime qTime = QDateTime(date, dayTime);
+
+ std::string id = "id" + boost::lexical_cast<std::string>(idCounter_++);
+
+ QString qAvatarPath = scaledAvatarPath.isEmpty() ? "qrc:/icons/avatar.png" : QUrl::fromLocalFile(scaledAvatarPath).toEncoded();
+
+ if (addAtTheTop) {
+ bool appendToPrevious = ((senderIsSelf && previousTopMessageWasSelf_) || (!senderIsSelf && !previousTopMessageWasSelf_&& previousTopSenderName_ == P2QSTRING(senderName)));
+ conversation_->addMessageTop(std::make_shared<MessageSnippet>(messageHTML, QtUtilities::htmlEscape(P2QSTRING(senderName)), qTime, qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id), ChatSnippet::getDirection(message)));
+
+ previousTopMessageWasSelf_ = senderIsSelf;
+ previousTopSenderName_ = P2QSTRING(senderName);
+ }
+ else {
+ bool appendToPrevious = ((senderIsSelf && previousBottomMessageWasSelf_) || (!senderIsSelf && !previousBottomMessageWasSelf_&& previousBottomSenderName_ == P2QSTRING(senderName)));
+ conversation_->addMessageBottom(std::make_shared<MessageSnippet>(messageHTML, QtUtilities::htmlEscape(P2QSTRING(senderName)), qTime, qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id), ChatSnippet::getDirection(message)));
+ previousBottomMessageWasSelf_ = senderIsSelf;
+ previousBottomSenderName_ = P2QSTRING(senderName);
+ }
+
+ // keep track of the days viewable in the chatView
+ if (!dates_.count(date)) {
+ dates_.insert(date);
+ }
}
void QtHistoryWindow::handleSomethingSelectedChanged(RosterItem* item) {
- onSelectedContactChanged(item);
+ onSelectedContactChanged(item);
}
void QtHistoryWindow::resetConversationView() {
- previousTopMessageWasSelf_ = false;
- previousBottomMessageWasSelf_ = false;
- previousTopSenderName_.clear();
- previousBottomSenderName_.clear();
+ previousTopMessageWasSelf_ = false;
+ previousBottomMessageWasSelf_ = false;
+ previousTopSenderName_.clear();
+ previousBottomSenderName_.clear();
- dates_.clear();
- conversation_->resetView();
+ dates_.clear();
+ conversation_->resetView();
}
void QtHistoryWindow::handleScrollRequested(int pos) {
- // first message starts with offset 5
- if (pos < 5) {
- pos = 5;
- }
-
- QDate currentDate;
- foreach (const QDate& date, dates_) {
- int snippetPosition = conversation_->getSnippetPositionByDate(date);
- if (snippetPosition <= pos) {
- currentDate = date;
- }
- }
-
- if (ui_.calendarWidget_->selectedDate() != currentDate) {
- ui_.calendarWidget_->setSelectedDate(currentDate);
- }
+ // first message starts with offset 5
+ if (pos < 5) {
+ pos = 5;
+ }
+
+ QDate currentDate;
+ for (const auto& date : dates_) {
+ int snippetPosition = conversation_->getSnippetPositionByDate(date);
+ if (snippetPosition <= pos) {
+ currentDate = date;
+ }
+ }
+
+ if (ui_.calendarWidget_->selectedDate() != currentDate) {
+ ui_.calendarWidget_->setSelectedDate(currentDate);
+ }
}
void QtHistoryWindow::handleScrollReachedTop() {
- if (dates_.empty()) {
- return;
- }
-
- int year, month, day;
- QDate firstDate = *dates_.begin();
- firstDate.getDate(&year, &month, &day);
- onScrollReachedTop(boost::gregorian::date(boost::numeric_cast<unsigned short>(year), boost::numeric_cast<unsigned short>(month), boost::numeric_cast<unsigned short>(day)));
+ if (dates_.empty()) {
+ return;
+ }
+
+ int year, month, day;
+ QDate firstDate = *dates_.begin();
+ firstDate.getDate(&year, &month, &day);
+ onScrollReachedTop(boost::gregorian::date(boost::numeric_cast<unsigned short>(year), boost::numeric_cast<unsigned short>(month), boost::numeric_cast<unsigned short>(day)));
}
void QtHistoryWindow::handleScrollReachedBottom() {
- if (dates_.empty()) {
- return;
- }
-
- int year, month, day;
- QDate lastDate = *dates_.rbegin();
- lastDate.getDate(&year, &month, &day);
- onScrollReachedBottom(boost::gregorian::date(boost::numeric_cast<unsigned short>(year), boost::numeric_cast<unsigned short>(month), boost::numeric_cast<unsigned short>(day)));
+ if (dates_.empty()) {
+ return;
+ }
+
+ int year, month, day;
+ QDate lastDate = *dates_.rbegin();
+ lastDate.getDate(&year, &month, &day);
+ onScrollReachedBottom(boost::gregorian::date(boost::numeric_cast<unsigned short>(year), boost::numeric_cast<unsigned short>(month), boost::numeric_cast<unsigned short>(day)));
}
void QtHistoryWindow::handleReturnPressed() {
- onReturnPressed(ui_.searchBox_->lineEdit()->text().toStdString());
+ onReturnPressed(ui_.searchBox_->lineEdit()->text().toStdString());
}
void QtHistoryWindow::handleCalendarClicked(const QDate& date) {
- int year, month, day;
- QDate tempDate = date; // getDate discards const qualifier
- tempDate.getDate(&year, &month, &day);
- onCalendarClicked(boost::gregorian::date(boost::numeric_cast<unsigned short>(year), boost::numeric_cast<unsigned short>(month), boost::numeric_cast<unsigned short>(day)));
+ int year, month, day;
+ QDate tempDate = date; // getDate discards const qualifier
+ tempDate.getDate(&year, &month, &day);
+ onCalendarClicked(boost::gregorian::date(boost::numeric_cast<unsigned short>(year), boost::numeric_cast<unsigned short>(month), boost::numeric_cast<unsigned short>(day)));
}
void QtHistoryWindow::setDate(const boost::gregorian::date& date) {
- ui_.calendarWidget_->setSelectedDate(QDate::fromJulianDay(date.julian_day()));
+ ui_.calendarWidget_->setSelectedDate(QDate::fromJulianDay(date.julian_day()));
}
void QtHistoryWindow::handleNextButtonClicked() {
- onNextButtonClicked();
+ onNextButtonClicked();
}
void QtHistoryWindow::handlePreviousButtonClicked() {
- onPreviousButtonClicked();
+ onPreviousButtonClicked();
}
void QtHistoryWindow::handleFontResized(int fontSizeSteps) {
- conversation_->resizeFont(fontSizeSteps);
+ conversation_->resizeFont(fontSizeSteps);
- emit fontResized(fontSizeSteps);
+ emit fontResized(fontSizeSteps);
}
void QtHistoryWindow::resetConversationViewTopInsertPoint() {
- previousTopMessageWasSelf_ = false;
- previousTopSenderName_ = QString();
- conversation_->resetTopInsertPoint();
+ previousTopMessageWasSelf_ = false;
+ previousTopSenderName_ = QString();
+ conversation_->resetTopInsertPoint();
}
std::string QtHistoryWindow::getSearchBoxText() {
- return ui_.searchBox_->lineEdit()->text().toStdString();
+ return ui_.searchBox_->lineEdit()->text().toStdString();
}
boost::gregorian::date QtHistoryWindow::getLastVisibleDate() {
- if (!dates_.empty()) {
- QDate lastDate = *dates_.rbegin();
- int year, month, day;
- lastDate.getDate(&year, &month, &day);
-
- return boost::gregorian::date(boost::numeric_cast<unsigned short>(year), boost::numeric_cast<unsigned short>(month), boost::numeric_cast<unsigned short>(day));
- }
- return boost::gregorian::date(boost::gregorian::not_a_date_time);
+ if (!dates_.empty()) {
+ QDate lastDate = *dates_.rbegin();
+ int year, month, day;
+ lastDate.getDate(&year, &month, &day);
+
+ return boost::gregorian::date(boost::numeric_cast<unsigned short>(year), boost::numeric_cast<unsigned short>(month), boost::numeric_cast<unsigned short>(day));
+ }
+ return boost::gregorian::date(boost::gregorian::not_a_date_time);
}
std::string QtHistoryWindow::getID() const {
- return "QtHistoryWindow";
+ return "QtHistoryWindow";
}
}
diff --git a/Swift/QtUI/QtHistoryWindow.h b/Swift/QtUI/QtHistoryWindow.h
index e17d29f..02d7fb8 100644
--- a/Swift/QtUI/QtHistoryWindow.h
+++ b/Swift/QtUI/QtHistoryWindow.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2013 Isode Limited.
+ * Copyright (c) 2013-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -19,65 +19,64 @@
#include <Swift/Controllers/UIInterfaces/HistoryWindow.h>
#include <Swift/QtUI/QtTabbable.h>
-
#include <Swift/QtUI/ui_QtHistoryWindow.h>
namespace Swift {
- class QtTabbable;
- class QtTreeWidget;
- class QtWebKitChatView;
- class QtChatTheme;
- class SettingsProvider;
- class UIEventStream;
-
- class QtHistoryWindow : public QtTabbable, public HistoryWindow {
- Q_OBJECT
-
- public:
- QtHistoryWindow(SettingsProvider*, UIEventStream*);
- ~QtHistoryWindow();
- void activate();
- void setRosterModel(Roster*);
- void addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, const std::string& avatarPath, const boost::posix_time::ptime& time, bool addAtTheTop);
- void resetConversationView();
- void resetConversationViewTopInsertPoint();
- void setDate(const boost::gregorian::date& date);
-
- void closeEvent(QCloseEvent* event);
- void showEvent(QShowEvent* event);
-
- std::string getSearchBoxText();
- boost::gregorian::date getLastVisibleDate();
-
- virtual std::string getID() const;
-
- signals:
- void fontResized(int);
-
- public slots:
- void handleFontResized(int fontSizeSteps);
-
- protected slots:
- void handleScrollRequested(int pos);
- void handleScrollReachedTop();
- void handleScrollReachedBottom();
- void handleReturnPressed();
- void handleCalendarClicked(const QDate& date);
- void handlePreviousButtonClicked();
- void handleNextButtonClicked();
-
- private:
- void handleSomethingSelectedChanged(RosterItem* item);
-
- Ui::QtHistoryWindow ui_;
- QtChatTheme* theme_;
- QtWebKitChatView* conversation_;
- QtTreeWidget* conversationRoster_;
- std::set<QDate> dates_;
- int idCounter_;
- bool previousTopMessageWasSelf_;
- QString previousTopSenderName_;
- bool previousBottomMessageWasSelf_;
- QString previousBottomSenderName_;
- };
+ class QtTabbable;
+ class QtTreeWidget;
+ class QtWebKitChatView;
+ class QtChatTheme;
+ class SettingsProvider;
+ class UIEventStream;
+
+ class QtHistoryWindow : public QtTabbable, public HistoryWindow {
+ Q_OBJECT
+
+ public:
+ QtHistoryWindow(SettingsProvider*, UIEventStream*);
+ ~QtHistoryWindow();
+ void activate();
+ void setRosterModel(Roster*);
+ void addMessage(const std::string& message, const std::string& senderName, bool senderIsSelf, const std::string& avatarPath, const boost::posix_time::ptime& time, bool addAtTheTop);
+ void resetConversationView();
+ void resetConversationViewTopInsertPoint();
+ void setDate(const boost::gregorian::date& date);
+
+ void closeEvent(QCloseEvent* event);
+ void showEvent(QShowEvent* event);
+
+ std::string getSearchBoxText();
+ boost::gregorian::date getLastVisibleDate();
+
+ virtual std::string getID() const;
+
+ signals:
+ void fontResized(int);
+
+ public slots:
+ void handleFontResized(int fontSizeSteps);
+
+ protected slots:
+ void handleScrollRequested(int pos);
+ void handleScrollReachedTop();
+ void handleScrollReachedBottom();
+ void handleReturnPressed();
+ void handleCalendarClicked(const QDate& date);
+ void handlePreviousButtonClicked();
+ void handleNextButtonClicked();
+
+ private:
+ void handleSomethingSelectedChanged(RosterItem* item);
+
+ Ui::QtHistoryWindow ui_;
+ QtChatTheme* theme_;
+ QtWebKitChatView* conversation_;
+ QtTreeWidget* conversationRoster_;
+ std::set<QDate> dates_;
+ int idCounter_;
+ bool previousTopMessageWasSelf_;
+ QString previousTopSenderName_;
+ bool previousBottomMessageWasSelf_;
+ QString previousBottomSenderName_;
+ };
}
diff --git a/Swift/QtUI/QtJoinMUCWindow.cpp b/Swift/QtUI/QtJoinMUCWindow.cpp
index 53944da..400d1bf 100644
--- a/Swift/QtUI/QtJoinMUCWindow.cpp
+++ b/Swift/QtUI/QtJoinMUCWindow.cpp
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/QtJoinMUCWindow.h>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
#include <QToolTip>
@@ -17,59 +17,60 @@ namespace Swift {
QtJoinMUCWindow::QtJoinMUCWindow(UIEventStream* uiEventStream) : uiEventStream(uiEventStream) {
- ui.setupUi(this);
+ ui.setupUi(this);
#if QT_VERSION >= 0x040700
- ui.room->setPlaceholderText(tr("someroom@rooms.example.com"));
+ ui.room->setPlaceholderText(tr("someroom@rooms.example.com"));
#endif
- connect(ui.room, SIGNAL(returnPressed()), this, SLOT(handleJoin()));
- connect(ui.searchButton, SIGNAL(clicked()), this, SLOT(handleSearch()));
- connect(ui.joinButton, SIGNAL(clicked()), this, SLOT(handleJoin()));
+ connect(ui.room, SIGNAL(returnPressed()), this, SLOT(handleJoin()));
+ connect(ui.searchButton, SIGNAL(clicked()), this, SLOT(handleSearch()));
+ connect(ui.joinButton, SIGNAL(clicked()), this, SLOT(handleJoin()));
#if QT_VERSION < 0x050200
- // FIXME: Temporarily set focus on the nickName field first, so that the
- // placeholder for the room is visible. This is just because Qt hides
- // the placeholder when a widget is focused for some reason.
- // Tracked upstream as QTBUG-33237 and fixed with Qt 5.2.0.
- ui.nickName->setFocus();
+ // FIXME: Temporarily set focus on the nickName field first, so that the
+ // placeholder for the room is visible. This is just because Qt hides
+ // the placeholder when a widget is focused for some reason.
+ // Tracked upstream as QTBUG-33237 and fixed with Qt 5.2.0.
+ ui.nickName->setFocus();
#endif
- ui.instantRoom->setChecked(true);
- ui.nickName->setValidator(new NickValidator(this));
- ui.room->setValidator(new RoomJIDValidator(this));
+ ui.instantRoom->setChecked(true);
+ ui.nickName->setValidator(new NickValidator(this));
+ ui.room->setValidator(new RoomJIDValidator(this));
}
void QtJoinMUCWindow::handleJoin() {
- if (ui.room->text().isEmpty() || !ui.room->hasAcceptableInput()) {
- QToolTip::showText(ui.room->mapToGlobal(QPoint()), tr("Please enter a valid room address."), ui.room);
- return;
- }
- if (ui.nickName->text().isEmpty() || !ui.nickName->hasAcceptableInput()) {
- QToolTip::showText(ui.nickName->mapToGlobal(QPoint()), tr("Please enter a valid nickname."), ui.nickName);
- return;
- }
+ if (ui.room->text().isEmpty() || !ui.room->hasAcceptableInput()) {
+ QToolTip::showText(ui.room->mapToGlobal(QPoint()), tr("Please enter a valid room address."), ui.room);
+ return;
+ }
+ if (ui.nickName->text().isEmpty() || !ui.nickName->hasAcceptableInput()) {
+ QToolTip::showText(ui.nickName->mapToGlobal(QPoint()), tr("Please enter a valid nickname."), ui.nickName);
+ return;
+ }
- lastSetNick = Q2PSTRING(ui.nickName->text());
- std::string password = Q2PSTRING(ui.password->text());
- JID room(Q2PSTRING(ui.room->text()));
- uiEventStream->send(boost::make_shared<JoinMUCUIEvent>(room, password, lastSetNick, ui.joinAutomatically->isChecked(), !ui.instantRoom->isChecked()));
- hide();
+ lastSetNick = Q2PSTRING(ui.nickName->text());
+ std::string password = Q2PSTRING(ui.password->text());
+ JID room(Q2PSTRING(ui.room->text()));
+ uiEventStream->send(std::make_shared<JoinMUCUIEvent>(room, password, lastSetNick, ui.joinAutomatically->isChecked(), !ui.instantRoom->isChecked()));
+ hide();
}
void QtJoinMUCWindow::handleSearch() {
- onSearchMUC();
+ onSearchMUC();
}
void QtJoinMUCWindow::setNick(const std::string& nick) {
- ui.nickName->setText(P2QSTRING(nick));
- lastSetNick = nick;
+ ui.nickName->setText(P2QSTRING(nick));
+ lastSetNick = nick;
}
void QtJoinMUCWindow::setMUC(const std::string& nick) {
- ui.room->setText(P2QSTRING(nick));
+ ui.room->setText(P2QSTRING(nick));
}
void QtJoinMUCWindow::show() {
- QWidget::show();
- QWidget::activateWindow();
- ui.password->setText("");
+ QWidget::show();
+ QWidget::activateWindow();
+ QWidget::raise();
+ ui.password->setText("");
}
}
diff --git a/Swift/QtUI/QtJoinMUCWindow.h b/Swift/QtUI/QtJoinMUCWindow.h
index 92580ff..c2e8068 100644
--- a/Swift/QtUI/QtJoinMUCWindow.h
+++ b/Swift/QtUI/QtJoinMUCWindow.h
@@ -1,13 +1,11 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swift/QtUI/ui_QtJoinMUCWindow.h>
-
#include <string>
#include <QValidator>
@@ -15,62 +13,63 @@
#include <Swift/Controllers/UIInterfaces/JoinMUCWindow.h>
#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/ui_QtJoinMUCWindow.h>
namespace Swift {
- class UIEventStream;
- class NickValidator : public QValidator {
- Q_OBJECT
- public:
- NickValidator(QObject* parent) : QValidator(parent) {
- }
-
- virtual QValidator::State validate(QString& input, int& /*pos*/) const {
- if (input.isEmpty()) {
- return QValidator::Intermediate;
- }
- JID test("alice", "wonderland.lit", Q2PSTRING(input));
-
- return test.isValid() ? QValidator::Acceptable : QValidator::Invalid;
- }
- };
-
- class RoomJIDValidator : public QValidator {
- Q_OBJECT
- public:
- RoomJIDValidator(QObject* parent) : QValidator(parent) {
- }
-
- virtual QValidator::State validate(QString& input, int& /*pos*/) const {
- if (input.isEmpty()) {
- return QValidator::Intermediate;
- }
- JID roomJID(Q2PSTRING(input));
-
- if (roomJID.getNode().empty() || roomJID.getDomain().empty()) {
- return QValidator::Intermediate;
- }
-
- return (roomJID.getResource().empty() && !roomJID.getNode().empty() && !roomJID.getDomain().empty() && roomJID.isValid()) ? QValidator::Acceptable : QValidator::Invalid;
- }
- };
-
- class QtJoinMUCWindow : public QWidget, public JoinMUCWindow {
- Q_OBJECT
- public:
- QtJoinMUCWindow(UIEventStream* uiEventStream);
-
- virtual void setNick(const std::string& nick);
- virtual void setMUC(const std::string& nick);
-
- virtual void show();
-
- private slots:
- void handleJoin();
- void handleSearch();
-
- private:
- Ui::QtJoinMUCWindow ui;
- std::string lastSetNick;
- UIEventStream* uiEventStream;
- };
+ class UIEventStream;
+ class NickValidator : public QValidator {
+ Q_OBJECT
+ public:
+ NickValidator(QObject* parent) : QValidator(parent) {
+ }
+
+ virtual QValidator::State validate(QString& input, int& /*pos*/) const {
+ if (input.isEmpty()) {
+ return QValidator::Intermediate;
+ }
+ JID test("alice", "wonderland.lit", Q2PSTRING(input));
+
+ return test.isValid() ? QValidator::Acceptable : QValidator::Invalid;
+ }
+ };
+
+ class RoomJIDValidator : public QValidator {
+ Q_OBJECT
+ public:
+ RoomJIDValidator(QObject* parent) : QValidator(parent) {
+ }
+
+ virtual QValidator::State validate(QString& input, int& /*pos*/) const {
+ if (input.isEmpty()) {
+ return QValidator::Intermediate;
+ }
+ JID roomJID(Q2PSTRING(input));
+
+ if (roomJID.getNode().empty() || roomJID.getDomain().empty()) {
+ return QValidator::Intermediate;
+ }
+
+ return (roomJID.getResource().empty() && !roomJID.getNode().empty() && !roomJID.getDomain().empty() && roomJID.isValid()) ? QValidator::Acceptable : QValidator::Invalid;
+ }
+ };
+
+ class QtJoinMUCWindow : public QWidget, public JoinMUCWindow {
+ Q_OBJECT
+ public:
+ QtJoinMUCWindow(UIEventStream* uiEventStream);
+
+ virtual void setNick(const std::string& nick);
+ virtual void setMUC(const std::string& nick);
+
+ virtual void show();
+
+ private slots:
+ void handleJoin();
+ void handleSearch();
+
+ private:
+ Ui::QtJoinMUCWindow ui;
+ std::string lastSetNick;
+ UIEventStream* uiEventStream;
+ };
}
diff --git a/Swift/QtUI/QtLineEdit.cpp b/Swift/QtUI/QtLineEdit.cpp
index 75deafe..d3ec4c4 100644
--- a/Swift/QtUI/QtLineEdit.cpp
+++ b/Swift/QtUI/QtLineEdit.cpp
@@ -1,10 +1,10 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/QtUI/QtLineEdit.h"
+#include <Swift/QtUI/QtLineEdit.h>
#include <QKeyEvent>
@@ -14,10 +14,10 @@ QtLineEdit::QtLineEdit(QWidget* parent) : QLineEdit(parent) {
}
void QtLineEdit::keyPressEvent(QKeyEvent* event) {
- if (event->key() == Qt::Key_Escape) {
- emit escapePressed();
- }
- QLineEdit::keyPressEvent(event);
+ if (event->key() == Qt::Key_Escape) {
+ emit escapePressed();
+ }
+ QLineEdit::keyPressEvent(event);
}
}
diff --git a/Swift/QtUI/QtLineEdit.h b/Swift/QtUI/QtLineEdit.h
index 1c7240a..851a2ff 100644
--- a/Swift/QtUI/QtLineEdit.h
+++ b/Swift/QtUI/QtLineEdit.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -9,13 +9,13 @@
#include <QLineEdit>
namespace Swift {
- class QtLineEdit : public QLineEdit {
- Q_OBJECT
- public:
- QtLineEdit(QWidget* parent = NULL);
- signals:
- void escapePressed();
- protected:
- virtual void keyPressEvent(QKeyEvent* event);
- };
+ class QtLineEdit : public QLineEdit {
+ Q_OBJECT
+ public:
+ QtLineEdit(QWidget* parent = nullptr);
+ signals:
+ void escapePressed();
+ protected:
+ virtual void keyPressEvent(QKeyEvent* event);
+ };
}
diff --git a/Swift/QtUI/QtLoginWindow.cpp b/Swift/QtUI/QtLoginWindow.cpp
index 229df7f..865d8b5 100644
--- a/Swift/QtUI/QtLoginWindow.cpp
+++ b/Swift/QtUI/QtLoginWindow.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -10,7 +10,7 @@
#include <cassert>
#include <boost/bind.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
#include <QApplication>
#include <QBoxLayout>
@@ -54,524 +54,523 @@
namespace Swift{
QtLoginWindow::QtLoginWindow(UIEventStream* uiEventStream, SettingsProvider* settings, TimerFactory* timerFactory) : QMainWindow(), settings_(settings), timerFactory_(timerFactory) {
- uiEventStream_ = uiEventStream;
+ uiEventStream_ = uiEventStream;
- setWindowTitle("Swift");
+ setWindowTitle("Swift");
#ifndef Q_OS_MAC
#ifdef Q_OS_WIN32
- setWindowIcon(QIcon(":/logo-icon-16-win.png"));
+ setWindowIcon(QIcon(":/logo-icon-16-win.png"));
#else
- setWindowIcon(QIcon(":/logo-icon-16.png"));
+ setWindowIcon(QIcon(":/logo-icon-16.png"));
#endif
#endif
- QtUtilities::setX11Resource(this, "Main");
- setAccessibleName(tr("Swift Login Window"));
- //setAccessibleDescription(tr("This window is used for providing credentials to log into your XMPP service"));
-
- resize(200, 500);
- setContentsMargins(0,0,0,0);
- QWidget *centralWidget = new QWidget(this);
- setCentralWidget(centralWidget);
- QBoxLayout *topLayout = new QBoxLayout(QBoxLayout::TopToBottom, centralWidget);
- stack_ = new QStackedWidget(centralWidget);
- topLayout->addWidget(stack_);
- topLayout->setMargin(0);
- loginWidgetWrapper_ = new QWidget(this);
- loginWidgetWrapper_->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
- QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, loginWidgetWrapper_);
- layout->addStretch(2);
-
- QLabel* logo = new QLabel(this);
- logo->setPixmap(QPixmap(":/logo-shaded-text.256.png"));
- logo->setScaledContents(true);
- logo->setFixedSize(192,192);
-
- QWidget *logoWidget = new QWidget(this);
- QHBoxLayout *logoLayout = new QHBoxLayout();
- logoLayout->setMargin(0);
- logoLayout->addStretch(0);
- logoLayout->addWidget(logo);
- logoLayout->addStretch(0);
- logoWidget->setLayout(logoLayout);
- layout->addWidget(logoWidget);
-
- layout->addStretch(2);
-
- QLabel* jidLabel = new QLabel(this);
- jidLabel->setText("<font size='-1'>" + tr("User address:") + "</font>");
- layout->addWidget(jidLabel);
-
-
- username_ = new QComboBox(this);
- username_->setEditable(true);
- username_->setWhatsThis(tr("User address - looks like someuser@someserver.com"));
- username_->setToolTip(tr("User address - looks like someuser@someserver.com"));
- username_->view()->installEventFilter(this);
- username_->setAccessibleName(tr("User address (of the form someuser@someserver.com)"));
- username_->setAccessibleDescription(tr("This is the user address that you'll be using to log in with"));
- layout->addWidget(username_);
- QLabel* jidHintLabel = new QLabel(this);
- jidHintLabel->setText("<font size='-1' color='grey' >" + tr("Example: alice@wonderland.lit") + "</font>");
- jidHintLabel->setAlignment(Qt::AlignRight);
- layout->addWidget(jidHintLabel);
-
-
- QLabel* passwordLabel = new QLabel();
- passwordLabel->setText("<font size='-1'>" + tr("Password:") + "</font>");
- passwordLabel->setAccessibleName(tr("User password"));
- passwordLabel->setAccessibleDescription(tr("This is the password you'll use to log in to the XMPP service"));
- layout->addWidget(passwordLabel);
-
-
- QWidget* w = new QWidget(this);
- w->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
- layout->addWidget(w);
-
- QHBoxLayout* credentialsLayout = new QHBoxLayout(w);
- credentialsLayout->setMargin(0);
- credentialsLayout->setSpacing(3);
- password_ = new QLineEdit(this);
- password_->setEchoMode(QLineEdit::Password);
- connect(password_, SIGNAL(returnPressed()), this, SLOT(loginClicked()));
- connect(username_->lineEdit(), SIGNAL(returnPressed()), password_, SLOT(setFocus()));
- connect(username_, SIGNAL(editTextChanged(const QString&)), this, SLOT(handleUsernameTextChanged()));
- credentialsLayout->addWidget(password_);
-
- certificateButton_ = new QToolButton(this);
- certificateButton_->setCheckable(true);
- certificateButton_->setIcon(QIcon(":/icons/certificate.png"));
- certificateButton_->setToolTip(tr("Click if you have a personal certificate used for login to the service."));
- certificateButton_->setWhatsThis(tr("Click if you have a personal certificate used for login to the service."));
- certificateButton_->setAccessibleName(tr("Login with certificate"));
- certificateButton_->setAccessibleDescription(tr("Click if you have a personal certificate used for login to the service."));
-
- credentialsLayout->addWidget(certificateButton_);
- connect(certificateButton_, SIGNAL(clicked(bool)), SLOT(handleCertficateChecked(bool)));
-
- loginButton_ = new QPushButton(this);
- loginButton_->setText(tr("Connect"));
- loginButton_->setAutoDefault(true);
- loginButton_->setDefault(true);
- loginButton_->setAccessibleName(tr("Connect now"));
- layout->addWidget(loginButton_);
-
- QLabel* connectionOptionsLabel = new QLabel(this);
- connectionOptionsLabel->setText("<a href=\"#\"><font size='-1'>" + QObject::tr("Connection Options") + "</font></a>");
- connectionOptionsLabel->setTextFormat(Qt::RichText);
- connectionOptionsLabel->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
- layout->addWidget(connectionOptionsLabel);
- connect(connectionOptionsLabel, SIGNAL(linkActivated(const QString&)), SLOT(handleOpenConnectionOptions()));
-
- message_ = new QLabel(this);
- message_->setTextFormat(Qt::RichText);
- message_->setWordWrap(true);
- layout->addWidget(message_);
-
- layout->addStretch(2);
- remember_ = new QCheckBox(tr("Remember Password?"), this);
- layout->addWidget(remember_);
- loginAutomatically_ = new QCheckBox(tr("Login Automatically?"), this);
- layout->addWidget(loginAutomatically_);
-
- connect(loginButton_, SIGNAL(clicked()), SLOT(loginClicked()));
- stack_->addWidget(loginWidgetWrapper_);
+ QtUtilities::setX11Resource(this, "Main");
+ setAccessibleName(tr("Swift Login Window"));
+ //setAccessibleDescription(tr("This window is used for providing credentials to log into your XMPP service"));
+
+ resize(200, 500);
+ setContentsMargins(0,0,0,0);
+ QWidget *centralWidget = new QWidget(this);
+ setCentralWidget(centralWidget);
+ QBoxLayout *topLayout = new QBoxLayout(QBoxLayout::TopToBottom, centralWidget);
+ stack_ = new QStackedWidget(centralWidget);
+ topLayout->addWidget(stack_);
+ topLayout->setMargin(0);
+ loginWidgetWrapper_ = new QWidget(this);
+ loginWidgetWrapper_->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
+ QBoxLayout *layout = new QBoxLayout(QBoxLayout::TopToBottom, loginWidgetWrapper_);
+ layout->addStretch(2);
+
+ QLabel* logo = new QLabel(this);
+ QIcon swiftWithTextLogo = QIcon(":/logo-shaded-text.png");
+ logo->setPixmap(swiftWithTextLogo.pixmap(QSize(192,192)));
+
+ QWidget *logoWidget = new QWidget(this);
+ QHBoxLayout *logoLayout = new QHBoxLayout();
+ logoLayout->setMargin(0);
+ logoLayout->addStretch(0);
+ logoLayout->addWidget(logo);
+ logoLayout->addStretch(0);
+ logoWidget->setLayout(logoLayout);
+ layout->addWidget(logoWidget);
+
+ layout->addStretch(2);
+
+ QLabel* jidLabel = new QLabel(this);
+ jidLabel->setText("<font size='-1'>" + tr("User address:") + "</font>");
+ layout->addWidget(jidLabel);
+
+
+ username_ = new QComboBox(this);
+ username_->setEditable(true);
+ username_->setWhatsThis(tr("User address - looks like someuser@someserver.com"));
+ username_->setToolTip(tr("User address - looks like someuser@someserver.com"));
+ username_->view()->installEventFilter(this);
+ username_->setAccessibleName(tr("User address (of the form someuser@someserver.com)"));
+ username_->setAccessibleDescription(tr("This is the user address that you'll be using to log in with"));
+ layout->addWidget(username_);
+ QLabel* jidHintLabel = new QLabel(this);
+ jidHintLabel->setText("<font size='-1' color='grey' >" + tr("Example: alice@wonderland.lit") + "</font>");
+ jidHintLabel->setAlignment(Qt::AlignRight);
+ layout->addWidget(jidHintLabel);
+
+
+ QLabel* passwordLabel = new QLabel();
+ passwordLabel->setText("<font size='-1'>" + tr("Password:") + "</font>");
+ passwordLabel->setAccessibleName(tr("User password"));
+ passwordLabel->setAccessibleDescription(tr("This is the password you'll use to log in to the XMPP service"));
+ layout->addWidget(passwordLabel);
+
+
+ QWidget* w = new QWidget(this);
+ w->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
+ layout->addWidget(w);
+
+ QHBoxLayout* credentialsLayout = new QHBoxLayout(w);
+ credentialsLayout->setMargin(0);
+ credentialsLayout->setSpacing(3);
+ password_ = new QLineEdit(this);
+ password_->setEchoMode(QLineEdit::Password);
+ connect(password_, SIGNAL(returnPressed()), this, SLOT(loginClicked()));
+ connect(username_->lineEdit(), SIGNAL(returnPressed()), password_, SLOT(setFocus()));
+ connect(username_, SIGNAL(editTextChanged(const QString&)), this, SLOT(handleUsernameTextChanged()));
+ credentialsLayout->addWidget(password_);
+
+ certificateButton_ = new QToolButton(this);
+ certificateButton_->setCheckable(true);
+ certificateButton_->setIcon(QIcon(":/icons/certificate.png"));
+ certificateButton_->setToolTip(tr("Click if you have a personal certificate used for login to the service."));
+ certificateButton_->setWhatsThis(tr("Click if you have a personal certificate used for login to the service."));
+ certificateButton_->setAccessibleName(tr("Login with certificate"));
+ certificateButton_->setAccessibleDescription(tr("Click if you have a personal certificate used for login to the service."));
+
+ credentialsLayout->addWidget(certificateButton_);
+ connect(certificateButton_, SIGNAL(clicked(bool)), SLOT(handleCertficateChecked(bool)));
+
+ loginButton_ = new QPushButton(this);
+ loginButton_->setText(tr("Connect"));
+ loginButton_->setAutoDefault(true);
+ loginButton_->setDefault(true);
+ loginButton_->setAccessibleName(tr("Connect now"));
+ layout->addWidget(loginButton_);
+
+ QLabel* connectionOptionsLabel = new QLabel(this);
+ connectionOptionsLabel->setText("<a href=\"#\"><font size='-1'>" + QObject::tr("Connection Options") + "</font></a>");
+ connectionOptionsLabel->setTextFormat(Qt::RichText);
+ connectionOptionsLabel->setAlignment(Qt::AlignRight|Qt::AlignVCenter);
+ layout->addWidget(connectionOptionsLabel);
+ connect(connectionOptionsLabel, SIGNAL(linkActivated(const QString&)), SLOT(handleOpenConnectionOptions()));
+
+ message_ = new QLabel(this);
+ message_->setTextFormat(Qt::RichText);
+ message_->setWordWrap(true);
+ layout->addWidget(message_);
+
+ layout->addStretch(2);
+ remember_ = new QCheckBox(tr("Remember Password?"), this);
+ layout->addWidget(remember_);
+ loginAutomatically_ = new QCheckBox(tr("Login Automatically?"), this);
+ layout->addWidget(loginAutomatically_);
+
+ connect(loginButton_, SIGNAL(clicked()), SLOT(loginClicked()));
+ stack_->addWidget(loginWidgetWrapper_);
#ifdef SWIFTEN_PLATFORM_MACOSX
- menuBar_ = new QMenuBar(NULL);
+ menuBar_ = new QMenuBar(nullptr);
#else
- menuBar_ = menuBar();
+ menuBar_ = menuBar();
#endif
- QApplication::setQuitOnLastWindowClosed(false);
+ QApplication::setQuitOnLastWindowClosed(false);
- swiftMenu_ = new QMenu(tr("&Swift"), this);
+ swiftMenu_ = new QMenu(tr("&Swift"), this);
#ifdef SWIFTEN_PLATFORM_MACOSX
- generalMenu_ = new QMenu(tr("&General"), this);
+ generalMenu_ = new QMenu(tr("&General"), this);
#else
- generalMenu_ = swiftMenu_;
+ generalMenu_ = swiftMenu_;
#endif
#ifdef SWIFTEN_PLATFORM_MACOSX
- QAction* aboutAction = new QAction(QString("&About %1").arg("Swift"), this);
+ QAction* aboutAction = new QAction(QString("&About %1").arg("Swift"), this);
#else
- QAction* aboutAction = new QAction(QString(tr("&About %1")).arg("Swift"), this);
+ QAction* aboutAction = new QAction(QString(tr("&About %1")).arg("Swift"), this);
#endif
- connect(aboutAction, SIGNAL(triggered()), SLOT(handleAbout()));
- swiftMenu_->addAction(aboutAction);
+ connect(aboutAction, SIGNAL(triggered()), SLOT(handleAbout()));
+ swiftMenu_->addAction(aboutAction);
- xmlConsoleAction_ = new QAction(tr("&Show Debug Console"), this);
- connect(xmlConsoleAction_, SIGNAL(triggered()), SLOT(handleShowXMLConsole()));
- generalMenu_->addAction(xmlConsoleAction_);
+ xmlConsoleAction_ = new QAction(tr("&Show Debug Console"), this);
+ connect(xmlConsoleAction_, SIGNAL(triggered()), SLOT(handleShowXMLConsole()));
+ generalMenu_->addAction(xmlConsoleAction_);
#ifdef SWIFT_EXPERIMENTAL_FT
- fileTransferOverviewAction_ = new QAction(tr("Show &File Transfer Overview"), this);
- connect(fileTransferOverviewAction_, SIGNAL(triggered()), SLOT(handleShowFileTransferOverview()));
- generalMenu_->addAction(fileTransferOverviewAction_);
+ fileTransferOverviewAction_ = new QAction(tr("Show &File Transfer Overview"), this);
+ connect(fileTransferOverviewAction_, SIGNAL(triggered()), SLOT(handleShowFileTransferOverview()));
+ generalMenu_->addAction(fileTransferOverviewAction_);
#endif
- highlightEditorAction_ = new QAction(tr("&Edit Highlight Rules"), this);
- connect(highlightEditorAction_, SIGNAL(triggered()), SLOT(handleShowHighlightEditor()));
- generalMenu_->addAction(highlightEditorAction_);
+ highlightEditorAction_ = new QAction(tr("&Edit Highlight Rules"), this);
+ connect(highlightEditorAction_, SIGNAL(triggered()), SLOT(handleShowHighlightEditor()));
+ generalMenu_->addAction(highlightEditorAction_);
- toggleSoundsAction_ = new QAction(tr("&Play Sounds"), this);
- toggleSoundsAction_->setCheckable(true);
- toggleSoundsAction_->setChecked(settings_->getSetting(SettingConstants::PLAY_SOUNDS));
- connect(toggleSoundsAction_, SIGNAL(toggled(bool)), SLOT(handleToggleSounds(bool)));
- generalMenu_->addAction(toggleSoundsAction_);
+ toggleSoundsAction_ = new QAction(tr("&Play Sounds"), this);
+ toggleSoundsAction_->setCheckable(true);
+ toggleSoundsAction_->setChecked(settings_->getSetting(SettingConstants::PLAY_SOUNDS));
+ connect(toggleSoundsAction_, SIGNAL(toggled(bool)), SLOT(handleToggleSounds(bool)));
+ generalMenu_->addAction(toggleSoundsAction_);
- toggleNotificationsAction_ = new QAction(tr("Display Pop-up &Notifications"), this);
- toggleNotificationsAction_->setCheckable(true);
- toggleNotificationsAction_->setChecked(settings_->getSetting(SettingConstants::SHOW_NOTIFICATIONS));
- connect(toggleNotificationsAction_, SIGNAL(toggled(bool)), SLOT(handleToggleNotifications(bool)));
+ toggleNotificationsAction_ = new QAction(tr("Display Pop-up &Notifications"), this);
+ toggleNotificationsAction_->setCheckable(true);
+ toggleNotificationsAction_->setChecked(settings_->getSetting(SettingConstants::SHOW_NOTIFICATIONS));
+ connect(toggleNotificationsAction_, SIGNAL(toggled(bool)), SLOT(handleToggleNotifications(bool)));
#ifndef SWIFTEN_PLATFORM_MACOSX
- swiftMenu_->addSeparator();
+ swiftMenu_->addSeparator();
#endif
#ifdef SWIFTEN_PLATFORM_MACOSX
- QAction* quitAction = new QAction("&Quit", this);
+ QAction* quitAction = new QAction("&Quit", this);
#else
- QAction* quitAction = new QAction(tr("&Quit"), this);
+ QAction* quitAction = new QAction(tr("&Quit"), this);
#endif
- connect(quitAction, SIGNAL(triggered()), SLOT(handleQuit()));
- swiftMenu_->addAction(quitAction);
+ connect(quitAction, SIGNAL(triggered()), SLOT(handleQuit()));
+ swiftMenu_->addAction(quitAction);
- setInitialMenus();
- settings_->onSettingChanged.connect(boost::bind(&QtLoginWindow::handleSettingChanged, this, _1));
+ setInitialMenus();
+ settings_->onSettingChanged.connect(boost::bind(&QtLoginWindow::handleSettingChanged, this, _1));
- bool eagle = settings_->getSetting(SettingConstants::FORGET_PASSWORDS);
- remember_->setEnabled(!eagle);
- loginAutomatically_->setEnabled(!eagle);
- xmlConsoleAction_->setEnabled(!eagle);
- if (eagle) {
- remember_->setChecked(false);
- loginAutomatically_->setChecked(false);
- }
+ bool eagle = settings_->getSetting(SettingConstants::FORGET_PASSWORDS);
+ remember_->setEnabled(!eagle);
+ loginAutomatically_->setEnabled(!eagle);
+ xmlConsoleAction_->setEnabled(!eagle);
+ if (eagle) {
+ remember_->setChecked(false);
+ loginAutomatically_->setChecked(false);
+ }
#ifdef SWIFTEN_PLATFORM_MACOSX
- // Temporary workaround for case 501. Could be that this code is still
- // needed when Qt provides a proper fix
- qApp->installEventFilter(this);
+ // Temporary workaround for case 501. Could be that this code is still
+ // needed when Qt provides a proper fix
+ qApp->installEventFilter(this);
#endif
- this->show();
+ this->show();
}
void QtLoginWindow::setShowNotificationToggle(bool toggle) {
- if (toggle) {
- QList< QAction* > generalMenuActions = generalMenu_->actions();
- generalMenu_->insertAction(generalMenuActions.at(generalMenuActions.count()-2), toggleNotificationsAction_);
- }
- else {
- generalMenu_->removeAction(toggleNotificationsAction_);
- }
+ if (toggle) {
+ QList< QAction* > generalMenuActions = generalMenu_->actions();
+ generalMenu_->insertAction(generalMenuActions.at(generalMenuActions.count()-2), toggleNotificationsAction_);
+ }
+ else {
+ generalMenu_->removeAction(toggleNotificationsAction_);
+ }
}
bool QtLoginWindow::eventFilter(QObject *obj, QEvent *event) {
- if (obj == username_->view() && event->type() == QEvent::KeyPress) {
- QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
- if (keyEvent->key() == Qt::Key_Delete || keyEvent->key() == Qt::Key_Backspace) {
- QString jid(username_->view()->currentIndex().data().toString());
- int result = QMessageBox::question(this, tr("Remove profile"), tr("Remove the profile '%1'?").arg(jid), QMessageBox::Yes | QMessageBox::No);
- if (result == QMessageBox::Yes) {
- onPurgeSavedLoginRequest(Q2PSTRING(jid));
- }
- return true;
- }
- }
+ if (obj == username_->view() && event->type() == QEvent::KeyPress) {
+ QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
+ if (keyEvent->key() == Qt::Key_Delete || keyEvent->key() == Qt::Key_Backspace) {
+ QString jid(username_->view()->currentIndex().data().toString());
+ int result = QMessageBox::question(this, tr("Remove profile"), tr("Remove the profile '%1'?").arg(jid), QMessageBox::Yes | QMessageBox::No);
+ if (result == QMessageBox::Yes) {
+ onPurgeSavedLoginRequest(Q2PSTRING(jid));
+ }
+ return true;
+ }
+ }
#ifdef SWIFTEN_PLATFORM_MACOSX
- // Dock clicked
- // Temporary workaround for case 501. Could be that this code is still
- // needed when Qt provides a proper fix
- if (obj == qApp && event->type() == QEvent::ApplicationActivate && !isVisible()) {
- bringToFront();
- }
+ // Dock clicked
+ // Temporary workaround for case 501. Could be that this code is still
+ // needed when Qt provides a proper fix
+ if (obj == qApp && event->type() == QEvent::ApplicationActivate && !isVisible()) {
+ bringToFront();
+ }
#endif
- return QObject::eventFilter(obj, event);
+ return QObject::eventFilter(obj, event);
}
void QtLoginWindow::handleSettingChanged(const std::string& settingPath) {
- if (settingPath == SettingConstants::PLAY_SOUNDS.getKey()) {
- toggleSoundsAction_->setChecked(settings_->getSetting(SettingConstants::PLAY_SOUNDS));
- }
- if (settingPath == SettingConstants::SHOW_NOTIFICATIONS.getKey()) {
- toggleNotificationsAction_->setChecked(settings_->getSetting(SettingConstants::SHOW_NOTIFICATIONS));
- }
+ if (settingPath == SettingConstants::PLAY_SOUNDS.getKey()) {
+ toggleSoundsAction_->setChecked(settings_->getSetting(SettingConstants::PLAY_SOUNDS));
+ }
+ if (settingPath == SettingConstants::SHOW_NOTIFICATIONS.getKey()) {
+ toggleNotificationsAction_->setChecked(settings_->getSetting(SettingConstants::SHOW_NOTIFICATIONS));
+ }
}
void QtLoginWindow::selectUser(const std::string& username) {
- for (int i = 0; i < usernames_.count(); i++) {
- if (P2QSTRING(username) == usernames_[i]) {
- username_->setCurrentIndex(i);
- password_->setFocus();
- break;
- }
- }
+ for (int i = 0; i < usernames_.count(); i++) {
+ if (P2QSTRING(username) == usernames_[i]) {
+ username_->setCurrentIndex(i);
+ password_->setFocus();
+ break;
+ }
+ }
}
void QtLoginWindow::removeAvailableAccount(const std::string& jid) {
- QString username = P2QSTRING(jid);
- int index = -1;
- for (int i = 0; i < usernames_.count(); i++) {
- if (username == usernames_[i]) {
- index = i;
- }
- }
- if (index >= 0) {
- usernames_.removeAt(index);
- passwords_.removeAt(index);
- certificateFiles_.removeAt(index);
- username_->removeItem(index);
- }
+ QString username = P2QSTRING(jid);
+ int index = -1;
+ for (int i = 0; i < usernames_.count(); i++) {
+ if (username == usernames_[i]) {
+ index = i;
+ }
+ }
+ if (index >= 0) {
+ usernames_.removeAt(index);
+ passwords_.removeAt(index);
+ certificateFiles_.removeAt(index);
+ username_->removeItem(index);
+ }
}
void QtLoginWindow::addAvailableAccount(const std::string& defaultJID, const std::string& defaultPassword, const std::string& defaultCertificate, const ClientOptions& options) {
- QString username = P2QSTRING(defaultJID);
- int index = -1;
- for (int i = 0; i < usernames_.count(); i++) {
- if (username == usernames_[i]) {
- index = i;
- }
- }
- if (index == -1) {
- usernames_.append(username);
- passwords_.append(P2QSTRING(defaultPassword));
- certificateFiles_.append(P2QSTRING(defaultCertificate));
- options_.push_back(options);
- username_->addItem(username);
- } else {
- usernames_[index] = username;
- passwords_[index] = P2QSTRING(defaultPassword);
- certificateFiles_[index] = P2QSTRING(defaultCertificate);
- options_[index] = options;
- }
+ QString username = P2QSTRING(defaultJID);
+ int index = -1;
+ for (int i = 0; i < usernames_.count(); i++) {
+ if (username == usernames_[i]) {
+ index = i;
+ }
+ }
+ if (index == -1) {
+ usernames_.append(username);
+ passwords_.append(P2QSTRING(defaultPassword));
+ certificateFiles_.append(P2QSTRING(defaultCertificate));
+ options_.push_back(options);
+ username_->addItem(username);
+ } else {
+ usernames_[index] = username;
+ passwords_[index] = P2QSTRING(defaultPassword);
+ certificateFiles_[index] = P2QSTRING(defaultCertificate);
+ options_[index] = options;
+ }
}
void QtLoginWindow::handleUsernameTextChanged() {
- QString username = username_->currentText();
- for (int i = 0; i < usernames_.count(); i++) {
- if (username_->currentText() == usernames_[i]) {
- certificateFile_ = certificateFiles_[i];
- password_->setText(passwords_[i]);
- remember_->setChecked(password_->text() != "");
- currentOptions_ = options_[i];
- }
- }
- certificateButton_->setChecked(!certificateFile_.isEmpty());
+ QString username = username_->currentText();
+ for (int i = 0; i < usernames_.count(); i++) {
+ if (username_->currentText() == usernames_[i]) {
+ certificateFile_ = certificateFiles_[i];
+ password_->setText(passwords_[i]);
+ remember_->setChecked(password_->text() != "");
+ currentOptions_ = options_[i];
+ }
+ }
+ certificateButton_->setChecked(!certificateFile_.isEmpty());
}
void QtLoginWindow::loggedOut() {
- stack_->removeWidget(stack_->currentWidget());
- stack_->addWidget(loginWidgetWrapper_);
- stack_->setCurrentWidget(loginWidgetWrapper_);
- setInitialMenus();
- setIsLoggingIn(false);
+ stack_->removeWidget(stack_->currentWidget());
+ stack_->addWidget(loginWidgetWrapper_);
+ stack_->setCurrentWidget(loginWidgetWrapper_);
+ setInitialMenus();
+ setIsLoggingIn(false);
}
void QtLoginWindow::setIsLoggingIn(bool loggingIn) {
- /* Change the for loop as well if you add to this.*/
- QWidget* widgets[5] = {username_, password_, remember_, loginAutomatically_, certificateButton_};
- loginButton_->setText(loggingIn ? tr("Cancel") : tr("Connect"));
- for (int i = 0; i < 5; i++) {
- widgets[i]->setEnabled(!loggingIn);
- }
- bool eagle = settings_->getSetting(SettingConstants::FORGET_PASSWORDS);
- remember_->setEnabled(!eagle);
- loginAutomatically_->setEnabled(!eagle);
+ /* Change the for loop as well if you add to this.*/
+ QWidget* widgets[5] = {username_, password_, remember_, loginAutomatically_, certificateButton_};
+ loginButton_->setText(loggingIn ? tr("Cancel") : tr("Connect"));
+ for (auto& widget : widgets) {
+ widget->setEnabled(!loggingIn);
+ }
+ bool eagle = settings_->getSetting(SettingConstants::FORGET_PASSWORDS);
+ remember_->setEnabled(!eagle);
+ loginAutomatically_->setEnabled(!eagle);
}
void QtLoginWindow::loginClicked() {
- if (username_->isEnabled()) {
- std::string banner = settings_->getSetting(QtUISettingConstants::CLICKTHROUGH_BANNER);
- if (!banner.empty()) {
- QMessageBox msgBox;
- msgBox.setWindowTitle(tr("Confirm terms of use"));
- msgBox.setText("");
- msgBox.setInformativeText(P2QSTRING(banner));
- msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
- msgBox.setDefaultButton(QMessageBox::No);
- if (msgBox.exec() != QMessageBox::Yes) {
- return;
- }
- }
- CertificateWithKey::ref certificate;
- std::string certificateString = Q2PSTRING(certificateFile_);
- if (!certificateString.empty()) {
+ if (username_->isEnabled()) {
+ std::string banner = settings_->getSetting(QtUISettingConstants::CLICKTHROUGH_BANNER);
+ if (!banner.empty()) {
+ QMessageBox msgBox;
+ msgBox.setWindowTitle(tr("Confirm terms of use"));
+ msgBox.setText("");
+ msgBox.setInformativeText(P2QSTRING(banner));
+ msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+ msgBox.setDefaultButton(QMessageBox::No);
+ if (msgBox.exec() != QMessageBox::Yes) {
+ return;
+ }
+ }
+ CertificateWithKey::ref certificate;
+ std::string certificateString = Q2PSTRING(certificateFile_);
+ if (!certificateString.empty()) {
#if defined(HAVE_SCHANNEL)
- if (isCAPIURI(certificateString)) {
- certificate = boost::make_shared<CAPICertificate>(certificateString, timerFactory_);
- } else {
- certificate = boost::make_shared<PKCS12Certificate>(certificateString, createSafeByteArray(Q2PSTRING(password_->text())));
- }
+ if (isCAPIURI(certificateString)) {
+ certificate = std::make_shared<CAPICertificate>(certificateString, timerFactory_);
+ } else {
+ certificate = std::make_shared<PKCS12Certificate>(certificateString, createSafeByteArray(Q2PSTRING(password_->text())));
+ }
#else
- certificate = boost::make_shared<PKCS12Certificate>(certificateString, createSafeByteArray(Q2PSTRING(password_->text())));
+ certificate = std::make_shared<PKCS12Certificate>(certificateString, createSafeByteArray(Q2PSTRING(password_->text())));
#endif
- }
+ }
- onLoginRequest(Q2PSTRING(username_->currentText()), Q2PSTRING(password_->text()), certificateString, certificate, currentOptions_, remember_->isChecked(), loginAutomatically_->isChecked());
- if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { /* Mustn't remember logins */
- username_->clearEditText();
- password_->setText("");
- }
- } else {
- onCancelLoginRequest();
- }
+ onLoginRequest(Q2PSTRING(username_->currentText()), Q2PSTRING(password_->text()), certificateString, certificate, currentOptions_, remember_->isChecked(), loginAutomatically_->isChecked());
+ if (settings_->getSetting(SettingConstants::FORGET_PASSWORDS)) { /* Mustn't remember logins */
+ username_->clearEditText();
+ password_->setText("");
+ }
+ } else {
+ onCancelLoginRequest();
+ }
}
void QtLoginWindow::setLoginAutomatically(bool loginAutomatically) {
- loginAutomatically_->setChecked(loginAutomatically);
+ loginAutomatically_->setChecked(loginAutomatically);
}
void QtLoginWindow::handleCertficateChecked(bool checked) {
- if (checked) {
+ if (checked) {
#ifdef HAVE_SCHANNEL
- certificateFile_ = P2QSTRING(selectCAPICertificate());
- if (certificateFile_.isEmpty()) {
- certificateButton_->setChecked(false);
- }
+ certificateFile_ = P2QSTRING(selectCAPICertificate());
+ if (certificateFile_.isEmpty()) {
+ certificateButton_->setChecked(false);
+ }
#else
- certificateFile_ = QFileDialog::getOpenFileName(this, tr("Select an authentication certificate"), QString(), tr("P12 files (*.cert *.p12 *.pfx);;All files (*.*)"));
- if (certificateFile_.isEmpty()) {
- certificateButton_->setChecked(false);
- }
+ certificateFile_ = QFileDialog::getOpenFileName(this, tr("Select an authentication certificate"), QString(), tr("P12 files (*.cert *.p12 *.pfx);;All files (*.*)"));
+ if (certificateFile_.isEmpty()) {
+ certificateButton_->setChecked(false);
+ }
#endif
- }
- else {
- certificateFile_ = "";
- }
+ }
+ else {
+ certificateFile_ = "";
+ }
}
void QtLoginWindow::handleAbout() {
- if (!aboutDialog_) {
- aboutDialog_ = new QtAboutWidget();
- aboutDialog_->show();
- }
- else {
- aboutDialog_->show();
- aboutDialog_->raise();
- aboutDialog_->activateWindow();
- }
+ if (!aboutDialog_) {
+ aboutDialog_ = new QtAboutWidget(settings_);
+ aboutDialog_->show();
+ }
+ else {
+ aboutDialog_->show();
+ aboutDialog_->raise();
+ aboutDialog_->activateWindow();
+ }
}
void QtLoginWindow::handleShowXMLConsole() {
- uiEventStream_->send(boost::make_shared<RequestXMLConsoleUIEvent>());
+ uiEventStream_->send(std::make_shared<RequestXMLConsoleUIEvent>());
}
void QtLoginWindow::handleShowFileTransferOverview() {
- uiEventStream_->send(boost::make_shared<RequestFileTransferListUIEvent>());
+ uiEventStream_->send(std::make_shared<RequestFileTransferListUIEvent>());
}
void QtLoginWindow::handleShowHighlightEditor() {
- uiEventStream_->send(boost::make_shared<RequestHighlightEditorUIEvent>());
+ uiEventStream_->send(std::make_shared<RequestHighlightEditorUIEvent>());
}
void QtLoginWindow::handleToggleSounds(bool enabled) {
- settings_->storeSetting(SettingConstants::PLAY_SOUNDS, enabled);
+ settings_->storeSetting(SettingConstants::PLAY_SOUNDS, enabled);
}
void QtLoginWindow::handleToggleNotifications(bool enabled) {
- settings_->storeSetting(SettingConstants::SHOW_NOTIFICATIONS, enabled);
+ settings_->storeSetting(SettingConstants::SHOW_NOTIFICATIONS, enabled);
}
void QtLoginWindow::handleQuit() {
- onQuitRequest();
+ onQuitRequest();
}
void QtLoginWindow::quit() {
- QApplication::quit();
+ QApplication::quit();
}
void QtLoginWindow::setInitialMenus() {
- menuBar_->clear();
- menuBar_->addMenu(swiftMenu_);
+ menuBar_->clear();
+ menuBar_->addMenu(swiftMenu_);
#ifdef SWIFTEN_PLATFORM_MACOSX
- menuBar_->addMenu(generalMenu_);
+ menuBar_->addMenu(generalMenu_);
#endif
}
void QtLoginWindow::morphInto(MainWindow *mainWindow) {
- setEnabled(false);
- QtMainWindow *qtMainWindow = dynamic_cast<QtMainWindow*>(mainWindow);
- assert(qtMainWindow);
- stack_->removeWidget(loginWidgetWrapper_);
- stack_->addWidget(qtMainWindow);
- stack_->setCurrentWidget(qtMainWindow);
- setEnabled(true);
- setInitialMenus();
- std::vector<QMenu*> mainWindowMenus = qtMainWindow->getMenus();
- viewMenu_ = mainWindowMenus[0];
- foreach (QMenu* menu, mainWindowMenus) {
- menuBar_->addMenu(menu);
- }
- setFocus();
+ setEnabled(false);
+ QtMainWindow *qtMainWindow = dynamic_cast<QtMainWindow*>(mainWindow);
+ assert(qtMainWindow);
+ stack_->removeWidget(loginWidgetWrapper_);
+ stack_->addWidget(qtMainWindow);
+ stack_->setCurrentWidget(qtMainWindow);
+ setEnabled(true);
+ setInitialMenus();
+ std::vector<QMenu*> mainWindowMenus = qtMainWindow->getMenus();
+ viewMenu_ = mainWindowMenus[0];
+ for (auto menu : mainWindowMenus) {
+ menuBar_->addMenu(menu);
+ }
+ setFocus();
}
void QtLoginWindow::setMessage(const std::string& message) {
- if (!message.empty()) {
- message_->setText("<center><font color=\"red\">" + P2QSTRING(message) + "</font></center>");
- }
- else {
- message_->setText("");
- }
+ if (!message.empty()) {
+ message_->setText("<center><font color=\"red\">" + P2QSTRING(message) + "</font></center>");
+ }
+ else {
+ message_->setText("");
+ }
}
void QtLoginWindow::toggleBringToFront() {
- if (!isVisible()) {
- bringToFront();
- }
- else {
- window()->hide();
- }
+ if (!isVisible()) {
+ bringToFront();
+ }
+ else {
+ window()->hide();
+ }
}
void QtLoginWindow::bringToFront() {
- window()->showNormal();
- window()->raise();
- window()->activateWindow();
+ window()->showNormal();
+ window()->raise();
+ window()->activateWindow();
}
void QtLoginWindow::hide() {
- window()->hide();
+ window()->hide();
}
QtLoginWindow::QtMenus QtLoginWindow::getMenus() const {
- return QtMenus(swiftMenu_, generalMenu_);
+ return QtMenus(swiftMenu_, generalMenu_);
}
void QtLoginWindow::resizeEvent(QResizeEvent*) {
- emit geometryChanged();
+ emit geometryChanged();
}
void QtLoginWindow::moveEvent(QMoveEvent*) {
- emit geometryChanged();
+ emit geometryChanged();
}
bool QtLoginWindow::askUserToTrustCertificatePermanently(const std::string& message, const std::vector<Certificate::ref>& certificates) {
- QMessageBox dialog(this);
-
- dialog.setText(tr("The certificate presented by the server is not valid."));
- dialog.setInformativeText(P2QSTRING(message) + "\n\n" + tr("Would you like to permanently trust this certificate? This must only be done if you know it is correct."));
-
- dialog.addButton(tr("Show Certificate"), QMessageBox::HelpRole);
- dialog.addButton(QMessageBox::Yes);
- dialog.addButton(QMessageBox::No);
- dialog.setDefaultButton(QMessageBox::No);
- while (true) {
- int result = dialog.exec();
- if (result == QMessageBox::Yes || result == QMessageBox::No) {
- return result == QMessageBox::Yes;
- }
- // FIXME: This isn't very nice, because the dialog disappears every time. We actually need a real
- // dialog with a custom button.
- QtMainWindow::openCertificateDialog(certificates, &dialog);
- }
+ QMessageBox dialog(this);
+
+ dialog.setText(tr("The certificate presented by the server is not valid."));
+ dialog.setInformativeText(P2QSTRING(message) + "\n\n" + tr("Would you like to permanently trust this certificate? This must only be done if you know it is correct."));
+
+ dialog.addButton(tr("Show Certificate"), QMessageBox::HelpRole);
+ dialog.addButton(QMessageBox::Yes);
+ dialog.addButton(QMessageBox::No);
+ dialog.setDefaultButton(QMessageBox::No);
+ while (true) {
+ int result = dialog.exec();
+ if (result == QMessageBox::Yes || result == QMessageBox::No) {
+ return result == QMessageBox::Yes;
+ }
+ // FIXME: This isn't very nice, because the dialog disappears every time. We actually need a real
+ // dialog with a custom button.
+ QtMainWindow::openCertificateDialog(certificates, &dialog);
+ }
}
void QtLoginWindow::handleOpenConnectionOptions() {
- QtConnectionSettingsWindow connectionSettings(currentOptions_);
- if (connectionSettings.exec() == QDialog::Accepted) {
- currentOptions_ = connectionSettings.getOptions();
- }
+ QtConnectionSettingsWindow connectionSettings(currentOptions_);
+ if (connectionSettings.exec() == QDialog::Accepted) {
+ currentOptions_ = connectionSettings.getOptions();
+ }
}
}
diff --git a/Swift/QtUI/QtLoginWindow.h b/Swift/QtUI/QtLoginWindow.h
index 66730fd..c42d65d 100644
--- a/Swift/QtUI/QtLoginWindow.h
+++ b/Swift/QtUI/QtLoginWindow.h
@@ -1,112 +1,113 @@
/*
- * Copyright (c) 2010-2012 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <QCheckBox>
+#include <QLineEdit>
#include <QMainWindow>
+#include <QMenuBar>
#include <QPointer>
-#include <QLineEdit>
#include <QPushButton>
-#include <QCheckBox>
#include <QStackedWidget>
-#include <QMenuBar>
-#include <Swift/Controllers/UIInterfaces/LoginWindow.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
+#include <Swift/Controllers/UIInterfaces/LoginWindow.h>
#include <Swift/Controllers/UIInterfaces/MainWindow.h>
-#include <QtAboutWidget.h>
+
+#include <Swift/QtUI/QtAboutWidget.h>
class QLabel;
class QToolButton;
class QComboBox;
namespace Swift {
- class SettingsProvider;
- class TimerFactory;
+ class SettingsProvider;
+ class TimerFactory;
- class QtLoginWindow : public QMainWindow, public LoginWindow {
- Q_OBJECT
- public:
- struct QtMenus {
- QtMenus(QMenu* swiftMenu, QMenu* generalMenu) : swiftMenu(swiftMenu), generalMenu(generalMenu) {}
- QMenu* swiftMenu;
- QMenu* generalMenu;
- };
+ class QtLoginWindow : public QMainWindow, public LoginWindow {
+ Q_OBJECT
+ public:
+ struct QtMenus {
+ QtMenus(QMenu* swiftMenu, QMenu* generalMenu) : swiftMenu(swiftMenu), generalMenu(generalMenu) {}
+ QMenu* swiftMenu;
+ QMenu* generalMenu;
+ };
- public:
- QtLoginWindow(UIEventStream* uiEventStream, SettingsProvider* settings, TimerFactory* timerFactory);
+ public:
+ QtLoginWindow(UIEventStream* uiEventStream, SettingsProvider* settings, TimerFactory* timerFactory);
- void morphInto(MainWindow *mainWindow);
- virtual void loggedOut();
- virtual void setShowNotificationToggle(bool);
- virtual void setMessage(const std::string& message);
- virtual void addAvailableAccount(const std::string& defaultJID, const std::string& defaultPassword, const std::string& defaultCertificate, const ClientOptions& options);
- virtual void removeAvailableAccount(const std::string& jid);
- virtual void setLoginAutomatically(bool loginAutomatically);
- virtual void setIsLoggingIn(bool loggingIn);
- void selectUser(const std::string& user);
- bool askUserToTrustCertificatePermanently(const std::string& message, const std::vector<Certificate::ref>& certificate);
- void hide();
- QtMenus getMenus() const;
- virtual void quit();
+ void morphInto(MainWindow *mainWindow);
+ virtual void loggedOut();
+ virtual void setShowNotificationToggle(bool);
+ virtual void setMessage(const std::string& message);
+ virtual void addAvailableAccount(const std::string& defaultJID, const std::string& defaultPassword, const std::string& defaultCertificate, const ClientOptions& options);
+ virtual void removeAvailableAccount(const std::string& jid);
+ virtual void setLoginAutomatically(bool loginAutomatically);
+ virtual void setIsLoggingIn(bool loggingIn);
+ void selectUser(const std::string& user);
+ bool askUserToTrustCertificatePermanently(const std::string& message, const std::vector<Certificate::ref>& certificate);
+ void hide();
+ QtMenus getMenus() const;
+ virtual void quit();
- signals:
- void geometryChanged();
+ signals:
+ void geometryChanged();
- private slots:
- void loginClicked();
- void handleCertficateChecked(bool);
- void handleQuit();
- void handleShowXMLConsole();
- void handleShowFileTransferOverview();
- void handleShowHighlightEditor();
- void handleToggleSounds(bool enabled);
- void handleToggleNotifications(bool enabled);
- void handleAbout();
- void bringToFront();
- void toggleBringToFront();
- void handleUsernameTextChanged();
- void resizeEvent(QResizeEvent* event);
- void moveEvent(QMoveEvent* event);
- void handleSettingChanged(const std::string& settingPath);
- void handleOpenConnectionOptions();
+ private slots:
+ void loginClicked();
+ void handleCertficateChecked(bool);
+ void handleQuit();
+ void handleShowXMLConsole();
+ void handleShowFileTransferOverview();
+ void handleShowHighlightEditor();
+ void handleToggleSounds(bool enabled);
+ void handleToggleNotifications(bool enabled);
+ void handleAbout();
+ void bringToFront();
+ void toggleBringToFront();
+ void handleUsernameTextChanged();
+ void resizeEvent(QResizeEvent* event);
+ void moveEvent(QMoveEvent* event);
+ void handleSettingChanged(const std::string& settingPath);
+ void handleOpenConnectionOptions();
- protected:
- bool eventFilter(QObject *obj, QEvent *event);
+ protected:
+ bool eventFilter(QObject *obj, QEvent *event);
- private:
- void setInitialMenus();
- QWidget* loginWidgetWrapper_;
- QStringList usernames_;
- QStringList passwords_;
- QStringList certificateFiles_;
- std::vector<ClientOptions> options_;
- QComboBox* username_;
- QLineEdit* password_;
- QPushButton* loginButton_;
- /* If you add a widget here, change setLoggingIn as well.*/
- QCheckBox* remember_;
- QCheckBox* loginAutomatically_;
- QStackedWidget* stack_;
- QLabel* message_;
- QString certificateFile_;
- QToolButton* certificateButton_;
- QMenuBar* menuBar_;
- QMenu* swiftMenu_;
- QMenu* generalMenu_;
- QMenu* viewMenu_;
- QAction* toggleSoundsAction_;
- QAction* toggleNotificationsAction_;
- UIEventStream* uiEventStream_;
- QPointer<QtAboutWidget> aboutDialog_;
- SettingsProvider* settings_;
- QAction* xmlConsoleAction_;
- QAction* fileTransferOverviewAction_;
- QAction* highlightEditorAction_;
- TimerFactory* timerFactory_;
- ClientOptions currentOptions_;
- };
+ private:
+ void setInitialMenus();
+ QWidget* loginWidgetWrapper_;
+ QStringList usernames_;
+ QStringList passwords_;
+ QStringList certificateFiles_;
+ std::vector<ClientOptions> options_;
+ QComboBox* username_;
+ QLineEdit* password_;
+ QPushButton* loginButton_;
+ /* If you add a widget here, change setLoggingIn as well.*/
+ QCheckBox* remember_;
+ QCheckBox* loginAutomatically_;
+ QStackedWidget* stack_;
+ QLabel* message_;
+ QString certificateFile_;
+ QToolButton* certificateButton_;
+ QMenuBar* menuBar_;
+ QMenu* swiftMenu_;
+ QMenu* generalMenu_;
+ QMenu* viewMenu_ = nullptr;
+ QAction* toggleSoundsAction_;
+ QAction* toggleNotificationsAction_;
+ UIEventStream* uiEventStream_;
+ QPointer<QtAboutWidget> aboutDialog_;
+ SettingsProvider* settings_;
+ QAction* xmlConsoleAction_;
+ QAction* fileTransferOverviewAction_;
+ QAction* highlightEditorAction_;
+ TimerFactory* timerFactory_;
+ ClientOptions currentOptions_;
+ };
}
diff --git a/Swift/QtUI/QtMUCConfigurationWindow.cpp b/Swift/QtUI/QtMUCConfigurationWindow.cpp
index 8e8cc0b..e07b8c6 100644
--- a/Swift/QtUI/QtMUCConfigurationWindow.cpp
+++ b/Swift/QtUI/QtMUCConfigurationWindow.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,37 +7,39 @@
#include <Swift/QtUI/QtMUCConfigurationWindow.h>
#include <boost/bind.hpp>
+
#include <QBoxLayout>
#include <QCloseEvent>
+
#include <Swift/QtUI/QtFormWidget.h>
namespace Swift {
QtMUCConfigurationWindow::QtMUCConfigurationWindow(Form::ref form) : closed_(false) {
- setAttribute(Qt::WA_DeleteOnClose);
-
- QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom, this);
- layout->setContentsMargins(0,0,0,0);
- layout->setSpacing(2);
- //QLabel* label = new QLabel(this);
- //label->setText(tr("Room configuration"));
- //layout->addWidget(label);
-
- formWidget_ = NULL;
- formWidget_ = new QtFormWidget(form, this);
- layout->addWidget(formWidget_);
-
- QWidget* buttonsWidget = new QWidget(this);
- layout->addWidget(buttonsWidget);
-
- QBoxLayout* buttonsLayout = new QBoxLayout(QBoxLayout::LeftToRight, buttonsWidget);
- cancelButton_ = new QPushButton(tr("Cancel"), buttonsWidget);
- buttonsLayout->addWidget(cancelButton_);
- connect(cancelButton_, SIGNAL(clicked()), this, SLOT(handleCancelClicked()));
- okButton_ = new QPushButton(tr("OK"), buttonsWidget);
- buttonsLayout->addWidget(okButton_);
- connect(okButton_, SIGNAL(clicked()), this, SLOT(handleOKClicked()));
- show();
+ setAttribute(Qt::WA_DeleteOnClose);
+
+ QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom, this);
+ layout->setContentsMargins(0,0,0,0);
+ layout->setSpacing(2);
+ //QLabel* label = new QLabel(this);
+ //label->setText(tr("Room configuration"));
+ //layout->addWidget(label);
+
+ formWidget_ = nullptr;
+ formWidget_ = new QtFormWidget(form, this);
+ layout->addWidget(formWidget_);
+
+ QWidget* buttonsWidget = new QWidget(this);
+ layout->addWidget(buttonsWidget);
+
+ QBoxLayout* buttonsLayout = new QBoxLayout(QBoxLayout::LeftToRight, buttonsWidget);
+ cancelButton_ = new QPushButton(tr("Cancel"), buttonsWidget);
+ buttonsLayout->addWidget(cancelButton_);
+ connect(cancelButton_, SIGNAL(clicked()), this, SLOT(handleCancelClicked()));
+ okButton_ = new QPushButton(tr("OK"), buttonsWidget);
+ buttonsLayout->addWidget(okButton_);
+ connect(okButton_, SIGNAL(clicked()), this, SLOT(handleOKClicked()));
+ show();
}
QtMUCConfigurationWindow::~QtMUCConfigurationWindow() {
@@ -45,19 +47,19 @@ QtMUCConfigurationWindow::~QtMUCConfigurationWindow() {
}
void QtMUCConfigurationWindow::closeEvent(QCloseEvent* /*event*/) {
- if (!closed_) {
- onFormCancelled();
- }
+ if (!closed_) {
+ onFormCancelled();
+ }
}
void QtMUCConfigurationWindow::handleCancelClicked() {
- close();
+ close();
}
void QtMUCConfigurationWindow::handleOKClicked() {
- onFormComplete(formWidget_->getCompletedForm());
- closed_ = true;
- close();
+ onFormComplete(formWidget_->getCompletedForm());
+ closed_ = true;
+ close();
}
diff --git a/Swift/QtUI/QtMUCConfigurationWindow.h b/Swift/QtUI/QtMUCConfigurationWindow.h
index dcf941f..da3e12a 100644
--- a/Swift/QtUI/QtMUCConfigurationWindow.h
+++ b/Swift/QtUI/QtMUCConfigurationWindow.h
@@ -1,39 +1,40 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <QWidget>
-#include <QPushButton>
+#include <boost/signals2.hpp>
+
#include <QLabel>
+#include <QPushButton>
+#include <QWidget>
-#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/Elements/Form.h>
class QBoxLayout;
class QCloseEvent;
namespace Swift {
- class QtFormWidget;
- class QtMUCConfigurationWindow : public QWidget {
- Q_OBJECT
- public:
- QtMUCConfigurationWindow(Form::ref form);
- virtual ~QtMUCConfigurationWindow();
- boost::signal<void (Form::ref)> onFormComplete;
- boost::signal<void ()> onFormCancelled;
- private slots:
- void handleCancelClicked();
- void handleOKClicked();
- protected:
- virtual void closeEvent(QCloseEvent* event);
- private:
- QtFormWidget* formWidget_;
- QPushButton* okButton_;
- QPushButton* cancelButton_;
- bool closed_;
- };
+ class QtFormWidget;
+ class QtMUCConfigurationWindow : public QWidget {
+ Q_OBJECT
+ public:
+ QtMUCConfigurationWindow(Form::ref form);
+ virtual ~QtMUCConfigurationWindow();
+ boost::signals2::signal<void (Form::ref)> onFormComplete;
+ boost::signals2::signal<void ()> onFormCancelled;
+ private slots:
+ void handleCancelClicked();
+ void handleOKClicked();
+ protected:
+ virtual void closeEvent(QCloseEvent* event);
+ private:
+ QtFormWidget* formWidget_;
+ QPushButton* okButton_;
+ QPushButton* cancelButton_;
+ bool closed_;
+ };
}
diff --git a/Swift/QtUI/QtMainWindow.cpp b/Swift/QtUI/QtMainWindow.cpp
index e2092f6..0c1dd97 100644
--- a/Swift/QtUI/QtMainWindow.cpp
+++ b/Swift/QtUI/QtMainWindow.cpp
@@ -1,14 +1,15 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/QtMainWindow.h>
+#include <memory>
+
#include <boost/bind.hpp>
#include <boost/optional.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
#include <QAction>
#include <QBoxLayout>
@@ -52,373 +53,374 @@
namespace Swift {
QtMainWindow::QtMainWindow(SettingsProvider* settings, UIEventStream* uiEventStream, QtLoginWindow::QtMenus loginMenus, StatusCache* statusCache, bool emoticonsExist, bool enableAdHocCommandOnJID) : QWidget(), MainWindow(false), loginMenus_(loginMenus) {
- uiEventStream_ = uiEventStream;
- settings_ = settings;
- setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
- QBoxLayout *mainLayout = new QBoxLayout(QBoxLayout::TopToBottom, this);
- mainLayout->setContentsMargins(0,0,0,0);
- mainLayout->setSpacing(0);
- meView_ = new QtRosterHeader(settings, statusCache, this);
- mainLayout->addWidget(meView_);
- connect(meView_, SIGNAL(onChangeStatusRequest(StatusShow::Type, const QString&)), this, SLOT(handleStatusChanged(StatusShow::Type, const QString&)));
- connect(meView_, SIGNAL(onEditProfileRequest()), this, SLOT(handleEditProfileRequest()));
- connect(meView_, SIGNAL(onShowCertificateInfo()), this, SLOT(handleShowCertificateInfo()));
-
- tabs_ = new QtTabWidget(this);
+ uiEventStream_ = uiEventStream;
+ settings_ = settings;
+ setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
+ QBoxLayout *mainLayout = new QBoxLayout(QBoxLayout::TopToBottom, this);
+ mainLayout->setContentsMargins(0,0,0,0);
+ mainLayout->setSpacing(0);
+ meView_ = new QtRosterHeader(settings, statusCache, this);
+ mainLayout->addWidget(meView_);
+ connect(meView_, SIGNAL(onChangeStatusRequest(StatusShow::Type, const QString&)), this, SLOT(handleStatusChanged(StatusShow::Type, const QString&)));
+ connect(meView_, SIGNAL(onEditProfileRequest()), this, SLOT(handleEditProfileRequest()));
+ connect(meView_, SIGNAL(onShowCertificateInfo()), this, SLOT(handleShowCertificateInfo()));
+
+ tabs_ = new QtTabWidget(this);
#if QT_VERSION >= 0x040500
- tabs_->setDocumentMode(true);
+ tabs_->setDocumentMode(true);
#endif
- tabs_->setTabPosition(QTabWidget::South);
- mainLayout->addWidget(tabs_);
- contactsTabWidget_ = new QWidget(this);
- contactsTabWidget_->setContentsMargins(0, 0, 0, 0);
- QBoxLayout *contactTabLayout = new QBoxLayout(QBoxLayout::TopToBottom, contactsTabWidget_);
- contactsTabWidget_->setLayout(contactTabLayout);
- contactTabLayout->setSpacing(0);
- contactTabLayout->setContentsMargins(0, 0, 0, 0);
-
- treeWidget_ = new QtRosterWidget(uiEventStream_, settings_, this);
-
- contactTabLayout->addWidget(treeWidget_);
- new QtFilterWidget(this, treeWidget_, uiEventStream_, contactTabLayout);
-
- tabs_->addTab(contactsTabWidget_, tr("&Contacts"));
-
- eventWindow_ = new QtEventWindow(uiEventStream_);
- connect(eventWindow_, SIGNAL(onNewEventCountUpdated(int)), this, SLOT(handleEventCountUpdated(int)));
-
- chatListWindow_ = new QtChatListWindow(uiEventStream_, settings_);
- connect(chatListWindow_, SIGNAL(onCountUpdated(int)), this, SLOT(handleChatCountUpdated(int)));
-
- tabs_->addTab(chatListWindow_, tr("C&hats"));
- tabs_->addTab(eventWindow_, tr("&Notices"));
-
- tabs_->setCurrentIndex(settings_->getSetting(QtUISettingConstants::CURRENT_ROSTER_TAB));
-
- connect(tabs_, SIGNAL(currentChanged(int)), this, SLOT(handleTabChanged(int)));
-
- tabBarCombo_ = NULL;
- if (settings_->getSetting(QtUISettingConstants::USE_SCREENREADER)) {
- tabs_->tabBar()->hide();
- tabBarCombo_ = new QComboBox(this);
- tabBarCombo_->setAccessibleName("Current View");
- tabBarCombo_->addItem(tr("Contacts"));
- tabBarCombo_->addItem(tr("Chats"));
- tabBarCombo_->addItem(tr("Notices"));
- tabBarCombo_->setCurrentIndex(tabs_->currentIndex());
- mainLayout->addWidget(tabBarCombo_);
- connect(tabBarCombo_, SIGNAL(currentIndexChanged(int)), tabs_, SLOT(setCurrentIndex(int)));
- }
-
-
- this->setLayout(mainLayout);
-
- QMenu* viewMenu = new QMenu(tr("&View"), this);
- menus_.push_back(viewMenu);
-
- compactRosterAction_ = new QAction(tr("&Compact Roster"), this);
- compactRosterAction_->setCheckable(true);
- compactRosterAction_->setChecked(false);
- connect(compactRosterAction_, SIGNAL(toggled(bool)), SLOT(handleCompactRosterToggled(bool)));
- viewMenu->addAction(compactRosterAction_);
- handleCompactRosterToggled(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
-
- showOfflineAction_ = new QAction(tr("&Show offline contacts"), this);
- showOfflineAction_->setCheckable(true);
- showOfflineAction_->setChecked(false);
- connect(showOfflineAction_, SIGNAL(toggled(bool)), SLOT(handleShowOfflineToggled(bool)));
- viewMenu->addAction(showOfflineAction_);
- handleShowOfflineToggled(settings_->getSetting(SettingConstants::SHOW_OFFLINE));
-
- if (emoticonsExist) {
- showEmoticonsAction_ = new QAction(tr("&Show Emoticons"), this);
- showEmoticonsAction_->setCheckable(true);
- showEmoticonsAction_->setChecked(false);
- connect(showEmoticonsAction_, SIGNAL(toggled(bool)), SLOT(handleShowEmoticonsToggled(bool)));
- viewMenu->addAction(showEmoticonsAction_);
- handleShowEmoticonsToggled(settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS));
- }
-
- QMenu* actionsMenu = new QMenu(tr("&Actions"), this);
- menus_.push_back(actionsMenu);
- QAction* editProfileAction = new QAction(tr("Edit &Profile…"), this);
- connect(editProfileAction, SIGNAL(triggered()), SLOT(handleEditProfileAction()));
- actionsMenu->addAction(editProfileAction);
- onlineOnlyActions_ << editProfileAction;
- QAction* joinMUCAction = new QAction(tr("Enter &Room…"), this);
- connect(joinMUCAction, SIGNAL(triggered()), SLOT(handleJoinMUCAction()));
- actionsMenu->addAction(joinMUCAction);
- onlineOnlyActions_ << joinMUCAction;
+ tabs_->setTabPosition(QTabWidget::South);
+ mainLayout->addWidget(tabs_);
+ contactsTabWidget_ = new QWidget(this);
+ contactsTabWidget_->setContentsMargins(0, 0, 0, 0);
+ QBoxLayout *contactTabLayout = new QBoxLayout(QBoxLayout::TopToBottom, contactsTabWidget_);
+ contactsTabWidget_->setLayout(contactTabLayout);
+ contactTabLayout->setSpacing(0);
+ contactTabLayout->setContentsMargins(0, 0, 0, 0);
+
+ treeWidget_ = new QtRosterWidget(uiEventStream_, settings_, this);
+
+ contactTabLayout->addWidget(treeWidget_);
+ new QtFilterWidget(this, treeWidget_, uiEventStream_, contactTabLayout);
+
+ tabs_->addTab(contactsTabWidget_, tr("&Contacts"));
+
+ eventWindow_ = new QtEventWindow(uiEventStream_);
+ connect(eventWindow_, SIGNAL(onNewEventCountUpdated(int)), this, SLOT(handleEventCountUpdated(int)));
+
+ chatListWindow_ = new QtChatListWindow(uiEventStream_, settings_);
+ connect(chatListWindow_, SIGNAL(onCountUpdated(int)), this, SLOT(handleChatCountUpdated(int)));
+
+ tabs_->addTab(chatListWindow_, tr("C&hats"));
+ tabs_->addTab(eventWindow_, tr("&Notices"));
+
+ tabs_->setCurrentIndex(settings_->getSetting(QtUISettingConstants::CURRENT_ROSTER_TAB));
+
+ connect(tabs_, SIGNAL(currentChanged(int)), this, SLOT(handleTabChanged(int)));
+
+ tabBarCombo_ = nullptr;
+ if (settings_->getSetting(QtUISettingConstants::USE_SCREENREADER)) {
+ tabs_->tabBar()->hide();
+ tabBarCombo_ = new QComboBox(this);
+ tabBarCombo_->setAccessibleName("Current View");
+ tabBarCombo_->addItem(tr("Contacts"));
+ tabBarCombo_->addItem(tr("Chats"));
+ tabBarCombo_->addItem(tr("Notices"));
+ tabBarCombo_->setCurrentIndex(tabs_->currentIndex());
+ mainLayout->addWidget(tabBarCombo_);
+ connect(tabBarCombo_, SIGNAL(currentIndexChanged(int)), tabs_, SLOT(setCurrentIndex(int)));
+ }
+
+
+ this->setLayout(mainLayout);
+
+ QMenu* viewMenu = new QMenu(tr("&View"), this);
+ menus_.push_back(viewMenu);
+
+ compactRosterAction_ = new QAction(tr("&Compact Roster"), this);
+ compactRosterAction_->setCheckable(true);
+ compactRosterAction_->setChecked(false);
+ connect(compactRosterAction_, SIGNAL(toggled(bool)), SLOT(handleCompactRosterToggled(bool)));
+ viewMenu->addAction(compactRosterAction_);
+ handleCompactRosterToggled(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
+
+ showOfflineAction_ = new QAction(tr("&Show offline contacts"), this);
+ showOfflineAction_->setCheckable(true);
+ showOfflineAction_->setChecked(false);
+ connect(showOfflineAction_, SIGNAL(toggled(bool)), SLOT(handleShowOfflineToggled(bool)));
+ viewMenu->addAction(showOfflineAction_);
+ handleShowOfflineToggled(settings_->getSetting(SettingConstants::SHOW_OFFLINE));
+
+ if (emoticonsExist) {
+ showEmoticonsAction_ = new QAction(tr("&Show Emoticons"), this);
+ showEmoticonsAction_->setCheckable(true);
+ showEmoticonsAction_->setChecked(false);
+ connect(showEmoticonsAction_, SIGNAL(toggled(bool)), SLOT(handleShowEmoticonsToggled(bool)));
+ viewMenu->addAction(showEmoticonsAction_);
+ handleShowEmoticonsToggled(settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS));
+ }
+
+ QMenu* actionsMenu = new QMenu(tr("&Actions"), this);
+ menus_.push_back(actionsMenu);
+ QAction* editProfileAction = new QAction(tr("Edit &Profile…"), this);
+ connect(editProfileAction, SIGNAL(triggered()), SLOT(handleEditProfileAction()));
+ actionsMenu->addAction(editProfileAction);
+ onlineOnlyActions_ << editProfileAction;
+ QAction* joinMUCAction = new QAction(tr("Enter &Room…"), this);
+ connect(joinMUCAction, SIGNAL(triggered()), SLOT(handleJoinMUCAction()));
+ actionsMenu->addAction(joinMUCAction);
+ onlineOnlyActions_ << joinMUCAction;
#ifdef SWIFT_EXPERIMENTAL_HISTORY
- QAction* viewLogsAction = new QAction(tr("&View History…"), this);
- connect(viewLogsAction, SIGNAL(triggered()), SLOT(handleViewLogsAction()));
- actionsMenu->addAction(viewLogsAction);
+ QAction* viewLogsAction = new QAction(tr("&View History…"), this);
+ connect(viewLogsAction, SIGNAL(triggered()), SLOT(handleViewLogsAction()));
+ actionsMenu->addAction(viewLogsAction);
#endif
- openBlockingListEditor_ = new QAction(tr("Edit &Blocking List…"), this);
- connect(openBlockingListEditor_, SIGNAL(triggered()), SLOT(handleEditBlockingList()));
- actionsMenu->addAction(openBlockingListEditor_);
- onlineOnlyActions_ << openBlockingListEditor_;
- openBlockingListEditor_->setVisible(false);
- addUserAction_ = new QAction(tr("&Add Contact…"), this);
- addUserAction_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D));
- addUserAction_->setShortcutContext(Qt::ApplicationShortcut);
- connect(addUserAction_, SIGNAL(triggered(bool)), this, SLOT(handleAddUserActionTriggered(bool)));
- actionsMenu->addAction(addUserAction_);
- onlineOnlyActions_ << addUserAction_;
- editUserAction_ = new QAction(tr("&Edit Selected Contact…"), this);
- connect(editUserAction_, SIGNAL(triggered(bool)), treeWidget_, SLOT(handleEditUserActionTriggered(bool)));
- actionsMenu->addAction(editUserAction_);
- onlineOnlyActions_ << editUserAction_;
- editUserAction_->setEnabled(false);
- chatUserAction_ = new QAction(tr("Start &Chat…"), this);
- chatUserAction_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_N));
- chatUserAction_->setShortcutContext(Qt::ApplicationShortcut);
- connect(chatUserAction_, SIGNAL(triggered(bool)), this, SLOT(handleChatUserActionTriggered(bool)));
- actionsMenu->addAction(chatUserAction_);
- onlineOnlyActions_ << chatUserAction_;
- if (enableAdHocCommandOnJID) {
- otherAdHocAction_ = new QAction(tr("Run Other Command"), this);
- connect(otherAdHocAction_, SIGNAL(triggered()), this, SLOT(handleOtherAdHocActionTriggered()));
- actionsMenu->addAction(otherAdHocAction_);
- onlineOnlyActions_ << otherAdHocAction_;
- }
- serverAdHocMenu_ = new QMenu(tr("Run Server Command"), this);
- actionsMenu->addMenu(serverAdHocMenu_);
- actionsMenu->addSeparator();
- QAction* signOutAction = new QAction(tr("&Sign Out"), this);
- connect(signOutAction, SIGNAL(triggered()), SLOT(handleSignOutAction()));
- actionsMenu->addAction(signOutAction);
-
- toggleRequestDeliveryReceipts_ = new QAction(tr("&Request Delivery Receipts"), this);
- toggleRequestDeliveryReceipts_->setCheckable(true);
- toggleRequestDeliveryReceipts_->setChecked(settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS));
- connect(toggleRequestDeliveryReceipts_, SIGNAL(toggled(bool)), SLOT(handleToggleRequestDeliveryReceipts(bool)));
-
- QList< QAction* > generalMenuActions = loginMenus_.generalMenu->actions();
- loginMenus_.generalMenu->insertAction(generalMenuActions.at(generalMenuActions.count()-2),toggleRequestDeliveryReceipts_);
-
- treeWidget_->onSomethingSelectedChanged.connect(boost::bind(&QtMainWindow::handleSomethingSelectedChanged, this, _1));
-
- setAvailableAdHocCommands(std::vector<DiscoItems::Item>());
- QAction* adHocAction = new QAction(tr("Collecting commands..."), this);
- adHocAction->setEnabled(false);
- serverAdHocMenu_->addAction(adHocAction);
- serverAdHocCommandActions_.append(adHocAction);
-
- settings_->onSettingChanged.connect(boost::bind(&QtMainWindow::handleSettingChanged, this, _1));
+ openBlockingListEditor_ = new QAction(tr("Edit &Blocking List…"), this);
+ connect(openBlockingListEditor_, SIGNAL(triggered()), SLOT(handleEditBlockingList()));
+ actionsMenu->addAction(openBlockingListEditor_);
+ onlineOnlyActions_ << openBlockingListEditor_;
+ openBlockingListEditor_->setVisible(false);
+ addUserAction_ = new QAction(tr("&Add Contact…"), this);
+ addUserAction_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_D));
+ addUserAction_->setShortcutContext(Qt::ApplicationShortcut);
+ connect(addUserAction_, SIGNAL(triggered(bool)), this, SLOT(handleAddUserActionTriggered(bool)));
+ actionsMenu->addAction(addUserAction_);
+ onlineOnlyActions_ << addUserAction_;
+ editUserAction_ = new QAction(tr("&Edit Selected Contact…"), this);
+ connect(editUserAction_, SIGNAL(triggered(bool)), treeWidget_, SLOT(handleEditUserActionTriggered(bool)));
+ actionsMenu->addAction(editUserAction_);
+ onlineOnlyActions_ << editUserAction_;
+ editUserAction_->setEnabled(false);
+ chatUserAction_ = new QAction(tr("Start &Chat…"), this);
+ chatUserAction_->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_N));
+ chatUserAction_->setShortcutContext(Qt::ApplicationShortcut);
+ connect(chatUserAction_, SIGNAL(triggered(bool)), this, SLOT(handleChatUserActionTriggered(bool)));
+ actionsMenu->addAction(chatUserAction_);
+ onlineOnlyActions_ << chatUserAction_;
+ if (enableAdHocCommandOnJID) {
+ otherAdHocAction_ = new QAction(tr("Run Other Command"), this);
+ connect(otherAdHocAction_, SIGNAL(triggered()), this, SLOT(handleOtherAdHocActionTriggered()));
+ actionsMenu->addAction(otherAdHocAction_);
+ onlineOnlyActions_ << otherAdHocAction_;
+ }
+ serverAdHocMenu_ = new QMenu(tr("Run Server Command"), this);
+ actionsMenu->addMenu(serverAdHocMenu_);
+ actionsMenu->addSeparator();
+ QAction* signOutAction = new QAction(tr("&Sign Out"), this);
+ connect(signOutAction, SIGNAL(triggered()), SLOT(handleSignOutAction()));
+ actionsMenu->addAction(signOutAction);
+
+ toggleRequestDeliveryReceipts_ = new QAction(tr("&Request Delivery Receipts"), this);
+ toggleRequestDeliveryReceipts_->setCheckable(true);
+ toggleRequestDeliveryReceipts_->setChecked(settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS));
+ connect(toggleRequestDeliveryReceipts_, SIGNAL(toggled(bool)), SLOT(handleToggleRequestDeliveryReceipts(bool)));
+
+ QList< QAction* > generalMenuActions = loginMenus_.generalMenu->actions();
+ loginMenus_.generalMenu->insertAction(generalMenuActions.at(generalMenuActions.count()-2),toggleRequestDeliveryReceipts_);
+
+ treeWidget_->onSomethingSelectedChanged.connect(boost::bind(&QtMainWindow::handleSomethingSelectedChanged, this, _1));
+
+ setAvailableAdHocCommands(std::vector<DiscoItems::Item>());
+ QAction* adHocAction = new QAction(tr("Collecting commands..."), this);
+ adHocAction->setEnabled(false);
+ serverAdHocMenu_->addAction(adHocAction);
+ serverAdHocCommandActions_.append(adHocAction);
+
+ settings_->onSettingChanged.connect(boost::bind(&QtMainWindow::handleSettingChanged, this, _1));
}
QtMainWindow::~QtMainWindow() {
- settings_->onSettingChanged.disconnect(boost::bind(&QtMainWindow::handleSettingChanged, this, _1));
+ settings_->onSettingChanged.disconnect(boost::bind(&QtMainWindow::handleSettingChanged, this, _1));
}
void QtMainWindow::handleTabChanged(int index) {
- settings_->storeSetting(QtUISettingConstants::CURRENT_ROSTER_TAB, index);
+ settings_->storeSetting(QtUISettingConstants::CURRENT_ROSTER_TAB, index);
}
void QtMainWindow::handleToggleRequestDeliveryReceipts(bool enabled) {
- settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, enabled);
+ settings_->storeSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS, enabled);
}
void QtMainWindow::handleShowCertificateInfo() {
- onShowCertificateRequest();
+ onShowCertificateRequest();
}
void QtMainWindow::handleEditBlockingList() {
- uiEventStream_->send(boost::make_shared<RequestBlockListDialogUIEvent>());
+ uiEventStream_->send(std::make_shared<RequestBlockListDialogUIEvent>());
}
void QtMainWindow::handleSomethingSelectedChanged(bool itemSelected) {
- bool isOnline = addUserAction_->isEnabled();
- editUserAction_->setEnabled(isOnline && itemSelected);
+ bool isOnline = addUserAction_->isEnabled();
+ editUserAction_->setEnabled(isOnline && itemSelected);
}
QtEventWindow* QtMainWindow::getEventWindow() {
- return eventWindow_;
+ return eventWindow_;
}
QtChatListWindow* QtMainWindow::getChatListWindow() {
- return chatListWindow_;
+ return chatListWindow_;
}
void QtMainWindow::setRosterModel(Roster* roster) {
- treeWidget_->setRosterModel(roster);
+ treeWidget_->setRosterModel(roster);
}
void QtMainWindow::handleEditProfileRequest() {
- uiEventStream_->send(boost::make_shared<RequestProfileEditorUIEvent>());
+ uiEventStream_->send(std::make_shared<RequestProfileEditorUIEvent>());
}
void QtMainWindow::handleEventCountUpdated(int count) {
- QColor eventTabColor = (count == 0) ? QColor() : QColor(255, 0, 0); // invalid resets to default
- int eventIndex = 2;
- tabs_->tabBar()->setTabTextColor(eventIndex, eventTabColor);
- QString text = tr("&Notices");
- if (count > 0) {
- text += QString(" (%1)").arg(count);
- }
- tabs_->setTabText(eventIndex, text);
+ QColor eventTabColor = (count == 0) ? QColor() : QColor(255, 0, 0); // invalid resets to default
+ int eventIndex = 2;
+ tabs_->tabBar()->setTabTextColor(eventIndex, eventTabColor);
+ QString text = tr("&Notices");
+ if (count > 0) {
+ text += QString(" (%1)").arg(count);
+ }
+ tabs_->setTabText(eventIndex, text);
}
void QtMainWindow::handleChatCountUpdated(int count) {
- QColor chatTabColor = (count == 0) ? QColor() : QColor(255, 0, 0); // invalid resets to default
- int chatIndex = 1;
- tabs_->tabBar()->setTabTextColor(chatIndex, chatTabColor);
- QString text = tr("C&hats");
- if (count > 0) {
- text += QString(" (%1)").arg(count);
- }
- tabs_->setTabText(chatIndex, text);
+ QColor chatTabColor = (count == 0) ? QColor() : QColor(255, 0, 0); // invalid resets to default
+ int chatIndex = 1;
+ tabs_->tabBar()->setTabTextColor(chatIndex, chatTabColor);
+ QString text = tr("C&hats");
+ if (count > 0) {
+ text += QString(" (%1)").arg(count);
+ }
+ tabs_->setTabText(chatIndex, text);
}
void QtMainWindow::handleAddUserActionTriggered(bool /*checked*/) {
- boost::shared_ptr<UIEvent> event(new RequestAddUserDialogUIEvent());
- uiEventStream_->send(event);
+ std::shared_ptr<UIEvent> event(new RequestAddUserDialogUIEvent());
+ uiEventStream_->send(event);
}
void QtMainWindow::handleChatUserActionTriggered(bool /*checked*/) {
- boost::shared_ptr<UIEvent> event(new RequestChatWithUserDialogUIEvent());
- uiEventStream_->send(event);
+ std::shared_ptr<UIEvent> event(new RequestChatWithUserDialogUIEvent());
+ uiEventStream_->send(event);
}
void QtMainWindow::handleOtherAdHocActionTriggered() {
- new QtAdHocCommandWithJIDWindow(uiEventStream_);
+ new QtAdHocCommandWithJIDWindow(uiEventStream_);
}
void QtMainWindow::handleSignOutAction() {
- loginMenus_.generalMenu->removeAction(toggleRequestDeliveryReceipts_);
- onSignOutRequest();
+ loginMenus_.generalMenu->removeAction(toggleRequestDeliveryReceipts_);
+ onSignOutRequest();
}
void QtMainWindow::handleEditProfileAction() {
- uiEventStream_->send(boost::make_shared<RequestProfileEditorUIEvent>());
+ uiEventStream_->send(std::make_shared<RequestProfileEditorUIEvent>());
}
void QtMainWindow::handleJoinMUCAction() {
- uiEventStream_->send(boost::make_shared<RequestJoinMUCUIEvent>());
+ uiEventStream_->send(std::make_shared<RequestJoinMUCUIEvent>());
}
void QtMainWindow::handleViewLogsAction() {
- uiEventStream_->send(boost::make_shared<RequestHistoryUIEvent>());
+ uiEventStream_->send(std::make_shared<RequestHistoryUIEvent>());
}
void QtMainWindow::handleStatusChanged(StatusShow::Type showType, const QString &statusMessage) {
- onChangeStatusRequest(showType, Q2PSTRING(statusMessage));
+ onChangeStatusRequest(showType, Q2PSTRING(statusMessage));
}
void QtMainWindow::handleSettingChanged(const std::string& settingPath) {
- if (settingPath == SettingConstants::SHOW_OFFLINE.getKey()) {
- handleShowOfflineToggled(settings_->getSetting(SettingConstants::SHOW_OFFLINE));
- }
- if (settingPath == QtUISettingConstants::SHOW_EMOTICONS.getKey()) {
- handleShowEmoticonsToggled(settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS));
- }
- if (settingPath == SettingConstants::REQUEST_DELIVERYRECEIPTS.getKey()) {
- toggleRequestDeliveryReceipts_->setChecked(settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS));
- }
- if (settingPath == QtUISettingConstants::COMPACT_ROSTER.getKey()) {
- handleCompactRosterToggled(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
- }
+ if (settingPath == SettingConstants::SHOW_OFFLINE.getKey()) {
+ handleShowOfflineToggled(settings_->getSetting(SettingConstants::SHOW_OFFLINE));
+ }
+ if (settingPath == QtUISettingConstants::SHOW_EMOTICONS.getKey()) {
+ handleShowEmoticonsToggled(settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS));
+ }
+ if (settingPath == SettingConstants::REQUEST_DELIVERYRECEIPTS.getKey()) {
+ toggleRequestDeliveryReceipts_->setChecked(settings_->getSetting(SettingConstants::REQUEST_DELIVERYRECEIPTS));
+ }
+ if (settingPath == QtUISettingConstants::COMPACT_ROSTER.getKey()) {
+ handleCompactRosterToggled(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
+ }
}
void QtMainWindow::handleCompactRosterToggled(bool state) {
- settings_->storeSetting(QtUISettingConstants::COMPACT_ROSTER, state);
- compactRosterAction_->setChecked(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
+ settings_->storeSetting(QtUISettingConstants::COMPACT_ROSTER, state);
+ compactRosterAction_->setChecked(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
}
void QtMainWindow::handleShowOfflineToggled(bool state) {
- settings_->storeSetting(SettingConstants::SHOW_OFFLINE, state);
- showOfflineAction_->setChecked(settings_->getSetting(SettingConstants::SHOW_OFFLINE));
+ settings_->storeSetting(SettingConstants::SHOW_OFFLINE, state);
+ showOfflineAction_->setChecked(settings_->getSetting(SettingConstants::SHOW_OFFLINE));
}
void QtMainWindow::handleShowEmoticonsToggled(bool state) {
- settings_->storeSetting(QtUISettingConstants::SHOW_EMOTICONS, state);
- showEmoticonsAction_->setChecked(settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS));
+ settings_->storeSetting(QtUISettingConstants::SHOW_EMOTICONS, state);
+ showEmoticonsAction_->setChecked(settings_->getSetting(QtUISettingConstants::SHOW_EMOTICONS));
}
void QtMainWindow::setMyNick(const std::string& nick) {
- meView_->setNick(P2QSTRING(nick));
+ meView_->setNick(P2QSTRING(nick));
}
void QtMainWindow::setMyJID(const JID& jid) {
- meView_->setJID(P2QSTRING(jid.toBare().toString()));
+ meView_->setJID(P2QSTRING(jid.toBare().toString()));
}
void QtMainWindow::setMyAvatarPath(const std::string& path) {
- meView_->setAvatar(P2QSTRING(path));
+ meView_->setAvatar(P2QSTRING(path));
}
void QtMainWindow::setMyStatusText(const std::string& status) {
- meView_->setStatusText(P2QSTRING(status));
+ meView_->setStatusText(P2QSTRING(status));
}
void QtMainWindow::setMyStatusType(StatusShow::Type type) {
- meView_->setStatusType(type);
- const bool online = (type != StatusShow::None);
- treeWidget_->setOnline(online);
- chatListWindow_->setOnline(online);
- foreach (QAction *action, onlineOnlyActions_) {
- action->setEnabled(online);
- }
- serverAdHocMenu_->setEnabled(online);
+ meView_->setStatusType(type);
+ const bool online = (type != StatusShow::None);
+ treeWidget_->setOnline(online);
+ chatListWindow_->setOnline(online);
+ for (auto action : onlineOnlyActions_) {
+ action->setEnabled(online);
+ }
+ serverAdHocMenu_->setEnabled(online);
}
-void QtMainWindow::setMyContactRosterItem(boost::shared_ptr<ContactRosterItem> contact) {
- meView_->setContactRosterItem(contact);
+void QtMainWindow::setMyContactRosterItem(std::shared_ptr<ContactRosterItem> contact) {
+ meView_->setContactRosterItem(contact);
}
void QtMainWindow::setConnecting() {
- meView_->setConnecting();
+ meView_->setConnecting();
}
void QtMainWindow::setStreamEncryptionStatus(bool tlsInPlaceAndValid) {
- meView_->setStreamEncryptionStatus(tlsInPlaceAndValid);
+ meView_->setStreamEncryptionStatus(tlsInPlaceAndValid);
}
void QtMainWindow::openCertificateDialog(const std::vector<Certificate::ref>& chain) {
- openCertificateDialog(chain, this);
+ openCertificateDialog(chain, this);
}
void QtMainWindow::openCertificateDialog(const std::vector<Certificate::ref>& chain, QWidget* parent) {
#if defined(SWIFTEN_PLATFORM_MACOSX)
- CocoaUIHelpers::displayCertificateChainAsSheet(parent, chain);
+ CocoaUIHelpers::displayCertificateChainAsSheet(parent, chain);
#elif defined(SWIFTEN_PLATFORM_WINDOWS)
- WinUIHelpers::displayCertificateChainAsSheet(parent, chain);
+ WinUIHelpers::displayCertificateChainAsSheet(parent, chain);
#else
- QtCertificateViewerDialog::displayCertificateChainAsSheet(parent, chain);
+ QtCertificateViewerDialog::displayCertificateChainAsSheet(parent, chain);
#endif
}
void QtMainWindow::handleAdHocActionTriggered(bool /*checked*/) {
- QAction* action = qobject_cast<QAction*>(sender());
- assert(action);
- DiscoItems::Item command = serverAdHocCommands_[serverAdHocCommandActions_.indexOf(action)];
- uiEventStream_->send(boost::shared_ptr<UIEvent>(new RequestAdHocUIEvent(command)));
+ QAction* action = qobject_cast<QAction*>(sender());
+ assert(action);
+ assert(serverAdHocCommandActions_.indexOf(action) >= 0);
+ DiscoItems::Item command = serverAdHocCommands_[serverAdHocCommandActions_.indexOf(action)];
+ uiEventStream_->send(std::make_shared<RequestAdHocUIEvent>(command));
}
void QtMainWindow::setAvailableAdHocCommands(const std::vector<DiscoItems::Item>& commands) {
- serverAdHocCommands_ = commands;
- foreach (QAction* action, serverAdHocCommandActions_) {
- delete action;
- }
- serverAdHocMenu_->clear();
- serverAdHocCommandActions_.clear();
- foreach (DiscoItems::Item command, commands) {
- QAction* action = new QAction(P2QSTRING(command.getName()), this);
- connect(action, SIGNAL(triggered(bool)), this, SLOT(handleAdHocActionTriggered(bool)));
- serverAdHocMenu_->addAction(action);
- serverAdHocCommandActions_.append(action);
- }
- if (serverAdHocCommandActions_.isEmpty()) {
- QAction* action = new QAction(tr("No Available Commands"), this);
- action->setEnabled(false);
- serverAdHocMenu_->addAction(action);
- serverAdHocCommandActions_.append(action);
- }
+ serverAdHocCommands_ = commands;
+ for (auto action : serverAdHocCommandActions_) {
+ delete action;
+ }
+ serverAdHocMenu_->clear();
+ serverAdHocCommandActions_.clear();
+ for (const auto& command : commands) {
+ QAction* action = new QAction(P2QSTRING(command.getName()), this);
+ connect(action, SIGNAL(triggered(bool)), this, SLOT(handleAdHocActionTriggered(bool)));
+ serverAdHocMenu_->addAction(action);
+ serverAdHocCommandActions_.append(action);
+ }
+ if (serverAdHocCommandActions_.isEmpty()) {
+ QAction* action = new QAction(tr("No Available Commands"), this);
+ action->setEnabled(false);
+ serverAdHocMenu_->addAction(action);
+ serverAdHocCommandActions_.append(action);
+ }
}
void QtMainWindow::setBlockingCommandAvailable(bool isAvailable) {
- openBlockingListEditor_->setVisible(isAvailable);
+ openBlockingListEditor_->setVisible(isAvailable);
}
}
diff --git a/Swift/QtUI/QtMainWindow.h b/Swift/QtUI/QtMainWindow.h
index 2e314f7..c46fdfc 100644
--- a/Swift/QtUI/QtMainWindow.h
+++ b/Swift/QtUI/QtMainWindow.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,16 +8,16 @@
#include <vector>
-#include <QWidget>
-#include <QMenu>
#include <QList>
+#include <QMenu>
+#include <QWidget>
#include <Swift/Controllers/UIInterfaces/MainWindow.h>
-#include <Swift/QtUI/QtRosterHeader.h>
-#include <Swift/QtUI/EventViewer/QtEventWindow.h>
#include <Swift/QtUI/ChatList/QtChatListWindow.h>
+#include <Swift/QtUI/EventViewer/QtEventWindow.h>
#include <Swift/QtUI/QtLoginWindow.h>
+#include <Swift/QtUI/QtRosterHeader.h>
class QComboBox;
class QLineEdit;
@@ -28,83 +28,83 @@ class QMenu;
class QTabWidget;
namespace Swift {
- class QtRosterWidget;
- class TreeWidget;
- class UIEventStream;
- class QtTabWidget;
- class SettingsProvider;
- class QtUIPreferences;
- class StatusCache;
+ class QtRosterWidget;
+ class TreeWidget;
+ class UIEventStream;
+ class QtTabWidget;
+ class SettingsProvider;
+ class QtUIPreferences;
+ class StatusCache;
- class QtMainWindow : public QWidget, public MainWindow {
- Q_OBJECT
- public:
- QtMainWindow(SettingsProvider*, UIEventStream* eventStream, QtLoginWindow::QtMenus loginMenus, StatusCache* statusCache, bool emoticonsExist, bool enableAdHocCommandOnJID);
- virtual ~QtMainWindow();
- std::vector<QMenu*> getMenus() {return menus_;}
- void setMyNick(const std::string& name);
- void setMyJID(const JID& jid);
- void setMyAvatarPath(const std::string& path);
- void setMyStatusText(const std::string& status);
- void setMyStatusType(StatusShow::Type type);
- void setMyContactRosterItem(boost::shared_ptr<ContactRosterItem> contact);
- void setConnecting();
- void setStreamEncryptionStatus(bool tlsInPlaceAndValid);
- void openCertificateDialog(const std::vector<Certificate::ref>& chain);
- static void openCertificateDialog(const std::vector<Certificate::ref>& chain, QWidget* parent);
- QtEventWindow* getEventWindow();
- QtChatListWindow* getChatListWindow();
- void setRosterModel(Roster* roster);
- void setAvailableAdHocCommands(const std::vector<DiscoItems::Item>& commands);
- void setBlockingCommandAvailable(bool isAvailable);
- private slots:
- void handleStatusChanged(StatusShow::Type showType, const QString &statusMessage);
- void handleSettingChanged(const std::string& settingPath);
- void handleCompactRosterToggled(bool);
- void handleShowOfflineToggled(bool);
- void handleShowEmoticonsToggled(bool);
- void handleJoinMUCAction();
- void handleViewLogsAction();
- void handleSignOutAction();
- void handleEditProfileAction();
- void handleAddUserActionTriggered(bool checked);
- void handleChatUserActionTriggered(bool checked);
- void handleOtherAdHocActionTriggered();
- void handleAdHocActionTriggered(bool checked);
- void handleEventCountUpdated(int count);
- void handleChatCountUpdated(int count);
- void handleEditProfileRequest();
- void handleTabChanged(int index);
- void handleToggleRequestDeliveryReceipts(bool enabled);
- void handleShowCertificateInfo();
- void handleEditBlockingList();
- void handleSomethingSelectedChanged(bool itemSelected);
+ class QtMainWindow : public QWidget, public MainWindow {
+ Q_OBJECT
+ public:
+ QtMainWindow(SettingsProvider*, UIEventStream* eventStream, QtLoginWindow::QtMenus loginMenus, StatusCache* statusCache, bool emoticonsExist, bool enableAdHocCommandOnJID);
+ virtual ~QtMainWindow();
+ std::vector<QMenu*> getMenus() {return menus_;}
+ void setMyNick(const std::string& name);
+ void setMyJID(const JID& jid);
+ void setMyAvatarPath(const std::string& path);
+ void setMyStatusText(const std::string& status);
+ void setMyStatusType(StatusShow::Type type);
+ void setMyContactRosterItem(std::shared_ptr<ContactRosterItem> contact);
+ void setConnecting();
+ void setStreamEncryptionStatus(bool tlsInPlaceAndValid);
+ void openCertificateDialog(const std::vector<Certificate::ref>& chain);
+ static void openCertificateDialog(const std::vector<Certificate::ref>& chain, QWidget* parent);
+ QtEventWindow* getEventWindow();
+ QtChatListWindow* getChatListWindow();
+ void setRosterModel(Roster* roster);
+ void setAvailableAdHocCommands(const std::vector<DiscoItems::Item>& commands);
+ void setBlockingCommandAvailable(bool isAvailable);
+ private slots:
+ void handleStatusChanged(StatusShow::Type showType, const QString &statusMessage);
+ void handleSettingChanged(const std::string& settingPath);
+ void handleCompactRosterToggled(bool);
+ void handleShowOfflineToggled(bool);
+ void handleShowEmoticonsToggled(bool);
+ void handleJoinMUCAction();
+ void handleViewLogsAction();
+ void handleSignOutAction();
+ void handleEditProfileAction();
+ void handleAddUserActionTriggered(bool checked);
+ void handleChatUserActionTriggered(bool checked);
+ void handleOtherAdHocActionTriggered();
+ void handleAdHocActionTriggered(bool checked);
+ void handleEventCountUpdated(int count);
+ void handleChatCountUpdated(int count);
+ void handleEditProfileRequest();
+ void handleTabChanged(int index);
+ void handleToggleRequestDeliveryReceipts(bool enabled);
+ void handleShowCertificateInfo();
+ void handleEditBlockingList();
+ void handleSomethingSelectedChanged(bool itemSelected);
- private:
- SettingsProvider* settings_;
- QtLoginWindow::QtMenus loginMenus_;
- std::vector<QMenu*> menus_;
- QtRosterWidget* treeWidget_;
- QtRosterHeader* meView_;
- QAction* addUserAction_;
- QAction* editUserAction_;
- QAction* chatUserAction_;
- QAction* otherAdHocAction_;
- QAction* showOfflineAction_;
- QAction* compactRosterAction_;
- QAction* showEmoticonsAction_;
- QAction* openBlockingListEditor_;
- QAction* toggleRequestDeliveryReceipts_;
- QMenu* serverAdHocMenu_;
- QtTabWidget* tabs_;
- QComboBox* tabBarCombo_;
- QWidget* contactsTabWidget_;
- QWidget* eventsTabWidget_;
- QtEventWindow* eventWindow_;
- QtChatListWindow* chatListWindow_;
- UIEventStream* uiEventStream_;
- std::vector<DiscoItems::Item> serverAdHocCommands_;
- QList<QAction*> serverAdHocCommandActions_;
- QList<QAction*> onlineOnlyActions_;
- };
+ private:
+ SettingsProvider* settings_;
+ QtLoginWindow::QtMenus loginMenus_;
+ std::vector<QMenu*> menus_;
+ QtRosterWidget* treeWidget_;
+ QtRosterHeader* meView_;
+ QAction* addUserAction_;
+ QAction* editUserAction_;
+ QAction* chatUserAction_;
+ QAction* otherAdHocAction_;
+ QAction* showOfflineAction_;
+ QAction* compactRosterAction_;
+ QAction* showEmoticonsAction_;
+ QAction* openBlockingListEditor_;
+ QAction* toggleRequestDeliveryReceipts_;
+ QMenu* serverAdHocMenu_;
+ QtTabWidget* tabs_;
+ QComboBox* tabBarCombo_;
+ QWidget* contactsTabWidget_;
+ QWidget* eventsTabWidget_;
+ QtEventWindow* eventWindow_;
+ QtChatListWindow* chatListWindow_;
+ UIEventStream* uiEventStream_;
+ std::vector<DiscoItems::Item> serverAdHocCommands_;
+ QList<QAction*> serverAdHocCommandActions_;
+ QList<QAction*> onlineOnlyActions_;
+ };
}
diff --git a/Swift/QtUI/QtNameWidget.cpp b/Swift/QtUI/QtNameWidget.cpp
index 428b243..0610a00 100644
--- a/Swift/QtUI/QtNameWidget.cpp
+++ b/Swift/QtUI/QtNameWidget.cpp
@@ -1,10 +1,10 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtNameWidget.h"
+#include <Swift/QtUI/QtNameWidget.h>
#include <QHBoxLayout>
#include <QMenu>
@@ -18,80 +18,80 @@
namespace Swift {
QtNameWidget::QtNameWidget(SettingsProvider* settings, QWidget *parent) : QWidget(parent), settings(settings), isOnline_(false) {
- QHBoxLayout* mainLayout = new QHBoxLayout(this);
- mainLayout->setSpacing(0);
- mainLayout->setContentsMargins(0,0,0,0);
+ QHBoxLayout* mainLayout = new QHBoxLayout(this);
+ mainLayout->setSpacing(0);
+ mainLayout->setContentsMargins(0,0,0,0);
- mode = settings->getSetting(QtUISettingConstants::SHOW_NICK_IN_ROSTER_HEADER) ? ShowNick : ShowJID;
+ mode = settings->getSetting(QtUISettingConstants::SHOW_NICK_IN_ROSTER_HEADER) ? ShowNick : ShowJID;
- textLabel = new QtElidingLabel(this);
- QFont font = textLabel->font();
- font.setBold(true);
- textLabel->setFont(font);
- mainLayout->addWidget(textLabel);
+ textLabel = new QtElidingLabel(this);
+ QFont font = textLabel->font();
+ font.setBold(true);
+ textLabel->setFont(font);
+ mainLayout->addWidget(textLabel);
}
void QtNameWidget::setNick(const QString& nick) {
- this->nick = nick;
- updateText();
+ this->nick = nick;
+ updateText();
}
void QtNameWidget::setJID(const QString& jid) {
- this->jid = jid;
- updateText();
+ this->jid = jid;
+ updateText();
}
void QtNameWidget::setOnline(const bool isOnline) {
- isOnline_ = isOnline;
+ isOnline_ = isOnline;
}
void QtNameWidget::mousePressEvent(QMouseEvent* event) {
- QMenu menu;
- bool hasNick = !nick.isEmpty();
-
- QAction* showAsNick = new QAction(hasNick ? tr("Show Nickname") : tr("(No Nickname Set)"), this);
- showAsNick->setCheckable(true);
- showAsNick->setEnabled(hasNick);
- if (mode == ShowNick && hasNick) {
- showAsNick->setChecked(true);
- }
- menu.addAction(showAsNick);
-
- QAction* showAsJID = new QAction(tr("Show Address"), this);
- showAsJID->setCheckable(true);
- if (mode == ShowJID || !hasNick) {
- showAsJID->setChecked(true);
- }
- menu.addAction(showAsJID);
-
- QAction* editProfile = new QAction(tr("Edit Profile"), this);
- menu.addAction(editProfile);
- editProfile->setEnabled(isOnline_);
-
- QAction* result = menu.exec(event->globalPos());
- if (result == showAsJID) {
- mode = ShowJID;
- }
- else if (result == showAsNick) {
- mode = ShowNick;
- }
- else if (result == editProfile) {
- emit onChangeNickRequest();
- }
- settings->storeSetting(QtUISettingConstants::SHOW_NICK_IN_ROSTER_HEADER, mode == ShowNick);
- updateText();
+ QMenu menu;
+ bool hasNick = !nick.isEmpty();
+
+ QAction* showAsNick = new QAction(hasNick ? tr("Show Nickname") : tr("(No Nickname Set)"), this);
+ showAsNick->setCheckable(true);
+ showAsNick->setEnabled(hasNick);
+ if (mode == ShowNick && hasNick) {
+ showAsNick->setChecked(true);
+ }
+ menu.addAction(showAsNick);
+
+ QAction* showAsJID = new QAction(tr("Show Address"), this);
+ showAsJID->setCheckable(true);
+ if (mode == ShowJID || !hasNick) {
+ showAsJID->setChecked(true);
+ }
+ menu.addAction(showAsJID);
+
+ QAction* editProfile = new QAction(tr("Edit Profile"), this);
+ menu.addAction(editProfile);
+ editProfile->setEnabled(isOnline_);
+
+ QAction* result = menu.exec(event->globalPos());
+ if (result == showAsJID) {
+ mode = ShowJID;
+ }
+ else if (result == showAsNick) {
+ mode = ShowNick;
+ }
+ else if (result == editProfile) {
+ emit onChangeNickRequest();
+ }
+ settings->storeSetting(QtUISettingConstants::SHOW_NICK_IN_ROSTER_HEADER, mode == ShowNick);
+ updateText();
}
void QtNameWidget::updateText() {
- QString text;
- if (mode == ShowNick && !nick.isEmpty()) {
- text = nick;
- }
- else {
- text = jid;
- }
- text.replace("<","&lt;");
- textLabel->setText(text);
+ QString text;
+ if (mode == ShowNick && !nick.isEmpty()) {
+ text = nick;
+ }
+ else {
+ text = jid;
+ }
+ text.replace("<","&lt;");
+ textLabel->setText(text);
}
}
diff --git a/Swift/QtUI/QtNameWidget.h b/Swift/QtUI/QtNameWidget.h
index 5f9962b..0da0ff6 100644
--- a/Swift/QtUI/QtNameWidget.h
+++ b/Swift/QtUI/QtNameWidget.h
@@ -9,38 +9,38 @@
#include <QWidget>
namespace Swift {
- class QtElidingLabel;
- class SettingsProvider;
-
- class QtNameWidget : public QWidget {
- Q_OBJECT
-
- public:
- QtNameWidget(SettingsProvider* settings, QWidget *parent);
-
- void setNick(const QString& text);
- void setJID(const QString& jid);
- void setOnline(const bool isOnline);
-
- signals:
- void onChangeNickRequest();
-
- private:
- void updateText();
- virtual void mousePressEvent(QMouseEvent* event);
-
- private:
- enum Mode {
- ShowNick,
- ShowJID
- };
-
- SettingsProvider* settings;
- Mode mode;
- QtElidingLabel* textLabel;
- QString jid;
- QString nick;
- bool isOnline_;
- };
+ class QtElidingLabel;
+ class SettingsProvider;
+
+ class QtNameWidget : public QWidget {
+ Q_OBJECT
+
+ public:
+ QtNameWidget(SettingsProvider* settings, QWidget *parent);
+
+ void setNick(const QString& text);
+ void setJID(const QString& jid);
+ void setOnline(const bool isOnline);
+
+ signals:
+ void onChangeNickRequest();
+
+ private:
+ void updateText();
+ virtual void mousePressEvent(QMouseEvent* event);
+
+ private:
+ enum Mode {
+ ShowNick,
+ ShowJID
+ };
+
+ SettingsProvider* settings;
+ Mode mode;
+ QtElidingLabel* textLabel;
+ QString jid;
+ QString nick;
+ bool isOnline_;
+ };
}
diff --git a/Swift/QtUI/QtPlainChatView.cpp b/Swift/QtUI/QtPlainChatView.cpp
index a794167..05a2eb0 100644
--- a/Swift/QtUI/QtPlainChatView.cpp
+++ b/Swift/QtUI/QtPlainChatView.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013-2015 Isode Limited.
+ * Copyright (c) 2013-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -18,7 +18,6 @@
#include <QVBoxLayout>
#include <Swiften/Base/FileSize.h>
-#include <Swiften/Base/foreach.h>
#include <Swift/Controllers/UIEvents/JoinMUCUIEvent.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
@@ -31,402 +30,402 @@ namespace Swift {
QtPlainChatView::QtPlainChatView(QtChatWindow *window, UIEventStream* eventStream)
: QtChatView(window), window_(window), eventStream_(eventStream), idGenerator_(0) {
- QVBoxLayout* mainLayout = new QVBoxLayout(this);
- mainLayout->setSpacing(0);
- mainLayout->setContentsMargins(0,0,0,0);
- log_ = new LogTextEdit(this);
- log_->setReadOnly(true);
- log_->setAccessibleName(tr("Chat Messages"));
- mainLayout->addWidget(log_);
+ QVBoxLayout* mainLayout = new QVBoxLayout(this);
+ mainLayout->setSpacing(0);
+ mainLayout->setContentsMargins(0,0,0,0);
+ log_ = new LogTextEdit(this);
+ log_->setReadOnly(true);
+ log_->setAccessibleName(tr("Chat Messages"));
+ mainLayout->addWidget(log_);
}
QtPlainChatView::~QtPlainChatView() {
}
QString chatMessageToString(const ChatWindow::ChatMessage& message) {
- QString result;
- foreach (boost::shared_ptr<ChatWindow::ChatMessagePart> part, message.getParts()) {
- boost::shared_ptr<ChatWindow::ChatTextMessagePart> textPart;
- boost::shared_ptr<ChatWindow::ChatURIMessagePart> uriPart;
- boost::shared_ptr<ChatWindow::ChatEmoticonMessagePart> emoticonPart;
- boost::shared_ptr<ChatWindow::ChatHighlightingMessagePart> highlightPart;
-
- if ((textPart = boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(part))) {
- QString text = QtUtilities::htmlEscape(P2QSTRING(textPart->text));
- text.replace("\n","<br/>");
- result += text;
- continue;
- }
- if ((uriPart = boost::dynamic_pointer_cast<ChatWindow::ChatURIMessagePart>(part))) {
- QString uri = QtUtilities::htmlEscape(P2QSTRING(uriPart->target));
- result += "<a href='" + uri + "' >" + uri + "</a>";
- continue;
- }
- if ((emoticonPart = boost::dynamic_pointer_cast<ChatWindow::ChatEmoticonMessagePart>(part))) {
- result += P2QSTRING(emoticonPart->alternativeText);
- continue;
- }
- if ((highlightPart = boost::dynamic_pointer_cast<ChatWindow::ChatHighlightingMessagePart>(part))) {
- //FIXME: Maybe do something here. Anything, really.
- continue;
- }
- }
- return result;
+ QString result;
+ for (auto&& part : message.getParts()) {
+ std::shared_ptr<ChatWindow::ChatTextMessagePart> textPart;
+ std::shared_ptr<ChatWindow::ChatURIMessagePart> uriPart;
+ std::shared_ptr<ChatWindow::ChatEmoticonMessagePart> emoticonPart;
+ std::shared_ptr<ChatWindow::ChatHighlightingMessagePart> highlightPart;
+
+ if ((textPart = std::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(part))) {
+ QString text = QtUtilities::htmlEscape(P2QSTRING(textPart->text));
+ text.replace("\n","<br/>");
+ result += text;
+ continue;
+ }
+ if ((uriPart = std::dynamic_pointer_cast<ChatWindow::ChatURIMessagePart>(part))) {
+ QString uri = QtUtilities::htmlEscape(P2QSTRING(uriPart->target));
+ result += "<a href='" + uri + "' >" + uri + "</a>";
+ continue;
+ }
+ if ((emoticonPart = std::dynamic_pointer_cast<ChatWindow::ChatEmoticonMessagePart>(part))) {
+ result += P2QSTRING(emoticonPart->alternativeText);
+ continue;
+ }
+ if ((highlightPart = std::dynamic_pointer_cast<ChatWindow::ChatHighlightingMessagePart>(part))) {
+ //FIXME: Maybe do something here. Anything, really.
+ continue;
+ }
+ }
+ return result;
}
-std::string QtPlainChatView::addMessage(const ChatWindow::ChatMessage& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& /*avatarPath*/, const boost::posix_time::ptime& time, const HighlightAction& /*highlight*/) {
- QString text = "<p>";
- if (label) {
- text += P2QSTRING(label->getLabel()) + "<br/>";
- }
- QString name = senderIsSelf ? "you" : P2QSTRING(senderName);
- text += QString(tr("At %1 %2 said:")).arg(ChatSnippet::timeToEscapedString(B2QDATE(time))).arg(name) + "<br/>";
- text += chatMessageToString(message);
- text += "</p>";
- log_->append(text);
- const std::string idx = senderIsSelf ? "" : senderName;
- lastMessageLabel_[idx] = label;
- return idx;
+std::string QtPlainChatView::addMessage(const ChatWindow::ChatMessage& message, const std::string& senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const std::string& /*avatarPath*/, const boost::posix_time::ptime& time) {
+ QString text = "<p>";
+ if (label) {
+ text += P2QSTRING(label->getLabel()) + "<br/>";
+ }
+ QString name = senderIsSelf ? "you" : P2QSTRING(senderName);
+ text += QString(tr("At %1 %2 said:")).arg(ChatSnippet::timeToEscapedString(B2QDATE(time))).arg(name) + "<br/>";
+ text += chatMessageToString(message);
+ text += "</p>";
+ log_->append(text);
+ const std::string idx = senderIsSelf ? "" : senderName;
+ lastMessageLabel_[idx] = label;
+ return idx;
}
-std::string QtPlainChatView::addAction(const ChatWindow::ChatMessage& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& /*avatarPath*/, const boost::posix_time::ptime& time, const HighlightAction& /*highlight*/) {
- QString text = "<p>";
- if (label) {
- text += P2QSTRING(label->getLabel()) + "<br/>";
- }
- QString name = senderIsSelf ? "you" : P2QSTRING(senderName);
- text += QString(tr("At %1 <i>%2 ")).arg(ChatSnippet::timeToEscapedString(B2QDATE(time))).arg(name);
- text += chatMessageToString(message);
- text += "</i></p>";
- log_->append(text);
- const std::string idx = senderIsSelf ? "" : senderName;
- lastMessageLabel_[idx] = label;
- return idx;
+std::string QtPlainChatView::addAction(const ChatWindow::ChatMessage& message, const std::string& senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const std::string& /*avatarPath*/, const boost::posix_time::ptime& time) {
+ QString text = "<p>";
+ if (label) {
+ text += P2QSTRING(label->getLabel()) + "<br/>";
+ }
+ QString name = senderIsSelf ? "you" : P2QSTRING(senderName);
+ text += QString(tr("At %1 <i>%2 ")).arg(ChatSnippet::timeToEscapedString(B2QDATE(time))).arg(name);
+ text += chatMessageToString(message);
+ text += "</i></p>";
+ log_->append(text);
+ const std::string idx = senderIsSelf ? "" : senderName;
+ lastMessageLabel_[idx] = label;
+ return idx;
}
std::string QtPlainChatView::addSystemMessage(const ChatWindow::ChatMessage& message, ChatWindow::Direction /*direction*/)
{
- QString text = "<p><i>";
- text += chatMessageToString(message);
- text += "</i></p>";
- log_->append(text);
- return "";
+ QString text = "<p><i>";
+ text += chatMessageToString(message);
+ text += "</i></p>";
+ log_->append(text);
+ return "";
}
void QtPlainChatView::addPresenceMessage(const ChatWindow::ChatMessage& message, ChatWindow::Direction /*direction*/)
{
- QString text = "<p><i>";
- text += chatMessageToString(message);
- text += "</i></p>";
- log_->append(text);
+ QString text = "<p><i>";
+ text += chatMessageToString(message);
+ text += "</i></p>";
+ log_->append(text);
}
void QtPlainChatView::addErrorMessage(const ChatWindow::ChatMessage& message)
{
- QString text = "<p><i>";
- text += chatMessageToString(message);
- text += "</i></p>";
- log_->append(text);
+ QString text = "<p><i>";
+ text += chatMessageToString(message);
+ text += "</i></p>";
+ log_->append(text);
}
-void QtPlainChatView::replaceMessage(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& /*highlight*/)
+void QtPlainChatView::replaceMessage(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time)
{
- QString text = "<p>";
- if (lastMessageLabel_[id]) {
- text += P2QSTRING(lastMessageLabel_[id]->getLabel()) + "<br/>";
- }
- QString name = id.empty() ? "you" : P2QSTRING(id);
- text += QString(tr("At %1 %2 corrected the last message to:")).arg(ChatSnippet::timeToEscapedString(B2QDATE(time))).arg(name) + "<br/>";
- text += chatMessageToString(message);
- text += "</p>";
- log_->append(text);
+ QString text = "<p>";
+ if (lastMessageLabel_[id]) {
+ text += P2QSTRING(lastMessageLabel_[id]->getLabel()) + "<br/>";
+ }
+ QString name = id.empty() ? "you" : P2QSTRING(id);
+ text += QString(tr("At %1 %2 corrected the last message to:")).arg(ChatSnippet::timeToEscapedString(B2QDATE(time))).arg(name) + "<br/>";
+ text += chatMessageToString(message);
+ text += "</p>";
+ log_->append(text);
}
-void QtPlainChatView::replaceWithAction(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& /*highlight*/)
+void QtPlainChatView::replaceWithAction(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time)
{
- QString text = "<p>";
- if (lastMessageLabel_[id]) {
- text += P2QSTRING(lastMessageLabel_[id]->getLabel()) + "<br/>";
- }
- QString name = id.empty() ? "you" : P2QSTRING(id);
- text += QString(tr("At %1 %2 corrected the last action to: <i>")).arg(ChatSnippet::timeToEscapedString(B2QDATE(time))).arg(name);
- text += chatMessageToString(message);
- text += "</i></p>";
- log_->append(text);
+ QString text = "<p>";
+ if (lastMessageLabel_[id]) {
+ text += P2QSTRING(lastMessageLabel_[id]->getLabel()) + "<br/>";
+ }
+ QString name = id.empty() ? "you" : P2QSTRING(id);
+ text += QString(tr("At %1 %2 corrected the last action to: <i>")).arg(ChatSnippet::timeToEscapedString(B2QDATE(time))).arg(name);
+ text += chatMessageToString(message);
+ text += "</i></p>";
+ log_->append(text);
}
void QtPlainChatView::replaceLastMessage(const ChatWindow::ChatMessage& message, const ChatWindow::TimestampBehaviour /*timestampBehaviour*/)
{
- QString text = "<p>The last message was corrected to:<br/>";
- text += chatMessageToString(message);
- text += "</p>";
- log_->append(text);
+ QString text = "<p>The last message was corrected to:<br/>";
+ text += chatMessageToString(message);
+ text += "</p>";
+ log_->append(text);
}
void QtPlainChatView::replaceSystemMessage(const ChatWindow::ChatMessage& message, const std::string& /*id*/, const ChatWindow::TimestampBehaviour /*timestampBehaviour*/) {
- QString text = "<p><i>";
- text += chatMessageToString(message);
- text += "</i></p>";
- log_->append(text);
+ QString text = "<p><i>";
+ text += chatMessageToString(message);
+ text += "</i></p>";
+ log_->append(text);
}
void QtPlainChatView::setAckState(const std::string& /*id*/, ChatWindow::AckState state)
{
- if (state == ChatWindow::Failed) {
- addSystemMessage(ChatWindow::ChatMessage("Message delivery failed due to disconnection from server."), ChatWindow::DefaultDirection);
- }
+ if (state == ChatWindow::Failed) {
+ addSystemMessage(ChatWindow::ChatMessage("Message delivery failed due to disconnection from server."), ChatWindow::DefaultDirection);
+ }
}
std::string QtPlainChatView::addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes, const std::string& description)
{
- const std::string ftId = "ft" + boost::lexical_cast<std::string>(idGenerator_++);
- const std::string sizeString = formatSize(sizeInBytes);
-
- FileTransfer* transfer;
- if (senderIsSelf) {
- QString description = QInputDialog::getText(this, tr("File transfer description"),
- tr("Description:"), QLineEdit::Normal, "");
- /* NOTE: it is not possible to abort if description is not provided, since we must always return a valid transfer id */
- const std::string descriptionMessage = description.isEmpty() ? "" : (" \"" + Q2PSTRING(description) + "\"");
- const std::string message = std::string() + "Confirm file transfer: <i>" + filename + " (" + sizeString + " bytes)</i>" + descriptionMessage;
- transfer = new FileTransfer(this, senderIsSelf, ftId, filename, ChatWindow::WaitingForAccept, Q2PSTRING(description), message, true);
- addSystemMessage(ChatWindow::ChatMessage("Preparing to start file transfer..."), ChatWindow::DefaultDirection);
- } else { /* incoming transfer */
- const std::string descriptionMessage = description.empty() ? "" : (" \"" + description + "\"");
- const std::string message = std::string() + "Incoming file transfer: <i>" + filename + " (" + sizeString + " bytes)</i>" + descriptionMessage;
- transfer = new FileTransfer(this, senderIsSelf, ftId, filename, ChatWindow::WaitingForAccept, "", message, true);
- addSystemMessage("Incoming file transfer from " + senderName + "...", ChatWindow::DefaultDirection);
- }
-
- fileTransfers_[ftId] = transfer;
- layout()->addWidget(transfer->dialog_);
-
- return ftId;
+ const std::string ftId = "ft" + boost::lexical_cast<std::string>(idGenerator_++);
+ const std::string sizeString = formatSize(sizeInBytes);
+
+ FileTransfer* transfer;
+ if (senderIsSelf) {
+ QString description = QInputDialog::getText(this, tr("File transfer description"),
+ tr("Description:"), QLineEdit::Normal, "");
+ /* NOTE: it is not possible to abort if description is not provided, since we must always return a valid transfer id */
+ const std::string descriptionMessage = description.isEmpty() ? "" : (" \"" + Q2PSTRING(description) + "\"");
+ const std::string message = std::string() + "Confirm file transfer: <i>" + filename + " (" + sizeString + " bytes)</i>" + descriptionMessage;
+ transfer = new FileTransfer(this, senderIsSelf, ftId, filename, ChatWindow::WaitingForAccept, Q2PSTRING(description), message, true);
+ addSystemMessage(ChatWindow::ChatMessage("Preparing to start file transfer..."), ChatWindow::DefaultDirection);
+ } else { /* incoming transfer */
+ const std::string descriptionMessage = description.empty() ? "" : (" \"" + description + "\"");
+ const std::string message = std::string() + "Incoming file transfer: <i>" + filename + " (" + sizeString + " bytes)</i>" + descriptionMessage;
+ transfer = new FileTransfer(this, senderIsSelf, ftId, filename, ChatWindow::WaitingForAccept, "", message, true);
+ addSystemMessage("Incoming file transfer from " + senderName + "...", ChatWindow::DefaultDirection);
+ }
+
+ fileTransfers_[ftId] = transfer;
+ layout()->addWidget(transfer->dialog_);
+
+ return ftId;
}
void QtPlainChatView::setFileTransferProgress(std::string id, const int percentageDone)
{
- FileTransferMap::iterator transfer = fileTransfers_.find(id);
- if (transfer != fileTransfers_.end()) {
- transfer->second->bar_->setValue(percentageDone);
- }
+ FileTransferMap::iterator transfer = fileTransfers_.find(id);
+ if (transfer != fileTransfers_.end()) {
+ transfer->second->bar_->setValue(percentageDone);
+ }
}
void QtPlainChatView::setFileTransferStatus(std::string id, const ChatWindow::FileTransferState state, const std::string& msg)
{
- FileTransferMap::iterator transferIter = fileTransfers_.find(id);
- if (transferIter == fileTransfers_.end()) {
- return;
- }
-
- /* store the layout index so we can restore it to the same location */
- FileTransfer* oldTransfer = transferIter->second;
- const int layoutIndex = layout()->indexOf(oldTransfer->dialog_);
- layout()->removeWidget(oldTransfer->dialog_);
- const std::string &label = (!msg.empty() ? msg : oldTransfer->message_);
- FileTransfer* transfer = new FileTransfer(this, oldTransfer->senderIsSelf_, oldTransfer->ftId_, oldTransfer->filename_, state, oldTransfer->description_, label, false);
- fileTransfers_[oldTransfer->ftId_] = transfer; /* replace the transfer object for this file id */
- delete oldTransfer;
-
- /* insert the new dialog at the old position in the layout list */
- QBoxLayout* parentLayout = dynamic_cast<QBoxLayout*>(layout());
- assert(parentLayout);
- parentLayout->insertWidget(layoutIndex, transfer->dialog_);
-
- /* log the transfer end result as a system message */
- if (state == ChatWindow::Finished) {
- addSystemMessage(ChatWindow::ChatMessage("The file transfer completed successfully."), ChatWindow::DefaultDirection);
- } else if (state == ChatWindow::Canceled) {
- addSystemMessage(ChatWindow::ChatMessage("The file transfer was canceled."), ChatWindow::DefaultDirection);
- } else if (state == ChatWindow::FTFailed) {
- addSystemMessage(ChatWindow::ChatMessage("The file transfer failed."), ChatWindow::DefaultDirection);
- }
+ FileTransferMap::iterator transferIter = fileTransfers_.find(id);
+ if (transferIter == fileTransfers_.end()) {
+ return;
+ }
+
+ /* store the layout index so we can restore it to the same location */
+ FileTransfer* oldTransfer = transferIter->second;
+ const int layoutIndex = layout()->indexOf(oldTransfer->dialog_);
+ layout()->removeWidget(oldTransfer->dialog_);
+ const std::string &label = (!msg.empty() ? msg : oldTransfer->message_);
+ FileTransfer* transfer = new FileTransfer(this, oldTransfer->senderIsSelf_, oldTransfer->ftId_, oldTransfer->filename_, state, oldTransfer->description_, label, false);
+ fileTransfers_[oldTransfer->ftId_] = transfer; /* replace the transfer object for this file id */
+ delete oldTransfer;
+
+ /* insert the new dialog at the old position in the layout list */
+ QBoxLayout* parentLayout = dynamic_cast<QBoxLayout*>(layout());
+ assert(parentLayout);
+ parentLayout->insertWidget(layoutIndex, transfer->dialog_);
+
+ /* log the transfer end result as a system message */
+ if (state == ChatWindow::Finished) {
+ addSystemMessage(ChatWindow::ChatMessage("The file transfer completed successfully."), ChatWindow::DefaultDirection);
+ } else if (state == ChatWindow::Canceled) {
+ addSystemMessage(ChatWindow::ChatMessage("The file transfer was canceled."), ChatWindow::DefaultDirection);
+ } else if (state == ChatWindow::FTFailed) {
+ addSystemMessage(ChatWindow::ChatMessage("The file transfer failed."), ChatWindow::DefaultDirection);
+ }
}
void QtPlainChatView::addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& /*reason*/, const std::string& password, bool /*direct*/, bool isImpromptu, bool isContinuation)
{
- PopupDialog *invite = new PopupDialog(this);
+ PopupDialog *invite = new PopupDialog(this);
- QLabel* statusLabel = new QLabel;
- std::string msg = senderName + " has invited you to join " + jid.toString() + "...";
- statusLabel->setText(P2QSTRING(msg));
- invite->layout_->addWidget(statusLabel);
- invite->layout_->addWidget(new QLabel); /* padding */
+ QLabel* statusLabel = new QLabel;
+ std::string msg = senderName + " has invited you to join " + jid.toString() + "...";
+ statusLabel->setText(P2QSTRING(msg));
+ invite->layout_->addWidget(statusLabel);
+ invite->layout_->addWidget(new QLabel); /* padding */
- AcceptMUCInviteAction* accept = new AcceptMUCInviteAction(invite, "Accept", jid, senderName, password, isImpromptu, isContinuation);
- connect(accept, SIGNAL(clicked()), SLOT(acceptMUCInvite()));
- invite->layout_->addWidget(accept);
+ AcceptMUCInviteAction* accept = new AcceptMUCInviteAction(invite, "Accept", jid, senderName, password, isImpromptu, isContinuation);
+ connect(accept, SIGNAL(clicked()), SLOT(acceptMUCInvite()));
+ invite->layout_->addWidget(accept);
- AcceptMUCInviteAction* reject = new AcceptMUCInviteAction(invite, "Reject", jid, senderName, password, isImpromptu, isContinuation);
- connect(reject, SIGNAL(clicked()), SLOT(rejectMUCInvite()));
- invite->layout_->addWidget(reject);
- statusLabel->setText(P2QSTRING(msg));
+ AcceptMUCInviteAction* reject = new AcceptMUCInviteAction(invite, "Reject", jid, senderName, password, isImpromptu, isContinuation);
+ connect(reject, SIGNAL(clicked()), SLOT(rejectMUCInvite()));
+ invite->layout_->addWidget(reject);
+ statusLabel->setText(P2QSTRING(msg));
- layout()->addWidget(invite->dialog_);
+ layout()->addWidget(invite->dialog_);
- addSystemMessage(ChatWindow::ChatMessage(msg), ChatWindow::DefaultDirection);
+ addSystemMessage(ChatWindow::ChatMessage(msg), ChatWindow::DefaultDirection);
}
void QtPlainChatView::scrollToBottom()
{
- log_->ensureCursorVisible();
- log_->verticalScrollBar()->setValue(log_->verticalScrollBar()->maximum());
+ log_->ensureCursorVisible();
+ log_->verticalScrollBar()->setValue(log_->verticalScrollBar()->maximum());
}
void QtPlainChatView::fileTransferAccept()
{
- FileTransfer::Action* action = dynamic_cast<FileTransfer::Action*>(sender());
- if (!action) {
- return;
- }
-
- FileTransferMap::iterator transferIter = fileTransfers_.find(action->id_);
- if (transferIter == fileTransfers_.end()) {
- return;
- }
-
- FileTransfer* transfer = transferIter->second;
-
- const std::string message = transfer->message_;
-
- if (transfer->senderIsSelf_) { /* if we are the sender, kick of the transfer */
- window_->onFileTransferStart(transfer->ftId_, transfer->description_);
- } else { /* ask the user where to save the file first */
- QString path = QFileDialog::getSaveFileName(this, tr("Save File"), P2QSTRING(transfer->filename_));
- if (path.isEmpty()) {
- fileTransferReject(); /* because the user did not select a desintation path */
- return;
- }
- window_->onFileTransferAccept(transfer->ftId_, Q2PSTRING(path));
- }
-
- setFileTransferStatus(transfer->ftId_, ChatWindow::Negotiating, message);
+ FileTransfer::Action* action = dynamic_cast<FileTransfer::Action*>(sender());
+ if (!action) {
+ return;
+ }
+
+ FileTransferMap::iterator transferIter = fileTransfers_.find(action->id_);
+ if (transferIter == fileTransfers_.end()) {
+ return;
+ }
+
+ FileTransfer* transfer = transferIter->second;
+
+ const std::string message = transfer->message_;
+
+ if (transfer->senderIsSelf_) { /* if we are the sender, kick of the transfer */
+ window_->onFileTransferStart(transfer->ftId_, transfer->description_);
+ } else { /* ask the user where to save the file first */
+ QString path = QFileDialog::getSaveFileName(this, tr("Save File"), P2QSTRING(transfer->filename_));
+ if (path.isEmpty()) {
+ fileTransferReject(); /* because the user did not select a desintation path */
+ return;
+ }
+ window_->onFileTransferAccept(transfer->ftId_, Q2PSTRING(path));
+ }
+
+ setFileTransferStatus(transfer->ftId_, ChatWindow::Negotiating, message);
}
void QtPlainChatView::fileTransferReject()
{
- FileTransfer::Action* action = dynamic_cast<FileTransfer::Action*>(sender());
- if (action) {
- window_->onFileTransferCancel(action->id_);
- fileTransferFinish();
- }
+ FileTransfer::Action* action = dynamic_cast<FileTransfer::Action*>(sender());
+ if (action) {
+ window_->onFileTransferCancel(action->id_);
+ fileTransferFinish();
+ }
}
void QtPlainChatView::fileTransferFinish()
{
- FileTransfer::Action* action = dynamic_cast<FileTransfer::Action*>(sender());
- if (action) {
- FileTransferMap::iterator transferIter = fileTransfers_.find(action->id_);
- if (transferIter != fileTransfers_.end()) {
- delete transferIter->second; /* cause the dialog to close */
- fileTransfers_.erase(transferIter);
- }
- }
+ FileTransfer::Action* action = dynamic_cast<FileTransfer::Action*>(sender());
+ if (action) {
+ FileTransferMap::iterator transferIter = fileTransfers_.find(action->id_);
+ if (transferIter != fileTransfers_.end()) {
+ delete transferIter->second; /* cause the dialog to close */
+ fileTransfers_.erase(transferIter);
+ }
+ }
}
void QtPlainChatView::acceptMUCInvite()
{
- AcceptMUCInviteAction *action = dynamic_cast<AcceptMUCInviteAction*>(sender());
- if (action) {
- eventStream_->send(boost::make_shared<JoinMUCUIEvent>(action->jid_.toString(), action->password_, boost::optional<std::string>(), false, false, action->isImpromptu_, action->isContinuation_));
- delete action->parent_;
- }
+ AcceptMUCInviteAction *action = dynamic_cast<AcceptMUCInviteAction*>(sender());
+ if (action) {
+ eventStream_->send(std::make_shared<JoinMUCUIEvent>(action->jid_.toString(), action->password_, boost::optional<std::string>(), false, false, action->isImpromptu_, action->isContinuation_));
+ delete action->parent_;
+ }
}
void QtPlainChatView::rejectMUCInvite()
{
- AcceptMUCInviteAction *action = dynamic_cast<AcceptMUCInviteAction*>(sender());
- if (action) {
- /* NOTE: no action required to reject an invite? */
- delete action->parent_;
- }
+ AcceptMUCInviteAction *action = dynamic_cast<AcceptMUCInviteAction*>(sender());
+ if (action) {
+ /* NOTE: no action required to reject an invite? */
+ delete action->parent_;
+ }
}
QtPlainChatView::FileTransfer::FileTransfer(QtPlainChatView* parent, bool senderIsSelf, const std::string& ftId, const std::string& filename, const ChatWindow::FileTransferState state, const std::string &desc, const std::string& msg, bool initializing)
-: PopupDialog(parent), bar_(0), senderIsSelf_(senderIsSelf), ftId_(ftId), filename_(filename), description_(desc), message_(msg), initializing_(initializing)
+: PopupDialog(parent), bar_(nullptr), senderIsSelf_(senderIsSelf), ftId_(ftId), filename_(filename), description_(desc), message_(msg), initializing_(initializing)
{
- QHBoxLayout* layout = new QHBoxLayout;
- QLabel* statusLabel = new QLabel;
- layout_->addWidget(statusLabel);
- layout_->addWidget(new QLabel); /* padding */
-
- if (initializing_) {
- FileTransfer::Action* accept = new FileTransfer::Action(senderIsSelf?"Confirm":"Accept", ftId);
- parent->connect(accept, SIGNAL(clicked()), SLOT(fileTransferAccept()));
- layout_->addWidget(accept);
- FileTransfer::Action* reject = new FileTransfer::Action(senderIsSelf?"Cancel":"Reject", ftId);
- parent->connect(reject, SIGNAL(clicked()), SLOT(fileTransferReject()));
- layout_->addWidget(reject);
- statusLabel->setText(P2QSTRING(msg));
- return;
- }
-
- std::string status = msg;
-
- switch (state) {
- case ChatWindow::Initialisation: {
- status = "Preparing to send <i>"+ filename + "</i>...";
- FileTransfer::Action* cancel = new FileTransfer::Action("Cancel", ftId);
- parent->connect(cancel, SIGNAL(clicked()), SLOT(fileTransferReject()));
- layout_->addWidget(cancel);
- break;
- }
- case ChatWindow::WaitingForAccept: {
- status = "Waiting for user to accept <i>" + filename + "</i>...";
- FileTransfer::Action* cancel = new FileTransfer::Action("Cancel", ftId);
- parent->connect(cancel, SIGNAL(clicked()), SLOT(fileTransferReject()));
- layout_->addWidget(cancel);
- break;
- }
- case ChatWindow::Negotiating: {
- status = "Preparing to transfer <i>" + filename + "</i>...";
- FileTransfer::Action* cancel = new FileTransfer::Action("Cancel", ftId);
- parent->connect(cancel, SIGNAL(clicked()), SLOT(fileTransferReject()));
- layout_->addWidget(cancel);
- break;
- }
- case ChatWindow::Transferring: {
- status = "Transferring <i>" + filename + "</i>...";
- bar_ = new QProgressBar;
- bar_->setRange(0, 100);
- bar_->setValue(0);
- layout->addWidget(bar_);
- FileTransfer::Action* cancel = new FileTransfer::Action("Cancel", ftId);
- parent->connect(cancel, SIGNAL(clicked()), SLOT(fileTransferReject()));
- layout_->addWidget(cancel);
- break;
- }
- case ChatWindow::Canceled: {
- status = "File <i>" + filename + "</i> was canceled.";
- FileTransfer::Action* finish = new FileTransfer::Action("Hide", ftId);
- parent->connect(finish, SIGNAL(clicked()), SLOT(fileTransferFinish()));
- layout_->addWidget(finish);
- break;
- }
- case ChatWindow::Finished: {
- status = "File <i>" + filename + "</i> was transfered successfully.";
- FileTransfer::Action* finish = new FileTransfer::Action("Hide", ftId);
- parent->connect(finish, SIGNAL(clicked()), SLOT(fileTransferFinish()));
- layout_->addWidget(finish);
- break;
- }
- case ChatWindow::FTFailed: {
- status = "File transfer failed: <i>" + filename + "</i>";
- FileTransfer::Action* finish = new FileTransfer::Action("Hide", ftId);
- parent->connect(finish, SIGNAL(clicked()), SLOT(fileTransferFinish()));
- layout_->addWidget(finish);
- break;
- }
- }
-
- statusLabel->setText(P2QSTRING(status));
+ QHBoxLayout* layout = new QHBoxLayout;
+ QLabel* statusLabel = new QLabel;
+ layout_->addWidget(statusLabel);
+ layout_->addWidget(new QLabel); /* padding */
+
+ if (initializing_) {
+ FileTransfer::Action* accept = new FileTransfer::Action(senderIsSelf?"Confirm":"Accept", ftId);
+ parent->connect(accept, SIGNAL(clicked()), SLOT(fileTransferAccept()));
+ layout_->addWidget(accept);
+ FileTransfer::Action* reject = new FileTransfer::Action(senderIsSelf?"Cancel":"Reject", ftId);
+ parent->connect(reject, SIGNAL(clicked()), SLOT(fileTransferReject()));
+ layout_->addWidget(reject);
+ statusLabel->setText(P2QSTRING(msg));
+ return;
+ }
+
+ std::string status = msg;
+
+ switch (state) {
+ case ChatWindow::Initialisation: {
+ status = "Preparing to send <i>"+ filename + "</i>...";
+ FileTransfer::Action* cancel = new FileTransfer::Action("Cancel", ftId);
+ parent->connect(cancel, SIGNAL(clicked()), SLOT(fileTransferReject()));
+ layout_->addWidget(cancel);
+ break;
+ }
+ case ChatWindow::WaitingForAccept: {
+ status = "Waiting for user to accept <i>" + filename + "</i>...";
+ FileTransfer::Action* cancel = new FileTransfer::Action("Cancel", ftId);
+ parent->connect(cancel, SIGNAL(clicked()), SLOT(fileTransferReject()));
+ layout_->addWidget(cancel);
+ break;
+ }
+ case ChatWindow::Negotiating: {
+ status = "Preparing to transfer <i>" + filename + "</i>...";
+ FileTransfer::Action* cancel = new FileTransfer::Action("Cancel", ftId);
+ parent->connect(cancel, SIGNAL(clicked()), SLOT(fileTransferReject()));
+ layout_->addWidget(cancel);
+ break;
+ }
+ case ChatWindow::Transferring: {
+ status = "Transferring <i>" + filename + "</i>...";
+ bar_ = new QProgressBar;
+ bar_->setRange(0, 100);
+ bar_->setValue(0);
+ layout->addWidget(bar_);
+ FileTransfer::Action* cancel = new FileTransfer::Action("Cancel", ftId);
+ parent->connect(cancel, SIGNAL(clicked()), SLOT(fileTransferReject()));
+ layout_->addWidget(cancel);
+ break;
+ }
+ case ChatWindow::Canceled: {
+ status = "File <i>" + filename + "</i> was canceled.";
+ FileTransfer::Action* finish = new FileTransfer::Action("Hide", ftId);
+ parent->connect(finish, SIGNAL(clicked()), SLOT(fileTransferFinish()));
+ layout_->addWidget(finish);
+ break;
+ }
+ case ChatWindow::Finished: {
+ status = "File <i>" + filename + "</i> was transfered successfully.";
+ FileTransfer::Action* finish = new FileTransfer::Action("Hide", ftId);
+ parent->connect(finish, SIGNAL(clicked()), SLOT(fileTransferFinish()));
+ layout_->addWidget(finish);
+ break;
+ }
+ case ChatWindow::FTFailed: {
+ status = "File transfer failed: <i>" + filename + "</i>";
+ FileTransfer::Action* finish = new FileTransfer::Action("Hide", ftId);
+ parent->connect(finish, SIGNAL(clicked()), SLOT(fileTransferFinish()));
+ layout_->addWidget(finish);
+ break;
+ }
+ }
+
+ statusLabel->setText(P2QSTRING(status));
}
void QtPlainChatView::LogTextEdit::contextMenuEvent(QContextMenuEvent *event)
{
- QMenu *menu = createStandardContextMenu();
- menu->exec(event->globalPos());
- delete menu;
+ QMenu *menu = createStandardContextMenu();
+ menu->exec(event->globalPos());
+ delete menu;
}
}
diff --git a/Swift/QtUI/QtPlainChatView.h b/Swift/QtUI/QtPlainChatView.h
index aeb50b6..d65672c 100644
--- a/Swift/QtUI/QtPlainChatView.h
+++ b/Swift/QtUI/QtPlainChatView.h
@@ -1,15 +1,15 @@
/*
- * Copyright (c) 2013-2015 Isode Limited.
+ * Copyright (c) 2013-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <memory>
#include <string>
#include <boost/date_time/posix_time/posix_time.hpp>
-#include <boost/shared_ptr.hpp>
#include <QTextEdit>
#include <QWidget>
@@ -23,112 +23,112 @@ class QTextEdit;
class QProgressBar;
namespace Swift {
- class HighlightAction;
- class SecurityLabel;
-
- class QtPlainChatView : public QtChatView {
- Q_OBJECT
- public:
- QtPlainChatView(QtChatWindow *window, UIEventStream* eventStream);
- virtual ~QtPlainChatView();
-
- /** Add message to window.
- * @return id of added message (for acks).
- */
- virtual std::string addMessage(const ChatWindow::ChatMessage& /*message*/, const std::string& /*senderName*/, bool /*senderIsSelf*/, boost::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime& /*time*/, const HighlightAction& /*highlight*/);
- /** Adds action to window.
- * @return id of added message (for acks);
- */
- virtual std::string addAction(const ChatWindow::ChatMessage& /*message*/, const std::string& /*senderName*/, bool /*senderIsSelf*/, boost::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime& /*time*/, const HighlightAction& /*highlight*/);
-
- virtual std::string addSystemMessage(const ChatWindow::ChatMessage& /*message*/, ChatWindow::Direction /*direction*/);
- virtual void addPresenceMessage(const ChatWindow::ChatMessage& /*message*/, ChatWindow::Direction /*direction*/);
- virtual void addErrorMessage(const ChatWindow::ChatMessage& /*message*/);
-
- virtual void replaceMessage(const ChatWindow::ChatMessage& /*message*/, const std::string& /*id*/, const boost::posix_time::ptime& /*time*/, const HighlightAction& /*highlight*/);
- virtual void replaceWithAction(const ChatWindow::ChatMessage& /*message*/, const std::string& /*id*/, const boost::posix_time::ptime& /*time*/, const HighlightAction& /*highlight*/);
- virtual void replaceLastMessage(const ChatWindow::ChatMessage& /*message*/, const ChatWindow::TimestampBehaviour /*timestampBehaviour*/);
- virtual void replaceSystemMessage(const ChatWindow::ChatMessage& message, const std::string& id, const ChatWindow::TimestampBehaviour /*timestampBehaviour*/);
- virtual void setAckState(const std::string& /*id*/, ChatWindow::AckState /*state*/);
-
- virtual std::string addFileTransfer(const std::string& /*senderName*/, bool /*senderIsSelf*/, const std::string& /*filename*/, const boost::uintmax_t /*sizeInBytes*/, const std::string& /*description*/);
- virtual void setFileTransferProgress(std::string, const int /*percentageDone*/);
- virtual void setFileTransferStatus(std::string, const ChatWindow::FileTransferState /*state*/, const std::string& /*msg*/ = "");
- virtual void addMUCInvitation(const std::string& /*senderName*/, const JID& /*jid*/, const std::string& /*reason*/, const std::string& /*password*/, bool /*direct*/, bool /*isImpromptu*/, bool /*isContinuation*/);
- virtual std::string addWhiteboardRequest(const QString& /*contact*/, bool /*senderIsSelf*/) {return "";};
- virtual void setWhiteboardSessionStatus(const std::string& /*id*/, const ChatWindow::WhiteboardSessionState /*state*/) {};
- virtual void setMessageReceiptState(const std::string& /*id*/, ChatWindow::ReceiptState /*state*/) {};
-
- virtual void showEmoticons(bool /*show*/) {};
- virtual void addLastSeenLine() {};
-
- public slots:
- virtual void resizeFont(int /*fontSizeSteps*/) {};
- virtual void scrollToBottom();
- virtual void handleKeyPressEvent(QKeyEvent* /*event*/) {};
- virtual void fileTransferAccept();
- virtual void fileTransferReject();
- virtual void fileTransferFinish();
- virtual void acceptMUCInvite();
- virtual void rejectMUCInvite();
-
- private:
- struct PopupDialog {
- PopupDialog(QtPlainChatView* parent) {
- dialog_ = new QFrame(parent);
- dialog_->setFrameShape(QFrame::Panel);
- dialog_->setFrameShadow(QFrame::Raised);
- layout_ = new QHBoxLayout;
- dialog_->setLayout(layout_);
- }
- virtual ~PopupDialog() {
- delete dialog_;
- }
- QFrame* dialog_;
- QHBoxLayout* layout_;
- };
-
- struct AcceptMUCInviteAction : public QPushButton {
- AcceptMUCInviteAction(PopupDialog* parent, const std::string& text, const JID& jid, const std::string& senderName, const std::string& password, bool isImpromptu, bool isContinuation)
- : QPushButton(P2QSTRING(text)), parent_(parent), jid_(jid), senderName_(senderName), password_(password), isImpromptu_(isImpromptu), isContinuation_(isContinuation) {}
- PopupDialog *parent_;
- JID jid_;
- std::string senderName_;
- std::string password_;
- bool isImpromptu_;
- bool isContinuation_;
- };
-
- struct FileTransfer : public PopupDialog {
- struct Action : QPushButton {
- Action(const std::string& text, const std::string& id)
- : QPushButton(P2QSTRING(text)), id_(id) {}
- std::string id_;
- };
- FileTransfer(QtPlainChatView* parent, bool senderIsSelf, const std::string& ftId, const std::string& filename, const ChatWindow::FileTransferState state, const std::string& desc, const std::string& msg, bool initializing);
- QProgressBar* bar_;
- bool senderIsSelf_;
- std::string ftId_;
- std::string filename_;
- std::string description_;
- std::string message_;
- bool initializing_;
- };
-
- class LogTextEdit : public QTextEdit {
- public:
- LogTextEdit(QWidget* parent) : QTextEdit(parent) {}
- virtual ~LogTextEdit() {}
- virtual void contextMenuEvent(QContextMenuEvent *event);
- };
-
- typedef std::map<std::string, FileTransfer*> FileTransferMap;
- QtChatWindow* window_;
- UIEventStream* eventStream_;
- LogTextEdit* log_;
- FileTransferMap fileTransfers_;
- std::map<std::string, boost::shared_ptr<SecurityLabel> > lastMessageLabel_;
- int idGenerator_;
-
- };
+ class HighlightAction;
+ class SecurityLabel;
+
+ class QtPlainChatView : public QtChatView {
+ Q_OBJECT
+ public:
+ QtPlainChatView(QtChatWindow *window, UIEventStream* eventStream);
+ virtual ~QtPlainChatView();
+
+ /** Add message to window.
+ * @return id of added message (for acks).
+ */
+ virtual std::string addMessage(const ChatWindow::ChatMessage& /*message*/, const std::string& /*senderName*/, bool /*senderIsSelf*/, std::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime& /*time*/);
+ /** Adds action to window.
+ * @return id of added message (for acks);
+ */
+ virtual std::string addAction(const ChatWindow::ChatMessage& /*message*/, const std::string& /*senderName*/, bool /*senderIsSelf*/, std::shared_ptr<SecurityLabel> /*label*/, const std::string& /*avatarPath*/, const boost::posix_time::ptime& /*time*/);
+
+ virtual std::string addSystemMessage(const ChatWindow::ChatMessage& /*message*/, ChatWindow::Direction /*direction*/);
+ virtual void addPresenceMessage(const ChatWindow::ChatMessage& /*message*/, ChatWindow::Direction /*direction*/);
+ virtual void addErrorMessage(const ChatWindow::ChatMessage& /*message*/);
+
+ virtual void replaceMessage(const ChatWindow::ChatMessage& /*message*/, const std::string& /*id*/, const boost::posix_time::ptime& /*time*/);
+ virtual void replaceWithAction(const ChatWindow::ChatMessage& /*message*/, const std::string& /*id*/, const boost::posix_time::ptime& /*time*/);
+ virtual void replaceLastMessage(const ChatWindow::ChatMessage& /*message*/, const ChatWindow::TimestampBehaviour /*timestampBehaviour*/);
+ virtual void replaceSystemMessage(const ChatWindow::ChatMessage& message, const std::string& id, const ChatWindow::TimestampBehaviour /*timestampBehaviour*/);
+ virtual void setAckState(const std::string& /*id*/, ChatWindow::AckState /*state*/);
+
+ virtual std::string addFileTransfer(const std::string& /*senderName*/, bool /*senderIsSelf*/, const std::string& /*filename*/, const boost::uintmax_t /*sizeInBytes*/, const std::string& /*description*/);
+ virtual void setFileTransferProgress(std::string, const int /*percentageDone*/);
+ virtual void setFileTransferStatus(std::string, const ChatWindow::FileTransferState /*state*/, const std::string& /*msg*/ = "");
+ virtual void addMUCInvitation(const std::string& /*senderName*/, const JID& /*jid*/, const std::string& /*reason*/, const std::string& /*password*/, bool /*direct*/, bool /*isImpromptu*/, bool /*isContinuation*/);
+ virtual std::string addWhiteboardRequest(const QString& /*contact*/, bool /*senderIsSelf*/) {return "";}
+ virtual void setWhiteboardSessionStatus(const std::string& /*id*/, const ChatWindow::WhiteboardSessionState /*state*/) {}
+ virtual void setMessageReceiptState(const std::string& /*id*/, ChatWindow::ReceiptState /*state*/) {}
+
+ virtual void showEmoticons(bool /*show*/) {}
+ virtual void addLastSeenLine() {}
+
+ public slots:
+ virtual void resizeFont(int /*fontSizeSteps*/) {}
+ virtual void scrollToBottom();
+ virtual void handleKeyPressEvent(QKeyEvent* /*event*/) {}
+ virtual void fileTransferAccept();
+ virtual void fileTransferReject();
+ virtual void fileTransferFinish();
+ virtual void acceptMUCInvite();
+ virtual void rejectMUCInvite();
+
+ private:
+ struct PopupDialog {
+ PopupDialog(QtPlainChatView* parent) {
+ dialog_ = new QFrame(parent);
+ dialog_->setFrameShape(QFrame::Panel);
+ dialog_->setFrameShadow(QFrame::Raised);
+ layout_ = new QHBoxLayout;
+ dialog_->setLayout(layout_);
+ }
+ virtual ~PopupDialog() {
+ delete dialog_;
+ }
+ QFrame* dialog_;
+ QHBoxLayout* layout_;
+ };
+
+ struct AcceptMUCInviteAction : public QPushButton {
+ AcceptMUCInviteAction(PopupDialog* parent, const std::string& text, const JID& jid, const std::string& senderName, const std::string& password, bool isImpromptu, bool isContinuation)
+ : QPushButton(P2QSTRING(text)), parent_(parent), jid_(jid), senderName_(senderName), password_(password), isImpromptu_(isImpromptu), isContinuation_(isContinuation) {}
+ PopupDialog *parent_;
+ JID jid_;
+ std::string senderName_;
+ std::string password_;
+ bool isImpromptu_;
+ bool isContinuation_;
+ };
+
+ struct FileTransfer : public PopupDialog {
+ struct Action : QPushButton {
+ Action(const std::string& text, const std::string& id)
+ : QPushButton(P2QSTRING(text)), id_(id) {}
+ std::string id_;
+ };
+ FileTransfer(QtPlainChatView* parent, bool senderIsSelf, const std::string& ftId, const std::string& filename, const ChatWindow::FileTransferState state, const std::string& desc, const std::string& msg, bool initializing);
+ QProgressBar* bar_;
+ bool senderIsSelf_;
+ std::string ftId_;
+ std::string filename_;
+ std::string description_;
+ std::string message_;
+ bool initializing_;
+ };
+
+ class LogTextEdit : public QTextEdit {
+ public:
+ LogTextEdit(QWidget* parent) : QTextEdit(parent) {}
+ virtual ~LogTextEdit() {}
+ virtual void contextMenuEvent(QContextMenuEvent *event);
+ };
+
+ typedef std::map<std::string, FileTransfer*> FileTransferMap;
+ QtChatWindow* window_;
+ UIEventStream* eventStream_;
+ LogTextEdit* log_;
+ FileTransferMap fileTransfers_;
+ std::map<std::string, std::shared_ptr<SecurityLabel> > lastMessageLabel_;
+ int idGenerator_;
+
+ };
}
diff --git a/Swift/QtUI/QtProfileWindow.cpp b/Swift/QtUI/QtProfileWindow.cpp
index 06d602a..80e275b 100644
--- a/Swift/QtUI/QtProfileWindow.cpp
+++ b/Swift/QtUI/QtProfileWindow.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2015 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -11,7 +11,6 @@
*/
#include <Swift/QtUI/QtProfileWindow.h>
-#include <Swift/QtUI/ui_QtProfileWindow.h>
#include <QCloseEvent>
#include <QMovie>
@@ -21,147 +20,148 @@
#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swift/QtUI/QtUtilities.h>
+#include <Swift/QtUI/ui_QtProfileWindow.h>
namespace Swift {
QtProfileWindow::QtProfileWindow() :
- QWidget(),
- ui(new Ui::QtProfileWindow) {
- ui->setupUi(this);
+ QWidget(),
+ ui(new Ui::QtProfileWindow) {
+ ui->setupUi(this);
- ui->statusLabel->setText(tr("Retrieving profile information for this user."));
- ui->statusLabel->setVisible(false);
+ ui->statusLabel->setText(tr("Retrieving profile information for this user."));
+ ui->statusLabel->setVisible(false);
- ui->emptyLabel->setText(tr("No profile information is available for this user."));
- ui->emptyLabel->setVisible(false);
+ ui->emptyLabel->setText(tr("No profile information is available for this user."));
+ ui->emptyLabel->setVisible(false);
- new QShortcut(QKeySequence::Close, this, SLOT(close()));
- ui->throbberLabel->setMovie(new QMovie(":/icons/throbber.gif", QByteArray(), this));
- connect(ui->savePushButton, SIGNAL(clicked()), SLOT(handleSave()));
- setEditable(false);
- setAttribute(Qt::WA_DeleteOnClose);
- setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
+ new QShortcut(QKeySequence::Close, this, SLOT(close()));
+ ui->throbberLabel->setMovie(new QMovie(":/icons/throbber.gif", QByteArray(), this));
+ connect(ui->savePushButton, SIGNAL(clicked()), SLOT(handleSave()));
+ setEditable(false);
+ setAttribute(Qt::WA_DeleteOnClose);
+ setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
- adjustSizeTimer.setSingleShot(true);
- connect(&adjustSizeTimer, SIGNAL(timeout()), SLOT(handleAdjustSizeTimeout()));
+ adjustSizeTimer.setSingleShot(true);
+ connect(&adjustSizeTimer, SIGNAL(timeout()), SLOT(handleAdjustSizeTimeout()));
}
QtProfileWindow::~QtProfileWindow() {
- delete ui;
+ delete ui;
}
void QtProfileWindow::setJID(const JID& jid) {
- this->jid = jid;
- updateTitle();
+ this->jid = jid;
+ updateTitle();
}
void QtProfileWindow::setVCard(VCard::ref vcard) {
- ui->vcard->setVCard(vcard);
- if (vcard->isEmpty()) {
- ui->vcard->setVisible(false);
- ui->emptyLabel->setVisible(true);
- } else {
- ui->vcard->setVisible(true);
- ui->emptyLabel->setVisible(false);
- }
- updateWindowSize();
+ ui->vcard->setVCard(vcard);
+ if (vcard->isEmpty()) {
+ ui->vcard->setVisible(false);
+ ui->emptyLabel->setVisible(true);
+ } else {
+ ui->vcard->setVisible(true);
+ ui->emptyLabel->setVisible(false);
+ }
+ updateWindowSize();
}
void QtProfileWindow::setEnabled(bool b) {
- ui->vcard->setEnabled(b);
- ui->savePushButton->setEnabled(b);
+ ui->vcard->setEnabled(b);
+ ui->savePushButton->setEnabled(b);
}
void QtProfileWindow::setEditable(bool b) {
- ui->throbberLabel->setVisible(b);
- ui->errorLabel->setVisible(b);
- ui->savePushButton->setVisible(b);
- ui->vcard->setEditable(b);
- updateTitle();
- updateWindowSize();
+ ui->throbberLabel->setVisible(b);
+ ui->errorLabel->setVisible(b);
+ ui->savePushButton->setVisible(b);
+ ui->vcard->setEditable(b);
+ updateTitle();
+ updateWindowSize();
}
void QtProfileWindow::setProcessing(bool processing) {
- if (processing) {
- ui->throbberLabel->movie()->start();
- ui->throbberLabel->show();
- ui->statusLabel->setVisible(true);
- ui->vcard->setVisible(false);
- }
- else {
- ui->throbberLabel->hide();
- ui->throbberLabel->movie()->stop();
- ui->statusLabel->setVisible(false);
- ui->vcard->setVisible(true);
- }
+ if (processing) {
+ ui->throbberLabel->movie()->start();
+ ui->throbberLabel->show();
+ ui->statusLabel->setVisible(true);
+ ui->vcard->setVisible(false);
+ }
+ else {
+ ui->throbberLabel->hide();
+ ui->throbberLabel->movie()->stop();
+ ui->statusLabel->setVisible(false);
+ ui->vcard->setVisible(true);
+ }
}
void QtProfileWindow::setError(const std::string& error) {
- if (!error.empty()) {
- ui->errorLabel->setText("<font color='red'>" + QtUtilities::htmlEscape(P2QSTRING(error)) + "</font>");
- }
- else {
- ui->errorLabel->setText("");
- }
+ if (!error.empty()) {
+ ui->errorLabel->setText("<font color='red'>" + QtUtilities::htmlEscape(P2QSTRING(error)) + "</font>");
+ }
+ else {
+ ui->errorLabel->setText("");
+ }
}
void QtProfileWindow::show() {
- QWidget::showNormal();
- QWidget::activateWindow();
- QWidget::raise();
+ QWidget::showNormal();
+ QWidget::activateWindow();
+ QWidget::raise();
}
void QtProfileWindow::hide() {
- QWidget::hide();
+ QWidget::hide();
}
QSize QtProfileWindow::sizeHint() const {
- return QWidget::sizeHint();
+ return QWidget::sizeHint();
}
void QtProfileWindow::updateTitle() {
- QString jidString;
- if (jid.isValid()) {
- jidString = QString(" ( %1 )").arg(P2QSTRING(jid.toString()));
- }
+ QString jidString;
+ if (jid.isValid()) {
+ jidString = QString(" ( %1 )").arg(P2QSTRING(jid.toString()));
+ }
- if (ui->vcard->isEditable()) {
- setWindowTitle(tr("Edit Profile") + jidString);
- } else {
- setWindowTitle(tr("Show Profile") + jidString);
- }
+ if (ui->vcard->isEditable()) {
+ setWindowTitle(tr("Edit Profile") + jidString);
+ } else {
+ setWindowTitle(tr("Show Profile") + jidString);
+ }
}
void QtProfileWindow::updateWindowSize() {
- // Delay resizing to the end of the event loop, because Qt calculates the correct layout asynchronously.
- // Qt will post LayoutRequests for widgets on the event loop on show and widgets will recaluclate their
- // layout as they process these events.
- // We use the complete and correct size hint from the freshly calculated layout by delaying execution of
- // the resize code to the end of Qt's event loop.
- if (!adjustSizeTimer.isActive()) {
- adjustSizeTimer.start(0);
- }
+ // Delay resizing to the end of the event loop, because Qt calculates the correct layout asynchronously.
+ // Qt will post LayoutRequests for widgets on the event loop on show and widgets will recaluclate their
+ // layout as they process these events.
+ // We use the complete and correct size hint from the freshly calculated layout by delaying execution of
+ // the resize code to the end of Qt's event loop.
+ if (!adjustSizeTimer.isActive()) {
+ adjustSizeTimer.start(0);
+ }
}
void QtProfileWindow::closeEvent(QCloseEvent* event) {
- event->accept();
- onWindowAboutToBeClosed(jid);
+ event->accept();
+ onWindowAboutToBeClosed(jid);
}
void QtProfileWindow::handleSave() {
- onVCardChangeRequest(ui->vcard->getVCard());
+ onVCardChangeRequest(ui->vcard->getVCard());
}
void QtProfileWindow::handleAdjustSizeTimeout() {
- // Force recaluclation of all layout geometry in children widgets.
- // This is required on Windows to have the correct size even on first show.
- QList<QWidget *> children = findChildren<QWidget*>();
- foreach(QWidget* child, children) {
- child->updateGeometry();
- }
-
- updateGeometry();
- adjustSize();
+ // Force recaluclation of all layout geometry in children widgets.
+ // This is required on Windows to have the correct size even on first show.
+ QList<QWidget *> children = findChildren<QWidget*>();
+ for (auto child : children) {
+ child->updateGeometry();
+ }
+
+ updateGeometry();
+ adjustSize();
}
}
diff --git a/Swift/QtUI/QtProfileWindow.h b/Swift/QtUI/QtProfileWindow.h
index 0821444..7315807 100644
--- a/Swift/QtUI/QtProfileWindow.h
+++ b/Swift/QtUI/QtProfileWindow.h
@@ -20,44 +20,44 @@
#include <Swift/Controllers/UIInterfaces/ProfileWindow.h>
namespace Ui {
- class QtProfileWindow;
+ class QtProfileWindow;
}
namespace Swift {
class QtProfileWindow : public QWidget, public ProfileWindow {
- Q_OBJECT
+ Q_OBJECT
- public:
- QtProfileWindow();
- virtual ~QtProfileWindow();
+ public:
+ QtProfileWindow();
+ virtual ~QtProfileWindow();
- virtual void setJID(const JID& jid);
- virtual void setVCard(VCard::ref vcard);
+ virtual void setJID(const JID& jid);
+ virtual void setVCard(VCard::ref vcard);
- virtual void setEnabled(bool b);
- virtual void setProcessing(bool processing);
- virtual void setError(const std::string& error);
- virtual void setEditable(bool b);
+ virtual void setEnabled(bool b);
+ virtual void setProcessing(bool processing);
+ virtual void setError(const std::string& error);
+ virtual void setEditable(bool b);
- virtual void show();
- virtual void hide();
+ virtual void show();
+ virtual void hide();
- virtual QSize sizeHint() const;
+ virtual QSize sizeHint() const;
- private:
- void updateTitle();
- void updateWindowSize();
- virtual void closeEvent(QCloseEvent* event);
+ private:
+ void updateTitle();
+ void updateWindowSize();
+ virtual void closeEvent(QCloseEvent* event);
- private slots:
- void handleSave();
- void handleAdjustSizeTimeout();
+ private slots:
+ void handleSave();
+ void handleAdjustSizeTimeout();
- private:
- Ui::QtProfileWindow* ui;
- JID jid;
- QTimer adjustSizeTimer;
+ private:
+ Ui::QtProfileWindow* ui;
+ JID jid;
+ QTimer adjustSizeTimer;
};
}
diff --git a/Swift/QtUI/QtResourceHelper.cpp b/Swift/QtUI/QtResourceHelper.cpp
index f76c438..a802b19 100644
--- a/Swift/QtUI/QtResourceHelper.cpp
+++ b/Swift/QtUI/QtResourceHelper.cpp
@@ -9,16 +9,16 @@
namespace Swift {
QString statusShowTypeToIconPath(StatusShow::Type type) {
- QString iconString;
- switch (type) {
- case StatusShow::Online: iconString = "online";break;
- case StatusShow::Away: iconString = "away";break;
- case StatusShow::XA: iconString = "away";break;
- case StatusShow::FFC: iconString = "online";break;
- case StatusShow::DND: iconString = "dnd";break;
- case StatusShow::None: iconString = "offline";break;
- }
- return QString(":/icons/%1.png").arg(iconString);
+ QString iconString;
+ switch (type) {
+ case StatusShow::Online: iconString = "online";break;
+ case StatusShow::Away: iconString = "away";break;
+ case StatusShow::XA: iconString = "away";break;
+ case StatusShow::FFC: iconString = "online";break;
+ case StatusShow::DND: iconString = "dnd";break;
+ case StatusShow::None: iconString = "offline";break;
+ }
+ return QString(":/icons/%1.png").arg(iconString);
}
}
diff --git a/Swift/QtUI/QtRosterHeader.cpp b/Swift/QtUI/QtRosterHeader.cpp
index 1a973c0..b405d10 100644
--- a/Swift/QtUI/QtRosterHeader.cpp
+++ b/Swift/QtUI/QtRosterHeader.cpp
@@ -1,13 +1,12 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtRosterHeader.h"
+#include <Swift/QtUI/QtRosterHeader.h>
#include <QBitmap>
-#include <qdebug.h>
#include <QFileInfo>
#include <QHBoxLayout>
#include <QHelpEvent>
@@ -18,121 +17,123 @@
#include <QToolTip>
#include <QVBoxLayout>
-#include "QtStatusWidget.h"
-#include <Swift/QtUI/QtElidingLabel.h>
+#include <qdebug.h>
+
#include <Swift/QtUI/QtClickableLabel.h>
+#include <Swift/QtUI/QtElidingLabel.h>
#include <Swift/QtUI/QtNameWidget.h>
+#include <Swift/QtUI/QtScaledAvatarCache.h>
+#include <Swift/QtUI/QtStatusWidget.h>
#include <Swift/QtUI/Roster/RosterTooltip.h>
-#include "QtScaledAvatarCache.h"
namespace Swift {
-QtRosterHeader::QtRosterHeader(SettingsProvider* settings, StatusCache* statusCache, QWidget* parent) : QWidget(parent), statusEdit_(NULL) {
- QHBoxLayout* topLayout = new QHBoxLayout();
- topLayout->setSpacing(3);
- topLayout->setContentsMargins(4,4,4,4);
- setLayout(topLayout);
- setMinimumHeight(50);
- setMaximumHeight(50);
-
- avatarLabel_ = new QtClickableLabel(this);
- avatarLabel_->setMinimumSize(avatarSize_, avatarSize_);
- avatarLabel_->setMaximumSize(avatarSize_, avatarSize_);
- avatarLabel_->setAlignment(Qt::AlignCenter);
- setAvatar(":/icons/avatar.png");
- avatarLabel_->setScaledContents(false);
- topLayout->addWidget(avatarLabel_);
- connect(avatarLabel_, SIGNAL(clicked()), this, SIGNAL(onEditProfileRequest()));
-
- QVBoxLayout* rightLayout = new QVBoxLayout();
- rightLayout->setSpacing(4);
- rightLayout->setContentsMargins(4,0,0,0);
- topLayout->addLayout(rightLayout);
-
- QHBoxLayout* nameAndSecurityLayout = new QHBoxLayout();
- nameAndSecurityLayout->setContentsMargins(4,0,0,0);
-
- nameWidget_ = new QtNameWidget(settings, this);
- connect(nameWidget_, SIGNAL(onChangeNickRequest()), this, SIGNAL(onEditProfileRequest()));
- nameAndSecurityLayout->addWidget(nameWidget_);
-
- securityInfoButton_ = new QToolButton(this);
- securityInfoButton_->setStyleSheet("QToolButton { border: none; } QToolButton:hover { border: 1px solid #bebebe; } QToolButton:pressed { border: 1px solid #757575; background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #777777, stop: 1 #d4d4d4);}");
- //securityInfoButton_->setAutoRaise(true);
- securityInfoButton_->setIcon(QIcon(":/icons/lock.png"));
- securityInfoButton_->setToolTip(tr("Connection is secured"));
- connect(securityInfoButton_, SIGNAL(clicked()), this, SIGNAL(onShowCertificateInfo()));
- nameAndSecurityLayout->addWidget(securityInfoButton_);
-
- rightLayout->addLayout(nameAndSecurityLayout);
-
- statusWidget_ = new QtStatusWidget(statusCache, this);
- connect(statusWidget_, SIGNAL(onChangeStatusRequest(StatusShow::Type, const QString&)), this, SLOT(handleChangeStatusRequest(StatusShow::Type, const QString&)));
- rightLayout->addWidget(statusWidget_);
-
- show();
+QtRosterHeader::QtRosterHeader(SettingsProvider* settings, StatusCache* statusCache, QWidget* parent) : QWidget(parent), statusEdit_(nullptr) {
+ QHBoxLayout* topLayout = new QHBoxLayout();
+ topLayout->setSpacing(3);
+ topLayout->setContentsMargins(4,4,4,4);
+ setLayout(topLayout);
+ setMinimumHeight(50);
+ setMaximumHeight(50);
+
+ avatarLabel_ = new QtClickableLabel(this);
+ avatarLabel_->setMinimumSize(avatarSize_, avatarSize_);
+ avatarLabel_->setMaximumSize(avatarSize_, avatarSize_);
+ avatarLabel_->setAlignment(Qt::AlignCenter);
+ setAvatar(":/icons/avatar.png");
+ avatarLabel_->setScaledContents(false);
+ topLayout->addWidget(avatarLabel_);
+ connect(avatarLabel_, SIGNAL(clicked()), this, SIGNAL(onEditProfileRequest()));
+
+ QVBoxLayout* rightLayout = new QVBoxLayout();
+ rightLayout->setSpacing(4);
+ rightLayout->setContentsMargins(4,0,0,0);
+ topLayout->addLayout(rightLayout);
+
+ QHBoxLayout* nameAndSecurityLayout = new QHBoxLayout();
+ nameAndSecurityLayout->setContentsMargins(4,0,0,0);
+
+ nameWidget_ = new QtNameWidget(settings, this);
+ connect(nameWidget_, SIGNAL(onChangeNickRequest()), this, SIGNAL(onEditProfileRequest()));
+ nameAndSecurityLayout->addWidget(nameWidget_);
+
+ securityInfoButton_ = new QToolButton(this);
+ securityInfoButton_->setStyleSheet("QToolButton { border: none; } QToolButton:hover { border: 1px solid #bebebe; } QToolButton:pressed { border: 1px solid #757575; background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #777777, stop: 1 #d4d4d4);}");
+ //securityInfoButton_->setAutoRaise(true);
+ securityInfoButton_->setIcon(QIcon(":/icons/lock.png"));
+ securityInfoButton_->setToolTip(tr("Connection is secured"));
+ connect(securityInfoButton_, SIGNAL(clicked()), this, SIGNAL(onShowCertificateInfo()));
+ nameAndSecurityLayout->addWidget(securityInfoButton_);
+
+ rightLayout->addLayout(nameAndSecurityLayout);
+
+ statusWidget_ = new QtStatusWidget(statusCache, this);
+ connect(statusWidget_, SIGNAL(onChangeStatusRequest(StatusShow::Type, const QString&)), this, SLOT(handleChangeStatusRequest(StatusShow::Type, const QString&)));
+ rightLayout->addWidget(statusWidget_);
+
+ show();
}
void QtRosterHeader::handleChangeStatusRequest(StatusShow::Type type, const QString& text) {
- emit onChangeStatusRequest(type, text);
+ emit onChangeStatusRequest(type, text);
}
void QtRosterHeader::setStatusText(const QString& statusMessage) {
- statusWidget_->setStatusText(statusMessage);
+ statusWidget_->setStatusText(statusMessage);
}
void QtRosterHeader::setStatusType(StatusShow::Type type) {
- statusWidget_->setStatusType(type);
- if (type == StatusShow::None) {
- nameWidget_->setOnline(false);
- disconnect(avatarLabel_, SIGNAL(clicked()), this, SIGNAL(onEditProfileRequest()));
- }
- else {
- nameWidget_->setOnline(true);
- connect(avatarLabel_, SIGNAL(clicked()), this, SIGNAL(onEditProfileRequest()), Qt::UniqueConnection);
- }
+ statusWidget_->setStatusType(type);
+ if (type == StatusShow::None) {
+ nameWidget_->setOnline(false);
+ disconnect(avatarLabel_, SIGNAL(clicked()), this, SIGNAL(onEditProfileRequest()));
+ }
+ else {
+ nameWidget_->setOnline(true);
+ connect(avatarLabel_, SIGNAL(clicked()), this, SIGNAL(onEditProfileRequest()), Qt::UniqueConnection);
+ }
}
void QtRosterHeader::setConnecting() {
- statusWidget_->setConnecting();
+ statusWidget_->setConnecting();
}
void QtRosterHeader::setStreamEncryptionStatus(bool tlsInPlace) {
- securityInfoButton_->setVisible(tlsInPlace);
+ securityInfoButton_->setVisible(tlsInPlace);
}
bool QtRosterHeader::event(QEvent* event) {
- if (event->type() == QEvent::ToolTip) {
- QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
- QtScaledAvatarCache scaledAvatarCache(avatarSize_);
- QString text = RosterTooltip::buildDetailedTooltip(contact_.get(), &scaledAvatarCache);
- QToolTip::showText(helpEvent->globalPos(), text);
- return true;
- }
- return QWidget::event(event);
+ if (event->type() == QEvent::ToolTip) {
+ QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
+ QtScaledAvatarCache scaledAvatarCache(avatarSize_);
+ QString text = RosterTooltip::buildDetailedTooltip(contact_.get(), &scaledAvatarCache);
+ QToolTip::showText(helpEvent->globalPos(), text);
+ return true;
+ }
+ return QWidget::event(event);
}
void QtRosterHeader::setAvatar(const QString& path) {
- QString scaledAvatarPath = QtScaledAvatarCache(avatarSize_).getScaledAvatarPath(path);
- QPixmap avatar;
- if (QFileInfo(scaledAvatarPath).exists()) {
- avatar.load(scaledAvatarPath);
- }
- else {
- avatar = QPixmap(":/icons/avatar.png").scaled(avatarSize_, avatarSize_, Qt::KeepAspectRatio, Qt::SmoothTransformation);
- }
- avatarLabel_->setPixmap(avatar);
+ QString scaledAvatarPath = QtScaledAvatarCache(avatarSize_).getScaledAvatarPath(path);
+ QPixmap avatar;
+ if (QFileInfo(scaledAvatarPath).exists()) {
+ avatar.load(scaledAvatarPath);
+ }
+ else {
+ avatar = QPixmap(":/icons/avatar.svg").scaled(avatarSize_, avatarSize_, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ }
+ avatarLabel_->setPixmap(avatar);
}
void QtRosterHeader::setNick(const QString& nick) {
- nameWidget_->setNick(nick);
+ nameWidget_->setNick(nick);
}
-void QtRosterHeader::setContactRosterItem(boost::shared_ptr<ContactRosterItem> contact) {
- contact_ = contact;
+void QtRosterHeader::setContactRosterItem(std::shared_ptr<ContactRosterItem> contact) {
+ contact_ = contact;
}
void QtRosterHeader::setJID(const QString& jid) {
- nameWidget_->setJID(jid);
+ nameWidget_->setJID(jid);
}
diff --git a/Swift/QtUI/QtRosterHeader.h b/Swift/QtUI/QtRosterHeader.h
index f9983a2..8370eb5 100644
--- a/Swift/QtUI/QtRosterHeader.h
+++ b/Swift/QtUI/QtRosterHeader.h
@@ -1,64 +1,66 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <QWidget>
+#include <string>
+
#include <QLabel>
#include <QPixmap>
#include <QSize>
#include <QToolButton>
+#include <QWidget>
-#include <string>
#include <Swiften/Elements/StatusShow.h>
#include <Swiften/Elements/VCard.h>
+
#include <Swift/Controllers/Roster/ContactRosterItem.h>
-#include "QtTextEdit.h"
+#include <Swift/QtUI/QtTextEdit.h>
class QHBoxLayout;
namespace Swift {
- class QtClickableLabel;
- class QtStatusWidget;
- class QtNameWidget;
- class SettingsProvider;
- class StatusCache;
-
- class QtRosterHeader : public QWidget {
- Q_OBJECT
- public:
- QtRosterHeader(SettingsProvider* settings, StatusCache* statusCache, QWidget* parent = NULL);
- void setAvatar(const QString& path);
+ class QtClickableLabel;
+ class QtStatusWidget;
+ class QtNameWidget;
+ class SettingsProvider;
+ class StatusCache;
+
+ class QtRosterHeader : public QWidget {
+ Q_OBJECT
+ public:
+ QtRosterHeader(SettingsProvider* settings, StatusCache* statusCache, QWidget* parent = nullptr);
+ void setAvatar(const QString& path);
- void setJID(const QString& jid);
- void setNick(const QString& nick);
- void setContactRosterItem(boost::shared_ptr<ContactRosterItem> contact);
+ void setJID(const QString& jid);
+ void setNick(const QString& nick);
+ void setContactRosterItem(std::shared_ptr<ContactRosterItem> contact);
- void setStatusText(const QString& statusMessage);
- void setStatusType(StatusShow::Type type);
- void setConnecting();
- void setStreamEncryptionStatus(bool tlsInPlace);
- private:
- bool event(QEvent* event);
- signals:
- void onChangeStatusRequest(StatusShow::Type showType, const QString &statusMessage);
- void onEditProfileRequest();
- void onShowCertificateInfo();
+ void setStatusText(const QString& statusMessage);
+ void setStatusType(StatusShow::Type type);
+ void setConnecting();
+ void setStreamEncryptionStatus(bool tlsInPlace);
+ private:
+ bool event(QEvent* event);
+ signals:
+ void onChangeStatusRequest(StatusShow::Type showType, const QString &statusMessage);
+ void onEditProfileRequest();
+ void onShowCertificateInfo();
- private slots:
- void handleChangeStatusRequest(StatusShow::Type type, const QString &statusMessage);
- private:
- QString name_;
- QtClickableLabel* avatarLabel_;
- QtNameWidget* nameWidget_;
- QtTextEdit* statusEdit_;
- QtStatusWidget* statusWidget_;
- QToolButton* securityInfoButton_;
- static const int avatarSize_;
- boost::shared_ptr<ContactRosterItem> contact_;
- };
+ private slots:
+ void handleChangeStatusRequest(StatusShow::Type type, const QString &statusMessage);
+ private:
+ QString name_;
+ QtClickableLabel* avatarLabel_;
+ QtNameWidget* nameWidget_;
+ QtTextEdit* statusEdit_;
+ QtStatusWidget* statusWidget_;
+ QToolButton* securityInfoButton_;
+ static const int avatarSize_;
+ std::shared_ptr<ContactRosterItem> contact_;
+ };
}
diff --git a/Swift/QtUI/QtScaledAvatarCache.cpp b/Swift/QtUI/QtScaledAvatarCache.cpp
index ec826dc..37ea6a9 100644
--- a/Swift/QtUI/QtScaledAvatarCache.cpp
+++ b/Swift/QtUI/QtScaledAvatarCache.cpp
@@ -1,61 +1,88 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtScaledAvatarCache.h"
+#include <Swift/QtUI/QtScaledAvatarCache.h>
-#include <QFileInfo>
+#include <QByteArray>
#include <QDir>
-#include <QPixmap>
+#include <QFileInfo>
#include <QImage>
#include <QImageReader>
#include <QPainter>
-#include <QByteArray>
+#include <QPixmap>
#include <Swiften/Base/Log.h>
+
#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
+namespace {
+ // This number needs to be incremented whenever the avatar scaling procedure changes.
+ const int QT_SCALED_AVATAR_CACHE_VERSION = 1;
+}
+
QtScaledAvatarCache::QtScaledAvatarCache(int size) : size(size) {
}
+static QPixmap cropToBiggestCenteredSquare(const QPixmap& input) {
+ QPixmap squareCropped;
+ if (input.width() != input.height()) {
+ QRect centeredSquare;
+ if (input.width() > input.height()) {
+ int x = (input.width() - input.height()) / 2;
+ centeredSquare = QRect(x, 0, input.height(), input.height());
+ }
+ else {
+ int y = (input.height() - input.width()) / 2;
+ centeredSquare = QRect(0, y, input.width(), input.width());
+ }
+ squareCropped = input.copy(centeredSquare);
+ }
+ else {
+ squareCropped = input;
+ }
+ return squareCropped;
+}
+
QString QtScaledAvatarCache::getScaledAvatarPath(const QString& path) {
- QFileInfo avatarFile(path);
- if (avatarFile.exists()) {
- if (!avatarFile.dir().exists(QString::number(size))) {
- if (!avatarFile.dir().mkdir(QString::number(size))) {
- return path;
- }
- }
- QDir targetDir(avatarFile.dir().absoluteFilePath(QString::number(size)));
- QString targetFile = targetDir.absoluteFilePath(avatarFile.baseName());
- if (!QFileInfo(targetFile).exists()) {
- QPixmap avatarPixmap;
- if (avatarPixmap.load(path)) {
- QPixmap maskedAvatar(avatarPixmap.size());
- maskedAvatar.fill(QColor(0, 0, 0, 0));
- QPainter maskPainter(&maskedAvatar);
- maskPainter.setBrush(Qt::black);
- maskPainter.drawRoundedRect(maskedAvatar.rect(), 25.0, 25.0, Qt::RelativeSize);
- maskPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
- maskPainter.drawPixmap(0, 0, avatarPixmap);
- maskPainter.end();
-
- if (!maskedAvatar.scaled(size, size, Qt::KeepAspectRatio, Qt::SmoothTransformation).save(targetFile, "PNG")) {
- return path;
- }
- } else {
- SWIFT_LOG(debug) << "Failed to load " << Q2PSTRING(path) << std::endl;
- }
- }
- return targetFile;
- }
- else {
- return path;
- }
+ QFileInfo avatarFile(path);
+ if (avatarFile.exists() && !avatarFile.absolutePath().startsWith(":/")) {
+ QString cacheSubPath = QString("ScaledAvatarCacheV%1/%2").arg(QString::number(QT_SCALED_AVATAR_CACHE_VERSION), QString::number(size));
+ if (!avatarFile.dir().mkpath(cacheSubPath)) {
+ SWIFT_LOG(error) << "avatarFile.dir(): " << Q2PSTRING(avatarFile.dir().absolutePath()) << std::endl;
+ SWIFT_LOG(error) << "Failed creating cache folder: " << Q2PSTRING(cacheSubPath) << std::endl;
+ return path;
+ }
+ QDir targetDir(avatarFile.dir().absoluteFilePath(cacheSubPath));
+ QString targetFile = targetDir.absoluteFilePath(avatarFile.baseName());
+ if (!QFileInfo(targetFile).exists()) {
+ QPixmap avatarPixmap;
+ if (avatarPixmap.load(path)) {
+ QPixmap squaredAvatarPixmap = cropToBiggestCenteredSquare(avatarPixmap);
+ QPixmap maskedAvatar(squaredAvatarPixmap.size());
+ maskedAvatar.fill(QColor(0, 0, 0, 0));
+ QPainter maskPainter(&maskedAvatar);
+ maskPainter.setBrush(Qt::black);
+ maskPainter.drawRoundedRect(maskedAvatar.rect(), 25.0, 25.0, Qt::RelativeSize);
+ maskPainter.setCompositionMode(QPainter::CompositionMode_SourceIn);
+ maskPainter.drawPixmap(0, 0, squaredAvatarPixmap);
+ maskPainter.end();
+ if (!maskedAvatar.scaled(size, size, Qt::KeepAspectRatio, Qt::SmoothTransformation).save(targetFile, "PNG")) {
+ return path;
+ }
+ } else {
+ SWIFT_LOG(warning) << "Failed to load " << Q2PSTRING(path) << std::endl;
+ }
+ }
+ return targetFile;
+ }
+ else {
+ return path;
+ }
}
diff --git a/Swift/QtUI/QtScaledAvatarCache.h b/Swift/QtUI/QtScaledAvatarCache.h
index 535c5e1..748fb40 100644
--- a/Swift/QtUI/QtScaledAvatarCache.h
+++ b/Swift/QtUI/QtScaledAvatarCache.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,16 +7,17 @@
#pragma once
#include <string>
+
#include <QString>
namespace Swift {
- class QtScaledAvatarCache {
- public:
- QtScaledAvatarCache(int size);
+ class QtScaledAvatarCache {
+ public:
+ QtScaledAvatarCache(int size);
- QString getScaledAvatarPath(const QString& path);
+ QString getScaledAvatarPath(const QString& path);
- private:
- int size;
- };
+ private:
+ int size;
+ };
}
diff --git a/Swift/QtUI/QtSettingsProvider.cpp b/Swift/QtUI/QtSettingsProvider.cpp
index b76a6d5..42ac22d 100644
--- a/Swift/QtUI/QtSettingsProvider.cpp
+++ b/Swift/QtUI/QtSettingsProvider.cpp
@@ -1,13 +1,13 @@
/*
- * Copyright (c) 2010-2012 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include <QtSettingsProvider.h>
+#include <Swift/QtUI/QtSettingsProvider.h>
-#include <QStringList>
#include <QFile>
+#include <QStringList>
namespace Swift {
@@ -19,105 +19,105 @@ QtSettingsProvider::~QtSettingsProvider() {
}
bool QtSettingsProvider::hasSetting(const std::string& key) {
- return !settings_.value(key.c_str()).isNull();
+ return !settings_.value(key.c_str()).isNull();
}
std::string QtSettingsProvider::getSetting(const Setting<std::string>& setting) {
- QVariant variant = settings_.value(setting.getKey().c_str());
- return variant.isNull() ? setting.getDefaultValue() : std::string(variant.toString().toUtf8());
+ QVariant variant = settings_.value(setting.getKey().c_str());
+ return variant.isNull() ? setting.getDefaultValue() : std::string(variant.toString().toUtf8());
}
void QtSettingsProvider::storeSetting(const Setting<std::string>& setting, const std::string& settingValue) {
- bool changed = false;
- if (getSetting(setting) != settingValue) {
- changed = true;
- }
- settings_.setValue(setting.getKey().c_str(), settingValue.c_str());
- if (changed) {
- onSettingChanged(setting.getKey());
- }
- updatePermissions();
+ bool changed = false;
+ if (getSetting(setting) != settingValue) {
+ changed = true;
+ }
+ settings_.setValue(setting.getKey().c_str(), settingValue.c_str());
+ if (changed) {
+ onSettingChanged(setting.getKey());
+ }
+ updatePermissions();
}
bool QtSettingsProvider::getSetting(const Setting<bool>& setting) {
- QVariant variant = settings_.value(setting.getKey().c_str());
- return variant.isNull() ? setting.getDefaultValue() : variant.toBool();
+ QVariant variant = settings_.value(setting.getKey().c_str());
+ return variant.isNull() ? setting.getDefaultValue() : variant.toBool();
}
void QtSettingsProvider::storeSetting(const Setting<bool>& setting, const bool& settingValue) {
- bool changed = false;
- if (getSetting(setting) != settingValue) {
- changed = true;
- }
- settings_.setValue(setting.getKey().c_str(), settingValue);
- if (changed) {
- onSettingChanged(setting.getKey());
- }
- updatePermissions();
+ bool changed = false;
+ if (getSetting(setting) != settingValue) {
+ changed = true;
+ }
+ settings_.setValue(setting.getKey().c_str(), settingValue);
+ if (changed) {
+ onSettingChanged(setting.getKey());
+ }
+ updatePermissions();
}
int QtSettingsProvider::getSetting(const Setting<int>& setting) {
- QVariant variant = settings_.value(setting.getKey().c_str());
- return variant.isNull() ? setting.getDefaultValue() : variant.toInt();
+ QVariant variant = settings_.value(setting.getKey().c_str());
+ return variant.isNull() ? setting.getDefaultValue() : variant.toInt();
}
void QtSettingsProvider::storeSetting(const Setting<int>& setting, const int& settingValue) {
- bool changed = false;
- if (getSetting(setting) != settingValue) {
- changed = true;
- }
- settings_.setValue(setting.getKey().c_str(), settingValue);
- if (changed) {
- onSettingChanged(setting.getKey());
- }
- updatePermissions();
+ bool changed = false;
+ if (getSetting(setting) != settingValue) {
+ changed = true;
+ }
+ settings_.setValue(setting.getKey().c_str(), settingValue);
+ if (changed) {
+ onSettingChanged(setting.getKey());
+ }
+ updatePermissions();
}
std::vector<std::string> QtSettingsProvider::getAvailableProfiles() {
- std::vector<std::string> profiles;
- QVariant profilesVariant = settings_.value("profileList");
- foreach(QString profileQString, profilesVariant.toStringList()) {
- profiles.push_back(std::string(profileQString.toUtf8()));
- }
- return profiles;
+ std::vector<std::string> profiles;
+ QVariant profilesVariant = settings_.value("profileList");
+ for (const auto& profileQString : profilesVariant.toStringList()) {
+ profiles.push_back(std::string(profileQString.toUtf8()));
+ }
+ return profiles;
}
void QtSettingsProvider::createProfile(const std::string& profile) {
- QStringList stringList = settings_.value("profileList").toStringList();
- stringList.append(profile.c_str());
- settings_.setValue("profileList", stringList);
- updatePermissions();
+ QStringList stringList = settings_.value("profileList").toStringList();
+ stringList.append(profile.c_str());
+ settings_.setValue("profileList", stringList);
+ updatePermissions();
}
void QtSettingsProvider::removeProfile(const std::string& profile) {
- QString profileStart(QString(profile.c_str()) + ":");
- foreach (QString key, settings_.allKeys()) {
- if (key.startsWith(profileStart)) {
- settings_.remove(key);
- }
- }
- QStringList stringList = settings_.value("profileList").toStringList();
- stringList.removeAll(profile.c_str());
- settings_.setValue("profileList", stringList);
- updatePermissions();
+ QString profileStart(QString(profile.c_str()) + ":");
+ for (auto&& key : settings_.allKeys()) {
+ if (key.startsWith(profileStart)) {
+ settings_.remove(key);
+ }
+ }
+ QStringList stringList = settings_.value("profileList").toStringList();
+ stringList.removeAll(profile.c_str());
+ settings_.setValue("profileList", stringList);
+ updatePermissions();
}
QSettings* QtSettingsProvider::getQSettings() {
- return &settings_;
+ return &settings_;
}
void QtSettingsProvider::updatePermissions() {
#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
- QFile file(settings_.fileName());
- if (file.exists()) {
- file.setPermissions(QFile::ReadOwner|QFile::WriteOwner);
- }
+ QFile file(settings_.fileName());
+ if (file.exists()) {
+ file.setPermissions(QFile::ReadOwner|QFile::WriteOwner);
+ }
#endif
}
bool QtSettingsProvider::getIsSettingFinal(const std::string& /*settingPath*/) {
- return false;
+ return false;
}
}
diff --git a/Swift/QtUI/QtSettingsProvider.h b/Swift/QtUI/QtSettingsProvider.h
index 128eefb..21e9211 100644
--- a/Swift/QtUI/QtSettingsProvider.h
+++ b/Swift/QtUI/QtSettingsProvider.h
@@ -1,40 +1,40 @@
/*
- * Copyright (c) 2010-2012 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swift/Controllers/Settings/SettingsProvider.h>
-
#include <QSettings>
+#include <Swift/Controllers/Settings/SettingsProvider.h>
+
namespace Swift {
class QtSettingsProvider : public SettingsProvider {
- public:
- QtSettingsProvider();
- virtual ~QtSettingsProvider();
- virtual std::string getSetting(const Setting<std::string>& setting);
- virtual void storeSetting(const Setting<std::string>& setting, const std::string& value);
- virtual bool getSetting(const Setting<bool>& setting);
- virtual void storeSetting(const Setting<bool>& setting, const bool& value);
- virtual int getSetting(const Setting<int>& setting);
- virtual void storeSetting(const Setting<int>& setting, const int& value);
- virtual std::vector<std::string> getAvailableProfiles();
- virtual void createProfile(const std::string& profile);
- virtual void removeProfile(const std::string& profile);
- virtual bool hasSetting(const std::string& key);
- QSettings* getQSettings();
- protected:
- virtual bool getIsSettingFinal(const std::string& settingPath);
-
- private:
- void updatePermissions();
-
- private:
- QSettings settings_;
+ public:
+ QtSettingsProvider();
+ virtual ~QtSettingsProvider();
+ virtual std::string getSetting(const Setting<std::string>& setting);
+ virtual void storeSetting(const Setting<std::string>& setting, const std::string& value);
+ virtual bool getSetting(const Setting<bool>& setting);
+ virtual void storeSetting(const Setting<bool>& setting, const bool& value);
+ virtual int getSetting(const Setting<int>& setting);
+ virtual void storeSetting(const Setting<int>& setting, const int& value);
+ virtual std::vector<std::string> getAvailableProfiles();
+ virtual void createProfile(const std::string& profile);
+ virtual void removeProfile(const std::string& profile);
+ virtual bool hasSetting(const std::string& key);
+ QSettings* getQSettings();
+ protected:
+ virtual bool getIsSettingFinal(const std::string& settingPath);
+
+ private:
+ void updatePermissions();
+
+ private:
+ QSettings settings_;
};
}
diff --git a/Swift/QtUI/QtSingleWindow.cpp b/Swift/QtUI/QtSingleWindow.cpp
index 0acd081..1fba497 100644
--- a/Swift/QtUI/QtSingleWindow.cpp
+++ b/Swift/QtUI/QtSingleWindow.cpp
@@ -1,15 +1,13 @@
/*
- * Copyright (c) 2010-2012 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/QtSingleWindow.h>
-
-#include <Swiften/Base/foreach.h>
-#include <Swift/QtUI/QtSettingsProvider.h>
#include <Swift/QtUI/QtChatTabs.h>
+#include <Swift/QtUI/QtSettingsProvider.h>
namespace Swift {
@@ -17,13 +15,13 @@ static const QString SINGLE_WINDOW_GEOMETRY = QString("SINGLE_WINDOW_GEOMETRY");
static const QString SINGLE_WINDOW_SPLITS = QString("SINGLE_WINDOW_SPLITS");
QtSingleWindow::QtSingleWindow(QtSettingsProvider* settings) : QSplitter() {
- settings_ = settings;
- QVariant geometryVariant = settings_->getQSettings()->value(SINGLE_WINDOW_GEOMETRY);
- if (geometryVariant.isValid()) {
- restoreGeometry(geometryVariant.toByteArray());
- }
- connect(this, SIGNAL(splitterMoved(int, int)), this, SLOT(handleSplitterMoved(int, int)));
- restoreSplitters();
+ settings_ = settings;
+ QVariant geometryVariant = settings_->getQSettings()->value(SINGLE_WINDOW_GEOMETRY);
+ if (geometryVariant.isValid()) {
+ restoreGeometry(geometryVariant.toByteArray());
+ }
+ connect(this, SIGNAL(splitterMoved(int, int)), this, SLOT(handleSplitterMoved(int, int)));
+ restoreSplitters();
}
QtSingleWindow::~QtSingleWindow() {
@@ -31,51 +29,51 @@ QtSingleWindow::~QtSingleWindow() {
}
void QtSingleWindow::addWidget(QWidget* widget) {
- QtChatTabs* tabs = dynamic_cast<QtChatTabs*>(widget);
- if (tabs) {
- connect(tabs, SIGNAL(onTitleChanged(const QString&)), this, SLOT(handleTabsTitleChanged(const QString&)));
- }
- QSplitter::addWidget(widget);
+ QtChatTabs* tabs = dynamic_cast<QtChatTabs*>(widget);
+ if (tabs) {
+ connect(tabs, SIGNAL(onTitleChanged(const QString&)), this, SLOT(handleTabsTitleChanged(const QString&)));
+ }
+ QSplitter::addWidget(widget);
}
void QtSingleWindow::handleTabsTitleChanged(const QString& title) {
- setWindowTitle(title);
+ setWindowTitle(title);
}
void QtSingleWindow::handleSplitterMoved(int, int) {
- QList<QVariant> variantValues;
- QList<int> intValues = sizes();
- foreach (int value, intValues) {
- variantValues.append(QVariant(value));
- }
- settings_->getQSettings()->setValue(SINGLE_WINDOW_SPLITS, QVariant(variantValues));
+ QList<QVariant> variantValues;
+ QList<int> intValues = sizes();
+ for (const auto& value : intValues) {
+ variantValues.append(QVariant(value));
+ }
+ settings_->getQSettings()->setValue(SINGLE_WINDOW_SPLITS, QVariant(variantValues));
}
void QtSingleWindow::restoreSplitters() {
- QList<QVariant> variantValues = settings_->getQSettings()->value(SINGLE_WINDOW_SPLITS).toList();
- QList<int> intValues;
- foreach (QVariant value, variantValues) {
- intValues.append(value.toInt());
- }
- setSizes(intValues);
+ QList<QVariant> variantValues = settings_->getQSettings()->value(SINGLE_WINDOW_SPLITS).toList();
+ QList<int> intValues;
+ for (auto&& value : variantValues) {
+ intValues.append(value.toInt());
+ }
+ setSizes(intValues);
}
void QtSingleWindow::insertAtFront(QWidget* widget) {
- insertWidget(0, widget);
- restoreSplitters();
+ insertWidget(0, widget);
+ restoreSplitters();
}
void QtSingleWindow::handleGeometryChanged() {
- settings_->getQSettings()->setValue(SINGLE_WINDOW_GEOMETRY, saveGeometry());
-
+ settings_->getQSettings()->setValue(SINGLE_WINDOW_GEOMETRY, saveGeometry());
}
-void QtSingleWindow::resizeEvent(QResizeEvent*) {
- handleGeometryChanged();
+void QtSingleWindow::resizeEvent(QResizeEvent* event) {
+ handleGeometryChanged();
+ QSplitter::resizeEvent(event);
}
void QtSingleWindow::moveEvent(QMoveEvent*) {
- handleGeometryChanged();
+ handleGeometryChanged();
}
}
diff --git a/Swift/QtUI/QtSingleWindow.h b/Swift/QtUI/QtSingleWindow.h
index e430c56..804be65 100644
--- a/Swift/QtUI/QtSingleWindow.h
+++ b/Swift/QtUI/QtSingleWindow.h
@@ -9,29 +9,29 @@
#include <QSplitter>
namespace Swift {
- class QtSettingsProvider;
-
- class QtSingleWindow : public QSplitter {
- Q_OBJECT
- public:
- QtSingleWindow(QtSettingsProvider* settings);
- virtual ~QtSingleWindow();
- void insertAtFront(QWidget* widget);
- void addWidget(QWidget* widget);
- protected:
- void resizeEvent(QResizeEvent*);
- void moveEvent(QMoveEvent*);
- private slots:
- void handleSplitterMoved(int, int);
- void handleTabsTitleChanged(const QString& title);
- private:
- void handleGeometryChanged();
- void restoreSplitters();
-
- private:
-
- QtSettingsProvider* settings_;
- };
+ class QtSettingsProvider;
+
+ class QtSingleWindow : public QSplitter {
+ Q_OBJECT
+ public:
+ QtSingleWindow(QtSettingsProvider* settings);
+ virtual ~QtSingleWindow();
+ void insertAtFront(QWidget* widget);
+ void addWidget(QWidget* widget);
+ protected:
+ void resizeEvent(QResizeEvent*);
+ void moveEvent(QMoveEvent*);
+ private slots:
+ void handleSplitterMoved(int, int);
+ void handleTabsTitleChanged(const QString& title);
+ private:
+ void handleGeometryChanged();
+ void restoreSplitters();
+
+ private:
+
+ QtSettingsProvider* settings_;
+ };
}
diff --git a/Swift/QtUI/QtSoundPlayer.cpp b/Swift/QtUI/QtSoundPlayer.cpp
index e9c500a..22f544d 100644
--- a/Swift/QtUI/QtSoundPlayer.cpp
+++ b/Swift/QtUI/QtSoundPlayer.cpp
@@ -1,43 +1,46 @@
/*
- * Copyright (c) 2010-2013 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtSoundPlayer.h"
+#include <Swift/QtUI/QtSoundPlayer.h>
-#include <QSound>
#include <iostream>
-#include <SwifTools/Application/ApplicationPathProvider.h>
-#include <QtSwiftUtil.h>
+#include <QSound>
+
#include <Swiften/Base/Path.h>
+#include <SwifTools/Application/ApplicationPathProvider.h>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+
namespace Swift {
-
+
QtSoundPlayer::QtSoundPlayer(ApplicationPathProvider* applicationPathProvider) : applicationPathProvider(applicationPathProvider) {
}
void QtSoundPlayer::playSound(SoundEffect sound, const std::string& soundResource) {
- switch (sound) {
- case MessageReceived:
- playSound(soundResource.empty() ? "/sounds/message-received.wav" : soundResource);
- break;
- }
+ switch (sound) {
+ case MessageReceived:
+ playSound(soundResource.empty() ? "/sounds/message-received.wav" : soundResource);
+ break;
+ }
}
void QtSoundPlayer::playSound(const std::string& soundResource) {
- boost::filesystem::path resourcePath = applicationPathProvider->getResourcePath(soundResource);
- if (boost::filesystem::exists(resourcePath)) {
- QSound::play(P2QSTRING(pathToString(resourcePath)));
- }
- else if (boost::filesystem::exists(soundResource)) {
- QSound::play(P2QSTRING(soundResource));
- }
- else {
- std::cerr << "Unable to find sound: " << soundResource << std::endl;
- }
+ boost::filesystem::path resourcePath = applicationPathProvider->getResourcePath(soundResource);
+ if (boost::filesystem::exists(resourcePath)) {
+ QSound::play(P2QSTRING(pathToString(resourcePath)));
+ }
+ else if (boost::filesystem::exists(soundResource)) {
+ QSound::play(P2QSTRING(soundResource));
+ }
+ else {
+ std::cerr << "Unable to find sound: " << soundResource << std::endl;
+ }
}
}
diff --git a/Swift/QtUI/QtSoundPlayer.h b/Swift/QtUI/QtSoundPlayer.h
index 208af09..8a0b8fe 100644
--- a/Swift/QtUI/QtSoundPlayer.h
+++ b/Swift/QtUI/QtSoundPlayer.h
@@ -1,30 +1,30 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/SoundPlayer.h"
-
#include <QObject>
+#include <Swift/Controllers/SoundPlayer.h>
+
namespace Swift {
- class ApplicationPathProvider;
-
+ class ApplicationPathProvider;
+
- class QtSoundPlayer : public QObject, public SoundPlayer {
- Q_OBJECT
- public:
- QtSoundPlayer(ApplicationPathProvider* applicationPathProvider);
+ class QtSoundPlayer : public QObject, public SoundPlayer {
+ Q_OBJECT
+ public:
+ QtSoundPlayer(ApplicationPathProvider* applicationPathProvider);
- void playSound(SoundEffect sound, const std::string& soundResource);
+ void playSound(SoundEffect sound, const std::string& soundResource);
- private:
- void playSound(const std::string& soundResource);
+ private:
+ void playSound(const std::string& soundResource);
- private:
- ApplicationPathProvider* applicationPathProvider;
- };
+ private:
+ ApplicationPathProvider* applicationPathProvider;
+ };
}
diff --git a/Swift/QtUI/QtSpellCheckHighlighter.cpp b/Swift/QtUI/QtSpellCheckHighlighter.cpp
index 0112d7a..cb467e2 100644
--- a/Swift/QtUI/QtSpellCheckHighlighter.cpp
+++ b/Swift/QtUI/QtSpellCheckHighlighter.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -21,21 +21,21 @@ QtSpellCheckHighlighter::~QtSpellCheckHighlighter() {
}
void QtSpellCheckHighlighter::highlightBlock(const QString& text) {
- misspelledPositions_.clear();
- std::string fragment = Q2PSTRING(text);
- checker_->checkFragment(fragment, misspelledPositions_);
+ misspelledPositions_.clear();
+ std::string fragment = Q2PSTRING(text);
+ checker_->checkFragment(fragment, misspelledPositions_);
- QTextCharFormat spellingErrorFormat;
- spellingErrorFormat.setUnderlineColor(QColor(Qt::red));
- spellingErrorFormat.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline);
+ QTextCharFormat spellingErrorFormat;
+ spellingErrorFormat.setUnderlineColor(QColor(Qt::red));
+ spellingErrorFormat.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline);
- foreach (PositionPair position, misspelledPositions_) {
- setFormat(boost::get<0>(position), boost::get<1>(position) - boost::get<0>(position), spellingErrorFormat);
- };
+ for (auto&& position : misspelledPositions_) {
+ setFormat(boost::get<0>(position), boost::get<1>(position) - boost::get<0>(position), spellingErrorFormat);
+ };
}
PositionPairList QtSpellCheckHighlighter::getMisspelledPositions() const {
- return misspelledPositions_;
+ return misspelledPositions_;
}
}
diff --git a/Swift/QtUI/QtSpellCheckHighlighter.h b/Swift/QtUI/QtSpellCheckHighlighter.h
index f4a43b8..5519a1d 100644
--- a/Swift/QtUI/QtSpellCheckHighlighter.h
+++ b/Swift/QtUI/QtSpellCheckHighlighter.h
@@ -1,15 +1,15 @@
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <SwifTools/SpellParser.h>
-
#include <QSyntaxHighlighter>
+#include <SwifTools/SpellParser.h>
+
class QString;
class QTextDocument;
@@ -18,20 +18,20 @@ namespace Swift {
class SpellChecker;
class QtSpellCheckHighlighter : public QSyntaxHighlighter {
- Q_OBJECT
+ Q_OBJECT
public:
- QtSpellCheckHighlighter(QTextDocument* parent, SpellChecker* spellChecker);
- virtual ~QtSpellCheckHighlighter();
+ QtSpellCheckHighlighter(QTextDocument* parent, SpellChecker* spellChecker);
+ virtual ~QtSpellCheckHighlighter();
- PositionPairList getMisspelledPositions() const;
+ PositionPairList getMisspelledPositions() const;
protected:
- virtual void highlightBlock(const QString& text);
+ virtual void highlightBlock(const QString& text);
private:
- SpellChecker* checker_;
- PositionPairList misspelledPositions_;
+ SpellChecker* checker_;
+ PositionPairList misspelledPositions_;
};
diff --git a/Swift/QtUI/QtSpellCheckerWindow.cpp b/Swift/QtUI/QtSpellCheckerWindow.cpp
index db2b1e7..a8178c4 100644
--- a/Swift/QtUI/QtSpellCheckerWindow.cpp
+++ b/Swift/QtUI/QtSpellCheckerWindow.cpp
@@ -4,112 +4,95 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "Swift/QtUI/QtSpellCheckerWindow.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
-#include <Swift/Controllers/Settings/SettingsProvider.h>
-#include <Swift/Controllers/SettingConstants.h>
-#include <Swift/QtUI/QtUISettingConstants.h>
-#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/QtSpellCheckerWindow.h>
#include <QCoreApplication>
-#include <QFileDialog>
#include <QDir>
+#include <QFileDialog>
#include <QStringList>
#include <QTimer>
+#include <Swiften/Base/Log.h>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/QtUISettingConstants.h>
+
namespace Swift {
QtSpellCheckerWindow::QtSpellCheckerWindow(SettingsProvider* settings, QWidget* parent) : QDialog(parent) {
- settings_ = settings;
- ui_.setupUi(this);
+ settings_ = settings;
+ ui_.setupUi(this);
#ifdef HAVE_HUNSPELL
- ui_.hunspellOptions->show();
+ ui_.hunspellOptions->show();
#else
- ui_.hunspellOptions->hide();
- QTimer::singleShot(0, this, SLOT(shrinkWindow()));
+ ui_.hunspellOptions->hide();
+ QTimer::singleShot(0, this, SLOT(shrinkWindow()));
#endif
- connect(ui_.spellChecker, SIGNAL(toggled(bool)), this, SLOT(handleChecker(bool)));
- connect(ui_.cancel, SIGNAL(clicked()), this, SLOT(handleCancel()));
- connect(ui_.apply, SIGNAL(clicked()), this, SLOT(handleApply()));
- connect(ui_.pathButton, SIGNAL(clicked()), this, SLOT(handlePathButton()));
- setFromSettings();
+ connect(ui_.spellChecker, SIGNAL(toggled(bool)), this, SLOT(handleChecker(bool)));
+ connect(ui_.cancel, SIGNAL(clicked()), this, SLOT(handleCancel()));
+ connect(ui_.apply, SIGNAL(clicked()), this, SLOT(handleApply()));
+ setFromSettings();
}
void QtSpellCheckerWindow::shrinkWindow() {
- resize(0,0);
+ resize(0,0);
}
void QtSpellCheckerWindow::setFromSettings() {
- ui_.spellChecker->setChecked(settings_->getSetting(SettingConstants::SPELL_CHECKER));
- ui_.pathContent->setText(P2QSTRING(settings_->getSetting(SettingConstants::DICT_PATH)));
- ui_.currentLanguageValue->setText(P2QSTRING(settings_->getSetting(SettingConstants::DICT_FILE)));
- std::string currentPath = settings_->getSetting(SettingConstants::DICT_PATH);
- QString filename = "*.dic";
- QDir dictDirectory = QDir(P2QSTRING(currentPath));
- QStringList files = dictDirectory.entryList(QStringList(filename), QDir::Files);
- showFiles(files);
- setEnabled(settings_->getSetting(SettingConstants::SPELL_CHECKER));
+ ui_.spellChecker->setChecked(settings_->getSetting(QtUISettingConstants::SPELL_CHECKER));
+ setEnabled(settings_->getSetting(QtUISettingConstants::SPELL_CHECKER));
}
-void QtSpellCheckerWindow::handleChecker(bool state) {
- setEnabled(state);
+void QtSpellCheckerWindow::setSupportedLanguages(const std::vector<std::string>& languages) {
+ languageItems_.clear();
+ ui_.languageView->clear();
+ for (const auto& shortLang : languages) {
+ auto locale = QLocale(P2QSTRING(shortLang));
+ auto label = QString("%1 ( %2 )").arg(locale.nativeLanguageName(), locale.nativeCountryName());
+
+ QListWidgetItem* item = new QListWidgetItem(label);
+ item->setData(Qt::UserRole, P2QSTRING(shortLang));
+ languageItems_[shortLang] = item;
+ ui_.languageView->addItem(item);
+ }
}
-void QtSpellCheckerWindow::setEnabled(bool state) {
- ui_.pathContent->setEnabled(state);
- ui_.languageView->setEnabled(state);
- ui_.pathButton->setEnabled(state);
- ui_.pathLabel->setEnabled(state);
- ui_.currentLanguage->setEnabled(state);
- ui_.currentLanguageValue->setEnabled(state);
- ui_.language->setEnabled(state);
+void QtSpellCheckerWindow::setActiveLanguage(const std::string& language) {
+ SWIFT_LOG_ASSERT(languageItems_.find(language) != languageItems_.end(), warning) << "Language '" << language << "' is not available." << std::endl;
+ if (languageItems_.find(language) != languageItems_.end()) {
+ languageItems_[language]->setSelected(true);
+ }
}
-void QtSpellCheckerWindow::handleApply() {
- settings_->storeSetting(SettingConstants::SPELL_CHECKER, ui_.spellChecker->isChecked());
- QList<QListWidgetItem* > selectedLanguage = ui_.languageView->selectedItems();
- if (!selectedLanguage.empty()) {
- settings_->storeSetting(SettingConstants::DICT_FILE, Q2PSTRING((selectedLanguage.first())->text()));
- }
- this->done(0);
+void QtSpellCheckerWindow::setAutomaticallyIdentifiesLanguage(bool isAutomaticallyIdentifying) {
+ ui_.languageView->setHidden(isAutomaticallyIdentifying);
}
-void QtSpellCheckerWindow::handleCancel() {
- this->done(0);
+void QtSpellCheckerWindow::handleChecker(bool state) {
+ setEnabled(state);
}
-void QtSpellCheckerWindow::handlePathButton() {
- std::string currentPath = settings_->getSetting(SettingConstants::DICT_PATH);
- QString dirpath = QFileDialog::getExistingDirectory(this, tr("Dictionary Path"), P2QSTRING(currentPath));
- if (dirpath != P2QSTRING(currentPath)) {
- ui_.languageView->clear();
- settings_->storeSetting(SettingConstants::DICT_FILE, "");
- ui_.currentLanguageValue->setText(" ");
- }
- if (!dirpath.isEmpty()) {
- if (!dirpath.endsWith("/")) {
- dirpath.append("/");
- }
- settings_->storeSetting(SettingConstants::DICT_PATH, Q2PSTRING(dirpath));
- QDir dictDirectory = QDir(dirpath);
- ui_.pathContent->setText(dirpath);
- QString filename = "*.dic";
- QStringList files = dictDirectory.entryList(QStringList(filename), QDir::Files);
- showFiles(files);
- }
+void QtSpellCheckerWindow::setEnabled(bool state) {
+ ui_.language->setEnabled(state);
}
-void QtSpellCheckerWindow::handlePersonalPathButton() {
- std::string currentPath = settings_->getSetting(SettingConstants::PERSONAL_DICT_PATH);
- QString filename = QFileDialog::getOpenFileName(this, tr("Select Personal Dictionary"), P2QSTRING(currentPath), tr("(*.dic"));
- settings_->storeSetting(SettingConstants::PERSONAL_DICT_PATH, Q2PSTRING(filename));
+void QtSpellCheckerWindow::handleApply() {
+ settings_->storeSetting(QtUISettingConstants::SPELL_CHECKER, ui_.spellChecker->isChecked());
+ QList<QListWidgetItem* > selectedLanguage = ui_.languageView->selectedItems();
+ if (!selectedLanguage.empty()) {
+ settings_->storeSetting(QtUISettingConstants::SPELL_CHECKER_LANGUAGE, Q2PSTRING(selectedLanguage.first()->data(Qt::UserRole).toString()));
+ }
+ this->done(0);
}
-void QtSpellCheckerWindow::showFiles(const QStringList& files) {
- ui_.languageView->clear();
- for (int i = 0; i < files.size(); ++i) {
- ui_.languageView->insertItem(i, files[i]);
- }
+void QtSpellCheckerWindow::handleCancel() {
+ this->done(0);
}
}
diff --git a/Swift/QtUI/QtSpellCheckerWindow.h b/Swift/QtUI/QtSpellCheckerWindow.h
index 7b63318..86ebd40 100644
--- a/Swift/QtUI/QtSpellCheckerWindow.h
+++ b/Swift/QtUI/QtSpellCheckerWindow.h
@@ -4,31 +4,49 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
-#include "ui_QtSpellCheckerWindow.h"
+#include <string>
+#include <unordered_map>
+#include <vector>
#include <QDialog>
+#include <Swift/QtUI/ui_QtSpellCheckerWindow.h>
+
+class QListWidgetItem;
+
namespace Swift {
- class SettingsProvider;
- class QtSpellCheckerWindow : public QDialog, protected Ui::QtSpellCheckerWindow {
- Q_OBJECT
- public:
- QtSpellCheckerWindow(SettingsProvider* settings, QWidget* parent = NULL);
- public slots:
- void handleChecker(bool state);
- void handleCancel();
- void handlePathButton();
- void handlePersonalPathButton();
- void handleApply();
- private slots:
- void shrinkWindow();
- private:
- void setEnabled(bool state);
- void setFromSettings();
- void showFiles(const QStringList& files);
- SettingsProvider* settings_;
- Ui::QtSpellCheckerWindow ui_;
- };
+ class SettingsProvider;
+ class QtSpellCheckerWindow : public QDialog, protected Ui::QtSpellCheckerWindow {
+ Q_OBJECT
+ public:
+ QtSpellCheckerWindow(SettingsProvider* settings, QWidget* parent = nullptr);
+
+ void setSupportedLanguages(const std::vector<std::string>& languages);
+ void setActiveLanguage(const std::string& language);
+ void setAutomaticallyIdentifiesLanguage(bool isAutomaticallyIdentifying);
+
+ public slots:
+ void handleChecker(bool state);
+ void handleCancel();
+ void handleApply();
+
+ private slots:
+ void shrinkWindow();
+
+ private:
+ void setEnabled(bool state);
+ void setFromSettings();
+
+ SettingsProvider* settings_;
+ Ui::QtSpellCheckerWindow ui_;
+ std::unordered_map<std::string, QListWidgetItem*> languageItems_;
+ };
}
diff --git a/Swift/QtUI/QtSpellCheckerWindow.ui b/Swift/QtUI/QtSpellCheckerWindow.ui
index b7f5161..dcb70fa 100644
--- a/Swift/QtUI/QtSpellCheckerWindow.ui
+++ b/Swift/QtUI/QtSpellCheckerWindow.ui
@@ -25,45 +25,6 @@
<widget class="QWidget" name="hunspellOptions" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <widget class="QLabel" name="pathLabel">
- <property name="text">
- <string>Dictionary Path:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="pathContent"/>
- </item>
- <item>
- <widget class="QPushButton" name="pathButton">
- <property name="text">
- <string>Change</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_3">
- <item>
- <widget class="QLabel" name="currentLanguage">
- <property name="text">
- <string>Current Language:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="currentLanguageValue">
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="language">
@@ -73,7 +34,11 @@
</widget>
</item>
<item>
- <widget class="QListWidget" name="languageView"/>
+ <widget class="QListWidget" name="languageView">
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ </widget>
</item>
</layout>
</item>
diff --git a/Swift/QtUI/QtStatusWidget.cpp b/Swift/QtUI/QtStatusWidget.cpp
index bf1b0c9..b175e5c 100644
--- a/Swift/QtUI/QtStatusWidget.cpp
+++ b/Swift/QtUI/QtStatusWidget.cpp
@@ -1,299 +1,302 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtStatusWidget.h"
+#include <Swift/QtUI/QtStatusWidget.h>
#include <algorithm>
-#include <boost/lambda/lambda.hpp>
+
#include <boost/lambda/bind.hpp>
+#include <boost/lambda/lambda.hpp>
+#include <QApplication>
#include <QBoxLayout>
#include <QComboBox>
-#include <QLabel>
-#include <QFrame>
-#include <QPoint>
-#include <QStackedWidget>
-#include <QApplication>
#include <QDesktopWidget>
-#include <qdebug.h>
+#include <QFrame>
+#include <QLabel>
#include <QListWidget>
#include <QListWidgetItem>
#include <QMovie>
+#include <QPoint>
+#include <QStackedWidget>
+
+#include <qdebug.h>
-#include "Swift/QtUI/QtElidingLabel.h"
-#include "Swift/QtUI/QtLineEdit.h"
-#include "Swift/QtUI/QtSwiftUtil.h"
-#include <Swift/Controllers/StatusUtil.h>
#include <Swift/Controllers/StatusCache.h>
+#include <Swift/Controllers/StatusUtil.h>
+
+#include <Swift/QtUI/QtElidingLabel.h>
+#include <Swift/QtUI/QtLineEdit.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
namespace lambda = boost::lambda;
namespace Swift {
QtStatusWidget::QtStatusWidget(StatusCache* statusCache, QWidget *parent) : QWidget(parent), statusCache_(statusCache), editCursor_(Qt::IBeamCursor), viewCursor_(Qt::PointingHandCursor) {
- allTypes_.push_back(StatusShow::Online);
- allTypes_.push_back(StatusShow::FFC);
- allTypes_.push_back(StatusShow::Away);
- allTypes_.push_back(StatusShow::XA);
- allTypes_.push_back(StatusShow::DND);
- allTypes_.push_back(StatusShow::None);
-
- isClicking_ = false;
- connecting_ = false;
- setMaximumHeight(24);
-
- connectingMovie_ = new QMovie(":/icons/connecting.mng");
-
- QHBoxLayout* mainLayout = new QHBoxLayout(this);
- mainLayout->setSpacing(0);
- mainLayout->setContentsMargins(0,0,0,0);
-
- stack_ = new QStackedWidget(this);
- stack_->setLineWidth(2);
- stack_->setFrameShape(QFrame::StyledPanel);
- mainLayout->addWidget(stack_);
-
- QWidget* page1 = new QWidget(this);
- stack_->addWidget(page1);
- QHBoxLayout* page1Layout = new QHBoxLayout(page1);
- page1Layout->setSpacing(0);
- page1Layout->setContentsMargins(0,0,0,0);
- page1->setCursor(viewCursor_);
-
- statusIcon_ = new QLabel(this);
- statusIcon_->setMinimumSize(16, 16);
- statusIcon_->setMaximumSize(16, 16);
- page1Layout->addWidget(statusIcon_);
-
- statusTextLabel_ = new QtElidingLabel(this);
- QFont font = statusTextLabel_->font();
- font.setItalic(true);
- statusTextLabel_->setFont(font);
- page1Layout->addWidget(statusTextLabel_);
-
- icons_[StatusShow::Online] = QIcon(":/icons/online.png");
- icons_[StatusShow::Away] = QIcon(":/icons/away.png");
- icons_[StatusShow::DND] = QIcon(":/icons/dnd.png");
- icons_[StatusShow::None] = QIcon(":/icons/offline.png");
-
- setStatusType(StatusShow::None);
-
- QWidget* page2 = new QWidget(this);
- QHBoxLayout* page2Layout = new QHBoxLayout(page2);
- page2Layout->setSpacing(0);
- page2Layout->setContentsMargins(0,0,0,0);
- stack_->addWidget(page2);
-
- statusEdit_ = new QtLineEdit(this);
- page2Layout->addWidget(statusEdit_);
- connect(statusEdit_, SIGNAL(returnPressed()), this, SLOT(handleEditComplete()));
- connect(statusEdit_, SIGNAL(escapePressed()), this, SLOT(handleEditCancelled()));
- connect(statusEdit_, SIGNAL(textChanged(const QString&)), this, SLOT(generateList()));
-
- setStatusText("");
-
-
- menu_ = new QListWidget();
- menu_->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint );
- menu_->setAlternatingRowColors(true);
- menu_->setFocusProxy(statusEdit_);
- menu_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- menu_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- QSizePolicy policy(menu_->sizePolicy());
- policy.setVerticalPolicy(QSizePolicy::Expanding);
- menu_->setSizePolicy(policy);
-
-
- connect(menu_, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(handleItemClicked(QListWidgetItem*)));
-
- viewMode();
+ allTypes_.push_back(StatusShow::Online);
+ allTypes_.push_back(StatusShow::FFC);
+ allTypes_.push_back(StatusShow::Away);
+ allTypes_.push_back(StatusShow::XA);
+ allTypes_.push_back(StatusShow::DND);
+ allTypes_.push_back(StatusShow::None);
+
+ isClicking_ = false;
+ connecting_ = false;
+ setMaximumHeight(24);
+
+ connectingMovie_ = new QMovie(":/icons/connecting.mng");
+
+ QHBoxLayout* mainLayout = new QHBoxLayout(this);
+ mainLayout->setSpacing(0);
+ mainLayout->setContentsMargins(0,0,0,0);
+
+ stack_ = new QStackedWidget(this);
+ stack_->setLineWidth(2);
+ stack_->setFrameShape(QFrame::StyledPanel);
+ mainLayout->addWidget(stack_);
+
+ QWidget* page1 = new QWidget(this);
+ stack_->addWidget(page1);
+ QHBoxLayout* page1Layout = new QHBoxLayout(page1);
+ page1Layout->setSpacing(0);
+ page1Layout->setContentsMargins(0,0,0,0);
+ page1->setCursor(viewCursor_);
+
+ statusIcon_ = new QLabel(this);
+ statusIcon_->setMinimumSize(16, 16);
+ statusIcon_->setMaximumSize(16, 16);
+ page1Layout->addWidget(statusIcon_);
+
+ statusTextLabel_ = new QtElidingLabel(this);
+ QFont font = statusTextLabel_->font();
+ font.setItalic(true);
+ statusTextLabel_->setFont(font);
+ page1Layout->addWidget(statusTextLabel_);
+
+ icons_[StatusShow::Online] = QIcon(":/icons/online.png");
+ icons_[StatusShow::Away] = QIcon(":/icons/away.png");
+ icons_[StatusShow::DND] = QIcon(":/icons/dnd.png");
+ icons_[StatusShow::None] = QIcon(":/icons/offline.png");
+
+ setStatusType(StatusShow::None);
+
+ QWidget* page2 = new QWidget(this);
+ QHBoxLayout* page2Layout = new QHBoxLayout(page2);
+ page2Layout->setSpacing(0);
+ page2Layout->setContentsMargins(0,0,0,0);
+ stack_->addWidget(page2);
+
+ statusEdit_ = new QtLineEdit(this);
+ page2Layout->addWidget(statusEdit_);
+ connect(statusEdit_, SIGNAL(returnPressed()), this, SLOT(handleEditComplete()));
+ connect(statusEdit_, SIGNAL(escapePressed()), this, SLOT(handleEditCancelled()));
+ connect(statusEdit_, SIGNAL(textChanged(const QString&)), this, SLOT(generateList()));
+
+ setStatusText("");
+
+
+ menu_ = new QListWidget();
+ menu_->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint );
+ menu_->setAlternatingRowColors(true);
+ menu_->setFocusProxy(statusEdit_);
+ menu_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ menu_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ QSizePolicy policy(menu_->sizePolicy());
+ policy.setVerticalPolicy(QSizePolicy::Expanding);
+ menu_->setSizePolicy(policy);
+
+
+ connect(menu_, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(handleItemClicked(QListWidgetItem*)));
+
+ viewMode();
}
QtStatusWidget::~QtStatusWidget() {
- delete menu_;
- delete connectingMovie_;
+ delete menu_;
+ delete connectingMovie_;
}
void QtStatusWidget::handleApplicationFocusChanged(QWidget* /*old*/, QWidget* /*now*/) {
- QWidget* now = qApp->focusWidget();
- if (!editing_ || stack_->currentIndex() == 0) {
- return;
- }
- if (!now || (now != menu_ && now != statusEdit_ && !now->isAncestorOf(statusEdit_) && !now->isAncestorOf(menu_) && !statusEdit_->isAncestorOf(now) && !menu_->isAncestorOf(now))) {
- handleEditCancelled();
- }
-
+ QWidget* now = qApp->focusWidget();
+ if (!editing_ || stack_->currentIndex() == 0) {
+ return;
+ }
+ if (!now || (now != menu_ && now != statusEdit_ && !now->isAncestorOf(statusEdit_) && !now->isAncestorOf(menu_) && !statusEdit_->isAncestorOf(now) && !menu_->isAncestorOf(now))) {
+ handleEditCancelled();
+ }
+
}
void QtStatusWidget::mousePressEvent(QMouseEvent*) {
- if (stack_->currentIndex() == 0) {
- handleClicked();
- }
+ if (stack_->currentIndex() == 0) {
+ handleClicked();
+ }
}
void QtStatusWidget::generateList() {
- if (!editing_) {
- return;
- }
- QString text = statusEdit_->text();
- newStatusText_ = text;
- menu_->clear();
- foreach (StatusShow::Type type, icons_.keys()) {
- QListWidgetItem* item = new QListWidgetItem(text == "" ? getNoMessage() : text, menu_);
- item->setIcon(icons_[type]);
- item->setToolTip(P2QSTRING(statusShowTypeToFriendlyName(type)) + ": " + item->text());
- item->setStatusTip(item->toolTip());
- item->setData(Qt::UserRole, QVariant(type));
- }
- std::vector<StatusCache::PreviousStatus> previousStatuses = statusCache_->getMatches(Q2PSTRING(text), 8);
- foreach (StatusCache::PreviousStatus savedStatus, previousStatuses) {
- if (savedStatus.first.empty() || std::find_if(allTypes_.begin(), allTypes_.end(),
- savedStatus.second == lambda::_1 && savedStatus.first == lambda::bind(&statusShowTypeToFriendlyName, lambda::_1)) != allTypes_.end()) {
- continue;
- }
- QListWidgetItem* item = new QListWidgetItem(P2QSTRING(savedStatus.first), menu_);
- item->setIcon(icons_[savedStatus.second]);
- item->setToolTip(item->text());
- item->setStatusTip(item->toolTip());
- item->setData(Qt::UserRole, QVariant(savedStatus.second));
- }
- foreach (StatusShow::Type type, icons_.keys()) {
- if (Q2PSTRING(text) == statusShowTypeToFriendlyName(type)) {
- continue;
- }
- QListWidgetItem* item = new QListWidgetItem(P2QSTRING(statusShowTypeToFriendlyName(type)), menu_);
- item->setIcon(icons_[type]);
- item->setToolTip(item->text());
- item->setStatusTip(item->toolTip());
- item->setData(Qt::UserRole, QVariant(type));
- }
- resizeMenu();
+ if (!editing_) {
+ return;
+ }
+ QString text = statusEdit_->text();
+ newStatusText_ = text;
+ menu_->clear();
+ for (const auto& type : icons_.keys()) {
+ QListWidgetItem* item = new QListWidgetItem(text == "" ? getNoMessage() : text, menu_);
+ item->setIcon(icons_[type]);
+ item->setToolTip(P2QSTRING(statusShowTypeToFriendlyName(type)) + ": " + item->text());
+ item->setStatusTip(item->toolTip());
+ item->setData(Qt::UserRole, QVariant(type));
+ }
+ std::vector<StatusCache::PreviousStatus> previousStatuses = statusCache_->getMatches(Q2PSTRING(text), 8);
+ for (const auto& savedStatus : previousStatuses) {
+ if (savedStatus.first.empty() || std::find_if(allTypes_.begin(), allTypes_.end(),
+ savedStatus.second == lambda::_1 && savedStatus.first == lambda::bind(&statusShowTypeToFriendlyName, lambda::_1)) != allTypes_.end()) {
+ continue;
+ }
+ QListWidgetItem* item = new QListWidgetItem(P2QSTRING(savedStatus.first), menu_);
+ item->setIcon(icons_[savedStatus.second]);
+ item->setToolTip(item->text());
+ item->setStatusTip(item->toolTip());
+ item->setData(Qt::UserRole, QVariant(savedStatus.second));
+ }
+ for (const auto& type : icons_.keys()) {
+ if (Q2PSTRING(text) == statusShowTypeToFriendlyName(type)) {
+ continue;
+ }
+ QListWidgetItem* item = new QListWidgetItem(P2QSTRING(statusShowTypeToFriendlyName(type)), menu_);
+ item->setIcon(icons_[type]);
+ item->setToolTip(item->text());
+ item->setStatusTip(item->toolTip());
+ item->setData(Qt::UserRole, QVariant(type));
+ }
+ resizeMenu();
}
void QtStatusWidget::resizeMenu() {
- int height = menu_->sizeHintForRow(0) * menu_->count();
- int marginLeft;
- int marginTop;
- int marginRight;
- int marginBottom;
- menu_->getContentsMargins(&marginLeft, &marginTop, &marginRight, &marginBottom);
- height += marginTop + marginBottom;
-
- menu_->setGeometry(menu_->x(), menu_->y(), menu_->width(), height);
+ int height = menu_->sizeHintForRow(0) * menu_->count();
+ int marginLeft;
+ int marginTop;
+ int marginRight;
+ int marginBottom;
+ menu_->getContentsMargins(&marginLeft, &marginTop, &marginRight, &marginBottom);
+ height += marginTop + marginBottom;
+
+ menu_->setGeometry(menu_->x(), menu_->y(), menu_->width(), height);
}
void QtStatusWidget::handleClicked() {
- editing_ = true;
- QDesktopWidget* desktop = QApplication::desktop();
- int screen = desktop->screenNumber(this);
- QPoint point = mapToGlobal(QPoint(0, height()));
- QRect geometry = desktop->availableGeometry(screen);
- int x = point.x();
- int y = point.y();
- int width = 200;
- int height = 80;
-
- int screenWidth = geometry.x() + geometry.width();
- if (x + width > screenWidth) {
- x = screenWidth - width;
- }
- //foreach (StatusShow::Type type, allTypes_) {
- // if (statusEdit_->text() == P2QSTRING(statusShowTypeToFriendlyName(type))) {
- statusEdit_->setText("");
- // }
- //}
- generateList();
-
- height = menu_->sizeHintForRow(0) * menu_->count();
- int marginLeft;
- int marginTop;
- int marginRight;
- int marginBottom;
- menu_->getContentsMargins(&marginLeft, &marginTop, &marginRight, &marginBottom);
- height += marginTop + marginBottom;
- width += marginLeft + marginRight;
-
- menu_->setGeometry(x, y, width, height);
- menu_->move(x, y);
- menu_->setMaximumWidth(width);
- menu_->show();
- activateWindow();
- statusEdit_->selectAll();
- stack_->setCurrentIndex(1);
- statusEdit_->setFocus();
- connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(handleApplicationFocusChanged(QWidget*, QWidget*)), Qt::QueuedConnection);
+ editing_ = true;
+ QDesktopWidget* desktop = QApplication::desktop();
+ int screen = desktop->screenNumber(this);
+ QPoint point = mapToGlobal(QPoint(0, height()));
+ QRect geometry = desktop->availableGeometry(screen);
+ int x = point.x();
+ int y = point.y();
+ int width = 200;
+ int height = 80;
+
+ int screenWidth = geometry.x() + geometry.width();
+ if (x + width > screenWidth) {
+ x = screenWidth - width;
+ }
+ //for (StatusShow::Type type : allTypes_) {
+ // if (statusEdit_->text() == P2QSTRING(statusShowTypeToFriendlyName(type))) {
+ statusEdit_->setText("");
+ // }
+ //}
+ generateList();
+
+ height = menu_->sizeHintForRow(0) * menu_->count();
+ int marginLeft;
+ int marginTop;
+ int marginRight;
+ int marginBottom;
+ menu_->getContentsMargins(&marginLeft, &marginTop, &marginRight, &marginBottom);
+ height += marginTop + marginBottom;
+ width += marginLeft + marginRight;
+
+ menu_->setGeometry(x, y, width, height);
+ menu_->move(x, y);
+ menu_->setMaximumWidth(width);
+ menu_->show();
+ activateWindow();
+ statusEdit_->selectAll();
+ stack_->setCurrentIndex(1);
+ statusEdit_->setFocus();
+ connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(handleApplicationFocusChanged(QWidget*, QWidget*)), Qt::QueuedConnection);
}
void QtStatusWidget::viewMode() {
- disconnect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(handleApplicationFocusChanged(QWidget*, QWidget*)));
- editing_ = false;
- menu_->hide();
- stack_->setCurrentIndex(0);
+ disconnect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(handleApplicationFocusChanged(QWidget*, QWidget*)));
+ editing_ = false;
+ menu_->hide();
+ stack_->setCurrentIndex(0);
}
void QtStatusWidget::handleEditComplete() {
- editing_ = false;
- statusText_ = newStatusText_;
- viewMode();
- emit onChangeStatusRequest(selectedStatusType_, statusText_);
- statusCache_->addRecent(Q2PSTRING(statusText_), selectedStatusType_);
+ editing_ = false;
+ statusText_ = newStatusText_;
+ viewMode();
+ emit onChangeStatusRequest(selectedStatusType_, statusText_);
+ statusCache_->addRecent(Q2PSTRING(statusText_), selectedStatusType_);
}
void QtStatusWidget::handleEditCancelled() {
- editing_ = false;
- setStatusText(statusText_);
- viewMode();
+ editing_ = false;
+ setStatusText(statusText_);
+ viewMode();
}
StatusShow::Type QtStatusWidget::getSelectedStatusShow() {
- return selectedStatusType_;
+ return selectedStatusType_;
}
void QtStatusWidget::handleItemClicked(QListWidgetItem* item) {
- editing_ = false;
- selectedStatusType_ = static_cast<StatusShow::Type>(item->data(Qt::UserRole).toInt());
- QString message = item->data(Qt::DisplayRole).toString();
- newStatusText_ = message == getNoMessage() ? "" : message;
- statusEdit_->setText(newStatusText_);
- handleEditComplete();
+ editing_ = false;
+ selectedStatusType_ = static_cast<StatusShow::Type>(item->data(Qt::UserRole).toInt());
+ QString message = item->data(Qt::DisplayRole).toString();
+ newStatusText_ = message == getNoMessage() ? "" : message;
+ statusEdit_->setText(newStatusText_);
+ handleEditComplete();
}
void QtStatusWidget::setNewToolTip() {
- if (connecting_) {
- statusTextLabel_->setToolTip(tr("Connecting"));
- } else {
- statusTextLabel_->setToolTip(P2QSTRING(statusShowTypeToFriendlyName(selectedStatusType_)) + ": " + statusTextLabel_->text());
- }
+ if (connecting_) {
+ statusTextLabel_->setToolTip(tr("Connecting"));
+ } else {
+ statusTextLabel_->setToolTip(P2QSTRING(statusShowTypeToFriendlyName(selectedStatusType_)) + ": " + statusTextLabel_->text());
+ }
}
void QtStatusWidget::setStatusText(const QString& text) {
- connectingMovie_->stop();
- statusText_ = text;
- statusEdit_->setText(text);
- QString escapedText(text.isEmpty() ? getNoMessage() : text);
- statusTextLabel_->setText(escapedText);
- setNewToolTip();
+ connectingMovie_->stop();
+ statusText_ = text;
+ statusEdit_->setText(text);
+ QString escapedText(text.isEmpty() ? getNoMessage() : text);
+ statusTextLabel_->setText(escapedText);
+ setNewToolTip();
}
void QtStatusWidget::setConnecting() {
- connecting_ = true;
- statusIcon_->setMovie(connectingMovie_);
- connectingMovie_->start();
- setNewToolTip();
+ connecting_ = true;
+ statusIcon_->setMovie(connectingMovie_);
+ connectingMovie_->start();
+ setNewToolTip();
}
void QtStatusWidget::setStatusType(StatusShow::Type type) {
- connecting_ = false;
- selectedStatusType_ = icons_.contains(type) ? type : StatusShow::Online;
- statusIcon_->setPixmap(icons_[selectedStatusType_].pixmap(16, 16));
- setNewToolTip();
+ connecting_ = false;
+ selectedStatusType_ = icons_.contains(type) ? type : StatusShow::Online;
+ statusIcon_->setPixmap(icons_[selectedStatusType_].pixmap(16, 16));
+ setNewToolTip();
}
QString QtStatusWidget::getNoMessage() {
- return QString(tr("(No message)"));
+ return QString(tr("(No message)"));
}
}
diff --git a/Swift/QtUI/QtStatusWidget.h b/Swift/QtUI/QtStatusWidget.h
index edee711..f346868 100644
--- a/Swift/QtUI/QtStatusWidget.h
+++ b/Swift/QtUI/QtStatusWidget.h
@@ -1,16 +1,16 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swiften/Elements/StatusShow.h"
-
-#include <QWidget>
-#include <QMap>
#include <QIcon>
+#include <QMap>
+#include <QWidget>
+
+#include <Swiften/Elements/StatusShow.h>
class QComboBox;
class QLabel;
@@ -20,55 +20,55 @@ class QListWidgetItem;
class QMovie;
namespace Swift {
- class QtLineEdit;
- class QtElidingLabel;
- class StatusCache;
+ class QtLineEdit;
+ class QtElidingLabel;
+ class StatusCache;
- class QtStatusWidget : public QWidget {
- Q_OBJECT
- public:
- QtStatusWidget(StatusCache* statusCache, QWidget *parent);
- ~QtStatusWidget();
- StatusShow::Type getSelectedStatusShow();
- void setStatusType(StatusShow::Type type);
- void setConnecting();
- signals:
- void onChangeStatusRequest(StatusShow::Type showType, const QString& text);
- public slots:
- void setStatusText(const QString& text);
- private slots:
- void generateList();
- void handleClicked();
- void handleEditComplete();
- void handleEditCancelled();
- void handleApplicationFocusChanged(QWidget* old, QWidget* now);
- protected slots:
- virtual void mousePressEvent(QMouseEvent* event);
- void handleItemClicked(QListWidgetItem* item);
- static QString getNoMessage();
- private:
- void resizeMenu();
- void viewMode();
- void setNewToolTip();
- //QComboBox *types_;
- StatusCache* statusCache_;
- QStackedWidget* stack_;
- QLabel* statusIcon_;
- QtElidingLabel* statusTextLabel_;
- QtLineEdit* statusEdit_;
- QString statusText_;
- QString newStatusText_;
- QMap<StatusShow::Type, QIcon> icons_;
- StatusShow::Type selectedStatusType_;
- bool isClicking_;
- QListWidget* menu_;
- QCursor editCursor_;
- QCursor viewCursor_;
- bool editing_;
- QMovie* connectingMovie_;
- bool connecting_;
- static const QString NO_MESSAGE;
- std::vector<StatusShow::Type> allTypes_;
- };
+ class QtStatusWidget : public QWidget {
+ Q_OBJECT
+ public:
+ QtStatusWidget(StatusCache* statusCache, QWidget *parent);
+ ~QtStatusWidget();
+ StatusShow::Type getSelectedStatusShow();
+ void setStatusType(StatusShow::Type type);
+ void setConnecting();
+ signals:
+ void onChangeStatusRequest(StatusShow::Type showType, const QString& text);
+ public slots:
+ void setStatusText(const QString& text);
+ private slots:
+ void generateList();
+ void handleClicked();
+ void handleEditComplete();
+ void handleEditCancelled();
+ void handleApplicationFocusChanged(QWidget* old, QWidget* now);
+ protected slots:
+ virtual void mousePressEvent(QMouseEvent* event);
+ void handleItemClicked(QListWidgetItem* item);
+ static QString getNoMessage();
+ private:
+ void resizeMenu();
+ void viewMode();
+ void setNewToolTip();
+ //QComboBox *types_;
+ StatusCache* statusCache_;
+ QStackedWidget* stack_;
+ QLabel* statusIcon_;
+ QtElidingLabel* statusTextLabel_;
+ QtLineEdit* statusEdit_;
+ QString statusText_;
+ QString newStatusText_;
+ QMap<StatusShow::Type, QIcon> icons_;
+ StatusShow::Type selectedStatusType_;
+ bool isClicking_;
+ QListWidget* menu_;
+ QCursor editCursor_;
+ QCursor viewCursor_;
+ bool editing_;
+ QMovie* connectingMovie_;
+ bool connecting_;
+ static const QString NO_MESSAGE;
+ std::vector<StatusShow::Type> allTypes_;
+ };
}
diff --git a/Swift/QtUI/QtStrings.h b/Swift/QtUI/QtStrings.h
index 586e775..d0cd421 100644
--- a/Swift/QtUI/QtStrings.h
+++ b/Swift/QtUI/QtStrings.h
@@ -16,7 +16,7 @@
QT_TRANSLATE_NOOP("CloseButton", "Close Tab");
-QT_TRANSLATE_NOOP3("QApplication", "QT_LAYOUT_DIRECTION", "Translate this to LTR for left-to-right or RTL for right-to-left languages");
+QT_TRANSLATE_NOOP3("QGuiApplication", "QT_LAYOUT_DIRECTION", "Translate this to LTR for left-to-right or RTL for right-to-left languages");
QT_TRANSLATE_NOOP("QLineEdit", "Select All");
QT_TRANSLATE_NOOP("QLineEdit", "&Undo");
diff --git a/Swift/QtUI/QtSubscriptionRequestWindow.cpp b/Swift/QtUI/QtSubscriptionRequestWindow.cpp
index 2ea7305..c8c4178 100644
--- a/Swift/QtUI/QtSubscriptionRequestWindow.cpp
+++ b/Swift/QtUI/QtSubscriptionRequestWindow.cpp
@@ -1,90 +1,90 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/QtUI/QtSubscriptionRequestWindow.h"
+#include <Swift/QtUI/QtSubscriptionRequestWindow.h>
-#include <QPushButton>
#include <QHBoxLayout>
-#include <QVBoxLayout>
#include <QLabel>
+#include <QPushButton>
+#include <QVBoxLayout>
#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
-QtSubscriptionRequestWindow::QtSubscriptionRequestWindow(boost::shared_ptr<SubscriptionRequestEvent> event, QWidget* parent) : QDialog(parent), event_(event) {
- QString text = QString(tr("%1 would like to add you to their contact list.")).arg(P2QSTRING(event->getJID().toString()));
- QVBoxLayout* layout = new QVBoxLayout();
- QLabel* label = new QLabel(text, this);
- layout->addWidget(label);
- label = new QLabel(tr("Would you like to add them to your contact list and share your status when you're online?"));
- //layout->addWidget(new QLabel);
- layout->addWidget(label);
+QtSubscriptionRequestWindow::QtSubscriptionRequestWindow(std::shared_ptr<SubscriptionRequestEvent> event, QWidget* parent) : QDialog(parent), event_(event) {
+ QString text = QString(tr("%1 would like to add you to their contact list.")).arg(P2QSTRING(event->getJID().toString()));
+ QVBoxLayout* layout = new QVBoxLayout();
+ QLabel* label = new QLabel(text, this);
+ layout->addWidget(label);
+ label = new QLabel(tr("Would you like to add them to your contact list and share your status when you're online?"));
+ //layout->addWidget(new QLabel);
+ layout->addWidget(label);
- if (event_->getConcluded()) {
- QLabel* doneLabel = new QLabel(tr("You have already replied to this request"));
- QPushButton* okButton = new QPushButton(tr("OK"), this);
- connect(okButton, SIGNAL(clicked()), this, SLOT(handleDefer()));
- layout->addWidget(doneLabel);
- layout->addWidget(okButton);
- } else {
- QPushButton* yesButton = new QPushButton(tr("Accept"), this);
- yesButton->setDefault(true);
- connect(yesButton, SIGNAL(clicked()), this, SLOT(handleYes()));
- QPushButton* noButton = new QPushButton(tr("Reject"), this);
- connect(noButton, SIGNAL(clicked()), this, SLOT(handleNo()));
- QPushButton* deferButton = new QPushButton(tr("Defer"), this);
- deferButton->setShortcut(QKeySequence(Qt::Key_Escape));
- connect(deferButton, SIGNAL(clicked()), this, SLOT(handleDefer()));
+ if (event_->getConcluded()) {
+ QLabel* doneLabel = new QLabel(tr("You have already replied to this request"));
+ QPushButton* okButton = new QPushButton(tr("OK"), this);
+ connect(okButton, SIGNAL(clicked()), this, SLOT(handleDefer()));
+ layout->addWidget(doneLabel);
+ layout->addWidget(okButton);
+ } else {
+ QPushButton* yesButton = new QPushButton(tr("Accept"), this);
+ yesButton->setDefault(true);
+ connect(yesButton, SIGNAL(clicked()), this, SLOT(handleYes()));
+ QPushButton* noButton = new QPushButton(tr("Reject"), this);
+ connect(noButton, SIGNAL(clicked()), this, SLOT(handleNo()));
+ QPushButton* deferButton = new QPushButton(tr("Defer"), this);
+ deferButton->setShortcut(QKeySequence(Qt::Key_Escape));
+ connect(deferButton, SIGNAL(clicked()), this, SLOT(handleDefer()));
- QHBoxLayout* buttonLayout = new QHBoxLayout();
- buttonLayout->addWidget(yesButton);
- buttonLayout->addWidget(noButton);
- buttonLayout->addWidget(deferButton);
- layout->addWidget(new QLabel);
- layout->addLayout(buttonLayout);
- layout->addWidget(new QLabel);
- QLabel* footer = new QLabel(tr("(If you choose to defer this choice, you will be asked again when you next login.)"));
- layout->addWidget(footer);
- }
+ QHBoxLayout* buttonLayout = new QHBoxLayout();
+ buttonLayout->addWidget(yesButton);
+ buttonLayout->addWidget(noButton);
+ buttonLayout->addWidget(deferButton);
+ layout->addWidget(new QLabel);
+ layout->addLayout(buttonLayout);
+ layout->addWidget(new QLabel);
+ QLabel* footer = new QLabel(tr("(If you choose to defer this choice, you will be asked again when you next login.)"));
+ layout->addWidget(footer);
+ }
- setLayout(layout);
+ setLayout(layout);
}
void QtSubscriptionRequestWindow::handleYes() {
- event_->accept();
- delete this;
+ event_->accept();
+ delete this;
}
void QtSubscriptionRequestWindow::handleNo() {
- event_->decline();
- delete this;
+ event_->decline();
+ delete this;
}
void QtSubscriptionRequestWindow::handleDefer() {
- event_->defer();
- delete this;
+ event_->defer();
+ delete this;
}
QtSubscriptionRequestWindow::~QtSubscriptionRequestWindow() {
- windows_.removeOne(this);
+ windows_.removeOne(this);
}
-QtSubscriptionRequestWindow* QtSubscriptionRequestWindow::getWindow(boost::shared_ptr<SubscriptionRequestEvent> event, QWidget* parent) {
- foreach (QtSubscriptionRequestWindow* window, windows_) {
- if (window->getEvent() == event) {
- return window;
- }
- }
- QtSubscriptionRequestWindow* window = new QtSubscriptionRequestWindow(event, parent);
- windows_.append(window);
- return window;
+QtSubscriptionRequestWindow* QtSubscriptionRequestWindow::getWindow(std::shared_ptr<SubscriptionRequestEvent> event, QWidget* parent) {
+ for (auto window : windows_) {
+ if (window->getEvent() == event) {
+ return window;
+ }
+ }
+ QtSubscriptionRequestWindow* window = new QtSubscriptionRequestWindow(event, parent);
+ windows_.append(window);
+ return window;
}
-boost::shared_ptr<SubscriptionRequestEvent> QtSubscriptionRequestWindow::getEvent() {
- return event_;
+std::shared_ptr<SubscriptionRequestEvent> QtSubscriptionRequestWindow::getEvent() {
+ return event_;
}
QList<QtSubscriptionRequestWindow*> QtSubscriptionRequestWindow::windows_;
diff --git a/Swift/QtUI/QtSubscriptionRequestWindow.h b/Swift/QtUI/QtSubscriptionRequestWindow.h
index 5b02991..3f1e816 100644
--- a/Swift/QtUI/QtSubscriptionRequestWindow.h
+++ b/Swift/QtUI/QtSubscriptionRequestWindow.h
@@ -1,34 +1,34 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <QDialog>
+#include <memory>
-#include <boost/shared_ptr.hpp>
+#include <QDialog>
-#include "Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h"
+#include <Swift/Controllers/XMPPEvents/SubscriptionRequestEvent.h>
namespace Swift {
- class QtSubscriptionRequestWindow : public QDialog {
- Q_OBJECT
- public:
- static QtSubscriptionRequestWindow* getWindow(boost::shared_ptr<SubscriptionRequestEvent> event, QWidget* parent = 0);
- ~QtSubscriptionRequestWindow();
- boost::shared_ptr<SubscriptionRequestEvent> getEvent();
- private slots:
- void handleYes();
- void handleNo();
- void handleDefer();
- private:
- QtSubscriptionRequestWindow(boost::shared_ptr<SubscriptionRequestEvent> event, QWidget* parent = 0);
- static QList<QtSubscriptionRequestWindow*> windows_;
- boost::shared_ptr<SubscriptionRequestEvent> event_;
- /*QPushButton* yesButton_;
- QPushButton* noButton_;
- QPushButton* deferButton_;*/
- };
+ class QtSubscriptionRequestWindow : public QDialog {
+ Q_OBJECT
+ public:
+ static QtSubscriptionRequestWindow* getWindow(std::shared_ptr<SubscriptionRequestEvent> event, QWidget* parent = nullptr);
+ ~QtSubscriptionRequestWindow();
+ std::shared_ptr<SubscriptionRequestEvent> getEvent();
+ private slots:
+ void handleYes();
+ void handleNo();
+ void handleDefer();
+ private:
+ QtSubscriptionRequestWindow(std::shared_ptr<SubscriptionRequestEvent> event, QWidget* parent = nullptr);
+ static QList<QtSubscriptionRequestWindow*> windows_;
+ std::shared_ptr<SubscriptionRequestEvent> event_;
+ /*QPushButton* yesButton_;
+ QPushButton* noButton_;
+ QPushButton* deferButton_;*/
+ };
}
diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp
index 756f530..3f6ce8e 100644
--- a/Swift/QtUI/QtSwift.cpp
+++ b/Swift/QtUI/QtSwift.cpp
@@ -1,54 +1,57 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/QtSwift.h>
-#include <string>
#include <map>
+#include <string>
#include <boost/bind.hpp>
-#include <QFile>
-#include <QMessageBox>
#include <QApplication>
+#include <QFile>
+#include <QFontDatabase>
#include <QMap>
+#include <QMessageBox>
#include <qdebug.h>
#include <Swiften/Base/Log.h>
#include <Swiften/Base/Path.h>
+#include <Swiften/Base/Paths.h>
#include <Swiften/Base/Platform.h>
-#include <Swiften/Elements/Presence.h>
#include <Swiften/Client/Client.h>
-#include <Swiften/Base/Paths.h>
+#include <Swiften/Elements/Presence.h>
#include <Swiften/TLS/TLSContextFactory.h>
#include <SwifTools/Application/PlatformApplicationPathProvider.h>
#include <SwifTools/AutoUpdater/AutoUpdater.h>
#include <SwifTools/AutoUpdater/PlatformAutoUpdaterFactory.h>
-#include <Swift/Controllers/Storages/CertificateFileStorageFactory.h>
-#include <Swift/Controllers/Storages/FileStoragesFactory.h>
-#include <Swift/Controllers/Settings/XMLSettingsProvider.h>
-#include <Swift/Controllers/Settings/SettingsProviderHierachy.h>
-#include <Swift/Controllers/SettingConstants.h>
-#include <Swift/Controllers/MainController.h>
#include <Swift/Controllers/ApplicationInfo.h>
#include <Swift/Controllers/BuildVersion.h>
+#include <Swift/Controllers/MainController.h>
+#include <Swift/Controllers/SettingConstants.h>
+#include <Swift/Controllers/Settings/SettingsProviderHierachy.h>
+#include <Swift/Controllers/Settings/XMLSettingsProvider.h>
#include <Swift/Controllers/StatusCache.h>
+#include <Swift/Controllers/Storages/CertificateFileStorageFactory.h>
+#include <Swift/Controllers/Storages/FileStoragesFactory.h>
-#include <Swift/QtUI/QtLoginWindow.h>
-#include <Swift/QtUI/QtChatTabsBase.h>
#include <Swift/QtUI/QtChatTabs.h>
+#include <Swift/QtUI/QtChatTabsBase.h>
#include <Swift/QtUI/QtChatTabsShortcutOnlySubstitute.h>
-#include <Swift/QtUI/QtSystemTray.h>
+#include <Swift/QtUI/QtChatWindowFactory.h>
+#include <Swift/QtUI/QtLoginWindow.h>
+#include <Swift/QtUI/QtSingleWindow.h>
#include <Swift/QtUI/QtSoundPlayer.h>
#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/QtSystemTray.h>
#include <Swift/QtUI/QtUIFactory.h>
-#include <Swift/QtUI/QtChatWindowFactory.h>
-#include <Swift/QtUI/QtSingleWindow.h>
+#include <Swift/QtUI/QtUISettingConstants.h>
+#include <Swift/QtUI/SwiftUpdateFeeds.h>
#if defined(SWIFTEN_PLATFORM_WINDOWS)
#include <Swift/QtUI/WindowsNotifier.h>
@@ -76,212 +79,275 @@
#include <Swift/QtUI/QtDBUSURIHandler.h>
#endif
-namespace Swift{
-
#if defined(SWIFTEN_PLATFORM_MACOSX)
-//#define SWIFT_APPCAST_URL "http://swift.im/appcast/swift-mac-dev.xml"
-#else
-//#define SWIFT_APPCAST_URL ""
+#include <Swift/QtUI/CocoaUIHelpers.h>
#endif
+namespace Swift{
+
po::options_description QtSwift::getOptionsDescription() {
- po::options_description result("Options");
- result.add_options()
- ("debug", "Turn on debug logging")
- ("help", "Show this help message")
- ("version", "Show version information")
- ("netbook-mode", "Use netbook mode display (unsupported)")
- ("no-tabs", "Don't manage chat windows in tabs (unsupported)")
- ("latency-debug", "Use latency debugging (unsupported)")
- ("multi-account", po::value<int>()->default_value(1), "Number of accounts to open windows for (unsupported)")
- ("start-minimized", "Don't show the login/roster window at startup")
- ("enable-jid-adhocs", "Enable AdHoc commands to custom JID's.")
- ("trellis", "Enable support for trellis layout")
+ po::options_description result("Options");
+ result.add_options()
+ ("debug", "Turn on debug logging")
+ ("help", "Show this help message")
+ ("version", "Show version information")
+ ("netbook-mode", "Use netbook mode display (unsupported)")
+ ("no-tabs", "Don't manage chat windows in tabs (unsupported)")
+ ("latency-debug", "Use latency debugging (unsupported)")
+ ("multi-account", po::value<int>()->default_value(1), "Number of accounts to open windows for (unsupported)")
+ ("start-minimized", "Don't show the login/roster window at startup")
+ ("enable-jid-adhocs", "Enable AdHoc commands to custom JID's.")
#if QT_VERSION >= 0x040800
- ("language", po::value<std::string>(), "Use a specific language, instead of the system-wide one")
+ ("language", po::value<std::string>(), "Use a specific language, instead of the system-wide one")
#endif
- ;
- return result;
+ ;
+ return result;
}
XMLSettingsProvider* QtSwift::loadSettingsFile(const QString& fileName) {
- QFile configFile(fileName);
- if (configFile.exists() && configFile.open(QIODevice::ReadOnly)) {
- QString xmlString;
- while (!configFile.atEnd()) {
- QByteArray line = configFile.readLine();
- xmlString += line + "\n";
- }
- return new XMLSettingsProvider(Q2PSTRING(xmlString));
- }
- return new XMLSettingsProvider("");
+ QFile configFile(fileName);
+ if (configFile.exists() && configFile.open(QIODevice::ReadOnly)) {
+ QString xmlString;
+ while (!configFile.atEnd()) {
+ QByteArray line = configFile.readLine();
+ xmlString += line + "\n";
+ }
+ return new XMLSettingsProvider(Q2PSTRING(xmlString));
+ }
+ return new XMLSettingsProvider("");
}
void QtSwift::loadEmoticonsFile(const QString& fileName, std::map<std::string, std::string>& emoticons) {
- QFile file(fileName);
- if (file.exists() && file.open(QIODevice::ReadOnly)) {
- while (!file.atEnd()) {
- QString line = file.readLine();
- line.replace("\n", "");
- line.replace("\r", "");
- QStringList tokens = line.split(" ");
- if (tokens.size() == 2) {
- QString emoticonFile = tokens[1];
- if (!emoticonFile.startsWith(":/") && !emoticonFile.startsWith("qrc:/")) {
- emoticonFile = "file://" + emoticonFile;
- }
- emoticons[Q2PSTRING(tokens[0])] = Q2PSTRING(emoticonFile);
- }
- }
- }
+ QFile file(fileName);
+ if (file.exists() && file.open(QIODevice::ReadOnly)) {
+ while (!file.atEnd()) {
+ QString line = file.readLine();
+ line.replace("\n", "");
+ line.replace("\r", "");
+ QStringList tokens = line.split(" ");
+ if (tokens.size() == 2) {
+ QString emoticonFile = tokens[1];
+ if (!emoticonFile.startsWith(":/") && !emoticonFile.startsWith("qrc:/")) {
+ emoticonFile = "file://" + emoticonFile;
+ }
+ emoticons[Q2PSTRING(tokens[0])] = Q2PSTRING(emoticonFile);
+ }
+ }
+ }
}
-QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMainThreadCaller_), autoUpdater_(NULL), idleDetector_(&idleQuerier_, networkFactories_.getTimerFactory(), 1000) {
- QCoreApplication::setApplicationName(SWIFT_APPLICATION_NAME);
- QCoreApplication::setOrganizationName(SWIFT_ORGANIZATION_NAME);
- QCoreApplication::setOrganizationDomain(SWIFT_ORGANIZATION_DOMAIN);
- QCoreApplication::setApplicationVersion(buildVersion);
-
- qtSettings_ = new QtSettingsProvider();
- xmlSettings_ = loadSettingsFile(P2QSTRING(pathToString(Paths::getExecutablePath() / "system-settings.xml")));
- settingsHierachy_ = new SettingsProviderHierachy();
- settingsHierachy_->addProviderToTopOfStack(xmlSettings_);
- settingsHierachy_->addProviderToTopOfStack(qtSettings_);
-
- networkFactories_.getTLSContextFactory()->setDisconnectOnCardRemoval(settingsHierachy_->getSetting(SettingConstants::DISCONNECT_ON_CARD_REMOVAL));
-
- std::map<std::string, std::string> emoticons;
- loadEmoticonsFile(":/emoticons/emoticons.txt", emoticons);
- loadEmoticonsFile(P2QSTRING(pathToString(Paths::getExecutablePath() / "emoticons.txt")), emoticons);
-
- if (options.count("netbook-mode")) {
- splitter_ = new QtSingleWindow(qtSettings_);
- } else {
- splitter_ = NULL;
- }
-
- int numberOfAccounts = 1;
- try {
- numberOfAccounts = options["multi-account"].as<int>();
- } catch (...) {
- /* This seems to fail on a Mac when the .app is launched directly (the usual path).*/
- numberOfAccounts = 1;
- }
-
- if (options.count("debug")) {
- Log::setLogLevel(Swift::Log::debug);
- }
-
- bool enableAdHocCommandOnJID = options.count("enable-jid-adhocs") > 0;
- tabs_ = NULL;
- if (options.count("no-tabs") && !splitter_) {
- tabs_ = new QtChatTabsShortcutOnlySubstitute();
- }
- else {
- tabs_ = new QtChatTabs(splitter_ != NULL, settingsHierachy_, options.count("trellis"));
- }
- bool startMinimized = options.count("start-minimized") > 0;
- applicationPathProvider_ = new PlatformApplicationPathProvider(SWIFT_APPLICATION_NAME);
- storagesFactory_ = new FileStoragesFactory(applicationPathProvider_->getDataDir(), networkFactories_.getCryptoProvider());
- certificateStorageFactory_ = new CertificateFileStorageFactory(applicationPathProvider_->getDataDir(), tlsFactories_.getCertificateFactory(), networkFactories_.getCryptoProvider());
- chatWindowFactory_ = new QtChatWindowFactory(splitter_, settingsHierachy_, qtSettings_, tabs_, "", emoticons);
- soundPlayer_ = new QtSoundPlayer(applicationPathProvider_);
-
- // Ugly, because the dock depends on the tray, but the temporary
- // multi-account hack creates one tray per account.
- QtSystemTray* systemTray = new QtSystemTray();
- systemTrays_.push_back(systemTray);
+const std::string& QtSwift::updateChannelToFeed(const std::string& channel) {
+ static const std::string invalidChannel;
+ if (channel == UpdateFeeds::StableChannel) {
+ return UpdateFeeds::StableAppcastFeed;
+ }
+ else if (channel == UpdateFeeds::TestingChannel) {
+ return UpdateFeeds::TestingAppcastFeed;
+ }
+ else if (channel == UpdateFeeds::DevelopmentChannel) {
+ return UpdateFeeds::DevelopmentAppcastFeed;
+ }
+ else {
+ return invalidChannel;
+ }
+}
+
+QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMainThreadCaller_), autoUpdater_(nullptr), idleDetector_(&idleQuerier_, networkFactories_.getTimerFactory(), 1000) {
+ QCoreApplication::setApplicationName(SWIFT_APPLICATION_NAME);
+ QCoreApplication::setOrganizationName(SWIFT_ORGANIZATION_NAME);
+ QCoreApplication::setOrganizationDomain(SWIFT_ORGANIZATION_DOMAIN);
+ QCoreApplication::setApplicationVersion(buildVersion);
+
+ qtSettings_ = new QtSettingsProvider();
+ xmlSettings_ = loadSettingsFile(P2QSTRING(pathToString(Paths::getExecutablePath() / "system-settings.xml")));
+ settingsHierachy_ = new SettingsProviderHierachy();
+ settingsHierachy_->addProviderToTopOfStack(xmlSettings_);
+ settingsHierachy_->addProviderToTopOfStack(qtSettings_);
+
+ networkFactories_.getTLSContextFactory()->setDisconnectOnCardRemoval(settingsHierachy_->getSetting(SettingConstants::DISCONNECT_ON_CARD_REMOVAL));
+
+ std::map<std::string, std::string> emoticons;
+ loadEmoticonsFile(":/emoticons/emoticons.txt", emoticons);
+ loadEmoticonsFile(P2QSTRING(pathToString(Paths::getExecutablePath() / "emoticons.txt")), emoticons);
+
+ if (options.count("netbook-mode")) {
+ splitter_ = new QtSingleWindow(qtSettings_);
+ } else {
+ splitter_ = nullptr;
+ }
+
+ int numberOfAccounts = 1;
+ try {
+ numberOfAccounts = options["multi-account"].as<int>();
+ } catch (...) {
+ /* This seems to fail on a Mac when the .app is launched directly (the usual path).*/
+ numberOfAccounts = 1;
+ }
+
+ if (options.count("debug")) {
+ Log::setLogLevel(Swift::Log::debug);
+ }
+
+ // Load fonts
+ std::vector<std::string> fontNames = {
+ "themes/Default/Lato2OFL/Lato-Black.ttf",
+ "themes/Default/Lato2OFL/Lato-BlackItalic.ttf",
+ "themes/Default/Lato2OFL/Lato-Bold.ttf",
+ "themes/Default/Lato2OFL/Lato-BoldItalic.ttf",
+ "themes/Default/Lato2OFL/Lato-Hairline.ttf",
+ "themes/Default/Lato2OFL/Lato-HairlineItalic.ttf",
+ "themes/Default/Lato2OFL/Lato-Heavy.ttf",
+ "themes/Default/Lato2OFL/Lato-HeavyItalic.ttf",
+ "themes/Default/Lato2OFL/Lato-Italic.ttf",
+ "themes/Default/Lato2OFL/Lato-Light.ttf",
+ "themes/Default/Lato2OFL/Lato-LightItalic.ttf",
+ "themes/Default/Lato2OFL/Lato-Medium.ttf",
+ "themes/Default/Lato2OFL/Lato-MediumItalic.ttf",
+ "themes/Default/Lato2OFL/Lato-Regular.ttf",
+ "themes/Default/Lato2OFL/Lato-Semibold.ttf",
+ "themes/Default/Lato2OFL/Lato-SemiboldItalic.ttf",
+ "themes/Default/Lato2OFL/Lato-Thin.ttf",
+ "themes/Default/Lato2OFL/Lato-ThinItalic.ttf"
+ };
+
+ for (auto&& fontName : fontNames) {
+ std::string fontPath = std::string(":/") + fontName;
+ int error = QFontDatabase::addApplicationFont(P2QSTRING(fontPath));
+ assert((error != -1) && "Failed to load font.");
+ }
+
+ bool enableAdHocCommandOnJID = options.count("enable-jid-adhocs") > 0;
+ tabs_ = nullptr;
+ if (options.count("no-tabs") && !splitter_) {
+ tabs_ = new QtChatTabsShortcutOnlySubstitute();
+ }
+ else {
+ tabs_ = new QtChatTabs(splitter_ != nullptr, settingsHierachy_, true);
+ }
+ bool startMinimized = options.count("start-minimized") > 0;
+ applicationPathProvider_ = new PlatformApplicationPathProvider(SWIFT_APPLICATION_NAME);
+ storagesFactory_ = new FileStoragesFactory(applicationPathProvider_->getDataDir(), networkFactories_.getCryptoProvider());
+ certificateStorageFactory_ = new CertificateFileStorageFactory(applicationPathProvider_->getDataDir(), tlsFactories_.getCertificateFactory(), networkFactories_.getCryptoProvider());
+ chatWindowFactory_ = new QtChatWindowFactory(splitter_, settingsHierachy_, qtSettings_, tabs_, ":/themes/Default/", emoticons);
+ soundPlayer_ = new QtSoundPlayer(applicationPathProvider_);
+
+ // Ugly, because the dock depends on the tray, but the temporary
+ // multi-account hack creates one tray per account.
+ QtSystemTray* systemTray = new QtSystemTray();
+ systemTrays_.push_back(systemTray);
#if defined(HAVE_GROWL)
- notifier_ = new GrowlNotifier(SWIFT_APPLICATION_NAME);
+ notifier_ = new GrowlNotifier(SWIFT_APPLICATION_NAME);
#elif defined(SWIFTEN_PLATFORM_WINDOWS)
- notifier_ = new WindowsNotifier(SWIFT_APPLICATION_NAME, applicationPathProvider_->getResourcePath("/images/logo-icon-32.png"), systemTray->getQSystemTrayIcon());
+ notifier_ = new WindowsNotifier(SWIFT_APPLICATION_NAME, applicationPathProvider_->getResourcePath("/images/logo-icon-32.png"), systemTray->getQSystemTrayIcon());
#elif defined(SWIFTEN_PLATFORM_LINUX)
- notifier_ = new FreeDesktopNotifier(SWIFT_APPLICATION_NAME);
+ notifier_ = new FreeDesktopNotifier(SWIFT_APPLICATION_NAME);
#elif defined(SWIFTEN_PLATFORM_MACOSX)
- notifier_ = new NotificationCenterNotifier();
+ notifier_ = new NotificationCenterNotifier();
#else
- notifier_ = new NullNotifier();
+ notifier_ = new NullNotifier();
#endif
#if defined(SWIFTEN_PLATFORM_MACOSX)
- dock_ = new MacOSXDock(&cocoaApplication_);
+ dock_ = new MacOSXDock(&cocoaApplication_);
#else
- dock_ = new NullDock();
+ dock_ = new NullDock();
#endif
#if defined(SWIFTEN_PLATFORM_MACOSX)
- uriHandler_ = new QtURIHandler();
+ uriHandler_ = new QtURIHandler();
#elif defined(SWIFTEN_PLATFORM_WIN32)
- uriHandler_ = new NullURIHandler();
+ uriHandler_ = new NullURIHandler();
#else
- uriHandler_ = new QtDBUSURIHandler();
+ uriHandler_ = new QtDBUSURIHandler();
#endif
- statusCache_ = new StatusCache(applicationPathProvider_);
-
- if (splitter_) {
- splitter_->show();
- }
-
- for (int i = 0; i < numberOfAccounts; i++) {
- if (i > 0) {
- // Don't add the first tray (see note above)
- systemTrays_.push_back(new QtSystemTray());
- }
- QtUIFactory* uiFactory = new QtUIFactory(settingsHierachy_, qtSettings_, tabs_, splitter_, systemTrays_[i], chatWindowFactory_, networkFactories_.getTimerFactory(), statusCache_, startMinimized, !emoticons.empty(), enableAdHocCommandOnJID);
- uiFactories_.push_back(uiFactory);
- MainController* mainController = new MainController(
- &clientMainThreadCaller_,
- &networkFactories_,
- uiFactory,
- settingsHierachy_,
- systemTrays_[i],
- soundPlayer_,
- storagesFactory_,
- certificateStorageFactory_,
- dock_,
- notifier_,
- uriHandler_,
- &idleDetector_,
- emoticons,
- options.count("latency-debug") > 0);
- mainControllers_.push_back(mainController);
- }
-
-
- // PlatformAutoUpdaterFactory autoUpdaterFactory;
- // if (autoUpdaterFactory.isSupported()) {
- // autoUpdater_ = autoUpdaterFactory.createAutoUpdater(SWIFT_APPCAST_URL);
- // autoUpdater_->checkForUpdates();
- // }
+ statusCache_ = new StatusCache(applicationPathProvider_);
+
+ if (splitter_) {
+ splitter_->show();
+ }
+
+ for (int i = 0; i < numberOfAccounts; i++) {
+ if (i > 0) {
+ // Don't add the first tray (see note above)
+ systemTrays_.push_back(new QtSystemTray());
+ }
+ QtUIFactory* uiFactory = new QtUIFactory(settingsHierachy_, qtSettings_, tabs_, splitter_, systemTrays_[i], chatWindowFactory_, networkFactories_.getTimerFactory(), statusCache_, startMinimized, !emoticons.empty(), enableAdHocCommandOnJID);
+ uiFactories_.push_back(uiFactory);
+ MainController* mainController = new MainController(
+ &clientMainThreadCaller_,
+ &networkFactories_,
+ uiFactory,
+ settingsHierachy_,
+ systemTrays_[i],
+ soundPlayer_,
+ storagesFactory_,
+ certificateStorageFactory_,
+ dock_,
+ notifier_,
+ uriHandler_,
+ &idleDetector_,
+ emoticons,
+ options.count("latency-debug") > 0);
+ mainControllers_.push_back(mainController);
+ }
+
+ connect(qApp, SIGNAL(aboutToQuit()), this, SLOT(handleAboutToQuit()));
+
+ PlatformAutoUpdaterFactory autoUpdaterFactory;
+ if (autoUpdaterFactory.isSupported() && settingsHierachy_->getSetting(QtUISettingConstants::ENABLE_SOFTWARE_UPDATES)
+ && !settingsHierachy_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL).empty()) {
+ autoUpdater_ = autoUpdaterFactory.createAutoUpdater(updateChannelToFeed(settingsHierachy_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL)));
+ autoUpdater_->checkForUpdates();
+ autoUpdater_->onSuggestRestartToUserToUpdate.connect(boost::bind(&QtSwift::handleRecommendRestartToInstallUpdate, this));
+
+ settingsHierachy_->onSettingChanged.connect([&](const std::string& path) {
+ if (path == QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL.getKey()) {
+ autoUpdater_->setAppcastFeed(updateChannelToFeed(settingsHierachy_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL)));
+ autoUpdater_->checkForUpdates();
+ }
+ });
+ }
}
QtSwift::~QtSwift() {
- delete autoUpdater_;
- foreach (QtUIFactory* factory, uiFactories_) {
- delete factory;
- }
- foreach (MainController* controller, mainControllers_) {
- delete controller;
- }
- delete notifier_;
- foreach (QtSystemTray* tray, systemTrays_) {
- delete tray;
- }
- delete tabs_;
- delete splitter_;
- delete settingsHierachy_;
- delete qtSettings_;
- delete xmlSettings_;
- delete statusCache_;
- delete uriHandler_;
- delete dock_;
- delete soundPlayer_;
- delete chatWindowFactory_;
- delete certificateStorageFactory_;
- delete storagesFactory_;
- delete applicationPathProvider_;
+ delete autoUpdater_;
+ for (auto* factory : uiFactories_) {
+ delete factory;
+ }
+ for (auto* controller : mainControllers_) {
+ delete controller;
+ }
+ delete notifier_;
+ for (auto* tray : systemTrays_) {
+ delete tray;
+ }
+ delete tabs_;
+ delete splitter_;
+ delete settingsHierachy_;
+ delete qtSettings_;
+ delete xmlSettings_;
+ delete statusCache_;
+ delete uriHandler_;
+ delete dock_;
+ delete soundPlayer_;
+ delete chatWindowFactory_;
+ delete certificateStorageFactory_;
+ delete storagesFactory_;
+ delete applicationPathProvider_;
+}
+
+void QtSwift::handleAboutToQuit() {
+#if defined(SWIFTEN_PLATFORM_MACOSX)
+ // This is required so Sparkle knows about the application shutting down
+ // and can update the application in background.
+ CocoaUIHelpers::sendCocoaApplicationWillTerminateNotification();
+#endif
+}
+
+void QtSwift::handleRecommendRestartToInstallUpdate() {
+ notifier_->showMessage(Notifier::SystemMessage, Q2PSTRING(tr("Swift Update Available")), Q2PSTRING(tr("Restart Swift to update to the new Swift version.")), "", [](){});
}
}
diff --git a/Swift/QtUI/QtSwift.h b/Swift/QtUI/QtSwift.h
index a971324..3ad5714 100644
--- a/Swift/QtUI/QtSwift.h
+++ b/Swift/QtUI/QtSwift.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -30,65 +30,72 @@ namespace po = boost::program_options;
class QSplitter;
namespace Swift {
- class QtUIFactory;
- class CertificateStorageFactory;
- class Dock;
- class Notifier;
- class StoragesFactory;
- class AutoUpdater;
- class ApplicationPathProvider;
- class AvatarStorage;
- class CapsStorage;
- class MainController;
- class QtSystemTray;
- class QtChatTabsBase;
- class QtChatWindowFactory;
- class QtSoundPlayer;
- class QtMUCSearchWindowFactory;
- class QtUserSearchWindowFactory;
- class EventLoop;
- class URIHandler;
- class SettingsProviderHierachy;
- class XMLSettingsProvider;
- class StatusCache;
- class QtSingleWindow;
-
- class QtSwift : public QObject {
- Q_OBJECT
- public:
- QtSwift(const po::variables_map& options);
- static po::options_description getOptionsDescription();
- ~QtSwift();
- private:
- XMLSettingsProvider* loadSettingsFile(const QString& fileName);
- void loadEmoticonsFile(const QString& fileName, std::map<std::string, std::string>& emoticons);
- private:
- QtEventLoop clientMainThreadCaller_;
- PlatformTLSFactories tlsFactories_;
- BoostNetworkFactories networkFactories_;
- QtChatWindowFactory* chatWindowFactory_;
- std::vector<MainController*> mainControllers_;
- std::vector<QtSystemTray*> systemTrays_;
- std::vector<QtUIFactory*> uiFactories_;
- QtSettingsProvider* qtSettings_;
- XMLSettingsProvider* xmlSettings_;
- SettingsProviderHierachy* settingsHierachy_;
- QtSingleWindow* splitter_;
- QtSoundPlayer* soundPlayer_;
- Dock* dock_;
- URIHandler* uriHandler_;
- QtChatTabsBase* tabs_;
- ApplicationPathProvider* applicationPathProvider_;
- StoragesFactory* storagesFactory_;
- CertificateStorageFactory* certificateStorageFactory_;
- AutoUpdater* autoUpdater_;
- Notifier* notifier_;
- StatusCache* statusCache_;
- PlatformIdleQuerier idleQuerier_;
- ActualIdleDetector idleDetector_;
+ class QtUIFactory;
+ class CertificateStorageFactory;
+ class Dock;
+ class Notifier;
+ class StoragesFactory;
+ class AutoUpdater;
+ class ApplicationPathProvider;
+ class AvatarStorage;
+ class CapsStorage;
+ class MainController;
+ class QtSystemTray;
+ class QtChatTabsBase;
+ class QtChatWindowFactory;
+ class QtSoundPlayer;
+ class QtMUCSearchWindowFactory;
+ class QtUserSearchWindowFactory;
+ class EventLoop;
+ class URIHandler;
+ class SettingsProviderHierachy;
+ class XMLSettingsProvider;
+ class StatusCache;
+ class QtSingleWindow;
+
+ class QtSwift : public QObject {
+ Q_OBJECT
+ public:
+ QtSwift(const po::variables_map& options);
+ static po::options_description getOptionsDescription();
+ ~QtSwift();
+
+ private slots:
+ void handleAboutToQuit();
+ void handleRecommendRestartToInstallUpdate();
+
+ private:
+ XMLSettingsProvider* loadSettingsFile(const QString& fileName);
+ void loadEmoticonsFile(const QString& fileName, std::map<std::string, std::string>& emoticons);
+ static const std::string& updateChannelToFeed(const std::string& channel);
+
+ private:
+ QtEventLoop clientMainThreadCaller_;
+ PlatformTLSFactories tlsFactories_;
+ BoostNetworkFactories networkFactories_;
+ QtChatWindowFactory* chatWindowFactory_;
+ std::vector<MainController*> mainControllers_;
+ std::vector<QtSystemTray*> systemTrays_;
+ std::vector<QtUIFactory*> uiFactories_;
+ QtSettingsProvider* qtSettings_;
+ XMLSettingsProvider* xmlSettings_;
+ SettingsProviderHierachy* settingsHierachy_;
+ QtSingleWindow* splitter_;
+ QtSoundPlayer* soundPlayer_;
+ Dock* dock_;
+ URIHandler* uriHandler_;
+ QtChatTabsBase* tabs_;
+ ApplicationPathProvider* applicationPathProvider_;
+ StoragesFactory* storagesFactory_;
+ CertificateStorageFactory* certificateStorageFactory_;
+ AutoUpdater* autoUpdater_;
+ Notifier* notifier_;
+ StatusCache* statusCache_;
+ PlatformIdleQuerier idleQuerier_;
+ ActualIdleDetector idleDetector_;
#if defined(SWIFTEN_PLATFORM_MACOSX)
- CocoaApplication cocoaApplication_;
- CocoaApplicationActivateHelper cocoaApplicationActivateHelper_;
+ CocoaApplication cocoaApplication_;
+ CocoaApplicationActivateHelper cocoaApplicationActivateHelper_;
#endif
- };
+ };
}
diff --git a/Swift/QtUI/QtSystemTray.cpp b/Swift/QtUI/QtSystemTray.cpp
index f000e6f..d9bfbc3 100644
--- a/Swift/QtUI/QtSystemTray.cpp
+++ b/Swift/QtUI/QtSystemTray.cpp
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma GCC diagnostic ignored "-Wredundant-decls"
-#include "Swift/QtUI/QtSystemTray.h"
+#include <Swift/QtUI/QtSystemTray.h>
#include <QtDebug>
#if defined (Q_OS_UNIX) && !defined(Q_OS_MAC)
@@ -19,72 +19,72 @@
#include <QAction>
namespace Swift {
-QtSystemTray::QtSystemTray() : QObject(), statusType_(StatusShow::None), trayMenu_(0), onlineIcon_(":icons/online.png"), awayIcon_(":icons/away.png"), dndIcon_(":icons/dnd.png"), offlineIcon_(":icons/offline.png"), newMessageIcon_(":icons/new-chat.png"), throbberMovie_(":/icons/connecting.mng"), unreadMessages_(false), connecting_(false) {
- trayIcon_ = new QSystemTrayIcon(offlineIcon_);
- trayIcon_->setToolTip("Swift");
- connect(trayIcon_, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(handleIconActivated(QSystemTrayIcon::ActivationReason)));
- connect(&throbberMovie_, SIGNAL(frameChanged(int)), this, SLOT(handleThrobberFrameChanged(int)));
+QtSystemTray::QtSystemTray() : QObject(), statusType_(StatusShow::None), trayMenu_(nullptr), onlineIcon_(":icons/online.png"), awayIcon_(":icons/away.png"), dndIcon_(":icons/dnd.png"), offlineIcon_(":icons/offline.png"), newMessageIcon_(":icons/new-chat.png"), throbberMovie_(":/icons/connecting.mng"), unreadMessages_(false), connecting_(false) {
+ trayIcon_ = new QSystemTrayIcon(offlineIcon_);
+ trayIcon_->setToolTip("Swift");
+ connect(trayIcon_, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(handleIconActivated(QSystemTrayIcon::ActivationReason)));
+ connect(&throbberMovie_, SIGNAL(frameChanged(int)), this, SLOT(handleThrobberFrameChanged(int)));
#if defined (Q_OS_UNIX) && !defined(Q_OS_MAC)
- bool isUnity = QDBusInterface("com.canonical.Unity.Launcher", "/com/canonical/Unity/Launcher").isValid();
- if (isUnity) {
- // Add an activation menu, because this is the only way to get the application to the
- // front on Unity. See the README for sni-qt (which handles Qt tray icons for Unity)
- trayMenu_ = new QMenu();
- QAction* showAction = new QAction(QString("Show/Hide"), this);
- connect(showAction, SIGNAL(triggered()), SIGNAL(clicked()));
- trayMenu_->addAction(showAction);
- trayIcon_->setContextMenu(trayMenu_);
- }
+ bool isUnity = QDBusInterface("com.canonical.Unity.Launcher", "/com/canonical/Unity/Launcher").isValid();
+ if (isUnity) {
+ // Add an activation menu, because this is the only way to get the application to the
+ // front on Unity. See the README for sni-qt (which handles Qt tray icons for Unity)
+ trayMenu_ = new QMenu();
+ QAction* showAction = new QAction(QString("Show/Hide"), this);
+ connect(showAction, SIGNAL(triggered()), SIGNAL(clicked()));
+ trayMenu_->addAction(showAction);
+ trayIcon_->setContextMenu(trayMenu_);
+ }
#endif
- trayIcon_->show();
+ trayIcon_->show();
}
QtSystemTray::~QtSystemTray() {
- delete trayMenu_;
- delete trayIcon_;
+ delete trayMenu_;
+ delete trayIcon_;
}
void QtSystemTray::setUnreadMessages(bool some) {
- unreadMessages_ = some;
- updateStatusIcon();
+ unreadMessages_ = some;
+ updateStatusIcon();
}
void QtSystemTray::handleThrobberFrameChanged(int /*frameNumber*/) {
- trayIcon_->setIcon(QIcon(throbberMovie_.currentPixmap()));
+ trayIcon_->setIcon(QIcon(throbberMovie_.currentPixmap()));
}
void QtSystemTray::setConnecting() {
- connecting_ = true;
- updateStatusIcon();
+ connecting_ = true;
+ updateStatusIcon();
}
void QtSystemTray::handleIconActivated(QSystemTrayIcon::ActivationReason reason) {
- if (reason == QSystemTrayIcon::Trigger) {
- emit clicked();
- }
+ if (reason == QSystemTrayIcon::Trigger) {
+ emit clicked();
+ }
}
void QtSystemTray::setStatusType(StatusShow::Type type) {
- connecting_ = false;
- statusType_ = type;
- updateStatusIcon();
+ connecting_ = false;
+ statusType_ = type;
+ updateStatusIcon();
}
void QtSystemTray::updateStatusIcon() {
- throbberMovie_.stop();
- if (unreadMessages_) {
- trayIcon_->setIcon(newMessageIcon_);
- } else if (connecting_) {
- throbberMovie_.start();
- } else {
- switch (statusType_) {
- case StatusShow::Online : trayIcon_->setIcon(onlineIcon_);break;
- case StatusShow::FFC : trayIcon_->setIcon(onlineIcon_);break;
- case StatusShow::Away : trayIcon_->setIcon(awayIcon_);break;
- case StatusShow::XA : trayIcon_->setIcon(awayIcon_);break;
- case StatusShow::DND : trayIcon_->setIcon(dndIcon_);break;
- case StatusShow::None : trayIcon_->setIcon(offlineIcon_);break;
- }
- }
+ throbberMovie_.stop();
+ if (unreadMessages_) {
+ trayIcon_->setIcon(newMessageIcon_);
+ } else if (connecting_) {
+ throbberMovie_.start();
+ } else {
+ switch (statusType_) {
+ case StatusShow::Online : trayIcon_->setIcon(onlineIcon_);break;
+ case StatusShow::FFC : trayIcon_->setIcon(onlineIcon_);break;
+ case StatusShow::Away : trayIcon_->setIcon(awayIcon_);break;
+ case StatusShow::XA : trayIcon_->setIcon(awayIcon_);break;
+ case StatusShow::DND : trayIcon_->setIcon(dndIcon_);break;
+ case StatusShow::None : trayIcon_->setIcon(offlineIcon_);break;
+ }
+ }
}
}
diff --git a/Swift/QtUI/QtSystemTray.h b/Swift/QtUI/QtSystemTray.h
index df460b2..ba2c5cb 100644
--- a/Swift/QtUI/QtSystemTray.h
+++ b/Swift/QtUI/QtSystemTray.h
@@ -1,50 +1,50 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/SystemTray.h"
-
-#include <QSystemTrayIcon>
#include <QMovie>
+#include <QSystemTrayIcon>
+
+#include <Swift/Controllers/SystemTray.h>
class QIcon;
class QMenu;
namespace Swift {
- class QtSystemTray : public QObject, public SystemTray {
- Q_OBJECT
- public:
- QtSystemTray();
- ~QtSystemTray();
- void setUnreadMessages(bool some);
- void setStatusType(StatusShow::Type type);
- void setConnecting();
- QSystemTrayIcon* getQSystemTrayIcon() {
- return trayIcon_;
- }
+ class QtSystemTray : public QObject, public SystemTray {
+ Q_OBJECT
+ public:
+ QtSystemTray();
+ ~QtSystemTray();
+ void setUnreadMessages(bool some);
+ void setStatusType(StatusShow::Type type);
+ void setConnecting();
+ QSystemTrayIcon* getQSystemTrayIcon() {
+ return trayIcon_;
+ }
- signals:
- void clicked();
- private slots:
- void handleIconActivated(QSystemTrayIcon::ActivationReason reason);
- void handleThrobberFrameChanged(int);
- private:
- void updateStatusIcon();
- StatusShow::Type statusType_;
- QSystemTrayIcon* trayIcon_;
- QMenu* trayMenu_;
- QIcon onlineIcon_;
- QIcon awayIcon_;
- QIcon dndIcon_;
- QIcon offlineIcon_;
- QIcon newMessageIcon_;
- QMovie throbberMovie_;
- bool unreadMessages_;
- bool connecting_;
- };
+ signals:
+ void clicked();
+ private slots:
+ void handleIconActivated(QSystemTrayIcon::ActivationReason reason);
+ void handleThrobberFrameChanged(int);
+ private:
+ void updateStatusIcon();
+ StatusShow::Type statusType_;
+ QSystemTrayIcon* trayIcon_;
+ QMenu* trayMenu_;
+ QIcon onlineIcon_;
+ QIcon awayIcon_;
+ QIcon dndIcon_;
+ QIcon offlineIcon_;
+ QIcon newMessageIcon_;
+ QMovie throbberMovie_;
+ bool unreadMessages_;
+ bool connecting_;
+ };
}
diff --git a/Swift/QtUI/QtTabWidget.cpp b/Swift/QtUI/QtTabWidget.cpp
index 1be3777..67e3ae9 100644
--- a/Swift/QtUI/QtTabWidget.cpp
+++ b/Swift/QtUI/QtTabWidget.cpp
@@ -1,10 +1,16 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtTabWidget.h"
+#include <Swift/QtUI/QtTabWidget.h>
+
+#include <QLabel>
+#include <QPainter>
+#include <QPoint>
+
+#include <Swift/QtUI/Trellis/QtDNDTabBar.h>
namespace Swift {
@@ -17,10 +23,44 @@ QtTabWidget::~QtTabWidget() {
}
QTabBar* QtTabWidget::tabBar() {
- return QTabWidget::tabBar();
+ return QTabWidget::tabBar();
}
void QtTabWidget::setTabBar(QTabBar* tabBar) {
- QTabWidget::setTabBar(tabBar);
+ QTabWidget::setTabBar(tabBar);
+ if (dynamic_cast<QtDNDTabBar*>(tabBar)) {
+ setAcceptDrops(true);
+ }
+ else {
+ setAcceptDrops(false);
+ }
}
+
+void QtTabWidget::dragEnterEvent(QDragEnterEvent* event) {
+ QtDNDTabBar* dndTabBar = dynamic_cast<QtDNDTabBar*>(tabBar());
+ if (dndTabBar) {
+ dndTabBar->dragEnterEvent(event);
+ }
+}
+
+void QtTabWidget::dropEvent(QDropEvent* event) {
+ QtDNDTabBar* dndTabBar = dynamic_cast<QtDNDTabBar*>(tabBar());
+ if (dndTabBar) {
+ dndTabBar->dropEvent(event);
+ }
+}
+
+void QtTabWidget::paintEvent(QPaintEvent * event) {
+ QTabWidget::paintEvent(event);
+ if (count() == 0) {
+ QLabel label;
+ label.setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
+ label.setGeometry(QRect(QPoint(0,0), size()) - QMargins(10,10,10,10));
+ label.setWordWrap(true);
+ label.setText(tr("This empty cell is a placeholder for chat windows. You can move existing chats to this cell by dragging the tab over here. You can change the number of cells via the 'Change layout' dialog under the 'View' menu or by using the %1 shortcut.").arg(QKeySequence(tr("Ctrl+Alt+L")).toString(QKeySequence::NativeText)));
+ QPainter painter(this);
+ painter.drawPixmap(label.geometry().topLeft(), label.grab());
+ }
+}
+
}
diff --git a/Swift/QtUI/QtTabWidget.h b/Swift/QtUI/QtTabWidget.h
index 0a723e2..f19721d 100644
--- a/Swift/QtUI/QtTabWidget.h
+++ b/Swift/QtUI/QtTabWidget.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -9,13 +9,18 @@
#include <QTabWidget>
namespace Swift {
- class QtTabWidget : public QTabWidget {
- Q_OBJECT
- public:
- QtTabWidget(QWidget* parent);
- virtual ~QtTabWidget();
+ class QtTabWidget : public QTabWidget {
+ Q_OBJECT
+ public:
+ QtTabWidget(QWidget* parent);
+ virtual ~QtTabWidget();
- QTabBar* tabBar();
- void setTabBar(QTabBar* tabBar);
- };
+ QTabBar* tabBar();
+ void setTabBar(QTabBar* tabBar);
+
+ protected:
+ virtual void dragEnterEvent(QDragEnterEvent* event);
+ virtual void dropEvent(QDropEvent* event);
+ virtual void paintEvent(QPaintEvent* event);
+ };
}
diff --git a/Swift/QtUI/QtTabbable.cpp b/Swift/QtUI/QtTabbable.cpp
index 2a0bbc2..df2cbfe 100644
--- a/Swift/QtUI/QtTabbable.cpp
+++ b/Swift/QtUI/QtTabbable.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -10,7 +10,6 @@
#include <QKeyEvent>
#include <QShortcut>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Base/Platform.h>
#include <Swift/QtUI/QtChatTabs.h>
@@ -23,47 +22,52 @@ QtTabbable::QtTabbable() : QWidget() {
}
QtTabbable::~QtTabbable() {
- emit windowClosing();
+
}
bool QtTabbable::isWidgetSelected() {
- /*isActiveWindow() shouldn't be necessary, but I don't trust it as far as I can throw it*/
- if (!isActiveWindow()) {
- return false;
- }
- QtChatTabs* parent = qobject_cast<QtChatTabs*>(window());
- return parent ? parent->getCurrentTab() == this : isAncestorOf(QApplication::focusWidget());
+ /*isActiveWindow() shouldn't be necessary, but I don't trust it as far as I can throw it*/
+ if (!isActiveWindow()) {
+ return false;
+ }
+ QtChatTabs* parent = qobject_cast<QtChatTabs*>(window());
+ return parent ? parent->getCurrentTab() == this : isAncestorOf(QApplication::focusWidget());
}
bool QtTabbable::event(QEvent* event) {
- QKeyEvent* keyEvent = dynamic_cast<QKeyEvent*>(event);
- if (keyEvent) {
- // According to Qt's focus documentation, one can only override CTRL+TAB via reimplementing QWidget::event().
- if (keyEvent->modifiers().testFlag(QtUtilities::ctrlHardwareKeyModifier) && keyEvent->key() == Qt::Key_Tab) {
- // Only handle KeyRelease event as Linux also generate KeyPress event in case of CTRL+TAB being pressed
- // in the roster of a MUC.
- if (keyEvent->type() == QEvent::KeyRelease) {
- emit requestNextTab();
- }
- return true;
- }
+ QKeyEvent* keyEvent = dynamic_cast<QKeyEvent*>(event);
+ if (keyEvent) {
+ // According to Qt's focus documentation, one can only override CTRL+TAB via reimplementing QWidget::event().
+ if (keyEvent->modifiers().testFlag(QtUtilities::ctrlHardwareKeyModifier) && keyEvent->key() == Qt::Key_Tab) {
+ // Only handle KeyRelease event as Linux also generate KeyPress event in case of CTRL+TAB being pressed
+ // in the roster of a MUC.
+ if (keyEvent->type() == QEvent::KeyRelease) {
+ emit requestNextTab();
+ }
+ return true;
+ }
#ifdef SWIFTEN_PLATFORM_LINUX
- else if (keyEvent->modifiers().testFlag(QtUtilities::ctrlHardwareKeyModifier) && keyEvent->key() == Qt::Key_Backtab && keyEvent->type() != QEvent::KeyRelease) {
+ else if (keyEvent->modifiers().testFlag(QtUtilities::ctrlHardwareKeyModifier) && keyEvent->key() == Qt::Key_Backtab && keyEvent->type() != QEvent::KeyRelease) {
#else
- else if (keyEvent->modifiers().testFlag(QtUtilities::ctrlHardwareKeyModifier) && keyEvent->key() == Qt::Key_Backtab) {
+ else if (keyEvent->modifiers().testFlag(QtUtilities::ctrlHardwareKeyModifier) && keyEvent->key() == Qt::Key_Backtab) {
#endif
#ifdef SWIFTEN_PLATFORM_WINDOWS
- // Windows emits both the KeyPress and KeyRelease events.
- if (keyEvent->type() == QEvent::KeyPress) {
+ // Windows emits both the KeyPress and KeyRelease events.
+ if (keyEvent->type() == QEvent::KeyPress) {
#else
- if (keyEvent->type() != QEvent::ShortcutOverride) {
+ if (keyEvent->type() != QEvent::ShortcutOverride) {
#endif
- emit requestPreviousTab();
- }
- return true;
- }
- }
- return QWidget::event(event);
+ emit requestPreviousTab();
+ }
+ return true;
+ }
+ }
+ return QWidget::event(event);
+}
+
+void QtTabbable::closeEvent(QCloseEvent* event) {
+ emit windowClosing();
+ event->accept();
}
}
diff --git a/Swift/QtUI/QtTabbable.h b/Swift/QtUI/QtTabbable.h
index db83ba9..5837702 100644
--- a/Swift/QtUI/QtTabbable.h
+++ b/Swift/QtUI/QtTabbable.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -11,29 +11,32 @@
#include <QWidget>
namespace Swift {
- class QtTabbable : public QWidget {
- Q_OBJECT
- public:
- enum AlertType {NoActivity, WaitingActivity, ImpendingActivity};
- virtual ~QtTabbable();
- bool isWidgetSelected();
- virtual AlertType getWidgetAlertState() {return NoActivity;}
- virtual int getCount() {return 0;}
- virtual std::string getID() const = 0;
+ class QtTabbable : public QWidget {
+ Q_OBJECT
+ public:
+ enum AlertType {NoActivity, WaitingActivity, ImpendingActivity};
+ virtual ~QtTabbable();
- protected:
- QtTabbable();
- bool event(QEvent* event);
+ bool isWidgetSelected();
+ virtual AlertType getWidgetAlertState() {return NoActivity;}
+ virtual int getCount() {return 0;}
+ virtual std::string getID() const = 0;
+ virtual void setEmphasiseFocus(bool /*emphasise*/) {}
- signals:
- void titleUpdated();
- void countUpdated();
- void windowClosing();
- void windowOpening();
- void wantsToActivate();
- void requestPreviousTab();
- void requestNextTab();
- void requestActiveTab();
- void requestFlash();
- };
+ protected:
+ QtTabbable();
+ virtual bool event(QEvent* event);
+ virtual void closeEvent(QCloseEvent* event);
+
+ signals:
+ void titleUpdated();
+ void countUpdated();
+ void windowClosing();
+ void windowOpening();
+ void wantsToActivate();
+ void requestPreviousTab();
+ void requestNextTab();
+ void requestActiveTab();
+ void requestFlash();
+ };
}
diff --git a/Swift/QtUI/QtTextEdit.cpp b/Swift/QtUI/QtTextEdit.cpp
index a0188d9..e9708bf 100644
--- a/Swift/QtUI/QtTextEdit.cpp
+++ b/Swift/QtUI/QtTextEdit.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -12,210 +12,256 @@
#include <QApplication>
#include <QKeyEvent>
+#include <QKeySequence>
#include <QMenu>
-#include <QTime>
#include <QTextDocument>
-#include <Swiften/Base/foreach.h>
-
-#include <Swift/Controllers/SettingConstants.h>
+#include <Swiften/Base/Log.h>
#include <SwifTools/SpellChecker.h>
#include <SwifTools/SpellCheckerFactory.h>
#include <Swift/QtUI/QtSpellCheckerWindow.h>
#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/QtUISettingConstants.h>
#include <Swift/QtUI/QtUtilities.h>
namespace Swift {
-QtTextEdit::QtTextEdit(SettingsProvider* settings, QWidget* parent) : QTextEdit(parent), checker_(NULL), highlighter_(NULL) {
- connect(this, SIGNAL(textChanged()), this, SLOT(handleTextChanged()));
- settings_ = settings;
+QtTextEdit::QtTextEdit(SettingsProvider* settings, QWidget* parent) : QTextEdit(parent), checker_(nullptr), highlighter_(nullptr) {
+ connect(this, SIGNAL(textChanged()), this, SLOT(handleTextChanged()));
+ settings_ = settings;
#ifdef HAVE_SPELLCHECKER
- setUpSpellChecker();
+ setUpSpellChecker();
#endif
- handleTextChanged();
- QTextOption textOption = document()->defaultTextOption();
- textOption.setWrapMode(QTextOption::WordWrap);
- document()->setDefaultTextOption(textOption);
+ handleTextChanged();
+ QTextOption textOption = document()->defaultTextOption();
+ textOption.setWrapMode(QTextOption::WordWrap);
+ document()->setDefaultTextOption(textOption);
}
QtTextEdit::~QtTextEdit() {
- delete checker_;
+ delete checker_;
}
void QtTextEdit::keyPressEvent(QKeyEvent* event) {
- int key = event->key();
- Qt::KeyboardModifiers modifiers = event->modifiers();
- if ((key == Qt::Key_Enter || key == Qt::Key_Return)
- && (modifiers == Qt::NoModifier || modifiers == Qt::KeypadModifier)) {
- emit returnPressed();
- }
- else if (((key == Qt::Key_PageUp || key == Qt::Key_PageDown) && modifiers == Qt::ShiftModifier)
- || (key == Qt::Key_C && modifiers == Qt::ControlModifier && textCursor().selectedText().isEmpty())
- || (key == Qt::Key_W && modifiers == Qt::ControlModifier)
- || (key == Qt::Key_PageUp && modifiers == Qt::ControlModifier)
- || (key == Qt::Key_PageDown && modifiers == Qt::ControlModifier)
- || (key == Qt::Key_Tab && modifiers == Qt::ControlModifier)
- || (key == Qt::Key_A && modifiers == Qt::AltModifier)
- || (key == Qt::Key_Tab)
- ) {
- emit unhandledKeyPressEvent(event);
- }
- else if ((key == Qt::Key_Up)
- || (key == Qt::Key_Down)) {
- emit unhandledKeyPressEvent(event);
- QTextEdit::keyPressEvent(event);
- }
- else if ((key == Qt::Key_K && modifiers == QtUtilities::ctrlHardwareKeyModifier)) {
- QTextCursor cursor = textCursor();
- cursor.setPosition(toPlainText().size(), QTextCursor::KeepAnchor);
- cursor.removeSelectedText();
- }
- else {
- QTextEdit::keyPressEvent(event);
- }
+ int key = event->key();
+ Qt::KeyboardModifiers modifiers = event->modifiers();
+ if ((key == Qt::Key_Enter || key == Qt::Key_Return)
+ && (modifiers == Qt::NoModifier || modifiers == Qt::KeypadModifier)) {
+ emit returnPressed();
+ }
+ else if (((key == Qt::Key_PageUp || key == Qt::Key_PageDown) && modifiers == Qt::ShiftModifier)
+ || (key == Qt::Key_C && modifiers == Qt::ControlModifier && textCursor().selectedText().isEmpty())
+ || (key == Qt::Key_W && modifiers == Qt::ControlModifier)
+ || (key == Qt::Key_PageUp && modifiers == Qt::ControlModifier)
+ || (key == Qt::Key_PageDown && modifiers == Qt::ControlModifier)
+ || (key == Qt::Key_Tab && modifiers == Qt::ControlModifier)
+ || (key == Qt::Key_A && modifiers == Qt::AltModifier)
+ || (key == Qt::Key_Tab)
+ || (event->matches(QKeySequence::ZoomIn))
+ || (event->matches(QKeySequence::ZoomOut))
+ ) {
+ emit unhandledKeyPressEvent(event);
+ }
+ else if ((key == Qt::Key_Up)
+ || (key == Qt::Key_Down)) {
+ emit unhandledKeyPressEvent(event);
+ QTextEdit::keyPressEvent(event);
+ }
+ else if ((key == Qt::Key_K && modifiers == QtUtilities::ctrlHardwareKeyModifier)) {
+ QTextCursor cursor = textCursor();
+ cursor.setPosition(toPlainText().size(), QTextCursor::KeepAnchor);
+ cursor.removeSelectedText();
+ }
+ else {
+ QTextEdit::keyPressEvent(event);
+ }
+}
+
+void QtTextEdit::setEmphasiseFocus(bool emphasise) {
+ emphasiseFocus_ = emphasise;
+ updateStyleSheet();
+}
+
+void QtTextEdit::setCorrectionHighlight(bool correctionHighlight) {
+ correctionHighlight_ = correctionHighlight;
+ updateStyleSheet();
+}
+
+void QtTextEdit::updateStyleSheet() {
+ QString newStyleSheet;
+
+ if (correctionHighlight_) {
+ newStyleSheet += "background: rgb(255, 255, 153); color: black;";
+ }
+
+ if (emphasiseFocus_) {
+ if (hasFocus()) {
+ newStyleSheet += "border: 2px solid palette(highlight);";
+ }
+ }
+
+ setStyleSheet(newStyleSheet);
+ handleTextChanged();
}
void QtTextEdit::focusInEvent(QFocusEvent* event) {
- receivedFocus();
- QTextEdit::focusInEvent(event);
+ receivedFocus();
+ QTextEdit::focusInEvent(event);
+ updateStyleSheet();
}
void QtTextEdit::focusOutEvent(QFocusEvent* event) {
- lostFocus();
- QTextEdit::focusOutEvent(event);
+ lostFocus();
+ QTextEdit::focusOutEvent(event);
+ updateStyleSheet();
}
void QtTextEdit::handleTextChanged() {
- QSize previous(maximumSize());
- setMaximumSize(QSize(maximumWidth(), sizeHint().height()));
- if (previous != maximumSize()) {
- updateGeometry();
- }
+ QSize previous(maximumSize());
+ setMaximumSize(QSize(maximumWidth(), sizeHint().height()));
+ if (previous != maximumSize()) {
+ updateGeometry();
+ }
}
void QtTextEdit::replaceMisspelledWord(const QString& word, int cursorPosition) {
- QTextCursor cursor = textCursor();
- PositionPair wordPosition = getWordFromCursor(cursorPosition);
- cursor.setPosition(boost::get<0>(wordPosition), QTextCursor::MoveAnchor);
- cursor.setPosition(boost::get<1>(wordPosition), QTextCursor::KeepAnchor);
- QTextCharFormat normalFormat;
- cursor.insertText(word, normalFormat);
+ QTextCursor cursor = textCursor();
+ PositionPair wordPosition = getWordFromCursor(cursorPosition);
+ cursor.setPosition(boost::get<0>(wordPosition), QTextCursor::MoveAnchor);
+ cursor.setPosition(boost::get<1>(wordPosition), QTextCursor::KeepAnchor);
+ QTextCharFormat normalFormat;
+ cursor.insertText(word, normalFormat);
}
PositionPair QtTextEdit::getWordFromCursor(int cursorPosition) {
- PositionPairList misspelledPositions = highlighter_->getMisspelledPositions();
- for (PositionPairList::iterator it = misspelledPositions.begin(); it != misspelledPositions.end(); ++it) {
- if (cursorPosition >= boost::get<0>(*it) && cursorPosition <= boost::get<1>(*it)) {
- return *it;
- }
- }
- return boost::make_tuple(-1,-1);
+ PositionPairList misspelledPositions = highlighter_->getMisspelledPositions();
+ for (auto& misspelledPosition : misspelledPositions) {
+ if (cursorPosition >= boost::get<0>(misspelledPosition) && cursorPosition <= boost::get<1>(misspelledPosition)) {
+ return misspelledPosition;
+ }
+ }
+ return boost::make_tuple(-1,-1);
}
QSize QtTextEdit::sizeHint() const {
- QSize hint = document()->size().toSize();
- QMargins margins = contentsMargins();
- return hint + QSize(margins.left() + margins.right(), margins.top() + margins.bottom());
+ QSize hint = document()->size().toSize();
+ QMargins margins = contentsMargins();
+ return hint + QSize(margins.left() + margins.right(), margins.top() + margins.bottom());
}
void QtTextEdit::contextMenuEvent(QContextMenuEvent* event) {
- QMenu* menu = createStandardContextMenu();
- QTextCursor cursor = cursorForPosition(event->pos());
+ QMenu* menu = createStandardContextMenu();
+ QTextCursor cursor = cursorForPosition(event->pos());
#ifdef HAVE_SPELLCHECKER
- QAction* insertPoint = menu->actions().first();
- QAction* settingsAction = new QAction(tr("Spell Checker Options"), menu);
- menu->insertAction(insertPoint, settingsAction);
- menu->insertAction(insertPoint, menu->addSeparator());
- addSuggestions(menu, event);
- QAction* result = menu->exec(event->globalPos());
- if (result == settingsAction) {
- spellCheckerSettingsWindow();
- }
- for (std::vector<QAction*>::iterator it = replaceWordActions_.begin(); it != replaceWordActions_.end(); ++it) {
- if (*it == result) {
- replaceMisspelledWord((*it)->text(), cursor.position());
- }
- }
+ QAction* insertPoint = menu->actions().first();
+ QAction* settingsAction = new QAction(tr("Spell Checker Options"), menu);
+ menu->insertAction(insertPoint, settingsAction);
+ menu->insertAction(insertPoint, menu->addSeparator());
+ addSuggestions(menu, event);
+ QAction* result = menu->exec(event->globalPos());
+ if (result == settingsAction) {
+ spellCheckerSettingsWindow();
+ }
+ for (auto& replaceWordAction : replaceWordActions_) {
+ if (replaceWordAction == result) {
+ replaceMisspelledWord(replaceWordAction->text(), cursor.position());
+ }
+ }
#else
- menu->exec(event->globalPos());
+ menu->exec(event->globalPos());
#endif
- delete menu;
+ delete menu;
}
void QtTextEdit::addSuggestions(QMenu* menu, QContextMenuEvent* event)
{
- replaceWordActions_.clear();
- if (checker_ && highlighter_) {
- QAction* insertPoint = menu->actions().first();
- QTextCursor cursor = cursorForPosition(event->pos());
- PositionPair wordPosition = getWordFromCursor(cursor.position());
- if (boost::get<0>(wordPosition) < 0) {
- // The click was executed outside a spellable word so no
- // suggestions are necessary
- return;
- }
- cursor.setPosition(boost::get<0>(wordPosition), QTextCursor::MoveAnchor);
- cursor.setPosition(boost::get<1>(wordPosition), QTextCursor::KeepAnchor);
- std::vector<std::string> wordList;
- checker_->getSuggestions(Q2PSTRING(cursor.selectedText()), wordList);
- if (wordList.size() == 0) {
- QAction* noSuggestions = new QAction(tr("No Suggestions"), menu);
- noSuggestions->setDisabled(true);
- menu->insertAction(insertPoint, noSuggestions);
- }
- else {
- for (std::vector<std::string>::iterator it = wordList.begin(); it != wordList.end(); ++it) {
- QAction* wordAction = new QAction(it->c_str(), menu);
- menu->insertAction(insertPoint, wordAction);
- replaceWordActions_.push_back(wordAction);
- }
- }
- menu->insertAction(insertPoint, menu->addSeparator());
- }
+ replaceWordActions_.clear();
+ if (checker_ && highlighter_) {
+ QAction* insertPoint = menu->actions().first();
+ QTextCursor cursor = cursorForPosition(event->pos());
+ PositionPair wordPosition = getWordFromCursor(cursor.position());
+ if (boost::get<0>(wordPosition) < 0) {
+ // The click was executed outside a spellable word so no
+ // suggestions are necessary
+ return;
+ }
+ cursor.setPosition(boost::get<0>(wordPosition), QTextCursor::MoveAnchor);
+ cursor.setPosition(boost::get<1>(wordPosition), QTextCursor::KeepAnchor);
+ std::vector<std::string> wordList;
+ checker_->getSuggestions(Q2PSTRING(cursor.selectedText()), wordList);
+ if (wordList.size() == 0) {
+ QAction* noSuggestions = new QAction(tr("No Suggestions"), menu);
+ noSuggestions->setDisabled(true);
+ menu->insertAction(insertPoint, noSuggestions);
+ }
+ else {
+ for (auto& word : wordList) {
+ QAction* wordAction = new QAction(word.c_str(), menu);
+ menu->insertAction(insertPoint, wordAction);
+ replaceWordActions_.push_back(wordAction);
+ }
+ }
+ menu->insertAction(insertPoint, menu->addSeparator());
+ }
}
#ifdef HAVE_SPELLCHECKER
-void QtTextEdit::setUpSpellChecker()
-{
- delete checker_;
- checker_ = NULL;
- if (settings_->getSetting(SettingConstants::SPELL_CHECKER)) {
- std::string dictPath = settings_->getSetting(SettingConstants::DICT_PATH);
- std::string dictFile = settings_->getSetting(SettingConstants::DICT_FILE);
- checker_ = SpellCheckerFactory().createSpellChecker(dictPath + dictFile);
- delete highlighter_;
- highlighter_ = NULL;
- highlighter_ = new QtSpellCheckHighlighter(document(), checker_);
- }
+void QtTextEdit::setUpSpellChecker() {
+ delete highlighter_;
+ highlighter_ = nullptr;
+ delete checker_;
+ checker_ = nullptr;
+ if (settings_->getSetting(QtUISettingConstants::SPELL_CHECKER)) {
+ checker_ = SpellCheckerFactory().createSpellChecker();
+ if (checker_) {
+ if (!checker_->isAutomaticallyDetectingLanguage()) {
+ checker_->setActiveLanguage(settings_->getSetting(QtUISettingConstants::SPELL_CHECKER_LANGUAGE));
+ }
+ highlighter_ = new QtSpellCheckHighlighter(document(), checker_);
+ }
+ else {
+ // Spellchecking is not working, as we did not get a valid checker from the factory. Disable spellchecking.
+ SWIFT_LOG(warning) << "Spellchecking is currently misconfigured in Swift (e.g. missing dictionary or broken dictionary file). Disable spellchecking." << std::endl;
+ settings_->storeSetting(QtUISettingConstants::SPELL_CHECKER, false);
+ }
+
+ }
}
#endif
void QtTextEdit::spellCheckerSettingsWindow() {
- if (!spellCheckerWindow_) {
- spellCheckerWindow_ = new QtSpellCheckerWindow(settings_);
- settings_->onSettingChanged.connect(boost::bind(&QtTextEdit::handleSettingChanged, this, _1));
- spellCheckerWindow_->show();
- }
- else {
- spellCheckerWindow_->show();
- spellCheckerWindow_->raise();
- spellCheckerWindow_->activateWindow();
- }
+ if (!spellCheckerWindow_) {
+ spellCheckerWindow_ = new QtSpellCheckerWindow(settings_);
+ settings_->onSettingChanged.connect(boost::bind(&QtTextEdit::handleSettingChanged, this, _1));
+ spellCheckerWindow_->show();
+ }
+ else {
+ spellCheckerWindow_->show();
+ spellCheckerWindow_->raise();
+ spellCheckerWindow_->activateWindow();
+ }
+ if (checker_) {
+ spellCheckerWindow_->setAutomaticallyIdentifiesLanguage(checker_->isAutomaticallyDetectingLanguage());
+ if (!checker_->isAutomaticallyDetectingLanguage()) {
+ spellCheckerWindow_->setSupportedLanguages(checker_->supportedLanguages());
+ spellCheckerWindow_->setActiveLanguage(checker_->activeLanguage());
+ }
+ }
}
void QtTextEdit::handleSettingChanged(const std::string& settings) {
- if (settings == SettingConstants::SPELL_CHECKER.getKey()
- || settings == SettingConstants::DICT_PATH.getKey()
- || settings == SettingConstants::DICT_FILE.getKey()) {
+ if (settings == QtUISettingConstants::SPELL_CHECKER.getKey() ||
+ settings == QtUISettingConstants::SPELL_CHECKER_LANGUAGE.getKey()) {
#ifdef HAVE_SPELLCHECKER
- setUpSpellChecker();
- highlighter_->rehighlight();
+ setUpSpellChecker();
+ if (highlighter_) {
+ highlighter_->rehighlight();
+ }
#endif
- }
+ }
}
}
diff --git a/Swift/QtUI/QtTextEdit.h b/Swift/QtUI/QtTextEdit.h
index 67826ba..228aa9e 100644
--- a/Swift/QtUI/QtTextEdit.h
+++ b/Swift/QtUI/QtTextEdit.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -9,7 +9,6 @@
#include <QPointer>
#include <QTextEdit>
-#include <Swift/Controllers/SettingConstants.h>
#include <Swift/Controllers/Settings/SettingsProvider.h>
#include <SwifTools/SpellParser.h>
@@ -17,47 +16,53 @@
#include <Swift/QtUI/QtSpellCheckHighlighter.h>
namespace Swift {
- class SpellChecker;
- class QtSpellCheckerWindow;
-
- class QtTextEdit : public QTextEdit {
- Q_OBJECT
- public:
- QtTextEdit(SettingsProvider* settings, QWidget* parent = 0);
- virtual ~QtTextEdit();
- virtual QSize sizeHint() const;
-
- signals:
- void wordCorrected(QString& word);
- void returnPressed();
- void unhandledKeyPressEvent(QKeyEvent* event);
- void receivedFocus();
- void lostFocus();
-
- public slots:
- void handleSettingChanged(const std::string& settings);
-
- protected:
- virtual void keyPressEvent(QKeyEvent* event);
- virtual void focusInEvent(QFocusEvent* event);
- virtual void focusOutEvent(QFocusEvent* event);
- virtual void contextMenuEvent(QContextMenuEvent* event);
-
- private slots:
- void handleTextChanged();
-
- private:
- void addSuggestions(QMenu* menu, QContextMenuEvent* event);
- void replaceMisspelledWord(const QString& word, int cursorPosition);
- void setUpSpellChecker();
- void spellCheckerSettingsWindow();
- PositionPair getWordFromCursor(int cursorPosition);
-
- private:
- SpellChecker* checker_;
- QtSpellCheckHighlighter* highlighter_;
- std::vector<QAction*> replaceWordActions_;
- SettingsProvider* settings_;
- QPointer<QtSpellCheckerWindow> spellCheckerWindow_;
- };
+ class SpellChecker;
+ class QtSpellCheckerWindow;
+
+ class QtTextEdit : public QTextEdit {
+ Q_OBJECT
+ public:
+ QtTextEdit(SettingsProvider* settings, QWidget* parent = nullptr);
+ virtual ~QtTextEdit();
+ virtual QSize sizeHint() const;
+
+ void setEmphasiseFocus(bool emphasise);
+ void setCorrectionHighlight(bool coorectionHighlight);
+
+ signals:
+ void wordCorrected(QString& word);
+ void returnPressed();
+ void unhandledKeyPressEvent(QKeyEvent* event);
+ void receivedFocus();
+ void lostFocus();
+
+ public slots:
+ void handleSettingChanged(const std::string& settings);
+
+ protected:
+ virtual void keyPressEvent(QKeyEvent* event);
+ virtual void focusInEvent(QFocusEvent* event);
+ virtual void focusOutEvent(QFocusEvent* event);
+ virtual void contextMenuEvent(QContextMenuEvent* event);
+
+ private slots:
+ void handleTextChanged();
+
+ private:
+ void addSuggestions(QMenu* menu, QContextMenuEvent* event);
+ void replaceMisspelledWord(const QString& word, int cursorPosition);
+ void setUpSpellChecker();
+ void spellCheckerSettingsWindow();
+ PositionPair getWordFromCursor(int cursorPosition);
+ void updateStyleSheet();
+
+ private:
+ SpellChecker* checker_;
+ QtSpellCheckHighlighter* highlighter_;
+ std::vector<QAction*> replaceWordActions_;
+ SettingsProvider* settings_;
+ QPointer<QtSpellCheckerWindow> spellCheckerWindow_;
+ bool emphasiseFocus_ = false;
+ bool correctionHighlight_ = false;
+ };
}
diff --git a/Swift/QtUI/QtTranslator.h b/Swift/QtUI/QtTranslator.h
index b74ea3e..92abf77 100644
--- a/Swift/QtUI/QtTranslator.h
+++ b/Swift/QtUI/QtTranslator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,19 +7,31 @@
#pragma once
#include <QCoreApplication>
+#include <QDateTime>
#include <Swift/Controllers/Translator.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
+
class QtTranslator : public Swift::Translator {
- public:
- QtTranslator() {
- }
+ public:
+ QtTranslator() {
+ }
- virtual std::string translate(const std::string& text, const std::string& context) {
+ virtual std::string translate(const std::string& text, const std::string& context) {
#if QT_VERSION >= 0x050000
- return std::string(QCoreApplication::translate(context.c_str(), text.c_str(), 0).toUtf8());
+ return std::string(QCoreApplication::translate(context.c_str(), text.c_str(), nullptr).toUtf8());
#else
- return std::string(QCoreApplication::translate(context.c_str(), text.c_str(), 0, QCoreApplication::UnicodeUTF8).toUtf8());
+ return std::string(QCoreApplication::translate(context.c_str(), text.c_str(), 0, QCoreApplication::UnicodeUTF8).toUtf8());
#endif
- }
+ }
+
+ virtual std::string ptimeToHumanReadableString(const boost::posix_time::ptime& time) {
+ return Q2PSTRING(QDateTime::fromTime_t(posixTimeToTimeT(time)).toString(Qt::SystemLocaleLongDate));
+ }
+
+ private:
+ static std::time_t posixTimeToTimeT(boost::posix_time::ptime pt) {
+ return std::time_t((pt - boost::posix_time::ptime(boost::gregorian::date(1970,1,1))).total_seconds());
+ }
};
diff --git a/Swift/QtUI/QtUIFactory.cpp b/Swift/QtUI/QtUIFactory.cpp
index 8dece86..9eed822 100644
--- a/Swift/QtUI/QtUIFactory.cpp
+++ b/Swift/QtUI/QtUIFactory.cpp
@@ -1,185 +1,191 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/QtUIFactory.h>
+#include <algorithm>
+
#include <QSplitter>
-#include <Swift/QtUI/QtXMLConsoleWidget.h>
+#include <Swiften/Whiteboard/WhiteboardSession.h>
+
+#include <Swift/Controllers/Settings/SettingsProviderHierachy.h>
+
+#include <Swift/QtUI/MUCSearch/QtMUCSearchWindow.h>
+#include <Swift/QtUI/QtAdHocCommandWindow.h>
+#include <Swift/QtUI/QtBlockListEditorWindow.h>
#include <Swift/QtUI/QtChatTabs.h>
#include <Swift/QtUI/QtChatTabsBase.h>
-#include <Swift/QtUI/QtMainWindow.h>
-#include <Swift/QtUI/QtLoginWindow.h>
-#include <Swift/QtUI/QtSystemTray.h>
-#include <Swift/QtUI/QtSettingsProvider.h>
-#include <Swift/QtUI/QtMainWindow.h>
#include <Swift/QtUI/QtChatWindow.h>
-#include <Swift/QtUI/QtJoinMUCWindow.h>
#include <Swift/QtUI/QtChatWindowFactory.h>
-#include <Swift/QtUI/QtSwiftUtil.h>
-#include <Swift/QtUI/MUCSearch/QtMUCSearchWindow.h>
-#include <Swift/QtUI/UserSearch/QtUserSearchWindow.h>
-#include <Swift/QtUI/QtProfileWindow.h>
#include <Swift/QtUI/QtContactEditWindow.h>
-#include <Swift/QtUI/QtAdHocCommandWindow.h>
#include <Swift/QtUI/QtFileTransferListWidget.h>
#include <Swift/QtUI/QtHighlightEditor.h>
-#include <Swift/QtUI/Whiteboard/QtWhiteboardWindow.h>
-#include <Swift/Controllers/Settings/SettingsProviderHierachy.h>
-#include <Swift/QtUI/QtUISettingConstants.h>
#include <Swift/QtUI/QtHistoryWindow.h>
-#include <Swiften/Whiteboard/WhiteboardSession.h>
+#include <Swift/QtUI/QtJoinMUCWindow.h>
+#include <Swift/QtUI/QtLoginWindow.h>
+#include <Swift/QtUI/QtMainWindow.h>
+#include <Swift/QtUI/QtProfileWindow.h>
+#include <Swift/QtUI/QtSettingsProvider.h>
#include <Swift/QtUI/QtSingleWindow.h>
-#include <Swift/QtUI/QtBlockListEditorWindow.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/QtSystemTray.h>
+#include <Swift/QtUI/QtUISettingConstants.h>
+#include <Swift/QtUI/QtXMLConsoleWidget.h>
+#include <Swift/QtUI/UserSearch/QtUserSearchWindow.h>
+#include <Swift/QtUI/Whiteboard/QtWhiteboardWindow.h>
namespace Swift {
-QtUIFactory::QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabsBase* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, StatusCache* statusCache, bool startMinimized, bool emoticonsExist, bool enableAdHocCommandOnJID) : settings(settings), qtOnlySettings(qtOnlySettings), tabsBase(tabs), netbookSplitter(netbookSplitter), systemTray(systemTray), chatWindowFactory(chatWindowFactory), timerFactory_(timerFactory), lastMainWindow(NULL), loginWindow(NULL), statusCache(statusCache), startMinimized(startMinimized), emoticonsExist_(emoticonsExist), enableAdHocCommandOnJID_(enableAdHocCommandOnJID) {
- chatFontSize = settings->getSetting(QtUISettingConstants::CHATWINDOW_FONT_SIZE);
- historyFontSize_ = settings->getSetting(QtUISettingConstants::HISTORYWINDOW_FONT_SIZE);
- this->tabs = dynamic_cast<QtChatTabs*>(tabsBase);
+QtUIFactory::QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabsBase* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, StatusCache* statusCache, bool startMinimized, bool emoticonsExist, bool enableAdHocCommandOnJID) : settings(settings), qtOnlySettings(qtOnlySettings), tabsBase(tabs), netbookSplitter(netbookSplitter), systemTray(systemTray), chatWindowFactory(chatWindowFactory), timerFactory_(timerFactory), lastMainWindow(nullptr), loginWindow(nullptr), statusCache(statusCache), startMinimized(startMinimized), emoticonsExist_(emoticonsExist), enableAdHocCommandOnJID_(enableAdHocCommandOnJID) {
+ chatFontSize = settings->getSetting(QtUISettingConstants::CHATWINDOW_FONT_SIZE);
+ historyFontSize_ = settings->getSetting(QtUISettingConstants::HISTORYWINDOW_FONT_SIZE);
+ this->tabs = dynamic_cast<QtChatTabs*>(tabsBase);
}
XMLConsoleWidget* QtUIFactory::createXMLConsoleWidget() {
- QtXMLConsoleWidget* widget = new QtXMLConsoleWidget();
- tabsBase->addTab(widget);
- showTabs();
- widget->show();
- return widget;
+ QtXMLConsoleWidget* widget = new QtXMLConsoleWidget();
+ tabsBase->addTab(widget);
+ showTabs();
+ widget->show();
+ return widget;
}
HistoryWindow* QtUIFactory::createHistoryWindow(UIEventStream* uiEventStream) {
- QtHistoryWindow* window = new QtHistoryWindow(settings, uiEventStream);
- tabsBase->addTab(window);
- showTabs();
- connect(window, SIGNAL(fontResized(int)), this, SLOT(handleHistoryWindowFontResized(int)));
+ QtHistoryWindow* window = new QtHistoryWindow(settings, uiEventStream);
+ tabsBase->addTab(window);
+ showTabs();
+ connect(window, SIGNAL(fontResized(int)), this, SLOT(handleHistoryWindowFontResized(int)));
- window->handleFontResized(historyFontSize_);
- window->show();
- return window;
+ window->handleFontResized(historyFontSize_);
+ window->show();
+ return window;
}
void QtUIFactory::handleHistoryWindowFontResized(int size) {
- historyFontSize_ = size;
- settings->storeSetting(QtUISettingConstants::HISTORYWINDOW_FONT_SIZE, size);
+ historyFontSize_ = size;
+ settings->storeSetting(QtUISettingConstants::HISTORYWINDOW_FONT_SIZE, size);
}
FileTransferListWidget* QtUIFactory::createFileTransferListWidget() {
- QtFileTransferListWidget* widget = new QtFileTransferListWidget();
- tabsBase->addTab(widget);
- showTabs();
- widget->show();
- return widget;
+ QtFileTransferListWidget* widget = new QtFileTransferListWidget();
+ tabsBase->addTab(widget);
+ showTabs();
+ widget->show();
+ return widget;
}
MainWindow* QtUIFactory::createMainWindow(UIEventStream* eventStream) {
- lastMainWindow = new QtMainWindow(settings, eventStream, loginWindow->getMenus(), statusCache, emoticonsExist_, enableAdHocCommandOnJID_);
- if (tabs) {
- tabs->setViewMenu(lastMainWindow->getMenus()[0]);
- }
- return lastMainWindow;
+ lastMainWindow = new QtMainWindow(settings, eventStream, loginWindow->getMenus(), statusCache, emoticonsExist_, enableAdHocCommandOnJID_);
+ if (tabs) {
+ tabs->setViewMenu(lastMainWindow->getMenus()[0]);
+ }
+ return lastMainWindow;
}
LoginWindow* QtUIFactory::createLoginWindow(UIEventStream* eventStream) {
- loginWindow = new QtLoginWindow(eventStream, settings, timerFactory_);
- if (netbookSplitter) {
- netbookSplitter->insertAtFront(loginWindow);
- }
- connect(systemTray, SIGNAL(clicked()), loginWindow, SLOT(toggleBringToFront()));
+ loginWindow = new QtLoginWindow(eventStream, settings, timerFactory_);
+ if (netbookSplitter) {
+ netbookSplitter->insertAtFront(loginWindow);
+ }
+ connect(systemTray, SIGNAL(clicked()), loginWindow, SLOT(toggleBringToFront()));
#ifndef SWIFT_MOBILE
- QVariant loginWindowGeometryVariant = qtOnlySettings->getQSettings()->value("loginWindowGeometry");
- if (loginWindowGeometryVariant.isValid()) {
- loginWindow->restoreGeometry(loginWindowGeometryVariant.toByteArray());
- }
- connect(loginWindow, SIGNAL(geometryChanged()), this, SLOT(handleLoginWindowGeometryChanged()));
- if (startMinimized) loginWindow->hide();
+ QVariant loginWindowGeometryVariant = qtOnlySettings->getQSettings()->value("loginWindowGeometry");
+ if (loginWindowGeometryVariant.isValid()) {
+ loginWindow->restoreGeometry(loginWindowGeometryVariant.toByteArray());
+ }
+ connect(loginWindow, SIGNAL(geometryChanged()), this, SLOT(handleLoginWindowGeometryChanged()));
+ if (startMinimized) loginWindow->hide();
#endif
- return loginWindow;
+ return loginWindow;
}
void QtUIFactory::handleLoginWindowGeometryChanged() {
- qtOnlySettings->getQSettings()->setValue("loginWindowGeometry", loginWindow->saveGeometry());
+ qtOnlySettings->getQSettings()->setValue("loginWindowGeometry", loginWindow->saveGeometry());
}
EventWindow* QtUIFactory::createEventWindow() {
- return lastMainWindow->getEventWindow();
+ return lastMainWindow->getEventWindow();
}
ChatListWindow* QtUIFactory::createChatListWindow(UIEventStream*) {
- return lastMainWindow->getChatListWindow();
+ return lastMainWindow->getChatListWindow();
}
MUCSearchWindow* QtUIFactory::createMUCSearchWindow() {
- return new QtMUCSearchWindow();
+ return new QtMUCSearchWindow();
}
ChatWindow* QtUIFactory::createChatWindow(const JID& contact, UIEventStream* eventStream) {
- QtChatWindow* window = dynamic_cast<QtChatWindow*>(chatWindowFactory->createChatWindow(contact, eventStream));
- chatWindows.push_back(window);
- std::vector<QPointer<QtChatWindow> > deletions;
- foreach (QPointer<QtChatWindow> existingWindow, chatWindows) {
- if (existingWindow.isNull()) {
- deletions.push_back(existingWindow);
- } else {
- connect(window, SIGNAL(fontResized(int)), existingWindow, SLOT(handleFontResized(int)));
- connect(existingWindow, SIGNAL(fontResized(int)), window, SLOT(handleFontResized(int)));
- }
- }
- foreach (QPointer<QtChatWindow> deletedWindow, deletions) {
- chatWindows.erase(std::remove(chatWindows.begin(), chatWindows.end(), deletedWindow), chatWindows.end());
- }
- connect(window, SIGNAL(fontResized(int)), this, SLOT(handleChatWindowFontResized(int)));
- window->handleFontResized(chatFontSize);
- return window;
+ QtChatWindow* window = dynamic_cast<QtChatWindow*>(chatWindowFactory->createChatWindow(contact, eventStream));
+
+ // remove already closed and thereby deleted chat windows
+ chatWindows.erase(std::remove_if(chatWindows.begin(), chatWindows.end(),
+ [](QPointer<QtChatWindow>& window) {
+ return window.isNull();
+ }), chatWindows.end());
+
+ chatWindows.push_back(window);
+
+ connect(window, SIGNAL(fontResized(int)), this, SLOT(handleChatWindowFontResized(int)));
+ window->handleFontResized(chatFontSize);
+ return window;
}
void QtUIFactory::handleChatWindowFontResized(int size) {
- chatFontSize = size;
- settings->storeSetting(QtUISettingConstants::CHATWINDOW_FONT_SIZE, size);
+ chatFontSize = size;
+ settings->storeSetting(QtUISettingConstants::CHATWINDOW_FONT_SIZE, size);
+
+ // resize font in other chat windows
+ for (auto&& existingWindow : chatWindows) {
+ if (!existingWindow.isNull()) {
+ existingWindow->handleFontResized(size);
+ }
+ }
}
UserSearchWindow* QtUIFactory::createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream, const std::set<std::string>& groups) {
- return new QtUserSearchWindow(eventStream, type, groups, qtOnlySettings);
+ return new QtUserSearchWindow(eventStream, type, groups, qtOnlySettings);
}
JoinMUCWindow* QtUIFactory::createJoinMUCWindow(UIEventStream* uiEventStream) {
- return new QtJoinMUCWindow(uiEventStream);
+ return new QtJoinMUCWindow(uiEventStream);
}
ProfileWindow* QtUIFactory::createProfileWindow() {
- return new QtProfileWindow();
+ return new QtProfileWindow();
}
ContactEditWindow* QtUIFactory::createContactEditWindow() {
- return new QtContactEditWindow();
+ return new QtContactEditWindow();
}
-WhiteboardWindow* QtUIFactory::createWhiteboardWindow(boost::shared_ptr<WhiteboardSession> whiteboardSession) {
- return new QtWhiteboardWindow(whiteboardSession);
+WhiteboardWindow* QtUIFactory::createWhiteboardWindow(std::shared_ptr<WhiteboardSession> whiteboardSession) {
+ return new QtWhiteboardWindow(whiteboardSession);
}
HighlightEditorWindow* QtUIFactory::createHighlightEditorWindow() {
- return new QtHighlightEditor(qtOnlySettings);
+ return new QtHighlightEditor(qtOnlySettings);
}
BlockListEditorWidget *QtUIFactory::createBlockListEditorWidget() {
- return new QtBlockListEditorWindow();
+ return new QtBlockListEditorWindow();
}
-AdHocCommandWindow* QtUIFactory::createAdHocCommandWindow(boost::shared_ptr<OutgoingAdHocCommandSession> command) {
- return new QtAdHocCommandWindow(command);
+AdHocCommandWindow* QtUIFactory::createAdHocCommandWindow(std::shared_ptr<OutgoingAdHocCommandSession> command) {
+ return new QtAdHocCommandWindow(command);
}
void QtUIFactory::showTabs() {
- if (tabs) {
- if (!tabs->isVisible()) {
- tabs->show();
- }
- }
+ if (tabs) {
+ if (!tabs->isVisible()) {
+ tabs->show();
+ }
+ }
}
}
diff --git a/Swift/QtUI/QtUIFactory.h b/Swift/QtUI/QtUIFactory.h
index 1d935bc..ce3b533 100644
--- a/Swift/QtUI/QtUIFactory.h
+++ b/Swift/QtUI/QtUIFactory.h
@@ -1,11 +1,13 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <vector>
+
#include <QObject>
#include <QPointer>
@@ -14,70 +16,69 @@
class QSplitter;
namespace Swift {
- class QtSettingsProvider;
- class SettingsProviderHierachy;
- class QtChatTabsBase;
- class QtChatTabs;
- class QtSystemTray;
- class QtLoginWindow;
- class QtMainWindow;
- class QtChatTheme;
- class QtChatWindowFactory;
- class QtChatWindow;
- class TimerFactory;
- class historyWindow_;
- class WhiteboardSession;
- class StatusCache;
- class QtSingleWindow;
+ class QtChatTabs;
+ class QtChatTabsBase;
+ class QtChatTheme;
+ class QtChatWindow;
+ class QtChatWindowFactory;
+ class QtLoginWindow;
+ class QtMainWindow;
+ class QtSettingsProvider;
+ class QtSingleWindow;
+ class QtSystemTray;
+ class SettingsProviderHierachy;
+ class StatusCache;
+ class TimerFactory;
+ class WhiteboardSession;
- class QtUIFactory : public QObject, public UIFactory {
- Q_OBJECT
- public:
- QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabsBase* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, StatusCache* statusCache, bool startMinimized, bool emoticonsExist, bool enableAdHocCommandOnJID);
+ class QtUIFactory : public QObject, public UIFactory {
+ Q_OBJECT
+ public:
+ QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabsBase* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, StatusCache* statusCache, bool startMinimized, bool emoticonsExist, bool enableAdHocCommandOnJID);
- virtual XMLConsoleWidget* createXMLConsoleWidget();
- virtual HistoryWindow* createHistoryWindow(UIEventStream*);
- virtual MainWindow* createMainWindow(UIEventStream* eventStream);
- virtual LoginWindow* createLoginWindow(UIEventStream* eventStream);
- virtual EventWindow* createEventWindow();
- virtual ChatListWindow* createChatListWindow(UIEventStream*);
- virtual MUCSearchWindow* createMUCSearchWindow();
- virtual ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream);
- virtual UserSearchWindow* createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream, const std::set<std::string>& groups);
- virtual JoinMUCWindow* createJoinMUCWindow(UIEventStream* uiEventStream);
- virtual ProfileWindow* createProfileWindow();
- virtual ContactEditWindow* createContactEditWindow();
- virtual FileTransferListWidget* createFileTransferListWidget();
- virtual WhiteboardWindow* createWhiteboardWindow(boost::shared_ptr<WhiteboardSession> whiteboardSession);
- virtual HighlightEditorWindow* createHighlightEditorWindow();
- virtual BlockListEditorWidget* createBlockListEditorWidget();
- virtual AdHocCommandWindow* createAdHocCommandWindow(boost::shared_ptr<OutgoingAdHocCommandSession> command);
+ virtual XMLConsoleWidget* createXMLConsoleWidget();
+ virtual HistoryWindow* createHistoryWindow(UIEventStream*);
+ virtual MainWindow* createMainWindow(UIEventStream* eventStream);
+ virtual LoginWindow* createLoginWindow(UIEventStream* eventStream);
+ virtual EventWindow* createEventWindow();
+ virtual ChatListWindow* createChatListWindow(UIEventStream*);
+ virtual MUCSearchWindow* createMUCSearchWindow();
+ virtual ChatWindow* createChatWindow(const JID &contact, UIEventStream* eventStream);
+ virtual UserSearchWindow* createUserSearchWindow(UserSearchWindow::Type type, UIEventStream* eventStream, const std::set<std::string>& groups);
+ virtual JoinMUCWindow* createJoinMUCWindow(UIEventStream* uiEventStream);
+ virtual ProfileWindow* createProfileWindow();
+ virtual ContactEditWindow* createContactEditWindow();
+ virtual FileTransferListWidget* createFileTransferListWidget();
+ virtual WhiteboardWindow* createWhiteboardWindow(std::shared_ptr<WhiteboardSession> whiteboardSession);
+ virtual HighlightEditorWindow* createHighlightEditorWindow();
+ virtual BlockListEditorWidget* createBlockListEditorWidget();
+ virtual AdHocCommandWindow* createAdHocCommandWindow(std::shared_ptr<OutgoingAdHocCommandSession> command);
- private slots:
- void handleLoginWindowGeometryChanged();
- void handleChatWindowFontResized(int);
- void handleHistoryWindowFontResized(int);
+ private slots:
+ void handleLoginWindowGeometryChanged();
+ void handleChatWindowFontResized(int);
+ void handleHistoryWindowFontResized(int);
- private:
- void showTabs();
+ private:
+ void showTabs();
- private:
- SettingsProviderHierachy* settings;
- QtSettingsProvider* qtOnlySettings;
- QtChatTabsBase* tabsBase;
- QtChatTabs* tabs;
- QtSingleWindow* netbookSplitter;
- QtSystemTray* systemTray;
- QtChatWindowFactory* chatWindowFactory;
- TimerFactory* timerFactory_;
- QtMainWindow* lastMainWindow;
- QtLoginWindow* loginWindow;
- StatusCache* statusCache;
- std::vector<QPointer<QtChatWindow> > chatWindows;
- bool startMinimized;
- int chatFontSize;
- int historyFontSize_;
- bool emoticonsExist_;
- bool enableAdHocCommandOnJID_;
- };
+ private:
+ SettingsProviderHierachy* settings;
+ QtSettingsProvider* qtOnlySettings;
+ QtChatTabsBase* tabsBase;
+ QtChatTabs* tabs;
+ QtSingleWindow* netbookSplitter;
+ QtSystemTray* systemTray;
+ QtChatWindowFactory* chatWindowFactory;
+ TimerFactory* timerFactory_;
+ QtMainWindow* lastMainWindow;
+ QtLoginWindow* loginWindow;
+ StatusCache* statusCache;
+ std::vector<QPointer<QtChatWindow> > chatWindows;
+ bool startMinimized;
+ int chatFontSize;
+ int historyFontSize_;
+ bool emoticonsExist_;
+ bool enableAdHocCommandOnJID_;
+ };
}
diff --git a/Swift/QtUI/QtUISettingConstants.cpp b/Swift/QtUI/QtUISettingConstants.cpp
index 812e3eb..24cc6dc 100644
--- a/Swift/QtUI/QtUISettingConstants.cpp
+++ b/Swift/QtUI/QtUISettingConstants.cpp
@@ -1,11 +1,13 @@
/*
- * Copyright (c) 2012-2013 Isode Limited.
+ * Copyright (c) 2012-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/QtUISettingConstants.h>
+#include <Swift/QtUI/SwiftUpdateFeeds.h>
+
namespace Swift {
const SettingsProvider::Setting<bool> QtUISettingConstants::COMPACT_ROSTER("compactRoster", false);
@@ -17,4 +19,11 @@ const SettingsProvider::Setting<int> QtUISettingConstants::HISTORYWINDOW_FONT_SI
const SettingsProvider::Setting<bool> QtUISettingConstants::SHOW_EMOTICONS("showEmoticons", true);
const SettingsProvider::Setting<bool> QtUISettingConstants::USE_PLAIN_CHATS("plainChats", false);
const SettingsProvider::Setting<bool> QtUISettingConstants::USE_SCREENREADER("screenreader", false);
+const SettingsProvider::Setting<bool> QtUISettingConstants::SPELL_CHECKER("spellChecker", false);
+const SettingsProvider::Setting<std::string> QtUISettingConstants::SPELL_CHECKER_LANGUAGE("spellCheckerLanguage", "en_US");
+const SettingsProvider::Setting<std::string> QtUISettingConstants::TRELLIS_GRID_SIZE("trellisGridSize", "");
+const SettingsProvider::Setting<std::string> QtUISettingConstants::TRELLIS_GRID_POSITIONS("trellisGridPositions", "");
+const SettingsProvider::Setting<bool> QtUISettingConstants::ENABLE_SOFTWARE_UPDATES("enableSoftwareUpdates", true);
+const SettingsProvider::Setting<std::string> QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL("softwareUpdateChannel", UpdateFeeds::StableChannel);
+
}
diff --git a/Swift/QtUI/QtUISettingConstants.h b/Swift/QtUI/QtUISettingConstants.h
index 4c17c0d..a569587 100644
--- a/Swift/QtUI/QtUISettingConstants.h
+++ b/Swift/QtUI/QtUISettingConstants.h
@@ -1,24 +1,53 @@
/*
- * Copyright (c) 2012-2013 Isode Limited.
+ * Copyright (c) 2012-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <string>
+
#include <Swift/Controllers/Settings/SettingsProvider.h>
namespace Swift {
- class QtUISettingConstants {
- public:
- static const SettingsProvider::Setting<bool> COMPACT_ROSTER;
- static const SettingsProvider::Setting<std::string> CLICKTHROUGH_BANNER;
- static const SettingsProvider::Setting<int> CURRENT_ROSTER_TAB;
- static const SettingsProvider::Setting<bool> SHOW_NICK_IN_ROSTER_HEADER;
- static const SettingsProvider::Setting<int> CHATWINDOW_FONT_SIZE;
- static const SettingsProvider::Setting<int> HISTORYWINDOW_FONT_SIZE;
- static const SettingsProvider::Setting<bool> SHOW_EMOTICONS;
- static const SettingsProvider::Setting<bool> USE_PLAIN_CHATS;
- static const SettingsProvider::Setting<bool> USE_SCREENREADER;
- };
+ class QtUISettingConstants {
+ public:
+ static const SettingsProvider::Setting<bool> COMPACT_ROSTER;
+ static const SettingsProvider::Setting<std::string> CLICKTHROUGH_BANNER;
+ static const SettingsProvider::Setting<int> CURRENT_ROSTER_TAB;
+ static const SettingsProvider::Setting<bool> SHOW_NICK_IN_ROSTER_HEADER;
+ static const SettingsProvider::Setting<int> CHATWINDOW_FONT_SIZE;
+ static const SettingsProvider::Setting<int> HISTORYWINDOW_FONT_SIZE;
+ static const SettingsProvider::Setting<bool> SHOW_EMOTICONS;
+ static const SettingsProvider::Setting<bool> USE_PLAIN_CHATS;
+ static const SettingsProvider::Setting<bool> USE_SCREENREADER;
+ static const SettingsProvider::Setting<bool> SPELL_CHECKER;
+ static const SettingsProvider::Setting<std::string> SPELL_CHECKER_LANGUAGE;
+ /**
+ * The #TRELLIS_GRID_SIZE setting specifies the dimensions of the grid used for the trellis
+ * layout.
+ *
+ * Its value is a Qt serialized representation.
+ */
+ static const SettingsProvider::Setting<std::string> TRELLIS_GRID_SIZE;
+ /**
+ * The #TRELLIS_GRID_POSITIONS setting specifies where conversations to contacts or rooms go
+ * in the trellis grid.
+ *
+ * Its value is a Qt serialized representation.
+ */
+ static const SettingsProvider::Setting<std::string> TRELLIS_GRID_POSITIONS;
+ /**
+ * The #ENABLE_SOFTWARE_UPDATES setting specifies, whether Swift
+ * should automatically check for software updates in regular
+ * intervals and install them automatically.
+ */
+ static const SettingsProvider::Setting<bool> ENABLE_SOFTWARE_UPDATES;
+ /**
+ * The #SOFTWARE_UPDATE_CHANNEL setting defines what update channel
+ * Swift uses to check for, and receive, updates.
+ */
+ static const SettingsProvider::Setting<std::string> SOFTWARE_UPDATE_CHANNEL;
+ };
}
diff --git a/Swift/QtUI/QtURIHandler.cpp b/Swift/QtUI/QtURIHandler.cpp
index 5ab2aa9..24bd328 100644
--- a/Swift/QtUI/QtURIHandler.cpp
+++ b/Swift/QtUI/QtURIHandler.cpp
@@ -1,30 +1,30 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtURIHandler.h"
+#include <Swift/QtUI/QtURIHandler.h>
#include <QCoreApplication>
#include <QFileOpenEvent>
#include <QUrl>
-#include "QtSwiftUtil.h"
+#include <Swift/QtUI/QtSwiftUtil.h>
using namespace Swift;
QtURIHandler::QtURIHandler() {
- qApp->installEventFilter(this);
+ qApp->installEventFilter(this);
}
bool QtURIHandler::eventFilter(QObject*, QEvent* event) {
- if (event->type() == QEvent::FileOpen) {
- QFileOpenEvent* fileOpenEvent = static_cast<QFileOpenEvent*>(event);
- if (fileOpenEvent->url().scheme() == "xmpp") {
- onURI(Q2PSTRING(fileOpenEvent->url().toString()));
- return true;
- }
- }
- return false;
+ if (event->type() == QEvent::FileOpen) {
+ QFileOpenEvent* fileOpenEvent = static_cast<QFileOpenEvent*>(event);
+ if (fileOpenEvent->url().scheme() == "xmpp") {
+ onURI(Q2PSTRING(fileOpenEvent->url().toString()));
+ return true;
+ }
+ }
+ return false;
}
diff --git a/Swift/QtUI/QtURIHandler.h b/Swift/QtUI/QtURIHandler.h
index 43aa737..309e55b 100644
--- a/Swift/QtUI/QtURIHandler.h
+++ b/Swift/QtUI/QtURIHandler.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,16 +7,17 @@
#pragma once
#include <QObject>
+
#include <SwifTools/URIHandler/URIHandler.h>
class QUrl;
namespace Swift {
- class QtURIHandler : public QObject, public URIHandler {
- public:
- QtURIHandler();
+ class QtURIHandler : public QObject, public URIHandler {
+ public:
+ QtURIHandler();
- private:
- bool eventFilter(QObject* obj, QEvent* event);
- };
+ private:
+ bool eventFilter(QObject* obj, QEvent* event);
+ };
}
diff --git a/Swift/QtUI/QtURLValidator.cpp b/Swift/QtUI/QtURLValidator.cpp
index 4b8e555..8017710 100644
--- a/Swift/QtUI/QtURLValidator.cpp
+++ b/Swift/QtUI/QtURLValidator.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Isode Limited.
+ * Copyright (c) 2012-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,6 +7,7 @@
#include <Swift/QtUI/QtURLValidator.h>
#include <Swiften/Base/URL.h>
+
#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
@@ -15,10 +16,10 @@ QtURLValidator::QtURLValidator(QObject* parent) : QValidator(parent) {
}
QValidator::State QtURLValidator::validate(QString& input, int&) const {
- URL url = URL::fromString(Q2PSTRING(input));
- bool valid = !url.isEmpty();
- valid &= (url.getScheme() == "http" || url.getScheme() == "https");
- return valid ? Acceptable : Intermediate;
+ URL url = URL::fromString(Q2PSTRING(input));
+ bool valid = !url.isEmpty();
+ valid &= (url.getScheme() == "http" || url.getScheme() == "https");
+ return valid ? Acceptable : Intermediate;
}
}
diff --git a/Swift/QtUI/QtURLValidator.h b/Swift/QtUI/QtURLValidator.h
index b374ef4..887828a 100644
--- a/Swift/QtUI/QtURLValidator.h
+++ b/Swift/QtUI/QtURLValidator.h
@@ -7,11 +7,11 @@
#include <QValidator>
namespace Swift {
- class QtURLValidator : public QValidator {
- Q_OBJECT
- public:
- QtURLValidator(QObject* parent);
- virtual QValidator::State validate(QString& input, int& pos) const;
- };
+ class QtURLValidator : public QValidator {
+ Q_OBJECT
+ public:
+ QtURLValidator(QObject* parent);
+ virtual QValidator::State validate(QString& input, int& pos) const;
+ };
}
diff --git a/Swift/QtUI/QtUpdateFeedSelectionDialog.cpp b/Swift/QtUI/QtUpdateFeedSelectionDialog.cpp
new file mode 100644
index 0000000..1f4058a
--- /dev/null
+++ b/Swift/QtUI/QtUpdateFeedSelectionDialog.cpp
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtUpdateFeedSelectionDialog.h>
+
+#include <QComboBox>
+
+#include <Swift/Controllers/Settings/SettingsProvider.h>
+
+#include <Swift/QtUI/QtUISettingConstants.h>
+#include <Swift/QtUI/SwiftUpdateFeeds.h>
+
+namespace Swift {
+
+QtUpdateFeedSelectionDialog::QtUpdateFeedSelectionDialog(SettingsProvider* settingsProvider) : QDialog(), settings_(settingsProvider) {
+ ui.setupUi(this);
+
+ connect(ui.currentChannelComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [&] (int newIndex) {
+ setDescriptionForIndex(newIndex);
+ });
+
+ auto updateChannel = settings_->getSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL);
+ if (updateChannel == UpdateFeeds::StableChannel) {
+ ui.currentChannelComboBox->setCurrentIndex(0);
+ }
+ else if (updateChannel == UpdateFeeds::TestingChannel) {
+ ui.currentChannelComboBox->setCurrentIndex(1);
+ }
+ else if (updateChannel == UpdateFeeds::DevelopmentChannel) {
+ ui.currentChannelComboBox->setCurrentIndex(2);
+ }
+
+ connect(this, &QDialog::accepted, [&]() {
+ auto newUpdateChannel = std::string("");
+ switch (ui.currentChannelComboBox->currentIndex()) {
+ case 0:
+ newUpdateChannel = UpdateFeeds::StableChannel;
+ break;
+ case 1:
+ newUpdateChannel = UpdateFeeds::TestingChannel;
+ break;
+ case 2:
+ newUpdateChannel = UpdateFeeds::DevelopmentChannel;
+ break;
+ }
+ settings_->storeSetting(QtUISettingConstants::SOFTWARE_UPDATE_CHANNEL, newUpdateChannel);
+ });
+
+ setAttribute(Qt::WA_DeleteOnClose);
+}
+
+void QtUpdateFeedSelectionDialog::setDescriptionForIndex(int index) {
+ switch (index) {
+ case 0:
+ ui.stableDescriptionLabel->show();
+ ui.testingDescriptionLabel->hide();
+ ui.developmentDescriptionLabel->hide();
+ break;
+ case 1:
+ ui.stableDescriptionLabel->hide();
+ ui.testingDescriptionLabel->show();
+ ui.developmentDescriptionLabel->hide();
+ break;
+ case 2:
+ ui.stableDescriptionLabel->hide();
+ ui.testingDescriptionLabel->hide();
+ ui.developmentDescriptionLabel->show();
+ break;
+ default:
+ ui.stableDescriptionLabel->hide();
+ ui.testingDescriptionLabel->hide();
+ ui.developmentDescriptionLabel->hide();
+ break;
+ }
+ setFixedSize(sizeHint());
+}
+
+
+
+}
diff --git a/Swift/QtUI/QtUpdateFeedSelectionDialog.h b/Swift/QtUI/QtUpdateFeedSelectionDialog.h
new file mode 100644
index 0000000..80b986f
--- /dev/null
+++ b/Swift/QtUI/QtUpdateFeedSelectionDialog.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <QDialog>
+
+#include <Swift/QtUI/ui_QtUpdateFeedSelectionDialog.h>
+
+namespace Swift {
+
+class SettingsProvider;
+
+class QtUpdateFeedSelectionDialog : public QDialog {
+ Q_OBJECT
+ public:
+ QtUpdateFeedSelectionDialog(SettingsProvider* settingsProvider);
+
+ private:
+ void setDescriptionForIndex(int index);
+
+ private:
+ Ui::QtUpdateFeedSelectionDialog ui;
+ SettingsProvider* settings_ = nullptr;
+};
+
+}
diff --git a/Swift/QtUI/QtUpdateFeedSelectionDialog.ui b/Swift/QtUI/QtUpdateFeedSelectionDialog.ui
new file mode 100644
index 0000000..2eac1f1
--- /dev/null
+++ b/Swift/QtUI/QtUpdateFeedSelectionDialog.ui
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>QtUpdateFeedSelectionDialog</class>
+ <widget class="QDialog" name="QtUpdateFeedSelectionDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>335</width>
+ <height>158</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Select Update Channel</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QComboBox" name="currentChannelComboBox">
+ <property name="currentText">
+ <string/>
+ </property>
+ <property name="currentIndex">
+ <number>-1</number>
+ </property>
+ <item>
+ <property name="text">
+ <string>Stable Channel</string>
+ </property>
+ <property name="icon">
+ <iconset theme=":/icons/delivery-success.svg"/>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Testing Channel</string>
+ </property>
+ <property name="icon">
+ <iconset theme=":/icons/delivery-warning.svg"/>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Development Channel</string>
+ </property>
+ <property name="icon">
+ <iconset theme=":/icons/delivery-warning.svg"/>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="stableDescriptionLabel">
+ <property name="text">
+ <string>This release channel includes our stable releases. They went throught internal QA testing and had previous RC releases to find critical bugs.</string>
+ </property>
+ <property name="textFormat">
+ <enum>Qt::PlainText</enum>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignJustify|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::NoTextInteraction</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="testingDescriptionLabel">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>This release channel includes our stable releases, beta releases and release candidates. They should be free from obvious bugs and are released for wider testing to find more obscure bugs.</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignJustify|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="developmentDescriptionLabel">
+ <property name="text">
+ <string>This release channel includes our stable releases, beta releases, release candidates and development releases. The development releases are not thoroughly tested and might contain bugs.</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignJustify|Qt::AlignTop</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>QtUpdateFeedSelectionDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>QtUpdateFeedSelectionDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/Swift/QtUI/QtUtilities.cpp b/Swift/QtUI/QtUtilities.cpp
index b4b1b09..401af17 100644
--- a/Swift/QtUI/QtUtilities.cpp
+++ b/Swift/QtUI/QtUtilities.cpp
@@ -22,23 +22,23 @@ namespace QtUtilities {
void setX11Resource(QWidget* widget, const QString& c) {
#if defined (Q_OS_UNIX) && !defined(Q_OS_MAC) && QT_VERSION < 0x050000
- char res_class[] = SWIFT_APPLICATION_NAME;
- XClassHint hint;
- QByteArray resName = (QString(SWIFT_APPLICATION_NAME) + "-" + c).toUtf8();
- hint.res_name = resName.data();
- hint.res_class = res_class;
- XSetClassHint(widget->x11Info().display(), widget->winId(), &hint);
+ char res_class[] = SWIFT_APPLICATION_NAME;
+ XClassHint hint;
+ QByteArray resName = (QString(SWIFT_APPLICATION_NAME) + "-" + c).toUtf8();
+ hint.res_name = resName.data();
+ hint.res_class = res_class;
+ XSetClassHint(widget->x11Info().display(), widget->winId(), &hint);
#else
- (void) widget;
- (void) c;
+ (void) widget;
+ (void) c;
#endif
}
QString htmlEscape(const QString& s) {
#if QT_VERSION >= 0x050000
- return s.toHtmlEscaped();
+ return s.toHtmlEscaped();
#else
- return Qt::escape(s);
+ return Qt::escape(s);
#endif
}
diff --git a/Swift/QtUI/QtUtilities.h b/Swift/QtUI/QtUtilities.h
index 4d71d7c..ad58499 100644
--- a/Swift/QtUI/QtUtilities.h
+++ b/Swift/QtUI/QtUtilities.h
@@ -12,11 +12,11 @@ class QString;
#include <QKeyEvent>
namespace QtUtilities {
- void setX11Resource(QWidget* widget, const QString& c);
- QString htmlEscape(const QString& s);
- #ifdef SWIFTEN_PLATFORM_MACOSX
- const Qt::KeyboardModifier ctrlHardwareKeyModifier = Qt::MetaModifier;
- #else
- const Qt::KeyboardModifier ctrlHardwareKeyModifier = Qt::ControlModifier;
- #endif
+ void setX11Resource(QWidget* widget, const QString& c);
+ QString htmlEscape(const QString& s);
+ #ifdef SWIFTEN_PLATFORM_MACOSX
+ const Qt::KeyboardModifier ctrlHardwareKeyModifier = Qt::MetaModifier;
+ #else
+ const Qt::KeyboardModifier ctrlHardwareKeyModifier = Qt::ControlModifier;
+ #endif
}
diff --git a/Swift/QtUI/QtVCardWidget/QtCloseButton.cpp b/Swift/QtUI/QtVCardWidget/QtCloseButton.cpp
index ebd62bc..da4f22f 100644
--- a/Swift/QtUI/QtVCardWidget/QtCloseButton.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtCloseButton.cpp
@@ -4,7 +4,13 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "QtCloseButton.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtVCardWidget/QtCloseButton.h>
#include <QMouseEvent>
#include <QPainter>
@@ -18,28 +24,28 @@ QtCloseButton::QtCloseButton(QWidget *parent) : QAbstractButton(parent) {
}
QSize QtCloseButton::sizeHint() const {
- return QSize(style()->pixelMetric(QStyle::PM_TabCloseIndicatorWidth, 0, 0), style()->pixelMetric(QStyle::PM_TabCloseIndicatorHeight, 0, 0));
+ return QSize(style()->pixelMetric(QStyle::PM_TabCloseIndicatorWidth, nullptr, nullptr), style()->pixelMetric(QStyle::PM_TabCloseIndicatorHeight, nullptr, nullptr));
}
bool QtCloseButton::event(QEvent *e) {
- if (e->type() == QEvent::Enter || e->type() == QEvent::Leave) {
- update();
- }
- return QAbstractButton::event(e);
+ if (e->type() == QEvent::Enter || e->type() == QEvent::Leave) {
+ update();
+ }
+ return QAbstractButton::event(e);
}
void QtCloseButton::paintEvent(QPaintEvent *) {
- QPainter painter(this);
- painter.setRenderHint(QPainter::HighQualityAntialiasing);
- QStyleOption opt;
- opt.init(this);
- opt.state |= QStyle::State_AutoRaise;
- if (underMouse() && !isDown()) {
- opt.state |= QStyle::State_Raised;
- } else if (isDown()) {
- opt.state |= QStyle::State_Sunken;
- }
- style()->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, &painter, this);
+ QPainter painter(this);
+ painter.setRenderHint(QPainter::HighQualityAntialiasing);
+ QStyleOption opt;
+ opt.init(this);
+ opt.state |= QStyle::State_AutoRaise;
+ if (underMouse() && !isDown()) {
+ opt.state |= QStyle::State_Raised;
+ } else if (isDown()) {
+ opt.state |= QStyle::State_Sunken;
+ }
+ style()->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, &painter, this);
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtCloseButton.h b/Swift/QtUI/QtVCardWidget/QtCloseButton.h
index cb92e12..0c6e192 100644
--- a/Swift/QtUI/QtVCardWidget/QtCloseButton.h
+++ b/Swift/QtUI/QtVCardWidget/QtCloseButton.h
@@ -4,21 +4,27 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <QAbstractButton>
namespace Swift {
- class QtCloseButton : public QAbstractButton {
- Q_OBJECT
- public:
- explicit QtCloseButton(QWidget *parent = 0);
- virtual QSize sizeHint() const;
+ class QtCloseButton : public QAbstractButton {
+ Q_OBJECT
+ public:
+ explicit QtCloseButton(QWidget *parent = nullptr);
+ virtual QSize sizeHint() const;
- protected:
- virtual bool event(QEvent *e);
- virtual void paintEvent(QPaintEvent* );
- };
+ protected:
+ virtual bool event(QEvent *e);
+ virtual void paintEvent(QPaintEvent* );
+ };
}
diff --git a/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.cpp b/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.cpp
index 10237ce..079f77d 100644
--- a/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.cpp
@@ -5,16 +5,18 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtRemovableItemDelegate.h"
-#include <Swiften/Base/Platform.h>
+#include <Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h>
+
#include <QEvent>
#include <QPainter>
+#include <Swiften/Base/Platform.h>
+
namespace Swift {
QtRemovableItemDelegate::QtRemovableItemDelegate(const QStyle* style) : style(style) {
@@ -22,42 +24,42 @@ QtRemovableItemDelegate::QtRemovableItemDelegate(const QStyle* style) : style(st
}
void QtRemovableItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
- QStyleOption opt;
- opt.state = option.state;
- opt.state |= QStyle::State_AutoRaise;
- if (option.state.testFlag(QStyle::State_MouseOver)) {
- opt.state |= QStyle::State_Raised;
- }
- opt.rect = option.rect;
- painter->save();
- painter->fillRect(option.rect, option.state & QStyle::State_Selected ? option.palette.highlight() : option.palette.base());
- if (index.data().toString().isEmpty()) {
+ QStyleOption opt;
+ opt.state = option.state;
+ opt.state |= QStyle::State_AutoRaise;
+ if (option.state.testFlag(QStyle::State_MouseOver)) {
+ opt.state |= QStyle::State_Raised;
+ }
+ opt.rect = option.rect;
+ painter->save();
+ painter->fillRect(option.rect, option.state & QStyle::State_Selected ? option.palette.highlight() : option.palette.base());
+ if (index.data().toString().isEmpty()) {
#ifdef SWIFTEN_PLATFORM_MACOSX
- // workaround for Qt not painting relative to the cell we're in, on OS X
- int height = style->pixelMetric(QStyle::PM_TabCloseIndicatorWidth, 0, 0);
- painter->translate(option.rect.x(), option.rect.y() + (option.rect.height() - height)/2);
+ // workaround for Qt not painting relative to the cell we're in, on OS X
+ int height = style->pixelMetric(QStyle::PM_TabCloseIndicatorWidth, nullptr, nullptr);
+ painter->translate(option.rect.x(), option.rect.y() + (option.rect.height() - height)/2);
#endif
- style->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, painter);
- }
- painter->restore();
+ style->drawPrimitive(QStyle::PE_IndicatorTabClose, &opt, painter);
+ }
+ painter->restore();
}
QWidget* QtRemovableItemDelegate::createEditor(QWidget*, const QStyleOptionViewItem&, const QModelIndex&) const {
- return NULL;
+ return nullptr;
}
bool QtRemovableItemDelegate::editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index) {
- if (index.data().toString().isEmpty() && event->type() == QEvent::MouseButtonRelease) {
- model->removeRow(index.row());
- return true;
- } else {
- return QItemDelegate::editorEvent(event, model, option, index);
- }
+ if (index.data().toString().isEmpty() && event->type() == QEvent::MouseButtonRelease) {
+ model->removeRow(index.row());
+ return true;
+ } else {
+ return QItemDelegate::editorEvent(event, model, option, index);
+ }
}
QSize QtRemovableItemDelegate::sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const {
- QSize size(style->pixelMetric(QStyle::PM_TabCloseIndicatorWidth, 0, 0) + 2, style->pixelMetric(QStyle::PM_TabCloseIndicatorHeight, 0, 0) + 2);
- return size;
+ QSize size(style->pixelMetric(QStyle::PM_TabCloseIndicatorWidth, nullptr, nullptr) + 2, style->pixelMetric(QStyle::PM_TabCloseIndicatorHeight, nullptr, nullptr) + 2);
+ return size;
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h b/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h
index 75137e1..ea9e0b2 100644
--- a/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h
+++ b/Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h
@@ -11,18 +11,18 @@
namespace Swift {
class QtRemovableItemDelegate : public QItemDelegate {
- public:
- QtRemovableItemDelegate(const QStyle* style);
+ public:
+ QtRemovableItemDelegate(const QStyle* style);
- virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex&) const;
- virtual QWidget* createEditor(QWidget*, const QStyleOptionViewItem&, const QModelIndex&) const;
- virtual QSize sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const;
+ virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex&) const;
+ virtual QWidget* createEditor(QWidget*, const QStyleOptionViewItem&, const QModelIndex&) const;
+ virtual QSize sizeHint(const QStyleOptionViewItem&, const QModelIndex&) const;
- protected:
- virtual bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index);
+ protected:
+ virtual bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index);
- private:
- const QStyle* style;
+ private:
+ const QStyle* style;
};
}
diff --git a/Swift/QtUI/QtVCardWidget/QtResizableLineEdit.cpp b/Swift/QtUI/QtVCardWidget/QtResizableLineEdit.cpp
index f60f9a8..9eef970 100644
--- a/Swift/QtUI/QtVCardWidget/QtResizableLineEdit.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtResizableLineEdit.cpp
@@ -5,54 +5,54 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtResizableLineEdit.h"
+#include <Swift/QtUI/QtVCardWidget/QtResizableLineEdit.h>
namespace Swift {
QtResizableLineEdit::QtResizableLineEdit(QWidget* parent) :
- QLineEdit(parent), editable(false) {
- connect(this, SIGNAL(textChanged(QString)), SLOT(textChanged(QString)));
- setMinimumWidth(30);
+ QLineEdit(parent), editable(false) {
+ connect(this, SIGNAL(textChanged(QString)), SLOT(textChanged(QString)));
+ setMinimumWidth(30);
}
QtResizableLineEdit::~QtResizableLineEdit() {
}
bool QtResizableLineEdit::isEditable() const {
- return editable;
+ return editable;
}
void QtResizableLineEdit::setEditable(const bool editable) {
- this->editable = editable;
- if (editable) {
- setReadOnly(false);
- } else {
- setReadOnly(true);
- }
+ this->editable = editable;
+ if (editable) {
+ setReadOnly(false);
+ } else {
+ setReadOnly(true);
+ }
}
QSize QtResizableLineEdit::sizeHint() const {
- int horizontalMargin = 10;
- int verticalMargin = 6;
- QSize textDimensions;
+ int horizontalMargin = 10;
+ int verticalMargin = 6;
+ QSize textDimensions;
#if QT_VERSION >= 0x040700
- textDimensions = fontMetrics().boundingRect(text().isEmpty() ? placeholderText() : text()).size();
+ textDimensions = fontMetrics().boundingRect(text().isEmpty() ? placeholderText() : text()).size();
#else
- textDimensions = fontMetrics().boundingRect(text().isEmpty() ? QString(" ") : text()).size();
+ textDimensions = fontMetrics().boundingRect(text().isEmpty() ? QString(" ") : text()).size();
#endif
- textDimensions.setWidth(textDimensions.width() + horizontalMargin);
- textDimensions.setHeight(textDimensions.height() + verticalMargin);
- return textDimensions;
+ textDimensions.setWidth(textDimensions.width() + horizontalMargin);
+ textDimensions.setHeight(textDimensions.height() + verticalMargin);
+ return textDimensions;
}
void QtResizableLineEdit::textChanged(QString) {
- updateGeometry();
+ updateGeometry();
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtResizableLineEdit.h b/Swift/QtUI/QtVCardWidget/QtResizableLineEdit.h
index 9022d38..eab5b2b 100644
--- a/Swift/QtUI/QtVCardWidget/QtResizableLineEdit.h
+++ b/Swift/QtUI/QtVCardWidget/QtResizableLineEdit.h
@@ -4,30 +4,36 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <QLineEdit>
namespace Swift {
- class QtResizableLineEdit : public QLineEdit {
- Q_OBJECT
- Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+ class QtResizableLineEdit : public QLineEdit {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
- public:
- explicit QtResizableLineEdit(QWidget* parent = 0);
- ~QtResizableLineEdit();
+ public:
+ explicit QtResizableLineEdit(QWidget* parent = nullptr);
+ ~QtResizableLineEdit();
- bool isEditable() const;
- void setEditable(const bool);
+ bool isEditable() const;
+ void setEditable(const bool);
- virtual QSize sizeHint() const;
+ virtual QSize sizeHint() const;
- private slots:
- void textChanged(QString);
+ private slots:
+ void textChanged(QString);
- private:
- bool editable;
- };
+ private:
+ bool editable;
+ };
}
diff --git a/Swift/QtUI/QtVCardWidget/QtTagComboBox.cpp b/Swift/QtUI/QtVCardWidget/QtTagComboBox.cpp
index 33863b2..02ceb0a 100644
--- a/Swift/QtUI/QtVCardWidget/QtTagComboBox.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtTagComboBox.cpp
@@ -5,12 +5,12 @@
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtTagComboBox.h"
+#include <Swift/QtUI/QtVCardWidget/QtTagComboBox.h>
#include <QAbstractItemView>
#include <QtGui>
@@ -18,14 +18,14 @@
namespace Swift {
QtTagComboBox::QtTagComboBox(QWidget* parent) : QComboBox(parent) {
- setEditable(false);
- displayModel = new QStandardItemModel(this);
- displayItem = new QStandardItem();
- displayItem->setText("");
- displayModel->insertRow(0, displayItem);
- editMenu = new QMenu(this);
- this->setModel(displayModel);
- editable = true;
+ setEditable(false);
+ displayModel = new QStandardItemModel(this);
+ displayItem = new QStandardItem();
+ displayItem->setText("");
+ displayModel->insertRow(0, displayItem);
+ editMenu = new QMenu(this);
+ this->setModel(displayModel);
+ editable = true;
}
QtTagComboBox::~QtTagComboBox() {
@@ -33,40 +33,40 @@ QtTagComboBox::~QtTagComboBox() {
}
bool QtTagComboBox::isEditable() const {
- return editable;
+ return editable;
}
void QtTagComboBox::setEditable(const bool editable) {
- this->editable = editable;
+ this->editable = editable;
}
void QtTagComboBox::addTag(const QString &id, const QString &label) {
- QAction* tagAction = new QAction(editMenu);
- tagAction->setText(label);
- tagAction->setCheckable(true);
- tagAction->setData(QString(id));
- editMenu->addAction(tagAction);
+ QAction* tagAction = new QAction(editMenu);
+ tagAction->setText(label);
+ tagAction->setCheckable(true);
+ tagAction->setData(QString(id));
+ editMenu->addAction(tagAction);
}
void QtTagComboBox::setTag(const QString &id, bool value) {
- QList<QAction*> tagActions = editMenu->actions();
- foreach(QAction* action, tagActions) {
- if (action->data() == id) {
- action->setChecked(value);
- updateDisplayItem();
- return;
- }
- }
+ QList<QAction*> tagActions = editMenu->actions();
+ for (auto action : tagActions) {
+ if (action->data() == id) {
+ action->setChecked(value);
+ updateDisplayItem();
+ return;
+ }
+ }
}
bool QtTagComboBox::isTagSet(const QString &id) const {
- QList<QAction*> tagActions = editMenu->actions();
- foreach(QAction* action, tagActions) {
- if (action->data() == id) {
- return action->isChecked();
- }
- }
- return false;
+ QList<QAction*> tagActions = editMenu->actions();
+ for (auto action : tagActions) {
+ if (action->data() == id) {
+ return action->isChecked();
+ }
+ }
+ return false;
}
void QtTagComboBox::showPopup() {
@@ -78,31 +78,31 @@ void QtTagComboBox::hidePopup() {
}
bool QtTagComboBox::event(QEvent* event) {
- if (event->type() == QEvent::MouseButtonPress ||
- event->type() == QEvent::KeyRelease) {
- if (!editable) return true;
-
- QPoint p = mapToGlobal(QPoint(0,0));
- p += QPoint(0, height());
- editMenu->exec(p);
- updateDisplayItem();
- return true;
- }
- return QComboBox::event(event);
+ if (event->type() == QEvent::MouseButtonPress ||
+ event->type() == QEvent::KeyRelease) {
+ if (!editable) return true;
+
+ QPoint p = mapToGlobal(QPoint(0,0));
+ p += QPoint(0, height());
+ editMenu->exec(p);
+ updateDisplayItem();
+ return true;
+ }
+ return QComboBox::event(event);
}
void QtTagComboBox::updateDisplayItem() {
- QList<QAction*> tagActions = editMenu->actions();
- QString text = "";
- foreach(QAction* action, tagActions) {
- if (action->isChecked()) {
- if (text != "") {
- text += ", ";
- }
- text += action->text();
- }
- }
- setItemText(0, text);
+ QList<QAction*> tagActions = editMenu->actions();
+ QString text = "";
+ for (auto action : tagActions) {
+ if (action->isChecked()) {
+ if (text != "") {
+ text += ", ";
+ }
+ text += action->text();
+ }
+ }
+ setItemText(0, text);
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtTagComboBox.h b/Swift/QtUI/QtVCardWidget/QtTagComboBox.h
index 37a60af..e9dbbdd 100644
--- a/Swift/QtUI/QtVCardWidget/QtTagComboBox.h
+++ b/Swift/QtUI/QtVCardWidget/QtTagComboBox.h
@@ -4,6 +4,12 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <QComboBox>
@@ -14,33 +20,33 @@
namespace Swift {
class QtTagComboBox : public QComboBox {
- Q_OBJECT
- Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
- public:
- explicit QtTagComboBox(QWidget* parent = 0);
- ~QtTagComboBox();
+ public:
+ explicit QtTagComboBox(QWidget* parent = nullptr);
+ ~QtTagComboBox();
- bool isEditable() const;
- void setEditable(const bool);
+ bool isEditable() const;
+ void setEditable(const bool);
- void addTag(const QString& id, const QString& label);
- void setTag(const QString& id, bool value);
- bool isTagSet(const QString& id) const;
+ void addTag(const QString& id, const QString& label);
+ void setTag(const QString& id, bool value);
+ bool isTagSet(const QString& id) const;
- virtual void showPopup();
- virtual void hidePopup();
+ virtual void showPopup();
+ virtual void hidePopup();
- virtual bool event(QEvent* event);
+ virtual bool event(QEvent* event);
- private:
- void updateDisplayItem();
+ private:
+ void updateDisplayItem();
- private:
- bool editable;
- QStandardItemModel* displayModel;
- QStandardItem* displayItem;
- QMenu* editMenu;
+ private:
+ bool editable;
+ QStandardItemModel* displayModel;
+ QStandardItem* displayItem;
+ QMenu* editMenu;
};
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardAddressField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardAddressField.cpp
index 5f9fddf..596006a 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardAddressField.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtVCardAddressField.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -20,163 +20,163 @@
namespace Swift {
QtVCardAddressField::QtVCardAddressField(QWidget* parent, QGridLayout *layout, bool editable) :
- QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Address")), streetLineEdit(NULL), poboxLineEdit(NULL), addressextLineEdit(NULL), cityLineEdit(NULL), pocodeLineEdit(NULL), regionLineEdit(NULL), countryLineEdit(NULL), textFieldGridLayout(NULL), textFieldGridLayoutItem(NULL), deliveryTypeLabel(NULL), domesticRadioButton(NULL), internationalRadioButton(NULL), buttonGroup(NULL) {
- connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Address")), streetLineEdit(nullptr), poboxLineEdit(nullptr), addressextLineEdit(nullptr), cityLineEdit(nullptr), pocodeLineEdit(nullptr), regionLineEdit(nullptr), countryLineEdit(nullptr), textFieldGridLayout(nullptr), textFieldGridLayoutItem(nullptr), deliveryTypeLabel(nullptr), domesticRadioButton(nullptr), internationalRadioButton(nullptr), buttonGroup(nullptr) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
}
QtVCardAddressField::~QtVCardAddressField() {
- disconnect(this, SLOT(handleEditibleChanged(bool)));
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
}
void QtVCardAddressField::setupContentWidgets() {
- textFieldGridLayout = new QGridLayout();
+ textFieldGridLayout = new QGridLayout();
- streetLineEdit = new QtResizableLineEdit(this);
- textFieldGridLayout->addWidget(streetLineEdit, 0, 0, Qt::AlignVCenter);
+ streetLineEdit = new QtResizableLineEdit(this);
+ textFieldGridLayout->addWidget(streetLineEdit, 0, 0, Qt::AlignVCenter);
- poboxLineEdit = new QtResizableLineEdit(this);
- textFieldGridLayout->addWidget(poboxLineEdit, 0, 1, Qt::AlignVCenter);
+ poboxLineEdit = new QtResizableLineEdit(this);
+ textFieldGridLayout->addWidget(poboxLineEdit, 0, 1, Qt::AlignVCenter);
- addressextLineEdit = new QtResizableLineEdit(this);
- textFieldGridLayout->addWidget(addressextLineEdit, 1, 0, Qt::AlignVCenter);
+ addressextLineEdit = new QtResizableLineEdit(this);
+ textFieldGridLayout->addWidget(addressextLineEdit, 1, 0, Qt::AlignVCenter);
- cityLineEdit = new QtResizableLineEdit(this);
- textFieldGridLayout->addWidget(cityLineEdit, 2, 0, Qt::AlignVCenter);
+ cityLineEdit = new QtResizableLineEdit(this);
+ textFieldGridLayout->addWidget(cityLineEdit, 2, 0, Qt::AlignVCenter);
- pocodeLineEdit = new QtResizableLineEdit(this);
- textFieldGridLayout->addWidget(pocodeLineEdit, 2, 1, Qt::AlignVCenter);
+ pocodeLineEdit = new QtResizableLineEdit(this);
+ textFieldGridLayout->addWidget(pocodeLineEdit, 2, 1, Qt::AlignVCenter);
- regionLineEdit = new QtResizableLineEdit(this);
- textFieldGridLayout->addWidget(regionLineEdit, 3, 0, Qt::AlignVCenter);
+ regionLineEdit = new QtResizableLineEdit(this);
+ textFieldGridLayout->addWidget(regionLineEdit, 3, 0, Qt::AlignVCenter);
- countryLineEdit = new QtResizableLineEdit(this);
- textFieldGridLayout->addWidget(countryLineEdit, 4, 0, Qt::AlignVCenter);
- textFieldGridLayout->setVerticalSpacing(2);
- getGridLayout()->addLayout(textFieldGridLayout, getGridLayout()->rowCount()-1, 2, 5, 2, Qt::AlignVCenter);
- textFieldGridLayoutItem = getGridLayout()->itemAtPosition(getGridLayout()->rowCount()-1, 2);
+ countryLineEdit = new QtResizableLineEdit(this);
+ textFieldGridLayout->addWidget(countryLineEdit, 4, 0, Qt::AlignVCenter);
+ textFieldGridLayout->setVerticalSpacing(2);
+ getGridLayout()->addLayout(textFieldGridLayout, getGridLayout()->rowCount()-1, 2, 5, 2, Qt::AlignVCenter);
+ textFieldGridLayoutItem = getGridLayout()->itemAtPosition(getGridLayout()->rowCount()-1, 2);
#if QT_VERSION >= 0x040700
- streetLineEdit->setPlaceholderText(tr("Street"));
- poboxLineEdit->setPlaceholderText(tr("PO Box"));
- addressextLineEdit->setPlaceholderText(tr("Address Extension"));
- cityLineEdit->setPlaceholderText(tr("City"));
- pocodeLineEdit->setPlaceholderText(tr("Postal Code"));
- regionLineEdit->setPlaceholderText(tr("Region"));
- countryLineEdit->setPlaceholderText(tr("Country"));
+ streetLineEdit->setPlaceholderText(tr("Street"));
+ poboxLineEdit->setPlaceholderText(tr("PO Box"));
+ addressextLineEdit->setPlaceholderText(tr("Address Extension"));
+ cityLineEdit->setPlaceholderText(tr("City"));
+ pocodeLineEdit->setPlaceholderText(tr("Postal Code"));
+ regionLineEdit->setPlaceholderText(tr("Region"));
+ countryLineEdit->setPlaceholderText(tr("Country"));
#endif
- deliveryTypeLabel = new QtElidingLabel(this);
- deliveryTypeLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
- getGridLayout()->addWidget(deliveryTypeLabel, getGridLayout()->rowCount()-3, 4, Qt::AlignVCenter);
+ deliveryTypeLabel = new QtElidingLabel(this);
+ deliveryTypeLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
+ getGridLayout()->addWidget(deliveryTypeLabel, getGridLayout()->rowCount()-3, 4, Qt::AlignVCenter);
- domesticRadioButton = new QRadioButton(tr("Domestic Delivery"), this);
- getGridLayout()->addWidget(domesticRadioButton, getGridLayout()->rowCount()-2, 4, Qt::AlignVCenter);
+ domesticRadioButton = new QRadioButton(tr("Domestic Delivery"), this);
+ getGridLayout()->addWidget(domesticRadioButton, getGridLayout()->rowCount()-2, 4, Qt::AlignVCenter);
- internationalRadioButton = new QRadioButton(tr("International Delivery"), this);
- getGridLayout()->addWidget(internationalRadioButton, getGridLayout()->rowCount()-1, 4, Qt::AlignVCenter);
+ internationalRadioButton = new QRadioButton(tr("International Delivery"), this);
+ getGridLayout()->addWidget(internationalRadioButton, getGridLayout()->rowCount()-1, 4, Qt::AlignVCenter);
- buttonGroup = new QButtonGroup(this);
- buttonGroup->addButton(domesticRadioButton);
- buttonGroup->addButton(internationalRadioButton);
+ buttonGroup = new QButtonGroup(this);
+ buttonGroup->addButton(domesticRadioButton);
+ buttonGroup->addButton(internationalRadioButton);
- setTabOrder(internationalRadioButton, getTagComboBox());
- getTagComboBox()->addTag("postal", tr("Postal"));
- getTagComboBox()->addTag("parcel", tr("Parcel"));
+ setTabOrder(internationalRadioButton, getTagComboBox());
+ getTagComboBox()->addTag("postal", tr("Postal"));
+ getTagComboBox()->addTag("parcel", tr("Parcel"));
- QtVCardHomeWork::setTagComboBox(getTagComboBox());
+ QtVCardHomeWork::setTagComboBox(getTagComboBox());
- textFields << streetLineEdit << poboxLineEdit << addressextLineEdit << cityLineEdit << pocodeLineEdit << regionLineEdit << countryLineEdit;
- childWidgets << deliveryTypeLabel << domesticRadioButton << internationalRadioButton;
+ textFields << streetLineEdit << poboxLineEdit << addressextLineEdit << cityLineEdit << pocodeLineEdit << regionLineEdit << countryLineEdit;
+ childWidgets << deliveryTypeLabel << domesticRadioButton << internationalRadioButton;
}
void QtVCardAddressField::customCleanup() {
- foreach(QWidget* widget, textFields) {
- widget->hide();
- textFieldGridLayout->removeWidget(widget);
- }
- getGridLayout()->removeItem(textFieldGridLayoutItem);
+ for (auto widget : textFields) {
+ widget->hide();
+ textFieldGridLayout->removeWidget(widget);
+ }
+ getGridLayout()->removeItem(textFieldGridLayoutItem);
}
bool QtVCardAddressField::isEmpty() const {
- return streetLineEdit->text().isEmpty() &&
- poboxLineEdit->text().isEmpty() &&
- addressextLineEdit->text().isEmpty() &&
- cityLineEdit->text().isEmpty() &&
- pocodeLineEdit->text().isEmpty() &&
- regionLineEdit->text().isEmpty() &&
- countryLineEdit->text().isEmpty();
+ return streetLineEdit->text().isEmpty() &&
+ poboxLineEdit->text().isEmpty() &&
+ addressextLineEdit->text().isEmpty() &&
+ cityLineEdit->text().isEmpty() &&
+ pocodeLineEdit->text().isEmpty() &&
+ regionLineEdit->text().isEmpty() &&
+ countryLineEdit->text().isEmpty();
}
void QtVCardAddressField::setAddress(const VCard::Address& address) {
- setPreferred(address.isPreferred);
- setHome(address.isHome);
- setWork(address.isWork);
- getTagComboBox()->setTag("postal", address.isPostal);
- getTagComboBox()->setTag("parcel", address.isParcel);
- domesticRadioButton->setChecked(address.deliveryType == VCard::DomesticDelivery);
- internationalRadioButton->setChecked(address.deliveryType == VCard::InternationalDelivery);
- streetLineEdit->setText(P2QSTRING(address.street));
- poboxLineEdit->setText(P2QSTRING(address.poBox));
- addressextLineEdit->setText(P2QSTRING(address.addressExtension));
- cityLineEdit->setText(P2QSTRING(address.locality));
- pocodeLineEdit->setText(P2QSTRING(address.postalCode));
- regionLineEdit->setText(P2QSTRING(address.region));
- countryLineEdit->setText(P2QSTRING(address.country));
+ setPreferred(address.isPreferred);
+ setHome(address.isHome);
+ setWork(address.isWork);
+ getTagComboBox()->setTag("postal", address.isPostal);
+ getTagComboBox()->setTag("parcel", address.isParcel);
+ domesticRadioButton->setChecked(address.deliveryType == VCard::DomesticDelivery);
+ internationalRadioButton->setChecked(address.deliveryType == VCard::InternationalDelivery);
+ streetLineEdit->setText(P2QSTRING(address.street));
+ poboxLineEdit->setText(P2QSTRING(address.poBox));
+ addressextLineEdit->setText(P2QSTRING(address.addressExtension));
+ cityLineEdit->setText(P2QSTRING(address.locality));
+ pocodeLineEdit->setText(P2QSTRING(address.postalCode));
+ regionLineEdit->setText(P2QSTRING(address.region));
+ countryLineEdit->setText(P2QSTRING(address.country));
}
VCard::Address QtVCardAddressField::getAddress() const {
- VCard::Address address;
- address.isPreferred = getPreferred();
- address.isHome = getHome();
- address.isWork = getWork();
- address.deliveryType = domesticRadioButton->isChecked() ? VCard::DomesticDelivery : (internationalRadioButton->isChecked() ? VCard::InternationalDelivery : VCard::None);
- address.isPostal = getTagComboBox()->isTagSet("postal");
- address.isParcel = getTagComboBox()->isTagSet("parcel");
- address.street = Q2PSTRING(streetLineEdit->text());
- address.poBox = Q2PSTRING(poboxLineEdit->text());
- address.addressExtension = Q2PSTRING(addressextLineEdit->text());
- address.locality = Q2PSTRING(cityLineEdit->text());
- address.postalCode = Q2PSTRING(pocodeLineEdit->text());
- address.region = Q2PSTRING(regionLineEdit->text());
- address.country = Q2PSTRING(countryLineEdit->text());
- return address;
+ VCard::Address address;
+ address.isPreferred = getPreferred();
+ address.isHome = getHome();
+ address.isWork = getWork();
+ address.deliveryType = domesticRadioButton->isChecked() ? VCard::DomesticDelivery : (internationalRadioButton->isChecked() ? VCard::InternationalDelivery : VCard::None);
+ address.isPostal = getTagComboBox()->isTagSet("postal");
+ address.isParcel = getTagComboBox()->isTagSet("parcel");
+ address.street = Q2PSTRING(streetLineEdit->text());
+ address.poBox = Q2PSTRING(poboxLineEdit->text());
+ address.addressExtension = Q2PSTRING(addressextLineEdit->text());
+ address.locality = Q2PSTRING(cityLineEdit->text());
+ address.postalCode = Q2PSTRING(pocodeLineEdit->text());
+ address.region = Q2PSTRING(regionLineEdit->text());
+ address.country = Q2PSTRING(countryLineEdit->text());
+ return address;
}
void QtVCardAddressField::handleEditibleChanged(bool isEditable) {
- assert(streetLineEdit);
- assert(poboxLineEdit);
- assert(addressextLineEdit);
- assert(cityLineEdit);
- assert(pocodeLineEdit);
- assert(regionLineEdit);
- assert(countryLineEdit);
- assert(deliveryTypeLabel);
- assert(domesticRadioButton);
- assert(internationalRadioButton);
-
- streetLineEdit->setEditable(isEditable);
- poboxLineEdit->setEditable(isEditable);
- addressextLineEdit->setEditable(isEditable);
- cityLineEdit->setEditable(isEditable);
- pocodeLineEdit->setEditable(isEditable);
- regionLineEdit->setEditable(isEditable);
- countryLineEdit->setEditable(isEditable);
-
- deliveryTypeLabel->setText(buttonGroup->checkedButton() == 0 ? "" : buttonGroup->checkedButton()->text());
- deliveryTypeLabel->setVisible(!isEditable);
-
- domesticRadioButton->setVisible(isEditable);
- internationalRadioButton->setVisible(isEditable);
-
- foreach (QWidget* widget, textFields) {
- QtResizableLineEdit* lineEdit;
- if ((lineEdit = dynamic_cast<QtResizableLineEdit*>(widget))) {
- lineEdit->setVisible(isEditable ? true : !lineEdit->text().isEmpty());
- lineEdit->setStyleSheet(isEditable ? "" : "QLineEdit { border: none; background: transparent; }");
- }
- }
+ assert(streetLineEdit);
+ assert(poboxLineEdit);
+ assert(addressextLineEdit);
+ assert(cityLineEdit);
+ assert(pocodeLineEdit);
+ assert(regionLineEdit);
+ assert(countryLineEdit);
+ assert(deliveryTypeLabel);
+ assert(domesticRadioButton);
+ assert(internationalRadioButton);
+
+ streetLineEdit->setEditable(isEditable);
+ poboxLineEdit->setEditable(isEditable);
+ addressextLineEdit->setEditable(isEditable);
+ cityLineEdit->setEditable(isEditable);
+ pocodeLineEdit->setEditable(isEditable);
+ regionLineEdit->setEditable(isEditable);
+ countryLineEdit->setEditable(isEditable);
+
+ deliveryTypeLabel->setText(buttonGroup->checkedButton() == nullptr ? "" : buttonGroup->checkedButton()->text());
+ deliveryTypeLabel->setVisible(!isEditable);
+
+ domesticRadioButton->setVisible(isEditable);
+ internationalRadioButton->setVisible(isEditable);
+
+ for (auto widget : textFields) {
+ QtResizableLineEdit* lineEdit;
+ if ((lineEdit = dynamic_cast<QtResizableLineEdit*>(widget))) {
+ lineEdit->setVisible(isEditable ? true : !lineEdit->text().isEmpty());
+ lineEdit->setStyleSheet(isEditable ? "" : "QLineEdit { border: none; background: transparent; }");
+ }
+ }
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardAddressField.h b/Swift/QtUI/QtVCardWidget/QtVCardAddressField.h
index 8cbee18..aeebbff 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardAddressField.h
+++ b/Swift/QtUI/QtVCardWidget/QtVCardAddressField.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -27,42 +27,42 @@ namespace Swift {
class QtElidingLabel;
class QtVCardAddressField : public QtVCardGeneralField, public QtVCardHomeWork {
- Q_OBJECT
-
- public:
- GENERIC_QT_VCARD_FIELD_INFO("Address", UNLIMITED_INSTANCES, QtVCardAddressField)
-
- QtVCardAddressField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
- virtual ~QtVCardAddressField();
-
- virtual bool isEmpty() const;
-
- void setAddress(const VCard::Address& address);
- VCard::Address getAddress() const;
-
- protected:
- virtual void setupContentWidgets();
- virtual void customCleanup();
-
- public slots:
- void handleEditibleChanged(bool isEditable);
-
- private:
- QList<QWidget*> textFields;
- QtResizableLineEdit* streetLineEdit;
- QtResizableLineEdit* poboxLineEdit;
- QtResizableLineEdit* addressextLineEdit;
- QtResizableLineEdit* cityLineEdit;
- QtResizableLineEdit* pocodeLineEdit;
- QtResizableLineEdit* regionLineEdit;
- QtResizableLineEdit* countryLineEdit;
- QGridLayout* textFieldGridLayout;
- QLayoutItem* textFieldGridLayoutItem;
-
- QtElidingLabel* deliveryTypeLabel;
- QRadioButton* domesticRadioButton;
- QRadioButton* internationalRadioButton;
- QButtonGroup* buttonGroup;
+ Q_OBJECT
+
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO(tr("Address"), UNLIMITED_INSTANCES, QtVCardAddressField)
+
+ QtVCardAddressField(QWidget* parent = nullptr, QGridLayout* layout = nullptr, bool editable = false);
+ virtual ~QtVCardAddressField();
+
+ virtual bool isEmpty() const;
+
+ void setAddress(const VCard::Address& address);
+ VCard::Address getAddress() const;
+
+ protected:
+ virtual void setupContentWidgets();
+ virtual void customCleanup();
+
+ public slots:
+ void handleEditibleChanged(bool isEditable);
+
+ private:
+ QList<QWidget*> textFields;
+ QtResizableLineEdit* streetLineEdit;
+ QtResizableLineEdit* poboxLineEdit;
+ QtResizableLineEdit* addressextLineEdit;
+ QtResizableLineEdit* cityLineEdit;
+ QtResizableLineEdit* pocodeLineEdit;
+ QtResizableLineEdit* regionLineEdit;
+ QtResizableLineEdit* countryLineEdit;
+ QGridLayout* textFieldGridLayout;
+ QLayoutItem* textFieldGridLayoutItem;
+
+ QtElidingLabel* deliveryTypeLabel;
+ QRadioButton* domesticRadioButton;
+ QRadioButton* internationalRadioButton;
+ QButtonGroup* buttonGroup;
};
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.cpp
index 64d2533..e4a75cd 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -22,86 +22,86 @@
namespace Swift {
QtVCardAddressLabelField::QtVCardAddressLabelField(QWidget* parent, QGridLayout *layout, bool editable) :
- QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Address Label")), addressLabelPlainTextEdit(NULL), deliveryTypeLabel(NULL), domesticRadioButton(NULL), internationalRadioButton(NULL), buttonGroup(NULL) {
- connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Address Label")), addressLabelPlainTextEdit(nullptr), deliveryTypeLabel(nullptr), domesticRadioButton(nullptr), internationalRadioButton(nullptr), buttonGroup(nullptr) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
}
QtVCardAddressLabelField::~QtVCardAddressLabelField() {
- disconnect(this, SLOT(handleEditibleChanged(bool)));
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
}
void QtVCardAddressLabelField::setupContentWidgets() {
- addressLabelPlainTextEdit = new QPlainTextEdit(this);
- addressLabelPlainTextEdit->setTabChangesFocus(true);
- getGridLayout()->addWidget(addressLabelPlainTextEdit, getGridLayout()->rowCount()-1, 2, 3, 2, Qt::AlignVCenter);
+ addressLabelPlainTextEdit = new QPlainTextEdit(this);
+ addressLabelPlainTextEdit->setTabChangesFocus(true);
+ getGridLayout()->addWidget(addressLabelPlainTextEdit, getGridLayout()->rowCount()-1, 2, 3, 2, Qt::AlignVCenter);
- deliveryTypeLabel = new QtElidingLabel(this);
- deliveryTypeLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
- getGridLayout()->addWidget(deliveryTypeLabel, getGridLayout()->rowCount()-2, 4, Qt::AlignVCenter);
+ deliveryTypeLabel = new QtElidingLabel(this);
+ deliveryTypeLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
+ getGridLayout()->addWidget(deliveryTypeLabel, getGridLayout()->rowCount()-2, 4, Qt::AlignVCenter);
- domesticRadioButton = new QRadioButton(tr("Domestic Delivery"), this);
- getGridLayout()->addWidget(domesticRadioButton, getGridLayout()->rowCount()-2, 4, Qt::AlignVCenter);
+ domesticRadioButton = new QRadioButton(tr("Domestic Delivery"), this);
+ getGridLayout()->addWidget(domesticRadioButton, getGridLayout()->rowCount()-2, 4, Qt::AlignVCenter);
- internationalRadioButton = new QRadioButton(tr("International Delivery"), this);
- getGridLayout()->addWidget(internationalRadioButton, getGridLayout()->rowCount()-1, 4, Qt::AlignVCenter);
+ internationalRadioButton = new QRadioButton(tr("International Delivery"), this);
+ getGridLayout()->addWidget(internationalRadioButton, getGridLayout()->rowCount()-1, 4, Qt::AlignVCenter);
- buttonGroup = new QButtonGroup(this);
- buttonGroup->addButton(domesticRadioButton);
- buttonGroup->addButton(internationalRadioButton);
+ buttonGroup = new QButtonGroup(this);
+ buttonGroup->addButton(domesticRadioButton);
+ buttonGroup->addButton(internationalRadioButton);
- setTabOrder(internationalRadioButton, getTagComboBox());
- getTagComboBox()->addTag("postal", tr("Postal"));
- getTagComboBox()->addTag("parcel", tr("Parcel"));
+ setTabOrder(internationalRadioButton, getTagComboBox());
+ getTagComboBox()->addTag("postal", tr("Postal"));
+ getTagComboBox()->addTag("parcel", tr("Parcel"));
- QtVCardHomeWork::setTagComboBox(getTagComboBox());
- deliveryTypeLabel->hide();
- childWidgets << addressLabelPlainTextEdit << deliveryTypeLabel << domesticRadioButton << internationalRadioButton;
+ QtVCardHomeWork::setTagComboBox(getTagComboBox());
+ deliveryTypeLabel->hide();
+ childWidgets << addressLabelPlainTextEdit << deliveryTypeLabel << domesticRadioButton << internationalRadioButton;
}
bool QtVCardAddressLabelField::isEmpty() const {
- return addressLabelPlainTextEdit->toPlainText().isEmpty();
+ return addressLabelPlainTextEdit->toPlainText().isEmpty();
}
void QtVCardAddressLabelField::setAddressLabel(const VCard::AddressLabel& addressLabel) {
- setPreferred(addressLabel.isPreferred);
- setHome(addressLabel.isHome);
- setWork(addressLabel.isWork);
- getTagComboBox()->setTag("postal", addressLabel.isPostal);
- getTagComboBox()->setTag("parcel", addressLabel.isParcel);
- domesticRadioButton->setChecked(addressLabel.deliveryType == VCard::DomesticDelivery);
- internationalRadioButton->setChecked(addressLabel.deliveryType == VCard::InternationalDelivery);
- std::string joinedLines = boost::algorithm::join(addressLabel.lines, "\n");
- addressLabelPlainTextEdit->setPlainText(P2QSTRING(joinedLines));
+ setPreferred(addressLabel.isPreferred);
+ setHome(addressLabel.isHome);
+ setWork(addressLabel.isWork);
+ getTagComboBox()->setTag("postal", addressLabel.isPostal);
+ getTagComboBox()->setTag("parcel", addressLabel.isParcel);
+ domesticRadioButton->setChecked(addressLabel.deliveryType == VCard::DomesticDelivery);
+ internationalRadioButton->setChecked(addressLabel.deliveryType == VCard::InternationalDelivery);
+ std::string joinedLines = boost::algorithm::join(addressLabel.lines, "\n");
+ addressLabelPlainTextEdit->setPlainText(P2QSTRING(joinedLines));
}
VCard::AddressLabel QtVCardAddressLabelField::getAddressLabel() const {
- VCard::AddressLabel addressLabel;
- addressLabel.isPreferred = getPreferred();
- addressLabel.isHome = getHome();
- addressLabel.isWork = getWork();
- addressLabel.deliveryType = domesticRadioButton->isChecked() ? VCard::DomesticDelivery : (internationalRadioButton->isChecked() ? VCard::InternationalDelivery : VCard::None);
- addressLabel.isPostal = getTagComboBox()->isTagSet("postal");
- addressLabel.isParcel = getTagComboBox()->isTagSet("parcel");
-
- std::string lines = Q2PSTRING(addressLabelPlainTextEdit->toPlainText());
- boost::split(addressLabel.lines, lines, boost::is_any_of("\n"));
- return addressLabel;
+ VCard::AddressLabel addressLabel;
+ addressLabel.isPreferred = getPreferred();
+ addressLabel.isHome = getHome();
+ addressLabel.isWork = getWork();
+ addressLabel.deliveryType = domesticRadioButton->isChecked() ? VCard::DomesticDelivery : (internationalRadioButton->isChecked() ? VCard::InternationalDelivery : VCard::None);
+ addressLabel.isPostal = getTagComboBox()->isTagSet("postal");
+ addressLabel.isParcel = getTagComboBox()->isTagSet("parcel");
+
+ std::string lines = Q2PSTRING(addressLabelPlainTextEdit->toPlainText());
+ boost::split(addressLabel.lines, lines, boost::is_any_of("\n"));
+ return addressLabel;
}
void QtVCardAddressLabelField::handleEditibleChanged(bool isEditable) {
- assert(addressLabelPlainTextEdit);
- assert(deliveryTypeLabel);
- assert(domesticRadioButton);
- assert(internationalRadioButton);
+ assert(addressLabelPlainTextEdit);
+ assert(deliveryTypeLabel);
+ assert(domesticRadioButton);
+ assert(internationalRadioButton);
- addressLabelPlainTextEdit->setReadOnly(!isEditable);
- addressLabelPlainTextEdit->setStyleSheet(isEditable ? "" : "QPlainTextEdit { background: transparent; }");
+ addressLabelPlainTextEdit->setReadOnly(!isEditable);
+ addressLabelPlainTextEdit->setStyleSheet(isEditable ? "" : "QPlainTextEdit { background: transparent; }");
- deliveryTypeLabel->setText(buttonGroup->checkedButton() == 0 ? "" : buttonGroup->checkedButton()->text());
- deliveryTypeLabel->setVisible(!isEditable);
+ deliveryTypeLabel->setText(buttonGroup->checkedButton() == nullptr ? "" : buttonGroup->checkedButton()->text());
+ deliveryTypeLabel->setVisible(!isEditable);
- domesticRadioButton->setVisible(isEditable);
- internationalRadioButton->setVisible(isEditable);
+ domesticRadioButton->setVisible(isEditable);
+ internationalRadioButton->setVisible(isEditable);
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.h b/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.h
index 7d9893b..ceca88a 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.h
+++ b/Swift/QtUI/QtVCardWidget/QtVCardAddressLabelField.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -27,32 +27,32 @@ namespace Swift {
class QtElidingLabel;
class QtVCardAddressLabelField : public QtVCardGeneralField, public QtVCardHomeWork {
- Q_OBJECT
+ Q_OBJECT
- public:
- GENERIC_QT_VCARD_FIELD_INFO("Address Label", UNLIMITED_INSTANCES, QtVCardAddressLabelField)
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO(tr("Address Label"), UNLIMITED_INSTANCES, QtVCardAddressLabelField)
- QtVCardAddressLabelField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
- virtual ~QtVCardAddressLabelField();
+ QtVCardAddressLabelField(QWidget* parent = nullptr, QGridLayout* layout = nullptr, bool editable = false);
+ virtual ~QtVCardAddressLabelField();
- virtual bool isEmpty() const;
+ virtual bool isEmpty() const;
- void setAddressLabel(const VCard::AddressLabel& addressLabel);
- VCard::AddressLabel getAddressLabel() const;
+ void setAddressLabel(const VCard::AddressLabel& addressLabel);
+ VCard::AddressLabel getAddressLabel() const;
- protected:
- virtual void setupContentWidgets();
+ protected:
+ virtual void setupContentWidgets();
- public slots:
- void handleEditibleChanged(bool isEditable);
+ public slots:
+ void handleEditibleChanged(bool isEditable);
- private:
- QPlainTextEdit* addressLabelPlainTextEdit;
+ private:
+ QPlainTextEdit* addressLabelPlainTextEdit;
- QtElidingLabel* deliveryTypeLabel;
- QRadioButton* domesticRadioButton;
- QRadioButton* internationalRadioButton;
- QButtonGroup* buttonGroup;
+ QtElidingLabel* deliveryTypeLabel;
+ QRadioButton* domesticRadioButton;
+ QRadioButton* internationalRadioButton;
+ QButtonGroup* buttonGroup;
};
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.cpp
index 7b0d02e..1111295 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.cpp
@@ -4,58 +4,65 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "QtVCardBirthdayField.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.h>
+
+#include <boost/algorithm/string.hpp>
#include <QGridLayout>
#include <QHBoxLayout>
-#include <boost/algorithm/string.hpp>
#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
QtVCardBirthdayField::QtVCardBirthdayField(QWidget* parent, QGridLayout *layout, bool editable) :
- QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Birthday"), false, false), birthdayLabel(NULL), birthdayDateEdit(NULL) {
- connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Birthday"), false, false), birthdayLabel(nullptr), birthdayDateEdit(nullptr) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
}
QtVCardBirthdayField::~QtVCardBirthdayField() {
- disconnect(this, SLOT(handleEditibleChanged(bool)));
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
}
void QtVCardBirthdayField::setupContentWidgets() {
- birthdayLabel = new QLabel(this);
- birthdayLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
- birthdayDateEdit = new QDateEdit(this);
- birthdayDateEdit->setCalendarPopup(true);
+ birthdayLabel = new QLabel(this);
+ birthdayLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
+ birthdayDateEdit = new QDateEdit(this);
+ birthdayDateEdit->setCalendarPopup(true);
- QHBoxLayout* birthdayLayout = new QHBoxLayout();
- birthdayLayout->addWidget(birthdayLabel);
- birthdayLayout->addWidget(birthdayDateEdit);
+ QHBoxLayout* birthdayLayout = new QHBoxLayout();
+ birthdayLayout->addWidget(birthdayLabel);
+ birthdayLayout->addWidget(birthdayDateEdit);
- getGridLayout()->addLayout(birthdayLayout, getGridLayout()->rowCount()-1, 2, Qt::AlignVCenter);
+ getGridLayout()->addLayout(birthdayLayout, getGridLayout()->rowCount()-1, 2, Qt::AlignVCenter);
- getTagComboBox()->hide();
- birthdayLabel->hide();
- childWidgets << birthdayLabel << birthdayDateEdit;
+ getTagComboBox()->hide();
+ birthdayLabel->hide();
+ childWidgets << birthdayLabel << birthdayDateEdit;
}
bool QtVCardBirthdayField::isEmpty() const {
- return false;
+ return false;
}
void QtVCardBirthdayField::setBirthday(const boost::posix_time::ptime& birthday) {
- birthdayDateEdit->setDate(B2QDATE(birthday).date());
+ birthdayDateEdit->setDate(B2QDATE(birthday).date());
}
boost::posix_time::ptime QtVCardBirthdayField::getBirthday() const {
- return boost::posix_time::from_time_t(QDateTime(birthdayDateEdit->date()).toTime_t());
+ return boost::posix_time::from_time_t(QDateTime(birthdayDateEdit->date()).toTime_t());
}
void QtVCardBirthdayField::handleEditibleChanged(bool isEditable) {
- birthdayLabel->setText(birthdayDateEdit->date().toString(Qt::DefaultLocaleLongDate));
- birthdayDateEdit->setVisible(isEditable);
- birthdayLabel->setVisible(!isEditable);
+ birthdayLabel->setText(birthdayDateEdit->date().toString(Qt::DefaultLocaleLongDate));
+ birthdayDateEdit->setVisible(isEditable);
+ birthdayLabel->setVisible(!isEditable);
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.h b/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.h
index 4be6e27..0383b6c 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.h
+++ b/Swift/QtUI/QtVCardWidget/QtVCardBirthdayField.h
@@ -4,40 +4,47 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <QDateEdit>
+
#include <Swiften/Elements/VCard.h>
-#include "QtCloseButton.h"
-#include "QtVCardFieldInfo.h"
-#include "QtVCardGeneralField.h"
+#include <Swift/QtUI/QtVCardWidget/QtCloseButton.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h>
namespace Swift {
class QtVCardBirthdayField : public QtVCardGeneralField {
- Q_OBJECT
+ Q_OBJECT
- public:
- GENERIC_QT_VCARD_FIELD_INFO("Birthday", 1, QtVCardBirthdayField)
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO(tr("Birthday"), 1, QtVCardBirthdayField)
- QtVCardBirthdayField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
- virtual ~QtVCardBirthdayField();
+ QtVCardBirthdayField(QWidget* parent = nullptr, QGridLayout* layout = nullptr, bool editable = false);
+ virtual ~QtVCardBirthdayField();
- virtual bool isEmpty() const;
+ virtual bool isEmpty() const;
- void setBirthday(const boost::posix_time::ptime& addressLabel);
- boost::posix_time::ptime getBirthday() const;
+ void setBirthday(const boost::posix_time::ptime& addressLabel);
+ boost::posix_time::ptime getBirthday() const;
- protected:
- virtual void setupContentWidgets();
+ protected:
+ virtual void setupContentWidgets();
- public slots:
- void handleEditibleChanged(bool isEditable);
+ public slots:
+ void handleEditibleChanged(bool isEditable);
- private:
- QLabel* birthdayLabel;
- QDateEdit* birthdayDateEdit;
+ private:
+ QLabel* birthdayLabel;
+ QDateEdit* birthdayDateEdit;
};
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.cpp
index 183e64d..2a8e1c9 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.cpp
@@ -4,9 +4,16 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "QtVCardDescriptionField.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.h>
#include <boost/algorithm/string.hpp>
+
#include <QFontMetrics>
#include <QGridLayout>
@@ -15,50 +22,50 @@
namespace Swift {
QtVCardDescriptionField::QtVCardDescriptionField(QWidget* parent, QGridLayout *layout, bool editable) :
- QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Description"), false, false), descriptionPlainTextEdit(NULL) {
- connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Description"), false, false), descriptionPlainTextEdit(nullptr) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
}
QtVCardDescriptionField::~QtVCardDescriptionField() {
- disconnect(this, SLOT(handleEditibleChanged(bool)));
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
}
void QtVCardDescriptionField::setupContentWidgets() {
- descriptionPlainTextEdit = new QPlainTextEdit(this);
- descriptionPlainTextEdit->setMinimumHeight(70);
- getGridLayout()->addWidget(descriptionPlainTextEdit, getGridLayout()->rowCount()-1, 2, 2, 2, Qt::AlignVCenter);
- getTagComboBox()->hide();
- childWidgets << descriptionPlainTextEdit;
+ descriptionPlainTextEdit = new QPlainTextEdit(this);
+ descriptionPlainTextEdit->setMinimumHeight(70);
+ getGridLayout()->addWidget(descriptionPlainTextEdit, getGridLayout()->rowCount()-1, 2, 2, 2, Qt::AlignVCenter);
+ getTagComboBox()->hide();
+ childWidgets << descriptionPlainTextEdit;
}
bool QtVCardDescriptionField::isEmpty() const {
- return descriptionPlainTextEdit->toPlainText().isEmpty();
+ return descriptionPlainTextEdit->toPlainText().isEmpty();
}
void QtVCardDescriptionField::setDescription(const std::string& description) {
- descriptionPlainTextEdit->setPlainText(P2QSTRING(description));
+ descriptionPlainTextEdit->setPlainText(P2QSTRING(description));
}
std::string QtVCardDescriptionField::getDescription() const {
- return Q2PSTRING(descriptionPlainTextEdit->toPlainText());
+ return Q2PSTRING(descriptionPlainTextEdit->toPlainText());
}
void QtVCardDescriptionField::handleEditibleChanged(bool isEditable) {
- assert(descriptionPlainTextEdit);
+ assert(descriptionPlainTextEdit);
- if (isEditable) {
- descriptionPlainTextEdit->setMinimumHeight(70);
- } else {
- QFontMetrics inputMetrics(descriptionPlainTextEdit->document()->defaultFont());
- QRect horizontalBounds = contentsRect().adjusted(0,0,0,9999);
- QRect boundingRect = inputMetrics.boundingRect(horizontalBounds, Qt::TextWordWrap, descriptionPlainTextEdit->toPlainText() + "A");
- int left, top, right, bottom;
- getContentsMargins(&left, &top, &right, &bottom);
- int height = boundingRect.height() + top + bottom + inputMetrics.height();
- descriptionPlainTextEdit->setMinimumHeight(height > 70 ? 70 : height);
- }
- descriptionPlainTextEdit->setReadOnly(!isEditable);
- descriptionPlainTextEdit->setStyleSheet(isEditable ? "" : "QPlainTextEdit { background: transparent; }");
+ if (isEditable) {
+ descriptionPlainTextEdit->setMinimumHeight(70);
+ } else {
+ QFontMetrics inputMetrics(descriptionPlainTextEdit->document()->defaultFont());
+ QRect horizontalBounds = contentsRect().adjusted(0,0,0,9999);
+ QRect boundingRect = inputMetrics.boundingRect(horizontalBounds, Qt::TextWordWrap, descriptionPlainTextEdit->toPlainText() + "A");
+ int left, top, right, bottom;
+ getContentsMargins(&left, &top, &right, &bottom);
+ int height = boundingRect.height() + top + bottom + inputMetrics.height();
+ descriptionPlainTextEdit->setMinimumHeight(height > 70 ? 70 : height);
+ }
+ descriptionPlainTextEdit->setReadOnly(!isEditable);
+ descriptionPlainTextEdit->setStyleSheet(isEditable ? "" : "QPlainTextEdit { background: transparent; }");
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.h b/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.h
index 3b1b3d9..c06dd97 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.h
+++ b/Swift/QtUI/QtVCardWidget/QtVCardDescriptionField.h
@@ -4,39 +4,45 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#pragma once
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
-#include <Swiften/Elements/VCard.h>
+#pragma once
#include <QPlainTextEdit>
-#include "QtVCardFieldInfo.h"
-#include "QtVCardGeneralField.h"
+#include <Swiften/Elements/VCard.h>
+
+#include <Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h>
namespace Swift {
class QtVCardDescriptionField : public QtVCardGeneralField {
- Q_OBJECT
+ Q_OBJECT
- public:
- GENERIC_QT_VCARD_FIELD_INFO("Description", 1, QtVCardDescriptionField)
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO(tr("Description"), 1, QtVCardDescriptionField)
- QtVCardDescriptionField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
- virtual ~QtVCardDescriptionField();
+ QtVCardDescriptionField(QWidget* parent = nullptr, QGridLayout* layout = nullptr, bool editable = false);
+ virtual ~QtVCardDescriptionField();
- virtual bool isEmpty() const;
+ virtual bool isEmpty() const;
- void setDescription(const std::string& description);
- std::string getDescription() const;
+ void setDescription(const std::string& description);
+ std::string getDescription() const;
- protected:
- virtual void setupContentWidgets();
+ protected:
+ virtual void setupContentWidgets();
- public slots:
- void handleEditibleChanged(bool isEditable);
+ public slots:
+ void handleEditibleChanged(bool isEditable);
- private:
- QPlainTextEdit* descriptionPlainTextEdit;
+ private:
+ QPlainTextEdit* descriptionPlainTextEdit;
};
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h b/Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h
index 168c01b..093357a 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h
+++ b/Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h
@@ -4,49 +4,55 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
+#include <typeinfo>
+
#include <QGridLayout>
#include <QObject>
#include <QString>
-#include <typeinfo>
-
#define GENERIC_QT_VCARD_FIELD_INFO(MENU_NAME, ALLOWED_INSTANCES, FIELD_CLASS) \
- class FieldInfo : public QtVCardFieldInfo { \
- public: \
- virtual ~FieldInfo() { \
- } \
- \
- virtual QString getMenuName() const { \
- return QObject::tr(MENU_NAME); \
- } \
- \
- virtual int getAllowedInstances() const { \
- return ALLOWED_INSTANCES; \
- } \
- \
- virtual QWidget* createFieldInstance(QWidget* parent, QGridLayout* layout, bool editable) const { \
- return new FIELD_CLASS(parent, layout, editable); \
- } \
- \
- virtual bool testInstance(QWidget* widget) const { \
- return dynamic_cast<FIELD_CLASS*>(widget) != 0; \
- } \
- };
+ class FieldInfo : public QtVCardFieldInfo { \
+ public: \
+ virtual ~FieldInfo() { \
+ } \
+ \
+ virtual QString getMenuName() const { \
+ return MENU_NAME; \
+ } \
+ \
+ virtual int getAllowedInstances() const { \
+ return ALLOWED_INSTANCES; \
+ } \
+ \
+ virtual QWidget* createFieldInstance(QWidget* parent, QGridLayout* layout, bool editable) const { \
+ return new FIELD_CLASS(parent, layout, editable); \
+ } \
+ \
+ virtual bool testInstance(QWidget* widget) const { \
+ return dynamic_cast<FIELD_CLASS*>(widget) != 0; \
+ } \
+ };
class QWidget;
namespace Swift {
- class QtVCardFieldInfo {
- public:
- static const int UNLIMITED_INSTANCES = -1;
-
- virtual ~QtVCardFieldInfo() {
- }
- virtual QString getMenuName() const = 0;
- virtual int getAllowedInstances() const = 0;
- virtual QWidget* createFieldInstance(QWidget* parent, QGridLayout* layout, bool editable) const = 0;
- virtual bool testInstance(QWidget*) const = 0;
- };
+ class QtVCardFieldInfo {
+ public:
+ static const int UNLIMITED_INSTANCES = -1;
+
+ virtual ~QtVCardFieldInfo() {
+ }
+ virtual QString getMenuName() const = 0;
+ virtual int getAllowedInstances() const = 0;
+ virtual QWidget* createFieldInstance(QWidget* parent, QGridLayout* layout, bool editable) const = 0;
+ virtual bool testInstance(QWidget*) const = 0;
+ };
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardGeneralField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardGeneralField.cpp
index ed30ae1..9bb6a35 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardGeneralField.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtVCardGeneralField.cpp
@@ -22,8 +22,8 @@
namespace Swift {
QtVCardGeneralField::QtVCardGeneralField(QWidget* parent, QGridLayout* layout, bool editable, int row, QString label, bool preferrable, bool taggable) :
- QWidget(parent), editable(editable), preferrable(preferrable), starVisible(false), taggable(taggable), layout(layout), row(row), preferredCheckBox(0), label(0), labelText(label),
- tagComboBox(0), tagLabel(NULL), closeButton(0) {
+ QWidget(parent), editable(editable), preferrable(preferrable), starVisible(false), taggable(taggable), layout(layout), row(row), preferredCheckBox(nullptr), label(nullptr), labelText(label),
+ tagComboBox(nullptr), tagLabel(nullptr), closeButton(nullptr) {
}
QtVCardGeneralField::~QtVCardGeneralField() {
@@ -31,126 +31,126 @@ QtVCardGeneralField::~QtVCardGeneralField() {
}
void QtVCardGeneralField::initialize() {
- if (preferrable) {
- preferredCheckBox = new QCheckBox(this);
- preferredCheckBox->setToolTip(tr("Stars can be used to mark preferred contact details."));
- preferredCheckBox->setStyleSheet(
- "QCheckBox::indicator { width: 18px; height: 18px; }"
- "QCheckBox::indicator:checked { image: url(:/icons/star-checked.png); }"
- "QCheckBox::indicator:unchecked { image: url(:/icons/star-unchecked.png); }"
- );
- layout->addWidget(preferredCheckBox, row, 0, Qt::AlignVCenter);
- childWidgets << preferredCheckBox;
- connect(preferredCheckBox, SIGNAL(stateChanged(int)), SLOT(handlePreferredStarStateChanged(int)));
- }
- label = new QLabel(this);
- label->setText(labelText);
- layout->addWidget(label, row, 1, Qt::AlignVCenter | Qt::AlignRight);
-
- tagLabel = new QtElidingLabel(this);
- tagLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
-
- tagComboBox = new QtTagComboBox(this);
- closeButton = new QtCloseButton(this);
- connect(closeButton, SIGNAL(clicked()), SLOT(handleCloseButtonClicked()));
-
- QHBoxLayout* tagLayout = new QHBoxLayout();
- tagLayout->addWidget(tagLabel);
- tagLayout->addWidget(tagComboBox);
-
- setupContentWidgets();
- layout->addLayout(tagLayout, row, 4, Qt::AlignTop);
- layout->addWidget(closeButton, row, 5, Qt::AlignCenter);
- closeButton->resize(12, 12);
- tagLabel->hide();
-
- childWidgets << label << tagComboBox << tagLabel << closeButton;
- setEditable(editable);
+ if (preferrable) {
+ preferredCheckBox = new QCheckBox(this);
+ preferredCheckBox->setToolTip(tr("Stars can be used to mark preferred contact details."));
+ preferredCheckBox->setStyleSheet(
+ "QCheckBox::indicator { width: 18px; height: 18px; }"
+ "QCheckBox::indicator:checked { image: url(:/icons/star-checked.png); }"
+ "QCheckBox::indicator:unchecked { image: url(:/icons/star-unchecked.png); }"
+ );
+ layout->addWidget(preferredCheckBox, row, 0, Qt::AlignVCenter);
+ childWidgets << preferredCheckBox;
+ connect(preferredCheckBox, SIGNAL(stateChanged(int)), SLOT(handlePreferredStarStateChanged(int)));
+ }
+ label = new QLabel(this);
+ label->setText(labelText);
+ layout->addWidget(label, row, 1, Qt::AlignVCenter | Qt::AlignRight);
+
+ tagLabel = new QtElidingLabel(this);
+ tagLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
+
+ tagComboBox = new QtTagComboBox(this);
+ closeButton = new QtCloseButton(this);
+ connect(closeButton, SIGNAL(clicked()), SLOT(handleCloseButtonClicked()));
+
+ QHBoxLayout* tagLayout = new QHBoxLayout();
+ tagLayout->addWidget(tagLabel);
+ tagLayout->addWidget(tagComboBox);
+
+ setupContentWidgets();
+ layout->addLayout(tagLayout, row, 4, Qt::AlignTop);
+ layout->addWidget(closeButton, row, 5, Qt::AlignCenter);
+ closeButton->resize(12, 12);
+ tagLabel->hide();
+
+ childWidgets << label << tagComboBox << tagLabel << closeButton;
+ setEditable(editable);
}
bool QtVCardGeneralField::isEditable() const {
- return editable;
+ return editable;
}
void QtVCardGeneralField::setEditable(bool editable) {
- assert(tagComboBox);
- assert(closeButton);
-
- this->editable = editable;
- if (taggable) {
- tagLabel->setText(tagComboBox->itemText(0));
- tagComboBox->setVisible(editable);
- tagLabel->setVisible(!editable);
- } else {
- tagLabel->hide();
- tagComboBox->hide();
- }
- closeButton->setVisible(editable);
- updatePreferredStarVisibility();
- editableChanged(this->editable);
+ assert(tagComboBox);
+ assert(closeButton);
+
+ this->editable = editable;
+ if (taggable) {
+ tagLabel->setText(tagComboBox->itemText(0));
+ tagComboBox->setVisible(editable);
+ tagLabel->setVisible(!editable);
+ } else {
+ tagLabel->hide();
+ tagComboBox->hide();
+ }
+ closeButton->setVisible(editable);
+ updatePreferredStarVisibility();
+ editableChanged(this->editable);
}
void QtVCardGeneralField::setStarVisible(const bool isVisible) {
- starVisible = isVisible;
- updatePreferredStarVisibility();
+ starVisible = isVisible;
+ updatePreferredStarVisibility();
}
bool QtVCardGeneralField::getStarVisible() const {
- return starVisible;
+ return starVisible;
}
void QtVCardGeneralField::setPreferred(const bool preferred) {
- if (preferredCheckBox) preferredCheckBox->setChecked(preferred);
- updatePreferredStarVisibility();
+ if (preferredCheckBox) preferredCheckBox->setChecked(preferred);
+ updatePreferredStarVisibility();
}
bool QtVCardGeneralField::getPreferred() const {
- return preferredCheckBox ? preferredCheckBox->isChecked() : false;
+ return preferredCheckBox ? preferredCheckBox->isChecked() : false;
}
void QtVCardGeneralField::customCleanup() {
}
QtTagComboBox* QtVCardGeneralField::getTagComboBox() const {
- return tagComboBox;
+ return tagComboBox;
}
QGridLayout* QtVCardGeneralField::getGridLayout() const {
- return layout;
+ return layout;
}
void QtVCardGeneralField::handleCloseButtonClicked() {
- customCleanup();
- foreach(QWidget* widget, childWidgets) {
- widget->hide();
- layout->removeWidget(widget);
- }
- deleteField(this);
+ customCleanup();
+ for (auto widget : childWidgets) {
+ widget->hide();
+ layout->removeWidget(widget);
+ }
+ deleteField(this);
}
void QtVCardGeneralField::handlePreferredStarStateChanged(int state) {
- if (state == Qt::Checked) {
- QToolTip::showText(QCursor::pos(), tr("Marked as your preferred %1. Click again to undo.").arg(labelText));
- }
+ if (state == Qt::Checked) {
+ QToolTip::showText(QCursor::pos(), tr("Marked as your preferred %1. Click again to undo.").arg(labelText));
+ }
}
void QtVCardGeneralField::updatePreferredStarVisibility() {
- if (preferredCheckBox) {
- bool showStar = false;
- if (editable) {
- if (starVisible) {
- showStar = true;
- }
- else {
- showStar = preferredCheckBox->isChecked();
- }
- }
- else {
- showStar = preferredCheckBox->isChecked();
- }
- preferredCheckBox->setVisible(showStar);
- preferredCheckBox->setEnabled(editable);
- }
+ if (preferredCheckBox) {
+ bool showStar = false;
+ if (editable) {
+ if (starVisible) {
+ showStar = true;
+ }
+ else {
+ showStar = preferredCheckBox->isChecked();
+ }
+ }
+ else {
+ showStar = preferredCheckBox->isChecked();
+ }
+ preferredCheckBox->setVisible(showStar);
+ preferredCheckBox->setEnabled(editable);
+ }
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h b/Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h
index 6583d12..48ecf9f 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h
+++ b/Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -25,69 +25,69 @@ namespace Swift {
class QtElidingLabel;
/*
- * covers features like:
- * - preffered (star ceckbox)
- * - combo check box
- * - label
- * - remove button
+ * covers features like:
+ * - preffered (star ceckbox)
+ * - combo check box
+ * - label
+ * - remove button
*/
class QtVCardGeneralField : public QWidget {
- Q_OBJECT
- Q_PROPERTY(bool editable READ isEditable WRITE setEditable NOTIFY editableChanged)
- Q_PROPERTY(bool empty READ isEmpty)
-
- public:
- explicit QtVCardGeneralField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false, int row = 0, QString label = QString(),
- bool preferrable = true, bool taggable = true);
- virtual ~QtVCardGeneralField();
-
- void initialize();
-
- virtual bool isEditable() const;
- virtual void setEditable(bool);
-
- virtual bool isEmpty() const = 0;
-
- void setStarVisible(const bool isVisible);
- bool getStarVisible() const;
-
- void setPreferred(const bool preferred);
- bool getPreferred() const;
-
- protected:
- virtual void setupContentWidgets() = 0;
- virtual void customCleanup();
-
- QtTagComboBox* getTagComboBox() const;
- QGridLayout* getGridLayout() const;
-
- signals:
- void editableChanged(bool);
- void deleteField(QtVCardGeneralField*);
-
- public slots:
- void handleCloseButtonClicked();
- void handlePreferredStarStateChanged(int statte);
-
- protected:
- QList<QWidget*> childWidgets;
-
- private:
- void updatePreferredStarVisibility();
-
- private:
- bool editable;
- bool preferrable;
- bool starVisible;
- bool taggable;
- QGridLayout* layout;
- int row;
- QCheckBox* preferredCheckBox;
- QLabel* label;
- QString labelText;
- QtTagComboBox* tagComboBox;
- QtElidingLabel* tagLabel;
- QtCloseButton* closeButton;
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable NOTIFY editableChanged)
+ Q_PROPERTY(bool empty READ isEmpty)
+
+ public:
+ explicit QtVCardGeneralField(QWidget* parent = nullptr, QGridLayout* layout = nullptr, bool editable = false, int row = 0, QString label = QString(),
+ bool preferrable = true, bool taggable = true);
+ virtual ~QtVCardGeneralField();
+
+ void initialize();
+
+ virtual bool isEditable() const;
+ virtual void setEditable(bool);
+
+ virtual bool isEmpty() const = 0;
+
+ void setStarVisible(const bool isVisible);
+ bool getStarVisible() const;
+
+ void setPreferred(const bool preferred);
+ bool getPreferred() const;
+
+ protected:
+ virtual void setupContentWidgets() = 0;
+ virtual void customCleanup();
+
+ QtTagComboBox* getTagComboBox() const;
+ QGridLayout* getGridLayout() const;
+
+ signals:
+ void editableChanged(bool);
+ void deleteField(QtVCardGeneralField*);
+
+ public slots:
+ void handleCloseButtonClicked();
+ void handlePreferredStarStateChanged(int statte);
+
+ protected:
+ QList<QWidget*> childWidgets;
+
+ private:
+ void updatePreferredStarVisibility();
+
+ private:
+ bool editable;
+ bool preferrable;
+ bool starVisible;
+ bool taggable;
+ QGridLayout* layout;
+ int row;
+ QCheckBox* preferredCheckBox;
+ QLabel* label;
+ QString labelText;
+ QtTagComboBox* tagComboBox;
+ QtElidingLabel* tagLabel;
+ QtCloseButton* closeButton;
};
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardHomeWork.cpp b/Swift/QtUI/QtVCardWidget/QtVCardHomeWork.cpp
index 3119a80..7f204ca 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardHomeWork.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtVCardHomeWork.cpp
@@ -4,36 +4,42 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "QtVCardHomeWork.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtVCardWidget/QtVCardHomeWork.h>
namespace Swift {
-QtVCardHomeWork::QtVCardHomeWork() : tagComboBox(0) {
+QtVCardHomeWork::QtVCardHomeWork() : tagComboBox(nullptr) {
}
QtVCardHomeWork::~QtVCardHomeWork() {
}
void QtVCardHomeWork::setTagComboBox(QtTagComboBox* tagBox) {
- tagComboBox = tagBox;
- tagComboBox->addTag("home", QObject::tr("Home"));
- tagComboBox->addTag("work", QObject::tr("Work"));
+ tagComboBox = tagBox;
+ tagComboBox->addTag("home", QObject::tr("Home"));
+ tagComboBox->addTag("work", QObject::tr("Work"));
}
void QtVCardHomeWork::setHome(const bool home) {
- tagComboBox->setTag("home", home);
+ tagComboBox->setTag("home", home);
}
bool QtVCardHomeWork::getHome() const {
- return tagComboBox->isTagSet("home");
+ return tagComboBox->isTagSet("home");
}
void QtVCardHomeWork::setWork(const bool work) {
- tagComboBox->setTag("work", work);
+ tagComboBox->setTag("work", work);
}
bool QtVCardHomeWork::getWork() const {
- return tagComboBox->isTagSet("work");
+ return tagComboBox->isTagSet("work");
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardHomeWork.h b/Swift/QtUI/QtVCardWidget/QtVCardHomeWork.h
index 768d984..dd1452a 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardHomeWork.h
+++ b/Swift/QtUI/QtVCardWidget/QtVCardHomeWork.h
@@ -4,28 +4,34 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <QObject>
-#include "QtTagComboBox.h"
+#include <Swift/QtUI/QtVCardWidget/QtTagComboBox.h>
namespace Swift {
class QtVCardHomeWork {
- public:
- QtVCardHomeWork();
- virtual ~QtVCardHomeWork();
+ public:
+ QtVCardHomeWork();
+ virtual ~QtVCardHomeWork();
- void setTagComboBox(QtTagComboBox* tagBox);
+ void setTagComboBox(QtTagComboBox* tagBox);
- void setHome(const bool home);
- bool getHome() const;
- void setWork(const bool work);
- bool getWork() const;
+ void setHome(const bool home);
+ bool getHome() const;
+ void setWork(const bool work);
+ bool getWork() const;
- private:
- QtTagComboBox* tagComboBox;
+ private:
+ QtTagComboBox* tagComboBox;
};
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.cpp
index bae9771..9deb7ba 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.cpp
@@ -4,11 +4,18 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "QtVCardInternetEMailField.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.h>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QTextDocument>
+
#include <Swiften/Base/Log.h>
#include <Swift/QtUI/QtSwiftUtil.h>
@@ -17,66 +24,66 @@
namespace Swift {
QtVCardInternetEMailField::QtVCardInternetEMailField(QWidget* parent, QGridLayout *layout, bool editable) :
- QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("E-Mail")), emailLineEdit(NULL), emailLabel(NULL) {
- connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("E-Mail")), emailLineEdit(nullptr), emailLabel(nullptr) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
}
QtVCardInternetEMailField::~QtVCardInternetEMailField() {
- disconnect(this, SLOT(handleEditibleChanged(bool)));
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
}
void QtVCardInternetEMailField::setupContentWidgets() {
- emailLabel = new QLabel(this);
- emailLabel->setOpenExternalLinks(true);
- emailLabel->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard);
- emailLineEdit = new QtResizableLineEdit(this);
+ emailLabel = new QLabel(this);
+ emailLabel->setOpenExternalLinks(true);
+ emailLabel->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard);
+ emailLineEdit = new QtResizableLineEdit(this);
#if QT_VERSION >= 0x040700
- emailLineEdit->setPlaceholderText(tr("alice@wonderland.lit"));
+ emailLineEdit->setPlaceholderText(tr("alice@wonderland.lit"));
#endif
- QHBoxLayout* emailLayout = new QHBoxLayout();
- emailLayout->addWidget(emailLabel);
- emailLayout->addWidget(emailLineEdit);
- getGridLayout()->addLayout(emailLayout, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
- setTabOrder(emailLineEdit, getTagComboBox());
- QtVCardHomeWork::setTagComboBox(getTagComboBox());
- emailLabel->hide();
- childWidgets << emailLabel << emailLineEdit;
+ QHBoxLayout* emailLayout = new QHBoxLayout();
+ emailLayout->addWidget(emailLabel);
+ emailLayout->addWidget(emailLineEdit);
+ getGridLayout()->addLayout(emailLayout, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
+ setTabOrder(emailLineEdit, getTagComboBox());
+ QtVCardHomeWork::setTagComboBox(getTagComboBox());
+ emailLabel->hide();
+ childWidgets << emailLabel << emailLineEdit;
}
bool QtVCardInternetEMailField::isEmpty() const {
- return emailLineEdit->text().isEmpty();
+ return emailLineEdit->text().isEmpty();
}
void QtVCardInternetEMailField::setInternetEMailAddress(const VCard::EMailAddress& address) {
- assert(address.isInternet);
- setPreferred(address.isPreferred);
- setHome(address.isHome);
- setWork(address.isWork);
- emailLineEdit->setText(P2QSTRING(address.address));
+ assert(address.isInternet);
+ setPreferred(address.isPreferred);
+ setHome(address.isHome);
+ setWork(address.isWork);
+ emailLineEdit->setText(P2QSTRING(address.address));
}
VCard::EMailAddress QtVCardInternetEMailField::getInternetEMailAddress() const {
- VCard::EMailAddress address;
- address.isInternet = true;
- address.isPreferred = getPreferred();
- address.isHome = getHome();
- address.isWork = getWork();
- address.address = Q2PSTRING(emailLineEdit->text());
- return address;
+ VCard::EMailAddress address;
+ address.isInternet = true;
+ address.isPreferred = getPreferred();
+ address.isHome = getHome();
+ address.isWork = getWork();
+ address.address = Q2PSTRING(emailLineEdit->text());
+ return address;
}
void QtVCardInternetEMailField::handleEditibleChanged(bool isEditable) {
- assert(emailLineEdit);
- assert(emailLabel);
+ assert(emailLineEdit);
+ assert(emailLabel);
- if (isEditable) {
- emailLineEdit->show();
- emailLabel->hide();
- } else {
- emailLineEdit->hide();
- emailLabel->setText(QString("<a href=\"mailto:%1\">%1</a>").arg(QtUtilities::htmlEscape(emailLineEdit->text())));
- emailLabel->show();
- }
+ if (isEditable) {
+ emailLineEdit->show();
+ emailLabel->hide();
+ } else {
+ emailLineEdit->hide();
+ emailLabel->setText(QString("<a href=\"mailto:%1\">%1</a>").arg(QtUtilities::htmlEscape(emailLineEdit->text())));
+ emailLabel->show();
+ }
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.h b/Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.h
index 3f8a27f..07f4f8d 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.h
+++ b/Swift/QtUI/QtVCardWidget/QtVCardInternetEMailField.h
@@ -4,40 +4,46 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <Swiften/Elements/VCard.h>
-#include "QtResizableLineEdit.h"
-#include "QtVCardFieldInfo.h"
-#include "QtVCardGeneralField.h"
-#include "QtVCardHomeWork.h"
+#include <Swift/QtUI/QtVCardWidget/QtResizableLineEdit.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardHomeWork.h>
namespace Swift {
class QtVCardInternetEMailField : public QtVCardGeneralField, public QtVCardHomeWork {
- Q_OBJECT
+ Q_OBJECT
- public:
- GENERIC_QT_VCARD_FIELD_INFO("E-Mail", UNLIMITED_INSTANCES, QtVCardInternetEMailField)
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO(tr("E-Mail"), UNLIMITED_INSTANCES, QtVCardInternetEMailField)
- QtVCardInternetEMailField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
- virtual ~QtVCardInternetEMailField();
+ QtVCardInternetEMailField(QWidget* parent = nullptr, QGridLayout* layout = nullptr, bool editable = false);
+ virtual ~QtVCardInternetEMailField();
- virtual bool isEmpty() const;
+ virtual bool isEmpty() const;
- void setInternetEMailAddress(const VCard::EMailAddress& address);
- VCard::EMailAddress getInternetEMailAddress() const;
+ void setInternetEMailAddress(const VCard::EMailAddress& address);
+ VCard::EMailAddress getInternetEMailAddress() const;
- protected:
- virtual void setupContentWidgets();
+ protected:
+ virtual void setupContentWidgets();
- public slots:
- void handleEditibleChanged(bool isEditable);
+ public slots:
+ void handleEditibleChanged(bool isEditable);
- private:
- QtResizableLineEdit* emailLineEdit;
- QLabel* emailLabel;
+ private:
+ QtResizableLineEdit* emailLineEdit;
+ QLabel* emailLabel;
};
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardJIDField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardJIDField.cpp
index 28a4438..f93ea06 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardJIDField.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtVCardJIDField.cpp
@@ -4,11 +4,18 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "QtVCardJIDField.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtVCardWidget/QtVCardJIDField.h>
+
+#include <boost/algorithm/string.hpp>
#include <QGridLayout>
#include <QTextDocument>
-#include <boost/algorithm/string.hpp>
#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swift/QtUI/QtUtilities.h>
@@ -16,58 +23,58 @@
namespace Swift {
QtVCardJIDField::QtVCardJIDField(QWidget* parent, QGridLayout *layout, bool editable) :
- QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("JID"), false, false), jidLabel(NULL), jidLineEdit(NULL) {
- connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("JID"), false, false), jidLabel(nullptr), jidLineEdit(nullptr) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
}
QtVCardJIDField::~QtVCardJIDField() {
- disconnect(this, SLOT(handleEditibleChanged(bool)));
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
}
void QtVCardJIDField::setupContentWidgets() {
- jidLabel = new QLabel(this);
- jidLabel->setOpenExternalLinks(true);
- jidLabel->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard);
- jidLineEdit = new QtResizableLineEdit(this);
+ jidLabel = new QLabel(this);
+ jidLabel->setOpenExternalLinks(true);
+ jidLabel->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard);
+ jidLineEdit = new QtResizableLineEdit(this);
#if QT_VERSION >= 0x040700
- jidLineEdit->setPlaceholderText(tr("alice@wonderland.lit"));
+ jidLineEdit->setPlaceholderText(tr("alice@wonderland.lit"));
#endif
- QHBoxLayout* jidLayout = new QHBoxLayout();
- jidLayout->addWidget(jidLabel);
- jidLayout->addWidget(jidLineEdit);
- getGridLayout()->addLayout(jidLayout, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
+ QHBoxLayout* jidLayout = new QHBoxLayout();
+ jidLayout->addWidget(jidLabel);
+ jidLayout->addWidget(jidLineEdit);
+ getGridLayout()->addLayout(jidLayout, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
- jidLabel->hide();
- getTagComboBox()->hide();
+ jidLabel->hide();
+ getTagComboBox()->hide();
- childWidgets << jidLabel << jidLineEdit;
+ childWidgets << jidLabel << jidLineEdit;
}
bool QtVCardJIDField::isEmpty() const {
- return jidLineEdit->text().isEmpty();
+ return jidLineEdit->text().isEmpty();
}
void QtVCardJIDField::setJID(const JID& jid) {
- std::string jidStr = jid.toBare().toString();
- jidLineEdit->setText(P2QSTRING(jidStr));
+ std::string jidStr = jid.toBare().toString();
+ jidLineEdit->setText(P2QSTRING(jidStr));
}
JID QtVCardJIDField::getJID() const {
- return JID(Q2PSTRING(jidLineEdit->text()));
+ return JID(Q2PSTRING(jidLineEdit->text()));
}
void QtVCardJIDField::handleEditibleChanged(bool isEditable) {
- assert(jidLineEdit);
- assert(jidLabel);
-
- if (isEditable) {
- jidLineEdit->show();
- jidLabel->hide();
- } else {
- jidLineEdit->hide();
- jidLabel->setText(QString("<a href=\"xmpp:%1\">%1</a>").arg(QtUtilities::htmlEscape(jidLineEdit->text())));
- jidLabel->show();
- }
+ assert(jidLineEdit);
+ assert(jidLabel);
+
+ if (isEditable) {
+ jidLineEdit->show();
+ jidLabel->hide();
+ } else {
+ jidLineEdit->hide();
+ jidLabel->setText(QString("<a href=\"xmpp:%1\">%1</a>").arg(QtUtilities::htmlEscape(jidLineEdit->text())));
+ jidLabel->show();
+ }
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardJIDField.h b/Swift/QtUI/QtVCardWidget/QtVCardJIDField.h
index 016bcf8..f2df9f9 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardJIDField.h
+++ b/Swift/QtUI/QtVCardWidget/QtVCardJIDField.h
@@ -4,39 +4,45 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <Swiften/Elements/VCard.h>
-#include "QtResizableLineEdit.h"
-#include "QtVCardFieldInfo.h"
-#include "QtVCardGeneralField.h"
+#include <Swift/QtUI/QtVCardWidget/QtResizableLineEdit.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h>
namespace Swift {
class QtVCardJIDField : public QtVCardGeneralField {
- Q_OBJECT
+ Q_OBJECT
- public:
- GENERIC_QT_VCARD_FIELD_INFO("JID", UNLIMITED_INSTANCES, QtVCardJIDField)
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO(tr("JID"), UNLIMITED_INSTANCES, QtVCardJIDField)
- QtVCardJIDField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
- virtual ~QtVCardJIDField();
+ QtVCardJIDField(QWidget* parent = nullptr, QGridLayout* layout = nullptr, bool editable = false);
+ virtual ~QtVCardJIDField();
- virtual bool isEmpty() const;
+ virtual bool isEmpty() const;
- void setJID(const JID& jid);
- JID getJID() const;
+ void setJID(const JID& jid);
+ JID getJID() const;
- protected:
- virtual void setupContentWidgets();
+ protected:
+ virtual void setupContentWidgets();
- public slots:
- void handleEditibleChanged(bool isEditable);
+ public slots:
+ void handleEditibleChanged(bool isEditable);
- private:
- QLabel* jidLabel;
- QtResizableLineEdit* jidLineEdit;
+ private:
+ QLabel* jidLabel;
+ QtResizableLineEdit* jidLineEdit;
};
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.cpp
index ba51078..5162c73 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.cpp
@@ -4,6 +4,12 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#include <Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.h>
#include <boost/algorithm/string.hpp>
@@ -17,129 +23,129 @@
namespace Swift {
QtVCardOrganizationField::QtVCardOrganizationField(QWidget* parent, QGridLayout *layout, bool editable) :
- QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Organization"), false, false), organizationLabel(NULL), organizationLineEdit(NULL), unitsTreeWidget(NULL), itemDelegate(NULL) {
- connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Organization"), false, false), organizationLabel(nullptr), organizationLineEdit(nullptr), unitsTreeWidget(nullptr), itemDelegate(nullptr) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
}
QtVCardOrganizationField::~QtVCardOrganizationField() {
- disconnect(this, SLOT(handleEditibleChanged(bool)));
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
}
void QtVCardOrganizationField::setupContentWidgets() {
- organizationLabel = new QLabel(this);
- organizationLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
- organizationLineEdit = new QtResizableLineEdit(this);
- QHBoxLayout* organizationLayout = new QHBoxLayout();
- organizationLayout->addWidget(organizationLabel);
- organizationLayout->addWidget(organizationLineEdit);
+ organizationLabel = new QLabel(this);
+ organizationLabel->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard);
+ organizationLineEdit = new QtResizableLineEdit(this);
+ QHBoxLayout* organizationLayout = new QHBoxLayout();
+ organizationLayout->addWidget(organizationLabel);
+ organizationLayout->addWidget(organizationLineEdit);
- getGridLayout()->addLayout(organizationLayout, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
+ getGridLayout()->addLayout(organizationLayout, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
- itemDelegate = new QtRemovableItemDelegate(style());
+ itemDelegate = new QtRemovableItemDelegate(style());
- unitsTreeWidget = new QTreeWidget(this);
- connect(unitsTreeWidget->model(), SIGNAL(rowsRemoved(QModelIndex, int, int)), SLOT(handleRowsRemoved(QModelIndex,int,int)));
- unitsTreeWidget->setColumnCount(2);
- unitsTreeWidget->header()->setStretchLastSection(false);
- unitsTreeWidget->header()->resizeSection(1, itemDelegate->sizeHint(QStyleOptionViewItem(), QModelIndex()).width());
+ unitsTreeWidget = new QTreeWidget(this);
+ connect(unitsTreeWidget->model(), SIGNAL(rowsRemoved(QModelIndex, int, int)), SLOT(handleRowsRemoved(QModelIndex,int,int)));
+ unitsTreeWidget->setColumnCount(2);
+ unitsTreeWidget->header()->setStretchLastSection(false);
+ unitsTreeWidget->header()->resizeSection(1, itemDelegate->sizeHint(QStyleOptionViewItem(), QModelIndex()).width());
#if QT_VERSION >= 0x050000
- unitsTreeWidget->header()->setSectionResizeMode(0, QHeaderView::Stretch);
+ unitsTreeWidget->header()->setSectionResizeMode(0, QHeaderView::Stretch);
#else
- unitsTreeWidget->header()->setResizeMode(0, QHeaderView::Stretch);
+ unitsTreeWidget->header()->setResizeMode(0, QHeaderView::Stretch);
#endif
- unitsTreeWidget->setHeaderHidden(true);
- unitsTreeWidget->setRootIsDecorated(false);
- unitsTreeWidget->setEditTriggers(QAbstractItemView::DoubleClicked);
- unitsTreeWidget->setItemDelegateForColumn(1, itemDelegate);
- connect(unitsTreeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)), SLOT(handleItemChanged(QTreeWidgetItem*,int)));
- getGridLayout()->addWidget(unitsTreeWidget, getGridLayout()->rowCount()-1, 4, 2, 1);
+ unitsTreeWidget->setHeaderHidden(true);
+ unitsTreeWidget->setRootIsDecorated(false);
+ unitsTreeWidget->setEditTriggers(QAbstractItemView::DoubleClicked);
+ unitsTreeWidget->setItemDelegateForColumn(1, itemDelegate);
+ connect(unitsTreeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)), SLOT(handleItemChanged(QTreeWidgetItem*,int)));
+ getGridLayout()->addWidget(unitsTreeWidget, getGridLayout()->rowCount()-1, 4, 2, 1);
- QTreeWidgetItem* item = new QTreeWidgetItem(QStringList("") << "");
- item->setFlags(item->flags() | Qt::ItemIsEditable);
- unitsTreeWidget->addTopLevelItem(item);
+ QTreeWidgetItem* item = new QTreeWidgetItem(QStringList("") << "");
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+ unitsTreeWidget->addTopLevelItem(item);
- getTagComboBox()->hide();
- organizationLabel->hide();
- childWidgets << organizationLabel << organizationLineEdit << unitsTreeWidget;
+ getTagComboBox()->hide();
+ organizationLabel->hide();
+ childWidgets << organizationLabel << organizationLineEdit << unitsTreeWidget;
}
bool QtVCardOrganizationField::isEmpty() const {
- return organizationLineEdit->text().isEmpty() && unitsTreeWidget->model()->rowCount() != 0;
+ return organizationLineEdit->text().isEmpty() && unitsTreeWidget->model()->rowCount() != 0;
}
void QtVCardOrganizationField::setOrganization(const VCard::Organization& organization) {
- organizationLineEdit->setText(P2QSTRING(organization.name));
- unitsTreeWidget->clear();
- foreach(std::string unit, organization.units) {
- QTreeWidgetItem* item = new QTreeWidgetItem(QStringList(P2QSTRING(unit)) << "");
- item->setFlags(item->flags() | Qt::ItemIsEditable);
- unitsTreeWidget->addTopLevelItem(item);
- }
-
- QTreeWidgetItem* item = new QTreeWidgetItem(QStringList("") << "");
- item->setFlags(item->flags() | Qt::ItemIsEditable);
- unitsTreeWidget->addTopLevelItem(item);
+ organizationLineEdit->setText(P2QSTRING(organization.name));
+ unitsTreeWidget->clear();
+ for (const auto& unit : organization.units) {
+ QTreeWidgetItem* item = new QTreeWidgetItem(QStringList(P2QSTRING(unit)) << "");
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+ unitsTreeWidget->addTopLevelItem(item);
+ }
+
+ QTreeWidgetItem* item = new QTreeWidgetItem(QStringList("") << "");
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+ unitsTreeWidget->addTopLevelItem(item);
}
VCard::Organization QtVCardOrganizationField::getOrganization() const {
- VCard::Organization organization;
- organization.name = Q2PSTRING(organizationLineEdit->text());
- for(int i=0; i < unitsTreeWidget->topLevelItemCount(); ++i) {
- QTreeWidgetItem* row = unitsTreeWidget->topLevelItem(i);
- if (!row->text(0).isEmpty()) {
- organization.units.push_back(Q2PSTRING(row->text(0)));
- }
- }
-
- return organization;
+ VCard::Organization organization;
+ organization.name = Q2PSTRING(organizationLineEdit->text());
+ for(int i=0; i < unitsTreeWidget->topLevelItemCount(); ++i) {
+ QTreeWidgetItem* row = unitsTreeWidget->topLevelItem(i);
+ if (!row->text(0).isEmpty()) {
+ organization.units.push_back(Q2PSTRING(row->text(0)));
+ }
+ }
+
+ return organization;
}
void QtVCardOrganizationField::handleEditibleChanged(bool isEditable) {
- assert(organizationLineEdit);
- assert(unitsTreeWidget);
-
- organizationLineEdit->setVisible(isEditable);
- organizationLabel->setVisible(!isEditable);
-
- if (!isEditable) {
- QString label;
- for(int i=0; i < unitsTreeWidget->topLevelItemCount(); ++i) {
- QTreeWidgetItem* row = unitsTreeWidget->topLevelItem(i);
- if (!row->text(0).isEmpty()) {
- label += row->text(0) + ", ";
- }
- }
- label += organizationLineEdit->text();
- organizationLabel->setText(label);
- }
- unitsTreeWidget->setVisible(isEditable);
+ assert(organizationLineEdit);
+ assert(unitsTreeWidget);
+
+ organizationLineEdit->setVisible(isEditable);
+ organizationLabel->setVisible(!isEditable);
+
+ if (!isEditable) {
+ QString label;
+ for(int i=0; i < unitsTreeWidget->topLevelItemCount(); ++i) {
+ QTreeWidgetItem* row = unitsTreeWidget->topLevelItem(i);
+ if (!row->text(0).isEmpty()) {
+ label += row->text(0) + ", ";
+ }
+ }
+ label += organizationLineEdit->text();
+ organizationLabel->setText(label);
+ }
+ unitsTreeWidget->setVisible(isEditable);
}
void QtVCardOrganizationField::handleItemChanged(QTreeWidgetItem *, int) {
- guaranteeEmptyRow();
+ guaranteeEmptyRow();
}
void QtVCardOrganizationField::handleRowsRemoved(const QModelIndex&, int, int) {
- guaranteeEmptyRow();
+ guaranteeEmptyRow();
}
void QtVCardOrganizationField::guaranteeEmptyRow() {
- bool hasEmptyRow = false;
- QList<QTreeWidgetItem*> rows = unitsTreeWidget->findItems("", Qt::MatchFixedString);
- foreach(QTreeWidgetItem* row, rows) {
- if (row->text(0).isEmpty()) {
- hasEmptyRow = true;
- }
- }
-
- if (!hasEmptyRow) {
- QTreeWidgetItem* item = new QTreeWidgetItem(QStringList("") << "");
- item->setFlags(item->flags() | Qt::ItemIsEditable);
- unitsTreeWidget->addTopLevelItem(item);
- unitsTreeWidget->setCurrentItem(item);
- }
+ bool hasEmptyRow = false;
+ QList<QTreeWidgetItem*> rows = unitsTreeWidget->findItems("", Qt::MatchFixedString);
+ for (auto row : rows) {
+ if (row->text(0).isEmpty()) {
+ hasEmptyRow = true;
+ }
+ }
+
+ if (!hasEmptyRow) {
+ QTreeWidgetItem* item = new QTreeWidgetItem(QStringList("") << "");
+ item->setFlags(item->flags() | Qt::ItemIsEditable);
+ unitsTreeWidget->addTopLevelItem(item);
+ unitsTreeWidget->setCurrentItem(item);
+ }
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.h b/Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.h
index 47868a7..23e89c0 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.h
+++ b/Swift/QtUI/QtVCardWidget/QtVCardOrganizationField.h
@@ -4,6 +4,12 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <QTreeWidget>
@@ -18,37 +24,37 @@
namespace Swift {
class QtVCardOrganizationField : public QtVCardGeneralField {
- Q_OBJECT
+ Q_OBJECT
- public:
- GENERIC_QT_VCARD_FIELD_INFO("Organization", UNLIMITED_INSTANCES, QtVCardOrganizationField)
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO(tr("Organization"), UNLIMITED_INSTANCES, QtVCardOrganizationField)
- QtVCardOrganizationField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
- virtual ~QtVCardOrganizationField();
+ QtVCardOrganizationField(QWidget* parent = nullptr, QGridLayout* layout = nullptr, bool editable = false);
+ virtual ~QtVCardOrganizationField();
- virtual bool isEmpty() const;
+ virtual bool isEmpty() const;
- void setOrganization(const VCard::Organization& organization);
- VCard::Organization getOrganization() const;
+ void setOrganization(const VCard::Organization& organization);
+ VCard::Organization getOrganization() const;
- protected:
- virtual void setupContentWidgets();
+ protected:
+ virtual void setupContentWidgets();
- public slots:
- void handleEditibleChanged(bool isEditable);
+ public slots:
+ void handleEditibleChanged(bool isEditable);
- private slots:
- void handleItemChanged(QTreeWidgetItem*, int);
- void handleRowsRemoved(const QModelIndex&, int, int);
+ private slots:
+ void handleItemChanged(QTreeWidgetItem*, int);
+ void handleRowsRemoved(const QModelIndex&, int, int);
- private:
- void guaranteeEmptyRow();
+ private:
+ void guaranteeEmptyRow();
- private:
- QLabel* organizationLabel;
- QtResizableLineEdit* organizationLineEdit;
- QTreeWidget* unitsTreeWidget;
- QtRemovableItemDelegate* itemDelegate;
+ private:
+ QLabel* organizationLabel;
+ QtResizableLineEdit* organizationLineEdit;
+ QTreeWidget* unitsTreeWidget;
+ QtRemovableItemDelegate* itemDelegate;
};
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.cpp b/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.cpp
index 75b1f07..eef6728 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.cpp
@@ -5,148 +5,148 @@
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.h>
-#include <Swift/QtUI/QtVCardWidget/ui_QtVCardPhotoAndNameFields.h>
-
#include <QMenu>
+#include <Swift/QtUI/QtVCardWidget/ui_QtVCardPhotoAndNameFields.h>
+
namespace Swift {
QtVCardPhotoAndNameFields::QtVCardPhotoAndNameFields(QWidget* parent) :
- QWidget(parent),
- ui(new Ui::QtVCardPhotoAndNameFields) {
- ui->setupUi(this);
- ui->lineEditPREFIX->hide();
- ui->lineEditMIDDLE->hide();
- ui->lineEditSUFFIX->hide();
- ui->lineEditFN->hide();
- ui->lineEditNICKNAME->hide();
- ui->labelFN->hide();
- ui->labelNICKNAME->hide();
- ui->labelFULLNAME->hide();
+ QWidget(parent),
+ ui(new Ui::QtVCardPhotoAndNameFields) {
+ ui->setupUi(this);
+ ui->lineEditPREFIX->hide();
+ ui->lineEditMIDDLE->hide();
+ ui->lineEditSUFFIX->hide();
+ ui->lineEditFN->hide();
+ ui->lineEditNICKNAME->hide();
+ ui->labelFN->hide();
+ ui->labelNICKNAME->hide();
+ ui->labelFULLNAME->hide();
#if QT_VERSION >= 0x040700
- ui->lineEditFN->setPlaceholderText(tr("Formatted Name"));
- ui->lineEditNICKNAME->setPlaceholderText(tr("Nickname"));
- ui->lineEditPREFIX->setPlaceholderText(tr("Prefix"));
- ui->lineEditGIVEN->setPlaceholderText(tr("Given Name"));
- ui->lineEditMIDDLE->setPlaceholderText(tr("Middle Name"));
- ui->lineEditFAMILY->setPlaceholderText(tr("Last Name"));
- ui->lineEditSUFFIX->setPlaceholderText(tr("Suffix"));
+ ui->lineEditFN->setPlaceholderText(tr("Formatted Name"));
+ ui->lineEditNICKNAME->setPlaceholderText(tr("Nickname"));
+ ui->lineEditPREFIX->setPlaceholderText(tr("Prefix"));
+ ui->lineEditGIVEN->setPlaceholderText(tr("Given Name"));
+ ui->lineEditMIDDLE->setPlaceholderText(tr("Middle Name"));
+ ui->lineEditFAMILY->setPlaceholderText(tr("Last Name"));
+ ui->lineEditSUFFIX->setPlaceholderText(tr("Suffix"));
#endif
- setEditable(false);
+ setEditable(false);
}
QtVCardPhotoAndNameFields::~QtVCardPhotoAndNameFields() {
- delete ui;
+ delete ui;
}
bool QtVCardPhotoAndNameFields::isEditable() const {
- return editable;
+ return editable;
}
void QtVCardPhotoAndNameFields::setEditable(bool editable) {
- this->editable = editable;
+ this->editable = editable;
- ui->avatarWidget->setEditable(editable);
- ui->lineEditFN->setVisible(editable);
- ui->labelFN->setVisible(!editable);
+ ui->avatarWidget->setEditable(editable);
+ ui->lineEditFN->setVisible(editable);
+ ui->labelFN->setVisible(!editable);
- ui->lineEditNICKNAME->setVisible(editable);
- ui->labelNICKNAME->setVisible(!editable);
+ ui->lineEditNICKNAME->setVisible(editable);
+ ui->labelNICKNAME->setVisible(!editable);
- // prefix given middle last suffix
- ui->lineEditPREFIX->setVisible(editable);
- ui->lineEditGIVEN->setVisible(editable);
- ui->lineEditMIDDLE->setVisible(editable);
- ui->lineEditFAMILY->setVisible(editable);
- ui->lineEditSUFFIX->setVisible(editable);
- ui->labelFULLNAME->setVisible(!editable);
+ // prefix given middle last suffix
+ ui->lineEditPREFIX->setVisible(editable);
+ ui->lineEditGIVEN->setVisible(editable);
+ ui->lineEditMIDDLE->setVisible(editable);
+ ui->lineEditFAMILY->setVisible(editable);
+ ui->lineEditSUFFIX->setVisible(editable);
+ ui->labelFULLNAME->setVisible(!editable);
- QStringList fullname;
- fullname << ui->lineEditPREFIX->text() << ui->lineEditGIVEN->text() << ui->lineEditMIDDLE->text();
- fullname << ui->lineEditFAMILY->text() << ui->lineEditSUFFIX->text();
- for (QStringList::iterator i = fullname.begin(); i != fullname.end(); i++) {
- *i = i->trimmed();
- }
- ui->labelFULLNAME->setText((fullname.filter(QRegExp(".+"))).join(" "));
+ QStringList fullname;
+ fullname << ui->lineEditPREFIX->text() << ui->lineEditGIVEN->text() << ui->lineEditMIDDLE->text();
+ fullname << ui->lineEditFAMILY->text() << ui->lineEditSUFFIX->text();
+ for (auto& i : fullname) {
+ i = i.trimmed();
+ }
+ ui->labelFULLNAME->setText((fullname.filter(QRegExp(".+"))).join(" "));
}
void QtVCardPhotoAndNameFields::setAvatar(const ByteArray &data, const std::string &type) {
- ui->avatarWidget->setAvatar(data, type);
+ ui->avatarWidget->setAvatar(data, type);
}
ByteArray QtVCardPhotoAndNameFields::getAvatarData() const {
- return ui->avatarWidget->getAvatarData();
+ return ui->avatarWidget->getAvatarData();
}
std::string QtVCardPhotoAndNameFields::getAvatarType() const {
- return ui->avatarWidget->getAvatarType();
+ return ui->avatarWidget->getAvatarType();
}
void QtVCardPhotoAndNameFields::setFormattedName(const QString& formattedName) {
- ui->lineEditFN->setText(formattedName);
- ui->labelFN->setText(formattedName);
+ ui->lineEditFN->setText(formattedName);
+ ui->labelFN->setText(formattedName);
}
QString QtVCardPhotoAndNameFields::getFormattedName() const {
- return ui->lineEditFN->text();
+ return ui->lineEditFN->text();
}
void QtVCardPhotoAndNameFields::setNickname(const QString& nickname) {
- ui->lineEditNICKNAME->setText(nickname);
- ui->labelNICKNAME->setText(nickname);
+ ui->lineEditNICKNAME->setText(nickname);
+ ui->labelNICKNAME->setText(nickname);
}
QString QtVCardPhotoAndNameFields::getNickname() const {
- return ui->lineEditNICKNAME->text();
+ return ui->lineEditNICKNAME->text();
}
void QtVCardPhotoAndNameFields::setPrefix(const QString& prefix) {
- ui->lineEditPREFIX->setText(prefix);
+ ui->lineEditPREFIX->setText(prefix);
}
QString QtVCardPhotoAndNameFields::getPrefix() const {
- return ui->lineEditPREFIX->text();
+ return ui->lineEditPREFIX->text();
}
void QtVCardPhotoAndNameFields::setGivenName(const QString& givenName) {
- ui->lineEditGIVEN->setText(givenName);
+ ui->lineEditGIVEN->setText(givenName);
}
QString QtVCardPhotoAndNameFields::getGivenName() const {
- return ui->lineEditGIVEN->text();
+ return ui->lineEditGIVEN->text();
}
void QtVCardPhotoAndNameFields::setMiddleName(const QString& middleName) {
- ui->lineEditMIDDLE->setText(middleName);
+ ui->lineEditMIDDLE->setText(middleName);
}
QString QtVCardPhotoAndNameFields::getMiddleName() const {
- return ui->lineEditMIDDLE->text();
+ return ui->lineEditMIDDLE->text();
}
void QtVCardPhotoAndNameFields::setFamilyName(const QString& familyName) {
- ui->lineEditFAMILY->setText(familyName);
+ ui->lineEditFAMILY->setText(familyName);
}
QString QtVCardPhotoAndNameFields::getFamilyName() const {
- return ui->lineEditFAMILY->text();
+ return ui->lineEditFAMILY->text();
}
void QtVCardPhotoAndNameFields::setSuffix(const QString& suffix) {
- ui->lineEditSUFFIX->setText(suffix);
+ ui->lineEditSUFFIX->setText(suffix);
}
QString QtVCardPhotoAndNameFields::getSuffix() const {
- return ui->lineEditSUFFIX->text();
+ return ui->lineEditSUFFIX->text();
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.h b/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.h
index ac35109..ca6a1f3 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.h
+++ b/Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.h
@@ -4,6 +4,12 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <QMenu>
@@ -12,51 +18,51 @@
#include <Swiften/Base/ByteArray.h>
namespace Ui {
- class QtVCardPhotoAndNameFields;
+ class QtVCardPhotoAndNameFields;
}
namespace Swift {
- class QtVCardPhotoAndNameFields : public QWidget {
- Q_OBJECT
- Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+ class QtVCardPhotoAndNameFields : public QWidget {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
- public:
- explicit QtVCardPhotoAndNameFields(QWidget* parent = 0);
- ~QtVCardPhotoAndNameFields();
+ public:
+ explicit QtVCardPhotoAndNameFields(QWidget* parent = nullptr);
+ ~QtVCardPhotoAndNameFields();
- bool isEditable() const;
- void setEditable(bool);
+ bool isEditable() const;
+ void setEditable(bool);
- void setAvatar(const ByteArray& data, const std::string& type);
- ByteArray getAvatarData() const;
- std::string getAvatarType() const;
+ void setAvatar(const ByteArray& data, const std::string& type);
+ ByteArray getAvatarData() const;
+ std::string getAvatarType() const;
- void setFormattedName(const QString& formattedName);
- QString getFormattedName() const;
+ void setFormattedName(const QString& formattedName);
+ QString getFormattedName() const;
- void setNickname(const QString& nickname);
- QString getNickname() const;
+ void setNickname(const QString& nickname);
+ QString getNickname() const;
- void setPrefix(const QString& prefix);
- QString getPrefix() const;
+ void setPrefix(const QString& prefix);
+ QString getPrefix() const;
- void setGivenName(const QString& givenName);
- QString getGivenName() const;
+ void setGivenName(const QString& givenName);
+ QString getGivenName() const;
- void setMiddleName(const QString& middleName);
- QString getMiddleName() const;
+ void setMiddleName(const QString& middleName);
+ QString getMiddleName() const;
- void setFamilyName(const QString& familyName);
- QString getFamilyName() const;
+ void setFamilyName(const QString& familyName);
+ QString getFamilyName() const;
- void setSuffix(const QString& suffix);
- QString getSuffix() const;
+ void setSuffix(const QString& suffix);
+ QString getSuffix() const;
- private:
- Ui::QtVCardPhotoAndNameFields* ui;
- bool editable;
- };
+ private:
+ Ui::QtVCardPhotoAndNameFields* ui;
+ bool editable;
+ };
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardRoleField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardRoleField.cpp
index af28d28..e9e29ad 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardRoleField.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtVCardRoleField.cpp
@@ -4,47 +4,54 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "QtVCardRoleField.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtVCardWidget/QtVCardRoleField.h>
-#include <QGridLayout>
#include <boost/algorithm/string.hpp>
+#include <QGridLayout>
+
#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
QtVCardRoleField::QtVCardRoleField(QWidget* parent, QGridLayout *layout, bool editable) :
- QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Role"), false, false), roleLineEdit(NULL) {
- connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Role"), false, false), roleLineEdit(nullptr) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
}
QtVCardRoleField::~QtVCardRoleField() {
}
void QtVCardRoleField::setupContentWidgets() {
- roleLineEdit = new QtResizableLineEdit(this);
- getGridLayout()->addWidget(roleLineEdit, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
- getTagComboBox()->hide();
- childWidgets << roleLineEdit;
+ roleLineEdit = new QtResizableLineEdit(this);
+ getGridLayout()->addWidget(roleLineEdit, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
+ getTagComboBox()->hide();
+ childWidgets << roleLineEdit;
}
bool QtVCardRoleField::isEmpty() const {
- return roleLineEdit->text().isEmpty();
+ return roleLineEdit->text().isEmpty();
}
void QtVCardRoleField::setRole(const std::string& role) {
- roleLineEdit->setText(P2QSTRING(role));
+ roleLineEdit->setText(P2QSTRING(role));
}
std::string QtVCardRoleField::getRole() const {
- return Q2PSTRING(roleLineEdit->text());
+ return Q2PSTRING(roleLineEdit->text());
}
void QtVCardRoleField::handleEditibleChanged(bool isEditable) {
- assert(roleLineEdit);
+ assert(roleLineEdit);
- roleLineEdit->setEditable(isEditable);
- roleLineEdit->setStyleSheet(isEditable ? "" : "QLineEdit { border: none; background: transparent; }");
+ roleLineEdit->setEditable(isEditable);
+ roleLineEdit->setStyleSheet(isEditable ? "" : "QLineEdit { border: none; background: transparent; }");
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardRoleField.h b/Swift/QtUI/QtVCardWidget/QtVCardRoleField.h
index 3c819ed..a507fef 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardRoleField.h
+++ b/Swift/QtUI/QtVCardWidget/QtVCardRoleField.h
@@ -4,38 +4,44 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <Swiften/Elements/VCard.h>
-#include "QtResizableLineEdit.h"
-#include "QtVCardFieldInfo.h"
-#include "QtVCardGeneralField.h"
+#include <Swift/QtUI/QtVCardWidget/QtResizableLineEdit.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h>
namespace Swift {
class QtVCardRoleField : public QtVCardGeneralField {
- Q_OBJECT
+ Q_OBJECT
- public:
- GENERIC_QT_VCARD_FIELD_INFO("Role", UNLIMITED_INSTANCES, QtVCardRoleField)
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO(tr("Role"), UNLIMITED_INSTANCES, QtVCardRoleField)
- QtVCardRoleField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
- virtual ~QtVCardRoleField();
+ QtVCardRoleField(QWidget* parent = nullptr, QGridLayout* layout = nullptr, bool editable = false);
+ virtual ~QtVCardRoleField();
- virtual bool isEmpty() const;
+ virtual bool isEmpty() const;
- void setRole(const std::string& role);
- std::string getRole() const;
+ void setRole(const std::string& role);
+ std::string getRole() const;
- protected:
- virtual void setupContentWidgets();
+ protected:
+ virtual void setupContentWidgets();
- public slots:
- void handleEditibleChanged(bool isEditable);
+ public slots:
+ void handleEditibleChanged(bool isEditable);
- private:
- QtResizableLineEdit* roleLineEdit;
+ private:
+ QtResizableLineEdit* roleLineEdit;
};
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.cpp
index 401d0a0..9421016 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.cpp
@@ -4,7 +4,13 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "QtVCardTelephoneField.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.h>
#include <QGridLayout>
@@ -13,88 +19,88 @@
namespace Swift {
QtVCardTelephoneField::QtVCardTelephoneField(QWidget* parent, QGridLayout *layout, bool editable) :
- QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Telephone")), telephoneLineEdit(NULL) {
- connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Telephone")), telephoneLineEdit(nullptr) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
}
QtVCardTelephoneField::~QtVCardTelephoneField() {
- disconnect(this, SLOT(handleEditibleChanged(bool)));
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
}
void QtVCardTelephoneField::setupContentWidgets() {
- telephoneLineEdit = new QtResizableLineEdit(this);
+ telephoneLineEdit = new QtResizableLineEdit(this);
#if QT_VERSION >= 0x040700
- telephoneLineEdit->setPlaceholderText(tr("0118 999 881 999 119 7253"));
+ telephoneLineEdit->setPlaceholderText(tr("0118 999 881 999 119 7253"));
#endif
- getGridLayout()->addWidget(telephoneLineEdit, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
- setTabOrder(telephoneLineEdit, getTagComboBox());
- QtVCardHomeWork::setTagComboBox(getTagComboBox());
-
- getTagComboBox()->addTag("voice", QObject::tr("Voice"));
- getTagComboBox()->addTag("fax", QObject::tr("Fax"));
- getTagComboBox()->addTag("pager", QObject::tr("Pager"));
- getTagComboBox()->addTag("msg", QObject::tr("Voice Messaging"));
- getTagComboBox()->addTag("cell", QObject::tr("Cell"));
- getTagComboBox()->addTag("video", QObject::tr("Video"));
- getTagComboBox()->addTag("bbs", QObject::tr("Bulletin Board System"));
- getTagComboBox()->addTag("modem", QObject::tr("Modem"));
- getTagComboBox()->addTag("isdn", QObject::tr("ISDN"));
- getTagComboBox()->addTag("pcs", QObject::tr("Personal Communication Services"));
-
- childWidgets << telephoneLineEdit;
+ getGridLayout()->addWidget(telephoneLineEdit, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
+ setTabOrder(telephoneLineEdit, getTagComboBox());
+ QtVCardHomeWork::setTagComboBox(getTagComboBox());
+
+ getTagComboBox()->addTag("voice", QObject::tr("Voice"));
+ getTagComboBox()->addTag("fax", QObject::tr("Fax"));
+ getTagComboBox()->addTag("pager", QObject::tr("Pager"));
+ getTagComboBox()->addTag("msg", QObject::tr("Voice Messaging"));
+ getTagComboBox()->addTag("cell", QObject::tr("Cell"));
+ getTagComboBox()->addTag("video", QObject::tr("Video"));
+ getTagComboBox()->addTag("bbs", QObject::tr("Bulletin Board System"));
+ getTagComboBox()->addTag("modem", QObject::tr("Modem"));
+ getTagComboBox()->addTag("isdn", QObject::tr("ISDN"));
+ getTagComboBox()->addTag("pcs", QObject::tr("Personal Communication Services"));
+
+ childWidgets << telephoneLineEdit;
}
bool QtVCardTelephoneField::isEmpty() const {
- return telephoneLineEdit->text().isEmpty();
+ return telephoneLineEdit->text().isEmpty();
}
void QtVCardTelephoneField::setTelephone(const VCard::Telephone& telephone) {
- setPreferred(telephone.isPreferred);
- setHome(telephone.isHome);
- setWork(telephone.isWork);
-
- telephoneLineEdit->setText(P2QSTRING(telephone.number));
-
- getTagComboBox()->setTag("voice", telephone.isVoice);
- getTagComboBox()->setTag("fax", telephone.isFax);
- getTagComboBox()->setTag("pager", telephone.isPager);
- getTagComboBox()->setTag("msg", telephone.isMSG);
- getTagComboBox()->setTag("cell", telephone.isCell);
- getTagComboBox()->setTag("video", telephone.isVideo);
- getTagComboBox()->setTag("bbs", telephone.isBBS);
- getTagComboBox()->setTag("modem", telephone.isModem);
- getTagComboBox()->setTag("isdn", telephone.isISDN);
- getTagComboBox()->setTag("pcs", telephone.isPCS);
+ setPreferred(telephone.isPreferred);
+ setHome(telephone.isHome);
+ setWork(telephone.isWork);
+
+ telephoneLineEdit->setText(P2QSTRING(telephone.number));
+
+ getTagComboBox()->setTag("voice", telephone.isVoice);
+ getTagComboBox()->setTag("fax", telephone.isFax);
+ getTagComboBox()->setTag("pager", telephone.isPager);
+ getTagComboBox()->setTag("msg", telephone.isMSG);
+ getTagComboBox()->setTag("cell", telephone.isCell);
+ getTagComboBox()->setTag("video", telephone.isVideo);
+ getTagComboBox()->setTag("bbs", telephone.isBBS);
+ getTagComboBox()->setTag("modem", telephone.isModem);
+ getTagComboBox()->setTag("isdn", telephone.isISDN);
+ getTagComboBox()->setTag("pcs", telephone.isPCS);
}
VCard::Telephone QtVCardTelephoneField::getTelephone() const {
- VCard::Telephone telephone;
-
- telephone.number = Q2PSTRING(telephoneLineEdit->text());
-
- telephone.isPreferred = getPreferred();
- telephone.isHome = getHome();
- telephone.isWork = getWork();
-
- telephone.isVoice = getTagComboBox()->isTagSet("voice");
- telephone.isFax = getTagComboBox()->isTagSet("fax");
- telephone.isPager = getTagComboBox()->isTagSet("pager");
- telephone.isMSG = getTagComboBox()->isTagSet("msg");
- telephone.isCell = getTagComboBox()->isTagSet("cell");
- telephone.isVideo = getTagComboBox()->isTagSet("video");
- telephone.isBBS = getTagComboBox()->isTagSet("bbs");
- telephone.isModem = getTagComboBox()->isTagSet("modem");
- telephone.isISDN = getTagComboBox()->isTagSet("isdn");
- telephone.isPCS = getTagComboBox()->isTagSet("pcs");
-
- return telephone;
+ VCard::Telephone telephone;
+
+ telephone.number = Q2PSTRING(telephoneLineEdit->text());
+
+ telephone.isPreferred = getPreferred();
+ telephone.isHome = getHome();
+ telephone.isWork = getWork();
+
+ telephone.isVoice = getTagComboBox()->isTagSet("voice");
+ telephone.isFax = getTagComboBox()->isTagSet("fax");
+ telephone.isPager = getTagComboBox()->isTagSet("pager");
+ telephone.isMSG = getTagComboBox()->isTagSet("msg");
+ telephone.isCell = getTagComboBox()->isTagSet("cell");
+ telephone.isVideo = getTagComboBox()->isTagSet("video");
+ telephone.isBBS = getTagComboBox()->isTagSet("bbs");
+ telephone.isModem = getTagComboBox()->isTagSet("modem");
+ telephone.isISDN = getTagComboBox()->isTagSet("isdn");
+ telephone.isPCS = getTagComboBox()->isTagSet("pcs");
+
+ return telephone;
}
void QtVCardTelephoneField::handleEditibleChanged(bool isEditable) {
- assert(telephoneLineEdit);
+ assert(telephoneLineEdit);
- telephoneLineEdit->setEditable(isEditable);
- telephoneLineEdit->setStyleSheet(isEditable ? "" : "QLineEdit { border: none; background: transparent; }");
+ telephoneLineEdit->setEditable(isEditable);
+ telephoneLineEdit->setStyleSheet(isEditable ? "" : "QLineEdit { border: none; background: transparent; }");
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.h b/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.h
index b433e3c..13bb232 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.h
+++ b/Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.h
@@ -4,39 +4,45 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <Swiften/Elements/VCard.h>
-#include "QtResizableLineEdit.h"
-#include "QtVCardFieldInfo.h"
-#include "QtVCardGeneralField.h"
-#include "QtVCardHomeWork.h"
+#include <Swift/QtUI/QtVCardWidget/QtResizableLineEdit.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardHomeWork.h>
namespace Swift {
class QtVCardTelephoneField : public QtVCardGeneralField, public QtVCardHomeWork {
- Q_OBJECT
+ Q_OBJECT
- public:
- GENERIC_QT_VCARD_FIELD_INFO("Telephone", UNLIMITED_INSTANCES, QtVCardTelephoneField)
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO(tr("Telephone"), UNLIMITED_INSTANCES, QtVCardTelephoneField)
- QtVCardTelephoneField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
- virtual ~QtVCardTelephoneField();
+ QtVCardTelephoneField(QWidget* parent = nullptr, QGridLayout* layout = nullptr, bool editable = false);
+ virtual ~QtVCardTelephoneField();
- virtual bool isEmpty() const;
+ virtual bool isEmpty() const;
- void setTelephone(const VCard::Telephone& telephone);
- VCard::Telephone getTelephone() const;
+ void setTelephone(const VCard::Telephone& telephone);
+ VCard::Telephone getTelephone() const;
- protected:
- virtual void setupContentWidgets();
+ protected:
+ virtual void setupContentWidgets();
- public slots:
- void handleEditibleChanged(bool isEditable);
+ public slots:
+ void handleEditibleChanged(bool isEditable);
- private:
- QtResizableLineEdit* telephoneLineEdit;
+ private:
+ QtResizableLineEdit* telephoneLineEdit;
};
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardTitleField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardTitleField.cpp
index 64b05c0..14c3813 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardTitleField.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtVCardTitleField.cpp
@@ -4,48 +4,55 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "QtVCardTitleField.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtVCardWidget/QtVCardTitleField.h>
-#include <QGridLayout>
#include <boost/algorithm/string.hpp>
+#include <QGridLayout>
+
#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
QtVCardTitleField::QtVCardTitleField(QWidget* parent, QGridLayout *layout, bool editable) :
- QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Title"), false, false), titleLineEdit(NULL) {
- connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("Title"), false, false), titleLineEdit(nullptr) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
}
QtVCardTitleField::~QtVCardTitleField() {
- disconnect(this, SLOT(handleEditibleChanged(bool)));
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
}
void QtVCardTitleField::setupContentWidgets() {
- titleLineEdit = new QtResizableLineEdit(this);
- getGridLayout()->addWidget(titleLineEdit, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
- getTagComboBox()->hide();
- childWidgets << titleLineEdit;
+ titleLineEdit = new QtResizableLineEdit(this);
+ getGridLayout()->addWidget(titleLineEdit, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
+ getTagComboBox()->hide();
+ childWidgets << titleLineEdit;
}
bool QtVCardTitleField::isEmpty() const {
- return titleLineEdit->text().isEmpty();
+ return titleLineEdit->text().isEmpty();
}
void QtVCardTitleField::setTitle(const std::string& title) {
- titleLineEdit->setText(P2QSTRING(title));
+ titleLineEdit->setText(P2QSTRING(title));
}
std::string QtVCardTitleField::getTitle() const {
- return Q2PSTRING(titleLineEdit->text());
+ return Q2PSTRING(titleLineEdit->text());
}
void QtVCardTitleField::handleEditibleChanged(bool isEditable) {
- assert(titleLineEdit);
+ assert(titleLineEdit);
- titleLineEdit->setEditable(isEditable);
- titleLineEdit->setStyleSheet(isEditable ? "" : "QLineEdit { border: none; background: transparent; }");
+ titleLineEdit->setEditable(isEditable);
+ titleLineEdit->setStyleSheet(isEditable ? "" : "QLineEdit { border: none; background: transparent; }");
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardTitleField.h b/Swift/QtUI/QtVCardWidget/QtVCardTitleField.h
index 28dc603..0ea3772 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardTitleField.h
+++ b/Swift/QtUI/QtVCardWidget/QtVCardTitleField.h
@@ -4,38 +4,44 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <Swiften/Elements/VCard.h>
-#include "QtResizableLineEdit.h"
-#include "QtVCardFieldInfo.h"
-#include "QtVCardGeneralField.h"
+#include <Swift/QtUI/QtVCardWidget/QtResizableLineEdit.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h>
namespace Swift {
class QtVCardTitleField : public QtVCardGeneralField {
- Q_OBJECT
+ Q_OBJECT
- public:
- GENERIC_QT_VCARD_FIELD_INFO("Title", UNLIMITED_INSTANCES, QtVCardTitleField)
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO(tr("Title"), UNLIMITED_INSTANCES, QtVCardTitleField)
- QtVCardTitleField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
- virtual ~QtVCardTitleField();
+ QtVCardTitleField(QWidget* parent = nullptr, QGridLayout* layout = nullptr, bool editable = false);
+ virtual ~QtVCardTitleField();
- virtual bool isEmpty() const;
+ virtual bool isEmpty() const;
- void setTitle(const std::string& title);
- std::string getTitle() const;
+ void setTitle(const std::string& title);
+ std::string getTitle() const;
- protected:
- virtual void setupContentWidgets();
+ protected:
+ virtual void setupContentWidgets();
- public slots:
- void handleEditibleChanged(bool isEditable);
+ public slots:
+ void handleEditibleChanged(bool isEditable);
- private:
- QtResizableLineEdit* titleLineEdit;
+ private:
+ QtResizableLineEdit* titleLineEdit;
};
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardURLField.cpp b/Swift/QtUI/QtVCardWidget/QtVCardURLField.cpp
index 18241b4..153b897 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardURLField.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtVCardURLField.cpp
@@ -4,68 +4,74 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "QtVCardURLField.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/QtVCardWidget/QtVCardURLField.h>
+
+#include <boost/algorithm/string.hpp>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QTextDocument>
-#include <boost/algorithm/string.hpp>
#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swift/QtUI/QtUtilities.h>
-
namespace Swift {
QtVCardURLField::QtVCardURLField(QWidget* parent, QGridLayout *layout, bool editable) :
- QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("URL"), false, false), urlLabel(NULL), urlLineEdit(NULL) {
- connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
+ QtVCardGeneralField(parent, layout, editable, layout->rowCount(), tr("URL"), false, false), urlLabel(nullptr), urlLineEdit(nullptr) {
+ connect(this, SIGNAL(editableChanged(bool)), SLOT(handleEditibleChanged(bool)));
}
QtVCardURLField::~QtVCardURLField() {
- disconnect(this, SLOT(handleEditibleChanged(bool)));
+ disconnect(this, SLOT(handleEditibleChanged(bool)));
}
void QtVCardURLField::setupContentWidgets() {
- urlLabel = new QLabel(this);
- urlLabel->setOpenExternalLinks(true);
- urlLabel->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard);
- urlLineEdit = new QtResizableLineEdit(this);
-
- QHBoxLayout* urlLayout = new QHBoxLayout();
- urlLayout->addWidget(urlLabel);
- urlLayout->addWidget(urlLineEdit);
-
- getGridLayout()->addLayout(urlLayout, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
- getTagComboBox()->hide();
- urlLabel->hide();
- childWidgets << urlLabel << urlLineEdit;
+ urlLabel = new QLabel(this);
+ urlLabel->setOpenExternalLinks(true);
+ urlLabel->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard);
+ urlLineEdit = new QtResizableLineEdit(this);
+
+ QHBoxLayout* urlLayout = new QHBoxLayout();
+ urlLayout->addWidget(urlLabel);
+ urlLayout->addWidget(urlLineEdit);
+
+ getGridLayout()->addLayout(urlLayout, getGridLayout()->rowCount()-1, 2, 1, 2, Qt::AlignVCenter);
+ getTagComboBox()->hide();
+ urlLabel->hide();
+ childWidgets << urlLabel << urlLineEdit;
}
bool QtVCardURLField::isEmpty() const {
- return urlLineEdit->text().isEmpty();
+ return urlLineEdit->text().isEmpty();
}
void QtVCardURLField::setURL(const std::string& url) {
- urlLineEdit->setText(P2QSTRING(url));
+ urlLineEdit->setText(P2QSTRING(url));
}
std::string QtVCardURLField::getURL() const {
- return Q2PSTRING(urlLineEdit->text());
+ return Q2PSTRING(urlLineEdit->text());
}
void QtVCardURLField::handleEditibleChanged(bool isEditable) {
- assert(urlLineEdit);
- assert(urlLabel);
-
- if (isEditable) {
- urlLineEdit->show();
- urlLabel->hide();
- } else {
- urlLineEdit->hide();
- urlLabel->setText(QString("<a href=\"%1\">%1</a>").arg(QtUtilities::htmlEscape(urlLineEdit->text())));
- urlLabel->show();
- }
+ assert(urlLineEdit);
+ assert(urlLabel);
+
+ if (isEditable) {
+ urlLineEdit->show();
+ urlLabel->hide();
+ } else {
+ urlLineEdit->hide();
+ urlLabel->setText(QString("<a href=\"%1\">%1</a>").arg(QtUtilities::htmlEscape(urlLineEdit->text())));
+ urlLabel->show();
+ }
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardURLField.h b/Swift/QtUI/QtVCardWidget/QtVCardURLField.h
index 2c011d8..3830a7b 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardURLField.h
+++ b/Swift/QtUI/QtVCardWidget/QtVCardURLField.h
@@ -4,39 +4,45 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <Swiften/Elements/VCard.h>
-#include "QtResizableLineEdit.h"
-#include "QtVCardFieldInfo.h"
-#include "QtVCardGeneralField.h"
+#include <Swift/QtUI/QtVCardWidget/QtResizableLineEdit.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardFieldInfo.h>
+#include <Swift/QtUI/QtVCardWidget/QtVCardGeneralField.h>
namespace Swift {
class QtVCardURLField : public QtVCardGeneralField {
- Q_OBJECT
+ Q_OBJECT
- public:
- GENERIC_QT_VCARD_FIELD_INFO("URL", UNLIMITED_INSTANCES, QtVCardURLField)
+ public:
+ GENERIC_QT_VCARD_FIELD_INFO(tr("URL"), UNLIMITED_INSTANCES, QtVCardURLField)
- QtVCardURLField(QWidget* parent = 0, QGridLayout* layout = 0, bool editable = false);
- virtual ~QtVCardURLField();
+ QtVCardURLField(QWidget* parent = nullptr, QGridLayout* layout = nullptr, bool editable = false);
+ virtual ~QtVCardURLField();
- virtual bool isEmpty() const;
+ virtual bool isEmpty() const;
- void setURL(const std::string& url);
- std::string getURL() const;
+ void setURL(const std::string& url);
+ std::string getURL() const;
- protected:
- virtual void setupContentWidgets();
+ protected:
+ virtual void setupContentWidgets();
- public slots:
- void handleEditibleChanged(bool isEditable);
+ public slots:
+ void handleEditibleChanged(bool isEditable);
- private:
- QLabel* urlLabel;
- QtResizableLineEdit* urlLineEdit;
+ private:
+ QLabel* urlLabel;
+ QtResizableLineEdit* urlLineEdit;
};
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardWidget.cpp b/Swift/QtUI/QtVCardWidget/QtVCardWidget.cpp
index 9092e08..290feca 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardWidget.cpp
+++ b/Swift/QtUI/QtVCardWidget/QtVCardWidget.cpp
@@ -5,13 +5,12 @@
*/
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/QtVCardWidget/QtVCardWidget.h>
-#include <Swift/QtUI/QtVCardWidget/ui_QtVCardWidget.h>
#include <QLineEdit>
#include <QMenu>
@@ -29,398 +28,399 @@
#include <Swift/QtUI/QtVCardWidget/QtVCardTelephoneField.h>
#include <Swift/QtUI/QtVCardWidget/QtVCardTitleField.h>
#include <Swift/QtUI/QtVCardWidget/QtVCardURLField.h>
+#include <Swift/QtUI/QtVCardWidget/ui_QtVCardWidget.h>
namespace Swift {
QtVCardWidget::QtVCardWidget(QWidget* parent) :
- QWidget(parent),
- ui(new ::Ui::QtVCardWidget) {
- ui->setupUi(this);
-
- ui->cardFields->setColumnStretch(0,0);
- ui->cardFields->setColumnStretch(1,0);
- ui->cardFields->setColumnStretch(2,2);
- ui->cardFields->setColumnStretch(3,1);
- ui->cardFields->setColumnStretch(4,2);
- menu = new QMenu(this);
-
- toolButton = new QToolButton(this);
- toolButton->setText(tr("Add Field"));
- toolButton->setArrowType(Qt::NoArrow);
- toolButton->setAutoRaise(false);
- toolButton->setPopupMode(QToolButton::InstantPopup);
- toolButton->hide();
- toolButton->setMenu(menu);
-
- addFieldType(menu, boost::make_shared<QtVCardInternetEMailField::FieldInfo>());
- addFieldType(menu, boost::make_shared<QtVCardTelephoneField::FieldInfo>());
- addFieldType(menu, boost::make_shared<QtVCardAddressField::FieldInfo>());
- addFieldType(menu, boost::make_shared<QtVCardAddressLabelField::FieldInfo>());
- addFieldType(menu, boost::make_shared<QtVCardBirthdayField::FieldInfo>());
- addFieldType(menu, boost::make_shared<QtVCardJIDField::FieldInfo>());
- addFieldType(menu, boost::make_shared<QtVCardDescriptionField::FieldInfo>());
- addFieldType(menu, boost::make_shared<QtVCardRoleField::FieldInfo>());
- addFieldType(menu, boost::make_shared<QtVCardTitleField::FieldInfo>());
- addFieldType(menu, boost::make_shared<QtVCardOrganizationField::FieldInfo>());
- addFieldType(menu, boost::make_shared<QtVCardURLField::FieldInfo>());
-
- setEditable(false);
- setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ QWidget(parent),
+ ui(new ::Ui::QtVCardWidget) {
+ ui->setupUi(this);
+
+ ui->cardFields->setColumnStretch(0,0);
+ ui->cardFields->setColumnStretch(1,0);
+ ui->cardFields->setColumnStretch(2,2);
+ ui->cardFields->setColumnStretch(3,1);
+ ui->cardFields->setColumnStretch(4,2);
+ menu = new QMenu(this);
+
+ toolButton = new QToolButton(this);
+ toolButton->setText(tr("Add Field"));
+ toolButton->setArrowType(Qt::NoArrow);
+ toolButton->setAutoRaise(false);
+ toolButton->setPopupMode(QToolButton::InstantPopup);
+ toolButton->hide();
+ toolButton->setMenu(menu);
+
+ addFieldType(menu, std::make_shared<QtVCardInternetEMailField::FieldInfo>());
+ addFieldType(menu, std::make_shared<QtVCardTelephoneField::FieldInfo>());
+ addFieldType(menu, std::make_shared<QtVCardAddressField::FieldInfo>());
+ addFieldType(menu, std::make_shared<QtVCardAddressLabelField::FieldInfo>());
+ addFieldType(menu, std::make_shared<QtVCardBirthdayField::FieldInfo>());
+ addFieldType(menu, std::make_shared<QtVCardJIDField::FieldInfo>());
+ addFieldType(menu, std::make_shared<QtVCardDescriptionField::FieldInfo>());
+ addFieldType(menu, std::make_shared<QtVCardRoleField::FieldInfo>());
+ addFieldType(menu, std::make_shared<QtVCardTitleField::FieldInfo>());
+ addFieldType(menu, std::make_shared<QtVCardOrganizationField::FieldInfo>());
+ addFieldType(menu, std::make_shared<QtVCardURLField::FieldInfo>());
+
+ setEditable(false);
+ setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
}
QtVCardWidget::~QtVCardWidget() {
- delete ui;
+ delete ui;
}
QSize QtVCardWidget::sizeHint() const {
- QSize newSizeHint = ui->photoAndName->sizeHint();
+ QSize newSizeHint = ui->photoAndName->sizeHint();
- // use mininmal size that does not require scrolling
- QSize fieldsWidgetSize = ui->scrollArea->widget()->minimumSize();
- fieldsWidgetSize.setWidth(ui->scrollArea->widget()->sizeHint().width());
+ // use mininmal size that does not require scrolling
+ QSize fieldsWidgetSize = ui->scrollArea->widget()->minimumSize();
+ fieldsWidgetSize.setWidth(ui->scrollArea->widget()->sizeHint().width());
- newSizeHint += QSize(0, ui->line->height());
+ newSizeHint += QSize(0, ui->line->height());
- newSizeHint = QSize(std::max(newSizeHint.width(), fieldsWidgetSize.width()), newSizeHint.height() + fieldsWidgetSize.height());
+ newSizeHint = QSize(std::max(newSizeHint.width(), fieldsWidgetSize.width()), newSizeHint.height() + fieldsWidgetSize.height());
- // add layout margin
- newSizeHint += QSize(layout()->contentsMargins().left() + layout()->contentsMargins().right(), layout()->contentsMargins().top() + layout()->contentsMargins().bottom());
+ // add layout margin
+ newSizeHint += QSize(layout()->contentsMargins().left() + layout()->contentsMargins().right(), layout()->contentsMargins().top() + layout()->contentsMargins().bottom());
- // the spaceing before and after the line between the profile header and its fields
- newSizeHint += QSize(0, layout()->spacing() * 2);
+ // the spaceing before and after the line between the profile header and its fields
+ newSizeHint += QSize(0, layout()->spacing() * 2);
- return newSizeHint;
+ return newSizeHint;
}
bool QtVCardWidget::isEditable() const {
- return editable;
+ return editable;
}
void QtVCardWidget::setEditable(bool editable) {
- this->editable = editable;
+ this->editable = editable;
- ui->photoAndName->setProperty("editable", QVariant(editable));
+ ui->photoAndName->setProperty("editable", QVariant(editable));
- foreach(QtVCardGeneralField* field, fields) {
- field->setEditable(editable);
- }
- toolButton->setVisible(editable);
+ for (auto field : fields) {
+ field->setEditable(editable);
+ }
+ toolButton->setVisible(editable);
- editableChanged(editable);
+ editableChanged(editable);
}
void QtVCardWidget::setVCard(VCard::ref vcard) {
- clearFields();
- this->vcard = boost::make_shared<VCard>(*vcard);
- ui->photoAndName->setFormattedName(P2QSTRING(vcard->getFullName()));
- ui->photoAndName->setNickname(P2QSTRING(vcard->getNickname()));
- ui->photoAndName->setPrefix(P2QSTRING(vcard->getPrefix()));
- ui->photoAndName->setGivenName(P2QSTRING(vcard->getGivenName()));
- ui->photoAndName->setMiddleName(P2QSTRING(vcard->getMiddleName()));
- ui->photoAndName->setFamilyName(P2QSTRING(vcard->getFamilyName()));
- ui->photoAndName->setSuffix(P2QSTRING(vcard->getSuffix()));
- ui->photoAndName->setAvatar(vcard->getPhoto(), vcard->getPhotoType());
-
- foreach (const VCard::EMailAddress& address, vcard->getEMailAddresses()) {
- if (address.isInternet) {
- QtVCardInternetEMailField* internetEmailField = new QtVCardInternetEMailField(this, ui->cardFields);
- internetEmailField->initialize();
- internetEmailField->setInternetEMailAddress(address);
- appendField(internetEmailField);
- }
- }
-
- foreach (const VCard::Telephone& telephone, vcard->getTelephones()) {
- QtVCardTelephoneField* telField = new QtVCardTelephoneField(this, ui->cardFields);
- telField->initialize();
- telField->setTelephone(telephone);
- appendField(telField);
- }
-
- foreach (const VCard::Address& address, vcard->getAddresses()) {
- QtVCardAddressField* addressField = new QtVCardAddressField(this, ui->cardFields);
- addressField->initialize();
- addressField->setAddress(address);
- appendField(addressField);
- }
-
- foreach (const VCard::AddressLabel& label, vcard->getAddressLabels()) {
- QtVCardAddressLabelField* addressLabelField = new QtVCardAddressLabelField(this, ui->cardFields);
- addressLabelField->initialize();
- addressLabelField->setAddressLabel(label);
- appendField(addressLabelField);
- }
-
- if (!vcard->getBirthday().is_not_a_date_time()) {
- QtVCardBirthdayField* bdayField = new QtVCardBirthdayField(this, ui->cardFields);
- bdayField->initialize();
- bdayField->setBirthday(vcard->getBirthday());
- appendField(bdayField);
- }
-
- foreach (const JID& jid, vcard->getJIDs()) {
- QtVCardJIDField* jidField = new QtVCardJIDField(this, ui->cardFields);
- jidField->initialize();
- jidField->setJID(jid);
- appendField(jidField);
- }
-
- if (!vcard->getDescription().empty()) {
- QtVCardDescriptionField* descField = new QtVCardDescriptionField(this, ui->cardFields);
- descField->initialize();
- descField->setDescription(vcard->getDescription());
- appendField(descField);
- }
-
- foreach (const VCard::Organization& org, vcard->getOrganizations()) {
- QtVCardOrganizationField* orgField = new QtVCardOrganizationField(this, ui->cardFields);
- orgField->initialize();
- orgField->setOrganization(org);
- appendField(orgField);
- }
-
- foreach (const std::string& role, vcard->getRoles()) {
- QtVCardRoleField* roleField = new QtVCardRoleField(this, ui->cardFields);
- roleField->initialize();
- roleField->setRole(role);
- appendField(roleField);
- }
-
- foreach (const std::string& title, vcard->getTitles()) {
- QtVCardTitleField* titleField = new QtVCardTitleField(this, ui->cardFields);
- titleField->initialize();
- titleField->setTitle(title);
- appendField(titleField);
- }
-
- foreach (const std::string& url, vcard->getURLs()) {
- QtVCardURLField* urlField = new QtVCardURLField(this, ui->cardFields);
- urlField->initialize();
- urlField->setURL(url);
- appendField(urlField);
- }
-
- relayoutToolButton();
- setEditable(editable);
+ clearFields();
+ this->vcard = std::make_shared<VCard>(*vcard);
+ ui->photoAndName->setFormattedName(P2QSTRING(vcard->getFullName()));
+ ui->photoAndName->setNickname(P2QSTRING(vcard->getNickname()));
+ ui->photoAndName->setPrefix(P2QSTRING(vcard->getPrefix()));
+ ui->photoAndName->setGivenName(P2QSTRING(vcard->getGivenName()));
+ ui->photoAndName->setMiddleName(P2QSTRING(vcard->getMiddleName()));
+ ui->photoAndName->setFamilyName(P2QSTRING(vcard->getFamilyName()));
+ ui->photoAndName->setSuffix(P2QSTRING(vcard->getSuffix()));
+ ui->photoAndName->setAvatar(vcard->getPhoto(), vcard->getPhotoType());
+
+ for (const auto& address : vcard->getEMailAddresses()) {
+ if (address.isInternet) {
+ QtVCardInternetEMailField* internetEmailField = new QtVCardInternetEMailField(this, ui->cardFields);
+ internetEmailField->initialize();
+ internetEmailField->setInternetEMailAddress(address);
+ appendField(internetEmailField);
+ }
+ }
+
+ for (const auto& telephone : vcard->getTelephones()) {
+ QtVCardTelephoneField* telField = new QtVCardTelephoneField(this, ui->cardFields);
+ telField->initialize();
+ telField->setTelephone(telephone);
+ appendField(telField);
+ }
+
+ for (const auto& address : vcard->getAddresses()) {
+ QtVCardAddressField* addressField = new QtVCardAddressField(this, ui->cardFields);
+ addressField->initialize();
+ addressField->setAddress(address);
+ appendField(addressField);
+ }
+
+ for (const auto& label : vcard->getAddressLabels()) {
+ QtVCardAddressLabelField* addressLabelField = new QtVCardAddressLabelField(this, ui->cardFields);
+ addressLabelField->initialize();
+ addressLabelField->setAddressLabel(label);
+ appendField(addressLabelField);
+ }
+
+ if (!vcard->getBirthday().is_not_a_date_time()) {
+ QtVCardBirthdayField* bdayField = new QtVCardBirthdayField(this, ui->cardFields);
+ bdayField->initialize();
+ bdayField->setBirthday(vcard->getBirthday());
+ appendField(bdayField);
+ }
+
+ for (const auto& jid : vcard->getJIDs()) {
+ QtVCardJIDField* jidField = new QtVCardJIDField(this, ui->cardFields);
+ jidField->initialize();
+ jidField->setJID(jid);
+ appendField(jidField);
+ }
+
+ if (!vcard->getDescription().empty()) {
+ QtVCardDescriptionField* descField = new QtVCardDescriptionField(this, ui->cardFields);
+ descField->initialize();
+ descField->setDescription(vcard->getDescription());
+ appendField(descField);
+ }
+
+ for (const auto& org : vcard->getOrganizations()) {
+ QtVCardOrganizationField* orgField = new QtVCardOrganizationField(this, ui->cardFields);
+ orgField->initialize();
+ orgField->setOrganization(org);
+ appendField(orgField);
+ }
+
+ for (const auto& role : vcard->getRoles()) {
+ QtVCardRoleField* roleField = new QtVCardRoleField(this, ui->cardFields);
+ roleField->initialize();
+ roleField->setRole(role);
+ appendField(roleField);
+ }
+
+ for (const auto& title : vcard->getTitles()) {
+ QtVCardTitleField* titleField = new QtVCardTitleField(this, ui->cardFields);
+ titleField->initialize();
+ titleField->setTitle(title);
+ appendField(titleField);
+ }
+
+ for (const auto& url : vcard->getURLs()) {
+ QtVCardURLField* urlField = new QtVCardURLField(this, ui->cardFields);
+ urlField->initialize();
+ urlField->setURL(url);
+ appendField(urlField);
+ }
+
+ relayoutToolButton();
+ setEditable(editable);
}
VCard::ref QtVCardWidget::getVCard() {
- clearEmptyFields();
- vcard->setFullName(Q2PSTRING(ui->photoAndName->getFormattedName()));
- vcard->setNickname(Q2PSTRING(ui->photoAndName->getNickname()));
- vcard->setPrefix(Q2PSTRING(ui->photoAndName->getPrefix()));
- vcard->setGivenName(Q2PSTRING(ui->photoAndName->getGivenName()));
- vcard->setMiddleName(Q2PSTRING(ui->photoAndName->getMiddleName()));
- vcard->setFamilyName(Q2PSTRING(ui->photoAndName->getFamilyName()));
- vcard->setSuffix(Q2PSTRING(ui->photoAndName->getSuffix()));
- vcard->setPhoto(ui->photoAndName->getAvatarData());
- vcard->setPhotoType(ui->photoAndName->getAvatarType());
-
- vcard->clearEMailAddresses();
- vcard->clearJIDs();
- vcard->clearURLs();
- vcard->clearTelephones();
- vcard->clearRoles();
- vcard->clearTitles();
- vcard->clearOrganizations();
- vcard->clearAddresses();
- vcard->clearAddressLabels();
-
-
- QtVCardBirthdayField* bdayField = NULL;
- QtVCardDescriptionField* descriptionField = NULL;
-
- foreach(QtVCardGeneralField* field, fields) {
- QtVCardInternetEMailField* emailField;
- if ((emailField = dynamic_cast<QtVCardInternetEMailField*>(field))) {
- vcard->addEMailAddress(emailField->getInternetEMailAddress());
- continue;
- }
-
- QtVCardTelephoneField* telephoneField;
- if ((telephoneField = dynamic_cast<QtVCardTelephoneField*>(field))) {
- vcard->addTelephone(telephoneField->getTelephone());
- continue;
- }
-
- QtVCardAddressField* addressField;
- if ((addressField = dynamic_cast<QtVCardAddressField*>(field))) {
- vcard->addAddress(addressField->getAddress());
- continue;
- }
-
- QtVCardAddressLabelField* addressLabelField;
- if ((addressLabelField = dynamic_cast<QtVCardAddressLabelField*>(field))) {
- vcard->addAddressLabel(addressLabelField->getAddressLabel());
- continue;
- }
-
- if ((bdayField = dynamic_cast<QtVCardBirthdayField*>(field))) {
- continue;
- }
-
- QtVCardJIDField* jidField;
- if ((jidField = dynamic_cast<QtVCardJIDField*>(field))) {
- vcard->addJID(jidField->getJID());
- continue;
- }
-
- if ((descriptionField = dynamic_cast<QtVCardDescriptionField*>(field))) {
- continue;
- }
-
- QtVCardOrganizationField* orgField;
- if ((orgField = dynamic_cast<QtVCardOrganizationField*>(field))) {
- vcard->addOrganization(orgField->getOrganization());
- continue;
- }
-
- QtVCardRoleField* roleField;
- if ((roleField = dynamic_cast<QtVCardRoleField*>(field))) {
- vcard->addRole(roleField->getRole());
- continue;
- }
-
- QtVCardTitleField* titleField;
- if ((titleField = dynamic_cast<QtVCardTitleField*>(field))) {
- vcard->addTitle(titleField->getTitle());
- continue;
- }
-
- QtVCardURLField* urlField;
- if ((urlField = dynamic_cast<QtVCardURLField*>(field))) {
- vcard->addURL(urlField->getURL());
- continue;
- }
- }
-
- if (bdayField) {
- vcard->setBirthday(bdayField->getBirthday());
- } else {
- vcard->setBirthday(boost::posix_time::ptime());
- }
-
- if (descriptionField) {
- vcard->setDescription(descriptionField->getDescription());
- } else {
- vcard->setDescription("");
- }
-
- return vcard;
+ clearEmptyFields();
+ vcard->setFullName(Q2PSTRING(ui->photoAndName->getFormattedName()));
+ vcard->setNickname(Q2PSTRING(ui->photoAndName->getNickname()));
+ vcard->setPrefix(Q2PSTRING(ui->photoAndName->getPrefix()));
+ vcard->setGivenName(Q2PSTRING(ui->photoAndName->getGivenName()));
+ vcard->setMiddleName(Q2PSTRING(ui->photoAndName->getMiddleName()));
+ vcard->setFamilyName(Q2PSTRING(ui->photoAndName->getFamilyName()));
+ vcard->setSuffix(Q2PSTRING(ui->photoAndName->getSuffix()));
+ vcard->setPhoto(ui->photoAndName->getAvatarData());
+ vcard->setPhotoType(ui->photoAndName->getAvatarType());
+
+ vcard->clearEMailAddresses();
+ vcard->clearJIDs();
+ vcard->clearURLs();
+ vcard->clearTelephones();
+ vcard->clearRoles();
+ vcard->clearTitles();
+ vcard->clearOrganizations();
+ vcard->clearAddresses();
+ vcard->clearAddressLabels();
+
+
+ QtVCardBirthdayField* bdayField = nullptr;
+ QtVCardDescriptionField* descriptionField = nullptr;
+
+ for (auto field : fields) {
+ QtVCardInternetEMailField* emailField;
+ if ((emailField = dynamic_cast<QtVCardInternetEMailField*>(field))) {
+ vcard->addEMailAddress(emailField->getInternetEMailAddress());
+ continue;
+ }
+
+ QtVCardTelephoneField* telephoneField;
+ if ((telephoneField = dynamic_cast<QtVCardTelephoneField*>(field))) {
+ vcard->addTelephone(telephoneField->getTelephone());
+ continue;
+ }
+
+ QtVCardAddressField* addressField;
+ if ((addressField = dynamic_cast<QtVCardAddressField*>(field))) {
+ vcard->addAddress(addressField->getAddress());
+ continue;
+ }
+
+ QtVCardAddressLabelField* addressLabelField;
+ if ((addressLabelField = dynamic_cast<QtVCardAddressLabelField*>(field))) {
+ vcard->addAddressLabel(addressLabelField->getAddressLabel());
+ continue;
+ }
+
+ if ((bdayField = dynamic_cast<QtVCardBirthdayField*>(field))) {
+ continue;
+ }
+
+ QtVCardJIDField* jidField;
+ if ((jidField = dynamic_cast<QtVCardJIDField*>(field))) {
+ vcard->addJID(jidField->getJID());
+ continue;
+ }
+
+ if ((descriptionField = dynamic_cast<QtVCardDescriptionField*>(field))) {
+ continue;
+ }
+
+ QtVCardOrganizationField* orgField;
+ if ((orgField = dynamic_cast<QtVCardOrganizationField*>(field))) {
+ vcard->addOrganization(orgField->getOrganization());
+ continue;
+ }
+
+ QtVCardRoleField* roleField;
+ if ((roleField = dynamic_cast<QtVCardRoleField*>(field))) {
+ vcard->addRole(roleField->getRole());
+ continue;
+ }
+
+ QtVCardTitleField* titleField;
+ if ((titleField = dynamic_cast<QtVCardTitleField*>(field))) {
+ vcard->addTitle(titleField->getTitle());
+ continue;
+ }
+
+ QtVCardURLField* urlField;
+ if ((urlField = dynamic_cast<QtVCardURLField*>(field))) {
+ vcard->addURL(urlField->getURL());
+ continue;
+ }
+ }
+
+ if (bdayField) {
+ vcard->setBirthday(bdayField->getBirthday());
+ } else {
+ vcard->setBirthday(boost::posix_time::ptime());
+ }
+
+ if (descriptionField) {
+ vcard->setDescription(descriptionField->getDescription());
+ } else {
+ vcard->setDescription("");
+ }
+
+ return vcard;
}
void QtVCardWidget::addField() {
- QAction* action = NULL;
- if ((action = dynamic_cast<QAction*>(sender()))) {
- boost::shared_ptr<QtVCardFieldInfo> fieldInfo = actionFieldInfo[action];
- QWidget* newField = fieldInfo->createFieldInstance(this, ui->cardFields, true);
- QtVCardGeneralField* newGeneralField = dynamic_cast<QtVCardGeneralField*>(newField);
- if (newGeneralField) {
- newGeneralField->initialize();
- }
- appendField(newGeneralField);
- relayoutToolButton();
- }
+ QAction* action = nullptr;
+ if ((action = dynamic_cast<QAction*>(sender()))) {
+ std::shared_ptr<QtVCardFieldInfo> fieldInfo = actionFieldInfo[action];
+ QWidget* newField = fieldInfo->createFieldInstance(this, ui->cardFields, true);
+ QtVCardGeneralField* newGeneralField = dynamic_cast<QtVCardGeneralField*>(newField);
+ if (newGeneralField) {
+ newGeneralField->initialize();
+ appendField(newGeneralField);
+ relayoutToolButton();
+ }
+ }
}
void QtVCardWidget::removeField(QtVCardGeneralField *field) {
- int sameFields = 0;
- QtVCardGeneralField* fieldToChange = NULL;
- foreach (QtVCardGeneralField* vcardField, fields) {
- if ((vcardField != field) && (typeid(*vcardField) == typeid(*field))) {
- sameFields++;
- fieldToChange = vcardField;
- }
- }
-
- if ((sameFields == 1) && fieldToChange) {
- fieldToChange->setStarVisible(false);
- }
-
- fields.remove(field);
- delete field;
+ int sameFields = 0;
+ QtVCardGeneralField* fieldToChange = nullptr;
+ for (auto vcardField : fields) {
+ if ((vcardField != field) && (typeid(*vcardField) == typeid(*field))) {
+ sameFields++;
+ fieldToChange = vcardField;
+ }
+ }
+
+ if ((sameFields == 1) && fieldToChange) {
+ fieldToChange->setStarVisible(false);
+ }
+
+ fields.remove(field);
+ delete field;
}
-void QtVCardWidget::addFieldType(QMenu* menu, boost::shared_ptr<QtVCardFieldInfo> fieldType) {
- if (!fieldType->getMenuName().isEmpty()) {
- QAction* action = new QAction(tr("Add %1").arg(fieldType->getMenuName()), this);
- actionFieldInfo[action] = fieldType;
- connect(action, SIGNAL(triggered()), this, SLOT(addField()));
- menu->addAction(action);
- }
+void QtVCardWidget::addFieldType(QMenu* menu, std::shared_ptr<QtVCardFieldInfo> fieldType) {
+ if (!fieldType->getMenuName().isEmpty()) {
+ QAction* action = new QAction(tr("Add %1").arg(fieldType->getMenuName()), this);
+ actionFieldInfo[action] = fieldType;
+ connect(action, SIGNAL(triggered()), this, SLOT(addField()));
+ menu->addAction(action);
+ }
}
-int QtVCardWidget::fieldTypeInstances(boost::shared_ptr<QtVCardFieldInfo> fieldType) {
- int instances = 0;
- for (int n = 0; n < ui->cardFields->count(); n++) {
- if (fieldType->testInstance(ui->cardFields->itemAt(n)->widget())) instances++;
- }
- return instances;
+int QtVCardWidget::fieldTypeInstances(std::shared_ptr<QtVCardFieldInfo> fieldType) {
+ int instances = 0;
+ for (int n = 0; n < ui->cardFields->count(); n++) {
+ if (fieldType->testInstance(ui->cardFields->itemAt(n)->widget())) instances++;
+ }
+ return instances;
}
void layoutDeleteChildren(QLayout *layout) {
- while(layout->count() > 0) {
- QLayoutItem* child;
- if ((child = layout->takeAt(0)) != 0) {
- if (child->layout()) {
- layoutDeleteChildren(child->layout());
- }
- if (dynamic_cast<QToolButton*>(child->widget())) {
- delete child;
- break;
- }
- delete child->widget();
- delete child;
- }
- }
+ while(layout->count() > 0) {
+ QLayoutItem* child;
+ if ((child = layout->takeAt(0)) != nullptr) {
+ if (child->layout()) {
+ layoutDeleteChildren(child->layout());
+ }
+ if (dynamic_cast<QToolButton*>(child->widget())) {
+ delete child;
+ break;
+ }
+ delete child->widget();
+ delete child;
+ }
+ }
}
void QtVCardWidget::clearFields() {
- foreach(QtVCardGeneralField* field, fields) {
- delete field;
- }
- fields.clear();
+ for (auto field : fields) {
+ delete field;
+ }
+ fields.clear();
- assert(ui->cardFields->count() >= 0);
- layoutDeleteChildren(ui->cardFields);
+ assert(ui->cardFields->count() >= 0);
+ layoutDeleteChildren(ui->cardFields);
}
void QtVCardWidget::clearEmptyFields() {
- std::vector<QtVCardGeneralField*> items_to_remove;
- foreach (QtVCardGeneralField* field, fields) {
- if (field->property("empty").isValid() && field->property("empty").toBool()) {
- ui->cardFields->removeWidget(field);
- items_to_remove.push_back(field);
- delete field;
- }
- }
-
- foreach(QtVCardGeneralField* field, items_to_remove) {
- fields.remove(field);
- }
+ std::vector<QtVCardGeneralField*> items_to_remove;
+ for (auto field : fields) {
+ if (field->property("empty").isValid() && field->property("empty").toBool()) {
+ ui->cardFields->removeWidget(field);
+ items_to_remove.push_back(field);
+ delete field;
+ }
+ }
+
+ for (auto field : items_to_remove) {
+ fields.remove(field);
+ }
}
void QtVCardWidget::appendField(QtVCardGeneralField *field) {
- connect(field, SIGNAL(deleteField(QtVCardGeneralField*)), SLOT(removeField(QtVCardGeneralField*)));
-
- QtVCardGeneralField* fieldToChange = NULL;
- foreach (QtVCardGeneralField* vcardField, fields) {
- if (typeid(*vcardField) == typeid(*field)) {
- fieldToChange = vcardField;
- break;
- }
- }
-
- if (fieldToChange) {
- fieldToChange->setStarVisible(true);
- field->setStarVisible(true);
- }
-
- fields.push_back(field);
+ connect(field, SIGNAL(deleteField(QtVCardGeneralField*)), SLOT(removeField(QtVCardGeneralField*)));
+
+ QtVCardGeneralField* fieldToChange = nullptr;
+ for (auto vcardField : fields) {
+ if (typeid(*vcardField) == typeid(*field)) {
+ fieldToChange = vcardField;
+ break;
+ }
+ }
+
+ if (fieldToChange) {
+ fieldToChange->setStarVisible(true);
+ field->setStarVisible(true);
+ }
+
+ fields.push_back(field);
}
void QtVCardWidget::relayoutToolButton() {
- ui->cardFields->addWidget(toolButton, ui->cardFields->rowCount(), ui->cardFields->columnCount()-2, 1, 1, Qt::AlignRight);
+ ui->cardFields->addWidget(toolButton, ui->cardFields->rowCount(), ui->cardFields->columnCount()-2, 1, 1, Qt::AlignRight);
}
}
diff --git a/Swift/QtUI/QtVCardWidget/QtVCardWidget.h b/Swift/QtUI/QtVCardWidget/QtVCardWidget.h
index 8c0ff31..9aae158 100644
--- a/Swift/QtUI/QtVCardWidget/QtVCardWidget.h
+++ b/Swift/QtUI/QtVCardWidget/QtVCardWidget.h
@@ -5,14 +5,15 @@
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/smart_ptr/make_shared.hpp>
+#include <list>
+#include <memory>
#include <QToolButton>
#include <QWidget>
@@ -24,50 +25,50 @@
#include <Swift/QtUI/QtVCardWidget/QtVCardPhotoAndNameFields.h>
namespace Ui {
- class QtVCardWidget;
+ class QtVCardWidget;
}
namespace Swift {
- class QtVCardWidget : public QWidget {
- Q_OBJECT
- Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
-
- public :
- explicit QtVCardWidget(QWidget* parent = 0);
- ~QtVCardWidget();
-
- bool isEditable() const;
- void setEditable(bool);
-
- void setVCard(VCard::ref vcard);
- VCard::ref getVCard();
-
- virtual QSize sizeHint() const;
-
- signals:
- void editableChanged(bool editable);
-
- private slots:
- void addField();
- void removeField(QtVCardGeneralField* field);
-
- private:
- void addFieldType(QMenu*, boost::shared_ptr<QtVCardFieldInfo>);
- int fieldTypeInstances(boost::shared_ptr<QtVCardFieldInfo>);
- void clearFields();
- void clearEmptyFields();
- void appendField(QtVCardGeneralField* field);
- void relayoutToolButton();
-
- private:
- VCard::ref vcard;
- Ui::QtVCardWidget* ui;
- QToolButton* toolButton;
- bool editable;
- QMenu* menu;
- std::list<QtVCardGeneralField*> fields;
- std::map<QAction*, boost::shared_ptr<QtVCardFieldInfo> > actionFieldInfo;
- };
+ class QtVCardWidget : public QWidget {
+ Q_OBJECT
+ Q_PROPERTY(bool editable READ isEditable WRITE setEditable)
+
+ public :
+ explicit QtVCardWidget(QWidget* parent = nullptr);
+ ~QtVCardWidget();
+
+ bool isEditable() const;
+ void setEditable(bool);
+
+ void setVCard(VCard::ref vcard);
+ VCard::ref getVCard();
+
+ virtual QSize sizeHint() const;
+
+ signals:
+ void editableChanged(bool editable);
+
+ private slots:
+ void addField();
+ void removeField(QtVCardGeneralField* field);
+
+ private:
+ void addFieldType(QMenu*, std::shared_ptr<QtVCardFieldInfo>);
+ int fieldTypeInstances(std::shared_ptr<QtVCardFieldInfo>);
+ void clearFields();
+ void clearEmptyFields();
+ void appendField(QtVCardGeneralField* field);
+ void relayoutToolButton();
+
+ private:
+ VCard::ref vcard;
+ Ui::QtVCardWidget* ui;
+ QToolButton* toolButton;
+ bool editable;
+ QMenu* menu;
+ std::list<QtVCardGeneralField*> fields;
+ std::map<QAction*, std::shared_ptr<QtVCardFieldInfo> > actionFieldInfo;
+ };
}
diff --git a/Swift/QtUI/QtWebKitChatView.cpp b/Swift/QtUI/QtWebKitChatView.cpp
index b543e34..6fe9397 100644
--- a/Swift/QtUI/QtWebKitChatView.cpp
+++ b/Swift/QtUI/QtWebKitChatView.cpp
@@ -8,6 +8,7 @@
#include <QApplication>
#include <QDesktopServices>
+#include <QDesktopWidget>
#include <QEventLoop>
#include <QFile>
#include <QFileDialog>
@@ -19,6 +20,7 @@
#include <QTimer>
#include <QVBoxLayout>
#include <QWebFrame>
+#include <QWebSettings>
#include <QtDebug>
#include <Swiften/Base/FileSize.h>
@@ -49,1004 +51,941 @@ const QString QtWebKitChatView::ButtonFileTransferAcceptRequest = QString("filet
const QString QtWebKitChatView::ButtonFileTransferOpenFile = QString("filetransfer-openfile");
const QString QtWebKitChatView::ButtonMUCInvite = QString("mucinvite");
+namespace {
+ const double minimalFontScaling = 0.8;
+}
+
QtWebKitChatView::QtWebKitChatView(QtChatWindow* window, UIEventStream* eventStream, QtChatTheme* theme, QWidget* parent, bool disableAutoScroll) : QtChatView(parent), window_(window), eventStream_(eventStream), fontSizeSteps_(0), disableAutoScroll_(disableAutoScroll), previousMessageKind_(PreviosuMessageWasNone), previousMessageWasSelf_(false), showEmoticons_(false), insertingLastLine_(false), idCounter_(0) {
- theme_ = theme;
-
- QVBoxLayout* mainLayout = new QVBoxLayout(this);
- mainLayout->setSpacing(0);
- mainLayout->setContentsMargins(0,0,0,0);
- webView_ = new QtWebView(this);
- connect(webView_, SIGNAL(linkClicked(const QUrl&)), SLOT(handleLinkClicked(const QUrl&)));
- connect(webView_, SIGNAL(loadFinished(bool)), SLOT(handleViewLoadFinished(bool)));
- connect(webView_, SIGNAL(gotFocus()), SIGNAL(gotFocus()));
- connect(webView_, SIGNAL(clearRequested()), SLOT(handleClearRequested()));
- connect(webView_, SIGNAL(fontGrowRequested()), SLOT(increaseFontSize()));
- connect(webView_, SIGNAL(fontShrinkRequested()), SLOT(decreaseFontSize()));
+ theme_ = theme;
+
+ QVBoxLayout* mainLayout = new QVBoxLayout(this);
+ mainLayout->setSpacing(0);
+ mainLayout->setContentsMargins(0,0,0,0);
+ webView_ = new QtWebView(this);
+ connect(webView_, SIGNAL(linkClicked(const QUrl&)), SLOT(handleLinkClicked(const QUrl&)));
+ connect(webView_, SIGNAL(loadFinished(bool)), SLOT(handleViewLoadFinished(bool)));
+ connect(webView_, SIGNAL(gotFocus()), SIGNAL(gotFocus()));
+ connect(webView_, SIGNAL(clearRequested()), SLOT(handleClearRequested()));
+ connect(webView_, SIGNAL(fontGrowRequested()), SLOT(increaseFontSize()));
+ connect(webView_, SIGNAL(fontShrinkRequested()), SLOT(decreaseFontSize()));
#if defined (Q_OS_UNIX) && !defined(Q_OS_MAC)
- /* To give a border on Linux, where it looks bad without */
- QStackedWidget* stack = new QStackedWidget(this);
- stack->addWidget(webView_);
- stack->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
- stack->setLineWidth(2);
- mainLayout->addWidget(stack);
+ /* To give a border on Linux, where it looks bad without */
+ QStackedWidget* stack = new QStackedWidget(this);
+ stack->addWidget(webView_);
+ stack->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
+ stack->setLineWidth(2);
+ mainLayout->addWidget(stack);
#else
- mainLayout->addWidget(webView_);
+ mainLayout->addWidget(webView_);
#endif
#ifdef SWIFT_EXPERIMENTAL_FT
- setAcceptDrops(true);
+ setAcceptDrops(true);
#endif
- webPage_ = new QWebPage(this);
- webPage_->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
- if (Log::getLogLevel() == Log::debug) {
- webPage_->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
- }
- webView_->setPage(webPage_);
- connect(webPage_, SIGNAL(selectionChanged()), SLOT(copySelectionToClipboard()));
- connect(webPage_, SIGNAL(scrollRequested(int, int, const QRect&)), SLOT(handleScrollRequested(int, int, const QRect&)));
-
- viewReady_ = false;
- isAtBottom_ = true;
- resetView();
+ webPage_ = new QWebPage(this);
+ webPage_->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
+ if (Log::getLogLevel() == Log::debug) {
+ webPage_->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
+ }
+ webView_->setPage(webPage_);
+ connect(webPage_, SIGNAL(selectionChanged()), SLOT(copySelectionToClipboard()));
- jsBridge = new QtChatWindowJSBridge();
- addToJSEnvironment("chatwindow", jsBridge);
- connect(jsBridge, SIGNAL(buttonClicked(QString,QString,QString,QString,QString,QString)), this, SLOT(handleHTMLButtonClicked(QString,QString,QString,QString,QString,QString)));
+ viewReady_ = false;
+ isAtBottom_ = true;
+ resetView();
+ jsBridge = new QtChatWindowJSBridge();
+ addToJSEnvironment("chatwindow", jsBridge);
+ connect(jsBridge, SIGNAL(buttonClicked(QString,QString,QString,QString,QString,QString)), this, SLOT(handleHTMLButtonClicked(QString,QString,QString,QString,QString,QString)));
+ connect(jsBridge, SIGNAL(verticalScrollBarPositionChanged(double)), this, SLOT(handleVerticalScrollBarPositionChanged(double)));
}
QtWebKitChatView::~QtWebKitChatView() {
- delete jsBridge;
+ delete jsBridge;
}
void QtWebKitChatView::handleClearRequested() {
- QMessageBox messageBox(this);
- messageBox.setWindowTitle(tr("Clear log"));
- messageBox.setText(tr("You are about to clear the contents of your chat log."));
- messageBox.setInformativeText(tr("Are you sure?"));
- messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
- messageBox.setDefaultButton(QMessageBox::Yes);
- int button = messageBox.exec();
- if (button == QMessageBox::Yes) {
- logCleared();
- resetView();
- }
+ QMessageBox messageBox(this);
+ messageBox.setWindowTitle(tr("Clear log"));
+ messageBox.setText(tr("You are about to clear the contents of your chat log."));
+ messageBox.setInformativeText(tr("Are you sure?"));
+ messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+ messageBox.setDefaultButton(QMessageBox::Yes);
+ int button = messageBox.exec();
+ if (button == QMessageBox::Yes) {
+ logCleared();
+ resetView();
+ }
}
void QtWebKitChatView::handleKeyPressEvent(QKeyEvent* event) {
- webView_->keyPressEvent(event);
-}
-
-void QtWebKitChatView::addMessageBottom(boost::shared_ptr<ChatSnippet> snippet) {
- if (viewReady_) {
- addToDOM(snippet);
- } else {
- /* If this asserts, the previous queuing code was necessary and should be reinstated */
- assert(false);
- }
-}
-
-void QtWebKitChatView::addMessageTop(boost::shared_ptr<ChatSnippet> snippet) {
- // save scrollbar maximum value
- if (!topMessageAdded_) {
- scrollBarMaximum_ = webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical);
- }
- topMessageAdded_ = true;
-
- QWebElement continuationElement = firstElement_.findFirst("#insert");
-
- bool insert = snippet->getAppendToPrevious();
- bool fallback = continuationElement.isNull();
-
- boost::shared_ptr<ChatSnippet> newSnippet = (insert && fallback) ? snippet->getContinuationFallbackSnippet() : snippet;
- QWebElement newElement = snippetToDOM(newSnippet);
-
- if (insert && !fallback) {
- Q_ASSERT(!continuationElement.isNull());
- continuationElement.replace(newElement);
- } else {
- continuationElement.removeFromDocument();
- topInsertPoint_.prependOutside(newElement);
- }
-
- firstElement_ = newElement;
-
- if (lastElement_.isNull()) {
- lastElement_ = firstElement_;
- }
-
- if (fontSizeSteps_ != 0) {
- double size = 1.0 + 0.2 * fontSizeSteps_;
- QString sizeString(QString().setNum(size, 'g', 3) + "em");
- const QWebElementCollection spans = firstElement_.findAll("span.swift_resizable");
- Q_FOREACH (QWebElement span, spans) {
- span.setStyleProperty("font-size", sizeString);
- }
- }
-}
-
-QWebElement QtWebKitChatView::snippetToDOM(boost::shared_ptr<ChatSnippet> snippet) {
- QWebElement newElement = newInsertPoint_.clone();
- newElement.setInnerXml(snippet->getContent());
- Q_ASSERT(!newElement.isNull());
- return newElement;
-}
-
-void QtWebKitChatView::addToDOM(boost::shared_ptr<ChatSnippet> snippet) {
- //qDebug() << snippet->getContent();
- rememberScrolledToBottom();
- bool insert = snippet->getAppendToPrevious();
- QWebElement continuationElement = lastElement_.findFirst("#insert");
- bool fallback = insert && continuationElement.isNull();
- boost::shared_ptr<ChatSnippet> newSnippet = (insert && fallback) ? snippet->getContinuationFallbackSnippet() : snippet;
- QWebElement newElement = snippetToDOM(newSnippet);
- if (insert && !fallback) {
- Q_ASSERT(!continuationElement.isNull());
- continuationElement.replace(newElement);
- } else {
- continuationElement.removeFromDocument();
- newInsertPoint_.prependOutside(newElement);
- }
- lastElement_ = newElement;
- if (fontSizeSteps_ != 0) {
- double size = 1.0 + 0.2 * fontSizeSteps_;
- QString sizeString(QString().setNum(size, 'g', 3) + "em");
- const QWebElementCollection spans = lastElement_.findAll("span.swift_resizable");
- Q_FOREACH (QWebElement span, spans) {
- span.setStyleProperty("font-size", sizeString);
- }
- }
- //qDebug() << "-----------------";
- //qDebug() << webPage_->mainFrame()->toHtml();
+ webView_->keyPressEvent(event);
+}
+
+void QtWebKitChatView::addMessageBottom(std::shared_ptr<ChatSnippet> snippet) {
+ if (viewReady_) {
+ addToDOM(snippet);
+ } else {
+ /* If this asserts, the previous queuing code was necessary and should be reinstated */
+ assert(false);
+ }
+}
+
+void QtWebKitChatView::addMessageTop(std::shared_ptr<ChatSnippet> /* snippet */) {
+ // TODO: Implement this in a sensible manner later.
+ SWIFT_LOG(error) << "Not yet implemented!" << std::endl;
+}
+
+void QtWebKitChatView::addToDOM(std::shared_ptr<ChatSnippet> snippet) {
+ //qDebug() << snippet->getContent();
+ rememberScrolledToBottom();
+
+ QWebElement insertElement = webPage_->mainFrame()->findFirstElement("#insert");
+ assert(!insertElement.isNull());
+ insertElement.prependOutside(snippet->getContent());
+
+ //qDebug() << "-----------------";
+ //qDebug() << webPage_->mainFrame()->toHtml();
}
void QtWebKitChatView::addLastSeenLine() {
- /* if the line is added we should break the snippet */
- insertingLastLine_ = true;
- if (lineSeparator_.isNull()) {
- lineSeparator_ = newInsertPoint_.clone();
- lineSeparator_.setInnerXml(QString("<hr/>"));
- newInsertPoint_.prependOutside(lineSeparator_);
- }
- else {
- QWebElement lineSeparatorC = lineSeparator_.clone();
- lineSeparatorC.removeFromDocument();
- }
- newInsertPoint_.prependOutside(lineSeparator_);
+ // Remove a potentially existing unread bar.
+ QWebElement existingUnreadBar = webPage_->mainFrame()->findFirstElement("div.unread");
+ if (!existingUnreadBar.isNull()) {
+ existingUnreadBar.removeFromDocument();
+ }
+
+ QWebElement insertElement = webPage_->mainFrame()->findFirstElement("#insert");
+ insertElement.prependOutside(theme_->getUnread());
}
void QtWebKitChatView::replaceLastMessage(const QString& newMessage, const ChatWindow::TimestampBehaviour timestampBehaviour) {
- assert(viewReady_);
- rememberScrolledToBottom();
- assert(!lastElement_.isNull());
- QWebElement replace = lastElement_.findFirst("span.swift_message");
- assert(!replace.isNull());
- QString old = lastElement_.toOuterXml();
- replace.setInnerXml(ChatSnippet::escape(newMessage));
- if (timestampBehaviour == ChatWindow::UpdateTimestamp) {
- replace = lastElement_.findFirst("span.swift_time");
- assert(!replace.isNull());
- replace.setInnerXml(ChatSnippet::timeToEscapedString(QDateTime::currentDateTime()));
- }
+ rememberScrolledToBottom();
+ QWebElement insertElement = webPage_->mainFrame()->findFirstElement("#insert");
+ assert(!insertElement.isNull());
+
+ QWebElement lastMessageElement = insertElement.previousSibling();
+ QWebElement messageChild = lastMessageElement.findFirst("span.swift_message");
+ assert(!messageChild.isNull());
+ messageChild.setInnerXml(ChatSnippet::escape(newMessage));
+ if (timestampBehaviour == ChatWindow::UpdateTimestamp) {
+ QWebElement timeChild = lastMessageElement.findFirst("span.swift_time");
+ assert(!timeChild.isNull());
+ timeChild.setInnerXml(ChatSnippet::timeToEscapedString(QDateTime::currentDateTime()));
+ }
}
void QtWebKitChatView::replaceLastMessage(const QString& newMessage, const QString& note) {
- rememberScrolledToBottom();
- replaceLastMessage(newMessage, ChatWindow::KeepTimestamp);
- QWebElement replace = lastElement_.findFirst("span.swift_time");
- assert(!replace.isNull());
- replace.setInnerXml(ChatSnippet::escape(note));
+ rememberScrolledToBottom();
+ replaceLastMessage(newMessage, ChatWindow::KeepTimestamp);
+ QWebElement replace = lastElement_.findFirst("span.swift_time");
+ assert(!replace.isNull());
+ replace.setInnerXml(ChatSnippet::escape(note));
}
QString QtWebKitChatView::getLastSentMessage() {
- return lastElement_.toPlainText();
+ return lastElement_.toPlainText();
}
void QtWebKitChatView::addToJSEnvironment(const QString& name, QObject* obj) {
- webView_->page()->currentFrame()->addToJavaScriptWindowObject(name, obj);
+ webView_->page()->currentFrame()->addToJavaScriptWindowObject(name, obj);
}
void QtWebKitChatView::replaceMessage(const QString& newMessage, const QString& id, const QDateTime& editTime) {
- rememberScrolledToBottom();
- QWebElement message = document_.findFirst("#" + id);
- if (!message.isNull()) {
- QWebElement replaceContent = message.findFirst("span.swift_inner_message");
- assert(!replaceContent.isNull());
- QString old = replaceContent.toOuterXml();
- replaceContent.setInnerXml(ChatSnippet::escape(newMessage));
- QWebElement replaceTime = message.findFirst("span.swift_time");
- assert(!replaceTime.isNull());
- old = replaceTime.toOuterXml();
- replaceTime.setInnerXml(ChatSnippet::escape(tr("%1 edited").arg(ChatSnippet::timeToEscapedString(editTime))));
- }
- else {
- qWarning() << "Trying to replace element with id " << id << " but it's not there.";
- }
+ rememberScrolledToBottom();
+ QWebElement message = document_.findFirst("#" + id);
+ if (!message.isNull()) {
+ QWebElement replaceContent = message.findFirst("span.swift_inner_message");
+ assert(!replaceContent.isNull());
+ QString old = replaceContent.toOuterXml();
+ replaceContent.setInnerXml(ChatSnippet::escape(newMessage));
+ QWebElement replaceTime = message.findFirst("span.swift_time");
+ assert(!replaceTime.isNull());
+ old = replaceTime.toOuterXml();
+ replaceTime.setInnerXml(ChatSnippet::escape(tr("%1 edited").arg(ChatSnippet::timeToEscapedString(editTime))));
+ }
+ else {
+ qWarning() << "Trying to replace element with id " << id << " but it's not there.";
+ }
}
void QtWebKitChatView::showEmoticons(bool show) {
- showEmoticons_ = show;
- {
- const QWebElementCollection spans = document_.findAll("span.swift_emoticon_image");
- Q_FOREACH (QWebElement span, spans) {
- span.setStyleProperty("display", show ? "inline" : "none");
- }
- }
- {
- const QWebElementCollection spans = document_.findAll("span.swift_emoticon_text");
- Q_FOREACH (QWebElement span, spans) {
- span.setStyleProperty("display", show ? "none" : "inline");
- }
- }
+ showEmoticons_ = show;
+ {
+ const QWebElementCollection spans = document_.findAll("span.swift_emoticon_image");
+ Q_FOREACH (QWebElement span, spans) {
+ span.setStyleProperty("display", show ? "inline" : "none");
+ }
+ }
+ {
+ const QWebElementCollection spans = document_.findAll("span.swift_emoticon_text");
+ Q_FOREACH (QWebElement span, spans) {
+ span.setStyleProperty("display", show ? "none" : "inline");
+ }
+ }
}
void QtWebKitChatView::copySelectionToClipboard() {
- if (!webPage_->selectedText().isEmpty()) {
- webPage_->triggerAction(QWebPage::Copy);
- }
+ if (!webPage_->selectedText().isEmpty()) {
+ webPage_->triggerAction(QWebPage::Copy);
+ }
}
void QtWebKitChatView::setAckXML(const QString& id, const QString& xml) {
- QWebElement message = document_.findFirst("#" + id);
- /* Deliberately not asserting here, so that when we start expiring old messages it won't hit us */
- if (message.isNull()) return;
- QWebElement ackElement = message.findFirst("span.swift_ack");
- assert(!ackElement.isNull());
- ackElement.setInnerXml(xml);
+ QWebElement message = document_.findFirst("#" + id);
+ /* Deliberately not asserting here, so that when we start expiring old messages it won't hit us */
+ if (message.isNull()) return;
+ QWebElement ackElement = message.findFirst("span.swift_ack");
+ assert(!ackElement.isNull());
+ ackElement.setInnerXml(xml);
}
void QtWebKitChatView::setReceiptXML(const QString& id, const QString& xml) {
- QWebElement message = document_.findFirst("#" + id);
- if (message.isNull()) return;
- QWebElement receiptElement = message.findFirst("span.swift_receipt");
- assert(!receiptElement.isNull());
- receiptElement.setInnerXml(xml);
+ QWebElement message = document_.findFirst("#" + id);
+ if (message.isNull()) return;
+ QWebElement receiptElement = message.findFirst("span.swift_receipt");
+ assert(!receiptElement.isNull());
+ receiptElement.setInnerXml(xml);
}
void QtWebKitChatView::displayReceiptInfo(const QString& id, bool showIt) {
- QWebElement message = document_.findFirst("#" + id);
- if (message.isNull()) return;
- QWebElement receiptElement = message.findFirst("span.swift_receipt");
- assert(!receiptElement.isNull());
- receiptElement.setStyleProperty("display", showIt ? "inline" : "none");
+ QWebElement message = document_.findFirst("#" + id);
+ if (message.isNull()) return;
+ QWebElement receiptElement = message.findFirst("span.swift_receipt");
+ assert(!receiptElement.isNull());
+ receiptElement.setStyleProperty("display", showIt ? "inline" : "none");
}
void QtWebKitChatView::rememberScrolledToBottom() {
- isAtBottom_ = webPage_->mainFrame()->scrollBarValue(Qt::Vertical) >= (webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical) - 1);
+ if (webPage_) {
+ isAtBottom_ = webPage_->mainFrame()->scrollBarValue(Qt::Vertical) >= (webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical) - 1);
+ }
}
void QtWebKitChatView::scrollToBottom() {
- isAtBottom_ = true;
- webPage_->mainFrame()->setScrollBarValue(Qt::Vertical, webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical));
- webView_->update(); /* Work around redraw bug in some versions of Qt. */
+ isAtBottom_ = true;
+ webPage_->mainFrame()->setScrollBarValue(Qt::Vertical, webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical));
+ webView_->update(); /* Work around redraw bug in some versions of Qt. */
}
void QtWebKitChatView::handleFrameSizeChanged() {
- if (topMessageAdded_) {
- // adjust new scrollbar position
- int newMaximum = webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical);
- webPage_->mainFrame()->setScrollBarValue(Qt::Vertical, newMaximum - scrollBarMaximum_);
- topMessageAdded_ = false;
- }
+ if (topMessageAdded_) {
+ // adjust new scrollbar position
+ int newMaximum = webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical);
+ webPage_->mainFrame()->setScrollBarValue(Qt::Vertical, newMaximum - scrollBarMaximum_);
+ topMessageAdded_ = false;
+ }
- if (isAtBottom_ && !disableAutoScroll_) {
- scrollToBottom();
- }
+ if (isAtBottom_ && !disableAutoScroll_) {
+ scrollToBottom();
+ }
}
void QtWebKitChatView::handleLinkClicked(const QUrl& url) {
- QDesktopServices::openUrl(url);
+ QDesktopServices::openUrl(url);
}
void QtWebKitChatView::handleViewLoadFinished(bool ok) {
- Q_ASSERT(ok);
- viewReady_ = true;
+ Q_ASSERT(ok);
+ viewReady_ = true;
}
void QtWebKitChatView::increaseFontSize(int numSteps) {
- //qDebug() << "Increasing";
- fontSizeSteps_ += numSteps;
- emit fontResized(fontSizeSteps_);
+ //qDebug() << "Increasing";
+ fontSizeSteps_ += numSteps;
+ emit fontResized(fontSizeSteps_);
}
void QtWebKitChatView::decreaseFontSize() {
- fontSizeSteps_--;
- if (fontSizeSteps_ < 0) {
- fontSizeSteps_ = 0;
- }
- emit fontResized(fontSizeSteps_);
+ fontSizeSteps_--;
+ if (fontSizeSteps_ < 0) {
+ fontSizeSteps_ = 0;
+ }
+ emit fontResized(fontSizeSteps_);
}
void QtWebKitChatView::resizeFont(int fontSizeSteps) {
- fontSizeSteps_ = fontSizeSteps;
- double size = 1.0 + 0.2 * fontSizeSteps_;
- QString sizeString(QString().setNum(size, 'g', 3) + "em");
- //qDebug() << "Setting to " << sizeString;
- const QWebElementCollection spans = document_.findAll("span.swift_resizable");
- Q_FOREACH (QWebElement span, spans) {
- span.setStyleProperty("font-size", sizeString);
- }
- webView_->setFontSizeIsMinimal(size == 1.0);
+ fontSizeSteps_ = fontSizeSteps;
+ double size = minimalFontScaling + 0.2 * fontSizeSteps_;
+ QString sizeString(QString().setNum(size, 'g', 3) + "em");
+
+ // Set the font size in the <style id="text-resize-style"> element in the theme <head> element.
+ QWebElement resizableTextStyle = document_.findFirst("style#text-resize-style");
+ assert(!resizableTextStyle.isNull());
+ resizableTextStyle.setInnerXml(QString("span.swift_resizable { font-size: %1;}").arg(sizeString));
+ webView_->setFontSizeIsMinimal(size == minimalFontScaling);
}
void QtWebKitChatView::resetView() {
- lastElement_ = QWebElement();
- firstElement_ = lastElement_;
- topMessageAdded_ = false;
- scrollBarMaximum_ = 0;
- QString pageHTML = theme_->getTemplate();
- pageHTML.replace("==bodyBackground==", "background-color:#e3e3e3");
- pageHTML.replace(pageHTML.indexOf("%@"), 2, theme_->getBase());
- if (pageHTML.count("%@") > 3) {
- pageHTML.replace(pageHTML.indexOf("%@"), 2, theme_->getMainCSS());
- }
- pageHTML.replace(pageHTML.indexOf("%@"), 2, "Variants/Blue on Green.css");
- pageHTML.replace(pageHTML.indexOf("%@"), 2, ""/*headerSnippet.getContent()*/);
- pageHTML.replace(pageHTML.indexOf("%@"), 2, ""/*footerSnippet.getContent()*/);
- QEventLoop syncLoop;
- connect(webView_, SIGNAL(loadFinished(bool)), &syncLoop, SLOT(quit()));
- webPage_->mainFrame()->setHtml(pageHTML);
- while (!viewReady_) {
- QTimer t;
- t.setSingleShot(true);
- connect(&t, SIGNAL(timeout()), &syncLoop, SLOT(quit()));
- t.start(50);
- syncLoop.exec();
- }
- document_ = webPage_->mainFrame()->documentElement();
-
- resetTopInsertPoint();
- QWebElement chatElement = document_.findFirst("#Chat");
- newInsertPoint_ = chatElement.clone();
- newInsertPoint_.setOuterXml("<div id='swift_insert'/>");
- chatElement.appendInside(newInsertPoint_);
- Q_ASSERT(!newInsertPoint_.isNull());
-
- scrollToBottom();
-
- connect(webPage_->mainFrame(), SIGNAL(contentsSizeChanged(const QSize&)), this, SLOT(handleFrameSizeChanged()), Qt::UniqueConnection);
+ lastElement_ = QWebElement();
+ firstElement_ = lastElement_;
+ topMessageAdded_ = false;
+ scrollBarMaximum_ = 0;
+ QString pageHTML = theme_->getTemplate();
+ pageHTML.replace("==bodyBackground==", "background-color:#e3e3e3");
+ pageHTML.replace(pageHTML.indexOf("%@"), 2, theme_->getBase());
+ if (pageHTML.count("%@") > 3) {
+ pageHTML.replace(pageHTML.indexOf("%@"), 2, theme_->getMainCSS());
+ }
+ pageHTML.replace(pageHTML.indexOf("%@"), 2, "Variants/Blue on Green.css");
+ pageHTML.replace(pageHTML.indexOf("%@"), 2, ""/*headerSnippet.getContent()*/);
+ pageHTML.replace(pageHTML.indexOf("%@"), 2, ""/*footerSnippet.getContent()*/);
+ QEventLoop syncLoop;
+ connect(webView_, SIGNAL(loadFinished(bool)), &syncLoop, SLOT(quit()));
+ webPage_->mainFrame()->setHtml(pageHTML);
+ while (!viewReady_) {
+ syncLoop.processEvents(QEventLoop::AllEvents, 50);
+ }
+ document_ = webPage_->mainFrame()->documentElement();
+
+ scrollToBottom();
+
+ connect(webPage_->mainFrame(), SIGNAL(contentsSizeChanged(const QSize&)), this, SLOT(handleFrameSizeChanged()), Qt::UniqueConnection);
+
+ // Hooking up to scroll bar update, because Qt does not provide a way to retrieve accurate scroll bar updates from C++ directly.
+ QWebElement body = document_.findFirst("body");
+ assert(!body.isNull());
+ body.setAttribute("onscroll", "chatwindow.verticalScrollBarPositionChanged(document.body.scrollTop / (document.body.scrollHeight - window.innerHeight))");
+
+ // Adjust web view default 96 DPI setting to screen DPI.
+ // For more information see https://webkit.org/blog/57/css-units/
+ webView_->setZoomFactor(QApplication::desktop()->screen()->logicalDpiX() / 96.0);
+
+ body.setStyleProperty("font-size", QString("%1pt").arg(QApplication::font().pointSize()));
}
static QWebElement findElementWithID(QWebElement document, QString elementName, QString id) {
- QWebElementCollection elements = document.findAll(elementName);
- Q_FOREACH(QWebElement element, elements) {
- if (element.attribute("id") == id) {
- return element;
- }
- }
- return QWebElement();
+ QWebElementCollection elements = document.findAll(elementName);
+ Q_FOREACH(QWebElement element, elements) {
+ if (element.attribute("id") == id) {
+ return element;
+ }
+ }
+ return QWebElement();
}
void QtWebKitChatView::setFileTransferProgress(QString id, const int percentageDone) {
- rememberScrolledToBottom();
- QWebElement ftElement = findElementWithID(document_, "div", id);
- if (ftElement.isNull()) {
- SWIFT_LOG(debug) << "Tried to access FT UI via invalid id!" << std::endl;
- return;
- }
- QWebElement progressBar = ftElement.findFirst("div.progressbar");
- progressBar.setStyleProperty("width", QString::number(percentageDone) + "%");
+ rememberScrolledToBottom();
+ QWebElement ftElement = findElementWithID(document_, "div", id);
+ if (ftElement.isNull()) {
+ SWIFT_LOG(debug) << "Tried to access FT UI via invalid id!" << std::endl;
+ return;
+ }
+ QWebElement progressBar = ftElement.findFirst("div.progressbar");
+ progressBar.setStyleProperty("width", QString::number(percentageDone) + "%");
- QWebElement progressBarValue = ftElement.findFirst("div.progressbar-value");
- progressBarValue.setInnerXml(QString::number(percentageDone) + " %");
+ QWebElement progressBarValue = ftElement.findFirst("div.progressbar-value");
+ progressBarValue.setInnerXml(QString::number(percentageDone) + " %");
}
void QtWebKitChatView::setFileTransferStatus(QString id, const ChatWindow::FileTransferState state, const QString& /* msg */) {
- rememberScrolledToBottom();
- QWebElement ftElement = findElementWithID(document_, "div", id);
- if (ftElement.isNull()) {
- SWIFT_LOG(debug) << "Tried to access FT UI via invalid id! id = " << Q2PSTRING(id) << std::endl;
- return;
- }
-
- QString newInnerHTML = "";
- if (state == ChatWindow::Initialisation) {
- QWebElement filenameSizeDescriptionElement = ftElement.parent().firstChild();
- QString description = QtUtilities::htmlEscape(descriptions_[id]);
- if (!description.isEmpty()) {
- filenameSizeDescriptionElement.prependOutside(QString(" \"%1\"").arg(description));
- }
- newInnerHTML = tr("Preparing to transfer.") + "<br/>" +
- buildChatWindowButton(tr("Cancel"), ButtonFileTransferCancel, id);
- }
- else if (state == ChatWindow::WaitingForAccept) {
- newInnerHTML = tr("Waiting for other side to accept the transfer.") + "<br/>" +
- buildChatWindowButton(tr("Cancel"), ButtonFileTransferCancel, id);
- }
- else if (state == ChatWindow::Negotiating) {
- // replace with text "Negotiaging" + Cancel button
- newInnerHTML = tr("Negotiating...") + "<br/>" +
- buildChatWindowButton(tr("Cancel"), ButtonFileTransferCancel, id);
- }
- else if (state == ChatWindow::Transferring) {
- // progress bar + Cancel Button
- newInnerHTML = "<div style=\"position: relative; width: 90%; height: 20px; border: 2px solid grey; -webkit-border-radius: 10px;\">"
- "<div class=\"progressbar\" style=\"width: 0%; height: 100%; background: #AAA; -webkit-border-radius: 6px;\">"
- "<div class=\"progressbar-value\" style=\"position: absolute; top: 0px; left: 0px; width: 100%; text-align: center; padding-top: 2px;\">"
- "0%"
- "</div>"
- "</div>"
- "</div>" +
- buildChatWindowButton(tr("Cancel"), ButtonFileTransferCancel, id);
- }
- else if (state == ChatWindow::Canceled) {
- newInnerHTML = tr("Transfer has been canceled!");
- }
- else if (state == ChatWindow::Finished) {
- // text "Successful transfer"
- newInnerHTML = tr("Transfer completed successfully." ) + " " + buildChatWindowButton(tr("Open file"), ButtonFileTransferOpenFile, id, filePaths_[id]);
- filePaths_.erase(id);
- }
- else if (state == ChatWindow::FTFailed) {
- newInnerHTML = tr("Transfer failed.");
- }
-
- ftElement.setInnerXml(newInnerHTML);
+ rememberScrolledToBottom();
+ QWebElement ftElement = findElementWithID(document_, "div", id);
+ if (ftElement.isNull()) {
+ SWIFT_LOG(debug) << "Tried to access FT UI via invalid id! id = " << Q2PSTRING(id) << std::endl;
+ return;
+ }
+
+ QString newInnerHTML = "";
+ if (state == ChatWindow::Initialisation) {
+ QWebElement filenameSizeDescriptionElement = ftElement.parent().firstChild();
+ QString description = QtUtilities::htmlEscape(descriptions_[id]);
+ if (!description.isEmpty()) {
+ filenameSizeDescriptionElement.prependOutside(QString(" \"%1\"").arg(description));
+ }
+ newInnerHTML = tr("Preparing to transfer.") + "<br/>" +
+ buildChatWindowButton(tr("Cancel"), ButtonFileTransferCancel, id);
+ }
+ else if (state == ChatWindow::WaitingForAccept) {
+ newInnerHTML = tr("Waiting for other side to accept the transfer.") + "<br/>" +
+ buildChatWindowButton(tr("Cancel"), ButtonFileTransferCancel, id);
+ }
+ else if (state == ChatWindow::Negotiating) {
+ // replace with text "Negotiaging" + Cancel button
+ newInnerHTML = tr("Negotiating...") + "<br/>" +
+ buildChatWindowButton(tr("Cancel"), ButtonFileTransferCancel, id);
+ }
+ else if (state == ChatWindow::Transferring) {
+ // progress bar + Cancel Button
+ newInnerHTML = "<div style=\"position: relative; width: 90%; height: 20px; border: 2px solid grey; -webkit-border-radius: 10px;\">"
+ "<div class=\"progressbar\" style=\"width: 0%; height: 100%; background: #AAA; -webkit-border-radius: 6px;\">"
+ "<div class=\"progressbar-value\" style=\"position: absolute; top: 0px; left: 0px; width: 100%; text-align: center; padding-top: 2px;\">"
+ "0%"
+ "</div>"
+ "</div>"
+ "</div>" +
+ buildChatWindowButton(tr("Cancel"), ButtonFileTransferCancel, id);
+ }
+ else if (state == ChatWindow::Canceled) {
+ newInnerHTML = tr("Transfer has been canceled!");
+ }
+ else if (state == ChatWindow::Finished) {
+ // text "Successful transfer"
+ newInnerHTML = tr("Transfer completed successfully." ) + " " + buildChatWindowButton(tr("Open file"), ButtonFileTransferOpenFile, id, filePaths_[id]);
+ filePaths_.erase(id);
+ }
+ else if (state == ChatWindow::FTFailed) {
+ newInnerHTML = tr("Transfer failed.");
+ }
+
+ ftElement.setInnerXml(newInnerHTML);
}
void QtWebKitChatView::setWhiteboardSessionStatus(QString id, const ChatWindow::WhiteboardSessionState state) {
- QWebElement divElement = findElementWithID(document_, "div", id);
- QString newInnerHTML;
- if (state == ChatWindow::WhiteboardAccepted) {
- newInnerHTML = tr("Started whiteboard chat") + "<br/>" + buildChatWindowButton(tr("Show whiteboard"), ButtonWhiteboardShowWindow, id);
- } else if (state == ChatWindow::WhiteboardTerminated) {
- newInnerHTML = tr("Whiteboard chat has been canceled");
- } else if (state == ChatWindow::WhiteboardRejected) {
- newInnerHTML = tr("Whiteboard chat request has been rejected");
- }
- divElement.setInnerXml(newInnerHTML);
+ QWebElement divElement = findElementWithID(document_, "div", id);
+ QString newInnerHTML;
+ if (state == ChatWindow::WhiteboardAccepted) {
+ newInnerHTML = tr("Started whiteboard chat") + "<br/>" + buildChatWindowButton(tr("Show whiteboard"), ButtonWhiteboardShowWindow, id);
+ } else if (state == ChatWindow::WhiteboardTerminated) {
+ newInnerHTML = tr("Whiteboard chat has been canceled");
+ } else if (state == ChatWindow::WhiteboardRejected) {
+ newInnerHTML = tr("Whiteboard chat request has been rejected");
+ }
+ divElement.setInnerXml(newInnerHTML);
}
void QtWebKitChatView::setMUCInvitationJoined(QString id) {
- QWebElement divElement = findElementWithID(document_, "div", id);
- QWebElement buttonElement = findElementWithID(divElement, "input", "mucinvite");
- if (!buttonElement.isNull()) {
- buttonElement.setAttribute("value", tr("Return to room"));
- }
+ QWebElement divElement = findElementWithID(document_, "div", id);
+ QWebElement buttonElement = findElementWithID(divElement, "input", "mucinvite");
+ if (!buttonElement.isNull()) {
+ buttonElement.setAttribute("value", tr("Return to room"));
+ }
}
void QtWebKitChatView::askDesktopToOpenFile(const QString& filename) {
- QFileInfo fileInfo(filename);
- if (fileInfo.exists() && fileInfo.isFile()) {
- QDesktopServices::openUrl(QUrl::fromLocalFile(filename));
- }
-}
-
-void QtWebKitChatView::handleScrollRequested(int, int dy, const QRect&) {
- rememberScrolledToBottom();
-
- int pos = webPage_->mainFrame()->scrollBarValue(Qt::Vertical) - dy;
- emit scrollRequested(pos);
-
- if (pos == 0) {
- emit scrollReachedTop();
- }
- else if (pos == webPage_->mainFrame()->scrollBarMaximum(Qt::Vertical)) {
- emit scrollReachedBottom();
- }
+ QFileInfo fileInfo(filename);
+ if (fileInfo.exists() && fileInfo.isFile()) {
+ QDesktopServices::openUrl(QUrl::fromLocalFile(filename));
+ }
}
int QtWebKitChatView::getSnippetPositionByDate(const QDate& date) {
- QWebElement message = webPage_->mainFrame()->documentElement().findFirst(".date" + date.toString(Qt::ISODate));
+ QWebElement message = webPage_->mainFrame()->documentElement().findFirst(".date" + date.toString(Qt::ISODate));
- return message.geometry().top();
+ return message.geometry().top();
}
void QtWebKitChatView::resetTopInsertPoint() {
- QWebElement continuationElement = firstElement_.findFirst("#insert");
- continuationElement.removeFromDocument();
- firstElement_ = QWebElement();
-
- topInsertPoint_.removeFromDocument();
- QWebElement chatElement = document_.findFirst("#Chat");
- topInsertPoint_ = chatElement.clone();
- topInsertPoint_.setOuterXml("<div id='swift_insert'/>");
- chatElement.prependInside(topInsertPoint_);
+ // TODO: Implement or refactor later.
+ SWIFT_LOG(error) << "Not yet implemented!" << std::endl;
}
-
std::string QtWebKitChatView::addMessage(
- const ChatWindow::ChatMessage& message,
- const std::string& senderName,
- bool senderIsSelf,
- boost::shared_ptr<SecurityLabel> label,
- const std::string& avatarPath,
- const boost::posix_time::ptime& time,
- const HighlightAction& highlight) {
- return addMessage(chatMessageToHTML(message), senderName, senderIsSelf, label, avatarPath, "", time, highlight, ChatSnippet::getDirection(message));
+ const ChatWindow::ChatMessage& message,
+ const std::string& senderName,
+ bool senderIsSelf,
+ std::shared_ptr<SecurityLabel> label,
+ const std::string& avatarPath,
+ const boost::posix_time::ptime& time) {
+ return addMessage(chatMessageToHTML(message), senderName, senderIsSelf, label, avatarPath, "", time, message.getFullMessageHighlightAction(), ChatSnippet::getDirection(message));
}
QString QtWebKitChatView::getHighlightSpanStart(const std::string& text, const std::string& background) {
- QString ecsapeColor = QtUtilities::htmlEscape(P2QSTRING(text));
- QString escapeBackground = QtUtilities::htmlEscape(P2QSTRING(background));
- if (ecsapeColor.isEmpty()) {
- ecsapeColor = "black";
- }
- if (escapeBackground.isEmpty()) {
- escapeBackground = "yellow";
- }
- return QString("<span style=\"color: %1; background: %2\">").arg(ecsapeColor).arg(escapeBackground);
+ QString ecsapeColor = QtUtilities::htmlEscape(P2QSTRING(text));
+ QString escapeBackground = QtUtilities::htmlEscape(P2QSTRING(background));
+ if (ecsapeColor.isEmpty()) {
+ ecsapeColor = "black";
+ }
+ if (escapeBackground.isEmpty()) {
+ escapeBackground = "yellow";
+ }
+ return QString("<span style=\"color: %1; background: %2\">").arg(ecsapeColor).arg(escapeBackground);
}
QString QtWebKitChatView::getHighlightSpanStart(const HighlightAction& highlight) {
- return getHighlightSpanStart(highlight.getTextColor(), highlight.getTextBackground());
+ return getHighlightSpanStart(highlight.getTextColor(), highlight.getTextBackground());
}
QString QtWebKitChatView::chatMessageToHTML(const ChatWindow::ChatMessage& message) {
- QString result;
- foreach (boost::shared_ptr<ChatWindow::ChatMessagePart> part, message.getParts()) {
- boost::shared_ptr<ChatWindow::ChatTextMessagePart> textPart;
- boost::shared_ptr<ChatWindow::ChatURIMessagePart> uriPart;
- boost::shared_ptr<ChatWindow::ChatEmoticonMessagePart> emoticonPart;
- boost::shared_ptr<ChatWindow::ChatHighlightingMessagePart> highlightPart;
-
- if ((textPart = boost::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(part))) {
- QString text = QtUtilities::htmlEscape(P2QSTRING(textPart->text));
- text.replace("\n","<br/>");
- result += text;
- continue;
- }
- if ((uriPart = boost::dynamic_pointer_cast<ChatWindow::ChatURIMessagePart>(part))) {
- QString uri = QtUtilities::htmlEscape(P2QSTRING(uriPart->target));
- result += "<a href='" + uri + "' >" + uri + "</a>";
- continue;
- }
- if ((emoticonPart = boost::dynamic_pointer_cast<ChatWindow::ChatEmoticonMessagePart>(part))) {
- QString textStyle = showEmoticons_ ? "style='display:none'" : "";
- QString imageStyle = showEmoticons_ ? "" : "style='display:none'";
- result += "<span class='swift_emoticon_image' " + imageStyle + "><img src='" + P2QSTRING(emoticonPart->imagePath) + "'/></span><span class='swift_emoticon_text' " + textStyle + ">" + QtUtilities::htmlEscape(P2QSTRING(emoticonPart->alternativeText)) + "</span>";
- continue;
- }
- if ((highlightPart = boost::dynamic_pointer_cast<ChatWindow::ChatHighlightingMessagePart>(part))) {
- QString spanStart = getHighlightSpanStart(highlightPart->foregroundColor, highlightPart->backgroundColor);
- result += spanStart + QtUtilities::htmlEscape(P2QSTRING(highlightPart->text)) + "</span>";
- continue;
- }
-
- }
- return result;
+ QString result;
+ for (const auto& part : message.getParts()) {
+ std::shared_ptr<ChatWindow::ChatTextMessagePart> textPart;
+ std::shared_ptr<ChatWindow::ChatURIMessagePart> uriPart;
+ std::shared_ptr<ChatWindow::ChatEmoticonMessagePart> emoticonPart;
+ std::shared_ptr<ChatWindow::ChatHighlightingMessagePart> highlightPart;
+
+ if ((textPart = std::dynamic_pointer_cast<ChatWindow::ChatTextMessagePart>(part))) {
+ QString text = QtUtilities::htmlEscape(P2QSTRING(textPart->text));
+ text.replace("\n","<br/>");
+ result += text;
+ continue;
+ }
+ if ((uriPart = std::dynamic_pointer_cast<ChatWindow::ChatURIMessagePart>(part))) {
+ QString uri = QtUtilities::htmlEscape(P2QSTRING(uriPart->target));
+ result += "<a href='" + uri + "' >" + uri + "</a>";
+ continue;
+ }
+ if ((emoticonPart = std::dynamic_pointer_cast<ChatWindow::ChatEmoticonMessagePart>(part))) {
+ QString textStyle = showEmoticons_ ? "style='display:none'" : "";
+ QString imageStyle = showEmoticons_ ? "" : "style='display:none'";
+ result += "<span class='swift_emoticon_image' " + imageStyle + "><img src='" + P2QSTRING(emoticonPart->imagePath) + "'/></span><span class='swift_emoticon_text' " + textStyle + ">" + QtUtilities::htmlEscape(P2QSTRING(emoticonPart->alternativeText)) + "</span>";
+ continue;
+ }
+ if ((highlightPart = std::dynamic_pointer_cast<ChatWindow::ChatHighlightingMessagePart>(part))) {
+ QString spanStart = getHighlightSpanStart(highlightPart->action.getTextColor(), highlightPart->action.getTextBackground());
+ result += spanStart + QtUtilities::htmlEscape(P2QSTRING(highlightPart->text)) + "</span>";
+ continue;
+ }
+
+ }
+ return result;
}
std::string QtWebKitChatView::addMessage(
- const QString& message,
- const std::string& senderName,
- bool senderIsSelf,
- boost::shared_ptr<SecurityLabel> label,
- const std::string& avatarPath,
- const QString& style,
- const boost::posix_time::ptime& time,
- const HighlightAction& highlight,
- ChatSnippet::Direction direction) {
+ const QString& message,
+ const std::string& senderName,
+ bool senderIsSelf,
+ std::shared_ptr<SecurityLabel> label,
+ const std::string& avatarPath,
+ const QString& style,
+ const boost::posix_time::ptime& time,
+ const HighlightAction& highlight,
+ ChatSnippet::Direction direction) {
- QString scaledAvatarPath = QtScaledAvatarCache(32).getScaledAvatarPath(avatarPath.c_str());
+ QString scaledAvatarPath = QtScaledAvatarCache(32).getScaledAvatarPath(avatarPath.c_str());
- QString htmlString;
- if (label) {
- htmlString = QString("<span style=\"border: thin dashed grey; padding-left: .5em; padding-right: .5em; color: %1; background-color: %2; font-size: 90%; margin-right: .5em; \" class='swift_label'>").arg(QtUtilities::htmlEscape(P2QSTRING(label->getForegroundColor()))).arg(QtUtilities::htmlEscape(P2QSTRING(label->getBackgroundColor())));
- htmlString += QString("%1</span> ").arg(QtUtilities::htmlEscape(P2QSTRING(label->getDisplayMarking())));
- }
+ QString htmlString;
+ if (label) {
+ htmlString = QString("<span style=\"border: thin dashed grey; padding-left: .5em; padding-right: .5em; color: %1; background-color: %2; font-size: 90%; margin-right: .5em; \" class='swift_label'>").arg(QtUtilities::htmlEscape(P2QSTRING(label->getForegroundColor()))).arg(QtUtilities::htmlEscape(P2QSTRING(label->getBackgroundColor())));
+ htmlString += QString("%1</span> ").arg(QtUtilities::htmlEscape(P2QSTRING(label->getDisplayMarking())));
+ }
- QString styleSpanStart = style == "" ? "" : "<span style=\"" + style + "\">";
- QString styleSpanEnd = style == "" ? "" : "</span>";
+ QString styleSpanStart = style == "" ? "" : "<span style=\"" + style + "\">";
+ QString styleSpanEnd = style == "" ? "" : "</span>";
- bool highlightWholeMessage = highlight.highlightWholeMessage() && highlight.getTextBackground() != "" && highlight.getTextColor() != "";
- QString highlightSpanStart = highlightWholeMessage ? getHighlightSpanStart(highlight) : "";
- QString highlightSpanEnd = highlightWholeMessage ? "</span>" : "";
- htmlString += "<span class='swift_inner_message'>" + styleSpanStart + highlightSpanStart + message + highlightSpanEnd + styleSpanEnd + "</span>" ;
+ bool highlightWholeMessage = highlight.highlightWholeMessage() && highlight.getTextBackground() != "" && highlight.getTextColor() != "";
+ QString highlightSpanStart = highlightWholeMessage ? getHighlightSpanStart(highlight) : "";
+ QString highlightSpanEnd = highlightWholeMessage ? "</span>" : "";
+ htmlString += "<span class='swift_inner_message'>" + styleSpanStart + highlightSpanStart + message + highlightSpanEnd + styleSpanEnd + "</span>" ;
- bool appendToPrevious = appendToPreviousCheck(PreviousMessageWasMessage, senderName, senderIsSelf);
+ bool appendToPrevious = appendToPreviousCheck(PreviousMessageWasMessage, senderName, senderIsSelf);
- QString qAvatarPath = scaledAvatarPath.isEmpty() ? "qrc:/icons/avatar.png" : QUrl::fromLocalFile(scaledAvatarPath).toEncoded();
- std::string id = "id" + boost::lexical_cast<std::string>(idCounter_++);
- addMessageBottom(boost::make_shared<MessageSnippet>(htmlString, QtUtilities::htmlEscape(P2QSTRING(senderName)), B2QDATE(time), qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id), direction));
+ QString qAvatarPath = scaledAvatarPath.isEmpty() ? "qrc:/icons/avatar.svg" : QUrl::fromLocalFile(scaledAvatarPath).toEncoded();
+ std::string id = "id" + boost::lexical_cast<std::string>(idCounter_++);
+ addMessageBottom(std::make_shared<MessageSnippet>(htmlString, QtUtilities::htmlEscape(P2QSTRING(senderName)), B2QDATE(time), qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id), direction));
- previousMessageWasSelf_ = senderIsSelf;
- previousSenderName_ = P2QSTRING(senderName);
- previousMessageKind_ = PreviousMessageWasMessage;
- return id;
+ previousMessageWasSelf_ = senderIsSelf;
+ previousSenderName_ = P2QSTRING(senderName);
+ previousMessageKind_ = PreviousMessageWasMessage;
+ return id;
}
-std::string QtWebKitChatView::addAction(const ChatWindow::ChatMessage& message, const std::string &senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
- return addMessage(" *" + chatMessageToHTML(message) + "*", senderName, senderIsSelf, label, avatarPath, "font-style:italic ", time, highlight, ChatSnippet::getDirection(message));
+std::string QtWebKitChatView::addAction(const ChatWindow::ChatMessage& message, const std::string &senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) {
+ return addMessage(" *" + chatMessageToHTML(message) + "*", senderName, senderIsSelf, label, avatarPath, "font-style:italic ", time, message.getFullMessageHighlightAction(), ChatSnippet::getDirection(message));
}
static QString encodeButtonArgument(const QString& str) {
- return QtUtilities::htmlEscape(P2QSTRING(Base64::encode(createByteArray(Q2PSTRING(str)))));
+ return QtUtilities::htmlEscape(P2QSTRING(Base64::encode(createByteArray(Q2PSTRING(str)))));
}
static QString decodeButtonArgument(const QString& str) {
- return P2QSTRING(byteArrayToString(Base64::decode(Q2PSTRING(str))));
+ return P2QSTRING(byteArrayToString(Base64::decode(Q2PSTRING(str))));
}
QString QtWebKitChatView::buildChatWindowButton(const QString& name, const QString& id, const QString& arg1, const QString& arg2, const QString& arg3, const QString& arg4, const QString& arg5) {
- QRegExp regex("[A-Za-z][A-Za-z0-9\\-\\_]+");
- Q_ASSERT(regex.exactMatch(id));
- QString html = QString("<input id='%2' type='submit' value='%1' onclick='chatwindow.buttonClicked(\"%2\", \"%3\", \"%4\", \"%5\", \"%6\", \"%7\");' />").arg(name).arg(id).arg(encodeButtonArgument(arg1)).arg(encodeButtonArgument(arg2)).arg(encodeButtonArgument(arg3)).arg(encodeButtonArgument(arg4)).arg(encodeButtonArgument(arg5));
- return html;
+ QRegExp regex("[A-Za-z][A-Za-z0-9\\-\\_]+");
+ Q_ASSERT(regex.exactMatch(id));
+ QString html = QString("<input id='%2' type='submit' value='%1' onclick='chatwindow.buttonClicked(\"%2\", \"%3\", \"%4\", \"%5\", \"%6\", \"%7\");' />").arg(name).arg(id).arg(encodeButtonArgument(arg1)).arg(encodeButtonArgument(arg2)).arg(encodeButtonArgument(arg3)).arg(encodeButtonArgument(arg4)).arg(encodeButtonArgument(arg5));
+ return html;
+}
+
+void QtWebKitChatView::resizeEvent(QResizeEvent* event) {
+ // This code ensures that if the user is scrolled all to the bottom of a chat view,
+ // the view stays scrolled to the bottom if the view is resized or if the message
+ // input widget becomes multi line.
+ if (isAtBottom_) {
+ scrollToBottom();
+ }
+ QWidget::resizeEvent(event);
}
std::string QtWebKitChatView::addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes, const std::string& description) {
- SWIFT_LOG(debug) << "addFileTransfer" << std::endl;
- QString ft_id = QString("ft%1").arg(P2QSTRING(boost::lexical_cast<std::string>(idCounter_++)));
-
- QString actionText;
- QString htmlString;
- QString formattedFileSize = P2QSTRING(formatSize(sizeInBytes));
- QString sanitizedFileName = QtUtilities::htmlEscape(P2QSTRING(filename));
- QString sanitizedDescription = QtUtilities::htmlEscape(P2QSTRING(description));
- if (senderIsSelf) {
- // outgoing
- filePaths_[ft_id] = sanitizedFileName;
- actionText = tr("Send file: %1 (%2)").arg(sanitizedFileName).arg(formattedFileSize);
- htmlString = actionText + " <br/>" +
- "<div id='" + ft_id + "'>" +
- buildChatWindowButton(tr("Cancel"), ButtonFileTransferCancel, ft_id) +
- buildChatWindowButton(tr("Set Description"), ButtonFileTransferSetDescription, ft_id) +
- buildChatWindowButton(tr("Send"), ButtonFileTransferSendRequest, ft_id) +
- "</div>";
- } else {
- // incoming
- actionText = tr("Receiving file: %1 (%2)").arg(sanitizedFileName).arg(formattedFileSize);
- if (!sanitizedDescription.isEmpty()) {
- actionText += QString(" \"%1\"").arg(sanitizedDescription);
- }
- htmlString = actionText + " <br/>" +
- "<div id='" + ft_id + "'>" +
- buildChatWindowButton(tr("Cancel"), ButtonFileTransferCancel, ft_id) +
- buildChatWindowButton(tr("Accept"), ButtonFileTransferAcceptRequest, ft_id, P2QSTRING(filename)) +
- "</div>";
- }
-
- //addMessage(message, senderName, senderIsSelf, boost::shared_ptr<SecurityLabel>(), "", boost::posix_time::second_clock::local_time());
-
- bool appendToPrevious = appendToPreviousCheck(PreviousMessageWasFileTransfer, senderName, senderIsSelf);
-
- QString qAvatarPath = "qrc:/icons/avatar.png";
- std::string id = "ftmessage" + boost::lexical_cast<std::string>(idCounter_++);
- addMessageBottom(boost::make_shared<MessageSnippet>(htmlString, QtUtilities::htmlEscape(P2QSTRING(senderName)), B2QDATE(boost::posix_time::second_clock::universal_time()), qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id), ChatSnippet::getDirection(actionText)));
-
- previousMessageWasSelf_ = senderIsSelf;
- previousSenderName_ = P2QSTRING(senderName);
- previousMessageKind_ = PreviousMessageWasFileTransfer;
- return Q2PSTRING(ft_id);
+ SWIFT_LOG(debug) << "addFileTransfer" << std::endl;
+ QString ft_id = QString("ft%1").arg(P2QSTRING(boost::lexical_cast<std::string>(idCounter_++)));
+
+ QString actionText;
+ QString htmlString;
+ QString formattedFileSize = P2QSTRING(formatSize(sizeInBytes));
+ QString sanitizedFileName = QtUtilities::htmlEscape(P2QSTRING(filename));
+ QString sanitizedDescription = QtUtilities::htmlEscape(P2QSTRING(description));
+ if (senderIsSelf) {
+ // outgoing
+ filePaths_[ft_id] = sanitizedFileName;
+ actionText = tr("Send file: %1 (%2)").arg(sanitizedFileName).arg(formattedFileSize);
+ htmlString = actionText + " <br/>" +
+ "<div id='" + ft_id + "'>" +
+ buildChatWindowButton(tr("Cancel"), ButtonFileTransferCancel, ft_id) +
+ buildChatWindowButton(tr("Set Description"), ButtonFileTransferSetDescription, ft_id) +
+ buildChatWindowButton(tr("Send"), ButtonFileTransferSendRequest, ft_id) +
+ "</div>";
+ } else {
+ // incoming
+ actionText = tr("Receiving file: %1 (%2)").arg(sanitizedFileName).arg(formattedFileSize);
+ if (!sanitizedDescription.isEmpty()) {
+ actionText += QString(" \"%1\"").arg(sanitizedDescription);
+ }
+ htmlString = actionText + " <br/>" +
+ "<div id='" + ft_id + "'>" +
+ buildChatWindowButton(tr("Cancel"), ButtonFileTransferCancel, ft_id) +
+ buildChatWindowButton(tr("Accept"), ButtonFileTransferAcceptRequest, ft_id, P2QSTRING(filename)) +
+ "</div>";
+ }
+
+ //addMessage(message, senderName, senderIsSelf, std::shared_ptr<SecurityLabel>(), "", boost::posix_time::second_clock::local_time());
+
+ bool appendToPrevious = appendToPreviousCheck(PreviousMessageWasFileTransfer, senderName, senderIsSelf);
+
+ QString qAvatarPath = "qrc:/icons/avatar.svg";
+ std::string id = "ftmessage" + boost::lexical_cast<std::string>(idCounter_++);
+ addMessageBottom(std::make_shared<MessageSnippet>(htmlString, QtUtilities::htmlEscape(P2QSTRING(senderName)), B2QDATE(boost::posix_time::second_clock::universal_time()), qAvatarPath, senderIsSelf, appendToPrevious, theme_, P2QSTRING(id), ChatSnippet::getDirection(actionText)));
+
+ previousMessageWasSelf_ = senderIsSelf;
+ previousSenderName_ = P2QSTRING(senderName);
+ previousMessageKind_ = PreviousMessageWasFileTransfer;
+ return Q2PSTRING(ft_id);
}
void QtWebKitChatView::setFileTransferProgress(std::string id, const int percentageDone) {
- setFileTransferProgress(P2QSTRING(id), percentageDone);
+ setFileTransferProgress(P2QSTRING(id), percentageDone);
}
void QtWebKitChatView::setFileTransferStatus(std::string id, const ChatWindow::FileTransferState state, const std::string& msg) {
- setFileTransferStatus(P2QSTRING(id), state, P2QSTRING(msg));
+ setFileTransferStatus(P2QSTRING(id), state, P2QSTRING(msg));
}
std::string QtWebKitChatView::addWhiteboardRequest(const QString& contact, bool senderIsSelf) {
- QString wb_id = QString("wb%1").arg(P2QSTRING(boost::lexical_cast<std::string>(idCounter_++)));
- QString htmlString;
- QString actionText;
- if (senderIsSelf) {
- actionText = tr("Starting whiteboard chat");
- htmlString = "<div id='" + wb_id + "'>" + actionText + "<br />"+
- buildChatWindowButton(tr("Cancel"), ButtonWhiteboardSessionCancel, wb_id) +
- "</div>";
- } else {
- actionText = tr("%1 would like to start a whiteboard chat");
- htmlString = "<div id='" + wb_id + "'>" + actionText.arg(QtUtilities::htmlEscape(contact)) + ": <br/>" +
- buildChatWindowButton(tr("Cancel"), ButtonWhiteboardSessionCancel, wb_id) +
- buildChatWindowButton(tr("Accept"), ButtonWhiteboardSessionAcceptRequest, wb_id) +
- "</div>";
- }
- QString qAvatarPath = "qrc:/icons/avatar.png";
- std::string id = "wbmessage" + boost::lexical_cast<std::string>(idCounter_++);
- addMessageBottom(boost::make_shared<MessageSnippet>(htmlString, QtUtilities::htmlEscape(contact), B2QDATE(boost::posix_time::second_clock::universal_time()), qAvatarPath, false, false, theme_, P2QSTRING(id), ChatSnippet::getDirection(actionText)));
- previousMessageWasSelf_ = false;
- previousSenderName_ = contact;
- return Q2PSTRING(wb_id);
+ QString wb_id = QString("wb%1").arg(P2QSTRING(boost::lexical_cast<std::string>(idCounter_++)));
+ QString htmlString;
+ QString actionText;
+ if (senderIsSelf) {
+ actionText = tr("Starting whiteboard chat");
+ htmlString = "<div id='" + wb_id + "'>" + actionText + "<br />"+
+ buildChatWindowButton(tr("Cancel"), ButtonWhiteboardSessionCancel, wb_id) +
+ "</div>";
+ } else {
+ actionText = tr("%1 would like to start a whiteboard chat");
+ htmlString = "<div id='" + wb_id + "'>" + actionText.arg(QtUtilities::htmlEscape(contact)) + ": <br/>" +
+ buildChatWindowButton(tr("Cancel"), ButtonWhiteboardSessionCancel, wb_id) +
+ buildChatWindowButton(tr("Accept"), ButtonWhiteboardSessionAcceptRequest, wb_id) +
+ "</div>";
+ }
+ QString qAvatarPath = "qrc:/icons/avatar.svg";
+ std::string id = "wbmessage" + boost::lexical_cast<std::string>(idCounter_++);
+ addMessageBottom(std::make_shared<MessageSnippet>(htmlString, QtUtilities::htmlEscape(contact), B2QDATE(boost::posix_time::second_clock::universal_time()), qAvatarPath, false, false, theme_, P2QSTRING(id), ChatSnippet::getDirection(actionText)));
+ previousMessageWasSelf_ = false;
+ previousSenderName_ = contact;
+ return Q2PSTRING(wb_id);
}
void QtWebKitChatView::setWhiteboardSessionStatus(const std::string& id, const ChatWindow::WhiteboardSessionState state) {
- setWhiteboardSessionStatus(P2QSTRING(id), state);
+ setWhiteboardSessionStatus(P2QSTRING(id), state);
}
static bool isFilePathWritable(const QString& path) {
- QFileInfo fileInfo = QFileInfo(path);
- if (fileInfo.exists()) {
- return fileInfo.isWritable();
- }
- else {
- bool writable = false;
- QFile writeTestFile(path);
- if (writeTestFile.open(QIODevice::ReadWrite)) {
- writeTestFile.write("test");
- if (writeTestFile.error() == QFileDevice::NoError) {
- writable = true;
- }
- }
- writeTestFile.close();
- writeTestFile.remove();
- return writable;
- }
+ QFileInfo fileInfo = QFileInfo(path);
+ if (fileInfo.exists()) {
+ return fileInfo.isWritable();
+ }
+ else {
+ bool writable = false;
+ QFile writeTestFile(path);
+ if (writeTestFile.open(QIODevice::ReadWrite)) {
+ writeTestFile.write("test");
+ if (writeTestFile.error() == QFileDevice::NoError) {
+ writable = true;
+ }
+ }
+ writeTestFile.close();
+ writeTestFile.remove();
+ return writable;
+ }
}
void QtWebKitChatView::setFileTransferWarning(QString id, QString warningText) {
- QWebElement ftElement = findElementWithID(document_, "div", id);
- if (ftElement.isNull()) {
- SWIFT_LOG(debug) << "Tried to access FT UI via invalid id! id = " << Q2PSTRING(id) << std::endl;
- return;
- }
+ QWebElement ftElement = findElementWithID(document_, "div", id);
+ if (ftElement.isNull()) {
+ SWIFT_LOG(debug) << "Tried to access FT UI via invalid id! id = " << Q2PSTRING(id) << std::endl;
+ return;
+ }
- removeFileTransferWarning(id);
- ftElement.appendInside(QString("<div class='ft_warning' style='color: red;'><br/>%1</div>").arg(QtUtilities::htmlEscape(warningText)));
+ removeFileTransferWarning(id);
+ ftElement.appendInside(QString("<div class='ft_warning' style='color: red;'><br/>%1</div>").arg(QtUtilities::htmlEscape(warningText)));
}
void QtWebKitChatView::removeFileTransferWarning(QString id) {
- QWebElement ftElement = findElementWithID(document_, "div", id);
- if (ftElement.isNull()) {
- SWIFT_LOG(debug) << "Tried to access FT UI via invalid id! id = " << Q2PSTRING(id) << std::endl;
- return;
- }
+ QWebElement ftElement = findElementWithID(document_, "div", id);
+ if (ftElement.isNull()) {
+ SWIFT_LOG(debug) << "Tried to access FT UI via invalid id! id = " << Q2PSTRING(id) << std::endl;
+ return;
+ }
- QWebElement warningElement = ftElement.findFirst(".ft_warning");
- if (!warningElement.isNull()) {
- warningElement.removeFromDocument();
- }
+ QWebElement warningElement = ftElement.findFirst(".ft_warning");
+ if (!warningElement.isNull()) {
+ warningElement.removeFromDocument();
+ }
}
void QtWebKitChatView::handleHTMLButtonClicked(QString id, QString encodedArgument1, QString encodedArgument2, QString encodedArgument3, QString encodedArgument4, QString encodedArgument5) {
- QString arg1 = decodeButtonArgument(encodedArgument1);
- QString arg2 = decodeButtonArgument(encodedArgument2);
- QString arg3 = decodeButtonArgument(encodedArgument3);
- QString arg4 = decodeButtonArgument(encodedArgument4);
- QString arg5 = decodeButtonArgument(encodedArgument5);
-
- if (id.startsWith(ButtonFileTransferCancel)) {
- QString ft_id = arg1;
- window_->onFileTransferCancel(Q2PSTRING(ft_id));
- }
- else if (id.startsWith(ButtonFileTransferSetDescription)) {
- QString ft_id = arg1;
- bool ok = false;
- QString text = QInputDialog::getText(this, tr("File transfer description"),
- tr("Description:"), QLineEdit::Normal, "", &ok);
- if (ok) {
- descriptions_[ft_id] = text;
- }
- }
- else if (id.startsWith(ButtonFileTransferSendRequest)) {
- QString ft_id = arg1;
- QString text = descriptions_.find(ft_id) == descriptions_.end() ? QString() : descriptions_[ft_id];
- window_->onFileTransferStart(Q2PSTRING(ft_id), Q2PSTRING(text));
- }
- else if (id.startsWith(ButtonFileTransferAcceptRequest)) {
- QString ft_id = arg1;
- QString filename = arg2;
-
- QString path = QFileDialog::getSaveFileName(this, tr("Save File"), filename);
- if (!path.isEmpty() && isFilePathWritable(path)) {
- filePaths_[ft_id] = path;
- window_->onFileTransferAccept(Q2PSTRING(ft_id), Q2PSTRING(path));
- removeFileTransferWarning(ft_id);
- }
- else {
- setFileTransferWarning(ft_id, tr("The chosen save location is not writable! Click the 'Accept' button to select a different save location."));
- }
- }
- else if (id.startsWith(ButtonFileTransferOpenFile)) {
- QString ft_id = arg1;
- QString filename = arg2;
- askDesktopToOpenFile(filename);
- }
- else if (id.startsWith(ButtonWhiteboardSessionAcceptRequest)) {
- QString id = arg1;
- setWhiteboardSessionStatus(id, ChatWindow::WhiteboardAccepted);
- window_->onWhiteboardSessionAccept();
- }
- else if (id.startsWith(ButtonWhiteboardSessionCancel)) {
- QString id = arg1;
- setWhiteboardSessionStatus(id, ChatWindow::WhiteboardTerminated);
- window_->onWhiteboardSessionCancel();
- }
- else if (id.startsWith(ButtonWhiteboardShowWindow)) {
- QString id = arg1;
- window_->onWhiteboardWindowShow();
- }
- else if (id.startsWith(ButtonMUCInvite)) {
- QString roomJID = arg1;
- QString password = arg2;
- QString elementID = arg3;
- QString isImpromptu = arg4;
- QString isContinuation = arg5;
- eventStream_->send(boost::make_shared<JoinMUCUIEvent>(Q2PSTRING(roomJID), Q2PSTRING(password), boost::optional<std::string>(), false, false, isImpromptu.contains("true"), isContinuation.contains("true")));
- setMUCInvitationJoined(elementID);
- }
- else {
- SWIFT_LOG(debug) << "Unknown HTML button! ( " << Q2PSTRING(id) << " )" << std::endl;
- }
+ QString arg1 = decodeButtonArgument(encodedArgument1);
+ QString arg2 = decodeButtonArgument(encodedArgument2);
+ QString arg3 = decodeButtonArgument(encodedArgument3);
+ QString arg4 = decodeButtonArgument(encodedArgument4);
+ QString arg5 = decodeButtonArgument(encodedArgument5);
+
+ if (id.startsWith(ButtonFileTransferCancel)) {
+ QString ft_id = arg1;
+ window_->onFileTransferCancel(Q2PSTRING(ft_id));
+ }
+ else if (id.startsWith(ButtonFileTransferSetDescription)) {
+ QString ft_id = arg1;
+ bool ok = false;
+ QString text = QInputDialog::getText(this, tr("File transfer description"),
+ tr("Description:"), QLineEdit::Normal, "", &ok);
+ if (ok) {
+ descriptions_[ft_id] = text;
+ }
+ }
+ else if (id.startsWith(ButtonFileTransferSendRequest)) {
+ QString ft_id = arg1;
+ QString text = descriptions_.find(ft_id) == descriptions_.end() ? QString() : descriptions_[ft_id];
+ window_->onFileTransferStart(Q2PSTRING(ft_id), Q2PSTRING(text));
+ }
+ else if (id.startsWith(ButtonFileTransferAcceptRequest)) {
+ QString ft_id = arg1;
+ QString filename = arg2;
+
+ QString path = QFileDialog::getSaveFileName(this, tr("Save File"), filename);
+ if (!path.isEmpty() && isFilePathWritable(path)) {
+ filePaths_[ft_id] = path;
+ window_->onFileTransferAccept(Q2PSTRING(ft_id), Q2PSTRING(path));
+ removeFileTransferWarning(ft_id);
+ }
+ else {
+ setFileTransferWarning(ft_id, tr("The chosen save location is not writable! Click the 'Accept' button to select a different save location."));
+ }
+ }
+ else if (id.startsWith(ButtonFileTransferOpenFile)) {
+ QString ft_id = arg1;
+ QString filename = arg2;
+ askDesktopToOpenFile(filename);
+ }
+ else if (id.startsWith(ButtonWhiteboardSessionAcceptRequest)) {
+ QString id = arg1;
+ setWhiteboardSessionStatus(id, ChatWindow::WhiteboardAccepted);
+ window_->onWhiteboardSessionAccept();
+ }
+ else if (id.startsWith(ButtonWhiteboardSessionCancel)) {
+ QString id = arg1;
+ setWhiteboardSessionStatus(id, ChatWindow::WhiteboardTerminated);
+ window_->onWhiteboardSessionCancel();
+ }
+ else if (id.startsWith(ButtonWhiteboardShowWindow)) {
+ QString id = arg1;
+ window_->onWhiteboardWindowShow();
+ }
+ else if (id.startsWith(ButtonMUCInvite)) {
+ QString roomJID = arg1;
+ QString password = arg2;
+ QString elementID = arg3;
+ QString isImpromptu = arg4;
+ QString isContinuation = arg5;
+ eventStream_->send(std::make_shared<JoinMUCUIEvent>(Q2PSTRING(roomJID), Q2PSTRING(password), boost::optional<std::string>(), false, false, isImpromptu.contains("true"), isContinuation.contains("true")));
+ setMUCInvitationJoined(elementID);
+ }
+ else {
+ SWIFT_LOG(debug) << "Unknown HTML button! ( " << Q2PSTRING(id) << " )" << std::endl;
+ }
+}
+
+void QtWebKitChatView::handleVerticalScrollBarPositionChanged(double position) {
+ rememberScrolledToBottom();
+ if (position == 0) {
+ emit scrollReachedTop();
+ }
+ else if (position == 1) {
+ emit scrollReachedBottom();
+ }
}
void QtWebKitChatView::addErrorMessage(const ChatWindow::ChatMessage& errorMessage) {
- if (window_->isWidgetSelected()) {
- window_->onAllMessagesRead();
- }
+ if (window_->isWidgetSelected()) {
+ window_->onAllMessagesRead();
+ }
- QString errorMessageHTML(chatMessageToHTML(errorMessage));
- std::string id = "id" + boost::lexical_cast<std::string>(idCounter_++);
- addMessageBottom(boost::make_shared<SystemMessageSnippet>("<span class=\"error\">" + errorMessageHTML + "</span>", QDateTime::currentDateTime(), false, theme_, P2QSTRING(id), ChatSnippet::getDirection(errorMessage)));
+ QString errorMessageHTML(chatMessageToHTML(errorMessage));
+ std::string id = "id" + boost::lexical_cast<std::string>(idCounter_++);
+ addMessageBottom(std::make_shared<SystemMessageSnippet>("<span class=\"error\">" + errorMessageHTML + "</span>", QDateTime::currentDateTime(), false, theme_, P2QSTRING(id), ChatSnippet::getDirection(errorMessage)));
- previousMessageWasSelf_ = false;
- previousMessageKind_ = PreviousMessageWasSystem;
+ previousMessageWasSelf_ = false;
+ previousMessageKind_ = PreviousMessageWasSystem;
}
std::string QtWebKitChatView::addSystemMessage(const ChatWindow::ChatMessage& message, ChatWindow::Direction direction) {
- if (window_->isWidgetSelected()) {
- window_->onAllMessagesRead();
- }
+ if (window_->isWidgetSelected()) {
+ window_->onAllMessagesRead();
+ }
- QString messageHTML = chatMessageToHTML(message);
- std::string id = "id" + boost::lexical_cast<std::string>(idCounter_++);
- addMessageBottom(boost::make_shared<SystemMessageSnippet>(messageHTML, QDateTime::currentDateTime(), false, theme_, P2QSTRING(id), getActualDirection(message, direction)));
+ QString messageHTML = chatMessageToHTML(message);
+ std::string id = "id" + boost::lexical_cast<std::string>(idCounter_++);
+ addMessageBottom(std::make_shared<SystemMessageSnippet>(messageHTML, QDateTime::currentDateTime(), false, theme_, P2QSTRING(id), getActualDirection(message, direction)));
- previousMessageKind_ = PreviousMessageWasSystem;
- return id;
+ previousMessageKind_ = PreviousMessageWasSystem;
+ return id;
}
-void QtWebKitChatView::replaceWithAction(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
- replaceMessage(" *" + chatMessageToHTML(message) + "*", id, time, "font-style:italic ", highlight);
+void QtWebKitChatView::replaceWithAction(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time) {
+ replaceMessage(" *" + chatMessageToHTML(message) + "*", id, time, "font-style:italic ", message.getFullMessageHighlightAction());
}
-void QtWebKitChatView::replaceMessage(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight) {
- replaceMessage(chatMessageToHTML(message), id, time, "", highlight);
+void QtWebKitChatView::replaceMessage(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time) {
+ replaceMessage(chatMessageToHTML(message), id, time, "", message.getFullMessageHighlightAction());
}
void QtWebKitChatView::replaceSystemMessage(const ChatWindow::ChatMessage& message, const std::string& id, ChatWindow::TimestampBehaviour timestampBehavior) {
- replaceSystemMessage(chatMessageToHTML(message), P2QSTRING(id), timestampBehavior);
+ replaceSystemMessage(chatMessageToHTML(message), P2QSTRING(id), timestampBehavior);
}
void QtWebKitChatView::replaceSystemMessage(const QString& newMessage, const QString& id, const ChatWindow::TimestampBehaviour timestampBehaviour) {
- rememberScrolledToBottom();
- QWebElement message = document_.findFirst("#" + id);
- if (!message.isNull()) {
- QWebElement replaceContent = message.findFirst("span.swift_message");
- assert(!replaceContent.isNull());
- QString old = replaceContent.toOuterXml();
- replaceContent.setInnerXml(ChatSnippet::escape(newMessage));
-
- if (timestampBehaviour == ChatWindow::UpdateTimestamp) {
- QWebElement replace = message.findFirst("span.swift_time");
- assert(!replace.isNull());
- replace.setInnerXml(ChatSnippet::timeToEscapedString(QDateTime::currentDateTime()));
- }
- }
- else {
- qWarning() << "Trying to replace element with id " << id << " but it's not there.";
- }
+ rememberScrolledToBottom();
+ QWebElement message = document_.findFirst("#" + id);
+ if (!message.isNull()) {
+ QWebElement replaceContent = message.findFirst("span.swift_message");
+ assert(!replaceContent.isNull());
+ QString old = replaceContent.toOuterXml();
+ replaceContent.setInnerXml(ChatSnippet::escape(newMessage));
+
+ if (timestampBehaviour == ChatWindow::UpdateTimestamp) {
+ QWebElement replace = message.findFirst("span.swift_time");
+ assert(!replace.isNull());
+ replace.setInnerXml(ChatSnippet::timeToEscapedString(QDateTime::currentDateTime()));
+ }
+ }
+ else {
+ qWarning() << "Trying to replace element with id " << id << " but it's not there.";
+ }
}
void QtWebKitChatView::replaceMessage(const QString& message, const std::string& id, const boost::posix_time::ptime& time, const QString& style, const HighlightAction& highlight) {
- if (!id.empty()) {
- if (window_->isWidgetSelected()) {
- window_->onAllMessagesRead();
- }
+ if (!id.empty()) {
+ if (window_->isWidgetSelected()) {
+ window_->onAllMessagesRead();
+ }
- QString messageHTML(message);
+ QString messageHTML(message);
- QString styleSpanStart = style == "" ? "" : "<span style=\"" + style + "\">";
- QString styleSpanEnd = style == "" ? "" : "</span>";
- QString highlightSpanStart = highlight.highlightWholeMessage() ? getHighlightSpanStart(highlight) : "";
- QString highlightSpanEnd = highlight.highlightWholeMessage() ? "</span>" : "";
- messageHTML = styleSpanStart + highlightSpanStart + messageHTML + highlightSpanEnd + styleSpanEnd;
+ QString styleSpanStart = style == "" ? "" : "<span style=\"" + style + "\">";
+ QString styleSpanEnd = style == "" ? "" : "</span>";
+ QString highlightSpanStart = highlight.highlightWholeMessage() ? getHighlightSpanStart(highlight) : "";
+ QString highlightSpanEnd = highlight.highlightWholeMessage() ? "</span>" : "";
+ messageHTML = styleSpanStart + highlightSpanStart + messageHTML + highlightSpanEnd + styleSpanEnd;
- replaceMessage(messageHTML, P2QSTRING(id), B2QDATE(time));
- }
- else {
- std::cerr << "Trying to replace a message with no id";
- }
+ replaceMessage(messageHTML, P2QSTRING(id), B2QDATE(time));
+ }
+ else {
+ std::cerr << "Trying to replace a message with no id";
+ }
}
void QtWebKitChatView::addPresenceMessage(const ChatWindow::ChatMessage& message, ChatWindow::Direction direction) {
- if (window_->isWidgetSelected()) {
- window_->onAllMessagesRead();
- }
+ if (window_->isWidgetSelected()) {
+ window_->onAllMessagesRead();
+ }
- QString messageHTML = chatMessageToHTML(message);
- std::string id = "id" + boost::lexical_cast<std::string>(idCounter_++);
- addMessageBottom(boost::make_shared<SystemMessageSnippet>(messageHTML, QDateTime::currentDateTime(), false, theme_, P2QSTRING(id), getActualDirection(message, direction)));
+ QString messageHTML = chatMessageToHTML(message);
+ std::string id = "id" + boost::lexical_cast<std::string>(idCounter_++);
+ addMessageBottom(std::make_shared<SystemMessageSnippet>(messageHTML, QDateTime::currentDateTime(), false, theme_, P2QSTRING(id), getActualDirection(message, direction)));
- previousMessageKind_ = PreviousMessageWasPresence;
+ previousMessageKind_ = PreviousMessageWasPresence;
}
void QtWebKitChatView::replaceLastMessage(const ChatWindow::ChatMessage& message, const ChatWindow::TimestampBehaviour timestampBehaviour) {
- replaceLastMessage(chatMessageToHTML(message), timestampBehaviour);
+ replaceLastMessage(chatMessageToHTML(message), timestampBehaviour);
}
void QtWebKitChatView::addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct, bool isImpromptu, bool isContinuation) {
- if (window_->isWidgetSelected()) {
- window_->onAllMessagesRead();
- }
+ if (window_->isWidgetSelected()) {
+ window_->onAllMessagesRead();
+ }
- QString message;
- if (isImpromptu) {
- message = QObject::tr("You've been invited to join a chat.") + "\n";
- } else {
- message = QObject::tr("You've been invited to enter the %1 room.").arg(P2QSTRING(jid.toString())) + "\n";
- }
- QString htmlString = message;
- if (!reason.empty()) {
- htmlString += QObject::tr("Reason: %1").arg(P2QSTRING(reason)) + "\n";
- }
- if (!direct) {
- htmlString += QObject::tr("This person may not have really sent this invitation!") + "\n";
- }
- htmlString = chatMessageToHTML(ChatWindow::ChatMessage(Q2PSTRING(htmlString)));
+ QString message;
+ if (isImpromptu) {
+ message = QObject::tr("You've been invited to join a chat.") + "\n";
+ } else {
+ message = QObject::tr("You've been invited to enter the %1 room.").arg(P2QSTRING(jid.toString())) + "\n";
+ }
+ QString htmlString = message;
+ if (!reason.empty()) {
+ htmlString += QObject::tr("Reason: %1").arg(P2QSTRING(reason)) + "\n";
+ }
+ if (!direct) {
+ htmlString += QObject::tr("This person may not have really sent this invitation!") + "\n";
+ }
+ htmlString = chatMessageToHTML(ChatWindow::ChatMessage(Q2PSTRING(htmlString)));
- QString id = QString(ButtonMUCInvite + "%1").arg(P2QSTRING(boost::lexical_cast<std::string>(idCounter_++)));
- htmlString += "<div id='" + id + "'>" +
- buildChatWindowButton(chatMessageToHTML(ChatWindow::ChatMessage(Q2PSTRING((tr("Accept Invite"))))), ButtonMUCInvite, QtUtilities::htmlEscape(P2QSTRING(jid.toString())), QtUtilities::htmlEscape(P2QSTRING(password)), id, QtUtilities::htmlEscape(isImpromptu ? "true" : "false"), QtUtilities::htmlEscape(isContinuation ? "true" : "false")) +
- "</div>";
+ QString id = QString(ButtonMUCInvite + "%1").arg(P2QSTRING(boost::lexical_cast<std::string>(idCounter_++)));
+ htmlString += "<div id='" + id + "'>" +
+ buildChatWindowButton(chatMessageToHTML(ChatWindow::ChatMessage(Q2PSTRING((tr("Accept Invite"))))), ButtonMUCInvite, QtUtilities::htmlEscape(P2QSTRING(jid.toString())), QtUtilities::htmlEscape(P2QSTRING(password)), id, QtUtilities::htmlEscape(isImpromptu ? "true" : "false"), QtUtilities::htmlEscape(isContinuation ? "true" : "false")) +
+ "</div>";
- bool appendToPrevious = appendToPreviousCheck(PreviousMessageWasMUCInvite, senderName, false);
+ bool appendToPrevious = appendToPreviousCheck(PreviousMessageWasMUCInvite, senderName, false);
- QString qAvatarPath = "qrc:/icons/avatar.png";
+ QString qAvatarPath = "qrc:/icons/avatar.svg";
- addMessageBottom(boost::make_shared<MessageSnippet>(htmlString, QtUtilities::htmlEscape(P2QSTRING(senderName)), B2QDATE(boost::posix_time::second_clock::universal_time()), qAvatarPath, false, appendToPrevious, theme_, id, ChatSnippet::getDirection(message)));
- previousMessageWasSelf_ = false;
- previousSenderName_ = P2QSTRING(senderName);
- previousMessageKind_ = PreviousMessageWasMUCInvite;
+ addMessageBottom(std::make_shared<MessageSnippet>(htmlString, QtUtilities::htmlEscape(P2QSTRING(senderName)), B2QDATE(boost::posix_time::second_clock::universal_time()), qAvatarPath, false, appendToPrevious, theme_, id, ChatSnippet::getDirection(message)));
+ previousMessageWasSelf_ = false;
+ previousSenderName_ = P2QSTRING(senderName);
+ previousMessageKind_ = PreviousMessageWasMUCInvite;
}
void QtWebKitChatView::setAckState(std::string const& id, ChatWindow::AckState state) {
- QString xml;
- switch (state) {
- case ChatWindow::Pending:
- xml = "<img src='qrc:/icons/throbber.gif' title='" + tr("This message has not been received by your server yet.") + "'/>";
- displayReceiptInfo(P2QSTRING(id), false);
- break;
- case ChatWindow::Received:
- xml = "";
- displayReceiptInfo(P2QSTRING(id), true);
- break;
- case ChatWindow::Failed: xml = "<img src='qrc:/icons/error.png' title='" + tr("This message may not have been transmitted.") + "'/>"; break;
- }
- setAckXML(P2QSTRING(id), xml);
+ QString xml;
+ switch (state) {
+ case ChatWindow::Pending:
+ xml = "<img src='qrc:/icons/throbber.gif' title='" + tr("This message has not been received by your server yet.") + "'/>";
+ displayReceiptInfo(P2QSTRING(id), false);
+ break;
+ case ChatWindow::Received:
+ xml = "";
+ displayReceiptInfo(P2QSTRING(id), true);
+ break;
+ case ChatWindow::Failed: xml = "<img src='qrc:/icons/error.png' title='" + tr("This message may not have been transmitted.") + "'/>"; break;
+ }
+ setAckXML(P2QSTRING(id), xml);
}
void QtWebKitChatView::setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state) {
- QString xml;
- switch (state) {
- case ChatWindow::ReceiptReceived:
- xml = "<img src='qrc:/icons/check.png' title='" + tr("The receipt for this message has been received.") + "'/>";
- break;
- case ChatWindow::ReceiptRequested:
- xml = "<img src='qrc:/icons/warn.png' title='" + tr("The receipt for this message has not yet been received. The recipient(s) might not have received this message.") + "'/>";
- break;
- case ChatWindow::ReceiptFailed:
- xml = "<img src='qrc:/icons/error.png' title='" + tr("Failed to transmit message to the receipient(s).") + "'/>";
- }
- setReceiptXML(P2QSTRING(id), xml);
+ QString xml;
+ switch (state) {
+ case ChatWindow::ReceiptReceived:
+ xml = "<img src='qrc:/icons/delivery-success.svg' title='" + tr("The receipt for this message has been received.") + "'/>";
+ break;
+ case ChatWindow::ReceiptRequested:
+ xml = "<img src='qrc:/icons/delivery-warning.svg' title='" + tr("The receipt for this message has not yet been received. The recipient(s) might not have received this message.") + "'/>";
+ break;
+ case ChatWindow::ReceiptFailed:
+ xml = "<img src='qrc:/icons/delivery-failure.svg' title='" + tr("Failed to transmit message to the receipient(s).") + "'/>";
+ }
+ setReceiptXML(P2QSTRING(id), xml);
}
bool QtWebKitChatView::appendToPreviousCheck(PreviousMessageKind messageKind, const std::string& senderName, bool senderIsSelf) {
- bool result = previousMessageKind_ == messageKind && ((senderIsSelf && previousMessageWasSelf_) || (!senderIsSelf && !previousMessageWasSelf_&& previousSenderName_ == P2QSTRING(senderName)));
- if (insertingLastLine_) {
- insertingLastLine_ = false;
- return false;
- }
- return result;
+ bool result = previousMessageKind_ == messageKind && ((senderIsSelf && previousMessageWasSelf_) || (!senderIsSelf && !previousMessageWasSelf_&& previousSenderName_ == P2QSTRING(senderName)));
+ if (insertingLastLine_) {
+ insertingLastLine_ = false;
+ return false;
+ }
+ return result;
}
ChatSnippet::Direction QtWebKitChatView::getActualDirection(const ChatWindow::ChatMessage& message, ChatWindow::Direction direction) {
- if (direction == ChatWindow::DefaultDirection) {
- return QCoreApplication::translate("QApplication", "QT_LAYOUT_DIRECTION") == "RTL" ? ChatSnippet::RTL : ChatSnippet::LTR;
- }
- else {
- return ChatSnippet::getDirection(message);
- }
+ if (direction == ChatWindow::DefaultDirection) {
+ return QCoreApplication::translate("QApplication", "QT_LAYOUT_DIRECTION") == "RTL" ? ChatSnippet::RTL : ChatSnippet::LTR;
+ }
+ else {
+ return ChatSnippet::getDirection(message);
+ }
}
-// void QtWebKitChatView::setShowEmoticons(bool value) {
-// showEmoticons_ = value;
-// }
-
-
}
diff --git a/Swift/QtUI/QtWebKitChatView.h b/Swift/QtUI/QtWebKitChatView.h
index 173a05b..098c1ac 100644
--- a/Swift/QtUI/QtWebKitChatView.h
+++ b/Swift/QtUI/QtWebKitChatView.h
@@ -6,7 +6,7 @@
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
#include <QList>
#include <QString>
@@ -25,171 +25,171 @@ class QUrl;
class QDate;
namespace Swift {
- class QtWebView;
- class QtChatTheme;
- class QtChatWindowJSBridge;
- class UIEventStream;
- class QtChatWindow;
- class QtWebKitChatView : public QtChatView {
- Q_OBJECT
-
- public:
- static const QString ButtonWhiteboardSessionCancel;
- static const QString ButtonWhiteboardSessionAcceptRequest;
- static const QString ButtonWhiteboardShowWindow;
- static const QString ButtonFileTransferCancel;
- static const QString ButtonFileTransferSetDescription;
- static const QString ButtonFileTransferSendRequest;
- static const QString ButtonFileTransferAcceptRequest;
- static const QString ButtonFileTransferOpenFile;
- static const QString ButtonMUCInvite;
- public:
- QtWebKitChatView(QtChatWindow* window, UIEventStream* eventStream, QtChatTheme* theme, QWidget* parent, bool disableAutoScroll = false);
- ~QtWebKitChatView();
-
- /** Add message to window.
- * @return id of added message (for acks).
- */
- virtual std::string addMessage(const ChatWindow::ChatMessage& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) SWIFTEN_OVERRIDE;
- /** Adds action to window.
- * @return id of added message (for acks);
- */
- virtual std::string addAction(const ChatWindow::ChatMessage& message, const std::string& senderName, bool senderIsSelf, boost::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time, const HighlightAction& highlight) SWIFTEN_OVERRIDE;
-
- virtual std::string addSystemMessage(const ChatWindow::ChatMessage& message, ChatWindow::Direction direction) SWIFTEN_OVERRIDE;
- virtual void addPresenceMessage(const ChatWindow::ChatMessage& message, ChatWindow::Direction direction) SWIFTEN_OVERRIDE;
-
- virtual void addErrorMessage(const ChatWindow::ChatMessage& message) SWIFTEN_OVERRIDE;
- virtual void replaceMessage(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight) SWIFTEN_OVERRIDE;
- virtual void replaceSystemMessage(const ChatWindow::ChatMessage& message, const std::string& id, ChatWindow::TimestampBehaviour timestampBehaviour) SWIFTEN_OVERRIDE;
- virtual void replaceWithAction(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time, const HighlightAction& highlight) SWIFTEN_OVERRIDE;
- virtual void replaceLastMessage(const ChatWindow::ChatMessage& message, const ChatWindow::TimestampBehaviour timestampBehaviour) SWIFTEN_OVERRIDE;
- virtual void setAckState(const std::string& id, ChatWindow::AckState state) SWIFTEN_OVERRIDE;
-
- virtual std::string addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes, const std::string& description) SWIFTEN_OVERRIDE;
- virtual void setFileTransferProgress(std::string, const int percentageDone) SWIFTEN_OVERRIDE;
- virtual void setFileTransferStatus(std::string, const ChatWindow::FileTransferState state, const std::string& msg = "") SWIFTEN_OVERRIDE;
- virtual void addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct, bool isImpromptu, bool isContinuation) SWIFTEN_OVERRIDE;
- virtual std::string addWhiteboardRequest(const QString& contact, bool senderIsSelf) SWIFTEN_OVERRIDE;
- virtual void setWhiteboardSessionStatus(const std::string& id, const ChatWindow::WhiteboardSessionState state) SWIFTEN_OVERRIDE;
- virtual void setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state) SWIFTEN_OVERRIDE;
-
- virtual void showEmoticons(bool show) SWIFTEN_OVERRIDE;
- void addMessageTop(boost::shared_ptr<ChatSnippet> snippet);
- void addMessageBottom(boost::shared_ptr<ChatSnippet> snippet);
-
- int getSnippetPositionByDate(const QDate& date); // FIXME : This probably shouldn't have been public
- virtual void addLastSeenLine() SWIFTEN_OVERRIDE;
-
- private: // previously public, now private
- void replaceLastMessage(const QString& newMessage, const ChatWindow::TimestampBehaviour timestampBehaviour);
- void replaceLastMessage(const QString& newMessage, const QString& note);
- void replaceMessage(const QString& newMessage, const QString& id, const QDateTime& time);
- void replaceSystemMessage(const QString& newMessage, const QString&id, const ChatWindow::TimestampBehaviour timestampBehaviour);
- void rememberScrolledToBottom();
- void setAckXML(const QString& id, const QString& xml);
- void setReceiptXML(const QString& id, const QString& xml);
- void displayReceiptInfo(const QString& id, bool showIt);
-
- QString getLastSentMessage();
- void addToJSEnvironment(const QString&, QObject*);
- void setFileTransferProgress(QString id, const int percentageDone);
- void setFileTransferStatus(QString id, const ChatWindow::FileTransferState state, const QString& msg);
- void setFileTransferWarning(QString id, QString warningText);
- void removeFileTransferWarning(QString id);
- void setWhiteboardSessionStatus(QString id, const ChatWindow::WhiteboardSessionState state);
- void setMUCInvitationJoined(QString id);
- void askDesktopToOpenFile(const QString& filename);
-
- signals:
- void gotFocus();
- void fontResized(int);
- void logCleared();
- void scrollRequested(int pos);
- void scrollReachedTop();
- void scrollReachedBottom();
-
- public slots:
- void copySelectionToClipboard();
- void handleLinkClicked(const QUrl&);
- void resetView();
- void resetTopInsertPoint();
- void increaseFontSize(int numSteps = 1);
- void decreaseFontSize();
- virtual void resizeFont(int fontSizeSteps) SWIFTEN_OVERRIDE;
- virtual void scrollToBottom() SWIFTEN_OVERRIDE;
- virtual void handleKeyPressEvent(QKeyEvent* event) SWIFTEN_OVERRIDE;
-
- private slots:
- void handleViewLoadFinished(bool);
- void handleFrameSizeChanged();
- void handleClearRequested();
- void handleScrollRequested(int dx, int dy, const QRect& rectToScroll);
- void handleHTMLButtonClicked(QString id, QString arg1, QString arg2, QString arg3, QString arg4, QString arg5);
-
- private:
- enum PreviousMessageKind {
- PreviosuMessageWasNone,
- PreviousMessageWasMessage,
- PreviousMessageWasSystem,
- PreviousMessageWasPresence,
- PreviousMessageWasFileTransfer,
- PreviousMessageWasMUCInvite
- };
- std::string addMessage(
- const QString& message,
- const std::string& senderName,
- bool senderIsSelf,
- boost::shared_ptr<SecurityLabel> label,
- const std::string& avatarPath,
- const QString& style,
- const boost::posix_time::ptime& time,
- const HighlightAction& highlight,
- ChatSnippet::Direction direction);
- void replaceMessage(
- const QString& message,
- const std::string& id,
- const boost::posix_time::ptime& time,
- const QString& style,
- const HighlightAction& highlight);
- bool appendToPreviousCheck(PreviousMessageKind messageKind, const std::string& senderName, bool senderIsSelf);
- static ChatSnippet::Direction getActualDirection(const ChatWindow::ChatMessage& message, ChatWindow::Direction direction);
- QString getHighlightSpanStart(const std::string& text, const std::string& background);
- QString getHighlightSpanStart(const HighlightAction& highlight);
- QString chatMessageToHTML(const ChatWindow::ChatMessage& message);
- static QString buildChatWindowButton(const QString& name, const QString& id, const QString& arg1 = QString(), const QString& arg2 = QString(), const QString& arg3 = QString(), const QString& arg4 = QString(), const QString& arg5 = QString());
-
- private:
- void headerEncode();
- void messageEncode();
- void addToDOM(boost::shared_ptr<ChatSnippet> snippet);
- QWebElement snippetToDOM(boost::shared_ptr<ChatSnippet> snippet);
-
- QtChatWindow* window_;
- UIEventStream* eventStream_;
- bool viewReady_;
- bool isAtBottom_;
- bool topMessageAdded_;
- int scrollBarMaximum_;
- QtWebView* webView_;
- QWebPage* webPage_;
- int fontSizeSteps_;
- QtChatTheme* theme_;
- QWebElement newInsertPoint_;
- QWebElement topInsertPoint_;
- QWebElement lineSeparator_;
- QWebElement lastElement_;
- QWebElement firstElement_;
- QWebElement document_;
- bool disableAutoScroll_;
- QtChatWindowJSBridge* jsBridge;
- PreviousMessageKind previousMessageKind_;
- bool previousMessageWasSelf_;
- bool showEmoticons_;
- bool insertingLastLine_;
- int idCounter_;
- QString previousSenderName_;
- std::map<QString, QString> descriptions_;
- std::map<QString, QString> filePaths_;
- };
+ class QtWebView;
+ class QtChatTheme;
+ class QtChatWindowJSBridge;
+ class UIEventStream;
+ class QtChatWindow;
+ class QtWebKitChatView : public QtChatView {
+ Q_OBJECT
+
+ public:
+ static const QString ButtonWhiteboardSessionCancel;
+ static const QString ButtonWhiteboardSessionAcceptRequest;
+ static const QString ButtonWhiteboardShowWindow;
+ static const QString ButtonFileTransferCancel;
+ static const QString ButtonFileTransferSetDescription;
+ static const QString ButtonFileTransferSendRequest;
+ static const QString ButtonFileTransferAcceptRequest;
+ static const QString ButtonFileTransferOpenFile;
+ static const QString ButtonMUCInvite;
+ public:
+ QtWebKitChatView(QtChatWindow* window, UIEventStream* eventStream, QtChatTheme* theme, QWidget* parent, bool disableAutoScroll = false);
+ ~QtWebKitChatView();
+
+ /** Add message to window.
+ * @return id of added message (for acks).
+ */
+ virtual std::string addMessage(const ChatWindow::ChatMessage& message, const std::string& senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) SWIFTEN_OVERRIDE;
+ /** Adds action to window.
+ * @return id of added message (for acks);
+ */
+ virtual std::string addAction(const ChatWindow::ChatMessage& message, const std::string& senderName, bool senderIsSelf, std::shared_ptr<SecurityLabel> label, const std::string& avatarPath, const boost::posix_time::ptime& time) SWIFTEN_OVERRIDE;
+
+ virtual std::string addSystemMessage(const ChatWindow::ChatMessage& message, ChatWindow::Direction direction) SWIFTEN_OVERRIDE;
+ virtual void addPresenceMessage(const ChatWindow::ChatMessage& message, ChatWindow::Direction direction) SWIFTEN_OVERRIDE;
+
+ virtual void addErrorMessage(const ChatWindow::ChatMessage& message) SWIFTEN_OVERRIDE;
+ virtual void replaceMessage(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time) SWIFTEN_OVERRIDE;
+ virtual void replaceSystemMessage(const ChatWindow::ChatMessage& message, const std::string& id, ChatWindow::TimestampBehaviour timestampBehaviour) SWIFTEN_OVERRIDE;
+ virtual void replaceWithAction(const ChatWindow::ChatMessage& message, const std::string& id, const boost::posix_time::ptime& time) SWIFTEN_OVERRIDE;
+ virtual void replaceLastMessage(const ChatWindow::ChatMessage& message, const ChatWindow::TimestampBehaviour timestampBehaviour) SWIFTEN_OVERRIDE;
+ virtual void setAckState(const std::string& id, ChatWindow::AckState state) SWIFTEN_OVERRIDE;
+
+ virtual std::string addFileTransfer(const std::string& senderName, bool senderIsSelf, const std::string& filename, const boost::uintmax_t sizeInBytes, const std::string& description) SWIFTEN_OVERRIDE;
+ virtual void setFileTransferProgress(std::string, const int percentageDone) SWIFTEN_OVERRIDE;
+ virtual void setFileTransferStatus(std::string, const ChatWindow::FileTransferState state, const std::string& msg = "") SWIFTEN_OVERRIDE;
+ virtual void addMUCInvitation(const std::string& senderName, const JID& jid, const std::string& reason, const std::string& password, bool direct, bool isImpromptu, bool isContinuation) SWIFTEN_OVERRIDE;
+ virtual std::string addWhiteboardRequest(const QString& contact, bool senderIsSelf) SWIFTEN_OVERRIDE;
+ virtual void setWhiteboardSessionStatus(const std::string& id, const ChatWindow::WhiteboardSessionState state) SWIFTEN_OVERRIDE;
+ virtual void setMessageReceiptState(const std::string& id, ChatWindow::ReceiptState state) SWIFTEN_OVERRIDE;
+
+ virtual void showEmoticons(bool show) SWIFTEN_OVERRIDE;
+ void addMessageTop(std::shared_ptr<ChatSnippet> snippet);
+ void addMessageBottom(std::shared_ptr<ChatSnippet> snippet);
+
+ int getSnippetPositionByDate(const QDate& date); // FIXME : This probably shouldn't have been public
+ virtual void addLastSeenLine() SWIFTEN_OVERRIDE;
+
+ private: // previously public, now private
+ void replaceLastMessage(const QString& newMessage, const ChatWindow::TimestampBehaviour timestampBehaviour);
+ void replaceLastMessage(const QString& newMessage, const QString& note);
+ void replaceMessage(const QString& newMessage, const QString& id, const QDateTime& time);
+ void replaceSystemMessage(const QString& newMessage, const QString&id, const ChatWindow::TimestampBehaviour timestampBehaviour);
+ void rememberScrolledToBottom();
+ void setAckXML(const QString& id, const QString& xml);
+ void setReceiptXML(const QString& id, const QString& xml);
+ void displayReceiptInfo(const QString& id, bool showIt);
+
+ QString getLastSentMessage();
+ void addToJSEnvironment(const QString&, QObject*);
+ void setFileTransferProgress(QString id, const int percentageDone);
+ void setFileTransferStatus(QString id, const ChatWindow::FileTransferState state, const QString& msg);
+ void setFileTransferWarning(QString id, QString warningText);
+ void removeFileTransferWarning(QString id);
+ void setWhiteboardSessionStatus(QString id, const ChatWindow::WhiteboardSessionState state);
+ void setMUCInvitationJoined(QString id);
+ void askDesktopToOpenFile(const QString& filename);
+
+ signals:
+ void gotFocus();
+ void fontResized(int);
+ void logCleared();
+ void scrollRequested(int pos);
+ void scrollReachedTop();
+ void scrollReachedBottom();
+
+ public slots:
+ void copySelectionToClipboard();
+ void handleLinkClicked(const QUrl&);
+ void resetView();
+ void resetTopInsertPoint();
+ void increaseFontSize(int numSteps = 1);
+ void decreaseFontSize();
+ virtual void resizeFont(int fontSizeSteps) SWIFTEN_OVERRIDE;
+ virtual void scrollToBottom() SWIFTEN_OVERRIDE;
+ virtual void handleKeyPressEvent(QKeyEvent* event) SWIFTEN_OVERRIDE;
+
+ private slots:
+ void handleViewLoadFinished(bool);
+ void handleFrameSizeChanged();
+ void handleClearRequested();
+ void handleHTMLButtonClicked(QString id, QString arg1, QString arg2, QString arg3, QString arg4, QString arg5);
+ void handleVerticalScrollBarPositionChanged(double position);
+
+ private:
+ enum PreviousMessageKind {
+ PreviosuMessageWasNone,
+ PreviousMessageWasMessage,
+ PreviousMessageWasSystem,
+ PreviousMessageWasPresence,
+ PreviousMessageWasFileTransfer,
+ PreviousMessageWasMUCInvite
+ };
+ std::string addMessage(
+ const QString& message,
+ const std::string& senderName,
+ bool senderIsSelf,
+ std::shared_ptr<SecurityLabel> label,
+ const std::string& avatarPath,
+ const QString& style,
+ const boost::posix_time::ptime& time,
+ const HighlightAction& highlight,
+ ChatSnippet::Direction direction);
+ void replaceMessage(
+ const QString& message,
+ const std::string& id,
+ const boost::posix_time::ptime& time,
+ const QString& style,
+ const HighlightAction& highlight);
+ bool appendToPreviousCheck(PreviousMessageKind messageKind, const std::string& senderName, bool senderIsSelf);
+ static ChatSnippet::Direction getActualDirection(const ChatWindow::ChatMessage& message, ChatWindow::Direction direction);
+ QString getHighlightSpanStart(const std::string& text, const std::string& background);
+ QString getHighlightSpanStart(const HighlightAction& highlight);
+ QString chatMessageToHTML(const ChatWindow::ChatMessage& message);
+ static QString buildChatWindowButton(const QString& name, const QString& id, const QString& arg1 = QString(), const QString& arg2 = QString(), const QString& arg3 = QString(), const QString& arg4 = QString(), const QString& arg5 = QString());
+
+ protected:
+ void resizeEvent(QResizeEvent* event) SWIFTEN_OVERRIDE;
+
+ private:
+ void headerEncode();
+ void messageEncode();
+ void addToDOM(std::shared_ptr<ChatSnippet> snippet);
+
+ QtChatWindow* window_;
+ UIEventStream* eventStream_;
+ bool viewReady_;
+ bool isAtBottom_;
+ bool topMessageAdded_;
+ int scrollBarMaximum_;
+ QtWebView* webView_;
+ QWebPage* webPage_;
+ int fontSizeSteps_;
+ QtChatTheme* theme_;
+ QWebElement lineSeparator_;
+ QWebElement lastElement_;
+ QWebElement firstElement_;
+ QWebElement document_;
+ bool disableAutoScroll_;
+ QtChatWindowJSBridge* jsBridge;
+ PreviousMessageKind previousMessageKind_;
+ bool previousMessageWasSelf_;
+ bool showEmoticons_;
+ bool insertingLastLine_;
+ int idCounter_;
+ QString previousSenderName_;
+ std::map<QString, QString> descriptions_;
+ std::map<QString, QString> filePaths_;
+ };
}
diff --git a/Swift/QtUI/QtWebView.cpp b/Swift/QtUI/QtWebView.cpp
index f9894e6..abdc17a 100644
--- a/Swift/QtUI/QtWebView.cpp
+++ b/Swift/QtUI/QtWebView.cpp
@@ -1,43 +1,56 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtWebView.h"
+#include <Swift/QtUI/QtWebView.h>
-#include <QKeyEvent>
-#include <QFocusEvent>
#include <boost/numeric/conversion/cast.hpp>
+
+#include <QFocusEvent>
+#include <QKeyEvent>
+#include <QKeySequence>
#include <QMenu>
+
#include <Swiften/Base/Log.h>
namespace Swift {
QtWebView::QtWebView(QWidget* parent) : QWebView(parent), fontSizeIsMinimal(false) {
- setRenderHint(QPainter::SmoothPixmapTransform);
- filteredActions.push_back(QWebPage::CopyLinkToClipboard);
- filteredActions.push_back(QWebPage::CopyImageToClipboard);
- filteredActions.push_back(QWebPage::Copy);
- if (Log::getLogLevel() == Log::debug) {
- filteredActions.push_back(QWebPage::InspectElement);
- }
+ setRenderHint(QPainter::SmoothPixmapTransform);
+ filteredActions.push_back(QWebPage::CopyLinkToClipboard);
+ filteredActions.push_back(QWebPage::CopyImageToClipboard);
+ filteredActions.push_back(QWebPage::Copy);
+ if (Log::getLogLevel() == Log::debug) {
+ filteredActions.push_back(QWebPage::InspectElement);
+ }
}
void QtWebView::keyPressEvent(QKeyEvent* event) {
- Qt::KeyboardModifiers modifiers = event->modifiers();
- int key = event->key();
- if (modifiers == Qt::ShiftModifier && (key == Qt::Key_PageUp || key == Qt::Key_PageDown)) {
- modifiers = Qt::NoModifier;
- }
- QKeyEvent* translatedEvent = new QKeyEvent(QEvent::KeyPress,
- key,
- modifiers,
- event->text(),
- event->isAutoRepeat(),
- boost::numeric_cast<unsigned short>(event->count()));
- QWebView::keyPressEvent(translatedEvent);
- delete translatedEvent;
+ Qt::KeyboardModifiers modifiers = event->modifiers();
+ int key = event->key();
+ if (event->matches(QKeySequence::ZoomIn)) {
+ event->accept();
+ emit fontGrowRequested();
+ return;
+ }
+ if (event->matches(QKeySequence::ZoomOut)) {
+ event->accept();
+ emit fontShrinkRequested();
+ return;
+ }
+ if (modifiers == Qt::ShiftModifier && (key == Qt::Key_PageUp || key == Qt::Key_PageDown)) {
+ modifiers = Qt::NoModifier;
+ }
+ QKeyEvent* translatedEvent = new QKeyEvent(QEvent::KeyPress,
+ key,
+ modifiers,
+ event->text(),
+ event->isAutoRepeat(),
+ boost::numeric_cast<unsigned short>(event->count()));
+ QWebView::keyPressEvent(translatedEvent);
+ delete translatedEvent;
}
void QtWebView::dragEnterEvent(QDragEnterEvent*) {
@@ -45,43 +58,43 @@ void QtWebView::dragEnterEvent(QDragEnterEvent*) {
}
void QtWebView::setFontSizeIsMinimal(bool minimum) {
- fontSizeIsMinimal = minimum;
+ fontSizeIsMinimal = minimum;
}
void QtWebView::contextMenuEvent(QContextMenuEvent* ev) {
- // Filter out the relevant actions from the standard actions
-
- QMenu* menu = page()->createStandardContextMenu();
- QList<QAction*> actions(menu->actions());
- for (int i = 0; i < actions.size(); ++i) {
- QAction* action = actions.at(i);
- bool removeAction = true;
- for(size_t j = 0; j < filteredActions.size(); ++j) {
- if (action == pageAction(filteredActions[j])) {
- removeAction = false;
- break;
- }
- }
- if (removeAction) {
- menu->removeAction(action);
- }
- }
-
- // Add our own custom actions
- menu->addAction(tr("Clear"), this, SIGNAL(clearRequested()));
- menu->addAction(tr("Increase font size"), this, SIGNAL(fontGrowRequested()));
- QAction* shrink = new QAction(tr("Decrease font size"), this);
- shrink->setEnabled(!fontSizeIsMinimal);
- connect(shrink, SIGNAL(triggered()), this, SIGNAL(fontShrinkRequested()));
- menu->addAction(shrink);
-
- menu->exec(ev->globalPos());
- delete menu;
+ // Filter out the relevant actions from the standard actions
+
+ QMenu* menu = page()->createStandardContextMenu();
+ QList<QAction*> actions(menu->actions());
+ for (auto action : actions) {
+ bool removeAction = true;
+ for(auto& filteredAction : filteredActions) {
+ if (action == pageAction(filteredAction)) {
+ removeAction = false;
+ break;
+ }
+ }
+ if (removeAction) {
+ menu->removeAction(action);
+ }
+ }
+
+ // Add our own custom actions
+ menu->addAction(tr("Clear"), this, SIGNAL(clearRequested()));
+ menu->addAction(tr("Increase font size"), this, SIGNAL(fontGrowRequested()), QKeySequence(QKeySequence::ZoomIn));
+ QAction* shrink = new QAction(tr("Decrease font size"), this);
+ shrink->setShortcut(QKeySequence(QKeySequence::ZoomOut));
+ shrink->setEnabled(!fontSizeIsMinimal);
+ connect(shrink, SIGNAL(triggered()), this, SIGNAL(fontShrinkRequested()));
+ menu->addAction(shrink);
+
+ menu->exec(ev->globalPos());
+ delete menu;
}
void QtWebView::focusInEvent(QFocusEvent* event) {
- QWebView::focusInEvent(event);
- emit gotFocus();
+ QWebView::focusInEvent(event);
+ emit gotFocus();
}
}
diff --git a/Swift/QtUI/QtWebView.h b/Swift/QtUI/QtWebView.h
index 792f5f7..985a0db 100644
--- a/Swift/QtUI/QtWebView.h
+++ b/Swift/QtUI/QtWebView.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,30 +7,31 @@
#pragma once
-#include <QWebView>
#include <vector>
+#include <QWebView>
+
namespace Swift {
- class QtWebView : public QWebView {
- Q_OBJECT
- public:
- QtWebView(QWidget* parent);
- void keyPressEvent(QKeyEvent* event);
- void dragEnterEvent(QDragEnterEvent *event);
- void contextMenuEvent(QContextMenuEvent* ev);
- void setFontSizeIsMinimal(bool minimum);
-
- signals:
- void gotFocus();
- void clearRequested();
- void fontGrowRequested();
- void fontShrinkRequested();
-
- protected:
- void focusInEvent(QFocusEvent* event);
-
- private:
- std::vector<QWebPage::WebAction> filteredActions;
- bool fontSizeIsMinimal;
- };
+ class QtWebView : public QWebView {
+ Q_OBJECT
+ public:
+ QtWebView(QWidget* parent);
+ void keyPressEvent(QKeyEvent* event);
+ void dragEnterEvent(QDragEnterEvent *event);
+ void contextMenuEvent(QContextMenuEvent* ev);
+ void setFontSizeIsMinimal(bool minimum);
+
+ signals:
+ void gotFocus();
+ void clearRequested();
+ void fontGrowRequested();
+ void fontShrinkRequested();
+
+ protected:
+ void focusInEvent(QFocusEvent* event);
+
+ private:
+ std::vector<QWebPage::WebAction> filteredActions;
+ bool fontSizeIsMinimal;
+ };
}
diff --git a/Swift/QtUI/QtWin32NotifierWindow.h b/Swift/QtUI/QtWin32NotifierWindow.h
index a586591..bf55706 100644
--- a/Swift/QtUI/QtWin32NotifierWindow.h
+++ b/Swift/QtUI/QtWin32NotifierWindow.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,22 +8,22 @@
#include <QWidget>
-#include "SwifTools/Notifier/Win32NotifierWindow.h"
+#include <SwifTools/Notifier/Win32NotifierWindow.h>
namespace Swift {
- class QtWin32NotifierWindow : public QWidget, public Win32NotifierWindow {
- public:
- QtWin32NotifierWindow(QWidget* parent = NULL) {
- setVisible(false);
- }
+ class QtWin32NotifierWindow : public QWidget, public Win32NotifierWindow {
+ public:
+ QtWin32NotifierWindow(QWidget* parent = NULL) {
+ setVisible(false);
+ }
- bool winEvent (MSG* message, long* result ) {
- onMessageReceived(message);
- return false;
- }
+ bool winEvent (MSG* message, long* result ) {
+ onMessageReceived(message);
+ return false;
+ }
- virtual HWND getID() const {
- return (HWND) winId();
- }
- };
+ virtual HWND getID() const {
+ return (HWND) winId();
+ }
+ };
}
diff --git a/Swift/QtUI/QtXMLConsoleWidget.cpp b/Swift/QtUI/QtXMLConsoleWidget.cpp
index ddb8661..a7f9702 100644
--- a/Swift/QtUI/QtXMLConsoleWidget.cpp
+++ b/Swift/QtUI/QtXMLConsoleWidget.cpp
@@ -1,19 +1,19 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtXMLConsoleWidget.h"
+#include <Swift/QtUI/QtXMLConsoleWidget.h>
#include <string>
+#include <QCheckBox>
#include <QCloseEvent>
-#include <QTextEdit>
-#include <QVBoxLayout>
#include <QPushButton>
#include <QScrollBar>
-#include <QCheckBox>
+#include <QTextEdit>
+#include <QVBoxLayout>
#include <Swiften/Base/format.h>
@@ -22,99 +22,99 @@
namespace Swift {
QtXMLConsoleWidget::QtXMLConsoleWidget() {
- setWindowTitle(tr("Console"));
+ setWindowTitle(tr("Console"));
- QVBoxLayout* layout = new QVBoxLayout(this);
- layout->setSpacing(0);
- layout->setContentsMargins(0,0,0,0);
+ QVBoxLayout* layout = new QVBoxLayout(this);
+ layout->setSpacing(0);
+ layout->setContentsMargins(0,0,0,0);
- textEdit = new QTextEdit(this);
- textEdit->setReadOnly(true);
- layout->addWidget(textEdit);
+ textEdit = new QTextEdit(this);
+ textEdit->setReadOnly(true);
+ layout->addWidget(textEdit);
- QWidget* bottom = new QWidget(this);
- layout->addWidget(bottom);
- bottom->setAutoFillBackground(true);
+ QWidget* bottom = new QWidget(this);
+ layout->addWidget(bottom);
+ bottom->setAutoFillBackground(true);
- QHBoxLayout* buttonLayout = new QHBoxLayout(bottom);
- buttonLayout->setContentsMargins(10,0,20,0);
- buttonLayout->setSpacing(0);
+ QHBoxLayout* buttonLayout = new QHBoxLayout(bottom);
+ buttonLayout->setContentsMargins(10,0,20,0);
+ buttonLayout->setSpacing(0);
- enabled = new QCheckBox(tr("Trace input/output"), bottom);
- enabled->setChecked(true);
- buttonLayout->addWidget(enabled);
+ enabled = new QCheckBox(tr("Trace input/output"), bottom);
+ enabled->setChecked(true);
+ buttonLayout->addWidget(enabled);
- buttonLayout->addStretch();
+ buttonLayout->addStretch();
- QPushButton* clearButton = new QPushButton(tr("Clear"), bottom);
- connect(clearButton, SIGNAL(clicked()), textEdit, SLOT(clear()));
- buttonLayout->addWidget(clearButton);
+ QPushButton* clearButton = new QPushButton(tr("Clear"), bottom);
+ connect(clearButton, SIGNAL(clicked()), textEdit, SLOT(clear()));
+ buttonLayout->addWidget(clearButton);
- setWindowTitle(tr("Debug Console"));
- emit titleUpdated();
+ setWindowTitle(tr("Debug Console"));
+ emit titleUpdated();
}
QtXMLConsoleWidget::~QtXMLConsoleWidget() {
}
void QtXMLConsoleWidget::showEvent(QShowEvent* event) {
- emit windowOpening();
- emit titleUpdated(); /* This just needs to be somewhere after construction */
- QWidget::showEvent(event);
+ emit windowOpening();
+ emit titleUpdated(); /* This just needs to be somewhere after construction */
+ QWidget::showEvent(event);
}
void QtXMLConsoleWidget::show() {
- QWidget::show();
- emit windowOpening();
+ QWidget::show();
+ emit windowOpening();
}
void QtXMLConsoleWidget::activate() {
- emit wantsToActivate();
+ emit wantsToActivate();
}
void QtXMLConsoleWidget::closeEvent(QCloseEvent* event) {
- emit windowClosing();
- event->accept();
+ emit windowClosing();
+ event->accept();
}
void QtXMLConsoleWidget::handleDataRead(const SafeByteArray& data) {
- boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
- std::string tag = Q2PSTRING(tr("<!-- IN %1 -->").arg(P2QSTRING(boost::posix_time::to_iso_extended_string(now))));
- appendTextIfEnabled(tag + "\n" + safeByteArrayToString(data) + "\n", QColor(33,98,33));
+ boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
+ std::string tag = Q2PSTRING(tr("<!-- IN %1 -->").arg(P2QSTRING(boost::posix_time::to_iso_extended_string(now))));
+ appendTextIfEnabled(tag + "\n" + safeByteArrayToString(data) + "\n", QColor(33,98,33));
}
void QtXMLConsoleWidget::handleDataWritten(const SafeByteArray& data) {
- boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
- std::string tag = Q2PSTRING(tr("<!-- OUT %1 -->").arg(P2QSTRING(boost::posix_time::to_iso_extended_string(now))));
- appendTextIfEnabled(tag + "\n" + safeByteArrayToString(data) + "\n", QColor(155,1,0));
+ boost::posix_time::ptime now = boost::posix_time::second_clock::local_time();
+ std::string tag = Q2PSTRING(tr("<!-- OUT %1 -->").arg(P2QSTRING(boost::posix_time::to_iso_extended_string(now))));
+ appendTextIfEnabled(tag + "\n" + safeByteArrayToString(data) + "\n", QColor(155,1,0));
}
std::string QtXMLConsoleWidget::getID() const {
- return "QtXMLConsoleWidget";
+ return "QtXMLConsoleWidget";
}
void QtXMLConsoleWidget::appendTextIfEnabled(const std::string& data, const QColor& color) {
- if (enabled->isChecked()) {
- QScrollBar* scrollBar = textEdit->verticalScrollBar();
- bool scrollToBottom = (!scrollBar || scrollBar->value() == scrollBar->maximum());
-
- QTextCursor cursor(textEdit->document());
- cursor.beginEditBlock();
- cursor.movePosition(QTextCursor::End);
- QTextCharFormat format;
- format.setForeground(QBrush(color));
- cursor.mergeCharFormat(format);
- cursor.insertText(P2QSTRING(data));
- cursor.endEditBlock();
-
- // Checking for the scrollbar again, because it could have appeared after inserting text.
- // In practice, I suspect that the scrollbar is always there, but hidden, but since we were
- // explicitly testing for this already above, I'm leaving the code in.
- scrollBar = textEdit->verticalScrollBar();
- if (scrollToBottom && scrollBar) {
- scrollBar->setValue(scrollBar->maximum());
- }
- }
+ if (enabled->isChecked()) {
+ QScrollBar* scrollBar = textEdit->verticalScrollBar();
+ bool scrollToBottom = (!scrollBar || scrollBar->value() == scrollBar->maximum());
+
+ QTextCursor cursor(textEdit->document());
+ cursor.beginEditBlock();
+ cursor.movePosition(QTextCursor::End);
+ QTextCharFormat format;
+ format.setForeground(QBrush(color));
+ cursor.mergeCharFormat(format);
+ cursor.insertText(P2QSTRING(data));
+ cursor.endEditBlock();
+
+ // Checking for the scrollbar again, because it could have appeared after inserting text.
+ // In practice, I suspect that the scrollbar is always there, but hidden, but since we were
+ // explicitly testing for this already above, I'm leaving the code in.
+ scrollBar = textEdit->verticalScrollBar();
+ if (scrollToBottom && scrollBar) {
+ scrollBar->setValue(scrollBar->maximum());
+ }
+ }
}
}
diff --git a/Swift/QtUI/QtXMLConsoleWidget.h b/Swift/QtUI/QtXMLConsoleWidget.h
index ace9bd5..ef10e63 100644
--- a/Swift/QtUI/QtXMLConsoleWidget.h
+++ b/Swift/QtUI/QtXMLConsoleWidget.h
@@ -1,42 +1,43 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/Controllers/UIInterfaces/XMLConsoleWidget.h"
-#include "QtTabbable.h"
+#include <Swift/Controllers/UIInterfaces/XMLConsoleWidget.h>
+
+#include <Swift/QtUI/QtTabbable.h>
class QTextEdit;
class QCheckBox;
class QColor;
namespace Swift {
- class QtXMLConsoleWidget : public QtTabbable, public XMLConsoleWidget {
- Q_OBJECT
+ class QtXMLConsoleWidget : public QtTabbable, public XMLConsoleWidget {
+ Q_OBJECT
- public:
- QtXMLConsoleWidget();
- ~QtXMLConsoleWidget();
+ public:
+ QtXMLConsoleWidget();
+ ~QtXMLConsoleWidget();
- void show();
- void activate();
+ void show();
+ void activate();
- virtual void handleDataRead(const SafeByteArray& data);
- virtual void handleDataWritten(const SafeByteArray& data);
+ virtual void handleDataRead(const SafeByteArray& data);
+ virtual void handleDataWritten(const SafeByteArray& data);
- virtual std::string getID() const;
+ virtual std::string getID() const;
- private:
- virtual void closeEvent(QCloseEvent* event);
- virtual void showEvent(QShowEvent* event);
+ private:
+ virtual void closeEvent(QCloseEvent* event);
+ virtual void showEvent(QShowEvent* event);
- void appendTextIfEnabled(const std::string& data, const QColor& color);
+ void appendTextIfEnabled(const std::string& data, const QColor& color);
- private:
- QTextEdit* textEdit;
- QCheckBox* enabled;
- };
+ private:
+ QTextEdit* textEdit;
+ QCheckBox* enabled;
+ };
}
diff --git a/Swift/QtUI/Roster/DelegateCommons.cpp b/Swift/QtUI/Roster/DelegateCommons.cpp
index 73cfbb5..e4a2f46 100644
--- a/Swift/QtUI/Roster/DelegateCommons.cpp
+++ b/Swift/QtUI/Roster/DelegateCommons.cpp
@@ -1,108 +1,111 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "DelegateCommons.h"
+#include <Swift/QtUI/Roster/DelegateCommons.h>
-#include <QtScaledAvatarCache.h>
+#include <QColor>
#include <QFileInfo>
-namespace Swift {
+#include <Swift/QtUI/QtScaledAvatarCache.h>
+namespace Swift {
void DelegateCommons::drawElidedText(QPainter* painter, const QRect& region, const QString& text, int flags) {
- QString adjustedText(painter->fontMetrics().elidedText(text, Qt::ElideRight, region.width(), Qt::TextShowMnemonic));
- painter->setClipRect(region);
- painter->drawText(region, flags, adjustedText.simplified());
- painter->setClipping(false);
+ QString adjustedText(painter->fontMetrics().elidedText(text, Qt::ElideRight, region.width(), Qt::TextShowMnemonic));
+ painter->setClipRect(region);
+ painter->drawText(region, flags, adjustedText.simplified());
+ painter->setClipping(false);
}
void DelegateCommons::paintContact(QPainter* painter, const QStyleOptionViewItem& option, const QColor& nameColor, const QString& avatarPath, const QIcon& presenceIcon, const QString& name, const QString& statusText, bool isIdle, int unreadCount, bool compact) const {
- painter->save();
- QRect fullRegion(option.rect);
- if ( option.state & QStyle::State_Selected ) {
- painter->fillRect(fullRegion, option.palette.highlight());
- painter->setPen(option.palette.highlightedText().color());
- } else {
- painter->setPen(QPen(nameColor));
- }
-
- QRect presenceIconRegion(QPoint(farLeftMargin, fullRegion.top()), QSize(presenceIconWidth, fullRegion.height() - verticalMargin));
-
- QRect idleIconRegion(QPoint(farLeftMargin, fullRegion.top()), QSize(presenceIconWidth*2, fullRegion.height() - verticalMargin));
- int calculatedAvatarSize = presenceIconRegion.height();
- //This overlaps the presenceIcon, so must be painted first
- QRect avatarRegion(QPoint(presenceIconRegion.right() - presenceIconWidth / 2, presenceIconRegion.top()), QSize(calculatedAvatarSize, calculatedAvatarSize));
-
- QPixmap avatarPixmap;
- if (!compact && !avatarPath.isEmpty()) {
- QString scaledAvatarPath = QtScaledAvatarCache(avatarRegion.height()).getScaledAvatarPath(avatarPath);
- if (QFileInfo(scaledAvatarPath).exists()) {
- avatarPixmap.load(scaledAvatarPath);
- }
- }
- if (!compact && avatarPixmap.isNull()) {
- avatarPixmap = QPixmap(":/icons/avatar.png").scaled(avatarRegion.height(), avatarRegion.width(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
- }
-
- if (!compact) {
- painter->drawPixmap(avatarRegion.topLeft() + QPoint(((avatarRegion.width() - avatarPixmap.width()) / 2), (avatarRegion.height() - avatarPixmap.height()) / 2), avatarPixmap);
- }
-
- //Paint the presence icon over the top of the avatar
- presenceIcon.paint(painter, presenceIconRegion, Qt::AlignBottom | Qt::AlignHCenter);
-
- if (isIdle) {
- idleIcon.paint(painter, idleIconRegion, Qt::AlignBottom | Qt::AlignHCenter);
- }
-
- QFontMetrics nameMetrics(nameFont);
- painter->setFont(nameFont);
- int extraFontWidth = nameMetrics.width("H");
- int leftOffset = (compact ? presenceIconRegion : avatarRegion).right() + horizontalMargin * 2 + extraFontWidth / 2;
- QRect textRegion(fullRegion.adjusted(leftOffset, 0, 0/*-leftOffset*/, 0));
-
- int nameHeight = nameMetrics.height() + verticalMargin;
- QRect nameRegion(textRegion.adjusted(0, verticalMargin, 0, 0));
-
- DelegateCommons::drawElidedText(painter, nameRegion, name);
-
- if (!compact) {
- painter->setFont(detailFont);
- painter->setPen(QPen(QColor(160,160,160)));
-
- QRect statusTextRegion(textRegion.adjusted(0, nameHeight, 0, 0));
- DelegateCommons::drawElidedText(painter, statusTextRegion, statusText);
- }
-
- if (unreadCount > 0) {
- QRect unreadRect(fullRegion.right() - unreadCountSize - horizontalMargin, fullRegion.top() + (fullRegion.height() - unreadCountSize) / 2, unreadCountSize, unreadCountSize);
- QPen pen(QColor("black"));
- pen.setWidth(1);
- painter->setRenderHint(QPainter::Antialiasing, true);
- painter->setPen(pen);
- painter->setBrush(QBrush(QColor("red"), Qt::SolidPattern));
- //painter->setBackgroundMode(Qt::OpaqueMode);
- painter->drawEllipse(unreadRect);
- painter->setBackgroundMode(Qt::TransparentMode);
- painter->setPen(QColor("white"));
- drawElidedText(painter, unreadRect, QString("%1").arg(unreadCount), Qt::AlignCenter);
- }
-
- painter->restore();
+ painter->save();
+ QRect fullRegion(option.rect);
+ if ( option.state & QStyle::State_Selected ) {
+ painter->fillRect(fullRegion, option.palette.highlight());
+ painter->setPen(option.palette.highlightedText().color());
+ } else {
+ painter->setPen(QPen(nameColor));
+ }
+ auto secondLineColor = painter->pen().color();
+ secondLineColor.setAlphaF(0.7);
+
+ QRect presenceIconRegion(QPoint(farLeftMargin, fullRegion.top()), QSize(presenceIconWidth, fullRegion.height() - verticalMargin));
+
+ QRect idleIconRegion(QPoint(farLeftMargin, fullRegion.top()), QSize(presenceIconWidth*2, fullRegion.height() - verticalMargin));
+ int calculatedAvatarSize = presenceIconRegion.height();
+ //This overlaps the presenceIcon, so must be painted first
+ QRect avatarRegion(QPoint(presenceIconRegion.right() - presenceIconWidth / 2, presenceIconRegion.top()), QSize(calculatedAvatarSize, calculatedAvatarSize));
+
+ QPixmap avatarPixmap;
+ if (!compact && !avatarPath.isEmpty()) {
+ QString scaledAvatarPath = QtScaledAvatarCache(avatarRegion.height()).getScaledAvatarPath(avatarPath);
+ if (QFileInfo(scaledAvatarPath).exists()) {
+ avatarPixmap.load(scaledAvatarPath);
+ }
+ }
+ if (!compact && avatarPixmap.isNull()) {
+ avatarPixmap = QPixmap(":/icons/avatar.svg").scaled(avatarRegion.height(), avatarRegion.width(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ }
+
+ if (!compact) {
+ painter->drawPixmap(avatarRegion.topLeft() + QPoint(((avatarRegion.width() - avatarPixmap.width()) / 2), (avatarRegion.height() - avatarPixmap.height()) / 2), avatarPixmap);
+ }
+
+ //Paint the presence icon over the top of the avatar
+ presenceIcon.paint(painter, presenceIconRegion, Qt::AlignBottom | Qt::AlignHCenter);
+
+ if (isIdle) {
+ idleIcon.paint(painter, idleIconRegion, Qt::AlignBottom | Qt::AlignHCenter);
+ }
+
+ QFontMetrics nameMetrics(nameFont);
+ painter->setFont(nameFont);
+ int extraFontWidth = nameMetrics.width("H");
+ int leftOffset = (compact ? presenceIconRegion : avatarRegion).right() + horizontalMargin * 2 + extraFontWidth / 2;
+ QRect textRegion(fullRegion.adjusted(leftOffset, 0, 0/*-leftOffset*/, 0));
+
+ int nameHeight = nameMetrics.height() + verticalMargin;
+ QRect nameRegion(textRegion.adjusted(0, verticalMargin, 0, 0));
+
+ DelegateCommons::drawElidedText(painter, nameRegion, name);
+
+ if (!compact) {
+ painter->setFont(detailFont);
+ painter->setPen(QPen(secondLineColor));
+
+ QRect statusTextRegion(textRegion.adjusted(0, nameHeight, 0, 0));
+ DelegateCommons::drawElidedText(painter, statusTextRegion, statusText);
+ }
+
+ if (unreadCount > 0) {
+ QRect unreadRect(fullRegion.right() - unreadCountSize - horizontalMargin, fullRegion.top() + (fullRegion.height() - unreadCountSize) / 2, unreadCountSize, unreadCountSize);
+ QPen pen(QColor("black"));
+ pen.setWidth(1);
+ painter->setRenderHint(QPainter::Antialiasing, true);
+ painter->setPen(pen);
+ painter->setBrush(QBrush(QColor("red"), Qt::SolidPattern));
+ //painter->setBackgroundMode(Qt::OpaqueMode);
+ painter->drawEllipse(unreadRect);
+ painter->setBackgroundMode(Qt::TransparentMode);
+ painter->setPen(QColor("white"));
+ drawElidedText(painter, unreadRect, QString("%1").arg(unreadCount), Qt::AlignCenter);
+ }
+
+ painter->restore();
}
QSize DelegateCommons::contactSizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/, bool compact ) const {
- int heightByAvatar = (compact ? presenceIconHeight : avatarSize) + verticalMargin * 2;
- QFontMetrics nameMetrics(nameFont);
- QFontMetrics statusMetrics(detailFont);
- int sizeByText = 2 * verticalMargin + nameMetrics.height() + (compact ? 0 : statusMetrics.height());
- //Doesn't work, yay! FIXME: why?
- //QSize size = (option.state & QStyle::State_Selected) ? QSize(150, 80) : QSize(150, avatarSize_ + margin_ * 2);
- //qDebug() << "Returning size" << size;
- return QSize(150, sizeByText > heightByAvatar ? sizeByText : heightByAvatar);
+ int heightByAvatar = (compact ? presenceIconHeight : avatarSize) + verticalMargin * 2;
+ QFontMetrics nameMetrics(nameFont);
+ QFontMetrics statusMetrics(detailFont);
+ int sizeByText = 2 * verticalMargin + nameMetrics.height() + (compact ? 0 : statusMetrics.height());
+ //Doesn't work, yay! FIXME: why?
+ //QSize size = (option.state & QStyle::State_Selected) ? QSize(150, 80) : QSize(150, avatarSize_ + margin_ * 2);
+ //qDebug() << "Returning size" << size;
+ return QSize(150, sizeByText > heightByAvatar ? sizeByText : heightByAvatar);
}
const int DelegateCommons::horizontalMargin = 2;
diff --git a/Swift/QtUI/Roster/DelegateCommons.h b/Swift/QtUI/Roster/DelegateCommons.h
index 084d41f..74b08f2 100644
--- a/Swift/QtUI/Roster/DelegateCommons.h
+++ b/Swift/QtUI/Roster/DelegateCommons.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,36 +8,36 @@
#include <QApplication>
#include <QFont>
+#include <QIcon>
#include <QPainter>
#include <QRect>
#include <QString>
-#include <QIcon>
#include <QStyleOptionViewItem>
namespace Swift {
- class DelegateCommons {
- public:
- DelegateCommons() : nameFont(QApplication::font()), detailFont(QApplication::font()), idleIcon(QIcon(":/icons/zzz.png")) {
- detailFontSizeDrop = nameFont.pointSize() >= 10 ? 2 : 0;
- detailFont.setStyle(QFont::StyleItalic);
- detailFont.setPointSize(nameFont.pointSize() - detailFontSizeDrop);
- }
+ class DelegateCommons {
+ public:
+ DelegateCommons() : nameFont(QApplication::font()), detailFont(QApplication::font()), idleIcon(QIcon(":/icons/zzz.png")) {
+ detailFontSizeDrop = nameFont.pointSize() >= 10 ? 2 : 0;
+ detailFont.setStyle(QFont::StyleItalic);
+ detailFont.setPointSize(nameFont.pointSize() - detailFontSizeDrop);
+ }
- static void drawElidedText(QPainter* painter, const QRect& region, const QString& text, int flags = Qt::AlignTop);
+ static void drawElidedText(QPainter* painter, const QRect& region, const QString& text, int flags = Qt::AlignTop);
- QSize contactSizeHint(const QStyleOptionViewItem& option, const QModelIndex& index, bool compact) const;
- void paintContact(QPainter* painter, const QStyleOptionViewItem& option, const QColor& nameColor, const QString& avatarPath, const QIcon& presenceIcon, const QString& name, const QString& statusText, bool isIdle, int unreadCount, bool compact) const;
+ QSize contactSizeHint(const QStyleOptionViewItem& option, const QModelIndex& index, bool compact) const;
+ void paintContact(QPainter* painter, const QStyleOptionViewItem& option, const QColor& nameColor, const QString& avatarPath, const QIcon& presenceIcon, const QString& name, const QString& statusText, bool isIdle, int unreadCount, bool compact) const;
- int detailFontSizeDrop;
- QFont nameFont;
- QFont detailFont;
- static const int horizontalMargin;
- static const int verticalMargin;
- static const int farLeftMargin;
- static const int avatarSize;
- static const int presenceIconHeight;
- static const int presenceIconWidth;
- static const int unreadCountSize;
- QIcon idleIcon;
- };
+ int detailFontSizeDrop;
+ QFont nameFont;
+ QFont detailFont;
+ static const int horizontalMargin;
+ static const int verticalMargin;
+ static const int farLeftMargin;
+ static const int avatarSize;
+ static const int presenceIconHeight;
+ static const int presenceIconWidth;
+ static const int unreadCountSize;
+ QIcon idleIcon;
+ };
}
diff --git a/Swift/QtUI/Roster/GroupItemDelegate.cpp b/Swift/QtUI/Roster/GroupItemDelegate.cpp
index a9942f8..0356aa0 100644
--- a/Swift/QtUI/Roster/GroupItemDelegate.cpp
+++ b/Swift/QtUI/Roster/GroupItemDelegate.cpp
@@ -1,10 +1,10 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "GroupItemDelegate.h"
+#include <Swift/QtUI/Roster/GroupItemDelegate.h>
#include <QPainter>
#include <QPen>
@@ -13,100 +13,100 @@
namespace Swift {
GroupItemDelegate::GroupItemDelegate() : groupFont_(QApplication::font()) {
- groupFont_.setPointSize(common_.nameFont.pointSize() - common_.detailFontSizeDrop);
- groupFont_.setWeight(QFont::Bold);
+ groupFont_.setPointSize(common_.nameFont.pointSize() - common_.detailFontSizeDrop);
+ groupFont_.setWeight(QFont::Bold);
}
QSize GroupItemDelegate::sizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/) const {
- QFontMetrics groupMetrics(groupFont_);
- return QSize(150, groupMetrics.height() + common_.verticalMargin + 2);
+ QFontMetrics groupMetrics(groupFont_);
+ return QSize(150, groupMetrics.height() + common_.verticalMargin + 2);
}
void GroupItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QString& name, int rowCount, bool expanded) const {
- painter->save();
- painter->setPen(QPen(QColor(189, 189, 189)));
- //FIXME: It looks like Qt is passing us a rectangle that's too small
- //This deliberately draws outside the lines, and we need to find a better solution.
- int correctionAmount = groupCornerRadius_ > 0 ? 0 : 1;
- QRect region(QPoint(option.rect.left() - correctionAmount, option.rect.top()), QSize(option.rect.width() + correctionAmount, option.rect.height() - common_.verticalMargin));
- QLinearGradient fillGradient(region.topLeft(), region.bottomLeft());
- fillGradient.setColorAt(0, QColor(244, 244, 244));
- fillGradient.setColorAt(0.1, QColor(231, 231, 231));
- fillGradient.setColorAt(1, QColor(209, 209, 209));
-
- QBrush backgroundBrush = QBrush(fillGradient);
- QPainterPath fillPath;
- fillPath.addRoundedRect(region, groupCornerRadius_, groupCornerRadius_);
- QPainterPath linePath;
- linePath.addRoundedRect(region, groupCornerRadius_, groupCornerRadius_);
- painter->fillPath(fillPath, backgroundBrush);
- painter->drawPath(linePath);
-
- int triangleHorizontalOffset = 1;
- int triangleWidth = 9;
- int triangleHeight = 5;
- paintExpansionTriangle(painter, region.adjusted(common_.horizontalMargin + triangleHorizontalOffset + 1, 0, 0, 0), triangleWidth, triangleHeight, expanded);
-
- int textLeftOffset = 3 * common_.horizontalMargin + 1 + triangleWidth + triangleHorizontalOffset;
- QFontMetrics fontMetrics(groupFont_);
- int textTopOffset = (region.height() - fontMetrics.height()) / 2;
- painter->setFont(groupFont_);
- int contactCountWidth = 0;
- QRect textRect = region.adjusted(textLeftOffset, textTopOffset, -1 * textLeftOffset, -1 * textTopOffset);
-
- if (!expanded) {
- QFontMetrics groupMetrics(groupFont_);
- int contactCount = rowCount;
- QString countString = QString("%1").arg(contactCount);
- contactCountWidth = groupMetrics.width(countString) + 2 * common_.horizontalMargin;
- int offsetAmount = textRect.width() - contactCountWidth + common_.horizontalMargin;
- QRect countRect = textRect.adjusted(offsetAmount, 0, 0/*-1 * offsetAmount*/, 0);
- paintShadowText(painter, countRect, countString);
- }
- QRect nameTextRect = expanded ? textRect : textRect.adjusted(0, 0, -contactCountWidth, 0);
- QString elidedName = fontMetrics.elidedText(name, Qt::ElideRight, nameTextRect.width(), Qt::TextShowMnemonic);
- paintShadowText(painter, nameTextRect, elidedName);
- painter->restore();
+ painter->save();
+ painter->setPen(QPen(QColor(189, 189, 189)));
+ //FIXME: It looks like Qt is passing us a rectangle that's too small
+ //This deliberately draws outside the lines, and we need to find a better solution.
+ int correctionAmount = groupCornerRadius_ > 0 ? 0 : 1;
+ QRect region(QPoint(option.rect.left() - correctionAmount, option.rect.top()), QSize(option.rect.width() + correctionAmount, option.rect.height() - common_.verticalMargin));
+ QLinearGradient fillGradient(region.topLeft(), region.bottomLeft());
+ fillGradient.setColorAt(0, QColor(244, 244, 244));
+ fillGradient.setColorAt(0.1, QColor(231, 231, 231));
+ fillGradient.setColorAt(1, QColor(209, 209, 209));
+
+ QBrush backgroundBrush = QBrush(fillGradient);
+ QPainterPath fillPath;
+ fillPath.addRoundedRect(region, groupCornerRadius_, groupCornerRadius_);
+ QPainterPath linePath;
+ linePath.addRoundedRect(region, groupCornerRadius_, groupCornerRadius_);
+ painter->fillPath(fillPath, backgroundBrush);
+ painter->drawPath(linePath);
+
+ int triangleHorizontalOffset = 1;
+ int triangleWidth = 9;
+ int triangleHeight = 5;
+ paintExpansionTriangle(painter, region.adjusted(common_.horizontalMargin + triangleHorizontalOffset + 1, 0, 0, 0), triangleWidth, triangleHeight, expanded);
+
+ int textLeftOffset = 3 * common_.horizontalMargin + 1 + triangleWidth + triangleHorizontalOffset;
+ QFontMetrics fontMetrics(groupFont_);
+ int textTopOffset = (region.height() - fontMetrics.height()) / 2;
+ painter->setFont(groupFont_);
+ int contactCountWidth = 0;
+ QRect textRect = region.adjusted(textLeftOffset, textTopOffset, -1 * textLeftOffset, -1 * textTopOffset);
+
+ if (!expanded) {
+ QFontMetrics groupMetrics(groupFont_);
+ int contactCount = rowCount;
+ QString countString = QString("%1").arg(contactCount);
+ contactCountWidth = groupMetrics.width(countString) + 2 * common_.horizontalMargin;
+ int offsetAmount = textRect.width() - contactCountWidth + common_.horizontalMargin;
+ QRect countRect = textRect.adjusted(offsetAmount, 0, 0/*-1 * offsetAmount*/, 0);
+ paintShadowText(painter, countRect, countString);
+ }
+ QRect nameTextRect = expanded ? textRect : textRect.adjusted(0, 0, -contactCountWidth, 0);
+ QString elidedName = fontMetrics.elidedText(name, Qt::ElideRight, nameTextRect.width(), Qt::TextShowMnemonic);
+ paintShadowText(painter, nameTextRect, elidedName);
+ painter->restore();
}
void GroupItemDelegate::paintExpansionTriangle(QPainter* painter, const QRect& region, int width, int height, bool expanded) const {
- // height is the height of the downward pointing triangle
- QPolygonF triangle;
- if (expanded) {
- QPointF triangleTopLeft(region.left(), region.top() + region.height() / 2 - height / 2);
- triangle << triangleTopLeft;
- triangle << triangleTopLeft + QPointF(width, 0);
- triangle << triangleTopLeft + QPointF(width / 2, height);
- // The expanded triangle should be a little lower, because its pointy shape makes it feel
- // as if it's too high.
- triangle.translate(QPointF(0,1));
- }
- else {
- QPointF triangleTopLeft(region.left() + ((width - height) / 2), region.top() + region.height() / 2 - width / 2);
- triangle << triangleTopLeft;
- triangle << triangleTopLeft + QPointF(height, width / 2);
- triangle << triangleTopLeft + QPointF(0, width);
- }
- //qDebug() << "Painting triangle: " << triangle;
-
- QPolygonF triangleShadow(triangle);
- triangleShadow.translate(QPointF(0, -1));
-
- QPainterPath trianglePath;
- QPainterPath triangleShadowPath;
- QBrush triangleBrush(QColor(110, 110, 110));
- QBrush triangleShadowBrush(QColor(47, 47, 47));
- trianglePath.addPolygon(triangle);
- triangleShadowPath.addPolygon(triangleShadow);
- painter->fillPath(triangleShadowPath, triangleShadowBrush);
- painter->fillPath(trianglePath, triangleBrush);
+ // height is the height of the downward pointing triangle
+ QPolygonF triangle;
+ if (expanded) {
+ QPointF triangleTopLeft(region.left(), region.top() + region.height() / 2 - height / 2);
+ triangle << triangleTopLeft;
+ triangle << triangleTopLeft + QPointF(width, 0);
+ triangle << triangleTopLeft + QPointF(width / 2, height);
+ // The expanded triangle should be a little lower, because its pointy shape makes it feel
+ // as if it's too high.
+ triangle.translate(QPointF(0,1));
+ }
+ else {
+ QPointF triangleTopLeft(region.left() + ((width - height) / 2), region.top() + region.height() / 2 - width / 2);
+ triangle << triangleTopLeft;
+ triangle << triangleTopLeft + QPointF(height, width / 2);
+ triangle << triangleTopLeft + QPointF(0, width);
+ }
+ //qDebug() << "Painting triangle: " << triangle;
+
+ QPolygonF triangleShadow(triangle);
+ triangleShadow.translate(QPointF(0, -1));
+
+ QPainterPath trianglePath;
+ QPainterPath triangleShadowPath;
+ QBrush triangleBrush(QColor(110, 110, 110));
+ QBrush triangleShadowBrush(QColor(47, 47, 47));
+ trianglePath.addPolygon(triangle);
+ triangleShadowPath.addPolygon(triangleShadow);
+ painter->fillPath(triangleShadowPath, triangleShadowBrush);
+ painter->fillPath(trianglePath, triangleBrush);
}
void GroupItemDelegate::paintShadowText(QPainter* painter, const QRect& region, const QString& text) const {
- painter->setPen(QPen(QColor(254, 254, 254)));
- painter->drawText(region.adjusted(0, 1, 0, 0), Qt::AlignTop, text);
- painter->setPen(QPen(QColor(115, 115, 115)));
- painter->drawText(region, Qt::AlignTop, text);
+ painter->setPen(QPen(QColor(254, 254, 254)));
+ painter->drawText(region.adjusted(0, 1, 0, 0), Qt::AlignTop, text);
+ painter->setPen(QPen(QColor(115, 115, 115)));
+ painter->drawText(region, Qt::AlignTop, text);
}
const int GroupItemDelegate::groupCornerRadius_ = 0;
diff --git a/Swift/QtUI/Roster/GroupItemDelegate.h b/Swift/QtUI/Roster/GroupItemDelegate.h
index 859f3ec..f989ed0 100644
--- a/Swift/QtUI/Roster/GroupItemDelegate.h
+++ b/Swift/QtUI/Roster/GroupItemDelegate.h
@@ -1,29 +1,29 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <QStyledItemDelegate>
#include <QColor>
#include <QFont>
+#include <QStyledItemDelegate>
-#include "DelegateCommons.h"
+#include <Swift/QtUI/Roster/DelegateCommons.h>
namespace Swift {
- class QtTreeWidgetItem;
- class GroupItemDelegate {
- public:
- GroupItemDelegate();
- QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
- void paint(QPainter* painter, const QStyleOptionViewItem& option, const QString& name, int rowCount, bool expanded) const;
- private:
- void paintShadowText(QPainter* painter, const QRect& region, const QString& text) const;
- void paintExpansionTriangle(QPainter* painter, const QRect& region, int width, int height, bool expanded) const;
- QFont groupFont_;
- static const int groupCornerRadius_;
- DelegateCommons common_;
- };
+ class QtTreeWidgetItem;
+ class GroupItemDelegate {
+ public:
+ GroupItemDelegate();
+ QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ void paint(QPainter* painter, const QStyleOptionViewItem& option, const QString& name, int rowCount, bool expanded) const;
+ private:
+ void paintShadowText(QPainter* painter, const QRect& region, const QString& text) const;
+ void paintExpansionTriangle(QPainter* painter, const QRect& region, int width, int height, bool expanded) const;
+ QFont groupFont_;
+ static const int groupCornerRadius_;
+ DelegateCommons common_;
+ };
}
diff --git a/Swift/QtUI/Roster/QtFilterWidget.cpp b/Swift/QtUI/Roster/QtFilterWidget.cpp
index acfd50f..2e1ead9 100644
--- a/Swift/QtUI/Roster/QtFilterWidget.cpp
+++ b/Swift/QtUI/Roster/QtFilterWidget.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -10,6 +10,8 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+#include <Swift/QtUI/Roster/QtFilterWidget.h>
+
#include <QEvent>
#include <QKeyEvent>
#include <QLayout>
@@ -18,31 +20,31 @@
#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
+
#include <Swift/QtUI/QtClosableLineEdit.h>
#include <Swift/QtUI/QtSwiftUtil.h>
-#include <Swift/QtUI/Roster/QtFilterWidget.h>
namespace Swift {
-QtFilterWidget::QtFilterWidget(QWidget* parent, QtTreeWidget* treeView, UIEventStream* eventStream, QBoxLayout* layout) : QWidget(parent), treeView_(treeView), eventStream_(eventStream), fuzzyRosterFilter_(0), isModifierSinglePressed_(false) {
- int targetIndex = layout->indexOf(treeView);
+QtFilterWidget::QtFilterWidget(QWidget* parent, QtTreeWidget* treeView, UIEventStream* eventStream, QBoxLayout* layout) : QWidget(parent), treeView_(treeView), eventStream_(eventStream), fuzzyRosterFilter_(nullptr), isModifierSinglePressed_(false) {
+ int targetIndex = layout->indexOf(treeView);
- QVBoxLayout* vboxLayout = new QVBoxLayout(this);
- vboxLayout->setSpacing(0);
- vboxLayout->setContentsMargins(0,0,0,0);
+ QVBoxLayout* vboxLayout = new QVBoxLayout(this);
+ vboxLayout->setSpacing(0);
+ vboxLayout->setContentsMargins(0,0,0,0);
- filterLineEdit_ = new QtClosableLineEdit(this);
- filterLineEdit_->hide();
- vboxLayout->addWidget(filterLineEdit_);
+ filterLineEdit_ = new QtClosableLineEdit(this);
+ filterLineEdit_->hide();
+ vboxLayout->addWidget(filterLineEdit_);
- vboxLayout->addWidget(treeView);
- setLayout(vboxLayout);
- layout->insertWidget(targetIndex, this);
+ vboxLayout->addWidget(treeView);
+ setLayout(vboxLayout);
+ layout->insertWidget(targetIndex, this);
- filterLineEdit_->installEventFilter(this);
- treeView->installEventFilter(this);
+ filterLineEdit_->installEventFilter(this);
+ treeView->installEventFilter(this);
- sourceModel_ = treeView_->model();
+ sourceModel_ = treeView_->model();
}
QtFilterWidget::~QtFilterWidget() {
@@ -50,118 +52,118 @@ QtFilterWidget::~QtFilterWidget() {
}
bool QtFilterWidget::eventFilter(QObject*, QEvent* event) {
- if (event->type() == QEvent::KeyPress ||
- event->type() == QEvent::KeyRelease ||
- // InputMethodQuery got introduced in Qt 5.
+ if (event->type() == QEvent::KeyPress ||
+ event->type() == QEvent::KeyRelease ||
+ // InputMethodQuery got introduced in Qt 5.
#if QT_VERSION >= 0x050000
- event->type() == QEvent::InputMethodQuery ||
+ event->type() == QEvent::InputMethodQuery ||
#endif
- event->type() == QEvent::InputMethod) {
- event->ignore();
- QKeyEvent* keyEvent = dynamic_cast<QKeyEvent*>(event);
- if (keyEvent) {
- if (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down) {
- return false;
- } else if ((keyEvent->key() == Qt::Key_Left || keyEvent->key() == Qt::Key_Right) && filterLineEdit_->text().isEmpty()) {
- return false;
- } else if (keyEvent->key() == Qt::Key_Alt && event->type() == QEvent::KeyPress) {
- isModifierSinglePressed_ = true;
- } else if ((keyEvent->key() == Qt::Key_Alt && event->type() == QEvent::KeyRelease && isModifierSinglePressed_)
- || (keyEvent->key() == Qt::Key_Menu)) {
- QPoint itemOffset(2,2);
- QPoint contextMenuPosition = treeView_->visualRect(treeView_->currentIndex()).topLeft() + itemOffset;;
- QApplication::postEvent(treeView_, new QContextMenuEvent(QContextMenuEvent::Keyboard, contextMenuPosition, treeView_->mapToGlobal(contextMenuPosition)));
- return true;
- } else if (keyEvent->key() == Qt::Key_Return) {
- JID target = treeView_->selectedJID();
- if (target.isValid()) {
- eventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(target)));
- }
- filterLineEdit_->setText("");
- updateRosterFilters();
- } else if (keyEvent->key() == Qt::Key_Escape) {
- filterLineEdit_->setText("");
- } else {
- isModifierSinglePressed_ = false;
- }
- }
-
- filterLineEdit_->event(event);
-
- if (event->type() == QEvent::KeyRelease) {
- updateRosterFilters();
- }
- return true;
- }
- return false;
+ event->type() == QEvent::InputMethod) {
+ event->ignore();
+ QKeyEvent* keyEvent = dynamic_cast<QKeyEvent*>(event);
+ if (keyEvent) {
+ if (keyEvent->key() == Qt::Key_Up || keyEvent->key() == Qt::Key_Down) {
+ return false;
+ } else if ((keyEvent->key() == Qt::Key_Left || keyEvent->key() == Qt::Key_Right) && filterLineEdit_->text().isEmpty()) {
+ return false;
+ } else if (keyEvent->key() == Qt::Key_Alt && event->type() == QEvent::KeyPress) {
+ isModifierSinglePressed_ = true;
+ } else if ((keyEvent->key() == Qt::Key_Alt && event->type() == QEvent::KeyRelease && isModifierSinglePressed_)
+ || (keyEvent->key() == Qt::Key_Menu)) {
+ QPoint itemOffset(2,2);
+ QPoint contextMenuPosition = treeView_->visualRect(treeView_->currentIndex()).topLeft() + itemOffset;;
+ QApplication::postEvent(treeView_, new QContextMenuEvent(QContextMenuEvent::Keyboard, contextMenuPosition, treeView_->mapToGlobal(contextMenuPosition)));
+ return true;
+ } else if (keyEvent->key() == Qt::Key_Return) {
+ JID target = treeView_->selectedJID();
+ if (target.isValid()) {
+ eventStream_->send(std::make_shared<RequestChatUIEvent>(target));
+ }
+ filterLineEdit_->setText("");
+ updateRosterFilters();
+ } else if (keyEvent->key() == Qt::Key_Escape) {
+ filterLineEdit_->setText("");
+ } else {
+ isModifierSinglePressed_ = false;
+ }
+ }
+
+ filterLineEdit_->event(event);
+
+ if (event->type() == QEvent::KeyRelease) {
+ updateRosterFilters();
+ }
+ return true;
+ }
+ return false;
}
void QtFilterWidget::popAllFilters() {
- std::vector<RosterFilter*> filters = treeView_->getRoster()->getFilters();
- foreach(RosterFilter* filter, filters) {
- filters_.push_back(filter);
- treeView_->getRoster()->removeFilter(filter);
- }
- treeView_->getRoster()->onFilterAdded.connect(boost::bind(&QtFilterWidget::handleFilterAdded, this, _1));
- treeView_->getRoster()->onFilterRemoved.connect(boost::bind(&QtFilterWidget::handleFilterRemoved, this, _1));
+ std::vector<RosterFilter*> filters = treeView_->getRoster()->getFilters();
+ for (auto filter : filters) {
+ filters_.push_back(filter);
+ treeView_->getRoster()->removeFilter(filter);
+ }
+ treeView_->getRoster()->onFilterAdded.connect(boost::bind(&QtFilterWidget::handleFilterAdded, this, _1));
+ treeView_->getRoster()->onFilterRemoved.connect(boost::bind(&QtFilterWidget::handleFilterRemoved, this, _1));
}
void QtFilterWidget::pushAllFilters() {
- treeView_->getRoster()->onFilterAdded.disconnect(boost::bind(&QtFilterWidget::handleFilterAdded, this, _1));
- treeView_->getRoster()->onFilterRemoved.disconnect(boost::bind(&QtFilterWidget::handleFilterRemoved, this, _1));
- foreach(RosterFilter* filter, filters_) {
- treeView_->getRoster()->addFilter(filter);
- }
- filters_.clear();
+ treeView_->getRoster()->onFilterAdded.disconnect(boost::bind(&QtFilterWidget::handleFilterAdded, this, _1));
+ treeView_->getRoster()->onFilterRemoved.disconnect(boost::bind(&QtFilterWidget::handleFilterRemoved, this, _1));
+ for (auto filter : filters_) {
+ treeView_->getRoster()->addFilter(filter);
+ }
+ filters_.clear();
}
void QtFilterWidget::updateRosterFilters() {
- if (fuzzyRosterFilter_) {
- if (filterLineEdit_->text().isEmpty()) {
- // remove currently installed search filter and put old filters back
- treeView_->getRoster()->removeFilter(fuzzyRosterFilter_);
- delete fuzzyRosterFilter_;
- fuzzyRosterFilter_ = NULL;
- pushAllFilters();
- } else {
- // remove currently intsalled search filter and put new search filter in place
- updateSearchFilter();
- }
- } else {
- if (!filterLineEdit_->text().isEmpty()) {
- // remove currently installed filters and put a search filter in place
- popAllFilters();
- updateSearchFilter();
- }
- }
- filterLineEdit_->setVisible(!filterLineEdit_->text().isEmpty());
+ if (fuzzyRosterFilter_) {
+ if (filterLineEdit_->text().isEmpty()) {
+ // remove currently installed search filter and put old filters back
+ treeView_->getRoster()->removeFilter(fuzzyRosterFilter_);
+ delete fuzzyRosterFilter_;
+ fuzzyRosterFilter_ = nullptr;
+ pushAllFilters();
+ } else {
+ // remove currently intsalled search filter and put new search filter in place
+ updateSearchFilter();
+ }
+ } else {
+ if (!filterLineEdit_->text().isEmpty()) {
+ // remove currently installed filters and put a search filter in place
+ popAllFilters();
+ updateSearchFilter();
+ }
+ }
+ filterLineEdit_->setVisible(!filterLineEdit_->text().isEmpty());
}
void QtFilterWidget::updateSearchFilter() {
- if (fuzzyRosterFilter_) {
- treeView_->getRoster()->removeFilter(fuzzyRosterFilter_);
- delete fuzzyRosterFilter_;
- fuzzyRosterFilter_ = NULL;
- }
- fuzzyRosterFilter_ = new FuzzyRosterFilter(Q2PSTRING(filterLineEdit_->text()));
- treeView_->getRoster()->addFilter(fuzzyRosterFilter_);
- treeView_->setCurrentIndex(sourceModel_->index(0, 0, sourceModel_->index(0,0)));
+ if (fuzzyRosterFilter_) {
+ treeView_->getRoster()->removeFilter(fuzzyRosterFilter_);
+ delete fuzzyRosterFilter_;
+ fuzzyRosterFilter_ = nullptr;
+ }
+ fuzzyRosterFilter_ = new FuzzyRosterFilter(Q2PSTRING(filterLineEdit_->text()));
+ treeView_->getRoster()->addFilter(fuzzyRosterFilter_);
+ treeView_->setCurrentIndex(sourceModel_->index(0, 0, sourceModel_->index(0,0)));
}
void QtFilterWidget::handleFilterAdded(RosterFilter* filter) {
- if (filter != fuzzyRosterFilter_) {
- filterLineEdit_->setText("");
- updateRosterFilters();
- }
+ if (filter != fuzzyRosterFilter_) {
+ filterLineEdit_->setText("");
+ updateRosterFilters();
+ }
}
void QtFilterWidget::handleFilterRemoved(RosterFilter* filter) {
- /* make sure we don't end up adding this one back in later */
- filters_.erase(std::remove(filters_.begin(), filters_.end(), filter), filters_.end());
- if (filter != fuzzyRosterFilter_) {
- filterLineEdit_->setText("");
- updateRosterFilters();
- }
+ /* make sure we don't end up adding this one back in later */
+ filters_.erase(std::remove(filters_.begin(), filters_.end(), filter), filters_.end());
+ if (filter != fuzzyRosterFilter_) {
+ filterLineEdit_->setText("");
+ updateRosterFilters();
+ }
}
}
diff --git a/Swift/QtUI/Roster/QtFilterWidget.h b/Swift/QtUI/Roster/QtFilterWidget.h
index d0307ea..ea3c325 100644
--- a/Swift/QtUI/Roster/QtFilterWidget.h
+++ b/Swift/QtUI/Roster/QtFilterWidget.h
@@ -4,6 +4,12 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <vector>
@@ -11,8 +17,8 @@
#include <QBoxLayout>
#include <QWidget>
-#include <Swift/Controllers/Roster/RosterFilter.h>
#include <Swift/Controllers/Roster/FuzzyRosterFilter.h>
+#include <Swift/Controllers/Roster/RosterFilter.h>
#include <Swift/QtUI/Roster/QtTreeWidget.h>
@@ -20,32 +26,32 @@ namespace Swift {
class UIEventStream;
class QtClosableLineEdit;
class QtFilterWidget : public QWidget {
- Q_OBJECT
- public:
- QtFilterWidget(QWidget* parent, QtTreeWidget* treeView, UIEventStream* eventStream, QBoxLayout* layout = 0);
- virtual ~QtFilterWidget();
-
- protected:
- bool eventFilter(QObject*, QEvent* event);
-
- private:
- void popAllFilters();
- void pushAllFilters();
-
- void updateRosterFilters();
- void updateSearchFilter();
-
- void handleFilterAdded(RosterFilter* filter);
- void handleFilterRemoved(RosterFilter* filter);
-
- private:
- QtClosableLineEdit* filterLineEdit_;
- QtTreeWidget* treeView_;
- UIEventStream* eventStream_;
- std::vector<RosterFilter*> filters_;
- QAbstractItemModel* sourceModel_;
- FuzzyRosterFilter* fuzzyRosterFilter_;
- bool isModifierSinglePressed_;
+ Q_OBJECT
+ public:
+ QtFilterWidget(QWidget* parent, QtTreeWidget* treeView, UIEventStream* eventStream, QBoxLayout* layout = nullptr);
+ virtual ~QtFilterWidget();
+
+ protected:
+ bool eventFilter(QObject*, QEvent* event);
+
+ private:
+ void popAllFilters();
+ void pushAllFilters();
+
+ void updateRosterFilters();
+ void updateSearchFilter();
+
+ void handleFilterAdded(RosterFilter* filter);
+ void handleFilterRemoved(RosterFilter* filter);
+
+ private:
+ QtClosableLineEdit* filterLineEdit_;
+ QtTreeWidget* treeView_;
+ UIEventStream* eventStream_;
+ std::vector<RosterFilter*> filters_;
+ QAbstractItemModel* sourceModel_;
+ FuzzyRosterFilter* fuzzyRosterFilter_;
+ bool isModifierSinglePressed_;
};
}
diff --git a/Swift/QtUI/Roster/QtOccupantListWidget.cpp b/Swift/QtUI/Roster/QtOccupantListWidget.cpp
index 4d7a543..a12863d 100644
--- a/Swift/QtUI/Roster/QtOccupantListWidget.cpp
+++ b/Swift/QtUI/Roster/QtOccupantListWidget.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2014 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,10 +7,10 @@
#include <Swift/QtUI/Roster/QtOccupantListWidget.h>
-#include <QContextMenuEvent>
-#include <QMenu>
#include <QAction>
+#include <QContextMenuEvent>
#include <QInputDialog>
+#include <QMenu>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
#include <Swift/Controllers/Roster/GroupRosterItem.h>
@@ -29,47 +29,47 @@ QtOccupantListWidget::~QtOccupantListWidget() {
}
void QtOccupantListWidget::setAvailableOccupantActions(const std::vector<ChatWindow::OccupantAction>& actions) {
- availableOccupantActions_ = actions;
+ availableOccupantActions_ = actions;
}
void QtOccupantListWidget::contextMenuEvent(QContextMenuEvent* event) {
- QModelIndex index = indexAt(event->pos());
- if (!index.isValid()) {
- return;
- }
+ QModelIndex index = indexAt(event->pos());
+ if (!index.isValid()) {
+ return;
+ }
- RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- if (contact) {
- onSomethingSelectedChanged(contact);
- QMenu contextMenu;
- if (availableOccupantActions_.empty()) {
- QAction* noAction = contextMenu.addAction(tr("No actions for this user"));
- noAction->setEnabled(false);
- contextMenu.exec(event->globalPos());
- }
- else {
- std::map<QAction*, ChatWindow::OccupantAction> actions;
- foreach (ChatWindow::OccupantAction availableAction, availableOccupantActions_) {
- QString text = "Error: missing string";
- switch (availableAction) {
- case ChatWindow::Kick: text = tr("Kick user"); break;
- case ChatWindow::Ban: text = tr("Kick and ban user"); break;
- case ChatWindow::MakeModerator: text = tr("Make moderator"); break;
- case ChatWindow::MakeParticipant: text = tr("Make participant"); break;
- case ChatWindow::MakeVisitor: text = tr("Remove voice"); break;
- case ChatWindow::AddContact: text = tr("Add to contacts"); break;
- case ChatWindow::ShowProfile: text = tr("Show profile"); break;
- }
- QAction* action = contextMenu.addAction(text);
- actions[action] = availableAction;
- }
- QAction* result = contextMenu.exec(event->globalPos());
- if (result) {
- onOccupantActionSelected(actions[result], contact);
- }
- }
- }
+ RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (contact) {
+ onSomethingSelectedChanged(contact);
+ QMenu contextMenu;
+ if (availableOccupantActions_.empty()) {
+ QAction* noAction = contextMenu.addAction(tr("No actions for this user"));
+ noAction->setEnabled(false);
+ contextMenu.exec(event->globalPos());
+ }
+ else {
+ std::map<QAction*, ChatWindow::OccupantAction> actions;
+ for (const auto& availableAction : availableOccupantActions_) {
+ QString text = "Error: missing string";
+ switch (availableAction) {
+ case ChatWindow::Kick: text = tr("Kick user"); break;
+ case ChatWindow::Ban: text = tr("Kick and ban user"); break;
+ case ChatWindow::MakeModerator: text = tr("Make moderator"); break;
+ case ChatWindow::MakeParticipant: text = tr("Make participant"); break;
+ case ChatWindow::MakeVisitor: text = tr("Remove voice"); break;
+ case ChatWindow::AddContact: text = tr("Add to contacts"); break;
+ case ChatWindow::ShowProfile: text = tr("Show profile"); break;
+ }
+ QAction* action = contextMenu.addAction(text);
+ actions[action] = availableAction;
+ }
+ QAction* result = contextMenu.exec(event->globalPos());
+ if (result) {
+ onOccupantActionSelected(actions[result], contact);
+ }
+ }
+ }
}
}
diff --git a/Swift/QtUI/Roster/QtOccupantListWidget.h b/Swift/QtUI/Roster/QtOccupantListWidget.h
index 645c21a..0f80943 100644
--- a/Swift/QtUI/Roster/QtOccupantListWidget.h
+++ b/Swift/QtUI/Roster/QtOccupantListWidget.h
@@ -1,31 +1,31 @@
/*
- * Copyright (c) 2011-2014 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <Swift/QtUI/Roster/QtTreeWidget.h>
-
-#include <Swiften/Base/boost_bsignals.h>
+#include <boost/signals2.hpp>
#include <Swift/Controllers/UIInterfaces/ChatWindow.h>
+#include <Swift/QtUI/Roster/QtTreeWidget.h>
+
namespace Swift {
class SettingsProvider;
class QtOccupantListWidget : public QtTreeWidget {
- Q_OBJECT
- public:
- QtOccupantListWidget(UIEventStream* eventStream, SettingsProvider* settings, MessageTarget privateMessageTarget, QWidget* parent = NULL);
- virtual ~QtOccupantListWidget();
- void setAvailableOccupantActions(const std::vector<ChatWindow::OccupantAction>& actions);
- boost::signal<void (ChatWindow::OccupantAction, ContactRosterItem*)> onOccupantActionSelected;
- protected:
- void contextMenuEvent(QContextMenuEvent* event);
- private:
- std::vector<ChatWindow::OccupantAction> availableOccupantActions_;
+ Q_OBJECT
+ public:
+ QtOccupantListWidget(UIEventStream* eventStream, SettingsProvider* settings, MessageTarget privateMessageTarget, QWidget* parent = nullptr);
+ virtual ~QtOccupantListWidget();
+ void setAvailableOccupantActions(const std::vector<ChatWindow::OccupantAction>& actions);
+ boost::signals2::signal<void (ChatWindow::OccupantAction, ContactRosterItem*)> onOccupantActionSelected;
+ protected:
+ void contextMenuEvent(QContextMenuEvent* event);
+ private:
+ std::vector<ChatWindow::OccupantAction> availableOccupantActions_;
};
}
diff --git a/Swift/QtUI/Roster/QtRosterWidget.cpp b/Swift/QtUI/Roster/QtRosterWidget.cpp
index bef8635..935d6f6 100644
--- a/Swift/QtUI/Roster/QtRosterWidget.cpp
+++ b/Swift/QtUI/Roster/QtRosterWidget.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2014 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,23 +7,24 @@
#include <Swift/QtUI/Roster/QtRosterWidget.h>
#include <QContextMenuEvent>
+#include <QFileDialog>
+#include <QInputDialog>
#include <QMenu>
#include <QMessageBox>
-#include <QInputDialog>
-#include <QFileDialog>
#include <QPushButton>
-#include <Swift/Controllers/UIEvents/RequestContactEditorUIEvent.h>
+#include <Swift/Controllers/Roster/ContactRosterItem.h>
+#include <Swift/Controllers/Roster/GroupRosterItem.h>
#include <Swift/Controllers/UIEvents/RemoveRosterItemUIEvent.h>
#include <Swift/Controllers/UIEvents/RenameGroupUIEvent.h>
-#include <Swift/Controllers/UIEvents/SendFileUIEvent.h>
+#include <Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h>
+#include <Swift/Controllers/UIEvents/RequestContactEditorUIEvent.h>
#include <Swift/Controllers/UIEvents/RequestWhiteboardUIEvent.h>
+#include <Swift/Controllers/UIEvents/SendFileUIEvent.h>
#include <Swift/Controllers/UIEvents/ShowProfileForRosterItemUIEvent.h>
-#include <Swift/Controllers/UIEvents/RequestChangeBlockStateUIEvent.h>
-#include <Swift/QtUI/QtContactEditWindow.h>
-#include <Swift/Controllers/Roster/ContactRosterItem.h>
-#include <Swift/Controllers/Roster/GroupRosterItem.h>
#include <Swift/Controllers/UIEvents/UIEventStream.h>
+
+#include <Swift/QtUI/QtContactEditWindow.h>
#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
@@ -37,125 +38,125 @@ QtRosterWidget::~QtRosterWidget() {
}
void QtRosterWidget::handleEditUserActionTriggered(bool /*checked*/) {
- QModelIndexList selectedIndexList = getSelectedIndexes();
- if (selectedIndexList.empty()) {
- return;
- }
- QModelIndex index = selectedIndexList[0];
- if (!index.isValid()) {
- return;
- }
- RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
- if (ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item)) {
- eventStream_->send(boost::make_shared<RequestContactEditorUIEvent>(contact->getJID()));
- }
+ QModelIndexList selectedIndexList = getSelectedIndexes();
+ if (selectedIndexList.empty()) {
+ return;
+ }
+ QModelIndex index = selectedIndexList[0];
+ if (!index.isValid()) {
+ return;
+ }
+ RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
+ if (ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item)) {
+ eventStream_->send(std::make_shared<RequestContactEditorUIEvent>(contact->getJID()));
+ }
}
void QtRosterWidget::contextMenuEvent(QContextMenuEvent* event) {
- QModelIndex index = indexAt(event->pos());
- if (!index.isValid()) {
- return;
- }
- RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
- QMenu contextMenu;
- if (ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item)) {
- QAction* editContact = contextMenu.addAction(tr("Edit…"));
- editContact->setEnabled(isOnline());
- QAction* removeContact = contextMenu.addAction(tr("Remove"));
- removeContact->setEnabled(isOnline());
- QAction* showProfileForContact = contextMenu.addAction(tr("Show Profile"));
-
- QAction* unblockContact = NULL;
- if (contact->blockState() == ContactRosterItem::IsBlocked ||
- contact->blockState() == ContactRosterItem::IsDomainBlocked) {
- unblockContact = contextMenu.addAction(tr("Unblock"));
- unblockContact->setEnabled(isOnline());
- }
-
- QAction* blockContact = NULL;
- if (contact->blockState() == ContactRosterItem::IsUnblocked) {
- blockContact = contextMenu.addAction(tr("Block"));
- blockContact->setEnabled(isOnline());
- }
+ QModelIndex index = indexAt(event->pos());
+ if (!index.isValid()) {
+ return;
+ }
+ RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
+ QMenu contextMenu;
+ if (ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item)) {
+ QAction* editContact = contextMenu.addAction(tr("Edit…"));
+ editContact->setEnabled(isOnline());
+ QAction* removeContact = contextMenu.addAction(tr("Remove"));
+ removeContact->setEnabled(isOnline());
+ QAction* showProfileForContact = contextMenu.addAction(tr("Show Profile"));
+
+ QAction* unblockContact = nullptr;
+ if (contact->blockState() == ContactRosterItem::IsBlocked ||
+ contact->blockState() == ContactRosterItem::IsDomainBlocked) {
+ unblockContact = contextMenu.addAction(tr("Unblock"));
+ unblockContact->setEnabled(isOnline());
+ }
+
+ QAction* blockContact = nullptr;
+ if (contact->blockState() == ContactRosterItem::IsUnblocked) {
+ blockContact = contextMenu.addAction(tr("Block"));
+ blockContact->setEnabled(isOnline());
+ }
#ifdef SWIFT_EXPERIMENTAL_FT
- QAction* sendFile = NULL;
- if (contact->supportsFeature(ContactRosterItem::FileTransferFeature)) {
- sendFile = contextMenu.addAction(tr("Send File"));
- sendFile->setEnabled(isOnline());
- }
+ QAction* sendFile = nullptr;
+ if (contact->supportsFeature(ContactRosterItem::FileTransferFeature)) {
+ sendFile = contextMenu.addAction(tr("Send File"));
+ sendFile->setEnabled(isOnline());
+ }
#endif
#ifdef SWIFT_EXPERIMENTAL_WB
- QAction* startWhiteboardChat = NULL;
- if (contact->supportsFeature(ContactRosterItem::WhiteboardFeature)) {
- startWhiteboardChat = contextMenu.addAction(tr("Start Whiteboard Chat"));
- startWhiteboardChat->setEnabled(isOnline());
- }
+ QAction* startWhiteboardChat = nullptr;
+ if (contact->supportsFeature(ContactRosterItem::WhiteboardFeature)) {
+ startWhiteboardChat = contextMenu.addAction(tr("Start Whiteboard Chat"));
+ startWhiteboardChat->setEnabled(isOnline());
+ }
#endif
- QAction* result = contextMenu.exec(event->globalPos());
- if (result == editContact) {
- eventStream_->send(boost::make_shared<RequestContactEditorUIEvent>(contact->getJID()));
- }
- else if (result == removeContact) {
- if (QtContactEditWindow::confirmContactDeletion(contact->getJID())) {
- eventStream_->send(boost::make_shared<RemoveRosterItemUIEvent>(contact->getJID()));
- }
- }
- else if (result == showProfileForContact) {
- eventStream_->send(boost::make_shared<ShowProfileForRosterItemUIEvent>(contact->getJID()));
- }
- else if (unblockContact && result == unblockContact) {
- if (contact->blockState() == ContactRosterItem::IsDomainBlocked) {
- QMessageBox messageBox(QMessageBox::Question, tr("Swift"), tr("%2 is currently blocked because of a block on all users of the %1 service.\n %2 cannot be unblocked individually; do you want to unblock all %1 users?").arg(P2QSTRING(contact->getJID().getDomain()), P2QSTRING(contact->getJID().toString())), QMessageBox::NoButton, this);
- QPushButton* unblockDomainButton = messageBox.addButton(tr("Unblock %1 domain").arg(P2QSTRING(contact->getJID().getDomain())), QMessageBox::AcceptRole);
- messageBox.addButton(QMessageBox::Abort);
-
- messageBox.exec();
- if (messageBox.clickedButton() == unblockDomainButton) {
- eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Unblocked, contact->getJID().getDomain()));
- }
- } else {
- eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Unblocked, contact->getJID()));
- }
- }
- else if (blockContact && result == blockContact) {
- eventStream_->send(boost::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Blocked, contact->getJID()));
- }
+ QAction* result = contextMenu.exec(event->globalPos());
+ if (result == editContact) {
+ eventStream_->send(std::make_shared<RequestContactEditorUIEvent>(contact->getJID()));
+ }
+ else if (result == removeContact) {
+ if (QtContactEditWindow::confirmContactDeletion(contact->getJID())) {
+ eventStream_->send(std::make_shared<RemoveRosterItemUIEvent>(contact->getJID()));
+ }
+ }
+ else if (result == showProfileForContact) {
+ eventStream_->send(std::make_shared<ShowProfileForRosterItemUIEvent>(contact->getJID()));
+ }
+ else if (unblockContact && result == unblockContact) {
+ if (contact->blockState() == ContactRosterItem::IsDomainBlocked) {
+ QMessageBox messageBox(QMessageBox::Question, tr("Swift"), tr("%2 is currently blocked because of a block on all users of the %1 service.\n %2 cannot be unblocked individually; do you want to unblock all %1 users?").arg(P2QSTRING(contact->getJID().getDomain()), P2QSTRING(contact->getJID().toString())), QMessageBox::NoButton, this);
+ QPushButton* unblockDomainButton = messageBox.addButton(tr("Unblock %1 domain").arg(P2QSTRING(contact->getJID().getDomain())), QMessageBox::AcceptRole);
+ messageBox.addButton(QMessageBox::Abort);
+
+ messageBox.exec();
+ if (messageBox.clickedButton() == unblockDomainButton) {
+ eventStream_->send(std::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Unblocked, contact->getJID().getDomain()));
+ }
+ } else {
+ eventStream_->send(std::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Unblocked, contact->getJID()));
+ }
+ }
+ else if (blockContact && result == blockContact) {
+ eventStream_->send(std::make_shared<RequestChangeBlockStateUIEvent>(RequestChangeBlockStateUIEvent::Blocked, contact->getJID()));
+ }
#ifdef SWIFT_EXPERIMENTAL_FT
- else if (sendFile && result == sendFile) {
- QString fileName = QFileDialog::getOpenFileName(this, tr("Send File"), "", tr("All Files (*);;"));
- if (!fileName.isEmpty()) {
- eventStream_->send(boost::make_shared<SendFileUIEvent>(contact->getJID(), Q2PSTRING(fileName)));
- }
- }
+ else if (sendFile && result == sendFile) {
+ QString fileName = QFileDialog::getOpenFileName(this, tr("Send File"), "", tr("All Files (*);;"));
+ if (!fileName.isEmpty()) {
+ eventStream_->send(std::make_shared<SendFileUIEvent>(contact->getJID(), Q2PSTRING(fileName)));
+ }
+ }
#endif
#ifdef SWIFT_EXPERIMENTAL_WB
- else if (startWhiteboardChat && result == startWhiteboardChat) {
- eventStream_->send(boost::make_shared<RequestWhiteboardUIEvent>(contact->getJID()));
- }
+ else if (startWhiteboardChat && result == startWhiteboardChat) {
+ eventStream_->send(std::make_shared<RequestWhiteboardUIEvent>(contact->getJID()));
+ }
#endif
- }
- else if (GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item)) {
- QAction* renameGroupAction = contextMenu.addAction(tr("Rename"));
- if (P2QSTRING(group->getDisplayName()) == tr("Contacts")) {
- renameGroupAction->setEnabled(false);
- }
- else {
- renameGroupAction->setEnabled(isOnline());
- }
- QAction* result = contextMenu.exec(event->globalPos());
- if (result == renameGroupAction) {
- renameGroup(group);
- }
- }
+ }
+ else if (GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item)) {
+ QAction* renameGroupAction = contextMenu.addAction(tr("Rename"));
+ if (P2QSTRING(group->getDisplayName()) == tr("Contacts")) {
+ renameGroupAction->setEnabled(false);
+ }
+ else {
+ renameGroupAction->setEnabled(isOnline());
+ }
+ QAction* result = contextMenu.exec(event->globalPos());
+ if (result == renameGroupAction) {
+ renameGroup(group);
+ }
+ }
}
void QtRosterWidget::renameGroup(GroupRosterItem* group) {
- bool ok;
- QString newName = QInputDialog::getText(NULL, tr("Rename group"), tr("Enter a new name for group '%1':").arg(P2QSTRING(group->getDisplayName())), QLineEdit::Normal, P2QSTRING(group->getDisplayName()), &ok);
- if (ok) {
- eventStream_->send(boost::make_shared<RenameGroupUIEvent>(group->getDisplayName(), Q2PSTRING(newName)));
- }
+ bool ok;
+ QString newName = QInputDialog::getText(nullptr, tr("Rename group"), tr("Enter a new name for group '%1':").arg(P2QSTRING(group->getDisplayName())), QLineEdit::Normal, P2QSTRING(group->getDisplayName()), &ok);
+ if (ok) {
+ eventStream_->send(std::make_shared<RenameGroupUIEvent>(group->getDisplayName(), Q2PSTRING(newName)));
+ }
}
}
diff --git a/Swift/QtUI/Roster/QtRosterWidget.h b/Swift/QtUI/Roster/QtRosterWidget.h
index d785af2..2cf8315 100644
--- a/Swift/QtUI/Roster/QtRosterWidget.h
+++ b/Swift/QtUI/Roster/QtRosterWidget.h
@@ -1,27 +1,27 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include "Swift/QtUI/Roster/QtTreeWidget.h"
+#include <Swift/QtUI/Roster/QtTreeWidget.h>
namespace Swift {
class QtUIPreferences;
class QtRosterWidget : public QtTreeWidget {
- Q_OBJECT
- public:
- QtRosterWidget(UIEventStream* eventStream, SettingsProvider* settings, QWidget* parent = 0);
- virtual ~QtRosterWidget();
- public slots:
- void handleEditUserActionTriggered(bool checked);
- protected:
- void contextMenuEvent(QContextMenuEvent* event);
- private:
- void renameGroup(GroupRosterItem* group);
+ Q_OBJECT
+ public:
+ QtRosterWidget(UIEventStream* eventStream, SettingsProvider* settings, QWidget* parent = nullptr);
+ virtual ~QtRosterWidget();
+ public slots:
+ void handleEditUserActionTriggered(bool checked);
+ protected:
+ void contextMenuEvent(QContextMenuEvent* event);
+ private:
+ void renameGroup(GroupRosterItem* group);
};
}
diff --git a/Swift/QtUI/Roster/QtTreeWidget.cpp b/Swift/QtUI/Roster/QtTreeWidget.cpp
index 06a76c3..1264a09 100644
--- a/Swift/QtUI/Roster/QtTreeWidget.cpp
+++ b/Swift/QtUI/Roster/QtTreeWidget.cpp
@@ -1,263 +1,267 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/Roster/QtTreeWidget.h>
-#include <boost/smart_ptr/make_shared.hpp>
+#include <memory>
+
#include <boost/bind.hpp>
-#include <QUrl>
+#include <QFont>
+#include <QLabel>
#include <QMimeData>
#include <QObject>
-#include <QLabel>
#include <QTimer>
#include <QToolTip>
+#include <QUrl>
#include <Swiften/Base/Platform.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
#include <Swift/Controllers/Roster/GroupRosterItem.h>
-#include <Swift/Controllers/UIEvents/UIEventStream.h>
+#include <Swift/Controllers/Settings/SettingsProvider.h>
#include <Swift/Controllers/UIEvents/RequestChatUIEvent.h>
#include <Swift/Controllers/UIEvents/SendFileUIEvent.h>
-#include <Swift/Controllers/Settings/SettingsProvider.h>
-
+#include <Swift/Controllers/UIEvents/UIEventStream.h>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swift/QtUI/QtUISettingConstants.h>
#include <Swift/QtUI/Roster/RosterModel.h>
-#include <QtSwiftUtil.h>
namespace Swift {
-QtTreeWidget::QtTreeWidget(UIEventStream* eventStream, SettingsProvider* settings, MessageTarget messageTarget, QWidget* parent) : QTreeView(parent), tooltipShown_(false), messageTarget_(messageTarget) {
- eventStream_ = eventStream;
- settings_ = settings;
- model_ = new RosterModel(this, settings_->getSetting(QtUISettingConstants::USE_SCREENREADER));
- setModel(model_);
- delegate_ = new RosterDelegate(this, settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
- setItemDelegate(delegate_);
- setHeaderHidden(true);
+QtTreeWidget::QtTreeWidget(UIEventStream* eventStream, SettingsProvider* settings, MessageTarget messageTarget, QWidget* parent) : QTreeView(parent), eventStream_(eventStream), settings_(settings), messageTarget_(messageTarget) {
+ model_ = new RosterModel(this, settings_->getSetting(QtUISettingConstants::USE_SCREENREADER));
+ setModel(model_);
+ delegate_ = new RosterDelegate(this, settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
+ setItemDelegate(delegate_);
+ setHeaderHidden(true);
#ifdef SWIFT_PLATFORM_MACOSX
- setAlternatingRowColors(true);
+ setAlternatingRowColors(true);
#endif
- setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
- expandAll();
- setAnimated(true);
- setIndentation(0);
+ setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
+ expandAll();
+ setAnimated(true);
+ setIndentation(0);
#ifdef SWIFT_EXPERIMENTAL_FT
- setAcceptDrops(true);
+ setAcceptDrops(true);
#endif
- setDragEnabled(true);
- setRootIsDecorated(true);
- connect(this, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleItemActivated(const QModelIndex&)));
- connect(model_, SIGNAL(itemExpanded(const QModelIndex&, bool)), this, SLOT(handleModelItemExpanded(const QModelIndex&, bool)));
- connect(this, SIGNAL(expanded(const QModelIndex&)), this, SLOT(handleExpanded(const QModelIndex&)));
- connect(this, SIGNAL(collapsed(const QModelIndex&)), this, SLOT(handleCollapsed(const QModelIndex&)));
- connect(this, SIGNAL(clicked(const QModelIndex&)), this, SLOT(handleClicked(const QModelIndex&)));
-
- settings_->onSettingChanged.connect(boost::bind(&QtTreeWidget::handleSettingChanged, this, _1));
+ setDragEnabled(true);
+ setRootIsDecorated(true);
+ connect(this, SIGNAL(activated(const QModelIndex&)), this, SLOT(handleItemActivated(const QModelIndex&)));
+ connect(model_, SIGNAL(itemExpanded(const QModelIndex&, bool)), this, SLOT(handleModelItemExpanded(const QModelIndex&, bool)));
+ connect(this, SIGNAL(expanded(const QModelIndex&)), this, SLOT(handleExpanded(const QModelIndex&)));
+ connect(this, SIGNAL(collapsed(const QModelIndex&)), this, SLOT(handleCollapsed(const QModelIndex&)));
+ connect(this, SIGNAL(clicked(const QModelIndex&)), this, SLOT(handleClicked(const QModelIndex&)));
+
+ settings_->onSettingChanged.connect(boost::bind(&QtTreeWidget::handleSettingChanged, this, _1));
+
+ QFont lato = font();
+ lato.setFamily("Lato");
+ setFont(lato);
}
QtTreeWidget::~QtTreeWidget() {
- settings_->onSettingChanged.disconnect(boost::bind(&QtTreeWidget::handleSettingChanged, this, _1));
- delete model_;
- delete delegate_;
+ settings_->onSettingChanged.disconnect(boost::bind(&QtTreeWidget::handleSettingChanged, this, _1));
+ delete model_;
+ delete delegate_;
}
void QtTreeWidget::handleSettingChanged(const std::string& setting) {
- if (setting == QtUISettingConstants::COMPACT_ROSTER.getKey()) {
- delegate_->setCompact(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
- repaint();
- }
+ if (setting == QtUISettingConstants::COMPACT_ROSTER.getKey()) {
+ delegate_->setCompact(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
+ repaint();
+ }
}
void QtTreeWidget::handleRefreshTooltip() {
- if (tooltipShown_) {
- QPoint position = QCursor::pos();
- QModelIndex index = indexAt(mapFromGlobal(position));
- QToolTip::showText(position, model_->data(index, Qt::ToolTipRole).toString());
- }
+ if (tooltipShown_) {
+ QPoint position = QCursor::pos();
+ QModelIndex index = indexAt(mapFromGlobal(position));
+ QToolTip::showText(position, model_->data(index, Qt::ToolTipRole).toString());
+ }
}
void QtTreeWidget::setRosterModel(Roster* roster) {
- roster_ = roster;
- model_->setRoster(roster);
- expandAll();
+ roster_ = roster;
+ model_->setRoster(roster);
+ expandAll();
}
void QtTreeWidget::refreshTooltip() {
- // Qt needs some time to emit the events we need to detect tooltip's visibility correctly; 20 ms should be enough
- QTimer::singleShot(20, this, SLOT(handleRefreshTooltip()));
+ // Qt needs some time to emit the events we need to detect tooltip's visibility correctly; 20 ms should be enough
+ QTimer::singleShot(20, this, SLOT(handleRefreshTooltip()));
}
QtTreeWidgetItem* QtTreeWidget::getRoot() {
- return treeRoot_;
+ return treeRoot_;
}
void QtTreeWidget::handleClicked(const QModelIndex& index) {
- GroupRosterItem* item = dynamic_cast<GroupRosterItem*>(static_cast<RosterItem*>(index.internalPointer()));
- if (item) {
- setExpanded(index, !isExpanded(index));
- }
- currentChanged(index, QModelIndex());
+ GroupRosterItem* item = dynamic_cast<GroupRosterItem*>(static_cast<RosterItem*>(index.internalPointer()));
+ if (item) {
+ setExpanded(index, !isExpanded(index));
+ }
+ currentChanged(index, QModelIndex());
}
QModelIndexList QtTreeWidget::getSelectedIndexes() const {
- // Not using selectedIndexes(), because this seems to cause a crash in Qt (4.7.0) in the
- // QModelIndexList destructor.
- // This is a workaround posted in http://www.qtcentre.org/threads/16933 (although this case
- // was resolved by linking against the debug libs, ours isn't, and we're not alone)
- QItemSelection ranges = selectionModel()->selection();
- QModelIndexList selectedIndexList;
- for (int i = 0; i < ranges.count(); ++i) {
- QModelIndex parent = ranges.at(i).parent();
- int right = ranges.at(i).model()->columnCount(parent) - 1;
- if (ranges.at(i).left() == 0 && ranges.at(i).right() == right) {
- for (int r = ranges.at(i).top(); r <= ranges.at(i).bottom(); ++r) {
- selectedIndexList.append(ranges.at(i).model()->index(r, 0, parent));
- }
- }
- }
- return selectedIndexList;
+ // Not using selectedIndexes(), because this seems to cause a crash in Qt (4.7.0) in the
+ // QModelIndexList destructor.
+ // This is a workaround posted in http://www.qtcentre.org/threads/16933 (although this case
+ // was resolved by linking against the debug libs, ours isn't, and we're not alone)
+ QItemSelection ranges = selectionModel()->selection();
+ QModelIndexList selectedIndexList;
+ for (int i = 0; i < ranges.count(); ++i) {
+ QModelIndex parent = ranges.at(i).parent();
+ int right = ranges.at(i).model()->columnCount(parent) - 1;
+ if (ranges.at(i).left() == 0 && ranges.at(i).right() == right) {
+ for (int r = ranges.at(i).top(); r <= ranges.at(i).bottom(); ++r) {
+ selectedIndexList.append(ranges.at(i).model()->index(r, 0, parent));
+ }
+ }
+ }
+ return selectedIndexList;
}
void QtTreeWidget::currentChanged(const QModelIndex& current, const QModelIndex& previous) {
- RosterItem* item = NULL;
- QModelIndexList selectedIndexList = getSelectedIndexes();
- if (selectedIndexList.empty() || !selectedIndexList[0].isValid()) {
- /* I didn't quite understand why using current didn't seem to work here.*/
- }
- else if (current.isValid()) {
- item = static_cast<RosterItem*>(current.internalPointer());
- item = dynamic_cast<ContactRosterItem*>(item);
- }
- onSomethingSelectedChanged(item);
- QTreeView::currentChanged(current, previous);
+ RosterItem* item = nullptr;
+ QModelIndexList selectedIndexList = getSelectedIndexes();
+ if (selectedIndexList.empty() || !selectedIndexList[0].isValid()) {
+ /* I didn't quite understand why using current didn't seem to work here.*/
+ }
+ else if (current.isValid()) {
+ item = static_cast<RosterItem*>(current.internalPointer());
+ item = dynamic_cast<ContactRosterItem*>(item);
+ }
+ onSomethingSelectedChanged(item);
+ QTreeView::currentChanged(current, previous);
}
void QtTreeWidget::handleItemActivated(const QModelIndex& index) {
- JID target = jidFromIndex(index);
- if (target.isValid()) {
- eventStream_->send(boost::shared_ptr<UIEvent>(new RequestChatUIEvent(target)));
- }
+ JID target = jidFromIndex(index);
+ if (target.isValid()) {
+ eventStream_->send(std::make_shared<RequestChatUIEvent>(target));
+ }
}
void QtTreeWidget::dragEnterEvent(QDragEnterEvent *event) {
- if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) {
- event->acceptProposedAction();
- }
+ if (event->mimeData()->hasUrls() && event->mimeData()->urls().size() == 1) {
+ event->acceptProposedAction();
+ }
}
void QtTreeWidget::dropEvent(QDropEvent *event) {
- QModelIndex index = indexAt(event->pos());
- if (index.isValid()) {
- RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
- if (ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item)) {
- if (contact->supportsFeature(ContactRosterItem::FileTransferFeature)) {
- QString filename = event->mimeData()->urls().at(0).toLocalFile();
- if (!filename.isEmpty()) {
- eventStream_->send(boost::make_shared<SendFileUIEvent>(contact->getJID(), Q2PSTRING(filename)));
- }
- }
- }
- }
+ QModelIndex index = indexAt(event->pos());
+ if (index.isValid()) {
+ RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
+ if (ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item)) {
+ if (contact->supportsFeature(ContactRosterItem::FileTransferFeature)) {
+ QString filename = event->mimeData()->urls().at(0).toLocalFile();
+ if (!filename.isEmpty()) {
+ eventStream_->send(std::make_shared<SendFileUIEvent>(contact->getJID(), Q2PSTRING(filename)));
+ }
+ }
+ }
+ }
}
void QtTreeWidget::dragMoveEvent(QDragMoveEvent* event) {
- QModelIndex index = indexAt(event->pos());
- if (index.isValid()) {
- RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
- if (ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item)) {
- if (contact->supportsFeature(ContactRosterItem::FileTransferFeature)) {
- event->accept();
- return;
- }
- }
- }
- QTreeView::dragMoveEvent(event);
+ QModelIndex index = indexAt(event->pos());
+ if (index.isValid()) {
+ RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
+ if (ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item)) {
+ if (contact->supportsFeature(ContactRosterItem::FileTransferFeature)) {
+ event->accept();
+ return;
+ }
+ }
+ }
+ QTreeView::dragMoveEvent(event);
}
bool QtTreeWidget::event(QEvent* event) {
- QChildEvent* childEvent = NULL;
- if ((childEvent = dynamic_cast<QChildEvent*>(event))) {
- if (childEvent->polished()) {
- if (dynamic_cast<QLabel*>(childEvent->child())) {
- tooltipShown_ = true;
- }
- }
- else if (childEvent->removed()) {
- if (childEvent->child()->objectName() == "qtooltip_label") {
- tooltipShown_ = false;
- }
- }
- }
- return QAbstractItemView::event(event);
+ QChildEvent* childEvent = nullptr;
+ if ((childEvent = dynamic_cast<QChildEvent*>(event))) {
+ if (childEvent->polished()) {
+ if (dynamic_cast<QLabel*>(childEvent->child())) {
+ tooltipShown_ = true;
+ }
+ }
+ else if (childEvent->removed()) {
+ if (childEvent->child()->objectName() == "qtooltip_label") {
+ tooltipShown_ = false;
+ }
+ }
+ }
+ return QAbstractItemView::event(event);
}
void QtTreeWidget::handleExpanded(const QModelIndex& index) {
- GroupRosterItem* item = dynamic_cast<GroupRosterItem*>(static_cast<RosterItem*>(index.internalPointer()));
- if (item) {
- item->setExpanded(true);
- }
+ GroupRosterItem* item = dynamic_cast<GroupRosterItem*>(static_cast<RosterItem*>(index.internalPointer()));
+ if (item) {
+ item->setExpanded(true);
+ }
}
void QtTreeWidget::handleCollapsed(const QModelIndex& index) {
- GroupRosterItem* item = dynamic_cast<GroupRosterItem*>(static_cast<RosterItem*>(index.internalPointer()));
- if (item) {
- item->setExpanded(false);
- }
+ GroupRosterItem* item = dynamic_cast<GroupRosterItem*>(static_cast<RosterItem*>(index.internalPointer()));
+ if (item) {
+ item->setExpanded(false);
+ }
}
void QtTreeWidget::handleModelItemExpanded(const QModelIndex& index, bool shouldExpand) {
- if (!index.isValid()) {
- return;
- }
- bool alreadyRight = this->isExpanded(index) == shouldExpand;
- if (alreadyRight) {
- return;
- }
- setExpanded(index, shouldExpand);
+ if (!index.isValid()) {
+ return;
+ }
+ bool alreadyRight = this->isExpanded(index) == shouldExpand;
+ if (alreadyRight) {
+ return;
+ }
+ setExpanded(index, shouldExpand);
}
void QtTreeWidget::drawBranches(QPainter*, const QRect&, const QModelIndex&) const {
}
void QtTreeWidget::show() {
- QWidget::show();
+ QWidget::show();
}
void QtTreeWidget::setMessageTarget(MessageTarget messageTarget) {
- messageTarget_ = messageTarget;
+ messageTarget_ = messageTarget;
}
JID QtTreeWidget::jidFromIndex(const QModelIndex& index) const {
- JID target;
- if (messageTarget_ == MessageDisplayJID) {
- target = JID(Q2PSTRING(index.data(DisplayJIDRole).toString()));
- target = target.toBare();
- }
- if (!target.isValid()) {
- target = JID(Q2PSTRING(index.data(JIDRole).toString()));
- }
- return target;
+ JID target;
+ if (messageTarget_ == MessageDisplayJID) {
+ target = JID(Q2PSTRING(index.data(DisplayJIDRole).toString()));
+ target = target.toBare();
+ }
+ if (!target.isValid()) {
+ target = JID(Q2PSTRING(index.data(JIDRole).toString()));
+ }
+ return target;
}
JID QtTreeWidget::selectedJID() const {
- QModelIndexList list = selectedIndexes();
- if (list.size() != 1) {
- return JID();
- }
- return jidFromIndex(list[0]);
+ QModelIndexList list = selectedIndexes();
+ if (list.size() != 1) {
+ return JID();
+ }
+ return jidFromIndex(list[0]);
}
void QtTreeWidget::setOnline(bool isOnline) {
- isOnline_ = isOnline;
+ isOnline_ = isOnline;
}
bool QtTreeWidget::isOnline() const {
- return isOnline_;
+ return isOnline_;
}
}
diff --git a/Swift/QtUI/Roster/QtTreeWidget.h b/Swift/QtUI/Roster/QtTreeWidget.h
index ff45547..331458a 100644
--- a/Swift/QtUI/Roster/QtTreeWidget.h
+++ b/Swift/QtUI/Roster/QtTreeWidget.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -7,74 +7,74 @@
#pragma once
#include <QDragEnterEvent>
-#include <QDropEvent>
#include <QDragMoveEvent>
+#include <QDropEvent>
#include <QModelIndex>
#include <QTreeView>
-
-#include <Swift/QtUI/Roster/RosterDelegate.h>
-#include <Swift/QtUI/Roster/RosterModel.h>
#include <Swift/Controllers/UIInterfaces/ChatWindow.h>
+#include <Swift/QtUI/Roster/RosterDelegate.h>
+#include <Swift/QtUI/Roster/RosterModel.h>
+
namespace Swift {
class UIEventStream;
class SettingsProvider;
class QtTreeWidget : public QTreeView {
- Q_OBJECT
- public:
- enum MessageTarget {MessageDefaultJID, MessageDisplayJID};
+ Q_OBJECT
+ public:
+ enum MessageTarget {MessageDefaultJID, MessageDisplayJID};
- QtTreeWidget(UIEventStream* eventStream, SettingsProvider* settings, MessageTarget messageTarget, QWidget* parent = 0);
- ~QtTreeWidget();
- void show();
- QtTreeWidgetItem* getRoot();
- void setRosterModel(Roster* roster);
- Roster* getRoster() {return roster_;}
- void refreshTooltip();
- void setMessageTarget(MessageTarget messageTarget);
- JID jidFromIndex(const QModelIndex& index) const;
- JID selectedJID() const;
- void setOnline(bool isOnline);
+ QtTreeWidget(UIEventStream* eventStream, SettingsProvider* settings, MessageTarget messageTarget, QWidget* parent = nullptr);
+ ~QtTreeWidget();
+ void show();
+ QtTreeWidgetItem* getRoot();
+ void setRosterModel(Roster* roster);
+ Roster* getRoster() {return roster_;}
+ void refreshTooltip();
+ void setMessageTarget(MessageTarget messageTarget);
+ JID jidFromIndex(const QModelIndex& index) const;
+ JID selectedJID() const;
+ void setOnline(bool isOnline);
- public:
- boost::signal<void (RosterItem*)> onSomethingSelectedChanged;
+ public:
+ boost::signals2::signal<void (RosterItem*)> onSomethingSelectedChanged;
- private slots:
- void handleItemActivated(const QModelIndex&);
- void handleModelItemExpanded(const QModelIndex&, bool expanded);
- void handleExpanded(const QModelIndex&);
- void handleCollapsed(const QModelIndex&);
- void handleClicked(const QModelIndex&);
- void handleSettingChanged(const std::string& setting);
- void handleRefreshTooltip();
+ private slots:
+ void handleItemActivated(const QModelIndex&);
+ void handleModelItemExpanded(const QModelIndex&, bool expanded);
+ void handleExpanded(const QModelIndex&);
+ void handleCollapsed(const QModelIndex&);
+ void handleClicked(const QModelIndex&);
+ void handleSettingChanged(const std::string& setting);
+ void handleRefreshTooltip();
- protected:
- void dragEnterEvent(QDragEnterEvent* event);
- void dropEvent(QDropEvent* event);
- void dragMoveEvent(QDragMoveEvent* event);
- bool event(QEvent* event);
- QModelIndexList getSelectedIndexes() const;
- bool isOnline() const;
+ protected:
+ void dragEnterEvent(QDragEnterEvent* event);
+ void dropEvent(QDropEvent* event);
+ void dragMoveEvent(QDragMoveEvent* event);
+ bool event(QEvent* event);
+ QModelIndexList getSelectedIndexes() const;
+ bool isOnline() const;
- private:
- void drawBranches(QPainter*, const QRect&, const QModelIndex&) const;
+ private:
+ void drawBranches(QPainter*, const QRect&, const QModelIndex&) const;
- protected slots:
- virtual void currentChanged(const QModelIndex& current, const QModelIndex& previous);
- protected:
- UIEventStream* eventStream_;
+ protected slots:
+ virtual void currentChanged(const QModelIndex& current, const QModelIndex& previous);
+ protected:
+ UIEventStream* eventStream_;
- private:
- RosterModel* model_;
- Roster* roster_;
- RosterDelegate* delegate_;
- QtTreeWidgetItem* treeRoot_;
- SettingsProvider* settings_;
- bool tooltipShown_;
- MessageTarget messageTarget_;
- bool isOnline_;
+ private:
+ RosterModel* model_;
+ Roster* roster_ = nullptr;
+ RosterDelegate* delegate_;
+ QtTreeWidgetItem* treeRoot_ = nullptr;
+ SettingsProvider* settings_;
+ bool tooltipShown_ = false;
+ MessageTarget messageTarget_;
+ bool isOnline_ = false;
};
}
diff --git a/Swift/QtUI/Roster/RosterDelegate.cpp b/Swift/QtUI/Roster/RosterDelegate.cpp
index c5bb290..061982e 100644
--- a/Swift/QtUI/Roster/RosterDelegate.cpp
+++ b/Swift/QtUI/Roster/RosterDelegate.cpp
@@ -1,83 +1,83 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "RosterDelegate.h"
+#include <Swift/QtUI/Roster/RosterDelegate.h>
#include <QApplication>
-#include <QPainter>
-#include <QColor>
+#include <QBitmap>
#include <QBrush>
+#include <QColor>
+#include <QDebug>
#include <QFontMetrics>
+#include <QPainter>
#include <QPainterPath>
#include <QPolygon>
-#include <qdebug.h>
-#include <QBitmap>
-#include "Swift/Controllers/Roster/ContactRosterItem.h"
-#include "Swift/Controllers/Roster/GroupRosterItem.h"
+#include <Swift/Controllers/Roster/ContactRosterItem.h>
+#include <Swift/Controllers/Roster/GroupRosterItem.h>
-#include "QtTreeWidget.h"
-#include "RosterModel.h"
+#include <Swift/QtUI/Roster/QtTreeWidget.h>
+#include <Swift/QtUI/Roster/RosterModel.h>
namespace Swift {
RosterDelegate::RosterDelegate(QtTreeWidget* tree, bool compact) : compact_(compact) {
- tree_ = tree;
- groupDelegate_ = new GroupItemDelegate();
+ tree_ = tree;
+ groupDelegate_ = new GroupItemDelegate();
}
RosterDelegate::~RosterDelegate() {
- delete groupDelegate_;
+ delete groupDelegate_;
}
void RosterDelegate::setCompact(bool compact) {
- compact_ = compact;
- emit sizeHintChanged(QModelIndex());
+ compact_ = compact;
+ emit sizeHintChanged(QModelIndex());
}
-
+
QSize RosterDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index ) const {
- RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
- if (dynamic_cast<GroupRosterItem*>(item)) {
- return groupDelegate_->sizeHint(option, index);
- }
- return contactSizeHint(option, index);
+ RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
+ if (dynamic_cast<GroupRosterItem*>(item)) {
+ return groupDelegate_->sizeHint(option, index);
+ }
+ return contactSizeHint(option, index);
}
QSize RosterDelegate::contactSizeHint(const QStyleOptionViewItem& option, const QModelIndex& index ) const {
- return common_.contactSizeHint(option, index, compact_);
+ return common_.contactSizeHint(option, index, compact_);
}
void RosterDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
- RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
- if (dynamic_cast<GroupRosterItem*>(item)) {
- paintGroup(painter, option, index);
- } else {
- paintContact(painter, option, index);
- }
+ RosterItem* item = static_cast<RosterItem*>(index.internalPointer());
+ if (dynamic_cast<GroupRosterItem*>(item)) {
+ paintGroup(painter, option, index);
+ } else {
+ paintContact(painter, option, index);
+ }
}
void RosterDelegate::paintGroup(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
- if (index.isValid()) {
- groupDelegate_->paint(painter, option, index.data(Qt::DisplayRole).toString(), index.data(ChildCountRole).toInt(), tree_->isExpanded(index));
- }
+ if (index.isValid()) {
+ groupDelegate_->paint(painter, option, index.data(Qt::DisplayRole).toString(), index.data(ChildCountRole).toInt(), tree_->isExpanded(index));
+ }
}
void RosterDelegate::paintContact(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
- QColor nameColor = index.data(Qt::TextColorRole).value<QColor>();
- QString avatarPath;
- if (index.data(AvatarRole).isValid() && !index.data(AvatarRole).value<QString>().isNull()) {
- avatarPath = index.data(AvatarRole).value<QString>();
- }
- QIcon presenceIcon = index.data(PresenceIconRole).isValid() && !index.data(PresenceIconRole).value<QIcon>().isNull()
- ? index.data(PresenceIconRole).value<QIcon>()
- : QIcon(":/icons/offline.png");
- bool isIdle = index.data(IdleRole).isValid() ? index.data(IdleRole).toBool() : false;
- QString name = index.data(Qt::DisplayRole).toString();
- QString statusText = index.data(StatusTextRole).toString();
- common_.paintContact(painter, option, nameColor, avatarPath, presenceIcon, name, statusText, isIdle, 0, compact_);
+ QColor nameColor = index.data(Qt::TextColorRole).value<QColor>();
+ QString avatarPath;
+ if (index.data(AvatarRole).isValid() && !index.data(AvatarRole).value<QString>().isNull()) {
+ avatarPath = index.data(AvatarRole).value<QString>();
+ }
+ QIcon presenceIcon = index.data(PresenceIconRole).isValid() && !index.data(PresenceIconRole).value<QIcon>().isNull()
+ ? index.data(PresenceIconRole).value<QIcon>()
+ : QIcon(":/icons/offline.png");
+ bool isIdle = index.data(IdleRole).isValid() ? index.data(IdleRole).toBool() : false;
+ QString name = index.data(Qt::DisplayRole).toString();
+ QString statusText = index.data(StatusTextRole).toString();
+ common_.paintContact(painter, option, nameColor, avatarPath, presenceIcon, name, statusText, isIdle, 0, compact_);
}
}
diff --git a/Swift/QtUI/Roster/RosterDelegate.h b/Swift/QtUI/Roster/RosterDelegate.h
index aedb6d6..34c1569 100644
--- a/Swift/QtUI/Roster/RosterDelegate.h
+++ b/Swift/QtUI/Roster/RosterDelegate.h
@@ -1,35 +1,35 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <QStyledItemDelegate>
#include <QColor>
#include <QFont>
+#include <QStyledItemDelegate>
-#include "GroupItemDelegate.h"
-#include "DelegateCommons.h"
+#include <Swift/QtUI/Roster/DelegateCommons.h>
+#include <Swift/QtUI/Roster/GroupItemDelegate.h>
namespace Swift {
- class QtTreeWidget;
- class RosterDelegate : public QStyledItemDelegate {
- public:
- RosterDelegate(QtTreeWidget* tree, bool compact);
- ~RosterDelegate();
- QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
- void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
- public slots:
- void setCompact(bool compact);
- private:
- QSize contactSizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
- void paintGroup(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
- void paintContact(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
- bool compact_;
- DelegateCommons common_;
- GroupItemDelegate* groupDelegate_;
- QtTreeWidget* tree_;
- };
+ class QtTreeWidget;
+ class RosterDelegate : public QStyledItemDelegate {
+ public:
+ RosterDelegate(QtTreeWidget* tree, bool compact);
+ ~RosterDelegate();
+ QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ public slots:
+ void setCompact(bool compact);
+ private:
+ QSize contactSizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ void paintGroup(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ void paintContact(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ bool compact_;
+ DelegateCommons common_;
+ GroupItemDelegate* groupDelegate_;
+ QtTreeWidget* tree_;
+ };
}
diff --git a/Swift/QtUI/Roster/RosterModel.cpp b/Swift/QtUI/Roster/RosterModel.cpp
index b7a1d0a..ef4d778 100644
--- a/Swift/QtUI/Roster/RosterModel.cpp
+++ b/Swift/QtUI/Roster/RosterModel.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -11,268 +11,269 @@
#include <QColor>
#include <QIcon>
#include <QMimeData>
+
#include <qdebug.h>
-#include <Swiften/Elements/StatusShow.h>
#include <Swiften/Base/Path.h>
+#include <Swiften/Elements/StatusShow.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
#include <Swift/Controllers/Roster/GroupRosterItem.h>
#include <Swift/Controllers/StatusUtil.h>
-#include <Swift/QtUI/Roster/QtTreeWidget.h>
-#include <Swift/QtUI/Roster/RosterTooltip.h>
#include <Swift/QtUI/QtResourceHelper.h>
#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/Roster/QtTreeWidget.h>
+#include <Swift/QtUI/Roster/RosterTooltip.h>
namespace Swift {
-RosterModel::RosterModel(QtTreeWidget* view, bool screenReaderMode) : roster_(NULL), view_(view), screenReader_(screenReaderMode) {
- const int tooltipAvatarSize = 96; // maximal suggested size according to XEP-0153
- cachedImageScaler_ = new QtScaledAvatarCache(tooltipAvatarSize);
+RosterModel::RosterModel(QtTreeWidget* view, bool screenReaderMode) : roster_(nullptr), view_(view), screenReader_(screenReaderMode) {
+ const int tooltipAvatarSize = 96; // maximal suggested size according to XEP-0153
+ cachedImageScaler_ = new QtScaledAvatarCache(tooltipAvatarSize);
}
RosterModel::~RosterModel() {
- delete cachedImageScaler_;
+ delete cachedImageScaler_;
}
void RosterModel::setRoster(Roster* roster) {
- roster_ = roster;
- if (roster_) {
- roster->onChildrenChanged.connect(boost::bind(&RosterModel::handleChildrenChanged, this, _1));
- roster->onDataChanged.connect(boost::bind(&RosterModel::handleDataChanged, this, _1));
- }
- reLayout();
+ roster_ = roster;
+ if (roster_) {
+ roster->onChildrenChanged.connect(boost::bind(&RosterModel::handleChildrenChanged, this, _1));
+ roster->onDataChanged.connect(boost::bind(&RosterModel::handleDataChanged, this, _1));
+ }
+ reLayout();
}
void RosterModel::reLayout() {
- //emit layoutChanged();
- beginResetModel();
- endResetModel(); // TODO: Not sure if this isn't too early?
- if (!roster_) {
- return;
- }
- foreach (RosterItem* item, roster_->getRoot()->getDisplayedChildren()) {
- GroupRosterItem* child = dynamic_cast<GroupRosterItem*>(item);
- if (!child) continue;
- emit itemExpanded(index(child), child->isExpanded());
- }
+ //emit layoutChanged();
+ beginResetModel();
+ endResetModel(); // TODO: Not sure if this isn't too early?
+ if (!roster_) {
+ return;
+ }
+ for (auto item : roster_->getRoot()->getDisplayedChildren()) {
+ GroupRosterItem* child = dynamic_cast<GroupRosterItem*>(item);
+ if (!child) continue;
+ emit itemExpanded(index(child), child->isExpanded());
+ }
}
void RosterModel::handleChildrenChanged(GroupRosterItem* /*group*/) {
- reLayout();
+ reLayout();
}
void RosterModel::handleDataChanged(RosterItem* item) {
- Q_ASSERT(item);
- QModelIndex modelIndex = index(item);
- if (modelIndex.isValid()) {
- emit dataChanged(modelIndex, modelIndex);
- view_->refreshTooltip();
- }
+ Q_ASSERT(item);
+ QModelIndex modelIndex = index(item);
+ if (modelIndex.isValid()) {
+ emit dataChanged(modelIndex, modelIndex);
+ view_->refreshTooltip();
+ }
}
Qt::ItemFlags RosterModel::flags(const QModelIndex& index) const {
- Qt::ItemFlags flags = QAbstractItemModel::flags(index);
- if (dynamic_cast<GroupRosterItem*>(getItem(index)) == NULL) {
- flags |= Qt::ItemIsDragEnabled;
- }
- return flags;
+ Qt::ItemFlags flags = QAbstractItemModel::flags(index);
+ if (dynamic_cast<GroupRosterItem*>(getItem(index)) == nullptr) {
+ flags |= Qt::ItemIsDragEnabled;
+ }
+ return flags;
}
int RosterModel::columnCount(const QModelIndex& /*parent*/) const {
- return 1;
+ return 1;
}
RosterItem* RosterModel::getItem(const QModelIndex& index) const {
- return index.isValid() ? static_cast<RosterItem*>(index.internalPointer()) : NULL;
+ return index.isValid() ? static_cast<RosterItem*>(index.internalPointer()) : nullptr;
}
QVariant RosterModel::data(const QModelIndex& index, int role) const {
- RosterItem* item = getItem(index);
- if (!item) return QVariant();
-
- switch (role) {
- case Qt::DisplayRole: return getScreenReaderTextOr(item, P2QSTRING(item->getDisplayName()));
- case Qt::TextColorRole: return getTextColor(item);
- case Qt::BackgroundColorRole: return getBackgroundColor(item);
- case Qt::ToolTipRole: return getToolTip(item);
- case StatusTextRole: return getStatusText(item);
- case AvatarRole: return getAvatar(item);
- case PresenceIconRole: return getPresenceIcon(item);
- case ChildCountRole: return getChildCount(item);
- case IdleRole: return getIsIdle(item);
- case JIDRole: return getJID(item);
- case DisplayJIDRole: return getDisplayJID(item);
- default: return QVariant();
- }
+ RosterItem* item = getItem(index);
+ if (!item) return QVariant();
+
+ switch (role) {
+ case Qt::DisplayRole: return getScreenReaderTextOr(item, P2QSTRING(item->getDisplayName()));
+ case Qt::TextColorRole: return getTextColor(item);
+ case Qt::BackgroundColorRole: return getBackgroundColor(item);
+ case Qt::ToolTipRole: return getToolTip(item);
+ case StatusTextRole: return getStatusText(item);
+ case AvatarRole: return getAvatar(item);
+ case PresenceIconRole: return getPresenceIcon(item);
+ case ChildCountRole: return getChildCount(item);
+ case IdleRole: return getIsIdle(item);
+ case JIDRole: return getJID(item);
+ case DisplayJIDRole: return getDisplayJID(item);
+ default: return QVariant();
+ }
}
QString RosterModel::getScreenReaderTextOr(RosterItem* item, const QString& alternative) const {
- QString name = P2QSTRING(item->getDisplayName());
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- if (contact && screenReader_) {
- name += ": " + P2QSTRING(statusShowTypeToFriendlyName(contact->getStatusShow()));
- if (!contact->getStatusText().empty()) {
- name += " (" + P2QSTRING(contact->getStatusText()) + ")";
- }
- return name;
- }
- else {
- return alternative;
- }
+ QString name = P2QSTRING(item->getDisplayName());
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (contact && screenReader_) {
+ name += ": " + P2QSTRING(statusShowTypeToFriendlyName(contact->getStatusShow()));
+ if (!contact->getStatusText().empty()) {
+ name += " (" + P2QSTRING(contact->getStatusText()) + ")";
+ }
+ return name;
+ }
+ else {
+ return alternative;
+ }
}
int RosterModel::getChildCount(RosterItem* item) const {
- GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
- return group ? group->getDisplayedChildren().size() : 0;
+ GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
+ return group ? group->getDisplayedChildren().size() : 0;
}
bool RosterModel::getIsIdle(RosterItem* item) const {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- return contact ? !contact->getIdleText().empty() : false;
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ return contact ? !contact->getIdleText().empty() : false;
}
QColor RosterModel::intToColor(int color) const {
- return QColor(
- ((color & 0xFF0000)>>16),
- ((color & 0xFF00)>>8),
- (color & 0xFF));
+ return QColor(
+ ((color & 0xFF0000)>>16),
+ ((color & 0xFF00)>>8),
+ (color & 0xFF));
}
QColor RosterModel::getTextColor(RosterItem* item) const {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- int color = 0;
- if (contact) {
- switch (contact->getStatusShow()) {
- case StatusShow::Online: color = 0x000000; break;
- case StatusShow::Away: color = 0x336699; break;
- case StatusShow::XA: color = 0x336699; break;
- case StatusShow::FFC: color = 0x000000; break;
- case StatusShow::DND: color = 0x990000; break;
- case StatusShow::None: color = 0x7F7F7F;break;
- }
- }
- return intToColor(color);
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ int color = 0;
+ if (contact) {
+ switch (contact->getStatusShow()) {
+ case StatusShow::Online: color = 0x595959; break;
+ case StatusShow::Away: color = 0x336699; break;
+ case StatusShow::XA: color = 0x336699; break;
+ case StatusShow::FFC: color = 0x595959; break;
+ case StatusShow::DND: color = 0x990000; break;
+ case StatusShow::None: color = 0x7F7F7F;break;
+ }
+ }
+ return intToColor(color);
}
QColor RosterModel::getBackgroundColor(RosterItem* item) const {
- return dynamic_cast<ContactRosterItem*>(item) ? intToColor(0xFFFFFF) : intToColor(0x969696);
+ return dynamic_cast<ContactRosterItem*>(item) ? intToColor(0xFFFFFF) : intToColor(0x969696);
}
QString RosterModel::getToolTip(RosterItem* item) const {
- QString tip(P2QSTRING(item->getDisplayName()));
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- if (contact) {
- return RosterTooltip::buildDetailedTooltip(contact, cachedImageScaler_);
- }
- return tip;
+ QString tip(P2QSTRING(item->getDisplayName()));
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (contact) {
+ return RosterTooltip::buildDetailedTooltip(contact, cachedImageScaler_);
+ }
+ return tip;
}
QString RosterModel::getAvatar(RosterItem* item) const {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- if (!contact) {
- return "";
- }
- return P2QSTRING(pathToString(contact->getAvatarPath()));
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (!contact) {
+ return "";
+ }
+ return P2QSTRING(pathToString(contact->getAvatarPath()));
}
QString RosterModel::getStatusText(RosterItem* item) const {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- if (!contact) return "";
- return P2QSTRING(contact->getStatusText());
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (!contact) return "";
+ return P2QSTRING(contact->getStatusText());
}
QString RosterModel::getJID(RosterItem* item) const {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- return contact ? P2QSTRING(contact->getJID().toString()) : QString();
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ return contact ? P2QSTRING(contact->getJID().toString()) : QString();
}
QString RosterModel::getDisplayJID(RosterItem* item) const {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- QString result = contact ? P2QSTRING(contact->getDisplayJID().toString()) : QString();
- if (result.isEmpty()) {
- result = getJID(item);
- }
- return result;
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ QString result = contact ? P2QSTRING(contact->getDisplayJID().toString()) : QString();
+ if (result.isEmpty()) {
+ result = getJID(item);
+ }
+ return result;
}
QIcon RosterModel::getPresenceIcon(RosterItem* item) const {
- ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
- if (!contact) return QIcon();
- if (contact->blockState() == ContactRosterItem::IsBlocked ||
- contact->blockState() == ContactRosterItem::IsDomainBlocked) {
- return QIcon(":/icons/stop.png");
- }
-
- return QIcon(statusShowTypeToIconPath(contact->getStatusShow()));
+ ContactRosterItem* contact = dynamic_cast<ContactRosterItem*>(item);
+ if (!contact) return QIcon();
+ if (contact->blockState() == ContactRosterItem::IsBlocked ||
+ contact->blockState() == ContactRosterItem::IsDomainBlocked) {
+ return QIcon(":/icons/stop.png");
+ }
+
+ return QIcon(statusShowTypeToIconPath(contact->getStatusShow()));
}
QModelIndex RosterModel::index(int row, int column, const QModelIndex& parent) const {
- if (!roster_) {
- return QModelIndex();
- }
- GroupRosterItem* parentItem;
- if (!parent.isValid()) {
- //top level
- parentItem = roster_->getRoot();
- } else {
- parentItem = dynamic_cast<GroupRosterItem*>(getItem(parent));
- if (!parentItem) return QModelIndex();
- }
- return static_cast<size_t>(row) < parentItem->getDisplayedChildren().size() ? createIndex(row, column, parentItem->getDisplayedChildren()[row]) : QModelIndex();
+ if (!roster_) {
+ return QModelIndex();
+ }
+ GroupRosterItem* parentItem;
+ if (!parent.isValid()) {
+ //top level
+ parentItem = roster_->getRoot();
+ } else {
+ parentItem = dynamic_cast<GroupRosterItem*>(getItem(parent));
+ if (!parentItem) return QModelIndex();
+ }
+ return static_cast<size_t>(row) < parentItem->getDisplayedChildren().size() ? createIndex(row, column, parentItem->getDisplayedChildren()[row]) : QModelIndex();
}
QModelIndex RosterModel::index(RosterItem* item) const {
- GroupRosterItem* parent = item->getParent();
- /* Recursive check that it's ok to create such an item
- Assuming there are more contacts in a group than groups in a
- group, this could save a decent chunk of search time at startup.*/
- if (parent == NULL || roster_ == NULL || (parent != roster_->getRoot() && !index(parent).isValid())) {
- return QModelIndex();
- }
- for (size_t i = 0; i < parent->getDisplayedChildren().size(); i++) {
- if (parent->getDisplayedChildren()[i] == item) {
- return createIndex(i, 0, item);
- }
- }
- return QModelIndex();
+ GroupRosterItem* parent = item->getParent();
+ /* Recursive check that it's ok to create such an item
+ Assuming there are more contacts in a group than groups in a
+ group, this could save a decent chunk of search time at startup.*/
+ if (parent == nullptr || roster_ == nullptr || (parent != roster_->getRoot() && !index(parent).isValid())) {
+ return QModelIndex();
+ }
+ for (size_t i = 0; i < parent->getDisplayedChildren().size(); i++) {
+ if (parent->getDisplayedChildren()[i] == item) {
+ return createIndex(i, 0, item);
+ }
+ }
+ return QModelIndex();
}
QModelIndex RosterModel::parent(const QModelIndex& child) const {
- if (!roster_ || !child.isValid()) {
- return QModelIndex();
- }
-
- GroupRosterItem* parent = getItem(child)->getParent();
- return (parent != roster_->getRoot()) ? index(parent) : QModelIndex();
+ if (!roster_ || !child.isValid()) {
+ return QModelIndex();
+ }
+
+ GroupRosterItem* parent = getItem(child)->getParent();
+ return (parent != roster_->getRoot()) ? index(parent) : QModelIndex();
}
int RosterModel::rowCount(const QModelIndex& parent) const {
- if (!roster_) return 0;
- RosterItem* item = parent.isValid() ? static_cast<RosterItem*>(parent.internalPointer()) : roster_->getRoot();
- Q_ASSERT(item);
- GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
- int count = group ? group->getDisplayedChildren().size() : 0;
-// qDebug() << "rowCount = " << count << " where parent.isValid() == " << parent.isValid() << ", group == " << (group ? P2QSTRING(group->getDisplayName()) : "*contact*");
- return count;
+ if (!roster_) return 0;
+ RosterItem* item = parent.isValid() ? static_cast<RosterItem*>(parent.internalPointer()) : roster_->getRoot();
+ Q_ASSERT(item);
+ GroupRosterItem* group = dynamic_cast<GroupRosterItem*>(item);
+ int count = group ? group->getDisplayedChildren().size() : 0;
+// qDebug() << "rowCount = " << count << " where parent.isValid() == " << parent.isValid() << ", group == " << (group ? P2QSTRING(group->getDisplayName()) : "*contact*");
+ return count;
}
QMimeData* RosterModel::mimeData(const QModelIndexList& indexes) const {
- QMimeData* data = QAbstractItemModel::mimeData(indexes);
-
- ContactRosterItem *item = dynamic_cast<ContactRosterItem*>(getItem(indexes.first()));
- if (item == NULL) {
- return data;
- }
-
- /* only a single JID in this list */
- QByteArray itemData;
- QDataStream dataStream(&itemData, QIODevice::WriteOnly);
- dataStream << P2QSTRING(item->getJID().toString());
- data->setData("application/vnd.swift.contact-jid-list", itemData);
- return data;
+ QMimeData* data = QAbstractItemModel::mimeData(indexes);
+
+ ContactRosterItem *item = dynamic_cast<ContactRosterItem*>(getItem(indexes.first()));
+ if (item == nullptr) {
+ return data;
+ }
+
+ /* only a single JID in this list */
+ QByteArray itemData;
+ QDataStream dataStream(&itemData, QIODevice::WriteOnly);
+ dataStream << P2QSTRING(item->getJID().toString());
+ data->setData("application/vnd.swift.contact-jid-list", itemData);
+ return data;
}
}
diff --git a/Swift/QtUI/Roster/RosterModel.h b/Swift/QtUI/Roster/RosterModel.h
index 47ed614..af0d43a 100644
--- a/Swift/QtUI/Roster/RosterModel.h
+++ b/Swift/QtUI/Roster/RosterModel.h
@@ -14,58 +14,58 @@
#include <Swift/QtUI/QtScaledAvatarCache.h>
namespace Swift {
- enum RosterRoles {
- StatusTextRole = Qt::UserRole,
- AvatarRole = Qt::UserRole + 1,
- PresenceIconRole = Qt::UserRole + 2,
- StatusShowTypeRole = Qt::UserRole + 3,
- ChildCountRole = Qt::UserRole + 4,
- IdleRole = Qt::UserRole + 5,
- JIDRole = Qt::UserRole + 6,
- DisplayJIDRole = Qt::UserRole + 7
- };
+ enum RosterRoles {
+ StatusTextRole = Qt::UserRole,
+ AvatarRole = Qt::UserRole + 1,
+ PresenceIconRole = Qt::UserRole + 2,
+ StatusShowTypeRole = Qt::UserRole + 3,
+ ChildCountRole = Qt::UserRole + 4,
+ IdleRole = Qt::UserRole + 5,
+ JIDRole = Qt::UserRole + 6,
+ DisplayJIDRole = Qt::UserRole + 7
+ };
- class QtTreeWidget;
+ class QtTreeWidget;
- class RosterModel : public QAbstractItemModel {
- Q_OBJECT
- public:
- RosterModel(QtTreeWidget* view, bool screenReaderMode);
- ~RosterModel();
- void setRoster(Roster* swiftRoster);
- Qt::ItemFlags flags(const QModelIndex& index) const;
- int columnCount(const QModelIndex& parent = QModelIndex()) const;
- QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
- QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
- QModelIndex index(RosterItem* item) const;
- QModelIndex parent(const QModelIndex& index) const;
- int rowCount(const QModelIndex& parent = QModelIndex()) const;
- QMimeData* mimeData(const QModelIndexList& indexes) const;
+ class RosterModel : public QAbstractItemModel {
+ Q_OBJECT
+ public:
+ RosterModel(QtTreeWidget* view, bool screenReaderMode);
+ ~RosterModel();
+ void setRoster(Roster* swiftRoster);
+ Qt::ItemFlags flags(const QModelIndex& index) const;
+ int columnCount(const QModelIndex& parent = QModelIndex()) const;
+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
+ QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
+ QModelIndex index(RosterItem* item) const;
+ QModelIndex parent(const QModelIndex& index) const;
+ int rowCount(const QModelIndex& parent = QModelIndex()) const;
+ QMimeData* mimeData(const QModelIndexList& indexes) const;
- signals:
- void itemExpanded(const QModelIndex& item, bool expanded);
- private:
- void handleDataChanged(RosterItem* item);
- void handleChildrenChanged(GroupRosterItem* item);
- RosterItem* getItem(const QModelIndex& index) const;
- QColor intToColor(int color) const;
- QColor getTextColor(RosterItem* item) const;
- QColor getBackgroundColor(RosterItem* item) const;
- QString getToolTip(RosterItem* item) const;
- QString getAvatar(RosterItem* item) const;
- QString getStatusText(RosterItem* item) const;
- QString getJID(RosterItem* item) const;
- QString getDisplayJID(RosterItem* item) const;
- QIcon getPresenceIcon(RosterItem* item) const;
- int getChildCount(RosterItem* item) const;
- bool getIsIdle(RosterItem* item) const;
- void reLayout();
- /** calculates screenreader-friendly text if in screenreader mode, otherwise uses alternative text */
- QString getScreenReaderTextOr(RosterItem* item, const QString& alternative) const;
- private:
- Roster* roster_;
- QtTreeWidget* view_;
- QtScaledAvatarCache* cachedImageScaler_;
- bool screenReader_;
- };
+ signals:
+ void itemExpanded(const QModelIndex& item, bool expanded);
+ private:
+ void handleDataChanged(RosterItem* item);
+ void handleChildrenChanged(GroupRosterItem* item);
+ RosterItem* getItem(const QModelIndex& index) const;
+ QColor intToColor(int color) const;
+ QColor getTextColor(RosterItem* item) const;
+ QColor getBackgroundColor(RosterItem* item) const;
+ QString getToolTip(RosterItem* item) const;
+ QString getAvatar(RosterItem* item) const;
+ QString getStatusText(RosterItem* item) const;
+ QString getJID(RosterItem* item) const;
+ QString getDisplayJID(RosterItem* item) const;
+ QIcon getPresenceIcon(RosterItem* item) const;
+ int getChildCount(RosterItem* item) const;
+ bool getIsIdle(RosterItem* item) const;
+ void reLayout();
+ /** calculates screenreader-friendly text if in screenreader mode, otherwise uses alternative text */
+ QString getScreenReaderTextOr(RosterItem* item, const QString& alternative) const;
+ private:
+ Roster* roster_;
+ QtTreeWidget* view_;
+ QtScaledAvatarCache* cachedImageScaler_;
+ bool screenReader_;
+ };
}
diff --git a/Swift/QtUI/Roster/RosterTooltip.cpp b/Swift/QtUI/Roster/RosterTooltip.cpp
index 86f175d..ea4c9cd 100644
--- a/Swift/QtUI/Roster/RosterTooltip.cpp
+++ b/Swift/QtUI/Roster/RosterTooltip.cpp
@@ -4,163 +4,172 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#include <Swift/QtUI/Roster/RosterTooltip.h>
+#include <QApplication>
#include <QObject>
#include <QString>
-#include <QApplication>
#include <Swiften/Base/Path.h>
#include <Swift/Controllers/Roster/ContactRosterItem.h>
#include <Swift/Controllers/StatusUtil.h>
+#include <Swift/Controllers/Translator.h>
-#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/QtResourceHelper.h>
#include <Swift/QtUI/QtScaledAvatarCache.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swift/QtUI/QtUtilities.h>
-#include <Swift/QtUI/QtResourceHelper.h>
using namespace QtUtilities;
namespace Swift {
QString RosterTooltip::buildDetailedTooltip(ContactRosterItem* contact, QtScaledAvatarCache* cachedImageScaler) {
- QString tooltipTemplate;
- if (QApplication::layoutDirection() == Qt::RightToLeft) {
- tooltipTemplate = QString(
- "<table style='white-space:pre'>"
- "<tr>"
- "<td>"
- "<img src=\"%1\" />"
- "</td>"
- "<td>"
- "<p style='font-size: 14px'>%3 %2</p>"
- "<table><tr><td valign='middle'>%5</td><td valign='middle'>%4</td></tr></table>"
- "%6"
- "%7"
- "%8"
- "%9"
- "</td>"
- "</tr>"
- "</table>");
- } else {
- tooltipTemplate = QString(
- "<table style='white-space:pre'>"
- "<tr>"
- "<td>"
- "<img src=\"%1\" />"
- "</td>"
- "<td>"
- "<p style='font-size: 14px'>%2 %3</p>"
- "<table><tr><td valign='middle'>%4</td><td valign='middle'>%5</td></tr></table>"
- "%6"
- "%7"
- "%8"
- "%9"
- "</td>"
- "</tr>"
- "</table>");
- }
- // prepare tooltip
- QString fullName = P2QSTRING(contact->getDisplayName());
-
- QString vCardSummary;
- VCard::ref vCard = contact->getVCard();
- if (vCard) {
- fullName = P2QSTRING(vCard->getFullName()).trimmed();
- if (fullName.isEmpty()) {
- fullName = (P2QSTRING(vCard->getGivenName()) + " " + P2QSTRING(vCard->getFamilyName())).trimmed();
- }
- if (fullName.isEmpty()) {
- fullName = P2QSTRING(contact->getDisplayName());
- }
- vCardSummary = buildVCardSummary(vCard);
- } else {
- contact->onVCardRequested();
- }
-
- QString scaledAvatarPath = cachedImageScaler->getScaledAvatarPath(P2QSTRING(contact->getAvatarPath().empty() ? ":/icons/avatar.png" : pathToString(contact->getAvatarPath())));
-
- QString bareJID = contact->getDisplayJID().toString().empty() ? "" : "( " + P2QSTRING(contact->getDisplayJID().toString()) + " )";
-
- QString presenceIconTag = QString("<img src='%1' />").arg(statusShowTypeToIconPath(contact->getStatusShow()));
-
- QString statusMessage = contact->getStatusText().empty() ? QObject::tr("(No message)") : P2QSTRING(contact->getStatusText());
-
- QString idleString = P2QSTRING(contact->getIdleText());
- if (!idleString.isEmpty()) {
- idleString = QObject::tr("Idle since %1").arg(idleString);
- idleString = htmlEscape(idleString) + "<br/>";
- }
-
- QString lastSeen = P2QSTRING(contact->getOfflineSinceText());
- if (!lastSeen.isEmpty()) {
- lastSeen = QObject::tr("Last seen %1").arg(lastSeen);
- lastSeen = htmlEscape(lastSeen) + "<br/>";
- }
-
- QString mucOccupant= P2QSTRING(contact->getMUCAffiliationText());
- if (!mucOccupant.isEmpty()) {
- mucOccupant = htmlEscape(mucOccupant) + "<br/>";
- }
-
- return tooltipTemplate.arg(scaledAvatarPath, htmlEscape(fullName), htmlEscape(bareJID), presenceIconTag, htmlEscape(statusMessage), mucOccupant, idleString, lastSeen, vCardSummary);
+ QString tooltipTemplate;
+ if (QApplication::layoutDirection() == Qt::RightToLeft) {
+ tooltipTemplate = QString(
+ "<table style='white-space:pre'>"
+ "<tr>"
+ "<td>"
+ "<img src=\"%1\" />"
+ "</td>"
+ "<td>"
+ "<p style='font-size: 14px'>%3 %2</p>"
+ "<table><tr><td valign='middle'>%5</td><td valign='middle'>%4</td></tr></table>"
+ "%6"
+ "%7"
+ "%8"
+ "%9"
+ "</td>"
+ "</tr>"
+ "</table>");
+ } else {
+ tooltipTemplate = QString(
+ "<table style='white-space:pre'>"
+ "<tr>"
+ "<td>"
+ "<img src=\"%1\" />"
+ "</td>"
+ "<td>"
+ "<p style='font-size: 14px'>%2 %3</p>"
+ "<table><tr><td valign='middle'>%4</td><td valign='middle'>%5</td></tr></table>"
+ "%6"
+ "%7"
+ "%8"
+ "%9"
+ "</td>"
+ "</tr>"
+ "</table>");
+ }
+ // prepare tooltip
+ QString fullName = P2QSTRING(contact->getDisplayName());
+
+ QString vCardSummary;
+ VCard::ref vCard = contact->getVCard();
+ if (vCard) {
+ fullName = P2QSTRING(vCard->getFullName()).trimmed();
+ if (fullName.isEmpty()) {
+ fullName = (P2QSTRING(vCard->getGivenName()) + " " + P2QSTRING(vCard->getFamilyName())).trimmed();
+ }
+ if (fullName.isEmpty()) {
+ fullName = P2QSTRING(contact->getDisplayName());
+ }
+ vCardSummary = buildVCardSummary(vCard);
+ } else {
+ contact->onVCardRequested();
+ }
+
+ QString scaledAvatarPath = cachedImageScaler->getScaledAvatarPath(P2QSTRING(contact->getAvatarPath().empty() ? ":/icons/avatar.svg" : pathToString(contact->getAvatarPath())));
+
+ QString bareJID = contact->getDisplayJID().toString().empty() ? "" : "( " + P2QSTRING(contact->getDisplayJID().toString()) + " )";
+
+ QString presenceIconTag = QString("<img src='%1' />").arg(statusShowTypeToIconPath(contact->getStatusShow()));
+
+ QString statusMessage = contact->getStatusText().empty() ? QObject::tr("(No message)") : P2QSTRING(contact->getStatusText());
+
+ boost::posix_time::ptime idleTime = contact->getIdle();
+ QString idleString;
+ if (!idleTime.is_not_a_date_time()) {
+ idleString = QObject::tr("Idle since %1").arg(P2QSTRING(Swift::Translator::getInstance()->ptimeToHumanReadableString(idleTime)));
+ idleString = htmlEscape(idleString) + "<br/>";
+ }
+
+ boost::posix_time::ptime lastSeenTime = contact->getOfflineSince();
+ QString lastSeen;
+ if (!lastSeenTime.is_not_a_date_time()) {
+ lastSeen = QObject::tr("Last seen %1").arg(P2QSTRING(Swift::Translator::getInstance()->ptimeToHumanReadableString(lastSeenTime)));
+ lastSeen = htmlEscape(lastSeen) + "<br/>";
+ }
+
+ QString mucOccupant= P2QSTRING(contact->getMUCAffiliationText());
+ if (!mucOccupant.isEmpty()) {
+ mucOccupant = htmlEscape(mucOccupant) + "<br/>";
+ }
+
+ return tooltipTemplate.arg(scaledAvatarPath, htmlEscape(fullName), htmlEscape(bareJID), presenceIconTag, htmlEscape(statusMessage), mucOccupant, idleString, lastSeen, vCardSummary);
}
QString RosterTooltip::buildVCardSummary(VCard::ref vcard) {
- QString summary;
- summary = "<table>";
-
- // star | name | content
- QString currentBlock;
- foreach (const VCard::Telephone& tel, vcard->getTelephones()) {
- QString type = tel.isFax ? QObject::tr("Fax") : QObject::tr("Telephone");
- QString field = buildVCardField(tel.isPreferred, type, htmlEscape(P2QSTRING(tel.number)));
- if (tel.isPreferred) {
- currentBlock = field;
- break;
- }
- currentBlock += field;
- }
- summary += currentBlock;
-
- currentBlock = "";
- foreach (const VCard::EMailAddress& mail, vcard->getEMailAddresses()) {
- QString field = buildVCardField(mail.isPreferred, QObject::tr("E-Mail"), htmlEscape(P2QSTRING(mail.address)));
- if (mail.isPreferred) {
- currentBlock = field;
- break;
- }
- currentBlock += field;
- }
- summary += currentBlock;
-
- currentBlock = "";
- foreach (const VCard::Organization& org, vcard->getOrganizations()) {
- QString field = buildVCardField(false, QObject::tr("Organization"), htmlEscape(P2QSTRING(org.name)));
- currentBlock += field;
- }
- summary += currentBlock;
-
- currentBlock = "";
- foreach(const std::string& title, vcard->getTitles()) {
- QString field = buildVCardField(false, QObject::tr("Title"), htmlEscape(P2QSTRING(title)));
- currentBlock += field;
- }
- summary += currentBlock;
-
- summary += "</table>";
- return summary;
+ QString summary;
+ summary = "<table>";
+
+ // star | name | content
+ QString currentBlock;
+ for (const auto& tel : vcard->getTelephones()) {
+ QString type = tel.isFax ? QObject::tr("Fax") : QObject::tr("Telephone");
+ QString field = buildVCardField(tel.isPreferred, type, htmlEscape(P2QSTRING(tel.number)));
+ if (tel.isPreferred) {
+ currentBlock = field;
+ break;
+ }
+ currentBlock += field;
+ }
+ summary += currentBlock;
+
+ currentBlock = "";
+ for (const auto& mail : vcard->getEMailAddresses()) {
+ QString field = buildVCardField(mail.isPreferred, QObject::tr("E-Mail"), htmlEscape(P2QSTRING(mail.address)));
+ if (mail.isPreferred) {
+ currentBlock = field;
+ break;
+ }
+ currentBlock += field;
+ }
+ summary += currentBlock;
+
+ currentBlock = "";
+ for (const auto& org : vcard->getOrganizations()) {
+ QString field = buildVCardField(false, QObject::tr("Organization"), htmlEscape(P2QSTRING(org.name)));
+ currentBlock += field;
+ }
+ summary += currentBlock;
+
+ currentBlock = "";
+ for (const auto& title : vcard->getTitles()) {
+ QString field = buildVCardField(false, QObject::tr("Title"), htmlEscape(P2QSTRING(title)));
+ currentBlock += field;
+ }
+ summary += currentBlock;
+
+ summary += "</table>";
+ return summary;
}
QString RosterTooltip::buildVCardField(bool preferred, const QString& name, const QString& content) {
- QString rowTemplate;
- if (QApplication::layoutDirection() == Qt::RightToLeft) {
- rowTemplate = QString("<tr><td>%3</td><td valign='middle'><strong>%2</strong></td><td valign='middle'>%1</td></tr>");
- } else {
- rowTemplate = QString("<tr><td>%1</td><td valign='middle'><strong>%2</strong></td><td valign='middle'>%3</td></tr>");
- }
- return rowTemplate.arg(preferred ? "<img src=':/icons/star-checked.png' />" : "", name, content);
+ QString rowTemplate;
+ if (QApplication::layoutDirection() == Qt::RightToLeft) {
+ rowTemplate = QString("<tr><td>%3</td><td valign='middle'><strong>%2</strong></td><td valign='middle'>%1</td></tr>");
+ } else {
+ rowTemplate = QString("<tr><td>%1</td><td valign='middle'><strong>%2</strong></td><td valign='middle'>%3</td></tr>");
+ }
+ return rowTemplate.arg(preferred ? "<img src=':/icons/star-checked.png' />" : "", name, content);
}
}
diff --git a/Swift/QtUI/Roster/RosterTooltip.h b/Swift/QtUI/Roster/RosterTooltip.h
index 37f5da2..642809f 100644
--- a/Swift/QtUI/Roster/RosterTooltip.h
+++ b/Swift/QtUI/Roster/RosterTooltip.h
@@ -16,12 +16,12 @@ class ContactRosterItem;
class QtScaledAvatarCache;
class RosterTooltip {
- public:
- static QString buildDetailedTooltip(ContactRosterItem* contact, QtScaledAvatarCache* cachedImageScaler);
+ public:
+ static QString buildDetailedTooltip(ContactRosterItem* contact, QtScaledAvatarCache* cachedImageScaler);
- private:
- static QString buildVCardSummary(VCard::ref vcard);
- static QString buildVCardField(bool preferred, const QString& name, const QString& content);
+ private:
+ static QString buildVCardSummary(VCard::ref vcard);
+ static QString buildVCardField(bool preferred, const QString& name, const QString& content);
};
}
diff --git a/Swift/QtUI/Roster/main.cpp b/Swift/QtUI/Roster/main.cpp
index c2fecb5..c0402e8 100644
--- a/Swift/QtUI/Roster/main.cpp
+++ b/Swift/QtUI/Roster/main.cpp
@@ -1,66 +1,67 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <QtGui>
-#include "QtTreeWidget.h"
-#include "QtTreeWidgetFactory.h"
-#include "Swiften/Elements/StatusShow.h"
+#include <Swiften/Elements/StatusShow.h>
+
+#include <Swift/QtUI/Roster/QtTreeWidget.h>
+#include <Swift/QtUI/Roster/QtTreeWidgetFactory.h>
int main(int argc, char *argv[])
{
- QApplication app(argc, argv);
+ QApplication app(argc, argv);
+
+ //Swift::RosterModel model;
+
+ //QTreeView view;
+ //view.setModel(&model);
+ //view.setWindowTitle("A roster");
+ //view.show();
- //Swift::RosterModel model;
+ Swift::QtTreeWidgetFactory treeWidgetFactory;
+ Swift::QtTreeWidget* tree = dynamic_cast<Swift::QtTreeWidget*>(treeWidgetFactory.createTreeWidget());
+ tree->show();
+ QList<Swift::QtTreeWidgetItem*> item3s;
+ for (int i = 0; i < 500; i++) {
+ Swift::QtTreeWidgetItem* group = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(tree));
+ group->setText("People");
+ group->setBackgroundColor(0xBBBBBB);
+ Swift::QtTreeWidgetItem* item1 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
+ Swift::QtTreeWidgetItem* item2 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
+ Swift::QtTreeWidgetItem* item3 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
+ Swift::QtTreeWidgetItem* item4 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
+ item1->setText("Remko");
+ item2->setText("Kevin");
+ item3->setText("Cath");
+ item4->setText("KimTypo");
+ item4->setText("Kim");
+ item3s.push_back(item3);
+ }
- //QTreeView view;
- //view.setModel(&model);
- //view.setWindowTitle("A roster");
- //view.show();
+ Swift::QtTreeWidgetItem* group = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(tree));
+ group->setText("Many People");
- Swift::QtTreeWidgetFactory treeWidgetFactory;
- Swift::QtTreeWidget* tree = dynamic_cast<Swift::QtTreeWidget*>(treeWidgetFactory.createTreeWidget());
- tree->show();
- QList<Swift::QtTreeWidgetItem*> item3s;
- for (int i = 0; i < 500; i++) {
- Swift::QtTreeWidgetItem* group = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(tree));
- group->setText("People");
- group->setBackgroundColor(0xBBBBBB);
- Swift::QtTreeWidgetItem* item1 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
- Swift::QtTreeWidgetItem* item2 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
- Swift::QtTreeWidgetItem* item3 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
- Swift::QtTreeWidgetItem* item4 = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
- item1->setText("Remko");
- item2->setText("Kevin");
- item3->setText("Cath");
- item4->setText("KimTypo");
- item4->setText("Kim");
- item3s.push_back(item3);
- }
-
- Swift::QtTreeWidgetItem* group = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(tree));
- group->setText("Many People");
-
- Swift::QtTreeWidgetItem* person350;
- Swift::QtTreeWidgetItem* person1200;
+ Swift::QtTreeWidgetItem* person350;
+ Swift::QtTreeWidgetItem* person1200;
- for (int i = 0; i < 1500; i++) {
- Swift::QtTreeWidgetItem* item = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
- item->setText(Q2PSTRING(QString("Some person %1").arg(i)));
- item->setStatusShow(Swift::StatusShow::Away);
- if (i == 350) person350 = item;
- if (i == 1200) person1200 = item;
- }
+ for (int i = 0; i < 1500; i++) {
+ Swift::QtTreeWidgetItem* item = dynamic_cast<Swift::QtTreeWidgetItem*>(treeWidgetFactory.createTreeWidgetItem(group));
+ item->setText(Q2PSTRING(QString("Some person %1").arg(i)));
+ item->setStatusShow(Swift::StatusShow::Away);
+ if (i == 350) person350 = item;
+ if (i == 1200) person1200 = item;
+ }
- for (int i = 0; i < item3s.size(); i++) {
- item3s[i]->setStatusShow(Swift::StatusShow::XA);
- }
+ for (int i = 0; i < item3s.size(); i++) {
+ item3s[i]->setStatusShow(Swift::StatusShow::XA);
+ }
- person350->setStatusShow(Swift::StatusShow::DND);
- person1200->setStatusShow(Swift::StatusShow::Online);
+ person350->setStatusShow(Swift::StatusShow::DND);
+ person1200->setStatusShow(Swift::StatusShow::Online);
- return app.exec();
+ return app.exec();
}
diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript
index c8313c2..88cb1ac 100644
--- a/Swift/QtUI/SConscript
+++ b/Swift/QtUI/SConscript
@@ -1,21 +1,21 @@
import os, datetime, re, time
import Version
-def generateDefaultTheme(dir) :
- sourceDir = dir.abspath
- result = "<!-- WARNING: This file is automatically generated. Any changes will be overwritten. -->\n"
- result += "<RCC version =\"1.0\">"
- result += "<qresource prefix=\"/themes/Default\">"
- for (path, dirs, files) in os.walk(sourceDir) :
- for file in files :
- filePath = os.path.join(path,file)
- result += "<file alias=\"%(alias)s\">%(path)s</file>" % {
- "alias": filePath[len(sourceDir)+1:],
- "path": filePath
- }
- result += "</qresource>"
- result += "</RCC>"
- return result
+def generateQRCTheme(dir, prefix) :
+ sourceDir = dir.abspath
+ result = "<!-- WARNING: This file is automatically generated. Any changes will be overwritten. -->\n"
+ result += "<RCC version =\"1.0\">"
+ result += "<qresource prefix=\"/themes/" + prefix + "\">"
+ for (path, dirs, files) in os.walk(sourceDir) :
+ for file in files :
+ filePath = os.path.join(path,file)
+ result += "<file alias=\"%(alias)s\">%(path)s</file>" % {
+ "alias": filePath[len(sourceDir)+1:],
+ "path": filePath
+ }
+ result += "</qresource>"
+ result += "</RCC>"
+ return result
Import("env")
@@ -24,33 +24,30 @@ myenv = env.Clone()
# Disable warnings that affect Qt
myenv["CXXFLAGS"] = filter(lambda x : x != "-Wfloat-equal", myenv["CXXFLAGS"])
if "clang" in env["CC"] :
- myenv.Append(CXXFLAGS = ["-Wno-float-equal", "-Wno-shorten-64-to-32", "-Wno-missing-prototypes", "-Wno-unreachable-code", "-Wno-disabled-macro-expansion", "-Wno-unused-private-field", "-Wno-extra-semi", "-Wno-duplicate-enum", "-Wno-missing-variable-declarations", "-Wno-conversion", "-Wno-undefined-reinterpret-cast"])
+ myenv.Append(CXXFLAGS = ["-Wno-float-equal", "-Wno-shorten-64-to-32", "-Wno-missing-prototypes", "-Wno-unreachable-code", "-Wno-disabled-macro-expansion", "-Wno-unused-private-field", "-Wno-extra-semi", "-Wno-duplicate-enum", "-Wno-missing-variable-declarations", "-Wno-conversion", "-Wno-undefined-reinterpret-cast"])
myenv.UseFlags(env["SWIFT_CONTROLLERS_FLAGS"])
myenv.UseFlags(env["SWIFTOOLS_FLAGS"])
if myenv["HAVE_XSS"] :
- myenv.UseFlags(env["XSS_FLAGS"])
+ myenv.UseFlags(env["XSS_FLAGS"])
if env["PLATFORM"] == "posix" :
- myenv.Append(LIBS = ["X11"])
+ myenv.Append(LIBS = ["X11"])
if myenv["HAVE_SPARKLE"] :
- myenv.UseFlags(env["SPARKLE_FLAGS"])
+ myenv.UseFlags(env["SPARKLE_FLAGS"])
myenv.UseFlags(env["SWIFTEN_FLAGS"])
myenv.UseFlags(env["SWIFTEN_DEP_FLAGS"])
if myenv.get("HAVE_BREAKPAD") :
- myenv.UseFlags(env["BREAKPAD_FLAGS"])
+ myenv.UseFlags(env["BREAKPAD_FLAGS"])
if myenv.get("HAVE_GROWL", False) :
- myenv.UseFlags(myenv["GROWL_FLAGS"])
- myenv.Append(CPPDEFINES = ["HAVE_GROWL"])
+ myenv.UseFlags(myenv["GROWL_FLAGS"])
+ myenv.Append(CPPDEFINES = ["HAVE_GROWL"])
if myenv["swift_mobile"] :
- myenv.Append(CPPDEFINES = ["SWIFT_MOBILE"])
-if myenv.get("HAVE_SNARL", False) :
- myenv.UseFlags(myenv["SNARL_FLAGS"])
- myenv.Append(CPPDEFINES = ["HAVE_SNARL"])
+ myenv.Append(CPPDEFINES = ["SWIFT_MOBILE"])
if myenv.get("HAVE_HUNSPELL", True):
- myenv.Append(CPPDEFINES = ["HAVE_HUNSPELL"])
- myenv.UseFlags(myenv["HUNSPELL_FLAGS"])
+ myenv.Append(CPPDEFINES = ["HAVE_HUNSPELL"])
+ myenv.UseFlags(myenv["HUNSPELL_FLAGS"])
if env["PLATFORM"] == "win32" :
- myenv.Append(LIBS = ["cryptui"])
+ myenv.Append(LIBS = ["cryptui"])
myenv.UseFlags(myenv["PLATFORM_FLAGS"])
myenv.Tool("qt4", toolpath = ["#/BuildTools/SCons/Tools"])
@@ -59,16 +56,18 @@ myenv.Tool("wix", toolpath = ["#/BuildTools/SCons/Tools"])
myenv.Tool("textfile", toolpath = ["#/BuildTools/SCons/Tools"])
qt4modules = ['QtCore', 'QtWebKit', 'QtGui']
if myenv["qt5"] :
- qt_version = '5'
- qt4modules += ['QtWidgets', 'QtWebKitWidgets', 'QtMultimedia']
- if env["PLATFORM"] != "win32" and env["PLATFORM"] != "darwin" :
- qt4modules += ['QtX11Extras']
+ qt_version = '5'
+ # QtSvg is required so the image format plugin for SVG images is installed
+ # correctly by Qt's deployment tools.
+ qt4modules += ['QtWidgets', 'QtWebKitWidgets', 'QtMultimedia', 'QtSvg']
+ if env["PLATFORM"] != "win32" and env["PLATFORM"] != "darwin" :
+ qt4modules += ['QtX11Extras']
else :
- qt_version = '4'
+ qt_version = '4'
if env["PLATFORM"] == "posix" :
- qt4modules += ["QtDBus"]
+ qt4modules += ["QtDBus"]
if env["PLATFORM"] != "win32" and env["PLATFORM"] != "darwin" :
- qt4modules += ["QtNetwork"]
+ qt4modules += ["QtNetwork"]
myenv.EnableQt4Modules(qt4modules, debug = False, version = qt_version)
@@ -76,167 +75,170 @@ myenv.Append(CPPPATH = ["."])
# Qt requires applications to be build with the -fPIC flag on some 32-bit Linux distributions.
if env["PLATFORM"] == "posix" :
- testEnv = myenv.Clone()
- conf = Configure(testEnv)
- if conf.CheckDeclaration("QT_REDUCE_RELOCATIONS", "#include <QtCore/qconfig.h>") and conf.CheckDeclaration("__i386__"):
- myenv.AppendUnique(CXXFLAGS = "-fPIC")
- testEnv = conf.Finish()
+ testEnv = myenv.Clone()
+ conf = Configure(testEnv)
+ if conf.CheckDeclaration("QT_REDUCE_RELOCATIONS", "#include <QtCore/qconfig.h>") and conf.CheckDeclaration("__i386__"):
+ myenv.AppendUnique(CXXFLAGS = "-fPIC")
+ testEnv = conf.Finish()
if env["PLATFORM"] == "win32" :
- #myenv.Append(LINKFLAGS = ["/SUBSYSTEM:CONSOLE"])
- myenv.Append(LINKFLAGS = ["/SUBSYSTEM:WINDOWS"])
- myenv.Append(LIBS = "qtmain")
- if myenv.get("HAVE_SCHANNEL", 0) :
- myenv.Append(LIBS = "Cryptui")
- myenv.Append(CPPDEFINES = "HAVE_SCHANNEL")
- if env["debug"] and not env["optimize"]:
- myenv.Append(LINKFLAGS = ["/NODEFAULTLIB:msvcrt"])
+ #myenv.Append(LINKFLAGS = ["/SUBSYSTEM:CONSOLE"])
+ myenv.Append(LINKFLAGS = ["/SUBSYSTEM:WINDOWS"])
+ myenv.Append(LIBS = "qtmain")
+ if myenv.get("HAVE_SCHANNEL", 0) :
+ myenv.Append(LIBS = "Cryptui")
+ myenv.Append(CPPDEFINES = "HAVE_SCHANNEL")
-myenv.WriteVal("DefaultTheme.qrc", myenv.Value(generateDefaultTheme(myenv.Dir("#/Swift/resources/themes/Default"))))
+if env["PLATFORM"] == "darwin" and env["HAVE_SPARKLE"] :
+ myenv.Append(LINKFLAGS = ["-Wl,-rpath,@loader_path/../Frameworks"])
+
+myenv.WriteVal("DefaultTheme.qrc", myenv.Value(generateQRCTheme(myenv.Dir("#/Swift/resources/themes/Default"), "Default")))
sources = [
- "main.cpp",
- "QtAboutWidget.cpp",
- "QtSpellCheckerWindow.cpp",
- "QtAvatarWidget.cpp",
- "QtUIFactory.cpp",
- "QtChatWindowFactory.cpp",
- "QtClickableLabel.cpp",
- "QtLoginWindow.cpp",
- "QtMainWindow.cpp",
- "QtProfileWindow.cpp",
- "QtBlockListEditorWindow.cpp",
- "QtNameWidget.cpp",
- "QtSettingsProvider.cpp",
- "QtStatusWidget.cpp",
- "QtScaledAvatarCache.cpp",
- "QtSwift.cpp",
- "QtURIHandler.cpp",
- "QtChatWindow.cpp",
- "QtChatView.cpp",
- "QtWebKitChatView.cpp",
- "QtPlainChatView.cpp",
- "QtChatTheme.cpp",
- "QtChatTabs.cpp",
- "QtChatTabsBase.cpp",
- "QtChatTabsShortcutOnlySubstitute.cpp",
- "QtSoundPlayer.cpp",
- "QtSystemTray.cpp",
- "QtCachedImageScaler.cpp",
- "QtTabbable.cpp",
- "QtTabWidget.cpp",
- "QtTextEdit.cpp",
- "QtXMLConsoleWidget.cpp",
- "QtHistoryWindow.cpp",
- "QtFileTransferListWidget.cpp",
- "QtFileTransferListItemModel.cpp",
- "QtAdHocCommandWindow.cpp",
- "QtAdHocCommandWithJIDWindow.cpp",
- "QtUtilities.cpp",
- "QtBookmarkDetailWindow.cpp",
- "QtAddBookmarkWindow.cpp",
- "QtEditBookmarkWindow.cpp",
- "QtEmoticonsGrid.cpp",
- "QtEmoticonCell.cpp",
- "QtContactEditWindow.cpp",
- "QtContactEditWidget.cpp",
- "QtSingleWindow.cpp",
- "QtHighlightEditor.cpp",
- "QtColorToolButton.cpp",
- "QtClosableLineEdit.cpp",
- "ChatSnippet.cpp",
- "MessageSnippet.cpp",
- "SystemMessageSnippet.cpp",
- "QtElidingLabel.cpp",
- "QtFormWidget.cpp",
- "QtFormResultItemModel.cpp",
- "QtLineEdit.cpp",
- "QtJoinMUCWindow.cpp",
- "QtConnectionSettingsWindow.cpp",
- "Roster/RosterModel.cpp",
- "Roster/QtTreeWidget.cpp",
-# "Roster/QtTreeWidgetItem.cpp",
- "Roster/RosterDelegate.cpp",
- "Roster/GroupItemDelegate.cpp",
- "Roster/DelegateCommons.cpp",
- "Roster/QtFilterWidget.cpp",
- "Roster/QtRosterWidget.cpp",
- "Roster/QtOccupantListWidget.cpp",
- "Roster/RosterTooltip.cpp",
- "EventViewer/EventModel.cpp",
- "EventViewer/EventDelegate.cpp",
- "EventViewer/TwoLineDelegate.cpp",
- "EventViewer/QtEventWindow.cpp",
- "EventViewer/QtEvent.cpp",
- "ChatList/QtChatListWindow.cpp",
- "ChatList/ChatListModel.cpp",
- "ChatList/ChatListDelegate.cpp",
- "ChatList/ChatListMUCItem.cpp",
- "ChatList/ChatListRecentItem.cpp",
- "ChatList/ChatListWhiteboardItem.cpp",
- "MUCSearch/QtMUCSearchWindow.cpp",
- "MUCSearch/MUCSearchModel.cpp",
- "MUCSearch/MUCSearchRoomItem.cpp",
- "MUCSearch/MUCSearchEmptyItem.cpp",
- "MUCSearch/MUCSearchDelegate.cpp",
- "UserSearch/ContactListDelegate.cpp",
- "UserSearch/ContactListModel.cpp",
- "UserSearch/QtContactListWidget.cpp",
- "UserSearch/QtSuggestingJIDInput.cpp",
- "UserSearch/QtUserSearchFirstPage.cpp",
- "UserSearch/QtUserSearchFirstMultiJIDPage.cpp",
- "UserSearch/QtUserSearchFieldsPage.cpp",
- "UserSearch/QtUserSearchResultsPage.cpp",
- "UserSearch/QtUserSearchDetailsPage.cpp",
- "UserSearch/QtUserSearchWindow.cpp",
- "UserSearch/UserSearchModel.cpp",
- "UserSearch/UserSearchDelegate.cpp",
- "Whiteboard/FreehandLineItem.cpp",
- "Whiteboard/GView.cpp",
- "Whiteboard/TextDialog.cpp",
- "Whiteboard/QtWhiteboardWindow.cpp",
- "Whiteboard/ColorWidget.cpp",
- "QtSubscriptionRequestWindow.cpp",
- "QtRosterHeader.cpp",
- "QtWebView.cpp",
- "qrc_DefaultTheme.cc",
- "qrc_Swift.cc",
- "QtChatWindowJSBridge.cpp",
- "QtMUCConfigurationWindow.cpp",
- "QtAffiliationEditor.cpp",
- "QtUISettingConstants.cpp",
- "QtURLValidator.cpp",
- "QtResourceHelper.cpp",
- "QtSpellCheckHighlighter.cpp",
- "Trellis/QtDynamicGridLayout.cpp",
- "Trellis/QtDNDTabBar.cpp",
- "Trellis/QtGridSelectionDialog.cpp"
+ "main.cpp",
+ "QtAboutWidget.cpp",
+ "QtSpellCheckerWindow.cpp",
+ "QtAvatarWidget.cpp",
+ "QtUIFactory.cpp",
+ "QtChatWindowFactory.cpp",
+ "QtClickableLabel.cpp",
+ "QtLoginWindow.cpp",
+ "QtMainWindow.cpp",
+ "QtProfileWindow.cpp",
+ "QtBlockListEditorWindow.cpp",
+ "QtNameWidget.cpp",
+ "QtSettingsProvider.cpp",
+ "QtStatusWidget.cpp",
+ "QtScaledAvatarCache.cpp",
+ "QtSwift.cpp",
+ "QtURIHandler.cpp",
+ "QtChatWindow.cpp",
+ "QtChatView.cpp",
+ "QtWebKitChatView.cpp",
+ "QtPlainChatView.cpp",
+ "QtChatTheme.cpp",
+ "QtChatTabs.cpp",
+ "QtChatTabsBase.cpp",
+ "QtChatTabsShortcutOnlySubstitute.cpp",
+ "QtSoundPlayer.cpp",
+ "QtSystemTray.cpp",
+ "QtCachedImageScaler.cpp",
+ "QtTabbable.cpp",
+ "QtTabWidget.cpp",
+ "QtTextEdit.cpp",
+ "QtXMLConsoleWidget.cpp",
+ "QtHistoryWindow.cpp",
+ "QtFileTransferListWidget.cpp",
+ "QtFileTransferListItemModel.cpp",
+ "QtAdHocCommandWindow.cpp",
+ "QtAdHocCommandWithJIDWindow.cpp",
+ "QtUtilities.cpp",
+ "QtBookmarkDetailWindow.cpp",
+ "QtAddBookmarkWindow.cpp",
+ "QtEditBookmarkWindow.cpp",
+ "QtEmoticonsGrid.cpp",
+ "QtEmoticonCell.cpp",
+ "QtContactEditWindow.cpp",
+ "QtContactEditWidget.cpp",
+ "QtSingleWindow.cpp",
+ "QtHighlightEditor.cpp",
+ "QtColorToolButton.cpp",
+ "QtClosableLineEdit.cpp",
+ "ChatSnippet.cpp",
+ "MessageSnippet.cpp",
+ "SystemMessageSnippet.cpp",
+ "QtElidingLabel.cpp",
+ "QtFormWidget.cpp",
+ "QtFormResultItemModel.cpp",
+ "QtLineEdit.cpp",
+ "QtJoinMUCWindow.cpp",
+ "QtConnectionSettingsWindow.cpp",
+ "Roster/RosterModel.cpp",
+ "Roster/QtTreeWidget.cpp",
+ "Roster/RosterDelegate.cpp",
+ "Roster/GroupItemDelegate.cpp",
+ "Roster/DelegateCommons.cpp",
+ "Roster/QtFilterWidget.cpp",
+ "Roster/QtRosterWidget.cpp",
+ "Roster/QtOccupantListWidget.cpp",
+ "Roster/RosterTooltip.cpp",
+ "EventViewer/EventModel.cpp",
+ "EventViewer/EventDelegate.cpp",
+ "EventViewer/TwoLineDelegate.cpp",
+ "EventViewer/QtEventWindow.cpp",
+ "EventViewer/QtEvent.cpp",
+ "ChatList/QtChatListWindow.cpp",
+ "ChatList/ChatListModel.cpp",
+ "ChatList/ChatListDelegate.cpp",
+ "ChatList/ChatListMUCItem.cpp",
+ "ChatList/ChatListRecentItem.cpp",
+ "ChatList/ChatListWhiteboardItem.cpp",
+ "MUCSearch/MUCSearchDelegate.cpp",
+ "MUCSearch/MUCSearchEmptyItem.cpp",
+ "MUCSearch/MUCSearchModel.cpp",
+ "MUCSearch/MUCSearchRoomItem.cpp",
+ "MUCSearch/MUCSearchServiceItem.cpp",
+ "MUCSearch/QtLeafSortFilterProxyModel.cpp",
+ "MUCSearch/QtMUCSearchWindow.cpp",
+ "UserSearch/ContactListDelegate.cpp",
+ "UserSearch/ContactListModel.cpp",
+ "UserSearch/QtContactListWidget.cpp",
+ "UserSearch/QtSuggestingJIDInput.cpp",
+ "UserSearch/QtUserSearchFirstPage.cpp",
+ "UserSearch/QtUserSearchFirstMultiJIDPage.cpp",
+ "UserSearch/QtUserSearchFieldsPage.cpp",
+ "UserSearch/QtUserSearchResultsPage.cpp",
+ "UserSearch/QtUserSearchDetailsPage.cpp",
+ "UserSearch/QtUserSearchWindow.cpp",
+ "UserSearch/UserSearchModel.cpp",
+ "UserSearch/UserSearchDelegate.cpp",
+ "Whiteboard/FreehandLineItem.cpp",
+ "Whiteboard/GView.cpp",
+ "Whiteboard/TextDialog.cpp",
+ "Whiteboard/QtWhiteboardWindow.cpp",
+ "Whiteboard/ColorWidget.cpp",
+ "QtSubscriptionRequestWindow.cpp",
+ "QtRosterHeader.cpp",
+ "QtWebView.cpp",
+ "qrc_DefaultTheme.cc",
+ "qrc_Swift.cc",
+ "QtChatWindowJSBridge.cpp",
+ "QtMUCConfigurationWindow.cpp",
+ "QtAffiliationEditor.cpp",
+ "QtUISettingConstants.cpp",
+ "QtURLValidator.cpp",
+ "QtResourceHelper.cpp",
+ "QtSpellCheckHighlighter.cpp",
+ "QtUpdateFeedSelectionDialog.cpp",
+ "Trellis/QtDynamicGridLayout.cpp",
+ "Trellis/QtDNDTabBar.cpp",
+ "Trellis/QtGridSelectionDialog.cpp"
]
if env["PLATFORM"] == "win32" :
- sources.extend(["qrc_SwiftWindows.cc"])
+ sources.extend(["qrc_SwiftWindows.cc"])
# QtVCardWidget
sources.extend([
- "QtVCardWidget/QtCloseButton.cpp",
- "QtVCardWidget/QtRemovableItemDelegate.cpp",
- "QtVCardWidget/QtResizableLineEdit.cpp",
- "QtVCardWidget/QtTagComboBox.cpp",
- "QtVCardWidget/QtVCardHomeWork.cpp",
- "QtVCardWidget/QtVCardAddressField.cpp",
- "QtVCardWidget/QtVCardAddressLabelField.cpp",
- "QtVCardWidget/QtVCardBirthdayField.cpp",
- "QtVCardWidget/QtVCardDescriptionField.cpp",
- "QtVCardWidget/QtVCardInternetEMailField.cpp",
- "QtVCardWidget/QtVCardJIDField.cpp",
- "QtVCardWidget/QtVCardOrganizationField.cpp",
- "QtVCardWidget/QtVCardPhotoAndNameFields.cpp",
- "QtVCardWidget/QtVCardRoleField.cpp",
- "QtVCardWidget/QtVCardTelephoneField.cpp",
- "QtVCardWidget/QtVCardTitleField.cpp",
- "QtVCardWidget/QtVCardURLField.cpp",
- "QtVCardWidget/QtVCardGeneralField.cpp",
- "QtVCardWidget/QtVCardWidget.cpp"
+ "QtVCardWidget/QtCloseButton.cpp",
+ "QtVCardWidget/QtRemovableItemDelegate.cpp",
+ "QtVCardWidget/QtResizableLineEdit.cpp",
+ "QtVCardWidget/QtTagComboBox.cpp",
+ "QtVCardWidget/QtVCardHomeWork.cpp",
+ "QtVCardWidget/QtVCardAddressField.cpp",
+ "QtVCardWidget/QtVCardAddressLabelField.cpp",
+ "QtVCardWidget/QtVCardBirthdayField.cpp",
+ "QtVCardWidget/QtVCardDescriptionField.cpp",
+ "QtVCardWidget/QtVCardInternetEMailField.cpp",
+ "QtVCardWidget/QtVCardJIDField.cpp",
+ "QtVCardWidget/QtVCardOrganizationField.cpp",
+ "QtVCardWidget/QtVCardPhotoAndNameFields.cpp",
+ "QtVCardWidget/QtVCardRoleField.cpp",
+ "QtVCardWidget/QtVCardTelephoneField.cpp",
+ "QtVCardWidget/QtVCardTitleField.cpp",
+ "QtVCardWidget/QtVCardURLField.cpp",
+ "QtVCardWidget/QtVCardGeneralField.cpp",
+ "QtVCardWidget/QtVCardWidget.cpp"
])
myenv.Uic4("QtVCardWidget/QtVCardPhotoAndNameFields.ui")
@@ -247,52 +249,52 @@ myenv.Uic4("QtProfileWindow.ui")
# Determine the version
myenv["SWIFT_VERSION"] = Version.getBuildVersion(env.Dir("#").abspath, "swift")
if env["PLATFORM"] == "win32" :
- swift_windows_version = Version.convertToWindowsVersion(myenv["SWIFT_VERSION"])
- myenv["SWIFT_VERSION_MAJOR"] = swift_windows_version[0]
- myenv["SWIFT_VERSION_MINOR"] = swift_windows_version[1]
- myenv["SWIFT_VERSION_PATCH"] = swift_windows_version[2]
+ swift_windows_version = Version.convertToWindowsVersion(myenv["SWIFT_VERSION"])
+ myenv["SWIFT_VERSION_MAJOR"] = swift_windows_version[0]
+ myenv["SWIFT_VERSION_MINOR"] = swift_windows_version[1]
+ myenv["SWIFT_VERSION_PATCH"] = swift_windows_version[2]
if env["PLATFORM"] == "win32" :
- res_env = myenv.Clone()
- res_env.Append(CPPDEFINES = [
- ("SWIFT_COPYRIGHT_YEAR", "\"\\\"2010-%s\\\"\"" % str(time.localtime()[0])),
- ("SWIFT_VERSION_MAJOR", "${SWIFT_VERSION_MAJOR}"),
- ("SWIFT_VERSION_MINOR", "${SWIFT_VERSION_MINOR}"),
- ("SWIFT_VERSION_PATCH", "${SWIFT_VERSION_PATCH}"),
- ])
- res = res_env.RES("#/Swift/resources/Windows/Swift.rc")
- # For some reason, SCons isn't picking up the dependency correctly
- # Adding it explicitly until i figure out why
- myenv.Depends(res, "../Controllers/BuildVersion.h")
- sources += [
- "WinUIHelpers.cpp",
- "CAPICertificateSelector.cpp",
- "WindowsNotifier.cpp",
- "#/Swift/resources/Windows/Swift.res"
- ]
+ res_env = myenv.Clone()
+ res_env.Append(CPPDEFINES = [
+ ("SWIFT_COPYRIGHT_YEAR", "\"\\\"2010-%s\\\"\"" % str(time.localtime()[0])),
+ ("SWIFT_VERSION_MAJOR", "${SWIFT_VERSION_MAJOR}"),
+ ("SWIFT_VERSION_MINOR", "${SWIFT_VERSION_MINOR}"),
+ ("SWIFT_VERSION_PATCH", "${SWIFT_VERSION_PATCH}"),
+ ])
+ res = res_env.RES("#/Swift/resources/Windows/Swift.rc")
+ # For some reason, SCons isn't picking up the dependency correctly
+ # Adding it explicitly until i figure out why
+ myenv.Depends(res, "../Controllers/BuildVersion.h")
+ sources += [
+ "WinUIHelpers.cpp",
+ "CAPICertificateSelector.cpp",
+ "WindowsNotifier.cpp",
+ "#/Swift/resources/Windows/Swift.res"
+ ]
if env["PLATFORM"] == "posix" :
- sources += [
- "FreeDesktopNotifier.cpp",
- "QtDBUSURIHandler.cpp",
- ]
+ sources += [
+ "FreeDesktopNotifier.cpp",
+ "QtDBUSURIHandler.cpp",
+ ]
if env["PLATFORM"] == "darwin" :
- sources += ["CocoaApplicationActivateHelper.mm"]
- sources += ["CocoaUIHelpers.mm"]
+ sources += ["CocoaApplicationActivateHelper.mm"]
+ sources += ["CocoaUIHelpers.mm"]
if env["PLATFORM"] == "darwin" or env["PLATFORM"] == "win32" :
- swiftProgram = myenv.Program("Swift", sources)
+ swiftProgram = myenv.Program("Swift", sources)
else :
- sources += ["QtCertificateViewerDialog.cpp"];
- myenv.Uic4("QtCertificateViewerDialog.ui");
- swiftProgram = myenv.Program("swift-im", sources)
+ sources += ["QtCertificateViewerDialog.cpp"];
+ myenv.Uic4("QtCertificateViewerDialog.ui");
+ swiftProgram = myenv.Program("swift-im", sources)
if env["PLATFORM"] != "darwin" and env["PLATFORM"] != "win32" :
- openURIProgram = myenv.Program("swift-open-uri", "swift-open-uri.cpp")
+ openURIProgram = myenv.Program("swift-open-uri", "swift-open-uri.cpp")
else :
- openURIProgram = []
+ openURIProgram = []
myenv.Uic4("MUCSearch/QtMUCSearchWindow.ui")
myenv.Uic4("UserSearch/QtUserSearchWizard.ui")
@@ -308,15 +310,16 @@ myenv.Uic4("QtConnectionSettings.ui")
myenv.Uic4("QtHighlightEditor.ui")
myenv.Uic4("QtBlockListEditorWindow.ui")
myenv.Uic4("QtSpellCheckerWindow.ui")
+myenv.Uic4("QtUpdateFeedSelectionDialog.ui")
myenv.Qrc("DefaultTheme.qrc")
myenv.Qrc("Swift.qrc")
if env["PLATFORM"] == "win32" :
- myenv.Qrc("SwiftWindows.qrc")
+ myenv.Qrc("SwiftWindows.qrc")
# Resources
commonResources = {
- "": ["#/Swift/resources/sounds"]
+ "": ["#/Swift/resources/sounds"]
}
myenv["TEXTFILESUFFIX"] = ""
@@ -329,138 +332,143 @@ myenv.MyTextfile(target = "COPYING", source = [myenv.File("../../COPYING.gpl"),
# Collect available languages
translation_languages = []
for file in os.listdir(Dir("#/Swift/Translations").abspath) :
- if file.startswith("swift_") and file.endswith(".ts") :
- translation_languages.append(file[6:-3])
+ if file.startswith("swift_") and file.endswith(".ts") :
+ translation_languages.append(file[6:-3])
# Generate translation modules
translation_sources = [env.File("#/Swift/Translations/swift.ts").abspath]
translation_modules = []
for lang in translation_languages :
- translation_resource = "#/Swift/resources/translations/swift_" + lang + ".qm"
- translation_source = "#/Swift/Translations/swift_" + lang + ".ts"
- translation_sources.append(env.File(translation_source).abspath)
- translation_modules.append(env.File(translation_resource).abspath)
- myenv.Qm(translation_resource, translation_source)
- commonResources["translations"] = commonResources.get("translations", []) + [translation_resource]
+ translation_resource = "#/Swift/resources/translations/swift_" + lang + ".qm"
+ translation_source = "#/Swift/Translations/swift_" + lang + ".ts"
+ translation_sources.append(env.File(translation_source).abspath)
+ translation_modules.append(env.File(translation_resource).abspath)
+ myenv.Qm(translation_resource, translation_source)
+ commonResources["translations"] = commonResources.get("translations", []) + [translation_resource]
# LUpdate translation (if requested)
if ARGUMENTS.get("update_translations", False) :
- myenv.Precious(translation_sources)
- remove_obsolete_option = ""
- codecfortr = ""
- if ARGUMENTS.get("remove_obsolete_translations", False) :
- remove_obsolete_option = " -no-obsolete"
- if qt_version == '4':
- codecfortr = "-codecfortr UTF-8"
- for translation_source in filter(lambda x: not x.endswith("_en.ts"), translation_sources) :
- t = myenv.Command([translation_source], [], [myenv.Action("$QT4_LUPDATE -I " + env.Dir("#").abspath + remove_obsolete_option + " -silent " + codecfortr + " -recursive Swift -ts " + translation_source, cmdstr = "$QT4_LUPDATECOMSTR")])
- myenv.AlwaysBuild(t)
+ myenv.Precious(translation_sources)
+ remove_obsolete_option = ""
+ codecfortr = ""
+ if ARGUMENTS.get("remove_obsolete_translations", False) :
+ remove_obsolete_option = " -no-obsolete"
+ if qt_version == '4':
+ codecfortr = "-codecfortr UTF-8"
+ for translation_source in filter(lambda x: not x.endswith("_en.ts"), translation_sources) :
+ t = myenv.Command([translation_source], [], [myenv.Action("$QT4_LUPDATE -I " + env.Dir("#").abspath + remove_obsolete_option + " -silent " + codecfortr + " -recursive Swift -ts " + translation_source, cmdstr = "$QT4_LUPDATECOMSTR")])
+ myenv.AlwaysBuild(t)
# NSIS installation script
if env["PLATFORM"] == "win32" :
- nsis_translation_install_script = ""
- nsis_translation_uninstall_script = ""
- for lang in translation_languages :
- nsis_translation_install_script += "File \"..\\..\\QtUI\\Swift\\translations\\swift_" + lang + ".qm\"\n"
- nsis_translation_uninstall_script += "delete $INSTDIR\\translations\\swift_" + lang + ".qm\n"
- myenv.WriteVal("../Packaging/nsis/translations-install.nsh", myenv.Value(nsis_translation_install_script))
- myenv.WriteVal("../Packaging/nsis/translations-uninstall.nsh", myenv.Value(nsis_translation_uninstall_script))
-
+ nsis_translation_install_script = ""
+ nsis_translation_uninstall_script = ""
+ for lang in translation_languages :
+ nsis_translation_install_script += "File \"..\\..\\QtUI\\Swift\\translations\\swift_" + lang + ".qm\"\n"
+ nsis_translation_uninstall_script += "delete $INSTDIR\\translations\\swift_" + lang + ".qm\n"
+ myenv.WriteVal("../Packaging/nsis/translations-install.nsh", myenv.Value(nsis_translation_install_script))
+ myenv.WriteVal("../Packaging/nsis/translations-uninstall.nsh", myenv.Value(nsis_translation_uninstall_script))
+
################################################################################
if env["PLATFORM"] == "darwin" :
- frameworks = []
- if env["HAVE_SPARKLE"] :
- frameworks.append(env["SPARKLE_FRAMEWORK"])
- if env["HAVE_GROWL"] :
- frameworks.append(env["GROWL_FRAMEWORK"])
- commonResources[""] = commonResources.get("", []) + ["#/Swift/resources/MacOSX/Swift.icns"]
- app = myenv.AppBundle("Swift", version = myenv["SWIFT_VERSION"], resources = commonResources, frameworks = frameworks, handlesXMPPURIs = True)
- if env["DIST"] :
- myenv.Command(["#/Packages/Swift/Swift-${SWIFT_VERSION}.dmg"], [app], ["Swift/Packaging/MacOSX/package.sh " + app.path + " Swift/Packaging/MacOSX/Swift.dmg.gz $TARGET $QTDIR"])
- dsym = myenv.Command(["Swift-${SWIFT_VERSION}.dSYM"], ["Swift"], ["dsymutil -o ${TARGET} ${SOURCE}"])
- myenv.Command(["#/Packages/Swift/Swift-${SWIFT_VERSION}.dSYM.zip"], dsym, ["cd ${SOURCE.dir} && zip -r ${TARGET.abspath} ${SOURCE.name}"])
+ frameworks = []
+ if env["HAVE_SPARKLE"] :
+ frameworks.append(env["SPARKLE_FRAMEWORK"])
+ if env["HAVE_GROWL"] :
+ frameworks.append(env["GROWL_FRAMEWORK"])
+ commonResources[""] = commonResources.get("", []) + ["#/Swift/resources/MacOSX/Swift.icns"]
+ app = myenv.AppBundle("Swift", version = myenv["SWIFT_VERSION"], resources = commonResources, frameworks = frameworks, handlesXMPPURIs = True, sparklePublicDSAKey = myenv["SWIFT_SPARKLE_PUBLIC_DSA_KEY"])
+ if env["DIST"] :
+ myenv.Command(["#/Packages/Swift/Swift-${SWIFT_VERSION}.dmg"], [app], ["Swift/Packaging/MacOSX/package.sh " + app.path + " Swift/Packaging/MacOSX/Swift.dmg.gz $TARGET $QTDIR " + "\"$CODE_SIGN_IDENTITY\""])
+ dsym = myenv.Command(["Swift-${SWIFT_VERSION}.dSYM"], ["Swift"], ["dsymutil -o ${TARGET} ${SOURCE}"])
+ myenv.Command(["#/Packages/Swift/Swift-${SWIFT_VERSION}.dSYM.zip"], dsym, ["cd ${SOURCE.dir} && zip -r ${TARGET.abspath} ${SOURCE.name}"])
if env.get("SWIFT_INSTALLDIR", "") :
- env.Install(os.path.join(env["SWIFT_INSTALLDIR"], "bin"), swiftProgram + openURIProgram)
- env.InstallAs(os.path.join(env["SWIFT_INSTALLDIR"], "share", "pixmaps", "swift.xpm"), "#/Swift/resources/logo/logo-icon-32.xpm")
- icons_path = os.path.join(env["SWIFT_INSTALLDIR"], "share", "icons", "hicolor")
- env.InstallAs(os.path.join(icons_path, "32x32", "apps", "swift.xpm"), "#/Swift/resources/logo/logo-icon-32.xpm")
- env.InstallAs(os.path.join(icons_path, "scalable", "apps", "swift.svg"), "#/Swift/resources/logo/logo-icon.svg")
- for i in ["16", "22", "24", "64", "128"] :
- env.InstallAs(os.path.join(icons_path, i + "x" + i, "apps", "swift.png"), "#/Swift/resources/logo/logo-icon-" + i + ".png")
- env.Install(os.path.join(env["SWIFT_INSTALLDIR"], "share", "applications"), "#/Swift/resources/swift.desktop")
- for dir, resource in commonResources.items() :
- env.Install(os.path.join(env["SWIFT_INSTALLDIR"], "share", "swift", dir), resource)
+ env.Install(os.path.join(env["SWIFT_INSTALLDIR"], "bin"), swiftProgram + openURIProgram)
+ env.InstallAs(os.path.join(env["SWIFT_INSTALLDIR"], "share", "pixmaps", "swift.xpm"), "#/Swift/resources/logo/logo-icon-32.xpm")
+ icons_path = os.path.join(env["SWIFT_INSTALLDIR"], "share", "icons", "hicolor")
+ env.InstallAs(os.path.join(icons_path, "32x32", "apps", "swift.xpm"), "#/Swift/resources/logo/logo-icon-32.xpm")
+ env.InstallAs(os.path.join(icons_path, "scalable", "apps", "swift.svg"), "#/Swift/resources/logo/logo-icon.svg")
+ for i in ["16", "22", "24", "64", "128"] :
+ env.InstallAs(os.path.join(icons_path, i + "x" + i, "apps", "swift.png"), "#/Swift/resources/logo/logo-icon-" + i + ".png")
+ env.Install(os.path.join(env["SWIFT_INSTALLDIR"], "share", "applications"), "#/Swift/resources/swift.desktop")
+ for dir, resource in commonResources.items() :
+ env.Install(os.path.join(env["SWIFT_INSTALLDIR"], "share", "swift", dir), resource)
if env["PLATFORM"] == "win32" :
- if env["DIST"] or ARGUMENTS.get("dump_trace") :
- commonResources[""] = commonResources.get("", []) + [
- #os.path.join(env["OPENSSL_DIR"], "bin", "ssleay32.dll"),
- #os.path.join(env["OPENSSL_DIR"], "bin", "libeay32.dll"),
- "#/Swift/resources/images",
- ]
- if env["SWIFTEN_DLL"] :
- commonResources[""] = commonResources.get("", []) + ["#/Swiften/${SWIFTEN_LIBRARY_FILE}"]
- qtplugins = {}
- qtplugins["imageformats"] = ["gif", "ico", "jpeg", "mng", "svg", "tiff"]
- qtlibs = ["QtCore", "QtGui", "QtNetwork", "QtWebKit", "QtXMLPatterns"]
- if qt_version == '4' :
- qtlibs.append("phonon")
- qtlibs = [lib + '4' for lib in qtlibs]
- else :
- qtlibs += ['QtQuick', 'QtQml', 'QtPositioning', 'QtMultimedia', 'QtSql', 'QtSensors', 'QtWidgets', 'QtWebChannel', 'QtWebKitWidgets', 'QtMultimediaWidgets', 'QtOpenGL', 'QtPrintSupport']
- qtlibs = [lib.replace('Qt', 'Qt5') for lib in qtlibs]
- qtlibs += ['icuin51', 'icuuc51', 'icudt51', 'libGLESv2', 'libEGL']
- qtplugins["platforms"] = ['windows']
- qtplugins["accessible"] = ["taccessiblewidgets"]
-
- windowsBundleFiles = myenv.WindowsBundle("Swift",
- resources = commonResources,
- qtplugins = qtplugins,
- qtlibs = qtlibs,
- qtversion = qt_version)
-
- if env["DIST"] :
- #myenv.Append(NSIS_OPTIONS = [
- # "/DmsvccRedistributableDir=\"" + env["vcredist"] + "\"",
- # "/DbuildVersion=" + myenv["SWIFT_VERSION"]
- # ])
- #myenv.Nsis("../Packaging/nsis/swift.nsi")
- if env["SCONS_STAGE"] == "build" and env.get("wix_bindir", None):
- def convertToRTF(env, target, source) :
- infile = open(source[0].abspath, 'r')
- outfile = open(target[0].abspath, 'w')
- outfile.write('{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\fs16\\f0\\pard\n')
- for line in infile:
- for char in line.decode("utf-8") :
- if ord(char) > 127 :
- # FIXME: This is incorrect, because it only works for latin1.
- # The correct way is \u<decimal utf16 point>? , but this is more
- # work
- outfile.write("\\'%X" % ord(char))
- else :
- outfile.write(char)
- outfile.write('\\par ')
- outfile.write('}')
- outfile.close()
- infile.close()
- copying = env.Command(["Swift/COPYING.rtf"], ["COPYING"], convertToRTF)
- wixvariables = {
- 'VCCRTFile': env["vcredist"],
- 'Version': str(myenv["SWIFT_VERSION_MAJOR"]) + "." + str(myenv["SWIFT_VERSION_MINOR"]) + "." + str(myenv["SWIFT_VERSION_PATCH"])
- }
- wixincludecontent = "<Include>"
- for key in wixvariables:
- wixincludecontent += "<?define %s = \"%s\" ?>" % (key, wixvariables[key])
- wixincludecontent += "</Include>"
- myenv.WriteVal("..\\Packaging\\Wix\\variables.wxs", env.Value(wixincludecontent))
- myenv["WIX_SOURCE_OBJECT_DIR"] = "Swift\\QtUI\\Swift"
- myenv.WiX_Heat('..\\Packaging\\WiX\\gen_files.wxs', windowsBundleFiles + copying)
- myenv.WiX_Candle('..\\Packaging\\WiX\\Swift.wixobj', '..\\Packaging\\WiX\\Swift.wxs')
- myenv.WiX_Candle('..\\Packaging\\WiX\\gen_files.wixobj', '..\\Packaging\\WiX\\gen_files.wxs')
- myenv.WiX_Light('#/Packages/Swift/Swift-' + myenv["SWIFT_VERSION"] + '.msi', ['..\\Packaging\\WiX\\gen_files.wixobj','..\\Packaging\\WiX\\Swift.wixobj'])
-
- if myenv["debug"] :
- myenv.InstallAs('#/Packages/Swift/Swift-' + myenv["SWIFT_VERSION"] + '.pdb', "Swift.pdb")
+ if env["DIST"] or ARGUMENTS.get("dump_trace") :
+ commonResources[""] = commonResources.get("", []) + [
+ #os.path.join(env["OPENSSL_DIR"], "bin", "ssleay32.dll"),
+ #os.path.join(env["OPENSSL_DIR"], "bin", "libeay32.dll"),
+ "#/Swift/resources/images",
+ ]
+ if env["SWIFTEN_DLL"] :
+ commonResources[""] = commonResources.get("", []) + ["#/Swiften/${SWIFTEN_LIBRARY_FILE}"]
+ qtplugins = {}
+ qtplugins["imageformats"] = ["gif", "ico", "jpeg", "mng", "svg", "tiff"]
+ qtlibs = ["QtCore", "QtGui", "QtNetwork", "QtWebKit", "QtXMLPatterns"]
+ if qt_version == '4' :
+ qtlibs.append("phonon")
+ qtlibs = [lib + '4' for lib in qtlibs]
+ else :
+ qtlibs += ['QtQuick', 'QtQml', 'QtPositioning', 'QtMultimedia', 'QtSql', 'QtSensors', 'QtWidgets', 'QtWebChannel', 'QtWebKitWidgets', 'QtMultimediaWidgets', 'QtOpenGL', 'QtPrintSupport']
+ qtlibs = [lib.replace('Qt', 'Qt5') for lib in qtlibs]
+ qtlibs += ['icuin51', 'icuuc51', 'icudt51', 'libGLESv2', 'libEGL']
+ qtplugins["platforms"] = ['windows']
+ qtplugins["accessible"] = ["taccessiblewidgets"]
+
+ windowsBundleFiles = myenv.WindowsBundle("Swift",
+ resources = commonResources,
+ qtplugins = qtplugins,
+ qtlibs = qtlibs,
+ qtversion = qt_version)
+
+ if env["DIST"] :
+ #myenv.Append(NSIS_OPTIONS = [
+ # "/DmsvccRedistributableDir=\"" + env["vcredist"] + "\"",
+ # "/DbuildVersion=" + myenv["SWIFT_VERSION"]
+ # ])
+ #myenv.Nsis("../Packaging/nsis/swift.nsi")
+ if env["SCONS_STAGE"] == "build" and env.get("wix_bindir", None):
+ def convertToRTF(env, target, source) :
+ infile = open(source[0].abspath, 'r')
+ outfile = open(target[0].abspath, 'w')
+ outfile.write('{\\rtf1\\ansi{\\fonttbl\\f0\\fswiss Helvetica;}\\fs16\\f0\\pard\n')
+ for line in infile:
+ for char in line.decode("utf-8") :
+ if ord(char) > 127 :
+ # FIXME: This is incorrect, because it only works for latin1.
+ # The correct way is \u<decimal utf16 point>? , but this is more
+ # work
+ outfile.write("\\'%X" % ord(char))
+ else :
+ outfile.write(char)
+ outfile.write('\\par ')
+ outfile.write('}')
+ outfile.close()
+ infile.close()
+ copying = env.Command(["Swift/COPYING.rtf"], ["COPYING"], convertToRTF)
+ wixvariables = {
+ 'VCCRTFile': env["vcredist"],
+ 'Version': str(myenv["SWIFT_VERSION_MAJOR"]) + "." + str(myenv["SWIFT_VERSION_MINOR"]) + "." + str(myenv["SWIFT_VERSION_PATCH"])
+ }
+ wixincludecontent = "<Include>"
+ for key in wixvariables:
+ wixincludecontent += "<?define %s = \"%s\" ?>" % (key, wixvariables[key])
+ wixincludecontent += "</Include>"
+ myenv.WriteVal("..\\Packaging\\Wix\\variables.wxs", env.Value(wixincludecontent))
+ myenv["WIX_SOURCE_OBJECT_DIR"] = "Swift\\QtUI\\Swift"
+ myenv.WiX_Heat('..\\Packaging\\WiX\\gen_files.wxs', windowsBundleFiles + copying)
+ myenv.WiX_Candle('..\\Packaging\\WiX\\Swift.wixobj', '..\\Packaging\\WiX\\Swift.wxs')
+ myenv.WiX_Candle('..\\Packaging\\WiX\\gen_files.wixobj', '..\\Packaging\\WiX\\gen_files.wxs')
+ lightTask = myenv.WiX_Light('#/Packages/Swift/Swift-' + myenv["SWIFT_VERSION"] + '.msi', ['..\\Packaging\\WiX\\gen_files.wixobj','..\\Packaging\\WiX\\Swift.wixobj'])
+ if myenv.get("SIGNTOOL_KEY_PFX", None) and myenv.get("SIGNTOOL_TIMESTAMP_URL", None) :
+ def signToolAction(target = None, source = None, env = None):
+ env.Execute('signtool.exe sign /fd SHA256 /f "${SIGNTOOL_KEY_PFX}" /t "${SIGNTOOL_TIMESTAMP_URL}" ' + str(target[0]))
+
+ myenv.AddPostAction(lightTask, signToolAction)
+
+ if myenv["debug"] :
+ myenv.InstallAs('#/Packages/Swift/Swift-' + myenv["SWIFT_VERSION"] + '.pdb', "Swift.pdb")
diff --git a/Swift/QtUI/Swift.qrc b/Swift/QtUI/Swift.qrc
index 0478d76..cfb0fec 100644
--- a/Swift/QtUI/Swift.qrc
+++ b/Swift/QtUI/Swift.qrc
@@ -4,7 +4,7 @@
<file alias="logo-icon-16.png">../resources/logo/logo-icon-16.png</file>
<file alias="logo-icon-16-win.png">../resources/logo/logo-icon-16-win.png</file>
<file alias="logo-chat-16.png">../resources/logo/logo-chat-16.png</file>
- <file alias="logo-shaded-text.256.png">../resources/logo/logo-shaded-text.256.png</file>
+ <file alias="logo-shaded-text.png">../resources/logo/logo-shaded-text.png</file>
<file alias="icons/online.png">../resources/icons/online.png</file>
<file alias="icons/connecting.mng">../resources/icons/connecting.mng</file>
<file alias="icons/away.png">../resources/icons/away.png</file>
@@ -16,12 +16,13 @@
<file alias="icons/warn.png">../resources/icons/warn.png</file>
<file alias="icons/check.png">../resources/icons/check.png</file>
<file alias="icons/throbber.gif">../resources/icons/throbber.gif</file>
- <file alias="icons/avatar.png">../resources/icons/avatar.png</file>
+ <file alias="icons/avatar.svg">../resources/icons/avatar.svg</file>
<file alias="icons/no-avatar.png">../resources/icons/no-avatar.png</file>
<file alias="icons/tray-standard.png">../resources/icons/tray-standard.png</file>
<file alias="icons/new-chat.png">../resources/icons/new-chat.png</file>
<file alias="icons/actions.png">../resources/icons/actions.png</file>
<file alias="COPYING">COPYING</file>
+ <file alias="ChangeLog.md">../ChangeLog.md</file>
<file alias="icons/line.png">../resources/icons/line.png</file>
<file alias="icons/rect.png">../resources/icons/rect.png</file>
<file alias="icons/circle.png">../resources/icons/circle.png</file>
@@ -43,5 +44,8 @@
<file alias="icons/star-unchecked.png">../resources/icons/star-unchecked2.png</file>
<file alias="icons/zzz.png">../resources/icons/zzz.png</file>
<file alias="icons/stop.png">../resources/icons/stop.png</file>
+ <file alias="icons/delivery-success.svg">../resources/icons/delivery-success.svg</file>
+ <file alias="icons/delivery-failure.svg">../resources/icons/delivery-failure.svg</file>
+ <file alias="icons/delivery-warning.svg">../resources/icons/delivery-warning.svg</file>
</qresource>
</RCC>
diff --git a/Swift/QtUI/SwiftUpdateFeeds.h b/Swift/QtUI/SwiftUpdateFeeds.h
new file mode 100644
index 0000000..a6476f5
--- /dev/null
+++ b/Swift/QtUI/SwiftUpdateFeeds.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2010-2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Base/Platform.h>
+
+namespace Swift {
+
+namespace UpdateFeeds {
+ const std::string StableChannel = "stable";
+ const std::string TestingChannel = "testing";
+ const std::string DevelopmentChannel = "development";
+
+#if defined(SWIFTEN_PLATFORM_MACOSX)
+ const std::string StableAppcastFeed = "https://swift.im/downloads/swift-stable-appcast-mac.xml";
+ const std::string TestingAppcastFeed = "https://swift.im/downloads/swift-testing-appcast-mac.xml";
+ const std::string DevelopmentAppcastFeed = "https://swift.im/downloads/swift-development-appcast-mac.xml";
+#else
+ const std::string StableAppcastFeed = "";
+ const std::string TestingAppcastFeed = "";
+ const std::string DevelopmentAppcastFeed = "";
+#endif
+}
+
+}
diff --git a/Swift/QtUI/SystemMessageSnippet.cpp b/Swift/QtUI/SystemMessageSnippet.cpp
index e752e32..eeb6b9a 100644
--- a/Swift/QtUI/SystemMessageSnippet.cpp
+++ b/Swift/QtUI/SystemMessageSnippet.cpp
@@ -1,26 +1,26 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "SystemMessageSnippet.h"
+#include <Swift/QtUI/SystemMessageSnippet.h>
#include <QDateTime>
namespace Swift {
SystemMessageSnippet::SystemMessageSnippet(const QString& message, const QDateTime& time, bool appendToPrevious, QtChatTheme* theme, const QString& id, Direction direction) : ChatSnippet(appendToPrevious) {
- if (appendToPrevious) {
- setContinuationFallbackSnippet(boost::shared_ptr<ChatSnippet>(new SystemMessageSnippet(message, time, false, theme, id, direction)));
- }
- content_ = theme->getStatus();
-
- content_.replace("%direction%", directionToCSS(direction));
- content_.replace("%message%", wrapResizable("<span class='swift_message'>" + escape(message) + "</span>"));
- content_.replace("%shortTime%", wrapResizable(escape(time.toString("h:mm"))));
- content_.replace("%time%", wrapResizable("<span class='swift_time'>" + timeToEscapedString(time) + "</span>"));
- content_ = QString("<div id='%1'>%2</div>").arg(id).arg(content_);
+ if (appendToPrevious) {
+ setContinuationFallbackSnippet(std::make_shared<SystemMessageSnippet>(message, time, false, theme, id, direction));
+ }
+ content_ = theme->getStatus();
+
+ content_.replace("%direction%", directionToCSS(direction));
+ content_.replace("%message%", wrapResizable("<span class='swift_message'>" + escape(message) + "</span>"));
+ content_.replace("%shortTime%", wrapResizable(escape(time.toString("h:mm"))));
+ content_.replace("%time%", wrapResizable("<span class='swift_time'>" + timeToEscapedString(time) + "</span>"));
+ content_.replace("%id%", id);
}
SystemMessageSnippet::~SystemMessageSnippet() {
diff --git a/Swift/QtUI/SystemMessageSnippet.h b/Swift/QtUI/SystemMessageSnippet.h
index 8cd68c2..c0d4d2f 100644
--- a/Swift/QtUI/SystemMessageSnippet.h
+++ b/Swift/QtUI/SystemMessageSnippet.h
@@ -8,23 +8,23 @@
#include <QString>
-#include "ChatSnippet.h"
+#include <Swift/QtUI/ChatSnippet.h>
class QDateTime;
namespace Swift {
- class SystemMessageSnippet : public ChatSnippet {
- public:
- SystemMessageSnippet(const QString& message, const QDateTime& time, bool appendToPrevious, QtChatTheme* theme, const QString& id, Direction direction);
- virtual ~SystemMessageSnippet();
+ class SystemMessageSnippet : public ChatSnippet {
+ public:
+ SystemMessageSnippet(const QString& message, const QDateTime& time, bool appendToPrevious, QtChatTheme* theme, const QString& id, Direction direction);
+ virtual ~SystemMessageSnippet();
- const QString& getContent() const {return content_;}
+ const QString& getContent() const {return content_;}
- /*QString getContinuationElementID() const {
- return "insert";
- };*/
+ /*QString getContinuationElementID() const {
+ return "insert";
+ };*/
- private:
- QString content_;
- };
+ private:
+ QString content_;
+ };
}
diff --git a/Swift/QtUI/Trellis/QtDNDTabBar.cpp b/Swift/QtUI/Trellis/QtDNDTabBar.cpp
index dbe397b..9a6c436 100644
--- a/Swift/QtUI/Trellis/QtDNDTabBar.cpp
+++ b/Swift/QtUI/Trellis/QtDNDTabBar.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -18,12 +18,12 @@
namespace Swift {
QtDNDTabBar::QtDNDTabBar(QWidget* parent) : QTabBar(parent) {
- setAcceptDrops(true);
+ setAcceptDrops(true);
- // detect the default tab bar height;
- insertTab(0, "");
- defaultTabHeight = QTabBar::sizeHint().height();
- removeTab(0);
+ // detect the default tab bar height;
+ insertTab(0, "");
+ defaultTabHeight = QTabBar::sizeHint().height();
+ removeTab(0);
}
QtDNDTabBar::~QtDNDTabBar() {
@@ -31,136 +31,136 @@ QtDNDTabBar::~QtDNDTabBar() {
}
int QtDNDTabBar::getDragIndex() const {
- return dragIndex;
+ return dragIndex;
}
QString QtDNDTabBar::getDragText() const {
- return dragText;
+ return dragText;
}
QWidget* QtDNDTabBar::getDragWidget() const {
- return dragWidget;
+ return dragWidget;
}
QSize QtDNDTabBar::sizeHint() const {
- QSize hint = QTabBar::sizeHint();
- if (hint.isEmpty()) {
- hint = QSize(parentWidget()->width(), defaultTabHeight);
- }
- return hint;
+ QSize hint = QTabBar::sizeHint();
+ if (hint.isEmpty()) {
+ hint = QSize(parentWidget()->width(), defaultTabHeight);
+ }
+ return hint;
}
QSize QtDNDTabBar::tabSizeHint(int index) const {
- QSize tabSize = QTabBar::tabSizeHint(index);
+ QSize tabSize = QTabBar::tabSizeHint(index);
#if defined(Q_OS_MAC)
- // With multiple tabs having the same label in a QTabBar, the size hint computed by
- // Qt on OS X is too small and it is elided even though there is enough horizontal
- // space available. We work around this issue by adding the width of a letter to the
- // size hint.
- tabSize += QSize(QFontMetrics(font()).width("I"), 0);
+ // With multiple tabs having the same label in a QTabBar, the size hint computed by
+ // Qt on OS X is too small and it is elided even though there is enough horizontal
+ // space available. We work around this issue by adding the width of a letter to the
+ // size hint.
+ tabSize += QSize(QFontMetrics(font()).width("I"), 0);
#endif
- return tabSize;
+ return tabSize;
}
void QtDNDTabBar::dragEnterEvent(QDragEnterEvent* dragEnterEvent) {
- QtDNDTabBar* sourceTabBar = dynamic_cast<QtDNDTabBar*>(dragEnterEvent->source());
- if (sourceTabBar) {
- dragEnterEvent->acceptProposedAction();
- }
+ QtDNDTabBar* sourceTabBar = dynamic_cast<QtDNDTabBar*>(dragEnterEvent->source());
+ if (sourceTabBar) {
+ dragEnterEvent->acceptProposedAction();
+ }
}
void QtDNDTabBar::dropEvent(QDropEvent* dropEvent) {
- QtDNDTabBar* sourceTabBar = dynamic_cast<QtDNDTabBar*>(dropEvent->source());
- if (sourceTabBar && dropEvent->mimeData() && dropEvent->mimeData()->data("action") == QByteArray("application/tab-detach")) {
- QtDNDTabBar* source = dynamic_cast<QtDNDTabBar*>(dropEvent->source());
-
- int targetTabIndex = tabAt(dropEvent->pos());
- QRect rect = tabRect(targetTabIndex);
- if (targetTabIndex >= 0 && (dropEvent->pos().x() - rect.left() - rect.width()/2 > 0)) {
- targetTabIndex++;
- }
-
- QWidget* tab = source->getDragWidget();
- assert(tab);
- QTabWidget* targetTabWidget = dynamic_cast<QTabWidget*>(parentWidget());
-
- QString tabText = source->getDragText();
-
- /*
- * When you add a widget to an empty QTabWidget, it's automatically made the current widget.
- * Making the widget the current widget, widget->show() is called for the widget. Directly reacting
- * to that event, and adding the widget again to the QTabWidget results in undefined behavior. For
- * example the tab label is shown but the widget is neither has the old nor in the new QTabWidget as
- * parent. Blocking signals on the QWidget to be added to a QTabWidget prevents this behavior.
- */
- targetTabWidget->setUpdatesEnabled(false);
- tab->blockSignals(true);
- targetTabWidget->insertTab(targetTabIndex, tab, tabText);
- dropEvent->acceptProposedAction();
- tab->blockSignals(false);
- targetTabWidget->setUpdatesEnabled(true);
- onDropSucceeded();
- }
+ QtDNDTabBar* sourceTabBar = dynamic_cast<QtDNDTabBar*>(dropEvent->source());
+ if (sourceTabBar && dropEvent->mimeData() && dropEvent->mimeData()->data("action") == QByteArray("application/tab-detach")) {
+ QtDNDTabBar* source = dynamic_cast<QtDNDTabBar*>(dropEvent->source());
+
+ int targetTabIndex = tabAt(dropEvent->pos());
+ QRect rect = tabRect(targetTabIndex);
+ if (targetTabIndex >= 0 && (dropEvent->pos().x() - rect.left() - rect.width()/2 > 0)) {
+ targetTabIndex++;
+ }
+
+ QWidget* tab = source->getDragWidget();
+ assert(tab);
+ QTabWidget* targetTabWidget = dynamic_cast<QTabWidget*>(parentWidget());
+
+ QString tabText = source->getDragText();
+
+ /*
+ * When you add a widget to an empty QTabWidget, it's automatically made the current widget.
+ * Making the widget the current widget, widget->show() is called for the widget. Directly reacting
+ * to that event, and adding the widget again to the QTabWidget results in undefined behavior. For
+ * example the tab label is shown but the widget is neither has the old nor in the new QTabWidget as
+ * parent. Blocking signals on the QWidget to be added to a QTabWidget prevents this behavior.
+ */
+ targetTabWidget->setUpdatesEnabled(false);
+ tab->blockSignals(true);
+ targetTabWidget->insertTab(targetTabIndex, tab, tabText);
+ dropEvent->acceptProposedAction();
+ tab->blockSignals(false);
+ targetTabWidget->setUpdatesEnabled(true);
+ onDropSucceeded();
+ }
}
bool QtDNDTabBar::event(QEvent* event) {
- QMouseEvent* mouseEvent = dynamic_cast<QMouseEvent*>(event);
- if (mouseEvent) {
- QWidget* childAtPoint = window()->childAt(mapTo(window(), mouseEvent->pos()));
- QtDNDTabBar* underMouse = dynamic_cast<QtDNDTabBar*>(childAtPoint);
- if (!underMouse && childAtPoint) {
- underMouse = dynamic_cast<QtDNDTabBar*>(childAtPoint->parent());
- }
- if (!underMouse && currentIndex() >= 0) {
- // detach and drag
-
- // stop move event
- QMouseEvent* finishMoveEvent = new QMouseEvent (QEvent::MouseMove, mouseEvent->pos (), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
- QTabBar::event(finishMoveEvent);
- delete finishMoveEvent;
- finishMoveEvent = NULL;
-
- // start drag
- QDrag* drag = new QDrag(this);
- QMimeData* mimeData = new QMimeData;
-
- // distinguish tab-reordering drops from other ones
- mimeData->setData("action", "application/tab-detach") ;
- drag->setMimeData(mimeData);
-
- // set drag image
- QRect rect = tabRect( currentIndex() );
+ QMouseEvent* mouseEvent = dynamic_cast<QMouseEvent*>(event);
+ if (mouseEvent) {
+ QWidget* childAtPoint = window()->childAt(mapTo(window(), mouseEvent->pos()));
+ QtDNDTabBar* underMouse = dynamic_cast<QtDNDTabBar*>(childAtPoint);
+ if (!underMouse && childAtPoint) {
+ underMouse = dynamic_cast<QtDNDTabBar*>(childAtPoint->parent());
+ }
+ if (!underMouse && currentIndex() >= 0) {
+ // detach and drag
+
+ // stop move event
+ QMouseEvent* finishMoveEvent = new QMouseEvent (QEvent::MouseMove, mouseEvent->pos (), Qt::NoButton, Qt::NoButton, Qt::NoModifier);
+ QTabBar::event(finishMoveEvent);
+ delete finishMoveEvent;
+ finishMoveEvent = nullptr;
+
+ // start drag
+ QDrag* drag = new QDrag(this);
+ QMimeData* mimeData = new QMimeData;
+
+ // distinguish tab-reordering drops from other ones
+ mimeData->setData("action", "application/tab-detach") ;
+ drag->setMimeData(mimeData);
+
+ // set drag image
+ QRect rect = tabRect( currentIndex() );
#if QT_VERSION >= 0x050000
- QPixmap pixmap = grab(rect);
+ QPixmap pixmap = grab(rect);
#else
- QPixmap pixmap = QPixmap::grabWidget(this, rect);
+ QPixmap pixmap = QPixmap::grabWidget(this, rect);
#endif
- QPixmap targetPixmap (pixmap.size ());
- QPainter painter (&targetPixmap);
- painter.setOpacity(0.9);
- painter.drawPixmap(0,0, pixmap);
- painter.end ();
- drag->setPixmap (targetPixmap);
-
- drag->setHotSpot(QPoint(drag->pixmap().width()/2, drag->pixmap().height()));
-
- dragIndex = currentIndex();
- dragText = tabText(dragIndex);
- dragWidget = dynamic_cast<QTabWidget*>(parent())->widget(dragIndex);
- assert(dragWidget);
- dynamic_cast<QTabWidget*>(parent())->removeTab(currentIndex());
- Qt::DropAction dropAction = drag->exec();
- if (dropAction == Qt::IgnoreAction) {
- // aborted drag, put tab back in place
- // disable event handling during the insert for the tab to prevent infinite recursion (stack overflow)
- dragWidget->blockSignals(true);
- dynamic_cast<QTabWidget*>(parent())->insertTab(dragIndex, dragWidget, dragText);
- dragWidget->blockSignals(false);
- }
- return true;
- }
- }
- return QTabBar::event(event);
+ QPixmap targetPixmap (pixmap.size ());
+ QPainter painter (&targetPixmap);
+ painter.setOpacity(0.9);
+ painter.drawPixmap(0,0, pixmap);
+ painter.end ();
+ drag->setPixmap (targetPixmap);
+
+ drag->setHotSpot(QPoint(drag->pixmap().width()/2, drag->pixmap().height()));
+
+ dragIndex = currentIndex();
+ dragText = tabText(dragIndex);
+ dragWidget = dynamic_cast<QTabWidget*>(parent())->widget(dragIndex);
+ assert(dragWidget);
+ dynamic_cast<QTabWidget*>(parent())->removeTab(currentIndex());
+ Qt::DropAction dropAction = drag->exec();
+ if (dropAction == Qt::IgnoreAction) {
+ // aborted drag, put tab back in place
+ // disable event handling during the insert for the tab to prevent infinite recursion (stack overflow)
+ dragWidget->blockSignals(true);
+ dynamic_cast<QTabWidget*>(parent())->insertTab(dragIndex, dragWidget, dragText);
+ dragWidget->blockSignals(false);
+ }
+ return true;
+ }
+ }
+ return QTabBar::event(event);
}
}
diff --git a/Swift/QtUI/Trellis/QtDNDTabBar.h b/Swift/QtUI/Trellis/QtDNDTabBar.h
index 71ca94b..6de04d5 100644
--- a/Swift/QtUI/Trellis/QtDNDTabBar.h
+++ b/Swift/QtUI/Trellis/QtDNDTabBar.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,34 +8,37 @@
#include <QTabBar>
+#include <Swift/QtUI/QtTabWidget.h>
+
namespace Swift {
class QtDNDTabBar : public QTabBar {
- Q_OBJECT
- public:
- explicit QtDNDTabBar(QWidget* parent = 0);
- virtual ~QtDNDTabBar();
-
- int getDragIndex() const;
- QString getDragText() const;
- QWidget* getDragWidget() const;
-
- virtual QSize sizeHint() const;
-
- signals:
- void onDropSucceeded();
-
- protected:
- virtual void dragEnterEvent(QDragEnterEvent* dragEnterEvent);
- virtual void dropEvent(QDropEvent* dropEvent);
- virtual bool event(QEvent* event);
- virtual QSize tabSizeHint(int index) const;
-
- private:
- int defaultTabHeight;
- int dragIndex;
- QString dragText;
- QWidget* dragWidget;
+ Q_OBJECT
+ public:
+ explicit QtDNDTabBar(QWidget* parent = nullptr);
+ virtual ~QtDNDTabBar();
+
+ int getDragIndex() const;
+ QString getDragText() const;
+ QWidget* getDragWidget() const;
+
+ virtual QSize sizeHint() const;
+
+ friend class QtTabWidget;
+ signals:
+ void onDropSucceeded();
+
+ protected:
+ virtual void dragEnterEvent(QDragEnterEvent* dragEnterEvent);
+ virtual void dropEvent(QDropEvent* dropEvent);
+ virtual bool event(QEvent* event);
+ virtual QSize tabSizeHint(int index) const;
+
+ private:
+ int defaultTabHeight;
+ int dragIndex = -1;
+ QString dragText;
+ QWidget* dragWidget = nullptr;
};
}
diff --git a/Swift/QtUI/Trellis/QtDynamicGridLayout.cpp b/Swift/QtUI/Trellis/QtDynamicGridLayout.cpp
index 3b8adf8..5600cc8 100644
--- a/Swift/QtUI/Trellis/QtDynamicGridLayout.cpp
+++ b/Swift/QtUI/Trellis/QtDynamicGridLayout.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -23,128 +23,129 @@
namespace Swift {
-QtDynamicGridLayout::QtDynamicGridLayout(QWidget* parent, bool enableDND) : QWidget(parent), dndEnabled_(enableDND), movingTab_(NULL) {
- gridLayout_ = new QGridLayout(this);
- setContentsMargins(0,0,0,0);
- setDimensions(QSize(1,1));
- connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(handleApplicationFocusChanged(QWidget*,QWidget*)));
+QtDynamicGridLayout::QtDynamicGridLayout(QWidget* parent, bool enableDND) : QWidget(parent), dndEnabled_(enableDND), movingTab_(nullptr) {
+ gridLayout_ = new QGridLayout(this);
+ setContentsMargins(0,0,0,0);
+ setDimensions(QSize(1,1));
+ connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(handleApplicationFocusChanged(QWidget*,QWidget*)));
}
QtDynamicGridLayout::~QtDynamicGridLayout() {
}
int QtDynamicGridLayout::addTab(QtTabbable* tab, const QString& title) {
- assert(gridLayout_->rowCount() > 0 && gridLayout_->columnCount() > 0);
-
- QPoint lastPos(0,0);
- if (tabPositions_.contains(P2QSTRING(tab->getID()))) {
- lastPos = tabPositions_[P2QSTRING(tab->getID())];
- }
-
- lastPos = QPoint(qMin(lastPos.x(), gridLayout_->columnCount() - 1), qMin(lastPos.y(), gridLayout_->rowCount() - 1));
-
- QLayoutItem* item = gridLayout_->itemAtPosition(lastPos.y(), lastPos.x());
- QtTabWidget* tabWidget = dynamic_cast<QtTabWidget*>(item ? item->widget() : 0);
- if (tabWidget) {
- tabWidget->addTab(tab, title);
- }
- return tabWidget ? indexOf(tab) : -1;
+ assert(gridLayout_->rowCount() > 0 && gridLayout_->columnCount() > 0);
+
+ QPoint lastPos(0,0);
+ if (tabPositions_.contains(P2QSTRING(tab->getID()))) {
+ lastPos = tabPositions_[P2QSTRING(tab->getID())];
+ }
+
+ lastPos = QPoint(qMin(lastPos.x(), gridLayout_->columnCount() - 1), qMin(lastPos.y(), gridLayout_->rowCount() - 1));
+
+ QLayoutItem* item = gridLayout_->itemAtPosition(lastPos.y(), lastPos.x());
+ QtTabWidget* tabWidget = dynamic_cast<QtTabWidget*>(item ? item->widget() : nullptr);
+ if (tabWidget) {
+ tabWidget->addTab(tab, title);
+ }
+ tab->setEmphasiseFocus(getDimension().width() > 1 || getDimension().height() > 1);
+ return tabWidget ? indexOf(tab) : -1;
}
int QtDynamicGridLayout::count() const {
- int count = 0;
- for (int y = 0; y < gridLayout_->rowCount(); y++) {
- for (int x = 0; x < gridLayout_->columnCount(); x++) {
- QLayoutItem* layoutItem = gridLayout_->itemAtPosition(y, x);
- QtTabWidget* tabWidget = dynamic_cast<QtTabWidget*>(layoutItem->widget());
- if (tabWidget) {
- count += tabWidget->count();
- }
- }
- }
- return count;
+ int count = 0;
+ for (int y = 0; y < gridLayout_->rowCount(); y++) {
+ for (int x = 0; x < gridLayout_->columnCount(); x++) {
+ QLayoutItem* layoutItem = gridLayout_->itemAtPosition(y, x);
+ QtTabWidget* tabWidget = dynamic_cast<QtTabWidget*>(layoutItem->widget());
+ if (tabWidget) {
+ count += tabWidget->count();
+ }
+ }
+ }
+ return count;
}
QWidget* QtDynamicGridLayout::widget(int index) const {
- QWidget* widgetAtIndex = NULL;
- for (int y = 0; y < gridLayout_->rowCount(); y++) {
- for (int x = 0; x < gridLayout_->columnCount(); x++) {
- QLayoutItem* layoutItem = gridLayout_->itemAtPosition(y, x);
- QtTabWidget* tabWidget = dynamic_cast<QtTabWidget*>(layoutItem->widget());
- if (tabWidget) {
- if (index < tabWidget->count()) {
- widgetAtIndex = tabWidget->widget(index);
- return widgetAtIndex;
- }
- else {
- index -= tabWidget->count();
- }
- }
- }
- }
- return widgetAtIndex;
+ QWidget* widgetAtIndex = nullptr;
+ for (int y = 0; y < gridLayout_->rowCount(); y++) {
+ for (int x = 0; x < gridLayout_->columnCount(); x++) {
+ QLayoutItem* layoutItem = gridLayout_->itemAtPosition(y, x);
+ QtTabWidget* tabWidget = dynamic_cast<QtTabWidget*>(layoutItem ? layoutItem->widget() : nullptr);
+ if (tabWidget) {
+ if (index < tabWidget->count()) {
+ widgetAtIndex = tabWidget->widget(index);
+ return widgetAtIndex;
+ }
+ else {
+ index -= tabWidget->count();
+ }
+ }
+ }
+ }
+ return widgetAtIndex;
}
int QtDynamicGridLayout::indexOf(const QWidget* widget) const {
- int index = 0;
- if (widget) {
- for (int y = 0; y < gridLayout_->rowCount(); y++) {
- for (int x = 0; x < gridLayout_->columnCount(); x++) {
- QLayoutItem* layoutItem = gridLayout_->itemAtPosition(y, x);
- QtTabWidget* tabWidget = dynamic_cast<QtTabWidget*>(layoutItem->widget());
- if (tabWidget) {
- for (int n = 0; n < tabWidget->count(); n++) {
- QWidget* nthWidget = tabWidget->widget(n);
- if (nthWidget == widget) {
- return index;
- }
- index++;
- }
- }
- }
- }
- }
- return -1;
+ int index = 0;
+ if (widget) {
+ for (int y = 0; y < gridLayout_->rowCount(); y++) {
+ for (int x = 0; x < gridLayout_->columnCount(); x++) {
+ QLayoutItem* layoutItem = gridLayout_->itemAtPosition(y, x);
+ QtTabWidget* tabWidget = dynamic_cast<QtTabWidget*>(layoutItem->widget());
+ if (tabWidget) {
+ for (int n = 0; n < tabWidget->count(); n++) {
+ QWidget* nthWidget = tabWidget->widget(n);
+ if (nthWidget == widget) {
+ return index;
+ }
+ index++;
+ }
+ }
+ }
+ }
+ }
+ return -1;
}
void QtDynamicGridLayout::handleApplicationFocusChanged(QWidget*, QWidget* newFocus) {
- if (movingTab_) {
- return;
- }
-
- if (newFocus) {
- if (isAncestorOf(newFocus)) {
- QtTabbable *newTab = dynamic_cast<QtTabbable*>(newFocus->parentWidget());
- if (newTab) {
- onCurrentIndexChanged(currentIndex());
- }
- }
- }
+ if (movingTab_ || resizing_) {
+ return;
+ }
+
+ if (newFocus) {
+ if (isAncestorOf(newFocus)) {
+ QtTabbable *newTab = dynamic_cast<QtTabbable*>(newFocus->parentWidget());
+ if (newTab) {
+ onCurrentIndexChanged(currentIndex());
+ }
+ }
+ }
}
int QtDynamicGridLayout::currentIndex() const {
- return indexOf(currentWidget());
+ return indexOf(currentWidget());
}
void QtDynamicGridLayout::setCurrentIndex(int index) {
- int tabIndex = -1;
- QtTabWidget* tabWidget = indexToTabWidget(index, tabIndex);
- if (tabIndex >= 0) {
- tabWidget->setCurrentIndex(tabIndex);
- if (!tabWidget->hasFocus()) {
- tabWidget->widget(tabIndex)->setFocus(Qt::TabFocusReason);
- }
- } else {
- assert(false);
- }
+ int tabIndex = -1;
+ QtTabWidget* tabWidget = indexToTabWidget(index, tabIndex);
+ if (tabIndex >= 0) {
+ tabWidget->setCurrentIndex(tabIndex);
+ if (!tabWidget->hasFocus()) {
+ tabWidget->widget(tabIndex)->setFocus(Qt::TabFocusReason);
+ }
+ } else {
+ assert(false);
+ }
}
void QtDynamicGridLayout::removeTab(int index) {
- int tabIndex = -1;
- QtTabWidget* tabWidget = indexToTabWidget(index, tabIndex);
- if (tabWidget) {
- tabWidget->removeTab(tabIndex);
- }
+ int tabIndex = -1;
+ QtTabWidget* tabWidget = indexToTabWidget(index, tabIndex);
+ if (tabWidget) {
+ tabWidget->removeTab(tabIndex);
+ }
}
/**
@@ -158,348 +159,375 @@ void QtDynamicGridLayout::removeTab(int index) {
* being out of sync in an inconsistent state.
*/
bool QtDynamicGridLayout::eventFilter(QObject* object, QEvent* event) {
- QtTabbable* tab = qobject_cast<QtTabbable*>(object);
- if (!tab) {
- return false;
- }
- if (tab && (tab != movingTab_)) {
- if (event->type() == QEvent::Show) {
- return true;
- }
- }
- return false;
+ QtTabbable* tab = qobject_cast<QtTabbable*>(object);
+ if (!tab) {
+ return false;
+ }
+ if (tab && (tab != movingTab_)) {
+ if (event->type() == QEvent::Show) {
+ return true;
+ }
+ }
+ return false;
}
QWidget* QtDynamicGridLayout::currentWidget() const {
- QWidget* current = NULL;
- current = focusWidget();
- while (current && !dynamic_cast<QtTabbable*>(current)) {
- if (current->parentWidget()) {
- current = current->parentWidget();
- } else {
- current = NULL;
- break;
- }
- }
- if (!current) {
- current = widget(0);
- }
- return current;
+ QWidget* current = nullptr;
+ current = focusWidget();
+ while (current && !dynamic_cast<QtTabbable*>(current)) {
+ if (current->parentWidget()) {
+ current = current->parentWidget();
+ } else {
+ current = nullptr;
+ break;
+ }
+ }
+ if (!current) {
+ current = widget(0);
+ }
+ return current;
}
void QtDynamicGridLayout::setCurrentWidget(QWidget* widget) {
- for (int y = 0; y < gridLayout_->rowCount(); y++) {
- for (int x = 0; x < gridLayout_->columnCount(); x++) {
- QLayoutItem* layoutItem = gridLayout_->itemAtPosition(y, x);
- QtTabWidget* tabWidget = dynamic_cast<QtTabWidget*>(layoutItem->widget());
- if (tabWidget) {
- for (int n = 0; n < tabWidget->count(); n++) {
- if (tabWidget->widget(n) == widget) {
- tabWidget->setCurrentWidget(widget);
- }
- }
- }
- }
- }
+ if (widget) {
+ for (int y = 0; y < gridLayout_->rowCount(); y++) {
+ for (int x = 0; x < gridLayout_->columnCount(); x++) {
+ QLayoutItem* layoutItem = gridLayout_->itemAtPosition(y, x);
+ QtTabWidget* tabWidget = dynamic_cast<QtTabWidget*>(layoutItem->widget());
+ if (tabWidget) {
+ for (int n = 0; n < tabWidget->count(); n++) {
+ if (tabWidget->widget(n) == widget) {
+ tabWidget->setCurrentWidget(widget);
+ }
+ }
+ }
+ }
+ }
+ }
}
QtTabWidget* QtDynamicGridLayout::indexToTabWidget(int index, int& tabIndex) {
- for (int y = 0; y < gridLayout_->rowCount(); y++) {
- for (int x = 0; x < gridLayout_->columnCount(); x++) {
- QLayoutItem* layoutItem = gridLayout_->itemAtPosition(y, x);
- QtTabWidget* tabWidget = dynamic_cast<QtTabWidget*>(layoutItem->widget());
- if (tabWidget) {
- if (index < tabWidget->count()) {
- tabIndex = index;
- return tabWidget;
- }
- else {
- index -= tabWidget->count();
- if (index < 0) {
- qWarning() << "Called QtDynamicGridLayout::setCurrentIndex with index out of bounds: index = " << index;
- tabIndex = -1;
- return NULL;
- }
- }
- }
- }
- }
- tabIndex = -1;
- return NULL;
+ for (int y = 0; y < gridLayout_->rowCount(); y++) {
+ for (int x = 0; x < gridLayout_->columnCount(); x++) {
+ QLayoutItem* layoutItem = gridLayout_->itemAtPosition(y, x);
+ QtTabWidget* tabWidget = dynamic_cast<QtTabWidget*>(layoutItem->widget());
+ if (tabWidget) {
+ if (index < tabWidget->count()) {
+ tabIndex = index;
+ return tabWidget;
+ }
+ else {
+ index -= tabWidget->count();
+ if (index < 0) {
+ qWarning() << "Called QtDynamicGridLayout::setCurrentIndex with index out of bounds: index = " << index;
+ tabIndex = -1;
+ return nullptr;
+ }
+ }
+ }
+ }
+ }
+ tabIndex = -1;
+ return nullptr;
}
bool QtDynamicGridLayout::isDNDEnabled() const {
- return dndEnabled_;
+ return dndEnabled_;
}
QHash<QString, QPoint> QtDynamicGridLayout::getTabPositions() const {
- return tabPositions_;
+ return tabPositions_;
}
void QtDynamicGridLayout::setTabPositions(const QHash<QString, QPoint> positions) {
- tabPositions_ = positions;
+ tabPositions_ = positions;
}
QSize QtDynamicGridLayout::getDimension() const {
- return QSize(gridLayout_->columnCount(), gridLayout_->rowCount());
+ return QSize(gridLayout_->columnCount(), gridLayout_->rowCount());
}
void QtDynamicGridLayout::setDimensions(const QSize& dim) {
- assert(dim.width() > 0 && dim.height() > 0);
- setUpdatesEnabled(false);
-
- QGridLayout* oldLayout = dynamic_cast<QGridLayout*>(layout());
- QGridLayout* newLayout = new QGridLayout;
- newLayout->setSpacing(4);
- newLayout->setContentsMargins(0,0,0,0);
-
- int oldWidth = oldLayout->columnCount();
- int oldHeight = oldLayout->rowCount();
- int maxCol = qMax(oldWidth, dim.width());
- int minCol = qMin(oldWidth, dim.width());
- int maxRow = qMax(oldHeight, dim.height());
- int minRow = qMin(oldHeight, dim.height());
-
- for (int row = 0; row < maxRow; row++) {
- for (int col = 0; col < maxCol; col++) {
- QLayoutItem* oldItem = oldLayout->itemAtPosition(row, col);
- QLayoutItem* newItem = newLayout->itemAtPosition(row, col);
- bool removeRow = !(row < dim.height());
- bool removeCol = !(col < dim.width());
-
- if (removeCol || removeRow) {
- if (oldItem) {
- int squeezeRow = removeRow ? (minRow - 1) : row;
- int squeezeCol = removeCol ? (minCol - 1) : col;
- newItem = newLayout->itemAtPosition(squeezeRow, squeezeCol);
- if (!newItem) {
- newLayout->addWidget(createDNDTabWidget(this), squeezeRow, squeezeCol);
- newItem = newLayout->itemAtPosition(squeezeRow, squeezeCol);
- }
- QtTabWidget* oldTabWidget = dynamic_cast<QtTabWidget*>(oldItem->widget());
- QtTabWidget* newTabWidget = dynamic_cast<QtTabWidget*>(newItem->widget());
- assert(oldTabWidget && newTabWidget);
-
- oldTabWidget->hide();
- while(oldTabWidget->count()) {
- QIcon icon = oldTabWidget->tabIcon(0);
- QString text = oldTabWidget->tabText(0);
- newTabWidget->addTab(oldTabWidget->widget(0), icon, text);
- }
- delete oldTabWidget;
- }
- } else {
- if (oldItem) {
- newLayout->addWidget(oldItem->widget(), row, col);
- newItem = newLayout->itemAtPosition(row, col);
- } else {
- newLayout->addWidget(createDNDTabWidget(this), row, col);
- }
- }
- }
- }
-
- for (int col = 0; col < dim.width(); col++) {
- newLayout->setColumnStretch(col, 1);
- }
- for (int row = 0; row < dim.height(); row++) {
- newLayout->setRowStretch(row, 1);
- }
-
- setUpdatesEnabled(true);
- delete layout();
- setLayout(newLayout);
- gridLayout_ = newLayout;
+ resizing_ = true;
+ assert(dim.width() > 0 && dim.height() > 0);
+ setUpdatesEnabled(false);
+
+ QWidget* restoredWidget = currentWidget();
+
+ QGridLayout* oldLayout = dynamic_cast<QGridLayout*>(layout());
+ QGridLayout* newLayout = new QGridLayout(this);
+ newLayout->setSpacing(4);
+ newLayout->setContentsMargins(0,0,0,0);
+
+ int oldWidth = oldLayout->columnCount();
+ int oldHeight = oldLayout->rowCount();
+ int maxCol = qMax(oldWidth, dim.width());
+ int minCol = qMin(oldWidth, dim.width());
+ int maxRow = qMax(oldHeight, dim.height());
+ int minRow = qMin(oldHeight, dim.height());
+
+ for (int row = 0; row < maxRow; row++) {
+ for (int col = 0; col < maxCol; col++) {
+ QLayoutItem* oldItem = oldLayout->itemAtPosition(row, col);
+ QLayoutItem* newItem = newLayout->itemAtPosition(row, col);
+ bool removeRow = !(row < dim.height());
+ bool removeCol = !(col < dim.width());
+
+ if (removeCol || removeRow) {
+ if (oldItem) {
+ int squeezeRow = removeRow ? (minRow - 1) : row;
+ int squeezeCol = removeCol ? (minCol - 1) : col;
+ newItem = newLayout->itemAtPosition(squeezeRow, squeezeCol);
+ if (!newItem) {
+ newLayout->addWidget(createDNDTabWidget(this), squeezeRow, squeezeCol);
+ newItem = newLayout->itemAtPosition(squeezeRow, squeezeCol);
+ }
+ QtTabWidget* oldTabWidget = dynamic_cast<QtTabWidget*>(oldItem->widget());
+ QtTabWidget* newTabWidget = dynamic_cast<QtTabWidget*>(newItem->widget());
+ assert(oldTabWidget && newTabWidget);
+
+ oldTabWidget->hide();
+ while(oldTabWidget->count()) {
+ QIcon icon = oldTabWidget->tabIcon(0);
+ QString text = oldTabWidget->tabText(0);
+ newTabWidget->addTab(oldTabWidget->widget(0), icon, text);
+ }
+ delete oldTabWidget;
+ }
+ } else {
+ if (oldItem) {
+ newLayout->addWidget(oldItem->widget(), row, col);
+ newItem = newLayout->itemAtPosition(row, col);
+ } else {
+ newLayout->addWidget(createDNDTabWidget(this), row, col);
+ }
+ }
+ }
+ }
+
+ for (int col = 0; col < dim.width(); col++) {
+ newLayout->setColumnStretch(col, 1);
+ }
+ for (int row = 0; row < dim.height(); row++) {
+ newLayout->setRowStretch(row, 1);
+ }
+
+ setUpdatesEnabled(true);
+ delete layout();
+ setLayout(newLayout);
+ gridLayout_ = newLayout;
+
+ resizing_ = false;
+ setCurrentWidget(restoredWidget);
+
+ updateEmphasiseFocusOnTabs();
+}
+
+void QtDynamicGridLayout::updateEmphasiseFocusOnTabs() {
+ const auto currentDimensions = getDimension();
+
+ for (int y = 0; y < gridLayout_->rowCount(); y++) {
+ for (int x = 0; x < gridLayout_->columnCount(); x++) {
+ QLayoutItem* layoutItem = gridLayout_->itemAtPosition(y, x);
+ QtTabWidget* tabWidget = dynamic_cast<QtTabWidget*>(layoutItem->widget());
+ assert(tabWidget);
+ for (int index = 0; index < tabWidget->count(); index++) {
+ QtTabbable* tab = dynamic_cast<QtTabbable*>(tabWidget->widget(index));
+ assert(tab);
+ tab->setEmphasiseFocus(currentDimensions.height() > 1 || currentDimensions.width() > 1);
+ }
+ }
+ }
}
void QtDynamicGridLayout::moveCurrentTabRight() {
- int index = currentIndex();
- if (index >= 0) {
- int tabIndex = -1;
- QtTabWidget* tabWidget = indexToTabWidget(index, tabIndex);
- assert(tabWidget);
- int newTabIndex = (tabIndex + 1) % tabWidget->count();
- moveTab(tabWidget, tabIndex, newTabIndex);
- }
+ int index = currentIndex();
+ if (index >= 0) {
+ int tabIndex = -1;
+ QtTabWidget* tabWidget = indexToTabWidget(index, tabIndex);
+ assert(tabWidget);
+ int newTabIndex = (tabIndex + 1) % tabWidget->count();
+ moveTab(tabWidget, tabIndex, newTabIndex);
+ }
}
void QtDynamicGridLayout::moveCurrentTabLeft() {
- int index = currentIndex();
- if (index >= 0) {
- int tabIndex = -1;
- QtTabWidget* tabWidget = indexToTabWidget(index, tabIndex);
- assert(tabWidget);
- int newTabIndex = (tabWidget->count() + tabIndex - 1) % tabWidget->count();
- moveTab(tabWidget, tabIndex, newTabIndex);
- }
+ int index = currentIndex();
+ if (index >= 0) {
+ int tabIndex = -1;
+ QtTabWidget* tabWidget = indexToTabWidget(index, tabIndex);
+ assert(tabWidget);
+ int newTabIndex = (tabWidget->count() + tabIndex - 1) % tabWidget->count();
+ moveTab(tabWidget, tabIndex, newTabIndex);
+ }
}
void QtDynamicGridLayout::moveCurrentTabToNextGroup() {
- int index = currentIndex();
- if (index >= 0) {
- int tabIndex = -1;
- QtTabWidget* tabWidget = indexToTabWidget(index, tabIndex);
-
- int row = -1;
- int col = -1;
- int tmp;
- gridLayout_->getItemPosition(gridLayout_->indexOf(tabWidget), &row, &col, &tmp, &tmp);
-
- // calculate next cell
- col++;
- if (!(col < gridLayout_->columnCount())) {
- col = 0;
- row++;
- if (!(row < gridLayout_->rowCount())) {
- row = 0;
- }
- }
-
- QtTabWidget* targetTabWidget = dynamic_cast<QtTabWidget*>(gridLayout_->itemAtPosition(row, col)->widget());
- assert(tabWidget);
- assert(targetTabWidget);
-
- // fetch tab information
- QWidget* tab = tabWidget->widget(tabIndex);
- QString tabText = tabWidget->tabText(tabIndex);
-
- // move tab
- tab->blockSignals(true);
- targetTabWidget->addTab(tab, tabText);
- tab->blockSignals(false);
- tab->setFocus(Qt::TabFocusReason);
-
- updateTabPositions();
- }
+ int index = currentIndex();
+ if (index >= 0) {
+ int tabIndex = -1;
+ QtTabWidget* tabWidget = indexToTabWidget(index, tabIndex);
+
+ int row = -1;
+ int col = -1;
+ int tmp;
+ gridLayout_->getItemPosition(gridLayout_->indexOf(tabWidget), &row, &col, &tmp, &tmp);
+
+ // calculate next cell
+ col++;
+ if (!(col < gridLayout_->columnCount())) {
+ col = 0;
+ row++;
+ if (!(row < gridLayout_->rowCount())) {
+ row = 0;
+ }
+ }
+
+ QtTabWidget* targetTabWidget = dynamic_cast<QtTabWidget*>(gridLayout_->itemAtPosition(row, col)->widget());
+ assert(tabWidget);
+ assert(targetTabWidget);
+
+ // fetch tab information
+ QWidget* tab = tabWidget->widget(tabIndex);
+ QString tabText = tabWidget->tabText(tabIndex);
+
+ // move tab
+ tab->blockSignals(true);
+ targetTabWidget->addTab(tab, tabText);
+ tab->blockSignals(false);
+ tab->setFocus(Qt::TabFocusReason);
+
+ updateTabPositions();
+ }
}
void QtDynamicGridLayout::moveCurrentTabToPreviousGroup() {
- int index = currentIndex();
- if (index >= 0) {
- int tabIndex = -1;
- QtTabWidget* tabWidget = indexToTabWidget(index, tabIndex);
-
- int row = -1;
- int col = -1;
- int tmp;
- gridLayout_->getItemPosition(gridLayout_->indexOf(tabWidget), &row, &col, &tmp, &tmp);
-
- // calculate next cell
- col--;
- if (col < 0) {
- col = gridLayout_->columnCount() - 1;
- row--;
- if (row < 0) {
- row = gridLayout_->rowCount() - 1;
- }
- }
-
- QtTabWidget* targetTabWidget = dynamic_cast<QtTabWidget*>(gridLayout_->itemAtPosition(row, col)->widget());
- assert(tabWidget);
- assert(targetTabWidget);
-
- // fetch tab information
- QWidget* tab = tabWidget->widget(tabIndex);
- QString tabText = tabWidget->tabText(tabIndex);
-
- // move tab
- tab->blockSignals(true);
- targetTabWidget->addTab(tab, tabText);
- tab->blockSignals(false);
- tab->setFocus(Qt::TabFocusReason);
-
- updateTabPositions();
- }
+ int index = currentIndex();
+ if (index >= 0) {
+ int tabIndex = -1;
+ QtTabWidget* tabWidget = indexToTabWidget(index, tabIndex);
+
+ int row = -1;
+ int col = -1;
+ int tmp;
+ gridLayout_->getItemPosition(gridLayout_->indexOf(tabWidget), &row, &col, &tmp, &tmp);
+
+ // calculate next cell
+ col--;
+ if (col < 0) {
+ col = gridLayout_->columnCount() - 1;
+ row--;
+ if (row < 0) {
+ row = gridLayout_->rowCount() - 1;
+ }
+ }
+
+ QtTabWidget* targetTabWidget = dynamic_cast<QtTabWidget*>(gridLayout_->itemAtPosition(row, col)->widget());
+ assert(tabWidget);
+ assert(targetTabWidget);
+
+ // fetch tab information
+ QWidget* tab = tabWidget->widget(tabIndex);
+ QString tabText = tabWidget->tabText(tabIndex);
+
+ // move tab
+ tab->blockSignals(true);
+ targetTabWidget->addTab(tab, tabText);
+ tab->blockSignals(false);
+ tab->setFocus(Qt::TabFocusReason);
+
+ updateTabPositions();
+ }
}
void QtDynamicGridLayout::handleTabCloseRequested(int index) {
- updateTabPositions();
- QtTabWidget* tabWidgetSender = dynamic_cast<QtTabWidget*>(sender());
- for (int y = 0; y < gridLayout_->rowCount(); y++) {
- for (int x = 0; x < gridLayout_->columnCount(); x++) {
- QLayoutItem* layoutItem = gridLayout_->itemAtPosition(y, x);
- QtTabWidget* tabWidget = dynamic_cast<QtTabWidget*>(layoutItem->widget());
- if (tabWidget == tabWidgetSender) {
- tabCloseRequested(index);
- }
- else {
- index += tabWidget->count();
- }
- }
- }
+ updateTabPositions();
+ QtTabWidget* tabWidgetSender = dynamic_cast<QtTabWidget*>(sender());
+ for (int y = 0; y < gridLayout_->rowCount(); y++) {
+ for (int x = 0; x < gridLayout_->columnCount(); x++) {
+ QLayoutItem* layoutItem = gridLayout_->itemAtPosition(y, x);
+ QtTabWidget* tabWidget = dynamic_cast<QtTabWidget*>(layoutItem->widget());
+ if (tabWidget == tabWidgetSender) {
+ tabCloseRequested(index);
+ }
+ else {
+ index += tabWidget->count();
+ }
+ }
+ }
}
void QtDynamicGridLayout::handleTabCurrentChanged(int index) {
- if (movingTab_) {
- return;
- }
-
- if (index >= 0) {
- QTabWidget* sendingTabWidget = dynamic_cast<QTabWidget*>(sender());
- assert(sendingTabWidget);
- sendingTabWidget->widget(index)->setFocus();
- }
+ if (movingTab_) {
+ return;
+ }
+
+ if (index >= 0) {
+ QTabWidget* sendingTabWidget = dynamic_cast<QTabWidget*>(sender());
+ assert(sendingTabWidget);
+ sendingTabWidget->widget(index)->setFocus();
+ }
}
void QtDynamicGridLayout::updateTabPositions() {
- for (int y = 0; y < gridLayout_->rowCount(); y++) {
- for (int x = 0; x < gridLayout_->columnCount(); x++) {
- QLayoutItem* layoutItem = gridLayout_->itemAtPosition(y, x);
- QtTabWidget* tabWidget = dynamic_cast<QtTabWidget*>(layoutItem->widget());
- assert(tabWidget);
- for (int index = 0; index < tabWidget->count(); index++) {
- QtTabbable* tab = dynamic_cast<QtTabbable*>(tabWidget->widget(index));
- assert(tab);
- tabPositions_.insert(P2QSTRING(tab->getID()), QPoint(x, y));
- }
- }
- }
+ for (int y = 0; y < gridLayout_->rowCount(); y++) {
+ for (int x = 0; x < gridLayout_->columnCount(); x++) {
+ QLayoutItem* layoutItem = gridLayout_->itemAtPosition(y, x);
+ QtTabWidget* tabWidget = dynamic_cast<QtTabWidget*>(layoutItem->widget());
+ assert(tabWidget);
+ for (int index = 0; index < tabWidget->count(); index++) {
+ QtTabbable* tab = dynamic_cast<QtTabbable*>(tabWidget->widget(index));
+ assert(tab);
+ tabPositions_.insert(P2QSTRING(tab->getID()), QPoint(x, y));
+ }
+ }
+ }
}
void QtDynamicGridLayout::moveTab(QtTabWidget* tabWidget, int oldIndex, int newIndex) {
#if QT_VERSION >= 0x040500
- SWIFT_LOG_ASSERT(movingTab_ == NULL, error) << std::endl;
- movingTab_ = qobject_cast<QtTabbable*>(tabWidget->widget(oldIndex));
- SWIFT_LOG_ASSERT(movingTab_ != NULL, error) << std::endl;
-
- if (movingTab_) {
- // Install event filter that filters out events issued during the internal movement of the
- // tab but not targeted at the moving tab.
- qApp->installEventFilter(this);
-
- tabWidget->tabBar()->moveTab(oldIndex, newIndex);
-
- qApp->removeEventFilter(this);
- SWIFT_LOG_ASSERT(movingTab_ == tabWidget->widget(newIndex), error) << std::endl;
- }
- movingTab_ = NULL;
- tabWidget->widget(newIndex)->setFocus();
+ SWIFT_LOG_ASSERT(movingTab_ == nullptr, error) << std::endl;
+ movingTab_ = qobject_cast<QtTabbable*>(tabWidget->widget(oldIndex));
+ SWIFT_LOG_ASSERT(movingTab_ != nullptr, error) << std::endl;
+
+ if (movingTab_) {
+ // Install event filter that filters out events issued during the internal movement of the
+ // tab but not targeted at the moving tab.
+ qApp->installEventFilter(this);
+
+ tabWidget->tabBar()->moveTab(oldIndex, newIndex);
+
+ qApp->removeEventFilter(this);
+ SWIFT_LOG_ASSERT(movingTab_ == tabWidget->widget(newIndex), error) << std::endl;
+ }
+ movingTab_ = nullptr;
+ tabWidget->widget(newIndex)->setFocus();
#else
#warning Qt 4.5 or later is needed. Trying anyway, some things will be disabled.
#endif
}
QtTabWidget* QtDynamicGridLayout::createDNDTabWidget(QWidget* parent) {
- QtTabWidget* tab = new QtTabWidget(parent);
- if (dndEnabled_) {
- QtDNDTabBar* tabBar = new QtDNDTabBar(tab);
- connect(tabBar, SIGNAL(onDropSucceeded()), this, SLOT(updateTabPositions()));
- tab->setTabBar(tabBar);
- }
- tab->setUsesScrollButtons(true);
- tab->setElideMode(Qt::ElideRight);
+ QtTabWidget* tab = new QtTabWidget(parent);
+ if (dndEnabled_) {
+ QtDNDTabBar* tabBar = new QtDNDTabBar(tab);
+ connect(tabBar, SIGNAL(onDropSucceeded()), this, SLOT(updateTabPositions()));
+ tab->setTabBar(tabBar);
+ }
+ tab->setUsesScrollButtons(true);
+ tab->setElideMode(Qt::ElideRight);
#if QT_VERSION >= 0x040500
- /*For Macs, change the tab rendering.*/
- tab->setDocumentMode(true);
- /*Closable tabs are only in Qt4.5 and later*/
- tab->setTabsClosable(true);
- tab->setMovable(true);
- connect(tab, SIGNAL(tabCloseRequested(int)), this, SLOT(handleTabCloseRequested(int)));
- connect(tab, SIGNAL(currentChanged(int)), this, SLOT(handleTabCurrentChanged(int)));
+ /*For Macs, change the tab rendering.*/
+ tab->setDocumentMode(true);
+ /*Closable tabs are only in Qt4.5 and later*/
+ tab->setTabsClosable(true);
+ tab->setMovable(true);
+ connect(tab, SIGNAL(tabCloseRequested(int)), this, SLOT(handleTabCloseRequested(int)));
+ connect(tab, SIGNAL(currentChanged(int)), this, SLOT(handleTabCurrentChanged(int)));
#else
#warning Qt 4.5 or later is needed. Trying anyway, some things will be disabled.
#endif
- return tab;
+ return tab;
}
}
diff --git a/Swift/QtUI/Trellis/QtDynamicGridLayout.h b/Swift/QtUI/Trellis/QtDynamicGridLayout.h
index ed8a9fc..682ae41 100644
--- a/Swift/QtUI/Trellis/QtDynamicGridLayout.h
+++ b/Swift/QtUI/Trellis/QtDynamicGridLayout.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -14,67 +14,69 @@
#include <QWidget>
namespace Swift {
- class QtTabbable;
- class QtTabWidget;
+ class QtTabbable;
+ class QtTabWidget;
- class QtDynamicGridLayout : public QWidget {
- Q_OBJECT
- public:
- explicit QtDynamicGridLayout(QWidget* parent = 0, bool enableDND = false);
- virtual ~QtDynamicGridLayout();
+ class QtDynamicGridLayout : public QWidget {
+ Q_OBJECT
+ public:
+ explicit QtDynamicGridLayout(QWidget* parent = nullptr, bool enableDND = false);
+ virtual ~QtDynamicGridLayout();
- QSize getDimension() const;
+ QSize getDimension() const;
- // emulate QtTabWidget API
- int addTab(QtTabbable* tab, const QString& title);
- void removeTab(int index);
- int count() const;
+ // emulate QtTabWidget API
+ int addTab(QtTabbable* tab, const QString& title);
+ void removeTab(int index);
+ int count() const;
- QWidget* widget(int index) const;
- QWidget* currentWidget() const;
- void setCurrentWidget(QWidget* widget);
+ QWidget* widget(int index) const;
+ QWidget* currentWidget() const;
+ void setCurrentWidget(QWidget* widget);
- QtTabWidget* indexToTabWidget(int index, int& tabIndex);
+ QtTabWidget* indexToTabWidget(int index, int& tabIndex);
- int indexOf(const QWidget* widget) const;
- int currentIndex() const;
- void setCurrentIndex(int index);
+ int indexOf(const QWidget* widget) const;
+ int currentIndex() const;
+ void setCurrentIndex(int index);
- bool isDNDEnabled() const;
+ bool isDNDEnabled() const;
- QHash<QString, QPoint> getTabPositions() const;
- void setTabPositions(const QHash<QString, QPoint> positions);
+ QHash<QString, QPoint> getTabPositions() const;
+ void setTabPositions(const QHash<QString, QPoint> positions);
- bool eventFilter(QObject* object, QEvent* event);
+ bool eventFilter(QObject* object, QEvent* event);
- signals:
- void tabCloseRequested(int index);
- void onCurrentIndexChanged(int newIndex);
+ signals:
+ void tabCloseRequested(int index);
+ void onCurrentIndexChanged(int newIndex);
- public slots:
- void setDimensions(const QSize& dim);
+ public slots:
+ void setDimensions(const QSize& dim);
- // Tab Management
- void moveCurrentTabRight();
- void moveCurrentTabLeft();
- void moveCurrentTabToNextGroup();
- void moveCurrentTabToPreviousGroup();
+ // Tab Management
+ void moveCurrentTabRight();
+ void moveCurrentTabLeft();
+ void moveCurrentTabToNextGroup();
+ void moveCurrentTabToPreviousGroup();
- void updateTabPositions();
+ void updateTabPositions();
- private slots:
- void handleTabCloseRequested(int index);
- void handleTabCurrentChanged(int index);
- void handleApplicationFocusChanged(QWidget* oldFocus, QWidget* newFocus);
+ private slots:
+ void handleTabCloseRequested(int index);
+ void handleTabCurrentChanged(int index);
+ void handleApplicationFocusChanged(QWidget* oldFocus, QWidget* newFocus);
- private:
- void moveTab(QtTabWidget* tabWidget, int oldIndex, int newIndex);
- QtTabWidget* createDNDTabWidget(QWidget* parent);
+ private:
+ void moveTab(QtTabWidget* tabWidget, int oldIndex, int newIndex);
+ QtTabWidget* createDNDTabWidget(QWidget* parent);
+ void updateEmphasiseFocusOnTabs();
- private:
- QGridLayout *gridLayout_;
- bool dndEnabled_;
- QHash<QString, QPoint> tabPositions_;
- QtTabbable* movingTab_;
- };
+ private:
+ QGridLayout *gridLayout_;
+ bool dndEnabled_;
+ QHash<QString, QPoint> tabPositions_;
+ QtTabbable* movingTab_;
+ bool resizing_ = false;
+ };
}
diff --git a/Swift/QtUI/Trellis/QtGridSelectionDialog.cpp b/Swift/QtUI/Trellis/QtGridSelectionDialog.cpp
index a3a1bf8..f03d0ec 100644
--- a/Swift/QtUI/Trellis/QtGridSelectionDialog.cpp
+++ b/Swift/QtUI/Trellis/QtGridSelectionDialog.cpp
@@ -1,157 +1,181 @@
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/Trellis/QtGridSelectionDialog.h>
+#include <QApplication>
+#include <QCursor>
#include <QPaintEvent>
#include <QPainter>
#include <QStyle>
-#include <QStyleOptionFrame>
-#include <QStyleOptionMenuItem>
-#include <QStyleOptionSizeGrip>
+#include <QStyleOption>
namespace Swift {
-QtGridSelectionDialog::QtGridSelectionDialog(QWidget* parent) : QWidget(parent) {
- frameSize = QSize(23,23) * 2;
- maxGridSize = QSize(7,7);
- minGridSize = QSize(1,1);
- currentGridSize = QSize(1,1);
- padding = 4;
- setWindowFlags(Qt::FramelessWindowHint);
- setCursor(Qt::SizeAllCursor);
- horizontalMargin = style()->pixelMetric(QStyle::PM_MenuVMargin) * 2;
- verticalMargin = style()->pixelMetric(QStyle::PM_MenuVMargin) * 2;
+QtGridSelectionDialog::QtGridSelectionDialog(QWidget* parent) : QWidget(parent), descriptionText(tr("Select the number of rows and columns for your layout. You can change the size by moving the mouse or cursor keys.")) {
+ frameSize = QSize(28,28) * 2;
+ maxGridSize = QSize(7,7);
+ minGridSize = QSize(1,1);
+ currentGridSize = QSize(1,1);
+ padding = 4;
+ setWindowFlags(Qt::FramelessWindowHint);
+ setCursor(Qt::SizeAllCursor);
+ horizontalMargin = style()->pixelMetric(QStyle::PM_LayoutLeftMargin);
+ verticalMargin = style()->pixelMetric(QStyle::PM_LayoutBottomMargin);
}
QSize QtGridSelectionDialog::sizeHint() const {
- // PM_MenuVMargin | frameSize | ( padding | frameSize ) * | PM_MenuVMargin
- int width = horizontalMargin + frameSize.width() + (padding + frameSize.width()) * (currentGridSize.width() - 1) + horizontalMargin;
- int height = verticalMargin + frameSize.height() + (padding + frameSize.height()) * (currentGridSize.height() - 1) + verticalMargin;
- return QSize(width, height);
+ // PM_MenuVMargin | frameSize | ( padding | frameSize ) * | PM_MenuVMargin
+ int width = horizontalMargin + frameSize.width() + (padding + frameSize.width()) * (currentGridSize.width() - 1) + horizontalMargin;
+ int height = verticalMargin + frameSize.height() + (padding + frameSize.height()) * (currentGridSize.height() - 1) + verticalMargin;
+
+ // Add space for descriptive centered text below.
+ auto fontMetrics = QFontMetrics(QApplication::font());
+ auto descriptionBB = fontMetrics.boundingRect(QRect(0,0,width - 2*horizontalMargin,1000), Qt::TextWordWrap, descriptionText, 0, 0);
+
+ height += descriptionBB.height() + descriptionBB.y();
+
+ return QSize(width, height);
}
void QtGridSelectionDialog::setCurrentGridSize(const QSize& size) {
- currentGridSize = size;
- emit currentGridSizeChanged(size);
+ currentGridSize = size;
+ emit currentGridSizeChanged(size);
}
QSize QtGridSelectionDialog::getCurrentGridSize() const {
- return currentGridSize;
+ return currentGridSize;
}
void QtGridSelectionDialog::setMinGridSize(const QSize& size) {
- minGridSize = size;
- emit minGridSizeChanged(size);
+ minGridSize = size;
+ emit minGridSizeChanged(size);
}
QSize QtGridSelectionDialog::getMinGridSize() const {
- return minGridSize;
+ return minGridSize;
}
void QtGridSelectionDialog::setMaxGridSize(const QSize& size) {
- maxGridSize = size;
- emit maxGridSizeChanged(size);
+ maxGridSize = size;
+ emit maxGridSizeChanged(size);
}
QSize QtGridSelectionDialog::getMaxGridSize() const {
- return maxGridSize;
+ return maxGridSize;
}
void QtGridSelectionDialog::keyReleaseEvent(QKeyEvent* event) {
- if (event) {
- QSize newGridSize = currentGridSize;
- if (event->key() == Qt::Key_Up) {
- newGridSize += QSize(0, -1);
- }
- else if (event->key() == Qt::Key_Down) {
- newGridSize += QSize(0, 1);
- }
- else if (event->key() == Qt::Key_Left) {
- newGridSize += QSize(-1, 0);
- }
- else if (event->key() == Qt::Key_Right) {
- newGridSize += QSize(1, 0);
- }
- else if (event->key() == Qt::Key_Return) {
- hide();
- setCurrentGridSize(currentGridSize);
- }
- if (minGridSize.expandedTo(newGridSize).boundedTo(maxGridSize) != currentGridSize) {
- currentGridSize = minGridSize.expandedTo(newGridSize).boundedTo(maxGridSize);
- resize(sizeHint());
- }
- }
+ if (event) {
+ QSize newGridSize = currentGridSize;
+ if (event->key() == Qt::Key_Up) {
+ newGridSize += QSize(0, -1);
+ }
+ else if (event->key() == Qt::Key_Down) {
+ newGridSize += QSize(0, 1);
+ }
+ else if (event->key() == Qt::Key_Left) {
+ newGridSize += QSize(-1, 0);
+ }
+ else if (event->key() == Qt::Key_Right) {
+ newGridSize += QSize(1, 0);
+ }
+ else if (event->key() == Qt::Key_Return) {
+ hide();
+ setCurrentGridSize(currentGridSize);
+ }
+ if (minGridSize.expandedTo(newGridSize).boundedTo(maxGridSize) != currentGridSize) {
+ currentGridSize = minGridSize.expandedTo(newGridSize).boundedTo(maxGridSize);
+
+ QSize newSizeHint = sizeHint();
+ resize(newSizeHint);
+ QCursor::setPos(mapToGlobal(QPoint(newSizeHint.width(), newSizeHint.height()) - QPoint(frameSize.width() / 2, frameSize.height() / 2)));
+ }
+ }
}
void QtGridSelectionDialog::mousePressEvent(QMouseEvent*) {
- hide();
- setCurrentGridSize(currentGridSize);
+ hide();
+ setCurrentGridSize(currentGridSize);
}
void QtGridSelectionDialog::paintEvent(QPaintEvent*) {
- QPainter painter(this);
- QStyleOptionMenuItem option;
- option.state = QStyle::State_Enabled | QStyle::State_Selected;
- option.menuRect = QRect(QPoint(0,0), frameSize);
- for (int x = 0; x < currentGridSize.width(); x++) {
- for (int y = 0; y < currentGridSize.height(); y++) {
- int xPos = horizontalMargin + (x * (frameSize.width() + padding));
- int yPos = verticalMargin + (y * (frameSize.height() + padding));
- option.menuRect.moveTo(QPoint(xPos, yPos));
- option.rect = option.menuRect;
- style()->drawControl(QStyle::CE_MenuItem, &option, &painter, 0);
- }
- }
-
- QStyleOptionSizeGrip sizeGripOption;
- sizeGripOption.init(this);
- sizeGripOption.corner = Qt::BottomRightCorner;
- style()->drawControl(QStyle::CE_SizeGrip, &sizeGripOption, &painter, this);
+ QPainter painter(this);
+ // draw grid
+ QRect gridCell = QRect(QPoint(0,0), frameSize);
+ painter.setBrush(palette().highlight());
+ painter.setPen(Qt::NoPen);
+ for (int x = 0; x < currentGridSize.width(); x++) {
+ for (int y = 0; y < currentGridSize.height(); y++) {
+ int xPos = horizontalMargin + (x * (frameSize.width() + padding));
+ int yPos = verticalMargin + (y * (frameSize.height() + padding));
+ gridCell.moveTo(QPoint(xPos, yPos));
+ painter.drawRect(gridCell);
+ }
+ }
+
+ // draw description text
+ auto fontMetrics = QFontMetrics(QApplication::font());
+ auto descriptionBB = fontMetrics.boundingRect(QRect(0,0, width() - 2 * horizontalMargin,0), Qt::AlignHCenter | Qt::AlignTop | Qt::TextWordWrap, descriptionText, 0, 0);
+
+ QStyleOption opt;
+ opt.initFrom(this);
+ int textY = verticalMargin + (currentGridSize.height() * (frameSize.height() + padding));
+ int textX = (size().width() - descriptionBB.width()) / 2;
+ style()->drawItemText(&painter, QRect(textX, textY, descriptionBB.width(), descriptionBB.height()), Qt::AlignHCenter | Qt::AlignTop | Qt::TextWordWrap, opt.palette, true, descriptionText, foregroundRole());
}
void QtGridSelectionDialog::showEvent(QShowEvent*) {
- int xPos = horizontalMargin + frameSize.width() + (padding + frameSize.width()) * (currentGridSize.width() - 1) - frameSize.width()/2;
- int yPos = verticalMargin + frameSize.height() + (padding + frameSize.height()) * (currentGridSize.height() - 1) - frameSize.height()/2;
- QCursor::setPos(mapToGlobal(QPoint(xPos, yPos)));
- setMouseTracking(true);
+ int xPos = horizontalMargin + frameSize.width() + (padding + frameSize.width()) * (currentGridSize.width() - 1) - frameSize.width()/2;
+ int yPos = verticalMargin + frameSize.height() + (padding + frameSize.height()) * (currentGridSize.height() - 1) - frameSize.height()/2;
+ QCursor::setPos(mapToGlobal(QPoint(xPos, yPos)));
+ setMouseTracking(true);
}
void QtGridSelectionDialog::hideEvent(QHideEvent*) {
- setMouseTracking(false);
+ setMouseTracking(false);
}
void QtGridSelectionDialog::mouseMoveEvent(QMouseEvent*) {
- QPoint diff = (frameGeometry().bottomRight() - QCursor::pos());
- QSize newDimensions = currentGridSize;
- if (diff.x() > frameSize.width() * 1.5) {
- newDimensions -= QSize(diff.x() / (frameSize.width() * 1.5), 0);
- }
- if (diff.y() > frameSize.height() * 1.5) {
- newDimensions -= QSize(0, diff.y() / (frameSize.height() * 1.5));
- }
- if (minGridSize.expandedTo(newDimensions).boundedTo(maxGridSize) != currentGridSize) {
- currentGridSize = minGridSize.expandedTo(newDimensions).boundedTo(maxGridSize);
- resize(sizeHint());
- }
+ QPoint diff = (frameGeometry().bottomRight() - QCursor::pos());
+ QSize newDimensions = currentGridSize;
+ if (diff.x() > frameSize.width() * 1.5) {
+ newDimensions -= QSize(diff.x() / (frameSize.width() * 1.5), 0);
+ }
+ if (diff.y() > frameSize.height() * 1.5) {
+ newDimensions -= QSize(0, diff.y() / (frameSize.height() * 1.5));
+ }
+ if (minGridSize.expandedTo(newDimensions).boundedTo(maxGridSize) != currentGridSize) {
+ currentGridSize = minGridSize.expandedTo(newDimensions).boundedTo(maxGridSize);
+ resize(sizeHint());
+ }
}
void QtGridSelectionDialog::leaveEvent(QEvent *) {
- QPoint diff = (frameGeometry().bottomRight() - QCursor::pos());
- QSize newGridSize = currentGridSize;
- if (diff.x() < 0) {
- newGridSize += QSize(1,0);
- }
- if (diff.y() < 0) {
- newGridSize += QSize(0,1);
- }
- if (minGridSize.expandedTo(newGridSize).boundedTo(maxGridSize) != currentGridSize) {
- currentGridSize = minGridSize.expandedTo(newGridSize).boundedTo(maxGridSize);
- resize(sizeHint());
- }
+ QPoint diff = (frameGeometry().bottomRight() - QCursor::pos());
+ QSize newGridSize = currentGridSize;
+ if (diff.x() < 0) {
+ newGridSize += QSize(1,0);
+ }
+ if (diff.y() < 0) {
+ newGridSize += QSize(0,1);
+ }
+ if (minGridSize.expandedTo(newGridSize).boundedTo(maxGridSize) != currentGridSize) {
+ currentGridSize = minGridSize.expandedTo(newGridSize).boundedTo(maxGridSize);
+ resize(sizeHint());
+ }
+}
+
+bool QtGridSelectionDialog::event(QEvent* event) {
+ // Hide the window when it becomes a non-top-level window.
+ if (event->type() == QEvent::WindowDeactivate) {
+ hide();
+ return true;
+ }
+ return QWidget::event(event);
}
}
diff --git a/Swift/QtUI/Trellis/QtGridSelectionDialog.h b/Swift/QtUI/Trellis/QtGridSelectionDialog.h
index abcc8b1..557963d 100644
--- a/Swift/QtUI/Trellis/QtGridSelectionDialog.h
+++ b/Swift/QtUI/Trellis/QtGridSelectionDialog.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -11,47 +11,50 @@
namespace Swift {
- class QtGridSelectionDialog : public QWidget {
- Q_OBJECT
-
- Q_PROPERTY(QSize currentGridSize READ getCurrentGridSize WRITE setCurrentGridSize NOTIFY currentGridSizeChanged)
- Q_PROPERTY(QSize minGridSize READ getMinGridSize WRITE setMinGridSize NOTIFY minGridSizeChanged)
- Q_PROPERTY(QSize maxGridSize READ getMaxGridSize WRITE setMaxGridSize NOTIFY maxGridSizeChanged)
- public:
- explicit QtGridSelectionDialog(QWidget* parent = 0);
-
- virtual QSize sizeHint() const;
-
- void setCurrentGridSize(const QSize& size);
- QSize getCurrentGridSize() const;
- void setMinGridSize(const QSize& size);
- QSize getMinGridSize() const;
- void setMaxGridSize(const QSize& size);
- QSize getMaxGridSize() const;
-
- signals:
- void currentGridSizeChanged(QSize);
- void minGridSizeChanged(QSize);
- void maxGridSizeChanged(QSize);
-
- protected:
- void keyReleaseEvent(QKeyEvent* event);
- void mousePressEvent(QMouseEvent* event);
- void mouseMoveEvent(QMouseEvent* event);
- void paintEvent(QPaintEvent* event);
- void showEvent(QShowEvent* event);
- void hideEvent(QHideEvent* event);
- void leaveEvent(QEvent *event);
-
- private:
- int padding;
- int horizontalMargin;
- int verticalMargin;
-
- QSize frameSize;
-
- QSize currentGridSize;
- QSize minGridSize;
- QSize maxGridSize;
- };
+ class QtGridSelectionDialog : public QWidget {
+ Q_OBJECT
+
+ Q_PROPERTY(QSize currentGridSize READ getCurrentGridSize WRITE setCurrentGridSize NOTIFY currentGridSizeChanged)
+ Q_PROPERTY(QSize minGridSize READ getMinGridSize WRITE setMinGridSize NOTIFY minGridSizeChanged)
+ Q_PROPERTY(QSize maxGridSize READ getMaxGridSize WRITE setMaxGridSize NOTIFY maxGridSizeChanged)
+ public:
+ explicit QtGridSelectionDialog(QWidget* parent = nullptr);
+
+ virtual QSize sizeHint() const;
+
+ void setCurrentGridSize(const QSize& size);
+ QSize getCurrentGridSize() const;
+ void setMinGridSize(const QSize& size);
+ QSize getMinGridSize() const;
+ void setMaxGridSize(const QSize& size);
+ QSize getMaxGridSize() const;
+
+ signals:
+ void currentGridSizeChanged(QSize);
+ void minGridSizeChanged(QSize);
+ void maxGridSizeChanged(QSize);
+
+ protected:
+ void keyReleaseEvent(QKeyEvent* event);
+ void mousePressEvent(QMouseEvent* event);
+ void mouseMoveEvent(QMouseEvent* event);
+ void paintEvent(QPaintEvent* event);
+ void showEvent(QShowEvent* event);
+ void hideEvent(QHideEvent* event);
+ void leaveEvent(QEvent *event);
+ bool event(QEvent* event);
+
+ private:
+ int padding;
+ int horizontalMargin;
+ int verticalMargin;
+
+ QSize frameSize;
+
+ QSize currentGridSize;
+ QSize minGridSize;
+ QSize maxGridSize;
+
+ const QString descriptionText;
+ };
}
diff --git a/Swift/QtUI/UserSearch/ContactListDelegate.cpp b/Swift/QtUI/UserSearch/ContactListDelegate.cpp
index 19290aa..75e25a1 100644
--- a/Swift/QtUI/UserSearch/ContactListDelegate.cpp
+++ b/Swift/QtUI/UserSearch/ContactListDelegate.cpp
@@ -5,15 +5,17 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/UserSearch/ContactListDelegate.h>
-#include <Swift/QtUI/UserSearch/ContactListModel.h>
+
#include <Swift/Controllers/Contact.h>
+
#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/UserSearch/ContactListModel.h>
namespace Swift {
@@ -24,29 +26,29 @@ ContactListDelegate::~ContactListDelegate() {
}
void ContactListDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
- if (!index.isValid()) {
- return;
- }
- const Contact::ref contact = static_cast<Contact*>(index.internalPointer())->shared_from_this();
- QColor nameColor = index.data(Qt::TextColorRole).value<QColor>();
- QString avatarPath = index.data(ContactListModel::AvatarRole).value<QString>();
- QIcon presenceIcon =index.data(ChatListRecentItem::PresenceIconRole).isValid() && !index.data(ChatListRecentItem::PresenceIconRole).value<QIcon>().isNull()
- ? index.data(ChatListRecentItem::PresenceIconRole).value<QIcon>()
- : QIcon(":/icons/offline.png");
- QString name = P2QSTRING(contact->name);
- QString statusText = P2QSTRING(contact->jid.toString());
- common_.paintContact(painter, option, nameColor, avatarPath, presenceIcon, name, statusText, false, 0, compact_);
+ if (!index.isValid()) {
+ return;
+ }
+ const Contact::ref contact = static_cast<Contact*>(index.internalPointer())->shared_from_this();
+ QColor nameColor = index.data(Qt::TextColorRole).value<QColor>();
+ QString avatarPath = index.data(ContactListModel::AvatarRole).value<QString>();
+ QIcon presenceIcon =index.data(ChatListRecentItem::PresenceIconRole).isValid() && !index.data(ChatListRecentItem::PresenceIconRole).value<QIcon>().isNull()
+ ? index.data(ChatListRecentItem::PresenceIconRole).value<QIcon>()
+ : QIcon(":/icons/offline.png");
+ QString name = P2QSTRING(contact->name);
+ QString statusText = P2QSTRING(contact->jid.toString());
+ common_.paintContact(painter, option, nameColor, avatarPath, presenceIcon, name, statusText, false, 0, compact_);
}
QSize ContactListDelegate::sizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/ ) const {
- QFontMetrics nameMetrics(common_.nameFont);
- QFontMetrics statusMetrics(common_.detailFont);
- int sizeByText = 2 * common_.verticalMargin + nameMetrics.height() + statusMetrics.height();
- return QSize(150, sizeByText);
+ QFontMetrics nameMetrics(common_.nameFont);
+ QFontMetrics statusMetrics(common_.detailFont);
+ int sizeByText = 2 * common_.verticalMargin + nameMetrics.height() + statusMetrics.height();
+ return QSize(150, sizeByText);
}
void ContactListDelegate::setCompact(bool compact) {
- compact_ = compact;
+ compact_ = compact;
}
}
diff --git a/Swift/QtUI/UserSearch/ContactListDelegate.h b/Swift/QtUI/UserSearch/ContactListDelegate.h
index 7680aba..208246a 100644
--- a/Swift/QtUI/UserSearch/ContactListDelegate.h
+++ b/Swift/QtUI/UserSearch/ContactListDelegate.h
@@ -13,18 +13,18 @@
namespace Swift {
class ContactListDelegate : public QStyledItemDelegate {
- public:
- ContactListDelegate(bool compact);
- virtual ~ContactListDelegate();
+ public:
+ ContactListDelegate(bool compact);
+ virtual ~ContactListDelegate();
- QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
- void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
- public slots:
- void setCompact(bool compact);
+ public slots:
+ void setCompact(bool compact);
- private:
- bool compact_;
- DelegateCommons common_;
+ private:
+ bool compact_;
+ DelegateCommons common_;
};
}
diff --git a/Swift/QtUI/UserSearch/ContactListModel.cpp b/Swift/QtUI/UserSearch/ContactListModel.cpp
index db13fbc..6ef85d7 100644
--- a/Swift/QtUI/UserSearch/ContactListModel.cpp
+++ b/Swift/QtUI/UserSearch/ContactListModel.cpp
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -15,125 +15,124 @@
#include <QMimeData>
#include <Swiften/Base/Path.h>
-#include <Swiften/Base/foreach.h>
#include <Swiften/Elements/StatusShow.h>
-#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swift/QtUI/QtResourceHelper.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
QDataStream& operator >>(QDataStream& in, StatusShow::Type& e){
- quint32 buffer;
- in >> buffer;
- switch(buffer) {
- case StatusShow::Online:
- e = StatusShow::Online;
- break;
- case StatusShow::Away:
- e = StatusShow::Away;
- break;
- case StatusShow::FFC:
- e = StatusShow::FFC;
- break;
- case StatusShow::XA:
- e = StatusShow::XA;
- break;
- case StatusShow::DND:
- e = StatusShow::DND;
- break;
- default:
- e = StatusShow::None;
- break;
- }
- return in;
+ quint32 buffer;
+ in >> buffer;
+ switch(buffer) {
+ case StatusShow::Online:
+ e = StatusShow::Online;
+ break;
+ case StatusShow::Away:
+ e = StatusShow::Away;
+ break;
+ case StatusShow::FFC:
+ e = StatusShow::FFC;
+ break;
+ case StatusShow::XA:
+ e = StatusShow::XA;
+ break;
+ case StatusShow::DND:
+ e = StatusShow::DND;
+ break;
+ default:
+ e = StatusShow::None;
+ break;
+ }
+ return in;
}
ContactListModel::ContactListModel(bool editable) : QAbstractItemModel(), editable_(editable) {
}
void ContactListModel::setList(const std::vector<Contact::ref>& list) {
- emit layoutAboutToBeChanged();
- contacts_ = list;
- emit layoutChanged();
+ emit layoutAboutToBeChanged();
+ contacts_ = list;
+ emit layoutChanged();
}
const std::vector<Contact::ref>& ContactListModel::getList() const {
- return contacts_;
+ return contacts_;
}
Contact::ref ContactListModel::getContact(const size_t i) const {
- return contacts_[i];
+ return contacts_[i];
}
Qt::ItemFlags ContactListModel::flags(const QModelIndex& index) const {
- Qt::ItemFlags flags = QAbstractItemModel::flags(index);
- if (index.isValid()) {
- flags = flags & ~Qt::ItemIsDropEnabled;
- } else {
- flags = Qt::ItemIsDropEnabled | flags;
- }
- return flags;
+ Qt::ItemFlags flags = QAbstractItemModel::flags(index);
+ if (index.isValid()) {
+ flags = flags & ~Qt::ItemIsDropEnabled;
+ } else {
+ flags = Qt::ItemIsDropEnabled | flags;
+ }
+ return flags;
}
int ContactListModel::columnCount(const QModelIndex&) const {
- return editable_ ? 2 : 1;
+ return editable_ ? 2 : 1;
}
QVariant ContactListModel::data(const QModelIndex& index, int role) const {
- if ((boost::numeric_cast<size_t>(index.row()) < contacts_.size()) && (index.column() == 0)) {
- const Contact::ref& contact = contacts_[index.row()];
- if (role == Qt::EditRole) {
- return P2QSTRING(contact->jid.toString());
- }
- return dataForContact(contact, role);
- } else {
- return QVariant();
- }
+ if ((boost::numeric_cast<size_t>(index.row()) < contacts_.size()) && (index.column() == 0)) {
+ const Contact::ref& contact = contacts_[index.row()];
+ if (role == Qt::EditRole) {
+ return P2QSTRING(contact->jid.toString());
+ }
+ return dataForContact(contact, role);
+ } else {
+ return QVariant();
+ }
}
QModelIndex ContactListModel::index(int row, int column, const QModelIndex& parent) const {
- if (!hasIndex(row, column, parent)) {
- return QModelIndex();
- }
+ if (!hasIndex(row, column, parent)) {
+ return QModelIndex();
+ }
- return boost::numeric_cast<size_t>(row) < contacts_.size() ? createIndex(row, column, contacts_[row].get()) : QModelIndex();
+ return boost::numeric_cast<size_t>(row) < contacts_.size() ? createIndex(row, column, contacts_[row].get()) : QModelIndex();
}
QModelIndex ContactListModel::parent(const QModelIndex& index) const {
- if (!index.isValid()) {
- return QModelIndex();
- }
- return QModelIndex();
+ if (!index.isValid()) {
+ return QModelIndex();
+ }
+ return QModelIndex();
}
int ContactListModel::rowCount(const QModelIndex& /*parent*/) const {
- return contacts_.size();
+ return contacts_.size();
}
bool ContactListModel::removeRows(int row, int /*count*/, const QModelIndex& /*parent*/) {
- if (boost::numeric_cast<size_t>(row) < contacts_.size()) {
- emit layoutAboutToBeChanged();
- contacts_.erase(contacts_.begin() + row);
- emit layoutChanged();
- onListChanged(getList());
- return true;
- }
- return false;
+ if (boost::numeric_cast<size_t>(row) < contacts_.size()) {
+ emit layoutAboutToBeChanged();
+ contacts_.erase(contacts_.begin() + row);
+ emit layoutChanged();
+ onListChanged(getList());
+ return true;
+ }
+ return false;
}
QVariant ContactListModel::dataForContact(const Contact::ref& contact, int role) const {
- switch (role) {
- case Qt::DisplayRole: return P2QSTRING(contact->name);
- case DetailTextRole: return P2QSTRING(contact->jid.toString());
- case AvatarRole: return QVariant(P2QSTRING(pathToString(contact->avatarPath)));
- case PresenceIconRole: return getPresenceIconForContact(contact);
- default: return QVariant();
- }
+ switch (role) {
+ case Qt::DisplayRole: return P2QSTRING(contact->name);
+ case DetailTextRole: return P2QSTRING(contact->jid.toString());
+ case AvatarRole: return QVariant(P2QSTRING(pathToString(contact->avatarPath)));
+ case PresenceIconRole: return getPresenceIconForContact(contact);
+ default: return QVariant();
+ }
}
QIcon ContactListModel::getPresenceIconForContact(const Contact::ref& contact) const {
- return QIcon(statusShowTypeToIconPath(contact->statusType));
+ return QIcon(statusShowTypeToIconPath(contact->statusType));
}
}
diff --git a/Swift/QtUI/UserSearch/ContactListModel.h b/Swift/QtUI/UserSearch/ContactListModel.h
index 51a4bd1..026b01b 100644
--- a/Swift/QtUI/UserSearch/ContactListModel.h
+++ b/Swift/QtUI/UserSearch/ContactListModel.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -13,52 +13,54 @@
#pragma once
#include <vector>
+
#include <boost/bind.hpp>
-#include <Swiften/Base/boost_bsignals.h>
+#include <boost/signals2.hpp>
#include <QAbstractItemModel>
#include <Swift/Controllers/Contact.h>
-#include <Swift/QtUI/ChatList/ChatListItem.h>
+
#include <Swift/QtUI/ChatList/ChatListGroupItem.h>
+#include <Swift/QtUI/ChatList/ChatListItem.h>
#include <Swift/QtUI/ChatList/ChatListRecentItem.h>
namespace Swift {
- class ContactListModel : public QAbstractItemModel {
- Q_OBJECT
- public:
- enum ContactRoles {
- DetailTextRole = Qt::UserRole,
- AvatarRole = Qt::UserRole + 1,
- PresenceIconRole = Qt::UserRole + 2
- };
+ class ContactListModel : public QAbstractItemModel {
+ Q_OBJECT
+ public:
+ enum ContactRoles {
+ DetailTextRole = Qt::UserRole,
+ AvatarRole = Qt::UserRole + 1,
+ PresenceIconRole = Qt::UserRole + 2
+ };
- public:
- ContactListModel(bool editable);
+ public:
+ ContactListModel(bool editable);
- void setList(const std::vector<Contact::ref>& list);
- const std::vector<Contact::ref>& getList() const;
- Contact::ref getContact(const size_t i) const;
+ void setList(const std::vector<Contact::ref>& list);
+ const std::vector<Contact::ref>& getList() const;
+ Contact::ref getContact(const size_t i) const;
- Qt::ItemFlags flags(const QModelIndex& index) const;
- int columnCount(const QModelIndex& parent = QModelIndex()) const;
- QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
- QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
- QModelIndex parent(const QModelIndex& index) const;
- int rowCount(const QModelIndex& parent = QModelIndex()) const;
- bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex());
+ Qt::ItemFlags flags(const QModelIndex& index) const;
+ int columnCount(const QModelIndex& parent = QModelIndex()) const;
+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
+ QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex& index) const;
+ int rowCount(const QModelIndex& parent = QModelIndex()) const;
+ bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex());
- private:
- QVariant dataForContact(const Contact::ref& contact, int role) const;
- QIcon getPresenceIconForContact(const Contact::ref& contact) const;
+ private:
+ QVariant dataForContact(const Contact::ref& contact, int role) const;
+ QIcon getPresenceIconForContact(const Contact::ref& contact) const;
- signals:
- void onListChanged(std::vector<Contact::ref> list);
- void onJIDsDropped(const std::vector<JID>& contact);
+ signals:
+ void onListChanged(std::vector<Contact::ref> list);
+ void onJIDsDropped(const std::vector<JID>& contact);
- private:
- bool editable_;
- std::vector<Contact::ref> contacts_;
- };
+ private:
+ bool editable_;
+ std::vector<Contact::ref> contacts_;
+ };
}
diff --git a/Swift/QtUI/UserSearch/QtContactListWidget.cpp b/Swift/QtUI/UserSearch/QtContactListWidget.cpp
index 9b76aba..73a8482 100644
--- a/Swift/QtUI/UserSearch/QtContactListWidget.cpp
+++ b/Swift/QtUI/UserSearch/QtContactListWidget.cpp
@@ -5,98 +5,99 @@
*/
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/UserSearch/QtContactListWidget.h>
-#include <Swift/QtUI/UserSearch/ContactListModel.h>
-#include <Swift/QtUI/UserSearch/ContactListDelegate.h>
-#include <Swift/QtUI/QtUISettingConstants.h>
+#include <QHeaderView>
+
#include <Swift/Controllers/Settings/SettingsProvider.h>
-#include <Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h>
-#include <QHeaderView>
+#include <Swift/QtUI/QtUISettingConstants.h>
+#include <Swift/QtUI/QtVCardWidget/QtRemovableItemDelegate.h>
+#include <Swift/QtUI/UserSearch/ContactListDelegate.h>
+#include <Swift/QtUI/UserSearch/ContactListModel.h>
namespace Swift {
QtContactListWidget::QtContactListWidget(QWidget* parent, SettingsProvider* settings) : QTreeView(parent), settings_(settings), limited_(false) {
- contactListModel_ = new ContactListModel(true);
- setModel(contactListModel_);
+ contactListModel_ = new ContactListModel(true);
+ setModel(contactListModel_);
- connect(contactListModel_, SIGNAL(onListChanged(std::vector<Contact::ref>)), this, SIGNAL(onListChanged(std::vector<Contact::ref>)));
- connect(contactListModel_, SIGNAL(onJIDsDropped(std::vector<JID>)), this, SIGNAL(onJIDsAdded(std::vector<JID>)));
+ connect(contactListModel_, SIGNAL(onListChanged(std::vector<Contact::ref>)), this, SIGNAL(onListChanged(std::vector<Contact::ref>)));
+ connect(contactListModel_, SIGNAL(onJIDsDropped(std::vector<JID>)), this, SIGNAL(onJIDsAdded(std::vector<JID>)));
- setSelectionMode(QAbstractItemView::SingleSelection);
- setSelectionBehavior(QAbstractItemView::SelectRows);
- setUniformRowHeights(true);
+ setSelectionMode(QAbstractItemView::SingleSelection);
+ setSelectionBehavior(QAbstractItemView::SelectRows);
+ setUniformRowHeights(true);
- setAlternatingRowColors(true);
- setIndentation(0);
- setHeaderHidden(true);
- setExpandsOnDoubleClick(false);
- setItemsExpandable(false);
- setEditTriggers(QAbstractItemView::DoubleClicked);
+ setAlternatingRowColors(true);
+ setIndentation(0);
+ setHeaderHidden(true);
+ setExpandsOnDoubleClick(false);
+ setItemsExpandable(false);
+ setEditTriggers(QAbstractItemView::DoubleClicked);
- contactListDelegate_ = new ContactListDelegate(settings->getSetting(QtUISettingConstants::COMPACT_ROSTER));
- removableItemDelegate_ = new QtRemovableItemDelegate(style());
+ contactListDelegate_ = new ContactListDelegate(settings->getSetting(QtUISettingConstants::COMPACT_ROSTER));
+ removableItemDelegate_ = new QtRemovableItemDelegate(style());
- setItemDelegateForColumn(0, contactListDelegate_);
- setItemDelegateForColumn(1, removableItemDelegate_);
+ setItemDelegateForColumn(0, contactListDelegate_);
+ setItemDelegateForColumn(1, removableItemDelegate_);
- header()->resizeSection(1, removableItemDelegate_->sizeHint(QStyleOptionViewItem(), QModelIndex()).width());
+ header()->resizeSection(1, removableItemDelegate_->sizeHint(QStyleOptionViewItem(), QModelIndex()).width());
- header()->setStretchLastSection(false);
+ header()->setStretchLastSection(false);
#if QT_VERSION >= 0x050000
- header()->setSectionResizeMode(0, QHeaderView::Stretch);
+ header()->setSectionResizeMode(0, QHeaderView::Stretch);
#else
- header()->setResizeMode(0, QHeaderView::Stretch);
+ header()->setResizeMode(0, QHeaderView::Stretch);
#endif
}
QtContactListWidget::~QtContactListWidget() {
- delete contactListDelegate_;
- delete removableItemDelegate_;
- delete contactListModel_;
+ delete contactListDelegate_;
+ delete removableItemDelegate_;
+ delete contactListModel_;
}
void QtContactListWidget::setList(const std::vector<Contact::ref>& list) {
- contactListModel_->setList(list);
+ contactListModel_->setList(list);
}
std::vector<Contact::ref> QtContactListWidget::getList() const {
- return contactListModel_->getList();
+ return contactListModel_->getList();
}
Contact::ref QtContactListWidget::getContact(const size_t i) {
- return contactListModel_->getContact(i);
+ return contactListModel_->getContact(i);
}
void QtContactListWidget::setMaximumNoOfContactsToOne(bool limited) {
- limited_ = limited;
+ limited_ = limited;
}
bool QtContactListWidget::isFull() const {
- return limited_ && (getList().size() == 1);
+ return limited_ && (getList().size() == 1);
}
void QtContactListWidget::updateContacts(const std::vector<Contact::ref>& contactUpdates) {
- std::vector<Contact::ref> contacts = contactListModel_->getList();
- foreach(const Contact::ref& contactUpdate, contactUpdates) {
- for(size_t n = 0; n < contacts.size(); n++) {
- if (contactUpdate->jid == contacts[n]->jid) {
- contacts[n] = contactUpdate;
- break;
- }
- }
- }
- contactListModel_->setList(contacts);
+ std::vector<Contact::ref> contacts = contactListModel_->getList();
+ for (const auto& contactUpdate : contactUpdates) {
+ for (auto&& contact : contacts) {
+ if (contactUpdate->jid == contact->jid) {
+ contact = contactUpdate;
+ break;
+ }
+ }
+ }
+ contactListModel_->setList(contacts);
}
void QtContactListWidget::handleSettingsChanged(const std::string&) {
- contactListDelegate_->setCompact(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
+ contactListDelegate_->setCompact(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
}
}
diff --git a/Swift/QtUI/UserSearch/QtContactListWidget.h b/Swift/QtUI/UserSearch/QtContactListWidget.h
index 43da011..f2483c3 100644
--- a/Swift/QtUI/UserSearch/QtContactListWidget.h
+++ b/Swift/QtUI/UserSearch/QtContactListWidget.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -14,14 +14,14 @@
#include <vector>
+#include <QDragEnterEvent>
+#include <QDragMoveEvent>
+#include <QDropEvent>
#include <QTreeView>
-#include <Swift/Controllers/Contact.h>
#include <Swiften/Base/Log.h>
-#include <QDragEnterEvent>
-#include <QDragMoveEvent>
-#include <QDropEvent>
+#include <Swift/Controllers/Contact.h>
namespace Swift {
@@ -31,33 +31,33 @@ class SettingsProvider;
class QtRemovableItemDelegate;
class QtContactListWidget : public QTreeView {
- Q_OBJECT
+ Q_OBJECT
public:
- QtContactListWidget(QWidget* parent, SettingsProvider* settings);
- virtual ~QtContactListWidget();
+ QtContactListWidget(QWidget* parent, SettingsProvider* settings);
+ virtual ~QtContactListWidget();
- void setList(const std::vector<Contact::ref>& list);
- std::vector<Contact::ref> getList() const;
- Contact::ref getContact(const size_t i);
- void setMaximumNoOfContactsToOne(bool limited);
- bool isFull() const;
+ void setList(const std::vector<Contact::ref>& list);
+ std::vector<Contact::ref> getList() const;
+ Contact::ref getContact(const size_t i);
+ void setMaximumNoOfContactsToOne(bool limited);
+ bool isFull() const;
public slots:
- void updateContacts(const std::vector<Contact::ref>& contactUpdates);
+ void updateContacts(const std::vector<Contact::ref>& contactUpdates);
signals:
- void onListChanged(std::vector<Contact::ref> list);
- void onJIDsAdded(const std::vector<JID>& jids);
+ void onListChanged(std::vector<Contact::ref> list);
+ void onJIDsAdded(const std::vector<JID>& jids);
private:
- void handleSettingsChanged(const std::string&);
+ void handleSettingsChanged(const std::string&);
private:
- SettingsProvider* settings_;
- ContactListModel* contactListModel_;
- ContactListDelegate* contactListDelegate_;
- QtRemovableItemDelegate* removableItemDelegate_;
- bool limited_;
+ SettingsProvider* settings_;
+ ContactListModel* contactListModel_;
+ ContactListDelegate* contactListDelegate_;
+ QtRemovableItemDelegate* removableItemDelegate_;
+ bool limited_;
};
}
diff --git a/Swift/QtUI/UserSearch/QtSuggestingJIDInput.cpp b/Swift/QtUI/UserSearch/QtSuggestingJIDInput.cpp
index 8ed6efb..8c46e38 100644
--- a/Swift/QtUI/UserSearch/QtSuggestingJIDInput.cpp
+++ b/Swift/QtUI/UserSearch/QtSuggestingJIDInput.cpp
@@ -5,205 +5,211 @@
*/
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/UserSearch/QtSuggestingJIDInput.h>
-#include <Swift/QtUI/UserSearch/ContactListDelegate.h>
-#include <Swift/Controllers/Settings/SettingsProvider.h>
-#include <Swift/QtUI/QtUISettingConstants.h>
-#include <Swift/QtUI/UserSearch/ContactListModel.h>
-#include <Swiften/Base/boost_bsignals.h>
#include <boost/bind.hpp>
-
-#include <Swift/QtUI/QtSwiftUtil.h>
+#include <boost/signals2.hpp>
#include <QAbstractItemView>
#include <QApplication>
#include <QDesktopWidget>
#include <QKeyEvent>
+#include <QtGlobal>
+#include <Swift/Controllers/Settings/SettingsProvider.h>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/QtUISettingConstants.h>
+#include <Swift/QtUI/UserSearch/ContactListDelegate.h>
+#include <Swift/QtUI/UserSearch/ContactListModel.h>
namespace Swift {
QtSuggestingJIDInput::QtSuggestingJIDInput(QWidget* parent, SettingsProvider* settings) : QLineEdit(parent), settings_(settings) {
- treeViewPopup_ = new QTreeView();
- treeViewPopup_->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
- //treeViewPopup_->setAttribute(Qt::WA_ShowWithoutActivating);
- treeViewPopup_->setAlternatingRowColors(true);
- treeViewPopup_->setIndentation(0);
- treeViewPopup_->setHeaderHidden(true);
- treeViewPopup_->setExpandsOnDoubleClick(false);
- treeViewPopup_->setItemsExpandable(false);
- treeViewPopup_->setSelectionMode(QAbstractItemView::SingleSelection);
- treeViewPopup_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
- treeViewPopup_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- QSizePolicy policy(treeViewPopup_->sizePolicy());
- policy.setVerticalPolicy(QSizePolicy::Expanding);
- treeViewPopup_->setSizePolicy(policy);
- treeViewPopup_->hide();
- treeViewPopup_->setFocusProxy(this);
- connect(treeViewPopup_, SIGNAL(clicked(QModelIndex)), this, SLOT(handleClicked(QModelIndex)));
- connect(treeViewPopup_, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(handleClicked(QModelIndex)));
-
- contactListModel_ = new ContactListModel(false);
- treeViewPopup_->setModel(contactListModel_);
-
- contactListDelegate_ = new ContactListDelegate(settings->getSetting(QtUISettingConstants::COMPACT_ROSTER));
- treeViewPopup_->setItemDelegate(contactListDelegate_);
-
- settings_->onSettingChanged.connect(boost::bind(&QtSuggestingJIDInput::handleSettingsChanged, this, _1));
+ treeViewPopup_ = new QTreeView();
+ treeViewPopup_->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
+ //treeViewPopup_->setAttribute(Qt::WA_ShowWithoutActivating);
+ treeViewPopup_->setAlternatingRowColors(true);
+ treeViewPopup_->setIndentation(0);
+ treeViewPopup_->setHeaderHidden(true);
+ treeViewPopup_->setExpandsOnDoubleClick(false);
+ treeViewPopup_->setItemsExpandable(false);
+ treeViewPopup_->setSelectionMode(QAbstractItemView::SingleSelection);
+ treeViewPopup_->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
+ treeViewPopup_->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+ QSizePolicy policy(treeViewPopup_->sizePolicy());
+ policy.setVerticalPolicy(QSizePolicy::Expanding);
+ treeViewPopup_->setSizePolicy(policy);
+ treeViewPopup_->hide();
+ treeViewPopup_->setFocusProxy(this);
+ connect(treeViewPopup_, SIGNAL(clicked(QModelIndex)), this, SLOT(handleClicked(QModelIndex)));
+ connect(treeViewPopup_, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(handleClicked(QModelIndex)));
+
+ contactListModel_ = new ContactListModel(false);
+ treeViewPopup_->setModel(contactListModel_);
+
+ contactListDelegate_ = new ContactListDelegate(settings->getSetting(QtUISettingConstants::COMPACT_ROSTER));
+ treeViewPopup_->setItemDelegate(contactListDelegate_);
+
+ settings_->onSettingChanged.connect(boost::bind(&QtSuggestingJIDInput::handleSettingsChanged, this, _1));
}
QtSuggestingJIDInput::~QtSuggestingJIDInput() {
- settings_->onSettingChanged.disconnect(boost::bind(&QtSuggestingJIDInput::handleSettingsChanged, this, _1));
- delete treeViewPopup_;
- delete contactListDelegate_;
- delete contactListModel_;
+ settings_->onSettingChanged.disconnect(boost::bind(&QtSuggestingJIDInput::handleSettingsChanged, this, _1));
+ delete treeViewPopup_;
+ delete contactListDelegate_;
+ delete contactListModel_;
}
Contact::ref QtSuggestingJIDInput::getContact() {
- if (!!currentContact_) {
- return currentContact_;
- }
-
- if (!text().isEmpty()) {
- JID jid(Q2PSTRING(text()));
- if (jid.isValid()) {
- Contact::ref manualContact = boost::make_shared<Contact>();
- manualContact->name = jid.toString();
- manualContact->jid = jid;
- return manualContact;
- }
- }
- return boost::shared_ptr<Contact>();
+ if (!!currentContact_) {
+ return currentContact_;
+ }
+
+ if (!text().isEmpty()) {
+ JID jid(Q2PSTRING(text()));
+ if (jid.isValid()) {
+ Contact::ref manualContact = std::make_shared<Contact>();
+ manualContact->name = jid.toString();
+ manualContact->jid = jid;
+ return manualContact;
+ }
+ }
+ return std::shared_ptr<Contact>();
}
void QtSuggestingJIDInput::setSuggestions(const std::vector<Contact::ref>& suggestions) {
- contactListModel_->setList(suggestions);
- positionPopup();
- if (!suggestions.empty()) {
- treeViewPopup_->setCurrentIndex(contactListModel_->index(0, 0));
- showPopup();
- } else {
- currentContact_.reset();
- hidePopup();
- }
+ contactListModel_->setList(suggestions);
+ positionPopup();
+ if (!suggestions.empty()) {
+ treeViewPopup_->setCurrentIndex(contactListModel_->index(0, 0));
+ showPopup();
+ } else {
+ currentContact_.reset();
+ hidePopup();
+ }
}
void QtSuggestingJIDInput::clear() {
- setText("");
- currentContact_.reset();
+ setText("");
+ currentContact_.reset();
}
void QtSuggestingJIDInput::keyPressEvent(QKeyEvent* event) {
- if (event->key() == Qt::Key_Up) {
- if (contactListModel_->rowCount() > 0) {
- int row = treeViewPopup_->currentIndex().row();
- row = (row + contactListModel_->rowCount() - 1) % contactListModel_->rowCount();
- treeViewPopup_->setCurrentIndex(contactListModel_->index(row, 0));
- }
- } else if (event->key() == Qt::Key_Down) {
- if (contactListModel_->rowCount() > 0) {
- int row = treeViewPopup_->currentIndex().row();
- row = (row + contactListModel_->rowCount() + 1) % contactListModel_->rowCount();
- treeViewPopup_->setCurrentIndex(contactListModel_->index(row, 0));
- }
- } else if (event->key() == Qt::Key_Return && treeViewPopup_->isVisible()) {
- QModelIndex index = treeViewPopup_->currentIndex();
- if (!contactListModel_->getList().empty() && index.isValid()) {
- currentContact_ = contactListModel_->getContact(index.row());
- if (currentContact_->jid.isValid()) {
- setText(P2QSTRING(currentContact_->jid.toString()));
- } else {
- setText(P2QSTRING(currentContact_->name));
- }
- hidePopup();
- clearFocus();
- } else {
- currentContact_.reset();
- }
- editingDone();
- } else {
- QLineEdit::keyPressEvent(event);
- }
+ if (event->key() == Qt::Key_Up) {
+ if (contactListModel_->rowCount() > 0) {
+ int row = treeViewPopup_->currentIndex().row();
+ row = (row + contactListModel_->rowCount() - 1) % contactListModel_->rowCount();
+ treeViewPopup_->setCurrentIndex(contactListModel_->index(row, 0));
+ }
+ } else if (event->key() == Qt::Key_Down) {
+ if (contactListModel_->rowCount() > 0) {
+ int row = treeViewPopup_->currentIndex().row();
+ row = (row + contactListModel_->rowCount() + 1) % contactListModel_->rowCount();
+ treeViewPopup_->setCurrentIndex(contactListModel_->index(row, 0));
+ }
+ } else if (event->key() == Qt::Key_Return && treeViewPopup_->isVisible()) {
+ QModelIndex index = treeViewPopup_->currentIndex();
+ if (!contactListModel_->getList().empty() && index.isValid()) {
+ currentContact_ = contactListModel_->getContact(index.row());
+ if (currentContact_->jid.isValid()) {
+ setText(P2QSTRING(currentContact_->jid.toString()));
+ } else {
+ setText(P2QSTRING(currentContact_->name));
+ }
+ hidePopup();
+ clearFocus();
+ } else {
+ currentContact_.reset();
+ }
+ editingDone();
+ } else {
+ QLineEdit::keyPressEvent(event);
+ }
}
void QtSuggestingJIDInput::hideEvent(QHideEvent* /* event */) {
- // Hide our popup when we are hidden (can happen when a dialog is closed by the user).
- treeViewPopup_->hide();
+ // Hide our popup when we are hidden (can happen when a dialog is closed by the user).
+ treeViewPopup_->hide();
}
void QtSuggestingJIDInput::handleApplicationFocusChanged(QWidget* /*old*/, QWidget* /*now*/) {
- /* Using the now argument gives use the wrong widget. This is part of the code needed
- to prevent stealing of focus when opening a the suggestion window. */
- QWidget* now = qApp->focusWidget();
- if (!now || (now != treeViewPopup_ && now != this && !now->isAncestorOf(this) && !now->isAncestorOf(treeViewPopup_) && !this->isAncestorOf(now) && !treeViewPopup_->isAncestorOf(now))) {
- hidePopup();
- }
+ /* Using the now argument gives use the wrong widget. This is part of the code needed
+ to prevent stealing of focus when opening a the suggestion window. */
+ QWidget* now = qApp->focusWidget();
+ if (!now || (now != treeViewPopup_ && now != this && !now->isAncestorOf(this) && !now->isAncestorOf(treeViewPopup_) && !this->isAncestorOf(now) && !treeViewPopup_->isAncestorOf(now))) {
+ hidePopup();
+ }
}
void QtSuggestingJIDInput::handleSettingsChanged(const std::string& setting) {
- if (setting == QtUISettingConstants::COMPACT_ROSTER.getKey()) {
- contactListDelegate_->setCompact(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
- }
+ if (setting == QtUISettingConstants::COMPACT_ROSTER.getKey()) {
+ contactListDelegate_->setCompact(settings_->getSetting(QtUISettingConstants::COMPACT_ROSTER));
+ }
}
void QtSuggestingJIDInput::handleClicked(const QModelIndex& index) {
- if (index.isValid()) {
- currentContact_ = contactListModel_->getContact(index.row());
- onUserSelected(currentContact_);
- hidePopup();
- }
+ if (index.isValid()) {
+ currentContact_ = contactListModel_->getContact(index.row());
+ onUserSelected(currentContact_);
+ hidePopup();
+ }
}
void QtSuggestingJIDInput::positionPopup() {
- QDesktopWidget* desktop = QApplication::desktop();
- int screen = desktop->screenNumber(this);
- QPoint point = mapToGlobal(QPoint(0, height()));
- QRect geometry = desktop->availableGeometry(screen);
- int x = point.x();
- int y = point.y();
- int width = this->width();
- int height = 80;
-
- int screenWidth = geometry.x() + geometry.width();
- if (x + width > screenWidth) {
- x = screenWidth - width;
- }
-
- height = treeViewPopup_->sizeHintForRow(0) * contactListModel_->rowCount();
- height = height > 200 ? 200 : height;
-
- int marginLeft;
- int marginTop;
- int marginRight;
- int marginBottom;
- treeViewPopup_->getContentsMargins(&marginLeft, &marginTop, &marginRight, &marginBottom);
- height += marginTop + marginBottom;
- width += marginLeft + marginRight;
-
- treeViewPopup_->setGeometry(x, y, width, height);
- treeViewPopup_->move(x, y);
- treeViewPopup_->setMaximumWidth(width);
+ QDesktopWidget* desktop = QApplication::desktop();
+ int screen = desktop->screenNumber(this);
+ QPoint point = mapToGlobal(QPoint(0, height()));
+ QRect geometry = desktop->availableGeometry(screen);
+ int x = point.x();
+ int y = point.y();
+ int width = this->width();
+ int height = 80;
+
+ int screenWidth = geometry.x() + geometry.width();
+ if (x + width > screenWidth) {
+ x = screenWidth - width;
+ }
+
+ height = treeViewPopup_->sizeHintForRow(0) * contactListModel_->rowCount();
+ height = height > 200 ? 200 : height;
+
+ int marginLeft;
+ int marginTop;
+ int marginRight;
+ int marginBottom;
+ treeViewPopup_->getContentsMargins(&marginLeft, &marginTop, &marginRight, &marginBottom);
+ height += marginTop + marginBottom;
+ width += marginLeft + marginRight;
+
+ treeViewPopup_->setGeometry(x, y, width, height);
+ treeViewPopup_->move(x, y);
+ treeViewPopup_->setMaximumWidth(width);
}
void QtSuggestingJIDInput::showPopup() {
- treeViewPopup_->show();
- activateWindow();
- connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(handleApplicationFocusChanged(QWidget*, QWidget*)), Qt::QueuedConnection);
- setFocus();
+ treeViewPopup_->show();
+ activateWindow();
+ connect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(handleApplicationFocusChanged(QWidget*, QWidget*)), Qt::QueuedConnection);
+ setFocus();
}
void QtSuggestingJIDInput::hidePopup() {
- disconnect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(handleApplicationFocusChanged(QWidget*, QWidget*)));
- treeViewPopup_->hide();
-
- // Give focus back to input widget because the hide() call passes the focus to the wrong widget.
- setFocus();
+ disconnect(qApp, SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(handleApplicationFocusChanged(QWidget*, QWidget*)));
+ treeViewPopup_->hide();
+
+ // Give focus back to input widget because the hide() call passes the focus to the wrong widget.
+ setFocus();
+#if defined(Q_WS_MAC)
+ // This workaround is needed on OS X, to bring the dialog containing this widget back to the front after
+ // the popup is hidden. Ubuntu 16.04 and Windows 8 do not have this issue.
+ window()->raise();
+#endif
}
}
diff --git a/Swift/QtUI/UserSearch/QtSuggestingJIDInput.h b/Swift/QtUI/UserSearch/QtSuggestingJIDInput.h
index d5ec45d..402667d 100644
--- a/Swift/QtUI/UserSearch/QtSuggestingJIDInput.h
+++ b/Swift/QtUI/UserSearch/QtSuggestingJIDInput.h
@@ -5,16 +5,18 @@
*/
/*
- * Copyright (c) 2014-2015 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
+#include <boost/signals2.hpp>
+
#include <QLineEdit>
#include <QTreeView>
-#include <Swiften/Base/boost_bsignals.h>
+
#include <Swift/Controllers/Contact.h>
namespace Swift {
@@ -24,44 +26,44 @@ class SettingsProvider;
class ContactListModel;
class QtSuggestingJIDInput : public QLineEdit {
- Q_OBJECT
- public:
- QtSuggestingJIDInput(QWidget* parent, SettingsProvider* settings);
- virtual ~QtSuggestingJIDInput();
+ Q_OBJECT
+ public:
+ QtSuggestingJIDInput(QWidget* parent, SettingsProvider* settings);
+ virtual ~QtSuggestingJIDInput();
- Contact::ref getContact();
+ Contact::ref getContact();
- void setSuggestions(const std::vector<Contact::ref>& suggestions);
+ void setSuggestions(const std::vector<Contact::ref>& suggestions);
- void clear();
+ void clear();
- boost::signal<void (const Contact::ref&)> onUserSelected;
+ boost::signals2::signal<void (const Contact::ref&)> onUserSelected;
- signals:
- void editingDone();
+ signals:
+ void editingDone();
- protected:
- virtual void keyPressEvent(QKeyEvent* event);
- virtual void hideEvent(QHideEvent* event);
+ protected:
+ virtual void keyPressEvent(QKeyEvent* event);
+ virtual void hideEvent(QHideEvent* event);
- private:
- void handleSettingsChanged(const std::string& setting);
+ private:
+ void handleSettingsChanged(const std::string& setting);
- private slots:
- void handleClicked(const QModelIndex& index);
- void handleApplicationFocusChanged(QWidget* old, QWidget* now);
+ private slots:
+ void handleClicked(const QModelIndex& index);
+ void handleApplicationFocusChanged(QWidget* old, QWidget* now);
- private:
- void positionPopup();
- void showPopup();
- void hidePopup();
+ private:
+ void positionPopup();
+ void showPopup();
+ void hidePopup();
- private:
- SettingsProvider* settings_;
- ContactListModel* contactListModel_;
- QTreeView* treeViewPopup_;
- ContactListDelegate* contactListDelegate_;
- Contact::ref currentContact_;
+ private:
+ SettingsProvider* settings_;
+ ContactListModel* contactListModel_;
+ QTreeView* treeViewPopup_;
+ ContactListDelegate* contactListDelegate_;
+ Contact::ref currentContact_;
};
}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchDetailsPage.cpp b/Swift/QtUI/UserSearch/QtUserSearchDetailsPage.cpp
index a6c1e24..96b6031 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchDetailsPage.cpp
+++ b/Swift/QtUI/UserSearch/QtUserSearchDetailsPage.cpp
@@ -1,17 +1,17 @@
/*
- * Copyright (c) 2011-2014 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/QtUI/UserSearch/QtUserSearchDetailsPage.h"
-
-#include <QVBoxLayout>
-#include <QLabel>
+#include <Swift/QtUI/UserSearch/QtUserSearchDetailsPage.h>
#include <boost/bind.hpp>
+#include <boost/signals2.hpp>
+
+#include <QLabel>
+#include <QVBoxLayout>
-#include <Swiften/Base/boost_bsignals.h>
#include <Swiften/JID/JID.h>
#include <Swift/QtUI/QtContactEditWidget.h>
@@ -19,10 +19,10 @@
namespace Swift {
QtUserSearchDetailsPage::QtUserSearchDetailsPage(const std::set<std::string>& groups) {
- QVBoxLayout* layout = new QVBoxLayout(this);
- layout->addWidget(new QLabel(tr("Please choose a name for the contact, and select the groups you want to add the contact to.")));
- editWidget = new QtContactEditWidget(groups, this);
- layout->addWidget(editWidget);
+ QVBoxLayout* layout = new QVBoxLayout(this);
+ layout->addWidget(new QLabel(tr("Please choose a name for the contact, and select the groups you want to add the contact to.")));
+ editWidget = new QtContactEditWidget(groups, this);
+ layout->addWidget(editWidget);
}
QtUserSearchDetailsPage::~QtUserSearchDetailsPage() {
@@ -30,27 +30,27 @@ QtUserSearchDetailsPage::~QtUserSearchDetailsPage() {
}
void QtUserSearchDetailsPage::setJID(const JID& jid) {
- contactJID = jid;
+ contactJID = jid;
}
void QtUserSearchDetailsPage::setNameSuggestions(const std::vector<std::string>& nameSuggestions) {
- editWidget->setNameSuggestions(nameSuggestions);
+ editWidget->setNameSuggestions(nameSuggestions);
}
void QtUserSearchDetailsPage::setName(const std::string& name) {
- editWidget->setName(name);
+ editWidget->setName(name);
}
std::set<std::string> QtUserSearchDetailsPage::getSelectedGroups() {
- return editWidget->getSelectedGroups();
+ return editWidget->getSelectedGroups();
}
std::string QtUserSearchDetailsPage::getName() {
- return editWidget->getName();
+ return editWidget->getName();
}
void QtUserSearchDetailsPage::clear() {
- editWidget->clear();
+ editWidget->clear();
}
}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchDetailsPage.h b/Swift/QtUI/UserSearch/QtUserSearchDetailsPage.h
index eefa630..7185bce 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchDetailsPage.h
+++ b/Swift/QtUI/UserSearch/QtUserSearchDetailsPage.h
@@ -1,44 +1,45 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <QWizardPage>
-
#include <set>
#include <string>
#include <vector>
+#include <QWizardPage>
+
#include <Swiften/Elements/VCard.h>
#include <Swiften/JID/JID.h>
+
#include <Swift/QtUI/UserSearch/ui_QtUserSearchFieldsPage.h>
namespace Swift {
- class QtContactEditWidget;
+ class QtContactEditWidget;
- class QtUserSearchDetailsPage : public QWizardPage {
- Q_OBJECT
- public:
- QtUserSearchDetailsPage(const std::set<std::string>& availableGroups);
- virtual ~QtUserSearchDetailsPage();
+ class QtUserSearchDetailsPage : public QWizardPage {
+ Q_OBJECT
+ public:
+ QtUserSearchDetailsPage(const std::set<std::string>& availableGroups);
+ virtual ~QtUserSearchDetailsPage();
- void setJID(const JID& jid);
- void setNameSuggestions(const std::vector<std::string>& nameSuggestions);
- void setName(const std::string& name);
+ void setJID(const JID& jid);
+ void setNameSuggestions(const std::vector<std::string>& nameSuggestions);
+ void setName(const std::string& name);
- std::set<std::string> getSelectedGroups();
- std::string getName();
+ std::set<std::string> getSelectedGroups();
+ std::string getName();
- void clear();
+ void clear();
- signals:
- void onUserTriggersFinish();
+ signals:
+ void onUserTriggersFinish();
- private:
- QtContactEditWidget* editWidget;
- JID contactJID;
- };
+ private:
+ QtContactEditWidget* editWidget;
+ JID contactJID;
+ };
}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchFieldsPage.cpp b/Swift/QtUI/UserSearch/QtUserSearchFieldsPage.cpp
index 13b61a7..3a6028d 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchFieldsPage.cpp
+++ b/Swift/QtUI/UserSearch/QtUserSearchFieldsPage.cpp
@@ -1,42 +1,42 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/QtUI/UserSearch/QtUserSearchFieldsPage.h"
+#include <Swift/QtUI/UserSearch/QtUserSearchFieldsPage.h>
namespace Swift {
-QtUserSearchFieldsPage::QtUserSearchFieldsPage() : formWidget_(0) {
- setupUi(this);
+QtUserSearchFieldsPage::QtUserSearchFieldsPage() : formWidget_(nullptr) {
+ setupUi(this);
}
bool QtUserSearchFieldsPage::isComplete() const {
- if (formWidget_) {
- return formWidget_->isEnabled();
- } else {
- return nickInput_->isEnabled() || firstInput_->isEnabled() || lastInput_->isEnabled() || emailInput_->isEnabled();
- }
+ if (formWidget_) {
+ return formWidget_->isEnabled();
+ } else {
+ return nickInput_->isEnabled() || firstInput_->isEnabled() || lastInput_->isEnabled() || emailInput_->isEnabled();
+ }
}
QtFormWidget* QtUserSearchFieldsPage::getFormWidget() {
- return formWidget_;
+ return formWidget_;
}
void QtUserSearchFieldsPage::setFormWidget(QtFormWidget *widget) {
- if (formWidget_) {
- delete formWidget_;
- formWidget_ = NULL;
- }
- if (widget) {
- formContainer_->layout()->addWidget(widget);
- }
- formWidget_ = widget;
+ if (formWidget_) {
+ delete formWidget_;
+ formWidget_ = nullptr;
+ }
+ if (widget) {
+ formContainer_->layout()->addWidget(widget);
+ }
+ formWidget_ = widget;
}
void QtUserSearchFieldsPage::emitCompletenessCheck() {
- emit completeChanged();
+ emit completeChanged();
}
}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchFieldsPage.h b/Swift/QtUI/UserSearch/QtUserSearchFieldsPage.h
index 70618f9..4089d05 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchFieldsPage.h
+++ b/Swift/QtUI/UserSearch/QtUserSearchFieldsPage.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -9,23 +9,22 @@
#include <QWizardPage>
#include <Swift/QtUI/QtFormWidget.h>
-
#include <Swift/QtUI/UserSearch/ui_QtUserSearchFieldsPage.h>
namespace Swift {
- class QtUserSearchFieldsPage : public QWizardPage, public Ui::QtUserSearchFieldsPage {
- Q_OBJECT
- public:
- QtUserSearchFieldsPage();
- virtual bool isComplete() const;
+ class QtUserSearchFieldsPage : public QWizardPage, public Ui::QtUserSearchFieldsPage {
+ Q_OBJECT
+ public:
+ QtUserSearchFieldsPage();
+ virtual bool isComplete() const;
- QtFormWidget* getFormWidget();
- void setFormWidget(QtFormWidget *widget);
+ QtFormWidget* getFormWidget();
+ void setFormWidget(QtFormWidget *widget);
- public slots:
- void emitCompletenessCheck();
+ public slots:
+ void emitCompletenessCheck();
- private:
- QtFormWidget *formWidget_;
- };
+ private:
+ QtFormWidget *formWidget_;
+ };
}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp b/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp
index 9abdcf0..1327a8f 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp
+++ b/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.cpp
@@ -5,97 +5,98 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.h"
+#include <Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.h>
#include <QMessageBox>
#include <QMimeData>
#include <QUrl>
-#include "Swift/QtUI/QtSwiftUtil.h"
#include <Swift/Controllers/Settings/SettingsProvider.h>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swift/QtUI/UserSearch/QtContactListWidget.h>
#include <Swift/QtUI/UserSearch/QtSuggestingJIDInput.h>
namespace Swift {
QtUserSearchFirstMultiJIDPage::QtUserSearchFirstMultiJIDPage(UserSearchWindow::Type type, const QString& title, SettingsProvider* settings) {
- setupUi(this);
- setTitle(title);
- QString introText = "";
- switch (type) {
- case UserSearchWindow::AddContact:
- introText = tr("Add another user to your contact list");
- break;
- case UserSearchWindow::ChatToContact:
- introText = tr("Chat to another user");
- break;
- case UserSearchWindow::InviteToChat:
- introText = tr("Invite contact to chat");
- break;
- }
-
- setSubTitle(QString(tr("%1. If you know their address you can enter it directly, or you can search for them.")).arg(introText));
-
- contactList_ = new QtContactListWidget(this, settings);
- horizontalLayout_5->addWidget(contactList_);
-
- jid_ = new QtSuggestingJIDInput(this, settings);
- horizontalLayout_6->insertWidget(0, jid_);
-
- connect(contactList_, SIGNAL(onListChanged(std::vector<Contact::ref>)), this, SLOT(emitCompletenessCheck()));
- connect(jid_, SIGNAL(editingDone()), this, SLOT(handleEditingDone()));
-
- setAcceptDrops(true);
+ setupUi(this);
+ setTitle(title);
+ QString introText = "";
+ switch (type) {
+ case UserSearchWindow::AddContact:
+ introText = tr("Add another user to your contact list");
+ break;
+ case UserSearchWindow::ChatToContact:
+ introText = tr("Chat to another user");
+ break;
+ case UserSearchWindow::InviteToChat:
+ introText = tr("Invite contact to chat");
+ break;
+ }
+
+ setSubTitle(QString(tr("%1. If you know their address you can enter it directly, or you can search for them.")).arg(introText));
+
+ contactList_ = new QtContactListWidget(this, settings);
+ horizontalLayout_5->addWidget(contactList_);
+
+ jid_ = new QtSuggestingJIDInput(this, settings);
+ horizontalLayout_6->insertWidget(0, jid_);
+
+ connect(contactList_, SIGNAL(onListChanged(std::vector<Contact::ref>)), this, SLOT(emitCompletenessCheck()));
+ connect(jid_, SIGNAL(editingDone()), this, SLOT(handleEditingDone()));
+
+ setAcceptDrops(true);
}
bool QtUserSearchFirstMultiJIDPage::isComplete() const {
- return !contactList_->getList().empty();
+ return !contactList_->getList().empty();
}
void QtUserSearchFirstMultiJIDPage::reset() {
- jid_->clear();
- reason_->clear();
+ jid_->clear();
+ reason_->clear();
}
void QtUserSearchFirstMultiJIDPage::emitCompletenessCheck() {
- emit completeChanged();
+ emit completeChanged();
}
void QtUserSearchFirstMultiJIDPage::handleEditingDone() {
- addContactButton_->setFocus();
+ addContactButton_->setFocus();
}
void QtUserSearchFirstMultiJIDPage::dragEnterEvent(QDragEnterEvent *event) {
- if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")
- || event->mimeData()->hasFormat("application/vnd.swift.contact-jid-muc")) {
- if (!contactList_->isFull()) {
- event->acceptProposedAction();
- }
- }
+ if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")
+ || event->mimeData()->hasFormat("application/vnd.swift.contact-jid-muc")) {
+ if (!contactList_->isFull()) {
+ event->acceptProposedAction();
+ }
+ }
}
void QtUserSearchFirstMultiJIDPage::dropEvent(QDropEvent *event) {
- if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")) {
- QByteArray dataBytes = event->mimeData()->data("application/vnd.swift.contact-jid-list");
- QDataStream dataStream(&dataBytes, QIODevice::ReadOnly);
- std::vector<JID> jids;
- while (!dataStream.atEnd()) {
- QString jidString;
- dataStream >> jidString;
- jids.push_back(Q2PSTRING(jidString));
- }
- onJIDsDropped(jids);
- } else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-muc")) {
- QMessageBox* messageBox = new QMessageBox(this);
- messageBox->setText(tr("You can't invite a room to chat."));
- messageBox->setWindowTitle(tr("Error inviting room to chat"));
- messageBox->show();
- }
+ if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-list")) {
+ QByteArray dataBytes = event->mimeData()->data("application/vnd.swift.contact-jid-list");
+ QDataStream dataStream(&dataBytes, QIODevice::ReadOnly);
+ std::vector<JID> jids;
+ while (!dataStream.atEnd()) {
+ QString jidString;
+ dataStream >> jidString;
+ jids.push_back(Q2PSTRING(jidString));
+ }
+ onJIDsDropped(jids);
+ } else if (event->mimeData()->hasFormat("application/vnd.swift.contact-jid-muc")) {
+ QMessageBox* messageBox = new QMessageBox(this);
+ messageBox->setText(tr("You can't invite a room to chat."));
+ messageBox->setWindowTitle(tr("Error inviting room to chat"));
+ messageBox->show();
+ }
}
}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.h b/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.h
index 8cc6616..d9147db 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.h
+++ b/Swift/QtUI/UserSearch/QtUserSearchFirstMultiJIDPage.h
@@ -5,7 +5,7 @@
*/
/*
- * Copyright (c) 2014 Isode Limited.
+ * Copyright (c) 2014-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -14,39 +14,40 @@
#include <QWizardPage>
-#include <Swift/QtUI/UserSearch/ui_QtUserSearchFirstMultiJIDPage.h>
#include <Swift/Controllers/UIInterfaces/UserSearchWindow.h>
+#include <Swift/QtUI/UserSearch/ui_QtUserSearchFirstMultiJIDPage.h>
+
namespace Swift {
- class UserSearchModel;
- class UserSearchDelegate;
- class UserSearchResult;
- class UIEventStream;
- class QtContactListWidget;
- class ContactSuggester;
- class AvatarManager;
- class VCardManager;
- class SettingsProvider;
- class QtSuggestingJIDInput;
-
- class QtUserSearchFirstMultiJIDPage : public QWizardPage, public Ui::QtUserSearchFirstMultiJIDPage {
- Q_OBJECT
- public:
- QtUserSearchFirstMultiJIDPage(UserSearchWindow::Type type, const QString& title, SettingsProvider* settings);
- virtual bool isComplete() const;
- void reset();
-
- signals:
- void onJIDsDropped(std::vector<JID> jid);
-
- public slots:
- void emitCompletenessCheck();
- void handleEditingDone();
- virtual void dragEnterEvent(QDragEnterEvent *event);
- virtual void dropEvent(QDropEvent *event);
-
- public:
- QtContactListWidget* contactList_;
- QtSuggestingJIDInput* jid_;
- };
+ class UserSearchModel;
+ class UserSearchDelegate;
+ class UserSearchResult;
+ class UIEventStream;
+ class QtContactListWidget;
+ class ContactSuggester;
+ class AvatarManager;
+ class VCardManager;
+ class SettingsProvider;
+ class QtSuggestingJIDInput;
+
+ class QtUserSearchFirstMultiJIDPage : public QWizardPage, public Ui::QtUserSearchFirstMultiJIDPage {
+ Q_OBJECT
+ public:
+ QtUserSearchFirstMultiJIDPage(UserSearchWindow::Type type, const QString& title, SettingsProvider* settings);
+ virtual bool isComplete() const;
+ void reset();
+
+ signals:
+ void onJIDsDropped(std::vector<JID> jid);
+
+ public slots:
+ void emitCompletenessCheck();
+ void handleEditingDone();
+ virtual void dragEnterEvent(QDragEnterEvent *event);
+ virtual void dropEvent(QDropEvent *event);
+
+ public:
+ QtContactListWidget* contactList_;
+ QtSuggestingJIDInput* jid_;
+ };
}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchFirstPage.cpp b/Swift/QtUI/UserSearch/QtUserSearchFirstPage.cpp
index 6e8744f..5d0c9fa 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchFirstPage.cpp
+++ b/Swift/QtUI/UserSearch/QtUserSearchFirstPage.cpp
@@ -1,49 +1,49 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/QtUI/UserSearch/QtUserSearchFirstPage.h"
-
-#include "Swift/QtUI/QtSwiftUtil.h"
+#include <Swift/QtUI/UserSearch/QtUserSearchFirstPage.h>
#include <Swiften/Base/Log.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
+
namespace Swift {
QtUserSearchFirstPage::QtUserSearchFirstPage(UserSearchWindow::Type type, const QString& title, SettingsProvider* settings) {
- setupUi(this);
- setTitle(title);
- setSubTitle(QString(tr("%1. If you know their address you can enter it directly, or you can search for them.")).arg(type == UserSearchWindow::AddContact ? tr("Add another user to your contact list") : tr("Chat to another user")));
- jid_ = new QtSuggestingJIDInput(this, settings);
- horizontalLayout_2->addWidget(jid_);
- jidWarning_ = new QLabel(this);
- jidWarning_->setPixmap(QPixmap(":icons/warn.png"));
- jidWarning_->hide();
- horizontalLayout_2->addWidget(jidWarning_);
- setTabOrder(byJID_, jid_);
- setTabOrder(jid_, byLocalSearch_);
- setTabOrder(byLocalSearch_, byRemoteSearch_);
- connect(jid_, SIGNAL(textChanged(const QString&)), this, SLOT(emitCompletenessCheck()));
- connect(jid_, SIGNAL(editingDone()), this, SLOT(emitCompletenessCheck()));
- connect(service_->lineEdit(), SIGNAL(textChanged(const QString&)), this, SLOT(emitCompletenessCheck()));
+ setupUi(this);
+ setTitle(title);
+ setSubTitle(QString(tr("%1. If you know their address you can enter it directly, or you can search for them.")).arg(type == UserSearchWindow::AddContact ? tr("Add another user to your contact list") : tr("Chat to another user")));
+ jid_ = new QtSuggestingJIDInput(this, settings);
+ horizontalLayout_2->addWidget(jid_);
+ jidWarning_ = new QLabel(this);
+ jidWarning_->setPixmap(QPixmap(":icons/warn.png"));
+ jidWarning_->hide();
+ horizontalLayout_2->addWidget(jidWarning_);
+ setTabOrder(byJID_, jid_);
+ setTabOrder(jid_, byLocalSearch_);
+ setTabOrder(byLocalSearch_, byRemoteSearch_);
+ connect(jid_, SIGNAL(textChanged(const QString&)), this, SLOT(emitCompletenessCheck()));
+ connect(jid_, SIGNAL(editingDone()), this, SLOT(emitCompletenessCheck()));
+ connect(service_->lineEdit(), SIGNAL(textChanged(const QString&)), this, SLOT(emitCompletenessCheck()));
}
bool QtUserSearchFirstPage::isComplete() const {
- bool complete = false;
- if (byJID_->isChecked()) {
- complete = JID(Q2PSTRING(jid_->text().trimmed())).isValid() && jidWarning_->toolTip().isEmpty();
- } else if (byLocalSearch_->isChecked()) {
- complete = true;
- } else if (byRemoteSearch_->isChecked()) {
- complete = JID(Q2PSTRING(service_->currentText().trimmed())).isValid();
- }
- return complete;
+ bool complete = false;
+ if (byJID_->isChecked()) {
+ complete = JID(Q2PSTRING(jid_->text().trimmed())).isValid() && jidWarning_->toolTip().isEmpty();
+ } else if (byLocalSearch_->isChecked()) {
+ complete = true;
+ } else if (byRemoteSearch_->isChecked()) {
+ complete = JID(Q2PSTRING(service_->currentText().trimmed())).isValid();
+ }
+ return complete;
}
void QtUserSearchFirstPage::emitCompletenessCheck() {
- emit completeChanged();
+ emit completeChanged();
}
}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchFirstPage.h b/Swift/QtUI/UserSearch/QtUserSearchFirstPage.h
index 4bc3923..2e73e9e 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchFirstPage.h
+++ b/Swift/QtUI/UserSearch/QtUserSearchFirstPage.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -8,26 +8,26 @@
#include <QWizardPage>
-#include <Swift/QtUI/UserSearch/ui_QtUserSearchFirstPage.h>
#include <Swift/Controllers/UIInterfaces/UserSearchWindow.h>
#include <Swift/QtUI/UserSearch/QtSuggestingJIDInput.h>
+#include <Swift/QtUI/UserSearch/ui_QtUserSearchFirstPage.h>
namespace Swift {
- class UserSearchModel;
- class UserSearchDelegate;
- class UserSearchResult;
- class UIEventStream;
+ class UserSearchModel;
+ class UserSearchDelegate;
+ class UserSearchResult;
+ class UIEventStream;
- class QtUserSearchFirstPage : public QWizardPage, public Ui::QtUserSearchFirstPage {
- Q_OBJECT
- public:
- QtUserSearchFirstPage(UserSearchWindow::Type type, const QString& title, SettingsProvider* settings);
- virtual bool isComplete() const;
- public slots:
- void emitCompletenessCheck();
- public:
- QtSuggestingJIDInput* jid_;
- QLabel* jidWarning_;
- };
+ class QtUserSearchFirstPage : public QWizardPage, public Ui::QtUserSearchFirstPage {
+ Q_OBJECT
+ public:
+ QtUserSearchFirstPage(UserSearchWindow::Type type, const QString& title, SettingsProvider* settings);
+ virtual bool isComplete() const;
+ public slots:
+ void emitCompletenessCheck();
+ public:
+ QtSuggestingJIDInput* jid_;
+ QLabel* jidWarning_;
+ };
}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchResultsPage.cpp b/Swift/QtUI/UserSearch/QtUserSearchResultsPage.cpp
index 39ef3e7..c8a9ad8 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchResultsPage.cpp
+++ b/Swift/QtUI/UserSearch/QtUserSearchResultsPage.cpp
@@ -1,39 +1,39 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/QtUI/UserSearch/QtUserSearchResultsPage.h"
+#include <Swift/QtUI/UserSearch/QtUserSearchResultsPage.h>
namespace Swift {
QtUserSearchResultsPage::QtUserSearchResultsPage() {
- setupUi(this);
- connect(results_, SIGNAL(activated(const QModelIndex&)), this, SLOT(emitCompletenessCheck()));
- connect(results_, SIGNAL(activated(const QModelIndex&)), this, SIGNAL(onUserTriggersContinue()));
- connect(results_, SIGNAL(clicked(const QModelIndex&)), this, SLOT(emitCompletenessCheck()));
- connect(results_, SIGNAL(entered(const QModelIndex&)), this, SLOT(emitCompletenessCheck()));
- results_->setExpandsOnDoubleClick(false);
- setNoResults(false);
+ setupUi(this);
+ connect(results_, SIGNAL(activated(const QModelIndex&)), this, SLOT(emitCompletenessCheck()));
+ connect(results_, SIGNAL(activated(const QModelIndex&)), this, SIGNAL(onUserTriggersContinue()));
+ connect(results_, SIGNAL(clicked(const QModelIndex&)), this, SLOT(emitCompletenessCheck()));
+ connect(results_, SIGNAL(entered(const QModelIndex&)), this, SLOT(emitCompletenessCheck()));
+ results_->setExpandsOnDoubleClick(false);
+ setNoResults(false);
}
bool QtUserSearchResultsPage::isComplete() const {
- return results_->currentIndex().isValid();
+ return results_->currentIndex().isValid();
}
void QtUserSearchResultsPage::setNoResults(bool noResults) {
- if (noResults) {
- results_->setEnabled(false);
- noResults_->show();
- } else {
- results_->setEnabled(true);
- noResults_->hide();
- }
+ if (noResults) {
+ results_->setEnabled(false);
+ noResults_->show();
+ } else {
+ results_->setEnabled(true);
+ noResults_->hide();
+ }
}
void QtUserSearchResultsPage::emitCompletenessCheck() {
- emit completeChanged();
+ emit completeChanged();
}
}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchResultsPage.h b/Swift/QtUI/UserSearch/QtUserSearchResultsPage.h
index 60be555..33227e6 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchResultsPage.h
+++ b/Swift/QtUI/UserSearch/QtUserSearchResultsPage.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -11,15 +11,15 @@
#include <Swift/QtUI/UserSearch/ui_QtUserSearchResultsPage.h>
namespace Swift {
- class QtUserSearchResultsPage : public QWizardPage, public Ui::QtUserSearchResultsPage {
- Q_OBJECT
- public:
- QtUserSearchResultsPage();
- virtual bool isComplete() const;
- void setNoResults(bool noResults);
- signals:
- void onUserTriggersContinue();
- public slots:
- void emitCompletenessCheck();
- };
+ class QtUserSearchResultsPage : public QWizardPage, public Ui::QtUserSearchResultsPage {
+ Q_OBJECT
+ public:
+ QtUserSearchResultsPage();
+ virtual bool isComplete() const;
+ void setNoResults(bool noResults);
+ signals:
+ void onUserTriggersContinue();
+ public slots:
+ void emitCompletenessCheck();
+ };
}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp b/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp
index 52b17b0..cf62540 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp
+++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.cpp
@@ -1,22 +1,20 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#include <Swift/QtUI/UserSearch/QtUserSearchWindow.h>
+#include <memory>
+
#include <boost/bind.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
#include <QItemDelegate>
#include <QModelIndex>
#include <QMovie>
#include <QWizardPage>
-#include <Swiften/Base/Log.h>
-#include <Swiften/Base/foreach.h>
-
#include <Swift/Controllers/UIEvents/AddContactUIEvent.h>
#include <Swift/Controllers/UIEvents/CreateImpromptuMUCUIEvent.h>
#include <Swift/Controllers/UIEvents/InviteToMUCUIEvent.h>
@@ -36,593 +34,606 @@
namespace Swift {
-QtUserSearchWindow::QtUserSearchWindow(UIEventStream* eventStream, UserSearchWindow::Type type, const std::set<std::string>& groups, SettingsProvider* settingsProvider) : eventStream_(eventStream), type_(type), model_(NULL), firstMultiJIDPage_(NULL), settings_(settingsProvider), searchNext_(false), supportsImpromptu_(false) {
- setupUi(this);
+QtUserSearchWindow::QtUserSearchWindow(UIEventStream* eventStream, UserSearchWindow::Type type, const std::set<std::string>& groups, SettingsProvider* settingsProvider) : eventStream_(eventStream), type_(type), model_(nullptr), firstMultiJIDPage_(nullptr), settings_(settingsProvider), searchNext_(false), supportsImpromptu_(false) {
+ setupUi(this);
#ifndef Q_OS_MAC
#ifdef Q_OS_WIN32
- setWindowIcon(QIcon(":/logo-icon-16-win.png"));
+ setWindowIcon(QIcon(":/logo-icon-16-win.png"));
#else
- setWindowIcon(QIcon(":/logo-icon-16.png"));
+ setWindowIcon(QIcon(":/logo-icon-16.png"));
#endif
#endif
- QString title;
- switch(type) {
- case AddContact:
- title = tr("Add Contact");
- break;
- case ChatToContact:
- title = tr("Chat to Users");
- break;
- case InviteToChat:
- title = tr("Add Users to Chat");
- break;
- }
- setWindowTitle(title);
-
- delegate_ = new UserSearchDelegate(this);
-
- setFirstPage(title);
- setSecondPage();
- setThirdPage();
-
- detailsPage_ = new QtUserSearchDetailsPage(groups);
- setPage(4, detailsPage_);
-
- connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(handleCurrentChanged(int)));
- connect(this, SIGNAL(accepted()), this, SLOT(handleAccepted()));
- clear();
+ QString title;
+ switch(type) {
+ case AddContact:
+ title = tr("Add Contact");
+ break;
+ case ChatToContact:
+ title = tr("Chat to Users");
+ break;
+ case InviteToChat:
+ title = tr("Add Users to Chat");
+ break;
+ }
+ setWindowTitle(title);
+
+ delegate_ = new UserSearchDelegate(this);
+
+ setFirstPage(title);
+ setSecondPage();
+ setThirdPage();
+
+ detailsPage_ = new QtUserSearchDetailsPage(groups);
+ setPage(4, detailsPage_);
+
+ connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(handleCurrentChanged(int)));
+ connect(this, SIGNAL(accepted()), this, SLOT(handleAccepted()));
+ clear();
}
QtUserSearchWindow::~QtUserSearchWindow() {
- delete model_;
+ delete model_;
}
void QtUserSearchWindow::handleCurrentChanged(int page) {
- searchNext_ = false;
- if (firstMultiJIDPage_) {
- firstMultiJIDPage_->reset();
- }
- resultsPage_->emitCompletenessCheck();
- if (page == 1 && lastPage_ == 3) {
- addSearchedJIDToList(getContact());
- setSecondPage();
- }
- else if (page == 2 && lastPage_ == 1) {
- setError("");
- /* next won't be called if JID is selected */
- JID server = getServerToSearch();
- clearForm();
- onFormRequested(server);
- setThirdPage();
- }
- else if (page == 3 && lastPage_ == 2) {
- JID server = getServerToSearch();
- handleSearch();
-
- if (type_ == AddContact) {
- bool remote = firstPage_->byRemoteSearch_->isChecked();
- firstPage_->byRemoteSearch_->setChecked(remote);
- firstPage_->service_->setEditText(P2QSTRING(server.toString()));
- } else {
- bool remote = firstMultiJIDPage_->byRemoteSearch_->isChecked();
- setFirstPage();
- firstMultiJIDPage_->byRemoteSearch_->setChecked(remote);
- firstMultiJIDPage_->service_->setEditText(P2QSTRING(server.toString()));
- }
- }
- else if (page == 4) {
- detailsPage_->clear();
- detailsPage_->setJID(getContactJID());
- onNameSuggestionRequested(getContactJID());
- }
- lastPage_ = page;
+ searchNext_ = false;
+ if (firstMultiJIDPage_) {
+ firstMultiJIDPage_->reset();
+ }
+ resultsPage_->emitCompletenessCheck();
+ if (page == 1 && lastPage_ == 3) {
+ addSearchedJIDToList(getContact());
+ setSecondPage();
+ }
+ else if (page == 2 && lastPage_ == 1) {
+ setError("");
+ /* next won't be called if JID is selected */
+ JID server = getServerToSearch();
+ clearForm();
+ onFormRequested(server);
+ setThirdPage();
+ }
+ else if (page == 3 && lastPage_ == 2) {
+ JID server = getServerToSearch();
+ handleSearch();
+
+ if (type_ == AddContact) {
+ bool remote = firstPage_->byRemoteSearch_->isChecked();
+ firstPage_->byRemoteSearch_->setChecked(remote);
+ firstPage_->service_->setEditText(P2QSTRING(server.toString()));
+ } else {
+ bool remote = firstMultiJIDPage_->byRemoteSearch_->isChecked();
+ setFirstPage();
+ firstMultiJIDPage_->byRemoteSearch_->setChecked(remote);
+ if (remote) {
+ firstMultiJIDPage_->service_->setEditText(P2QSTRING(server.toString()));
+ }
+ }
+ }
+ else if (page == 4) {
+ detailsPage_->clear();
+ detailsPage_->setJID(getContactJID());
+ onNameSuggestionRequested(getContactJID());
+ }
+ lastPage_ = page;
}
JID QtUserSearchWindow::getServerToSearch() {
- if (type_ == AddContact) {
- return firstPage_->byRemoteSearch_->isChecked() ? JID(Q2PSTRING(firstPage_->service_->currentText().trimmed())) : myServer_;
- } else {
- return firstMultiJIDPage_->byRemoteSearch_->isChecked() ? JID(Q2PSTRING(firstMultiJIDPage_->service_->currentText().trimmed())) : myServer_;
- }
+ if (type_ == AddContact) {
+ return firstPage_->byRemoteSearch_->isChecked() ? JID(Q2PSTRING(firstPage_->service_->currentText().trimmed())) : myServer_;
+ } else {
+ return firstMultiJIDPage_->byRemoteSearch_->isChecked() ? JID(Q2PSTRING(firstMultiJIDPage_->service_->currentText().trimmed())) : myServer_;
+ }
}
void QtUserSearchWindow::handleAccepted() {
- JID jid;
- std::vector<JID> jids;
- switch(type_) {
- case AddContact:
- jid = getContactJID();
- eventStream_->send(boost::make_shared<AddContactUIEvent>(jid, detailsPage_->getName(), detailsPage_->getSelectedGroups()));
- break;
- case ChatToContact:
- if (contactVector_.size() == 1) {
- boost::shared_ptr<UIEvent> event(new RequestChatUIEvent(contactVector_[0]->jid));
- eventStream_->send(event);
- break;
- }
-
- foreach(Contact::ref contact, contactVector_) {
- jids.push_back(contact->jid);
- }
-
- eventStream_->send(boost::make_shared<CreateImpromptuMUCUIEvent>(jids, JID(), Q2PSTRING(firstMultiJIDPage_->reason_->text())));
- break;
- case InviteToChat:
- foreach(Contact::ref contact, contactVector_) {
- jids.push_back(contact->jid);
- }
- eventStream_->send(boost::make_shared<InviteToMUCUIEvent>(roomJID_, jids, Q2PSTRING(firstMultiJIDPage_->reason_->text())));
- break;
- }
+ JID jid;
+ std::vector<JID> jids;
+ switch(type_) {
+ case AddContact:
+ jid = getContactJID();
+ eventStream_->send(std::make_shared<AddContactUIEvent>(jid, detailsPage_->getName(), detailsPage_->getSelectedGroups()));
+ break;
+ case ChatToContact:
+ if (contactVector_.size() == 1) {
+ std::shared_ptr<UIEvent> event(new RequestChatUIEvent(contactVector_[0]->jid));
+ eventStream_->send(event);
+ break;
+ }
+
+ for (Contact::ref contact : contactVector_) {
+ jids.push_back(contact->jid);
+ }
+
+ eventStream_->send(std::make_shared<CreateImpromptuMUCUIEvent>(jids, Q2PSTRING(firstMultiJIDPage_->reason_->text())));
+ break;
+ case InviteToChat:
+ for (Contact::ref contact : contactVector_) {
+ jids.push_back(contact->jid);
+ }
+ eventStream_->send(std::make_shared<InviteToMUCUIEvent>(originatorJID_, jids, Q2PSTRING(firstMultiJIDPage_->reason_->text())));
+ break;
+ }
}
void QtUserSearchWindow::handleContactSuggestionRequested(const QString& text) {
- std::string stdText = Q2PSTRING(text);
- onContactSuggestionsRequested(stdText);
+ std::string stdText = Q2PSTRING(text);
+ onContactSuggestionsRequested(stdText);
}
void QtUserSearchWindow::addContact() {
- if (!!firstMultiJIDPage_->jid_->getContact()) {
- contactVector_.push_back(firstMultiJIDPage_->jid_->getContact());
- firstMultiJIDPage_->jid_->clear();
- }
- firstMultiJIDPage_->contactList_->setList(contactVector_);
- firstMultiJIDPage_->emitCompletenessCheck();
- if (type_ == ChatToContact) {
- firstMultiJIDPage_->groupBox->setEnabled(supportsImpromptu_ ? 1 : (contactVector_.size() < 1));
- }
+ auto contactToAdd = firstMultiJIDPage_->jid_->getContact();
+ if (!!contactToAdd) {
+ contactVector_.push_back(contactToAdd);
+ firstMultiJIDPage_->jid_->clear();
+ }
+
+ firstMultiJIDPage_->contactList_->setList(contactVector_);
+ firstMultiJIDPage_->emitCompletenessCheck();
+ if (type_ == ChatToContact) {
+ firstMultiJIDPage_->groupBox->setEnabled(supportsImpromptu_ ? 1 : (contactVector_.size() < 1));
+ }
+
+ if (!!contactToAdd && contactToAdd->jid.isValid() && contactToAdd->statusType == StatusShow::None) {
+ onJIDUpdateRequested({contactToAdd->jid});
+ }
}
void QtUserSearchWindow::setWarning(const boost::optional<std::string>& message) {
- if (message) {
- firstPage_->jidWarning_->setToolTip(P2QSTRING((*message)));
- firstPage_->jidWarning_->setAccessibleDescription(P2QSTRING((*message)));
- firstPage_->jidWarning_->show();
- }
- else {
- firstPage_->jidWarning_->setToolTip("");
- firstPage_->jidWarning_->setAccessibleDescription("");
- firstPage_->jidWarning_->hide();
- }
- firstPage_->emitCompletenessCheck();
+ if (message) {
+ firstPage_->jidWarning_->setToolTip(P2QSTRING((*message)));
+ firstPage_->jidWarning_->setAccessibleDescription(P2QSTRING((*message)));
+ firstPage_->jidWarning_->show();
+ }
+ else {
+ firstPage_->jidWarning_->setToolTip("");
+ firstPage_->jidWarning_->setAccessibleDescription("");
+ firstPage_->jidWarning_->hide();
+ }
+ firstPage_->emitCompletenessCheck();
}
int QtUserSearchWindow::nextId() const {
- if (type_ == AddContact) {
- switch (currentId()) {
- case 1: return firstPage_->byJID_->isChecked() ? (type_ == AddContact ? 4 : -1) : 2;
- case 2: return 3;
- case 3: return type_ == AddContact ? 4 : -1;
- case 4: return -1;
- default: return -1;
- }
- } else {
- switch (currentId()) {
- case 1: return searchNext_ ? 2 : -1;
- case 2: return 3;
- case 3: return 1;
- case 4: return -1;
- default: return -1;
- }
- }
+ if (type_ == AddContact) {
+ switch (currentId()) {
+ case 1: return firstPage_->byJID_->isChecked() ? (type_ == AddContact ? 4 : -1) : 2;
+ case 2: return 3;
+ case 3: return type_ == AddContact ? 4 : -1;
+ case 4: return -1;
+ default: return -1;
+ }
+ } else {
+ switch (currentId()) {
+ case 1: return searchNext_ ? 2 : -1;
+ case 2: return 3;
+ case 3: return 1;
+ case 4: return -1;
+ default: return -1;
+ }
+ }
}
void QtUserSearchWindow::handleFirstPageRadioChange() {
- if (firstPage_->byJID_->isChecked()) {
- firstPage_->jid_->setText("");
- firstPage_->jid_->setEnabled(true);
- firstPage_->service_->setEnabled(false);
- restart();
- }
- else if (firstPage_->byRemoteSearch_->isChecked()) {
- firstPage_->service_->setEditText("");
- firstPage_->jid_->setEnabled(false);
- firstPage_->service_->setEnabled(true);
- //firstPage_->jid_->setText("");
- restart();
- }
- else {
- firstPage_->jid_->setEnabled(false);
- firstPage_->service_->setEnabled(false);
- restart();
- }
+ if (firstPage_->byJID_->isChecked()) {
+ firstPage_->jid_->setText("");
+ firstPage_->jid_->setEnabled(true);
+ firstPage_->service_->setEnabled(false);
+ restart();
+ }
+ else if (firstPage_->byRemoteSearch_->isChecked()) {
+ firstPage_->service_->setEditText("");
+ firstPage_->jid_->setEnabled(false);
+ firstPage_->service_->setEnabled(true);
+ //firstPage_->jid_->setText("");
+ restart();
+ }
+ else {
+ firstPage_->jid_->setEnabled(false);
+ firstPage_->service_->setEnabled(false);
+ restart();
+ }
}
void QtUserSearchWindow::handleSearch() {
- boost::shared_ptr<SearchPayload> search(new SearchPayload());
- if (fieldsPage_->getFormWidget()) {
- search->setForm(fieldsPage_->getFormWidget()->getCompletedForm());
- search->getForm()->clearEmptyTextFields();
- } else {
- if (fieldsPage_->nickInput_->isEnabled() && !fieldsPage_->nickInput_->text().isEmpty()) {
- search->setNick(Q2PSTRING(fieldsPage_->nickInput_->text()));
- }
- if (fieldsPage_->firstInput_->isEnabled() && !fieldsPage_->firstInput_->text().isEmpty()) {
- search->setFirst(Q2PSTRING(fieldsPage_->firstInput_->text()));
- }
- if (fieldsPage_->lastInput_->isEnabled() && !fieldsPage_->lastInput_->text().isEmpty()) {
- search->setLast(Q2PSTRING(fieldsPage_->lastInput_->text()));
- }
- if (fieldsPage_->emailInput_->isEnabled() && !fieldsPage_->emailInput_->text().isEmpty()) {
- search->setEMail(Q2PSTRING(fieldsPage_->emailInput_->text()));
- }
- }
- onSearchRequested(search, getServerToSearch());
+ std::shared_ptr<SearchPayload> search(new SearchPayload());
+ if (fieldsPage_->getFormWidget()) {
+ search->setForm(fieldsPage_->getFormWidget()->getCompletedForm());
+ search->getForm()->clearEmptyTextFields();
+ } else {
+ if (fieldsPage_->nickInput_->isEnabled() && !fieldsPage_->nickInput_->text().isEmpty()) {
+ search->setNick(Q2PSTRING(fieldsPage_->nickInput_->text()));
+ }
+ if (fieldsPage_->firstInput_->isEnabled() && !fieldsPage_->firstInput_->text().isEmpty()) {
+ search->setFirst(Q2PSTRING(fieldsPage_->firstInput_->text()));
+ }
+ if (fieldsPage_->lastInput_->isEnabled() && !fieldsPage_->lastInput_->text().isEmpty()) {
+ search->setLast(Q2PSTRING(fieldsPage_->lastInput_->text()));
+ }
+ if (fieldsPage_->emailInput_->isEnabled() && !fieldsPage_->emailInput_->text().isEmpty()) {
+ search->setEMail(Q2PSTRING(fieldsPage_->emailInput_->text()));
+ }
+ }
+ onSearchRequested(search, getServerToSearch());
}
JID QtUserSearchWindow::getContactJID() const {
- JID jid;
-
- bool useSearchResult;
- if (type_ == AddContact) {
- useSearchResult = !firstPage_->byJID_->isChecked();
- } else {
- useSearchResult = true;
- }
-
- if (useSearchResult) {
- if (dynamic_cast<UserSearchModel*>(model_)) {
- UserSearchResult* userItem = static_cast<UserSearchResult*>(resultsPage_->results_->currentIndex().internalPointer());
- if (userItem) { /* Remember to leave this if we change to dynamic cast */
- jid = userItem->getJID();
- }
- } else if (dynamic_cast<QtFormResultItemModel*>(model_)) {
- int row = resultsPage_->results_->currentIndex().row();
-
- Form::FormItem item = dynamic_cast<QtFormResultItemModel*>(model_)->getForm()->getItems().at(row);
- JID fallbackJid;
- foreach(FormField::ref field, item) {
- if (field->getType() == FormField::JIDSingleType) {
- jid = JID(field->getJIDSingleValue());
- break;
- }
- if (field->getName() == "jid") {
- fallbackJid = field->getValues()[0];
- }
- }
- if (!jid.isValid()) {
- jid = fallbackJid;
- }
- }
- }
- else {
- jid = JID(Q2PSTRING(firstPage_->jid_->text().trimmed()));
- }
- return jid;
+ JID jid;
+
+ bool useSearchResult;
+ if (type_ == AddContact) {
+ useSearchResult = !firstPage_->byJID_->isChecked();
+ } else {
+ useSearchResult = true;
+ }
+
+ if (useSearchResult) {
+ if (dynamic_cast<UserSearchModel*>(model_)) {
+ UserSearchResult* userItem = static_cast<UserSearchResult*>(resultsPage_->results_->currentIndex().internalPointer());
+ if (userItem) { /* Remember to leave this if we change to dynamic cast */
+ jid = userItem->getJID();
+ }
+ } else if (dynamic_cast<QtFormResultItemModel*>(model_)) {
+ int row = resultsPage_->results_->currentIndex().row();
+
+ Form::FormItem item = dynamic_cast<QtFormResultItemModel*>(model_)->getForm()->getItems().at(row);
+ JID fallbackJid;
+ for (FormField::ref field : item) {
+ if (field->getType() == FormField::JIDSingleType) {
+ jid = JID(field->getJIDSingleValue());
+ break;
+ }
+ if (field->getName() == "jid") {
+ fallbackJid = field->getValues()[0];
+ }
+ }
+ if (!jid.isValid()) {
+ jid = fallbackJid;
+ }
+ }
+ }
+ else {
+ jid = JID(Q2PSTRING(firstPage_->jid_->text().trimmed()));
+ }
+ return jid;
}
Contact::ref QtUserSearchWindow::getContact() const {
- return boost::make_shared<Contact>("", getContactJID(), StatusShow::None, "");
+ return std::make_shared<Contact>("", getContactJID(), StatusShow::None, "");
}
void QtUserSearchWindow::addSearchedJIDToList(const Contact::ref& contact) {
- std::vector<JID> jids;
- jids.push_back(contact->jid);
- handleJIDsAdded(jids);
- firstMultiJIDPage_->jid_->clear();
+ std::vector<JID> jids;
+ jids.push_back(contact->jid);
+ handleJIDsAdded(jids);
+ firstMultiJIDPage_->jid_->clear();
}
void QtUserSearchWindow::handleOnSearchedJIDSelected(const Contact::ref& contact) {
- firstPage_->jid_->setText(P2QSTRING(contact->jid.toString()));
+ firstPage_->jid_->setText(P2QSTRING(contact->jid.toString()));
}
void QtUserSearchWindow::show() {
- clear();
- if (type_ == AddContact) {
- setWarning(boost::optional<std::string>());
- }
- QWidget::show();
+ clear();
+ if (type_ == AddContact) {
+ setWarning(boost::optional<std::string>());
+ }
+ QWidget::show();
+ raise();
}
void QtUserSearchWindow::addSavedServices(const std::vector<JID>& services) {
- if (type_ == AddContact) {
- firstPage_->service_->clear();
- foreach (JID jid, services) {
- firstPage_->service_->addItem(P2QSTRING(jid.toString()));
- }
- firstPage_->service_->clearEditText();
- } else {
- firstMultiJIDPage_->service_->clear();
- foreach (JID jid, services) {
- firstMultiJIDPage_->service_->addItem(P2QSTRING(jid.toString()));
- }
- firstMultiJIDPage_->service_->clearEditText();
- }
-}
-
-void QtUserSearchWindow::setSearchFields(boost::shared_ptr<SearchPayload> fields) {
- fieldsPage_->fetchingThrobber_->hide();
- fieldsPage_->fetchingThrobber_->movie()->stop();
- fieldsPage_->fetchingLabel_->hide();
-
- fieldsPage_->instructionsLabel_->setText(fields->getInstructions() ? P2QSTRING(fields->getInstructions().get()) : "Enter search terms");
- if (fields->getForm()) {
- fieldsPage_->setFormWidget(new QtFormWidget(fields->getForm(), fieldsPage_));
- } else {
- fieldsPage_->setFormWidget(NULL);
- bool enabled[8] = {!!fields->getNick(), !!fields->getNick(), !!fields->getFirst(), !!fields->getFirst(), !!fields->getLast(), !!fields->getLast(), !!fields->getEMail(), !!fields->getEMail()};
- QWidget* legacySearchWidgets[8] = {fieldsPage_->nickInputLabel_, fieldsPage_->nickInput_, fieldsPage_->firstInputLabel_, fieldsPage_->firstInput_, fieldsPage_->lastInputLabel_, fieldsPage_->lastInput_, fieldsPage_->emailInputLabel_, fieldsPage_->emailInput_};
- for (int i = 0; i < 8; i++) {
- legacySearchWidgets[i]->setVisible(enabled[i]);
- legacySearchWidgets[i]->setEnabled(enabled[i]);
- }
- }
- fieldsPage_->emitCompletenessCheck();
+ if (type_ == AddContact) {
+ firstPage_->service_->clear();
+ for (auto&& jid : services) {
+ firstPage_->service_->addItem(P2QSTRING(jid.toString()));
+ }
+ firstPage_->service_->clearEditText();
+ } else {
+ firstMultiJIDPage_->service_->clear();
+ for (auto&& jid : services) {
+ firstMultiJIDPage_->service_->addItem(P2QSTRING(jid.toString()));
+ }
+ firstMultiJIDPage_->service_->clearEditText();
+ }
+}
+
+void QtUserSearchWindow::setSearchFields(std::shared_ptr<SearchPayload> fields) {
+ fieldsPage_->fetchingThrobber_->hide();
+ fieldsPage_->fetchingThrobber_->movie()->stop();
+ fieldsPage_->fetchingLabel_->hide();
+
+ fieldsPage_->instructionsLabel_->setText(fields->getInstructions() ? P2QSTRING(fields->getInstructions().get()) : "Enter search terms");
+ if (fields->getForm()) {
+ fieldsPage_->setFormWidget(new QtFormWidget(fields->getForm(), fieldsPage_));
+ } else {
+ fieldsPage_->setFormWidget(nullptr);
+ bool enabled[8] = {!!fields->getNick(), !!fields->getNick(), !!fields->getFirst(), !!fields->getFirst(), !!fields->getLast(), !!fields->getLast(), !!fields->getEMail(), !!fields->getEMail()};
+ QWidget* legacySearchWidgets[8] = {fieldsPage_->nickInputLabel_, fieldsPage_->nickInput_, fieldsPage_->firstInputLabel_, fieldsPage_->firstInput_, fieldsPage_->lastInputLabel_, fieldsPage_->lastInput_, fieldsPage_->emailInputLabel_, fieldsPage_->emailInput_};
+ for (int i = 0; i < 8; i++) {
+ legacySearchWidgets[i]->setVisible(enabled[i]);
+ legacySearchWidgets[i]->setEnabled(enabled[i]);
+ }
+ }
+ fieldsPage_->emitCompletenessCheck();
}
void QtUserSearchWindow::setNameSuggestions(const std::vector<std::string>& suggestions) {
- if (detailsPage_) {
- detailsPage_->setNameSuggestions(suggestions);
- }
+ if (detailsPage_) {
+ detailsPage_->setNameSuggestions(suggestions);
+ }
}
void QtUserSearchWindow::prepopulateJIDAndName(const JID& jid, const std::string& name) {
- firstPage_->jid_->setText(P2QSTRING(jid.toBare().toString()));
- detailsPage_->setJID(jid);
- lastPage_ = 1;
- restart();
- next();
- detailsPage_->setName(name);
+ firstPage_->jid_->setText(P2QSTRING(jid.toBare().toString()));
+ detailsPage_->setJID(jid);
+ lastPage_ = 1;
+ restart();
+ next();
+ detailsPage_->setName(name);
}
void QtUserSearchWindow::setContactSuggestions(const std::vector<Contact::ref>& suggestions) {
- if (type_ == AddContact) {
- firstPage_->jid_->setSuggestions(suggestions);
- } else {
- firstMultiJIDPage_->jid_->setSuggestions(suggestions);
- }
+ if (type_ == AddContact) {
+ firstPage_->jid_->setSuggestions(suggestions);
+ } else {
+ firstMultiJIDPage_->jid_->setSuggestions(suggestions);
+ }
}
void QtUserSearchWindow::setJIDs(const std::vector<JID> &jids) {
- foreach(JID jid, jids) {
- addSearchedJIDToList(boost::make_shared<Contact>("", jid, StatusShow::None, ""));
- }
- onJIDUpdateRequested(jids);
+ for (auto&& jid : jids) {
+ addSearchedJIDToList(std::make_shared<Contact>("", jid, StatusShow::None, ""));
+ }
+ onJIDUpdateRequested(jids);
+}
+
+void QtUserSearchWindow::setOriginator(const JID& originator) {
+ originatorJID_ = originator;
}
void QtUserSearchWindow::setRoomJID(const JID& roomJID) {
- roomJID_ = roomJID;
+ roomJID_ = roomJID;
}
std::string QtUserSearchWindow::getReason() const {
- return Q2PSTRING(firstMultiJIDPage_->reason_->text());
+ return Q2PSTRING(firstMultiJIDPage_->reason_->text());
}
std::vector<JID> QtUserSearchWindow::getJIDs() const {
- std::vector<JID> jids;
- foreach (Contact::ref contact, contactVector_) {
- jids.push_back(contact->jid);
- }
- return jids;
+ std::vector<JID> jids;
+ for (Contact::ref contact : contactVector_) {
+ jids.push_back(contact->jid);
+ }
+ return jids;
}
void QtUserSearchWindow::setCanStartImpromptuChats(bool supportsImpromptu) {
- supportsImpromptu_ = supportsImpromptu;
- if (type_ == ChatToContact) {
- firstMultiJIDPage_->contactList_->setMaximumNoOfContactsToOne(!supportsImpromptu_);
- }
+ supportsImpromptu_ = supportsImpromptu;
+ if (type_ == ChatToContact) {
+ firstMultiJIDPage_->contactList_->setMaximumNoOfContactsToOne(!supportsImpromptu_);
+ }
}
void QtUserSearchWindow::updateContacts(const std::vector<Contact::ref>& contacts) {
- if (type_ != AddContact) {
- firstMultiJIDPage_->contactList_->updateContacts(contacts);
- }
+ if (type_ != AddContact) {
+ firstMultiJIDPage_->contactList_->updateContacts(contacts);
+ }
}
void QtUserSearchWindow::addContacts(const std::vector<Contact::ref>& contacts) {
- if (type_ != AddContact) {
- /* prevent duplicate JIDs from appearing in the contact list */
- foreach (Contact::ref newContact, contacts) {
- bool found = false;
- foreach (Contact::ref oldContact, contactVector_) {
- if (newContact->jid == oldContact->jid) {
- found = true;
- break;
- }
- }
- if (!found) {
- contactVector_.push_back(newContact);
- }
- }
- if (!supportsImpromptu_ && contactVector_.size() > 1) {
- contactVector_.resize(1); /* can't chat with more than one user */
- }
- firstMultiJIDPage_->contactList_->setList(contactVector_);
- firstMultiJIDPage_->emitCompletenessCheck();
- if (type_ == ChatToContact) {
- firstMultiJIDPage_->groupBox->setEnabled(supportsImpromptu_ ? true : (contactVector_.size() < 1));
- }
- }
+ if (type_ != AddContact) {
+ /* prevent duplicate JIDs from appearing in the contact list */
+ for (Contact::ref newContact : contacts) {
+ bool found = false;
+ for (Contact::ref oldContact : contactVector_) {
+ if (newContact->jid == oldContact->jid) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ contactVector_.push_back(newContact);
+ }
+ }
+ if (type_ != InviteToChat && !supportsImpromptu_ && contactVector_.size() > 1) {
+ contactVector_.resize(1); /* can't chat with more than one user */
+ }
+ firstMultiJIDPage_->contactList_->setList(contactVector_);
+ firstMultiJIDPage_->emitCompletenessCheck();
+ if (type_ == ChatToContact) {
+ firstMultiJIDPage_->groupBox->setEnabled(supportsImpromptu_ ? true : (contactVector_.size() < 1));
+ }
+ }
}
void QtUserSearchWindow::setCanSupplyDescription(bool allowed) {
- firstMultiJIDPage_->label->setVisible(allowed);
- firstMultiJIDPage_->reason_->setVisible(allowed);
+ firstMultiJIDPage_->label->setVisible(allowed);
+ firstMultiJIDPage_->reason_->setVisible(allowed);
}
void QtUserSearchWindow::handleAddViaSearch() {
- searchNext_ = true;
- next();
+ searchNext_ = true;
+ next();
}
void QtUserSearchWindow::handleListChanged(std::vector<Contact::ref> list) {
- contactVector_ = list;
- if (type_ == ChatToContact) {
- firstMultiJIDPage_->groupBox->setEnabled(supportsImpromptu_ ? 1 : (contactVector_.size() < 1));
- }
+ contactVector_ = list;
+ if (type_ == ChatToContact) {
+ firstMultiJIDPage_->groupBox->setEnabled(supportsImpromptu_ ? 1 : (contactVector_.size() < 1));
+ }
}
void QtUserSearchWindow::handleJIDsAdded(std::vector<JID> jids) {
- onJIDAddRequested(jids);
+ onJIDAddRequested(jids);
}
void QtUserSearchWindow::setResults(const std::vector<UserSearchResult>& results) {
- UserSearchModel *newModel = new UserSearchModel();
- newModel->setResults(results);
- resultsPage_->results_->setModel(newModel);
- resultsPage_->results_->setItemDelegate(delegate_);
- resultsPage_->results_->setHeaderHidden(true);
- delete model_;
- model_ = newModel;
- resultsPage_->setNoResults(model_->rowCount() == 0);
- resultsPage_->emitCompletenessCheck();
+ UserSearchModel *newModel = new UserSearchModel();
+ newModel->setResults(results);
+ resultsPage_->results_->setModel(newModel);
+ resultsPage_->results_->setItemDelegate(delegate_);
+ resultsPage_->results_->setHeaderHidden(true);
+ delete model_;
+ model_ = newModel;
+ resultsPage_->setNoResults(model_->rowCount() == 0);
+ resultsPage_->emitCompletenessCheck();
}
void QtUserSearchWindow::setResultsForm(Form::ref results) {
- QtFormResultItemModel *newModel = new QtFormResultItemModel(this);
- newModel->setForm(results);
- resultsPage_->results_->setModel(newModel);
- resultsPage_->results_->setItemDelegate(new QItemDelegate());
- resultsPage_->results_->setHeaderHidden(false);
+ QtFormResultItemModel *newModel = new QtFormResultItemModel(this);
+ newModel->setForm(results);
+ resultsPage_->results_->setModel(newModel);
+ resultsPage_->results_->setItemDelegate(new QItemDelegate());
+ resultsPage_->results_->setHeaderHidden(false);
#if QT_VERSION >= 0x050000
- resultsPage_->results_->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
+ resultsPage_->results_->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
#else
- resultsPage_->results_->header()->setResizeMode(QHeaderView::ResizeToContents);
+ resultsPage_->results_->header()->setResizeMode(QHeaderView::ResizeToContents);
#endif
- delete model_;
- model_ = newModel;
- resultsPage_->setNoResults(model_->rowCount() == 0);
- resultsPage_->emitCompletenessCheck();
+ delete model_;
+ model_ = newModel;
+ resultsPage_->setNoResults(model_->rowCount() == 0);
+ resultsPage_->emitCompletenessCheck();
}
void QtUserSearchWindow::setSelectedService(const JID& jid) {
- myServer_ = jid;
+ myServer_ = jid;
}
void QtUserSearchWindow::handleJIDEditingDone() {
- onJIDEditFieldChanged(JID(Q2PSTRING(firstPage_->jid_->text())));
+ onJIDEditFieldChanged(JID(Q2PSTRING(firstPage_->jid_->text())));
}
void QtUserSearchWindow::setFirstPage(QString title) {
- if (page(1) != 0) {
- removePage(1);
- }
- if (type_ == AddContact) {
- firstPage_ = new QtUserSearchFirstPage(type_, title.isEmpty() ? firstPage_->title() : title, settings_);
- connect(firstPage_->jid_, SIGNAL(textEdited(QString)), this, SLOT(handleContactSuggestionRequested(QString)));
- connect(firstPage_->jid_, SIGNAL(textEdited(QString)), this, SLOT(handleJIDEditingDone()), Qt::UniqueConnection);
- firstPage_->jid_->onUserSelected.connect(boost::bind(&QtUserSearchWindow::handleOnSearchedJIDSelected, this, _1));
- connect(firstPage_->byJID_, SIGNAL(toggled(bool)), this, SLOT(handleFirstPageRadioChange()));
- connect(firstPage_->byLocalSearch_, SIGNAL(toggled(bool)), this, SLOT(handleFirstPageRadioChange()));
- connect(firstPage_->byRemoteSearch_, SIGNAL(toggled(bool)), this, SLOT(handleFirstPageRadioChange()));
+ if (page(1) != nullptr) {
+ removePage(1);
+ }
+ if (type_ == AddContact) {
+ firstPage_ = new QtUserSearchFirstPage(type_, title.isEmpty() ? firstPage_->title() : title, settings_);
+ connect(firstPage_->jid_, SIGNAL(textEdited(QString)), this, SLOT(handleContactSuggestionRequested(QString)));
+ connect(firstPage_->jid_, SIGNAL(textEdited(QString)), this, SLOT(handleJIDEditingDone()), Qt::UniqueConnection);
+ firstPage_->jid_->onUserSelected.connect(boost::bind(&QtUserSearchWindow::handleOnSearchedJIDSelected, this, _1));
+ connect(firstPage_->byJID_, SIGNAL(toggled(bool)), this, SLOT(handleFirstPageRadioChange()));
+ connect(firstPage_->byLocalSearch_, SIGNAL(toggled(bool)), this, SLOT(handleFirstPageRadioChange()));
+ connect(firstPage_->byRemoteSearch_, SIGNAL(toggled(bool)), this, SLOT(handleFirstPageRadioChange()));
#if QT_VERSION >= 0x040700
- firstPage_->jid_->setPlaceholderText(tr("alice@wonderland.lit"));
+ firstPage_->jid_->setPlaceholderText(tr("alice@wonderland.lit"));
#endif
- firstPage_->service_->setEnabled(false);
- setPage(1, firstPage_);
- } else {
- firstMultiJIDPage_ = new QtUserSearchFirstMultiJIDPage(type_, title.isEmpty() ? firstMultiJIDPage_->title() : title, settings_);
- connect(firstMultiJIDPage_->addContactButton_, SIGNAL(clicked()), this, SLOT(addContact()));
- connect(firstMultiJIDPage_->jid_, SIGNAL(textEdited(QString)), this, SLOT(handleContactSuggestionRequested(QString)));
- firstMultiJIDPage_->jid_->onUserSelected.connect(boost::bind(&QtUserSearchWindow::addSearchedJIDToList, this, _1));
- connect(firstMultiJIDPage_->addViaSearchButton_, SIGNAL(clicked()), this, SLOT(handleAddViaSearch()));
- connect(firstMultiJIDPage_->contactList_, SIGNAL(onListChanged(std::vector<Contact::ref>)), this, SLOT(handleListChanged(std::vector<Contact::ref>)));
- connect(firstMultiJIDPage_->contactList_, SIGNAL(onJIDsAdded(std::vector<JID>)), this, SLOT(handleJIDsAdded(std::vector<JID>)));
- connect(firstMultiJIDPage_, SIGNAL(onJIDsDropped(std::vector<JID>)), this, SLOT(handleJIDsAdded(std::vector<JID>)));
- setPage(1, firstMultiJIDPage_);
- }
+ firstPage_->service_->setEnabled(false);
+ setPage(1, firstPage_);
+ } else {
+ firstMultiJIDPage_ = new QtUserSearchFirstMultiJIDPage(type_, title.isEmpty() ? firstMultiJIDPage_->title() : title, settings_);
+ connect(firstMultiJIDPage_->addContactButton_, SIGNAL(clicked()), this, SLOT(addContact()));
+ connect(firstMultiJIDPage_->jid_, SIGNAL(textEdited(QString)), this, SLOT(handleContactSuggestionRequested(QString)));
+ firstMultiJIDPage_->jid_->onUserSelected.connect(boost::bind(&QtUserSearchWindow::addSearchedJIDToList, this, _1));
+ connect(firstMultiJIDPage_->addViaSearchButton_, SIGNAL(clicked()), this, SLOT(handleAddViaSearch()));
+ connect(firstMultiJIDPage_->contactList_, SIGNAL(onListChanged(std::vector<Contact::ref>)), this, SLOT(handleListChanged(std::vector<Contact::ref>)));
+ connect(firstMultiJIDPage_->contactList_, SIGNAL(onJIDsAdded(std::vector<JID>)), this, SLOT(handleJIDsAdded(std::vector<JID>)));
+ connect(firstMultiJIDPage_, SIGNAL(onJIDsDropped(std::vector<JID>)), this, SLOT(handleJIDsAdded(std::vector<JID>)));
+ setPage(1, firstMultiJIDPage_);
+ }
}
void QtUserSearchWindow::setSecondPage() {
- if (page(2) != 0) {
- removePage(2);
- }
- fieldsPage_ = new QtUserSearchFieldsPage();
- fieldsPage_->fetchingThrobber_->setMovie(new QMovie(":/icons/throbber.gif", QByteArray(), this));
- fieldsPage_->fetchingThrobber_->movie()->stop();
- setPage(2, fieldsPage_);
+ if (page(2) != nullptr) {
+ removePage(2);
+ }
+ fieldsPage_ = new QtUserSearchFieldsPage();
+ fieldsPage_->fetchingThrobber_->setMovie(new QMovie(":/icons/throbber.gif", QByteArray(), this));
+ fieldsPage_->fetchingThrobber_->movie()->stop();
+ setPage(2, fieldsPage_);
}
void QtUserSearchWindow::setThirdPage() {
- if (page(3) != 0) {
- removePage(3);
- }
- resultsPage_ = new QtUserSearchResultsPage();
+ if (page(3) != nullptr) {
+ removePage(3);
+ }
+ resultsPage_ = new QtUserSearchResultsPage();
#ifdef SWIFT_PLATFORM_MACOSX
- resultsPage_->results_->setAlternatingRowColors(true);
+ resultsPage_->results_->setAlternatingRowColors(true);
#endif
- if (type_ == AddContact) {
- connect(resultsPage_, SIGNAL(onUserTriggersContinue()), this, SLOT(next()));
- }
- else {
- connect(resultsPage_, SIGNAL(onUserTriggersContinue()), this, SLOT(next()));
- }
- setPage(3, resultsPage_);
+ if (type_ == AddContact) {
+ connect(resultsPage_, SIGNAL(onUserTriggersContinue()), this, SLOT(next()));
+ }
+ else {
+ connect(resultsPage_, SIGNAL(onUserTriggersContinue()), this, SLOT(next()));
+ }
+ setPage(3, resultsPage_);
}
void QtUserSearchWindow::clearForm() {
- fieldsPage_->fetchingThrobber_->show();
- fieldsPage_->fetchingThrobber_->movie()->start();
- fieldsPage_->fetchingLabel_->show();
- QWidget* legacySearchWidgets[8] = {fieldsPage_->nickInputLabel_, fieldsPage_->nickInput_, fieldsPage_->firstInputLabel_, fieldsPage_->firstInput_, fieldsPage_->lastInputLabel_, fieldsPage_->lastInput_, fieldsPage_->emailInputLabel_, fieldsPage_->emailInput_};
- for (int i = 0; i < 8; i++) {
- legacySearchWidgets[i]->hide();
- if (QLineEdit* edit = qobject_cast<QLineEdit*>(legacySearchWidgets[i])) {
- edit->clear();
- }
- }
- fieldsPage_->emitCompletenessCheck();
+ fieldsPage_->fetchingThrobber_->show();
+ fieldsPage_->fetchingThrobber_->movie()->start();
+ fieldsPage_->fetchingLabel_->show();
+ QWidget* legacySearchWidgets[8] = {fieldsPage_->nickInputLabel_, fieldsPage_->nickInput_, fieldsPage_->firstInputLabel_, fieldsPage_->firstInput_, fieldsPage_->lastInputLabel_, fieldsPage_->lastInput_, fieldsPage_->emailInputLabel_, fieldsPage_->emailInput_};
+ for (auto&& legacySearchWidget : legacySearchWidgets) {
+ legacySearchWidget->hide();
+ if (QLineEdit* edit = qobject_cast<QLineEdit*>(legacySearchWidget)) {
+ edit->clear();
+ }
+ }
+ fieldsPage_->emitCompletenessCheck();
}
void QtUserSearchWindow::clear() {
- QString howText;
- if (type_ == AddContact) {
- firstPage_->errorLabel_->setVisible(false);
- howText = QString(tr("How would you like to find the user to add?"));
- firstPage_->howLabel_->setText(howText);
- firstPage_->byJID_->setChecked(true);
- handleFirstPageRadioChange();
- } else {
- contactVector_.clear();
- firstMultiJIDPage_->contactList_->setList(contactVector_);
- firstMultiJIDPage_->errorLabel_->setVisible(false);
- if (type_ == ChatToContact) {
- howText = QString(tr("List of participants:"));
- } else if (type_ == InviteToChat) {
- howText = QString(tr("Who do you want to invite to the chat?"));
- }
- firstMultiJIDPage_->howLabel_->setText(howText);
- }
- clearForm();
- resultsPage_->results_->setModel(NULL);
- delete model_;
- model_ = NULL;
- restart();
- lastPage_ = 1;
+ QString howText;
+ if (type_ == AddContact) {
+ firstPage_->errorLabel_->setVisible(false);
+ howText = QString(tr("How would you like to find the user to add?"));
+ firstPage_->howLabel_->setText(howText);
+ firstPage_->byJID_->setChecked(true);
+ handleFirstPageRadioChange();
+ } else {
+ contactVector_.clear();
+ firstMultiJIDPage_->contactList_->setList(contactVector_);
+ firstMultiJIDPage_->errorLabel_->setVisible(false);
+ if (type_ == ChatToContact) {
+ howText = QString(tr("List of participants:"));
+ } else if (type_ == InviteToChat) {
+ howText = QString(tr("Who do you want to invite to the chat?"));
+ }
+ firstMultiJIDPage_->howLabel_->setText(howText);
+ }
+ clearForm();
+ resultsPage_->results_->setModel(nullptr);
+ delete model_;
+ model_ = nullptr;
+ restart();
+ lastPage_ = 1;
}
void QtUserSearchWindow::setError(const QString& error) {
- if (error.isEmpty()) {
- if (type_ == AddContact) {
- firstPage_->errorLabel_->hide();
- } else {
- firstMultiJIDPage_->errorLabel_->hide();
- }
- }
- else {
- if (type_ == AddContact) {
- firstPage_->errorLabel_->setText(QString("<font color='red'>%1</font>").arg(error));
- firstPage_->errorLabel_->show();
- } else {
- firstMultiJIDPage_->errorLabel_->setText(QString("<font color='red'>%1</font>").arg(error));
- firstMultiJIDPage_->errorLabel_->show();
- }
- restart();
- lastPage_ = 1;
- }
+ if (error.isEmpty()) {
+ if (type_ == AddContact) {
+ firstPage_->errorLabel_->hide();
+ } else {
+ firstMultiJIDPage_->errorLabel_->hide();
+ }
+ }
+ else {
+ if (type_ == AddContact) {
+ firstPage_->errorLabel_->setText(QString("<font color='red'>%1</font>").arg(error));
+ firstPage_->errorLabel_->show();
+ } else {
+ firstMultiJIDPage_->errorLabel_->setText(QString("<font color='red'>%1</font>").arg(error));
+ firstMultiJIDPage_->errorLabel_->show();
+ }
+ restart();
+ lastPage_ = 1;
+ }
}
void QtUserSearchWindow::setSearchError(bool error) {
- if (error) {
- setError(tr("Error while searching"));
- }
+ if (error) {
+ setError(tr("Error while searching"));
+ }
}
void QtUserSearchWindow::setServerSupportsSearch(bool support) {
- if (!support) {
- setError(tr("This server doesn't support searching for users."));
- }
+ if (!support) {
+ setError(tr("This server doesn't support searching for users."));
+ }
}
}
diff --git a/Swift/QtUI/UserSearch/QtUserSearchWindow.h b/Swift/QtUI/UserSearch/QtUserSearchWindow.h
index 15e68bf..0714ac1 100644
--- a/Swift/QtUI/UserSearch/QtUserSearchWindow.h
+++ b/Swift/QtUI/UserSearch/QtUserSearchWindow.h
@@ -1,104 +1,110 @@
/*
- * Copyright (c) 2010-2014 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <QWizard>
#include <set>
-#include <Swift/QtUI/UserSearch/ui_QtUserSearchWizard.h>
+#include <QWizard>
+
+#include <Swiften/Base/Override.h>
+
#include <Swift/Controllers/UIInterfaces/UserSearchWindow.h>
+#include <Swift/QtUI/UserSearch/ui_QtUserSearchWizard.h>
+
namespace Swift {
- class UserSearchModel;
- class UserSearchDelegate;
- class UserSearchResult;
- class UIEventStream;
- class QtUserSearchFirstPage;
- class QtUserSearchFirstMultiJIDPage;
- class QtUserSearchFieldsPage;
- class QtUserSearchResultsPage;
- class QtUserSearchDetailsPage;
- class QtFormResultItemModel;
- class SettingsProvider;
+ class UserSearchModel;
+ class UserSearchDelegate;
+ class UserSearchResult;
+ class UIEventStream;
+ class QtUserSearchFirstPage;
+ class QtUserSearchFirstMultiJIDPage;
+ class QtUserSearchFieldsPage;
+ class QtUserSearchResultsPage;
+ class QtUserSearchDetailsPage;
+ class QtFormResultItemModel;
+ class SettingsProvider;
- class QtUserSearchWindow : public QWizard, public UserSearchWindow, private Ui::QtUserSearchWizard {
- Q_OBJECT
- public:
- QtUserSearchWindow(UIEventStream* eventStream, UserSearchWindow::Type type, const std::set<std::string>& groups, SettingsProvider* settingsProvider);
- virtual ~QtUserSearchWindow();
+ class QtUserSearchWindow : public QWizard, public UserSearchWindow, private Ui::QtUserSearchWizard {
+ Q_OBJECT
+ public:
+ QtUserSearchWindow(UIEventStream* eventStream, UserSearchWindow::Type type, const std::set<std::string>& groups, SettingsProvider* settingsProvider);
+ virtual ~QtUserSearchWindow();
- virtual void addSavedServices(const std::vector<JID>& services);
+ virtual void addSavedServices(const std::vector<JID>& services) SWIFTEN_OVERRIDE;
- virtual void clear();
- virtual void show();
- virtual void setResults(const std::vector<UserSearchResult>& results);
- virtual void setResultsForm(Form::ref results);
- virtual void setSelectedService(const JID& jid);
- virtual void setServerSupportsSearch(bool error);
- virtual void setSearchError(bool error);
- virtual void setSearchFields(boost::shared_ptr<SearchPayload> fields);
- virtual void setNameSuggestions(const std::vector<std::string>& suggestions);
- virtual void prepopulateJIDAndName(const JID& jid, const std::string& name);
- virtual void setContactSuggestions(const std::vector<Contact::ref>& suggestions);
- virtual void setJIDs(const std::vector<JID> &jids);
- virtual void setRoomJID(const JID &roomJID);
- virtual std::string getReason() const;
- virtual std::vector<JID> getJIDs() const;
- virtual void setCanStartImpromptuChats(bool supportsImpromptu);
- virtual void updateContacts(const std::vector<Contact::ref> &contacts);
- virtual void addContacts(const std::vector<Contact::ref>& contacts);
- virtual void setCanSupplyDescription(bool allowed);
- virtual void setWarning(const boost::optional<std::string>& message);
+ virtual void clear() SWIFTEN_OVERRIDE;
+ virtual void show() SWIFTEN_OVERRIDE;
+ virtual void setResults(const std::vector<UserSearchResult>& results) SWIFTEN_OVERRIDE;
+ virtual void setResultsForm(Form::ref results) SWIFTEN_OVERRIDE;
+ virtual void setSelectedService(const JID& jid) SWIFTEN_OVERRIDE;
+ virtual void setServerSupportsSearch(bool error) SWIFTEN_OVERRIDE;
+ virtual void setSearchError(bool error) SWIFTEN_OVERRIDE;
+ virtual void setSearchFields(std::shared_ptr<SearchPayload> fields) SWIFTEN_OVERRIDE;
+ virtual void setNameSuggestions(const std::vector<std::string>& suggestions) SWIFTEN_OVERRIDE;
+ virtual void prepopulateJIDAndName(const JID& jid, const std::string& name) SWIFTEN_OVERRIDE;
+ virtual void setContactSuggestions(const std::vector<Contact::ref>& suggestions) SWIFTEN_OVERRIDE;
+ virtual void setJIDs(const std::vector<JID> &jids) SWIFTEN_OVERRIDE;
+ virtual void setOriginator(const JID& originator) SWIFTEN_OVERRIDE;
+ virtual void setRoomJID(const JID &roomJID) SWIFTEN_OVERRIDE;
+ virtual std::string getReason() const SWIFTEN_OVERRIDE;
+ virtual std::vector<JID> getJIDs() const SWIFTEN_OVERRIDE;
+ virtual void setCanStartImpromptuChats(bool supportsImpromptu) SWIFTEN_OVERRIDE;
+ virtual void updateContacts(const std::vector<Contact::ref> &contacts) SWIFTEN_OVERRIDE;
+ virtual void addContacts(const std::vector<Contact::ref>& contacts) SWIFTEN_OVERRIDE;
+ virtual void setCanSupplyDescription(bool allowed) SWIFTEN_OVERRIDE;
+ virtual void setWarning(const boost::optional<std::string>& message) SWIFTEN_OVERRIDE;
- protected:
- virtual int nextId() const;
+ protected:
+ virtual int nextId() const SWIFTEN_OVERRIDE;
- private slots:
- void handleFirstPageRadioChange();
- virtual void handleCurrentChanged(int);
- virtual void handleAccepted();
- void handleContactSuggestionRequested(const QString& text);
- void addContact();
- void handleAddViaSearch();
- void handleListChanged(std::vector<Contact::ref> list);
- void handleJIDsAdded(std::vector<JID> jids);
- void handleJIDEditingDone();
+ private slots:
+ void handleFirstPageRadioChange();
+ void handleCurrentChanged(int);
+ void handleAccepted();
+ void handleContactSuggestionRequested(const QString& text);
+ void addContact();
+ void handleAddViaSearch();
+ void handleListChanged(std::vector<Contact::ref> list);
+ void handleJIDsAdded(std::vector<JID> jids);
+ void handleJIDEditingDone();
- private:
- void setFirstPage(QString title = "");
- void setSecondPage();
- void setThirdPage();
+ private:
+ void setFirstPage(QString title = "");
+ void setSecondPage();
+ void setThirdPage();
- private:
- void clearForm();
- void setError(const QString& error);
- JID getServerToSearch();
- void handleSearch();
- JID getContactJID() const;
- Contact::ref getContact() const;
- void addSearchedJIDToList(const Contact::ref& contact);
- void handleOnSearchedJIDSelected(const Contact::ref& contact);
+ private:
+ void clearForm();
+ void setError(const QString& error);
+ JID getServerToSearch();
+ void handleSearch();
+ JID getContactJID() const;
+ Contact::ref getContact() const;
+ void addSearchedJIDToList(const Contact::ref& contact);
+ void handleOnSearchedJIDSelected(const Contact::ref& contact);
- private:
- UIEventStream* eventStream_;
- UserSearchWindow::Type type_;
- QAbstractItemModel* model_;
- UserSearchDelegate* delegate_;
- QtUserSearchFirstPage* firstPage_;
- QtUserSearchFirstMultiJIDPage* firstMultiJIDPage_;
- QtUserSearchFieldsPage* fieldsPage_;
- QtUserSearchResultsPage* resultsPage_;
- QtUserSearchDetailsPage* detailsPage_;
- JID myServer_;
- JID roomJID_;
- int lastPage_;
- std::vector<Contact::ref> contactVector_;
- SettingsProvider* settings_;
- bool searchNext_;
- bool supportsImpromptu_;
- };
+ private:
+ UIEventStream* eventStream_;
+ UserSearchWindow::Type type_;
+ QAbstractItemModel* model_;
+ UserSearchDelegate* delegate_;
+ QtUserSearchFirstPage* firstPage_;
+ QtUserSearchFirstMultiJIDPage* firstMultiJIDPage_;
+ QtUserSearchFieldsPage* fieldsPage_;
+ QtUserSearchResultsPage* resultsPage_;
+ QtUserSearchDetailsPage* detailsPage_;
+ JID myServer_;
+ JID roomJID_;
+ JID originatorJID_;
+ int lastPage_;
+ std::vector<Contact::ref> contactVector_;
+ SettingsProvider* settings_;
+ bool searchNext_;
+ bool supportsImpromptu_;
+ };
}
diff --git a/Swift/QtUI/UserSearch/UserSearchDelegate.cpp b/Swift/QtUI/UserSearch/UserSearchDelegate.cpp
index 1ac9eb3..8c7ca9a 100644
--- a/Swift/QtUI/UserSearch/UserSearchDelegate.cpp
+++ b/Swift/QtUI/UserSearch/UserSearchDelegate.cpp
@@ -27,44 +27,44 @@ UserSearchDelegate::~UserSearchDelegate() {
}
QSize UserSearchDelegate::sizeHint(const QStyleOptionViewItem& /*option*/, const QModelIndex& /*index*/ ) const {
- //UserSearchItem* item = static_cast<UserSearchItem*>(index.internalPointer());
- QFontMetrics nameMetrics(common_.nameFont);
- QFontMetrics statusMetrics(common_.detailFont);
- int sizeByText = 2 * common_.verticalMargin + nameMetrics.height() + statusMetrics.height();
- return QSize(150, sizeByText);
+ //UserSearchItem* item = static_cast<UserSearchItem*>(index.internalPointer());
+ QFontMetrics nameMetrics(common_.nameFont);
+ QFontMetrics statusMetrics(common_.detailFont);
+ int sizeByText = 2 * common_.verticalMargin + nameMetrics.height() + statusMetrics.height();
+ return QSize(150, sizeByText);
}
-void UserSearchDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
- UserSearchResult* item = static_cast<UserSearchResult*>(index.internalPointer());
- painter->save();
- QRect fullRegion(option.rect);
- if (option.state & QStyle::State_Selected) {
- painter->fillRect(fullRegion, option.palette.highlight());
- painter->setPen(option.palette.highlightedText().color());
- }
- else {
- QColor nameColor = UserSearchModel::data(item, Qt::TextColorRole).value<QColor> ();
- painter->setPen(QPen(nameColor));
- }
-
- QFontMetrics nameMetrics(common_.nameFont);
- painter->setFont(common_.nameFont);
- int extraFontWidth = nameMetrics.width("H");
- int leftOffset = common_.horizontalMargin * 2 + extraFontWidth / 2;
- QRect textRegion(fullRegion.adjusted(leftOffset, 0, 0, 0));
-
- int nameHeight = nameMetrics.height() + common_.verticalMargin;
- QRect nameRegion(textRegion.adjusted(0, common_.verticalMargin, 0, 0));
-
- painter->drawText(nameRegion, Qt::AlignTop, UserSearchModel::data(item, Qt::DisplayRole).toString());
-
- painter->setFont(common_.detailFont);
- painter->setPen(QPen(QColor(160, 160, 160)));
-
- QRect detailRegion(textRegion.adjusted(0, nameHeight, 0, 0));
- painter->drawText(detailRegion, Qt::AlignTop, UserSearchModel::data(item, UserSearchModel::DetailTextRole).toString());
-
- painter->restore();
+void UserSearchDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
+ UserSearchResult* item = static_cast<UserSearchResult*>(index.internalPointer());
+ painter->save();
+ QRect fullRegion(option.rect);
+ if (option.state & QStyle::State_Selected) {
+ painter->fillRect(fullRegion, option.palette.highlight());
+ painter->setPen(option.palette.highlightedText().color());
+ }
+ else {
+ QColor nameColor = UserSearchModel::data(item, Qt::TextColorRole).value<QColor> ();
+ painter->setPen(QPen(nameColor));
+ }
+
+ QFontMetrics nameMetrics(common_.nameFont);
+ painter->setFont(common_.nameFont);
+ int extraFontWidth = nameMetrics.width("H");
+ int leftOffset = common_.horizontalMargin * 2 + extraFontWidth / 2;
+ QRect textRegion(fullRegion.adjusted(leftOffset, 0, 0, 0));
+
+ int nameHeight = nameMetrics.height() + common_.verticalMargin;
+ QRect nameRegion(textRegion.adjusted(0, common_.verticalMargin, 0, 0));
+
+ painter->drawText(nameRegion, Qt::AlignTop, UserSearchModel::data(item, Qt::DisplayRole).toString());
+
+ painter->setFont(common_.detailFont);
+ painter->setPen(QPen(QColor(160, 160, 160)));
+
+ QRect detailRegion(textRegion.adjusted(0, nameHeight, 0, 0));
+ painter->drawText(detailRegion, Qt::AlignTop, UserSearchModel::data(item, UserSearchModel::DetailTextRole).toString());
+
+ painter->restore();
}
}
diff --git a/Swift/QtUI/UserSearch/UserSearchDelegate.h b/Swift/QtUI/UserSearch/UserSearchDelegate.h
index 92fa0e8..a5639ec 100644
--- a/Swift/QtUI/UserSearch/UserSearchDelegate.h
+++ b/Swift/QtUI/UserSearch/UserSearchDelegate.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2015 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -13,18 +13,18 @@
#include <Swift/QtUI/Roster/DelegateCommons.h>
namespace Swift {
- class UserSearchDelegate : public QStyledItemDelegate {
- Q_OBJECT
-
- public:
- UserSearchDelegate(QObject* parent = 0);
- virtual ~UserSearchDelegate();
-
- void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
- QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index ) const;
- private:
- DelegateCommons common_;
- };
+ class UserSearchDelegate : public QStyledItemDelegate {
+ Q_OBJECT
+
+ public:
+ UserSearchDelegate(QObject* parent = nullptr);
+ virtual ~UserSearchDelegate();
+
+ void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
+ QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index ) const;
+ private:
+ DelegateCommons common_;
+ };
}
diff --git a/Swift/QtUI/UserSearch/UserSearchModel.cpp b/Swift/QtUI/UserSearch/UserSearchModel.cpp
index c758492..b6ac3cf 100644
--- a/Swift/QtUI/UserSearch/UserSearchModel.cpp
+++ b/Swift/QtUI/UserSearch/UserSearchModel.cpp
@@ -1,12 +1,12 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "Swift/QtUI/UserSearch/UserSearchModel.h"
+#include <Swift/QtUI/UserSearch/UserSearchModel.h>
-#include "Swift/QtUI/QtSwiftUtil.h"
+#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
@@ -14,76 +14,76 @@ UserSearchModel::UserSearchModel() {
}
void UserSearchModel::clear() {
- emit layoutAboutToBeChanged();
- results_.clear();
- emit layoutChanged();
+ emit layoutAboutToBeChanged();
+ results_.clear();
+ emit layoutChanged();
}
void UserSearchModel::setResults(const std::vector<UserSearchResult>& results) {
- clear();
- emit layoutAboutToBeChanged();
- results_ = results;
- emit layoutChanged();
+ clear();
+ emit layoutAboutToBeChanged();
+ results_ = results;
+ emit layoutChanged();
}
int UserSearchModel::columnCount(const QModelIndex& /*parent*/) const {
- return 1;
+ return 1;
}
QVariant UserSearchModel::data(const QModelIndex& index, int role) const {
- if (!index.isValid()) return QVariant();
- UserSearchResult* result = static_cast<UserSearchResult*>(index.internalPointer());
- return data(result, role);
+ if (!index.isValid()) return QVariant();
+ UserSearchResult* result = static_cast<UserSearchResult*>(index.internalPointer());
+ return data(result, role);
}
QVariant UserSearchModel::data(UserSearchResult* item, int role) {
- switch (role) {
- case Qt::DisplayRole: return QVariant(nameLine(item));
- case DetailTextRole: return QVariant(detailLine(item));
- default: return QVariant();
- }
+ switch (role) {
+ case Qt::DisplayRole: return QVariant(nameLine(item));
+ case DetailTextRole: return QVariant(detailLine(item));
+ default: return QVariant();
+ }
}
QString UserSearchModel::nameLine(UserSearchResult* item) {
- QString result;
- const std::map<std::string, std::string> fields = item->getFields();
- std::map<std::string, std::string>::const_iterator first = fields.find("first");
- if (first != fields.end()) {
- result += P2QSTRING((*first).second);
- }
- std::map<std::string, std::string>::const_iterator last = fields.find("last");
- if (last != fields.end()) {
- if (!result.isEmpty()) {
- result += " ";
- }
- result += P2QSTRING((*last).second);
- }
- if (result.isEmpty()) {
- result = P2QSTRING(item->getJID().toString());
- }
- return result;
+ QString result;
+ const std::map<std::string, std::string> fields = item->getFields();
+ std::map<std::string, std::string>::const_iterator first = fields.find("first");
+ if (first != fields.end()) {
+ result += P2QSTRING((*first).second);
+ }
+ std::map<std::string, std::string>::const_iterator last = fields.find("last");
+ if (last != fields.end()) {
+ if (!result.isEmpty()) {
+ result += " ";
+ }
+ result += P2QSTRING((*last).second);
+ }
+ if (result.isEmpty()) {
+ result = P2QSTRING(item->getJID().toString());
+ }
+ return result;
}
QString UserSearchModel::detailLine(UserSearchResult* item) {
- return P2QSTRING(item->getJID().toString());
+ return P2QSTRING(item->getJID().toString());
}
QModelIndex UserSearchModel::index(int row, int column, const QModelIndex & parent) const {
- if (!hasIndex(row, column, parent)) {
- return QModelIndex();
- }
- return row < static_cast<int>(results_.size()) ? createIndex(row, column, reinterpret_cast<void*>(const_cast<UserSearchResult*>(&(results_[row])))) : QModelIndex();
+ if (!hasIndex(row, column, parent)) {
+ return QModelIndex();
+ }
+ return row < static_cast<int>(results_.size()) ? createIndex(row, column, reinterpret_cast<void*>(const_cast<UserSearchResult*>(&(results_[row])))) : QModelIndex();
}
QModelIndex UserSearchModel::parent(const QModelIndex& /*index*/) const {
- return QModelIndex();
+ return QModelIndex();
}
int UserSearchModel::rowCount(const QModelIndex& parentIndex) const {
- if (!parentIndex.isValid()) {
- return results_.size();
- }
- return 0;
+ if (!parentIndex.isValid()) {
+ return results_.size();
+ }
+ return 0;
}
}
diff --git a/Swift/QtUI/UserSearch/UserSearchModel.h b/Swift/QtUI/UserSearch/UserSearchModel.h
index 5048100..a3940da 100644
--- a/Swift/QtUI/UserSearch/UserSearchModel.h
+++ b/Swift/QtUI/UserSearch/UserSearchModel.h
@@ -1,41 +1,41 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
#pragma once
-#include <boost/shared_ptr.hpp>
+#include <memory>
#include <QAbstractItemModel>
#include <QList>
-#include "Swift/Controllers/Chat/UserSearchController.h"
+#include <Swift/Controllers/Chat/UserSearchController.h>
namespace Swift {
- class UserSearchModel : public QAbstractItemModel {
- Q_OBJECT
- public:
- enum UserItemRoles {
- DetailTextRole = Qt::UserRole/*,
- AvatarRole = Qt::UserRole + 1,
- PresenceIconRole = Qt::UserRole + 2,
- StatusShowTypeRole = Qt::UserRole + 3*/
- };
- UserSearchModel();
- void clear();
- void setResults(const std::vector<UserSearchResult>& results);
- int columnCount(const QModelIndex& parent = QModelIndex()) const;
- QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
- static QVariant data(UserSearchResult* item, int role);
- QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
- QModelIndex parent(const QModelIndex& index) const;
- int rowCount(const QModelIndex& parent = QModelIndex()) const;
- private:
- static QString nameLine(UserSearchResult* item);
- static QString detailLine(UserSearchResult* item);
- std::vector<UserSearchResult> results_;
- };
+ class UserSearchModel : public QAbstractItemModel {
+ Q_OBJECT
+ public:
+ enum UserItemRoles {
+ DetailTextRole = Qt::UserRole/*,
+ AvatarRole = Qt::UserRole + 1,
+ PresenceIconRole = Qt::UserRole + 2,
+ StatusShowTypeRole = Qt::UserRole + 3*/
+ };
+ UserSearchModel();
+ void clear();
+ void setResults(const std::vector<UserSearchResult>& results);
+ int columnCount(const QModelIndex& parent = QModelIndex()) const;
+ QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
+ static QVariant data(UserSearchResult* item, int role);
+ QModelIndex index(int row, int column, const QModelIndex & parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex& index) const;
+ int rowCount(const QModelIndex& parent = QModelIndex()) const;
+ private:
+ static QString nameLine(UserSearchResult* item);
+ static QString detailLine(UserSearchResult* item);
+ std::vector<UserSearchResult> results_;
+ };
}
diff --git a/Swift/QtUI/Whiteboard/ColorWidget.cpp b/Swift/QtUI/Whiteboard/ColorWidget.cpp
index e96b760..7669ecc 100644
--- a/Swift/QtUI/Whiteboard/ColorWidget.cpp
+++ b/Swift/QtUI/Whiteboard/ColorWidget.cpp
@@ -4,34 +4,41 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+
+#include <Swift/QtUI/Whiteboard/ColorWidget.h>
-#include "ColorWidget.h"
-#include <QPainter>
#include <QMouseEvent>
+#include <QPainter>
namespace Swift {
- ColorWidget::ColorWidget(QWidget* parent) : QWidget(parent) {
- setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
- }
-
- QSize ColorWidget::sizeHint() const {
- return QSize(20, 20);
- }
-
- void ColorWidget::setColor(QColor color) {
- this->color = color;
- update();
- }
-
- void ColorWidget::paintEvent(QPaintEvent* /*event*/) {
- QPainter painter(this);
- painter.fillRect(0, 0, 20, 20, color);
- }
-
- void ColorWidget::mouseReleaseEvent(QMouseEvent* event) {
- if (event->button() == Qt::LeftButton) {
- emit clicked();
- }
- }
+ ColorWidget::ColorWidget(QWidget* parent) : QWidget(parent) {
+ setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
+ }
+
+ QSize ColorWidget::sizeHint() const {
+ return QSize(20, 20);
+ }
+
+ void ColorWidget::setColor(QColor color) {
+ this->color = color;
+ update();
+ }
+
+ void ColorWidget::paintEvent(QPaintEvent* /*event*/) {
+ QPainter painter(this);
+ painter.fillRect(0, 0, 20, 20, color);
+ }
+
+ void ColorWidget::mouseReleaseEvent(QMouseEvent* event) {
+ if (event->button() == Qt::LeftButton) {
+ emit clicked();
+ }
+ }
}
diff --git a/Swift/QtUI/Whiteboard/ColorWidget.h b/Swift/QtUI/Whiteboard/ColorWidget.h
index ae1af0f..56ada0c 100644
--- a/Swift/QtUI/Whiteboard/ColorWidget.h
+++ b/Swift/QtUI/Whiteboard/ColorWidget.h
@@ -4,30 +4,36 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <QWidget>
namespace Swift {
- class ColorWidget : public QWidget {
- Q_OBJECT
- public:
- ColorWidget(QWidget* parent = 0);
- QSize sizeHint() const;
+ class ColorWidget : public QWidget {
+ Q_OBJECT
+ public:
+ ColorWidget(QWidget* parent = nullptr);
+ QSize sizeHint() const;
- public slots:
- void setColor(QColor color);
+ public slots:
+ void setColor(QColor color);
- private:
- QColor color;
+ private:
+ QColor color;
- protected:
- void paintEvent(QPaintEvent* /*event*/);
- void mouseReleaseEvent(QMouseEvent* event);
+ protected:
+ void paintEvent(QPaintEvent* /*event*/);
+ void mouseReleaseEvent(QMouseEvent* event);
- signals:
- void clicked();
+ signals:
+ void clicked();
- };
+ };
}
diff --git a/Swift/QtUI/Whiteboard/FreehandLineItem.cpp b/Swift/QtUI/Whiteboard/FreehandLineItem.cpp
index 8821062..4ac93b8 100644
--- a/Swift/QtUI/Whiteboard/FreehandLineItem.cpp
+++ b/Swift/QtUI/Whiteboard/FreehandLineItem.cpp
@@ -4,94 +4,99 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "FreehandLineItem.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+#include <Swift/QtUI/Whiteboard/FreehandLineItem.h>
namespace Swift {
- FreehandLineItem::FreehandLineItem(QGraphicsItem* parent) : QGraphicsItem(parent) {
- }
+ FreehandLineItem::FreehandLineItem(QGraphicsItem* parent) : QGraphicsItem(parent) {
+ }
- QRectF FreehandLineItem::boundingRect() const
- {
- return boundRect;
- }
+ QRectF FreehandLineItem::boundingRect() const
+ {
+ return boundRect;
+ }
- void FreehandLineItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
- {
- painter->setPen(pen_);
- if (points_.size() > 0) {
- QVector<QPointF>::const_iterator it = points_.begin();
- QPointF previous = *it;
- ++it;
- for (; it != points_.end(); ++it) {
- painter->drawLine(previous, *it);
- previous = *it;
- }
- }
- }
+ void FreehandLineItem::paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/)
+ {
+ painter->setPen(pen_);
+ if (points_.size() > 0) {
+ QVector<QPointF>::const_iterator it = points_.begin();
+ QPointF previous = *it;
+ ++it;
+ for (; it != points_.end(); ++it) {
+ painter->drawLine(previous, *it);
+ previous = *it;
+ }
+ }
+ }
- void FreehandLineItem::setStartPoint(QPointF point)
- {
- points_.clear();
- points_.append(point);
- QRectF rect(point, point);
- prepareGeometryChange();
- boundRect = rect;
- }
+ void FreehandLineItem::setStartPoint(QPointF point)
+ {
+ points_.clear();
+ points_.append(point);
+ QRectF rect(point, point);
+ prepareGeometryChange();
+ boundRect = rect;
+ }
- void FreehandLineItem::lineTo(QPointF point)
- {
- qreal x1, x2, y1, y2;
- x1 = points_.last().x();
- x2 = point.x();
- y1 = points_.last().y();
- y2 = point.y();
- if (x1 > x2) {
- qreal temp = x1;
- x1 = x2;
- x2 = temp;
- }
- if (y1 > y2) {
- qreal temp = y1;
- y1 = y2;
- y2 = temp;
- }
- QRectF rect(x1-1, y1-1, x2+1-x1, y2+1-y1);
+ void FreehandLineItem::lineTo(QPointF point)
+ {
+ qreal x1, x2, y1, y2;
+ x1 = points_.last().x();
+ x2 = point.x();
+ y1 = points_.last().y();
+ y2 = point.y();
+ if (x1 > x2) {
+ qreal temp = x1;
+ x1 = x2;
+ x2 = temp;
+ }
+ if (y1 > y2) {
+ qreal temp = y1;
+ y1 = y2;
+ y2 = temp;
+ }
+ QRectF rect(x1-1, y1-1, x2+1-x1, y2+1-y1);
- points_.append(point);
+ points_.append(point);
- prepareGeometryChange();
- boundRect |= rect;
- }
+ prepareGeometryChange();
+ boundRect |= rect;
+ }
- bool FreehandLineItem::collidesWithPath(const QPainterPath& path, Qt::ItemSelectionMode /*mode*/) const
- {
- QVector<QPointF>::const_iterator it;
- QSizeF size(1,1);
- for (it = points_.begin(); it != points_.end(); ++it) {
- if (path.intersects(QRectF(*it, size))) {
- return true;
- }
- }
- return false;
- }
+ bool FreehandLineItem::collidesWithPath(const QPainterPath& path, Qt::ItemSelectionMode /*mode*/) const
+ {
+ QVector<QPointF>::const_iterator it;
+ QSizeF size(1,1);
+ for (it = points_.begin(); it != points_.end(); ++it) {
+ if (path.intersects(QRectF(*it, size))) {
+ return true;
+ }
+ }
+ return false;
+ }
- void FreehandLineItem::setPen(const QPen& pen)
- {
- pen_ = pen;
- update(boundRect);
- }
+ void FreehandLineItem::setPen(const QPen& pen)
+ {
+ pen_ = pen;
+ update(boundRect);
+ }
- QPen FreehandLineItem::pen() const
- {
- return pen_;
- }
+ QPen FreehandLineItem::pen() const
+ {
+ return pen_;
+ }
- const QVector<QPointF>& FreehandLineItem::points() const {
- return points_;
- }
+ const QVector<QPointF>& FreehandLineItem::points() const {
+ return points_;
+ }
- int FreehandLineItem::type() const {
- return Type;
- }
+ int FreehandLineItem::type() const {
+ return Type;
+ }
}
diff --git a/Swift/QtUI/Whiteboard/FreehandLineItem.h b/Swift/QtUI/Whiteboard/FreehandLineItem.h
index b1af3d1..5b83d95 100644
--- a/Swift/QtUI/Whiteboard/FreehandLineItem.h
+++ b/Swift/QtUI/Whiteboard/FreehandLineItem.h
@@ -4,30 +4,37 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
+#include <iostream>
+
#include <QGraphicsItem>
#include <QPainter>
-#include <iostream>
namespace Swift {
- class FreehandLineItem : public QGraphicsItem {
- public:
- enum {Type = UserType + 1};
- FreehandLineItem(QGraphicsItem* parent = 0);
- QRectF boundingRect() const;
- void paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/ = 0);
- void setStartPoint(QPointF point);
- void lineTo(QPointF point);
- bool collidesWithPath(const QPainterPath& path, Qt::ItemSelectionMode /*mode*/ = Qt::IntersectsItemShape) const;
- void setPen(const QPen& pen);
- QPen pen() const;
- const QVector<QPointF>& points() const;
- int type() const;
+ class FreehandLineItem : public QGraphicsItem {
+ public:
+ enum {Type = UserType + 1};
+ FreehandLineItem(QGraphicsItem* parent = nullptr);
+ QRectF boundingRect() const;
+ void paint(QPainter* painter, const QStyleOptionGraphicsItem* /*option*/, QWidget* /*widget*/ = nullptr);
+ void setStartPoint(QPointF point);
+ void lineTo(QPointF point);
+ bool collidesWithPath(const QPainterPath& path, Qt::ItemSelectionMode /*mode*/ = Qt::IntersectsItemShape) const;
+ void setPen(const QPen& pen);
+ QPen pen() const;
+ const QVector<QPointF>& points() const;
+ int type() const;
- private:
- QPen pen_;
- QVector<QPointF> points_;
- QRectF boundRect;
- };
+ private:
+ QPen pen_;
+ QVector<QPointF> points_;
+ QRectF boundRect;
+ };
}
diff --git a/Swift/QtUI/Whiteboard/GView.cpp b/Swift/QtUI/Whiteboard/GView.cpp
index f92322a..80061fd 100644
--- a/Swift/QtUI/Whiteboard/GView.cpp
+++ b/Swift/QtUI/Whiteboard/GView.cpp
@@ -4,493 +4,500 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "GView.h"
-#include <QtSwiftUtil.h>
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/Whiteboard/GView.h>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
namespace Swift {
- GView::GView(QGraphicsScene* scene, QWidget* parent) : QGraphicsView(scene, parent), zValue(0), mousePressed(false), brush(QColor(Qt::white)), defaultBrush(QColor(Qt::white)), mode(GView::Select), lastItem(NULL), selectionRect(NULL), textDialog(NULL) {
- }
-
- void GView::setLineWidth(int i) {
- pen.setWidth(i);
- if (selectionRect) {
- QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
- changePenAndBrush(selectionRect->data(1).value<QGraphicsItem*>(), pen, brush);
- lastItemChanged(item, items_.indexOf(item)+1, Update);
- } else {
- defaultPen.setWidth(i);
- }
- }
-
- void GView::setLineColor(QColor color) {
- pen.setColor(color);
- if (selectionRect) {
- QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
- changePenAndBrush(selectionRect->data(1).value<QGraphicsItem*>(), pen, brush);
- lastItemChanged(item, items_.indexOf(item)+1, Update);
- } else {
- defaultPen.setColor(color);
- }
- lineColorChanged(color);
- }
-
- QColor GView::getLineColor() {
- return pen.color();
- }
-
- void GView::setBrushColor(QColor color) {
- brush.setColor(color);
- if (selectionRect) {
- QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
- changePenAndBrush(selectionRect->data(1).value<QGraphicsItem*>(), pen, brush);
- lastItemChanged(item, items_.indexOf(item)+1, Update);
- } else {
- defaultBrush.setColor(color);
- }
- brushColorChanged(color);
- }
-
- QColor GView::getBrushColor() {
- return brush.color();
- }
-
- void GView::setMode(Mode mode) {
- this->mode = mode;
- lastItem = 0;
- deselect();
- }
-
- void GView::addItem(QGraphicsItem* item, QString id, int pos) {
- itemsMap_.insert(id, item);
- if (pos > items_.size()) {
- item->setZValue(zValue++);
- scene()->addItem(item);
- items_.append(item);
- } else {
- QGraphicsItem* temp = items_.at(pos-1);
- item->setZValue(temp->zValue());
- scene()->addItem(item);
- item->stackBefore(temp);
- items_.insert(pos-1, item);
- }
- }
-
- void GView::clear() {
- scene()->clear();
- items_.clear();
- itemsMap_.clear();
- lastItem = 0;
- selectionRect = 0;
- brush = QBrush(QColor(Qt::white));
- defaultBrush = QBrush(QColor(Qt::white));
- pen = QPen();
- pen.setWidth(1);
- defaultPen = pen;
- lineWidthChanged(1);
- lineColorChanged(pen.color());
- brushColorChanged(brush.color());
- }
-
- QGraphicsItem* GView::getItem(QString id) {
- return itemsMap_.value(id);
- }
-
- void GView::deleteItem(QString id) {
- deselect(id);
- QGraphicsItem* item = itemsMap_.value(id);
- items_.removeOne(item);
- itemsMap_.remove(id);
- scene()->removeItem(item);
- delete item;
- }
-
- QString GView::getNewID() {
- return P2QSTRING(idGenerator.generateID());
- }
-
- void GView::mouseMoveEvent(QMouseEvent* event)
- {
- if (!mousePressed) {
- return;
- }
-
- if (mode == Line) {
- QGraphicsLineItem* item = qgraphicsitem_cast<QGraphicsLineItem*>(lastItem);
- if(item != 0) {
- QLineF line = item->line();
- line.setP1(this->mapToScene(event->pos()));
- item->setLine(line);
-
- }
- }
- else if (mode == Rect) {
- QGraphicsRectItem* item = qgraphicsitem_cast<QGraphicsRectItem*>(lastItem);
- if (item != 0) {
- QPointF beginPoint = item->data(0).toPointF();
- QPointF newPoint = this->mapToScene(event->pos());
- QRectF rect = item->rect();
- if (beginPoint.x() <= newPoint.x() && beginPoint.y() <= newPoint.y()) {
- rect.setTopLeft(beginPoint);
- rect.setBottomRight(newPoint);
- }
- else if (beginPoint.x() > newPoint.x() && beginPoint.y() <= newPoint.y()) {
- rect.setTopRight(beginPoint);
- rect.setBottomLeft(newPoint);
- }
- else if (beginPoint.x() <= newPoint.x() && beginPoint.y() > newPoint.y()) {
- rect.setBottomLeft(beginPoint);
- rect.setTopRight(newPoint);
- }
- else if (beginPoint.x() > newPoint.x() && beginPoint.y() > newPoint.y()) {
- rect.setBottomRight(beginPoint);
- rect.setTopLeft(newPoint);
- }
- item->setRect(rect);
- }
- }
- else if (mode == Circle) {
- QGraphicsEllipseItem* item = qgraphicsitem_cast<QGraphicsEllipseItem*>(lastItem);
- QPainterPath path;
- QPointF beginPoint = item->data(0).toPointF();
- QPointF newPoint = this->mapToScene(event->pos());
- QRectF rect = item->rect();
- if (beginPoint.x() <= newPoint.x() && beginPoint.y() <= newPoint.y()) {
- rect.setTopLeft(beginPoint);
- rect.setBottomRight(newPoint);
- }
- else if (beginPoint.x() > newPoint.x() && beginPoint.y() <= newPoint.y()) {
- rect.setTopRight(beginPoint);
- rect.setBottomLeft(newPoint);
- }
- else if (beginPoint.x() <= newPoint.x() && beginPoint.y() > newPoint.y()) {
- rect.setBottomLeft(beginPoint);
- rect.setTopRight(newPoint);
- }
- else if (beginPoint.x() > newPoint.x() && beginPoint.y() > newPoint.y()) {
- rect.setBottomRight(beginPoint);
- rect.setTopLeft(newPoint);
- }
-
- item->setRect(rect);
- }
- else if (mode == HandLine) {
- FreehandLineItem* item = qgraphicsitem_cast<FreehandLineItem*>(lastItem);
- if (item != 0) {
- QPointF newPoint = this->mapToScene(event->pos());
- item->lineTo(newPoint);
- }
- }
- else if (mode == Polygon) {
- QGraphicsPolygonItem* item = qgraphicsitem_cast<QGraphicsPolygonItem*>(lastItem);
- QPointF newPoint = this->mapToScene(event->pos());
- QPolygonF polygon = item->polygon();
- polygon.erase(polygon.end()-1);
- polygon.append(newPoint);
- item->setPolygon(polygon);
- }
- else if (mode == Select) {
- QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
- if (item != 0) {
- QPainterPath path;
- QPointF beginPoint = selectionRect->data(0).toPointF();
- QPointF newPoint = this->mapToScene(event->pos());
- item->setPos(beginPoint + newPoint);
- selectionRect->setPos(beginPoint + newPoint);
- }
- }
- }
-
- void GView::mousePressEvent(QMouseEvent *event)
- {
- mousePressed = true;
- deselect();
- if (mode == Line) {
- QPointF point = this->mapToScene(event->pos());
- QGraphicsItem* item = scene()->addLine(point.x(), point.y(), point.x(), point.y(), pen);
- QString id = getNewID();
- item->setZValue(10000000);
- item->setData(100, id);
- item->setData(101, items_.size());
- lastItem = item;
- }
- else if (mode == Rect) {
- QPointF point = this->mapToScene(event->pos());
- QGraphicsRectItem* item = scene()->addRect(point.x(), point.y(), 0, 0, pen, brush);
- QString id = getNewID();
- item->setZValue(10000000);
- item->setData(0, point);
- item->setData(100, id);
- item->setData(101, items_.size());
- lastItem = item;
- }
- else if (mode == Rubber) {
- QPointF point = this->mapToScene(event->pos());
- int w = pen.width();
- QRectF rect(point.x()-w, point.y()-w, w*2, w*2);
- QList<QGraphicsItem*> list = scene()->items(rect);
- if (!list.isEmpty())
- {
- QGraphicsItem* item = scene()->items(rect).first();
- QString id = item->data(100).toString();
- int pos = items_.indexOf(item)+1;
- itemDeleted(id, pos);
- deleteItem(id);
- }
- }
- else if (mode == Circle) {
- QPointF point = this->mapToScene(event->pos());
- QGraphicsEllipseItem* item = scene()->addEllipse(point.x(), point.y(), 0, 0, pen, brush);
- QString id = getNewID();
- item->setZValue(10000000);
- item->setData(0, point);
- item->setData(100, id);
- item->setData(101, items_.size());
- lastItem = item;
- }
- else if (mode == HandLine) {
- QPointF point = this->mapToScene(event->pos());
- FreehandLineItem* item = new FreehandLineItem;
- QString id = getNewID();
- item->setPen(pen);
- item->setStartPoint(point);
- item->setZValue(10000000);
- item->setData(100, id);
- item->setData(101, items_.size());
- scene()->addItem(item);
- lastItem = item;
- }
- else if (mode == Text) {
- QPointF point = this->mapToScene(event->pos());
- QGraphicsTextItem* item = scene()->addText("");
- QString id = getNewID();
- item->setData(100, id);
- item->setData(101, items_.size());
- item->setDefaultTextColor(pen.color());
- textDialog = new TextDialog(item, this);
- connect(textDialog, SIGNAL(accepted(QGraphicsTextItem*)), this, SLOT(handleTextItemModified(QGraphicsTextItem*)));
- textDialog->setAttribute(Qt::WA_DeleteOnClose);
- textDialog->show();
- item->setPos(point);
- lastItem = item;
- }
- else if (mode == Polygon) {
- QPointF point = this->mapToScene(event->pos());
- QGraphicsPolygonItem* item = dynamic_cast<QGraphicsPolygonItem*>(lastItem);
- if (item == 0) {
- QPolygonF polygon;
- polygon.append(point);
- polygon.append(point);
- item = scene()->addPolygon(polygon, pen, brush);
- QString id = getNewID();
- item->setZValue(10000000);
- item->setData(100, id);
- item->setData(101, items_.size());
- lastItem = item;
- }
- else {
- QPolygonF polygon;
- polygon = item->polygon();
- polygon.append(point);
- item->setPolygon(polygon);
- }
- }
- else if (mode == Select) {
- QPointF point = this->mapToScene(event->pos());
- int w = pen.width();
- if (w == 0) {
- w = 1;
- }
- QRectF rect(point.x()-w, point.y()-w, w*2, w*2);
- QList<QGraphicsItem*> list = scene()->items(rect);
- if (!list.isEmpty()) {
- QPen pen;
- pen.setColor(QColor(Qt::gray));
- pen.setStyle(Qt::DashLine);
- QGraphicsItem *item = scene()->items(rect).first();
- selectionRect = scene()->addRect(item->boundingRect(), pen);
- selectionRect->setZValue(1000000);
- selectionRect->setData(0, item->pos()-point);
- selectionRect->setPos(item->pos());
- QVariant var(QVariant::UserType);
- var.setValue(item);
- selectionRect->setData(1, var);
- setActualPenAndBrushFromItem(item);
- }
- }
- }
-
- void GView::mouseReleaseEvent(QMouseEvent* /*event*/)
- {
- mousePressed = false;
- QGraphicsPolygonItem* polygon = dynamic_cast<QGraphicsPolygonItem*>(lastItem);
- if (polygon && polygon->polygon().size() >= 3) {
- lastItemChanged(polygon, items_.indexOf(polygon)+1, Update);
- } else if (lastItem) {
- zValue++;
- lastItem->setZValue(zValue++);
- items_.append(lastItem);
- itemsMap_.insert(lastItem->data(100).toString(), lastItem);
-
- lastItemChanged(lastItem, items_.size(), New);
- } else if (selectionRect){
- QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
- lastItemChanged(item, items_.indexOf(item)+1, Update);
- }
- }
-
-
- void GView::handleTextItemModified(QGraphicsTextItem* item) {
- lastItemChanged(item, item->data(101).toInt(), Update);
- }
-
- void GView::moveUpSelectedItem()
- {
- if (selectionRect) {
- QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
- int pos = items_.indexOf(item);
- if (pos < items_.size()-1) {
- lastItemChanged(item, pos+1, MoveUp);
- move(item, pos+2);
- }
- }
- }
-
- void GView::moveDownSelectedItem()
- {
- if (selectionRect) {
- QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
- int pos = items_.indexOf(item);
- if (pos > 0) {
- lastItemChanged(item, pos+1, MoveDown);
- move(item, pos);
- }
- }
- }
-
- void GView::move(QGraphicsItem* item, int npos) {
- int pos = items_.indexOf(item);
- QGraphicsItem* itemAfter = NULL;
- if (npos-1 > pos) {
- if (npos == items_.size()) {
- item->setZValue(zValue++);
- } else {
- itemAfter = items_.at(npos);
- }
-
- items_.insert(npos, item);
- items_.removeAt(pos);
- } else if (npos-1 < pos) {
- itemAfter = items_.at(npos-1);
- items_.insert(npos-1, item);
- items_.removeAt(pos+1);
- }
- if (itemAfter) {
- item->setZValue(itemAfter->zValue());
- item->stackBefore(itemAfter);
- }
- }
-
- void GView::changePenAndBrush(QGraphicsItem* item, QPen pen, QBrush brush) {
- QGraphicsLineItem* lineItem = qgraphicsitem_cast<QGraphicsLineItem*>(item);
- if (lineItem) {
- lineItem->setPen(pen);
- }
-
- FreehandLineItem* handLineItem = qgraphicsitem_cast<FreehandLineItem*>(item);
- if (handLineItem) {
- handLineItem->setPen(pen);
- }
-
- QGraphicsRectItem* rectItem = qgraphicsitem_cast<QGraphicsRectItem*>(item);
- if (rectItem) {
- rectItem->setPen(pen);
- rectItem->setBrush(brush);
- }
-
- QGraphicsTextItem* textItem = qgraphicsitem_cast<QGraphicsTextItem*>(item);
- if (textItem) {
- textItem->setDefaultTextColor(pen.color());
- }
-
- QGraphicsPolygonItem* polygonItem = qgraphicsitem_cast<QGraphicsPolygonItem*>(item);
- if (polygonItem) {
- polygonItem->setPen(pen);
- polygonItem->setBrush(brush);
- }
-
- QGraphicsEllipseItem* ellipseItem = qgraphicsitem_cast<QGraphicsEllipseItem*>(item);
- if (ellipseItem) {
- ellipseItem->setPen(pen);
- ellipseItem->setBrush(brush);
- }
- lineColorChanged(pen.color());
- brushColorChanged(brush.color());
- }
-
- void GView::setActualPenAndBrushFromItem(QGraphicsItem* item) {
- QGraphicsLineItem* lineItem = qgraphicsitem_cast<QGraphicsLineItem*>(item);
- if (lineItem) {
- pen = lineItem->pen();
- }
-
- FreehandLineItem* handLineItem = qgraphicsitem_cast<FreehandLineItem*>(item);
- if (handLineItem) {
- pen = handLineItem->pen();
- }
-
- QGraphicsRectItem* rectItem = qgraphicsitem_cast<QGraphicsRectItem*>(item);
- if (rectItem) {
- pen = rectItem->pen();
- brush = rectItem->brush();
- }
-
- QGraphicsTextItem* textItem = qgraphicsitem_cast<QGraphicsTextItem*>(item);
- if (textItem) {
- pen.setColor(textItem->defaultTextColor());
- }
-
- QGraphicsPolygonItem* polygonItem = qgraphicsitem_cast<QGraphicsPolygonItem*>(item);
- if (polygonItem) {
- pen = polygonItem->pen();
- brush = polygonItem->brush();
- }
-
- QGraphicsEllipseItem* ellipseItem = qgraphicsitem_cast<QGraphicsEllipseItem*>(item);
- if (ellipseItem) {
- pen = ellipseItem->pen();
- brush = ellipseItem->brush();
- }
- lineWidthChanged(pen.width());
- lineColorChanged(pen.color());
- brushColorChanged(brush.color());
- }
-
- void GView::deselect() {
- if (selectionRect != 0) {
- pen = defaultPen;
- brush = defaultBrush;
- scene()->removeItem(selectionRect);
- delete selectionRect;
- selectionRect = 0;
- lineWidthChanged(pen.width());
- lineColorChanged(pen.color());
- brushColorChanged(brush.color());
- }
- }
-
- void GView::deselect(QString id) {
- if (selectionRect != 0) {
- QGraphicsItem* item = getItem(id);
- if (item && selectionRect->data(1).value<QGraphicsItem*>() == item) {
- pen = defaultPen;
- brush = defaultBrush;
- scene()->removeItem(selectionRect);
- delete selectionRect;
- selectionRect = 0;
- lineWidthChanged(pen.width());
- lineColorChanged(pen.color());
- brushColorChanged(brush.color());
- }
- }
- }
+ GView::GView(QGraphicsScene* scene, QWidget* parent) : QGraphicsView(scene, parent), zValue(0), mousePressed(false), brush(QColor(Qt::white)), defaultBrush(QColor(Qt::white)), mode(GView::Select), lastItem(nullptr), selectionRect(nullptr), textDialog(nullptr) {
+ }
+
+ void GView::setLineWidth(int i) {
+ pen.setWidth(i);
+ if (selectionRect) {
+ QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
+ changePenAndBrush(selectionRect->data(1).value<QGraphicsItem*>(), pen, brush);
+ lastItemChanged(item, items_.indexOf(item)+1, Update);
+ } else {
+ defaultPen.setWidth(i);
+ }
+ }
+
+ void GView::setLineColor(QColor color) {
+ pen.setColor(color);
+ if (selectionRect) {
+ QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
+ changePenAndBrush(selectionRect->data(1).value<QGraphicsItem*>(), pen, brush);
+ lastItemChanged(item, items_.indexOf(item)+1, Update);
+ } else {
+ defaultPen.setColor(color);
+ }
+ lineColorChanged(color);
+ }
+
+ QColor GView::getLineColor() {
+ return pen.color();
+ }
+
+ void GView::setBrushColor(QColor color) {
+ brush.setColor(color);
+ if (selectionRect) {
+ QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
+ changePenAndBrush(selectionRect->data(1).value<QGraphicsItem*>(), pen, brush);
+ lastItemChanged(item, items_.indexOf(item)+1, Update);
+ } else {
+ defaultBrush.setColor(color);
+ }
+ brushColorChanged(color);
+ }
+
+ QColor GView::getBrushColor() {
+ return brush.color();
+ }
+
+ void GView::setMode(Mode mode) {
+ this->mode = mode;
+ lastItem = nullptr;
+ deselect();
+ }
+
+ void GView::addItem(QGraphicsItem* item, QString id, int pos) {
+ itemsMap_.insert(id, item);
+ if (pos > items_.size()) {
+ item->setZValue(zValue++);
+ scene()->addItem(item);
+ items_.append(item);
+ } else {
+ QGraphicsItem* temp = items_.at(pos-1);
+ item->setZValue(temp->zValue());
+ scene()->addItem(item);
+ item->stackBefore(temp);
+ items_.insert(pos-1, item);
+ }
+ }
+
+ void GView::clear() {
+ scene()->clear();
+ items_.clear();
+ itemsMap_.clear();
+ lastItem = nullptr;
+ selectionRect = nullptr;
+ brush = QBrush(QColor(Qt::white));
+ defaultBrush = QBrush(QColor(Qt::white));
+ pen = QPen();
+ pen.setWidth(1);
+ defaultPen = pen;
+ lineWidthChanged(1);
+ lineColorChanged(pen.color());
+ brushColorChanged(brush.color());
+ }
+
+ QGraphicsItem* GView::getItem(QString id) {
+ return itemsMap_.value(id);
+ }
+
+ void GView::deleteItem(QString id) {
+ deselect(id);
+ QGraphicsItem* item = itemsMap_.value(id);
+ items_.removeOne(item);
+ itemsMap_.remove(id);
+ scene()->removeItem(item);
+ delete item;
+ }
+
+ QString GView::getNewID() {
+ return P2QSTRING(idGenerator.generateID());
+ }
+
+ void GView::mouseMoveEvent(QMouseEvent* event)
+ {
+ if (!mousePressed) {
+ return;
+ }
+
+ if (mode == Line) {
+ QGraphicsLineItem* item = qgraphicsitem_cast<QGraphicsLineItem*>(lastItem);
+ if(item != nullptr) {
+ QLineF line = item->line();
+ line.setP1(this->mapToScene(event->pos()));
+ item->setLine(line);
+
+ }
+ }
+ else if (mode == Rect) {
+ QGraphicsRectItem* item = qgraphicsitem_cast<QGraphicsRectItem*>(lastItem);
+ if (item != nullptr) {
+ QPointF beginPoint = item->data(0).toPointF();
+ QPointF newPoint = this->mapToScene(event->pos());
+ QRectF rect = item->rect();
+ if (beginPoint.x() <= newPoint.x() && beginPoint.y() <= newPoint.y()) {
+ rect.setTopLeft(beginPoint);
+ rect.setBottomRight(newPoint);
+ }
+ else if (beginPoint.x() > newPoint.x() && beginPoint.y() <= newPoint.y()) {
+ rect.setTopRight(beginPoint);
+ rect.setBottomLeft(newPoint);
+ }
+ else if (beginPoint.x() <= newPoint.x() && beginPoint.y() > newPoint.y()) {
+ rect.setBottomLeft(beginPoint);
+ rect.setTopRight(newPoint);
+ }
+ else if (beginPoint.x() > newPoint.x() && beginPoint.y() > newPoint.y()) {
+ rect.setBottomRight(beginPoint);
+ rect.setTopLeft(newPoint);
+ }
+ item->setRect(rect);
+ }
+ }
+ else if (mode == Circle) {
+ QGraphicsEllipseItem* item = qgraphicsitem_cast<QGraphicsEllipseItem*>(lastItem);
+ QPainterPath path;
+ QPointF beginPoint = item->data(0).toPointF();
+ QPointF newPoint = this->mapToScene(event->pos());
+ QRectF rect = item->rect();
+ if (beginPoint.x() <= newPoint.x() && beginPoint.y() <= newPoint.y()) {
+ rect.setTopLeft(beginPoint);
+ rect.setBottomRight(newPoint);
+ }
+ else if (beginPoint.x() > newPoint.x() && beginPoint.y() <= newPoint.y()) {
+ rect.setTopRight(beginPoint);
+ rect.setBottomLeft(newPoint);
+ }
+ else if (beginPoint.x() <= newPoint.x() && beginPoint.y() > newPoint.y()) {
+ rect.setBottomLeft(beginPoint);
+ rect.setTopRight(newPoint);
+ }
+ else if (beginPoint.x() > newPoint.x() && beginPoint.y() > newPoint.y()) {
+ rect.setBottomRight(beginPoint);
+ rect.setTopLeft(newPoint);
+ }
+
+ item->setRect(rect);
+ }
+ else if (mode == HandLine) {
+ FreehandLineItem* item = qgraphicsitem_cast<FreehandLineItem*>(lastItem);
+ if (item != nullptr) {
+ QPointF newPoint = this->mapToScene(event->pos());
+ item->lineTo(newPoint);
+ }
+ }
+ else if (mode == Polygon) {
+ QGraphicsPolygonItem* item = qgraphicsitem_cast<QGraphicsPolygonItem*>(lastItem);
+ QPointF newPoint = this->mapToScene(event->pos());
+ QPolygonF polygon = item->polygon();
+ polygon.erase(polygon.end()-1);
+ polygon.append(newPoint);
+ item->setPolygon(polygon);
+ }
+ else if (mode == Select) {
+ QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
+ if (item != nullptr) {
+ QPainterPath path;
+ QPointF beginPoint = selectionRect->data(0).toPointF();
+ QPointF newPoint = this->mapToScene(event->pos());
+ item->setPos(beginPoint + newPoint);
+ selectionRect->setPos(beginPoint + newPoint);
+ }
+ }
+ }
+
+ void GView::mousePressEvent(QMouseEvent *event)
+ {
+ mousePressed = true;
+ deselect();
+ if (mode == Line) {
+ QPointF point = this->mapToScene(event->pos());
+ QGraphicsItem* item = scene()->addLine(point.x(), point.y(), point.x(), point.y(), pen);
+ QString id = getNewID();
+ item->setZValue(10000000);
+ item->setData(100, id);
+ item->setData(101, items_.size());
+ lastItem = item;
+ }
+ else if (mode == Rect) {
+ QPointF point = this->mapToScene(event->pos());
+ QGraphicsRectItem* item = scene()->addRect(point.x(), point.y(), 0, 0, pen, brush);
+ QString id = getNewID();
+ item->setZValue(10000000);
+ item->setData(0, point);
+ item->setData(100, id);
+ item->setData(101, items_.size());
+ lastItem = item;
+ }
+ else if (mode == Rubber) {
+ QPointF point = this->mapToScene(event->pos());
+ int w = pen.width();
+ QRectF rect(point.x()-w, point.y()-w, w*2, w*2);
+ QList<QGraphicsItem*> list = scene()->items(rect);
+ if (!list.isEmpty())
+ {
+ QGraphicsItem* item = scene()->items(rect).first();
+ QString id = item->data(100).toString();
+ int pos = items_.indexOf(item)+1;
+ itemDeleted(id, pos);
+ deleteItem(id);
+ }
+ }
+ else if (mode == Circle) {
+ QPointF point = this->mapToScene(event->pos());
+ QGraphicsEllipseItem* item = scene()->addEllipse(point.x(), point.y(), 0, 0, pen, brush);
+ QString id = getNewID();
+ item->setZValue(10000000);
+ item->setData(0, point);
+ item->setData(100, id);
+ item->setData(101, items_.size());
+ lastItem = item;
+ }
+ else if (mode == HandLine) {
+ QPointF point = this->mapToScene(event->pos());
+ FreehandLineItem* item = new FreehandLineItem;
+ QString id = getNewID();
+ item->setPen(pen);
+ item->setStartPoint(point);
+ item->setZValue(10000000);
+ item->setData(100, id);
+ item->setData(101, items_.size());
+ scene()->addItem(item);
+ lastItem = item;
+ }
+ else if (mode == Text) {
+ QPointF point = this->mapToScene(event->pos());
+ QGraphicsTextItem* item = scene()->addText("");
+ QString id = getNewID();
+ item->setData(100, id);
+ item->setData(101, items_.size());
+ item->setDefaultTextColor(pen.color());
+ textDialog = new TextDialog(item, this);
+ connect(textDialog, SIGNAL(accepted(QGraphicsTextItem*)), this, SLOT(handleTextItemModified(QGraphicsTextItem*)));
+ textDialog->setAttribute(Qt::WA_DeleteOnClose);
+ textDialog->show();
+ item->setPos(point);
+ lastItem = item;
+ }
+ else if (mode == Polygon) {
+ QPointF point = this->mapToScene(event->pos());
+ QGraphicsPolygonItem* item = dynamic_cast<QGraphicsPolygonItem*>(lastItem);
+ if (item == nullptr) {
+ QPolygonF polygon;
+ polygon.append(point);
+ polygon.append(point);
+ item = scene()->addPolygon(polygon, pen, brush);
+ QString id = getNewID();
+ item->setZValue(10000000);
+ item->setData(100, id);
+ item->setData(101, items_.size());
+ lastItem = item;
+ }
+ else {
+ QPolygonF polygon;
+ polygon = item->polygon();
+ polygon.append(point);
+ item->setPolygon(polygon);
+ }
+ }
+ else if (mode == Select) {
+ QPointF point = this->mapToScene(event->pos());
+ int w = pen.width();
+ if (w == 0) {
+ w = 1;
+ }
+ QRectF rect(point.x()-w, point.y()-w, w*2, w*2);
+ QList<QGraphicsItem*> list = scene()->items(rect);
+ if (!list.isEmpty()) {
+ QPen pen;
+ pen.setColor(QColor(Qt::gray));
+ pen.setStyle(Qt::DashLine);
+ QGraphicsItem *item = scene()->items(rect).first();
+ selectionRect = scene()->addRect(item->boundingRect(), pen);
+ selectionRect->setZValue(1000000);
+ selectionRect->setData(0, item->pos()-point);
+ selectionRect->setPos(item->pos());
+ QVariant var(QVariant::UserType);
+ var.setValue(item);
+ selectionRect->setData(1, var);
+ setActualPenAndBrushFromItem(item);
+ }
+ }
+ }
+
+ void GView::mouseReleaseEvent(QMouseEvent* /*event*/)
+ {
+ mousePressed = false;
+ QGraphicsPolygonItem* polygon = dynamic_cast<QGraphicsPolygonItem*>(lastItem);
+ if (polygon && polygon->polygon().size() >= 3) {
+ lastItemChanged(polygon, items_.indexOf(polygon)+1, Update);
+ } else if (lastItem) {
+ zValue++;
+ lastItem->setZValue(zValue++);
+ items_.append(lastItem);
+ itemsMap_.insert(lastItem->data(100).toString(), lastItem);
+
+ lastItemChanged(lastItem, items_.size(), New);
+ } else if (selectionRect){
+ QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
+ lastItemChanged(item, items_.indexOf(item)+1, Update);
+ }
+ }
+
+
+ void GView::handleTextItemModified(QGraphicsTextItem* item) {
+ lastItemChanged(item, item->data(101).toInt(), Update);
+ }
+
+ void GView::moveUpSelectedItem()
+ {
+ if (selectionRect) {
+ QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
+ int pos = items_.indexOf(item);
+ if (pos < items_.size()-1) {
+ lastItemChanged(item, pos+1, MoveUp);
+ move(item, pos+2);
+ }
+ }
+ }
+
+ void GView::moveDownSelectedItem()
+ {
+ if (selectionRect) {
+ QGraphicsItem* item = selectionRect->data(1).value<QGraphicsItem*>();
+ int pos = items_.indexOf(item);
+ if (pos > 0) {
+ lastItemChanged(item, pos+1, MoveDown);
+ move(item, pos);
+ }
+ }
+ }
+
+ void GView::move(QGraphicsItem* item, int npos) {
+ int pos = items_.indexOf(item);
+ QGraphicsItem* itemAfter = nullptr;
+ if (npos-1 > pos) {
+ if (npos == items_.size()) {
+ item->setZValue(zValue++);
+ } else {
+ itemAfter = items_.at(npos);
+ }
+
+ items_.insert(npos, item);
+ items_.removeAt(pos);
+ } else if (npos-1 < pos) {
+ itemAfter = items_.at(npos-1);
+ items_.insert(npos-1, item);
+ items_.removeAt(pos+1);
+ }
+ if (itemAfter) {
+ item->setZValue(itemAfter->zValue());
+ item->stackBefore(itemAfter);
+ }
+ }
+
+ void GView::changePenAndBrush(QGraphicsItem* item, QPen pen, QBrush brush) {
+ QGraphicsLineItem* lineItem = qgraphicsitem_cast<QGraphicsLineItem*>(item);
+ if (lineItem) {
+ lineItem->setPen(pen);
+ }
+
+ FreehandLineItem* handLineItem = qgraphicsitem_cast<FreehandLineItem*>(item);
+ if (handLineItem) {
+ handLineItem->setPen(pen);
+ }
+
+ QGraphicsRectItem* rectItem = qgraphicsitem_cast<QGraphicsRectItem*>(item);
+ if (rectItem) {
+ rectItem->setPen(pen);
+ rectItem->setBrush(brush);
+ }
+
+ QGraphicsTextItem* textItem = qgraphicsitem_cast<QGraphicsTextItem*>(item);
+ if (textItem) {
+ textItem->setDefaultTextColor(pen.color());
+ }
+
+ QGraphicsPolygonItem* polygonItem = qgraphicsitem_cast<QGraphicsPolygonItem*>(item);
+ if (polygonItem) {
+ polygonItem->setPen(pen);
+ polygonItem->setBrush(brush);
+ }
+
+ QGraphicsEllipseItem* ellipseItem = qgraphicsitem_cast<QGraphicsEllipseItem*>(item);
+ if (ellipseItem) {
+ ellipseItem->setPen(pen);
+ ellipseItem->setBrush(brush);
+ }
+ lineColorChanged(pen.color());
+ brushColorChanged(brush.color());
+ }
+
+ void GView::setActualPenAndBrushFromItem(QGraphicsItem* item) {
+ QGraphicsLineItem* lineItem = qgraphicsitem_cast<QGraphicsLineItem*>(item);
+ if (lineItem) {
+ pen = lineItem->pen();
+ }
+
+ FreehandLineItem* handLineItem = qgraphicsitem_cast<FreehandLineItem*>(item);
+ if (handLineItem) {
+ pen = handLineItem->pen();
+ }
+
+ QGraphicsRectItem* rectItem = qgraphicsitem_cast<QGraphicsRectItem*>(item);
+ if (rectItem) {
+ pen = rectItem->pen();
+ brush = rectItem->brush();
+ }
+
+ QGraphicsTextItem* textItem = qgraphicsitem_cast<QGraphicsTextItem*>(item);
+ if (textItem) {
+ pen.setColor(textItem->defaultTextColor());
+ }
+
+ QGraphicsPolygonItem* polygonItem = qgraphicsitem_cast<QGraphicsPolygonItem*>(item);
+ if (polygonItem) {
+ pen = polygonItem->pen();
+ brush = polygonItem->brush();
+ }
+
+ QGraphicsEllipseItem* ellipseItem = qgraphicsitem_cast<QGraphicsEllipseItem*>(item);
+ if (ellipseItem) {
+ pen = ellipseItem->pen();
+ brush = ellipseItem->brush();
+ }
+ lineWidthChanged(pen.width());
+ lineColorChanged(pen.color());
+ brushColorChanged(brush.color());
+ }
+
+ void GView::deselect() {
+ if (selectionRect != nullptr) {
+ pen = defaultPen;
+ brush = defaultBrush;
+ scene()->removeItem(selectionRect);
+ delete selectionRect;
+ selectionRect = nullptr;
+ lineWidthChanged(pen.width());
+ lineColorChanged(pen.color());
+ brushColorChanged(brush.color());
+ }
+ }
+
+ void GView::deselect(QString id) {
+ if (selectionRect != nullptr) {
+ QGraphicsItem* item = getItem(id);
+ if (item && selectionRect->data(1).value<QGraphicsItem*>() == item) {
+ pen = defaultPen;
+ brush = defaultBrush;
+ scene()->removeItem(selectionRect);
+ delete selectionRect;
+ selectionRect = nullptr;
+ lineWidthChanged(pen.width());
+ lineColorChanged(pen.color());
+ brushColorChanged(brush.color());
+ }
+ }
+ }
}
diff --git a/Swift/QtUI/Whiteboard/GView.h b/Swift/QtUI/Whiteboard/GView.h
index bc64589..4af5a53 100644
--- a/Swift/QtUI/Whiteboard/GView.h
+++ b/Swift/QtUI/Whiteboard/GView.h
@@ -4,73 +4,81 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
-#include <QGraphicsView>
+#include <iostream>
+
#include <QGraphicsLineItem>
+#include <QGraphicsView>
#include <QMouseEvent>
#include <QPen>
-#include <iostream>
+
#include <Swiften/Base/IDGenerator.h>
-#include "TextDialog.h"
-#include "FreehandLineItem.h"
+#include <Swift/QtUI/Whiteboard/FreehandLineItem.h>
+#include <Swift/QtUI/Whiteboard/TextDialog.h>
namespace Swift {
- class GView : public QGraphicsView {
- Q_OBJECT
- public:
- enum Mode { Rubber, Line, Rect, Circle, HandLine, Text, Polygon, Select };
- enum Type { New, Update, MoveUp, MoveDown };
- GView(QGraphicsScene* scene, QWidget* parent = 0);
- void setLineWidth(int i);
- void setLineColor(QColor color);
- QColor getLineColor();
- void setBrushColor(QColor color);
- QColor getBrushColor();
- void setMode(Mode mode);
- void mouseMoveEvent(QMouseEvent* event);
- void mousePressEvent(QMouseEvent* event);
- void mouseReleaseEvent(QMouseEvent* /*event*/);
- void addItem(QGraphicsItem* item, QString id, int pos);
- void clear();
- QGraphicsItem* getItem(QString id);
- void deleteItem(QString id);
- QString getNewID();
- void move(QGraphicsItem* item, int npos);
- void deselect(QString id);
+ class GView : public QGraphicsView {
+ Q_OBJECT
+ public:
+ enum Mode { Rubber, Line, Rect, Circle, HandLine, Text, Polygon, Select };
+ enum Type { New, Update, MoveUp, MoveDown };
+ GView(QGraphicsScene* scene, QWidget* parent = nullptr);
+ void setLineWidth(int i);
+ void setLineColor(QColor color);
+ QColor getLineColor();
+ void setBrushColor(QColor color);
+ QColor getBrushColor();
+ void setMode(Mode mode);
+ void mouseMoveEvent(QMouseEvent* event);
+ void mousePressEvent(QMouseEvent* event);
+ void mouseReleaseEvent(QMouseEvent* /*event*/);
+ void addItem(QGraphicsItem* item, QString id, int pos);
+ void clear();
+ QGraphicsItem* getItem(QString id);
+ void deleteItem(QString id);
+ QString getNewID();
+ void move(QGraphicsItem* item, int npos);
+ void deselect(QString id);
- signals:
- void lastItemChanged(QGraphicsItem* item, int pos, GView::Type type);
- void itemDeleted(QString id, int pos);
- void lineWidthChanged(int i);
- void lineColorChanged(QColor color);
- void brushColorChanged(QColor color);
+ signals:
+ void lastItemChanged(QGraphicsItem* item, int pos, GView::Type type);
+ void itemDeleted(QString id, int pos);
+ void lineWidthChanged(int i);
+ void lineColorChanged(QColor color);
+ void brushColorChanged(QColor color);
- public slots:
- void moveUpSelectedItem();
- void moveDownSelectedItem();
+ public slots:
+ void moveUpSelectedItem();
+ void moveDownSelectedItem();
- private slots:
- void handleTextItemModified(QGraphicsTextItem*);
+ private slots:
+ void handleTextItemModified(QGraphicsTextItem*);
- private:
- void changePenAndBrush(QGraphicsItem* item, QPen pen, QBrush brush);
- void setActualPenAndBrushFromItem(QGraphicsItem* item);
- void deselect();
+ private:
+ void changePenAndBrush(QGraphicsItem* item, QPen pen, QBrush brush);
+ void setActualPenAndBrushFromItem(QGraphicsItem* item);
+ void deselect();
- int zValue;
- bool mousePressed;
- QPen pen;
- QBrush brush;
- QPen defaultPen;
- QBrush defaultBrush;
- Mode mode;
- QGraphicsItem* lastItem;
- QGraphicsRectItem* selectionRect;
- TextDialog* textDialog;
- QMap<QString, QGraphicsItem*> itemsMap_;
- QList<QGraphicsItem*> items_;
- IDGenerator idGenerator;
- };
+ int zValue;
+ bool mousePressed;
+ QPen pen;
+ QBrush brush;
+ QPen defaultPen;
+ QBrush defaultBrush;
+ Mode mode;
+ QGraphicsItem* lastItem;
+ QGraphicsRectItem* selectionRect;
+ TextDialog* textDialog;
+ QMap<QString, QGraphicsItem*> itemsMap_;
+ QList<QGraphicsItem*> items_;
+ IDGenerator idGenerator;
+ };
}
diff --git a/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp b/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp
index 916246c..62f5b89 100644
--- a/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp
+++ b/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp
@@ -5,18 +5,18 @@
*/
/*
- * Copyright (c) 2015 Isode Limited.
+ * Copyright (c) 2015-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "QtWhiteboardWindow.h"
+#include <Swift/QtUI/Whiteboard/QtWhiteboardWindow.h>
#include <iostream>
+#include <memory>
#include <boost/bind.hpp>
#include <boost/numeric/conversion/cast.hpp>
-#include <boost/smart_ptr/make_shared.hpp>
#include <QLabel>
#include <QMessageBox>
@@ -32,374 +32,374 @@
#include <Swift/QtUI/Whiteboard/WhiteboardElementDrawingVisitor.h>
namespace Swift {
- QtWhiteboardWindow::QtWhiteboardWindow(WhiteboardSession::ref whiteboardSession) : QWidget() {
+ QtWhiteboardWindow::QtWhiteboardWindow(WhiteboardSession::ref whiteboardSession) : QWidget() {
#ifndef Q_OS_MAC
#ifdef Q_OS_WIN32
- setWindowIcon(QIcon(":/logo-icon-16-win.png"));
+ setWindowIcon(QIcon(":/logo-icon-16-win.png"));
#else
- setWindowIcon(QIcon(":/logo-icon-16.png"));
+ setWindowIcon(QIcon(":/logo-icon-16.png"));
#endif
#endif
- layout = new QVBoxLayout(this);
- hLayout = new QHBoxLayout;
- sidebarLayout = new QVBoxLayout;
- toolboxLayout = new QGridLayout;
-
- scene = new QGraphicsScene(this);
- scene->setSceneRect(0, 0, 400, 400);
-
- graphicsView = new GView(scene, this);
- graphicsView->setMode(GView::Line);
- connect(graphicsView, SIGNAL(lastItemChanged(QGraphicsItem*, int, GView::Type)), this, SLOT(handleLastItemChanged(QGraphicsItem*, int, GView::Type)));
- connect(graphicsView, SIGNAL(itemDeleted(QString, int)), this, SLOT(handleItemDeleted(QString, int)));
-
- widthBox = new QSpinBox(this);
- connect(widthBox, SIGNAL(valueChanged(int)), this, SLOT(changeLineWidth(int)));
- connect(graphicsView, SIGNAL(lineWidthChanged(int)), widthBox, SLOT(setValue(int)));
- widthBox->setValue(1);
-
- moveUpButton = new QPushButton("Move Up", this);
- connect(moveUpButton, SIGNAL(clicked()), graphicsView, SLOT(moveUpSelectedItem()));
-
- moveDownButton = new QPushButton("Move Down", this);
- connect(moveDownButton, SIGNAL(clicked()), graphicsView, SLOT(moveDownSelectedItem()));
-
- strokeLayout = new QHBoxLayout;
- strokeColor = new ColorWidget;
- strokeLayout->addWidget(new QLabel("Stroke:"));
- strokeLayout->addWidget(strokeColor);
- connect(strokeColor, SIGNAL(clicked()), this, SLOT(showColorDialog()));
- connect(graphicsView, SIGNAL(lineColorChanged(QColor)), strokeColor, SLOT(setColor(QColor)));
-
- fillLayout = new QHBoxLayout;
- fillColor = new ColorWidget;
- fillLayout->addWidget(new QLabel("Fill:"));
- fillLayout->addWidget(fillColor);
- connect(fillColor, SIGNAL(clicked()), this, SLOT(showBrushColorDialog()));
- connect(graphicsView, SIGNAL(brushColorChanged(QColor)), fillColor, SLOT(setColor(QColor)));
-
- rubberButton = new QToolButton(this);
- rubberButton->setIcon(QIcon(":/icons/eraser.png"));
- rubberButton->setCheckable(true);
- rubberButton->setAutoExclusive(true);
- connect(rubberButton, SIGNAL(clicked()), this, SLOT(setRubberMode()));
-
- lineButton = new QToolButton(this);
- lineButton->setIcon(QIcon(":/icons/line.png"));
- lineButton->setCheckable(true);
- lineButton->setAutoExclusive(true);
- lineButton->setChecked(true);
- connect(lineButton, SIGNAL(clicked()), this, SLOT(setLineMode()));
-
- rectButton = new QToolButton(this);
- rectButton->setIcon(QIcon(":/icons/rect.png"));
- rectButton->setCheckable(true);
- rectButton->setAutoExclusive(true);
- connect(rectButton, SIGNAL(clicked()), this, SLOT(setRectMode()));
-
- circleButton = new QToolButton(this);
- circleButton->setIcon(QIcon(":/icons/circle.png"));
- circleButton->setCheckable(true);
- circleButton->setAutoExclusive(true);
- connect(circleButton, SIGNAL(clicked()), this, SLOT(setCircleMode()));
-
- handLineButton = new QToolButton(this);
- handLineButton->setIcon(QIcon(":/icons/handline.png"));
- handLineButton->setCheckable(true);
- handLineButton->setAutoExclusive(true);
- connect(handLineButton, SIGNAL(clicked()), this, SLOT(setHandLineMode()));
-
- textButton = new QToolButton(this);
- textButton->setIcon(QIcon(":/icons/text.png"));
- textButton->setCheckable(true);
- textButton->setAutoExclusive(true);
- connect(textButton, SIGNAL(clicked()), this, SLOT(setTextMode()));
-
- polygonButton = new QToolButton(this);
- polygonButton->setIcon(QIcon(":/icons/polygon.png"));
- polygonButton->setCheckable(true);
- polygonButton->setAutoExclusive(true);
- connect(polygonButton, SIGNAL(clicked()), this, SLOT(setPolygonMode()));
-
- selectButton = new QToolButton(this);
- selectButton->setIcon(QIcon(":/icons/cursor.png"));
- selectButton->setCheckable(true);
- selectButton->setAutoExclusive(true);
- connect(selectButton, SIGNAL(clicked()), this, SLOT(setSelectMode()));
-
- toolboxLayout->addWidget(rubberButton, 0, 0);
- toolboxLayout->addWidget(selectButton, 0, 1);
- toolboxLayout->addWidget(lineButton, 0, 2);
- toolboxLayout->addWidget(circleButton, 1, 0);
- toolboxLayout->addWidget(handLineButton, 1, 1);
- toolboxLayout->addWidget(rectButton, 1, 2);
- toolboxLayout->addWidget(textButton, 2, 0);
- toolboxLayout->addWidget(polygonButton, 2, 1);
-
- sidebarLayout->addLayout(toolboxLayout);
- sidebarLayout->addSpacing(30);
- sidebarLayout->addWidget(moveUpButton);
- sidebarLayout->addWidget(moveDownButton);
- sidebarLayout->addSpacing(40);
- sidebarLayout->addWidget(widthBox);
- sidebarLayout->addLayout(strokeLayout);
- sidebarLayout->addLayout(fillLayout);
- sidebarLayout->addStretch();
- hLayout->addWidget(graphicsView);
- hLayout->addLayout(sidebarLayout);
- layout->addLayout(hLayout);
- this->setLayout(layout);
-
- setSession(whiteboardSession);
- }
-
- void QtWhiteboardWindow::handleWhiteboardOperationReceive(const WhiteboardOperation::ref operation) {
- WhiteboardInsertOperation::ref insertOp = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation);
- if (insertOp) {
- WhiteboardElementDrawingVisitor visitor(graphicsView, operation->getPos(), GView::New);
- insertOp->getElement()->accept(visitor);
- }
-
- WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(operation);
- if (updateOp) {
- WhiteboardElementDrawingVisitor visitor(graphicsView, operation->getPos(), GView::Update);
- updateOp->getElement()->accept(visitor);
- if (updateOp->getPos() != updateOp->getNewPos()) {
- graphicsView->move(graphicsView->getItem(P2QSTRING(updateOp->getElement()->getID())), updateOp->getNewPos());
- }
- }
-
- WhiteboardDeleteOperation::ref deleteOp = boost::dynamic_pointer_cast<WhiteboardDeleteOperation>(operation);
- if (deleteOp) {
- graphicsView->deleteItem(P2QSTRING(deleteOp->getElementID()));
- }
- }
-
- void QtWhiteboardWindow::changeLineWidth(int i)
- {
- graphicsView->setLineWidth(i);
- }
-
- void QtWhiteboardWindow::showColorDialog()
- {
- QColor color = QColorDialog::getColor(graphicsView->getLineColor(), 0, "Select pen color", QColorDialog::ShowAlphaChannel);
- if(color.isValid())
- graphicsView->setLineColor(color);
- }
-
- void QtWhiteboardWindow::showBrushColorDialog()
- {
- QColor color = QColorDialog::getColor(graphicsView->getBrushColor(), 0, "Select brush color", QColorDialog::ShowAlphaChannel);
- if(color.isValid())
- graphicsView->setBrushColor(color);
- }
-
- void QtWhiteboardWindow::setRubberMode()
- {
- graphicsView->setMode(GView::Rubber);
- }
-
- void QtWhiteboardWindow::setLineMode()
- {
- graphicsView->setMode(GView::Line);
- }
-
- void QtWhiteboardWindow::setRectMode()
- {
- graphicsView->setMode(GView::Rect);
- }
-
- void QtWhiteboardWindow::setCircleMode()
- {
- graphicsView->setMode(GView::Circle);
- }
-
- void QtWhiteboardWindow::setHandLineMode()
- {
- graphicsView->setMode(GView::HandLine);
- }
-
- void QtWhiteboardWindow::setTextMode()
- {
- graphicsView->setMode(GView::Text);
- }
-
- void QtWhiteboardWindow::setPolygonMode()
- {
- graphicsView->setMode(GView::Polygon);
- }
-
- void QtWhiteboardWindow::setSelectMode()
- {
- graphicsView->setMode(GView::Select);
- }
-
- void QtWhiteboardWindow::show()
- {
- QWidget::show();
- }
-
- void QtWhiteboardWindow::setSession(WhiteboardSession::ref session) {
- graphicsView->clear();
- whiteboardSession_ = session;
- whiteboardSession_->onOperationReceived.connect(boost::bind(&QtWhiteboardWindow::handleWhiteboardOperationReceive, this, _1));
- whiteboardSession_->onRequestAccepted.connect(boost::bind(&QWidget::show, this));
- whiteboardSession_->onSessionTerminated.connect(boost::bind(&QtWhiteboardWindow::handleSessionTerminate, this));
- }
-
- void QtWhiteboardWindow::activateWindow() {
- QWidget::activateWindow();
- }
-
- void QtWhiteboardWindow::setName(const std::string& name) {
- setWindowTitle(P2QSTRING(name));
- }
-
- void QtWhiteboardWindow::handleLastItemChanged(QGraphicsItem* item, int pos, GView::Type type) {
- WhiteboardElement::ref el;
- QGraphicsLineItem* lineItem = qgraphicsitem_cast<QGraphicsLineItem*>(item);
- if (lineItem != 0) {
- QLine line = lineItem->line().toLine();
- QColor color = lineItem->pen().color();
- WhiteboardLineElement::ref element = boost::make_shared<WhiteboardLineElement>(line.x1()+lineItem->pos().x(), line.y1()+lineItem->pos().y(), line.x2()+lineItem->pos().x(), line.y2()+lineItem->pos().y());
- element->setColor(WhiteboardColor(color.red(), color.green(), color.blue(), color.alpha()));
- element->setPenWidth(lineItem->pen().width());
-
- element->setID(lineItem->data(100).toString().toStdString());
- el = element;
- }
-
- FreehandLineItem* freehandLineItem = qgraphicsitem_cast<FreehandLineItem*>(item);
- if (freehandLineItem != 0) {
- WhiteboardFreehandPathElement::ref element = boost::make_shared<WhiteboardFreehandPathElement>();
- QColor color = freehandLineItem->pen().color();
- std::vector<std::pair<int, int> > points;
- QVector<QPointF>::const_iterator it = freehandLineItem->points().constBegin();
- for ( ; it != freehandLineItem->points().constEnd(); ++it) {
- points.push_back(std::pair<int, int>(
- boost::numeric_cast<int>(it->x()+item->pos().x()),
- boost::numeric_cast<int>(it->y()+item->pos().y())));
- }
-
- element->setColor(WhiteboardColor(color.red(), color.green(), color.blue(), color.alpha()));
- element->setPenWidth(freehandLineItem->pen().width());
- element->setPoints(points);
-
- element->setID(freehandLineItem->data(100).toString().toStdString());
- el = element;
- }
-
- QGraphicsRectItem* rectItem = qgraphicsitem_cast<QGraphicsRectItem*>(item);
- if (rectItem != 0) {
- QRectF rect = rectItem->rect();
- WhiteboardRectElement::ref element = boost::make_shared<WhiteboardRectElement>(rect.x()+item->pos().x(), rect.y()+item->pos().y(), rect.width(), rect.height());
- QColor penColor = rectItem->pen().color();
- QColor brushColor = rectItem->brush().color();
-
- element->setBrushColor(WhiteboardColor(brushColor.red(), brushColor.green(), brushColor.blue(), brushColor.alpha()));
- element->setPenColor(WhiteboardColor(penColor.red(), penColor.green(), penColor.blue(), penColor.alpha()));
- element->setPenWidth(rectItem->pen().width());
-
- element->setID(rectItem->data(100).toString().toStdString());
- el = element;
- }
-
- QGraphicsTextItem* textItem = qgraphicsitem_cast<QGraphicsTextItem*>(item);
- if (textItem != 0) {
- QPointF point = textItem->pos();
- WhiteboardTextElement::ref element = boost::make_shared<WhiteboardTextElement>(point.x(), point.y());
- element->setText(textItem->toPlainText().toStdString());
- element->setSize(textItem->font().pointSize());
- QColor color = textItem->defaultTextColor();
- element->setColor(WhiteboardColor(color.red(), color.green(), color.blue(), color.alpha()));
-
- element->setID(textItem->data(100).toString().toStdString());
- el = element;
- }
-
- QGraphicsPolygonItem* polygonItem = qgraphicsitem_cast<QGraphicsPolygonItem*>(item);
- if (polygonItem) {
- WhiteboardPolygonElement::ref element = boost::make_shared<WhiteboardPolygonElement>();
- QPolygonF polygon = polygonItem->polygon();
- std::vector<std::pair<int, int> > points;
- QVector<QPointF>::const_iterator it = polygon.begin();
- for (; it != polygon.end(); ++it) {
- points.push_back(std::pair<int, int>(
- boost::numeric_cast<int>(it->x()+item->pos().x()),
- boost::numeric_cast<int>(it->y()+item->pos().y())));
- }
-
- element->setPoints(points);
-
- QColor penColor = polygonItem->pen().color();
- QColor brushColor = polygonItem->brush().color();
- element->setPenColor(WhiteboardColor(penColor.red(), penColor.green(), penColor.blue(), penColor.alpha()));
- element->setBrushColor(WhiteboardColor(brushColor.red(), brushColor.green(), brushColor.blue(), brushColor.alpha()));
- element->setPenWidth(polygonItem->pen().width());
-
- element->setID(polygonItem->data(100).toString().toStdString());
- el = element;
- }
-
- QGraphicsEllipseItem* ellipseItem = qgraphicsitem_cast<QGraphicsEllipseItem*>(item);
- if (ellipseItem) {
- QRectF rect = ellipseItem->rect();
- int cx = boost::numeric_cast<int>(rect.x()+rect.width()/2 + item->pos().x());
- int cy = boost::numeric_cast<int>(rect.y()+rect.height()/2 + item->pos().y());
- int rx = boost::numeric_cast<int>(rect.width()/2);
- int ry = boost::numeric_cast<int>(rect.height()/2);
- WhiteboardEllipseElement::ref element = boost::make_shared<WhiteboardEllipseElement>(cx, cy, rx, ry);
-
- QColor penColor = ellipseItem->pen().color();
- QColor brushColor = ellipseItem->brush().color();
- element->setPenColor(WhiteboardColor(penColor.red(), penColor.green(), penColor.blue(), penColor.alpha()));
- element->setBrushColor(WhiteboardColor(brushColor.red(), brushColor.green(), brushColor.blue(), brushColor.alpha()));
- element->setPenWidth(ellipseItem->pen().width());
-
- element->setID(ellipseItem->data(100).toString().toStdString());
- el = element;
- }
-
- if (type == GView::New) {
- WhiteboardInsertOperation::ref insertOp = boost::make_shared<WhiteboardInsertOperation>();
- insertOp->setPos(pos);
- insertOp->setElement(el);
- whiteboardSession_->sendOperation(insertOp);
- } else {
- WhiteboardUpdateOperation::ref updateOp = boost::make_shared<WhiteboardUpdateOperation>();
- updateOp->setPos(pos);
- if (type == GView::Update) {
- updateOp->setNewPos(pos);
- } else if (type == GView::MoveUp) {
- updateOp->setNewPos(pos+1);
- } else if (type == GView::MoveDown) {
- updateOp->setNewPos(pos-1);
- }
- updateOp->setElement(el);
- whiteboardSession_->sendOperation(updateOp);
- }
- }
-
- void QtWhiteboardWindow::handleItemDeleted(QString id, int pos) {
- WhiteboardDeleteOperation::ref deleteOp = boost::make_shared<WhiteboardDeleteOperation>();
- deleteOp->setElementID(Q2PSTRING(id));
- deleteOp->setPos(pos);
- whiteboardSession_->sendOperation(deleteOp);
- }
-
- void QtWhiteboardWindow::handleSessionTerminate() {
- hide();
- }
-
- void QtWhiteboardWindow::closeEvent(QCloseEvent* event) {
- QMessageBox box(this);
- box.setText(tr("Closing window is equivalent closing the session. Are you sure you want to do this?"));
- box.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
- box.setIcon(QMessageBox::Question);
- if (box.exec() == QMessageBox::Yes) {
- whiteboardSession_->cancel();
- } else {
- event->ignore();
- }
- }
+ layout = new QVBoxLayout(this);
+ hLayout = new QHBoxLayout;
+ sidebarLayout = new QVBoxLayout;
+ toolboxLayout = new QGridLayout;
+
+ scene = new QGraphicsScene(this);
+ scene->setSceneRect(0, 0, 400, 400);
+
+ graphicsView = new GView(scene, this);
+ graphicsView->setMode(GView::Line);
+ connect(graphicsView, SIGNAL(lastItemChanged(QGraphicsItem*, int, GView::Type)), this, SLOT(handleLastItemChanged(QGraphicsItem*, int, GView::Type)));
+ connect(graphicsView, SIGNAL(itemDeleted(QString, int)), this, SLOT(handleItemDeleted(QString, int)));
+
+ widthBox = new QSpinBox(this);
+ connect(widthBox, SIGNAL(valueChanged(int)), this, SLOT(changeLineWidth(int)));
+ connect(graphicsView, SIGNAL(lineWidthChanged(int)), widthBox, SLOT(setValue(int)));
+ widthBox->setValue(1);
+
+ moveUpButton = new QPushButton("Move Up", this);
+ connect(moveUpButton, SIGNAL(clicked()), graphicsView, SLOT(moveUpSelectedItem()));
+
+ moveDownButton = new QPushButton("Move Down", this);
+ connect(moveDownButton, SIGNAL(clicked()), graphicsView, SLOT(moveDownSelectedItem()));
+
+ strokeLayout = new QHBoxLayout;
+ strokeColor = new ColorWidget;
+ strokeLayout->addWidget(new QLabel("Stroke:"));
+ strokeLayout->addWidget(strokeColor);
+ connect(strokeColor, SIGNAL(clicked()), this, SLOT(showColorDialog()));
+ connect(graphicsView, SIGNAL(lineColorChanged(QColor)), strokeColor, SLOT(setColor(QColor)));
+
+ fillLayout = new QHBoxLayout;
+ fillColor = new ColorWidget;
+ fillLayout->addWidget(new QLabel("Fill:"));
+ fillLayout->addWidget(fillColor);
+ connect(fillColor, SIGNAL(clicked()), this, SLOT(showBrushColorDialog()));
+ connect(graphicsView, SIGNAL(brushColorChanged(QColor)), fillColor, SLOT(setColor(QColor)));
+
+ rubberButton = new QToolButton(this);
+ rubberButton->setIcon(QIcon(":/icons/eraser.png"));
+ rubberButton->setCheckable(true);
+ rubberButton->setAutoExclusive(true);
+ connect(rubberButton, SIGNAL(clicked()), this, SLOT(setRubberMode()));
+
+ lineButton = new QToolButton(this);
+ lineButton->setIcon(QIcon(":/icons/line.png"));
+ lineButton->setCheckable(true);
+ lineButton->setAutoExclusive(true);
+ lineButton->setChecked(true);
+ connect(lineButton, SIGNAL(clicked()), this, SLOT(setLineMode()));
+
+ rectButton = new QToolButton(this);
+ rectButton->setIcon(QIcon(":/icons/rect.png"));
+ rectButton->setCheckable(true);
+ rectButton->setAutoExclusive(true);
+ connect(rectButton, SIGNAL(clicked()), this, SLOT(setRectMode()));
+
+ circleButton = new QToolButton(this);
+ circleButton->setIcon(QIcon(":/icons/circle.png"));
+ circleButton->setCheckable(true);
+ circleButton->setAutoExclusive(true);
+ connect(circleButton, SIGNAL(clicked()), this, SLOT(setCircleMode()));
+
+ handLineButton = new QToolButton(this);
+ handLineButton->setIcon(QIcon(":/icons/handline.png"));
+ handLineButton->setCheckable(true);
+ handLineButton->setAutoExclusive(true);
+ connect(handLineButton, SIGNAL(clicked()), this, SLOT(setHandLineMode()));
+
+ textButton = new QToolButton(this);
+ textButton->setIcon(QIcon(":/icons/text.png"));
+ textButton->setCheckable(true);
+ textButton->setAutoExclusive(true);
+ connect(textButton, SIGNAL(clicked()), this, SLOT(setTextMode()));
+
+ polygonButton = new QToolButton(this);
+ polygonButton->setIcon(QIcon(":/icons/polygon.png"));
+ polygonButton->setCheckable(true);
+ polygonButton->setAutoExclusive(true);
+ connect(polygonButton, SIGNAL(clicked()), this, SLOT(setPolygonMode()));
+
+ selectButton = new QToolButton(this);
+ selectButton->setIcon(QIcon(":/icons/cursor.png"));
+ selectButton->setCheckable(true);
+ selectButton->setAutoExclusive(true);
+ connect(selectButton, SIGNAL(clicked()), this, SLOT(setSelectMode()));
+
+ toolboxLayout->addWidget(rubberButton, 0, 0);
+ toolboxLayout->addWidget(selectButton, 0, 1);
+ toolboxLayout->addWidget(lineButton, 0, 2);
+ toolboxLayout->addWidget(circleButton, 1, 0);
+ toolboxLayout->addWidget(handLineButton, 1, 1);
+ toolboxLayout->addWidget(rectButton, 1, 2);
+ toolboxLayout->addWidget(textButton, 2, 0);
+ toolboxLayout->addWidget(polygonButton, 2, 1);
+
+ sidebarLayout->addLayout(toolboxLayout);
+ sidebarLayout->addSpacing(30);
+ sidebarLayout->addWidget(moveUpButton);
+ sidebarLayout->addWidget(moveDownButton);
+ sidebarLayout->addSpacing(40);
+ sidebarLayout->addWidget(widthBox);
+ sidebarLayout->addLayout(strokeLayout);
+ sidebarLayout->addLayout(fillLayout);
+ sidebarLayout->addStretch();
+ hLayout->addWidget(graphicsView);
+ hLayout->addLayout(sidebarLayout);
+ layout->addLayout(hLayout);
+ this->setLayout(layout);
+
+ setSession(whiteboardSession);
+ }
+
+ void QtWhiteboardWindow::handleWhiteboardOperationReceive(const WhiteboardOperation::ref operation) {
+ WhiteboardInsertOperation::ref insertOp = std::dynamic_pointer_cast<WhiteboardInsertOperation>(operation);
+ if (insertOp) {
+ WhiteboardElementDrawingVisitor visitor(graphicsView, operation->getPos(), GView::New);
+ insertOp->getElement()->accept(visitor);
+ }
+
+ WhiteboardUpdateOperation::ref updateOp = std::dynamic_pointer_cast<WhiteboardUpdateOperation>(operation);
+ if (updateOp) {
+ WhiteboardElementDrawingVisitor visitor(graphicsView, operation->getPos(), GView::Update);
+ updateOp->getElement()->accept(visitor);
+ if (updateOp->getPos() != updateOp->getNewPos()) {
+ graphicsView->move(graphicsView->getItem(P2QSTRING(updateOp->getElement()->getID())), updateOp->getNewPos());
+ }
+ }
+
+ WhiteboardDeleteOperation::ref deleteOp = std::dynamic_pointer_cast<WhiteboardDeleteOperation>(operation);
+ if (deleteOp) {
+ graphicsView->deleteItem(P2QSTRING(deleteOp->getElementID()));
+ }
+ }
+
+ void QtWhiteboardWindow::changeLineWidth(int i)
+ {
+ graphicsView->setLineWidth(i);
+ }
+
+ void QtWhiteboardWindow::showColorDialog()
+ {
+ QColor color = QColorDialog::getColor(graphicsView->getLineColor(), nullptr, "Select pen color", QColorDialog::ShowAlphaChannel);
+ if(color.isValid())
+ graphicsView->setLineColor(color);
+ }
+
+ void QtWhiteboardWindow::showBrushColorDialog()
+ {
+ QColor color = QColorDialog::getColor(graphicsView->getBrushColor(), nullptr, "Select brush color", QColorDialog::ShowAlphaChannel);
+ if(color.isValid())
+ graphicsView->setBrushColor(color);
+ }
+
+ void QtWhiteboardWindow::setRubberMode()
+ {
+ graphicsView->setMode(GView::Rubber);
+ }
+
+ void QtWhiteboardWindow::setLineMode()
+ {
+ graphicsView->setMode(GView::Line);
+ }
+
+ void QtWhiteboardWindow::setRectMode()
+ {
+ graphicsView->setMode(GView::Rect);
+ }
+
+ void QtWhiteboardWindow::setCircleMode()
+ {
+ graphicsView->setMode(GView::Circle);
+ }
+
+ void QtWhiteboardWindow::setHandLineMode()
+ {
+ graphicsView->setMode(GView::HandLine);
+ }
+
+ void QtWhiteboardWindow::setTextMode()
+ {
+ graphicsView->setMode(GView::Text);
+ }
+
+ void QtWhiteboardWindow::setPolygonMode()
+ {
+ graphicsView->setMode(GView::Polygon);
+ }
+
+ void QtWhiteboardWindow::setSelectMode()
+ {
+ graphicsView->setMode(GView::Select);
+ }
+
+ void QtWhiteboardWindow::show()
+ {
+ QWidget::show();
+ }
+
+ void QtWhiteboardWindow::setSession(WhiteboardSession::ref session) {
+ graphicsView->clear();
+ whiteboardSession_ = session;
+ whiteboardSession_->onOperationReceived.connect(boost::bind(&QtWhiteboardWindow::handleWhiteboardOperationReceive, this, _1));
+ whiteboardSession_->onRequestAccepted.connect(boost::bind(&QWidget::show, this));
+ whiteboardSession_->onSessionTerminated.connect(boost::bind(&QtWhiteboardWindow::handleSessionTerminate, this));
+ }
+
+ void QtWhiteboardWindow::activateWindow() {
+ QWidget::activateWindow();
+ }
+
+ void QtWhiteboardWindow::setName(const std::string& name) {
+ setWindowTitle(P2QSTRING(name));
+ }
+
+ void QtWhiteboardWindow::handleLastItemChanged(QGraphicsItem* item, int pos, GView::Type type) {
+ WhiteboardElement::ref el;
+ QGraphicsLineItem* lineItem = qgraphicsitem_cast<QGraphicsLineItem*>(item);
+ if (lineItem != nullptr) {
+ QLine line = lineItem->line().toLine();
+ QColor color = lineItem->pen().color();
+ WhiteboardLineElement::ref element = std::make_shared<WhiteboardLineElement>(line.x1()+lineItem->pos().x(), line.y1()+lineItem->pos().y(), line.x2()+lineItem->pos().x(), line.y2()+lineItem->pos().y());
+ element->setColor(WhiteboardColor(color.red(), color.green(), color.blue(), color.alpha()));
+ element->setPenWidth(lineItem->pen().width());
+
+ element->setID(lineItem->data(100).toString().toStdString());
+ el = element;
+ }
+
+ FreehandLineItem* freehandLineItem = qgraphicsitem_cast<FreehandLineItem*>(item);
+ if (freehandLineItem != nullptr) {
+ WhiteboardFreehandPathElement::ref element = std::make_shared<WhiteboardFreehandPathElement>();
+ QColor color = freehandLineItem->pen().color();
+ std::vector<std::pair<int, int> > points;
+ QVector<QPointF>::const_iterator it = freehandLineItem->points().constBegin();
+ for ( ; it != freehandLineItem->points().constEnd(); ++it) {
+ points.push_back(std::pair<int, int>(
+ boost::numeric_cast<int>(it->x()+item->pos().x()),
+ boost::numeric_cast<int>(it->y()+item->pos().y())));
+ }
+
+ element->setColor(WhiteboardColor(color.red(), color.green(), color.blue(), color.alpha()));
+ element->setPenWidth(freehandLineItem->pen().width());
+ element->setPoints(points);
+
+ element->setID(freehandLineItem->data(100).toString().toStdString());
+ el = element;
+ }
+
+ QGraphicsRectItem* rectItem = qgraphicsitem_cast<QGraphicsRectItem*>(item);
+ if (rectItem != nullptr) {
+ QRectF rect = rectItem->rect();
+ WhiteboardRectElement::ref element = std::make_shared<WhiteboardRectElement>(rect.x()+item->pos().x(), rect.y()+item->pos().y(), rect.width(), rect.height());
+ QColor penColor = rectItem->pen().color();
+ QColor brushColor = rectItem->brush().color();
+
+ element->setBrushColor(WhiteboardColor(brushColor.red(), brushColor.green(), brushColor.blue(), brushColor.alpha()));
+ element->setPenColor(WhiteboardColor(penColor.red(), penColor.green(), penColor.blue(), penColor.alpha()));
+ element->setPenWidth(rectItem->pen().width());
+
+ element->setID(rectItem->data(100).toString().toStdString());
+ el = element;
+ }
+
+ QGraphicsTextItem* textItem = qgraphicsitem_cast<QGraphicsTextItem*>(item);
+ if (textItem != nullptr) {
+ QPointF point = textItem->pos();
+ WhiteboardTextElement::ref element = std::make_shared<WhiteboardTextElement>(point.x(), point.y());
+ element->setText(textItem->toPlainText().toStdString());
+ element->setSize(textItem->font().pointSize());
+ QColor color = textItem->defaultTextColor();
+ element->setColor(WhiteboardColor(color.red(), color.green(), color.blue(), color.alpha()));
+
+ element->setID(textItem->data(100).toString().toStdString());
+ el = element;
+ }
+
+ QGraphicsPolygonItem* polygonItem = qgraphicsitem_cast<QGraphicsPolygonItem*>(item);
+ if (polygonItem) {
+ WhiteboardPolygonElement::ref element = std::make_shared<WhiteboardPolygonElement>();
+ QPolygonF polygon = polygonItem->polygon();
+ std::vector<std::pair<int, int> > points;
+ QVector<QPointF>::const_iterator it = polygon.begin();
+ for (; it != polygon.end(); ++it) {
+ points.push_back(std::pair<int, int>(
+ boost::numeric_cast<int>(it->x()+item->pos().x()),
+ boost::numeric_cast<int>(it->y()+item->pos().y())));
+ }
+
+ element->setPoints(points);
+
+ QColor penColor = polygonItem->pen().color();
+ QColor brushColor = polygonItem->brush().color();
+ element->setPenColor(WhiteboardColor(penColor.red(), penColor.green(), penColor.blue(), penColor.alpha()));
+ element->setBrushColor(WhiteboardColor(brushColor.red(), brushColor.green(), brushColor.blue(), brushColor.alpha()));
+ element->setPenWidth(polygonItem->pen().width());
+
+ element->setID(polygonItem->data(100).toString().toStdString());
+ el = element;
+ }
+
+ QGraphicsEllipseItem* ellipseItem = qgraphicsitem_cast<QGraphicsEllipseItem*>(item);
+ if (ellipseItem) {
+ QRectF rect = ellipseItem->rect();
+ int cx = boost::numeric_cast<int>(rect.x()+rect.width()/2 + item->pos().x());
+ int cy = boost::numeric_cast<int>(rect.y()+rect.height()/2 + item->pos().y());
+ int rx = boost::numeric_cast<int>(rect.width()/2);
+ int ry = boost::numeric_cast<int>(rect.height()/2);
+ WhiteboardEllipseElement::ref element = std::make_shared<WhiteboardEllipseElement>(cx, cy, rx, ry);
+
+ QColor penColor = ellipseItem->pen().color();
+ QColor brushColor = ellipseItem->brush().color();
+ element->setPenColor(WhiteboardColor(penColor.red(), penColor.green(), penColor.blue(), penColor.alpha()));
+ element->setBrushColor(WhiteboardColor(brushColor.red(), brushColor.green(), brushColor.blue(), brushColor.alpha()));
+ element->setPenWidth(ellipseItem->pen().width());
+
+ element->setID(ellipseItem->data(100).toString().toStdString());
+ el = element;
+ }
+
+ if (type == GView::New) {
+ WhiteboardInsertOperation::ref insertOp = std::make_shared<WhiteboardInsertOperation>();
+ insertOp->setPos(pos);
+ insertOp->setElement(el);
+ whiteboardSession_->sendOperation(insertOp);
+ } else {
+ WhiteboardUpdateOperation::ref updateOp = std::make_shared<WhiteboardUpdateOperation>();
+ updateOp->setPos(pos);
+ if (type == GView::Update) {
+ updateOp->setNewPos(pos);
+ } else if (type == GView::MoveUp) {
+ updateOp->setNewPos(pos+1);
+ } else if (type == GView::MoveDown) {
+ updateOp->setNewPos(pos-1);
+ }
+ updateOp->setElement(el);
+ whiteboardSession_->sendOperation(updateOp);
+ }
+ }
+
+ void QtWhiteboardWindow::handleItemDeleted(QString id, int pos) {
+ WhiteboardDeleteOperation::ref deleteOp = std::make_shared<WhiteboardDeleteOperation>();
+ deleteOp->setElementID(Q2PSTRING(id));
+ deleteOp->setPos(pos);
+ whiteboardSession_->sendOperation(deleteOp);
+ }
+
+ void QtWhiteboardWindow::handleSessionTerminate() {
+ hide();
+ }
+
+ void QtWhiteboardWindow::closeEvent(QCloseEvent* event) {
+ QMessageBox box(this);
+ box.setText(tr("Closing window is equivalent closing the session. Are you sure you want to do this?"));
+ box.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
+ box.setIcon(QMessageBox::Question);
+ if (box.exec() == QMessageBox::Yes) {
+ whiteboardSession_->cancel();
+ } else {
+ event->ignore();
+ }
+ }
}
diff --git a/Swift/QtUI/Whiteboard/QtWhiteboardWindow.h b/Swift/QtUI/Whiteboard/QtWhiteboardWindow.h
index 3957bb7..21aa7ca 100644
--- a/Swift/QtUI/Whiteboard/QtWhiteboardWindow.h
+++ b/Swift/QtUI/Whiteboard/QtWhiteboardWindow.h
@@ -4,85 +4,91 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#pragma once
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
-#include <Swift/Controllers/UIInterfaces/WhiteboardWindow.h>
-#include <Swiften/Elements/Message.h>
-#include <Swiften/Whiteboard/WhiteboardSession.h>
-#include <Swiften/Elements/Whiteboard/WhiteboardElement.h>
+#pragma once
-#include <QWidget>
-#include <QGraphicsView>
+#include <QCloseEvent>
+#include <QColorDialog>
#include <QGraphicsScene>
-#include <QVBoxLayout>
-#include <QHBoxLayout>
+#include <QGraphicsView>
#include <QGridLayout>
+#include <QHBoxLayout>
#include <QPainter>
#include <QPushButton>
#include <QSpinBox>
-#include <QColorDialog>
#include <QToolButton>
-#include <QCloseEvent>
+#include <QVBoxLayout>
+#include <QWidget>
+
+#include <Swiften/Elements/Message.h>
+#include <Swiften/Elements/Whiteboard/WhiteboardElement.h>
+#include <Swiften/Whiteboard/WhiteboardSession.h>
+
+#include <Swift/Controllers/UIInterfaces/WhiteboardWindow.h>
-#include "GView.h"
-#include "ColorWidget.h"
+#include <Swift/QtUI/Whiteboard/ColorWidget.h>
+#include <Swift/QtUI/Whiteboard/GView.h>
namespace Swift {
- class QtWhiteboardWindow : public QWidget, public WhiteboardWindow
- {
- Q_OBJECT
- public:
- QtWhiteboardWindow(WhiteboardSession::ref whiteboardSession);
- void show();
- void setSession(WhiteboardSession::ref session);
- void activateWindow();
- void setName(const std::string& name);
+ class QtWhiteboardWindow : public QWidget, public WhiteboardWindow
+ {
+ Q_OBJECT
+ public:
+ QtWhiteboardWindow(WhiteboardSession::ref whiteboardSession);
+ void show();
+ void setSession(WhiteboardSession::ref session);
+ void activateWindow();
+ void setName(const std::string& name);
- private slots:
- void changeLineWidth(int i);
- void showColorDialog();
- void showBrushColorDialog();
- void setRubberMode();
- void setLineMode();
- void setRectMode();
- void setCircleMode();
- void setHandLineMode();
- void setTextMode();
- void setPolygonMode();
- void setSelectMode();
- void handleLastItemChanged(QGraphicsItem* item, int pos, GView::Type type);
- void handleItemDeleted(QString id, int pos);
+ private slots:
+ void changeLineWidth(int i);
+ void showColorDialog();
+ void showBrushColorDialog();
+ void setRubberMode();
+ void setLineMode();
+ void setRectMode();
+ void setCircleMode();
+ void setHandLineMode();
+ void setTextMode();
+ void setPolygonMode();
+ void setSelectMode();
+ void handleLastItemChanged(QGraphicsItem* item, int pos, GView::Type type);
+ void handleItemDeleted(QString id, int pos);
- private:
- void handleSessionTerminate();
- void handleWhiteboardOperationReceive(const WhiteboardOperation::ref operation);
- void closeEvent(QCloseEvent* event);
+ private:
+ void handleSessionTerminate();
+ void handleWhiteboardOperationReceive(const WhiteboardOperation::ref operation);
+ void closeEvent(QCloseEvent* event);
- private:
- QGraphicsScene* scene;
- GView* graphicsView;
- QVBoxLayout* layout;
- QVBoxLayout* sidebarLayout;
- QHBoxLayout* hLayout;
- QGridLayout* toolboxLayout;
- QHBoxLayout* strokeLayout;
- QHBoxLayout* fillLayout;
- ColorWidget* strokeColor;
- ColorWidget* fillColor;
- QWidget* widget;
- QPushButton* moveUpButton;
- QPushButton* moveDownButton;
- QSpinBox* widthBox;
- QToolButton* rubberButton;
- QToolButton* lineButton;
- QToolButton* rectButton;
- QToolButton* circleButton;
- QToolButton* handLineButton;
- QToolButton* textButton;
- QToolButton* polygonButton;
- QToolButton* selectButton;
+ private:
+ QGraphicsScene* scene;
+ GView* graphicsView;
+ QVBoxLayout* layout;
+ QVBoxLayout* sidebarLayout;
+ QHBoxLayout* hLayout;
+ QGridLayout* toolboxLayout;
+ QHBoxLayout* strokeLayout;
+ QHBoxLayout* fillLayout;
+ ColorWidget* strokeColor;
+ ColorWidget* fillColor;
+ QPushButton* moveUpButton;
+ QPushButton* moveDownButton;
+ QSpinBox* widthBox;
+ QToolButton* rubberButton;
+ QToolButton* lineButton;
+ QToolButton* rectButton;
+ QToolButton* circleButton;
+ QToolButton* handLineButton;
+ QToolButton* textButton;
+ QToolButton* polygonButton;
+ QToolButton* selectButton;
- std::string lastOpID;
- WhiteboardSession::ref whiteboardSession_;
- };
+ std::string lastOpID;
+ WhiteboardSession::ref whiteboardSession_;
+ };
}
diff --git a/Swift/QtUI/Whiteboard/TextDialog.cpp b/Swift/QtUI/Whiteboard/TextDialog.cpp
index 021895a..c15e7b4 100644
--- a/Swift/QtUI/Whiteboard/TextDialog.cpp
+++ b/Swift/QtUI/Whiteboard/TextDialog.cpp
@@ -4,49 +4,55 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "TextDialog.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/Whiteboard/TextDialog.h>
namespace Swift {
- TextDialog::TextDialog(QGraphicsTextItem* item, QWidget* parent) : QDialog(parent)
- {
- this->item = item;
-
- layout = new QVBoxLayout(this);
- hLayout = new QHBoxLayout;
-
- editor = new QLineEdit(this);
- connect(editor, SIGNAL(textChanged(const QString&)), this, SLOT(changeItemText(const QString&)));
-
- fontSizeBox = new QSpinBox(this);
- fontSizeBox->setMinimum(1);
- connect(fontSizeBox, SIGNAL(valueChanged(int)), this, SLOT(changeItemFontSize(int)));
- fontSizeBox->setValue(13);
-
-
- buttonBox = new QDialogButtonBox(this);
- buttonBox->setStandardButtons(QDialogButtonBox::Ok);
- connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
-
- hLayout->addWidget(editor);
- hLayout->addWidget(fontSizeBox);
- layout->addLayout(hLayout);
- layout->addWidget(buttonBox);
- }
-
- void TextDialog::changeItemText(const QString &text)
- {
- item->setPlainText(text);
- }
-
- void TextDialog::changeItemFontSize(int i)
- {
- QFont font = item->font();
- font.setPointSize(i);
- item->setFont(font);
- }
-
- void TextDialog::accept() {
- emit accepted(item);
- done(QDialog::Accepted);
- }
+ TextDialog::TextDialog(QGraphicsTextItem* item, QWidget* parent) : QDialog(parent)
+ {
+ this->item = item;
+
+ layout = new QVBoxLayout(this);
+ hLayout = new QHBoxLayout;
+
+ editor = new QLineEdit(this);
+ connect(editor, SIGNAL(textChanged(const QString&)), this, SLOT(changeItemText(const QString&)));
+
+ fontSizeBox = new QSpinBox(this);
+ fontSizeBox->setMinimum(1);
+ connect(fontSizeBox, SIGNAL(valueChanged(int)), this, SLOT(changeItemFontSize(int)));
+ fontSizeBox->setValue(13);
+
+
+ buttonBox = new QDialogButtonBox(this);
+ buttonBox->setStandardButtons(QDialogButtonBox::Ok);
+ connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
+
+ hLayout->addWidget(editor);
+ hLayout->addWidget(fontSizeBox);
+ layout->addLayout(hLayout);
+ layout->addWidget(buttonBox);
+ }
+
+ void TextDialog::changeItemText(const QString &text)
+ {
+ item->setPlainText(text);
+ }
+
+ void TextDialog::changeItemFontSize(int i)
+ {
+ QFont font = item->font();
+ font.setPointSize(i);
+ item->setFont(font);
+ }
+
+ void TextDialog::accept() {
+ emit accepted(item);
+ done(QDialog::Accepted);
+ }
}
diff --git a/Swift/QtUI/Whiteboard/TextDialog.h b/Swift/QtUI/Whiteboard/TextDialog.h
index 64a0fe2..513d381 100644
--- a/Swift/QtUI/Whiteboard/TextDialog.h
+++ b/Swift/QtUI/Whiteboard/TextDialog.h
@@ -4,40 +4,46 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
+#include <iostream>
+
#include <QDialog>
-#include <QVBoxLayout>
-#include <QHBoxLayout>
#include <QDialogButtonBox>
-#include <QLineEdit>
#include <QGraphicsTextItem>
+#include <QHBoxLayout>
+#include <QLineEdit>
#include <QSpinBox>
-
-#include <iostream>
+#include <QVBoxLayout>
namespace Swift {
- class TextDialog : public QDialog
- {
- Q_OBJECT
- public:
- TextDialog(QGraphicsTextItem* item, QWidget* parent = 0);
-
- private:
- QGraphicsTextItem* item;
- QLineEdit* editor;
- QDialogButtonBox* buttonBox;
- QVBoxLayout* layout;
- QHBoxLayout* hLayout;
- QSpinBox* fontSizeBox;
-
- signals:
- void accepted(QGraphicsTextItem* item);
-
- private slots:
- void accept();
- void changeItemText(const QString &text);
- void changeItemFontSize(int i);
- };
+ class TextDialog : public QDialog
+ {
+ Q_OBJECT
+ public:
+ TextDialog(QGraphicsTextItem* item, QWidget* parent = nullptr);
+
+ private:
+ QGraphicsTextItem* item;
+ QLineEdit* editor;
+ QDialogButtonBox* buttonBox;
+ QVBoxLayout* layout;
+ QHBoxLayout* hLayout;
+ QSpinBox* fontSizeBox;
+
+ signals:
+ void accepted(QGraphicsTextItem* item);
+
+ private slots:
+ void accept();
+ void changeItemText(const QString &text);
+ void changeItemFontSize(int i);
+ };
}
diff --git a/Swift/QtUI/Whiteboard/WhiteboardElementDrawingVisitor.h b/Swift/QtUI/Whiteboard/WhiteboardElementDrawingVisitor.h
index 74c6c1d..5a5aefa 100644
--- a/Swift/QtUI/Whiteboard/WhiteboardElementDrawingVisitor.h
+++ b/Swift/QtUI/Whiteboard/WhiteboardElementDrawingVisitor.h
@@ -4,184 +4,192 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
#include <Swiften/Elements/Whiteboard/WhiteboardElementVisitor.h>
+#include <Swiften/Elements/Whiteboard/WhiteboardEllipseElement.h>
+#include <Swiften/Elements/Whiteboard/WhiteboardFreehandPathElement.h>
#include <Swiften/Elements/Whiteboard/WhiteboardLineElement.h>
#include <Swiften/Elements/Whiteboard/WhiteboardPolygonElement.h>
+#include <Swiften/Elements/Whiteboard/WhiteboardRectElement.h>
#include <Swiften/Elements/Whiteboard/WhiteboardTextElement.h>
-#include <Swiften/Elements/Whiteboard/WhiteboardEllipseElement.h>
-#include <Swiften/Elements/Whiteboard/WhiteboardFreehandPathElement.h>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
#include <Swift/QtUI/Whiteboard/GView.h>
-#include <QtSwiftUtil.h>
namespace Swift {
- class WhiteboardElementDrawingVisitor : public WhiteboardElementVisitor {
- public:
- WhiteboardElementDrawingVisitor(GView* graphicsView, int pos, GView::Type type) : graphicsView_(graphicsView), pos_(pos), type_(type) {}
-
- void visit(WhiteboardLineElement& element) {
- QGraphicsLineItem *item;
- if (type_ == GView::New) {
- item = new QGraphicsLineItem(element.x1(), element.y1(), element.x2(), element.y2());
- graphicsView_->addItem(item, P2QSTRING(element.getID()), pos_);
- } else {
- item = qgraphicsitem_cast<QGraphicsLineItem*>(graphicsView_->getItem(P2QSTRING(element.getID())));
- QLineF line(element.x1(), element.y1(), element.x2(), element.y2());
- item->setLine(line);
- item->setPos(0,0);
- graphicsView_->deselect(P2QSTRING(element.getID()));
- }
- if (item) {
- QPen pen;
- WhiteboardColor color = element.getColor();
- pen.setColor(QColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()));
- pen.setWidth(element.getPenWidth());
- item->setPen(pen);
- QString id = P2QSTRING(element.getID());
- item->setData(100, id);
- }
- }
-
- void visit(WhiteboardFreehandPathElement& element) {
- FreehandLineItem *item;
- if (type_ == GView::New) {
- item = new FreehandLineItem;
- } else {
- item = qgraphicsitem_cast<FreehandLineItem*>(graphicsView_->getItem(P2QSTRING(element.getID())));
- item->setPos(0,0);
- graphicsView_->deselect(P2QSTRING(element.getID()));
- }
-
- if (item) {
- QPen pen;
- WhiteboardColor color = element.getColor();
- pen.setColor(QColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()));
- pen.setWidth(element.getPenWidth());
- item->setPen(pen);
-
- std::vector<std::pair<int, int> >::const_iterator it = element.getPoints().begin();
- item->setStartPoint(QPointF(it->first, it->second));
- for (++it; it != element.getPoints().end(); ++it) {
- item->lineTo(QPointF(it->first, it->second));
- }
-
- QString id = P2QSTRING(element.getID());
- item->setData(100, id);
- }
- if (type_ == GView::New) {
- graphicsView_->addItem(item, P2QSTRING(element.getID()), pos_);
- }
- }
-
- void visit(WhiteboardRectElement& element) {
- QGraphicsRectItem* item;
- if (type_ == GView::New) {
- item = new QGraphicsRectItem(element.getX(), element.getY(), element.getWidth(), element.getHeight());
- graphicsView_->addItem(item, P2QSTRING(element.getID()), pos_);
- } else {
- item = qgraphicsitem_cast<QGraphicsRectItem*>(graphicsView_->getItem(P2QSTRING(element.getID())));
- QRectF rect(element.getX(), element.getY(), element.getWidth(), element.getHeight());
- item->setRect(rect);
- item->setPos(0,0);
- graphicsView_->deselect(P2QSTRING(element.getID()));
- }
-
- if (item) {
- QPen pen;
- QBrush brush(Qt::SolidPattern);
- WhiteboardColor penColor = element.getPenColor();
- WhiteboardColor brushColor = element.getBrushColor();
- pen.setColor(QColor(penColor.getRed(), penColor.getGreen(), penColor.getBlue(), penColor.getAlpha()));
- pen.setWidth(element.getPenWidth());
- brush.setColor(QColor(brushColor.getRed(), brushColor.getGreen(), brushColor.getBlue(), brushColor.getAlpha()));
- item->setPen(pen);
- item->setBrush(brush);
- QString id = P2QSTRING(element.getID());
- item->setData(100, id);
- }
- }
-
- void visit(WhiteboardPolygonElement& element) {
- QGraphicsPolygonItem* item = qgraphicsitem_cast<QGraphicsPolygonItem*>(graphicsView_->getItem(P2QSTRING(element.getID())));
- if (item == 0 && type_ == GView::New) {
- item = new QGraphicsPolygonItem();
- QString id = P2QSTRING(element.getID());
- item->setData(100, id);
- graphicsView_->addItem(item, id, pos_);
- }
- graphicsView_->deselect(P2QSTRING(element.getID()));
- QPen pen;
- QBrush brush(Qt::SolidPattern);
- WhiteboardColor penColor = element.getPenColor();
- WhiteboardColor brushColor = element.getBrushColor();
- pen.setColor(QColor(penColor.getRed(), penColor.getGreen(), penColor.getBlue(), penColor.getAlpha()));
- pen.setWidth(element.getPenWidth());
- brush.setColor(QColor(brushColor.getRed(), brushColor.getGreen(), brushColor.getBlue(), brushColor.getAlpha()));
- item->setPen(pen);
- item->setBrush(brush);
-
- item->setPos(0,0);
- QPolygonF polygon;
- std::vector<std::pair<int, int> >::const_iterator it = element.getPoints().begin();
- for (; it != element.getPoints().end(); ++it) {
- polygon.append(QPointF(it->first, it->second));
- }
- item->setPolygon(polygon);
- }
-
- void visit(WhiteboardTextElement& element) {
- QGraphicsTextItem* item;
- QString id = P2QSTRING(element.getID());
- if (type_ == GView::New) {
- item = new QGraphicsTextItem;
- graphicsView_->addItem(item, id, pos_);
- } else {
- item = qgraphicsitem_cast<QGraphicsTextItem*>(graphicsView_->getItem(id));
- graphicsView_->deselect(P2QSTRING(element.getID()));
- }
- if (item) {
- item->setPlainText(P2QSTRING(element.getText()));
- item->setPos(QPointF(element.getX(), element.getY()));
- QFont font = item->font();
- font.setPointSize(element.getSize());
- item->setFont(font);
- WhiteboardColor color = element.getColor();
- item->setDefaultTextColor(QColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()));
- item->setData(100, id);
- }
- }
-
- void visit(WhiteboardEllipseElement& element) {
- QRectF rect;
- QGraphicsEllipseItem* item;
- QString id = P2QSTRING(element.getID());
- rect.setTopLeft(QPointF(element.getCX()-element.getRX(), element.getCY()-element.getRY()));
- rect.setBottomRight(QPointF(element.getCX()+element.getRX(), element.getCY()+element.getRY()));
- if (type_ == GView::New) {
- item = new QGraphicsEllipseItem(rect);
- graphicsView_->addItem(item, id, pos_);
- } else {
- item = qgraphicsitem_cast<QGraphicsEllipseItem*>(graphicsView_->getItem(id));
- item->setRect(rect);
- item->setPos(0,0);
- graphicsView_->deselect(P2QSTRING(element.getID()));
- }
- QPen pen;
- QBrush brush(Qt::SolidPattern);
- WhiteboardColor penColor = element.getPenColor();
- WhiteboardColor brushColor = element.getBrushColor();
- pen.setColor(QColor(penColor.getRed(), penColor.getGreen(), penColor.getBlue(), penColor.getAlpha()));
- pen.setWidth(element.getPenWidth());
- brush.setColor(QColor(brushColor.getRed(), brushColor.getGreen(), brushColor.getBlue(), brushColor.getAlpha()));
- item->setPen(pen);
- item->setBrush(brush);
- item->setData(100, id);
- }
-
- private:
- GView* graphicsView_;
- int pos_;
- GView::Type type_;
- };
+ class WhiteboardElementDrawingVisitor : public WhiteboardElementVisitor {
+ public:
+ WhiteboardElementDrawingVisitor(GView* graphicsView, int pos, GView::Type type) : graphicsView_(graphicsView), pos_(pos), type_(type) {}
+
+ void visit(WhiteboardLineElement& element) {
+ QGraphicsLineItem *item;
+ if (type_ == GView::New) {
+ item = new QGraphicsLineItem(element.x1(), element.y1(), element.x2(), element.y2());
+ graphicsView_->addItem(item, P2QSTRING(element.getID()), pos_);
+ } else {
+ item = qgraphicsitem_cast<QGraphicsLineItem*>(graphicsView_->getItem(P2QSTRING(element.getID())));
+ QLineF line(element.x1(), element.y1(), element.x2(), element.y2());
+ item->setLine(line);
+ item->setPos(0,0);
+ graphicsView_->deselect(P2QSTRING(element.getID()));
+ }
+ if (item) {
+ QPen pen;
+ WhiteboardColor color = element.getColor();
+ pen.setColor(QColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()));
+ pen.setWidth(element.getPenWidth());
+ item->setPen(pen);
+ QString id = P2QSTRING(element.getID());
+ item->setData(100, id);
+ }
+ }
+
+ void visit(WhiteboardFreehandPathElement& element) {
+ FreehandLineItem *item;
+ if (type_ == GView::New) {
+ item = new FreehandLineItem;
+ } else {
+ item = qgraphicsitem_cast<FreehandLineItem*>(graphicsView_->getItem(P2QSTRING(element.getID())));
+ item->setPos(0,0);
+ graphicsView_->deselect(P2QSTRING(element.getID()));
+ }
+
+ if (item) {
+ QPen pen;
+ WhiteboardColor color = element.getColor();
+ pen.setColor(QColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()));
+ pen.setWidth(element.getPenWidth());
+ item->setPen(pen);
+
+ std::vector<std::pair<int, int> >::const_iterator it = element.getPoints().begin();
+ item->setStartPoint(QPointF(it->first, it->second));
+ for (++it; it != element.getPoints().end(); ++it) {
+ item->lineTo(QPointF(it->first, it->second));
+ }
+
+ QString id = P2QSTRING(element.getID());
+ item->setData(100, id);
+ }
+ if (type_ == GView::New) {
+ graphicsView_->addItem(item, P2QSTRING(element.getID()), pos_);
+ }
+ }
+
+ void visit(WhiteboardRectElement& element) {
+ QGraphicsRectItem* item;
+ if (type_ == GView::New) {
+ item = new QGraphicsRectItem(element.getX(), element.getY(), element.getWidth(), element.getHeight());
+ graphicsView_->addItem(item, P2QSTRING(element.getID()), pos_);
+ } else {
+ item = qgraphicsitem_cast<QGraphicsRectItem*>(graphicsView_->getItem(P2QSTRING(element.getID())));
+ QRectF rect(element.getX(), element.getY(), element.getWidth(), element.getHeight());
+ item->setRect(rect);
+ item->setPos(0,0);
+ graphicsView_->deselect(P2QSTRING(element.getID()));
+ }
+
+ if (item) {
+ QPen pen;
+ QBrush brush(Qt::SolidPattern);
+ WhiteboardColor penColor = element.getPenColor();
+ WhiteboardColor brushColor = element.getBrushColor();
+ pen.setColor(QColor(penColor.getRed(), penColor.getGreen(), penColor.getBlue(), penColor.getAlpha()));
+ pen.setWidth(element.getPenWidth());
+ brush.setColor(QColor(brushColor.getRed(), brushColor.getGreen(), brushColor.getBlue(), brushColor.getAlpha()));
+ item->setPen(pen);
+ item->setBrush(brush);
+ QString id = P2QSTRING(element.getID());
+ item->setData(100, id);
+ }
+ }
+
+ void visit(WhiteboardPolygonElement& element) {
+ QGraphicsPolygonItem* item = qgraphicsitem_cast<QGraphicsPolygonItem*>(graphicsView_->getItem(P2QSTRING(element.getID())));
+ if (item == nullptr && type_ == GView::New) {
+ item = new QGraphicsPolygonItem();
+ QString id = P2QSTRING(element.getID());
+ item->setData(100, id);
+ graphicsView_->addItem(item, id, pos_);
+ }
+ graphicsView_->deselect(P2QSTRING(element.getID()));
+ QPen pen;
+ QBrush brush(Qt::SolidPattern);
+ WhiteboardColor penColor = element.getPenColor();
+ WhiteboardColor brushColor = element.getBrushColor();
+ pen.setColor(QColor(penColor.getRed(), penColor.getGreen(), penColor.getBlue(), penColor.getAlpha()));
+ pen.setWidth(element.getPenWidth());
+ brush.setColor(QColor(brushColor.getRed(), brushColor.getGreen(), brushColor.getBlue(), brushColor.getAlpha()));
+ item->setPen(pen);
+ item->setBrush(brush);
+
+ item->setPos(0,0);
+ QPolygonF polygon;
+ std::vector<std::pair<int, int> >::const_iterator it = element.getPoints().begin();
+ for (; it != element.getPoints().end(); ++it) {
+ polygon.append(QPointF(it->first, it->second));
+ }
+ item->setPolygon(polygon);
+ }
+
+ void visit(WhiteboardTextElement& element) {
+ QGraphicsTextItem* item;
+ QString id = P2QSTRING(element.getID());
+ if (type_ == GView::New) {
+ item = new QGraphicsTextItem;
+ graphicsView_->addItem(item, id, pos_);
+ } else {
+ item = qgraphicsitem_cast<QGraphicsTextItem*>(graphicsView_->getItem(id));
+ graphicsView_->deselect(P2QSTRING(element.getID()));
+ }
+ if (item) {
+ item->setPlainText(P2QSTRING(element.getText()));
+ item->setPos(QPointF(element.getX(), element.getY()));
+ QFont font = item->font();
+ font.setPointSize(element.getSize());
+ item->setFont(font);
+ WhiteboardColor color = element.getColor();
+ item->setDefaultTextColor(QColor(color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha()));
+ item->setData(100, id);
+ }
+ }
+
+ void visit(WhiteboardEllipseElement& element) {
+ QRectF rect;
+ QGraphicsEllipseItem* item;
+ QString id = P2QSTRING(element.getID());
+ rect.setTopLeft(QPointF(element.getCX()-element.getRX(), element.getCY()-element.getRY()));
+ rect.setBottomRight(QPointF(element.getCX()+element.getRX(), element.getCY()+element.getRY()));
+ if (type_ == GView::New) {
+ item = new QGraphicsEllipseItem(rect);
+ graphicsView_->addItem(item, id, pos_);
+ } else {
+ item = qgraphicsitem_cast<QGraphicsEllipseItem*>(graphicsView_->getItem(id));
+ item->setRect(rect);
+ item->setPos(0,0);
+ graphicsView_->deselect(P2QSTRING(element.getID()));
+ }
+ QPen pen;
+ QBrush brush(Qt::SolidPattern);
+ WhiteboardColor penColor = element.getPenColor();
+ WhiteboardColor brushColor = element.getBrushColor();
+ pen.setColor(QColor(penColor.getRed(), penColor.getGreen(), penColor.getBlue(), penColor.getAlpha()));
+ pen.setWidth(element.getPenWidth());
+ brush.setColor(QColor(brushColor.getRed(), brushColor.getGreen(), brushColor.getBlue(), brushColor.getAlpha()));
+ item->setPen(pen);
+ item->setBrush(brush);
+ item->setData(100, id);
+ }
+
+ private:
+ GView* graphicsView_;
+ int pos_;
+ GView::Type type_;
+ };
}
diff --git a/Swift/QtUI/WinUIHelpers.cpp b/Swift/QtUI/WinUIHelpers.cpp
index 161ff1d..ec39c38 100644
--- a/Swift/QtUI/WinUIHelpers.cpp
+++ b/Swift/QtUI/WinUIHelpers.cpp
@@ -4,58 +4,62 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
-#include "WinUIHelpers.h"
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
+#include <Swift/QtUI/WinUIHelpers.h>
#include <windows.h>
#include <Wincrypt.h>
#include <cryptuiapi.h>
#pragma comment(lib, "cryptui.lib")
-#include <boost/shared_ptr.hpp>
-
-#include <Swiften/Base/foreach.h>
+#include <memory>
namespace Swift {
void WinUIHelpers::displayCertificateChainAsSheet(QWidget* parent, const std::vector<Certificate::ref>& chain) {
- if (chain.empty()) {
- return;
- }
-
- // create certificate store to store the certificate chain in
- HCERTSTORE chainStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, NULL);
- if (!chainStore) {
- return;
- }
-
- ByteArray certAsDER = chain[0]->toDER();
- boost::shared_ptr<const CERT_CONTEXT> certificate_chain;
- {
- PCCERT_CONTEXT certChain;
- BOOL ok = CertAddCertificateContextToStore(chainStore, CertCreateCertificateContext(X509_ASN_ENCODING, vecptr(certAsDER), certAsDER.size()), CERT_STORE_ADD_ALWAYS, &certChain);
- // maybe free the cert contex we created
- if (!ok || !certChain) {
- return;
- }
- certificate_chain.reset(certChain, CertFreeCertificateContext);
- }
-
- for (size_t i = 1; i < chain.size(); ++i) {
- ByteArray certAsDER = chain[i]->toDER();
- CertAddCertificateContextToStore(chainStore, CertCreateCertificateContext(X509_ASN_ENCODING, vecptr(certAsDER), certAsDER.size()), CERT_STORE_ADD_ALWAYS, NULL);
- }
-
- CRYPTUI_VIEWCERTIFICATE_STRUCT viewDialogProperties = { 0 };
- viewDialogProperties.dwSize = sizeof(viewDialogProperties);
- viewDialogProperties.hwndParent = (HWND) parent->winId();
- viewDialogProperties.dwFlags = CRYPTUI_DISABLE_EDITPROPERTIES | CRYPTUI_DISABLE_ADDTOSTORE | CRYPTUI_ENABLE_REVOCATION_CHECKING;
- viewDialogProperties.pCertContext = certificate_chain.get();
- viewDialogProperties.cStores = 1;
- viewDialogProperties.rghStores = &chainStore;
- BOOL properties_changed;
-
- // blocking call that shows modal certificate dialog
- BOOL rv = ::CryptUIDlgViewCertificate(&viewDialogProperties, &properties_changed);
+ if (chain.empty()) {
+ return;
+ }
+
+ // create certificate store to store the certificate chain in
+ HCERTSTORE chainStore = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, NULL, CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG, NULL);
+ if (!chainStore) {
+ return;
+ }
+
+ ByteArray certAsDER = chain[0]->toDER();
+ std::shared_ptr<const CERT_CONTEXT> certificate_chain;
+ {
+ PCCERT_CONTEXT certChain;
+ BOOL ok = CertAddCertificateContextToStore(chainStore, CertCreateCertificateContext(X509_ASN_ENCODING, vecptr(certAsDER), certAsDER.size()), CERT_STORE_ADD_ALWAYS, &certChain);
+ // maybe free the cert contex we created
+ if (!ok || !certChain) {
+ return;
+ }
+ certificate_chain.reset(certChain, CertFreeCertificateContext);
+ }
+
+ for (size_t i = 1; i < chain.size(); ++i) {
+ ByteArray certAsDER = chain[i]->toDER();
+ CertAddCertificateContextToStore(chainStore, CertCreateCertificateContext(X509_ASN_ENCODING, vecptr(certAsDER), certAsDER.size()), CERT_STORE_ADD_ALWAYS, NULL);
+ }
+
+ CRYPTUI_VIEWCERTIFICATE_STRUCT viewDialogProperties = { 0 };
+ viewDialogProperties.dwSize = sizeof(viewDialogProperties);
+ viewDialogProperties.hwndParent = (HWND) parent->winId();
+ viewDialogProperties.dwFlags = CRYPTUI_DISABLE_EDITPROPERTIES | CRYPTUI_DISABLE_ADDTOSTORE | CRYPTUI_ENABLE_REVOCATION_CHECKING;
+ viewDialogProperties.pCertContext = certificate_chain.get();
+ viewDialogProperties.cStores = 1;
+ viewDialogProperties.rghStores = &chainStore;
+ BOOL properties_changed;
+
+ // blocking call that shows modal certificate dialog
+ BOOL rv = ::CryptUIDlgViewCertificate(&viewDialogProperties, &properties_changed);
}
}
diff --git a/Swift/QtUI/WinUIHelpers.h b/Swift/QtUI/WinUIHelpers.h
index d34d236..36f5c9e 100644
--- a/Swift/QtUI/WinUIHelpers.h
+++ b/Swift/QtUI/WinUIHelpers.h
@@ -4,16 +4,23 @@
* See Documentation/Licenses/BSD-simplified.txt for more information.
*/
+/*
+ * Copyright (c) 2016 Isode Limited.
+ * All rights reserved.
+ * See the COPYING file for more information.
+ */
+
#pragma once
-#include <Swiften/TLS/Certificate.h>
#include <QWidget>
+#include <Swiften/TLS/Certificate.h>
+
namespace Swift {
class WinUIHelpers {
public:
- static void displayCertificateChainAsSheet(QWidget* parent, const std::vector<Certificate::ref>& chain);
+ static void displayCertificateChainAsSheet(QWidget* parent, const std::vector<Certificate::ref>& chain);
};
}
diff --git a/Swift/QtUI/WindowsNotifier.cpp b/Swift/QtUI/WindowsNotifier.cpp
index 1352dfa..d6e8ba9 100644
--- a/Swift/QtUI/WindowsNotifier.cpp
+++ b/Swift/QtUI/WindowsNotifier.cpp
@@ -1,54 +1,50 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#include "WindowsNotifier.h"
+#include <Swift/QtUI/WindowsNotifier.h>
-#include <QSystemTrayIcon>
#include <cassert>
#include <iostream>
+
#include <boost/bind.hpp>
-#include "QtWin32NotifierWindow.h"
-#include "QtSwiftUtil.h"
+#include <QSystemTrayIcon>
+
+#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/QtWin32NotifierWindow.h>
namespace Swift {
WindowsNotifier::WindowsNotifier(const std::string& name, const boost::filesystem::path& icon, QSystemTrayIcon* tray) : tray(tray) {
- notifierWindow = new QtWin32NotifierWindow();
- snarlNotifier = new SnarlNotifier(name, notifierWindow, icon);
- connect(tray, SIGNAL(messageClicked()), SLOT(handleMessageClicked()));
+ notifierWindow = new QtWin32NotifierWindow();
+ connect(tray, SIGNAL(messageClicked()), SLOT(handleMessageClicked()));
}
WindowsNotifier::~WindowsNotifier() {
- delete snarlNotifier;
- delete notifierWindow;
+ delete notifierWindow;
}
void WindowsNotifier::showMessage(Type type, const std::string& subject, const std::string& description, const boost::filesystem::path& picture, boost::function<void()> callback) {
- if (snarlNotifier->isAvailable()) {
- snarlNotifier->showMessage(type, subject, description, picture, callback);
- return;
- }
- std::vector<Notifier::Type> defaultTypes = getDefaultTypes();
- if (std::find(defaultTypes.begin(), defaultTypes.end(), type) == defaultTypes.end()) {
- return;
- }
- lastCallback = callback;
- int timeout = (type == IncomingMessage || type == SystemMessage) ? DEFAULT_MESSAGE_NOTIFICATION_TIMEOUT_SECONDS : DEFAULT_STATUS_NOTIFICATION_TIMEOUT_SECONDS;
- tray->showMessage(P2QSTRING(subject), P2QSTRING(description), type == SystemMessage ? QSystemTrayIcon::Information : QSystemTrayIcon::NoIcon, timeout * 1000);
+ std::vector<Notifier::Type> defaultTypes = getDefaultTypes();
+ if (std::find(defaultTypes.begin(), defaultTypes.end(), type) == defaultTypes.end()) {
+ return;
+ }
+ lastCallback = callback;
+ int timeout = (type == IncomingMessage || type == SystemMessage) ? DEFAULT_MESSAGE_NOTIFICATION_TIMEOUT_SECONDS : DEFAULT_STATUS_NOTIFICATION_TIMEOUT_SECONDS;
+ tray->showMessage(P2QSTRING(subject), P2QSTRING(description), type == SystemMessage ? QSystemTrayIcon::Information : QSystemTrayIcon::NoIcon, timeout * 1000);
}
void WindowsNotifier::handleMessageClicked() {
- if (lastCallback) {
- lastCallback();
- }
+ if (lastCallback) {
+ lastCallback();
+ }
}
void WindowsNotifier::purgeCallbacks() {
- lastCallback = boost::function<void()>();
+ lastCallback = boost::function<void()>();
}
}
diff --git a/Swift/QtUI/WindowsNotifier.h b/Swift/QtUI/WindowsNotifier.h
index fe6bf18..945ef6b 100644
--- a/Swift/QtUI/WindowsNotifier.h
+++ b/Swift/QtUI/WindowsNotifier.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -9,29 +9,30 @@
#include <map>
#include <QObject>
+
#include <SwifTools/Notifier/Notifier.h>
-#include <SwifTools/Notifier/SnarlNotifier.h>
class QSystemTrayIcon;
namespace Swift {
- class WindowsNotifier : public QObject, public Notifier {
- Q_OBJECT
+ class Win32NotifierWindow;
+
+ class WindowsNotifier : public QObject, public Notifier {
+ Q_OBJECT
- public:
- WindowsNotifier(const std::string& name, const boost::filesystem::path& icon, QSystemTrayIcon* tray);
- ~WindowsNotifier();
+ public:
+ WindowsNotifier(const std::string& name, const boost::filesystem::path& icon, QSystemTrayIcon* tray);
+ ~WindowsNotifier();
- virtual void showMessage(Type type, const std::string& subject, const std::string& description, const boost::filesystem::path& picture, boost::function<void()> callback);
- virtual void purgeCallbacks();
+ virtual void showMessage(Type type, const std::string& subject, const std::string& description, const boost::filesystem::path& picture, boost::function<void()> callback);
+ virtual void purgeCallbacks();
- private slots:
- void handleMessageClicked();
+ private slots:
+ void handleMessageClicked();
- private:
- QSystemTrayIcon* tray;
- Win32NotifierWindow* notifierWindow;
- SnarlNotifier* snarlNotifier;
- boost::function<void()> lastCallback;
- };
+ private:
+ QSystemTrayIcon* tray;
+ Win32NotifierWindow* notifierWindow;
+ boost::function<void()> lastCallback;
+ };
}
diff --git a/Swift/QtUI/main.cpp b/Swift/QtUI/main.cpp
index 2b8716c..472c99a 100644
--- a/Swift/QtUI/main.cpp
+++ b/Swift/QtUI/main.cpp
@@ -1,99 +1,125 @@
/*
- * Copyright (c) 2010 Isode Limited.
+ * Copyright (c) 2010-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
+#include <cstdlib>
+#include <iostream>
+#include <locale>
+#include <memory>
+#include <sstream>
+
+#include <boost/date_time/gregorian/gregorian.hpp>
+#include <boost/program_options.hpp>
#include <boost/program_options/options_description.hpp>
#include <boost/program_options/variables_map.hpp>
-#include <boost/program_options.hpp>
#include <boost/version.hpp>
-#include <iostream>
+
#include <QApplication>
-#include <QTextCodec>
-#include <QTranslator>
#include <QLocale>
#include <QStringList>
+#include <QTextCodec>
+#include <QTranslator>
+
+#include <Swiften/Base/Path.h>
-#include <Swift/Controllers/Translator.h>
#include <Swift/Controllers/ApplicationInfo.h>
#include <Swift/Controllers/BuildVersion.h>
+#include <Swift/Controllers/Translator.h>
+
#include <SwifTools/Application/PlatformApplicationPathProvider.h>
#include <SwifTools/CrashReporter.h>
-#include <stdlib.h>
-#include <Swiften/Base/Path.h>
-#include "QtSwift.h"
-#include "QtTranslator.h"
-#include "QtSwiftUtil.h"
+#include <Swift/QtUI/QtSwift.h>
+#include <Swift/QtUI/QtSwiftUtil.h>
+#include <Swift/QtUI/QtTranslator.h>
int main(int argc, char* argv[]) {
- Swift::PlatformApplicationPathProvider applicationPathProvider(SWIFT_APPLICATION_NAME);
+ Swift::PlatformApplicationPathProvider applicationPathProvider(SWIFT_APPLICATION_NAME);
- Swift::CrashReporter crashReporter(applicationPathProvider.getDataDir() / "crashes");
+ // Set crash report prefix to include date and version.
+ std::stringstream prefix;
+
+ // This date_facet will be cleaned up by the stringstream.
+ auto outputFacet = new boost::gregorian::date_facet();
+ outputFacet->format("%Y-%m-%d");
+ prefix.imbue(std::locale(std::locale::classic(), outputFacet));
+
+ prefix << buildVersion << "_" << boost::gregorian::date(boost::gregorian::day_clock::local_day()) << "_";
+
+ Swift::CrashReporter crashReporter(applicationPathProvider.getDataDir() / "crashes", prefix.str());
#if QT_VERSION < 0x050000
- QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
+ QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
#endif
- // Parse program options
- boost::program_options::options_description desc = Swift::QtSwift::getOptionsDescription();
- boost::program_options::variables_map vm;
- try {
- boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
- } catch (const boost::program_options::unknown_option& option) {
+ // Parse program options
+ boost::program_options::options_description desc = Swift::QtSwift::getOptionsDescription();
+ boost::program_options::variables_map vm;
+ try {
+ boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
+ } catch (const boost::program_options::unknown_option& option) {
#if BOOST_VERSION >= 104200
- std::cout << "Ignoring unknown option " << option.get_option_name() << " but continuing." << std::endl;
+ std::cout << "Ignoring unknown option " << option.get_option_name() << " but continuing." << std::endl;
#else
- std::cout << "Error: " << option.what() << " (continuing)" << std::endl;
+ std::cout << "Error: " << option.what() << " (continuing)" << std::endl;
#endif
- }
- boost::program_options::notify(vm);
- if (vm.count("help") > 0) {
- std::cout << SWIFT_APPLICATION_NAME << " is an instant messaging client for the XMPP network." << std::endl;
- std::cout << std::endl;
- std::cout << "Usage: " << argv[0] << " [OPTIONS]..." << std::endl;
- std::cout << std::endl;
- std::cout << desc << std::endl;
- return 1;
- }
- if (vm.count("version") > 0) {
- std::cout << SWIFT_APPLICATION_NAME << " " << buildVersion << std::endl;
- return 0;
- }
-
- // Translation
+ }
+ boost::program_options::notify(vm);
+ if (vm.count("help") > 0) {
+ std::cout << SWIFT_APPLICATION_NAME << " is an instant messaging client for the XMPP network." << std::endl;
+ std::cout << std::endl;
+ std::cout << "Usage: " << argv[0] << " [OPTIONS]..." << std::endl;
+ std::cout << std::endl;
+ std::cout << desc << std::endl;
+ return 1;
+ }
+ if (vm.count("version") > 0) {
+ std::cout << SWIFT_APPLICATION_NAME << " " << buildVersion << std::endl;
+ return 0;
+ }
+
+ // Translation
#if QT_VERSION < 0x050000
- QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
+ QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
#endif
- boost::filesystem::path someTranslationPath = applicationPathProvider.getResourcePath("/translations/swift_en.qm");
+ boost::filesystem::path someTranslationPath = applicationPathProvider.getResourcePath("/translations/swift_en.qm");
- QTranslator qtTranslator;
- if (!someTranslationPath.empty()) {
+ QTranslator qtTranslator;
+ if (!someTranslationPath.empty()) {
#if QT_VERSION >= 0x040800
- if (vm.count("language") > 0) {
- qtTranslator.load(QString(SWIFT_APPLICATION_NAME).toLower() + "_" + P2QSTRING(vm["language"].as<std::string>()), P2QSTRING(Swift::pathToString(someTranslationPath.parent_path())));
- }
- else {
- qtTranslator.load(QLocale::system(), QString(SWIFT_APPLICATION_NAME).toLower(), "_", P2QSTRING(Swift::pathToString(someTranslationPath)));
- }
+ if (vm.count("language") > 0) {
+ qtTranslator.load(QString(SWIFT_APPLICATION_NAME).toLower() + "_" + P2QSTRING(vm["language"].as<std::string>()), P2QSTRING(Swift::pathToString(someTranslationPath.parent_path())));
+ }
+ else {
+ qtTranslator.load(QLocale::system(), QString(SWIFT_APPLICATION_NAME).toLower(), "_", P2QSTRING(Swift::pathToString(someTranslationPath)));
+ }
#else
- //std::cout << "Loading " << std::string(QLocale::system().name().toUtf8()) << std::endl;
- qtTranslator.load(QString(SWIFT_APPLICATION_NAME).toLower() + "_" + QLocale::system().name(), P2QSTRING(Swift::pathToString(someTranslationPath)));
+ //std::cout << "Loading " << std::string(QLocale::system().name().toUtf8()) << std::endl;
+ qtTranslator.load(QString(SWIFT_APPLICATION_NAME).toLower() + "_" + QLocale::system().name(), P2QSTRING(Swift::pathToString(someTranslationPath)));
#endif
- }
+ }
- QApplication app(argc, argv);
+ QApplication app(argc, argv);
- app.installTranslator(&qtTranslator);
- QtTranslator swiftTranslator;
- Swift::Translator::setInstance(&swiftTranslator);
+ app.installTranslator(&qtTranslator);
+ QtTranslator swiftTranslator;
+ Swift::Translator::setInstance(&swiftTranslator);
+#if QT_VERSION < 0x050501
+ /* According to Qt documenation, Qt is suppsoed to set the applications layout
+ * direction based on the translatable QT_LAYOUT_DIRECTION string. There is a
+ * bug in Qt prior version 5.5.1, i.e. QTBUG-43447, thus we set the layout
+ * direction manually based on the tranlsated QT_LAYOUT_DIRECTION string.
+ */
+ app.setLayoutDirection(QGuiApplication::tr("QT_LAYOUT_DIRECTION") == QLatin1String("RTL") ? Qt::RightToLeft : Qt::LeftToRight);
+#endif
- Swift::QtSwift swift(vm);
- int result = app.exec();
+ Swift::QtSwift swift(vm);
+ int result = app.exec();
- Swift::Translator::setInstance(NULL);
+ Swift::Translator::setInstance(nullptr);
- return result;
+ return result;
}
diff --git a/Swift/QtUI/swift-open-uri.cpp b/Swift/QtUI/swift-open-uri.cpp
index a8ae0a4..23a8851 100644
--- a/Swift/QtUI/swift-open-uri.cpp
+++ b/Swift/QtUI/swift-open-uri.cpp
@@ -1,30 +1,31 @@
/*
- * Copyright (c) 2011 Isode Limited.
+ * Copyright (c) 2011-2016 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
+#include <iostream>
+
#include <QCoreApplication>
#include <QDBusConnection>
#include <QDBusMessage>
-#include <iostream>
int main(int argc, char* argv[]) {
- QCoreApplication app(argc, argv);
+ QCoreApplication app(argc, argv);
- QDBusConnection bus = QDBusConnection::sessionBus();
- if (!bus.isConnected()) {
- return -1;
- }
- if (argc != 2) {
- std::cerr << "Usage: " << argv[0] << " uri" << std::endl;
- return -1;
- }
+ QDBusConnection bus = QDBusConnection::sessionBus();
+ if (!bus.isConnected()) {
+ return -1;
+ }
+ if (argc != 2) {
+ std::cerr << "Usage: " << argv[0] << " uri" << std::endl;
+ return -1;
+ }
- QDBusMessage msg = QDBusMessage::createMethodCall("im.swift.Swift.URIHandler", "/", "im.swift.Swift.URIHandler", "openURI");
- msg << argv[1];
+ QDBusMessage msg = QDBusMessage::createMethodCall("im.swift.Swift.URIHandler", "/", "im.swift.Swift.URIHandler", "openURI");
+ msg << argv[1];
- bus.call(msg);
+ bus.call(msg);
- return 0;
+ return 0;
}
diff --git a/Swift/SConscript b/Swift/SConscript
index bf19873..daff755 100644
--- a/Swift/SConscript
+++ b/Swift/SConscript
@@ -5,17 +5,13 @@ Import("env")
SConscript("Controllers/SConscript")
if env["SCONS_STAGE"] == "build" :
- if not GetOption("help") and not env.get("HAVE_OPENSSL", 0) and not env.get("HAVE_SCHANNEL", 0) and not env.get("HAVE_SECURETRANSPORT", 0):
- print "Error: Swift requires OpenSSL support, and OpenSSL was not found."
- if "Swift" in env["PROJECTS"] :
- env["PROJECTS"].remove("Swift")
- elif not GetOption("help") and not env.get("HAVE_QT", 0) :
- if "Swift" in env["PROJECTS"] :
- print "Warning: Swift requires Qt. Not building the Swift Qt application."
- env["PROJECTS"].remove("Swift")
- elif not GetOption("help") and env["target"] == "native" and "Swift" in env["PROJECTS"] :
- try :
- SConscript("QtUI/SConscript")
- except Exception as e:
- print "Warning: %s" % str(e)
- env["PROJECTS"].remove("Swift")
+ if not GetOption("help") and not env.get("HAVE_QT", 0) :
+ if "Swift" in env["PROJECTS"] :
+ print "Warning: Swift requires Qt. Not building the Swift Qt application."
+ env["PROJECTS"].remove("Swift")
+ elif not GetOption("help") and env["target"] == "native" and "Swift" in env["PROJECTS"] :
+ try :
+ SConscript("QtUI/SConscript")
+ except Exception as e:
+ print "Warning: %s" % str(e)
+ env["PROJECTS"].remove("Swift")
diff --git a/Swift/Translations/swift_ca.ts b/Swift/Translations/swift_ca.ts
index a512f1f..8fa72b2 100644
--- a/Swift/Translations/swift_ca.ts
+++ b/Swift/Translations/swift_ca.ts
@@ -704,7 +704,7 @@
</message>
</context>
<context>
- <name>QApplication</name>
+ <name>QGuiApplication</name>
<message>
<location filename="../QtUI/QtStrings.h" line="19"/>
<source>QT_LAYOUT_DIRECTION</source>
diff --git a/Swift/Translations/swift_cs.ts b/Swift/Translations/swift_cs.ts
index 314cd60..3621733 100644
--- a/Swift/Translations/swift_cs.ts
+++ b/Swift/Translations/swift_cs.ts
@@ -697,7 +697,7 @@
</message>
</context>
<context>
- <name>QApplication</name>
+ <name>QGuiApplication</name>
<message>
<location filename="../QtUI/QtStrings.h" line="19"/>
<source>QT_LAYOUT_DIRECTION</source>
diff --git a/Swift/Translations/swift_de.ts b/Swift/Translations/swift_de.ts
index 3f86218..6eaa2ca 100644
--- a/Swift/Translations/swift_de.ts
+++ b/Swift/Translations/swift_de.ts
@@ -879,7 +879,7 @@
</message>
</context>
<context>
- <name>QApplication</name>
+ <name>QGuiApplication</name>
<message>
<location filename="../QtUI/QtStrings.h" line="19"/>
<source>QT_LAYOUT_DIRECTION</source>
diff --git a/Swift/Translations/swift_es.ts b/Swift/Translations/swift_es.ts
index 384c411..e6d414d 100644
--- a/Swift/Translations/swift_es.ts
+++ b/Swift/Translations/swift_es.ts
@@ -704,7 +704,7 @@
</message>
</context>
<context>
- <name>QApplication</name>
+ <name>QGuiApplication</name>
<message>
<location filename="../QtUI/QtStrings.h" line="19"/>
<source>QT_LAYOUT_DIRECTION</source>
diff --git a/Swift/Translations/swift_fr.ts b/Swift/Translations/swift_fr.ts
index b95c0d1..f344a83 100644
--- a/Swift/Translations/swift_fr.ts
+++ b/Swift/Translations/swift_fr.ts
@@ -573,7 +573,7 @@
</message>
</context>
<context>
- <name>QApplication</name>
+ <name>QGuiApplication</name>
<message>
<location filename="../QtUI/QtStrings.h" line="19"/>
<source>QT_LAYOUT_DIRECTION</source>
diff --git a/Swift/Translations/swift_gl.ts b/Swift/Translations/swift_gl.ts
index c189a1d..46acb93 100644
--- a/Swift/Translations/swift_gl.ts
+++ b/Swift/Translations/swift_gl.ts
@@ -575,7 +575,7 @@
</message>
</context>
<context>
- <name>QApplication</name>
+ <name>QGuiApplication</name>
<message>
<location filename="../QtUI/QtStrings.h" line="19"/>
<source>QT_LAYOUT_DIRECTION</source>
diff --git a/Swift/Translations/swift_he.ts b/Swift/Translations/swift_he.ts
index 4a810f8..3a8f400 100644
--- a/Swift/Translations/swift_he.ts
+++ b/Swift/Translations/swift_he.ts
@@ -697,7 +697,7 @@
</message>
</context>
<context>
- <name>QApplication</name>
+ <name>QGuiApplication</name>
<message>
<location filename="../QtUI/QtStrings.h" line="19"/>
<source>QT_LAYOUT_DIRECTION</source>
@@ -2704,7 +2704,7 @@ If you choose to defer this choice, you will be asked again when you next login.
<location filename="../QtUI/QtAboutWidget.cpp" line="49"/>
<location filename="../QtUI/QtAboutWidget.cpp" line="50"/>
<source>TRANSLATION_AUTHOR</source>
- <translation>Isratine Citizen</translation>
+ <translation>Hebrew Translation Team</translation>
</message>
<message>
<location filename="../QtUI/QtAboutWidget.cpp" line="52"/>
diff --git a/Swift/Translations/swift_hu.ts b/Swift/Translations/swift_hu.ts
index 54167e2..d8601aa 100644
--- a/Swift/Translations/swift_hu.ts
+++ b/Swift/Translations/swift_hu.ts
@@ -454,7 +454,7 @@
</message>
</context>
<context>
- <name>QApplication</name>
+ <name>QGuiApplication</name>
<message>
<source>QT_LAYOUT_DIRECTION</source>
<comment>Translate this to LTR for left-to-right or RTL for right-to-left languages</comment>
diff --git a/Swift/Translations/swift_nl.ts b/Swift/Translations/swift_nl.ts
index 3134e65..2686e5e 100644
--- a/Swift/Translations/swift_nl.ts
+++ b/Swift/Translations/swift_nl.ts
@@ -695,7 +695,7 @@
</message>
</context>
<context>
- <name>QApplication</name>
+ <name>QGuiApplication</name>
<message>
<source>QT_LAYOUT_DIRECTION</source>
<comment>Translate this to LTR for left-to-right or RTL for right-to-left languages</comment>
diff --git a/Swift/Translations/swift_pl.ts b/Swift/Translations/swift_pl.ts
index cc461a1..838725e 100644
--- a/Swift/Translations/swift_pl.ts
+++ b/Swift/Translations/swift_pl.ts
@@ -573,7 +573,7 @@
</message>
</context>
<context>
- <name>QApplication</name>
+ <name>QGuiApplication</name>
<message>
<location filename="../QtUI/QtStrings.h" line="19"/>
<source>QT_LAYOUT_DIRECTION</source>
diff --git a/Swift/Translations/swift_ru.ts b/Swift/Translations/swift_ru.ts
index 56069a5..08492f7 100644
--- a/Swift/Translations/swift_ru.ts
+++ b/Swift/Translations/swift_ru.ts
@@ -695,7 +695,7 @@
</message>
</context>
<context>
- <name>QApplication</name>
+ <name>QGuiApplication</name>
<message>
<location filename="../QtUI/QtStrings.h" line="19"/>
<source>QT_LAYOUT_DIRECTION</source>
diff --git a/Swift/Translations/swift_sk.ts b/Swift/Translations/swift_sk.ts
index e99a638..77db4f8 100644
--- a/Swift/Translations/swift_sk.ts
+++ b/Swift/Translations/swift_sk.ts
@@ -698,7 +698,7 @@
</message>
</context>
<context>
- <name>QApplication</name>
+ <name>QGuiApplication</name>
<message>
<location filename="../QtUI/QtStrings.h" line="19"/>
<source>QT_LAYOUT_DIRECTION</source>
diff --git a/Swift/Translations/swift_sv.ts b/Swift/Translations/swift_sv.ts
index b979dab..6aedfb8 100644
--- a/Swift/Translations/swift_sv.ts
+++ b/Swift/Translations/swift_sv.ts
@@ -580,7 +580,7 @@
</message>
</context>
<context>
- <name>QApplication</name>
+ <name>QGuiApplication</name>
<message>
<location filename="../QtUI/QtStrings.h" line="19"/>
<source>QT_LAYOUT_DIRECTION</source>
diff --git a/Swift/resources/icons/avatar.png b/Swift/resources/icons/avatar.png
deleted file mode 100644
index 4b73b44..0000000
--- a/Swift/resources/icons/avatar.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/icons/avatar.svg b/Swift/resources/icons/avatar.svg
index e9f3a89..54e2aae 100644
--- a/Swift/resources/icons/avatar.svg
+++ b/Swift/resources/icons/avatar.svg
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
@@ -13,96 +14,4747 @@
height="128"
id="svg2459"
sodipodi:version="0.32"
- inkscape:version="0.46"
+ inkscape:version="0.91+devel+osxmenu r12922"
sodipodi:docname="avatar.svg"
- inkscape:output_extension="org.inkscape.output.svg.inkscape"
- version="1.0"
- inkscape:export-filename="/Users/remko/src/swift/Swift/resources/icons/avatar.png"
- inkscape:export-xdpi="33.75"
- inkscape:export-ydpi="33.75">
+ viewBox="0 0 89 89"
+ version="1.1">
+ <metadata
+ id="metadata8">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
<defs
- id="defs2461">
+ id="defs6">
+ <linearGradient
+ id="linearGradient4748"
+ spreadMethod="pad"
+ gradientTransform="matrix(1e-8,132.483,132.483,-1e-8,100,38.223)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop4750"
+ offset="0"
+ style="stop-opacity:1;stop-color:#191716" />
+ <stop
+ id="stop4752"
+ offset="1"
+ style="stop-opacity:1;stop-color:#6e6c6f" />
+ </linearGradient>
+ <clipPath
+ id="clipPath4744"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4746"
+ d="m 832.219,1466.16 c -75.211,-74.1 -87.246,-182.97 -48.348,-242.43 4.039,147.22 143.539,286.73 290.739,290.74 -59.43,38.96 -168.247,26.93 -242.391,-48.31 z m 266.441,-914.762 -197.316,0 c -31.125,0 -56.375,-25.226 -56.375,-56.347 0,-31.141 25.25,-56.391 56.375,-56.391 l 9.851,0 c 15.836,-33.269 49.496,-56.43 88.805,-56.43 39.31,0 72.97,23.161 88.81,56.43 l 9.85,0 c 31.12,0 56.37,25.25 56.37,56.391 0,31.121 -25.25,56.347 -56.37,56.347 z m 28.17,140.954 -253.662,0 c -31.148,0 -56.375,-25.243 -56.375,-56.372 0,-31.14 25.227,-56.371 56.375,-56.371 l 253.662,0 c 31.12,0 56.38,25.231 56.38,56.371 0,31.129 -25.26,56.372 -56.38,56.372 z m -23.99,112.757 -205.703,0 c -14.852,129.922 -73.711,203.561 -125.934,268.971 -53.258,66.65 -95.355,119.35 -95.355,238.34 0,173.87 142.394,310.06 324.152,310.06 178.73,0 324.15,-145.41 324.15,-324.14 0,-108.68 -38.54,-155.55 -91.94,-220.48 -51.08,-62.12 -114.03,-138.649 -129.37,-272.751 z M 1000,1707.05 c -225.77,0 -408.727,-168.87 -408.727,-394.63 0,-281.87 205.59,-286.54 223.61,-535.549 2.211,-31.051 27.137,-56.332 58.285,-56.332 l 253.662,0 c 31.12,0 56.11,25.281 58.29,56.332 17.96,251.809 223.61,253.679 223.61,521.469 0,225.74 -182.99,408.71 -408.73,408.71 z"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4730"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4732"
+ d="m 300.047,1685.95 c 0.398,27.09 19.152,49.74 44.312,56.1 -18.988,-13.76 -33.398,-33.44 -44.312,-56.1 m 1399.743,3.16 c -10.51,21.05 -24.24,39.32 -42.19,52.41 23.18,-6.73 40.49,-27.43 42.19,-52.41"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4718"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4720"
+ d="m 292.504,1668.47 0,15.42 c 0,37.22 30.211,67.46 67.344,67.52 -5.477,-2.7 -10.633,-5.84 -15.489,-9.36 -25.16,-6.36 -43.914,-29.01 -44.312,-56.1 -2.727,-5.66 -5.235,-11.5 -7.543,-17.48 m 1414.956,3.42 c -2.34,5.91 -4.89,11.66 -7.67,17.22 -1.7,24.98 -19.01,45.68 -42.19,52.41 -5.12,3.73 -10.59,7.05 -16.41,9.88 36.65,-0.61 66.27,-30.63 66.27,-67.51 l 0,-12"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4706"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4708"
+ d="m 284.973,1646.18 0,36.54 c 0,42.07 34.191,76.27 76.203,76.27 l 19.051,0 c -7.243,-1.89 -14.024,-4.44 -20.379,-7.58 -37.133,-0.06 -67.344,-30.3 -67.344,-67.52 l 0,-15.42 c -2.793,-7.26 -5.293,-14.7 -7.531,-22.29 M 1715,1650.2 c -2.24,7.4 -4.74,14.64 -7.54,21.69 l 0,12 c 0,36.88 -29.62,66.9 -66.27,67.51 -6.46,3.14 -13.37,5.7 -20.75,7.59 l 18.4,0 c 41.99,0 76.16,-34.2 76.16,-76.27 l 0,-32.52"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4694"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4696"
+ d="m 277.438,1615.76 0,65.79 c 0,46.88 38.121,85.02 84.96,85.02 l 1275.232,0 c 46.81,0 84.91,-38.14 84.91,-85.02 l 0,-61.09 c -2.1,10.03 -4.59,20.01 -7.54,29.74 l 0,32.52 c 0,42.07 -34.17,76.27 -76.16,76.27 l -18.4,0 c -9.8,2.51 -20.45,3.85 -32.01,3.85 l -1176.856,0 c -11.301,0 -21.726,-1.34 -31.347,-3.85 l -19.051,0 c -42.012,0 -76.203,-34.2 -76.203,-76.27 l 0,-36.54 c -2.942,-9.98 -5.434,-20.18 -7.535,-30.42"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4682"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4684"
+ d="m 269.906,1565.73 0,114.65 c 0,5.91 0.551,11.69 1.602,17.3 3.906,14.17 9.91,27.48 17.656,39.57 17.145,22.41 44.145,36.89 74.453,36.89 l 1272.793,0 c 30.68,0 57.96,-14.84 75.06,-37.74 7.24,-11.48 12.92,-24.04 16.74,-37.38 1.22,-6.03 1.86,-12.26 1.86,-18.64 l 0,-109.22 c -1.67,16.1 -4.08,32.78 -7.53,49.3 l 0,61.09 c 0,46.88 -38.1,85.02 -84.91,85.02 l -1275.232,0 c -46.839,0 -84.96,-38.14 -84.96,-85.02 l 0,-65.79 c -3.458,-16.85 -5.864,-33.79 -7.532,-50.03"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4670"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4672"
+ d="m 1733.79,1489.91 c 0,21.11 -0.48,50.07 -3.72,81.25 l 0,109.22 c 0,6.38 -0.64,12.61 -1.86,18.64 3.63,-12.69 5.58,-26.09 5.58,-39.92 l 0,-169.19 m -1467.485,0 0,169.19 c 0,13.35 1.812,26.29 5.203,38.58 -1.051,-5.61 -1.602,-11.39 -1.602,-17.3 l 0,-114.65 c -2.988,-29.11 -3.601,-55.94 -3.601,-75.82 M 1711.47,1736.4 c -17.1,22.9 -44.38,37.74 -75.06,37.74 l -1272.793,0 c -30.308,0 -57.308,-14.48 -74.453,-36.89 8.082,12.62 18.059,23.91 29.524,33.46 13.878,7.04 29.558,11.01 46.152,11.01 l 1270.36,0 c 16.65,0 32.38,-4 46.3,-11.09 11.68,-9.76 21.81,-21.31 29.97,-34.23"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4658"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4660"
+ d="m 1681.5,1770.63 c -13.92,7.09 -29.65,11.09 -46.3,11.09 l -1270.36,0 c -16.594,0 -32.274,-3.97 -46.152,-11.01 7.277,6.08 15.144,11.44 23.519,16.01 7.688,1.69 15.672,2.58 23.855,2.58 l 1267.928,0 c 8.2,0 16.19,-0.9 23.89,-2.59 8.41,-4.59 16.32,-9.98 23.62,-16.08"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4646"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4648"
+ d="m 1657.88,1786.71 c -7.7,1.69 -15.69,2.59 -23.89,2.59 l -1267.928,0 c -8.183,0 -16.167,-0.89 -23.855,-2.58 7.367,4.02 15.133,7.43 23.203,10.14 0.621,0.01 1.25,0.02 1.875,0.02 l 1265.485,0 c 0.62,0 1.25,-0.01 1.87,-0.02 8.08,-2.71 15.86,-6.12 23.24,-10.15"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4634"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4636"
+ d="m 365.41,1796.86 c 14.512,4.88 30.031,7.52 46.164,7.52 l 1176.856,0 c 16.15,0 31.68,-2.64 46.21,-7.52 -0.62,0.01 -1.25,0.02 -1.87,0.02 l -1265.485,0 c -0.625,0 -1.254,-0.01 -1.875,-0.02"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4622"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4624"
+ d="m 300.039,1666.88 0,18.18 c 0,0.3 0,0.6 0.008,0.89 10.914,22.66 25.324,42.34 44.312,56.1 4.602,1.16 9.418,1.78 14.371,1.78 l 14.618,0 c -2.598,-0.9 -5.047,-1.89 -7.313,-2.96 -30.355,-13.17 -51.543,-40.91 -65.996,-73.99 m 1399.891,2.86 c -14.26,31.74 -35.08,58.22 -64.87,71.04 -2.36,1.11 -4.93,2.12 -7.64,3.05 l 13.84,0 c 5.67,0 11.15,-0.8 16.34,-2.31 17.95,-13.09 31.68,-31.36 42.19,-52.41 0.09,-1.33 0.14,-2.69 0.14,-4.05 l 0,-15.32"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4610"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4612"
+ d="m 292.504,1647.49 0,20.98 c 2.308,5.98 4.816,11.82 7.543,17.48 -0.008,-0.29 -0.008,-0.59 -0.008,-0.89 l 0,-18.18 c -2.75,-6.29 -5.258,-12.77 -7.535,-19.39 m 1414.956,3.36 c -2.28,6.45 -4.78,12.77 -7.53,18.89 l 0,15.32 c 0,1.36 -0.05,2.72 -0.14,4.05 2.78,-5.56 5.33,-11.31 7.67,-17.22 l 0,-21.04 m -49.86,90.67 c -5.19,1.51 -10.67,2.31 -16.34,2.31 l -13.84,0 c -12.66,4.33 -28.7,6.72 -43.38,6.72 l -1168.177,0 c -14.347,0 -30.086,-2.39 -42.515,-6.72 l -14.618,0 c -4.953,0 -9.769,-0.62 -14.371,-1.78 4.856,3.52 10.012,6.66 15.489,9.36 0.035,0 0.07,0 0.105,0 l 1280.097,0 c 0.38,0 0.76,0 1.14,-0.01 5.82,-2.83 11.29,-6.15 16.41,-9.88"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4598"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4600"
+ d="m 284.973,1622.14 0,24.04 c 2.238,7.59 4.738,15.03 7.531,22.29 l 0,-20.98 c -2.856,-8.29 -5.356,-16.78 -7.531,-25.35 M 1715,1626.08 c -2.18,8.39 -4.68,16.69 -7.54,24.77 l 0,21.04 c 2.8,-7.05 5.3,-14.29 7.54,-21.69 l 0,-24.12 m -73.81,125.32 c -0.38,0.01 -0.76,0.01 -1.14,0.01 l -1280.097,0 c -0.035,0 -0.07,0 -0.105,0 6.355,3.14 13.136,5.69 20.379,7.58 l 1240.213,0 c 7.38,-1.89 14.29,-4.45 20.75,-7.59"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4586"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4588"
+ d="m 277.438,1584.72 0,31.04 c 2.101,10.24 4.593,20.44 7.535,30.42 l 0,-24.04 c -3.157,-12.43 -5.637,-25.03 -7.535,-37.42 m 1445.102,4.76 c -1.91,12.16 -4.39,24.48 -7.54,36.6 l 0,24.12 c 2.95,-9.73 5.44,-19.71 7.54,-29.74 l 0,-30.98 m -102.1,169.51 -1240.213,0 c 9.621,2.51 20.046,3.85 31.347,3.85 l 1176.856,0 c 11.56,0 22.21,-1.34 32.01,-3.85"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4574"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4576"
+ d="m 269.906,1516.99 0,48.74 c 1.668,16.24 4.074,33.18 7.532,50.03 l 0,-31.04 c -1.008,-6.58 -1.852,-13.09 -2.547,-19.49 -1.856,-17.17 -3.489,-33.62 -4.985,-48.24 m 1460.164,2.4 c -1.34,13.97 -2.78,29.53 -4.4,45.73 -0.81,7.97 -1.84,16.13 -3.13,24.36 l 0,30.98 c 3.45,-16.52 5.86,-33.2 7.53,-49.3 l 0,-51.77 M 271.508,1697.68 c 2.746,14.67 8.922,28.16 17.656,39.57 -7.746,-12.09 -13.75,-25.4 -17.656,-39.57 m 1456.702,1.34 c -3.82,13.34 -9.5,25.9 -16.74,37.38 8.13,-10.88 13.95,-23.59 16.74,-37.38"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4562"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4564"
+ d="m 1733.79,1484.29 c -1.22,9.68 -2.42,21.66 -3.72,35.1 l 0,51.77 c 3.24,-31.18 3.72,-60.14 3.72,-81.25 l 0,169.19 c 0,13.83 -1.95,27.23 -5.58,39.92 -2.79,13.79 -8.61,26.5 -16.74,37.38 -8.16,12.92 -18.29,24.47 -29.97,34.23 5.69,-2.9 11.08,-6.32 16.1,-10.2 22.2,-23.62 36.84,-54.42 40.01,-88.5 l 0,-150.54 c -0.78,-15.53 -2.2,-37.1 -3.82,-37.1 m -1467.485,0 c -1.696,0 -3.172,23.66 -3.93,39.27 l 0,147.2 c 2.945,34.65 17.738,65.97 40.301,89.88 4.996,3.83 10.355,7.21 16.012,10.07 -11.465,-9.55 -21.442,-20.84 -29.524,-33.46 -8.734,-11.41 -14.91,-24.9 -17.656,-39.57 -3.391,-12.29 -5.203,-25.23 -5.203,-38.58 l 0,-169.19 c 0,19.88 0.613,46.71 3.601,75.82 l 0,-48.74 c -1.277,-12.47 -2.461,-23.6 -3.601,-32.7"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4550"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4552"
+ d="m 1737.61,1521.39 0,150.54 c 0.43,-4.61 0.64,-9.27 0.64,-13.98 l 0,-121.07 c 0,-0.85 -0.23,-7.34 -0.64,-15.49 m -1475.235,2.17 c -0.348,7.13 -0.543,12.58 -0.543,13.35 l 0,121.04 c 0,4.32 0.184,8.59 0.543,12.81 l 0,-147.2 M 1697.6,1760.43 c -5.02,3.88 -10.41,7.3 -16.1,10.2 -7.3,6.1 -15.21,11.49 -23.62,16.08 4.39,-0.97 8.68,-2.19 12.86,-3.67 9.82,-6.47 18.83,-14.07 26.86,-22.61 m -1394.924,0.21 c 7.988,8.47 16.945,16 26.695,22.43 4.172,1.47 8.453,2.69 12.836,3.65 -8.375,-4.57 -16.242,-9.93 -23.519,-16.01 -5.657,-2.86 -11.016,-6.24 -16.012,-10.07"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4538"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4540"
+ d="m 1670.74,1783.04 c -4.18,1.48 -8.47,2.7 -12.86,3.67 -7.38,4.03 -15.16,7.44 -23.24,10.15 3.91,-0.06 7.77,-0.31 11.59,-0.74 8.6,-3.6 16.81,-8 24.51,-13.08 m -1341.369,0.03 c 7.688,5.07 15.871,9.45 24.453,13.05 3.813,0.43 7.672,0.68 11.586,0.74 -8.07,-2.71 -15.836,-6.12 -23.203,-10.14 -4.383,-0.96 -8.664,-2.18 -12.836,-3.65"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4526"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4528"
+ d="m 1646.23,1796.12 c -3.82,0.43 -7.68,0.68 -11.59,0.74 -14.53,4.88 -30.06,7.52 -46.21,7.52 l -1176.856,0 c -16.133,0 -31.652,-2.64 -46.164,-7.52 -3.914,-0.06 -7.773,-0.31 -11.586,-0.74 8.504,3.58 17.395,6.38 26.61,8.33 l 1239.166,0 c 9.22,-1.95 18.12,-4.75 26.63,-8.33"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4514"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4516"
+ d="m 1619.6,1804.45 -1239.166,0 c 10.046,2.14 20.468,3.26 31.14,3.26 l 1176.856,0 c 10.68,0 21.11,-1.12 31.17,-3.26"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4502"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4504"
+ d="m 300.039,1647.09 0,19.79 c 14.453,33.08 35.641,60.82 65.996,73.99 2.266,1.07 4.715,2.06 7.313,2.96 l 1254.072,0 c 2.71,-0.93 5.28,-1.94 7.64,-3.05 29.79,-12.82 50.61,-39.3 64.87,-71.04 l 0,-19.86 c -14.6,36.12 -36.98,66.82 -69.54,79.58 -12.02,5.62 -34.69,8.79 -50.74,8.79 l -1159.494,0 c -15.613,0 -37.769,-3.14 -49.566,-8.71 -33.051,-13.05 -55.789,-45.06 -70.551,-82.45"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4490"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4492"
+ d="m 292.504,1625.41 0,22.08 c 2.277,6.62 4.785,13.1 7.535,19.39 l 0,-19.79 c -2.793,-7.06 -5.301,-14.33 -7.535,-21.68 m 1414.956,3.26 c -2.23,7.21 -4.74,14.31 -7.53,21.21 l 0,19.86 c 2.75,-6.12 5.25,-12.44 7.53,-18.89 l 0,-22.18 m -80.04,115.16 -1254.072,0 c 12.429,4.33 28.168,6.72 42.515,6.72 l 1168.177,0 c 14.68,0 30.72,-2.39 43.38,-6.72"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4478"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4480"
+ d="m 284.973,1595.72 0,26.42 c 2.175,8.57 4.675,17.06 7.531,25.35 l 0,-22.08 c -2.977,-9.79 -5.473,-19.76 -7.531,-29.69 m 1430.027,3.9 c -2.07,9.74 -4.57,19.49 -7.54,29.05 l 0,22.18 c 2.86,-8.08 5.36,-16.38 7.54,-24.77 l 0,-26.46"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4466"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4468"
+ d="m 277.438,1542.25 0,42.47 c 1.898,12.39 4.378,24.99 7.535,37.42 l 0,-26.42 c -2.77,-13.34 -4.739,-26.61 -6.008,-39.28 -0.477,-4.81 -0.985,-9.55 -1.527,-14.19 m 1445.102,4.06 c -0.35,3.3 -0.68,6.65 -0.98,10.03 -1.3,13.94 -3.44,28.6 -6.56,43.28 l 0,26.46 c 3.15,-12.12 5.63,-24.44 7.54,-36.6 l 0,-43.17"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4454"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4456"
+ d="m 269.906,1493.76 0,23.23 c 1.496,14.62 3.129,31.07 4.985,48.24 0.695,6.4 1.539,12.91 2.547,19.49 l 0,-42.47 c -2.114,-18.17 -4.708,-34.91 -7.532,-48.49 m 1460.164,0.72 c -2.92,14.47 -5.51,32.43 -7.53,51.83 l 0,43.17 c 1.29,-8.23 2.32,-16.39 3.13,-24.36 1.62,-16.2 3.06,-31.76 4.4,-45.73 l 0,-24.91"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4442"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4444"
+ d="m 1733.79,1478.66 c -1.28,4.6 -2.53,9.92 -3.72,15.82 l 0,24.91 c 1.3,-13.44 2.5,-25.42 3.72,-35.1 1.62,0 3.04,21.57 3.82,37.1 l 0,-33.75 c -1.16,-5.35 -2.45,-8.98 -3.82,-8.98 m -1467.485,0 c -1.41,0 -2.743,3.87 -3.93,9.5 l 0,35.4 c 0.758,-15.61 2.234,-39.27 3.93,-39.27 1.14,9.1 2.324,20.23 3.601,32.7 l 0,-23.23 c -1.168,-5.61 -2.375,-10.69 -3.601,-15.1 m -3.93,192.1 0,8.44 c 0,13.42 2.59,26.24 7.297,38 1.82,4.26 3.832,8.44 6.016,12.49 6.843,12.04 16.05,22.58 26.988,30.95 -22.563,-23.91 -37.356,-55.23 -40.301,-89.88 m 1475.235,1.17 c -3.17,34.08 -17.81,64.88 -40.01,88.5 24.31,-18.76 40.01,-48.2 40.01,-81.23 l 0,-7.27"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4430"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4432"
+ d="m 1737.61,1487.64 0,33.75 c 0.41,8.15 0.64,14.64 0.64,15.49 l 0,121.07 c 0,4.71 -0.21,9.37 -0.64,13.98 l 0,7.27 c 0,33.03 -15.7,62.47 -40.01,81.23 -8.03,8.54 -17.04,16.14 -26.86,22.61 5.12,-1.8 10.07,-3.97 14.81,-6.47 34.86,-28.3 57.17,-71.47 57.17,-119.77 l 0,-125.88 c 0,-3.57 -2.09,-29.31 -5.11,-43.28 m -1475.235,0.52 c -2.973,14.09 -5.02,39.26 -5.02,42.79 l 0,125.85 c 0,21.43 4.387,41.84 12.317,60.4 -4.707,-11.76 -7.297,-24.58 -7.297,-38 l 0,-8.44 c -0.359,-4.22 -0.543,-8.49 -0.543,-12.81 l 0,-121.04 c 0,-0.77 0.195,-6.22 0.543,-13.35 l 0,-35.4 m 13.313,241.53 c 9.757,18.13 23.039,34.09 38.917,46.96 4.731,2.48 9.665,4.64 14.766,6.42 -9.75,-6.43 -18.707,-13.96 -26.695,-22.43 -10.938,-8.37 -20.145,-18.91 -26.988,-30.95"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4418"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4420"
+ d="m 1685.55,1776.57 c -4.74,2.5 -9.69,4.67 -14.81,6.47 -7.7,5.08 -15.91,9.48 -24.51,13.08 4.29,-0.48 8.51,-1.19 12.66,-2.11 9.5,-4.9 18.43,-10.75 26.66,-17.44 m -1370.945,0.08 c 8.207,6.66 17.102,12.48 26.571,17.36 4.14,0.92 8.359,1.63 12.648,2.11 -8.582,-3.6 -16.765,-7.98 -24.453,-13.05 -5.101,-1.78 -10.035,-3.94 -14.766,-6.42"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4406"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4408"
+ d="m 1658.89,1794.01 c -4.15,0.92 -8.37,1.63 -12.66,2.11 -8.51,3.58 -17.41,6.38 -26.63,8.33 l 11.96,0 c 0.52,0 1.05,0 1.57,-0.01 8.95,-2.71 17.57,-6.22 25.76,-10.43 m -1317.714,0 c 8.176,4.22 16.785,7.72 25.726,10.43 0.536,0.01 1.067,0.01 1.606,0.01 l 11.926,0 c -9.215,-1.95 -18.106,-4.75 -26.61,-8.33 -4.289,-0.48 -8.508,-1.19 -12.648,-2.11"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4394"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4396"
+ d="m 366.902,1804.44 c 14.145,4.29 29.145,6.6 44.672,6.6 l 1176.856,0 c 15.54,0 30.55,-2.31 44.7,-6.6 -0.52,0.01 -1.05,0.01 -1.57,0.01 l -11.96,0 c -10.06,2.14 -20.49,3.26 -31.17,3.26 l -1176.856,0 c -10.672,0 -21.094,-1.12 -31.14,-3.26 l -11.926,0 c -0.539,0 -1.07,0 -1.606,-0.01"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4382"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4384"
+ d="m 300.039,1626.46 0,20.63 c 14.762,37.39 37.5,69.4 70.551,82.45 11.797,5.57 33.953,8.71 49.566,8.71 l 1159.494,0 c 16.05,0 38.72,-3.17 50.74,-8.79 32.56,-12.76 54.94,-43.46 69.54,-79.58 l 0,-20.74 c -14.72,40.73 -38.77,76.51 -74.2,89 -10.68,5 -36.2,7.81 -50.47,7.81 l -1150.815,0 c -13.875,0 -38.812,-2.78 -49.3,-7.74 -35.868,-12.73 -60.274,-49.86 -75.106,-91.75"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4370"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4372"
+ d="m 292.504,1601.8 0,23.61 c 2.234,7.35 4.742,14.62 7.535,21.68 l 0,-20.63 c -2.863,-8.09 -5.371,-16.35 -7.535,-24.66 m 1414.956,3.18 c -2.17,8.15 -4.67,16.25 -7.53,24.16 l 0,20.74 c 2.79,-6.9 5.3,-14 7.53,-21.21 l 0,-23.69"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4358"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4360"
+ d="m 284.973,1564.2 0,31.52 c 2.058,9.93 4.554,19.9 7.531,29.69 l 0,-23.61 c -3.289,-12.61 -5.781,-25.31 -7.531,-37.6 M 1715,1568.43 c -1.79,12 -4.28,24.33 -7.54,36.55 l 0,23.69 c 2.97,-9.56 5.47,-19.31 7.54,-29.05 l 0,-31.19"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4346"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4348"
+ d="m 277.438,1509.34 0,32.91 c 0.542,4.64 1.05,9.38 1.527,14.19 1.269,12.67 3.238,25.94 6.008,39.28 l 0,-31.52 c -0.801,-5.62 -1.446,-11.16 -1.938,-16.56 -1.211,-13.6 -3.16,-26.63 -5.597,-38.3 m 1445.102,1.27 c -2.25,11.32 -4.02,23.86 -5.1,36.95 -0.57,6.77 -1.38,13.76 -2.44,20.87 l 0,31.19 c 3.12,-14.68 5.26,-29.34 6.56,-43.28 0.3,-3.38 0.63,-6.73 0.98,-10.03 l 0,-35.7"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4334"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4336"
+ d="m 269.906,1481.84 0,11.92 c 2.824,13.58 5.418,30.32 7.532,48.49 l 0,-32.91 c -2.18,-10.44 -4.75,-19.79 -7.532,-27.5 m 1460.164,0.36 c -2.82,7.95 -5.39,17.62 -7.53,28.41 l 0,35.7 c 2.02,-19.4 4.61,-37.36 7.53,-51.83 l 0,-12.28"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4322"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4324"
+ d="m 1733.79,1473.04 c -1.28,2.71 -2.52,5.78 -3.72,9.16 l 0,12.28 c 1.19,-5.9 2.44,-11.22 3.72,-15.82 1.37,0 2.66,3.63 3.82,8.98 l 0,-10.78 c -1.21,-2.39 -2.49,-3.82 -3.82,-3.82 m -1467.485,0 c -1.367,0 -2.688,1.52 -3.93,4.05 l 0,11.07 c 1.187,-5.63 2.52,-9.5 3.93,-9.5 1.226,4.41 2.433,9.49 3.601,15.1 l 0,-11.92 c -1.168,-3.23 -2.371,-6.18 -3.601,-8.8 m 3.367,244.16 c 1.726,4.31 3.742,8.49 6.016,12.49 -2.184,-4.05 -4.196,-8.23 -6.016,-12.49"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4310"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4312"
+ d="m 1737.61,1476.86 0,10.78 c 3.02,13.97 5.11,39.71 5.11,43.28 l 0,125.88 c 0,48.3 -22.31,91.47 -57.17,119.77 6.56,-3.45 12.73,-7.54 18.44,-12.18 21.18,-22.49 35.88,-51.14 41.1,-82.93 0.04,-1.14 0.05,-2.28 0.05,-3.43 l 0,-171.22 c -1.71,-10.96 -4.38,-23.72 -7.53,-29.95 m -1475.235,0.23 c -3.168,6.42 -5.84,19.36 -7.535,30.32 l 0,170.62 c 0,0.94 0.012,1.87 0.035,2.8 5.145,32.15 19.973,61.1 41.387,83.76 5.679,4.59 11.824,8.64 18.343,12.06 -15.878,-12.87 -29.16,-28.83 -38.917,-46.96 -2.274,-4 -4.29,-8.18 -6.016,-12.49 -7.93,-18.56 -12.317,-38.97 -12.317,-60.4 l 0,-125.85 c 0,-3.53 2.047,-28.7 5.02,-42.79 l 0,-11.07"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4298"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4300"
+ d="m 1745.14,1506.81 0,171.22 c 0,1.15 -0.01,2.29 -0.05,3.43 1.38,-8.4 2.1,-17.02 2.1,-25.8 l 0,-130.7 c 0,-2.61 -0.75,-9.87 -2.05,-18.15 m -1490.3,0.6 c -1.242,8.05 -1.957,15.02 -1.957,17.58 l 0,130.67 c 0,8.56 0.679,16.97 1.992,25.17 -0.023,-0.93 -0.035,-1.86 -0.035,-2.8 l 0,-170.62 m 1449.15,256.98 c -5.71,4.64 -11.88,8.73 -18.44,12.18 -8.23,6.69 -17.16,12.54 -26.66,17.44 4.83,-1.08 9.56,-2.46 14.15,-4.1 11.38,-7.19 21.77,-15.77 30.95,-25.52 m -1407.728,0.2 c 9.14,9.67 19.476,18.2 30.773,25.34 4.594,1.64 9.313,3 14.141,4.08 -9.469,-4.88 -18.364,-10.7 -26.571,-17.36 -6.519,-3.42 -12.664,-7.47 -18.343,-12.06"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4286"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4288"
+ d="m 1673.04,1789.91 c -4.59,1.64 -9.32,3.02 -14.15,4.1 -8.19,4.21 -16.81,7.72 -25.76,10.43 4.26,-0.05 8.47,-0.31 12.61,-0.76 9.58,-3.73 18.73,-8.35 27.3,-13.77 m -1346.005,0.02 c 8.57,5.41 17.688,10.03 27.25,13.74 4.149,0.46 8.36,0.72 12.617,0.77 -8.941,-2.71 -17.55,-6.21 -25.726,-10.43 -4.828,-1.08 -9.547,-2.44 -14.141,-4.08"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4274"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4276"
+ d="m 354.285,1803.67 c 9.606,3.73 19.664,6.56 30.063,8.36 l 1231.322,0 c 10.41,-1.8 20.47,-4.63 30.07,-8.35 -4.14,0.45 -8.35,0.71 -12.61,0.76 -14.15,4.29 -29.16,6.6 -44.7,6.6 l -1176.856,0 c -15.527,0 -30.527,-2.31 -44.672,-6.6 -4.257,-0.05 -8.468,-0.31 -12.617,-0.77"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4262"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4264"
+ d="m 1615.67,1812.03 -1231.322,0 c 8.847,1.54 17.945,2.34 27.226,2.34 l 1176.856,0 c 9.29,0 18.39,-0.8 27.24,-2.34"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4250"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4252"
+ d="m 300.039,1604.76 0,21.7 c 14.832,41.89 39.238,79.02 75.106,91.75 10.488,4.96 35.425,7.74 49.3,7.74 l 1150.815,0 c 14.27,0 39.79,-2.81 50.47,-7.81 35.43,-12.49 59.48,-48.27 74.2,-89 l 0,-21.81 c -14.49,45.48 -40.39,87.47 -78.86,99.49 -9.35,4.37 -37.72,6.84 -50.2,6.84 l -1142.132,0 c -12.144,0 -39.863,-2.44 -49.039,-6.78 -38.863,-12.2 -65.121,-55.61 -79.66,-102.12"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4238"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4240"
+ d="m 292.504,1575.71 0,26.09 c 2.164,8.31 4.672,16.57 7.535,24.66 l 0,-21.7 c -3.012,-9.63 -5.519,-19.4 -7.535,-29.05 m 1414.956,3.18 c -2.03,9.47 -4.54,19.03 -7.53,28.44 l 0,21.81 c 2.86,-7.91 5.36,-16.01 7.53,-24.16 l 0,-26.09"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4226"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4228"
+ d="m 284.973,1521.07 0,43.13 c 1.75,12.29 4.242,24.99 7.531,37.6 l 0,-26.09 c -2.645,-12.67 -4.438,-25.15 -5.395,-36.86 -0.48,-6.08 -1.207,-12.04 -2.136,-17.78 M 1715,1523.42 c -0.72,4.99 -1.29,10.13 -1.67,15.35 -0.96,12.71 -2.91,26.33 -5.87,40.12 l 0,26.09 c 3.26,-12.22 5.75,-24.55 7.54,-36.55 l 0,-45.01"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4214"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4216"
+ d="m 277.438,1490.42 0,18.92 c 2.437,11.67 4.386,24.7 5.597,38.3 0.492,5.4 1.137,10.94 1.938,16.56 l 0,-43.13 c -1.817,-11.22 -4.422,-21.64 -7.535,-30.65 m 1445.102,0.55 c -3.2,9.52 -5.82,20.57 -7.54,32.45 l 0,45.01 c 1.06,-7.11 1.87,-14.1 2.44,-20.87 1.08,-13.09 2.85,-25.63 5.1,-36.95 l 0,-19.64"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4202"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4204"
+ d="m 269.906,1473.14 0,8.7 c 2.782,7.71 5.352,17.06 7.532,27.5 l 0,-18.92 c -2.274,-6.58 -4.821,-12.42 -7.532,-17.28 m 1460.164,0.22 c -2.73,4.94 -5.28,10.9 -7.53,17.61 l 0,19.64 c 2.14,-10.79 4.71,-20.46 7.53,-28.41 l 0,-8.84"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4190"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4192"
+ d="m 1733.79,1467.42 c -1.27,1.77 -2.51,3.76 -3.72,5.94 l 0,8.84 c 1.2,-3.38 2.44,-6.45 3.72,-9.16 1.33,0 2.61,1.43 3.82,3.82 l 0,-7.4 c -1.23,-1.3 -2.51,-2.04 -3.82,-2.04 m -1467.485,0 c -1.352,0 -2.664,0.78 -3.93,2.15 l 0,7.52 c 1.242,-2.53 2.563,-4.05 3.93,-4.05 1.23,2.62 2.433,5.57 3.601,8.8 l 0,-8.7 c -1.172,-2.09 -2.375,-4.01 -3.601,-5.72"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4178"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4180"
+ d="m 1737.61,1469.46 0,7.4 c 3.15,6.23 5.82,18.99 7.53,29.95 l 0,-21.63 c -2.14,-6.82 -4.71,-12.75 -7.53,-15.72 m -1475.235,0.11 c -2.82,3.06 -5.391,9.06 -7.535,15.92 l 0,21.92 c 1.695,-10.96 4.367,-23.9 7.535,-30.32 l 0,-7.52 m -7.5,211.26 c 0.84,33.78 16.816,63.88 41.387,83.76 -21.414,-22.66 -36.242,-51.61 -41.387,-83.76 m 1490.215,0.63 c -5.22,31.79 -19.92,60.44 -41.1,82.93 24.27,-19.75 40.09,-49.52 41.1,-82.93"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4166"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4168"
+ d="m 1745.14,1485.18 0,21.63 c 1.3,8.28 2.05,15.54 2.05,18.15 l 0,130.7 c 0,8.78 -0.72,17.4 -2.1,25.8 -1.01,33.41 -16.83,63.18 -41.1,82.93 -9.18,9.75 -19.57,18.33 -30.95,25.52 5.72,-2.05 11.23,-4.52 16.51,-7.37 37.81,-29.91 62.1,-76.18 62.1,-128.03 l 0,-135.5 c 0,-5.56 -2.53,-21.22 -6.51,-33.83 m -1490.3,0.31 c -3.93,12.57 -6.434,28.02 -6.434,33.54 l 0,135.48 c 0,51.88 24.328,98.17 62.168,128.08 5.266,2.84 10.766,5.3 16.461,7.34 -11.297,-7.14 -21.633,-15.67 -30.773,-25.34 -24.571,-19.88 -40.547,-49.98 -41.387,-83.76 -1.313,-8.2 -1.992,-16.61 -1.992,-25.17 l 0,-130.67 c 0,-2.56 0.715,-9.53 1.957,-17.58 l 0,-21.92"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4154"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4156"
+ d="m 1689.55,1782.54 c -5.28,2.85 -10.79,5.32 -16.51,7.37 -8.57,5.42 -17.72,10.04 -27.3,13.77 4.69,-0.52 9.3,-1.29 13.82,-2.3 10.7,-5.2 20.74,-11.53 29.99,-18.84 m -1378.976,0.05 c 9.215,7.29 19.235,13.6 29.899,18.79 4.519,1 9.129,1.77 13.812,2.29 -9.562,-3.71 -18.68,-8.33 -27.25,-13.74 -5.695,-2.04 -11.195,-4.5 -16.461,-7.34"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4142"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4144-7"
+ d="m 340.473,1801.38 c 9.035,4.39 18.531,7.97 28.394,10.65 0.289,0 0.574,0 0.863,0 l 14.618,0 c -10.399,-1.8 -20.457,-4.63 -30.063,-8.36 -4.683,-0.52 -9.293,-1.29 -13.812,-2.29 m 1319.087,0 c -4.52,1.01 -9.13,1.78 -13.82,2.3 -9.6,3.72 -19.66,6.55 -30.07,8.35 l 14.68,0 c 0.27,0 0.54,0 0.81,0 9.86,-2.68 19.37,-6.26 28.4,-10.65"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4130"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4132"
+ d="m 368.867,1812.03 c 13.617,3.69 27.934,5.67 42.707,5.67 l 1176.856,0 c 14.78,0 29.1,-1.98 42.73,-5.67 -0.27,0 -0.54,0 -0.81,0 l -14.68,0 c -8.85,1.54 -17.95,2.34 -27.24,2.34 l -1176.856,0 c -9.281,0 -18.379,-0.8 -27.226,-2.34 l -14.618,0 c -0.289,0 -0.574,0 -0.863,0"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4118"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4120-5"
+ d="m 300.039,1581.56 0,23.2 c 14.539,46.51 40.797,89.92 79.66,102.12 9.176,4.34 36.895,6.78 49.039,6.78 l 1142.132,0 c 12.48,0 40.85,-2.47 50.2,-6.84 38.47,-12.02 64.37,-54.01 78.86,-99.49 l 0,-23.29 c -13.69,50.25 -41.7,100.12 -83.52,111.46 -8.02,3.75 -39.23,5.86 -49.93,5.86 l -1133.453,0 c -10.406,0 -40.91,-2.09 -48.773,-5.81 -42.18,-11.48 -70.563,-62.86 -84.215,-113.99"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4106"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4108"
+ d="m 292.504,1543.34 0,32.37 c 2.016,9.65 4.523,19.42 7.535,29.05 l 0,-23.2 c -3.465,-12.97 -5.98,-25.94 -7.535,-38.22 m 1414.956,3.8 c -1.62,11.93 -4.14,24.43 -7.53,36.9 l 0,23.29 c 2.99,-9.41 5.5,-18.97 7.53,-28.44 l 0,-31.75"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4094"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4096"
+ d="m 284.973,1496.09 0,24.98 c 0.929,5.74 1.656,11.7 2.136,17.78 0.957,11.71 2.75,24.19 5.395,36.86 l 0,-32.37 c -0.57,-4.53 -1.012,-8.96 -1.32,-13.28 -0.836,-12.15 -3.051,-23.72 -6.211,-33.97 m 1430.027,0.8 c -2.97,10.04 -5.03,21.3 -5.78,33.1 -0.37,5.54 -0.96,11.28 -1.76,17.15 l 0,31.75 c 2.96,-13.79 4.91,-27.41 5.87,-40.12 0.38,-5.22 0.95,-10.36 1.67,-15.35 l 0,-26.53"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4082"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4084"
+ d="m 277.438,1477.41 0,13.01 c 3.113,9.01 5.718,19.43 7.535,30.65 l 0,-24.98 c -2.125,-6.9 -4.68,-13.2 -7.535,-18.68 m 1445.102,0.3 c -2.88,5.63 -5.44,12.1 -7.54,19.18 l 0,26.53 c 1.72,-11.88 4.34,-22.93 7.54,-32.45 l 0,-13.26"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4070"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4072"
+ d="m 269.906,1465.72 0,7.42 c 2.711,4.86 5.258,10.7 7.532,17.28 l 0,-13.01 c -2.333,-4.48 -4.868,-8.42 -7.532,-11.69 m 1460.164,0.15 c -2.67,3.31 -5.21,7.3 -7.53,11.84 l 0,13.26 c 2.25,-6.71 4.8,-12.67 7.53,-17.61 l 0,-7.49"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4058"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4060"
+ d="m 1733.79,1461.8 c -1.26,1.21 -2.51,2.57 -3.72,4.07 l 0,7.49 c 1.21,-2.18 2.45,-4.17 3.72,-5.94 1.31,0 2.59,0.74 3.82,2.04 l 0,-6.44 c -1.24,-0.79 -2.52,-1.22 -3.82,-1.22 m -1467.485,0 c -1.34,0 -2.653,0.46 -3.93,1.29 l 0,6.48 c 1.266,-1.37 2.578,-2.15 3.93,-2.15 1.226,1.71 2.429,3.63 3.601,5.72 l 0,-7.42 c -1.176,-1.44 -2.379,-2.75 -3.601,-3.92"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4046"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4048"
+ d="m 1737.61,1463.02 0,6.44 c 2.82,2.97 5.39,8.9 7.53,15.72 l 0,-12.69 c -2.28,-4.32 -4.82,-7.74 -7.53,-9.47 m -1475.235,0.07 c -2.711,1.78 -5.254,5.24 -7.535,9.59 l 0,12.81 c 2.144,-6.86 4.715,-12.86 7.535,-15.92 l 0,-6.48"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4034"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4036"
+ d="m 1745.14,1472.49 0,12.69 c 3.98,12.61 6.51,28.27 6.51,33.83 l 0,135.5 c 0,51.85 -24.29,98.12 -62.1,128.03 7.61,-4.12 14.73,-9.04 21.24,-14.64 19.87,-21.2 34.3,-47.55 41.05,-76.81 0.55,-4.66 0.84,-9.41 0.84,-14.23 l 0,-184.09 c -1.89,-7.09 -4.48,-14.49 -7.54,-20.28 m -1490.3,0.19 c -3.059,5.85 -5.645,13.29 -7.531,20.39 l 0,183.79 c 0,4.62 0.261,9.18 0.773,13.67 6.715,29.57 21.266,56.19 41.344,77.56 6.488,5.55 13.578,10.42 21.148,14.5 -37.84,-29.91 -62.168,-76.2 -62.168,-128.08 l 0,-135.48 c 0,-5.52 2.504,-20.97 6.434,-33.54 l 0,-12.81"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4022"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4024"
+ d="m 1752.68,1492.77 0,184.09 c 0,4.82 -0.29,9.57 -0.84,14.23 2.8,-12.13 4.28,-24.75 4.28,-37.72 l 0,-140.32 c 0,-4.39 -1.26,-12.12 -3.44,-20.28 m -1505.371,0.3 c -2.141,8.05 -3.375,15.66 -3.375,20 l 0,140.3 c 0,12.76 1.433,25.2 4.148,37.16 -0.512,-4.49 -0.773,-9.05 -0.773,-13.67 l 0,-183.79 M 1710.79,1767.9 c -6.51,5.6 -13.63,10.52 -21.24,14.64 -9.25,7.31 -19.29,13.64 -29.99,18.84 5.32,-1.19 10.51,-2.7 15.56,-4.53 13.19,-7.99 25.19,-17.75 35.67,-28.95 m -1421.364,0.19 c 10.445,11.12 22.39,20.82 35.508,28.77 5.039,1.82 10.23,3.33 15.539,4.52 -10.664,-5.19 -20.684,-11.5 -29.899,-18.79 -7.57,-4.08 -14.66,-8.95 -21.148,-14.5"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath4010"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4012-9"
+ d="m 1675.12,1796.85 c -5.05,1.83 -10.24,3.34 -15.56,4.53 -9.03,4.39 -18.54,7.97 -28.4,10.65 4.62,-0.03 9.18,-0.28 13.68,-0.76 10.62,-3.81 20.76,-8.66 30.28,-14.42 m -1350.186,0.01 c 9.504,5.76 19.625,10.6 30.238,14.41 4.504,0.47 9.074,0.73 13.695,0.76 -9.863,-2.68 -19.359,-6.26 -28.394,-10.65 -5.309,-1.19 -10.5,-2.7 -15.539,-4.52"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3998"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path4000"
+ d="m 355.172,1811.27 c 11.035,3.95 22.594,6.78 34.555,8.34 l 1220.563,0 c 11.96,-1.56 23.52,-4.39 34.55,-8.34 -4.5,0.48 -9.06,0.73 -13.68,0.76 -13.63,3.69 -27.95,5.67 -42.73,5.67 l -1176.856,0 c -14.773,0 -29.09,-1.98 -42.707,-5.67 -4.621,-0.03 -9.191,-0.29 -13.695,-0.76"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3986"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3988-5"
+ d="m 1610.29,1819.61 -1220.563,0 c 7.148,0.93 14.445,1.41 21.847,1.41 l 1176.856,0 c 7.4,0 14.7,-0.48 21.86,-1.41"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3974"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3976"
+ d="m 300.039,1555.75 0,25.81 c 13.652,51.13 42.035,102.51 84.215,113.99 7.863,3.72 38.367,5.81 48.773,5.81 l 1133.453,0 c 10.7,0 41.91,-2.11 49.93,-5.86 41.82,-11.34 69.83,-61.21 83.52,-111.46 l 0,-25.8 c -11.81,54.85 -42.37,115.46 -88.19,125.94 -6.68,3.12 -40.73,4.88 -49.65,4.88 l -1124.77,0 c -8.675,0 -41.961,-1.74 -48.515,-4.83 -46.184,-10.61 -77.149,-72.96 -88.766,-128.48"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3962"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3964"
+ d="m 292.504,1501.79 0,41.55 c 1.555,12.28 4.07,25.25 7.535,38.22 l 0,-25.81 c -2.516,-12.01 -4.125,-23.7 -4.785,-34.48 -0.395,-6.74 -1.34,-13.28 -2.75,-19.48 m 1414.956,1.36 c -1.21,5.78 -2.02,11.83 -2.36,18.06 -0.65,11.54 -2.39,24.13 -5.17,37.03 l 0,25.8 c 3.39,-12.47 5.91,-24.97 7.53,-36.9 l 0,-43.99"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3950"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3952"
+ d="m 284.973,1479.79 0,16.3 c 3.16,10.25 5.375,21.82 6.211,33.97 0.308,4.32 0.75,8.75 1.32,13.28 l 0,-41.55 c -1.816,-8 -4.395,-15.44 -7.531,-22 M 1715,1480.2 c -3.2,6.83 -5.78,14.59 -7.54,22.95 l 0,43.99 c 0.8,-5.87 1.39,-11.61 1.76,-17.15 0.75,-11.8 2.81,-23.06 5.78,-33.1 l 0,-16.69"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3938"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3940"
+ d="m 277.438,1467.14 0,10.27 c 2.855,5.48 5.41,11.78 7.535,18.68 l 0,-16.3 c -2.25,-4.7 -4.789,-8.96 -7.535,-12.65 m 1445.102,0.19 c -2.76,3.75 -5.3,8.08 -7.54,12.87 l 0,16.69 c 2.1,-7.08 4.66,-13.55 7.54,-19.18 l 0,-10.38"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3926"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3928"
+ d="m 269.906,1458.92 0,6.8 c 2.664,3.27 5.199,7.21 7.532,11.69 l 0,-10.27 c -2.372,-3.18 -4.899,-5.95 -7.532,-8.22 m 1460.164,0.1 c -2.64,2.3 -5.17,5.09 -7.53,8.31 l 0,10.38 c 2.32,-4.54 4.86,-8.53 7.53,-11.84 l 0,-6.85"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3914"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3916"
+ d="m 1733.79,1456.18 c -1.26,0.84 -2.5,1.79 -3.72,2.84 l 0,6.85 c 1.21,-1.5 2.46,-2.86 3.72,-4.07 1.3,0 2.58,0.43 3.82,1.22 l 0,-6.05 c -1.25,-0.51 -2.52,-0.79 -3.82,-0.79 m -1467.485,0 c -1.332,0 -2.649,0.29 -3.93,0.84 l 0,6.07 c 1.277,-0.83 2.59,-1.29 3.93,-1.29 1.222,1.17 2.425,2.48 3.601,3.92 l 0,-6.8 c -1.179,-1.01 -2.383,-1.93 -3.601,-2.74"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3902"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3904"
+ d="m 1737.61,1456.97 0,6.05 c 2.71,1.73 5.25,5.15 7.53,9.47 l 0,-9.36 c -2.34,-2.88 -4.87,-5.06 -7.53,-6.16 m -1475.235,0.05 c -2.656,1.12 -5.187,3.33 -7.535,6.24 l 0,9.42 c 2.281,-4.35 4.824,-7.81 7.535,-9.59 l 0,-6.07"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3890"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3892"
+ d="m 1745.14,1463.13 0,9.36 c 3.06,5.79 5.65,13.19 7.54,20.28 l 0,-16.83 c -2.18,-4.86 -4.72,-9.34 -7.54,-12.81 m -1490.3,0.13 c -2.813,3.49 -5.356,7.99 -7.531,12.87 l 0,16.94 c 1.886,-7.1 4.472,-14.54 7.531,-20.39 l 0,-9.42 m -6.758,227.27 c 3.523,30.91 18.848,58.31 41.344,77.56 -20.078,-21.37 -34.629,-47.99 -41.344,-77.56 m 1503.758,0.56 c -6.75,29.26 -21.18,55.61 -41.05,76.81 22.24,-19.11 37.42,-46.22 41.05,-76.81"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3878"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3880"
+ d="m 1752.68,1475.94 0,16.83 c 2.18,8.16 3.44,15.89 3.44,20.28 l 0,140.32 c 0,12.97 -1.48,25.59 -4.28,37.72 -3.63,30.59 -18.81,57.7 -41.05,76.81 -10.48,11.2 -22.48,20.96 -35.67,28.95 6.36,-2.3 12.49,-5.09 18.35,-8.33 38,-29.34 63.43,-74.18 66.75,-124.96 l 0,-161.64 c -0.95,-7.42 -3.65,-17.3 -7.54,-25.98 m -1505.371,0.19 c -3.926,8.8 -6.645,18.82 -7.536,26.23 l 0,160.38 c 3.094,51.14 28.618,96.31 66.829,125.81 5.851,3.23 11.972,6.01 18.332,8.31 -13.118,-7.95 -25.063,-17.65 -35.508,-28.77 -22.496,-19.25 -37.821,-46.65 -41.344,-77.56 -2.715,-11.96 -4.148,-24.4 -4.148,-37.16 l 0,-140.3 c 0,-4.34 1.234,-11.95 3.375,-20 l 0,-16.94"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3866"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3868"
+ d="m 1760.22,1501.92 0,161.64 c 0.24,-3.75 0.37,-7.53 0.37,-11.34 l 0,-145.13 c 0,-1.52 -0.13,-3.27 -0.37,-5.17 m -1520.447,0.44 c -0.207,1.74 -0.316,3.34 -0.316,4.75 l 0,145.11 c 0,3.53 0.109,7.04 0.316,10.52 l 0,-160.38 m 1453.697,286.16 c -5.86,3.24 -11.99,6.03 -18.35,8.33 -9.52,5.76 -19.66,10.61 -30.28,14.42 5.1,-0.54 10.12,-1.36 15.03,-2.44 12.01,-5.49 23.27,-12.33 33.6,-20.31 m -1386.868,0.03 c 10.32,7.97 21.55,14.78 33.531,20.27 4.922,1.08 9.937,1.9 15.039,2.45 -10.613,-3.81 -20.734,-8.65 -30.238,-14.41 -6.36,-2.3 -12.481,-5.08 -18.332,-8.31"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3854"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3856"
+ d="m 340.133,1808.82 c 9.929,4.55 20.379,8.18 31.211,10.79 l 18.383,0 c -11.961,-1.56 -23.52,-4.39 -34.555,-8.34 -5.102,-0.55 -10.117,-1.37 -15.039,-2.45 m 1319.737,0.01 c -4.91,1.08 -9.93,1.9 -15.03,2.44 -11.03,3.95 -22.59,6.78 -34.55,8.34 l 18.38,0 c 10.83,-2.61 21.27,-6.23 31.2,-10.78"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3842"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3844"
+ d="m 1628.67,1819.61 -18.38,0 c -7.16,0.93 -14.46,1.41 -21.86,1.41 l -1176.856,0 c -7.402,0 -14.699,-0.48 -21.847,-1.41 l -18.383,0 c 7.406,1.78 14.992,3.08 22.73,3.86 l 1211.856,0 c 7.74,-0.78 15.34,-2.08 22.74,-3.86"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3830"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3832"
+ d="m 300.039,1521.79 0,33.96 c 11.617,55.52 42.582,117.87 88.766,128.48 6.554,3.09 39.84,4.83 48.515,4.83 l 1124.77,0 c 8.92,0 42.97,-1.76 49.65,-4.88 45.82,-10.48 76.38,-71.09 88.19,-125.94 l 0,-32.89 c -6.77,58.55 -40.91,137.88 -92.85,147.51 -5.34,2.5 -42.25,3.91 -49.38,3.91 l -1116.091,0 c -6.937,0 -43.007,-1.4 -48.25,-3.88 -52.687,-9.78 -87.371,-92.24 -93.32,-151.1"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3818"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3820"
+ d="m 292.504,1481.38 0,20.41 c 1.41,6.2 2.355,12.74 2.75,19.48 0.66,10.78 2.269,22.47 4.785,34.48 l 0,-33.96 c -0.32,-3.18 -0.559,-6.29 -0.711,-9.31 -0.531,-11.23 -2.996,-21.84 -6.824,-31.1 m 1414.956,0.54 c -3.65,9.12 -5.99,19.53 -6.47,30.51 -0.19,4.16 -0.55,8.48 -1.06,12.92 l 0,32.89 c 2.78,-12.9 4.52,-25.49 5.17,-37.03 0.34,-6.23 1.15,-12.28 2.36,-18.06 l 0,-21.23"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3806"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3808"
+ d="m 284.973,1467.34 0,12.45 c 3.136,6.56 5.715,14 7.531,22 l 0,-20.41 c -2.121,-5.15 -4.668,-9.87 -7.531,-14.04 M 1715,1467.57 c -2.88,4.27 -5.43,9.1 -7.54,14.35 l 0,21.23 c 1.76,-8.36 4.34,-16.12 7.54,-22.95 l 0,-12.63"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3794"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3796"
+ d="m 277.438,1458.34 0,8.8 c 2.746,3.69 5.285,7.95 7.535,12.65 l 0,-12.45 c -2.321,-3.38 -4.848,-6.4 -7.535,-9 m 1445.102,0.13 c -2.7,2.63 -5.23,5.68 -7.54,9.1 l 0,12.63 c 2.24,-4.79 4.78,-9.12 7.54,-12.87 l 0,-8.86"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3782"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3784"
+ d="m 269.906,1452.47 0,6.45 c 2.633,2.27 5.16,5.04 7.532,8.22 l 0,-8.8 c -2.395,-2.31 -4.918,-4.29 -7.532,-5.87 m 1460.164,0.07 c -2.62,1.6 -5.14,3.6 -7.53,5.93 l 0,8.86 c 2.36,-3.22 4.89,-6.01 7.53,-8.31 l 0,-6.48"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3770"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3772"
+ d="m 1733.79,1450.56 c -1.26,0.57 -2.5,1.23 -3.72,1.98 l 0,6.48 c 1.22,-1.05 2.46,-2 3.72,-2.84 1.3,0 2.57,0.28 3.82,0.79 l 0,-5.87 c -1.25,-0.36 -2.53,-0.54 -3.82,-0.54 m -1467.485,0 c -1.328,0 -2.645,0.19 -3.93,0.57 l 0,5.89 c 1.281,-0.55 2.598,-0.84 3.93,-0.84 1.218,0.81 2.422,1.73 3.601,2.74 l 0,-6.45 c -1.183,-0.72 -2.383,-1.36 -3.601,-1.91"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3758"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3760"
+ d="m 1737.61,1451.1 0,5.87 c 2.66,1.1 5.19,3.28 7.53,6.16 l 0,-7.82 c -2.38,-2.01 -4.91,-3.47 -7.53,-4.21 m -1475.235,0.03 c -2.629,0.76 -5.152,2.25 -7.535,4.27 l 0,7.86 c 2.348,-2.91 4.879,-5.12 7.535,-6.24 l 0,-5.89"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3746"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3748"
+ d="m 1745.14,1455.31 0,7.82 c 2.82,3.47 5.36,7.95 7.54,12.81 l 0,-11.94 c -2.29,-3.41 -4.82,-6.4 -7.54,-8.69 m -1490.3,0.09 c -2.715,2.31 -5.246,5.31 -7.531,8.73 l 0,12 c 2.175,-4.88 4.718,-9.38 7.531,-12.87 l 0,-7.86"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3734"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3736"
+ d="m 1752.68,1464 0,11.94 c 3.89,8.68 6.59,18.56 7.54,25.98 l 0,-23.11 c -2.01,-5.23 -4.57,-10.37 -7.54,-14.81 m -1505.371,0.13 c -2.977,4.46 -5.532,9.61 -7.536,14.85 l 0,23.38 c 0.891,-7.41 3.61,-17.43 7.536,-26.23 l 0,-12 m -7.536,198.61 0,12.95 c 0,9.08 0.946,17.93 2.743,26.49 7.847,25.92 21.515,49.35 39.464,68.75 7.461,6.79 15.723,12.72 24.622,17.62 -38.211,-29.5 -63.735,-74.67 -66.829,-125.81 m 1520.447,0.82 c -3.32,50.78 -28.75,95.62 -66.75,124.96 8.94,-4.93 17.23,-10.9 24.72,-17.74 17.78,-19.26 31.34,-42.46 39.19,-68.14 1.86,-8.69 2.84,-17.71 2.84,-26.95 l 0,-12.13"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3722"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3724"
+ d="m 1760.22,1478.81 0,23.11 c 0.24,1.9 0.37,3.65 0.37,5.17 l 0,145.13 c 0,3.81 -0.13,7.59 -0.37,11.34 l 0,12.13 c 0,9.24 -0.98,18.26 -2.84,26.95 4.99,-16.32 7.67,-33.64 7.67,-51.57 l 0,-149.93 c 0,-6.16 -1.77,-14.34 -4.83,-22.33 m -1520.447,0.17 c -3.035,7.93 -4.789,16.05 -4.789,22.16 l 0,149.93 c 0,17.77 2.633,34.92 7.532,51.11 -1.797,-8.56 -2.743,-17.41 -2.743,-26.49 l 0,-12.95 c -0.207,-3.48 -0.316,-6.99 -0.316,-10.52 l 0,-145.11 c 0,-1.41 0.109,-3.01 0.316,-4.75 l 0,-23.38 m 1478.417,291.8 c -7.49,6.84 -15.78,12.81 -24.72,17.74 -10.33,7.98 -21.59,14.82 -33.6,20.31 5.83,-1.28 11.51,-2.94 17.03,-4.94 15.38,-8.93 29.3,-20.12 41.29,-33.11 m -1436.21,0.15 c 11.958,12.92 25.809,24.05 41.122,32.95 5.523,2 11.207,3.66 17.031,4.94 -11.981,-5.49 -23.211,-12.3 -33.531,-20.27 -8.899,-4.9 -17.161,-10.83 -24.622,-17.62"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3710"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3712"
+ d="m 323.102,1803.88 c 10.507,6.11 21.699,11.17 33.425,15.02 4.75,0.47 9.555,0.71 14.422,0.71 l 0.395,0 c -10.832,-2.61 -21.282,-6.24 -31.211,-10.79 -5.824,-1.28 -11.508,-2.94 -17.031,-4.94 m 1353.798,0.01 c -5.52,2 -11.2,3.66 -17.03,4.94 -9.93,4.55 -20.37,8.17 -31.2,10.78 l 0.47,0 c 4.83,0 9.61,-0.24 14.33,-0.7 11.73,-3.86 22.92,-8.91 33.43,-15.02"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3698"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3700"
+ d="m 356.527,1818.9 c 5.426,1.78 10.977,3.31 16.618,4.57 l 20.929,0 c -7.738,-0.78 -15.324,-2.08 -22.73,-3.86 l -0.395,0 c -4.867,0 -9.672,-0.24 -14.422,-0.71 m 1286.943,0.01 c -4.72,0.46 -9.5,0.7 -14.33,0.7 l -0.47,0 c -7.4,1.78 -15,3.08 -22.74,3.86 l 20.94,0 c 5.64,-1.26 11.17,-2.78 16.6,-4.56"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3686"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3688"
+ d="m 300.039,1483.55 0,38.24 c 5.949,58.86 40.633,141.32 93.32,151.1 5.243,2.48 41.313,3.88 48.25,3.88 l 1116.091,0 c 7.13,0 44.04,-1.41 49.38,-3.91 51.94,-9.63 86.08,-88.96 92.85,-147.51 l 0,-40.96 c -1.76,6.06 -2.83,12.54 -3.05,19.26 -2.07,57.51 -39.3,150.12 -94.46,157.89 -4.01,1.87 -43.76,2.93 -49.11,2.93 l -1107.408,0 c -5.203,0 -44.058,-1.04 -47.988,-2.9 -54.883,-7.74 -92.285,-100.36 -94.516,-157.89 -0.253,-7.04 -1.429,-13.82 -3.359,-20.13"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3674"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3676"
+ d="m 292.504,1466.79 0,14.59 c 3.828,9.26 6.293,19.87 6.824,31.1 0.152,3.02 0.391,6.13 0.711,9.31 l 0,-38.24 c -1.863,-6.09 -4.43,-11.74 -7.535,-16.76 m 1414.956,0.3 c -3.14,5.18 -5.71,11.01 -7.53,17.3 l 0,40.96 c 0.51,-4.44 0.87,-8.76 1.06,-12.92 0.48,-10.98 2.82,-21.39 6.47,-30.51 l 0,-14.83"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3662"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3664"
+ d="m 284.973,1456.95 0,10.39 c 2.863,4.17 5.41,8.89 7.531,14.04 l 0,-14.59 c -2.246,-3.64 -4.777,-6.94 -7.531,-9.84 M 1715,1457.11 c -2.77,2.94 -5.3,6.29 -7.54,9.98 l 0,14.83 c 2.11,-5.25 4.66,-10.08 7.54,-14.35 l 0,-10.46"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3650"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3652"
+ d="m 277.438,1450.42 0,7.92 c 2.687,2.6 5.214,5.62 7.535,9 l 0,-10.39 c -2.36,-2.49 -4.883,-4.68 -7.535,-6.53 m 1445.102,0.08 c -2.66,1.88 -5.18,4.09 -7.54,6.61 l 0,10.46 c 2.31,-3.42 4.84,-6.47 7.54,-9.1 l 0,-7.97"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3638"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3640"
+ d="m 269.906,1446.23 0,6.24 c 2.614,1.58 5.137,3.56 7.532,5.87 l 0,-7.92 c -2.415,-1.69 -4.934,-3.1 -7.532,-4.19 m 1460.164,0.05 c -2.6,1.1 -5.12,2.52 -7.53,4.22 l 0,7.97 c 2.39,-2.33 4.91,-4.33 7.53,-5.93 l 0,-6.26"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3626"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3628"
+ d="m 1733.79,1444.94 c -1.26,0.37 -2.5,0.82 -3.72,1.34 l 0,6.26 c 1.22,-0.75 2.46,-1.41 3.72,-1.98 1.29,0 2.57,0.18 3.82,0.54 l 0,-5.78 c -1.26,-0.25 -2.53,-0.38 -3.82,-0.38 m -1467.485,0 c -1.328,0 -2.641,0.13 -3.93,0.4 l 0,5.79 c 1.285,-0.38 2.602,-0.57 3.93,-0.57 1.218,0.55 2.418,1.19 3.601,1.91 l 0,-6.24 c -1.183,-0.5 -2.386,-0.93 -3.601,-1.29"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3614"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3616"
+ d="m 1737.61,1445.32 0,5.78 c 2.62,0.74 5.15,2.2 7.53,4.21 l 0,-7.01 c -2.4,-1.44 -4.93,-2.47 -7.53,-2.98 m -1475.235,0.02 c -2.605,0.53 -5.129,1.57 -7.535,3.02 l 0,7.04 c 2.383,-2.02 4.906,-3.51 7.535,-4.27 l 0,-5.79"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3602"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3604"
+ d="m 1745.14,1448.3 0,7.01 c 2.72,2.29 5.25,5.28 7.54,8.69 l 0,-9.56 c -2.34,-2.46 -4.87,-4.55 -7.54,-6.14 m -1490.3,0.06 c -2.664,1.6 -5.188,3.71 -7.531,6.17 l 0,9.6 c 2.285,-3.42 4.816,-6.42 7.531,-8.73 l 0,-7.04"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3590"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3592"
+ d="m 1752.68,1454.44 0,9.56 c 2.97,4.44 5.53,9.58 7.54,14.81 l 0,-14.29 c -2.21,-3.71 -4.75,-7.16 -7.54,-10.08 m -1505.371,0.09 c -2.793,2.94 -5.329,6.39 -7.536,10.11 l 0,14.34 c 2.004,-5.24 4.559,-10.39 7.536,-14.85 l 0,-9.6 m -4.793,247.65 c 5.664,26.95 19.793,50.85 39.464,68.75 -17.949,-19.4 -31.617,-42.83 -39.464,-68.75 m 1514.864,0.46 c -7.85,25.68 -21.41,48.88 -39.19,68.14 19.47,-17.78 33.48,-41.44 39.19,-68.14"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3578"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3580"
+ d="m 1760.22,1464.52 0,14.29 c 3.06,7.99 4.83,16.17 4.83,22.33 l 0,149.93 c 0,17.93 -2.68,35.25 -7.67,51.57 -5.71,26.7 -19.72,50.36 -39.19,68.14 -11.99,12.99 -25.91,24.18 -41.29,33.11 7.09,-2.56 13.91,-5.69 20.41,-9.34 37.44,-28.26 63.61,-70.71 70.44,-119.28 0,-0.25 0,-0.5 0,-0.75 l 0,-191.95 c -1.58,-6.09 -4.18,-12.39 -7.53,-18.05 m -1520.447,0.12 c -3.359,5.68 -5.953,11.98 -7.531,18.09 l 0,191.79 c 0,0.17 0,0.35 0,0.52 6.778,48.67 32.965,91.2 70.469,119.51 6.492,3.64 13.305,6.77 20.391,9.33 -15.313,-8.9 -29.164,-20.03 -41.122,-32.95 -19.671,-17.9 -33.8,-41.8 -39.464,-68.75 -4.899,-16.19 -7.532,-33.34 -7.532,-51.11 l 0,-149.93 c 0,-6.11 1.754,-14.23 4.789,-22.16 l 0,-14.34"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3566"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3568"
+ d="m 1767.75,1482.57 0,191.95 c 0,0.25 0,0.5 0,0.75 1.16,-8.28 1.77,-16.74 1.77,-25.34 l 0,-154.75 c 0,-3.89 -0.62,-8.2 -1.77,-12.61 m -1535.508,0.16 c -1.125,4.36 -1.734,8.61 -1.734,12.46 l 0,154.74 c 0,8.52 0.594,16.9 1.734,25.11 0,-0.17 0,-0.35 0,-0.52 l 0,-191.79 m 70.469,311.82 c 11.512,8.68 24.082,16.03 37.492,21.8 5.34,1.15 10.789,2.01 16.324,2.55 -11.726,-3.85 -22.918,-8.91 -33.425,-15.02 -7.086,-2.56 -13.899,-5.69 -20.391,-9.33 m 1394.599,0 c -6.5,3.65 -13.32,6.78 -20.41,9.34 -10.51,6.11 -21.7,11.16 -33.43,15.02 5.53,-0.54 10.97,-1.39 16.3,-2.54 13.43,-5.78 26.02,-13.13 37.54,-21.82"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3554"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3556"
+ d="m 340.203,1816.35 c 6.352,2.74 12.895,5.12 19.594,7.12 l 13.348,0 c -5.641,-1.26 -11.192,-2.79 -16.618,-4.57 -5.535,-0.54 -10.984,-1.4 -16.324,-2.55 m 1319.567,0.02 c -5.33,1.15 -10.77,2 -16.3,2.54 -5.43,1.78 -10.96,3.3 -16.6,4.56 l 13.35,0 c 6.69,-2 13.21,-4.37 19.55,-7.1"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3542"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3544"
+ d="m 300.039,1466.03 0,17.52 c 1.93,6.31 3.106,13.09 3.359,20.13 2.231,57.53 39.633,150.15 94.516,157.89 3.93,1.86 42.785,2.9 47.988,2.9 l 1107.408,0 c 5.35,0 45.1,-1.06 49.11,-2.93 55.16,-7.77 92.39,-100.38 94.46,-157.89 0.22,-6.72 1.29,-13.2 3.05,-19.26 l 0,-17.98 c -4.32,8.36 -6.93,18.1 -7.17,28.46 -1.37,55.99 -40.55,150.17 -95.01,155.35 -2.67,1.25 -45.27,1.95 -48.83,1.95 l -1098.729,0 c -3.468,0 -45.101,-0.69 -47.722,-1.93 -54.235,-5.16 -93.508,-99.35 -94.996,-155.35 -0.258,-10.52 -2.969,-20.41 -7.434,-28.86"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3530"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3532"
+ d="m 292.504,1454.96 0,11.83 c 3.105,5.02 5.672,10.67 7.535,16.76 l 0,-17.52 c -2.137,-4.05 -4.676,-7.76 -7.535,-11.07 m 1414.956,0.2 c -2.87,3.36 -5.41,7.14 -7.53,11.25 l 0,17.98 c 1.82,-6.29 4.39,-12.12 7.53,-17.3 l 0,-11.93"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3518"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3520"
+ d="m 284.973,1447.81 0,9.14 c 2.754,2.9 5.285,6.2 7.531,9.84 l 0,-11.83 c -2.313,-2.67 -4.836,-5.07 -7.531,-7.15 M 1715,1447.92 c -2.7,2.11 -5.23,4.53 -7.54,7.24 l 0,11.93 c 2.24,-3.69 4.77,-7.04 7.54,-9.98 l 0,-9.19"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3506"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3508"
+ d="m 277.438,1443.05 0,7.37 c 2.652,1.85 5.175,4.04 7.535,6.53 l 0,-9.14 c -2.387,-1.85 -4.907,-3.45 -7.535,-4.76 m 1445.102,0.06 c -2.63,1.33 -5.16,2.94 -7.54,4.81 l 0,9.19 c 2.36,-2.52 4.88,-4.73 7.54,-6.61 l 0,-7.39"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3494"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3496"
+ d="m 269.906,1440.13 0,6.1 c 2.598,1.09 5.117,2.5 7.532,4.19 l 0,-7.37 c -2.426,-1.22 -4.946,-2.2 -7.532,-2.92 m 1460.164,0.03 c -2.59,0.73 -5.11,1.72 -7.53,2.95 l 0,7.39 c 2.41,-1.7 4.93,-3.12 7.53,-4.22 l 0,-6.12"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3482"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3484"
+ d="m 1733.79,1439.31 c -1.25,0.23 -2.49,0.51 -3.72,0.85 l 0,6.12 c 1.22,-0.52 2.46,-0.97 3.72,-1.34 1.29,0 2.56,0.13 3.82,0.38 l 0,-5.73 c -1.26,-0.18 -2.53,-0.28 -3.82,-0.28 m -1467.485,0 c -1.325,0 -2.637,0.1 -3.93,0.29 l 0,5.74 c 1.289,-0.27 2.602,-0.4 3.93,-0.4 1.215,0.36 2.418,0.79 3.601,1.29 l 0,-6.1 c -1.187,-0.33 -2.386,-0.6 -3.601,-0.82"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3470"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3472"
+ d="m 1737.61,1439.59 0,5.73 c 2.6,0.51 5.13,1.54 7.53,2.98 l 0,-6.55 c -2.42,-1.05 -4.94,-1.79 -7.53,-2.16 m -1475.235,0.01 c -2.59,0.38 -5.109,1.13 -7.535,2.19 l 0,6.57 c 2.406,-1.45 4.93,-2.49 7.535,-3.02 l 0,-5.74"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3458"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3460"
+ d="m 1745.14,1441.75 0,6.55 c 2.67,1.59 5.2,3.68 7.54,6.14 l 0,-8.24 c -2.38,-1.81 -4.9,-3.31 -7.54,-4.45 m -1490.3,0.04 c -2.633,1.15 -5.152,2.67 -7.531,4.48 l 0,8.26 c 2.343,-2.46 4.867,-4.57 7.531,-6.17 l 0,-6.57"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3446"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3448"
+ d="m 1752.68,1446.2 0,8.24 c 2.79,2.92 5.33,6.37 7.54,10.08 l 0,-11.1 c -2.3,-2.72 -4.83,-5.16 -7.54,-7.22 m -1505.371,0.07 c -2.711,2.07 -5.239,4.51 -7.536,7.23 l 0,11.14 c 2.207,-3.72 4.743,-7.17 7.536,-10.11 l 0,-8.26"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3434"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3436"
+ d="m 1760.22,1453.42 0,11.1 c 3.35,5.66 5.95,11.96 7.53,18.05 l 0,-17.7 c -2.08,-4.12 -4.62,-8.01 -7.53,-11.45 m -1520.447,0.08 c -2.91,3.46 -5.453,7.35 -7.531,11.47 l 0,17.76 c 1.578,-6.11 4.172,-12.41 7.531,-18.09 l 0,-11.14 m -7.531,221.54 c 0.055,14.34 2.32,28.18 6.469,41.19 8.187,20.91 20.055,39.98 34.816,56.42 8.688,8.52 18.493,15.9 29.184,21.9 -37.504,-28.31 -63.691,-70.84 -70.469,-119.51 m 1535.508,0.23 c -6.83,48.57 -33,91.02 -70.44,119.28 10.71,-6.02 20.55,-13.43 29.25,-21.98 14.65,-16.34 26.45,-35.27 34.62,-56.03 4.19,-13.02 6.49,-26.89 6.57,-41.27"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3422"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3424"
+ d="m 1767.75,1464.87 0,17.7 c 1.15,4.41 1.77,8.72 1.77,12.61 l 0,154.75 c 0,8.6 -0.61,17.06 -1.77,25.34 -0.08,14.38 -2.38,28.25 -6.57,41.27 8.27,-21 12.8,-43.85 12.8,-67.75 l 0,-159.57 c 0,-7.92 -2.28,-16.54 -6.23,-24.35 m -1535.508,0.1 c -3.93,7.78 -6.207,16.37 -6.207,24.26 l 0,159.56 c 0,23.77 4.496,46.53 12.676,67.44 -4.149,-13.01 -6.414,-26.85 -6.469,-41.19 -1.14,-8.21 -1.734,-16.59 -1.734,-25.11 l 0,-154.74 c 0,-3.85 0.609,-8.1 1.734,-12.46 l 0,-17.76 m 1494.318,307.6 c -8.7,8.55 -18.54,15.96 -29.25,21.98 -11.52,8.69 -24.11,16.04 -37.54,21.82 6.36,-1.37 12.57,-3.15 18.6,-5.32 18.14,-10.09 34.43,-23.14 48.19,-38.48 m -1453.033,0.08 c 13.739,15.3 29.977,28.31 48.063,38.38 6.035,2.17 12.246,3.95 18.613,5.32 -13.41,-5.77 -25.98,-13.12 -37.492,-21.8 -10.691,-6 -20.496,-13.38 -29.184,-21.9"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3410"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3412"
+ d="m 321.59,1811.03 c 8.715,4.85 17.871,9.02 27.371,12.44 l 10.836,0 c -6.699,-2 -13.242,-4.38 -19.594,-7.12 -6.367,-1.37 -12.578,-3.15 -18.613,-5.32 m 1356.78,0.02 c -6.03,2.17 -12.24,3.95 -18.6,5.32 -6.34,2.73 -12.86,5.1 -19.55,7.1 l 10.83,0 c 9.49,-3.41 18.62,-7.57 27.32,-12.42"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3398"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3400"
+ d="m 300.039,1452.66 0,13.37 c 4.465,8.45 7.176,18.34 7.434,28.86 1.488,56 40.761,150.19 94.996,155.35 2.621,1.24 44.254,1.93 47.722,1.93 l 1098.729,0 c 3.56,0 46.16,-0.7 48.83,-1.95 54.46,-5.18 93.64,-99.36 95.01,-155.35 0.24,-10.36 2.85,-20.1 7.17,-28.46 l 0,-13.53 c -6.9,9.07 -11.13,20.64 -11.28,33.21 -0.69,54.46 -41.82,150.22 -95.56,152.81 -1.34,0.62 -46.78,0.98 -48.56,0.98 l -1090.046,0 c -1.734,0 -46.152,-0.35 -47.464,-0.97 -53.582,-2.58 -94.731,-98.34 -95.473,-152.81 -0.16,-12.68 -4.485,-24.34 -11.508,-33.44"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3386"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3388"
+ d="m 292.504,1444.76 0,10.2 c 2.859,3.31 5.398,7.02 7.535,11.07 l 0,-13.37 c -2.25,-2.92 -4.777,-5.57 -7.535,-7.9 m 1414.956,0.13 c -2.76,2.36 -5.29,5.05 -7.53,7.99 l 0,13.53 c 2.12,-4.11 4.66,-7.89 7.53,-11.25 l 0,-10.27"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3374"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3376"
+ d="m 284.973,1439.48 0,8.33 c 2.695,2.08 5.218,4.48 7.531,7.15 l 0,-10.2 c -2.352,-2 -4.875,-3.77 -7.531,-5.28 M 1715,1439.56 c -2.66,1.53 -5.18,3.31 -7.54,5.33 l 0,10.27 c 2.31,-2.71 4.84,-5.13 7.54,-7.24 l 0,-8.36"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3362"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3364"
+ d="m 277.438,1436.05 0,7 c 2.628,1.31 5.148,2.91 7.535,4.76 l 0,-8.33 c -2.407,-1.36 -4.926,-2.51 -7.535,-3.43 m 1445.102,0.05 c -2.62,0.92 -5.13,2.08 -7.54,3.46 l 0,8.36 c 2.38,-1.87 4.91,-3.48 7.54,-4.81 l 0,-7.01"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3350"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3352"
+ d="m 269.906,1434.13 0,6 c 2.586,0.72 5.106,1.7 7.532,2.92 l 0,-7 c -2.438,-0.85 -4.954,-1.5 -7.532,-1.92 m 1460.164,0.02 c -2.58,0.43 -5.1,1.08 -7.53,1.95 l 0,7.01 c 2.42,-1.23 4.94,-2.22 7.53,-2.95 l 0,-6.01"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3338"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3340"
+ d="m 1733.79,1433.69 c -1.25,0.1 -2.49,0.26 -3.72,0.46 l 0,6.01 c 1.23,-0.34 2.47,-0.62 3.72,-0.85 1.29,0 2.56,0.1 3.82,0.28 l 0,-5.7 c -1.26,-0.13 -2.53,-0.2 -3.82,-0.2 m -1467.485,0 c -1.325,0 -2.637,0.08 -3.93,0.21 l 0,5.7 c 1.293,-0.19 2.605,-0.29 3.93,-0.29 1.215,0.22 2.414,0.49 3.601,0.82 l 0,-6 c -1.187,-0.19 -2.386,-0.34 -3.601,-0.44"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3326"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3328"
+ d="m 1737.61,1433.89 0,5.7 c 2.59,0.37 5.11,1.11 7.53,2.16 l 0,-6.27 c -2.43,-0.78 -4.95,-1.32 -7.53,-1.59 m -1475.235,0.01 c -2.578,0.28 -5.098,0.83 -7.535,1.61 l 0,6.28 c 2.426,-1.06 4.945,-1.81 7.535,-2.19 l 0,-5.7"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3314"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3316"
+ d="m 1745.14,1435.48 0,6.27 c 2.64,1.14 5.16,2.64 7.54,4.45 l 0,-7.43 c -2.4,-1.35 -4.92,-2.46 -7.54,-3.29 m -1490.3,0.03 c -2.613,0.84 -5.129,1.95 -7.531,3.31 l 0,7.45 c 2.379,-1.81 4.898,-3.33 7.531,-4.48 l 0,-6.28"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3302"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3304"
+ d="m 1752.68,1438.77 0,7.43 c 2.71,2.06 5.24,4.5 7.54,7.22 l 0,-9.35 c -2.35,-2.03 -4.87,-3.81 -7.54,-5.3 m -1505.371,0.05 c -2.664,1.5 -5.188,3.28 -7.536,5.31 l 0,9.37 c 2.297,-2.72 4.825,-5.16 7.536,-7.23 l 0,-7.45"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3290"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3292"
+ d="m 1760.22,1444.07 0,9.35 c 2.91,3.44 5.45,7.33 7.53,11.45 l 0,-12.71 c -2.23,-2.98 -4.76,-5.7 -7.53,-8.09 m -1520.447,0.06 c -2.769,2.39 -5.3,5.12 -7.531,8.1 l 0,12.74 c 2.078,-4.12 4.621,-8.01 7.531,-11.47 l 0,-9.37 m -1.062,272.1 c 6.894,21.59 18.992,40.89 34.816,56.42 -14.761,-16.44 -26.629,-35.51 -34.816,-56.42 m 1522.469,0.31 c -8.17,20.76 -19.97,39.69 -34.62,56.03 15.7,-15.43 27.72,-34.6 34.62,-56.03"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3278"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3280"
+ d="m 1767.75,1452.16 0,12.71 c 3.95,7.81 6.23,16.43 6.23,24.35 l 0,159.57 c 0,23.9 -4.53,46.75 -12.8,67.75 -6.9,21.43 -18.92,40.6 -34.62,56.03 -13.76,15.34 -30.05,28.39 -48.19,38.48 7.89,-2.83 15.47,-6.33 22.67,-10.42 37.49,-27.67 64.49,-68.78 73.83,-116.16 0.28,-3.67 0.42,-7.38 0.42,-11.12 l 0,-207.34 c -1.83,-4.96 -4.39,-9.65 -7.54,-13.85 m -1535.508,0.07 c -3.152,4.2 -5.711,8.89 -7.531,13.85 l 0,207.27 c 0,3.7 0.137,7.38 0.41,11.03 9.317,47.39 36.301,88.51 73.789,116.21 7.203,4.09 14.785,7.59 22.68,10.44 -18.086,-10.07 -34.324,-23.08 -48.063,-38.38 -15.824,-15.53 -27.922,-34.83 -34.816,-56.42 -8.18,-20.91 -12.676,-43.67 -12.676,-67.44 l 0,-159.56 c 0,-7.89 2.277,-16.48 6.207,-24.26 l 0,-12.74"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3266"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3268"
+ d="m 1775.29,1466.01 0,207.34 c 0,3.74 -0.14,7.45 -0.42,11.12 2.35,-11.92 3.58,-24.23 3.58,-36.83 l 0,-164.38 c 0,-5.85 -1.12,-11.71 -3.16,-17.25 m -1550.579,0.07 c -2.035,5.52 -3.152,11.36 -3.152,17.19 l 0,164.37 c 0,12.56 1.226,24.85 3.562,36.74 -0.273,-3.65 -0.41,-7.33 -0.41,-11.03 l 0,-207.27 m 74.199,334.51 c 12.457,9.2 26.07,16.91 40.582,22.88 l 9.469,0 c -9.5,-3.42 -18.656,-7.59 -27.371,-12.44 -7.895,-2.85 -15.477,-6.35 -22.68,-10.44 m 1402.13,0.04 c -7.2,4.09 -14.78,7.59 -22.67,10.42 -8.7,4.85 -17.83,9.01 -27.32,12.42 l 9.47,0 c 14.49,-5.96 28.08,-13.66 40.52,-22.84"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3254"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3256"
+ d="m 300.039,1441.39 0,11.27 c 7.023,9.1 11.348,20.76 11.508,33.44 0.742,54.47 41.891,150.23 95.473,152.81 1.312,0.62 45.73,0.97 47.464,0.97 l 1090.046,0 c 1.78,0 47.22,-0.36 48.56,-0.98 53.74,-2.59 94.87,-98.35 95.56,-152.81 0.15,-12.57 4.38,-24.14 11.28,-33.21 l 0,-11.33 c -9.48,8.98 -15.39,21.68 -15.39,35.75 0,52.94 -43.09,150.28 -96.11,150.28 l -1176.856,0 c -52.933,0 -95.957,-97.34 -95.957,-150.28 0,-14.15 -5.988,-26.92 -15.578,-35.91"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3242"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3244"
+ d="m 292.504,1435.59 0,9.17 c 2.758,2.33 5.285,4.98 7.535,7.9 l 0,-11.27 c -2.312,-2.16 -4.836,-4.11 -7.535,-5.8 m 1414.956,0.09 c -2.7,1.71 -5.22,3.68 -7.53,5.87 l 0,11.33 c 2.24,-2.94 4.77,-5.63 7.53,-7.99 l 0,-9.21"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3230"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3232"
+ d="m 284.973,1431.72 0,7.76 c 2.656,1.51 5.179,3.28 7.531,5.28 l 0,-9.17 c -2.383,-1.5 -4.899,-2.79 -7.531,-3.87 M 1715,1431.78 c -2.64,1.08 -5.16,2.39 -7.54,3.9 l 0,9.21 c 2.36,-2.02 4.88,-3.8 7.54,-5.33 l 0,-7.78"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3218"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3220"
+ d="m 277.438,1429.33 0,6.72 c 2.609,0.92 5.128,2.07 7.535,3.43 l 0,-7.76 c -2.422,-0.99 -4.938,-1.79 -7.535,-2.39 m 1445.102,0.03 c -2.6,0.6 -5.12,1.42 -7.54,2.42 l 0,7.78 c 2.41,-1.38 4.92,-2.54 7.54,-3.46 l 0,-6.74"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3206"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3208"
+ d="m 269.906,1428.2 0,5.93 c 2.578,0.42 5.094,1.07 7.532,1.92 l 0,-6.72 c -2.446,-0.56 -4.961,-0.94 -7.532,-1.13 m 1460.164,0.01 c -2.57,0.19 -5.09,0.58 -7.53,1.15 l 0,6.74 c 2.43,-0.87 4.95,-1.52 7.53,-1.95 l 0,-5.94"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3194"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3196"
+ d="m 1733.79,1428.07 c -1.25,0 -2.49,0.05 -3.72,0.14 l 0,5.94 c 1.23,-0.2 2.47,-0.36 3.72,-0.46 1.29,0 2.56,0.07 3.82,0.2 l 0,-5.67 c -1.26,-0.1 -2.54,-0.15 -3.82,-0.15 m -1467.485,0 c -1.321,0 -2.633,0.05 -3.93,0.16 l 0,5.67 c 1.293,-0.13 2.605,-0.21 3.93,-0.21 1.215,0.1 2.414,0.25 3.601,0.44 l 0,-5.93 c -1.187,-0.09 -2.39,-0.13 -3.601,-0.13"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3182"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3184"
+ d="m 1737.61,1428.22 0,5.67 c 2.58,0.27 5.1,0.81 7.53,1.59 l 0,-6.09 c -2.44,-0.58 -4.96,-0.97 -7.53,-1.17 m -1475.235,0.01 c -2.574,0.2 -5.086,0.6 -7.535,1.19 l 0,6.09 c 2.437,-0.78 4.957,-1.33 7.535,-1.61 l 0,-5.67"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3170"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3172"
+ d="m 1745.14,1429.39 0,6.09 c 2.62,0.83 5.14,1.94 7.54,3.29 l 0,-6.93 c -2.42,-1.01 -4.94,-1.83 -7.54,-2.45 m -1490.3,0.03 c -2.594,0.62 -5.113,1.45 -7.531,2.46 l 0,6.94 c 2.402,-1.36 4.918,-2.47 7.531,-3.31 l 0,-6.09"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3158"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3160"
+ d="m 1752.68,1431.84 0,6.93 c 2.67,1.49 5.19,3.27 7.54,5.3 l 0,-8.28 c -2.38,-1.52 -4.9,-2.84 -7.54,-3.95 m -1505.371,0.04 c -2.637,1.11 -5.157,2.44 -7.536,3.96 l 0,8.29 c 2.348,-2.03 4.872,-3.81 7.536,-5.31 l 0,-6.94"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3146"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3148"
+ d="m 1760.22,1435.79 0,8.28 c 2.77,2.39 5.3,5.11 7.53,8.09 l 0,-10.43 c -2.31,-2.21 -4.83,-4.2 -7.53,-5.94 m -1520.447,0.05 c -2.703,1.74 -5.222,3.73 -7.531,5.95 l 0,10.44 c 2.231,-2.98 4.762,-5.71 7.531,-8.1 l 0,-8.29"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3134"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3136"
+ d="m 1767.75,1441.73 0,10.43 c 3.15,4.2 5.71,8.89 7.54,13.85 l 0,-15.06 c -2.14,-3.38 -4.67,-6.47 -7.54,-9.22 m -1535.508,0.06 c -2.863,2.75 -5.398,5.84 -7.531,9.21 l 0,15.08 c 1.82,-4.96 4.379,-9.65 7.531,-13.85 l 0,-10.44 m -7.121,242.59 c 1.32,17.59 5.77,34.33 12.797,49.66 6.883,13.61 15.312,26.29 25.066,37.84 10.364,11.34 22.485,21.06 35.926,28.71 -37.488,-27.7 -64.472,-68.82 -73.789,-116.21 m 1549.749,0.09 c -9.34,47.38 -36.34,88.49 -73.83,116.16 13.43,-7.63 25.54,-17.34 35.9,-28.67 9.78,-11.55 18.23,-24.26 25.13,-37.89 7.02,-15.31 11.47,-32.02 12.8,-49.6"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3122"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3124"
+ d="m 1775.29,1450.95 0,15.06 c 2.04,5.54 3.16,11.4 3.16,17.25 l 0,164.38 c 0,12.6 -1.23,24.91 -3.58,36.83 -1.33,17.58 -5.78,34.29 -12.8,49.6 12.47,-24.64 19.86,-52.29 20.75,-81.55 l 0,-178.25 c -0.52,-8.54 -3.21,-16.5 -7.53,-23.32 M 224.711,1451 c -4.32,6.81 -7.016,14.75 -7.535,23.27 l 0,178.25 c 0.894,29.25 8.273,56.89 20.742,81.52 -7.027,-15.33 -11.477,-32.07 -12.797,-49.66 -2.336,-11.89 -3.562,-24.18 -3.562,-36.74 l 0,-164.37 c 0,-5.83 1.117,-11.67 3.152,-17.19 l 0,-15.08 m 38.273,320.88 c 15.965,18.89 35.457,34.7 57.454,46.42 5.832,2.07 11.82,3.8 17.945,5.17 l 1.109,0 c -14.512,-5.97 -28.125,-13.68 -40.582,-22.88 -13.441,-7.65 -25.562,-17.37 -35.926,-28.71 m 1473.956,0.08 c -10.36,11.33 -22.47,21.04 -35.9,28.67 -12.44,9.18 -26.03,16.88 -40.52,22.84 l 1.16,0 c 6.07,-1.36 12.01,-3.07 17.79,-5.12 22,-11.71 41.5,-27.51 57.47,-46.39"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath3110"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3112"
+ d="m 1782.82,1474.27 0,178.25 c 0.06,-2 0.1,-4.01 0.1,-6.03 l 0,-169.19 c 0,-1.01 -0.04,-2.03 -0.1,-3.03 m -1565.644,0 c -0.063,1.01 -0.09,2.02 -0.09,3.03 l 0,169.19 c 0,2.02 0.027,4.03 0.09,6.03 l 0,-178.25 m 103.262,344.03 c 3.425,1.82 6.917,3.55 10.46,5.17 l 7.485,0 c -6.125,-1.37 -12.113,-3.1 -17.945,-5.17 m 1359.032,0.05 c -5.78,2.05 -11.72,3.76 -17.79,5.12 l 7.42,0 c 3.52,-1.61 6.97,-3.31 10.37,-5.12"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient3094"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop3096"
+ offset="0"
+ style="stop-opacity:1;stop-color:#f8f9f9" />
+ <stop
+ id="stop3098"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#e9e8e8" />
+ <stop
+ id="stop3100"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#e9e8e8" />
+ <stop
+ id="stop3102"
+ offset="1"
+ style="stop-opacity:1;stop-color:#f5f5f4" />
+ </linearGradient>
+ <clipPath
+ id="clipPath3090"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3092"
+ d="m 1605.93,1823.47 -1211.856,0 c 5.758,0.58 11.59,0.89 17.5,0.89 l 1176.856,0 c 5.91,0 11.74,-0.31 17.5,-0.89"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient3074"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop3076"
+ offset="0"
+ style="stop-opacity:1;stop-color:#f7f7f7" />
+ <stop
+ id="stop3078"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#e5e4e3" />
+ <stop
+ id="stop3080"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#e5e4e3" />
+ <stop
+ id="stop3082"
+ offset="1"
+ style="stop-opacity:1;stop-color:#f2f2f2" />
+ </linearGradient>
+ <clipPath
+ id="clipPath3070"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3072"
+ d="m 1626.87,1823.47 -20.94,0 c -5.76,0.58 -11.59,0.89 -17.5,0.89 l -1176.856,0 c -5.91,0 -11.742,-0.31 -17.5,-0.89 l -20.929,0 c 8.171,1.82 16.55,3.07 25.101,3.71 l 1203.514,0 c 8.55,-0.64 16.93,-1.89 25.11,-3.71"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient3054"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop3056"
+ offset="0"
+ style="stop-opacity:1;stop-color:#f5f5f4" />
+ <stop
+ id="stop3058"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#e3e3e1" />
+ <stop
+ id="stop3060"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#e3e3e1" />
+ <stop
+ id="stop3062"
+ offset="1"
+ style="stop-opacity:1;stop-color:#eff0ef" />
+ </linearGradient>
+ <clipPath
+ id="clipPath3050"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3052"
+ d="m 1601.76,1827.18 -1203.514,0 c 4.399,0.34 8.848,0.5 13.328,0.5 l 1176.856,0 c 4.48,0 8.93,-0.16 13.33,-0.5"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient3034"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop3036"
+ offset="0"
+ style="stop-opacity:1;stop-color:#f6f6f6" />
+ <stop
+ id="stop3038"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#e2dfde" />
+ <stop
+ id="stop3040"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#e2dfde" />
+ <stop
+ id="stop3042"
+ offset="1"
+ style="stop-opacity:1;stop-color:#eff0ef" />
+ </linearGradient>
+ <clipPath
+ id="clipPath3030"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3032"
+ d="m 1640.22,1823.47 -13.35,0 c -8.18,1.82 -16.56,3.07 -25.11,3.71 l 23.81,0 c 4.95,-1.03 9.85,-2.27 14.65,-3.71 m -1267.075,0 -13.348,0 c 4.801,1.44 9.691,2.68 14.644,3.71 l 23.805,0 c -8.551,-0.64 -16.93,-1.89 -25.101,-3.71"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient3014"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop3016"
+ offset="0"
+ style="stop-opacity:1;stop-color:#f2f2f2" />
+ <stop
+ id="stop3018"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#dfdedc" />
+ <stop
+ id="stop3020"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#dfdedc" />
+ <stop
+ id="stop3022"
+ offset="1"
+ style="stop-opacity:1;stop-color:#ededed" />
+ </linearGradient>
+ <clipPath
+ id="clipPath3010"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path3012"
+ d="m 1625.57,1827.18 -23.81,0 c -4.4,0.34 -8.85,0.5 -13.33,0.5 l -1176.856,0 c -4.48,0 -8.929,-0.16 -13.328,-0.5 l -23.805,0 c 10.235,2.14 20.778,3.42 31.559,3.75 l 1188,0 c 10.79,-0.33 21.33,-1.61 31.57,-3.75"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient2994"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop2996"
+ offset="0"
+ style="stop-opacity:1;stop-color:#eeefef" />
+ <stop
+ id="stop2998"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#dbdad8" />
+ <stop
+ id="stop3000"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#dbdad8" />
+ <stop
+ id="stop3002"
+ offset="1"
+ style="stop-opacity:1;stop-color:#eaebe9" />
+ </linearGradient>
+ <clipPath
+ id="clipPath2990"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2992"
+ d="m 1594,1830.93 -1188,0 c 1.852,0.05 3.711,0.08 5.574,0.08 l 1176.856,0 c 1.86,0 3.72,-0.03 5.57,-0.08"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient2974"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop2976"
+ offset="0"
+ style="stop-opacity:1;stop-color:#f3f3f3" />
+ <stop
+ id="stop2978"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#dddbd9" />
+ <stop
+ id="stop2980"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#dddbd9" />
+ <stop
+ id="stop2982"
+ offset="1"
+ style="stop-opacity:1;stop-color:#ededed" />
+ </linearGradient>
+ <clipPath
+ id="clipPath2970"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2972"
+ d="m 1651.05,1823.47 -10.83,0 c -4.8,1.44 -9.7,2.68 -14.65,3.71 l 2.35,0 c 4.6,0 9.16,-0.2 13.66,-0.59 3.2,-0.96 6.35,-2 9.47,-3.12 m -1291.253,0 -10.836,0 c 3.113,1.12 6.25,2.15 9.434,3.11 4.539,0.4 9.136,0.6 13.777,0.6 l 2.269,0 c -4.953,-1.03 -9.843,-2.27 -14.644,-3.71"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient2954"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop2956"
+ offset="0"
+ style="stop-opacity:1;stop-color:#eff0ef" />
+ <stop
+ id="stop2958"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#dad9d8" />
+ <stop
+ id="stop2960"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#dad9d8" />
+ <stop
+ id="stop2962"
+ offset="1"
+ style="stop-opacity:1;stop-color:#eaebe9" />
+ </linearGradient>
+ <clipPath
+ id="clipPath2950"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2952"
+ d="m 358.395,1826.58 c 5.761,1.72 11.66,3.18 17.644,4.35 l 29.961,0 c -10.781,-0.33 -21.324,-1.61 -31.559,-3.75 l -2.269,0 c -4.641,0 -9.238,-0.2 -13.777,-0.6 m 1283.185,0.01 c -4.5,0.39 -9.06,0.59 -13.66,0.59 l -2.35,0 c -10.24,2.14 -20.78,3.42 -31.57,3.75 l 29.97,0 c 5.98,-1.17 11.85,-2.62 17.61,-4.34"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient2934"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop2936"
+ offset="0"
+ style="stop-opacity:1;stop-color:#ececec" />
+ <stop
+ id="stop2938"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d7d5d5" />
+ <stop
+ id="stop2940"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d7d5d5" />
+ <stop
+ id="stop2942"
+ offset="1"
+ style="stop-opacity:1;stop-color:#e7e8e6" />
+ </linearGradient>
+ <clipPath
+ id="clipPath2930"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2932"
+ d="m 1623.97,1830.93 -29.97,0 c -1.85,0.05 -3.71,0.08 -5.57,0.08 l -1176.856,0 c -1.863,0 -3.722,-0.03 -5.574,-0.08 l -29.961,0 c 11.508,2.24 23.383,3.41 35.535,3.41 l 1176.856,0 c 12.15,0 24.03,-1.17 35.54,-3.41"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient2914"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop2916"
+ offset="0"
+ style="stop-opacity:1;stop-color:#f2f2f2" />
+ <stop
+ id="stop2918"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d8d7d5" />
+ <stop
+ id="stop2920"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d8d7d5" />
+ <stop
+ id="stop2922"
+ offset="1"
+ style="stop-opacity:1;stop-color:#eaebe9" />
+ </linearGradient>
+ <clipPath
+ id="clipPath2910"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2912"
+ d="m 1660.52,1823.47 -9.47,0 c -3.12,1.12 -6.27,2.16 -9.47,3.12 5.98,-0.53 11.87,-1.4 17.63,-2.59 0.43,-0.17 0.88,-0.35 1.31,-0.53 m -1311.559,0 -9.469,0 c 0.41,0.17 0.824,0.34 1.238,0.51 5.778,1.19 11.672,2.07 17.665,2.6 -3.184,-0.96 -6.321,-1.99 -9.434,-3.11"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient2894"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop2896"
+ offset="0"
+ style="stop-opacity:1;stop-color:#ededed" />
+ <stop
+ id="stop2898"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d6d4d3" />
+ <stop
+ id="stop2900"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d6d4d3" />
+ <stop
+ id="stop2902"
+ offset="1"
+ style="stop-opacity:1;stop-color:#e8e8e7" />
+ </linearGradient>
+ <clipPath
+ id="clipPath2890"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2892"
+ d="m 340.73,1823.98 c 6.254,2.52 12.668,4.72 19.227,6.57 3.633,0.25 7.297,0.38 10.992,0.38 l 5.09,0 c -5.984,-1.17 -11.883,-2.63 -17.644,-4.35 -5.993,-0.53 -11.887,-1.41 -17.665,-2.6 m 1318.48,0.02 c -5.76,1.19 -11.65,2.06 -17.63,2.59 -5.76,1.72 -11.63,3.17 -17.61,4.34 l 5.17,0 c 3.66,0 7.29,-0.13 10.89,-0.38 6.54,-1.85 12.94,-4.03 19.18,-6.55"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient2874"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop2876"
+ offset="0"
+ style="stop-opacity:1;stop-color:#eaeae8" />
+ <stop
+ id="stop2878"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d1d1cf" />
+ <stop
+ id="stop2880"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d1d1cf" />
+ <stop
+ id="stop2882"
+ offset="1"
+ style="stop-opacity:1;stop-color:#e4e4e3" />
+ </linearGradient>
+ <clipPath
+ id="clipPath2870"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2872"
+ d="m 359.957,1830.55 c 5.848,1.65 11.813,3.03 17.875,4.12 l 1244.338,0 c 6.06,-1.09 12.01,-2.47 17.86,-4.12 -3.6,0.25 -7.23,0.38 -10.89,0.38 l -5.17,0 c -11.51,2.24 -23.39,3.41 -35.54,3.41 l -1176.856,0 c -12.152,0 -24.027,-1.17 -35.535,-3.41 l -5.09,0 c -3.695,0 -7.359,-0.13 -10.992,-0.38"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient2854"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop2856"
+ offset="0"
+ style="stop-opacity:1;stop-color:#e5e5e4" />
+ <stop
+ id="stop2858"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#cdccc9" />
+ <stop
+ id="stop2860"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#cdccc9" />
+ <stop
+ id="stop2862"
+ offset="1"
+ style="stop-opacity:1;stop-color:#e1dedd" />
+ </linearGradient>
+ <clipPath
+ id="clipPath2850"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2852"
+ d="m 1622.17,1834.67 -1244.338,0 c 10.953,1.97 22.23,3 33.742,3 l 1176.856,0 c 11.51,0 22.79,-1.03 33.74,-3"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient2834"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop2836"
+ offset="0"
+ style="stop-opacity:1;stop-color:#eff0ef" />
+ <stop
+ id="stop2838"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d3d3d2" />
+ <stop
+ id="stop2840"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d3d3d2" />
+ <stop
+ id="stop2842"
+ offset="1"
+ style="stop-opacity:1;stop-color:#e8e8e7" />
+ </linearGradient>
+ <clipPath
+ id="clipPath2830"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2832"
+ d="m 1661.68,1823.47 -1.16,0 c -0.43,0.18 -0.88,0.36 -1.31,0.53 0.83,-0.17 1.65,-0.34 2.47,-0.53 m -1322.188,0 -1.109,0 c 0.781,0.17 1.562,0.34 2.347,0.51 -0.414,-0.17 -0.828,-0.34 -1.238,-0.51"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient2814"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop2816"
+ offset="0"
+ style="stop-opacity:1;stop-color:#ebeceb" />
+ <stop
+ id="stop2818"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d0cfce" />
+ <stop
+ id="stop2820"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d0cfce" />
+ <stop
+ id="stop2822"
+ offset="1"
+ style="stop-opacity:1;stop-color:#e5e5e4" />
+ </linearGradient>
+ <clipPath
+ id="clipPath2810"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2812"
+ d="m 1669.1,1823.47 -7.42,0 c -0.82,0.19 -1.64,0.36 -2.47,0.53 -6.24,2.52 -12.64,4.7 -19.18,6.55 5.86,-0.4 11.64,-1.12 17.31,-2.16 3.99,-1.51 7.91,-3.16 11.76,-4.92 m -1330.717,0 -7.485,0 c 3.84,1.76 7.739,3.39 11.707,4.9 5.684,1.04 11.473,1.77 17.352,2.18 -6.559,-1.85 -12.973,-4.05 -19.227,-6.57 -0.785,-0.17 -1.566,-0.34 -2.347,-0.51"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient2794"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop2796"
+ offset="0"
+ style="stop-opacity:1;stop-color:#e7e8e6" />
+ <stop
+ id="stop2798"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#cbcbc8" />
+ <stop
+ id="stop2800"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#cbcbc8" />
+ <stop
+ id="stop2802"
+ offset="1"
+ style="stop-opacity:1;stop-color:#e2e1df" />
+ </linearGradient>
+ <clipPath
+ id="clipPath2790"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2792"
+ d="m 342.605,1828.37 c 6.149,2.34 12.446,4.38 18.872,6.09 2.73,0.14 5.488,0.21 8.253,0.21 l 8.102,0 c -6.062,-1.09 -12.027,-2.47 -17.875,-4.12 -5.879,-0.41 -11.668,-1.14 -17.352,-2.18 m 1314.735,0.02 c -5.67,1.04 -11.45,1.76 -17.31,2.16 -5.85,1.65 -11.8,3.03 -17.86,4.12 l 8.18,0 c 2.74,0 5.46,-0.07 8.16,-0.21 6.41,-1.71 12.69,-3.73 18.83,-6.07"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient2774"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop2776"
+ offset="0"
+ style="stop-opacity:1;stop-color:#e2e2e0" />
+ <stop
+ id="stop2778"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#c7c6c4" />
+ <stop
+ id="stop2780"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#c7c6c4" />
+ <stop
+ id="stop2782"
+ offset="1"
+ style="stop-opacity:1;stop-color:#dddbd9" />
+ </linearGradient>
+ <clipPath
+ id="clipPath2770"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2772"
+ d="m 361.477,1834.46 c 6.011,1.6 12.136,2.93 18.363,3.95 l 1240.32,0 c 6.22,-1.02 12.34,-2.34 18.35,-3.95 -2.7,0.14 -5.42,0.21 -8.16,0.21 l -8.18,0 c -10.95,1.97 -22.23,3 -33.74,3 l -1176.856,0 c -11.512,0 -22.789,-1.03 -33.742,-3 l -8.102,0 c -2.765,0 -5.523,-0.07 -8.253,-0.21"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient2754"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop2756"
+ offset="0"
+ style="stop-opacity:1;stop-color:#dfdedc" />
+ <stop
+ id="stop2758"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#c2c1c0" />
+ <stop
+ id="stop2760"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#c2c1c0" />
+ <stop
+ id="stop2762"
+ offset="1"
+ style="stop-opacity:1;stop-color:#d8d7d5" />
+ </linearGradient>
+ <clipPath
+ id="clipPath2750"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2752"
+ d="m 1620.16,1838.41 -1240.32,0 c 10.328,1.7 20.933,2.59 31.734,2.59 l 1176.856,0 c 10.8,0 21.4,-0.89 31.73,-2.59"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2738"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2740"
+ d="m 270.363,869.172 c 0,0.019 0,0.039 0,0.058 l 0,-0.058"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2726"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2728"
+ d="m 1641.26,343.949 -1282.53,0 c -4.168,0 -8.234,0.43 -12.16,1.262 -15.765,8.5 -29.785,19.84 -41.371,33.32 -3.312,7.328 -5.16,15.457 -5.16,24 l 0,139.258 C 320.723,446.949 355.73,369.34 414.906,369.34 l 1170.184,0 c 59.08,0 94.12,80.832 114.84,178.332 l 0,-145.141 c 0,-8.551 -1.85,-16.679 -5.17,-24.011 -11.54,-13.469 -25.53,-24.801 -41.27,-33.29 -3.94,-0.839 -8.03,-1.281 -12.23,-1.281"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2714"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2716"
+ d="m 1640.05,339.66 -1280.097,0 c -0.652,0 -1.301,0.012 -1.945,0.02 -3.899,1.679 -7.723,3.531 -11.438,5.531 3.926,-0.832 7.992,-1.262 12.16,-1.262 l 1282.53,0 c 4.2,0 8.29,0.442 12.23,1.281 -3.72,-2.011 -7.54,-3.859 -11.45,-5.539 -0.66,-0.019 -1.32,-0.031 -1.99,-0.031 m 54.71,38.86 c 3.32,7.332 5.17,15.46 5.17,24.011 l 0,145.141 c 2.75,12.969 5.26,26.258 7.53,39.66 l 0,-180.32 c 0,-4.563 -0.45,-9.024 -1.32,-13.332 -3.47,-5.309 -7.26,-10.371 -11.38,-15.16 m -1389.561,0.011 c -4.101,4.778 -7.898,9.821 -11.355,15.11 -0.879,4.32 -1.34,8.789 -1.34,13.371 l 0,173.488 c 2.269,-13.102 4.777,-26.078 7.535,-38.711 l 0,-139.258 c 0,-8.543 1.848,-16.672 5.16,-24"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2702"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2704"
+ d="m 1630.71,335.371 -1261.374,0 c -3.852,1.277 -7.625,2.719 -11.328,4.309 0.644,-0.008 1.293,-0.02 1.945,-0.02 l 1280.097,0 c 0.67,0 1.33,0.012 1.99,0.031 -3.7,-1.601 -7.48,-3.043 -11.33,-4.32 m -1336.866,58.27 c -3.25,4.961 -6.207,10.14 -8.836,15.5 -0.024,0.781 -0.035,1.558 -0.035,2.339 l 0,219.079 c 2.175,-16.758 4.668,-33.539 7.531,-50.059 l 0,-173.488 c 0,-4.582 0.461,-9.051 1.34,-13.371 m 1412.296,0.039 c 0.87,4.308 1.32,8.769 1.32,13.332 l 0,180.32 c 2.87,16.898 5.36,33.996 7.54,51.047 l 0,-226.899 c 0,-0.75 -0.01,-1.5 -0.03,-2.242 -2.63,-5.379 -5.58,-10.578 -8.83,-15.558"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2690"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2692"
+ d="m 1614.87,331.082 -1229.702,0 c -5.395,1.129 -10.676,2.566 -15.832,4.289 l 1261.374,0 c -5.16,-1.723 -10.44,-3.16 -15.84,-4.289 M 285.008,409.141 c -2.942,5.988 -5.473,12.199 -7.57,18.609 l 0,274.059 c 1.941,-23.129 4.406,-47.161 7.535,-71.25 l 0,-219.079 c 0,-0.781 0.011,-1.558 0.035,-2.339 m 1429.962,0.097 c 0.02,0.742 0.03,1.492 0.03,2.242 l 0,226.899 c 3.13,24.48 5.59,48.832 7.54,72.109 l 0,-282.5 c -2.09,-6.457 -4.63,-12.718 -7.57,-18.75"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2678"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2680"
+ d="m 1585.09,327.988 -1170.184,0 c -10.187,0 -20.136,1.071 -29.738,3.094 l 1229.702,0 c -9.61,-2.023 -19.57,-3.094 -29.78,-3.094 M 277.438,427.75 c -4.59,14.051 -7.075,29.051 -7.075,44.602 l 0,396.82 c 0,-26.902 0.782,-92.352 7.075,-167.363 l 0,-274.059 m 1445.102,0.238 0,282.5 c 2.84,34.063 4.55,65.864 5.57,92.621 0.15,3.84 0.28,7.59 0.4,11.211 0.13,3.891 0.24,7.649 0.34,11.27 0.11,3.961 0.2,7.73 0.28,11.34 0.08,4.019 0.15,7.832 0.21,11.39 0.06,4.16 0.1,7.989 0.13,11.461 0.03,3.528 0.04,6.688 0.04,9.449 l 0,-9.421 0,-11.27 0,-10.937 0,-10.301 0,-8.871 0,-4.461 0,-341.617 c 0,-15.473 -2.45,-30.383 -6.97,-44.364"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2666"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2668"
+ d="m 346.57,345.211 c -18.472,3.91 -33.773,16.527 -41.371,33.32 11.586,-13.48 25.606,-24.82 41.371,-33.32 m 1306.92,0.019 c 15.74,8.489 29.73,19.821 41.27,33.29 -7.58,-16.758 -22.83,-29.372 -41.27,-33.29 m -68.4,24.11 -1170.184,0 c -59.176,0 -94.183,77.609 -114.867,172.449 l 0,33.973 c 12.254,-63.84 30.117,-122.231 55.738,-155.66 15.95,-22.743 42.161,-36.473 65.891,-36.473 l 1163.422,0 c 59.64,0 94.93,93.293 114.84,197.019 l 0,-32.976 c -20.72,-97.5 -55.76,-178.332 -114.84,-178.332"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2654"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2656"
+ d="m 358.008,339.68 c -4.449,0.129 -8.793,0.691 -12.985,1.64 -18.277,9.692 -34.304,23.09 -47.074,39.2 -1.797,4.171 -3.183,8.562 -4.105,13.121 3.457,-5.289 7.254,-10.332 11.355,-15.11 7.598,-16.793 22.899,-29.41 41.371,-33.32 3.715,-2 7.539,-3.852 11.438,-5.531 m 1284.032,0.011 c 3.91,1.68 7.73,3.528 11.45,5.539 18.44,3.918 33.69,16.532 41.27,33.29 4.12,4.789 7.91,9.851 11.38,15.16 -0.93,-4.571 -2.32,-8.981 -4.12,-13.168 -12.74,-16.102 -28.73,-29.492 -46.99,-39.184 -4.2,-0.949 -8.54,-1.508 -12.99,-1.637 M 300.039,541.789 c -2.758,12.633 -5.266,25.609 -7.535,38.711 l 0,39.539 c 2.238,-14.891 4.738,-29.719 7.535,-44.277 l 0,-33.973 m 1399.891,5.883 0,32.976 c 2.81,14.653 5.31,29.5 7.53,44.332 l 0,-37.648 c -2.27,-13.402 -4.78,-26.691 -7.53,-39.66"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2642"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2644"
+ d="m 1638.84,335.371 -8.13,0 c 3.85,1.277 7.63,2.719 11.33,4.32 4.45,0.129 8.79,0.688 12.99,1.637 -4.05,-2.137 -8.2,-4.098 -12.45,-5.867 -1.24,-0.063 -2.49,-0.09 -3.74,-0.09 m -1269.504,0 -8.16,0 c -1.25,0 -2.488,0.027 -3.723,0.09 -4.246,1.758 -8.391,3.719 -12.43,5.859 4.192,-0.949 8.536,-1.511 12.985,-1.64 3.703,-1.59 7.476,-3.032 11.328,-4.309 m 1332.684,45.141 c 1.8,4.187 3.19,8.597 4.12,13.168 3.25,4.98 6.2,10.179 8.83,15.558 -0.12,-3.949 -0.54,-7.816 -1.23,-11.59 -3.51,-5.988 -7.43,-11.726 -11.72,-17.136 M 297.949,380.52 c -4.281,5.402 -8.195,11.101 -11.703,17.07 -0.699,3.762 -1.117,7.621 -1.238,11.551 2.629,-5.36 5.586,-10.539 8.836,-15.5 0.922,-4.559 2.308,-8.95 4.105,-13.121 m -5.445,199.98 c -2.863,16.52 -5.356,33.301 -7.531,50.059 l 0,48.261 c 2.086,-19.32 4.578,-39.101 7.531,-58.781 l 0,-39.539 m 1414.956,6.832 0,37.648 c 3.01,20.059 5.5,40.079 7.54,59.469 l 0,-46.07 c -2.18,-17.051 -4.67,-34.149 -7.54,-51.047"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2630"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2632"
+ d="m 1630.6,331.082 -15.73,0 c 5.4,1.129 10.68,2.566 15.84,4.289 l 8.13,0 c 1.25,0 2.5,0.027 3.74,0.09 -3.91,-1.633 -7.91,-3.09 -11.98,-4.379 m -1245.432,0 -15.746,0 c -4.067,1.289 -8.063,2.746 -11.969,4.379 1.235,-0.063 2.473,-0.09 3.723,-0.09 l 8.16,0 c 5.156,-1.723 10.437,-3.16 15.832,-4.289 m -98.922,66.508 c -3.305,5.621 -6.25,11.492 -8.805,17.551 0,0.269 -0.003,0.539 -0.003,0.82 l 0,11.789 c 2.097,-6.41 4.628,-12.621 7.57,-18.609 0.121,-3.93 0.539,-7.789 1.238,-11.551 m 1427.494,0.058 c 0.69,3.774 1.11,7.641 1.23,11.59 2.94,6.032 5.48,12.293 7.57,18.75 l 0,-12.027 c 0,-0.242 -0.01,-0.473 -0.01,-0.711 -2.55,-6.078 -5.49,-11.961 -8.79,-17.602 M 284.973,630.559 c -3.129,24.089 -5.594,48.121 -7.535,71.25 l 0,71.41 c 1.484,-28.231 3.89,-60.641 7.535,-94.399 l 0,-48.261 m 1430.027,7.82 0,46.07 c 1.33,12.641 2.46,25 3.42,36.942 1.11,13.828 2.57,27.211 4.12,39.839 l 0,-50.742 c -1.95,-23.277 -4.41,-47.629 -7.54,-72.109"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2618"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2620"
+ d="m 1613.6,326.789 -1227.209,0 c -5.782,1.102 -11.446,2.531 -16.969,4.293 l 15.746,0 c 9.602,-2.023 19.551,-3.094 29.738,-3.094 l 1170.184,0 c 10.21,0 20.17,1.071 29.78,3.094 l 15.73,0 c -5.53,-1.762 -11.21,-3.203 -17,-4.293 M 277.441,415.141 c -3.117,7.398 -5.648,15.109 -7.535,23.058 l 0,434.789 c 0.149,0.453 0.301,0.692 0.457,0.692 2.473,-14.41 4.707,-43.032 6.082,-78.918 0.27,-6.852 0.602,-14.043 0.993,-21.543 l 0,-71.41 c -6.293,75.011 -7.075,140.461 -7.075,167.363 l 0,0.058 c 0,-0.019 0,-0.039 0,-0.058 l 0,-396.82 c 0,-15.551 2.485,-30.551 7.075,-44.602 l 0,-11.789 c 0,-0.281 0.003,-0.551 0.003,-0.82 m 1445.089,0.109 c 0,0.238 0.01,0.469 0.01,0.711 l 0,12.027 c 4.52,13.981 6.97,28.891 6.97,44.364 l 0,341.617 c 0.19,1.582 0.38,3.14 0.56,4.672 l 0,-380.121 c -1.88,-8.02 -4.41,-15.801 -7.54,-23.27 m 0.01,295.238 0,50.742 c 1.7,13.93 3.52,26.942 5.13,38.602 0.15,1.098 0.3,2.188 0.44,3.277 -1.02,-26.757 -2.73,-58.558 -5.57,-92.621"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2606"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2608"
+ d="m 1539.19,323.539 -1078.674,0 c -1.715,0 -48.977,0.25 -50.543,0.711 -8.032,0.219 -15.911,1.082 -23.582,2.539 l 1227.209,0 c -7.66,-1.449 -15.52,-2.309 -23.54,-2.527 -1.57,-0.473 -49.14,-0.723 -50.87,-0.723 M 269.906,438.199 c -2.605,10.973 -3.984,22.403 -3.984,34.153 l 0,338.359 c 0,2.309 1.746,55.598 3.984,62.277 l 0,-434.789 m 1460.164,0.321 0,380.121 c 0.17,1.429 0.33,2.839 0.49,4.218 0.39,3.481 0.75,6.821 1.07,10.012 0.35,3.559 0.66,6.93 0.93,10.109 0.32,3.668 0.57,7.071 0.77,10.192 0.26,3.859 0.43,7.289 0.53,10.269 0.07,2.18 0.11,4.11 0.11,5.789 l 0,-5.699 0,-9.609 0,-8.473 0,-6.25 0,-0.808 0,-366.039 c 0,-11.641 -1.35,-22.961 -3.9,-33.832"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2594"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2596"
+ d="m 1729.51,813.969 0,4.461 c 0.19,0.789 0.38,1.582 0.56,2.359 l 0,-2.148 c -0.18,-1.532 -0.37,-3.09 -0.56,-4.672"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2582"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2584"
+ d="m 1730.07,818.641 0,2.148 c 0.17,0.691 0.33,1.383 0.49,2.07 -0.16,-1.379 -0.32,-2.789 -0.49,-4.218"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2570"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2572"
+ d="m 1585.09,383.629 -1163.422,0 c -23.73,0 -49.941,13.73 -65.891,36.473 -25.621,33.429 -43.484,91.82 -55.738,155.66 l 0,36.699 c 12.742,-75.371 32.477,-147.242 61.652,-181.723 14.352,-20.468 45.379,-32.816 66.735,-32.816 l 1156.664,0 c 60.33,0 95.99,108.226 114.84,217.758 l 0,-35.032 c -19.91,-103.726 -55.2,-197.019 -114.84,-197.019"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2558"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2560"
+ d="m 345.023,341.32 c -21.203,4.809 -38.652,19.641 -47.074,39.2 12.77,-16.11 28.797,-29.508 47.074,-39.2 m 1310.007,0.008 c 18.26,9.692 34.25,23.082 46.99,39.184 -8.41,-19.543 -25.82,-34.352 -46.99,-39.184 M 300.039,575.762 c -2.797,14.558 -5.297,29.386 -7.535,44.277 l 0,43.18 c 2.18,-16.84 4.684,-33.891 7.535,-50.758 l 0,-36.699 m 1399.891,4.886 0,35.032 c 2.9,16.851 5.4,33.742 7.53,50.261 l 0,-40.961 c -2.22,-14.832 -4.72,-29.679 -7.53,-44.332"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2546"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2548"
+ d="m 357.453,335.461 c -4.863,0.23 -9.617,0.93 -14.207,2.039 -20.926,10.969 -39.012,26.691 -52.82,45.719 -1.848,4.59 -3.258,9.402 -4.18,14.371 3.508,-5.969 7.422,-11.668 11.703,-17.07 8.422,-19.559 25.871,-34.391 47.074,-39.2 4.039,-2.14 8.184,-4.101 12.43,-5.859 m 1285.127,0 c 4.25,1.769 8.4,3.73 12.45,5.867 21.17,4.832 38.58,19.641 46.99,39.184 4.29,5.41 8.21,11.148 11.72,17.136 -0.93,-5 -2.34,-9.828 -4.19,-14.437 -13.78,-19.02 -31.84,-34.742 -52.76,-45.711 -4.59,-1.109 -9.34,-1.809 -14.21,-2.039 M 292.504,620.039 c -2.953,19.68 -5.445,39.461 -7.531,58.781 l 0,55.282 c 1.886,-22.43 4.367,-46.43 7.531,-70.883 l 0,-43.18 m 1414.956,4.941 0,40.961 c 3.19,24.637 5.54,48.481 7.18,70.239 0.11,1.468 0.23,2.941 0.36,4.41 l 0,-56.141 c -2.04,-19.39 -4.53,-39.41 -7.54,-59.469"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2534"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2536"
+ d="m 1637.63,331.082 -7.03,0 c 4.07,1.289 8.07,2.746 11.98,4.379 4.87,0.23 9.62,0.93 14.21,2.039 -4.37,-2.289 -8.87,-4.371 -13.47,-6.23 -1.88,-0.129 -3.78,-0.188 -5.69,-0.188 m -1268.208,0 -7.024,0 c -1.914,0 -3.82,0.059 -5.703,0.188 -4.593,1.859 -9.086,3.941 -13.449,6.23 4.59,-1.109 9.344,-1.809 14.207,-2.039 3.906,-1.633 7.902,-3.09 11.969,-4.379 m 1340.128,52.129 c 1.85,4.609 3.26,9.437 4.19,14.437 3.3,5.641 6.24,11.524 8.79,17.602 -0.03,-4.301 -0.39,-8.539 -1.05,-12.672 -3.5,-6.769 -7.49,-13.238 -11.93,-19.367 m -1419.124,0.008 c -4.434,6.109 -8.422,12.551 -11.922,19.293 -0.66,4.117 -1.02,8.34 -1.063,12.629 2.555,-6.059 5.5,-11.93 8.805,-17.551 0.922,-4.969 2.332,-9.781 4.18,-14.371 m -5.453,295.601 c -3.645,33.758 -6.051,66.168 -7.535,94.399 l 0,71.519 c 1.574,-12.226 2.746,-26.66 3.304,-42.527 0.731,-19.563 2.102,-42.82 4.231,-68.109 l 0,-55.282 m 1430.027,5.629 0,56.141 c 1.55,17.359 4.42,33.769 7.54,48.351 l 0,-27.711 c -1.55,-12.628 -3.01,-26.011 -4.12,-39.839 -0.96,-11.942 -2.09,-24.301 -3.42,-36.942"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2522"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2524"
+ d="m 1630.64,326.789 -17.04,0 c 5.79,1.09 11.47,2.531 17,4.293 l 7.03,0 c 1.91,0 3.81,0.059 5.69,0.188 -4.14,-1.68 -8.37,-3.168 -12.68,-4.481 m -1244.249,0 -17.032,0 c -4.308,1.313 -8.527,2.801 -12.664,4.481 1.883,-0.129 3.789,-0.188 5.703,-0.188 l 7.024,0 c 5.523,-1.762 11.187,-3.191 16.969,-4.293 m -107.887,75.723 c -3.316,6.398 -6.199,13.047 -8.598,19.929 l 0,15.758 c 1.887,-7.949 4.418,-15.66 7.535,-23.058 0.043,-4.289 0.403,-8.512 1.063,-12.629 m 1442.976,0.066 c 0.66,4.133 1.02,8.371 1.05,12.672 3.13,7.469 5.66,15.25 7.54,23.27 l 0,-15.942 c -2.39,-6.906 -5.27,-13.59 -8.59,-20 m 1.06,358.652 0,27.711 c 1.75,8.2 3.59,15.829 5.31,22.719 0.22,0.899 0.44,1.781 0.66,2.66 -0.12,-3.621 -0.25,-7.371 -0.4,-11.211 -0.14,-1.089 -0.29,-2.179 -0.44,-3.277 -1.61,-11.66 -3.43,-24.672 -5.13,-38.602 M 277.438,773.219 c -0.391,7.5 -0.723,14.691 -0.993,21.543 -1.375,35.886 -3.609,64.508 -6.082,78.918 -0.156,0 -0.308,-0.239 -0.457,-0.692 l 0,4.981 c 0.153,0.101 0.305,0.16 0.457,0.16 2.699,-7.09 5.18,-18.649 7.075,-33.391 l 0,-71.519"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2510"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2512"
+ d="m 1612.54,322.5 -1225.142,0 c -6.14,1.059 -12.171,2.5 -18.039,4.289 l 17.032,0 c 7.671,-1.457 15.55,-2.32 23.582,-2.539 1.566,-0.461 48.828,-0.711 50.543,-0.711 l 1078.674,0 c 1.73,0 49.3,0.25 50.87,0.723 8.02,0.218 15.88,1.078 23.54,2.527 l 17.04,0 c -5.89,-1.789 -11.93,-3.23 -18.1,-4.289 M 269.906,422.441 c -3.715,10.649 -6.277,21.829 -7.531,33.399 l 0,374.941 c 1.379,17.5 4.215,44.84 7.531,47.188 l 0,-4.981 c -2.238,-6.679 -3.984,-59.968 -3.984,-62.277 l 0,-338.359 c 0,-11.75 1.379,-23.18 3.984,-34.153 l 0,-15.758 m 1460.164,0.137 0,15.942 c 2.55,10.871 3.9,22.191 3.9,33.832 l 0,366.039 c 0.12,0.621 0.24,1.218 0.36,1.82 0.63,3.148 1.19,6.09 1.66,8.809 0.58,3.281 1.05,6.25 1.42,8.878 0.07,0.524 0.13,1.024 0.2,1.5 l 0,-402.867 c -1.22,-11.769 -3.79,-23.133 -7.54,-33.953"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2498"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2500"
+ d="m 1543.78,319.102 -1087.827,0 c -3.426,0 -47.781,0.488 -50.914,1.41 -5.98,0.316 -11.863,0.988 -17.641,1.988 l 1225.142,0 c -5.73,-0.988 -11.57,-1.648 -17.5,-1.969 -3.16,-0.929 -47.8,-1.429 -51.26,-1.429 M 262.375,455.84 c -0.59,5.422 -0.895,10.941 -0.895,16.512 l 0,344.207 c 0,1.402 0.325,6.972 0.895,14.222 l 0,-374.941 m 1475.235,0.691 0,402.867 c 0.38,2.934 0.62,5.411 0.74,7.422 0.05,0.899 0.07,1.7 0.07,2.41 l 0,-2.351 0,-7.828 0,-5.742 0,-1.309 0,-379.648 c 0,-5.34 -0.27,-10.622 -0.81,-15.821"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2486"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2488"
+ d="m 1733.97,838.391 0,0.808 c 0.12,0.34 0.24,0.68 0.36,1.012 -0.12,-0.602 -0.24,-1.199 -0.36,-1.82"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2474"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2476"
+ d="m 1729.51,818.43 0,8.871 c 0.19,0.5 0.38,0.988 0.56,1.469 l 0,-7.981 c -0.18,-0.777 -0.37,-1.57 -0.56,-2.359"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2462"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2464"
+ d="m 1730.07,820.789 0,7.981 c 0.54,1.402 1.06,2.769 1.56,4.101 -0.32,-3.191 -0.68,-6.531 -1.07,-10.012 -0.16,-0.687 -0.32,-1.379 -0.49,-2.07"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2450"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2452"
+ d="m 1585.09,397.922 -1156.664,0 c -21.356,0 -52.383,12.348 -66.735,32.816 -29.175,34.481 -48.91,106.352 -61.652,181.723 l 0,39.59 c 12.93,-86.852 34.645,-175.86 67.563,-210.672 12.761,-18.188 48.597,-29.18 67.582,-29.18 l 1149.906,0 c 61.25,0 97.42,126.653 114.84,240.981 l 0,-37.5 C 1681.08,506.148 1645.42,397.922 1585.09,397.922"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2438"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2440"
+ d="m 300.039,612.461 c -2.851,16.867 -5.355,33.918 -7.535,50.758 l 0,47.511 c 2.07,-19 4.57,-38.781 7.535,-58.679 l 0,-39.59 m 1399.891,3.219 0,37.5 c 3.09,20.281 5.59,40.172 7.53,58.91 l 0,-46.149 c -2.13,-16.519 -4.63,-33.41 -7.53,-50.261"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2426"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2428"
+ d="m 343.246,337.5 c -10.391,2.512 -19.961,7.16 -28.211,13.461 -2.336,1.891 -4.621,3.859 -6.844,5.879 -7.636,7.39 -13.738,16.371 -17.765,26.379 13.808,-19.028 31.894,-34.75 52.82,-45.719 m 1313.544,0 c 20.92,10.969 38.98,26.691 52.76,45.711 -4.1,-10.191 -10.34,-19.301 -18.17,-26.77 -1.95,-1.761 -3.95,-3.48 -5.99,-5.152 -8.33,-6.449 -18.04,-11.219 -28.6,-13.789 M 292.504,663.219 c -3.164,24.453 -5.645,48.453 -7.531,70.883 l 0,77.539 c 0.023,-0.661 0.047,-1.321 0.07,-1.981 0.918,-26.23 3.328,-61.012 7.461,-98.93 l 0,-47.511 m 1414.956,2.722 0,46.149 c 1.42,13.672 2.55,26.742 3.39,38.871 0.71,10.238 2.2,20.098 4.15,29.367 l 0,-39.738 c -0.13,-1.469 -0.25,-2.942 -0.36,-4.41 -1.64,-21.758 -3.99,-45.602 -7.18,-70.239"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2414"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2416"
+ d="m 1643.32,331.27 c 4.6,1.859 9.1,3.941 13.47,6.23 10.56,2.57 20.27,7.34 28.6,13.789 -8.21,-6.711 -17.11,-12.598 -26.57,-17.527 -5.01,-1.301 -10.19,-2.141 -15.5,-2.492 m -1286.625,0 c -5.312,0.351 -10.488,1.191 -15.492,2.48 -9.305,4.859 -18.066,10.629 -26.168,17.211 8.25,-6.301 17.82,-10.949 28.211,-13.461 4.363,-2.289 8.856,-4.371 13.449,-6.23 m 1334.685,25.171 c 7.83,7.469 14.07,16.579 18.17,26.77 4.44,6.129 8.43,12.598 11.93,19.367 -0.87,-5.437 -2.25,-10.707 -4.1,-15.75 -7.35,-11.219 -16.1,-21.43 -26,-30.387 M 308.191,356.84 c -9.726,8.871 -18.339,18.941 -25.593,29.988 -1.844,5.031 -3.227,10.274 -4.094,15.684 3.5,-6.742 7.488,-13.184 11.922,-19.293 4.027,-10.008 10.129,-18.989 17.765,-26.379 m -23.218,377.262 c -2.129,25.289 -3.5,48.546 -4.231,68.109 -0.558,15.867 -1.73,30.301 -3.304,42.527 l 0,20.633 c 3.874,-13.551 6.71,-32.223 7.535,-53.73 l 0,-77.539 M 1715,740.59 l 0,39.738 c 2.11,10.07 4.76,19.453 7.54,27.883 l 0,-19.27 c -3.12,-14.582 -5.99,-30.992 -7.54,-48.351"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2402"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2404"
+ d="m 1636.41,326.789 -5.77,0 c 4.31,1.313 8.54,2.801 12.68,4.481 5.31,0.351 10.49,1.191 15.5,2.492 -4.71,-2.461 -9.54,-4.672 -14.51,-6.641 -2.6,-0.223 -5.24,-0.332 -7.9,-0.332 m -1267.051,0 -5.742,0 c -2.668,0 -5.32,0.109 -7.933,0.332 -4.954,1.969 -9.786,4.18 -14.481,6.629 5.004,-1.289 10.18,-2.129 15.492,-2.48 4.137,-1.68 8.356,-3.168 12.664,-4.481 m 1348.021,60.039 c 1.85,5.043 3.23,10.313 4.1,15.75 3.32,6.41 6.2,13.094 8.59,20 l 0,-2.148 c 0,-3.969 -0.25,-7.891 -0.73,-11.739 -3.41,-7.632 -7.42,-14.941 -11.96,-21.863 m -1434.782,0 c -4.536,6.91 -8.536,14.192 -11.95,21.801 -0.492,3.871 -0.742,7.812 -0.742,11.801 l 0,2.011 c 2.399,-6.882 5.282,-13.531 8.598,-19.929 0.867,-5.41 2.25,-10.653 4.094,-15.684 m 1439.942,402.113 0,19.27 c 1.82,5.527 3.69,10.66 5.5,15.289 0.27,0.699 0.54,1.398 0.81,2.09 -0.1,-3.621 -0.21,-7.379 -0.34,-11.27 -0.22,-0.879 -0.44,-1.761 -0.66,-2.66 -1.72,-6.89 -3.56,-14.519 -5.31,-22.719 M 277.438,844.738 c -1.895,14.742 -4.376,26.301 -7.075,33.391 -0.152,0 -0.304,-0.059 -0.457,-0.16 l 0,4.543 c 0.153,0.047 0.305,0.07 0.457,0.07 2.559,-3.98 4.973,-9.844 7.075,-17.211 l 0,-20.633"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2390"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2392"
+ d="m 1630.88,322.5 -18.34,0 c 6.17,1.059 12.21,2.5 18.1,4.289 l 5.77,0 c 2.66,0 5.3,0.109 7.9,0.332 -4.38,-1.742 -8.86,-3.281 -13.43,-4.621 m -1243.482,0 -18.308,0 c -4.559,1.34 -9.031,2.879 -13.406,4.621 2.613,-0.223 5.265,-0.332 7.933,-0.332 l 5.742,0 c 5.868,-1.789 11.899,-3.23 18.039,-4.289 m -116.75,86.129 c -3.343,7.453 -6.121,15.211 -8.273,23.223 l 0,23.988 c 1.254,-11.57 3.816,-22.75 7.531,-33.399 l 0,-2.011 c 0,-3.989 0.25,-7.93 0.742,-11.801 m 1458.692,0.062 c 0.48,3.848 0.73,7.77 0.73,11.739 l 0,2.148 c 3.75,10.82 6.32,22.184 7.54,33.953 l 0,-24.519 c -2.15,-8.051 -4.93,-15.84 -8.27,-23.321 m -1466.965,422.09 0,32.16 c 2.109,10.321 4.711,18.739 7.531,19.571 l 0,-4.543 c -3.316,-2.348 -6.152,-29.688 -7.531,-47.188"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2378"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2380"
+ d="m 1611.82,318.211 -1223.761,0 c -6.461,1.027 -12.793,2.469 -18.969,4.289 l 18.308,0 c 5.778,-1 11.661,-1.672 17.641,-1.988 3.133,-0.922 47.488,-1.41 50.914,-1.41 l 1087.827,0 c 3.46,0 48.1,0.5 51.26,1.429 5.93,0.321 11.77,0.981 17.5,1.969 l 18.34,0 c -6.2,-1.82 -12.56,-3.262 -19.06,-4.289 M 262.375,431.852 c -3.477,12.918 -5.332,26.5 -5.332,40.5 l 0,350.07 c 0,4.367 2.094,24.687 5.332,40.519 l 0,-32.16 c -0.57,-7.25 -0.895,-12.82 -0.895,-14.222 l 0,-344.207 c 0,-5.571 0.305,-11.09 0.895,-16.512 l 0,-23.988 m 1475.235,0.16 0,24.519 c 0.54,5.199 0.81,10.481 0.81,15.821 l 0,379.648 c 0.35,1.059 0.68,2.07 0.99,3.039 0.91,2.891 1.64,5.371 2.19,7.449 0.86,3.262 1.28,5.524 1.28,6.742 l 0,-5.41 0,-2.621 0,-388.847 c 0,-13.942 -1.83,-27.473 -5.27,-40.34"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2366"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2368"
+ d="m 1548.37,314.648 -1096.975,0 c -5.141,0 -46.594,0.731 -51.293,2.114 -4.059,0.328 -8.075,0.808 -12.043,1.449 l 1223.761,0 c -3.89,-0.621 -7.83,-1.09 -11.81,-1.422 -4.73,-1.391 -46.45,-2.141 -51.64,-2.141"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2354"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2356"
+ d="m 1738.42,852 0,1.309 c 0.34,0.589 0.67,1.171 0.99,1.73 -0.31,-0.969 -0.64,-1.98 -0.99,-3.039"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2342"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2344"
+ d="m 1733.97,839.199 0,6.25 c 0.7,1.242 1.38,2.43 2.02,3.571 -0.47,-2.719 -1.03,-5.661 -1.66,-8.809 -0.12,-0.332 -0.24,-0.672 -0.36,-1.012"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2330"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2332"
+ d="m 1729.51,827.301 0,10.301 c 0.19,0.328 0.38,0.668 0.56,0.988 l 0,-9.82 c -0.18,-0.481 -0.37,-0.969 -0.56,-1.469"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2318"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2320"
+ d="m 1730.07,828.77 0,9.82 c 0.86,1.519 1.7,2.98 2.49,4.39 -0.27,-3.179 -0.58,-6.55 -0.93,-10.109 -0.5,-1.332 -1.02,-2.699 -1.56,-4.101"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2306"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2308"
+ d="m 1585.09,412.199 -1149.906,0 c -18.985,0 -54.821,10.992 -67.582,29.18 -32.918,34.812 -54.633,123.82 -67.563,210.672 l 0,42.711 c 12.633,-97.102 36.523,-208.332 73.477,-242.742 11.164,-15.918 51.816,-25.532 68.425,-25.532 l 1143.149,0 c 62.58,0 99.48,150.371 114.84,267.473 l 0,-40.781 C 1682.51,538.852 1646.34,412.199 1585.09,412.199"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2294"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2296"
+ d="m 300.039,652.051 c -2.965,19.898 -5.465,39.679 -7.535,58.679 l 0,54.43 c 1.793,-21.512 4.293,-45.488 7.535,-70.398 l 0,-42.711 m 1399.891,1.129 0,40.781 c 3.45,26.301 5.81,50.918 7.14,71.777 0.1,1.653 0.24,3.293 0.39,4.922 l 0,-58.57 c -1.94,-18.738 -4.44,-38.629 -7.53,-58.91"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2282"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2284"
+ d="m 315.035,350.961 c -2.394,1.82 -4.68,3.789 -6.844,5.879 2.223,-2.02 4.508,-3.988 6.844,-5.879 m 1370.355,0.328 c 2.04,1.672 4.04,3.391 5.99,5.152 -1.91,-1.82 -3.9,-3.543 -5.99,-5.152 M 292.504,710.73 c -4.133,37.918 -6.543,72.7 -7.461,98.93 -0.023,0.66 -0.047,1.32 -0.07,1.981 l 0,42.07 c 2.398,-10.66 3.976,-23.082 4.367,-36.609 0.469,-14.422 1.515,-32.133 3.164,-51.942 l 0,-54.43 m 1414.956,1.36 0,58.57 c 1.23,12.559 4.02,24.352 7.54,34.891 l 0,-25.223 c -1.95,-9.269 -3.44,-19.129 -4.15,-29.367 -0.84,-12.129 -1.97,-25.199 -3.39,-38.871"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2270"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2272"
+ d="m 341.203,333.75 c -10.058,2.602 -19.406,6.988 -27.668,12.82 -5.347,4.239 -10.422,8.809 -15.187,13.692 -6.766,7.758 -12.145,16.738 -15.75,26.566 7.254,-11.047 15.867,-21.117 25.593,-29.988 2.164,-2.09 4.45,-4.059 6.844,-5.879 8.102,-6.582 16.863,-12.352 26.168,-17.211 m 1317.617,0.012 c 9.46,4.929 18.36,10.816 26.57,17.527 2.09,1.609 4.08,3.332 5.99,5.152 9.9,8.957 18.65,19.168 26,30.387 -3.64,-9.93 -9.09,-18.996 -15.95,-26.797 -4.64,-4.742 -9.57,-9.179 -14.76,-13.32 -8.31,-5.902 -17.72,-10.34 -27.85,-12.949 m 56.18,446.566 0,25.223 c 2.28,6.828 4.86,13.129 7.54,18.808 l 0,-16.148 c -2.78,-8.43 -5.43,-17.813 -7.54,-27.883 M 284.973,811.641 c -0.825,21.507 -3.661,40.179 -7.535,53.73 l 0,11 c 2.945,-6.062 5.527,-13.742 7.535,-22.66 l 0,-42.07"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2258"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2260"
+ d="m 1644.31,327.121 c 4.97,1.969 9.8,4.18 14.51,6.641 10.13,2.609 19.54,7.047 27.85,12.949 -7.93,-6.313 -16.47,-11.879 -25.51,-16.602 -5.44,-1.5 -11.07,-2.507 -16.85,-2.988 m -1288.626,0 c -5.778,0.488 -11.399,1.5 -16.832,2.988 -8.965,4.692 -17.438,10.211 -25.317,16.461 8.262,-5.832 17.61,-10.218 27.668,-12.82 4.695,-2.449 9.527,-4.66 14.481,-6.629 m 1345.746,32.91 c 6.86,7.801 12.31,16.867 15.95,26.797 4.54,6.922 8.55,14.231 11.96,21.863 -0.74,-5.89 -2.03,-11.613 -3.82,-17.109 -6.72,-11.512 -14.82,-22.102 -24.09,-31.551 m -1403.082,0.231 c -9.176,9.398 -17.215,19.918 -23.891,31.328 -1.781,5.48 -3.066,11.18 -3.809,17.039 3.414,-7.609 7.414,-14.891 11.95,-21.801 3.605,-9.828 8.984,-18.808 15.75,-26.566 m 1424.192,447.949 0,16.148 c 1.87,3.981 3.79,7.661 5.68,10.969 0.31,0.543 0.61,1.07 0.91,1.602 -0.08,-3.61 -0.17,-7.379 -0.28,-11.34 -0.27,-0.692 -0.54,-1.391 -0.81,-2.09 -1.81,-4.629 -3.68,-9.762 -5.5,-15.289 m -1445.102,57.16 c -2.102,7.367 -4.516,13.231 -7.075,17.211 -0.152,0 -0.304,-0.023 -0.457,-0.07 l 0,4.476 c 0.153,0.032 0.305,0.043 0.457,0.043 2.5,-2.551 4.887,-6.16 7.075,-10.66 l 0,-11"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2246"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2248"
+ d="m 1635.2,322.5 -4.32,0 c 4.57,1.34 9.05,2.879 13.43,4.621 5.78,0.481 11.41,1.488 16.85,2.988 -5.03,-2.629 -10.21,-5 -15.54,-7.078 -3.43,-0.351 -6.9,-0.531 -10.42,-0.531 m -1266.11,0 -4.25,0 c -3.535,0 -7.035,0.18 -10.485,0.531 -5.308,2.09 -10.484,4.449 -15.503,7.078 5.433,-1.488 11.054,-2.5 16.832,-2.988 4.375,-1.742 8.847,-3.281 13.406,-4.621 m 1356.43,69.082 c 1.79,5.496 3.08,11.219 3.82,17.109 3.34,7.481 6.12,15.27 8.27,23.321 l 0,-7.102 c 0,-2.898 -0.12,-5.781 -0.36,-8.621 -3.22,-8.609 -7.15,-16.867 -11.73,-24.707 M 274.457,391.59 c -4.57,7.82 -8.5,16.051 -11.719,24.64 -0.242,2.86 -0.363,5.758 -0.363,8.68 l 0,6.942 c 2.152,-8.012 4.93,-15.77 8.273,-23.223 0.743,-5.859 2.028,-11.559 3.809,-17.039 m -12.082,471.351 0,13.707 c 2.273,5.852 4.828,9.93 7.531,10.34 l 0,-4.476 c -2.82,-0.832 -5.422,-9.25 -7.531,-19.571"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2234"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2236"
+ d="m 1631.37,318.211 -19.55,0 c 6.5,1.027 12.86,2.469 19.06,4.289 l 4.32,0 c 3.52,0 6.99,0.18 10.42,0.531 -4.65,-1.832 -9.4,-3.441 -14.25,-4.82 m -1243.311,0 -19.473,0 c -4.84,1.379 -9.59,3 -14.231,4.82 3.45,-0.351 6.95,-0.531 10.485,-0.531 l 4.25,0 c 6.176,-1.82 12.508,-3.262 18.969,-4.289 M 262.738,416.23 c -3.519,9.391 -6.187,19.211 -7.898,29.34 l 0,401.239 c 1.73,10.011 4.359,21.66 7.535,29.839 l 0,-13.707 c -3.238,-15.832 -5.332,-36.152 -5.332,-40.519 l 0,-350.07 c 0,-14 1.855,-27.582 5.332,-40.5 l 0,-6.942 c 0,-2.922 0.121,-5.82 0.363,-8.68 m 1474.512,0.059 c 0.24,2.84 0.36,5.723 0.36,8.621 l 0,7.102 c 3.44,12.867 5.27,26.398 5.27,40.34 l 0,388.847 c 0.89,1.571 1.64,2.91 2.26,4.02 l 0,-419.43 c -1.7,-10.18 -4.36,-20.059 -7.89,-29.5"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2222"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2224"
+ d="m 1611.62,313.922 -1223.397,0 c -6.692,1.019 -13.243,2.457 -19.637,4.289 l 19.473,0 c 3.968,-0.641 7.984,-1.121 12.043,-1.449 4.699,-1.383 46.152,-2.114 51.293,-2.114 l 1096.975,0 c 5.19,0 46.91,0.75 51.64,2.141 3.98,0.332 7.92,0.801 11.81,1.422 l 19.55,0 c -6.43,-1.84 -13.02,-3.281 -19.75,-4.289 M 254.84,445.57 c -1.469,8.711 -2.238,17.66 -2.238,26.782 l 0,355.918 c 0,3.152 0.812,10.281 2.238,18.539 l 0,-401.239 m 1490.3,0.219 0,419.43 c 0.36,0.64 0.68,1.211 0.95,1.703 0.83,1.488 1.25,2.258 1.25,2.308 l 0,-1.23 0,-395.648 c 0,-9.051 -0.75,-17.922 -2.2,-26.563"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2210"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2212"
+ d="m 1552.96,310.199 -1106.128,0 c -6.852,0 -45.398,0.981 -51.664,2.821 -2.328,0.25 -4.648,0.55 -6.945,0.902 l 1223.397,0 c -2.2,-0.332 -4.41,-0.621 -6.63,-0.863 -6.31,-1.86 -45.12,-2.86 -52.03,-2.86"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2198"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2200"
+ d="m 1742.88,861.199 0,2.621 c 0.81,0.821 1.56,1.559 2.26,2.219 l 0,-0.82 c -0.62,-1.11 -1.37,-2.449 -2.26,-4.02"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2186"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2188"
+ d="m 1745.14,865.219 0,0.82 c 0.33,0.313 0.65,0.609 0.95,0.883 -0.27,-0.492 -0.59,-1.063 -0.95,-1.703"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2174"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2176"
+ d="m 1738.42,853.309 0,5.742 c 1.13,1.25 2.19,2.398 3.18,3.437 -0.55,-2.078 -1.28,-4.558 -2.19,-7.449 -0.32,-0.559 -0.65,-1.141 -0.99,-1.73"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2162"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2164"
+ d="m 1733.97,845.449 0,8.473 c 1.2,1.418 2.35,2.75 3.44,3.976 -0.37,-2.628 -0.84,-5.597 -1.42,-8.878 -0.64,-1.141 -1.32,-2.329 -2.02,-3.571"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2150"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2152"
+ d="m 1729.51,837.602 0,10.937 c 0.19,0.231 0.38,0.461 0.56,0.691 l 0,-10.64 c -0.18,-0.32 -0.37,-0.66 -0.56,-0.988"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2138"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2140"
+ d="m 1730.07,838.59 0,10.64 c 1.13,1.379 2.22,2.7 3.26,3.942 -0.2,-3.121 -0.45,-6.524 -0.77,-10.192 -0.79,-1.41 -1.63,-2.871 -2.49,-4.39"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2126"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2128"
+ d="m 1585.09,426.488 -1143.149,0 c -16.609,0 -57.261,9.614 -68.425,25.532 -36.954,34.41 -60.844,145.64 -73.477,242.742 l 0,45.937 c 11.457,-103.777 37.934,-244.738 79.391,-278.039 9.566,-13.648 55.035,-21.879 69.269,-21.879 l 1136.391,0 c 64.85,0 102.83,184.09 114.84,299.16 l 0,-45.98 C 1684.57,576.859 1647.67,426.488 1585.09,426.488"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2114"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2116"
+ d="m 1699.93,693.961 0,45.98 c 1.55,14.86 2.67,28.571 3.35,40.59 0.51,8.789 2.01,17.168 4.18,24.969 l 0,-34.84 c -0.15,-1.629 -0.29,-3.269 -0.39,-4.922 -1.33,-20.859 -3.69,-45.476 -7.14,-71.777 m -1399.891,0.801 c -3.242,24.91 -5.742,48.886 -7.535,70.398 l 0,74.641 c 0.601,-4.879 0.988,-9.981 1.133,-15.25 0.578,-20.871 2.711,-50.442 6.402,-83.852 l 0,-45.937"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2102"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2104"
+ d="m 292.504,765.16 c -1.649,19.809 -2.695,37.52 -3.164,51.942 -0.391,13.527 -1.969,25.949 -4.367,36.609 l 0,16.68 c 3.457,-8.532 6.101,-18.942 7.531,-30.59 l 0,-74.641 m 1414.956,5.5 0,34.84 c 2.02,7.23 4.62,13.961 7.54,20.078 l 0,-20.027 c -3.52,-10.539 -6.31,-22.332 -7.54,-34.891"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2090"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2092"
+ d="m 313.535,346.57 c -5.594,3.942 -10.695,8.551 -15.187,13.692 4.765,-4.883 9.84,-9.453 15.187,-13.692 m 1373.135,0.141 c 5.19,4.141 10.12,8.578 14.76,13.32 -4.38,-4.992 -9.34,-9.461 -14.76,-13.32 m 28.33,458.84 0,20.027 c 2.35,4.91 4.9,9.422 7.54,13.461 l 0,-14.68 c -2.68,-5.679 -5.26,-11.98 -7.54,-18.808 m -1430.027,48.16 c -2.008,8.918 -4.59,16.598 -7.535,22.66 l 0,7.938 c 2.777,-3.758 5.32,-8.45 7.535,-13.918 l 0,-16.68"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2078"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2080"
+ d="m 1661.16,330.109 c 9.04,4.723 17.58,10.289 25.51,16.602 5.42,3.859 10.38,8.328 14.76,13.32 9.27,9.449 17.37,20.039 24.09,31.551 -3.29,-10.133 -8.27,-19.512 -14.59,-27.812 -6.55,-7.461 -13.76,-14.329 -21.53,-20.508 -8.5,-5.864 -18.03,-10.352 -28.24,-13.153 m -1322.308,0 c -10.153,2.782 -19.625,7.243 -28.098,13.051 -7.902,6.262 -15.219,13.238 -21.856,20.828 -6.257,8.25 -11.175,17.551 -14.441,27.602 6.676,-11.41 14.715,-21.93 23.891,-31.328 4.492,-5.141 9.593,-9.75 15.187,-13.692 7.879,-6.25 16.352,-11.769 25.317,-16.461 m 1383.688,494.25 0,14.68 c 1.93,2.973 3.9,5.691 5.86,8.133 0.32,0.387 0.63,0.769 0.94,1.148 -0.06,-3.558 -0.13,-7.371 -0.21,-11.39 -0.3,-0.532 -0.6,-1.059 -0.91,-1.602 -1.89,-3.308 -3.81,-6.988 -5.68,-10.969 M 277.438,876.371 c -2.188,4.5 -4.575,8.109 -7.075,10.66 -0.152,0 -0.304,-0.011 -0.457,-0.043 l 0,4.473 c 0.153,0.008 0.305,0.019 0.457,0.019 2.469,-1.73 4.848,-4.148 7.075,-7.171 l 0,-7.938"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2066"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2068"
+ d="m 1645.62,323.031 c 5.33,2.078 10.51,4.449 15.54,7.078 10.21,2.801 19.74,7.289 28.24,13.153 -7.95,-6.321 -16.49,-11.91 -25.54,-16.68 -5.88,-1.711 -11.98,-2.922 -18.24,-3.551 m -1291.265,0 c -6.257,0.641 -12.343,1.84 -18.222,3.559 -8.981,4.738 -17.469,10.289 -25.379,16.57 8.473,-5.808 17.945,-10.269 28.098,-13.051 5.019,-2.629 10.195,-4.988 15.503,-7.078 M 1710.93,363.77 c 6.32,8.3 11.3,17.679 14.59,27.812 4.58,7.84 8.51,16.098 11.73,24.707 -0.53,-6.348 -1.65,-12.551 -3.3,-18.519 -6.26,-12.309 -14.01,-23.719 -23.02,-34 m -1422.032,0.218 c -8.941,10.231 -16.648,21.582 -22.875,33.801 -1.636,5.949 -2.75,12.109 -3.285,18.441 3.219,-8.589 7.149,-16.82 11.719,-24.64 3.266,-10.051 8.184,-19.352 14.441,-27.602 m -26.523,512.66 0,8.641 c 2.344,3.609 4.879,5.93 7.531,6.172 l 0,-4.473 c -2.703,-0.41 -5.258,-4.488 -7.531,-10.34"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2054"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2056"
+ d="m 1633.99,318.211 -2.62,0 c 4.85,1.379 9.6,2.988 14.25,4.82 6.26,0.629 12.36,1.84 18.24,3.551 -5.35,-2.82 -10.88,-5.352 -16.56,-7.582 -4.36,-0.52 -8.81,-0.789 -13.31,-0.789 m -1265.404,0 -2.524,0 c -4.535,0 -9.007,0.269 -13.406,0.801 -5.664,2.226 -11.179,4.758 -16.523,7.578 5.879,-1.719 11.965,-2.918 18.222,-3.559 4.641,-1.82 9.391,-3.441 14.231,-4.82 M 1733.95,397.77 c 1.65,5.968 2.77,12.171 3.3,18.519 3.53,9.441 6.19,19.32 7.89,29.5 l 0,-16.398 c 0,-1.231 -0.02,-2.461 -0.06,-3.68 -2.86,-9.711 -6.61,-19.063 -11.13,-27.941 m -1467.927,0.019 c -4.515,8.859 -8.25,18.18 -11.121,27.871 -0.039,1.238 -0.062,2.481 -0.062,3.731 l 0,16.179 c 1.711,-10.129 4.379,-19.949 7.898,-29.34 0.535,-6.332 1.649,-12.492 3.285,-18.441 m -11.183,449.02 0,21.16 c 2.137,6.711 4.695,12.961 7.535,17.32 l 0,-8.641 c -3.176,-8.179 -5.805,-19.828 -7.535,-29.839"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2042"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2044"
+ d="m 1632.15,313.922 -20.53,0 c 6.73,1.008 13.32,2.449 19.75,4.289 l 2.62,0 c 4.5,0 8.95,0.269 13.31,0.789 -4.94,-1.93 -9.99,-3.629 -15.15,-5.078 m -1243.927,0 -20.43,0 c -5.152,1.449 -10.199,3.148 -15.137,5.09 4.399,-0.532 8.871,-0.801 13.406,-0.801 l 2.524,0 c 6.394,-1.832 12.945,-3.27 19.637,-4.289 M 254.902,425.66 c -4.382,14.809 -6.742,30.481 -6.742,46.692 l 0,361.769 c 0,6.238 2.559,20.91 6.68,33.848 l 0,-21.16 c -1.426,-8.258 -2.238,-15.387 -2.238,-18.539 l 0,-355.918 c 0,-9.122 0.769,-18.071 2.238,-26.782 l 0,-16.179 c 0,-1.25 0.023,-2.493 0.062,-3.731 m 1490.178,0.051 c 0.04,1.219 0.06,2.449 0.06,3.68 l 0,16.398 c 1.45,8.641 2.2,17.512 2.2,26.563 l 0,395.648 c 1.76,1.461 3.01,2.18 3.73,2.18 0.48,0 0.73,-0.321 0.73,-0.95 l 0,-396.878 c 0,-16.192 -2.35,-31.84 -6.72,-46.641"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2030"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2032"
+ d="m 1612.08,309.629 -1224.35,0 c -6.785,1.012 -13.445,2.449 -19.937,4.293 l 20.43,0 c 2.297,-0.352 4.617,-0.652 6.945,-0.902 6.266,-1.84 44.812,-2.821 51.664,-2.821 l 1106.128,0 c 6.91,0 45.72,1 52.03,2.86 2.22,0.242 4.43,0.531 6.63,0.863 l 20.53,0 c -6.53,-1.844 -13.24,-3.281 -20.07,-4.293"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2018"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2020"
+ d="m 1557.55,305.75 -1115.277,0 c -8.562,0 -44.207,1.23 -52.039,3.52 -0.839,0.121 -1.668,0.23 -2.504,0.359 l 1224.35,0 c -0.7,-0.109 -1.41,-0.207 -2.12,-0.301 -7.89,-2.328 -43.77,-3.578 -52.41,-3.578"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath2006"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path2008"
+ d="m 1733.97,853.922 0,9.609 c 1.26,1 2.47,1.918 3.64,2.758 l 0,-6.891 c -0.07,-0.476 -0.13,-0.976 -0.2,-1.5 -1.09,-1.226 -2.24,-2.558 -3.44,-3.976"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1994"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1996"
+ d="m 1737.61,859.398 0,6.891 c 0.25,0.18 0.49,0.359 0.74,0.531 -0.12,-2.011 -0.36,-4.488 -0.74,-7.422"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1982"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1984"
+ d="m 1729.51,848.539 0,11.27 c 0.19,0.16 0.38,0.332 0.56,0.492 l 0,-11.071 c -0.18,-0.23 -0.37,-0.46 -0.56,-0.691"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1970"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1972"
+ d="m 1730.07,849.23 0,11.071 c 1.31,1.121 2.57,2.168 3.79,3.14 -0.1,-2.98 -0.27,-6.41 -0.53,-10.269 -1.04,-1.242 -2.13,-2.563 -3.26,-3.942"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1958"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1960"
+ d="m 1585.09,440.781 -1136.391,0 c -14.234,0 -59.703,8.231 -69.269,21.879 -41.457,33.301 -67.934,174.262 -79.391,278.039 l 0,54.071 c 8.016,-100.59 37.711,-289.399 85.305,-321.469 7.972,-11.371 58.25,-18.242 70.117,-18.242 l 1129.629,0 c 69.81,0 109.57,243.929 114.41,340.25 0.09,1.832 0.23,3.652 0.43,5.441 l 0,-60.809 c -12.01,-115.07 -49.99,-299.16 -114.84,-299.16"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1946"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1948"
+ d="m 1699.93,739.941 0,60.809 c 1.11,10.281 3.82,19.828 7.53,28.32 l 0,-23.57 c -2.17,-7.801 -3.67,-16.18 -4.18,-24.969 -0.68,-12.019 -1.8,-25.73 -3.35,-40.59 m -1399.891,0.758 c -3.691,33.41 -5.824,62.981 -6.402,83.852 -0.145,5.269 -0.532,10.371 -1.133,15.25 l 0,25.238 c 3.168,-9.629 5.137,-20.867 5.434,-33.039 0.242,-10.102 0.945,-22.75 2.101,-37.23 l 0,-54.071"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1934"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1936"
+ d="m 1707.46,805.5 0,23.57 c 2.21,5.051 4.77,9.731 7.54,13.969 l 0,-17.461 c -2.92,-6.117 -5.52,-12.848 -7.54,-20.078 M 292.504,839.801 c -1.43,11.648 -4.074,22.058 -7.531,30.59 l 0,11.148 c 2.925,-4.699 5.48,-10.258 7.531,-16.5 l 0,-25.238"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1922"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1924"
+ d="m 1715,825.578 0,17.461 c 2.38,3.633 4.92,6.941 7.54,9.902 l 0,-13.902 C 1719.9,835 1717.35,830.488 1715,825.578 M 284.973,870.391 c -2.215,5.468 -4.758,10.16 -7.535,13.918 l 0,6.632 c 2.699,-2.543 5.23,-5.703 7.535,-9.402 l 0,-11.148"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1910"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1912"
+ d="m 310.754,343.16 c -8.356,5.719 -15.746,12.77 -21.856,20.828 6.637,-7.59 13.954,-14.566 21.856,-20.828 m 1378.646,0.102 c 7.77,6.179 14.98,13.047 21.53,20.508 -6.04,-7.918 -13.31,-14.848 -21.53,-20.508 m 33.14,495.777 0,13.902 c 1.98,2.231 4.01,4.258 6.05,6.059 0.29,0.262 0.59,0.52 0.88,0.781 -0.03,-3.472 -0.07,-7.301 -0.13,-11.461 -0.31,-0.379 -0.62,-0.761 -0.94,-1.148 -1.96,-2.442 -3.93,-5.16 -5.86,-8.133 m -1445.102,45.27 c -2.227,3.023 -4.606,5.441 -7.075,7.171 -0.152,0 -0.304,-0.011 -0.457,-0.019 l 0,4.461 c 0.153,0 0.305,0.008 0.457,0.008 2.449,-1.192 4.821,-2.871 7.075,-4.989 l 0,-6.632"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1898"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1900"
+ d="m 1663.86,326.582 c 9.05,4.77 17.59,10.359 25.54,16.68 8.22,5.66 15.49,12.59 21.53,20.508 9.01,10.281 16.76,21.691 23.02,34 -2.87,-10.438 -7.36,-20.211 -13.17,-29.04 -8.2,-10.57 -17.63,-20.14 -28.05,-28.5 -8.75,-5.96 -18.47,-10.609 -28.87,-13.648 M 336.133,326.59 c -10.34,3.019 -20.008,7.629 -28.723,13.551 -10.551,8.441 -20.074,18.121 -28.351,28.82 -5.75,8.777 -10.188,18.48 -13.036,28.828 6.227,-12.219 13.934,-23.57 22.875,-33.801 6.11,-8.058 13.5,-15.109 21.856,-20.828 7.91,-6.281 16.398,-11.832 25.379,-16.57 m -73.758,558.699 0,6.672 c 2.383,2.359 4.91,3.801 7.531,3.961 l 0,-4.461 c -2.652,-0.242 -5.187,-2.563 -7.531,-6.172"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1886"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1888"
+ d="m 1647.3,319 c 5.68,2.23 11.21,4.762 16.56,7.582 10.4,3.039 20.12,7.688 28.87,13.648 -8.03,-6.429 -16.65,-12.14 -25.77,-17.019 -6.33,-1.981 -12.9,-3.402 -19.66,-4.211 m -1294.644,0.012 c -6.746,0.82 -13.304,2.238 -19.629,4.207 -9.054,4.859 -17.632,10.543 -25.617,16.922 8.715,-5.922 18.383,-10.532 28.723,-13.551 5.344,-2.82 10.859,-5.352 16.523,-7.578 M 1720.78,368.73 c 5.81,8.829 10.3,18.602 13.17,29.04 4.52,8.878 8.27,18.23 11.13,27.941 -0.22,-6.813 -1.06,-13.481 -2.46,-19.941 -5.71,-13.321 -13.08,-25.75 -21.84,-37.04 m -1441.721,0.231 c -8.7,11.25 -16.02,23.617 -21.704,36.859 -1.39,6.418 -2.226,13.059 -2.453,19.84 2.871,-9.691 6.606,-19.012 11.121,-27.871 2.848,-10.348 7.286,-20.051 13.036,-28.828 m 1459.361,490.09 0,7.828 c 2.47,1.742 4.72,3.121 6.72,4.152 l 0,-4.992 c -0.7,-0.66 -1.45,-1.398 -2.26,-2.219 l 0,5.41 c 0,-1.218 -0.42,-3.48 -1.28,-6.742 -0.99,-1.039 -2.05,-2.187 -3.18,-3.437 m -1483.58,8.918 0,12.941 c 2.269,4.481 4.808,8.36 7.535,11.051 l 0,-6.672 c -2.84,-4.359 -5.398,-10.609 -7.535,-17.32"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1874"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1876"
+ d="m 1632.77,313.922 -0.62,0 c 5.16,1.449 10.21,3.148 15.15,5.078 6.76,0.809 13.33,2.23 19.66,4.211 -5.66,-3.039 -11.51,-5.762 -17.54,-8.141 -5.44,-0.761 -11,-1.148 -16.65,-1.148 m -1264.977,0 -0.508,0 c -5.683,0 -11.277,0.398 -16.758,1.156 -6.004,2.383 -11.847,5.102 -17.5,8.141 6.325,-1.969 12.883,-3.387 19.629,-4.207 4.938,-1.942 9.985,-3.641 15.137,-5.09 M 1742.62,405.77 c 1.4,6.46 2.24,13.128 2.46,19.941 4.37,14.801 6.72,30.449 6.72,46.641 l 0,396.878 c 0,0.629 -0.25,0.95 -0.73,0.95 -0.72,0 -1.97,-0.719 -3.73,-2.18 l 0,1.23 c 0,-0.05 -0.42,-0.82 -1.25,-2.308 -0.3,-0.274 -0.62,-0.57 -0.95,-0.883 l 0,4.992 c 3,1.539 5.45,2.289 7.29,2.289 0.08,0 0.17,0 0.25,0 l 0,-435.672 c -2.31,-11.058 -5.71,-21.726 -10.06,-31.878 m -1485.265,0.05 c -4.347,10.129 -7.734,20.77 -10.046,31.801 l 0,423.238 c 1.898,6.84 4.472,14 7.531,20.051 l 0,-12.941 c -4.121,-12.938 -6.68,-27.61 -6.68,-33.848 l 0,-361.769 c 0,-16.211 2.36,-31.883 6.742,-46.692 0.227,-6.781 1.063,-13.422 2.453,-19.84"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1862"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1864"
+ d="m 1631.56,309.629 -19.48,0 c 6.83,1.012 13.54,2.449 20.07,4.293 l 0.62,0 c 5.65,0 11.21,0.387 16.65,1.148 -5.25,-2.07 -10.63,-3.89 -16.12,-5.429 -0.58,-0.012 -1.16,-0.012 -1.74,-0.012 m -1243.83,0 -19.222,0 c -0.625,0 -1.254,0 -1.875,0.012 -5.488,1.55 -10.856,3.359 -16.106,5.437 5.481,-0.758 11.075,-1.156 16.758,-1.156 l 0.508,0 c 6.492,-1.844 13.152,-3.281 19.937,-4.293 M 247.309,437.621 c -2.352,11.219 -3.586,22.828 -3.586,34.731 l 0,367.617 c 0,4.89 1.304,12.672 3.586,20.89 l 0,-423.238 m 1505.371,0.027 0,435.672 c 2.33,-0.101 3.57,-1.48 3.57,-4.09 l 0,-396.878 c 0,-11.891 -1.23,-23.5 -3.57,-34.704"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1850"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1852"
+ d="m 1613.98,305.34 -1227.984,0 c -0.242,0.058 -0.476,0.121 -0.695,0.191 -6.348,1.02 -12.574,2.399 -18.668,4.11 0.621,-0.012 1.25,-0.012 1.875,-0.012 l 19.222,0 c 0.836,-0.129 1.665,-0.238 2.504,-0.359 7.832,-2.29 43.477,-3.52 52.039,-3.52 l 1115.277,0 c 8.64,0 44.52,1.25 52.41,3.578 0.71,0.094 1.42,0.192 2.12,0.301 l 19.48,0 c 0.58,0 1.16,0 1.74,0.012 -5.99,-1.68 -12.12,-3.039 -18.36,-4.039 -0.3,-0.09 -0.62,-0.18 -0.96,-0.262"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1838"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1840"
+ d="m 1562.14,301.301 -1124.429,0 c -10.035,0 -41.492,1.41 -51.715,4.039 l 1227.984,0 c -10.55,-2.629 -41.8,-4.039 -51.84,-4.039"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1826"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1828"
+ d="m 1585.09,455.059 -1129.629,0 c -11.867,0 -62.145,6.871 -70.117,18.242 -47.594,32.07 -77.289,220.879 -85.305,321.469 l 0,63.66 c 1.293,-5.961 2.059,-12.328 2.195,-18.989 1.52,-74.722 34.938,-326.152 89.024,-355.5 6.379,-9.101 61.469,-14.589 70.961,-14.589 l 1122.871,0 c 66.4,0 106.88,253.136 110.62,340.738 0.35,8.031 1.85,15.629 4.22,22.609 l 0,-31.949 c -0.2,-1.789 -0.34,-3.609 -0.43,-5.441 -4.84,-96.321 -44.6,-340.25 -114.41,-340.25"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1814"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1816"
+ d="m 300.039,794.77 c -1.156,14.48 -1.859,27.128 -2.101,37.23 -0.297,12.172 -2.266,23.41 -5.434,33.039 l 0,14.281 c 3.258,-6.058 5.848,-13.121 7.535,-20.89 l 0,-63.66 m 1399.891,5.98 0,31.949 c 1.97,5.821 4.54,11.211 7.53,16.09 l 0,-19.719 c -3.71,-8.492 -6.42,-18.039 -7.53,-28.32"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1802"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1804"
+ d="m 1707.46,829.07 0,19.719 c 2.29,3.723 4.83,7.152 7.54,10.231 l 0,-15.981 c -2.77,-4.238 -5.33,-8.918 -7.54,-13.969 M 292.504,865.039 c -2.051,6.242 -4.606,11.801 -7.531,16.5 l 0,8.68 c 2.773,-3.098 5.308,-6.77 7.531,-10.899 l 0,-14.281"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1790"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1792"
+ d="m 1715,843.039 0,15.981 c 2.4,2.718 4.92,5.171 7.54,7.332 l 0,-13.411 c -2.62,-2.961 -5.16,-6.269 -7.54,-9.902 m -1430.027,38.5 c -2.305,3.699 -4.836,6.859 -7.535,9.402 l 0,5.93 c 2.656,-1.781 5.179,-4.012 7.535,-6.652 l 0,-8.68"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1778"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1780"
+ d="m 1722.54,852.941 0,13.411 c 2.03,1.679 4.12,3.179 6.23,4.488 0.44,0.269 0.87,0.531 1.3,0.789 l 0,-11.328 c -0.18,-0.16 -0.37,-0.332 -0.56,-0.492 l 0,9.421 c 0,-2.761 -0.01,-5.921 -0.04,-9.449 -0.29,-0.261 -0.59,-0.519 -0.88,-0.781 -2.04,-1.801 -4.07,-3.828 -6.05,-6.059 m -1445.102,38 c -2.254,2.118 -4.626,3.797 -7.075,4.989 -0.152,0 -0.304,-0.008 -0.457,-0.008 l 0,4.449 c 0.153,0.008 0.305,0.008 0.457,0.008 2.434,-0.809 4.801,-1.988 7.075,-3.508 l 0,-5.93"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1766"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1768"
+ d="m 307.41,340.141 c -11.242,7.64 -20.898,17.449 -28.351,28.82 8.277,-10.699 17.8,-20.379 28.351,-28.82 m 1385.32,0.089 c 10.42,8.36 19.85,17.93 28.05,28.5 -7.4,-11.23 -16.95,-20.929 -28.05,-28.5 m 37.34,520.071 0,11.328 c 2.64,1.562 5.16,2.859 7.54,3.902 l 0,-9.242 c -1.17,-0.84 -2.38,-1.758 -3.64,-2.758 l 0,5.699 c 0,-1.679 -0.04,-3.609 -0.11,-5.789 -1.22,-0.972 -2.48,-2.019 -3.79,-3.14 m -1467.695,31.66 0,5.758 c 2.406,1.601 4.93,2.551 7.531,2.652 l 0,-4.449 c -2.621,-0.16 -5.148,-1.602 -7.531,-3.961"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1754"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1756"
+ d="m 1666.96,323.211 c 9.12,4.879 17.74,10.59 25.77,17.019 11.1,7.571 20.65,17.27 28.05,28.5 8.76,11.29 16.13,23.719 21.84,37.04 -2.34,-10.75 -6.23,-20.918 -11.44,-30.27 -9.65,-14.34 -21.37,-27.16 -34.73,-38.031 -8.98,-6.117 -18.89,-10.969 -29.49,-14.258 m -1333.933,0.008 c -10.531,3.281 -20.398,8.09 -29.336,14.16 -13.488,10.949 -25.32,23.902 -35.035,38.391 -5.14,9.289 -8.984,19.378 -11.301,30.05 5.684,-13.242 13.004,-25.609 21.704,-36.859 7.453,-11.371 17.109,-21.18 28.351,-28.82 7.985,-6.379 16.563,-12.063 25.617,-16.922 m 1404.583,543.07 0,9.242 c 2.7,1.188 5.23,2.039 7.53,2.571 l 0,-7.071 c -2,-1.031 -4.25,-2.41 -6.72,-4.152 l 0,2.351 c 0,-0.71 -0.02,-1.511 -0.07,-2.41 -0.25,-0.172 -0.49,-0.351 -0.74,-0.531 m -1482.77,14.621 0,9.371 c 2.336,3.098 4.863,5.668 7.535,7.438 l 0,-5.758 c -2.727,-2.691 -5.266,-6.57 -7.535,-11.051"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1742"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1744"
+ d="m 1649.42,315.07 c 6.03,2.379 11.88,5.102 17.54,8.141 10.6,3.289 20.51,8.141 29.49,14.258 -8.09,-6.571 -16.78,-12.43 -25.96,-17.469 -6.78,-2.25 -13.82,-3.918 -21.07,-4.93 m -1298.893,0.008 c -7.234,1.024 -14.261,2.684 -21.027,4.934 -9.129,5.019 -17.766,10.84 -25.809,17.367 8.938,-6.07 18.805,-10.879 29.336,-14.16 5.653,-3.039 11.496,-5.758 17.5,-8.141 M 1731.18,375.5 c 5.21,9.352 9.1,19.52 11.44,30.27 4.35,10.152 7.75,20.82 10.06,31.878 l 0,-3.789 c 0,-6.05 -0.45,-11.988 -1.32,-17.808 -4.96,-14.469 -11.79,-28.082 -20.18,-40.551 m -1462.524,0.27 c -8.328,12.421 -15.105,25.968 -20.043,40.371 -0.859,5.781 -1.304,11.699 -1.304,17.718 l 0,3.762 c 2.312,-11.031 5.699,-21.672 10.046,-31.801 2.317,-10.672 6.161,-20.761 11.301,-30.05 m -21.347,485.089 0,16.422 c 2.171,4.77 4.711,9.27 7.531,13 l 0,-9.371 c -3.059,-6.051 -5.633,-13.211 -7.531,-20.051 m 1497.831,10.172 0,7.071 c 1.98,0.457 3.79,0.679 5.43,0.679 0.74,0 1.44,-0.043 2.11,-0.133 l 0,-5.328 c -0.08,0 -0.17,0 -0.25,0 -1.84,0 -4.29,-0.75 -7.29,-2.289"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1730"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1732"
+ d="m 1633.3,309.641 c 5.49,1.539 10.87,3.359 16.12,5.429 7.25,1.012 14.29,2.68 21.07,4.93 -5.95,-3.27 -12.1,-6.191 -18.45,-8.738 -6.12,-0.992 -12.37,-1.543 -18.74,-1.621 m -1266.667,0 c -6.363,0.089 -12.617,0.648 -18.731,1.64 -6.324,2.547 -12.468,5.469 -18.402,8.731 6.766,-2.25 13.793,-3.91 21.027,-4.934 5.25,-2.078 10.618,-3.887 16.106,-5.437 m 1384.727,106.41 c 0.87,5.82 1.32,11.758 1.32,17.808 l 0,3.789 c 2.34,11.204 3.57,22.813 3.57,34.704 l 0,396.878 c 0,2.61 -1.24,3.989 -3.57,4.09 l 0,5.328 c 3.88,-0.519 6.5,-2.539 7.54,-5.878 l 0,-413.598 c -1.13,-14.981 -4.17,-29.434 -8.86,-43.121 m -1502.747,0.09 c -4.683,13.668 -7.711,28.097 -8.84,43.058 l 0,392.981 c 1.051,7.48 3.723,16.718 7.536,25.101 l 0,-16.422 c -2.282,-8.218 -3.586,-16 -3.586,-20.89 l 0,-367.617 c 0,-11.903 1.234,-23.512 3.586,-34.731 l 0,-3.762 c 0,-6.019 0.445,-11.937 1.304,-17.718"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1718"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1720"
+ d="m 1630.35,305.34 -16.37,0 c 0.34,0.082 0.66,0.172 0.96,0.262 6.24,1 12.37,2.359 18.36,4.039 6.37,0.078 12.62,0.629 18.74,1.621 -5.55,-2.242 -11.25,-4.192 -17.06,-5.852 -1.54,-0.051 -3.08,-0.07 -4.63,-0.07 m -1244.354,0 -16.266,0 c -1.601,0 -3.199,0.031 -4.785,0.082 -5.808,1.656 -11.496,3.617 -17.043,5.859 6.114,-0.992 12.368,-1.551 18.731,-1.64 6.094,-1.711 12.32,-3.09 18.668,-4.11 0.219,-0.07 0.453,-0.133 0.695,-0.191 m 1374.224,153.832 0,413.598 c 0.32,-1.051 0.49,-2.231 0.49,-3.54 l 0,-396.878 c 0,-4.43 -0.17,-8.832 -0.49,-13.18 m -1520.447,0.027 c -0.324,4.34 -0.492,8.731 -0.492,13.153 l 0,373.468 c 0,1.899 0.168,4.051 0.492,6.36 l 0,-392.981"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1706"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1708"
+ d="m 1616.63,301.051 -1233.314,0 c -1.089,0.23 -2.082,0.48 -2.953,0.73 -5.226,0.981 -10.367,2.199 -15.418,3.641 1.586,-0.051 3.184,-0.082 4.785,-0.082 l 16.266,0 c 10.223,-2.629 41.68,-4.039 51.715,-4.039 l 1124.429,0 c 10.04,0 41.29,1.41 51.84,4.039 l 16.37,0 c 1.55,0 3.09,0.019 4.63,0.07 -4.94,-1.398 -9.96,-2.59 -15.07,-3.551 -0.95,-0.277 -2.06,-0.55 -3.28,-0.808"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1694"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1696"
+ d="m 1566.73,296.852 -1133.582,0 c -11.035,0 -37.191,1.457 -49.832,4.199 l 1233.314,0 c -12.84,-2.742 -38.86,-4.199 -49.9,-4.199"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1682"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1684"
+ d="m 1585.09,469.352 -1122.871,0 c -9.492,0 -64.582,5.488 -70.961,14.589 -54.086,29.348 -87.504,280.778 -89.024,355.5 -0.136,6.661 -0.902,13.028 -2.195,18.989 l 0,18.832 c 3.941,-8.813 6.313,-19.172 6.492,-30.371 1.117,-69.231 36.91,-330.301 90.637,-352.313 4.785,-6.828 64.687,-10.949 71.809,-10.949 l 1116.113,0 c 62.98,0 104.13,262.359 106.84,341.25 0.38,11.172 3.34,21.453 8,30.25 l 0,-22.43 c -2.37,-6.98 -3.87,-14.578 -4.22,-22.609 -3.74,-87.602 -44.22,-340.738 -110.62,-340.738"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1670"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1672"
+ d="m 1699.93,832.699 0,22.43 c 2.17,4.101 4.71,7.883 7.53,11.293 l 0,-17.633 c -2.99,-4.879 -5.56,-10.269 -7.53,-16.09 M 300.039,858.43 c -1.687,7.769 -4.277,14.832 -7.535,20.89 l 0,10.559 c 2.894,-3.688 5.437,-7.93 7.535,-12.617 l 0,-18.832"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1658"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1660"
+ d="m 1707.46,848.789 0,17.633 c 2.34,2.808 4.87,5.367 7.54,7.637 l 0,-15.039 c -2.71,-3.079 -5.25,-6.508 -7.54,-10.231 M 292.504,879.32 c -2.223,4.129 -4.758,7.801 -7.531,10.899 l 0,7.371 c 2.703,-2.18 5.226,-4.77 7.531,-7.711 l 0,-10.559"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1646"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1648"
+ d="m 1715,859.02 0,15.039 c 2.41,2.043 4.93,3.851 7.54,5.402 l 0,-13.109 c -2.62,-2.161 -5.14,-4.614 -7.54,-7.332 M 284.973,890.219 c -2.356,2.64 -4.879,4.871 -7.535,6.652 l 0,5.508 c 2.628,-1.25 5.148,-2.859 7.535,-4.789 l 0,-7.371"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1634"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1636"
+ d="m 1722.54,866.352 0,13.109 c 2.09,1.238 4.24,2.32 6.42,3.211 0.37,0.156 0.74,0.308 1.11,0.449 l 0,-11.492 c -0.43,-0.258 -0.86,-0.52 -1.3,-0.789 -2.11,-1.309 -4.2,-2.809 -6.23,-4.488 M 277.438,896.871 c -2.274,1.52 -4.641,2.699 -7.075,3.508 -0.152,0 -0.304,0 -0.457,-0.008 l 0,4.449 c 0.153,0.012 0.305,0.012 0.457,0.012 2.422,-0.531 4.789,-1.352 7.075,-2.453 l 0,-5.508"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1622"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1624"
+ d="m 1730.07,871.629 0,11.492 c 2.61,1.02 5.13,1.789 7.54,2.34 l 0,-9.93 c -2.38,-1.043 -4.9,-2.34 -7.54,-3.902 m -1467.695,26.09 0,5.269 c 2.426,1.121 4.945,1.774 7.531,1.832 l 0,-4.449 c -2.601,-0.101 -5.125,-1.051 -7.531,-2.652"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1610"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1612"
+ d="m 303.691,337.379 c -14.48,9.84 -26.527,23.012 -35.035,38.391 9.715,-14.489 21.547,-27.442 35.035,-38.391 m 1392.759,0.09 c 13.36,10.871 25.08,23.691 34.73,38.031 -8.46,-15.219 -20.4,-28.25 -34.73,-38.031 m 41.16,538.062 0,9.93 c 2.65,0.598 5.17,0.918 7.53,0.988 l 0,-8.347 c -2.3,-0.532 -4.83,-1.383 -7.53,-2.571 m -1482.77,14.75 0,7.547 c 2.379,2.184 4.898,3.953 7.535,5.16 l 0,-5.269 c -2.672,-1.77 -5.199,-4.34 -7.535,-7.438"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1598"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1600"
+ d="m 1670.49,320 c 9.18,5.039 17.87,10.898 25.96,17.469 14.33,9.781 26.27,22.812 34.73,38.031 8.39,12.469 15.22,26.082 20.18,40.551 -1.65,-11.012 -4.8,-21.539 -9.23,-31.371 -10.78,-19.039 -24.95,-35.91 -41.67,-49.77 -9.16,-6.289 -19.23,-11.34 -29.97,-14.91 M 329.5,320.012 c -10.676,3.547 -20.699,8.57 -29.812,14.808 -16.864,13.95 -31.141,30.969 -41.965,50.18 -4.375,9.762 -7.481,20.211 -9.11,31.141 4.938,-14.403 11.715,-27.95 20.043,-40.371 8.508,-15.379 20.555,-28.551 35.035,-38.391 8.043,-6.527 16.68,-12.348 25.809,-17.367 m -82.191,557.269 0,11.617 c 2.281,3.383 4.808,6.422 7.531,8.93 l 0,-7.547 c -2.82,-3.73 -5.36,-8.23 -7.531,-13 m 1497.831,0.821 0,8.347 c 0.3,0 0.59,0.012 0.88,0.012 2.41,0 4.64,-0.281 6.66,-0.813 l 0,-7 c -0.67,0.09 -1.37,0.133 -2.11,0.133 -1.64,0 -3.45,-0.222 -5.43,-0.679"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1586"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1588"
+ d="m 1652.04,311.262 c 6.35,2.547 12.5,5.468 18.45,8.738 10.74,3.57 20.81,8.621 29.97,14.91 -8.1,-6.711 -16.8,-12.719 -26.01,-17.922 -7.2,-2.558 -14.69,-4.488 -22.41,-5.726 m -1304.138,0.019 c -7.703,1.239 -15.172,3.168 -22.359,5.719 -9.145,5.18 -17.801,11.148 -25.855,17.82 9.113,-6.238 19.136,-11.261 29.812,-14.808 5.934,-3.262 12.078,-6.184 18.402,-8.731 M 1742.13,384.68 c 4.43,9.832 7.58,20.359 9.23,31.371 4.69,13.687 7.73,28.14 8.86,43.121 l 0,-20.832 c 0,-3.078 -0.11,-6.121 -0.33,-9.141 -3.92,-15.769 -9.95,-30.711 -17.76,-44.519 M 257.723,385 c -7.754,13.762 -13.735,28.629 -17.637,44.328 -0.207,2.981 -0.313,5.981 -0.313,9.012 l 0,20.859 c 1.129,-14.961 4.157,-29.39 8.84,-43.058 1.629,-10.93 4.735,-21.379 9.11,-31.141 m -17.95,467.18 0,22.242 c 2.008,5.078 4.559,10.058 7.536,14.476 l 0,-11.617 c -3.813,-8.383 -6.485,-17.621 -7.536,-25.101 m 1520.447,20.59 c -1.04,3.339 -3.66,5.359 -7.54,5.878 l 0,7 c 3,-0.789 5.54,-2.148 7.54,-4.007 l 0,-8.871"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1574"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1576"
+ d="m 1634.98,305.41 c 5.81,1.66 11.51,3.61 17.06,5.852 7.72,1.238 15.21,3.168 22.41,5.726 -6.19,-3.508 -12.62,-6.648 -19.25,-9.398 -6.59,-1.211 -13.34,-1.949 -20.22,-2.18 m -1270.035,0.012 c -6.871,0.238 -13.621,0.976 -20.199,2.187 -6.613,2.75 -13.016,5.891 -19.203,9.391 7.187,-2.551 14.656,-4.48 22.359,-5.719 5.547,-2.242 11.235,-4.203 17.043,-5.859 M 1759.89,429.199 c 0.22,3.02 0.33,6.063 0.33,9.141 l 0,20.832 c 0.32,4.348 0.49,8.75 0.49,13.18 l 0,396.878 c 0,1.309 -0.17,2.489 -0.49,3.54 l 0,8.871 c 3.17,-2.95 4.95,-7.172 4.95,-12.411 l 0,-396.878 c 0,-14.872 -1.83,-29.332 -5.28,-43.153 m -1519.804,0.129 c -3.426,13.781 -5.242,28.203 -5.242,43.024 l 0,379.32 c 0,6.629 1.797,14.808 4.929,22.75 l 0,-22.242 c -0.324,-2.309 -0.492,-4.461 -0.492,-6.36 l 0,-373.468 c 0,-4.422 0.168,-8.813 0.492,-13.153 l 0,-20.859 c 0,-3.031 0.106,-6.031 0.313,-9.012"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1562"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1564"
+ d="m 1629.14,301.051 -12.51,0 c 1.22,0.258 2.33,0.531 3.28,0.808 5.11,0.961 10.13,2.153 15.07,3.551 6.88,0.231 13.63,0.969 20.22,2.18 -5.82,-2.41 -11.8,-4.531 -17.92,-6.32 -2.69,-0.149 -5.41,-0.219 -8.14,-0.219 m -1245.824,0 -12.367,0 c -2.789,0 -5.554,0.078 -8.308,0.23 -6.106,1.797 -12.079,3.91 -17.895,6.328 6.578,-1.211 13.328,-1.949 20.199,-2.187 5.051,-1.442 10.192,-2.66 15.418,-3.641 0.871,-0.25 1.864,-0.5 2.953,-0.73"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1550"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1552"
+ d="m 1619.26,296.762 -1238.576,0 c -1.938,0.398 -3.704,0.828 -5.254,1.277 -4.321,0.922 -8.59,2.012 -12.789,3.242 2.754,-0.152 5.519,-0.23 8.308,-0.23 l 12.367,0 c 12.641,-2.742 38.797,-4.199 49.832,-4.199 l 1133.582,0 c 11.04,0 37.06,1.457 49.9,4.199 l 12.51,0 c 2.73,0 5.45,0.07 8.14,0.219 -4.07,-1.192 -8.2,-2.239 -12.39,-3.141 -1.65,-0.488 -3.55,-0.938 -5.63,-1.367"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1538"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1540"
+ d="m 1617.32,296.379 -1234.707,0 c -0.66,0.121 -1.301,0.25 -1.929,0.383 l 1238.576,0 c -0.63,-0.133 -1.28,-0.262 -1.94,-0.383"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1526"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1528"
+ d="m 1585.09,483.629 -1116.113,0 c -7.122,0 -67.024,4.121 -71.809,10.949 -53.727,22.012 -89.52,283.082 -90.637,352.313 -0.179,11.199 -2.551,21.558 -6.492,30.371 l 0,12.609 c 6.598,-9.562 10.66,-21.922 10.789,-35.531 0.852,-63.738 38.887,-334.449 92.254,-349.129 3.191,-4.539 67.906,-7.289 72.652,-7.289 l 1109.356,0 c 59.57,0 101.32,271.566 103.05,341.738 0.33,13.281 4.79,25.281 11.79,34.731 l 0,-19.262 c -4.66,-8.797 -7.62,-19.078 -8,-30.25 -2.71,-78.891 -43.86,-341.25 -106.84,-341.25"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1514"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1516"
+ d="m 1699.93,855.129 0,19.262 c 2.26,3.058 4.79,5.859 7.53,8.339 l 0,-16.308 c -2.82,-3.41 -5.36,-7.192 -7.53,-11.293 M 300.039,877.262 c -2.098,4.687 -4.641,8.929 -7.535,12.617 l 0,8.691 c 2.766,-2.539 5.297,-5.461 7.535,-8.699 l 0,-12.609"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1502"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1504"
+ d="m 1707.46,866.422 0,16.308 c 2.37,2.149 4.89,4.059 7.54,5.719 l 0,-14.39 c -2.67,-2.27 -5.2,-4.829 -7.54,-7.637 M 292.504,889.879 c -2.305,2.941 -4.828,5.531 -7.531,7.711 l 0,6.59 c 2.66,-1.571 5.179,-3.45 7.531,-5.61 l 0,-8.691"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1490"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1492"
+ d="m 1715,874.059 0,14.39 c 2.42,1.52 4.94,2.821 7.54,3.891 l 0,-12.879 c -2.61,-1.551 -5.13,-3.359 -7.54,-5.402 M 284.973,897.59 c -2.387,1.93 -4.907,3.539 -7.535,4.789 l 0,5.262 c 2.609,-0.879 5.128,-2.039 7.535,-3.461 l 0,-6.59"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1478"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1480"
+ d="m 1722.54,879.461 0,12.879 c 2.15,0.89 4.36,1.621 6.6,2.172 0.31,0.078 0.62,0.148 0.93,0.218 l 0,-11.609 c -0.37,-0.141 -0.74,-0.293 -1.11,-0.449 -2.18,-0.891 -4.33,-1.973 -6.42,-3.211 M 277.438,902.379 c -2.286,1.101 -4.653,1.922 -7.075,2.453 -0.152,0 -0.304,0 -0.457,-0.012 l 0,4.461 c 0.153,0 0.305,0 0.457,0 2.414,-0.312 4.778,-0.871 7.075,-1.64 l 0,-5.262"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1466"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1468"
+ d="m 1730.07,883.121 0,11.609 c 2.59,0.59 5.11,0.95 7.54,1.11 l 0,-10.379 c -2.41,-0.551 -4.93,-1.32 -7.54,-2.34 m -1467.695,19.867 0,5 c 2.437,0.793 4.953,1.242 7.531,1.293 l 0,-4.461 c -2.586,-0.058 -5.105,-0.711 -7.531,-1.832"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1454"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1456"
+ d="m 1737.61,885.461 0,10.379 c 0.92,0.058 1.83,0.09 2.73,0.09 1.65,0 3.25,-0.102 4.8,-0.289 l 0,-9.192 c -2.36,-0.07 -4.88,-0.39 -7.53,-0.988 m -1482.77,12.367 0,6.5 c 2.402,1.563 4.922,2.813 7.535,3.66 l 0,-5 c -2.637,-1.207 -5.156,-2.976 -7.535,-5.16"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1442"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1444"
+ d="m 299.688,334.82 c -18.227,12.469 -32.848,29.828 -41.965,50.18 10.824,-19.211 25.101,-36.23 41.965,-50.18 m 1400.772,0.09 c 16.72,13.86 30.89,30.731 41.67,49.77 -9.1,-20.16 -23.61,-37.371 -41.67,-49.77 m 52.22,550.738 c -2.02,0.532 -4.25,0.813 -6.66,0.813 -0.29,0 -0.58,-0.012 -0.88,-0.012 l 0,9.192 c 2.68,-0.34 5.21,-0.961 7.54,-1.832 l 0,-8.161 m -1505.371,3.25 0,9.122 c 2.336,2.429 4.863,4.57 7.531,6.308 l 0,-6.5 c -2.723,-2.508 -5.25,-5.547 -7.531,-8.93"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1430"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1432"
+ d="m 1674.45,316.988 c 9.21,5.203 17.91,11.211 26.01,17.922 18.06,12.399 32.57,29.61 41.67,49.77 7.81,13.808 13.84,28.75 17.76,44.519 -0.79,-11.199 -3.02,-22.019 -6.5,-32.25 -11.31,-24.961 -28.05,-46.949 -48.69,-64.437 -9.27,-6.442 -19.43,-11.684 -30.25,-15.524 M 325.543,317 c -10.754,3.82 -20.859,9.031 -30.094,15.41 -20.793,17.602 -37.64,39.762 -48.976,64.922 -3.426,10.168 -5.614,20.887 -6.387,31.996 3.902,-15.699 9.883,-30.566 17.637,-44.328 9.117,-20.352 23.738,-37.711 41.965,-50.18 8.054,-6.672 16.71,-12.64 25.855,-17.82 m -85.77,557.422 0,13.758 c 2.204,3.59 4.739,6.929 7.536,9.84 l 0,-9.122 c -2.977,-4.418 -5.528,-9.398 -7.536,-14.476 m 1520.447,7.219 c -2,1.859 -4.54,3.218 -7.54,4.007 l 0,8.161 c 2.81,-1.047 5.34,-2.469 7.54,-4.219 l 0,-7.949"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1418"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1420"
+ d="m 1655.2,307.59 c 6.63,2.75 13.06,5.89 19.25,9.398 10.82,3.84 20.98,9.082 30.25,15.524 -8.06,-6.832 -16.71,-12.973 -25.86,-18.332 -7.59,-2.871 -15.49,-5.09 -23.64,-6.59 m -1310.454,0.019 c -8.133,1.5 -16.012,3.719 -23.574,6.582 -9.106,5.34 -17.703,11.438 -25.723,18.219 9.235,-6.379 19.34,-11.59 30.094,-15.41 6.187,-3.5 12.59,-6.641 19.203,-9.391 m 1408.644,89.34 c 3.48,10.231 5.71,21.051 6.5,32.25 3.45,13.821 5.28,28.281 5.28,43.153 l 0,396.878 c 0,5.239 -1.78,9.461 -4.95,12.411 l 0,7.949 c 3.35,-2.668 5.93,-6.11 7.53,-10.149 l 0,-433.332 c -2.49,-17.281 -7.39,-33.777 -14.36,-49.16 m -1506.917,0.383 c -6.911,15.348 -11.774,31.797 -14.231,49.02 l 0,424.339 c 1.602,6.008 4.188,12.039 7.531,17.489 l 0,-13.758 c -3.132,-7.942 -4.929,-16.121 -4.929,-22.75 l 0,-379.32 c 0,-14.821 1.816,-29.243 5.242,-43.024 0.773,-11.109 2.961,-21.828 6.387,-31.996"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1406"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1408"
+ d="m 1637.28,301.27 c 6.12,1.789 12.1,3.91 17.92,6.32 8.15,1.5 16.05,3.719 23.64,6.59 -6.4,-3.75 -13.04,-7.121 -19.9,-10.071 -7.05,-1.468 -14.28,-2.429 -21.66,-2.839 m -1274.639,0.011 c -7.368,0.418 -14.586,1.379 -21.621,2.848 -6.84,2.949 -13.469,6.32 -19.848,10.062 7.562,-2.863 15.441,-5.082 23.574,-6.582 5.816,-2.418 11.789,-4.531 17.895,-6.328 m 1405.109,144.828 0,433.332 c 1.22,-3.07 1.88,-6.5 1.88,-10.211 l 0,-396.878 c 0,-8.911 -0.64,-17.672 -1.88,-26.243 m -1535.508,0.243 c -1.211,8.488 -1.84,17.179 -1.84,26 l 0,385.168 c 0,4.21 0.645,8.679 1.84,13.171 l 0,-424.339"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1394"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1396"
+ d="m 1627.92,296.762 -8.66,0 c 2.08,0.429 3.98,0.879 5.63,1.367 4.19,0.902 8.32,1.949 12.39,3.141 7.38,0.41 14.61,1.371 21.66,2.839 -6.06,-2.621 -12.29,-4.91 -18.67,-6.859 -4.07,-0.328 -8.19,-0.488 -12.35,-0.488 m -1247.236,0 -8.512,0 c -4.207,0 -8.387,0.168 -12.512,0.5 -6.371,1.949 -12.586,4.25 -18.64,6.867 7.035,-1.469 14.253,-2.43 21.621,-2.848 4.199,-1.23 8.468,-2.32 12.789,-3.242 1.55,-0.449 3.316,-0.879 5.254,-1.277"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1382"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1384"
+ d="m 1637.35,296.379 -20.03,0 c 0.66,0.121 1.31,0.25 1.94,0.383 l 8.66,0 c 4.16,0 8.28,0.16 12.35,0.488 -0.97,-0.301 -1.94,-0.59 -2.92,-0.871 m -1254.737,0 -19.996,0 c -0.988,0.281 -1.976,0.582 -2.957,0.883 4.125,-0.332 8.305,-0.5 12.512,-0.5 l 8.512,0 c 0.628,-0.133 1.269,-0.262 1.929,-0.383"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1370"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1372"
+ d="m 1585.09,497.922 -1109.356,0 c -4.746,0 -69.461,2.75 -72.652,7.289 -53.367,14.68 -91.402,285.391 -92.254,349.129 -0.129,13.609 -4.191,25.969 -10.789,35.531 l 0,9.93 c 9.207,-9.473 15.016,-22.961 15.09,-38.02 0.422,-58.242 40.859,-338.59 93.867,-345.929 1.594,-2.27 71.125,-3.641 73.496,-3.641 l 1102.598,0 c 56.16,0 98.44,280.777 99.27,342.238 0.2,14.789 6.21,27.992 15.57,37.422 l 0,-17.48 c -7,-9.45 -11.46,-21.45 -11.79,-34.731 -1.73,-70.172 -43.48,-341.738 -103.05,-341.738"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1358"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1360"
+ d="m 1699.93,874.391 0,17.48 c 2.32,2.34 4.84,4.438 7.53,6.277 l 0,-15.418 c -2.74,-2.48 -5.27,-5.281 -7.53,-8.339 m -1399.891,15.48 c -2.238,3.238 -4.769,6.16 -7.535,8.699 l 0,7.551 c 2.703,-1.832 5.223,-3.949 7.535,-6.32 l 0,-9.93"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1346"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1348"
+ d="m 1707.46,882.73 0,15.418 c 2.39,1.633 4.91,3.051 7.54,4.243 l 0,-13.942 c -2.65,-1.66 -5.17,-3.57 -7.54,-5.719 M 292.504,898.57 c -2.352,2.16 -4.871,4.039 -7.531,5.61 l 0,6.082 c 2.629,-1.141 5.152,-2.524 7.531,-4.141 l 0,-7.551"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1334"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1336"
+ d="m 1715,888.449 0,13.942 c 2.43,1.097 4.95,2 7.54,2.679 l 0,-12.73 c -2.6,-1.07 -5.12,-2.371 -7.54,-3.891 M 284.973,904.18 c -2.407,1.422 -4.926,2.582 -7.535,3.461 l 0,5.078 c 2.593,-0.59 5.113,-1.418 7.535,-2.457 l 0,-6.082"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1322"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1324"
+ d="m 1722.54,892.34 0,12.73 c 2.21,0.59 4.48,1.02 6.78,1.282 0.25,0.019 0.5,0.046 0.75,0.07 l 0,-11.692 c -0.31,-0.07 -0.62,-0.14 -0.93,-0.218 -2.24,-0.551 -4.45,-1.282 -6.6,-2.172 M 277.438,907.641 c -2.297,0.769 -4.661,1.328 -7.075,1.64 -0.152,0 -0.304,0 -0.457,0 l 0,4.449 c 0.153,0 0.305,0 0.457,0 2.41,-0.14 4.774,-0.48 7.075,-1.011 l 0,-5.078"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1310"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1312"
+ d="m 1730.07,894.73 0,11.692 c 1.57,0.148 3.11,0.226 4.64,0.226 0.97,0 1.94,-0.027 2.9,-0.089 l 0,-10.719 c -2.43,-0.16 -4.95,-0.52 -7.54,-1.11 m -1467.695,13.258 0,4.821 c 2.445,0.57 4.965,0.882 7.531,0.921 l 0,-4.449 c -2.578,-0.051 -5.094,-0.5 -7.531,-1.293"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1298"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1300"
+ d="m 1745.14,895.641 c -1.55,0.187 -3.15,0.289 -4.8,0.289 -0.9,0 -1.81,-0.032 -2.73,-0.09 l 0,10.719 c 2.6,-0.168 5.12,-0.547 7.53,-1.129 l 0,-9.789 m -1490.3,8.687 0,5.871 c 2.418,1.133 4.937,2.012 7.535,2.61 l 0,-4.821 c -2.613,-0.847 -5.133,-2.097 -7.535,-3.66"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1286"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1288"
+ d="m 1752.68,893.809 c -2.33,0.871 -4.86,1.492 -7.54,1.832 l 0,9.789 c 2.65,-0.641 5.17,-1.532 7.54,-2.629 l 0,-8.992 m -1505.371,4.211 0,7.652 c 2.375,1.769 4.894,3.297 7.531,4.527 l 0,-5.871 c -2.668,-1.738 -5.195,-3.879 -7.531,-6.308"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1274"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1276"
+ d="m 295.449,332.41 c -22.629,15.66 -40.023,38.371 -48.976,64.922 11.336,-25.16 28.183,-47.32 48.976,-64.922 m 1409.251,0.102 c 20.64,17.488 37.38,39.476 48.69,64.437 -8.97,-26.34 -26.25,-48.871 -48.69,-64.437 M 239.773,888.18 l 0,10.539 c 2.293,2.59 4.821,4.929 7.536,6.953 l 0,-7.652 c -2.797,-2.911 -5.332,-6.25 -7.536,-9.84 m 1520.447,1.41 c -2.2,1.75 -4.73,3.172 -7.54,4.219 l 0,8.992 c 2.72,-1.262 5.24,-2.801 7.54,-4.602 l 0,-8.609"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1262"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1264"
+ d="m 1678.84,314.18 c 9.15,5.359 17.8,11.5 25.86,18.332 22.44,15.566 39.72,38.097 48.69,64.437 6.97,15.383 11.87,31.879 14.36,49.16 l 0,-3.3 c 0,-10.207 -1.12,-20.18 -3.24,-29.77 -10.79,-32.391 -30.15,-60.891 -55.38,-82.801 -9.32,-6.547 -19.48,-11.968 -30.29,-16.058 m -1357.668,0.011 c -10.746,4.071 -20.86,9.45 -30.133,15.95 -25.406,22.019 -44.883,50.738 -55.656,83.379 -2.055,9.441 -3.141,19.25 -3.141,29.289 l 0,3.543 c 2.457,-17.223 7.32,-33.672 14.231,-49.02 8.953,-26.551 26.347,-49.262 48.976,-64.922 8.02,-6.781 16.617,-12.879 25.723,-18.219 m -88.93,556.5 0,17.098 c 2.078,3.941 4.617,7.633 7.531,10.93 l 0,-10.539 c -3.343,-5.45 -5.929,-11.481 -7.531,-17.489 m 1535.508,8.75 c -1.6,4.039 -4.18,7.481 -7.53,10.149 l 0,8.609 c 2.91,-2.301 5.45,-5 7.53,-8.039 l 0,-10.719"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1250"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1252"
+ d="m 1658.94,304.109 c 6.86,2.95 13.5,6.321 19.9,10.071 10.81,4.09 20.97,9.511 30.29,16.058 -7.95,-6.898 -16.48,-13.136 -25.51,-18.648 -7.91,-3.192 -16.16,-5.711 -24.68,-7.481 m -1317.92,0.02 c -8.497,1.769 -16.727,4.281 -24.614,7.473 -8.972,5.468 -17.457,11.679 -25.367,18.539 9.273,-6.5 19.387,-11.879 30.133,-15.95 6.379,-3.742 13.008,-7.113 19.848,-10.062 m 1423.49,108.91 c 2.12,9.59 3.24,19.563 3.24,29.77 l 0,3.3 c 1.24,8.571 1.88,17.332 1.88,26.243 l 0,396.878 c 0,3.711 -0.66,7.141 -1.88,10.211 l 0,10.719 c 4.03,-5.879 6.33,-13.031 6.33,-20.93 l 0,-396.878 c 0,-20.711 -3.36,-40.653 -9.57,-59.313 M 235.383,413.52 c -6.11,18.519 -9.422,38.3 -9.422,58.832 l 0,391.027 c 0,8.359 2.293,16.84 6.281,24.41 l 0,-17.098 c -1.195,-4.492 -1.84,-8.961 -1.84,-13.171 l 0,-385.168 c 0,-8.821 0.629,-17.512 1.84,-26 l 0,-3.543 c 0,-10.039 1.086,-19.848 3.141,-29.289"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1238"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1240"
+ d="m 1640.27,297.25 c 6.38,1.949 12.61,4.238 18.67,6.859 8.52,1.77 16.77,4.289 24.68,7.481 -6.54,-3.988 -13.34,-7.59 -20.37,-10.762 -7.46,-1.746 -15.14,-2.957 -22.98,-3.578 m -1280.61,0.012 c -7.824,0.629 -15.48,1.84 -22.933,3.59 -7.008,3.168 -13.797,6.769 -20.321,10.75 7.887,-3.192 16.117,-5.704 24.614,-7.473 6.054,-2.617 12.269,-4.918 18.64,-6.867"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1226"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1228"
+ d="m 1652.53,296.379 -15.18,0 c 0.98,0.281 1.95,0.57 2.92,0.871 7.84,0.621 15.52,1.832 22.98,3.578 -3.52,-1.59 -7.09,-3.078 -10.72,-4.449 m -1289.913,0 -15.14,0 c -3.641,1.383 -7.219,2.871 -10.75,4.473 7.453,-1.75 15.109,-2.961 22.933,-3.59 0.981,-0.301 1.969,-0.602 2.957,-0.883"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1214"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1216"
+ d="m 1585.09,512.211 -1102.598,0 c -2.371,0 -71.902,1.371 -73.496,3.641 -53.008,7.339 -93.445,287.687 -93.867,345.929 -0.074,15.059 -5.883,28.547 -15.09,38.02 l 0,8.461 c 11.797,-8.934 19.387,-23.082 19.387,-39.032 0,-52.75 42.836,-342.742 95.48,-342.742 l 1170.184,0 c 52.74,0 95.48,289.992 95.48,342.742 0,15.911 7.62,30.032 19.36,38.961 l 0,-16.32 c -9.36,-9.43 -15.37,-22.633 -15.57,-37.422 -0.83,-61.461 -43.11,-342.238 -99.27,-342.238"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1202"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1204"
+ d="m 1699.93,891.871 0,16.32 c 2.35,1.789 4.88,3.379 7.53,4.731 l 0,-14.774 c -2.69,-1.839 -5.21,-3.937 -7.53,-6.277 m -1399.891,7.93 c -2.312,2.371 -4.832,4.488 -7.535,6.32 l 0,6.828 c 2.66,-1.34 5.18,-2.91 7.535,-4.687 l 0,-8.461"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1190"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1192"
+ d="m 1707.46,898.148 0,14.774 c 2.41,1.219 4.93,2.25 7.54,3.058 l 0,-13.589 c -2.63,-1.192 -5.15,-2.61 -7.54,-4.243 m -1414.956,7.973 c -2.379,1.617 -4.902,3 -7.531,4.141 l 0,5.726 c 2.613,-0.808 5.129,-1.828 7.531,-3.039 l 0,-6.828"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1178"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1180"
+ d="m 1715,902.391 0,13.589 c 2.44,0.758 4.95,1.329 7.54,1.7 l 0,-12.61 c -2.59,-0.679 -5.11,-1.582 -7.54,-2.679 m -1430.027,7.871 c -2.422,1.039 -4.942,1.867 -7.535,2.457 l 0,4.961 c 2.585,-0.371 5.101,-0.942 7.535,-1.692 l 0,-5.726"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1166"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1168"
+ d="m 1722.54,905.07 0,12.61 c 2.28,0.332 4.6,0.5 6.97,0.5 l 0,0 c 0.19,0 0.38,0 0.56,0 l 0,-11.758 c -0.25,-0.024 -0.5,-0.051 -0.75,-0.07 -2.3,-0.262 -4.57,-0.692 -6.78,-1.282 m -1445.102,7.649 c -2.301,0.531 -4.665,0.871 -7.075,1.011 -0.152,0 -0.304,0 -0.457,0 l 0,4.45 c 0.153,0 0.305,0 0.457,0 l 0,0 c 2.403,0 4.766,-0.168 7.075,-0.5 l 0,-4.961"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1154"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1156"
+ d="m 1730.07,906.422 0,11.758 c 2.57,-0.032 5.08,-0.258 7.54,-0.66 l 0,-10.961 c -0.96,0.062 -1.93,0.089 -2.9,0.089 -1.53,0 -3.07,-0.078 -4.64,-0.226 m -1467.695,6.387 0,4.722 c 2.453,0.399 4.969,0.617 7.531,0.649 l 0,-4.45 c -2.566,-0.039 -5.086,-0.351 -7.531,-0.921"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1142"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1144"
+ d="m 1745.14,905.43 c -2.41,0.582 -4.93,0.961 -7.53,1.129 l 0,10.961 c 2.58,-0.43 5.1,-1.051 7.53,-1.872 l 0,-10.218 m -1490.3,4.769 0,5.461 c 2.433,0.82 4.949,1.442 7.535,1.871 l 0,-4.722 c -2.598,-0.598 -5.117,-1.477 -7.535,-2.61"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1130"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1132"
+ d="m 1752.68,902.801 c -2.37,1.097 -4.89,1.988 -7.54,2.629 l 0,10.218 c 2.62,-0.867 5.14,-1.957 7.54,-3.238 l 0,-9.609 m -1505.371,2.871 0,6.726 c 2.398,1.293 4.914,2.383 7.531,3.262 l 0,-5.461 c -2.637,-1.23 -5.156,-2.758 -7.531,-4.527"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1118"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1120"
+ d="m 1760.22,898.199 c -2.3,1.801 -4.82,3.34 -7.54,4.602 l 0,9.609 c 2.67,-1.43 5.19,-3.101 7.54,-4.98 l 0,-9.231 m -1520.447,0.52 0,8.691 c 2.344,1.879 4.868,3.559 7.536,4.988 l 0,-6.726 c -2.715,-2.024 -5.243,-4.363 -7.536,-6.953"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1106"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1108"
+ d="m 291.039,330.141 c -27.859,19.507 -48.18,49.07 -55.656,83.379 10.773,-32.641 30.25,-61.36 55.656,-83.379 m 1418.091,0.097 c 25.23,21.91 44.59,50.41 55.38,82.801 -7.55,-34.027 -27.75,-63.379 -55.38,-82.801 m -1476.888,557.551 0,12.063 c 2.231,2.789 4.754,5.32 7.531,7.558 l 0,-8.691 c -2.914,-3.297 -5.453,-6.989 -7.531,-10.93 m 1535.508,2.371 c -2.08,3.039 -4.62,5.738 -7.53,8.039 l 0,9.231 c 2.77,-2.219 5.3,-4.739 7.53,-7.508 l 0,-9.762"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1094"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1096"
+ d="m 1683.62,311.59 c 9.03,5.512 17.56,11.75 25.51,18.648 27.63,19.422 47.83,48.774 55.38,82.801 6.21,18.66 9.57,38.602 9.57,59.313 l 0,396.878 c 0,7.899 -2.3,15.051 -6.33,20.93 l 0,9.762 c 3.15,-3.91 5.71,-8.32 7.54,-13.082 l 0,-439.551 c 0,-4.551 -0.21,-9.059 -0.62,-13.508 -8.47,-41.609 -30.38,-78.429 -60.98,-105.703 -9.28,-6.609 -19.36,-12.168 -30.07,-16.488 m -1367.214,0.012 c -10.644,4.289 -20.672,9.796 -29.91,16.359 -30.805,27.398 -52.824,64.48 -61.223,106.398 -0.371,4.262 -0.562,8.582 -0.562,12.93 l 0,439.383 c 1.824,4.808 4.379,9.238 7.531,13.18 l 0,-12.063 c -3.988,-7.57 -6.281,-16.051 -6.281,-24.41 l 0,-391.027 c 0,-20.532 3.312,-40.313 9.422,-58.832 7.476,-34.309 27.797,-63.872 55.656,-83.379 7.91,-6.86 16.395,-13.071 25.367,-18.539"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1082"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1084"
+ d="m 1663.25,300.828 c 7.03,3.172 13.83,6.774 20.37,10.762 10.71,4.32 20.79,9.879 30.07,16.488 -7.77,-6.93 -16.12,-13.238 -24.94,-18.859 -8.16,-3.508 -16.69,-6.328 -25.5,-8.391 m -1326.523,0.024 c -8.782,2.058 -17.278,4.867 -25.418,8.359 -8.778,5.59 -17.071,11.859 -24.813,18.75 9.238,-6.563 19.266,-12.07 29.91,-16.359 6.524,-3.981 13.313,-7.582 20.321,-10.75 M 1774.67,433.781 c 0.41,4.449 0.62,8.957 0.62,13.508 l 0,439.551 c 2.1,-5.461 3.25,-11.399 3.25,-17.61 l 0,-396.878 c 0,-13.211 -1.33,-26.102 -3.87,-38.571 m -1549.397,0.578 c -2.461,12.289 -3.75,24.993 -3.75,37.993 l 0,396.878 c 0,6.149 1.125,12.032 3.188,17.442 l 0,-439.383 c 0,-4.348 0.191,-8.668 0.562,-12.93"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ id="clipPath1070"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1072"
+ d="m 1665.11,296.379 -12.58,0 c 3.63,1.371 7.2,2.859 10.72,4.449 8.81,2.063 17.34,4.883 25.5,8.391 -7.55,-4.809 -15.44,-9.098 -23.64,-12.84 m -1317.633,0 -12.543,0 c -8.2,3.73 -16.086,8.031 -23.625,12.832 8.14,-3.492 16.636,-6.301 25.418,-8.359 3.531,-1.602 7.109,-3.09 10.75,-4.473"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient1054"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop1056"
+ offset="0"
+ style="stop-opacity:1;stop-color:#ededed" />
+ <stop
+ id="stop1058"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d4d3d2" />
+ <stop
+ id="stop1060"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d4d3d2" />
+ <stop
+ id="stop1062"
+ offset="1"
+ style="stop-opacity:1;stop-color:#e7e8e6" />
+ </linearGradient>
+ <clipPath
+ id="clipPath1050"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1052"
+ d="m 1571.32,292.398 -1142.73,0 c -11.457,0 -32.172,1.383 -45.977,3.981 l 1234.707,0 c -13.91,-2.598 -34.53,-3.981 -46,-3.981"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient1034"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop1036"
+ offset="0"
+ style="stop-opacity:1;stop-color:#ececec" />
+ <stop
+ id="stop1038"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d3d3d2" />
+ <stop
+ id="stop1040"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d3d3d2" />
+ <stop
+ id="stop1042"
+ offset="1"
+ style="stop-opacity:1;stop-color:#e7e8e6" />
+ </linearGradient>
+ <clipPath
+ id="clipPath1030"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1032"
+ d="m 1604.44,289.719 -1208.948,0 c -9.25,1.07 -18.258,2.601 -25,4.582 -2.644,0.629 -5.273,1.328 -7.875,2.078 l 19.996,0 c 13.805,-2.598 34.52,-3.981 45.977,-3.981 l 1142.73,0 c 11.47,0 32.09,1.383 46,3.981 l 20.03,0 c -2.48,-0.707 -4.97,-1.367 -7.49,-1.981 -6.84,-2.027 -16.02,-3.597 -25.42,-4.679"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient1014"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop1016"
+ offset="0"
+ style="stop-opacity:1;stop-color:#e9e9e8" />
+ <stop
+ id="stop1018"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#cfcecd" />
+ <stop
+ id="stop1020"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#cfcecd" />
+ <stop
+ id="stop1022"
+ offset="1"
+ style="stop-opacity:1;stop-color:#e3e3e1" />
+ </linearGradient>
+ <clipPath
+ id="clipPath1010"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path1012"
+ d="m 1575.91,287.949 -1151.883,0 c -8.043,0 -18.433,0.61 -28.535,1.77 l 1208.948,0 c -10.11,-1.16 -20.48,-1.77 -28.53,-1.77"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient994"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop996"
+ offset="0"
+ style="stop-opacity:1;stop-color:#ececec" />
+ <stop
+ id="stop998"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d3d0d1" />
+ <stop
+ id="stop1000"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d3d0d1" />
+ <stop
+ id="stop1002"
+ offset="1"
+ style="stop-opacity:1;stop-color:#e6e6e5" />
+ </linearGradient>
+ <clipPath
+ id="clipPath990"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path992"
+ d="m 1629.14,289.719 -24.7,0 c 9.4,1.082 18.58,2.652 25.42,4.679 2.52,0.614 5.01,1.274 7.49,1.981 l 15.18,0 c -5.77,-2.188 -11.67,-4.098 -17.69,-5.719 -1.08,-0.308 -2.18,-0.621 -3.31,-0.922 -0.8,-0.008 -1.59,-0.019 -2.39,-0.019 m -1233.648,0 -24.543,0 c -0.824,0 -1.648,0.011 -2.472,0.019 -0.993,0.262 -1.965,0.532 -2.918,0.813 -6.157,1.64 -12.188,3.59 -18.082,5.828 l 15.14,0 c 2.602,-0.75 5.231,-1.449 7.875,-2.078 6.742,-1.981 15.75,-3.512 25,-4.582"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient974"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop976"
+ offset="0"
+ style="stop-opacity:1;stop-color:#e8e8e7" />
+ <stop
+ id="stop978"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#cecdcc" />
+ <stop
+ id="stop980"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#cecdcc" />
+ <stop
+ id="stop982"
+ offset="1"
+ style="stop-opacity:1;stop-color:#e2e2e0" />
+ </linearGradient>
+ <clipPath
+ id="clipPath970"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path972"
+ d="m 1580.5,283.5 -1161.031,0 c -16.082,0 -35.692,2.172 -50.992,6.238 0.824,-0.008 1.648,-0.019 2.472,-0.019 l 24.543,0 c 10.102,-1.16 20.492,-1.77 28.535,-1.77 l 1151.883,0 c 8.05,0 18.42,0.61 28.53,1.77 l 24.7,0 c 0.8,0 1.59,0.011 2.39,0.019 -15.36,-4.066 -34.94,-6.238 -51.03,-6.238"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient954"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop956"
+ offset="0"
+ style="stop-opacity:1;stop-color:#ebeceb" />
+ <stop
+ id="stop958"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d0cfce" />
+ <stop
+ id="stop960"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d0cfce" />
+ <stop
+ id="stop962"
+ offset="1"
+ style="stop-opacity:1;stop-color:#e5e5e4" />
+ </linearGradient>
+ <clipPath
+ id="clipPath950"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path952"
+ d="m 1631.53,289.738 c 1.13,0.301 2.23,0.614 3.31,0.922 6.02,1.621 11.92,3.531 17.69,5.719 l 12.58,0 c -3.71,-1.688 -7.49,-3.27 -11.32,-4.731 -7.27,-1.148 -14.7,-1.796 -22.26,-1.91 m -1263.053,0 c -7.559,0.121 -14.997,0.774 -22.262,1.922 -3.82,1.461 -7.578,3.031 -11.281,4.719 l 12.543,0 c 5.894,-2.238 11.925,-4.188 18.082,-5.828 0.953,-0.281 1.925,-0.551 2.918,-0.813"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient934"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop936"
+ offset="0"
+ style="stop-opacity:1;stop-color:#e7e8e6" />
+ <stop
+ id="stop938"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#cbcbc8" />
+ <stop
+ id="stop940"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#cbcbc8" />
+ <stop
+ id="stop942"
+ offset="1"
+ style="stop-opacity:1;stop-color:#e2e1df" />
+ </linearGradient>
+ <clipPath
+ id="clipPath930"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path932"
+ d="m 1622.5,282.68 -1244.98,0 c -10.778,2.121 -21.247,5.14 -31.305,8.98 7.265,-1.148 14.703,-1.801 22.262,-1.922 15.3,-4.066 34.91,-6.238 50.992,-6.238 l 1161.031,0 c 16.09,0 35.67,2.172 51.03,6.238 7.56,0.114 14.99,0.762 22.26,1.91 -10.05,-3.828 -20.52,-6.847 -31.29,-8.968"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient914"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop916"
+ offset="0"
+ style="stop-opacity:1;stop-color:#e2e2e0" />
+ <stop
+ id="stop918"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#c7c6c4" />
+ <stop
+ id="stop920"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#c7c6c4" />
+ <stop
+ id="stop922"
+ offset="1"
+ style="stop-opacity:1;stop-color:#dddbd9" />
+ </linearGradient>
+ <clipPath
+ id="clipPath910"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path912"
+ d="m 1585.09,279.051 -1170.184,0 c -12.785,0 -25.285,1.25 -37.386,3.629 l 1244.98,0 c -12.11,-2.379 -24.62,-3.629 -37.41,-3.629"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient894"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop896"
+ offset="0"
+ style="stop-opacity:1;stop-color:#ffffff" />
+ <stop
+ id="stop898"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#e4e4e3" />
+ <stop
+ id="stop900"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#e4e4e3" />
+ <stop
+ id="stop902"
+ offset="1"
+ style="stop-opacity:1;stop-color:#fafafa" />
+ </linearGradient>
+ <clipPath
+ id="clipPath890"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path892"
+ d="m 1585.09,526.488 -1170.184,0 c -52.644,0 -95.48,289.992 -95.48,342.742 0,15.95 -7.59,30.098 -19.387,39.032 l 0,533.128 c 9.59,8.99 15.578,21.76 15.578,35.91 0,52.94 43.024,150.28 95.957,150.28 l 1176.856,0 c 53.02,0 96.11,-97.34 96.11,-150.28 0,-14.07 5.91,-26.77 15.39,-35.75 l 0,-533.359 c -11.74,-8.929 -19.36,-23.05 -19.36,-38.961 0,-52.75 -42.74,-342.742 -95.48,-342.742"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient874"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop876"
+ offset="0"
+ style="stop-opacity:1;stop-color:#ffffff" />
+ <stop
+ id="stop878"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#e2e2e0" />
+ <stop
+ id="stop880"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#e2e2e0" />
+ <stop
+ id="stop882"
+ offset="1"
+ style="stop-opacity:1;stop-color:#f9f9f9" />
+ </linearGradient>
+ <clipPath
+ id="clipPath870"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path872"
+ d="m 1699.93,908.191 0,533.359 c 2.31,-2.19 4.83,-4.16 7.53,-5.87 l 0,-522.758 c -2.65,-1.352 -5.18,-2.942 -7.53,-4.731 m -1399.891,0.071 c -2.355,1.777 -4.875,3.347 -7.535,4.687 l 0,522.641 c 2.699,1.69 5.223,3.64 7.535,5.8 l 0,-533.128"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient854"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop856"
+ offset="0"
+ style="stop-opacity:1;stop-color:#feffff" />
+ <stop
+ id="stop858"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#e2e1df" />
+ <stop
+ id="stop860"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#e2e1df" />
+ <stop
+ id="stop862"
+ offset="1"
+ style="stop-opacity:1;stop-color:#f8f9f9" />
+ </linearGradient>
+ <clipPath
+ id="clipPath850"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path852"
+ d="m 1707.46,912.922 0,522.758 c 2.38,-1.51 4.9,-2.82 7.54,-3.9 l 0,-515.8 c -2.61,-0.808 -5.13,-1.839 -7.54,-3.058 m -1414.956,0.027 c -2.402,1.211 -4.918,2.231 -7.531,3.039 l 0,515.732 c 2.632,1.08 5.148,2.37 7.531,3.87 l 0,-522.641"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient834"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop836"
+ offset="0"
+ style="stop-opacity:1;stop-color:#fcfcfc" />
+ <stop
+ id="stop838"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#e1e0df" />
+ <stop
+ id="stop840"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#e1e0df" />
+ <stop
+ id="stop842"
+ offset="1"
+ style="stop-opacity:1;stop-color:#f6f6f6" />
+ </linearGradient>
+ <clipPath
+ id="clipPath830"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path832"
+ d="m 1715,915.98 0,515.8 c 2.42,-1 4.94,-1.82 7.54,-2.42 l 0,-511.68 c -2.59,-0.371 -5.1,-0.942 -7.54,-1.7 m -1430.027,0.008 c -2.434,0.75 -4.95,1.321 -7.535,1.692 l 0,511.65 c 2.597,0.6 5.113,1.4 7.535,2.39 l 0,-515.732"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient814"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop816"
+ offset="0"
+ style="stop-opacity:1;stop-color:#fafafa" />
+ <stop
+ id="stop818"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#dfdedc" />
+ <stop
+ id="stop820"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#dfdedc" />
+ <stop
+ id="stop822"
+ offset="1"
+ style="stop-opacity:1;stop-color:#f5f5f4" />
+ </linearGradient>
+ <clipPath
+ id="clipPath810"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path812"
+ d="m 277.438,917.68 c -2.309,0.332 -4.672,0.5 -7.075,0.5 l 0,0 0,0 c -0.152,0 -0.304,0 -0.457,0 l 0,510.02 c 2.571,0.19 5.086,0.57 7.532,1.13 l 0,-511.65 m 1445.102,0 0,511.68 c 2.44,-0.57 4.96,-0.96 7.53,-1.15 l 0,-510.03 c -0.18,0 -0.37,0 -0.56,0 l 0,0 0,0 c -2.37,0 -4.69,-0.168 -6.97,-0.5"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient794"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop796"
+ offset="0"
+ style="stop-opacity:1;stop-color:#fafafa" />
+ <stop
+ id="stop798"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#dedcdb" />
+ <stop
+ id="stop800"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#dedcdb" />
+ <stop
+ id="stop802"
+ offset="1"
+ style="stop-opacity:1;stop-color:#f3f3f3" />
+ </linearGradient>
+ <clipPath
+ id="clipPath790"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path792"
+ d="m 1737.61,917.52 c -2.46,0.402 -4.97,0.628 -7.54,0.66 l 0,510.03 c 1.23,-0.09 2.47,-0.14 3.72,-0.14 1.28,0 2.56,0.05 3.82,0.15 l 0,-510.7 m -1475.235,0.011 0,510.699 c 1.297,-0.11 2.609,-0.16 3.93,-0.16 1.211,0 2.414,0.04 3.601,0.13 l 0,-510.02 c -2.562,-0.032 -5.078,-0.25 -7.531,-0.649"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient774"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop776"
+ offset="0"
+ style="stop-opacity:1;stop-color:#f8f9f9" />
+ <stop
+ id="stop778"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#dbdad8" />
+ <stop
+ id="stop780"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#dbdad8" />
+ <stop
+ id="stop782"
+ offset="1"
+ style="stop-opacity:1;stop-color:#f1f1f0" />
+ </linearGradient>
+ <clipPath
+ id="clipPath770"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path772"
+ d="m 1745.14,915.648 c -2.43,0.821 -4.95,1.442 -7.53,1.872 l 0,510.7 c 2.57,0.2 5.09,0.59 7.53,1.17 l 0,-513.742 m -1490.3,0.012 0,513.76 c 2.449,-0.59 4.961,-0.99 7.535,-1.19 l 0,-510.699 c -2.586,-0.429 -5.102,-1.051 -7.535,-1.871"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient754"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop756"
+ offset="0"
+ style="stop-opacity:1;stop-color:#f7f7f7" />
+ <stop
+ id="stop758"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#dad9d8" />
+ <stop
+ id="stop760"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#dad9d8" />
+ <stop
+ id="stop762"
+ offset="1"
+ style="stop-opacity:1;stop-color:#eff0ef" />
+ </linearGradient>
+ <clipPath
+ id="clipPath750"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path752"
+ d="m 247.309,912.398 0,519.482 c 2.418,-1.01 4.937,-1.84 7.531,-2.46 l 0,-513.76 c -2.617,-0.879 -5.133,-1.969 -7.531,-3.262 m 1505.371,0.012 c -2.4,1.281 -4.92,2.371 -7.54,3.238 l 0,513.742 c 2.6,0.62 5.12,1.44 7.54,2.45 l 0,-519.43"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient734"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop736"
+ offset="0"
+ style="stop-opacity:1;stop-color:#f6f6f6" />
+ <stop
+ id="stop738"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d8d7d5" />
+ <stop
+ id="stop740"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d8d7d5" />
+ <stop
+ id="stop742"
+ offset="1"
+ style="stop-opacity:1;stop-color:#ededed" />
+ </linearGradient>
+ <clipPath
+ id="clipPath730"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path732"
+ d="m 239.773,907.41 0,528.43 c 2.379,-1.52 4.899,-2.85 7.536,-3.96 l 0,-519.482 c -2.668,-1.429 -5.192,-3.109 -7.536,-4.988 m 1520.447,0.02 c -2.35,1.879 -4.87,3.55 -7.54,4.98 l 0,519.43 c 2.64,1.11 5.16,2.43 7.54,3.95 l 0,-528.36"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient714"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop716"
+ offset="0"
+ style="stop-opacity:1;stop-color:#f3f3f3" />
+ <stop
+ id="stop718"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d7d6d4" />
+ <stop
+ id="stop720"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d7d6d4" />
+ <stop
+ id="stop722"
+ offset="1"
+ style="stop-opacity:1;stop-color:#ebeceb" />
+ </linearGradient>
+ <clipPath
+ id="clipPath710"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path712"
+ d="m 232.242,899.852 0,541.938 c 2.309,-2.22 4.828,-4.21 7.531,-5.95 l 0,-528.43 c -2.777,-2.238 -5.3,-4.769 -7.531,-7.558 m 1535.508,0.07 c -2.23,2.769 -4.76,5.289 -7.53,7.508 l 0,528.36 c 2.7,1.74 5.22,3.73 7.53,5.94 l 0,-541.808"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient694"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop696"
+ offset="0"
+ style="stop-opacity:1;stop-color:#f2f2f2" />
+ <stop
+ id="stop698"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d5d4d3" />
+ <stop
+ id="stop700"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d5d4d3" />
+ <stop
+ id="stop702"
+ offset="1"
+ style="stop-opacity:1;stop-color:#eaebe9" />
+ </linearGradient>
+ <clipPath
+ id="clipPath690"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path692"
+ d="m 286.496,327.961 c -34.055,24.168 -57.363,62.539 -61.223,106.398 8.399,-41.918 30.418,-79 61.223,-106.398 m 1427.194,0.117 c 30.6,27.274 52.51,64.094 60.98,105.703 -4.01,-43.551 -27.18,-81.633 -60.98,-105.703 m -1488.979,558.594 0,564.328 c 2.133,-3.37 4.668,-6.46 7.531,-9.21 l 0,-541.938 c -3.152,-3.942 -5.707,-8.372 -7.531,-13.18 m 1550.579,0.168 c -1.83,4.762 -4.39,9.172 -7.54,13.082 l 0,541.808 c 2.87,2.75 5.4,5.84 7.54,9.22 l 0,-564.11 m -1537.372,847.2 c 6.375,13.91 14.867,26.66 25.066,37.84 -9.754,-11.55 -18.183,-24.23 -25.066,-37.84 m 1524.152,0.03 c -6.9,13.63 -15.35,26.34 -25.13,37.89 10.22,-11.18 18.74,-23.95 25.13,-37.89"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient674"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop676"
+ offset="0"
+ style="stop-opacity:1;stop-color:#eff0ef" />
+ <stop
+ id="stop678"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d3d3d2" />
+ <stop
+ id="stop680"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d3d3d2" />
+ <stop
+ id="stop682"
+ offset="1"
+ style="stop-opacity:1;stop-color:#e8e8e7" />
+ </linearGradient>
+ <clipPath
+ id="clipPath670"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path672"
+ d="m 311.309,309.211 c -55.301,23.699 -94.133,78.68 -94.133,142.559 l 0,1022.5 c 0.519,-8.52 3.215,-16.46 7.535,-23.27 l 0,-564.328 c -2.063,-5.41 -3.188,-11.293 -3.188,-17.442 l 0,0 0,-396.878 0,0 c 0,-13 1.289,-25.704 3.75,-37.993 3.86,-43.859 27.168,-82.23 61.223,-106.398 7.742,-6.891 16.035,-13.16 24.813,-18.75 m 1377.441,0.008 c 8.82,5.621 17.17,11.929 24.94,18.859 33.8,24.07 56.97,62.152 60.98,105.703 2.54,12.469 3.87,25.36 3.87,38.571 l 0,396.878 c 0,6.211 -1.15,12.149 -3.25,17.61 l 0,564.11 c 4.32,6.82 7.01,14.78 7.53,23.32 l 0,-1022.5 c 0,-63.879 -38.82,-118.848 -94.07,-142.551 m 94.07,1343.301 c -0.89,29.26 -8.28,56.91 -20.75,81.55 -6.39,13.94 -14.91,26.71 -25.13,37.89 -15.97,18.88 -35.47,34.68 -57.47,46.39 60.14,-21.33 103.35,-78.86 103.35,-146.17 l 0,-19.66 m -1565.644,0 0,19.66 c 0,67.26 43.152,124.75 103.262,146.12 -21.997,-11.72 -41.489,-27.53 -57.454,-46.42 -10.199,-11.18 -18.691,-23.93 -25.066,-37.84 -12.469,-24.63 -19.848,-52.27 -20.742,-81.52"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient654"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop656"
+ offset="0"
+ style="stop-opacity:1;stop-color:#ebeceb" />
+ <stop
+ id="stop658"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d0cfce" />
+ <stop
+ id="stop660"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#d0cfce" />
+ <stop
+ id="stop662"
+ offset="1"
+ style="stop-opacity:1;stop-color:#e5e5e4" />
+ </linearGradient>
+ <clipPath
+ id="clipPath650"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path652"
+ d="m 1653.79,291.648 c 3.83,1.461 7.61,3.043 11.32,4.731 8.2,3.742 16.09,8.031 23.64,12.84 55.25,23.703 94.07,78.672 94.07,142.551 l 0,1022.5 c 0.06,1 0.1,2.02 0.1,3.03 l 0,169.19 c 0,2.02 -0.04,4.03 -0.1,6.03 l 0,19.66 c 0,67.31 -43.21,124.84 -103.35,146.17 -3.4,1.81 -6.85,3.51 -10.37,5.12 -3.85,1.76 -7.77,3.41 -11.76,4.92 73.41,-13.35 129.27,-77.85 129.27,-155.04 l 0,-1226.061 c 0,-78.488 -57.67,-143.758 -132.82,-155.641 M 346.215,291.66 c -75.188,11.899 -132.824,77.149 -132.824,155.629 l 0,1226.061 c 0,77.15 55.8,141.62 129.214,155.02 -3.968,-1.51 -7.867,-3.14 -11.707,-4.9 -3.543,-1.62 -7.035,-3.35 -10.46,-5.17 -60.11,-21.37 -103.262,-78.86 -103.262,-146.12 l 0,-19.66 c -0.063,-2 -0.09,-4.01 -0.09,-6.03 l 0,0 0,-169.19 0,0 c 0,-1.01 0.027,-2.02 0.09,-3.03 l 0,-1022.5 c 0,-63.879 38.832,-118.86 94.133,-142.559 7.539,-4.801 15.425,-9.102 23.625,-12.832 3.703,-1.688 7.461,-3.258 11.281,-4.719"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient634"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop636"
+ offset="0"
+ style="stop-opacity:1;stop-color:#e7e8e6" />
+ <stop
+ id="stop638"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#cbcbc8" />
+ <stop
+ id="stop640"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#cbcbc8" />
+ <stop
+ id="stop642"
+ offset="1"
+ style="stop-opacity:1;stop-color:#e2e1df" />
+ </linearGradient>
+ <clipPath
+ id="clipPath630"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path632"
+ d="m 1630.35,282.68 -7.85,0 c 10.77,2.121 21.24,5.14 31.29,8.968 75.15,11.883 132.82,77.153 132.82,155.641 l 0,1226.061 c 0,77.19 -55.86,141.69 -129.27,155.04 -6.14,2.34 -12.42,4.36 -18.83,6.07 84.47,-4.26 151.88,-74.41 151.88,-159.94 l 0,-1231.711 c 0,-88.297 -71.79,-160.129 -160.04,-160.129 m -1252.83,0 -7.79,0 c -88.324,0 -160.125,71.832 -160.125,160.129 l 0,1231.711 c 0,85.5 67.368,155.63 151.872,159.94 -6.426,-1.71 -12.723,-3.75 -18.872,-6.09 -73.414,-13.4 -129.214,-77.87 -129.214,-155.02 l 0,-1226.061 c 0,-78.48 57.636,-143.73 132.824,-155.629 10.058,-3.84 20.527,-6.859 31.305,-8.98"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient614"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop616"
+ offset="0"
+ style="stop-opacity:1;stop-color:#e2e2e0" />
+ <stop
+ id="stop618"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#c7c6c4" />
+ <stop
+ id="stop620"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#c7c6c4" />
+ <stop
+ id="stop622"
+ offset="1"
+ style="stop-opacity:1;stop-color:#dddbd9" />
+ </linearGradient>
+ <clipPath
+ id="clipPath610"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path612"
+ d="m 1631.56,275.641 -1263.052,0 c -89.75,0 -162.688,72.98 -162.688,162.699 l 0,1237.35 c 0,89.7 72.938,162.72 162.688,162.72 l 11.332,0 c -6.227,-1.02 -12.352,-2.35 -18.363,-3.95 -84.504,-4.31 -151.872,-74.44 -151.872,-159.94 l 0,-1231.711 c 0,-88.297 71.801,-160.129 160.125,-160.129 l 7.79,0 c 12.101,-2.379 24.601,-3.629 37.386,-3.629 l 1170.184,0 c 12.79,0 25.3,1.25 37.41,3.629 l 7.85,0 c 88.25,0 160.04,71.832 160.04,160.129 l 0,1231.711 c 0,85.53 -67.41,155.68 -151.88,159.94 -6.01,1.61 -12.13,2.93 -18.35,3.95 l 11.4,0 c 89.68,0 162.62,-73.02 162.62,-162.72 l 0,-1237.35 c 0,-89.719 -72.94,-162.699 -162.62,-162.699"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient594"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop596"
+ offset="0"
+ style="stop-opacity:1;stop-color:#dfdedc" />
+ <stop
+ id="stop598"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#c2c1c0" />
+ <stop
+ id="stop600"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#c2c1c0" />
+ <stop
+ id="stop602"
+ offset="1"
+ style="stop-opacity:1;stop-color:#d8d7d5" />
+ </linearGradient>
+ <clipPath
+ id="clipPath590"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path592"
+ d="m 1632.77,268.609 -1265.485,0 c -91.172,0 -165.25,74.11 -165.25,165.25 l 0,1243.001 c 0,91.15 74.078,165.29 165.25,165.29 l 1265.485,0 c 91.12,0 165.19,-74.14 165.19,-165.29 l 0,-1243.001 c 0,-91.14 -74.07,-165.25 -165.19,-165.25 M 368.508,1838.41 c -89.75,0 -162.688,-73.02 -162.688,-162.72 l 0,-1237.35 c 0,-89.719 72.938,-162.699 162.688,-162.699 l 1263.052,0 c 89.68,0 162.62,72.98 162.62,162.699 l 0,1237.35 c 0,89.7 -72.94,162.72 -162.62,162.72 l -11.4,0 c -10.33,1.7 -20.93,2.59 -31.73,2.59 l 0,0 -1176.856,0 0,0 c -10.801,0 -21.406,-0.89 -31.734,-2.59 l -11.332,0"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient574"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop576"
+ offset="0"
+ style="stop-opacity:1;stop-color:#dad9d8" />
+ <stop
+ id="stop578"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#bfbdbb" />
+ <stop
+ id="stop580"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#bfbdbb" />
+ <stop
+ id="stop582"
+ offset="1"
+ style="stop-opacity:1;stop-color:#d3d3d2" />
+ </linearGradient>
+ <clipPath
+ id="clipPath570"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path572"
+ d="m 1633.99,261.57 -1267.928,0 c -92.597,0 -167.808,75.258 -167.808,167.821 l 0,1248.639 c 0,92.59 75.211,167.86 167.808,167.86 l 1267.928,0 c 92.55,0 167.76,-75.27 167.76,-167.86 l 0,-1248.639 c 0,-92.563 -75.21,-167.821 -167.76,-167.821 M 367.285,1842.15 c -91.172,0 -165.25,-74.14 -165.25,-165.29 l 0,-1243.001 c 0,-91.14 74.078,-165.25 165.25,-165.25 l 1265.485,0 c 91.12,0 165.19,74.11 165.19,165.25 l 0,1243.001 c 0,91.15 -74.07,165.29 -165.19,165.29 l -1265.485,0"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient554"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop556"
+ offset="0"
+ style="stop-opacity:1;stop-color:#d5d4d3" />
+ <stop
+ id="stop558"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#bbbab8" />
+ <stop
+ id="stop560"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#bbbab8" />
+ <stop
+ id="stop562"
+ offset="1"
+ style="stop-opacity:1;stop-color:#cfcecd" />
+ </linearGradient>
+ <clipPath
+ id="clipPath550"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path552"
+ d="m 1635.2,254.531 -1270.36,0 c -94.02,0 -170.371,76.41 -170.371,170.379 l 0,1254.29 c 0,94.03 76.351,170.44 170.371,170.44 l 1270.36,0 c 93.98,0 170.33,-76.41 170.33,-170.44 l 0,-1254.29 c 0,-93.969 -76.35,-170.379 -170.33,-170.379 M 366.062,1845.89 c -92.597,0 -167.808,-75.27 -167.808,-167.86 l 0,-1248.639 c 0,-92.563 75.211,-167.821 167.808,-167.821 l 1267.928,0 c 92.55,0 167.76,75.258 167.76,167.821 l 0,1248.639 c 0,92.59 -75.21,167.86 -167.76,167.86 l -1267.928,0"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient534"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop536"
+ offset="0"
+ style="stop-opacity:1;stop-color:#d1d1cf" />
+ <stop
+ id="stop538"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#b7b6b5" />
+ <stop
+ id="stop540"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#b7b6b5" />
+ <stop
+ id="stop542"
+ offset="1"
+ style="stop-opacity:1;stop-color:#cac9c8" />
+ </linearGradient>
+ <clipPath
+ id="clipPath530"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path532"
+ d="m 1636.41,247.488 -1272.793,0 c -95.441,0 -172.933,77.563 -172.933,172.942 l 0,1259.95 c 0,95.47 77.492,173 172.933,173 l 1272.793,0 c 95.42,0 172.91,-77.53 172.91,-173 l 0,-1259.95 c 0,-95.379 -77.49,-172.942 -172.91,-172.942 M 364.84,1849.64 c -94.02,0 -170.371,-76.41 -170.371,-170.44 l 0,-1254.29 c 0,-93.969 76.351,-170.379 170.371,-170.379 l 1270.36,0 c 93.98,0 170.33,76.41 170.33,170.379 l 0,1254.29 c 0,94.03 -76.35,170.44 -170.33,170.44 l -1270.36,0"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient514"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop516"
+ offset="0"
+ style="stop-opacity:1;stop-color:#cdccc9" />
+ <stop
+ id="stop518"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#b3b3b2" />
+ <stop
+ id="stop520"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#b3b3b2" />
+ <stop
+ id="stop522"
+ offset="1"
+ style="stop-opacity:1;stop-color:#c6c5c3" />
+ </linearGradient>
+ <clipPath
+ id="clipPath510"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path512"
+ d="m 1637.63,240.449 -1275.232,0 c -96.871,0 -175.5,78.699 -175.5,175.512 l 0,1265.589 c 0,96.91 78.629,175.57 175.5,175.57 l 1275.232,0 c 96.84,0 175.47,-78.66 175.47,-175.57 l 0,-1265.589 c 0,-96.813 -78.63,-175.512 -175.47,-175.512 M 363.617,1853.38 c -95.441,0 -172.933,-77.53 -172.933,-173 l 0,-1259.95 c 0,-95.379 77.492,-172.942 172.933,-172.942 l 1272.793,0 c 95.42,0 172.91,77.563 172.91,172.942 l 0,1259.95 c 0,95.47 -77.49,173 -172.91,173 l -1272.793,0"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient494"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop496"
+ offset="0"
+ style="stop-opacity:1;stop-color:#c7c6c4" />
+ <stop
+ id="stop498"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#aeaead" />
+ <stop
+ id="stop500"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#aeaead" />
+ <stop
+ id="stop502"
+ offset="1"
+ style="stop-opacity:1;stop-color:#c1c0bf" />
+ </linearGradient>
+ <clipPath
+ id="clipPath490"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path492"
+ d="m 1638.84,233.422 -1277.664,0 c -98.293,0 -178.063,79.84 -178.063,178.058 l 0,1271.24 c 0,98.36 79.77,178.14 178.063,178.14 l 1277.664,0 c 98.28,0 178.05,-79.78 178.05,-178.14 l 0,-1271.24 c 0,-98.218 -79.77,-178.058 -178.05,-178.058 M 362.398,1857.12 c -96.871,0 -175.5,-78.66 -175.5,-175.57 l 0,-1265.589 c 0,-96.813 78.629,-175.512 175.5,-175.512 l 1275.232,0 c 96.84,0 175.47,78.699 175.47,175.512 l 0,1265.589 c 0,96.91 -78.63,175.57 -175.47,175.57 l -1275.232,0"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient474"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop476"
+ offset="0"
+ style="stop-opacity:1;stop-color:#c2c1c0" />
+ <stop
+ id="stop478"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#ababaa" />
+ <stop
+ id="stop480"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#ababaa" />
+ <stop
+ id="stop482"
+ offset="1"
+ style="stop-opacity:1;stop-color:#bebcba" />
+ </linearGradient>
+ <clipPath
+ id="clipPath470"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path472"
+ d="m 1640.05,226.379 -1280.097,0 c -99.719,0 -180.625,80.992 -180.625,180.633 l 0,1276.878 c 0,99.8 80.906,180.72 180.625,180.72 l 1280.097,0 c 99.72,0 180.62,-80.92 180.62,-180.72 l 0,-1276.878 c 0,-99.641 -80.9,-180.633 -180.62,-180.633 M 361.176,1860.86 c -98.293,0 -178.063,-79.78 -178.063,-178.14 l 0,-1271.24 c 0,-98.218 79.77,-178.058 178.063,-178.058 l 1277.664,0 c 98.28,0 178.05,79.84 178.05,178.058 l 0,1271.24 c 0,98.36 -79.77,178.14 -178.05,178.14 l -1277.664,0"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient454"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,-164.901,-164.901,0,100,186.835)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop456"
+ offset="0"
+ style="stop-opacity:1;stop-color:#bfbdbb" />
+ <stop
+ id="stop458"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#a6a6a5" />
+ <stop
+ id="stop460"
+ offset="0.714464"
+ style="stop-opacity:1;stop-color:#a6a6a5" />
+ <stop
+ id="stop462"
+ offset="1"
+ style="stop-opacity:1;stop-color:#b9b8b7" />
+ </linearGradient>
+ <clipPath
+ id="clipPath450"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path452"
+ d="m 1641.26,219.34 -1282.53,0 c -101.14,0 -183.187,82.14 -183.187,183.191 l 0,1282.529 c 0,101.24 82.047,183.29 183.187,183.29 l 1282.53,0 c 101.15,0 183.2,-82.05 183.2,-183.29 l 0,-1282.529 c 0,-101.051 -82.05,-183.191 -183.2,-183.191 M 359.953,1864.61 c -99.719,0 -180.625,-80.92 -180.625,-180.72 l 0,-1276.878 c 0,-99.641 80.906,-180.633 180.625,-180.633 l 1280.097,0 c 99.72,0 180.62,80.992 180.62,180.633 l 0,1276.878 c 0,99.8 -80.9,180.72 -180.62,180.72 l -1280.097,0"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient438"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop440"
+ offset="0"
+ style="stop-opacity:1;stop-color:#95968f" />
+ <stop
+ id="stop442"
+ offset="1"
+ style="stop-opacity:1;stop-color:#686a68" />
+ </linearGradient>
+ <clipPath
+ id="clipPath434"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path436"
+ d="m 1698.32,211.551 -1396.636,0 c 17.867,4.578 36.941,7.051 56.742,7.051 l 1283.144,0 c 19.8,0 38.88,-2.473 56.75,-7.051"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient420"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop422"
+ offset="0"
+ style="stop-opacity:1;stop-color:#9b9c94" />
+ <stop
+ id="stop424"
+ offset="1"
+ style="stop-opacity:1;stop-color:#6f716d" />
+ </linearGradient>
+ <clipPath
+ id="clipPath416"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path418"
+ d="m 1704.28,208.461 -1408.499,0 c -1.398,0 -2.758,0.098 -4.062,0.277 3.273,1.012 6.597,1.953 9.965,2.813 l 1396.636,0 c 3.37,-0.86 6.7,-1.801 9.99,-2.813 -1.3,-0.179 -2.64,-0.277 -4.03,-0.277"
+ inkscape:connector-curvature="0" />
+ </clipPath>
<linearGradient
- id="linearGradient3151">
+ id="linearGradient402"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop404"
+ offset="0"
+ style="stop-opacity:1;stop-color:#a0a19a" />
+ <stop
+ id="stop406"
+ offset="1"
+ style="stop-opacity:1;stop-color:#737471" />
+ </linearGradient>
+ <clipPath
+ id="clipPath398"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path400"
+ d="m 1707.28,205.371 -1414.495,0 c -2.93,0 -5.719,0.359 -8.242,1.027 2.367,0.821 4.754,1.602 7.176,2.34 1.304,-0.179 2.664,-0.277 4.062,-0.277 l 1408.499,0 c 1.39,0 2.73,0.098 4.03,0.277 2.42,-0.75 4.81,-1.527 7.18,-2.347 -2.51,-0.661 -5.29,-1.02 -8.21,-1.02"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient384"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop386"
+ offset="0"
+ style="stop-opacity:1;stop-color:#a9aaa2" />
+ <stop
+ id="stop388"
+ offset="1"
+ style="stop-opacity:1;stop-color:#787a77" />
+ </linearGradient>
+ <clipPath
+ id="clipPath380"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path382"
+ d="m 1710.28,202.27 -1420.495,0 c -4.203,0 -8.156,0.66 -11.574,1.812 2.086,0.797 4.199,1.578 6.332,2.316 2.523,-0.668 5.312,-1.027 8.242,-1.027 l 1414.495,0 c 2.92,0 5.7,0.359 8.21,1.02 2.13,-0.743 4.24,-1.52 6.33,-2.321 -3.4,-1.14 -7.34,-1.8 -11.54,-1.8"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient366"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop368"
+ offset="0"
+ style="stop-opacity:1;stop-color:#b0b1a8" />
+ <stop
+ id="stop370"
+ offset="1"
+ style="stop-opacity:1;stop-color:#7e7f7c" />
+ </linearGradient>
+ <clipPath
+ id="clipPath362"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path364"
+ d="m 1713.28,199.18 -1426.491,0 c -5.332,0 -10.305,0.929 -14.465,2.539 1.942,0.812 3.903,1.601 5.887,2.363 3.418,-1.152 7.371,-1.812 11.574,-1.812 l 1420.495,0 c 4.2,0 8.14,0.66 11.54,1.8 1.98,-0.761 3.94,-1.55 5.88,-2.359 -4.14,-1.602 -9.09,-2.531 -14.42,-2.531"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient348"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop350"
+ offset="0"
+ style="stop-opacity:1;stop-color:#b8b8ae" />
+ <stop
+ id="stop352"
+ offset="1"
+ style="stop-opacity:1;stop-color:#848581" />
+ </linearGradient>
+ <clipPath
+ id="clipPath344"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path346"
+ d="m 1716.28,196.09 -1432.491,0 c -6.34,0 -12.223,1.18 -17.039,3.191 1.84,0.84 3.695,1.649 5.574,2.438 4.16,-1.61 9.133,-2.539 14.465,-2.539 l 1426.491,0 c 5.33,0 10.28,0.929 14.42,2.531 1.88,-0.789 3.74,-1.602 5.57,-2.441 -4.79,-2.008 -10.65,-3.18 -16.99,-3.18"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient330"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop332"
+ offset="0"
+ style="stop-opacity:1;stop-color:#bfbfb5" />
+ <stop
+ id="stop334"
+ offset="1"
+ style="stop-opacity:1;stop-color:#888a85" />
+ </linearGradient>
+ <clipPath
+ id="clipPath326"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path328"
+ d="m 1719.29,192.988 -1438.497,0 c -7.25,0 -13.957,1.403 -19.371,3.774 1.758,0.859 3.531,1.699 5.328,2.519 4.816,-2.011 10.699,-3.191 17.039,-3.191 l 1432.491,0 c 6.34,0 12.2,1.172 16.99,3.18 1.8,-0.821 3.58,-1.661 5.33,-2.52 -5.39,-2.359 -12.07,-3.762 -19.31,-3.762"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient312"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop314"
+ offset="0"
+ style="stop-opacity:1;stop-color:#c6c6bb" />
+ <stop
+ id="stop316"
+ offset="1"
+ style="stop-opacity:1;stop-color:#8e908a" />
+ </linearGradient>
+ <clipPath
+ id="clipPath308"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path310"
+ d="m 1722.29,189.898 -1444.497,0 c -8.066,0 -15.516,1.582 -21.484,4.25 1.683,0.891 3.39,1.762 5.113,2.614 5.414,-2.371 12.121,-3.774 19.371,-3.774 l 1438.497,0 c 7.24,0 13.92,1.403 19.31,3.762 1.73,-0.852 3.43,-1.719 5.11,-2.621 -5.94,-2.649 -13.36,-4.231 -21.42,-4.231"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient294"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
<stop
- style="stop-color:#b5b5b5;stop-opacity:1;"
+ id="stop296"
offset="0"
- id="stop3153" />
+ style="stop-opacity:1;stop-color:#cecec3" />
<stop
- style="stop-color:#ffffff;stop-opacity:1;"
+ id="stop298"
offset="1"
- id="stop3155" />
+ style="stop-opacity:1;stop-color:#94958e" />
</linearGradient>
+ <clipPath
+ id="clipPath290"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path292"
+ d="m 1725.29,186.809 -1450.493,0 c -8.797,0 -16.914,1.73 -23.41,4.64 1.621,0.922 3.261,1.821 4.922,2.699 5.968,-2.668 13.418,-4.25 21.484,-4.25 l 1444.497,0 c 8.06,0 15.48,1.582 21.42,4.231 1.66,-0.867 3.3,-1.77 4.92,-2.688 -6.46,-2.91 -14.55,-4.632 -23.34,-4.632"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient276"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop278"
+ offset="0"
+ style="stop-opacity:1;stop-color:#d6d6cb" />
+ <stop
+ id="stop280"
+ offset="1"
+ style="stop-opacity:1;stop-color:#999a93" />
+ </linearGradient>
+ <clipPath
+ id="clipPath272"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path274"
+ d="m 1728.29,183.711 -1456.493,0 c -9.442,0 -18.16,1.848 -25.145,4.961 1.559,0.949 3.137,1.867 4.735,2.777 6.496,-2.91 14.613,-4.64 23.41,-4.64 l 1450.493,0 c 8.79,0 16.88,1.722 23.34,4.632 1.6,-0.91 3.18,-1.839 4.74,-2.781 -6.96,-3.101 -15.65,-4.949 -25.08,-4.949"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient258"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop260"
+ offset="0"
+ style="stop-opacity:1;stop-color:#dcdcd2" />
+ <stop
+ id="stop262"
+ offset="1"
+ style="stop-opacity:1;stop-color:#9c9d96" />
+ </linearGradient>
+ <clipPath
+ id="clipPath254"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path256"
+ d="m 1731.29,180.621 -1462.493,0 c -10.008,0 -19.258,1.93 -26.703,5.188 1.5,0.98 3.019,1.929 4.558,2.863 6.985,-3.113 15.703,-4.961 25.145,-4.961 l 1456.493,0 c 9.43,0 18.12,1.848 25.08,4.949 1.53,-0.93 3.06,-1.89 4.55,-2.859 -7.41,-3.25 -16.63,-5.18 -26.63,-5.18"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient240"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop242"
+ offset="0"
+ style="stop-opacity:1;stop-color:#e2e3d8" />
+ <stop
+ id="stop244"
+ offset="1"
+ style="stop-opacity:1;stop-color:#a1a39b" />
+ </linearGradient>
+ <clipPath
+ id="clipPath236"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path238"
+ d="m 1734.29,177.531 -1468.489,0 c -10.5,0 -20.215,1.989 -28.09,5.36 1.441,0.988 2.902,1.961 4.383,2.918 7.445,-3.258 16.695,-5.188 26.703,-5.188 l 1462.493,0 c 10,0 19.22,1.93 26.63,5.18 1.49,-0.961 2.95,-1.93 4.39,-2.93 -7.85,-3.359 -17.53,-5.34 -28.02,-5.34"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient222"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop224"
+ offset="0"
+ style="stop-opacity:1;stop-color:#e4e4db" />
+ <stop
+ id="stop226"
+ offset="1"
+ style="stop-opacity:1;stop-color:#a5a59c" />
+ </linearGradient>
+ <clipPath
+ id="clipPath218"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path220"
+ d="m 1740.22,169.219 -1480.353,0 c -12.113,0 -23.351,2.179 -32.594,5.883 3.348,2.699 6.832,5.296 10.438,7.789 7.875,-3.371 17.59,-5.36 28.09,-5.36 l 1468.489,0 c 10.49,0 20.17,1.981 28.02,5.34 3.6,-2.48 7.09,-5.082 10.44,-7.781 -9.22,-3.699 -20.43,-5.871 -32.53,-5.871"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient204"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop206"
+ offset="0"
+ style="stop-opacity:1;stop-color:#e8e9de" />
+ <stop
+ id="stop208"
+ offset="1"
+ style="stop-opacity:1;stop-color:#a7a89f" />
+ </linearGradient>
+ <clipPath
+ id="clipPath200"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path202"
+ d="m 1746.16,160.91 -1492.226,0 c -13.278,0 -25.653,2.219 -36.039,6.031 2.996,2.821 6.121,5.539 9.378,8.161 9.243,-3.704 20.481,-5.883 32.594,-5.883 l 1480.353,0 c 12.1,0 23.31,2.172 32.53,5.871 3.25,-2.629 6.38,-5.352 9.37,-8.16 -10.36,-3.809 -22.7,-6.02 -35.96,-6.02"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient186"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop188"
+ offset="0"
+ style="stop-opacity:1;stop-color:#eaeae0" />
+ <stop
+ id="stop190"
+ offset="1"
+ style="stop-opacity:1;stop-color:#a8a9a1" />
+ </linearGradient>
+ <clipPath
+ id="clipPath182"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path184"
+ d="m 1752.09,152.602 -1504.09,0 c -14.023,0 -27.168,2.148 -38.449,5.886 2.648,2.903 5.437,5.723 8.344,8.453 10.386,-3.812 22.761,-6.031 36.039,-6.031 l 1492.226,0 c 13.26,0 25.6,2.211 35.96,6.02 2.91,-2.739 5.69,-5.551 8.35,-8.461 -11.26,-3.731 -24.38,-5.867 -38.38,-5.867"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient168"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop170"
+ offset="0"
+ style="stop-opacity:1;stop-color:#ecede3" />
+ <stop
+ id="stop172"
+ offset="1"
+ style="stop-opacity:1;stop-color:#aaaba2" />
+ </linearGradient>
+ <clipPath
+ id="clipPath164"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path166"
+ d="m 1758.03,144.289 -1515.964,0 c -14.39,0 -27.957,2 -39.859,5.52 2.316,2.972 4.77,5.863 7.344,8.679 11.281,-3.738 24.426,-5.886 38.449,-5.886 l 1504.09,0 c 14,0 27.12,2.136 38.38,5.867 2.57,-2.809 5.02,-5.707 7.34,-8.668 -11.88,-3.52 -25.42,-5.512 -39.78,-5.512"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient150"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop152"
+ offset="0"
+ style="stop-opacity:1;stop-color:#eff0e6" />
+ <stop
+ id="stop154"
+ offset="1"
+ style="stop-opacity:1;stop-color:#acada4" />
+ </linearGradient>
+ <clipPath
+ id="clipPath146"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path148"
+ d="m 1763.96,135.98 -1527.827,0 c -14.403,0 -28.063,1.79 -40.297,5 1.996,3.008 4.117,5.95 6.371,8.829 11.902,-3.52 25.469,-5.52 39.859,-5.52 l 1515.964,0 c 14.36,0 27.9,1.992 39.78,5.512 2.24,-2.879 4.37,-5.832 6.36,-8.84 -12.2,-3.191 -25.83,-4.981 -40.21,-4.981"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient132"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop134"
+ offset="0"
+ style="stop-opacity:1;stop-color:#f2f2e8" />
+ <stop
+ id="stop136"
+ offset="1"
+ style="stop-opacity:1;stop-color:#aeaea6" />
+ </linearGradient>
+ <clipPath
+ id="clipPath128"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path130"
+ d="m 1769.89,127.672 -1539.691,0 c -14.09,0 -27.531,1.547 -39.801,4.367 1.684,3.031 3.504,6.02 5.438,8.941 12.234,-3.21 25.894,-5 40.297,-5 l 1527.827,0 c 14.38,0 28.01,1.79 40.21,4.981 1.94,-2.922 3.75,-5.902 5.44,-8.941 -12.24,-2.801 -25.66,-4.348 -39.72,-4.348"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient114"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop116"
+ offset="0"
+ style="stop-opacity:1;stop-color:#f5f5ea" />
+ <stop
+ id="stop118"
+ offset="1"
+ style="stop-opacity:1;stop-color:#b0b0a8" />
+ </linearGradient>
+ <clipPath
+ id="clipPath110"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path112"
+ d="m 1775.83,119.359 -1551.564,0 c -13.473,0 -26.407,1.301 -38.407,3.68 1.387,3.051 2.903,6.051 4.539,9 12.27,-2.82 25.711,-4.367 39.801,-4.367 l 1539.691,0 c 14.06,0 27.48,1.547 39.72,4.348 1.64,-2.95 3.15,-5.95 4.54,-9 -11.98,-2.372 -24.88,-3.661 -38.32,-3.661"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient96"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop98"
+ offset="0"
+ style="stop-opacity:1;stop-color:#f7f8ed" />
+ <stop
+ id="stop100"
+ offset="1"
+ style="stop-opacity:1;stop-color:#b1b2a9" />
+ </linearGradient>
+ <clipPath
+ id="clipPath92"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path94"
+ d="m 1781.76,111.051 -1563.432,0 c -12.574,0 -24.715,1.039 -36.152,2.98 1.105,3.039 2.332,6.047 3.683,9.008 12,-2.379 24.934,-3.68 38.407,-3.68 l 1551.564,0 c 13.44,0 26.34,1.289 38.32,3.661 1.34,-2.95 2.58,-5.961 3.68,-9.008 -11.41,-1.922 -23.52,-2.961 -36.07,-2.961"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient78"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop80"
+ offset="0"
+ style="stop-opacity:1;stop-color:#f9f9ef" />
+ <stop
+ id="stop82"
+ offset="1"
+ style="stop-opacity:1;stop-color:#b2b3a9" />
+ </linearGradient>
+ <clipPath
+ id="clipPath74"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path76"
+ d="m 1787.69,102.738 -1575.292,0 c -11.421,0 -22.507,0.801 -33.089,2.293 0.836,3.039 1.793,6.028 2.867,9 11.437,-1.941 23.578,-2.98 36.152,-2.98 l 1563.432,0 c 12.55,0 24.66,1.039 36.07,2.961 1.07,-2.961 2.03,-5.953 2.86,-8.992 -10.55,-1.489 -21.61,-2.282 -33,-2.282"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient60"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop62"
+ offset="0"
+ style="stop-opacity:1;stop-color:#fbfbf2" />
+ <stop
+ id="stop64"
+ offset="1"
+ style="stop-opacity:1;stop-color:#b6b6ac" />
+ </linearGradient>
+ <clipPath
+ id="clipPath56"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path58"
+ d="m 1793.63,94.4297 -1587.165,0 c -10.024,0 -19.805,0.5703 -29.246,1.6601 0.578,3.0118 1.277,6.0002 2.09,8.9412 10.582,-1.492 21.668,-2.293 33.089,-2.293 l 1575.292,0 c 11.39,0 22.45,0.793 33,2.282 0.82,-2.95 1.51,-5.9302 2.09,-8.938 -9.41,-1.082 -19.16,-1.6523 -29.15,-1.6523"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient42"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop44"
+ offset="0"
+ style="stop-opacity:1;stop-color:#fcfdf4" />
+ <stop
+ id="stop46"
+ offset="1"
+ style="stop-opacity:1;stop-color:#b7b7ad" />
+ </linearGradient>
+ <clipPath
+ id="clipPath38"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path40"
+ d="m 1799.56,86.1211 -1599.033,0 c -8.39,0 -16.632,0.3789 -24.656,1.0977 0.336,2.9804 0.785,5.9414 1.348,8.871 9.441,-1.0898 19.222,-1.6601 29.246,-1.6601 l 1587.165,0 c 9.99,0 19.74,0.5703 29.15,1.6523 0.57,-2.9336 1.01,-5.8828 1.35,-8.8711 -8,-0.7109 -16.21,-1.0898 -24.57,-1.0898"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <linearGradient
+ id="linearGradient24"
+ spreadMethod="pad"
+ gradientTransform="matrix(0,20.8601,20.8601,0,100,1)"
+ gradientUnits="userSpaceOnUse"
+ y2="0"
+ x2="1"
+ y1="0"
+ x1="0">
+ <stop
+ id="stop26"
+ offset="0"
+ style="stop-opacity:1;stop-color:#fcfdf4" />
+ <stop
+ id="stop28"
+ offset="1"
+ style="stop-opacity:1;stop-color:#b7b7ad" />
+ </linearGradient>
+ <clipPath
+ id="clipPath20"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ id="path22-8"
+ d="m 1824.85,10 -1649.702,0 0,64.3281 c 0,4.3438 0.247,8.6407 0.723,12.8907 8.024,-0.7188 16.266,-1.0977 24.656,-1.0977 l 1599.033,0 c 8.36,0 16.57,0.3789 24.57,1.0898 0.48,-4.2421 0.72,-8.539 0.72,-12.8828 l 0,-64.3281"
+ inkscape:connector-curvature="0" />
+ </clipPath>
<inkscape:perspective
- sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="0 : 526.18109 : 1"
+ id="perspective2390"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <linearGradient
+ id="linearGradient3150">
+ <stop
+ id="stop3152"
+ offset="0"
+ style="stop-color:#235071;stop-opacity:1;" />
+ <stop
+ id="stop3154"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3170">
+ <stop
+ id="stop3172"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop3174"
+ offset="1"
+ style="stop-color:#848484;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ y2="0.52999997"
+ x2="97.685806"
+ y1="51.163727"
+ x1="80.78746"
+ gradientTransform="matrix(1.0000709,0,0,0.988411,-151.89821,-7.7970763)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3802"
+ xlink:href="#linearGradient3150-4"
+ inkscape:collect="always" />
+ <linearGradient
+ y2="0.52999997"
+ x2="97.685806"
+ y1="51.163727"
+ x1="80.78746"
+ gradientTransform="matrix(1.0000709,0,0,0.988411,-154.02756,-2.82859)"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3796"
+ xlink:href="#linearGradient3150-4"
+ inkscape:collect="always" />
+ <linearGradient
+ gradientTransform="matrix(1.0000709,0,0,0.988411,-0.00448627,0.010545)"
+ y2="0.52999997"
+ x2="97.685806"
+ y1="51.163727"
+ x1="80.78746"
+ gradientUnits="userSpaceOnUse"
+ id="linearGradient3168-3"
+ xlink:href="#linearGradient3150-4"
+ inkscape:collect="always" />
+ <inkscape:perspective
+ id="perspective2390-2"
+ inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
+ <linearGradient
+ id="linearGradient3150-4">
+ <stop
+ id="stop3152-7"
+ offset="0"
+ style="stop-color:#235071;stop-opacity:1;" />
+ <stop
+ id="stop3154-3"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3170-7">
+ <stop
+ id="stop3172-6"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop3174-8"
+ offset="1"
+ style="stop-color:#848484;stop-opacity:1;" />
+ </linearGradient>
+ <inkscape:perspective
+ id="perspective2390-3"
inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
- id="perspective2390" />
+ inkscape:vp_z="744.09448 : 526.18109 : 1"
+ inkscape:vp_y="0 : 1000 : 0"
+ inkscape:vp_x="0 : 526.18109 : 1"
+ sodipodi:type="inkscape:persp3d" />
<linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient3151"
- id="linearGradient3157"
- x1="17.991968"
- y1="115.66266"
- x2="96.913872"
- y2="12.610445"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.9442617,0,0,0.9442617,4.0741457,4.0741457)" />
+ id="linearGradient3150-6">
+ <stop
+ id="stop3152-6"
+ offset="0"
+ style="stop-color:#235071;stop-opacity:1;" />
+ <stop
+ id="stop3154-4"
+ offset="1"
+ style="stop-color:#ffffff;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ id="linearGradient3170-6">
+ <stop
+ id="stop3172-1"
+ offset="0"
+ style="stop-color:#000000;stop-opacity:1;" />
+ <stop
+ id="stop3174-1"
+ offset="1"
+ style="stop-color:#848484;stop-opacity:1;" />
+ </linearGradient>
</defs>
<sodipodi:namedview
- id="base"
pagecolor="#ffffff"
bordercolor="#666666"
- borderopacity="1.0"
- gridtolerance="10000"
- guidetolerance="10"
+ borderopacity="1"
objecttolerance="10"
- inkscape:pageopacity="0.0"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
inkscape:pageshadow="2"
- inkscape:zoom="1.9453125"
- inkscape:cx="64"
- inkscape:cy="48.751619"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
+ inkscape:window-width="1680"
+ inkscape:window-height="1001"
+ id="namedview4"
showgrid="false"
- inkscape:window-width="996"
- inkscape:window-height="701"
- inkscape:window-x="1503"
- inkscape:window-y="236" />
- <metadata
- id="metadata2464">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- </cc:Work>
- </rdf:RDF>
- </metadata>
+ inkscape:zoom="6.6691528"
+ inkscape:cx="64.454266"
+ inkscape:cy="68.648241"
+ inkscape:window-x="0"
+ inkscape:window-y="23"
+ inkscape:window-maximized="0"
+ inkscape:current-layer="g10"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0" />
<g
- inkscape:label="Layer 1"
+ id="g10"
inkscape:groupmode="layer"
- id="layer1">
- <rect
- style="opacity:1;fill:url(#linearGradient3157);fill-opacity:1;stroke:#8c8c8c;stroke-width:9.59699999999999953;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect2380"
- width="116.94396"
- height="116.94396"
- x="5.9135523"
- y="5.9135523"
- ry="28.779495"
- inkscape:export-filename="/Users/remko/src/swift/Swift/resources/icons/avatar.png"
- inkscape:export-xdpi="34.093784"
- inkscape:export-ydpi="34.093784" />
+ inkscape:label="ink_ext_XXXXXX"
+ transform="matrix(1.25,0,0,-1.25,-508.98876,369.64004)">
+ <circle
+ style="opacity:1;fill:#dddddd;fill-opacity:1;stroke:#ffffff;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="backgroundCircle"
+ cx="442.77222"
+ cy="-260.09323"
+ transform="scale(1,-1)"
+ r="32.661972" />
+ <g
+ id="g2734"
+ transform="matrix(0.03695799,0,0,0.03695799,357.71523,119.9194)">
+ <g
+ clip-path="url(#clipPath2738)"
+ id="g2736">
+ <g
+ transform="matrix(15.2,0,0,15.2,263.9,861.9)"
+ id="g2742">
+ <image
+ id="image2744"
+ xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAYAAABWKLW/AAAABHNCSVQICAgIfAhkiAAAABVJREFUCJljfPbs6X8GKGBiQAIoHACHDwO2XpusvQAAAABJRU5ErkJggg=="
+ transform="matrix(1,0,0,-1,0,1)"
+ height="1"
+ width="1" />
+ </g>
+ </g>
+ </g>
+ <g
+ transform="matrix(0.43868508,0,0,-0.43868508,477.6681,346.11711)"
+ id="layer1-0"
+ inkscape:label="Layer 1">
+ <path
+ id="path3804-2"
+ d="m -116.04602,140.16881 c 63.47233,14.0107 52.472994,34.41414 26.064348,51.55181 -12.825068,4.12386 -28.784578,9.13824 -49.659768,14.98061 9.85394,-1.19384 18.77655,-1.96723 26.84565,-2.37837 -8.07516,3.9199 -16.15628,7.45211 -23.12664,10.37832 16.08126,-4.16073 29.80986,-7.64031 41.752958,-10.59453 43.679839,1.70458 46.902784,20.93179 6.531716,58.03826 60.709281,-31.2105 76.647981,-54.18473 40.59663,-69.00345 18.498251,-3.84931 25.553871,-4.38862 29.470841,-4.04631 -9.4225,-5.84736 -15.93053,-8.83589 -23.2204,-9.3899 16.00173,-21.3204 -18.176669,-34.68275 -75.255335,-39.53644 z"
+ style="fill:#235071;fill-opacity:1;fill-rule:nonzero;stroke:#235071;stroke-width:2.39899993;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ inkscape:connector-curvature="0" />
+ <path
+ id="path3806-8"
+ d="m -37.962505,185.06086 c 0,1.09434 -0.97348,1.9825 -2.17294,1.9825 -1.19948,0 -2.172957,-0.88816 -2.172957,-1.9825 0,-1.09433 0.973477,-1.98249 2.172957,-1.98249 1.19946,0 2.17294,0.88816 2.17294,1.98249 z"
+ style="fill:#ffa859;fill-opacity:1;fill-rule:nonzero;stroke:none"
+ inkscape:connector-curvature="0" />
+ </g>
<path
- id="path2469"
- style="fill:#8c8c8c;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.17320289000000000px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 84.186703,55.87472 C 115.18862,33.344515 86.918967,19.476275 33.840876,14.909522 C 111.17407,32.181205 49.997334,61.470216 17.987699,75.066628 C 91.222651,55.894928 106.3968,53.862851 112.44381,54.397544 C 88.313377,39.246156 87.961827,47.960949 15.015231,68.617437 C 82.095674,60.394538 97.654781,75.133863 56.523078,113.38543 C 107.45479,86.892681 118.9257,67.742581 84.186703,55.87472 z M 96.159637,51.145757 C 96.159637,52.029347 95.382795,52.74646 94.425618,52.74646 C 93.46843,52.74646 92.69159,52.029347 92.69159,51.145757 C 92.69159,50.262174 93.46843,49.545057 94.425618,49.545057 C 95.382795,49.545057 96.159637,50.262174 96.159637,51.145757 z"
- inkscape:export-filename="/Users/remko/src/swift/Swift/resources/icons/avatar.png"
- inkscape:export-xdpi="34.093784"
- inkscape:export-ydpi="34.093784" />
+ sodipodi:open="true"
+ sodipodi:end="9.4489119"
+ sodipodi:start="3.2027767"
+ sodipodi:type="arc"
+ style="fill:#ffd632;fill-opacity:0;fill-rule:nonzero;stroke:#235071;stroke-width:5.0999999;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
+ id="path6540"
+ sodipodi:cx="-102"
+ sodipodi:cy="82.462494"
+ sodipodi:rx="32"
+ sodipodi:ry="32"
+ d="m -133.94012,80.505826 a 32,32 0 0 1 33.60086,-30.000208 32,32 0 0 1 30.310148,33.32155 32,32 0 0 1 -33.039378,30.617482 32,32 0 0 1 -30.92219,-32.754367"
+ transform="matrix(1.0298331,0,0,-1.0298331,547.81489,345.01645)" />
</g>
</svg>
diff --git a/Swift/resources/icons/delivery-failure.svg b/Swift/resources/icons/delivery-failure.svg
new file mode 100644
index 0000000..c1a0c08
--- /dev/null
+++ b/Swift/resources/icons/delivery-failure.svg
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" viewBox="0 0 133 133" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
+ <g id="Layer-1" transform="matrix(1,0,0,1,0,-164.708)">
+ <g id="path4233" transform="matrix(1.00826,0,0,1.00826,-0.546361,-1.90685)">
+ <circle cx="66.146" cy="230.854" r="65.604" style="fill:rgb(224,102,102);"/>
+ <path d="M66.57,165.252L66.993,165.256L67.416,165.262L67.838,165.272L68.259,165.284L68.68,165.298L69.1,165.316L69.52,165.336L69.938,165.358L70.356,165.383L70.774,165.411L71.19,165.442L71.606,165.475L72.021,165.51L72.436,165.548L72.849,165.589L73.262,165.632L73.675,165.678L74.086,165.727L74.497,165.778L74.906,165.831L75.315,165.887L75.724,165.946L76.131,166.007L76.538,166.07L76.943,166.136L77.348,166.205L77.753,166.276L78.156,166.349L78.558,166.425L78.96,166.503L79.36,166.584L79.76,166.667L80.159,166.753L80.557,166.841L80.954,166.931L81.35,167.024L81.746,167.119L82.14,167.217L82.533,167.317L82.926,167.419L83.317,167.524L83.708,167.631L84.097,167.741L84.486,167.852L84.873,167.967L85.26,168.083L85.645,168.202L86.03,168.323L86.414,168.446L86.796,168.572L87.178,168.7L87.558,168.83L87.937,168.962L88.316,169.097L88.693,169.234L89.069,169.373L89.444,169.514L89.818,169.658L90.191,169.804L90.563,169.952L90.934,170.102L91.303,170.255L91.672,170.409L92.039,170.566L92.405,170.725L92.77,170.886L93.134,171.049L93.496,171.215L93.858,171.382L94.218,171.552L94.577,171.724L94.935,171.898L95.292,172.074L95.647,172.252L96.001,172.432L96.354,172.614L96.706,172.798L97.057,172.985L97.406,173.173L97.754,173.364L98.1,173.556L98.446,173.751L98.79,173.947L99.133,174.146L99.474,174.346L99.814,174.549L100.153,174.754L100.491,174.96L100.827,175.169L101.162,175.379L101.495,175.592L101.827,175.806L102.158,176.022L102.487,176.241L102.815,176.461L103.141,176.683L103.467,176.907L103.79,177.133L104.113,177.361L104.433,177.59L104.753,177.822L105.071,178.055L105.387,178.291L105.702,178.528L106.016,178.767L106.328,179.007L106.639,179.25L106.948,179.495L107.255,179.741L107.561,179.989L107.866,180.239L108.169,180.49L108.471,180.744L108.77,180.999L109.069,181.256L109.366,181.515L109.661,181.775L109.955,182.037L110.247,182.301L110.537,182.567L110.826,182.834L111.114,183.104L111.399,183.374L111.683,183.647L111.966,183.921L112.247,184.197L112.526,184.474L112.803,184.753L113.079,185.034L113.353,185.317L113.626,185.601L113.896,185.886L114.166,186.174L114.433,186.463L114.699,186.753L114.963,187.045L115.225,187.339L115.485,187.634L115.744,187.931L116.001,188.23L116.256,188.529L116.51,188.831L116.761,189.134L117.011,189.439L117.259,189.745L117.505,190.052L117.75,190.361L117.993,190.672L118.233,190.984L118.472,191.298L118.709,191.613L118.945,191.929L119.178,192.247L119.41,192.567L119.639,192.887L119.867,193.21L120.093,193.533L120.317,193.859L120.539,194.185L120.759,194.513L120.978,194.842L121.194,195.173L121.408,195.505L121.621,195.838L121.831,196.173L122.04,196.509L122.246,196.847L122.451,197.186L122.654,197.526L122.854,197.867L123.053,198.21L123.249,198.554L123.444,198.9L123.636,199.246L123.827,199.594L124.015,199.943L124.202,200.294L124.386,200.646L124.568,200.999L124.748,201.353L124.927,201.708L125.102,202.065L125.276,202.423L125.448,202.782L125.618,203.142L125.785,203.504L125.951,203.866L126.114,204.23L126.275,204.595L126.434,204.961L126.591,205.328L126.746,205.697L126.898,206.066L127.048,206.437L127.196,206.809L127.342,207.182L127.486,207.556L127.627,207.931L127.766,208.307L127.903,208.684L128.038,209.063L128.17,209.442L128.3,209.822L128.428,210.204L128.554,210.586L128.677,210.97L128.798,211.355L128.917,211.74L129.033,212.127L129.148,212.514L129.259,212.903L129.369,213.292L129.476,213.683L129.581,214.074L129.683,214.467L129.783,214.86L129.881,215.255L129.976,215.65L130.069,216.046L130.159,216.443L130.247,216.841L130.333,217.24L130.416,217.64L130.497,218.04L130.575,218.442L130.651,218.844L130.724,219.247L130.795,219.652L130.864,220.057L130.93,220.462L130.993,220.869L131.054,221.276L131.113,221.685L131.169,222.094L131.222,222.503L131.273,222.914L131.322,223.325L131.368,223.738L131.411,224.151L131.452,224.564L131.49,224.979L131.525,225.394L131.558,225.81L131.589,226.226L131.617,226.644L131.642,227.062L131.664,227.48L131.684,227.9L131.702,228.32L131.716,228.741L131.728,229.162L131.738,229.584L131.744,230.007L131.748,230.43L131.75,230.854L131.748,231.278L131.744,231.702L131.738,232.124L131.728,232.546L131.716,232.968L131.702,233.389L131.684,233.809L131.664,234.228L131.642,234.647L131.617,235.065L131.589,235.482L131.558,235.899L131.525,236.315L131.49,236.73L131.452,237.144L131.411,237.558L131.368,237.971L131.322,238.383L131.273,238.794L131.222,239.205L131.169,239.615L131.113,240.024L131.054,240.432L130.993,240.839L130.93,241.246L130.864,241.652L130.795,242.057L130.724,242.461L130.651,242.864L130.575,243.266L130.497,243.668L130.416,244.069L130.333,244.468L130.247,244.867L130.159,245.265L130.069,245.662L129.976,246.059L129.881,246.454L129.783,246.848L129.683,247.242L129.581,247.634L129.476,248.025L129.369,248.416L129.259,248.805L129.148,249.194L129.033,249.582L128.917,249.968L128.798,250.354L128.677,250.738L128.554,251.122L128.428,251.504L128.3,251.886L128.17,252.266L128.038,252.646L127.903,253.024L127.766,253.401L127.627,253.777L127.486,254.153L127.342,254.527L127.196,254.899L127.048,255.271L126.898,255.642L126.746,256.012L126.591,256.38L126.434,256.747L126.275,257.113L126.114,257.478L125.951,257.842L125.785,258.205L125.618,258.566L125.448,258.927L125.276,259.286L125.102,259.643L124.927,260L124.748,260.356L124.568,260.71L124.386,261.063L124.202,261.414L124.015,261.765L123.827,262.114L123.636,262.462L123.444,262.809L123.249,263.154L123.053,263.498L122.854,263.841L122.654,264.182L122.451,264.523L122.246,264.861L122.04,265.199L121.831,265.535L121.621,265.87L121.408,266.203L121.194,266.535L120.978,266.866L120.759,267.195L120.539,267.523L120.317,267.85L120.093,268.175L119.867,268.499L119.639,268.821L119.41,269.142L119.178,269.461L118.945,269.779L118.709,270.096L118.472,270.411L118.233,270.724L117.993,271.036L117.75,271.347L117.505,271.656L117.259,271.964L117.011,272.27L116.761,272.574L116.51,272.877L116.256,273.179L116.001,273.479L115.744,273.777L115.485,274.074L115.225,274.369L114.963,274.663L114.699,274.955L114.433,275.246L114.166,275.535L113.896,275.822L113.626,276.108L113.353,276.392L113.079,276.674L112.803,276.955L112.526,277.234L112.247,277.512L111.966,277.787L111.683,278.062L111.399,278.334L111.114,278.605L110.826,278.874L110.537,279.141L110.247,279.407L109.955,279.671L109.661,279.933L109.366,280.194L109.069,280.452L108.77,280.709L108.471,280.964L108.169,281.218L107.866,281.47L107.561,281.719L107.255,281.967L106.948,282.214L106.639,282.458L106.328,282.701L106.016,282.942L105.702,283.181L105.387,283.418L105.071,283.653L104.753,283.887L104.433,284.118L104.113,284.348L103.79,284.576L103.467,284.801L103.141,285.025L102.815,285.248L102.487,285.468L102.158,285.686L101.827,285.902L101.495,286.117L101.162,286.329L100.827,286.54L100.491,286.748L100.153,286.955L99.814,287.159L99.474,287.362L99.133,287.563L98.79,287.761L98.446,287.958L98.1,288.152L97.754,288.345L97.406,288.535L97.057,288.724L96.706,288.91L96.354,289.094L96.001,289.277L95.647,289.457L95.292,289.635L94.935,289.811L94.577,289.985L94.218,290.157L93.858,290.326L93.496,290.494L93.134,290.659L92.77,290.822L92.405,290.983L92.039,291.142L91.672,291.299L91.303,291.454L90.934,291.606L90.563,291.757L90.191,291.905L89.818,292.05L89.444,292.194L89.069,292.335L88.693,292.475L88.316,292.611L87.937,292.746L87.558,292.879L87.178,293.009L86.796,293.137L86.414,293.262L86.03,293.386L85.645,293.507L85.26,293.625L84.873,293.742L84.486,293.856L84.097,293.968L83.708,294.077L83.317,294.184L82.926,294.289L82.533,294.391L82.14,294.491L81.746,294.589L81.35,294.684L80.954,294.777L80.557,294.867L80.159,294.955L79.76,295.041L79.36,295.124L78.96,295.205L78.558,295.283L78.156,295.359L77.753,295.433L77.348,295.504L76.943,295.572L76.538,295.638L76.131,295.702L75.724,295.763L75.315,295.821L74.906,295.877L74.497,295.931L74.086,295.982L73.675,296.03L73.262,296.076L72.849,296.119L72.436,296.16L72.021,296.198L71.606,296.234L71.19,296.267L70.774,296.297L70.356,296.325L69.938,296.35L69.52,296.373L69.1,296.393L68.68,296.41L68.259,296.425L67.838,296.437L67.416,296.446L66.993,296.453L66.57,296.457L66.146,296.458L65.722,296.457L65.298,296.453L64.876,296.446L64.454,296.437L64.032,296.425L63.611,296.41L63.191,296.393L62.772,296.373L62.353,296.35L61.935,296.325L61.518,296.297L61.101,296.267L60.685,296.234L60.27,296.198L59.856,296.16L59.442,296.119L59.029,296.076L58.617,296.03L58.206,295.982L57.795,295.931L57.385,295.877L56.976,295.821L56.568,295.763L56.161,295.702L55.754,295.638L55.348,295.572L54.943,295.504L54.539,295.433L54.136,295.359L53.734,295.283L53.332,295.205L52.931,295.124L52.532,295.041L52.133,294.955L51.735,294.867L51.338,294.777L50.941,294.684L50.546,294.589L50.152,294.491L49.758,294.391L49.366,294.289L48.975,294.184L48.584,294.077L48.195,293.968L47.806,293.856L47.418,293.742L47.032,293.625L46.646,293.507L46.262,293.386L45.878,293.262L45.496,293.137L45.114,293.009L44.734,292.879L44.354,292.746L43.976,292.611L43.599,292.475L43.223,292.335L42.847,292.194L42.473,292.05L42.101,291.905L41.729,291.757L41.358,291.606L40.988,291.454L40.62,291.299L40.253,291.142L39.887,290.983L39.522,290.822L39.158,290.659L38.795,290.494L38.434,290.326L38.073,290.157L37.714,289.985L37.357,289.811L37,289.635L36.644,289.457L36.29,289.277L35.937,289.094L35.586,288.91L35.235,288.724L34.886,288.535L34.538,288.345L34.191,288.152L33.846,287.958L33.502,287.761L33.159,287.563L32.818,287.362L32.477,287.159L32.139,286.955L31.801,286.748L31.465,286.54L31.13,286.329L30.797,286.117L30.465,285.902L30.134,285.686L29.805,285.468L29.477,285.248L29.15,285.025L28.825,284.801L28.501,284.576L28.179,284.348L27.858,284.118L27.539,283.887L27.221,283.653L26.904,283.418L26.589,283.181L26.276,282.942L25.964,282.701L25.653,282.458L25.344,282.214L25.036,281.967L24.73,281.719L24.426,281.47L24.123,281.218L23.821,280.964L23.521,280.709L23.223,280.452L22.926,280.194L22.631,279.933L22.337,279.671L22.045,279.407L21.754,279.141L21.465,278.874L21.178,278.605L20.892,278.334L20.608,278.062L20.326,277.787L20.045,277.512L19.766,277.234L19.488,276.955L19.213,276.674L18.938,276.392L18.666,276.108L18.395,275.822L18.126,275.535L17.859,275.246L17.593,274.955L17.329,274.663L17.067,274.369L16.806,274.074L16.548,273.777L16.291,273.479L16.036,273.179L15.782,272.877L15.53,272.574L15.281,272.27L15.033,271.964L14.786,271.656L14.542,271.347L14.299,271.036L14.058,270.724L13.819,270.411L13.582,270.096L13.347,269.779L13.113,269.461L12.882,269.142L12.652,268.821L12.424,268.499L12.199,268.175L11.975,267.85L11.752,267.523L11.532,267.195L11.314,266.866L11.098,266.535L10.883,266.203L10.671,265.87L10.46,265.535L10.252,265.199L10.045,264.861L9.841,264.523L9.638,264.182L9.437,263.841L9.239,263.498L9.042,263.154L8.848,262.809L8.655,262.462L8.465,262.114L8.276,261.765L8.09,261.414L7.906,261.063L7.723,260.71L7.543,260.356L7.365,260L7.189,259.643L7.015,259.286L6.844,258.927L6.674,258.566L6.506,258.205L6.341,257.842L6.178,257.478L6.017,257.113L5.858,256.747L5.701,256.38L5.546,256.012L5.394,255.642L5.243,255.271L5.095,254.899L4.95,254.527L4.806,254.153L4.665,253.777L4.525,253.401L4.389,253.024L4.254,252.646L4.121,252.266L3.991,251.886L3.863,251.504L3.738,251.122L3.614,250.738L3.493,250.354L3.375,249.968L3.258,249.582L3.144,249.194L3.032,248.805L2.923,248.416L2.816,248.025L2.711,247.634L2.609,247.242L2.509,246.848L2.411,246.454L2.316,246.059L2.223,245.662L2.133,245.265L2.045,244.867L1.959,244.468L1.876,244.069L1.795,243.668L1.717,243.266L1.641,242.864L1.567,242.461L1.496,242.057L1.428,241.652L1.362,241.246L1.298,240.839L1.237,240.432L1.179,240.024L1.123,239.615L1.069,239.205L1.018,238.794L0.97,238.383L0.924,237.971L0.881,237.558L0.84,237.144L0.802,236.73L0.766,236.315L0.733,235.899L0.703,235.482L0.675,235.065L0.65,234.647L0.627,234.228L0.607,233.809L0.59,233.389L0.575,232.968L0.563,232.546L0.554,232.124L0.547,231.702L0.543,231.278L0.542,230.854L0.543,230.43L0.547,230.007L0.554,229.584L0.563,229.162L0.575,228.741L0.59,228.32L0.607,227.9L0.627,227.48L0.65,227.062L0.675,226.644L0.703,226.226L0.733,225.81L0.766,225.394L0.802,224.979L0.84,224.564L0.881,224.151L0.924,223.738L0.97,223.325L1.018,222.914L1.069,222.503L1.123,222.094L1.179,221.685L1.237,221.276L1.298,220.869L1.362,220.462L1.428,220.057L1.496,219.652L1.567,219.247L1.641,218.844L1.717,218.442L1.795,218.04L1.876,217.64L1.959,217.24L2.045,216.841L2.133,216.443L2.223,216.046L2.316,215.65L2.411,215.255L2.509,214.86L2.609,214.467L2.711,214.074L2.816,213.683L2.923,213.292L3.032,212.903L3.144,212.514L3.258,212.127L3.375,211.74L3.493,211.355L3.614,210.97L3.738,210.586L3.863,210.204L3.991,209.822L4.121,209.442L4.254,209.063L4.389,208.684L4.525,208.307L4.665,207.931L4.806,207.556L4.95,207.182L5.095,206.809L5.243,206.437L5.394,206.066L5.546,205.697L5.701,205.328L5.858,204.961L6.017,204.595L6.178,204.23L6.341,203.866L6.506,203.504L6.674,203.142L6.844,202.782L7.015,202.423L7.189,202.065L7.365,201.708L7.543,201.353L7.723,200.999L7.906,200.646L8.09,200.294L8.276,199.943L8.465,199.594L8.655,199.246L8.848,198.9L9.042,198.554L9.239,198.21L9.437,197.867L9.638,197.526L9.841,197.186L10.045,196.847L10.252,196.509L10.46,196.173L10.671,195.838L10.883,195.505L11.098,195.173L11.314,194.842L11.532,194.513L11.752,194.185L11.975,193.859L12.199,193.533L12.424,193.21L12.652,192.887L12.882,192.567L13.113,192.247L13.347,191.929L13.582,191.613L13.819,191.298L14.058,190.984L14.299,190.672L14.542,190.361L14.786,190.052L15.033,189.745L15.281,189.439L15.53,189.134L15.782,188.831L16.036,188.529L16.291,188.23L16.548,187.931L16.806,187.634L17.067,187.339L17.329,187.045L17.593,186.753L17.859,186.463L18.126,186.174L18.395,185.886L18.666,185.601L18.938,185.317L19.213,185.034L19.488,184.753L19.766,184.474L20.045,184.197L20.326,183.921L20.608,183.647L20.892,183.374L21.178,183.104L21.465,182.834L21.754,182.567L22.045,182.301L22.337,182.037L22.631,181.775L22.926,181.515L23.223,181.256L23.521,180.999L23.821,180.744L24.123,180.49L24.426,180.239L24.73,179.989L25.036,179.741L25.344,179.495L25.653,179.25L25.964,179.007L26.276,178.767L26.589,178.528L26.904,178.291L27.221,178.055L27.539,177.822L27.858,177.59L28.179,177.361L28.501,177.133L28.825,176.907L29.15,176.683L29.477,176.461L29.805,176.241L30.134,176.022L30.465,175.806L30.797,175.592L31.13,175.379L31.465,175.169L31.801,174.96L32.139,174.754L32.477,174.549L32.818,174.346L33.159,174.146L33.502,173.947L33.846,173.751L34.191,173.556L34.538,173.364L34.886,173.173L35.235,172.985L35.586,172.798L35.937,172.614L36.29,172.432L36.644,172.252L37,172.074L37.357,171.898L37.714,171.724L38.073,171.552L38.434,171.382L38.795,171.215L39.158,171.049L39.522,170.886L39.887,170.725L40.253,170.566L40.62,170.409L40.988,170.255L41.358,170.102L41.729,169.952L42.101,169.804L42.473,169.658L42.847,169.514L43.223,169.373L43.599,169.234L43.976,169.097L44.354,168.962L44.734,168.83L45.114,168.7L45.496,168.572L45.878,168.446L46.262,168.323L46.646,168.202L47.032,168.083L47.418,167.967L47.806,167.852L48.195,167.741L48.584,167.631L48.975,167.524L49.366,167.419L49.758,167.317L50.152,167.217L50.546,167.119L50.941,167.024L51.338,166.931L51.735,166.841L52.133,166.753L52.532,166.667L52.931,166.584L53.332,166.503L53.734,166.425L54.136,166.349L54.539,166.276L54.943,166.205L55.348,166.136L55.754,166.07L56.161,166.007L56.568,165.946L56.976,165.887L57.385,165.831L57.795,165.778L58.206,165.727L58.617,165.678L59.029,165.632L59.442,165.589L59.856,165.548L60.27,165.51L60.685,165.475L61.101,165.442L61.518,165.411L61.935,165.383L62.353,165.358L62.772,165.336L63.191,165.316L63.611,165.298L64.032,165.284L64.454,165.272L64.876,165.262L65.298,165.256L65.722,165.252L66.146,165.25L66.57,165.252ZM65.741,168.252L65.337,168.255L64.933,168.262L64.53,168.271L64.127,168.282L63.726,168.296L63.325,168.313L62.924,168.332L62.524,168.353L62.125,168.377L61.727,168.404L61.329,168.433L60.932,168.465L60.536,168.498L60.141,168.535L59.746,168.574L59.352,168.615L58.958,168.659L58.566,168.705L58.174,168.754L57.783,168.805L57.393,168.858L57.003,168.914L56.614,168.972L56.226,169.033L55.839,169.096L55.453,169.161L55.067,169.229L54.683,169.299L54.299,169.371L53.916,169.446L53.533,169.523L53.152,169.602L52.771,169.684L52.392,169.768L52.013,169.854L51.635,169.943L51.258,170.034L50.882,170.127L50.507,170.222L50.132,170.32L49.759,170.42L49.386,170.522L49.015,170.626L48.644,170.733L48.275,170.842L47.906,170.953L47.538,171.066L47.171,171.182L46.805,171.299L46.44,171.419L46.076,171.541L45.714,171.665L45.352,171.792L44.991,171.92L44.631,172.051L44.272,172.183L43.914,172.318L43.557,172.455L43.202,172.594L42.847,172.736L42.493,172.879L42.141,173.024L41.789,173.172L41.439,173.321L41.09,173.473L40.742,173.627L40.394,173.783L40.048,173.94L39.704,174.1L39.36,174.262L39.017,174.426L38.676,174.592L38.336,174.76L37.996,174.93L37.658,175.102L37.322,175.275L36.986,175.451L36.652,175.629L36.318,175.809L35.986,175.991L35.656,176.174L35.326,176.36L34.998,176.548L34.671,176.737L34.345,176.929L34.02,177.122L33.697,177.317L33.375,177.514L33.054,177.713L32.735,177.914L32.416,178.117L32.099,178.321L31.784,178.528L31.47,178.736L31.157,178.946L30.845,179.158L30.535,179.372L30.226,179.588L29.918,179.805L29.612,180.024L29.307,180.245L29.003,180.468L28.701,180.693L28.401,180.919L28.101,181.147L27.803,181.377L27.507,181.609L27.212,181.842L26.918,182.077L26.626,182.314L26.335,182.552L26.046,182.793L25.758,183.035L25.472,183.278L25.187,183.524L24.904,183.77L24.622,184.019L24.342,184.269L24.063,184.521L23.785,184.775L23.51,185.03L23.235,185.287L22.963,185.546L22.691,185.806L22.422,186.067L22.154,186.331L21.887,186.596L21.622,186.862L21.359,187.13L21.097,187.4L20.837,187.671L20.579,187.944L20.322,188.218L20.067,188.494L19.813,188.771L19.561,189.05L19.311,189.33L19.062,189.612L18.815,189.896L18.57,190.18L18.326,190.467L18.084,190.754L17.844,191.044L17.606,191.334L17.369,191.627L17.134,191.92L16.9,192.215L16.669,192.512L16.439,192.81L16.211,193.109L15.984,193.41L15.76,193.712L15.537,194.015L15.316,194.32L15.097,194.626L14.879,194.934L14.664,195.243L14.45,195.553L14.238,195.865L14.028,196.178L13.82,196.492L13.613,196.808L13.408,197.125L13.206,197.443L13.005,197.762L12.806,198.083L12.609,198.405L12.414,198.729L12.22,199.053L12.029,199.379L11.839,199.706L11.652,200.034L11.466,200.364L11.282,200.695L11.101,201.027L10.921,201.36L10.743,201.694L10.567,202.03L10.393,202.367L10.221,202.705L10.051,203.044L9.884,203.384L9.718,203.726L9.554,204.068L9.392,204.412L9.232,204.757L9.074,205.103L8.918,205.45L8.765,205.798L8.613,206.147L8.464,206.498L8.316,206.849L8.171,207.202L8.027,207.555L7.886,207.91L7.747,208.266L7.61,208.623L7.475,208.98L7.342,209.339L7.212,209.699L7.083,210.06L6.957,210.422L6.833,210.785L6.711,211.149L6.591,211.514L6.473,211.879L6.358,212.246L6.245,212.614L6.134,212.983L6.025,213.353L5.918,213.723L5.814,214.095L5.712,214.467L5.612,214.841L5.514,215.215L5.419,215.59L5.325,215.966L5.235,216.343L5.146,216.721L5.06,217.1L4.976,217.48L4.894,217.86L4.815,218.242L4.738,218.624L4.663,219.007L4.591,219.391L4.52,219.776L4.453,220.161L4.387,220.547L4.324,220.935L4.264,221.323L4.206,221.711L4.15,222.101L4.096,222.491L4.045,222.882L3.997,223.274L3.951,223.667L3.907,224.06L3.865,224.454L3.827,224.849L3.79,225.244L3.756,225.641L3.725,226.038L3.696,226.435L3.669,226.834L3.645,227.233L3.623,227.632L3.604,228.033L3.588,228.434L3.574,228.836L3.562,229.238L3.553,229.641L3.547,230.045L3.543,230.449L3.542,230.854L3.543,231.259L3.547,231.663L3.553,232.067L3.562,232.47L3.574,232.873L3.588,233.274L3.604,233.676L3.623,234.076L3.645,234.476L3.669,234.875L3.696,235.273L3.725,235.671L3.756,236.068L3.79,236.464L3.827,236.859L3.865,237.254L3.907,237.648L3.951,238.042L3.997,238.434L4.045,238.826L4.096,239.217L4.15,239.607L4.206,239.997L4.264,240.386L4.324,240.774L4.387,241.161L4.453,241.547L4.52,241.933L4.591,242.317L4.663,242.701L4.738,243.084L4.815,243.467L4.894,243.848L4.976,244.229L5.06,244.608L5.146,244.987L5.235,245.365L5.325,245.742L5.419,246.118L5.514,246.493L5.612,246.868L5.712,247.241L5.814,247.614L5.918,247.985L6.025,248.356L6.134,248.725L6.245,249.094L6.358,249.462L6.473,249.829L6.591,250.195L6.711,250.56L6.833,250.924L6.957,251.286L7.083,251.648L7.212,252.009L7.342,252.369L7.475,252.728L7.61,253.086L7.747,253.443L7.886,253.798L8.027,254.153L8.171,254.507L8.316,254.859L8.464,255.211L8.613,255.561L8.765,255.91L8.918,256.258L9.074,256.606L9.232,256.952L9.392,257.296L9.554,257.64L9.718,257.983L9.884,258.324L10.051,258.664L10.221,259.004L10.393,259.342L10.567,259.678L10.743,260.014L10.921,260.348L11.101,260.682L11.282,261.014L11.466,261.344L11.652,261.674L11.839,262.002L12.029,262.329L12.22,262.655L12.414,262.98L12.609,263.303L12.806,263.625L13.005,263.946L13.206,264.265L13.408,264.584L13.613,264.901L13.82,265.216L14.028,265.531L14.238,265.843L14.45,266.155L14.664,266.465L14.879,266.774L15.097,267.082L15.316,267.388L15.537,267.693L15.76,267.997L15.984,268.299L16.211,268.599L16.439,268.899L16.669,269.197L16.9,269.493L17.134,269.788L17.369,270.082L17.606,270.374L17.844,270.665L18.084,270.954L18.326,271.242L18.57,271.528L18.815,271.813L19.062,272.096L19.311,272.378L19.561,272.658L19.813,272.937L20.067,273.215L20.322,273.49L20.579,273.765L20.837,274.037L21.097,274.309L21.359,274.578L21.622,274.846L21.887,275.113L22.154,275.378L22.422,275.641L22.691,275.903L22.963,276.163L23.235,276.421L23.51,276.678L23.785,276.933L24.063,277.187L24.342,277.439L24.622,277.689L24.904,277.938L25.187,278.185L25.472,278.43L25.758,278.674L26.046,278.916L26.335,279.156L26.626,279.394L26.918,279.631L27.212,279.866L27.507,280.1L27.803,280.331L28.101,280.561L28.401,280.789L28.701,281.016L29.003,281.24L29.307,281.463L29.612,281.684L29.918,281.903L30.226,282.121L30.535,282.336L30.845,282.55L31.157,282.762L31.47,282.972L31.784,283.18L32.099,283.387L32.416,283.592L32.735,283.794L33.054,283.995L33.375,284.194L33.697,284.391L34.02,284.586L34.345,284.78L34.671,284.971L34.998,285.161L35.326,285.348L35.656,285.534L35.986,285.718L36.318,285.899L36.652,286.079L36.986,286.257L37.322,286.433L37.658,286.607L37.996,286.779L38.336,286.949L38.676,287.117L39.017,287.282L39.36,287.446L39.704,287.608L40.048,287.768L40.394,287.926L40.742,288.082L41.09,288.235L41.439,288.387L41.789,288.537L42.141,288.684L42.493,288.829L42.847,288.973L43.202,289.114L43.557,289.253L43.914,289.39L44.272,289.525L44.631,289.658L44.991,289.788L45.352,289.917L45.714,290.043L46.076,290.167L46.44,290.289L46.805,290.409L47.171,290.527L47.538,290.642L47.906,290.755L48.275,290.866L48.644,290.975L49.015,291.082L49.386,291.186L49.759,291.288L50.132,291.388L50.507,291.486L50.882,291.581L51.258,291.675L51.635,291.765L52.013,291.854L52.392,291.94L52.771,292.024L53.152,292.106L53.533,292.185L53.916,292.262L54.299,292.337L54.683,292.409L55.067,292.48L55.453,292.547L55.839,292.613L56.226,292.676L56.614,292.736L57.003,292.794L57.393,292.85L57.783,292.904L58.174,292.955L58.566,293.003L58.958,293.049L59.352,293.093L59.746,293.135L60.14,293.173L60.536,293.21L60.932,293.244L61.329,293.275L61.727,293.304L62.125,293.331L62.524,293.355L62.924,293.377L63.324,293.396L63.726,293.412L64.127,293.426L64.53,293.438L64.933,293.447L65.337,293.453L65.741,293.457L66.146,293.458L66.551,293.457L66.955,293.453L67.359,293.447L67.762,293.438L68.164,293.426L68.566,293.412L68.967,293.396L69.368,293.377L69.767,293.355L70.166,293.331L70.565,293.304L70.962,293.275L71.359,293.244L71.756,293.21L72.151,293.173L72.546,293.135L72.94,293.093L73.333,293.049L73.726,293.003L74.118,292.955L74.509,292.904L74.899,292.85L75.289,292.794L75.677,292.736L76.065,292.676L76.453,292.613L76.839,292.547L77.224,292.48L77.609,292.409L77.993,292.337L78.376,292.262L78.758,292.185L79.14,292.106L79.52,292.024L79.9,291.94L80.279,291.854L80.657,291.765L81.034,291.675L81.41,291.581L81.785,291.486L82.159,291.388L82.533,291.288L82.905,291.186L83.277,291.082L83.647,290.975L84.017,290.866L84.386,290.755L84.754,290.642L85.121,290.527L85.486,290.409L85.851,290.289L86.215,290.167L86.578,290.043L86.94,289.917L87.301,289.788L87.661,289.658L88.02,289.525L88.377,289.39L88.734,289.253L89.09,289.114L89.445,288.973L89.798,288.829L90.151,288.684L90.502,288.537L90.853,288.387L91.202,288.235L91.55,288.082L91.897,287.926L92.243,287.768L92.588,287.608L92.932,287.446L93.274,287.282L93.616,287.117L93.956,286.949L94.295,286.779L94.633,286.607L94.97,286.433L95.306,286.257L95.64,286.079L95.973,285.899L96.305,285.718L96.636,285.534L96.966,285.348L97.294,285.161L97.621,284.971L97.947,284.78L98.271,284.586L98.595,284.391L98.917,284.194L99.238,283.995L99.557,283.794L99.875,283.592L100.192,283.387L100.508,283.18L100.822,282.972L101.135,282.762L101.447,282.55L101.757,282.336L102.066,282.121L102.374,281.903L102.68,281.684L102.985,281.463L103.288,281.24L103.59,281.016L103.891,280.789L104.19,280.561L104.488,280.331L104.785,280.1L105.08,279.866L105.373,279.631L105.665,279.394L105.956,279.156L106.246,278.916L106.533,278.674L106.82,278.43L107.104,278.185L107.388,277.938L107.67,277.689L107.95,277.439L108.229,277.187L108.506,276.933L108.782,276.678L109.056,276.421L109.329,276.163L109.6,275.903L109.87,275.641L110.138,275.378L110.404,275.113L110.669,274.846L110.933,274.578L111.194,274.309L111.454,274.037L111.713,273.765L111.97,273.49L112.225,273.215L112.479,272.937L112.731,272.658L112.981,272.378L113.23,272.096L113.476,271.813L113.722,271.528L113.965,271.242L114.207,270.954L114.448,270.665L114.686,270.374L114.923,270.082L115.158,269.788L115.391,269.493L115.623,269.197L115.853,268.899L116.081,268.599L116.307,268.299L116.532,267.997L116.755,267.693L116.976,267.388L117.195,267.082L117.412,266.774L117.628,266.465L117.842,266.155L118.054,265.843L118.264,265.531L118.472,265.216L118.679,264.901L118.883,264.584L119.086,264.265L119.287,263.946L119.486,263.625L119.683,263.303L119.878,262.98L120.071,262.655L120.263,262.329L120.452,262.002L120.64,261.674L120.826,261.344L121.009,261.014L121.191,260.682L121.371,260.348L121.549,260.014L121.725,259.678L121.898,259.342L122.07,259.004L122.24,258.664L122.408,258.324L122.574,257.983L122.738,257.64L122.9,257.296L123.06,256.952L123.217,256.606L123.373,256.258L123.527,255.91L123.679,255.561L123.828,255.211L123.976,254.859L124.121,254.507L124.264,254.153L124.406,253.798L124.545,253.443L124.682,253.086L124.817,252.728L124.949,252.369L125.08,252.009L125.208,251.648L125.335,251.286L125.459,250.923L125.581,250.56L125.701,250.195L125.818,249.829L125.934,249.462L126.047,249.094L126.158,248.726L126.267,248.356L126.374,247.985L126.478,247.614L126.58,247.241L126.68,246.868L126.778,246.493L126.873,246.118L126.966,245.742L127.057,245.365L127.146,244.987L127.232,244.608L127.316,244.229L127.398,243.848L127.477,243.467L127.554,243.084L127.629,242.701L127.701,242.317L127.771,241.933L127.839,241.547L127.904,241.161L127.967,240.774L128.028,240.386L128.086,239.997L128.142,239.608L128.195,239.217L128.246,238.826L128.295,238.434L128.341,238.042L128.385,237.648L128.426,237.254L128.465,236.859L128.502,236.464L128.535,236.068L128.567,235.671L128.596,235.273L128.623,234.875L128.647,234.476L128.668,234.076L128.687,233.676L128.704,233.274L128.718,232.873L128.729,232.47L128.738,232.067L128.745,231.664L128.748,231.259L128.75,230.854L128.748,230.449L128.745,230.045L128.738,229.641L128.729,229.238L128.718,228.836L128.704,228.434L128.687,228.033L128.668,227.632L128.647,227.233L128.623,226.834L128.596,226.435L128.567,226.038L128.535,225.641L128.502,225.244L128.465,224.849L128.426,224.454L128.385,224.06L128.341,223.667L128.295,223.274L128.246,222.882L128.195,222.491L128.142,222.101L128.086,221.711L128.028,221.323L127.967,220.935L127.904,220.547L127.839,220.161L127.771,219.776L127.701,219.391L127.629,219.007L127.554,218.624L127.477,218.242L127.398,217.86L127.316,217.48L127.232,217.1L127.146,216.721L127.057,216.343L126.966,215.966L126.873,215.59L126.778,215.215L126.68,214.841L126.58,214.467L126.478,214.095L126.374,213.723L126.267,213.353L126.158,212.983L126.047,212.614L125.934,212.246L125.818,211.879L125.701,211.514L125.581,211.149L125.459,210.785L125.335,210.422L125.208,210.06L125.08,209.699L124.949,209.339L124.817,208.98L124.682,208.623L124.545,208.266L124.406,207.91L124.264,207.555L124.121,207.202L123.976,206.849L123.828,206.498L123.679,206.147L123.527,205.798L123.373,205.45L123.217,205.103L123.06,204.757L122.9,204.412L122.738,204.068L122.574,203.726L122.408,203.384L122.24,203.044L122.07,202.705L121.898,202.367L121.725,202.03L121.549,201.694L121.371,201.36L121.191,201.027L121.009,200.695L120.826,200.364L120.64,200.034L120.452,199.706L120.263,199.379L120.071,199.053L119.878,198.729L119.683,198.405L119.486,198.083L119.287,197.762L119.086,197.443L118.883,197.125L118.679,196.808L118.472,196.492L118.264,196.178L118.054,195.865L117.842,195.553L117.628,195.243L117.412,194.934L117.195,194.626L116.976,194.32L116.755,194.015L116.532,193.712L116.307,193.41L116.081,193.109L115.853,192.81L115.623,192.512L115.391,192.215L115.158,191.92L114.923,191.627L114.686,191.334L114.448,191.044L114.207,190.755L113.965,190.467L113.722,190.18L113.476,189.896L113.23,189.612L112.981,189.33L112.731,189.05L112.479,188.771L112.225,188.494L111.97,188.218L111.713,187.944L111.454,187.671L111.194,187.4L110.933,187.13L110.669,186.862L110.404,186.596L110.138,186.331L109.87,186.067L109.6,185.806L109.329,185.546L109.056,185.287L108.782,185.03L108.506,184.775L108.229,184.521L107.95,184.269L107.67,184.019L107.388,183.77L107.104,183.524L106.82,183.278L106.533,183.035L106.246,182.793L105.956,182.552L105.666,182.314L105.373,182.077L105.08,181.842L104.785,181.609L104.488,181.377L104.19,181.147L103.891,180.919L103.59,180.693L103.288,180.468L102.985,180.245L102.68,180.024L102.374,179.805L102.066,179.588L101.757,179.372L101.447,179.158L101.135,178.946L100.822,178.736L100.508,178.528L100.192,178.321L99.875,178.117L99.557,177.914L99.238,177.713L98.917,177.514L98.595,177.317L98.271,177.122L97.947,176.929L97.621,176.737L97.294,176.548L96.966,176.36L96.636,176.174L96.305,175.991L95.973,175.809L95.64,175.629L95.306,175.451L94.97,175.275L94.633,175.102L94.295,174.93L93.956,174.76L93.616,174.592L93.274,174.426L92.932,174.262L92.588,174.1L92.243,173.94L91.897,173.783L91.55,173.627L91.202,173.473L90.853,173.321L90.502,173.172L90.151,173.024L89.798,172.879L89.445,172.736L89.09,172.594L88.734,172.455L88.377,172.318L88.02,172.183L87.661,172.051L87.301,171.92L86.94,171.792L86.578,171.665L86.215,171.541L85.851,171.419L85.486,171.299L85.121,171.182L84.754,171.066L84.386,170.953L84.017,170.842L83.647,170.733L83.277,170.626L82.905,170.522L82.533,170.42L82.159,170.32L81.785,170.222L81.41,170.127L81.034,170.034L80.657,169.943L80.279,169.854L79.9,169.768L79.52,169.684L79.14,169.602L78.758,169.523L78.376,169.446L77.993,169.371L77.609,169.299L77.224,169.229L76.839,169.161L76.453,169.096L76.065,169.033L75.677,168.972L75.289,168.914L74.899,168.858L74.509,168.805L74.118,168.754L73.726,168.705L73.333,168.659L72.94,168.615L72.546,168.574L72.151,168.535L71.756,168.498L71.359,168.465L70.962,168.433L70.565,168.404L70.166,168.377L69.767,168.353L69.368,168.332L68.967,168.313L68.566,168.296L68.164,168.282L67.762,168.271L67.359,168.262L66.955,168.255L66.551,168.252L66.146,168.25L65.741,168.252Z" style="fill:white;"/>
+ </g>
+ <g id="g4154" transform="matrix(1,0,0,1,-2.58446,2.58446)">
+ <path id="path4982" d="M104.215,201.977L42.438,263.755L33.245,254.562L95.023,192.785L104.215,201.977Z" style="fill:white;"/>
+ <path id="path4152" d="M104.215,254.562L95.023,263.755L33.245,201.977L42.438,192.785L104.215,254.562Z" style="fill:white;"/>
+ </g>
+ </g>
+</svg>
diff --git a/Swift/resources/icons/delivery-success.svg b/Swift/resources/icons/delivery-success.svg
new file mode 100644
index 0000000..faf6ae1
--- /dev/null
+++ b/Swift/resources/icons/delivery-success.svg
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" viewBox="0 0 133 133" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
+ <g id="Layer-1" transform="matrix(1,0,0,1,0,-164.708)">
+ <g id="path4233" transform="matrix(1.00826,0,0,1.00826,-0.546361,-1.90685)">
+ <circle cx="66.146" cy="230.854" r="65.604" style="fill:rgb(146,196,126);"/>
+ <path d="M66.57,165.252L66.993,165.256L67.416,165.262L67.838,165.272L68.259,165.284L68.68,165.298L69.1,165.316L69.52,165.336L69.938,165.358L70.356,165.383L70.774,165.411L71.19,165.442L71.606,165.475L72.021,165.51L72.436,165.548L72.849,165.589L73.262,165.632L73.675,165.678L74.086,165.727L74.497,165.778L74.906,165.831L75.315,165.887L75.724,165.946L76.131,166.007L76.538,166.07L76.943,166.136L77.348,166.205L77.753,166.276L78.156,166.349L78.558,166.425L78.96,166.503L79.36,166.584L79.76,166.667L80.159,166.753L80.557,166.841L80.954,166.931L81.35,167.024L81.746,167.119L82.14,167.217L82.533,167.317L82.926,167.419L83.317,167.524L83.708,167.631L84.097,167.741L84.486,167.852L84.873,167.967L85.26,168.083L85.645,168.202L86.03,168.323L86.414,168.446L86.796,168.572L87.178,168.7L87.558,168.83L87.937,168.962L88.316,169.097L88.693,169.234L89.069,169.373L89.444,169.514L89.818,169.658L90.191,169.804L90.563,169.952L90.934,170.102L91.303,170.255L91.672,170.409L92.039,170.566L92.405,170.725L92.77,170.886L93.134,171.049L93.496,171.215L93.858,171.382L94.218,171.552L94.577,171.724L94.935,171.898L95.292,172.074L95.647,172.252L96.001,172.432L96.354,172.614L96.706,172.798L97.057,172.985L97.406,173.173L97.754,173.364L98.1,173.556L98.446,173.751L98.79,173.947L99.133,174.146L99.474,174.346L99.814,174.549L100.153,174.754L100.491,174.96L100.827,175.169L101.162,175.379L101.495,175.592L101.827,175.806L102.158,176.022L102.487,176.241L102.815,176.461L103.141,176.683L103.467,176.907L103.79,177.133L104.113,177.361L104.433,177.59L104.753,177.822L105.071,178.055L105.387,178.291L105.702,178.528L106.016,178.767L106.328,179.007L106.639,179.25L106.948,179.495L107.255,179.741L107.561,179.989L107.866,180.239L108.169,180.49L108.471,180.744L108.77,180.999L109.069,181.256L109.366,181.515L109.661,181.775L109.955,182.037L110.247,182.301L110.537,182.567L110.826,182.834L111.114,183.104L111.399,183.374L111.683,183.647L111.966,183.921L112.247,184.197L112.526,184.474L112.803,184.753L113.079,185.034L113.353,185.317L113.626,185.601L113.896,185.886L114.166,186.174L114.433,186.463L114.699,186.753L114.963,187.045L115.225,187.339L115.485,187.634L115.744,187.931L116.001,188.23L116.256,188.529L116.51,188.831L116.761,189.134L117.011,189.439L117.259,189.745L117.505,190.052L117.75,190.361L117.993,190.672L118.233,190.984L118.472,191.298L118.709,191.613L118.945,191.929L119.178,192.247L119.41,192.567L119.639,192.887L119.867,193.21L120.093,193.533L120.317,193.859L120.539,194.185L120.759,194.513L120.978,194.842L121.194,195.173L121.408,195.505L121.621,195.838L121.831,196.173L122.04,196.509L122.246,196.847L122.451,197.186L122.654,197.526L122.854,197.867L123.053,198.21L123.249,198.554L123.444,198.9L123.636,199.246L123.827,199.594L124.015,199.943L124.202,200.294L124.386,200.646L124.568,200.999L124.748,201.353L124.927,201.708L125.102,202.065L125.276,202.423L125.448,202.782L125.618,203.142L125.785,203.504L125.951,203.866L126.114,204.23L126.275,204.595L126.434,204.961L126.591,205.328L126.746,205.697L126.898,206.066L127.048,206.437L127.196,206.809L127.342,207.182L127.486,207.556L127.627,207.931L127.766,208.307L127.903,208.684L128.038,209.063L128.17,209.442L128.3,209.822L128.428,210.204L128.554,210.586L128.677,210.97L128.798,211.355L128.917,211.74L129.033,212.127L129.148,212.514L129.259,212.903L129.369,213.292L129.476,213.683L129.581,214.074L129.683,214.467L129.783,214.86L129.881,215.255L129.976,215.65L130.069,216.046L130.159,216.443L130.247,216.841L130.333,217.24L130.416,217.64L130.497,218.04L130.575,218.442L130.651,218.844L130.724,219.247L130.795,219.652L130.864,220.057L130.93,220.462L130.993,220.869L131.054,221.276L131.113,221.685L131.169,222.094L131.222,222.503L131.273,222.914L131.322,223.325L131.368,223.738L131.411,224.151L131.452,224.564L131.49,224.979L131.525,225.394L131.558,225.81L131.589,226.226L131.617,226.644L131.642,227.062L131.664,227.48L131.684,227.9L131.702,228.32L131.716,228.741L131.728,229.162L131.738,229.584L131.744,230.007L131.748,230.43L131.75,230.854L131.748,231.278L131.744,231.702L131.738,232.124L131.728,232.546L131.716,232.968L131.702,233.389L131.684,233.809L131.664,234.228L131.642,234.647L131.617,235.065L131.589,235.482L131.558,235.899L131.525,236.315L131.49,236.73L131.452,237.144L131.411,237.558L131.368,237.971L131.322,238.383L131.273,238.794L131.222,239.205L131.169,239.615L131.113,240.024L131.054,240.432L130.993,240.839L130.93,241.246L130.864,241.652L130.795,242.057L130.724,242.461L130.651,242.864L130.575,243.266L130.497,243.668L130.416,244.069L130.333,244.468L130.247,244.867L130.159,245.265L130.069,245.662L129.976,246.059L129.881,246.454L129.783,246.848L129.683,247.242L129.581,247.634L129.476,248.025L129.369,248.416L129.259,248.805L129.148,249.194L129.033,249.582L128.917,249.968L128.798,250.354L128.677,250.738L128.554,251.122L128.428,251.504L128.3,251.886L128.17,252.266L128.038,252.646L127.903,253.024L127.766,253.401L127.627,253.777L127.486,254.153L127.342,254.527L127.196,254.899L127.048,255.271L126.898,255.642L126.746,256.012L126.591,256.38L126.434,256.747L126.275,257.113L126.114,257.478L125.951,257.842L125.785,258.205L125.618,258.566L125.448,258.927L125.276,259.286L125.102,259.643L124.927,260L124.748,260.356L124.568,260.71L124.386,261.063L124.202,261.414L124.015,261.765L123.827,262.114L123.636,262.462L123.444,262.809L123.249,263.154L123.053,263.498L122.854,263.841L122.654,264.182L122.451,264.523L122.246,264.861L122.04,265.199L121.831,265.535L121.621,265.87L121.408,266.203L121.194,266.535L120.978,266.866L120.759,267.195L120.539,267.523L120.317,267.85L120.093,268.175L119.867,268.499L119.639,268.821L119.41,269.142L119.178,269.461L118.945,269.779L118.709,270.096L118.472,270.411L118.233,270.724L117.993,271.036L117.75,271.347L117.505,271.656L117.259,271.964L117.011,272.27L116.761,272.574L116.51,272.877L116.256,273.179L116.001,273.479L115.744,273.777L115.485,274.074L115.225,274.369L114.963,274.663L114.699,274.955L114.433,275.246L114.166,275.535L113.896,275.822L113.626,276.108L113.353,276.392L113.079,276.674L112.803,276.955L112.526,277.234L112.247,277.512L111.966,277.787L111.683,278.062L111.399,278.334L111.114,278.605L110.826,278.874L110.537,279.141L110.247,279.407L109.955,279.671L109.661,279.933L109.366,280.194L109.069,280.452L108.77,280.709L108.471,280.964L108.169,281.218L107.866,281.47L107.561,281.719L107.255,281.967L106.948,282.214L106.639,282.458L106.328,282.701L106.016,282.942L105.702,283.181L105.387,283.418L105.071,283.653L104.753,283.887L104.433,284.118L104.113,284.348L103.79,284.576L103.467,284.801L103.141,285.025L102.815,285.248L102.487,285.468L102.158,285.686L101.827,285.902L101.495,286.117L101.162,286.329L100.827,286.54L100.491,286.748L100.153,286.955L99.814,287.159L99.474,287.362L99.133,287.563L98.79,287.761L98.446,287.958L98.1,288.152L97.754,288.345L97.406,288.535L97.057,288.724L96.706,288.91L96.354,289.094L96.001,289.277L95.647,289.457L95.292,289.635L94.935,289.811L94.577,289.985L94.218,290.157L93.858,290.326L93.496,290.494L93.134,290.659L92.77,290.822L92.405,290.983L92.039,291.142L91.672,291.299L91.303,291.454L90.934,291.606L90.563,291.757L90.191,291.905L89.818,292.05L89.444,292.194L89.069,292.335L88.693,292.475L88.316,292.611L87.937,292.746L87.558,292.879L87.178,293.009L86.796,293.137L86.414,293.262L86.03,293.386L85.645,293.507L85.26,293.625L84.873,293.742L84.486,293.856L84.097,293.968L83.708,294.077L83.317,294.184L82.926,294.289L82.533,294.391L82.14,294.491L81.746,294.589L81.35,294.684L80.954,294.777L80.557,294.867L80.159,294.955L79.76,295.041L79.36,295.124L78.96,295.205L78.558,295.283L78.156,295.359L77.753,295.433L77.348,295.504L76.943,295.572L76.538,295.638L76.131,295.702L75.724,295.763L75.315,295.821L74.906,295.877L74.497,295.931L74.086,295.982L73.675,296.03L73.262,296.076L72.849,296.119L72.436,296.16L72.021,296.198L71.606,296.234L71.19,296.267L70.774,296.297L70.356,296.325L69.938,296.35L69.52,296.373L69.1,296.393L68.68,296.41L68.259,296.425L67.838,296.437L67.416,296.446L66.993,296.453L66.57,296.457L66.146,296.458L65.722,296.457L65.298,296.453L64.876,296.446L64.454,296.437L64.032,296.425L63.611,296.41L63.191,296.393L62.772,296.373L62.353,296.35L61.935,296.325L61.518,296.297L61.101,296.267L60.685,296.234L60.27,296.198L59.856,296.16L59.442,296.119L59.029,296.076L58.617,296.03L58.206,295.982L57.795,295.931L57.385,295.877L56.976,295.821L56.568,295.763L56.161,295.702L55.754,295.638L55.348,295.572L54.943,295.504L54.539,295.433L54.136,295.359L53.734,295.283L53.332,295.205L52.931,295.124L52.532,295.041L52.133,294.955L51.735,294.867L51.338,294.777L50.941,294.684L50.546,294.589L50.152,294.491L49.758,294.391L49.366,294.289L48.975,294.184L48.584,294.077L48.195,293.968L47.806,293.856L47.418,293.742L47.032,293.625L46.646,293.507L46.262,293.386L45.878,293.262L45.496,293.137L45.114,293.009L44.734,292.879L44.354,292.746L43.976,292.611L43.599,292.475L43.223,292.335L42.847,292.194L42.473,292.05L42.101,291.905L41.729,291.757L41.358,291.606L40.988,291.454L40.62,291.299L40.253,291.142L39.887,290.983L39.522,290.822L39.158,290.659L38.795,290.494L38.434,290.326L38.073,290.157L37.714,289.985L37.357,289.811L37,289.635L36.644,289.457L36.29,289.277L35.937,289.094L35.586,288.91L35.235,288.724L34.886,288.535L34.538,288.345L34.191,288.152L33.846,287.958L33.502,287.761L33.159,287.563L32.818,287.362L32.477,287.159L32.139,286.955L31.801,286.748L31.465,286.54L31.13,286.329L30.797,286.117L30.465,285.902L30.134,285.686L29.805,285.468L29.477,285.248L29.15,285.025L28.825,284.801L28.501,284.576L28.179,284.348L27.858,284.118L27.539,283.887L27.221,283.653L26.904,283.418L26.589,283.181L26.276,282.942L25.964,282.701L25.653,282.458L25.344,282.214L25.036,281.967L24.73,281.719L24.426,281.47L24.123,281.218L23.821,280.964L23.521,280.709L23.223,280.452L22.926,280.194L22.631,279.933L22.337,279.671L22.045,279.407L21.754,279.141L21.465,278.874L21.178,278.605L20.892,278.334L20.608,278.062L20.326,277.787L20.045,277.512L19.766,277.234L19.488,276.955L19.213,276.674L18.938,276.392L18.666,276.108L18.395,275.822L18.126,275.535L17.859,275.246L17.593,274.955L17.329,274.663L17.067,274.369L16.806,274.074L16.548,273.777L16.291,273.479L16.036,273.179L15.782,272.877L15.53,272.574L15.281,272.27L15.033,271.964L14.786,271.656L14.542,271.347L14.299,271.036L14.058,270.724L13.819,270.411L13.582,270.096L13.347,269.779L13.113,269.461L12.882,269.142L12.652,268.821L12.424,268.499L12.199,268.175L11.975,267.85L11.752,267.523L11.532,267.195L11.314,266.866L11.098,266.535L10.883,266.203L10.671,265.87L10.46,265.535L10.252,265.199L10.045,264.861L9.841,264.523L9.638,264.182L9.437,263.841L9.239,263.498L9.042,263.154L8.848,262.809L8.655,262.462L8.465,262.114L8.276,261.765L8.09,261.414L7.906,261.063L7.723,260.71L7.543,260.356L7.365,260L7.189,259.643L7.015,259.286L6.844,258.927L6.674,258.566L6.506,258.205L6.341,257.842L6.178,257.478L6.017,257.113L5.858,256.747L5.701,256.38L5.546,256.012L5.394,255.642L5.243,255.271L5.095,254.899L4.95,254.527L4.806,254.153L4.665,253.777L4.525,253.401L4.389,253.024L4.254,252.646L4.121,252.266L3.991,251.886L3.863,251.504L3.738,251.122L3.614,250.738L3.493,250.354L3.375,249.968L3.258,249.582L3.144,249.194L3.032,248.805L2.923,248.416L2.816,248.025L2.711,247.634L2.609,247.242L2.509,246.848L2.411,246.454L2.316,246.059L2.223,245.662L2.133,245.265L2.045,244.867L1.959,244.468L1.876,244.069L1.795,243.668L1.717,243.266L1.641,242.864L1.567,242.461L1.496,242.057L1.428,241.652L1.362,241.246L1.298,240.839L1.237,240.432L1.179,240.024L1.123,239.615L1.069,239.205L1.018,238.794L0.97,238.383L0.924,237.971L0.881,237.558L0.84,237.144L0.802,236.73L0.766,236.315L0.733,235.899L0.703,235.482L0.675,235.065L0.65,234.647L0.627,234.228L0.607,233.809L0.59,233.389L0.575,232.968L0.563,232.546L0.554,232.124L0.547,231.702L0.543,231.278L0.542,230.854L0.543,230.43L0.547,230.007L0.554,229.584L0.563,229.162L0.575,228.741L0.59,228.32L0.607,227.9L0.627,227.48L0.65,227.062L0.675,226.644L0.703,226.226L0.733,225.81L0.766,225.394L0.802,224.979L0.84,224.564L0.881,224.151L0.924,223.738L0.97,223.325L1.018,222.914L1.069,222.503L1.123,222.094L1.179,221.685L1.237,221.276L1.298,220.869L1.362,220.462L1.428,220.057L1.496,219.652L1.567,219.247L1.641,218.844L1.717,218.442L1.795,218.04L1.876,217.64L1.959,217.24L2.045,216.841L2.133,216.443L2.223,216.046L2.316,215.65L2.411,215.255L2.509,214.86L2.609,214.467L2.711,214.074L2.816,213.683L2.923,213.292L3.032,212.903L3.144,212.514L3.258,212.127L3.375,211.74L3.493,211.355L3.614,210.97L3.738,210.586L3.863,210.204L3.991,209.822L4.121,209.442L4.254,209.063L4.389,208.684L4.525,208.307L4.665,207.931L4.806,207.556L4.95,207.182L5.095,206.809L5.243,206.437L5.394,206.066L5.546,205.697L5.701,205.328L5.858,204.961L6.017,204.595L6.178,204.23L6.341,203.866L6.506,203.504L6.674,203.142L6.844,202.782L7.015,202.423L7.189,202.065L7.365,201.708L7.543,201.353L7.723,200.999L7.906,200.646L8.09,200.294L8.276,199.943L8.465,199.594L8.655,199.246L8.848,198.9L9.042,198.554L9.239,198.21L9.437,197.867L9.638,197.526L9.841,197.186L10.045,196.847L10.252,196.509L10.46,196.173L10.671,195.838L10.883,195.505L11.098,195.173L11.314,194.842L11.532,194.513L11.752,194.185L11.975,193.859L12.199,193.533L12.424,193.21L12.652,192.887L12.882,192.567L13.113,192.247L13.347,191.929L13.582,191.613L13.819,191.298L14.058,190.984L14.299,190.672L14.542,190.361L14.786,190.052L15.033,189.745L15.281,189.439L15.53,189.134L15.782,188.831L16.036,188.529L16.291,188.23L16.548,187.931L16.806,187.634L17.067,187.339L17.329,187.045L17.593,186.753L17.859,186.463L18.126,186.174L18.395,185.886L18.666,185.601L18.938,185.317L19.213,185.034L19.488,184.753L19.766,184.474L20.045,184.197L20.326,183.921L20.608,183.647L20.892,183.374L21.178,183.104L21.465,182.834L21.754,182.567L22.045,182.301L22.337,182.037L22.631,181.775L22.926,181.515L23.223,181.256L23.521,180.999L23.821,180.744L24.123,180.49L24.426,180.239L24.73,179.989L25.036,179.741L25.344,179.495L25.653,179.25L25.964,179.007L26.276,178.767L26.589,178.528L26.904,178.291L27.221,178.055L27.539,177.822L27.858,177.59L28.179,177.361L28.501,177.133L28.825,176.907L29.15,176.683L29.477,176.461L29.805,176.241L30.134,176.022L30.465,175.806L30.797,175.592L31.13,175.379L31.465,175.169L31.801,174.96L32.139,174.754L32.477,174.549L32.818,174.346L33.159,174.146L33.502,173.947L33.846,173.751L34.191,173.556L34.538,173.364L34.886,173.173L35.235,172.985L35.586,172.798L35.937,172.614L36.29,172.432L36.644,172.252L37,172.074L37.357,171.898L37.714,171.724L38.073,171.552L38.434,171.382L38.795,171.215L39.158,171.049L39.522,170.886L39.887,170.725L40.253,170.566L40.62,170.409L40.988,170.255L41.358,170.102L41.729,169.952L42.101,169.804L42.473,169.658L42.847,169.514L43.223,169.373L43.599,169.234L43.976,169.097L44.354,168.962L44.734,168.83L45.114,168.7L45.496,168.572L45.878,168.446L46.262,168.323L46.646,168.202L47.032,168.083L47.418,167.967L47.806,167.852L48.195,167.741L48.584,167.631L48.975,167.524L49.366,167.419L49.758,167.317L50.152,167.217L50.546,167.119L50.941,167.024L51.338,166.931L51.735,166.841L52.133,166.753L52.532,166.667L52.931,166.584L53.332,166.503L53.734,166.425L54.136,166.349L54.539,166.276L54.943,166.205L55.348,166.136L55.754,166.07L56.161,166.007L56.568,165.946L56.976,165.887L57.385,165.831L57.795,165.778L58.206,165.727L58.617,165.678L59.029,165.632L59.442,165.589L59.856,165.548L60.27,165.51L60.685,165.475L61.101,165.442L61.518,165.411L61.935,165.383L62.353,165.358L62.772,165.336L63.191,165.316L63.611,165.298L64.032,165.284L64.454,165.272L64.876,165.262L65.298,165.256L65.722,165.252L66.146,165.25L66.57,165.252ZM65.741,168.252L65.337,168.255L64.933,168.262L64.53,168.271L64.127,168.282L63.726,168.296L63.325,168.313L62.924,168.332L62.524,168.353L62.125,168.377L61.727,168.404L61.329,168.433L60.932,168.465L60.536,168.498L60.141,168.535L59.746,168.574L59.352,168.615L58.958,168.659L58.566,168.705L58.174,168.754L57.783,168.805L57.393,168.858L57.003,168.914L56.614,168.972L56.226,169.033L55.839,169.096L55.453,169.161L55.067,169.229L54.683,169.299L54.299,169.371L53.916,169.446L53.533,169.523L53.152,169.602L52.771,169.684L52.392,169.768L52.013,169.854L51.635,169.943L51.258,170.034L50.882,170.127L50.507,170.222L50.132,170.32L49.759,170.42L49.386,170.522L49.015,170.626L48.644,170.733L48.275,170.842L47.906,170.953L47.538,171.066L47.171,171.182L46.805,171.299L46.44,171.419L46.076,171.541L45.714,171.665L45.352,171.792L44.991,171.92L44.631,172.051L44.272,172.183L43.914,172.318L43.557,172.455L43.202,172.594L42.847,172.736L42.493,172.879L42.141,173.024L41.789,173.172L41.439,173.321L41.09,173.473L40.742,173.627L40.394,173.783L40.048,173.94L39.704,174.1L39.36,174.262L39.017,174.426L38.676,174.592L38.336,174.76L37.996,174.93L37.658,175.102L37.322,175.275L36.986,175.451L36.652,175.629L36.318,175.809L35.986,175.991L35.656,176.174L35.326,176.36L34.998,176.548L34.671,176.737L34.345,176.929L34.02,177.122L33.697,177.317L33.375,177.514L33.054,177.713L32.735,177.914L32.416,178.117L32.099,178.321L31.784,178.528L31.47,178.736L31.157,178.946L30.845,179.158L30.535,179.372L30.226,179.588L29.918,179.805L29.612,180.024L29.307,180.245L29.003,180.468L28.701,180.693L28.401,180.919L28.101,181.147L27.803,181.377L27.507,181.609L27.212,181.842L26.918,182.077L26.626,182.314L26.335,182.552L26.046,182.793L25.758,183.035L25.472,183.278L25.187,183.524L24.904,183.77L24.622,184.019L24.342,184.269L24.063,184.521L23.785,184.775L23.51,185.03L23.235,185.287L22.963,185.546L22.691,185.806L22.422,186.067L22.154,186.331L21.887,186.596L21.622,186.862L21.359,187.13L21.097,187.4L20.837,187.671L20.579,187.944L20.322,188.218L20.067,188.494L19.813,188.771L19.561,189.05L19.311,189.33L19.062,189.612L18.815,189.896L18.57,190.18L18.326,190.467L18.084,190.754L17.844,191.044L17.606,191.334L17.369,191.627L17.134,191.92L16.9,192.215L16.669,192.512L16.439,192.81L16.211,193.109L15.984,193.41L15.76,193.712L15.537,194.015L15.316,194.32L15.097,194.626L14.879,194.934L14.664,195.243L14.45,195.553L14.238,195.865L14.028,196.178L13.82,196.492L13.613,196.808L13.408,197.125L13.206,197.443L13.005,197.762L12.806,198.083L12.609,198.405L12.414,198.729L12.22,199.053L12.029,199.379L11.839,199.706L11.652,200.034L11.466,200.364L11.282,200.695L11.101,201.027L10.921,201.36L10.743,201.694L10.567,202.03L10.393,202.367L10.221,202.705L10.051,203.044L9.884,203.384L9.718,203.726L9.554,204.068L9.392,204.412L9.232,204.757L9.074,205.103L8.918,205.45L8.765,205.798L8.613,206.147L8.464,206.498L8.316,206.849L8.171,207.202L8.027,207.555L7.886,207.91L7.747,208.266L7.61,208.623L7.475,208.98L7.342,209.339L7.212,209.699L7.083,210.06L6.957,210.422L6.833,210.785L6.711,211.149L6.591,211.514L6.473,211.879L6.358,212.246L6.245,212.614L6.134,212.983L6.025,213.353L5.918,213.723L5.814,214.095L5.712,214.467L5.612,214.841L5.514,215.215L5.419,215.59L5.325,215.966L5.235,216.343L5.146,216.721L5.06,217.1L4.976,217.48L4.894,217.86L4.815,218.242L4.738,218.624L4.663,219.007L4.591,219.391L4.52,219.776L4.453,220.161L4.387,220.547L4.324,220.935L4.264,221.323L4.206,221.711L4.15,222.101L4.096,222.491L4.045,222.882L3.997,223.274L3.951,223.667L3.907,224.06L3.865,224.454L3.827,224.849L3.79,225.244L3.756,225.641L3.725,226.038L3.696,226.435L3.669,226.834L3.645,227.233L3.623,227.632L3.604,228.033L3.588,228.434L3.574,228.836L3.562,229.238L3.553,229.641L3.547,230.045L3.543,230.449L3.542,230.854L3.543,231.259L3.547,231.663L3.553,232.067L3.562,232.47L3.574,232.873L3.588,233.274L3.604,233.676L3.623,234.076L3.645,234.476L3.669,234.875L3.696,235.273L3.725,235.671L3.756,236.068L3.79,236.464L3.827,236.859L3.865,237.254L3.907,237.648L3.951,238.042L3.997,238.434L4.045,238.826L4.096,239.217L4.15,239.607L4.206,239.997L4.264,240.386L4.324,240.774L4.387,241.161L4.453,241.547L4.52,241.933L4.591,242.317L4.663,242.701L4.738,243.084L4.815,243.467L4.894,243.848L4.976,244.229L5.06,244.608L5.146,244.987L5.235,245.365L5.325,245.742L5.419,246.118L5.514,246.493L5.612,246.868L5.712,247.241L5.814,247.614L5.918,247.985L6.025,248.356L6.134,248.725L6.245,249.094L6.358,249.462L6.473,249.829L6.591,250.195L6.711,250.56L6.833,250.924L6.957,251.286L7.083,251.648L7.212,252.009L7.342,252.369L7.475,252.728L7.61,253.086L7.747,253.443L7.886,253.798L8.027,254.153L8.171,254.507L8.316,254.859L8.464,255.211L8.613,255.561L8.765,255.91L8.918,256.258L9.074,256.606L9.232,256.952L9.392,257.296L9.554,257.64L9.718,257.983L9.884,258.324L10.051,258.664L10.221,259.004L10.393,259.342L10.567,259.678L10.743,260.014L10.921,260.348L11.101,260.682L11.282,261.014L11.466,261.344L11.652,261.674L11.839,262.002L12.029,262.329L12.22,262.655L12.414,262.98L12.609,263.303L12.806,263.625L13.005,263.946L13.206,264.265L13.408,264.584L13.613,264.901L13.82,265.216L14.028,265.531L14.238,265.843L14.45,266.155L14.664,266.465L14.879,266.774L15.097,267.082L15.316,267.388L15.537,267.693L15.76,267.997L15.984,268.299L16.211,268.599L16.439,268.899L16.669,269.197L16.9,269.493L17.134,269.788L17.369,270.082L17.606,270.374L17.844,270.665L18.084,270.954L18.326,271.242L18.57,271.528L18.815,271.813L19.062,272.096L19.311,272.378L19.561,272.658L19.813,272.937L20.067,273.215L20.322,273.49L20.579,273.765L20.837,274.037L21.097,274.309L21.359,274.578L21.622,274.846L21.887,275.113L22.154,275.378L22.422,275.641L22.691,275.903L22.963,276.163L23.235,276.421L23.51,276.678L23.785,276.933L24.063,277.187L24.342,277.439L24.622,277.689L24.904,277.938L25.187,278.185L25.472,278.43L25.758,278.674L26.046,278.916L26.335,279.156L26.626,279.394L26.918,279.631L27.212,279.866L27.507,280.1L27.803,280.331L28.101,280.561L28.401,280.789L28.701,281.016L29.003,281.24L29.307,281.463L29.612,281.684L29.918,281.903L30.226,282.121L30.535,282.336L30.845,282.55L31.157,282.762L31.47,282.972L31.784,283.18L32.099,283.387L32.416,283.592L32.735,283.794L33.054,283.995L33.375,284.194L33.697,284.391L34.02,284.586L34.345,284.78L34.671,284.971L34.998,285.161L35.326,285.348L35.656,285.534L35.986,285.718L36.318,285.899L36.652,286.079L36.986,286.257L37.322,286.433L37.658,286.607L37.996,286.779L38.336,286.949L38.676,287.117L39.017,287.282L39.36,287.446L39.704,287.608L40.048,287.768L40.394,287.926L40.742,288.082L41.09,288.235L41.439,288.387L41.789,288.537L42.141,288.684L42.493,288.829L42.847,288.973L43.202,289.114L43.557,289.253L43.914,289.39L44.272,289.525L44.631,289.658L44.991,289.788L45.352,289.917L45.714,290.043L46.076,290.167L46.44,290.289L46.805,290.409L47.171,290.527L47.538,290.642L47.906,290.755L48.275,290.866L48.644,290.975L49.015,291.082L49.386,291.186L49.759,291.288L50.132,291.388L50.507,291.486L50.882,291.581L51.258,291.675L51.635,291.765L52.013,291.854L52.392,291.94L52.771,292.024L53.152,292.106L53.533,292.185L53.916,292.262L54.299,292.337L54.683,292.409L55.067,292.48L55.453,292.547L55.839,292.613L56.226,292.676L56.614,292.736L57.003,292.794L57.393,292.85L57.783,292.904L58.174,292.955L58.566,293.003L58.958,293.049L59.352,293.093L59.746,293.135L60.14,293.173L60.536,293.21L60.932,293.244L61.329,293.275L61.727,293.304L62.125,293.331L62.524,293.355L62.924,293.377L63.324,293.396L63.726,293.412L64.127,293.426L64.53,293.438L64.933,293.447L65.337,293.453L65.741,293.457L66.146,293.458L66.551,293.457L66.955,293.453L67.359,293.447L67.762,293.438L68.164,293.426L68.566,293.412L68.967,293.396L69.368,293.377L69.767,293.355L70.166,293.331L70.565,293.304L70.962,293.275L71.359,293.244L71.756,293.21L72.151,293.173L72.546,293.135L72.94,293.093L73.333,293.049L73.726,293.003L74.118,292.955L74.509,292.904L74.899,292.85L75.289,292.794L75.677,292.736L76.065,292.676L76.453,292.613L76.839,292.547L77.224,292.48L77.609,292.409L77.993,292.337L78.376,292.262L78.758,292.185L79.14,292.106L79.52,292.024L79.9,291.94L80.279,291.854L80.657,291.765L81.034,291.675L81.41,291.581L81.785,291.486L82.159,291.388L82.533,291.288L82.905,291.186L83.277,291.082L83.647,290.975L84.017,290.866L84.386,290.755L84.754,290.642L85.121,290.527L85.486,290.409L85.851,290.289L86.215,290.167L86.578,290.043L86.94,289.917L87.301,289.788L87.661,289.658L88.02,289.525L88.377,289.39L88.734,289.253L89.09,289.114L89.445,288.973L89.798,288.829L90.151,288.684L90.502,288.537L90.853,288.387L91.202,288.235L91.55,288.082L91.897,287.926L92.243,287.768L92.588,287.608L92.932,287.446L93.274,287.282L93.616,287.117L93.956,286.949L94.295,286.779L94.633,286.607L94.97,286.433L95.306,286.257L95.64,286.079L95.973,285.899L96.305,285.718L96.636,285.534L96.966,285.348L97.294,285.161L97.621,284.971L97.947,284.78L98.271,284.586L98.595,284.391L98.917,284.194L99.238,283.995L99.557,283.794L99.875,283.592L100.192,283.387L100.508,283.18L100.822,282.972L101.135,282.762L101.447,282.55L101.757,282.336L102.066,282.121L102.374,281.903L102.68,281.684L102.985,281.463L103.288,281.24L103.59,281.016L103.891,280.789L104.19,280.561L104.488,280.331L104.785,280.1L105.08,279.866L105.373,279.631L105.665,279.394L105.956,279.156L106.246,278.916L106.533,278.674L106.82,278.43L107.104,278.185L107.388,277.938L107.67,277.689L107.95,277.439L108.229,277.187L108.506,276.933L108.782,276.678L109.056,276.421L109.329,276.163L109.6,275.903L109.87,275.641L110.138,275.378L110.404,275.113L110.669,274.846L110.933,274.578L111.194,274.309L111.454,274.037L111.713,273.765L111.97,273.49L112.225,273.215L112.479,272.937L112.731,272.658L112.981,272.378L113.23,272.096L113.476,271.813L113.722,271.528L113.965,271.242L114.207,270.954L114.448,270.665L114.686,270.374L114.923,270.082L115.158,269.788L115.391,269.493L115.623,269.197L115.853,268.899L116.081,268.599L116.307,268.299L116.532,267.997L116.755,267.693L116.976,267.388L117.195,267.082L117.412,266.774L117.628,266.465L117.842,266.155L118.054,265.843L118.264,265.531L118.472,265.216L118.679,264.901L118.883,264.584L119.086,264.265L119.287,263.946L119.486,263.625L119.683,263.303L119.878,262.98L120.071,262.655L120.263,262.329L120.452,262.002L120.64,261.674L120.826,261.344L121.009,261.014L121.191,260.682L121.371,260.348L121.549,260.014L121.725,259.678L121.898,259.342L122.07,259.004L122.24,258.664L122.408,258.324L122.574,257.983L122.738,257.64L122.9,257.296L123.06,256.952L123.217,256.606L123.373,256.258L123.527,255.91L123.679,255.561L123.828,255.211L123.976,254.859L124.121,254.507L124.264,254.153L124.406,253.798L124.545,253.443L124.682,253.086L124.817,252.728L124.949,252.369L125.08,252.009L125.208,251.648L125.335,251.286L125.459,250.923L125.581,250.56L125.701,250.195L125.818,249.829L125.934,249.462L126.047,249.094L126.158,248.726L126.267,248.356L126.374,247.985L126.478,247.614L126.58,247.241L126.68,246.868L126.778,246.493L126.873,246.118L126.966,245.742L127.057,245.365L127.146,244.987L127.232,244.608L127.316,244.229L127.398,243.848L127.477,243.467L127.554,243.084L127.629,242.701L127.701,242.317L127.771,241.933L127.839,241.547L127.904,241.161L127.967,240.774L128.028,240.386L128.086,239.997L128.142,239.608L128.195,239.217L128.246,238.826L128.295,238.434L128.341,238.042L128.385,237.648L128.426,237.254L128.465,236.859L128.502,236.464L128.535,236.068L128.567,235.671L128.596,235.273L128.623,234.875L128.647,234.476L128.668,234.076L128.687,233.676L128.704,233.274L128.718,232.873L128.729,232.47L128.738,232.067L128.745,231.664L128.748,231.259L128.75,230.854L128.748,230.449L128.745,230.045L128.738,229.641L128.729,229.238L128.718,228.836L128.704,228.434L128.687,228.033L128.668,227.632L128.647,227.233L128.623,226.834L128.596,226.435L128.567,226.038L128.535,225.641L128.502,225.244L128.465,224.849L128.426,224.454L128.385,224.06L128.341,223.667L128.295,223.274L128.246,222.882L128.195,222.491L128.142,222.101L128.086,221.711L128.028,221.323L127.967,220.935L127.904,220.547L127.839,220.161L127.771,219.776L127.701,219.391L127.629,219.007L127.554,218.624L127.477,218.242L127.398,217.86L127.316,217.48L127.232,217.1L127.146,216.721L127.057,216.343L126.966,215.966L126.873,215.59L126.778,215.215L126.68,214.841L126.58,214.467L126.478,214.095L126.374,213.723L126.267,213.353L126.158,212.983L126.047,212.614L125.934,212.246L125.818,211.879L125.701,211.514L125.581,211.149L125.459,210.785L125.335,210.422L125.208,210.06L125.08,209.699L124.949,209.339L124.817,208.98L124.682,208.623L124.545,208.266L124.406,207.91L124.264,207.555L124.121,207.202L123.976,206.849L123.828,206.498L123.679,206.147L123.527,205.798L123.373,205.45L123.217,205.103L123.06,204.757L122.9,204.412L122.738,204.068L122.574,203.726L122.408,203.384L122.24,203.044L122.07,202.705L121.898,202.367L121.725,202.03L121.549,201.694L121.371,201.36L121.191,201.027L121.009,200.695L120.826,200.364L120.64,200.034L120.452,199.706L120.263,199.379L120.071,199.053L119.878,198.729L119.683,198.405L119.486,198.083L119.287,197.762L119.086,197.443L118.883,197.125L118.679,196.808L118.472,196.492L118.264,196.178L118.054,195.865L117.842,195.553L117.628,195.243L117.412,194.934L117.195,194.626L116.976,194.32L116.755,194.015L116.532,193.712L116.307,193.41L116.081,193.109L115.853,192.81L115.623,192.512L115.391,192.215L115.158,191.92L114.923,191.627L114.686,191.334L114.448,191.044L114.207,190.755L113.965,190.467L113.722,190.18L113.476,189.896L113.23,189.612L112.981,189.33L112.731,189.05L112.479,188.771L112.225,188.494L111.97,188.218L111.713,187.944L111.454,187.671L111.194,187.4L110.933,187.13L110.669,186.862L110.404,186.596L110.138,186.331L109.87,186.067L109.6,185.806L109.329,185.546L109.056,185.287L108.782,185.03L108.506,184.775L108.229,184.521L107.95,184.269L107.67,184.019L107.388,183.77L107.104,183.524L106.82,183.278L106.533,183.035L106.246,182.793L105.956,182.552L105.666,182.314L105.373,182.077L105.08,181.842L104.785,181.609L104.488,181.377L104.19,181.147L103.891,180.919L103.59,180.693L103.288,180.468L102.985,180.245L102.68,180.024L102.374,179.805L102.066,179.588L101.757,179.372L101.447,179.158L101.135,178.946L100.822,178.736L100.508,178.528L100.192,178.321L99.875,178.117L99.557,177.914L99.238,177.713L98.917,177.514L98.595,177.317L98.271,177.122L97.947,176.929L97.621,176.737L97.294,176.548L96.966,176.36L96.636,176.174L96.305,175.991L95.973,175.809L95.64,175.629L95.306,175.451L94.97,175.275L94.633,175.102L94.295,174.93L93.956,174.76L93.616,174.592L93.274,174.426L92.932,174.262L92.588,174.1L92.243,173.94L91.897,173.783L91.55,173.627L91.202,173.473L90.853,173.321L90.502,173.172L90.151,173.024L89.798,172.879L89.445,172.736L89.09,172.594L88.734,172.455L88.377,172.318L88.02,172.183L87.661,172.051L87.301,171.92L86.94,171.792L86.578,171.665L86.215,171.541L85.851,171.419L85.486,171.299L85.121,171.182L84.754,171.066L84.386,170.953L84.017,170.842L83.647,170.733L83.277,170.626L82.905,170.522L82.533,170.42L82.159,170.32L81.785,170.222L81.41,170.127L81.034,170.034L80.657,169.943L80.279,169.854L79.9,169.768L79.52,169.684L79.14,169.602L78.758,169.523L78.376,169.446L77.993,169.371L77.609,169.299L77.224,169.229L76.839,169.161L76.453,169.096L76.065,169.033L75.677,168.972L75.289,168.914L74.899,168.858L74.509,168.805L74.118,168.754L73.726,168.705L73.333,168.659L72.94,168.615L72.546,168.574L72.151,168.535L71.756,168.498L71.359,168.465L70.962,168.433L70.565,168.404L70.166,168.377L69.767,168.353L69.368,168.332L68.967,168.313L68.566,168.296L68.164,168.282L67.762,168.271L67.359,168.262L66.955,168.255L66.551,168.252L66.146,168.25L65.741,168.252Z" style="fill:white;"/>
+ </g>
+ <path id="path4982" d="M106.02,213.402L57.326,262.095L26.272,231.041L35.464,221.848L57.326,243.71L96.827,204.209L106.02,213.402Z" style="fill:white;"/>
+ </g>
+</svg>
diff --git a/Swift/resources/icons/delivery-warning.svg b/Swift/resources/icons/delivery-warning.svg
new file mode 100644
index 0000000..940552e
--- /dev/null
+++ b/Swift/resources/icons/delivery-warning.svg
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg width="100%" height="100%" viewBox="0 0 133 133" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
+ <g id="Layer-1" transform="matrix(1,0,0,1,0,-164.708)">
+ <g id="path4233" transform="matrix(1.00826,0,0,1.00826,-0.546361,-1.90685)">
+ <circle cx="66.146" cy="230.854" r="65.604" style="fill:rgb(219,203,103);"/>
+ <path d="M66.57,165.252L66.993,165.256L67.416,165.262L67.838,165.272L68.259,165.284L68.68,165.298L69.1,165.316L69.52,165.336L69.938,165.358L70.356,165.383L70.774,165.411L71.19,165.442L71.606,165.475L72.021,165.51L72.436,165.548L72.849,165.589L73.262,165.632L73.675,165.678L74.086,165.727L74.497,165.778L74.906,165.831L75.315,165.887L75.724,165.946L76.131,166.007L76.538,166.07L76.943,166.136L77.348,166.205L77.753,166.276L78.156,166.349L78.558,166.425L78.96,166.503L79.36,166.584L79.76,166.667L80.159,166.753L80.557,166.841L80.954,166.931L81.35,167.024L81.746,167.119L82.14,167.217L82.533,167.317L82.926,167.419L83.317,167.524L83.708,167.631L84.097,167.741L84.486,167.852L84.873,167.967L85.26,168.083L85.645,168.202L86.03,168.323L86.414,168.446L86.796,168.572L87.178,168.7L87.558,168.83L87.937,168.962L88.316,169.097L88.693,169.234L89.069,169.373L89.444,169.514L89.818,169.658L90.191,169.804L90.563,169.952L90.934,170.102L91.303,170.255L91.672,170.409L92.039,170.566L92.405,170.725L92.77,170.886L93.134,171.049L93.496,171.215L93.858,171.382L94.218,171.552L94.577,171.724L94.935,171.898L95.292,172.074L95.647,172.252L96.001,172.432L96.354,172.614L96.706,172.798L97.057,172.985L97.406,173.173L97.754,173.364L98.1,173.556L98.446,173.751L98.79,173.947L99.133,174.146L99.474,174.346L99.814,174.549L100.153,174.754L100.491,174.96L100.827,175.169L101.162,175.379L101.495,175.592L101.827,175.806L102.158,176.022L102.487,176.241L102.815,176.461L103.141,176.683L103.467,176.907L103.79,177.133L104.113,177.361L104.433,177.59L104.753,177.822L105.071,178.055L105.387,178.291L105.702,178.528L106.016,178.767L106.328,179.007L106.639,179.25L106.948,179.495L107.255,179.741L107.561,179.989L107.866,180.239L108.169,180.49L108.471,180.744L108.77,180.999L109.069,181.256L109.366,181.515L109.661,181.775L109.955,182.037L110.247,182.301L110.537,182.567L110.826,182.834L111.114,183.104L111.399,183.374L111.683,183.647L111.966,183.921L112.247,184.197L112.526,184.474L112.803,184.753L113.079,185.034L113.353,185.317L113.626,185.601L113.896,185.886L114.166,186.174L114.433,186.463L114.699,186.753L114.963,187.045L115.225,187.339L115.485,187.634L115.744,187.931L116.001,188.23L116.256,188.529L116.51,188.831L116.761,189.134L117.011,189.439L117.259,189.745L117.505,190.052L117.75,190.361L117.993,190.672L118.233,190.984L118.472,191.298L118.709,191.613L118.945,191.929L119.178,192.247L119.41,192.567L119.639,192.887L119.867,193.21L120.093,193.533L120.317,193.859L120.539,194.185L120.759,194.513L120.978,194.842L121.194,195.173L121.408,195.505L121.621,195.838L121.831,196.173L122.04,196.509L122.246,196.847L122.451,197.186L122.654,197.526L122.854,197.867L123.053,198.21L123.249,198.554L123.444,198.9L123.636,199.246L123.827,199.594L124.015,199.943L124.202,200.294L124.386,200.646L124.568,200.999L124.748,201.353L124.927,201.708L125.102,202.065L125.276,202.423L125.448,202.782L125.618,203.142L125.785,203.504L125.951,203.866L126.114,204.23L126.275,204.595L126.434,204.961L126.591,205.328L126.746,205.697L126.898,206.066L127.048,206.437L127.196,206.809L127.342,207.182L127.486,207.556L127.627,207.931L127.766,208.307L127.903,208.684L128.038,209.063L128.17,209.442L128.3,209.822L128.428,210.204L128.554,210.586L128.677,210.97L128.798,211.355L128.917,211.74L129.033,212.127L129.148,212.514L129.259,212.903L129.369,213.292L129.476,213.683L129.581,214.074L129.683,214.467L129.783,214.86L129.881,215.255L129.976,215.65L130.069,216.046L130.159,216.443L130.247,216.841L130.333,217.24L130.416,217.64L130.497,218.04L130.575,218.442L130.651,218.844L130.724,219.247L130.795,219.652L130.864,220.057L130.93,220.462L130.993,220.869L131.054,221.276L131.113,221.685L131.169,222.094L131.222,222.503L131.273,222.914L131.322,223.325L131.368,223.738L131.411,224.151L131.452,224.564L131.49,224.979L131.525,225.394L131.558,225.81L131.589,226.226L131.617,226.644L131.642,227.062L131.664,227.48L131.684,227.9L131.702,228.32L131.716,228.741L131.728,229.162L131.738,229.584L131.744,230.007L131.748,230.43L131.75,230.854L131.748,231.278L131.744,231.702L131.738,232.124L131.728,232.546L131.716,232.968L131.702,233.389L131.684,233.809L131.664,234.228L131.642,234.647L131.617,235.065L131.589,235.482L131.558,235.899L131.525,236.315L131.49,236.73L131.452,237.144L131.411,237.558L131.368,237.971L131.322,238.383L131.273,238.794L131.222,239.205L131.169,239.615L131.113,240.024L131.054,240.432L130.993,240.839L130.93,241.246L130.864,241.652L130.795,242.057L130.724,242.461L130.651,242.864L130.575,243.266L130.497,243.668L130.416,244.069L130.333,244.468L130.247,244.867L130.159,245.265L130.069,245.662L129.976,246.059L129.881,246.454L129.783,246.848L129.683,247.242L129.581,247.634L129.476,248.025L129.369,248.416L129.259,248.805L129.148,249.194L129.033,249.582L128.917,249.968L128.798,250.354L128.677,250.738L128.554,251.122L128.428,251.504L128.3,251.886L128.17,252.266L128.038,252.646L127.903,253.024L127.766,253.401L127.627,253.777L127.486,254.153L127.342,254.527L127.196,254.899L127.048,255.271L126.898,255.642L126.746,256.012L126.591,256.38L126.434,256.747L126.275,257.113L126.114,257.478L125.951,257.842L125.785,258.205L125.618,258.566L125.448,258.927L125.276,259.286L125.102,259.643L124.927,260L124.748,260.356L124.568,260.71L124.386,261.063L124.202,261.414L124.015,261.765L123.827,262.114L123.636,262.462L123.444,262.809L123.249,263.154L123.053,263.498L122.854,263.841L122.654,264.182L122.451,264.523L122.246,264.861L122.04,265.199L121.831,265.535L121.621,265.87L121.408,266.203L121.194,266.535L120.978,266.866L120.759,267.195L120.539,267.523L120.317,267.85L120.093,268.175L119.867,268.499L119.639,268.821L119.41,269.142L119.178,269.461L118.945,269.779L118.709,270.096L118.472,270.411L118.233,270.724L117.993,271.036L117.75,271.347L117.505,271.656L117.259,271.964L117.011,272.27L116.761,272.574L116.51,272.877L116.256,273.179L116.001,273.479L115.744,273.777L115.485,274.074L115.225,274.369L114.963,274.663L114.699,274.955L114.433,275.246L114.166,275.535L113.896,275.822L113.626,276.108L113.353,276.392L113.079,276.674L112.803,276.955L112.526,277.234L112.247,277.512L111.966,277.787L111.683,278.062L111.399,278.334L111.114,278.605L110.826,278.874L110.537,279.141L110.247,279.407L109.955,279.671L109.661,279.933L109.366,280.194L109.069,280.452L108.77,280.709L108.471,280.964L108.169,281.218L107.866,281.47L107.561,281.719L107.255,281.967L106.948,282.214L106.639,282.458L106.328,282.701L106.016,282.942L105.702,283.181L105.387,283.418L105.071,283.653L104.753,283.887L104.433,284.118L104.113,284.348L103.79,284.576L103.467,284.801L103.141,285.025L102.815,285.248L102.487,285.468L102.158,285.686L101.827,285.902L101.495,286.117L101.162,286.329L100.827,286.54L100.491,286.748L100.153,286.955L99.814,287.159L99.474,287.362L99.133,287.563L98.79,287.761L98.446,287.958L98.1,288.152L97.754,288.345L97.406,288.535L97.057,288.724L96.706,288.91L96.354,289.094L96.001,289.277L95.647,289.457L95.292,289.635L94.935,289.811L94.577,289.985L94.218,290.157L93.858,290.326L93.496,290.494L93.134,290.659L92.77,290.822L92.405,290.983L92.039,291.142L91.672,291.299L91.303,291.454L90.934,291.606L90.563,291.757L90.191,291.905L89.818,292.05L89.444,292.194L89.069,292.335L88.693,292.475L88.316,292.611L87.937,292.746L87.558,292.879L87.178,293.009L86.796,293.137L86.414,293.262L86.03,293.386L85.645,293.507L85.26,293.625L84.873,293.742L84.486,293.856L84.097,293.968L83.708,294.077L83.317,294.184L82.926,294.289L82.533,294.391L82.14,294.491L81.746,294.589L81.35,294.684L80.954,294.777L80.557,294.867L80.159,294.955L79.76,295.041L79.36,295.124L78.96,295.205L78.558,295.283L78.156,295.359L77.753,295.433L77.348,295.504L76.943,295.572L76.538,295.638L76.131,295.702L75.724,295.763L75.315,295.821L74.906,295.877L74.497,295.931L74.086,295.982L73.675,296.03L73.262,296.076L72.849,296.119L72.436,296.16L72.021,296.198L71.606,296.234L71.19,296.267L70.774,296.297L70.356,296.325L69.938,296.35L69.52,296.373L69.1,296.393L68.68,296.41L68.259,296.425L67.838,296.437L67.416,296.446L66.993,296.453L66.57,296.457L66.146,296.458L65.722,296.457L65.298,296.453L64.876,296.446L64.454,296.437L64.032,296.425L63.611,296.41L63.191,296.393L62.772,296.373L62.353,296.35L61.935,296.325L61.518,296.297L61.101,296.267L60.685,296.234L60.27,296.198L59.856,296.16L59.442,296.119L59.029,296.076L58.617,296.03L58.206,295.982L57.795,295.931L57.385,295.877L56.976,295.821L56.568,295.763L56.161,295.702L55.754,295.638L55.348,295.572L54.943,295.504L54.539,295.433L54.136,295.359L53.734,295.283L53.332,295.205L52.931,295.124L52.532,295.041L52.133,294.955L51.735,294.867L51.338,294.777L50.941,294.684L50.546,294.589L50.152,294.491L49.758,294.391L49.366,294.289L48.975,294.184L48.584,294.077L48.195,293.968L47.806,293.856L47.418,293.742L47.032,293.625L46.646,293.507L46.262,293.386L45.878,293.262L45.496,293.137L45.114,293.009L44.734,292.879L44.354,292.746L43.976,292.611L43.599,292.475L43.223,292.335L42.847,292.194L42.473,292.05L42.101,291.905L41.729,291.757L41.358,291.606L40.988,291.454L40.62,291.299L40.253,291.142L39.887,290.983L39.522,290.822L39.158,290.659L38.795,290.494L38.434,290.326L38.073,290.157L37.714,289.985L37.357,289.811L37,289.635L36.644,289.457L36.29,289.277L35.937,289.094L35.586,288.91L35.235,288.724L34.886,288.535L34.538,288.345L34.191,288.152L33.846,287.958L33.502,287.761L33.159,287.563L32.818,287.362L32.477,287.159L32.139,286.955L31.801,286.748L31.465,286.54L31.13,286.329L30.797,286.117L30.465,285.902L30.134,285.686L29.805,285.468L29.477,285.248L29.15,285.025L28.825,284.801L28.501,284.576L28.179,284.348L27.858,284.118L27.539,283.887L27.221,283.653L26.904,283.418L26.589,283.181L26.276,282.942L25.964,282.701L25.653,282.458L25.344,282.214L25.036,281.967L24.73,281.719L24.426,281.47L24.123,281.218L23.821,280.964L23.521,280.709L23.223,280.452L22.926,280.194L22.631,279.933L22.337,279.671L22.045,279.407L21.754,279.141L21.465,278.874L21.178,278.605L20.892,278.334L20.608,278.062L20.326,277.787L20.045,277.512L19.766,277.234L19.488,276.955L19.213,276.674L18.938,276.392L18.666,276.108L18.395,275.822L18.126,275.535L17.859,275.246L17.593,274.955L17.329,274.663L17.067,274.369L16.806,274.074L16.548,273.777L16.291,273.479L16.036,273.179L15.782,272.877L15.53,272.574L15.281,272.27L15.033,271.964L14.786,271.656L14.542,271.347L14.299,271.036L14.058,270.724L13.819,270.411L13.582,270.096L13.347,269.779L13.113,269.461L12.882,269.142L12.652,268.821L12.424,268.499L12.199,268.175L11.975,267.85L11.752,267.523L11.532,267.195L11.314,266.866L11.098,266.535L10.883,266.203L10.671,265.87L10.46,265.535L10.252,265.199L10.045,264.861L9.841,264.523L9.638,264.182L9.437,263.841L9.239,263.498L9.042,263.154L8.848,262.809L8.655,262.462L8.465,262.114L8.276,261.765L8.09,261.414L7.906,261.063L7.723,260.71L7.543,260.356L7.365,260L7.189,259.643L7.015,259.286L6.844,258.927L6.674,258.566L6.506,258.205L6.341,257.842L6.178,257.478L6.017,257.113L5.858,256.747L5.701,256.38L5.546,256.012L5.394,255.642L5.243,255.271L5.095,254.899L4.95,254.527L4.806,254.153L4.665,253.777L4.525,253.401L4.389,253.024L4.254,252.646L4.121,252.266L3.991,251.886L3.863,251.504L3.738,251.122L3.614,250.738L3.493,250.354L3.375,249.968L3.258,249.582L3.144,249.194L3.032,248.805L2.923,248.416L2.816,248.025L2.711,247.634L2.609,247.242L2.509,246.848L2.411,246.454L2.316,246.059L2.223,245.662L2.133,245.265L2.045,244.867L1.959,244.468L1.876,244.069L1.795,243.668L1.717,243.266L1.641,242.864L1.567,242.461L1.496,242.057L1.428,241.652L1.362,241.246L1.298,240.839L1.237,240.432L1.179,240.024L1.123,239.615L1.069,239.205L1.018,238.794L0.97,238.383L0.924,237.971L0.881,237.558L0.84,237.144L0.802,236.73L0.766,236.315L0.733,235.899L0.703,235.482L0.675,235.065L0.65,234.647L0.627,234.228L0.607,233.809L0.59,233.389L0.575,232.968L0.563,232.546L0.554,232.124L0.547,231.702L0.543,231.278L0.542,230.854L0.543,230.43L0.547,230.007L0.554,229.584L0.563,229.162L0.575,228.741L0.59,228.32L0.607,227.9L0.627,227.48L0.65,227.062L0.675,226.644L0.703,226.226L0.733,225.81L0.766,225.394L0.802,224.979L0.84,224.564L0.881,224.151L0.924,223.738L0.97,223.325L1.018,222.914L1.069,222.503L1.123,222.094L1.179,221.685L1.237,221.276L1.298,220.869L1.362,220.462L1.428,220.057L1.496,219.652L1.567,219.247L1.641,218.844L1.717,218.442L1.795,218.04L1.876,217.64L1.959,217.24L2.045,216.841L2.133,216.443L2.223,216.046L2.316,215.65L2.411,215.255L2.509,214.86L2.609,214.467L2.711,214.074L2.816,213.683L2.923,213.292L3.032,212.903L3.144,212.514L3.258,212.127L3.375,211.74L3.493,211.355L3.614,210.97L3.738,210.586L3.863,210.204L3.991,209.822L4.121,209.442L4.254,209.063L4.389,208.684L4.525,208.307L4.665,207.931L4.806,207.556L4.95,207.182L5.095,206.809L5.243,206.437L5.394,206.066L5.546,205.697L5.701,205.328L5.858,204.961L6.017,204.595L6.178,204.23L6.341,203.866L6.506,203.504L6.674,203.142L6.844,202.782L7.015,202.423L7.189,202.065L7.365,201.708L7.543,201.353L7.723,200.999L7.906,200.646L8.09,200.294L8.276,199.943L8.465,199.594L8.655,199.246L8.848,198.9L9.042,198.554L9.239,198.21L9.437,197.867L9.638,197.526L9.841,197.186L10.045,196.847L10.252,196.509L10.46,196.173L10.671,195.838L10.883,195.505L11.098,195.173L11.314,194.842L11.532,194.513L11.752,194.185L11.975,193.859L12.199,193.533L12.424,193.21L12.652,192.887L12.882,192.567L13.113,192.247L13.347,191.929L13.582,191.613L13.819,191.298L14.058,190.984L14.299,190.672L14.542,190.361L14.786,190.052L15.033,189.745L15.281,189.439L15.53,189.134L15.782,188.831L16.036,188.529L16.291,188.23L16.548,187.931L16.806,187.634L17.067,187.339L17.329,187.045L17.593,186.753L17.859,186.463L18.126,186.174L18.395,185.886L18.666,185.601L18.938,185.317L19.213,185.034L19.488,184.753L19.766,184.474L20.045,184.197L20.326,183.921L20.608,183.647L20.892,183.374L21.178,183.104L21.465,182.834L21.754,182.567L22.045,182.301L22.337,182.037L22.631,181.775L22.926,181.515L23.223,181.256L23.521,180.999L23.821,180.744L24.123,180.49L24.426,180.239L24.73,179.989L25.036,179.741L25.344,179.495L25.653,179.25L25.964,179.007L26.276,178.767L26.589,178.528L26.904,178.291L27.221,178.055L27.539,177.822L27.858,177.59L28.179,177.361L28.501,177.133L28.825,176.907L29.15,176.683L29.477,176.461L29.805,176.241L30.134,176.022L30.465,175.806L30.797,175.592L31.13,175.379L31.465,175.169L31.801,174.96L32.139,174.754L32.477,174.549L32.818,174.346L33.159,174.146L33.502,173.947L33.846,173.751L34.191,173.556L34.538,173.364L34.886,173.173L35.235,172.985L35.586,172.798L35.937,172.614L36.29,172.432L36.644,172.252L37,172.074L37.357,171.898L37.714,171.724L38.073,171.552L38.434,171.382L38.795,171.215L39.158,171.049L39.522,170.886L39.887,170.725L40.253,170.566L40.62,170.409L40.988,170.255L41.358,170.102L41.729,169.952L42.101,169.804L42.473,169.658L42.847,169.514L43.223,169.373L43.599,169.234L43.976,169.097L44.354,168.962L44.734,168.83L45.114,168.7L45.496,168.572L45.878,168.446L46.262,168.323L46.646,168.202L47.032,168.083L47.418,167.967L47.806,167.852L48.195,167.741L48.584,167.631L48.975,167.524L49.366,167.419L49.758,167.317L50.152,167.217L50.546,167.119L50.941,167.024L51.338,166.931L51.735,166.841L52.133,166.753L52.532,166.667L52.931,166.584L53.332,166.503L53.734,166.425L54.136,166.349L54.539,166.276L54.943,166.205L55.348,166.136L55.754,166.07L56.161,166.007L56.568,165.946L56.976,165.887L57.385,165.831L57.795,165.778L58.206,165.727L58.617,165.678L59.029,165.632L59.442,165.589L59.856,165.548L60.27,165.51L60.685,165.475L61.101,165.442L61.518,165.411L61.935,165.383L62.353,165.358L62.772,165.336L63.191,165.316L63.611,165.298L64.032,165.284L64.454,165.272L64.876,165.262L65.298,165.256L65.722,165.252L66.146,165.25L66.57,165.252ZM65.741,168.252L65.337,168.255L64.933,168.262L64.53,168.271L64.127,168.282L63.726,168.296L63.325,168.313L62.924,168.332L62.524,168.353L62.125,168.377L61.727,168.404L61.329,168.433L60.932,168.465L60.536,168.498L60.141,168.535L59.746,168.574L59.352,168.615L58.958,168.659L58.566,168.705L58.174,168.754L57.783,168.805L57.393,168.858L57.003,168.914L56.614,168.972L56.226,169.033L55.839,169.096L55.453,169.161L55.067,169.229L54.683,169.299L54.299,169.371L53.916,169.446L53.533,169.523L53.152,169.602L52.771,169.684L52.392,169.768L52.013,169.854L51.635,169.943L51.258,170.034L50.882,170.127L50.507,170.222L50.132,170.32L49.759,170.42L49.386,170.522L49.015,170.626L48.644,170.733L48.275,170.842L47.906,170.953L47.538,171.066L47.171,171.182L46.805,171.299L46.44,171.419L46.076,171.541L45.714,171.665L45.352,171.792L44.991,171.92L44.631,172.051L44.272,172.183L43.914,172.318L43.557,172.455L43.202,172.594L42.847,172.736L42.493,172.879L42.141,173.024L41.789,173.172L41.439,173.321L41.09,173.473L40.742,173.627L40.394,173.783L40.048,173.94L39.704,174.1L39.36,174.262L39.017,174.426L38.676,174.592L38.336,174.76L37.996,174.93L37.658,175.102L37.322,175.275L36.986,175.451L36.652,175.629L36.318,175.809L35.986,175.991L35.656,176.174L35.326,176.36L34.998,176.548L34.671,176.737L34.345,176.929L34.02,177.122L33.697,177.317L33.375,177.514L33.054,177.713L32.735,177.914L32.416,178.117L32.099,178.321L31.784,178.528L31.47,178.736L31.157,178.946L30.845,179.158L30.535,179.372L30.226,179.588L29.918,179.805L29.612,180.024L29.307,180.245L29.003,180.468L28.701,180.693L28.401,180.919L28.101,181.147L27.803,181.377L27.507,181.609L27.212,181.842L26.918,182.077L26.626,182.314L26.335,182.552L26.046,182.793L25.758,183.035L25.472,183.278L25.187,183.524L24.904,183.77L24.622,184.019L24.342,184.269L24.063,184.521L23.785,184.775L23.51,185.03L23.235,185.287L22.963,185.546L22.691,185.806L22.422,186.067L22.154,186.331L21.887,186.596L21.622,186.862L21.359,187.13L21.097,187.4L20.837,187.671L20.579,187.944L20.322,188.218L20.067,188.494L19.813,188.771L19.561,189.05L19.311,189.33L19.062,189.612L18.815,189.896L18.57,190.18L18.326,190.467L18.084,190.754L17.844,191.044L17.606,191.334L17.369,191.627L17.134,191.92L16.9,192.215L16.669,192.512L16.439,192.81L16.211,193.109L15.984,193.41L15.76,193.712L15.537,194.015L15.316,194.32L15.097,194.626L14.879,194.934L14.664,195.243L14.45,195.553L14.238,195.865L14.028,196.178L13.82,196.492L13.613,196.808L13.408,197.125L13.206,197.443L13.005,197.762L12.806,198.083L12.609,198.405L12.414,198.729L12.22,199.053L12.029,199.379L11.839,199.706L11.652,200.034L11.466,200.364L11.282,200.695L11.101,201.027L10.921,201.36L10.743,201.694L10.567,202.03L10.393,202.367L10.221,202.705L10.051,203.044L9.884,203.384L9.718,203.726L9.554,204.068L9.392,204.412L9.232,204.757L9.074,205.103L8.918,205.45L8.765,205.798L8.613,206.147L8.464,206.498L8.316,206.849L8.171,207.202L8.027,207.555L7.886,207.91L7.747,208.266L7.61,208.623L7.475,208.98L7.342,209.339L7.212,209.699L7.083,210.06L6.957,210.422L6.833,210.785L6.711,211.149L6.591,211.514L6.473,211.879L6.358,212.246L6.245,212.614L6.134,212.983L6.025,213.353L5.918,213.723L5.814,214.095L5.712,214.467L5.612,214.841L5.514,215.215L5.419,215.59L5.325,215.966L5.235,216.343L5.146,216.721L5.06,217.1L4.976,217.48L4.894,217.86L4.815,218.242L4.738,218.624L4.663,219.007L4.591,219.391L4.52,219.776L4.453,220.161L4.387,220.547L4.324,220.935L4.264,221.323L4.206,221.711L4.15,222.101L4.096,222.491L4.045,222.882L3.997,223.274L3.951,223.667L3.907,224.06L3.865,224.454L3.827,224.849L3.79,225.244L3.756,225.641L3.725,226.038L3.696,226.435L3.669,226.834L3.645,227.233L3.623,227.632L3.604,228.033L3.588,228.434L3.574,228.836L3.562,229.238L3.553,229.641L3.547,230.045L3.543,230.449L3.542,230.854L3.543,231.259L3.547,231.663L3.553,232.067L3.562,232.47L3.574,232.873L3.588,233.274L3.604,233.676L3.623,234.076L3.645,234.476L3.669,234.875L3.696,235.273L3.725,235.671L3.756,236.068L3.79,236.464L3.827,236.859L3.865,237.254L3.907,237.648L3.951,238.042L3.997,238.434L4.045,238.826L4.096,239.217L4.15,239.607L4.206,239.997L4.264,240.386L4.324,240.774L4.387,241.161L4.453,241.547L4.52,241.933L4.591,242.317L4.663,242.701L4.738,243.084L4.815,243.467L4.894,243.848L4.976,244.229L5.06,244.608L5.146,244.987L5.235,245.365L5.325,245.742L5.419,246.118L5.514,246.493L5.612,246.868L5.712,247.241L5.814,247.614L5.918,247.985L6.025,248.356L6.134,248.725L6.245,249.094L6.358,249.462L6.473,249.829L6.591,250.195L6.711,250.56L6.833,250.924L6.957,251.286L7.083,251.648L7.212,252.009L7.342,252.369L7.475,252.728L7.61,253.086L7.747,253.443L7.886,253.798L8.027,254.153L8.171,254.507L8.316,254.859L8.464,255.211L8.613,255.561L8.765,255.91L8.918,256.258L9.074,256.606L9.232,256.952L9.392,257.296L9.554,257.64L9.718,257.983L9.884,258.324L10.051,258.664L10.221,259.004L10.393,259.342L10.567,259.678L10.743,260.014L10.921,260.348L11.101,260.682L11.282,261.014L11.466,261.344L11.652,261.674L11.839,262.002L12.029,262.329L12.22,262.655L12.414,262.98L12.609,263.303L12.806,263.625L13.005,263.946L13.206,264.265L13.408,264.584L13.613,264.901L13.82,265.216L14.028,265.531L14.238,265.843L14.45,266.155L14.664,266.465L14.879,266.774L15.097,267.082L15.316,267.388L15.537,267.693L15.76,267.997L15.984,268.299L16.211,268.599L16.439,268.899L16.669,269.197L16.9,269.493L17.134,269.788L17.369,270.082L17.606,270.374L17.844,270.665L18.084,270.954L18.326,271.242L18.57,271.528L18.815,271.813L19.062,272.096L19.311,272.378L19.561,272.658L19.813,272.937L20.067,273.215L20.322,273.49L20.579,273.765L20.837,274.037L21.097,274.309L21.359,274.578L21.622,274.846L21.887,275.113L22.154,275.378L22.422,275.641L22.691,275.903L22.963,276.163L23.235,276.421L23.51,276.678L23.785,276.933L24.063,277.187L24.342,277.439L24.622,277.689L24.904,277.938L25.187,278.185L25.472,278.43L25.758,278.674L26.046,278.916L26.335,279.156L26.626,279.394L26.918,279.631L27.212,279.866L27.507,280.1L27.803,280.331L28.101,280.561L28.401,280.789L28.701,281.016L29.003,281.24L29.307,281.463L29.612,281.684L29.918,281.903L30.226,282.121L30.535,282.336L30.845,282.55L31.157,282.762L31.47,282.972L31.784,283.18L32.099,283.387L32.416,283.592L32.735,283.794L33.054,283.995L33.375,284.194L33.697,284.391L34.02,284.586L34.345,284.78L34.671,284.971L34.998,285.161L35.326,285.348L35.656,285.534L35.986,285.718L36.318,285.899L36.652,286.079L36.986,286.257L37.322,286.433L37.658,286.607L37.996,286.779L38.336,286.949L38.676,287.117L39.017,287.282L39.36,287.446L39.704,287.608L40.048,287.768L40.394,287.926L40.742,288.082L41.09,288.235L41.439,288.387L41.789,288.537L42.141,288.684L42.493,288.829L42.847,288.973L43.202,289.114L43.557,289.253L43.914,289.39L44.272,289.525L44.631,289.658L44.991,289.788L45.352,289.917L45.714,290.043L46.076,290.167L46.44,290.289L46.805,290.409L47.171,290.527L47.538,290.642L47.906,290.755L48.275,290.866L48.644,290.975L49.015,291.082L49.386,291.186L49.759,291.288L50.132,291.388L50.507,291.486L50.882,291.581L51.258,291.675L51.635,291.765L52.013,291.854L52.392,291.94L52.771,292.024L53.152,292.106L53.533,292.185L53.916,292.262L54.299,292.337L54.683,292.409L55.067,292.48L55.453,292.547L55.839,292.613L56.226,292.676L56.614,292.736L57.003,292.794L57.393,292.85L57.783,292.904L58.174,292.955L58.566,293.003L58.958,293.049L59.352,293.093L59.746,293.135L60.14,293.173L60.536,293.21L60.932,293.244L61.329,293.275L61.727,293.304L62.125,293.331L62.524,293.355L62.924,293.377L63.324,293.396L63.726,293.412L64.127,293.426L64.53,293.438L64.933,293.447L65.337,293.453L65.741,293.457L66.146,293.458L66.551,293.457L66.955,293.453L67.359,293.447L67.762,293.438L68.164,293.426L68.566,293.412L68.967,293.396L69.368,293.377L69.767,293.355L70.166,293.331L70.565,293.304L70.962,293.275L71.359,293.244L71.756,293.21L72.151,293.173L72.546,293.135L72.94,293.093L73.333,293.049L73.726,293.003L74.118,292.955L74.509,292.904L74.899,292.85L75.289,292.794L75.677,292.736L76.065,292.676L76.453,292.613L76.839,292.547L77.224,292.48L77.609,292.409L77.993,292.337L78.376,292.262L78.758,292.185L79.14,292.106L79.52,292.024L79.9,291.94L80.279,291.854L80.657,291.765L81.034,291.675L81.41,291.581L81.785,291.486L82.159,291.388L82.533,291.288L82.905,291.186L83.277,291.082L83.647,290.975L84.017,290.866L84.386,290.755L84.754,290.642L85.121,290.527L85.486,290.409L85.851,290.289L86.215,290.167L86.578,290.043L86.94,289.917L87.301,289.788L87.661,289.658L88.02,289.525L88.377,289.39L88.734,289.253L89.09,289.114L89.445,288.973L89.798,288.829L90.151,288.684L90.502,288.537L90.853,288.387L91.202,288.235L91.55,288.082L91.897,287.926L92.243,287.768L92.588,287.608L92.932,287.446L93.274,287.282L93.616,287.117L93.956,286.949L94.295,286.779L94.633,286.607L94.97,286.433L95.306,286.257L95.64,286.079L95.973,285.899L96.305,285.718L96.636,285.534L96.966,285.348L97.294,285.161L97.621,284.971L97.947,284.78L98.271,284.586L98.595,284.391L98.917,284.194L99.238,283.995L99.557,283.794L99.875,283.592L100.192,283.387L100.508,283.18L100.822,282.972L101.135,282.762L101.447,282.55L101.757,282.336L102.066,282.121L102.374,281.903L102.68,281.684L102.985,281.463L103.288,281.24L103.59,281.016L103.891,280.789L104.19,280.561L104.488,280.331L104.785,280.1L105.08,279.866L105.373,279.631L105.665,279.394L105.956,279.156L106.246,278.916L106.533,278.674L106.82,278.43L107.104,278.185L107.388,277.938L107.67,277.689L107.95,277.439L108.229,277.187L108.506,276.933L108.782,276.678L109.056,276.421L109.329,276.163L109.6,275.903L109.87,275.641L110.138,275.378L110.404,275.113L110.669,274.846L110.933,274.578L111.194,274.309L111.454,274.037L111.713,273.765L111.97,273.49L112.225,273.215L112.479,272.937L112.731,272.658L112.981,272.378L113.23,272.096L113.476,271.813L113.722,271.528L113.965,271.242L114.207,270.954L114.448,270.665L114.686,270.374L114.923,270.082L115.158,269.788L115.391,269.493L115.623,269.197L115.853,268.899L116.081,268.599L116.307,268.299L116.532,267.997L116.755,267.693L116.976,267.388L117.195,267.082L117.412,266.774L117.628,266.465L117.842,266.155L118.054,265.843L118.264,265.531L118.472,265.216L118.679,264.901L118.883,264.584L119.086,264.265L119.287,263.946L119.486,263.625L119.683,263.303L119.878,262.98L120.071,262.655L120.263,262.329L120.452,262.002L120.64,261.674L120.826,261.344L121.009,261.014L121.191,260.682L121.371,260.348L121.549,260.014L121.725,259.678L121.898,259.342L122.07,259.004L122.24,258.664L122.408,258.324L122.574,257.983L122.738,257.64L122.9,257.296L123.06,256.952L123.217,256.606L123.373,256.258L123.527,255.91L123.679,255.561L123.828,255.211L123.976,254.859L124.121,254.507L124.264,254.153L124.406,253.798L124.545,253.443L124.682,253.086L124.817,252.728L124.949,252.369L125.08,252.009L125.208,251.648L125.335,251.286L125.459,250.923L125.581,250.56L125.701,250.195L125.818,249.829L125.934,249.462L126.047,249.094L126.158,248.726L126.267,248.356L126.374,247.985L126.478,247.614L126.58,247.241L126.68,246.868L126.778,246.493L126.873,246.118L126.966,245.742L127.057,245.365L127.146,244.987L127.232,244.608L127.316,244.229L127.398,243.848L127.477,243.467L127.554,243.084L127.629,242.701L127.701,242.317L127.771,241.933L127.839,241.547L127.904,241.161L127.967,240.774L128.028,240.386L128.086,239.997L128.142,239.608L128.195,239.217L128.246,238.826L128.295,238.434L128.341,238.042L128.385,237.648L128.426,237.254L128.465,236.859L128.502,236.464L128.535,236.068L128.567,235.671L128.596,235.273L128.623,234.875L128.647,234.476L128.668,234.076L128.687,233.676L128.704,233.274L128.718,232.873L128.729,232.47L128.738,232.067L128.745,231.664L128.748,231.259L128.75,230.854L128.748,230.449L128.745,230.045L128.738,229.641L128.729,229.238L128.718,228.836L128.704,228.434L128.687,228.033L128.668,227.632L128.647,227.233L128.623,226.834L128.596,226.435L128.567,226.038L128.535,225.641L128.502,225.244L128.465,224.849L128.426,224.454L128.385,224.06L128.341,223.667L128.295,223.274L128.246,222.882L128.195,222.491L128.142,222.101L128.086,221.711L128.028,221.323L127.967,220.935L127.904,220.547L127.839,220.161L127.771,219.776L127.701,219.391L127.629,219.007L127.554,218.624L127.477,218.242L127.398,217.86L127.316,217.48L127.232,217.1L127.146,216.721L127.057,216.343L126.966,215.966L126.873,215.59L126.778,215.215L126.68,214.841L126.58,214.467L126.478,214.095L126.374,213.723L126.267,213.353L126.158,212.983L126.047,212.614L125.934,212.246L125.818,211.879L125.701,211.514L125.581,211.149L125.459,210.785L125.335,210.422L125.208,210.06L125.08,209.699L124.949,209.339L124.817,208.98L124.682,208.623L124.545,208.266L124.406,207.91L124.264,207.555L124.121,207.202L123.976,206.849L123.828,206.498L123.679,206.147L123.527,205.798L123.373,205.45L123.217,205.103L123.06,204.757L122.9,204.412L122.738,204.068L122.574,203.726L122.408,203.384L122.24,203.044L122.07,202.705L121.898,202.367L121.725,202.03L121.549,201.694L121.371,201.36L121.191,201.027L121.009,200.695L120.826,200.364L120.64,200.034L120.452,199.706L120.263,199.379L120.071,199.053L119.878,198.729L119.683,198.405L119.486,198.083L119.287,197.762L119.086,197.443L118.883,197.125L118.679,196.808L118.472,196.492L118.264,196.178L118.054,195.865L117.842,195.553L117.628,195.243L117.412,194.934L117.195,194.626L116.976,194.32L116.755,194.015L116.532,193.712L116.307,193.41L116.081,193.109L115.853,192.81L115.623,192.512L115.391,192.215L115.158,191.92L114.923,191.627L114.686,191.334L114.448,191.044L114.207,190.755L113.965,190.467L113.722,190.18L113.476,189.896L113.23,189.612L112.981,189.33L112.731,189.05L112.479,188.771L112.225,188.494L111.97,188.218L111.713,187.944L111.454,187.671L111.194,187.4L110.933,187.13L110.669,186.862L110.404,186.596L110.138,186.331L109.87,186.067L109.6,185.806L109.329,185.546L109.056,185.287L108.782,185.03L108.506,184.775L108.229,184.521L107.95,184.269L107.67,184.019L107.388,183.77L107.104,183.524L106.82,183.278L106.533,183.035L106.246,182.793L105.956,182.552L105.666,182.314L105.373,182.077L105.08,181.842L104.785,181.609L104.488,181.377L104.19,181.147L103.891,180.919L103.59,180.693L103.288,180.468L102.985,180.245L102.68,180.024L102.374,179.805L102.066,179.588L101.757,179.372L101.447,179.158L101.135,178.946L100.822,178.736L100.508,178.528L100.192,178.321L99.875,178.117L99.557,177.914L99.238,177.713L98.917,177.514L98.595,177.317L98.271,177.122L97.947,176.929L97.621,176.737L97.294,176.548L96.966,176.36L96.636,176.174L96.305,175.991L95.973,175.809L95.64,175.629L95.306,175.451L94.97,175.275L94.633,175.102L94.295,174.93L93.956,174.76L93.616,174.592L93.274,174.426L92.932,174.262L92.588,174.1L92.243,173.94L91.897,173.783L91.55,173.627L91.202,173.473L90.853,173.321L90.502,173.172L90.151,173.024L89.798,172.879L89.445,172.736L89.09,172.594L88.734,172.455L88.377,172.318L88.02,172.183L87.661,172.051L87.301,171.92L86.94,171.792L86.578,171.665L86.215,171.541L85.851,171.419L85.486,171.299L85.121,171.182L84.754,171.066L84.386,170.953L84.017,170.842L83.647,170.733L83.277,170.626L82.905,170.522L82.533,170.42L82.159,170.32L81.785,170.222L81.41,170.127L81.034,170.034L80.657,169.943L80.279,169.854L79.9,169.768L79.52,169.684L79.14,169.602L78.758,169.523L78.376,169.446L77.993,169.371L77.609,169.299L77.224,169.229L76.839,169.161L76.453,169.096L76.065,169.033L75.677,168.972L75.289,168.914L74.899,168.858L74.509,168.805L74.118,168.754L73.726,168.705L73.333,168.659L72.94,168.615L72.546,168.574L72.151,168.535L71.756,168.498L71.359,168.465L70.962,168.433L70.565,168.404L70.166,168.377L69.767,168.353L69.368,168.332L68.967,168.313L68.566,168.296L68.164,168.282L67.762,168.271L67.359,168.262L66.955,168.255L66.551,168.252L66.146,168.25L65.741,168.252Z" style="fill:white;"/>
+ </g>
+ <g transform="matrix(1,0,0,1,-1.55155,8.75145)">
+ <g transform="matrix(1,0,0,1,-18.2398,144.929)">
+ <rect x="79.437" y="34.964" width="13" height="62.363" style="fill:white;"/>
+ </g>
+ <g transform="matrix(1,0,0,1.14583,0,156.831)">
+ <rect x="61.197" y="82.456" width="13" height="11.345" style="fill:white;"/>
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/Swift/resources/logo/logo-shaded-text.256.png b/Swift/resources/logo/logo-shaded-text.256.png
deleted file mode 100644
index 5605ad0..0000000
--- a/Swift/resources/logo/logo-shaded-text.256.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/logo/logo-shaded-text.png b/Swift/resources/logo/logo-shaded-text.png
new file mode 100644
index 0000000..8bc3bef
--- /dev/null
+++ b/Swift/resources/logo/logo-shaded-text.png
Binary files differ
diff --git a/Swift/resources/logo/logo-shaded-text.svg b/Swift/resources/logo/logo-shaded-text.svg
index 68192e9..deb8340 100644
--- a/Swift/resources/logo/logo-shaded-text.svg
+++ b/Swift/resources/logo/logo-shaded-text.svg
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
@@ -8,17 +9,18 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="744.09003"
- height="744"
+ width="175.8864mm"
+ height="175.8864mm"
id="svg2459"
sodipodi:version="0.32"
- inkscape:version="0.46"
- sodipodi:docname="logo-text.svg"
+ inkscape:version="0.91+devel+osxmenu r12922"
+ sodipodi:docname="logo-shaded-text.svg"
inkscape:output_extension="org.inkscape.output.svg.inkscape"
inkscape:export-xdpi="18.796354"
inkscape:export-ydpi="18.796354"
version="1.0"
- inkscape:export-filename="/Users/remko/src/swift/resources/logo/blog.png">
+ inkscape:export-filename="/Users/remko/src/swift/resources/logo/blog.png"
+ viewBox="0 0 664.77 664.76749">
<defs
id="defs2461">
<linearGradient
@@ -45,10 +47,10 @@
</linearGradient>
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
- inkscape:vp_x="0 : 526.18109 : 1"
- inkscape:vp_y="0 : 1000 : 0"
- inkscape:vp_z="744.09448 : 526.18109 : 1"
- inkscape:persp3d-origin="372.04724 : 350.78739 : 1"
+ inkscape:vp_x="0 : 526.18107 : 1"
+ inkscape:vp_y="0 : 999.99996 : 0"
+ inkscape:vp_z="744.09725 : 526.18107 : 1"
+ inkscape:persp3d-origin="372.04862 : 350.78737 : 1"
id="perspective2390" />
<filter
inkscape:collect="always"
@@ -70,15 +72,22 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.0074671"
- inkscape:cx="375"
- inkscape:cy="367.42652"
+ inkscape:cx="254.12047"
+ inkscape:cy="374.35139"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
- inkscape:window-width="1169"
- inkscape:window-height="990"
- inkscape:window-x="695"
- inkscape:window-y="75" />
+ inkscape:window-width="1680"
+ inkscape:window-height="1001"
+ inkscape:window-x="0"
+ inkscape:window-y="23"
+ inkscape:window-maximized="0"
+ borderlayer="false"
+ units="mm"
+ fit-margin-top="0"
+ fit-margin-left="0"
+ fit-margin-right="0"
+ fit-margin-bottom="0" />
<metadata
id="metadata2464">
<rdf:RDF>
@@ -87,33 +96,37 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
- id="layer1">
+ id="layer1"
+ transform="translate(12.742622,-46.453819)">
<path
style="opacity:0.35820899;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:0.82541478px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter3237)"
- d="M 115.78906,165.28485 C 350.10074,221.97501 309.63531,304.49349 212.19531,373.84735 C 164.88631,390.51853 105.57186,410.97398 28.664058,434.5661 C 65.101978,429.72741 98.209468,426.47848 128.03906,424.8161 C 98.134688,440.73611 68.227048,455.00104 42.414058,466.8786 C 101.67266,450.07359 152.5607,435.94556 196.60156,424.0036 C 357.97622,430.8864 369.87302,508.77947 220.75781,659.0036 C 445.02711,532.63072 503.94812,439.58103 370.66406,379.59735 C 439.14989,363.96856 465.05721,361.86643 479.53906,363.2536 C 444.72231,339.57148 420.60352,327.54967 393.66406,325.3161 C 452.90693,238.96094 326.66051,184.93904 115.78906,165.28485 z M 396.16406,338.9411 C 400.59386,338.94111 404.19531,342.54255 404.19531,346.97235 C 404.1953,351.40217 400.59387,354.97235 396.16406,354.97235 C 391.73423,354.97236 388.13281,351.40217 388.13281,346.97235 C 388.1328,342.54255 391.73424,338.9411 396.16406,338.9411 z"
+ d="m 115.78906,165.28485 c 234.31168,56.69016 193.84625,139.20864 96.40625,208.5625 -47.309,16.67118 -106.62345,37.12663 -183.531252,60.71875 36.43792,-4.83869 69.54541,-8.08762 99.375002,-9.75 -29.904372,15.92001 -59.812012,30.18494 -85.625002,42.0625 59.258602,-16.80501 110.146642,-30.93304 154.187502,-42.875 161.37466,6.8828 173.27146,84.77587 24.15625,235 224.2693,-126.37288 283.19031,-219.42257 149.90625,-279.40625 68.48583,-15.62879 94.39315,-17.73092 108.875,-16.34375 -34.81675,-23.68212 -58.93554,-35.70393 -85.875,-37.9375 59.24287,-86.35516 -67.00355,-140.37706 -277.875,-160.03125 z m 280.375,173.65625 c 4.4298,10e-6 8.03125,3.60145 8.03125,8.03125 -1e-5,4.42982 -3.60144,8 -8.03125,8 -4.42983,10e-6 -8.03125,-3.57018 -8.03125,-8 -1e-5,-4.4298 3.60143,-8.03125 8.03125,-8.03125 z"
id="path2441"
- transform="matrix(1.2286617,0,0,1.2286617,7.4362342,-159.13251)" />
+ transform="matrix(1.2286617,0,0,1.2286617,7.4362425,-127.54827)"
+ inkscape:connector-curvature="0" />
<path
style="opacity:0.35820899;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:1.00333011px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
- d="M 193.43655,38.683901 C 481.36377,106.86408 431.64137,206.12084 311.88952,289.5279 C 253.76866,309.57308 180.85932,334.14392 86.387308,362.50752 C 131.16565,356.68778 171.8703,352.78146 208.52634,350.78268 C 171.78326,369.92726 135.03618,387.08152 103.32012,401.36485 C 176.12602,381.15723 238.61951,364.20345 292.72972,349.8432 C 491.00731,358.12042 505.62549,451.75302 322.41016,632.40439 C 597.96661,480.43489 670.40043,368.53822 506.63621,296.40496 C 590.78377,277.6106 622.61572,275.12026 640.40936,276.7884 C 597.63051,248.30952 567.9961,233.81513 534.89597,231.12916 C 607.68329,127.28416 452.52952,62.318851 193.43655,38.683901 z M 537.9677,247.51387 C 543.41055,247.51388 547.79717,251.84478 547.79717,257.17184 C 547.79718,262.49891 543.41054,266.8298 537.9677,266.8298 C 532.52484,266.8298 528.09981,262.49891 528.09981,257.17184 C 528.09981,251.84478 532.52483,247.51387 537.9677,247.51387 z"
- id="path2469" />
+ d="m 193.43656,70.268137 c 287.92722,68.180183 238.20482,167.436943 118.45297,250.844003 -58.12086,20.04518 -131.0302,44.61602 -225.502214,72.97962 44.778344,-5.81974 85.482994,-9.72606 122.139034,-11.72484 -36.74308,19.14458 -73.49016,36.29884 -105.20622,50.58217 72.8059,-20.20762 135.29939,-37.1614 189.4096,-51.52165 198.27759,8.27722 212.89577,101.90982 29.68044,282.56119 C 597.96662,512.01913 670.40044,400.12246 506.63622,327.9892 590.78378,309.19484 622.61573,306.7045 640.40937,308.37264 597.63052,279.89376 567.99611,265.39937 534.89598,262.7134 607.6833,158.8684 452.52953,93.903087 193.43656,70.268137 Z M 537.96771,279.09811 c 5.44285,10e-6 9.82947,4.33091 9.82947,9.65797 10e-6,5.32707 -4.38663,9.65796 -9.82947,9.65796 -5.44286,0 -9.86789,-4.33089 -9.86789,-9.65796 0,-5.32706 4.42502,-9.65797 9.86789,-9.65797 z"
+ id="path2469"
+ inkscape:connector-curvature="0" />
<text
xml:space="preserve"
- style="font-size:160.47987366px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bodoni SvtyTwo OS ITC TT;-inkscape-font-specification:Bodoni SvtyTwo OS ITC TT"
- x="22.41254"
- y="527.68341"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:160.48001099px;line-height:125%;font-family:'Bodoni 72 Oldstyle';-inkscape-font-specification:'Bodoni 72 Oldstyle, Normal';font-variant-ligatures:none;font-variant-caps:normal;font-variant-numeric:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ x="22.412548"
+ y="557.24536"
id="text4727"
sodipodi:linespacing="125%"
- transform="scale(0.9359712,1.0684089)"><tspan
+ transform="scale(0.93597122,1.0684089)"><tspan
sodipodi:role="line"
id="tspan4729"
- x="22.41254"
- y="527.68341">Swift</tspan></text>
+ x="22.412548"
+ y="557.24536">Swift</tspan></text>
</g>
</svg>
diff --git a/Swift/resources/themes/Default/Demo.html b/Swift/resources/themes/Default/Demo.html
deleted file mode 100755
index cbe5bb1..0000000
--- a/Swift/resources/themes/Default/Demo.html
+++ /dev/null
@@ -1,91 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8" />
- <base href="%@">
-
- <style id="mainStyle" type="text/css" media="screen,print"> @import url( "Variants/Yellow on Green Alternating.css" ); </style>
-
-</head>
-<body style="background-color:#e3e3e3">
-<div id="Chat">
- <div class="chatItem incomingItem">
- <table width="100%">
- <tr>
- <td valign="top">
- <img src="images/DummyContact.png" alt="%sender%" title="%sender%" class="avatar">
- <div class="myBubble">
- <div class="indicator"></div>
- <table class="tableBubble" cellspacing="0" cellpadding="0">
- <tr>
- <td class="tl"></td>
- <td class="tr"></td>
- </tr>
- <tr>
- <td class="message">
- Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
- <div class="timeStamp">Torrey @ 4:55 am</div>
- <div class="followUp"></div>
- <div>
- testing 1
- <div class="timeStamp">%sender% @ %time%</div>
- </div>
- <div class="followUp"></div>
- <div class="followUpMessage">
- testing 123
- <div class="timeStamp">%sender% @ %time%</div>
- </div>
- <div class="followUp"></div>
- <div>
- testing 123testing 123testing 123testing 123
- testing 123testing 123
- <div class="timeStamp">%sender% @ %time%</div>
- </div>
- </td>
- <td class="messageRight"></td>
- </tr>
- <tr>
- <td class="bl"></td>
- <td class="br"></td>
- </tr>
- </table>
- </div>
- </td>
- </tr>
- </table>
- </div>
-
- <div class="chatItem outgoingItem">
- <table width="100%">
- <tr>
- <td valign="top">
- <img src="images/DummyContact.png" alt="%sender%" title="%sender%" class="avatar">
- <div class="myBubble">
- <div class="indicator"></div>
- <table class="tableBubble" cellspacing="0" cellpadding="0">
- <tr>
- <td class="tl"></td>
- <td class="tr"></td>
- </tr>
- <tr>
- <td class="message">
- Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas aliquam sapien. Aliquam sed erat eu leo bibendum egestas. Praesent mauris. Quisque eget eros et neque scelerisque convallis. Phasellus orci. Pellentesque interdum tellus a erat. venenatis tristique.
- <div class="timeStamp">Torrey @ 4:55 am</div>
- </td>
- <td class="messageRight"></td>
- </tr>
- <tr>
- <td class="bl"></td>
- <td class="br"></td>
- </tr>
- </table>
- </div>
- </td>
- </tr>
- </table>
- </div>
-
-</div>
-</body>
-</html>
diff --git a/Swift/resources/themes/Default/Header.html b/Swift/resources/themes/Default/Header.html
deleted file mode 100755
index 960dfa1..0000000
--- a/Swift/resources/themes/Default/Header.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<div id="heading">
- <div class="conversationIncomingIcon"><img src="%incomingIconPath%" /></div>
- <div class="conversationWith">%chatName%</div>
- <div class="conversationTime">Conversation began %timeOpened%</div>
-</div>
diff --git a/Swift/resources/themes/Default/Incoming/Content.html b/Swift/resources/themes/Default/Incoming/Content.html
index dc5f8b2..15bc088 100755..100644
--- a/Swift/resources/themes/Default/Incoming/Content.html
+++ b/Swift/resources/themes/Default/Incoming/Content.html
@@ -1,30 +1,19 @@
-<div class="chatItem incomingItem">
- <table width="100%">
- <tr>
- <td valign="top">
- <img src="%userIconPath%" class="avatar" title="%sender%" ondragstart="return false" />
- <div class="myBubble">
- <div class="indicator"></div>
- <table class="tableBubble" cellspacing="0" cellpadding="0">
- <tr>
- <td class="tl"></td>
- <td class="tr"></td>
- </tr>
- <tr>
- <td class="message" style="direction: %direction%">
- %message%
- <div class="timeStamp"><span class="name">%wrapped_sender% @</span> %time%</div>
- <span id="insert"></span>
- </td>
- <td class="messageRight"></td>
- </tr>
- <tr>
- <td class="bl"></td>
- <td class="br"></td>
- </tr>
- </table>
- </div>
- </td>
- </tr>
- </table>
+<!--OTHERS MESSAGE-->
+<div class="message" id="%id%">
+ <div class="user">
+ <div class="otheravatar">
+ <img src="%userIconPath%"/>
+ </div>
+ <div class="otherright">
+ <span class="swift_ack"></span>
+ <span class="swift_receipt"></span>
+ </div>
+ </div>
+ <div class="text">
+ <p class="otherusername username">%wrapped_sender%</p>
+ <div class="time">
+ %time%
+ </div>
+ <div class="message-content">%message%</div>
+ </div>
</div>
diff --git a/Swift/resources/themes/Default/Incoming/Context.html b/Swift/resources/themes/Default/Incoming/Context.html
deleted file mode 100755
index 1f0c528..0000000
--- a/Swift/resources/themes/Default/Incoming/Context.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<div class="chatItem incomingItem">
- <table width="100%">
- <tr>
- <td valign="top">
- <img src="%userIconPath%" class="avatar" ondragstart="return false" />
- <div class="myBubble">
- <div class="indicator"></div>
- <table class="tableBubble" cellspacing="0" cellpadding="0">
- <tr>
- <td class="tl"></td>
- <td class="tr"></td>
- </tr>
- <tr>
- <td class="message" style="direction: %direction%">
- %message%
- <div class="timeStamp"><span class="name">%sender% @</span> %time%</div>
- <span id="insert"></span>
- </td>
- <td class="messageRight"></td>
- </tr>
- <tr>
- <td class="bl"></td>
- <td class="br"></td>
- </tr>
- </table>
- </div>
- </td>
- </tr>
- </table>
-</div>
diff --git a/Swift/resources/themes/Default/Incoming/NextContent.html b/Swift/resources/themes/Default/Incoming/NextContent.html
index aff669b..36fdaa3 100755..100644
--- a/Swift/resources/themes/Default/Incoming/NextContent.html
+++ b/Swift/resources/themes/Default/Incoming/NextContent.html
@@ -1,10 +1,18 @@
-<div>
- <div class="followUp"></div>
- <div style="direction: %direction%">
-
- %message%
- <div class="timeStamp">%time%</div>
- </div>
- <span id="insert"></span>
+<!--OTHERS MESSAGE ADDITIONAL-->
+<div class="message additional" id="%id%">
+ <div class="user">
+ <div class="systemavatar">
+ <img/>
+ </div>
+ <div class="systemright">
+ <span class="swift_ack"></span>
+ <span class="swift_receipt"></span>
+ </div>
+ </div>
+ <div class="text">
+ <div class="time">
+ %time%
+ </div>
+ <div class="message-content">%message%</div>
+ </div>
</div>
-
diff --git a/Swift/resources/themes/Default/Incoming/NextContext.html b/Swift/resources/themes/Default/Incoming/NextContext.html
deleted file mode 100755
index c0a8846..0000000
--- a/Swift/resources/themes/Default/Incoming/NextContext.html
+++ /dev/null
@@ -1,7 +0,0 @@
- <div class="followUp"></div>
- <div style="direction: %direction%">
-
- %message%
- <div class="timeStamp">%time%</div>
- </div><span id="insert"></span>
-
diff --git a/Swift/resources/themes/Default/Incoming/buddy_icon.png b/Swift/resources/themes/Default/Incoming/buddy_icon.png
deleted file mode 100644
index 0757aaa..0000000
--- a/Swift/resources/themes/Default/Incoming/buddy_icon.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/LICENSE.txt b/Swift/resources/themes/Default/LICENSE.txt
deleted file mode 100644
index 2eee1ee..0000000
--- a/Swift/resources/themes/Default/LICENSE.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-The images, css and html is dual licensed under the BSD and AFL license.
-The source files for the bubbles can be found at http://www.itorrey.com/adiumx/
-
-The fading javascript is not covered in this license. The code is fadomatic and is covered under its own license as set by its author.
-
-BSD LICENSE
-Copyright (c) 2007, Torrey Rice/Renkoo6¾3 All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Torrey Rice and Renkoo nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-Renkoo is a service mark of Renkoo, Inc.
-
-http://www.opensource.org/licenses/bsd-license.php
-
-
-
-# Larry Rosen has ceased to use or recommend any version # of the Academic Free License below version 2.1 The Academic Free License v. 2.1 This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following notice immediately following the copyright notice for the Original Work: Licensed under the Academic Free License version 2.1 1) Grant of Copyright License. Licensor hereby grants You a world-wide, royalty-free, non-exclusive, perpetual, sublicenseable license to do the following: a) to reproduce the Original Work in copies; b) to prepare derivative works ("Derivative Works") based upon the Original Work; c) to distribute copies of the Original Work and Derivative Works to the public; d) to perform the Original Work publicly; and e) to display the Original Work publicly. 2) Grant of Patent License. Licensor hereby grants You a world-wide, royalty-free, non-exclusive, perpetual, sublicenseable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, to make, use, sell and offer for sale the Original Work and Derivative Works. 3) Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor hereby agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work, and by publishing the address of that information repository in a notice immediately following the copyright notice that applies to the Original Work. 4) Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior written permission of the Licensor. Nothing in this License shall be deemed to grant any rights to trademarks, copyrights, patents, trade secrets or any other intellectual property of Licensor except as expressly stated herein. No patent license is granted to make, use, sell or offer to sell embodiments of any patent claims other than the licensed claims defined in Section 2. No right is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under different terms from this License any Original Work that Licensor otherwise would have a right to license. 5) This section intentionally omitted. 6) Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work. 7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately proceeding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to Original Work is granted hereunder except under this disclaimer. 8) Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to any person for any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to liability for death or personal injury resulting from Licensor's negligence to the extent applicable law prohibits such limitation. Some jurisdictions do not allow the exclusion or limitation of incidental or consequential damages, so this exclusion and limitation may not apply to You. 9) Acceptance and Termination. If You distribute copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. Nothing else but this License (or another written agreement between Licensor and You) grants You permission to create Derivative Works based upon the Original Work or to exercise any of the rights granted in Section 1 herein, and any attempt to do so except under the terms of this License (or another written agreement between Licensor and You) is expressly prohibited by U.S. copyright law, the equivalent laws of other countries, and by international treaty. Therefore, by exercising any of the rights granted to You in Section 1 herein, You indicate Your acceptance of this License and all of its terms and conditions. 10) Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware. 11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of the U.S. Copyright Act, 17 U.S.C. 0‡30¨¢0¡ã0ˆ3 101 et seq., the equivalent laws of other countries, and international treaty. This section shall survive the termination of this License. 12) Attorneys Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License. 13) Miscellaneous. This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. 14) Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. 15) Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You. This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved. Permission is hereby granted to copy and distribute this license without modification. This license may not be modified without the express written permission of its copyright owner. \ No newline at end of file
diff --git a/Swift/resources/themes/Default/Lato2OFL/Lato-Black.ttf b/Swift/resources/themes/Default/Lato2OFL/Lato-Black.ttf
new file mode 100644
index 0000000..e2aeb6c
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/Lato-Black.ttf
Binary files differ
diff --git a/Swift/resources/themes/Default/Lato2OFL/Lato-BlackItalic.ttf b/Swift/resources/themes/Default/Lato2OFL/Lato-BlackItalic.ttf
new file mode 100644
index 0000000..8167388
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/Lato-BlackItalic.ttf
Binary files differ
diff --git a/Swift/resources/themes/Default/Lato2OFL/Lato-Bold.ttf b/Swift/resources/themes/Default/Lato2OFL/Lato-Bold.ttf
new file mode 100644
index 0000000..ef5ae3b
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/Lato-Bold.ttf
Binary files differ
diff --git a/Swift/resources/themes/Default/Lato2OFL/Lato-BoldItalic.ttf b/Swift/resources/themes/Default/Lato2OFL/Lato-BoldItalic.ttf
new file mode 100644
index 0000000..664cd02
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/Lato-BoldItalic.ttf
Binary files differ
diff --git a/Swift/resources/themes/Default/Lato2OFL/Lato-Hairline.ttf b/Swift/resources/themes/Default/Lato2OFL/Lato-Hairline.ttf
new file mode 100644
index 0000000..4c5a8fd
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/Lato-Hairline.ttf
Binary files differ
diff --git a/Swift/resources/themes/Default/Lato2OFL/Lato-HairlineItalic.ttf b/Swift/resources/themes/Default/Lato2OFL/Lato-HairlineItalic.ttf
new file mode 100644
index 0000000..af5ac3d
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/Lato-HairlineItalic.ttf
Binary files differ
diff --git a/Swift/resources/themes/Default/Lato2OFL/Lato-Heavy.ttf b/Swift/resources/themes/Default/Lato2OFL/Lato-Heavy.ttf
new file mode 100644
index 0000000..fc70ab7
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/Lato-Heavy.ttf
Binary files differ
diff --git a/Swift/resources/themes/Default/Lato2OFL/Lato-HeavyItalic.ttf b/Swift/resources/themes/Default/Lato2OFL/Lato-HeavyItalic.ttf
new file mode 100644
index 0000000..823188c
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/Lato-HeavyItalic.ttf
Binary files differ
diff --git a/Swift/resources/themes/Default/Lato2OFL/Lato-Italic.ttf b/Swift/resources/themes/Default/Lato2OFL/Lato-Italic.ttf
new file mode 100644
index 0000000..b23256f
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/Lato-Italic.ttf
Binary files differ
diff --git a/Swift/resources/themes/Default/Lato2OFL/Lato-Light.ttf b/Swift/resources/themes/Default/Lato2OFL/Lato-Light.ttf
new file mode 100644
index 0000000..0809b8e
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/Lato-Light.ttf
Binary files differ
diff --git a/Swift/resources/themes/Default/Lato2OFL/Lato-LightItalic.ttf b/Swift/resources/themes/Default/Lato2OFL/Lato-LightItalic.ttf
new file mode 100644
index 0000000..2d03739
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/Lato-LightItalic.ttf
Binary files differ
diff --git a/Swift/resources/themes/Default/Lato2OFL/Lato-Medium.ttf b/Swift/resources/themes/Default/Lato2OFL/Lato-Medium.ttf
new file mode 100644
index 0000000..2c612da
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/Lato-Medium.ttf
Binary files differ
diff --git a/Swift/resources/themes/Default/Lato2OFL/Lato-MediumItalic.ttf b/Swift/resources/themes/Default/Lato2OFL/Lato-MediumItalic.ttf
new file mode 100644
index 0000000..63ecd02
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/Lato-MediumItalic.ttf
Binary files differ
diff --git a/Swift/resources/themes/Default/Lato2OFL/Lato-Regular.ttf b/Swift/resources/themes/Default/Lato2OFL/Lato-Regular.ttf
new file mode 100644
index 0000000..adbfc46
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/Lato-Regular.ttf
Binary files differ
diff --git a/Swift/resources/themes/Default/Lato2OFL/Lato-Semibold.ttf b/Swift/resources/themes/Default/Lato2OFL/Lato-Semibold.ttf
new file mode 100644
index 0000000..60ac82d
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/Lato-Semibold.ttf
Binary files differ
diff --git a/Swift/resources/themes/Default/Lato2OFL/Lato-SemiboldItalic.ttf b/Swift/resources/themes/Default/Lato2OFL/Lato-SemiboldItalic.ttf
new file mode 100644
index 0000000..cc23390
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/Lato-SemiboldItalic.ttf
Binary files differ
diff --git a/Swift/resources/themes/Default/Lato2OFL/Lato-Thin.ttf b/Swift/resources/themes/Default/Lato2OFL/Lato-Thin.ttf
new file mode 100644
index 0000000..0f84dc1
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/Lato-Thin.ttf
Binary files differ
diff --git a/Swift/resources/themes/Default/Lato2OFL/Lato-ThinItalic.ttf b/Swift/resources/themes/Default/Lato2OFL/Lato-ThinItalic.ttf
new file mode 100644
index 0000000..7fbca2f
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/Lato-ThinItalic.ttf
Binary files differ
diff --git a/Swift/resources/themes/Default/Lato2OFL/OFL.txt b/Swift/resources/themes/Default/Lato2OFL/OFL.txt
new file mode 100755
index 0000000..8a7280e
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/OFL.txt
@@ -0,0 +1,94 @@
+Copyright (c) 2010-2015, Åukasz Dziedzic (dziedzic@typoland.com),
+with Reserved Font Name Lato.
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/Swift/resources/themes/Default/Lato2OFL/README.txt b/Swift/resources/themes/Default/Lato2OFL/README.txt
new file mode 100755
index 0000000..272db62
--- /dev/null
+++ b/Swift/resources/themes/Default/Lato2OFL/README.txt
@@ -0,0 +1,72 @@
+
+Lato font family (Desktop version)
+
+==================================
+
+Version 2.015; Latin+Cyrillic+Greek+IPA opensource
+
+Created by: tyPoland Lukasz Dziedzic
+Creation year: 2015
+
+Copyright (c) 2010-2015 by tyPoland Lukasz Dziedzic with Reserved Font Name "Lato". Licensed under the SIL Open Font License, Version 1.1.
+
+Lato is a trademark of tyPoland Lukasz Dziedzic.
+
+Source URL: http://www.latofonts.com/
+License URL: http://scripts.sil.org/OFL
+
+================
+
+Lato is a sanserif typeface family designed in the Summer 2010 and extended in the Summer 2013 by Warsaw-based designer Lukasz Dziedzic ("Lato" means "Summer" in Polish). It tries to carefully balance some potentially conflicting priorities: it should seem quite "transparent" when used in body text but would display some original traits when used in larger sizes. The classical proportions, particularly visible in the uppercase, give the letterforms familiar harmony and elegance. At the same time, its sleek sanserif look makes evident the fact that Lato was designed in the 2010s, even though it does not follow any current trend. The semi-rounded details of the letters give Lato a feeling of warmth, while the strong structure provides stability and seriousness. In 2013-2014, the family was greatly extended (with the help of Adam Twardoch and Botio Nikoltchev) to cover 3000+ glyphs over nine weights with italics. It now supports 100+ Latin-based languages, 50+ Cyrillic-based languages as well as Greek and IPA phonetics. The Lato fonts are available free of charge under the SIL Open Font License from http://www.latofonts.com/
+
+================
+
+CONTENTS:
+
+This folder contains 18 font files in OpenType TT (.ttf) format. You can install these fonts on your computer and use in any desktop applications (such as Word, InDesign, Illustrator, Photoshop, Keynote or Pages).
+
+================
+
+REVISION LOG:
+
+# Version 2.015 (2015-08-06)
+Initial implementation of mark positioning (should work for most glyphs)
+Autohinted using ttfautohint 1.3.
+
+# Version 2.010 (2014-09-01)
+Improved some contour bugs and diacritics positioning.
+Improved outline quality.
+Revised OTL features so that they work in browsers (ot-sanitise).
+Autohinted using ttfautohint 1.1.
+Interpolated the Medium weight differently so it provides more visual difference from Regular.
+
+# Version 2.007 (2014-02-27)
+Greatly expanded character set, revised metrics, four additional weights.
+
+# Version 1.104 (2011-11-08)
+Merged the distribution again
+Autohinted with updated ttfautohint 0.4 (which no longer causes Adobe and iOS problems)
+except the Hai and Lig weights which are hinted in FLS 5.1.
+
+# Version 1.102 (2011-10-28)
+Added OpenType Layout features
+Ssplit between desktop and web versions
+Desktop version: all weights autohinted with FontLab Studio
+Web version autohinted with ttfautohint 0.4 except the Hai and Lig weights
+
+# Version 1.101 (2011-09-30)
+Fixed OS/2 table Unicode and codepage entries
+
+# Version 1.100 (2011-09-12)
+Added Polish diacritics to the character set
+Weights Hai and Lig autohinted with FontLab Studio
+Other weights autohinted with ttfautohint 0.3
+
+# Version 1.011 (2010-12-29)
+Added the soft hyphen glyph
+
+# Version 1.010 (2010-12-13)
+Initial version released under SIL Open Font License
+Western character set
+
+================
diff --git a/Swift/resources/themes/Default/Outgoing/Content.html b/Swift/resources/themes/Default/Outgoing/Content.html
index b0475d2..e73e785 100755..100644
--- a/Swift/resources/themes/Default/Outgoing/Content.html
+++ b/Swift/resources/themes/Default/Outgoing/Content.html
@@ -1,30 +1,19 @@
-<div class="chatItem outgoingItem">
- <table width="100%">
- <tr>
- <td valign="top">
- <img src="%userIconPath%" class="avatar" title="%sender%" ondragstart="return false" />
- <div class="myBubble">
- <div class="indicator"></div>
- <table class="tableBubble" cellspacing="0" cellpadding="0">
- <tr>
- <td class="tl"></td>
- <td class="tr"></td>
- </tr>
- <tr>
- <td class="message" style="direction: %direction%">
- %message%
- <div class="timeStamp"><span class="name">%wrapped_sender% @</span> %time%</div>
- <span id="insert"></span>
- </td>
- <td class="messageRight"></td>
- </tr>
- <tr>
- <td class="bl"></td>
- <td class="br"></td>
- </tr>
- </table>
- </div>
- </td>
- </tr>
- </table>
+<!--MY MESSAGE-->
+<div class="message" id="%id%">
+ <div class="user">
+ <div class="myavatar">
+ <img src="%userIconPath%"/>
+ </div>
+ <div class="myright">
+ <span class="swift_ack"></span>
+ <span class="swift_receipt"></span>
+ </div>
+ </div>
+ <div class="text">
+ <p class="myusername username">%wrapped_sender%</p>
+ <div class="time">
+ %time%
+ </div>
+ <div class="message-content">%message%</div>
+ </div>
</div>
diff --git a/Swift/resources/themes/Default/Outgoing/Context.html b/Swift/resources/themes/Default/Outgoing/Context.html
deleted file mode 100755
index 679d786..0000000
--- a/Swift/resources/themes/Default/Outgoing/Context.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<div class="chatItem outgoingItem">
- <table width="100%">
- <tr>
- <td valign="top">
- <img src="%userIconPath%" class="avatar" ondragstart="return false" />
- <div class="myBubble">
- <div class="indicator"></div>
- <table class="tableBubble" cellspacing="0" cellpadding="0">
- <tr>
- <td class="tl"></td>
- <td class="tr"></td>
- </tr>
- <tr>
- <td class="message" style="direction: %direction%">
-
- %message%
- <div class="timeStamp"><span class="name">%sender% @</span> %time%</div>
- <span id="insert"></span>
- </td>
- <td class="messageRight"></td>
- </tr>
- <tr>
- <td class="bl"></td>
- <td class="br"></td>
- </tr>
- </table>
- </div>
- </td>
- </tr>
- </table>
-</div>
diff --git a/Swift/resources/themes/Default/Outgoing/NextContent.html b/Swift/resources/themes/Default/Outgoing/NextContent.html
index fe6490e..f96f65a 100755..100644
--- a/Swift/resources/themes/Default/Outgoing/NextContent.html
+++ b/Swift/resources/themes/Default/Outgoing/NextContent.html
@@ -1,9 +1,19 @@
-<div>
- <div class="followUp"></div>
- <div style="direction: %direction%">
- %message%
- <div class="timeStamp">%time%</div>
- </div>
- <span id="insert"></span>
+<!--My MESSAGE ADDITIONAL-->
+<div class="message additional" id="%id%">
+ <div class="user">
+ <div class="systemavatar">
+ <img/>
+ </div>
+ <div class="systemright">
+ <span class="swift_ack"></span>
+ <span class="swift_receipt"></span>
+ </div>
+ </div>
+ <div class="text">
+ <div class="time">
+ %time%
+ </div>
+ <div class="message-content">%message%</div>
+ </div>
</div>
diff --git a/Swift/resources/themes/Default/Outgoing/NextContext.html b/Swift/resources/themes/Default/Outgoing/NextContext.html
deleted file mode 100755
index f66aeeb..0000000
--- a/Swift/resources/themes/Default/Outgoing/NextContext.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<div class="followUp"></div>
-<div style="direction: %direction%">
- %message%
- <div class="timeStamp">%time%</div>
-</div><span id="insert"></span>
-
diff --git a/Swift/resources/themes/Default/Outgoing/buddy_icon.png b/Swift/resources/themes/Default/Outgoing/buddy_icon.png
deleted file mode 100644
index 0757aaa..0000000
--- a/Swift/resources/themes/Default/Outgoing/buddy_icon.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/Status.html b/Swift/resources/themes/Default/Status.html
index e7add89..0a0aaed 100755..100644
--- a/Swift/resources/themes/Default/Status.html
+++ b/Swift/resources/themes/Default/Status.html
@@ -1,27 +1,15 @@
-<div class="chatItem statusMessage">
- <table width="100%">
- <tr>
- <td valign="top">
- <div class="myBubble">
- <table class="tableBubble" cellspacing="0" cellpadding="0">
- <tr>
- <td class="tl"></td>
- <td class="tr"></td>
- </tr>
- <tr>
- <td class="message" style="direction: %direction%">
- %message%
- <div class="timeStamp">%time%</div>
- </td>
- <td class="messageRight"></td>
- </tr>
- <tr>
- <td class="bl"></td>
- <td class="br"></td>
- </tr>
- </table>
- </div>
- </td>
- </tr>
- </table>
+<!--SYSTEM MESSAGE-->
+<div class="message" id="%id%">
+ <div class="user">
+ <div class="systemavatar">
+ <img/>
+ </div>
+ <div class="systemright"></div>
+ </div>
+ <div class="text">
+ <div class="time">
+ %time%
+ </div>
+ <p class="system-message">%message%</p>
+ </div>
</div>
diff --git a/Swift/resources/themes/Default/Template.html b/Swift/resources/themes/Default/Template.html
index 9d5c3a0..74c5e46 100755..100644
--- a/Swift/resources/themes/Default/Template.html
+++ b/Swift/resources/themes/Default/Template.html
@@ -1,343 +1,20 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8" />
- <base href="%@">
-
- <script type="text/javascript">
- //<![CDATA[
-
- isDebug = false;
-
- // Fade interval in milliseconds
- // Make this larger if you experience performance issues
- Fadomatic.INTERVAL_MILLIS = 50;
-
- // Creates a fader
- // element - The element to fade
- // speed - The speed to fade at, from 0.0 to 100.0
- // initialOpacity (optional, default 100) - element's starting opacity, 0 to 100
- // minOpacity (optional, default 0) - element's minimum opacity, 0 to 100
- // maxOpacity (optional, default 0) - element's minimum opacity, 0 to 100
- function Fadomatic (element, rate, initialOpacity, minOpacity, maxOpacity) {
- this._element = element;
- this._intervalId = null;
- this._rate = rate;
- this._isFadeOut = true;
-
- // Set initial opacity and bounds
- // NB use 99 instead of 100 to avoid flicker at start of fade
- this._minOpacity = 0;
- this._maxOpacity = 99;
- this._opacity = 99;
-
- if (typeof minOpacity != 'undefined') {
- if (minOpacity < 0) {
- this._minOpacity = 0;
- } else if (minOpacity > 99) {
- this._minOpacity = 99;
- } else {
- this._minOpacity = minOpacity;
- }
- }
-
- if (typeof maxOpacity != 'undefined') {
- if (maxOpacity < 0) {
- this._maxOpacity = 0;
- } else if (maxOpacity > 99) {
- this._maxOpacity = 99;
- } else {
- this._maxOpacity = maxOpacity;
- }
-
- if (this._maxOpacity < this._minOpacity) {
- this._maxOpacity = this._minOpacity;
- }
- }
-
- if (typeof initialOpacity != 'undefined') {
- if (initialOpacity > this._maxOpacity) {
- this._opacity = this._maxOpacity;
- } else if (initialOpacity < this._minOpacity) {
- this._opacity = this._minOpacity;
- } else {
- this._opacity = initialOpacity;
- }
- }
-
- // See if we're using W3C opacity, MSIE filter, or just
- // toggling visiblity
- if(typeof element.style.opacity != 'undefined') {
-
- this._updateOpacity = this._updateOpacityW3c;
-
- } else if(typeof element.style.filter != 'undefined') {
-
- // If there's not an alpha filter on the element already,
- // add one
- if (element.style.filter.indexOf("alpha") == -1) {
-
- // Attempt to preserve existing filters
- var existingFilters="";
- if (element.style.filter) {
- existingFilters = element.style.filter+" ";
- }
- element.style.filter = existingFilters+"alpha(opacity="+this._opacity+")";
- }
-
- this._updateOpacity = this._updateOpacityMSIE;
-
- } else {
-
- this._updateOpacity = this._updateVisibility;
- }
-
- this._updateOpacity();
- }
-
- // Initiates a fade out
- Fadomatic.prototype.fadeOut = function () {
- this._isFadeOut = true;
- this._beginFade();
- }
-
- // Initiates a fade in
- Fadomatic.prototype.fadeIn = function () {
- this._isFadeOut = false;
- this._beginFade();
- }
-
- // Makes the element completely opaque, stops any fade in progress
- Fadomatic.prototype.show = function () {
- this.haltFade();
- this._opacity = this._maxOpacity;
- this._updateOpacity();
- }
-
- // Makes the element completely transparent, stops any fade in progress
- Fadomatic.prototype.hide = function () {
- this.haltFade();
- this._opacity = 0;
- this._updateOpacity();
- }
-
- // Halts any fade in progress
- Fadomatic.prototype.haltFade = function () {
-
- clearInterval(this._intervalId);
- }
-
- // Resumes a fade where it was halted
- Fadomatic.prototype.resumeFade = function () {
-
- this._beginFade();
- }
-
- // Pseudo-private members
-
- Fadomatic.prototype._beginFade = function () {
-
- this.haltFade();
- var objref = this;
- this._intervalId = setInterval(function() { objref._tickFade(); },Fadomatic.INTERVAL_MILLIS);
- }
-
- Fadomatic.prototype._tickFade = function () {
-
- if (this._isFadeOut) {
- this._opacity -= this._rate;
- if (this._opacity < this._minOpacity) {
- this._opacity = this._minOpacity;
- this.haltFade();
- }
- } else {
- this._opacity += this._rate;
- if (this._opacity > this._maxOpacity ) {
- this._opacity = this._maxOpacity;
- this.haltFade();
- }
- }
-
- this._updateOpacity();
- }
-
- Fadomatic.prototype._updateVisibility = function () {
-
- if (this._opacity > 0) {
- this._element.style.visibility = 'visible';
- } else {
- this._element.style.visibility = 'hidden';
- }
- }
-
- Fadomatic.prototype._updateOpacityW3c = function () {
-
- this._element.style.opacity = this._opacity/100;
- this._updateVisibility();
- }
-
- Fadomatic.prototype._updateOpacityMSIE = function () {
-
- this._element.filters.alpha.opacity = this._opacity;
- this._updateVisibility();
- }
-
- Fadomatic.prototype._updateOpacity = null;
-
-
-
- //Do this on load
- function initEvents() {
- if(document.getElementById("heading") == null){
- document.getElementById("bodyNode").style.marginTop = "5px";
- }
-
- if(isDebug == false) {
- document.getElementById("debug").style.display = "none";
- }
-
-
- alignChat(true);
- }
- //Debugging function
- function trace(msg) {
- var node = document.createElement("div");
- var debugCon = document.getElementById("debug");
- node.innerHTML = msg;
- debugCon.appendChild(node);
- }
-
-
- //Appending new content to the message view
- function appendMessage(html) {
- var shouldScroll = nearBottom();
-
- //Remove any existing insertion point
- var insert = document.getElementById("insert");
-
- if(insert) insert.parentNode.removeChild(insert);
-
- //Append the new message to the bottom of our chat block
- var chat = document.getElementById("Chat");
- var range = document.createRange();
- range.selectNode(chat);
- var documentFragment = range.createContextualFragment(html);
- var myFrag = chat.appendChild(documentFragment);
-
- // Don't do the fadomatic, it's too slow
- /*
- var frag1 = document.getElementById("insert");
- if (frag1) {
- var frag= frag1.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
-
- try {
- var fader = new Fadomatic(frag, 9, 0, 0, 95);
- } catch(e) {
- trace(e);
- }
- fader.fadeIn();
- }
- */
-
- alignChat(shouldScroll);
- }
-
-
- function appendNextMessage(html){
- var shouldScroll = nearBottom();
-
- //Locate the insertion point
- var insert = document.getElementById("insert");
-
- //make new node
- range = document.createRange();
- range.selectNode(insert.parentNode);
- newNode = range.createContextualFragment(html);
-
- //swap
- var pointer = insert.parentNode;
- insert.parentNode.replaceChild(newNode,insert);
- var els = pointer.getElementsByTagName("div");
-
- alignChat(shouldScroll);
- }
-
-
- //Auto-scroll to bottom. Use nearBottom to determine if a scrollToBottom is desired.
- function nearBottom() {
- return ( document.body.scrollTop >= ( document.body.offsetHeight - ( window.innerHeight * 1.2 ) ) );
- }
-
- var intervall_scroll;
- function scrollToBottom() {
- //document.body.scrollTop = (document.body.scrollHeight-window.innerHeight);
- //return;
- if( intervall_scroll ) clearInterval( intervall_scroll );
- intervall_scroll = setInterval( function() {
- var target_scroll = (document.body.scrollHeight-window.innerHeight) - 1;
- var scrolldiff = target_scroll - document.body.scrollTop;
- if ( document.body.scrollTop != target_scroll ) {
- var saved_scroll = document.body.scrollTop;
- document.body.scrollTop += scrolldiff / 5 + ( scrolldiff >= 0 ? (scrolldiff != 0 ) : -1 );
- } else {
- saved_scroll = -1;
- clearInterval( intervall_scroll );
- }
- } , 10 );
- return;
- }
-
-
- //Dynamically exchange the active stylesheet
- function setStylesheet( id, url ) {
- var code = "<style id=\"" + id + "\" type=\"text/css\" media=\"screen,print\">";
- if( url.length ) code += "@import url( \"" + url + "\" );";
- code += "</style>";
- var range = document.createRange();
- var head = document.getElementsByTagName( "head" ).item(0);
- range.selectNode( head );
- documentFragment = range.createContextualFragment( code );
- head.removeChild( document.getElementById( id ) );
- head.appendChild( documentFragment );
- }
-
- //Align our chat to the bottom of the window. If true is passed, view will also be scrolled down
- function alignChat(shouldScroll) {
-
- var windowHeight = window.innerHeight;
-
- if(windowHeight > 0) {
- var contentElement = document.getElementById('Chat');
- var contentHeight = contentElement.offsetHeight;
- if (windowHeight - contentHeight > 0) {
- contentElement.style.position = 'relative';
- contentElement.style.top = '0px';
- } else {
- contentElement.style.position = 'static';
- }
- }
-
- if(shouldScroll) scrollToBottom();
- }
-
- function windowDidResize() {
- alignChat(true/*nearBottom()*/); //nearBottom buggy with inavtive tabs
- }
-
- window.onresize = windowDidResize;
- //]]>
- </script>
-
- <style id="mainStyle" type="text/css" media="screen,print"> @import url( "%@" ); </style>
-
-</head>
-<body style="==bodyBackground==" id="bodyNode" onload="initEvents()">
-%@
-<div id="Chat">
-</div>
-%@
-<div id="debug"></div>
-</body>
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <link rel="stylesheet" href="qrc:///themes/Default/lato.css"/>
+ <link rel="stylesheet" href="qrc:///themes/Default/main.css"/>
+ <style id="text-resize-style">
+ </style>
+ </head>
+ <body>
+ <div class="container">
+ <div class="message-block">
+ <div id="insert">
+ <div class="user"></div><div class="text"></div>
+ </div>
+ </div>
+ </div>
+ </body>
</html>
diff --git a/Swift/resources/themes/Default/Unread.html b/Swift/resources/themes/Default/Unread.html
new file mode 100644
index 0000000..3e25431
--- /dev/null
+++ b/Swift/resources/themes/Default/Unread.html
@@ -0,0 +1 @@
+<div class='unread'><div class="user"></div><div class="text"><span class="swift_resizable"><p>Unread</p></span></div></div> \ No newline at end of file
diff --git a/Swift/resources/themes/Default/Variants/Blue on Green Alternating.css b/Swift/resources/themes/Default/Variants/Blue on Green Alternating.css
deleted file mode 100644
index 5b910eb..0000000
--- a/Swift/resources/themes/Default/Variants/Blue on Green Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Blue on Green.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/blueIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Blue on Green No Names Alt.css b/Swift/resources/themes/Default/Variants/Blue on Green No Names Alt.css
deleted file mode 100644
index ebad314..0000000
--- a/Swift/resources/themes/Default/Variants/Blue on Green No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Blue on Green Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Blue on Green No Names.css b/Swift/resources/themes/Default/Variants/Blue on Green No Names.css
deleted file mode 100644
index 2a0902c..0000000
--- a/Swift/resources/themes/Default/Variants/Blue on Green No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Blue on Green.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Blue on Green.css b/Swift/resources/themes/Default/Variants/Blue on Green.css
deleted file mode 100644
index 361c8c6..0000000
--- a/Swift/resources/themes/Default/Variants/Blue on Green.css
+++ /dev/null
@@ -1,90 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#7fc5f8;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/blueIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/blueCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/blueCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/blueCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/blueBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/blueBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/blueCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/blueCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#ddf0fe;
- border-bottom:1px solid #fff;
-}
-
-/*incoming */
-
-.incomingItem .myBubble .indicator {
- background:url("../images/greenIndicator.png") no-repeat top left;
-}
-
-.incomingItem .timeStamp {
- color:#9ecf35;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/greenCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/greenCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/greenCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/greenBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/greenBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/greenCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/greenCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#e2efc4;
- border-bottom:1px solid #fff;
-}
-
-
diff --git a/Swift/resources/themes/Default/Variants/Blue on Red Alternating.css b/Swift/resources/themes/Default/Variants/Blue on Red Alternating.css
deleted file mode 100644
index 5481c10..0000000
--- a/Swift/resources/themes/Default/Variants/Blue on Red Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Blue on Red.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/blueIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Blue on Red No Names Alt.css b/Swift/resources/themes/Default/Variants/Blue on Red No Names Alt.css
deleted file mode 100644
index 9818a6c..0000000
--- a/Swift/resources/themes/Default/Variants/Blue on Red No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Blue on Red Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Blue on Red No Names.css b/Swift/resources/themes/Default/Variants/Blue on Red No Names.css
deleted file mode 100644
index 3ac8c9a..0000000
--- a/Swift/resources/themes/Default/Variants/Blue on Red No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Blue on Red.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Blue on Red.css b/Swift/resources/themes/Default/Variants/Blue on Red.css
deleted file mode 100644
index 0717920..0000000
--- a/Swift/resources/themes/Default/Variants/Blue on Red.css
+++ /dev/null
@@ -1,89 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#7fc5f8;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/blueIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/blueCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/blueCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/blueCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/blueBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/blueBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/blueCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/blueCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#ddf0fe;
- border-bottom:1px solid #fff;
-}
-
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#f88f8f;
-}
-
-.incomingItem .myBubble .indicator {
- background:url("../images/redIndicator.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/redCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/redCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/redCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/redBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/redBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/redCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/redCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#ffdada;
- border-bottom:1px solid #fff;
-}
diff --git a/Swift/resources/themes/Default/Variants/Blue on Steel Alternating.css b/Swift/resources/themes/Default/Variants/Blue on Steel Alternating.css
deleted file mode 100644
index 8473d1f..0000000
--- a/Swift/resources/themes/Default/Variants/Blue on Steel Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Blue on Steel.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/blueIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Blue on Steel No Names Alt.css b/Swift/resources/themes/Default/Variants/Blue on Steel No Names Alt.css
deleted file mode 100644
index 1925d5c..0000000
--- a/Swift/resources/themes/Default/Variants/Blue on Steel No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Blue on Steel Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Blue on Steel No Names.css b/Swift/resources/themes/Default/Variants/Blue on Steel No Names.css
deleted file mode 100644
index 573aa58..0000000
--- a/Swift/resources/themes/Default/Variants/Blue on Steel No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Blue on Steel.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Blue on Steel.css b/Swift/resources/themes/Default/Variants/Blue on Steel.css
deleted file mode 100644
index 48ab03d..0000000
--- a/Swift/resources/themes/Default/Variants/Blue on Steel.css
+++ /dev/null
@@ -1,91 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#7fc5f8;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/blueIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/blueCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/blueCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/blueCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/blueBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/blueBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/blueCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/blueCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#ddf0fe;
- border-bottom:1px solid #fff;
-}
-
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#a9a9a9;
-}
-
-.incomingItem .myBubble .indicator {
- background:url("../images/steelIndicator.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/steelCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/steelCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/steelCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/steelBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/steelBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/steelCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/steelCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#ececec;
- border-bottom:1px solid #fff;
-}
-
-
diff --git a/Swift/resources/themes/Default/Variants/Blue on Yellow Alternating.css b/Swift/resources/themes/Default/Variants/Blue on Yellow Alternating.css
deleted file mode 100644
index d7927fc..0000000
--- a/Swift/resources/themes/Default/Variants/Blue on Yellow Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Blue on Yellow.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/blueIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Blue on Yellow No Names Alt.css b/Swift/resources/themes/Default/Variants/Blue on Yellow No Names Alt.css
deleted file mode 100644
index 38d374d..0000000
--- a/Swift/resources/themes/Default/Variants/Blue on Yellow No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Blue on Yellow Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Blue on Yellow No Names.css b/Swift/resources/themes/Default/Variants/Blue on Yellow No Names.css
deleted file mode 100644
index 3fdc8cd..0000000
--- a/Swift/resources/themes/Default/Variants/Blue on Yellow No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Blue on Yellow.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Blue on Yellow.css b/Swift/resources/themes/Default/Variants/Blue on Yellow.css
deleted file mode 100644
index b019b0b..0000000
--- a/Swift/resources/themes/Default/Variants/Blue on Yellow.css
+++ /dev/null
@@ -1,91 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#7fc5f8;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/blueIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/blueCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/blueCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/blueCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/blueBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/blueBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/blueCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/blueCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#ddf0fe;
- border-bottom:1px solid #fff;
-}
-
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#bdb410;
-}
-
-.incomingItem .myBubble .indicator {
- background:url("../images/yellowIndicator.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/yellowCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/yellowCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/yellowCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/yellowBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/yellowBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/yellowCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/yellowCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#f4f0a7;
- border-bottom:1px solid #fff;
-}
-
-
diff --git a/Swift/resources/themes/Default/Variants/Green on Blue Alternating.css b/Swift/resources/themes/Default/Variants/Green on Blue Alternating.css
deleted file mode 100644
index 272c0d0..0000000
--- a/Swift/resources/themes/Default/Variants/Green on Blue Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Green on Blue.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/greenIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Green on Blue No Names Alt.css b/Swift/resources/themes/Default/Variants/Green on Blue No Names Alt.css
deleted file mode 100644
index 973f91a..0000000
--- a/Swift/resources/themes/Default/Variants/Green on Blue No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Green on Blue Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Green on Blue No Names.css b/Swift/resources/themes/Default/Variants/Green on Blue No Names.css
deleted file mode 100644
index 0d92eb0..0000000
--- a/Swift/resources/themes/Default/Variants/Green on Blue No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Green on Blue.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Green on Blue.css b/Swift/resources/themes/Default/Variants/Green on Blue.css
deleted file mode 100644
index 7185f4f..0000000
--- a/Swift/resources/themes/Default/Variants/Green on Blue.css
+++ /dev/null
@@ -1,91 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#9ecf35;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/greenIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/greenCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/greenCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/greenCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/greenBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/greenBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/greenCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/greenCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#e2efc4;
- border-bottom:1px solid #fff;
-}
-
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#7fc5f8;
-}
-
-.incomingItem .myBubble .indicator {
- background:url("../images/blueIndicator.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/blueCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/blueCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/blueCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/blueBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/blueBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/blueCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/blueCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#ddf0fe;
- border-bottom:1px solid #fff;
-}
-
-
diff --git a/Swift/resources/themes/Default/Variants/Green on Red Alternating.css b/Swift/resources/themes/Default/Variants/Green on Red Alternating.css
deleted file mode 100644
index e656dc0..0000000
--- a/Swift/resources/themes/Default/Variants/Green on Red Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Green on Red.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/greenIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Green on Red No Names Alt.css b/Swift/resources/themes/Default/Variants/Green on Red No Names Alt.css
deleted file mode 100644
index 5fd2482..0000000
--- a/Swift/resources/themes/Default/Variants/Green on Red No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Green on Red Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Green on Red No Names.css b/Swift/resources/themes/Default/Variants/Green on Red No Names.css
deleted file mode 100644
index 23dae81..0000000
--- a/Swift/resources/themes/Default/Variants/Green on Red No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Green on Red.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Green on Red.css b/Swift/resources/themes/Default/Variants/Green on Red.css
deleted file mode 100644
index cdf38b3..0000000
--- a/Swift/resources/themes/Default/Variants/Green on Red.css
+++ /dev/null
@@ -1,91 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#9ecf35;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/greenIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/greenCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/greenCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/greenCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/greenBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/greenBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/greenCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/greenCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#e2efc4;
- border-bottom:1px solid #fff;
-}
-
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#f88f8f;
-}
-
-.incomingItem .myBubble .indicator {
- background:url("../images/redIndicator.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/redCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/redCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/redCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/redBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/redBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/redCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/redCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#ffdada;
- border-bottom:1px solid #fff;
-}
-
-
diff --git a/Swift/resources/themes/Default/Variants/Green on Steel Alternating.css b/Swift/resources/themes/Default/Variants/Green on Steel Alternating.css
deleted file mode 100644
index 3c14f7f..0000000
--- a/Swift/resources/themes/Default/Variants/Green on Steel Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Green on Steel.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/greenIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Green on Steel No Names Alt.css b/Swift/resources/themes/Default/Variants/Green on Steel No Names Alt.css
deleted file mode 100644
index cfd6bb9..0000000
--- a/Swift/resources/themes/Default/Variants/Green on Steel No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Green on Steel Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Green on Steel No Names.css b/Swift/resources/themes/Default/Variants/Green on Steel No Names.css
deleted file mode 100644
index 41bc9de..0000000
--- a/Swift/resources/themes/Default/Variants/Green on Steel No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Green on Steel.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Green on Steel.css b/Swift/resources/themes/Default/Variants/Green on Steel.css
deleted file mode 100644
index 30a78a0..0000000
--- a/Swift/resources/themes/Default/Variants/Green on Steel.css
+++ /dev/null
@@ -1,91 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#9ecf35;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/greenIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/greenCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/greenCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/greenCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/greenBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/greenBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/greenCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/greenCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#e2efc4;
- border-bottom:1px solid #fff;
-}
-
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#a9a9a9;
-}
-
-.incomingItem .myBubble .indicator {
- background:url("../images/steelIndicator.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/steelCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/steelCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/steelCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/steelBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/steelBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/steelCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/steelCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#ececec;
- border-bottom:1px solid #fff;
-}
-
-
diff --git a/Swift/resources/themes/Default/Variants/Green on Yellow Alternating.css b/Swift/resources/themes/Default/Variants/Green on Yellow Alternating.css
deleted file mode 100644
index d0553e8..0000000
--- a/Swift/resources/themes/Default/Variants/Green on Yellow Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Green on Yellow.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/greenIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Green on Yellow No Names Alt.css b/Swift/resources/themes/Default/Variants/Green on Yellow No Names Alt.css
deleted file mode 100644
index 27adc33..0000000
--- a/Swift/resources/themes/Default/Variants/Green on Yellow No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Green on Yellow Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Green on Yellow No Names.css b/Swift/resources/themes/Default/Variants/Green on Yellow No Names.css
deleted file mode 100644
index 8c8cb28..0000000
--- a/Swift/resources/themes/Default/Variants/Green on Yellow No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Green on Yellow.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Green on Yellow.css b/Swift/resources/themes/Default/Variants/Green on Yellow.css
deleted file mode 100644
index d7f64d3..0000000
--- a/Swift/resources/themes/Default/Variants/Green on Yellow.css
+++ /dev/null
@@ -1,91 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#9ecf35;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/greenIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/greenCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/greenCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/greenCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/greenBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/greenBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/greenCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/greenCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#e2efc4;
- border-bottom:1px solid #fff;
-}
-
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#bdb410;
-}
-
-.incomingItem .myBubble .indicator {
- background:url("../images/yellowIndicator.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/yellowCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/yellowCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/yellowCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/yellowBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/yellowBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/yellowCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/yellowCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#f4f0a7;
- border-bottom:1px solid #fff;
-}
-
-
diff --git a/Swift/resources/themes/Default/Variants/Red on Blue Alternating.css b/Swift/resources/themes/Default/Variants/Red on Blue Alternating.css
deleted file mode 100644
index 5d241fb..0000000
--- a/Swift/resources/themes/Default/Variants/Red on Blue Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Red on Blue.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/redIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Red on Blue No Names Alt.css b/Swift/resources/themes/Default/Variants/Red on Blue No Names Alt.css
deleted file mode 100644
index 2e80935..0000000
--- a/Swift/resources/themes/Default/Variants/Red on Blue No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Red on Blue Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Red on Blue No Names.css b/Swift/resources/themes/Default/Variants/Red on Blue No Names.css
deleted file mode 100644
index da98b5c..0000000
--- a/Swift/resources/themes/Default/Variants/Red on Blue No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Red on Blue.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Red on Blue.css b/Swift/resources/themes/Default/Variants/Red on Blue.css
deleted file mode 100644
index f6e646c..0000000
--- a/Swift/resources/themes/Default/Variants/Red on Blue.css
+++ /dev/null
@@ -1,90 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#f88f8f;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/redIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/redCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/redCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/redCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/redBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/redBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/redCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/redCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#ffdada;
- border-bottom:1px solid #fff;
-}
-
-
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#7fc5f8;
-}
-
-.incomingItem .myBubble .indicator {
- background:url("../images/blueIndicator.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/blueCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/blueCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/blueCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/blueBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/blueBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/blueCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/blueCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#ddf0fe;
- border-bottom:1px solid #fff;
-}
diff --git a/Swift/resources/themes/Default/Variants/Red on Green Alternating.css b/Swift/resources/themes/Default/Variants/Red on Green Alternating.css
deleted file mode 100644
index db8effa..0000000
--- a/Swift/resources/themes/Default/Variants/Red on Green Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Red on Green.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/redIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Red on Green No Names Alt.css b/Swift/resources/themes/Default/Variants/Red on Green No Names Alt.css
deleted file mode 100644
index 9a230f2..0000000
--- a/Swift/resources/themes/Default/Variants/Red on Green No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Red on Green Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Red on Green No Names.css b/Swift/resources/themes/Default/Variants/Red on Green No Names.css
deleted file mode 100644
index 1bbc2a5..0000000
--- a/Swift/resources/themes/Default/Variants/Red on Green No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Red on Green.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Red on Green.css b/Swift/resources/themes/Default/Variants/Red on Green.css
deleted file mode 100644
index 0e7c12b..0000000
--- a/Swift/resources/themes/Default/Variants/Red on Green.css
+++ /dev/null
@@ -1,95 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#f88f8f;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/redIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/redCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/redCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/redCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/redBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/redBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/redCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/redCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#ffdada;
- border-bottom:1px solid #fff;
-}
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#9ecf35;
-}
-
-
-.incomingItem .myBubble .indicator {
- background:url("../images/greenIndicator.png") no-repeat top left;
-}
-
-.incomingItem .timeStamp {
- color:#9ecf35;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/greenCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/greenCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/greenCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/greenBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/greenBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/greenCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/greenCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#e2efc4;
- border-bottom:1px solid #fff;
-}
-
-
diff --git a/Swift/resources/themes/Default/Variants/Red on Steel Alternating.css b/Swift/resources/themes/Default/Variants/Red on Steel Alternating.css
deleted file mode 100644
index ad7eb15..0000000
--- a/Swift/resources/themes/Default/Variants/Red on Steel Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Red on Steel.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/redIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Red on Steel No Names Alt.css b/Swift/resources/themes/Default/Variants/Red on Steel No Names Alt.css
deleted file mode 100644
index 9c6ab55..0000000
--- a/Swift/resources/themes/Default/Variants/Red on Steel No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Red on Steel Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Red on Steel No Names.css b/Swift/resources/themes/Default/Variants/Red on Steel No Names.css
deleted file mode 100644
index aa2b60a..0000000
--- a/Swift/resources/themes/Default/Variants/Red on Steel No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Red on Steel.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Red on Steel.css b/Swift/resources/themes/Default/Variants/Red on Steel.css
deleted file mode 100644
index 8a39df2..0000000
--- a/Swift/resources/themes/Default/Variants/Red on Steel.css
+++ /dev/null
@@ -1,93 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#f88f8f;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/redIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/redCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/redCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/redCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/redBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/redBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/redCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/redCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#ffdada;
- border-bottom:1px solid #fff;
-}
-
-
-
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#a9a9a9;
-}
-
-.incomingItem .myBubble .indicator {
- background:url("../images/steelIndicator.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/steelCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/steelCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/steelCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/steelBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/steelBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/steelCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/steelCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#ececec;
- border-bottom:1px solid #fff;
-}
-
-
diff --git a/Swift/resources/themes/Default/Variants/Red on Yellow Alternating.css b/Swift/resources/themes/Default/Variants/Red on Yellow Alternating.css
deleted file mode 100644
index b264d7d..0000000
--- a/Swift/resources/themes/Default/Variants/Red on Yellow Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Red on Yellow.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/redIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Red on Yellow No Names Alt.css b/Swift/resources/themes/Default/Variants/Red on Yellow No Names Alt.css
deleted file mode 100644
index dc4394e..0000000
--- a/Swift/resources/themes/Default/Variants/Red on Yellow No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Red on Yellow Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Red on Yellow No Names.css b/Swift/resources/themes/Default/Variants/Red on Yellow No Names.css
deleted file mode 100644
index 9ca44ec..0000000
--- a/Swift/resources/themes/Default/Variants/Red on Yellow No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Red on Yellow.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Red on Yellow.css b/Swift/resources/themes/Default/Variants/Red on Yellow.css
deleted file mode 100644
index f2dc5a0..0000000
--- a/Swift/resources/themes/Default/Variants/Red on Yellow.css
+++ /dev/null
@@ -1,91 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#f88f8f;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/redIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/redCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/redCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/redCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/redBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/redBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/redCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/redCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#ffdada;
- border-bottom:1px solid #fff;
-}
-
-
-
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#bdb410;
-}
-
-.incomingItem .myBubble .indicator {
- background:url("../images/yellowIndicator.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/yellowCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/yellowCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/yellowCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/yellowBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/yellowBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/yellowCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/yellowCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#f4f0a7;
- border-bottom:1px solid #fff;
-}
diff --git a/Swift/resources/themes/Default/Variants/Steel on Blue Alternating.css b/Swift/resources/themes/Default/Variants/Steel on Blue Alternating.css
deleted file mode 100644
index 8c15ec2..0000000
--- a/Swift/resources/themes/Default/Variants/Steel on Blue Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Steel on Blue.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/steelIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Steel on Blue No Names Alt.css b/Swift/resources/themes/Default/Variants/Steel on Blue No Names Alt.css
deleted file mode 100644
index 7edfcb1..0000000
--- a/Swift/resources/themes/Default/Variants/Steel on Blue No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Steel on Blue Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Steel on Blue No Names.css b/Swift/resources/themes/Default/Variants/Steel on Blue No Names.css
deleted file mode 100644
index f7058b9..0000000
--- a/Swift/resources/themes/Default/Variants/Steel on Blue No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Steel on Blue.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Steel on Blue.css b/Swift/resources/themes/Default/Variants/Steel on Blue.css
deleted file mode 100644
index 6203dc2..0000000
--- a/Swift/resources/themes/Default/Variants/Steel on Blue.css
+++ /dev/null
@@ -1,92 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#a9a9a9;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/steelIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/steelCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/steelCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/steelCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/steelBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/steelBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/steelCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/steelCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#ececec;
- border-bottom:1px solid #fff;
-}
-
-
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#7fc5f8;
-}
-
-.incomingItem .myBubble .indicator {
- background:url("../images/blueIndicator.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/blueCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/blueCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/blueCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/blueBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/blueBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/blueCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/blueCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#ddf0fe;
- border-bottom:1px solid #fff;
-}
-
-
diff --git a/Swift/resources/themes/Default/Variants/Steel on Green Alternating.css b/Swift/resources/themes/Default/Variants/Steel on Green Alternating.css
deleted file mode 100644
index 69474f0..0000000
--- a/Swift/resources/themes/Default/Variants/Steel on Green Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Steel on Green.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/steelIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Steel on Green No Names Alt.css b/Swift/resources/themes/Default/Variants/Steel on Green No Names Alt.css
deleted file mode 100644
index 6fc5606..0000000
--- a/Swift/resources/themes/Default/Variants/Steel on Green No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Steel on Green Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Steel on Green No Names.css b/Swift/resources/themes/Default/Variants/Steel on Green No Names.css
deleted file mode 100644
index f07264b..0000000
--- a/Swift/resources/themes/Default/Variants/Steel on Green No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Steel on Green.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Steel on Green.css b/Swift/resources/themes/Default/Variants/Steel on Green.css
deleted file mode 100644
index 800dc6b..0000000
--- a/Swift/resources/themes/Default/Variants/Steel on Green.css
+++ /dev/null
@@ -1,97 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#a9a9a9;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/steelIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/steelCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/steelCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/steelCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/steelBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/steelBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/steelCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/steelCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#ececec;
- border-bottom:1px solid #fff;
-}
-
-
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#9ecf35;
-}
-
-
-.incomingItem .myBubble .indicator {
- background:url("../images/greenIndicator.png") no-repeat top left;
-}
-
-.incomingItem .timeStamp {
- color:#9ecf35;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/greenCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/greenCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/greenCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/greenBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/greenBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/greenCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/greenCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#e2efc4;
- border-bottom:1px solid #fff;
-}
-
-
diff --git a/Swift/resources/themes/Default/Variants/Steel on Red Alternating.css b/Swift/resources/themes/Default/Variants/Steel on Red Alternating.css
deleted file mode 100644
index 64a783b..0000000
--- a/Swift/resources/themes/Default/Variants/Steel on Red Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Steel on Red.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/steelIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Steel on Red No Names Alt.css b/Swift/resources/themes/Default/Variants/Steel on Red No Names Alt.css
deleted file mode 100644
index 995f329..0000000
--- a/Swift/resources/themes/Default/Variants/Steel on Red No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Steel on Red Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Steel on Red No Names.css b/Swift/resources/themes/Default/Variants/Steel on Red No Names.css
deleted file mode 100644
index b5e622e..0000000
--- a/Swift/resources/themes/Default/Variants/Steel on Red No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Steel on Red.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Steel on Red.css b/Swift/resources/themes/Default/Variants/Steel on Red.css
deleted file mode 100644
index 922c6ef..0000000
--- a/Swift/resources/themes/Default/Variants/Steel on Red.css
+++ /dev/null
@@ -1,89 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#a9a9a9;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/steelIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/steelCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/steelCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/steelCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/steelBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/steelBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/steelCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/steelCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#ececec;
- border-bottom:1px solid #fff;
-}
-
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#f88f8f;
-}
-
-.incomingItem .myBubble .indicator {
- background:url("../images/redIndicator.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/redCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/redCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/redCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/redBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/redBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/redCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/redCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#ffdada;
- border-bottom:1px solid #fff;
-}
diff --git a/Swift/resources/themes/Default/Variants/Steel on Yellow Alternating.css b/Swift/resources/themes/Default/Variants/Steel on Yellow Alternating.css
deleted file mode 100644
index 0249230..0000000
--- a/Swift/resources/themes/Default/Variants/Steel on Yellow Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Steel on Yellow.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/steelIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Steel on Yellow No Names Alt.css b/Swift/resources/themes/Default/Variants/Steel on Yellow No Names Alt.css
deleted file mode 100644
index 9ab928c..0000000
--- a/Swift/resources/themes/Default/Variants/Steel on Yellow No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Steel on Yellow Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Steel on Yellow No Names.css b/Swift/resources/themes/Default/Variants/Steel on Yellow No Names.css
deleted file mode 100644
index ecf7861..0000000
--- a/Swift/resources/themes/Default/Variants/Steel on Yellow No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Steel on Yellow.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Steel on Yellow.css b/Swift/resources/themes/Default/Variants/Steel on Yellow.css
deleted file mode 100644
index 2d91510..0000000
--- a/Swift/resources/themes/Default/Variants/Steel on Yellow.css
+++ /dev/null
@@ -1,92 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#a9a9a9;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/steelIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/steelCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/steelCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/steelCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/steelBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/steelBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/steelCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/steelCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#ececec;
- border-bottom:1px solid #fff;
-}
-
-
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#bdb410;
-}
-
-.incomingItem .myBubble .indicator {
- background:url("../images/yellowIndicator.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/yellowCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/yellowCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/yellowCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/yellowBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/yellowBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/yellowCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/yellowCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#f4f0a7;
- border-bottom:1px solid #fff;
-}
-
-
diff --git a/Swift/resources/themes/Default/Variants/Yellow on Blue Alternating.css b/Swift/resources/themes/Default/Variants/Yellow on Blue Alternating.css
deleted file mode 100644
index 361856d..0000000
--- a/Swift/resources/themes/Default/Variants/Yellow on Blue Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Yellow on Blue.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/yellowIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Yellow on Blue No Names Alt.css b/Swift/resources/themes/Default/Variants/Yellow on Blue No Names Alt.css
deleted file mode 100644
index 2e31a7c..0000000
--- a/Swift/resources/themes/Default/Variants/Yellow on Blue No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Yellow on Blue Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Yellow on Blue No Names.css b/Swift/resources/themes/Default/Variants/Yellow on Blue No Names.css
deleted file mode 100644
index 808377f..0000000
--- a/Swift/resources/themes/Default/Variants/Yellow on Blue No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Yellow on Blue.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Yellow on Blue.css b/Swift/resources/themes/Default/Variants/Yellow on Blue.css
deleted file mode 100644
index 7e745e9..0000000
--- a/Swift/resources/themes/Default/Variants/Yellow on Blue.css
+++ /dev/null
@@ -1,91 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#bdb410;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/yellowIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/yellowCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/yellowCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/yellowCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/yellowBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/yellowBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/yellowCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/yellowCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#f4f0a7;
- border-bottom:1px solid #fff;
-}
-
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#7fc5f8;
-}
-
-.incomingItem .myBubble .indicator {
- background:url("../images/blueIndicator.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/blueCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/blueCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/blueCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/blueBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/blueBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/blueCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/blueCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#ddf0fe;
- border-bottom:1px solid #fff;
-}
-
-
diff --git a/Swift/resources/themes/Default/Variants/Yellow on Green Alternating.css b/Swift/resources/themes/Default/Variants/Yellow on Green Alternating.css
deleted file mode 100644
index cb88dfb..0000000
--- a/Swift/resources/themes/Default/Variants/Yellow on Green Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Yellow on Green.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/yellowIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Yellow on Green No Names Alt.css b/Swift/resources/themes/Default/Variants/Yellow on Green No Names Alt.css
deleted file mode 100644
index 24fe8ef..0000000
--- a/Swift/resources/themes/Default/Variants/Yellow on Green No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Yellow on Green Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Yellow on Green No Names.css b/Swift/resources/themes/Default/Variants/Yellow on Green No Names.css
deleted file mode 100644
index 0c7d12b..0000000
--- a/Swift/resources/themes/Default/Variants/Yellow on Green No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Yellow on Green.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Yellow on Green.css b/Swift/resources/themes/Default/Variants/Yellow on Green.css
deleted file mode 100644
index de4afc6..0000000
--- a/Swift/resources/themes/Default/Variants/Yellow on Green.css
+++ /dev/null
@@ -1,96 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#bdb410;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/yellowIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/yellowCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/yellowCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/yellowCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/yellowBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/yellowBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/yellowCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/yellowCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#f4f0a7;
- border-bottom:1px solid #fff;
-}
-
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#9ecf35;
-}
-
-
-.incomingItem .myBubble .indicator {
- background:url("../images/greenIndicator.png") no-repeat top left;
-}
-
-.incomingItem .timeStamp {
- color:#9ecf35;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/greenCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/greenCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/greenCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/greenBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/greenBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/greenCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/greenCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#e2efc4;
- border-bottom:1px solid #fff;
-}
-
-
diff --git a/Swift/resources/themes/Default/Variants/Yellow on Red Alternating.css b/Swift/resources/themes/Default/Variants/Yellow on Red Alternating.css
deleted file mode 100644
index 592b8c4..0000000
--- a/Swift/resources/themes/Default/Variants/Yellow on Red Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Yellow on Red.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/yellowIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Yellow on Red No Names Alt.css b/Swift/resources/themes/Default/Variants/Yellow on Red No Names Alt.css
deleted file mode 100644
index fe464d9..0000000
--- a/Swift/resources/themes/Default/Variants/Yellow on Red No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Yellow on Red Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Yellow on Red No Names.css b/Swift/resources/themes/Default/Variants/Yellow on Red No Names.css
deleted file mode 100644
index f35c8a2..0000000
--- a/Swift/resources/themes/Default/Variants/Yellow on Red No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Yellow on Red.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Yellow on Red.css b/Swift/resources/themes/Default/Variants/Yellow on Red.css
deleted file mode 100644
index f73f0d0..0000000
--- a/Swift/resources/themes/Default/Variants/Yellow on Red.css
+++ /dev/null
@@ -1,91 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#bdb410;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/yellowIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/yellowCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/yellowCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/yellowCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/yellowBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/yellowBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/yellowCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/yellowCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#f4f0a7;
- border-bottom:1px solid #fff;
-}
-
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#f88f8f;
-}
-
-.incomingItem .myBubble .indicator {
- background:url("../images/redIndicator.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/redCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/redCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/redCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/redBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/redBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/redCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/redCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#ffdada;
- border-bottom:1px solid #fff;
-}
-
-
diff --git a/Swift/resources/themes/Default/Variants/Yellow on Steel Alternating.css b/Swift/resources/themes/Default/Variants/Yellow on Steel Alternating.css
deleted file mode 100644
index a019487..0000000
--- a/Swift/resources/themes/Default/Variants/Yellow on Steel Alternating.css
+++ /dev/null
@@ -1,7 +0,0 @@
-@import url("Yellow on Steel.css");
-@import url("../alternating.css");
-
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/yellowIndicator2.png") no-repeat top left;
-}
diff --git a/Swift/resources/themes/Default/Variants/Yellow on Steel No Names Alt.css b/Swift/resources/themes/Default/Variants/Yellow on Steel No Names Alt.css
deleted file mode 100644
index 273bcbb..0000000
--- a/Swift/resources/themes/Default/Variants/Yellow on Steel No Names Alt.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Yellow on Steel Alternating.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Yellow on Steel No Names.css b/Swift/resources/themes/Default/Variants/Yellow on Steel No Names.css
deleted file mode 100644
index 1f8d314..0000000
--- a/Swift/resources/themes/Default/Variants/Yellow on Steel No Names.css
+++ /dev/null
@@ -1,2 +0,0 @@
-@import url("Yellow on Steel.css");
-@import url("../noname.css");
diff --git a/Swift/resources/themes/Default/Variants/Yellow on Steel.css b/Swift/resources/themes/Default/Variants/Yellow on Steel.css
deleted file mode 100644
index 680f0c8..0000000
--- a/Swift/resources/themes/Default/Variants/Yellow on Steel.css
+++ /dev/null
@@ -1,91 +0,0 @@
-@import url("../main.css");
-
-/* outgoing */
-
-
-.outgoingItem .timeStamp {
- color:#bdb410;
-}
-
-.outgoingItem .myBubble .indicator {
- background:url("../images/yellowIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("../images/yellowCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("../images/yellowCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("../images/yellowCurves.png") no-repeat -10px 0;
-}
-
-.outgoingItem .tableBubble .message {
- background:url("../images/yellowBackground.png") repeat-y top left;
-}
-
-.outgoingItem .tableBubble .messageRight {
- background:url("../images/yellowBackground.png") repeat-y top right;
-}
-
-.outgoingItem .tableBubble .bl {
- background:url("../images/yellowCurves.png") no-repeat bottom left;
-}
-
-.outgoingItem .tableBubble .br {
- background:url("../images/yellowCurves.png") no-repeat bottom right;
-}
-
-.outgoingItem .followUp {
- background-color:#f4f0a7;
- border-bottom:1px solid #fff;
-}
-
-
-/*incoming */
-
-.incomingItem .timeStamp {
- color:#a9a9a9;
-}
-
-.incomingItem .myBubble .indicator {
- background:url("../images/steelIndicator.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tl {
- background:url("../images/steelCurves.png") no-repeat top left;
-}
-
-.incomingItem .tableBubble .tr {
- background:url("../images/steelCurves.png") no-repeat top right;
-}
-
-.incomingItem .tableBubble .head {
- background:url("../images/steelCurves.png") no-repeat -10px 0;
-}
-
-.incomingItem .tableBubble .message {
- background:url("../images/steelBackground.png") repeat-y top left;
-}
-
-.incomingItem .tableBubble .messageRight {
- background:url("../images/steelBackground.png") repeat-y top right;
-}
-
-.incomingItem .tableBubble .bl {
- background:url("../images/steelCurves.png") no-repeat bottom left;
-}
-
-.incomingItem .tableBubble .br {
- background:url("../images/steelCurves.png") no-repeat bottom right;
-}
-
-.incomingItem .followUp {
- background-color:#ececec;
- border-bottom:1px solid #fff;
-}
-
-
diff --git a/Swift/resources/themes/Default/alternating.css b/Swift/resources/themes/Default/alternating.css
deleted file mode 100644
index 2b21147..0000000
--- a/Swift/resources/themes/Default/alternating.css
+++ /dev/null
@@ -1,16 +0,0 @@
-
-.outgoingItem .avatar {
- float:right;
-}
-
-.outgoingItem .indicator {
- float:right;
- position:relative;
- left:11px;
- top:8px;
-}
-
-.myBubble {
- margin-right:40px;
-}
-
diff --git a/Swift/resources/themes/Default/images/DummyContact.png b/Swift/resources/themes/Default/images/DummyContact.png
deleted file mode 100755
index 5149ea5..0000000
--- a/Swift/resources/themes/Default/images/DummyContact.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/alert.png b/Swift/resources/themes/Default/images/alert.png
deleted file mode 100755
index ad59ebc..0000000
--- a/Swift/resources/themes/Default/images/alert.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/blueBackground.gif b/Swift/resources/themes/Default/images/blueBackground.gif
deleted file mode 100755
index 1aad572..0000000
--- a/Swift/resources/themes/Default/images/blueBackground.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/blueBackground.png b/Swift/resources/themes/Default/images/blueBackground.png
deleted file mode 100644
index c3eecf5..0000000
--- a/Swift/resources/themes/Default/images/blueBackground.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/blueCurves.gif b/Swift/resources/themes/Default/images/blueCurves.gif
deleted file mode 100755
index 90e3823..0000000
--- a/Swift/resources/themes/Default/images/blueCurves.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/blueCurves.png b/Swift/resources/themes/Default/images/blueCurves.png
deleted file mode 100644
index 7a6afe1..0000000
--- a/Swift/resources/themes/Default/images/blueCurves.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/blueIndicator.gif b/Swift/resources/themes/Default/images/blueIndicator.gif
deleted file mode 100755
index 3a1b40a..0000000
--- a/Swift/resources/themes/Default/images/blueIndicator.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/blueIndicator.png b/Swift/resources/themes/Default/images/blueIndicator.png
deleted file mode 100644
index 29b65cb..0000000
--- a/Swift/resources/themes/Default/images/blueIndicator.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/blueIndicator2.png b/Swift/resources/themes/Default/images/blueIndicator2.png
deleted file mode 100644
index d7c3621..0000000
--- a/Swift/resources/themes/Default/images/blueIndicator2.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/blueIndicatorAlt.gif b/Swift/resources/themes/Default/images/blueIndicatorAlt.gif
deleted file mode 100644
index aaacb89..0000000
--- a/Swift/resources/themes/Default/images/blueIndicatorAlt.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/greenBackground.gif b/Swift/resources/themes/Default/images/greenBackground.gif
deleted file mode 100755
index a11a52d..0000000
--- a/Swift/resources/themes/Default/images/greenBackground.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/greenBackground.png b/Swift/resources/themes/Default/images/greenBackground.png
deleted file mode 100644
index dfeb36e..0000000
--- a/Swift/resources/themes/Default/images/greenBackground.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/greenCurves.gif b/Swift/resources/themes/Default/images/greenCurves.gif
deleted file mode 100755
index 165892a..0000000
--- a/Swift/resources/themes/Default/images/greenCurves.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/greenCurves.png b/Swift/resources/themes/Default/images/greenCurves.png
deleted file mode 100644
index 13fae75..0000000
--- a/Swift/resources/themes/Default/images/greenCurves.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/greenIndicator.gif b/Swift/resources/themes/Default/images/greenIndicator.gif
deleted file mode 100755
index b6409c7..0000000
--- a/Swift/resources/themes/Default/images/greenIndicator.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/greenIndicator.png b/Swift/resources/themes/Default/images/greenIndicator.png
deleted file mode 100644
index 381db82..0000000
--- a/Swift/resources/themes/Default/images/greenIndicator.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/greenIndicator2.png b/Swift/resources/themes/Default/images/greenIndicator2.png
deleted file mode 100644
index 1dedb31..0000000
--- a/Swift/resources/themes/Default/images/greenIndicator2.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/greenIndicatorAlt.gif b/Swift/resources/themes/Default/images/greenIndicatorAlt.gif
deleted file mode 100644
index 3ccbc23..0000000
--- a/Swift/resources/themes/Default/images/greenIndicatorAlt.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/redBackground.gif b/Swift/resources/themes/Default/images/redBackground.gif
deleted file mode 100755
index ce1443e..0000000
--- a/Swift/resources/themes/Default/images/redBackground.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/redBackground.png b/Swift/resources/themes/Default/images/redBackground.png
deleted file mode 100644
index bbacbc7..0000000
--- a/Swift/resources/themes/Default/images/redBackground.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/redCurves.gif b/Swift/resources/themes/Default/images/redCurves.gif
deleted file mode 100755
index 55e496d..0000000
--- a/Swift/resources/themes/Default/images/redCurves.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/redCurves.png b/Swift/resources/themes/Default/images/redCurves.png
deleted file mode 100644
index 3e7065a..0000000
--- a/Swift/resources/themes/Default/images/redCurves.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/redIndicator.gif b/Swift/resources/themes/Default/images/redIndicator.gif
deleted file mode 100755
index 58e189c..0000000
--- a/Swift/resources/themes/Default/images/redIndicator.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/redIndicator.png b/Swift/resources/themes/Default/images/redIndicator.png
deleted file mode 100644
index 9c906a9..0000000
--- a/Swift/resources/themes/Default/images/redIndicator.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/redIndicator2.png b/Swift/resources/themes/Default/images/redIndicator2.png
deleted file mode 100644
index 1f625a0..0000000
--- a/Swift/resources/themes/Default/images/redIndicator2.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/redIndicatorAlt.gif b/Swift/resources/themes/Default/images/redIndicatorAlt.gif
deleted file mode 100644
index 1f9c4f1..0000000
--- a/Swift/resources/themes/Default/images/redIndicatorAlt.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/silverBackground.gif b/Swift/resources/themes/Default/images/silverBackground.gif
deleted file mode 100755
index b2798a4..0000000
--- a/Swift/resources/themes/Default/images/silverBackground.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/silverCurves.gif b/Swift/resources/themes/Default/images/silverCurves.gif
deleted file mode 100755
index b7bca30..0000000
--- a/Swift/resources/themes/Default/images/silverCurves.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/steelBackground.gif b/Swift/resources/themes/Default/images/steelBackground.gif
deleted file mode 100755
index c292710..0000000
--- a/Swift/resources/themes/Default/images/steelBackground.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/steelBackground.png b/Swift/resources/themes/Default/images/steelBackground.png
deleted file mode 100644
index b1180d3..0000000
--- a/Swift/resources/themes/Default/images/steelBackground.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/steelCurves.gif b/Swift/resources/themes/Default/images/steelCurves.gif
deleted file mode 100755
index 663c5c3..0000000
--- a/Swift/resources/themes/Default/images/steelCurves.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/steelCurves.png b/Swift/resources/themes/Default/images/steelCurves.png
deleted file mode 100644
index e1ddeb0..0000000
--- a/Swift/resources/themes/Default/images/steelCurves.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/steelHeading.jpg b/Swift/resources/themes/Default/images/steelHeading.jpg
deleted file mode 100755
index a319c7e..0000000
--- a/Swift/resources/themes/Default/images/steelHeading.jpg
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/steelIndicator.gif b/Swift/resources/themes/Default/images/steelIndicator.gif
deleted file mode 100755
index 0d91eed..0000000
--- a/Swift/resources/themes/Default/images/steelIndicator.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/steelIndicator.png b/Swift/resources/themes/Default/images/steelIndicator.png
deleted file mode 100644
index 48a3af5..0000000
--- a/Swift/resources/themes/Default/images/steelIndicator.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/steelIndicator2.png b/Swift/resources/themes/Default/images/steelIndicator2.png
deleted file mode 100644
index 1a34ac7..0000000
--- a/Swift/resources/themes/Default/images/steelIndicator2.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/steelIndicatorAlt.gif b/Swift/resources/themes/Default/images/steelIndicatorAlt.gif
deleted file mode 100644
index 5d7686d..0000000
--- a/Swift/resources/themes/Default/images/steelIndicatorAlt.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/typing-left.png b/Swift/resources/themes/Default/images/typing-left.png
deleted file mode 100755
index e5448a5..0000000
--- a/Swift/resources/themes/Default/images/typing-left.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/typing-right.png b/Swift/resources/themes/Default/images/typing-right.png
deleted file mode 100755
index 1e997d4..0000000
--- a/Swift/resources/themes/Default/images/typing-right.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/yellowBackground.gif b/Swift/resources/themes/Default/images/yellowBackground.gif
deleted file mode 100755
index adcdb5d..0000000
--- a/Swift/resources/themes/Default/images/yellowBackground.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/yellowBackground.png b/Swift/resources/themes/Default/images/yellowBackground.png
deleted file mode 100644
index ea79d06..0000000
--- a/Swift/resources/themes/Default/images/yellowBackground.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/yellowCurves.gif b/Swift/resources/themes/Default/images/yellowCurves.gif
deleted file mode 100755
index c8bf931..0000000
--- a/Swift/resources/themes/Default/images/yellowCurves.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/yellowCurves.png b/Swift/resources/themes/Default/images/yellowCurves.png
deleted file mode 100644
index b4133ba..0000000
--- a/Swift/resources/themes/Default/images/yellowCurves.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/yellowHeading.jpg b/Swift/resources/themes/Default/images/yellowHeading.jpg
deleted file mode 100755
index bd6f049..0000000
--- a/Swift/resources/themes/Default/images/yellowHeading.jpg
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/yellowIndicator.gif b/Swift/resources/themes/Default/images/yellowIndicator.gif
deleted file mode 100755
index 537414c..0000000
--- a/Swift/resources/themes/Default/images/yellowIndicator.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/yellowIndicator.png b/Swift/resources/themes/Default/images/yellowIndicator.png
deleted file mode 100644
index bfaf230..0000000
--- a/Swift/resources/themes/Default/images/yellowIndicator.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/yellowIndicator2.png b/Swift/resources/themes/Default/images/yellowIndicator2.png
deleted file mode 100644
index c59fe2b..0000000
--- a/Swift/resources/themes/Default/images/yellowIndicator2.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/yellowIndicatorAlt.gif b/Swift/resources/themes/Default/images/yellowIndicatorAlt.gif
deleted file mode 100644
index f3cd7b0..0000000
--- a/Swift/resources/themes/Default/images/yellowIndicatorAlt.gif
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/yellowTL.png b/Swift/resources/themes/Default/images/yellowTL.png
deleted file mode 100644
index 2bdfa65..0000000
--- a/Swift/resources/themes/Default/images/yellowTL.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/images/yellowTR.png b/Swift/resources/themes/Default/images/yellowTR.png
deleted file mode 100644
index 1aff191..0000000
--- a/Swift/resources/themes/Default/images/yellowTR.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/incoming_icon.png b/Swift/resources/themes/Default/incoming_icon.png
deleted file mode 100755
index 7080fd6..0000000
--- a/Swift/resources/themes/Default/incoming_icon.png
+++ /dev/null
Binary files differ
diff --git a/Swift/resources/themes/Default/lato.css b/Swift/resources/themes/Default/lato.css
new file mode 100644
index 0000000..c8bc47a
--- /dev/null
+++ b/Swift/resources/themes/Default/lato.css
@@ -0,0 +1,143 @@
+@font-face {
+ font-family: 'Lato';
+ src: url('qrc:///themes/Default/Lato2OFL/Lato-Hairline.ttf') format('truetype');
+ font-style: normal;
+ font-weight: 100;
+ text-rendering: optimizeLegibility;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('qrc:///themes/Default/Lato2OFL/Lato-HairlineItalic.ttf') format('truetype');
+ font-style: italic;
+ font-weight: 100;
+ text-rendering: optimizeLegibility;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('qrc:///themes/Default/Lato2OFL/Lato-Thin.ttf') format('truetype');
+ font-style: normal;
+ font-weight: 200;
+ text-rendering: optimizeLegibility;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('qrc:///themes/Default/Lato2OFL/Lato-ThinItalic.ttf') format('truetype');
+ font-style: italic;
+ font-weight: 200;
+ text-rendering: optimizeLegibility;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('qrc:///themes/Default/Lato2OFL/Lato-Light.ttf') format('truetype');
+ font-style: normal;
+ font-weight: 300;
+ text-rendering: optimizeLegibility;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('qrc:///themes/Default/Lato2OFL/Lato-LightItalic.ttf') format('truetype');
+ font-style: italic;
+ font-weight: 300;
+ text-rendering: optimizeLegibility;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('qrc:///themes/Default/Lato2OFL/Lato-Regular.ttf') format('truetype');
+ font-style: normal;
+ font-weight: 400;
+ text-rendering: optimizeLegibility;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('qrc:///themes/Default/Lato2OFL/Lato-Italic.ttf') format('truetype');
+ font-style: italic;
+ font-weight: 400;
+ text-rendering: optimizeLegibility;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('qrc:///themes/Default/Lato2OFL/Lato-Medium.ttf') format('truetype');
+ font-style: normal;
+ font-weight: 500;
+ text-rendering: optimizeLegibility;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('qrc:///themes/Default/Lato2OFL/Lato-MediumItalic.ttf') format('truetype');
+ font-style: italic;
+ font-weight: 500;
+ text-rendering: optimizeLegibility;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('qrc:///themes/Default/Lato2OFL/Lato-Semibold.ttf') format('truetype');
+ font-style: normal;
+ font-weight: 600;
+ text-rendering: optimizeLegibility;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('qrc:///themes/Default/Lato2OFL/Lato-SemiboldItalic.ttf') format('truetype');
+ font-style: italic;
+ font-weight: 600;
+ text-rendering: optimizeLegibility;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('qrc:///themes/Default/Lato2OFL/Lato-Bold.ttf') format('truetype');
+ font-style: normal;
+ font-weight: 700;
+ text-rendering: optimizeLegibility;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('qrc:///themes/Default/Lato2OFL/Lato-BoldItalic.ttf') format('truetype');
+ font-style: italic;
+ font-weight: 700;
+ text-rendering: optimizeLegibility;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('qrc:///themes/Default/Lato2OFL/Lato-Heavy.ttf') format('truetype');
+ font-style: normal;
+ font-weight: 800;
+ text-rendering: optimizeLegibility;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('qrc:///themes/Default/Lato2OFL/Lato-HeavyItalic.ttf') format('truetype');
+ font-style: italic;
+ font-weight: 800;
+ text-rendering: optimizeLegibility;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('qrc:///themes/Default/Lato2OFL/Lato-Black.ttf') format('truetype');
+ font-style: normal;
+ font-weight: 900;
+ text-rendering: optimizeLegibility;
+}
+
+@font-face {
+ font-family: 'Lato';
+ src: url('qrc:///themes/Default/Lato2OFL/Lato-BlackItalic.ttf') format('truetype');
+ font-style: italic;
+ font-weight: 900;
+ text-rendering: optimizeLegibility;
+}
diff --git a/Swift/resources/themes/Default/main.css b/Swift/resources/themes/Default/main.css
index afca281..bd69596 100755..100644
--- a/Swift/resources/themes/Default/main.css
+++ b/Swift/resources/themes/Default/main.css
@@ -1,293 +1,232 @@
-* {
- word-wrap: break-word;
- word-break:break-word;
-}
-
-#header1 {
- position: fixed;
- top: 0px;
- left: 0px;
- right: 0px;
- margin: 0;
- padding: 10px;
- overflow: auto;
- color: white;
- text-align: center;
- font-size: 10px;
- font-weight: regular;
- background: rgba(0,0,0,.65);
- z-index: 999;
-}
-
-#heading {
- position: fixed;
- top: 0px;
- left: 0px;
- margin: 0;
- padding: 5px;
- font-weight: regular;
- background-color:#fbfbed;
- z-index: 999;
- width:100%;
- height:45px;
- border-bottom:2px solid #d5d5d5;
- background:url("images/steelHeading.jpg") repeat-x top left;
-
-}
-
-#heading .conversationIncomingIcon {
- position:absolute;
- left:5px;
- top:5px;
-}
-
-#heading .conversationIncomingIcon img {
- width:48px;
- height:48px;
-}
-
-#heading .conversationWith {
- position:relative;
- left:60px;
- margin:5px 0 0 0;
- overflow:hide;
-}
-
-#heading .conversationTime {
- position:relative;
- left:60px;
- color:#6d6d6d;
-}
-
-body {
- margin-top: 65px;
- background-color: white;
- color: black;
-}
-
-.status_container {
-}
-
+/* Chat Window Container */
body {
- font-family: "DejaVu Sans", "Myriad Pro", Myriad, "Lucida Grande", "Trebuchet MS", Arial, "Droid Sans", sans-serif;
+ font-family: 'Lato', sans-serif;
+ margin: 0;
+ padding: 0;
}
-.followUp {
- clear:right;
- height:1px;
- font-size:1px;
- line-height:1px;
- margin:4px 0 4px 0;
+/* This turns the insert marker element into a vertical fill.
+ * This way the colored side bar is expanded to the full height of the view. */
+#insert {
+ display: table-row;
+ height: 100%;
}
-.chatItem {
- /*Removing opacity, because this causes Qt's WebKit to draw low-quality images */
- /*opacity:0.96;*/
+.container {
+ height: 100%;
+ width: 100%;
+ background-color: #fff;
+ position: absolute;
+ display: table;
}
+/* Holds all user and message content */
-.tableBubble {
- width:100%;
+.message-block {
+ display: table;
+ border: 0px solid black;
+ border-spacing: 0;
+ height: 100%;
+ width: 100%;
+ z-index: 10;
+ top: 0;
+ left: 0;
+ overflow-wrap: break-word; /* Allow breaking of long words (e.g. URLs) to prevent overflow. */
}
-.tableBubble .tl {
- height:8px;
-}
-
-.tableBubble .tr {
- width:8px;
- height:8px;
-}
+/* Individual message */
.message {
- padding:0 1em 0 1.25em;
- word-wrap: break-word;
-}
-
-.tableBubble .message {
- font-size:11px;
-}
-
-.tableBubble .message img {
- vertical-align:middle;
-}
-
-.tableBubble .messageRight {
- width:1px;
-}
-
-.tableBubble .bl {
- height:10px;
+ display: table-row;
+ border: inherit;
+ width: 100%;
+ margin-top: 10px;
+ border-top: 0.2em solid transparent;
+}
+
+.additional {
+ margin-top: -12px;
+}
+
+.unread {
+ height: 30px;
+ display: table-row;
+ border: inherit;
+ /*width: 100%;*/
+ margin-top: -6px;
+ margin-bottom: -15px;
+ margin-left: 190px;
+ margin-right: 20px;
+ text-align: right;
}
-.tableBubble .br {
- width:8px;
- height:10px;
+.unread p {
+ margin-top: 0px;
+ font-size: 75%;
+ text-transform: uppercase;
+ color: #ffd180;
+ border-top: solid 1px #ffd180;
+ margin-left: 20px;
+ margin-right: 20px;
}
-.tableBubble .timeStamp {
- margin-left:7px;
- text-align:right;
- float:right;
-}
-
-.myBubble .indicator {
- position:absolute;
- top:8px;
- left:0;
- width:13px;
- height:11px;
-}
-
-.myBubble {
- position:relative;
- padding-left:10px;
- margin-left:33px;
- margin-right:10px;
-}
-
-.chatItem .avatar {
- max-width:32px;
- max-height:32px;
- float:left;
-}
-
-/****** STatus ******/
-
-.statusMessage {
- opacity:0.8;
- color:#676767;
-}
-
-.statusMessage .myBubble .indicator {
- background:url("images/steelIndicator.png") no-repeat top left;
-}
-
-.statusMessage .tableBubble .tl {
- background:url("images/steelCurves.png") no-repeat top left;
-}
-
-.statusMessage .tableBubble .tr {
- background:url("images/steelCurves.png") no-repeat top right;
-}
-
-.statusMessage .tableBubble .head {
- background:url("images/steelCurves.png") no-repeat -10px 0;
-}
+/* Left column content */
-.statusMessage .tableBubble .message {
- background:url("images/steelBackground.png") repeat-y top left;
+:not(.additional) > .user {
+ height: 2.5em;
}
-.statusMessage .tableBubble .messageRight {
- background:url("images/steelBackground.png") repeat-y top right;
+.user {
+ display: table-cell;
+ border: inherit;
+ margin-top: 2px;
+ text-align: right;
+ width: 4.6em;
+ max-width: 4.6em;
+ min-width: 4.6em;
+ background-color: #595959;
}
-.statusMessage .tableBubble .bl {
- background:url("images/steelCurves.png") no-repeat bottom left;
-}
+div.time {
+ color: #ffffff;
+ font-size: 80%;
+ font-weight: 300;
-.statusMessage .tableBubble .br {
- background:url("images/steelCurves.png") no-repeat bottom right;
+ float: right;
+ background-color: #595959;
+ border-top-left-radius: 3ex 3ex;
+ border-bottom-left-radius: 3ex 3ex;
+ /* min-width: 50px; */
+ text-align: right;
+ padding-left: 0.5em;
+ padding-right: 0.5em;
+ padding-top: 0.05ex;
+ padding-bottom: 0.05ex;
+ margin-left: 0.5em;
}
-.statusMessage .followUp {
- background-color:#f4f0a7;
- border-bottom:1px solid #fff;
+.myavatar {
+ height: 2.5em;
+ width: 2.5em;
+ display: inline-block;
+ margin: 0 auto;
+ background-color: #92c47e;
+ border-top-left-radius: 50%;
+ border-bottom-left-radius: 50%;
}
-.statusMessage .timeStamp {
- color:#676767;
+.otheravatar {
+ height: 2.5em;
+ width: 2.5em;
+ display: inline-block;
+ margin: 0 auto;
+ background-color: #6eb6ce;
+ border-top-left-radius: 50%;
+ border-bottom-left-radius: 50%;
}
-
-/*incoming */
-
-.incomingItem .myBubble .indicator {
- background:url("images/yellowIndicator.png") no-repeat top left;
+.myavatar img {
+ border-radius: 50%;
+ height: 2.5em;
+ position: relative;
+ left: -1px;
}
-.incomingItem .tableBubble .tl {
- background:url("images/yellowCurves.png") no-repeat top left;
+.otheravatar img {
+ border-radius: 50%;
+ height: 2.5em;
+ position: relative;
+ left: -1px;
}
-.incomingItem .tableBubble .tr {
- background:url("images/yellowCurves.png") no-repeat top right;
+.myright {
+ float: right;
+ width: 1.05em; /* myuser width/2 - ( other avatar width/2) = 1.05em*/
+ height: 2.5em;
+ background: #92c47e;
}
-.incomingItem .tableBubble .head {
- background:url("images/yellowCurves.png") no-repeat -10px 0;
+.otherright {
+ float: right;
+ width: 1.05em; /* myuser width/2 - ( other avatar width/2) = 1.05em*/
+ height: 2.5em;
+ background: #6eb6ce;
}
-.incomingItem .tableBubble .message {
- background:url("images/yellowBackground.png") repeat-y top left;
+:not(.additional) > div > .systemavatar {
+ height: 2.5em;
}
-.incomingItem .tableBubble .messageRight {
- background:url("images/yellowBackground.png") repeat-y top right;
+.systemavatar {
+ width: 2.5em;
+ display: inline-block;
+ margin: 0 auto;
+ background-color: #595959;
+ border-top-left-radius: 50%;
+ border-bottom-left-radius: 50%;
}
-.incomingItem .tableBubble .bl {
- background:url("images/yellowCurves.png") no-repeat bottom left;
+:not(.additional) > div > .systemright {
+ height: 2.5em;
}
-.incomingItem .tableBubble .br {
- background:url("images/yellowCurves.png") no-repeat bottom right;
+.systemright {
+ float: right;
+ width: 1.05em; /* myuser width/2 - ( other avatar width/2) = 1.05em*/
+ background: #595959;
}
-.incomingItem .followUp {
- background-color:#f4f0a7;
- border-bottom:1px solid #fff;
+/* Right column content */
+.message:not(.additional) {
+ border-top: 1.2em solid transparent; /* Workaround for table rows not having a padding. */
}
-.incomingItem .timeStamp {
- color:#bdb410;
+.message:not(.additional) .text {
+ min-height: 2.5em;
}
-/* outgoing */
-
-
-.outgoingItem .myBubble .indicator {
- background:url("images/greenIndicator.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tl {
- background:url("images/greenCurves.png") no-repeat top left;
-}
-
-.outgoingItem .tableBubble .tr {
- background:url("images/greenCurves.png") no-repeat top right;
-}
-
-.outgoingItem .tableBubble .head {
- background:url("images/greenCurves.png") no-repeat -10px 0;
-}
+.text {
+ display: table-cell;
+ border: inherit;
+ color: #595959;
+ vertical-align: top;
-.outgoingItem .tableBubble .message {
- background:url("images/greenBackground.png") repeat-y top left;
+ /* Break long URLs at any point. */
+ word-break: break-word;
+ word-wrap: break-word;
+ hyphens: auto;
}
-.outgoingItem .tableBubble .messageRight {
- background:url("images/greenBackground.png") repeat-y top right;
+.username {
+ margin-left: 20px;
+ font-weight: 700;
+ margin-top: 0px;
+ margin-bottom: 0.2em;
}
-.outgoingItem .tableBubble .bl {
- background:url("images/greenCurves.png") no-repeat bottom left;
+.myusername {
+ color: #92c47e;
}
-.outgoingItem .tableBubble .br {
- background:url("images/greenCurves.png") no-repeat bottom right;
+.otherusername {
+ color: #6eb6ce;
}
-.outgoingItem .followUp {
- background-color:#e2efc4;
- border-bottom:1px solid #fff;
+.message-content {
+ margin-left: 20px;
+ margin-right: 20px;
}
-.outgoingItem .timeStamp {
- color:#9ecf35;
+.system-message {
+ margin-left: 20px;
+ margin-right: 20px;
+ margin-top: 0px;
+ margin-bottom: 0px;
+ color: #aaa;
+ font-style: italic;
}
-html {
- height: 101%;
+/* receipt */
+span.swift_receipt > img {
+ height: 12px;
}
diff --git a/Swift/resources/themes/Default/noname.css b/Swift/resources/themes/Default/noname.css
deleted file mode 100644
index 9d905a9..0000000
--- a/Swift/resources/themes/Default/noname.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.name {
- display:none;
-}
diff --git a/Swift/resources/themes/Default/outgoing_icon.png b/Swift/resources/themes/Default/outgoing_icon.png
deleted file mode 100755
index 7080fd6..0000000
--- a/Swift/resources/themes/Default/outgoing_icon.png
+++ /dev/null
Binary files differ