X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=blobdiff_plain;f=src%2Fqtui%2Fmainwin.cpp;h=f40aa9c9a5af24c12d1f3dac13fa77cc4b40064c;hp=2a5b379d102567edc21e1006ae03b788b393b0a6;hb=9f33f6e471dedbefe7bbe336a40312894628afe1;hpb=b099603e2e1297ec41a354dc949729e4f77d7bbd diff --git a/src/qtui/mainwin.cpp b/src/qtui/mainwin.cpp index 2a5b379d..f40aa9c9 100644 --- a/src/qtui/mainwin.cpp +++ b/src/qtui/mainwin.cpp @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2005-09 by the Quassel Project * + * Copyright (C) 2005-2010 by the Quassel Project * * devel@quassel-irc.org * * * * This program is free software; you can redistribute it and/or modify * @@ -26,6 +26,7 @@ # include # include # include +# include # include # include #endif @@ -69,7 +70,7 @@ #include "inputwidget.h" #include "irclistmodel.h" #include "ircconnectionwizard.h" -#include "jumpkeyhandler.h" +#include "legacysystemtray.h" #include "msgprocessorstatuswidget.h" #include "nicklistwidget.h" #include "qtuiapplication.h" @@ -78,15 +79,12 @@ #include "qtuistyle.h" #include "settingsdlg.h" #include "settingspagedlg.h" -#include "systemtray.h" +#include "statusnotifieritem.h" #include "toolbaractionprovider.h" #include "topicwidget.h" #include "verticaldock.h" #ifndef HAVE_KDE -# ifdef HAVE_DBUS -# include "desktopnotificationbackend.h" -# endif # ifdef HAVE_PHONON # include "phononnotificationbackend.h" # endif @@ -122,6 +120,10 @@ #include "settingspages/notificationssettingspage.h" #include "settingspages/topicwidgetsettingspage.h" +#ifndef HAVE_KDE +# include "settingspages/shortcutssettingspage.h" +#endif + MainWin::MainWin(QWidget *parent) #ifdef HAVE_KDE : KMainWindow(parent), @@ -133,11 +135,10 @@ MainWin::MainWin(QWidget *parent) _coreConnectionStatusWidget(new CoreConnectionStatusWidget(Client::coreConnection(), this)), _titleSetter(this), _awayLog(0), - _layoutLoaded(false) + _layoutLoaded(false), + _activeBufferViewIndex(-1) { -#ifdef Q_WS_WIN - dwTickCount = 0; -#endif + setAttribute(Qt::WA_DeleteOnClose, false); // we delete the mainwin manually QtUiSettings uiSettings; QString style = uiSettings.value("Style", QString()).toString(); @@ -150,8 +151,6 @@ MainWin::MainWin(QWidget *parent) setWindowTitle("Quassel IRC"); setWindowIconText("Quassel IRC"); updateIcon(); - - installEventFilter(new JumpKeyHandler(this)); } void MainWin::init() { @@ -183,9 +182,10 @@ void MainWin::init() { setupBufferWidget(); setupMenus(); setupTopicWidget(); - setupChatMonitor(); setupNickWidget(); setupInputWidget(); + setupChatMonitor(); + setupViewMenuTail(); setupStatusBar(); setupToolBars(); setupSystray(); @@ -193,15 +193,15 @@ void MainWin::init() { setupHotList(); #ifndef HAVE_KDE - QtUi::registerNotificationBackend(new TaskbarNotificationBackend(this)); - QtUi::registerNotificationBackend(new SystrayNotificationBackend(this)); # ifdef HAVE_PHONON QtUi::registerNotificationBackend(new PhononNotificationBackend(this)); # endif -# ifdef HAVE_DBUS - QtUi::registerNotificationBackend(new DesktopNotificationBackend(this)); +# ifndef QT_NO_SYSTEMTRAYICON + QtUi::registerNotificationBackend(new SystrayNotificationBackend(this)); # endif + QtUi::registerNotificationBackend(new TaskbarNotificationBackend(this)); + #else /* HAVE_KDE */ QtUi::registerNotificationBackend(new KNotificationBackend(this)); #endif /* HAVE_KDE */ @@ -210,6 +210,9 @@ void MainWin::init() { QtUi::registerNotificationBackend(new IndicatorNotificationBackend(this)); #endif + // we assume that at this point, all configurable actions are defined! + QtUi::loadShortcuts(); + connect(bufferWidget(), SIGNAL(currentChanged(BufferId)), SLOT(currentBufferChanged(BufferId))); setDisconnectedState(); // Disable menus and stuff @@ -251,6 +254,9 @@ void MainWin::saveStateToSettings(UiSettings &s) { s.setValue("MainWinMinimized", isMinimized()); s.setValue("MainWinMaximized", isMaximized()); s.setValue("MainWinHidden", !isVisible()); + BufferId lastBufId = Client::bufferModel()->currentBuffer(); + if(lastBufId.isValid()) + s.setValue("LastUsedBufferId", lastBufId.toInt()); #ifdef HAVE_KDE saveAutoSaveSettings(); @@ -277,8 +283,8 @@ void MainWin::restoreStateFromSettings(UiSettings &s) { move(_normalPos); #endif - if(s.value("MainWinHidden").toBool()) - hideToTray(); + if(s.value("MainWinHidden").toBool() && QtUi::haveSystemTray()) + QtUi::hideMainWidget(); else if(s.value("MainWinMinimized").toBool()) showMinimized(); else if(maximized) @@ -304,7 +310,7 @@ void MainWin::updateIcon() { } void MainWin::setupActions() { - ActionCollection *coll = QtUi::actionCollection("General"); + ActionCollection *coll = QtUi::actionCollection("General", tr("General")); // File coll->addAction("ConnectCore", new Action(SmallIcon("network-connect"), tr("&Connect to Core..."), coll, this, SLOT(showCoreConnectionDlg()))); @@ -314,8 +320,9 @@ void MainWin::setupActions() { this, SLOT(showCoreInfoDlg()))); coll->addAction("ConfigureNetworks", new Action(SmallIcon("configure"), tr("Configure &Networks..."), coll, this, SLOT(on_actionConfigureNetworks_triggered()))); + // FIXME: use QKeySequence::Quit once we depend on Qt 4.6 coll->addAction("Quit", new Action(SmallIcon("application-exit"), tr("&Quit"), coll, - this, SLOT(quit()), tr("Ctrl+Q"))); + this, SLOT(quit()), Qt::CTRL + Qt::Key_Q)); // View coll->addAction("ConfigureBufferViews", new Action(tr("&Configure Chat Lists..."), coll, @@ -330,20 +337,46 @@ void MainWin::setupActions() { coll->addAction("ShowAwayLog", new Action(tr("Show Away Log"), coll, this, SLOT(showAwayLog()))); coll->addAction("ToggleMenuBar", new Action(SmallIcon("show-menu"), tr("Show &Menubar"), coll, - 0, 0, tr("Ctrl+M")))->setCheckable(true); + 0, 0, QKeySequence(Qt::CTRL + Qt::Key_M)))->setCheckable(true); coll->addAction("ToggleStatusBar", new Action(tr("Show Status &Bar"), coll, 0, 0))->setCheckable(true); +#ifdef HAVE_KDE + QAction *fullScreenAct = KStandardAction::fullScreen(this, SLOT(toggleFullscreen()), this, coll); +#else + QAction *fullScreenAct = new Action(SmallIcon("view-fullscreen"), tr("&Full Screen Mode"), coll, + this, SLOT(toggleFullscreen()), QKeySequence(Qt::Key_F11)); + fullScreenAct->setCheckable(true); +#endif + coll->addAction("ToggleFullscreen", fullScreenAct); + // Settings - coll->addAction("ConfigureQuassel", new Action(SmallIcon("configure"), tr("&Configure Quassel..."), coll, - this, SLOT(showSettingsDlg()), tr("F7"))); + QAction *configureShortcutsAct = new Action(SmallIcon("configure-shortcuts"), tr("Configure &Shortcuts..."), coll, + this, SLOT(showShortcutsDlg())); + configureShortcutsAct->setMenuRole(QAction::NoRole); + coll->addAction("ConfigureShortcuts", configureShortcutsAct); + + #ifdef Q_WS_MAC + QAction *configureQuasselAct = new Action(SmallIcon("configure"), tr("&Configure Quassel..."), coll, + this, SLOT(showSettingsDlg())); + configureQuasselAct->setMenuRole(QAction::PreferencesRole); + #else + QAction *configureQuasselAct = new Action(SmallIcon("configure"), tr("&Configure Quassel..."), coll, + this, SLOT(showSettingsDlg()), QKeySequence(Qt::Key_F7)); + #endif + coll->addAction("ConfigureQuassel", configureQuasselAct); // Help - coll->addAction("AboutQuassel", new Action(SmallIcon("quassel"), tr("&About Quassel"), coll, - this, SLOT(showAboutDlg()))); - coll->addAction("AboutQt", new Action(QIcon(":/pics/qt-logo.png"), tr("About &Qt"), coll, - qApp, SLOT(aboutQt()))); + QAction *aboutQuasselAct = new Action(SmallIcon("quassel"), tr("&About Quassel"), coll, + this, SLOT(showAboutDlg())); + aboutQuasselAct->setMenuRole(QAction::AboutRole); + coll->addAction("AboutQuassel", aboutQuasselAct); + + QAction *aboutQtAct = new Action(QIcon(":/pics/qt-logo.png"), tr("About &Qt"), coll, + qApp, SLOT(aboutQt())); + aboutQtAct->setMenuRole(QAction::AboutQtRole); + coll->addAction("AboutQt", aboutQtAct); coll->addAction("DebugNetworkModel", new Action(SmallIcon("tools-report-bug"), tr("Debug &NetworkModel"), coll, this, SLOT(on_actionDebugNetworkModel_triggered()))); coll->addAction("DebugBufferViewOverlay", new Action(SmallIcon("tools-report-bug"), tr("Debug &BufferViewOverlay"), coll, @@ -358,8 +391,73 @@ void MainWin::setupActions() { QtUi::style(), SLOT(reload()), QKeySequence::Refresh)); // Navigation + coll = QtUi::actionCollection("Navigation", tr("Navigation")); + coll->addAction("JumpHotBuffer", new Action(tr("Jump to hot chat"), coll, this, SLOT(on_jumpHotBuffer_triggered()), QKeySequence(Qt::META + Qt::Key_A))); + + // Jump keys +#ifdef Q_WS_MAC + const int bindModifier = Qt::ControlModifier | Qt::AltModifier; + const int jumpModifier = Qt::ControlModifier; +#else + const int bindModifier = Qt::ControlModifier; + const int jumpModifier = Qt::AltModifier; +#endif + + coll->addAction("BindJumpKey0", new Action(tr("Set Quick Access #0"), coll, this, SLOT(bindJumpKey()), + QKeySequence(bindModifier + Qt::Key_0)))->setProperty("Index", 0); + coll->addAction("BindJumpKey1", new Action(tr("Set Quick Access #1"), coll, this, SLOT(bindJumpKey()), + QKeySequence(bindModifier + Qt::Key_1)))->setProperty("Index", 1); + coll->addAction("BindJumpKey2", new Action(tr("Set Quick Access #2"), coll, this, SLOT(bindJumpKey()), + QKeySequence(bindModifier + Qt::Key_2)))->setProperty("Index", 2); + coll->addAction("BindJumpKey3", new Action(tr("Set Quick Access #3"), coll, this, SLOT(bindJumpKey()), + QKeySequence(bindModifier + Qt::Key_3)))->setProperty("Index", 3); + coll->addAction("BindJumpKey4", new Action(tr("Set Quick Access #4"), coll, this, SLOT(bindJumpKey()), + QKeySequence(bindModifier + Qt::Key_4)))->setProperty("Index", 4); + coll->addAction("BindJumpKey5", new Action(tr("Set Quick Access #5"), coll, this, SLOT(bindJumpKey()), + QKeySequence(bindModifier + Qt::Key_5)))->setProperty("Index", 5); + coll->addAction("BindJumpKey6", new Action(tr("Set Quick Access #6"), coll, this, SLOT(bindJumpKey()), + QKeySequence(bindModifier + Qt::Key_6)))->setProperty("Index", 6); + coll->addAction("BindJumpKey7", new Action(tr("Set Quick Access #7"), coll, this, SLOT(bindJumpKey()), + QKeySequence(bindModifier + Qt::Key_7)))->setProperty("Index", 7); + coll->addAction("BindJumpKey8", new Action(tr("Set Quick Access #8"), coll, this, SLOT(bindJumpKey()), + QKeySequence(bindModifier + Qt::Key_8)))->setProperty("Index", 8); + coll->addAction("BindJumpKey9", new Action(tr("Set Quick Access #9"), coll, this, SLOT(bindJumpKey()), + QKeySequence(bindModifier + Qt::Key_9)))->setProperty("Index", 9); + + coll->addAction("JumpKey0", new Action(tr("Quick Access #0"), coll, this, SLOT(onJumpKey()), + QKeySequence(jumpModifier + Qt::Key_0)))->setProperty("Index", 0); + coll->addAction("JumpKey1", new Action(tr("Quick Access #1"), coll, this, SLOT(onJumpKey()), + QKeySequence(jumpModifier + Qt::Key_1)))->setProperty("Index", 1); + coll->addAction("JumpKey2", new Action(tr("Quick Access #2"), coll, this, SLOT(onJumpKey()), + QKeySequence(jumpModifier + Qt::Key_2)))->setProperty("Index", 2); + coll->addAction("JumpKey3", new Action(tr("Quick Access #3"), coll, this, SLOT(onJumpKey()), + QKeySequence(jumpModifier + Qt::Key_3)))->setProperty("Index", 3); + coll->addAction("JumpKey4", new Action(tr("Quick Access #4"), coll, this, SLOT(onJumpKey()), + QKeySequence(jumpModifier + Qt::Key_4)))->setProperty("Index", 4); + coll->addAction("JumpKey5", new Action(tr("Quick Access #5"), coll, this, SLOT(onJumpKey()), + QKeySequence(jumpModifier + Qt::Key_5)))->setProperty("Index", 5); + coll->addAction("JumpKey6", new Action(tr("Quick Access #6"), coll, this, SLOT(onJumpKey()), + QKeySequence(jumpModifier + Qt::Key_6)))->setProperty("Index", 6); + coll->addAction("JumpKey7", new Action(tr("Quick Access #7"), coll, this, SLOT(onJumpKey()), + QKeySequence(jumpModifier + Qt::Key_7)))->setProperty("Index", 7); + coll->addAction("JumpKey8", new Action(tr("Quick Access #8"), coll, this, SLOT(onJumpKey()), + QKeySequence(jumpModifier + Qt::Key_8)))->setProperty("Index", 8); + coll->addAction("JumpKey9", new Action(tr("Quick Access #9"), coll, this, SLOT(onJumpKey()), + QKeySequence(jumpModifier + Qt::Key_9)))->setProperty("Index", 9); + + // Buffer navigation + coll->addAction("NextBufferView", new Action(SmallIcon("go-next-view"), tr("Activate Next Chat List"), coll, + this, SLOT(nextBufferView()), QKeySequence(QKeySequence::Forward))); + coll->addAction("PreviousBufferView", new Action(SmallIcon("go-previous-view"), tr("Activate Previous Chat List"), coll, + this, SLOT(previousBufferView()), QKeySequence::Back)); + coll->addAction("NextBuffer", new Action(SmallIcon("go-down"), tr("Go to Next Chat"), coll, + this, SLOT(nextBuffer()), QKeySequence(Qt::ALT + Qt::Key_Down))); + coll->addAction("PreviousBuffer", new Action(SmallIcon("go-up"), tr("Go to Previous Chat"), coll, + this, SLOT(previousBuffer()), QKeySequence(Qt::ALT + Qt::Key_Up))); + coll->addAction("HideCurrentBuffer", new Action(tr("Hide Current Buffer"), coll, + this, SLOT(hideCurrentBuffer()), QKeySequence(Qt::ControlModifier + Qt::Key_W))); } void MainWin::setupMenus() { @@ -405,6 +503,8 @@ void MainWin::setupMenus() { #ifdef HAVE_KDE _settingsMenu->addAction(KStandardAction::configureNotifications(this, SLOT(showNotificationsDlg()), this)); _settingsMenu->addAction(KStandardAction::keyBindings(this, SLOT(showShortcutsDlg()), this)); +#else + _settingsMenu->addAction(coll->action("ConfigureShortcuts")); #endif _settingsMenu->addAction(coll->action("ConfigureQuassel")); @@ -469,7 +569,11 @@ void MainWin::addBufferView(ClientBufferViewConfig *config) { _bufferViewsMenu->addAction(dock->toggleViewAction()); connect(dock->toggleViewAction(), SIGNAL(toggled(bool)), this, SLOT(bufferViewToggled(bool))); + connect(dock, SIGNAL(visibilityChanged(bool)), SLOT(bufferViewVisibilityChanged(bool))); _bufferViews.append(dock); + + if(!activeBufferView()) + nextBufferView(); } void MainWin::removeBufferView(int bufferViewConfigId) { @@ -483,14 +587,26 @@ void MainWin::removeBufferView(int bufferViewConfigId) { dock = qobject_cast(action->parent()); if(dock && actionData.toInt() == bufferViewConfigId) { removeAction(action); - _bufferViews.removeAll(dock); Client::bufferViewOverlay()->removeView(dock->bufferViewId()); + _bufferViews.removeAll(dock); + + if(dock->isActive()) { + dock->setActive(false); + _activeBufferViewIndex = -1; + nextBufferView(); + } + dock->deleteLater(); } } } void MainWin::bufferViewToggled(bool enabled) { + if(!enabled && !isVisible()) { + // hiding the mainwindow triggers a toggle of the bufferview (which pretty much sucks big time) + // since this isn't our fault and we can't do anything about it, we suppress the resulting calls + return; + } QAction *action = qobject_cast(sender()); Q_ASSERT(action); BufferViewDock *dock = qobject_cast(action->parent()); @@ -500,28 +616,18 @@ void MainWin::bufferViewToggled(bool enabled) { if(!_bufferViews.contains(dock)) return; - if(enabled) { + if(enabled) Client::bufferViewOverlay()->addView(dock->bufferViewId()); - BufferViewConfig *config = dock->config(); - if(config && config->isInitialized()) { - BufferIdList buffers; - if(config->networkId().isValid()) { - foreach(BufferId bufferId, config->bufferList()) { - if(Client::networkModel()->networkId(bufferId) == config->networkId()) - buffers << bufferId; - } - foreach(BufferId bufferId, config->temporarilyRemovedBuffers().toList()) { - if(Client::networkModel()->networkId(bufferId) == config->networkId()) - buffers << bufferId; - } - } else { - buffers = BufferIdList::fromSet(config->bufferList().toSet() + config->temporarilyRemovedBuffers()); - } - Client::backlogManager()->checkForBacklog(buffers); - } - } else { + else Client::bufferViewOverlay()->removeView(dock->bufferViewId()); - } +} + +void MainWin::bufferViewVisibilityChanged(bool visible) { + Q_UNUSED(visible); + BufferViewDock *dock = qobject_cast(sender()); + Q_ASSERT(dock); + if((!dock->isHidden() && !activeBufferView()) || (dock->isHidden() && dock->isActive())) + nextBufferView(); } BufferView *MainWin::allBuffersView() const { @@ -531,6 +637,90 @@ BufferView *MainWin::allBuffersView() const { return 0; } +BufferView *MainWin::activeBufferView() const { + if(_activeBufferViewIndex < 0 || _activeBufferViewIndex >= _bufferViews.count()) + return 0; + BufferViewDock *dock = _bufferViews.at(_activeBufferViewIndex); + return dock->isActive() ? qobject_cast(dock->widget()) : 0; +} + +void MainWin::changeActiveBufferView(int bufferViewId) { + if(bufferViewId < 0) + return; + + BufferView *current = activeBufferView(); + if(current) { + qobject_cast(current->parent())->setActive(false); + _activeBufferViewIndex = -1; + } + + for(int i = 0; i < _bufferViews.count(); i++) { + BufferViewDock *dock = _bufferViews.at(i); + if(dock->bufferViewId() == bufferViewId && !dock->isHidden()) { + _activeBufferViewIndex = i; + dock->setActive(true); + return; + } + } + + nextBufferView(); // fallback +} + +void MainWin::changeActiveBufferView(bool backwards) { + BufferView *current = activeBufferView(); + if(current) + qobject_cast(current->parent())->setActive(false); + + if(!_bufferViews.count()) + return; + + int c = _bufferViews.count(); + while(c--) { // yes, this will reactivate the current active one if all others fail + if(backwards) { + if(--_activeBufferViewIndex < 0) + _activeBufferViewIndex = _bufferViews.count()-1; + } else { + if(++_activeBufferViewIndex >= _bufferViews.count()) + _activeBufferViewIndex = 0; + } + + BufferViewDock *dock = _bufferViews.at(_activeBufferViewIndex); + if(dock->isHidden()) + continue; + + dock->setActive(true); + return; + } + + _activeBufferViewIndex = -1; +} + +void MainWin::nextBufferView() { + changeActiveBufferView(false); +} + +void MainWin::previousBufferView() { + changeActiveBufferView(true); +} + +void MainWin::nextBuffer() { + BufferView *view = activeBufferView(); + if(view) + view->nextBuffer(); +} + +void MainWin::previousBuffer() { + BufferView *view = activeBufferView(); + if(view) + view->previousBuffer(); +} + +void MainWin::hideCurrentBuffer() { + BufferView *view = activeBufferView(); + if(view) + view->hideCurrentBuffer(); +} + void MainWin::showNotificationsDlg() { SettingsPageDlg dlg(new NotificationsSettingsPage(this), this); dlg.exec(); @@ -585,9 +775,10 @@ void MainWin::setupChatMonitor() { dock->setObjectName("ChatMonitorDock"); ChatMonitorFilter *filter = new ChatMonitorFilter(Client::messageModel(), this); - ChatMonitorView *chatView = new ChatMonitorView(filter, this); - chatView->show(); - dock->setWidget(chatView); + _chatMonitorView = new ChatMonitorView(filter, this); + _chatMonitorView->setFocusProxy(_inputWidget); + _chatMonitorView->show(); + dock->setWidget(_chatMonitorView); dock->hide(); addDockWidget(Qt::TopDockWidgetArea, dock, Qt::Vertical); @@ -613,17 +804,19 @@ void MainWin::setupInputWidget() { _bufferWidget->setFocusProxy(_inputWidget); _inputWidget->inputLine()->installEventFilter(_bufferWidget); + + connect(_topicWidget, SIGNAL(switchedPlain()), _bufferWidget, SLOT(setFocus())); } void MainWin::setupTopicWidget() { VerticalDock *dock = new VerticalDock(tr("Topic"), this); dock->setObjectName("TopicDock"); - TopicWidget *topicwidget = new TopicWidget(dock); + _topicWidget = new TopicWidget(dock); - dock->setWidget(topicwidget); + dock->setWidget(_topicWidget); - topicwidget->setModel(Client::bufferModel()); - topicwidget->setSelectionModel(Client::bufferModel()->standardSelectionModel()); + _topicWidget->setModel(Client::bufferModel()); + _topicWidget->setSelectionModel(Client::bufferModel()->standardSelectionModel()); addDockWidget(Qt::TopDockWidgetArea, dock, Qt::Vertical); @@ -631,6 +824,11 @@ void MainWin::setupTopicWidget() { dock->toggleViewAction()->setText(tr("Show Topic Line")); } +void MainWin::setupViewMenuTail() { + _viewMenu->addSeparator(); + _viewMenu->addAction(QtUi::actionCollection("General")->action("ToggleFullscreen")); +} + void MainWin::setupTitleSetter() { _titleSetter.setModel(Client::bufferModel()); _titleSetter.setSelectionModel(Client::bufferModel()->standardSelectionModel()); @@ -675,7 +873,14 @@ void MainWin::saveStatusBarStatus(bool enabled) { } void MainWin::setupSystray() { - _systemTray = new SystemTray(this); +#ifdef HAVE_DBUS + _systemTray = new StatusNotifierItem(this); +#elif !defined QT_NO_SYSTEMTRAYICON + _systemTray = new LegacySystemTray(this); +#else + _systemTray = new SystemTray(this); // dummy +#endif + _systemTray->init(); } void MainWin::setupToolBars() { @@ -745,6 +950,15 @@ void MainWin::setConnectedState() { IrcConnectionWizard *wizard = new IrcConnectionWizard(this, Qt::Sheet); wizard->show(); } + else { + // Monolithic always preselects last used buffer - Client only if the connection died + if(Client::coreConnection()->wasReconnect() || Quassel::runMode() == Quassel::Monolithic) { + QtUiSettings s; + BufferId lastUsedBufferId(s.value("LastUsedBufferId").toInt()); + if(lastUsedBufferId.isValid()) + Client::bufferModel()->switchToBuffer(lastUsedBufferId); + } + } } void MainWin::loadLayout() { @@ -752,20 +966,28 @@ void MainWin::loadLayout() { int accountId = Client::currentCoreAccount().accountId().toInt(); QByteArray state = s.value(QString("MainWinState-%1").arg(accountId)).toByteArray(); if(state.isEmpty()) { - // Make sure that the default bufferview is shown - if(_bufferViews.count()) - _bufferViews.at(0)->show(); + foreach(BufferViewDock *view, _bufferViews) + view->show(); + _layoutLoaded = true; return; } restoreState(state, accountId); + int bufferViewId = s.value(QString("ActiveBufferView-%1").arg(accountId), -1).toInt(); + if(bufferViewId >= 0) + changeActiveBufferView(bufferViewId); + _layoutLoaded = true; } void MainWin::saveLayout() { QtUiSettings s; - int accountId = Client::currentCoreAccount().accountId().toInt(); - if(accountId > 0) s.setValue(QString("MainWinState-%1").arg(accountId) , saveState(accountId)); + int accountId = _bufferViews.count()? Client::currentCoreAccount().accountId().toInt() : 0; // only save if we still have a layout! + if(accountId > 0) { + s.setValue(QString("MainWinState-%1").arg(accountId) , saveState(accountId)); + BufferView *view = activeBufferView(); + s.setValue(QString("ActiveBufferView-%1").arg(accountId), view ? view->config()->bufferViewId() : -1); + } } void MainWin::disconnectedFromCore() { @@ -784,12 +1006,18 @@ void MainWin::disconnectedFromCore() { if(dock && actionData.toInt() != -1) { removeAction(action); _bufferViews.removeAll(dock); - Client::bufferViewOverlay()->removeView(dock->bufferViewId()); dock->deleteLater(); } } + // store last active buffer QtUiSettings s; + BufferId lastBufId = _bufferWidget->currentBuffer(); + if(lastBufId.isValid()) { + s.setValue("LastUsedBufferId", lastBufId.toInt()); + // clear the current selection + Client::bufferModel()->standardSelectionModel()->clearSelection(); + } restoreState(s.value("MainWinState").toByteArray()); setDisconnectedState(); } @@ -805,7 +1033,7 @@ void MainWin::setDisconnectedState() { if(_msgProcessorStatusWidget) _msgProcessorStatusWidget->setProgress(0, 0); updateIcon(); - systemTray()->setState(SystemTray::Inactive); + systemTray()->setState(SystemTray::Passive); } void MainWin::userAuthenticationRequired(CoreAccount *account, bool *valid, const QString &errorMessage) { @@ -967,11 +1195,24 @@ void MainWin::showAboutDlg() { AboutDlg(this).exec(); } -#ifdef HAVE_KDE void MainWin::showShortcutsDlg() { - KShortcutsDialog::configure(QtUi::actionCollection("General"), KShortcutsEditor::LetterShortcutsDisallowed); -} +#ifdef HAVE_KDE + KShortcutsDialog dlg(KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsDisallowed, this); + foreach(KActionCollection *coll, QtUi::actionCollections()) + dlg.addCollection(coll, coll->property("Category").toString()); + dlg.exec(); +#else + SettingsPageDlg dlg(new ShortcutsSettingsPage(QtUi::actionCollections(), this), this); + dlg.exec(); #endif +} + +void MainWin::toggleFullscreen() { + if(isFullScreen()) + showNormal(); + else + showFullScreen(); +} /********************************************************************************************************/ @@ -979,7 +1220,7 @@ bool MainWin::event(QEvent *event) { if(event->type() == QEvent::WindowActivate) { BufferId buffer = Client::bufferModel()->currentBuffer(); if(buffer.isValid()) - QtUi::closeNotifications(buffer); + Client::instance()->markBufferAsRead(buffer); } return QMainWindow::event(event); } @@ -1002,8 +1243,8 @@ void MainWin::closeEvent(QCloseEvent *event) { QtUiSettings s; QtUiApplication* app = qobject_cast qApp; Q_ASSERT(app); - if(!app->isAboutToQuit() && s.value("UseSystemTrayIcon").toBool() && s.value("MinimizeOnClose").toBool()) { - hideToTray(); + if(!app->isAboutToQuit() && QtUi::haveSystemTray() && s.value("MinimizeOnClose").toBool()) { + QtUi::hideMainWidget(); event->ignore(); } else { event->accept(); @@ -1011,71 +1252,6 @@ void MainWin::closeEvent(QCloseEvent *event) { } } -void MainWin::changeEvent(QEvent *event) { -#ifdef Q_WS_WIN - if(event->type() == QEvent::ActivationChange) - dwTickCount = GetTickCount(); // needed for toggleMinimizedToTray() -#endif - - QMainWindow::changeEvent(event); -} - -void MainWin::hideToTray() { - if(!systemTray()->isSystemTrayAvailable()) { - qWarning() << Q_FUNC_INFO << "was called with no SystemTray available!"; - return; - } - hide(); - systemTray()->setIconVisible(); -} - -void MainWin::toggleMinimizedToTray() { -#ifdef Q_WS_WIN - // the problem is that we lose focus when the systray icon is activated - // and we don't know the former active window - // therefore we watch for activation event and use our stopwatch :) - // courtesy: KSystemTrayIcon - if(GetTickCount() - dwTickCount >= 300) - // we weren't active in the last 300ms -> activate - forceActivated(); - else - hideToTray(); - -#else - - if(!isVisible() || isMinimized()) - // restore - forceActivated(); - else - hideToTray(); - -#endif -} - -void MainWin::forceActivated() { -#ifdef HAVE_KDE - show(); - KWindowSystem::forceActiveWindow(winId()); -#else - -#ifdef Q_WS_X11 - // Bypass focus stealing prevention - QX11Info::setAppUserTime(QX11Info::appTime()); -#endif - - if(windowState() & Qt::WindowMinimized) { - // restore - setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); - } - - // this does not actually work on all platforms... and causes more evil than good - // move(frameGeometry().topLeft()); // avoid placement policies - show(); - raise(); - activateWindow(); -#endif /* HAVE_KDE */ -} - void MainWin::messagesInserted(const QModelIndex &parent, int start, int end) { Q_UNUSED(parent); @@ -1115,14 +1291,14 @@ void MainWin::messagesInserted(const QModelIndex &parent, int start, int end) { else type = AbstractNotificationBackend::HighlightFocused; - QtUi::invokeNotification(bufId, type, sender, contents); + QtUi::instance()->invokeNotification(bufId, type, sender, contents); } } } void MainWin::currentBufferChanged(BufferId buffer) { if(buffer.isValid()) - QtUi::closeNotifications(buffer); + Client::instance()->markBufferAsRead(buffer); } void MainWin::clientNetworkCreated(NetworkId id) { @@ -1159,6 +1335,14 @@ void MainWin::clientNetworkUpdated() { switch(net->connectionState()) { case Network::Initialized: action->setIcon(SmallIcon("network-connect")); + // if we have no currently selected buffer, jump to the first connecting statusbuffer + if(!bufferWidget()->currentBuffer().isValid()) { + QModelIndex idx = Client::networkModel()->networkIndex(net->networkId()); + if(idx.isValid()) { + BufferId statusBufferId = idx.data(NetworkModel::BufferIdRole).value(); + Client::bufferModel()->switchToBuffer(statusBufferId); + } + } break; case Network::Disconnected: action->setIcon(SmallIcon("network-disconnect")); @@ -1194,6 +1378,34 @@ void MainWin::on_jumpHotBuffer_triggered() { Client::bufferModel()->switchToBuffer(bufferId); } +void MainWin::onJumpKey() { + QAction *action = qobject_cast(sender()); + if(!action || !Client::bufferModel()) + return; + int idx = action->property("Index").toInt(); + + if(_jumpKeyMap.isEmpty()) + _jumpKeyMap = CoreAccountSettings().jumpKeyMap(); + + if(!_jumpKeyMap.contains(idx)) + return; + + BufferId buffer = _jumpKeyMap.value(idx); + if(buffer.isValid()) + Client::bufferModel()->switchToBuffer(buffer); + +} + +void MainWin::bindJumpKey() { + QAction *action = qobject_cast(sender()); + if(!action || !Client::bufferModel()) + return; + int idx = action->property("Index").toInt(); + + _jumpKeyMap[idx] = Client::bufferModel()->currentBuffer(); + CoreAccountSettings().setJumpKeyMap(_jumpKeyMap); +} + void MainWin::on_actionDebugNetworkModel_triggered() { QTreeView *view = new QTreeView; view->setAttribute(Qt::WA_DeleteOnClose); @@ -1238,4 +1450,3 @@ void MainWin::on_actionDebugLog_triggered() { void MainWin::showStatusBarMessage(const QString &message) { statusBar()->showMessage(message, 10000); } -