From 56288a13972bf8466b57c9d5d1ec382fc7e287cc Mon Sep 17 00:00:00 2001 From: Manuel Nickschas Date: Tue, 20 Jul 2010 09:04:51 +0200 Subject: [PATCH] Introduce the concept of an "active" bufferview For things like keyboard navigation, we need to mark a given bufferview as the active one, so concepts like "next/previous channel" have something to refer to. We now mark the active bufferview by a little dot. The user can switch through the visible views using the "Forward" and "Back" standard keys, which usually map to Alt + Right/Left. No (re)storing of the active view yet. --- src/qtui/mainwin.cpp | 79 +++++++++++++++++++++++++++++++++--- src/qtui/mainwin.h | 6 +++ src/uisupport/bufferview.cpp | 38 +++++++++++++---- src/uisupport/bufferview.h | 12 +++++- 4 files changed, 120 insertions(+), 15 deletions(-) diff --git a/src/qtui/mainwin.cpp b/src/qtui/mainwin.cpp index 1362e850..a144904b 100644 --- a/src/qtui/mainwin.cpp +++ b/src/qtui/mainwin.cpp @@ -134,7 +134,8 @@ MainWin::MainWin(QWidget *parent) _coreConnectionStatusWidget(new CoreConnectionStatusWidget(Client::coreConnection(), this)), _titleSetter(this), _awayLog(0), - _layoutLoaded(false) + _layoutLoaded(false), + _activeBufferViewIndex(-1) { setAttribute(Qt::WA_DeleteOnClose, false); // we delete the mainwin manually @@ -419,6 +420,12 @@ void MainWin::setupActions() { 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(QKeySequence::Back))); } void MainWin::setupMenus() { @@ -530,7 +537,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) { @@ -544,8 +555,15 @@ 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(); } } @@ -566,11 +584,18 @@ void MainWin::bufferViewToggled(bool enabled) { if(!_bufferViews.contains(dock)) return; - if(enabled) { + if(enabled) Client::bufferViewOverlay()->addView(dock->bufferViewId()); - } 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 { @@ -580,6 +605,50 @@ 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(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::showNotificationsDlg() { SettingsPageDlg dlg(new NotificationsSettingsPage(this), this); dlg.exec(); diff --git a/src/qtui/mainwin.h b/src/qtui/mainwin.h index 02b7ff58..bdff05d1 100644 --- a/src/qtui/mainwin.h +++ b/src/qtui/mainwin.h @@ -70,6 +70,7 @@ class MainWin void addBufferView(ClientBufferViewConfig *config); BufferView *allBuffersView() const; + BufferView *activeBufferView() const; inline BufferWidget *bufferWidget() const { return _bufferWidget; } inline SystemTray *systemTray() const { return _systemTray; } @@ -84,6 +85,8 @@ class MainWin public slots: void showStatusBarMessage(const QString &message); + void nextBufferView(); //!< Activate the next bufferview + void previousBufferView(); //!< Activate the previous bufferview //! Quit application void quit(); @@ -149,6 +152,8 @@ class MainWin void saveLayout(); void bufferViewToggled(bool enabled); + void bufferViewVisibilityChanged(bool visible); + void changeActiveBufferView(bool backwards); signals: void connectToCore(const QVariantMap &connInfo); @@ -201,6 +206,7 @@ class MainWin BufferHotListFilter *_bufferHotList; QHash _jumpKeyMap; + int _activeBufferViewIndex; friend class QtUi; }; diff --git a/src/uisupport/bufferview.cpp b/src/uisupport/bufferview.cpp index ecaf7e94..076c9a87 100644 --- a/src/uisupport/bufferview.cpp +++ b/src/uisupport/bufferview.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 * @@ -246,8 +246,8 @@ void BufferView::dropEvent(QDropEvent *event) { return QTreeView::dropEvent(event); int res = QMessageBox::question(0, tr("Merge buffers permanently?"), - tr("Do you want to merge the buffer \"%1\" permanently into buffer \"%2\"?\n This cannot be reversed!").arg(Client::networkModel()->bufferName(bufferId2)).arg(Client::networkModel()->bufferName(bufferId1)), - QMessageBox::Yes|QMessageBox::No, QMessageBox::No); + tr("Do you want to merge the buffer \"%1\" permanently into buffer \"%2\"?\n This cannot be reversed!").arg(Client::networkModel()->bufferName(bufferId2)).arg(Client::networkModel()->bufferName(bufferId1)), + QMessageBox::Yes|QMessageBox::No, QMessageBox::No); if(res == QMessageBox::Yes) { Client::mergeBuffersPermanently(bufferId1, bufferId2); } @@ -408,7 +408,7 @@ void BufferView::addFilterActions(QMenu *contextMenu, const QModelIndex &index) if(!filterActions.isEmpty()) { contextMenu->addSeparator(); foreach(QAction *action, filterActions) { - contextMenu->addAction(action); + contextMenu->addAction(action); } } } @@ -444,11 +444,11 @@ void BufferView::wheelEvent(QWheelEvent* event) { QModelIndex parent = currentIndex.parent(); QModelIndex aunt = parent.sibling( parent.row() + rowDelta, parent.column() ); if( rowDelta == -1 ) - resultingIndex = aunt.child( model()->rowCount( aunt ) - 1, 0 ); + resultingIndex = aunt.child( model()->rowCount( aunt ) - 1, 0 ); else - resultingIndex = aunt.child( 0, 0 ); + resultingIndex = aunt.child( 0, 0 ); if( !resultingIndex.isValid() ) - return; + return; } selectionModel()->setCurrentIndex( resultingIndex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows ); selectionModel()->select( resultingIndex, QItemSelectionModel::ClearAndSelect ); @@ -528,16 +528,36 @@ bool BufferViewDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, c // BufferView Dock // ============================== BufferViewDock::BufferViewDock(BufferViewConfig *config, QWidget *parent) - : QDockWidget(config->bufferViewName(), parent) + : QDockWidget(parent), + _active(false), + _title(config->bufferViewName()) { setObjectName("BufferViewDock-" + QString::number(config->bufferViewId())); toggleViewAction()->setData(config->bufferViewId()); setAllowedAreas(Qt::RightDockWidgetArea|Qt::LeftDockWidgetArea); connect(config, SIGNAL(bufferViewNameSet(const QString &)), this, SLOT(bufferViewRenamed(const QString &))); + updateTitle(); +} + +void BufferViewDock::updateTitle() { + QString title = _title; + if(isActive()) + title.prepend(QString::fromUtf8("• ")); + setWindowTitle(title); +} + +void BufferViewDock::setActive(bool active) { + if(active != isActive()) { + _active = active; + updateTitle(); + if(active) + raise(); // for tabbed docks + } } void BufferViewDock::bufferViewRenamed(const QString &newName) { - setWindowTitle(newName); + _title = newName; + updateTitle(); toggleViewAction()->setText(newName); } diff --git a/src/uisupport/bufferview.h b/src/uisupport/bufferview.h index 5d19a138..5dc1a2d9 100644 --- a/src/uisupport/bufferview.h +++ b/src/uisupport/bufferview.h @@ -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 * @@ -121,9 +121,19 @@ public: int bufferViewId() const; BufferViewConfig *config() const; inline BufferView *bufferView() const { return qobject_cast(widget()); } + inline bool isActive() const { return _active; } public slots: + void setActive(bool active = true); + +private slots: void bufferViewRenamed(const QString &newName); + void updateTitle(); + +private: + + bool _active; + QString _title; }; #endif -- 2.20.1