diff options
author | Tobias Markmann <tm@ayena.de> | 2015-03-17 15:00:02 (GMT) |
---|---|---|
committer | Kevin Smith <kevin.smith@isode.com> | 2015-04-10 15:12:53 (GMT) |
commit | 6a2e6d58233cbf40b34f962f2b2f9b1589969e13 (patch) | |
tree | b0a62c32adc64fda30fc024f38acfb2a6da6351e /Swift | |
parent | b4e3ecf40ee5fda0ba46f714bd24a6d9f3a4cb5e (diff) | |
download | swift-6a2e6d58233cbf40b34f962f2b2f9b1589969e13.zip swift-6a2e6d58233cbf40b34f962f2b2f9b1589969e13.tar.bz2 |
Fix keyboard shortcuts for --no-tabs mode
This commit enables the following shortcuts for --no-tabs mode:
- CTRL + Tab or CTRL/CMD + PageDown to switch to the next chat window
- CTRL + Shift + Tab or CTRL/CMD + PageUp to switch to the previous chat window
- CTRL/CMD + W to close the current chat window
- ALT + A to switch to the next chat window with active messages
Test-Information:
Verified that the new shortcuts work as expected and verified that
standard mode and netbook mode still work as usual.
Change-Id: I3831b6c02f5d664cc8b21d7571e20aed00de89b4
Diffstat (limited to 'Swift')
-rw-r--r-- | Swift/QtUI/QtChatTabs.h | 6 | ||||
-rw-r--r-- | Swift/QtUI/QtChatTabsBase.cpp | 19 | ||||
-rw-r--r-- | Swift/QtUI/QtChatTabsBase.h | 21 | ||||
-rw-r--r-- | Swift/QtUI/QtChatTabsShortcutOnlySubstitute.cpp | 109 | ||||
-rw-r--r-- | Swift/QtUI/QtChatTabsShortcutOnlySubstitute.h | 40 | ||||
-rw-r--r-- | Swift/QtUI/QtChatWindowFactory.cpp | 15 | ||||
-rw-r--r-- | Swift/QtUI/QtChatWindowFactory.h | 8 | ||||
-rw-r--r-- | Swift/QtUI/QtSwift.cpp | 10 | ||||
-rw-r--r-- | Swift/QtUI/QtSwift.h | 6 | ||||
-rw-r--r-- | Swift/QtUI/QtUIFactory.cpp | 11 | ||||
-rw-r--r-- | Swift/QtUI/QtUIFactory.h | 4 | ||||
-rw-r--r-- | Swift/QtUI/SConscript | 2 |
12 files changed, 229 insertions, 22 deletions
diff --git a/Swift/QtUI/QtChatTabs.h b/Swift/QtUI/QtChatTabs.h index bee03ec..71d4ddc 100644 --- a/Swift/QtUI/QtChatTabs.h +++ b/Swift/QtUI/QtChatTabs.h @@ -10,6 +10,8 @@ #include <QRect> #include <QShortcut> +#include <Swift/QtUI/QtChatTabsBase.h> + class QTabWidget; class QMenu; @@ -21,13 +23,13 @@ namespace Swift { class QtDynamicGridLayout; class QtGridSelectionDialog; - class QtChatTabs : public QWidget { + class QtChatTabs : public QWidget, public QtChatTabsBase { Q_OBJECT public: QtChatTabs(bool singleWindow, SettingsProvider* settingsProvider, bool trellisMode); virtual ~QtChatTabs(); - void addTab(QtTabbable* tab); + virtual void addTab(QtTabbable* tab); void minimise(); QtTabbable* getCurrentTab(); void setViewMenu(QMenu* viewMenu); diff --git a/Swift/QtUI/QtChatTabsBase.cpp b/Swift/QtUI/QtChatTabsBase.cpp new file mode 100644 index 0000000..140ff08 --- /dev/null +++ b/Swift/QtUI/QtChatTabsBase.cpp @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2015 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <Swift/QtUI/QtChatTabsBase.h> + +namespace Swift { + +QtChatTabsBase::QtChatTabsBase() { + +} + +QtChatTabsBase::~QtChatTabsBase() { + +} + +} diff --git a/Swift/QtUI/QtChatTabsBase.h b/Swift/QtUI/QtChatTabsBase.h new file mode 100644 index 0000000..753b706 --- /dev/null +++ b/Swift/QtUI/QtChatTabsBase.h @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2015 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#pragma once + +namespace Swift { + +class QtTabbable; + +class QtChatTabsBase { + public: + QtChatTabsBase(); + virtual ~QtChatTabsBase(); + + virtual void addTab(QtTabbable* tab) = 0; +}; + +} diff --git a/Swift/QtUI/QtChatTabsShortcutOnlySubstitute.cpp b/Swift/QtUI/QtChatTabsShortcutOnlySubstitute.cpp new file mode 100644 index 0000000..7f44177 --- /dev/null +++ b/Swift/QtUI/QtChatTabsShortcutOnlySubstitute.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2015 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#include <Swift/QtUI/QtChatTabsShortcutOnlySubstitute.h> + +#include <cassert> + +#include <QApplication> +#include <QShortcut> + +#include <Swiften/Base/Log.h> +#include <Swiften/Base/foreach.h> + +#include <Swift/QtUI/QtTabbable.h> + +namespace Swift { + +QtChatTabsShortcutOnlySubstitute::QtChatTabsShortcutOnlySubstitute() : QWidget() { + +} + +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())); +} + +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(); + } +} + +void QtChatTabsShortcutOnlySubstitute::handleRequestedNextTab() { + QtTabbable* senderTab = dynamic_cast<QtTabbable*>(sender()); + + QList<QtTabbable*> tabs = tabbableWindows(); + + int currentIndex = tabs.indexOf(senderTab); + assert(currentIndex >= 0); + + QtTabbable* nextTab = tabs.at((currentIndex + 1) % tabs.size()); + nextTab->activateWindow(); +} + +void QtChatTabsShortcutOnlySubstitute::handleRequestedActiveTab() { + QtTabbable* senderTab = dynamic_cast<QtTabbable*>(sender()); + + QtTabbable::AlertType types[] = {QtTabbable::WaitingActivity, QtTabbable::ImpendingActivity}; + + QList<QtTabbable*> tabs = tabbableWindows(); + + for (int j = 0; j < 2; j++) { + 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); + } +} + +void QtChatTabsShortcutOnlySubstitute::handleRequestedPreviousTab() { + QtTabbable* senderTab = dynamic_cast<QtTabbable*>(sender()); + + QList<QtTabbable*> tabs = tabbableWindows(); + + int currentIndex = tabs.indexOf(senderTab); + assert(currentIndex >= 0); + + QtTabbable* previousTab = tabs.at((currentIndex + tabs.size() - 1) % tabs.size()); + previousTab->activateWindow(); +} + +QList<QtTabbable*> QtChatTabsShortcutOnlySubstitute::tabbableWindows() const { + QList<QWidget*> windows = qApp->topLevelWidgets(); + + QList<QtTabbable*> tabbables; + foreach(QWidget* topLevelWidget, windows) { + QtTabbable* tabbable = dynamic_cast<QtTabbable*>(topLevelWidget); + if (tabbable) { + tabbables << tabbable; + } + } + + return tabbables; +} + +} + diff --git a/Swift/QtUI/QtChatTabsShortcutOnlySubstitute.h b/Swift/QtUI/QtChatTabsShortcutOnlySubstitute.h new file mode 100644 index 0000000..069bb0b --- /dev/null +++ b/Swift/QtUI/QtChatTabsShortcutOnlySubstitute.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2015 Isode Limited. + * All rights reserved. + * See the COPYING file for more information. + */ + +#pragma once + +#include <QWidget> +#include <QList> + +#include <Swift/QtUI/QtChatTabsBase.h> + +class QShortcut; + +namespace Swift { + +class QtChatTabsShortcutOnlySubstitute : public QWidget, public QtChatTabsBase { + Q_OBJECT + + public: + QtChatTabsShortcutOnlySubstitute(); + virtual ~QtChatTabsShortcutOnlySubstitute(); + + virtual void addTab(QtTabbable* tab); + + private slots: + void handleCloseTabShortcut(); + void handleRequestedNextTab(); + void handleRequestedActiveTab(); + void handleRequestedPreviousTab(); + + private: + QList<QtTabbable*> tabbableWindows() const; + + private: + QList<QShortcut*> shortcuts_; +}; + +} diff --git a/Swift/QtUI/QtChatWindowFactory.cpp b/Swift/QtUI/QtChatWindowFactory.cpp index 1774653..b9ba89d 100644 --- a/Swift/QtUI/QtChatWindowFactory.cpp +++ b/Swift/QtUI/QtChatWindowFactory.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -10,6 +10,7 @@ #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> @@ -21,19 +22,21 @@ namespace Swift { static const QString SPLITTER_STATE = "mucSplitterState"; static const QString CHAT_TABS_GEOMETRY = "chatTabsGeometry"; -QtChatWindowFactory::QtChatWindowFactory(QtSingleWindow* splitter, SettingsProvider* settings, QtSettingsProvider* qtSettings, QtChatTabs* tabs, const QString& themePath, const std::map<std::string, std::string>& emoticons) : themePath_(themePath), emoticons_(emoticons) { +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) { - splitter->addWidget(tabs_); - } else if (tabs_) { + 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()) { - tabs_->restoreGeometry(chatTabsGeometryVariant.toByteArray()); + fullTabs->restoreGeometry(chatTabsGeometryVariant.toByteArray()); } - connect(tabs_, SIGNAL(geometryChanged()), this, SLOT(handleWindowGeometryChanged())); + connect(fullTabs, SIGNAL(geometryChanged()), this, SLOT(handleWindowGeometryChanged())); } } diff --git a/Swift/QtUI/QtChatWindowFactory.h b/Swift/QtUI/QtChatWindowFactory.h index c38202f..6b1f0a1 100644 --- a/Swift/QtUI/QtChatWindowFactory.h +++ b/Swift/QtUI/QtChatWindowFactory.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -19,7 +19,7 @@ #include <Swift/QtUI/QtSettingsProvider.h> namespace Swift { - class QtChatTabs; + class QtChatTabsBase; class QtChatTheme; class UIEventStream; class QtUIPreferences; @@ -27,7 +27,7 @@ namespace Swift { class QtChatWindowFactory : public QObject, public ChatWindowFactory { Q_OBJECT public: - QtChatWindowFactory(QtSingleWindow* splitter, SettingsProvider* settings, QtSettingsProvider* qtSettings, QtChatTabs* tabs, const QString& themePath, const std::map<std::string, std::string>& emoticons); + 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: @@ -39,7 +39,7 @@ namespace Swift { QString themePath_; SettingsProvider* settings_; QtSettingsProvider* qtOnlySettings_; - QtChatTabs* tabs_; + QtChatTabsBase* tabs_; QtChatTheme* theme_; std::map<std::string, std::string> emoticons_; }; diff --git a/Swift/QtUI/QtSwift.cpp b/Swift/QtUI/QtSwift.cpp index bce3ca4..20d7bc9 100644 --- a/Swift/QtUI/QtSwift.cpp +++ b/Swift/QtUI/QtSwift.cpp @@ -38,7 +38,9 @@ #include <Swift/Controllers/StatusCache.h> #include <Swift/QtUI/QtLoginWindow.h> +#include <Swift/QtUI/QtChatTabsBase.h> #include <Swift/QtUI/QtChatTabs.h> +#include <Swift/QtUI/QtChatTabsShortcutOnlySubstitute.h> #include <Swift/QtUI/QtSystemTray.h> #include <Swift/QtUI/QtSoundPlayer.h> #include <Swift/QtUI/QtSwiftUtil.h> @@ -165,7 +167,13 @@ QtSwift::QtSwift(const po::variables_map& options) : networkFactories_(&clientMa } bool enableAdHocCommandOnJID = options.count("enable-jid-adhocs") > 0; - tabs_ = options.count("no-tabs") && !splitter_ ? NULL : new QtChatTabs(splitter_ != NULL, settingsHierachy_, options.count("trellis")); + 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()); diff --git a/Swift/QtUI/QtSwift.h b/Swift/QtUI/QtSwift.h index cbe9c62..a971324 100644 --- a/Swift/QtUI/QtSwift.h +++ b/Swift/QtUI/QtSwift.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010-2014 Isode Limited. + * Copyright (c) 2010-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -41,7 +41,7 @@ namespace Swift { class CapsStorage; class MainController; class QtSystemTray; - class QtChatTabs; + class QtChatTabsBase; class QtChatWindowFactory; class QtSoundPlayer; class QtMUCSearchWindowFactory; @@ -77,7 +77,7 @@ namespace Swift { QtSoundPlayer* soundPlayer_; Dock* dock_; URIHandler* uriHandler_; - QtChatTabs* tabs_; + QtChatTabsBase* tabs_; ApplicationPathProvider* applicationPathProvider_; StoragesFactory* storagesFactory_; CertificateStorageFactory* certificateStorageFactory_; diff --git a/Swift/QtUI/QtUIFactory.cpp b/Swift/QtUI/QtUIFactory.cpp index c7b64b3..8dece86 100644 --- a/Swift/QtUI/QtUIFactory.cpp +++ b/Swift/QtUI/QtUIFactory.cpp @@ -10,6 +10,7 @@ #include <Swift/QtUI/QtXMLConsoleWidget.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> @@ -36,14 +37,15 @@ namespace Swift { -QtUIFactory::QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabs* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, StatusCache* statusCache, bool startMinimized, bool emoticonsExist, bool enableAdHocCommandOnJID) : settings(settings), qtOnlySettings(qtOnlySettings), tabs(tabs), netbookSplitter(netbookSplitter), systemTray(systemTray), chatWindowFactory(chatWindowFactory), timerFactory_(timerFactory), lastMainWindow(NULL), loginWindow(NULL), statusCache(statusCache), startMinimized(startMinimized), emoticonsExist_(emoticonsExist), enableAdHocCommandOnJID_(enableAdHocCommandOnJID) { +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); } XMLConsoleWidget* QtUIFactory::createXMLConsoleWidget() { QtXMLConsoleWidget* widget = new QtXMLConsoleWidget(); - tabs->addTab(widget); + tabsBase->addTab(widget); showTabs(); widget->show(); return widget; @@ -51,8 +53,7 @@ XMLConsoleWidget* QtUIFactory::createXMLConsoleWidget() { HistoryWindow* QtUIFactory::createHistoryWindow(UIEventStream* uiEventStream) { QtHistoryWindow* window = new QtHistoryWindow(settings, uiEventStream); - tabs->addTab(window); - + tabsBase->addTab(window); showTabs(); connect(window, SIGNAL(fontResized(int)), this, SLOT(handleHistoryWindowFontResized(int))); @@ -68,7 +69,7 @@ void QtUIFactory::handleHistoryWindowFontResized(int size) { FileTransferListWidget* QtUIFactory::createFileTransferListWidget() { QtFileTransferListWidget* widget = new QtFileTransferListWidget(); - tabs->addTab(widget); + tabsBase->addTab(widget); showTabs(); widget->show(); return widget; diff --git a/Swift/QtUI/QtUIFactory.h b/Swift/QtUI/QtUIFactory.h index 05b4f6a..1d935bc 100644 --- a/Swift/QtUI/QtUIFactory.h +++ b/Swift/QtUI/QtUIFactory.h @@ -16,6 +16,7 @@ class QSplitter; namespace Swift { class QtSettingsProvider; class SettingsProviderHierachy; + class QtChatTabsBase; class QtChatTabs; class QtSystemTray; class QtLoginWindow; @@ -32,7 +33,7 @@ namespace Swift { class QtUIFactory : public QObject, public UIFactory { Q_OBJECT public: - QtUIFactory(SettingsProviderHierachy* settings, QtSettingsProvider* qtOnlySettings, QtChatTabs* tabs, QtSingleWindow* netbookSplitter, QtSystemTray* systemTray, QtChatWindowFactory* chatWindowFactory, TimerFactory* timerFactory, StatusCache* statusCache, bool startMinimized, bool emoticonsExist, bool enableAdHocCommandOnJID); + 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*); @@ -63,6 +64,7 @@ namespace Swift { private: SettingsProviderHierachy* settings; QtSettingsProvider* qtOnlySettings; + QtChatTabsBase* tabsBase; QtChatTabs* tabs; QtSingleWindow* netbookSplitter; QtSystemTray* systemTray; diff --git a/Swift/QtUI/SConscript b/Swift/QtUI/SConscript index 36f7cc9..f3251d2 100644 --- a/Swift/QtUI/SConscript +++ b/Swift/QtUI/SConscript @@ -108,6 +108,8 @@ sources = [ "QtPlainChatView.cpp", "QtChatTheme.cpp", "QtChatTabs.cpp", + "QtChatTabsBase.cpp", + "QtChatTabsShortcutOnlySubstitute.cpp", "QtSoundPlayer.cpp", "QtSystemTray.cpp", "QtCachedImageScaler.cpp", |