MRU tab switching implemented

This commit is contained in:
wwwwww 2011-11-02 23:37:50 +00:00 committed by abirvalg
parent 1d399aabc8
commit 753b0185df
9 changed files with 168 additions and 15 deletions

View file

@ -85,6 +85,7 @@ Preferences::Preferences():
newTabsOpenAfterCurrentOne( false ),
newTabsOpenInBackground( true ),
hideSingleTab( false ),
mruTabOrder ( false ),
hideMenubar( false ),
enableTrayIcon( true ),
startToTray( false ),
@ -570,6 +571,7 @@ Class load() throw( exError )
c.preferences.newTabsOpenAfterCurrentOne = ( preferences.namedItem( "newTabsOpenAfterCurrentOne" ).toElement().text() == "1" );
c.preferences.newTabsOpenInBackground = ( preferences.namedItem( "newTabsOpenInBackground" ).toElement().text() == "1" );
c.preferences.hideSingleTab = ( preferences.namedItem( "hideSingleTab" ).toElement().text() == "1" );
c.preferences.mruTabOrder = ( preferences.namedItem( "mruTabOrder" ).toElement().text() == "1" );
c.preferences.hideMenubar = ( preferences.namedItem( "hideMenubar" ).toElement().text() == "1" );
c.preferences.enableTrayIcon = ( preferences.namedItem( "enableTrayIcon" ).toElement().text() == "1" );
c.preferences.startToTray = ( preferences.namedItem( "startToTray" ).toElement().text() == "1" );
@ -1038,6 +1040,10 @@ void save( Class const & c ) throw( exError )
opt.appendChild( dd.createTextNode( c.preferences.hideSingleTab ? "1":"0" ) );
preferences.appendChild( opt );
opt = dd.createElement( "mruTabOrder" );
opt.appendChild( dd.createTextNode( c.preferences.mruTabOrder ? "1":"0" ) );
preferences.appendChild( opt );
opt = dd.createElement( "hideMenubar" );
opt.appendChild( dd.createTextNode( c.preferences.hideMenubar ? "1":"0" ) );
preferences.appendChild( opt );

View file

@ -140,6 +140,7 @@ struct Preferences
bool newTabsOpenAfterCurrentOne;
bool newTabsOpenInBackground;
bool hideSingleTab;
bool mruTabOrder;
bool hideMenubar;
bool enableTrayIcon;
bool startToTray;

View file

@ -189,7 +189,8 @@ HEADERS += folding.hh \
dprintf.hh \
mainstatusbar.hh \
gdappstyle.hh \
ufile.hh
ufile.hh \
mruqmenu.hh
FORMS += groups.ui \
dictgroupwidget.ui \
mainwindow.ui \
@ -277,7 +278,8 @@ SOURCES += folding.cc \
maintabwidget.cc \
mainstatusbar.cc \
gdappstyle.cc \
ufile.cc
ufile.cc \
mruqmenu.cc
win32 {
SOURCES += mouseover_win32/ThTypes.c \
wordbyauto.cc \

View file

@ -6,10 +6,12 @@
#include "loaddictionaries.hh"
#include "preferences.hh"
#include "about.hh"
#include "mruqmenu.hh"
#include <limits.h>
#include <QDir>
#include <QMessageBox>
#include <QIcon>
#include <QList>
#include <QToolBar>
#include <QCloseEvent>
#include <QDesktopServices>
@ -203,6 +205,9 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
addTabAction.setShortcut( QKeySequence( "Ctrl+T" ) );
// Tab management
tabListMenu = new MRUQMenu(tr("Opened tabs"), ui.tabWidget);
connect (tabListMenu, SIGNAL(ctrlReleased()), this, SLOT(ctrlReleased()));
connect( &addTabAction, SIGNAL( triggered() ),
this, SLOT( addNewTab() ) );
@ -423,6 +428,8 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
ui.wordList->viewport()->installEventFilter( this );
ui.dictsList->installEventFilter( this );
ui.dictsList->viewport()->installEventFilter( this );
//tabWidget doesn't propagate Ctrl+Tab to the parent widget unless event filter is installed
ui.tabWidget->installEventFilter( this );
if ( cfg.mainWindowGeometry.size() )
restoreGeometry( cfg.mainWindowGeometry );
@ -499,6 +506,12 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
updateStatusLine();
}
void MainWindow::ctrlTabPressed()
{
emit fillWindowsMenu();
tabListButton->click();
}
void MainWindow::mousePressEvent( QMouseEvent *event)
{
@ -846,7 +859,6 @@ vector< sptr< Dictionary::Class > > const & MainWindow::getActiveDicts()
void MainWindow::createTabList()
{
tabListMenu = new QMenu(tr("Opened tabs"), ui.tabWidget);
tabListMenu->setIcon(QIcon(":/icons/windows-list.png"));
connect(tabListMenu, SIGNAL(aboutToShow()), this, SLOT(fillWindowsMenu()));
connect(tabListMenu, SIGNAL(triggered(QAction*)), this, SLOT(switchToWindow(QAction*)));
@ -865,18 +877,43 @@ void MainWindow::fillWindowsMenu()
{
tabListMenu->clear();
for (int i = 0; i < ui.tabWidget->count(); i++)
if(cfg.preferences.mruTabOrder)
{
QAction *act = tabListMenu->addAction( ui.tabWidget->tabIcon( i ),
ui.tabWidget->tabText( i ) );
act->setData( i );
if (ui.tabWidget->currentIndex() == i)
for (int i = 0; i < mruList.count(); i++)
{
QFont f( act->font() );
f.setBold( true );
act->setFont( f );
QAction *act = tabListMenu->addAction(ui.tabWidget->tabIcon(ui.tabWidget->indexOf(mruList.at(i))), ui.tabWidget->tabText(ui.tabWidget->indexOf(mruList.at(i))));
//remember the index of the Tab to be later used in ctrlReleased()
act->setData(ui.tabWidget->indexOf(mruList.at(i)));
if (ui.tabWidget->currentIndex() == ui.tabWidget->indexOf(mruList.at(i)))
{
QFont f( act->font() );
f.setBold( true );
act->setFont( f );
}
}
if (tabListMenu->actions().size() > 1)
{
tabListMenu->setActiveAction(tabListMenu->actions().at(1));
}
}
else
{
for (int i = 0; i < ui.tabWidget->count(); i++)
{
QAction *act = tabListMenu->addAction( ui.tabWidget->tabIcon( i ),
ui.tabWidget->tabText( i ) );
act->setData( i );
if (ui.tabWidget->currentIndex() == i)
{
QFont f( act->font() );
f.setBold( true );
act->setFont( f );
}
}
}
return;
}
void MainWindow::switchToWindow(QAction *act)
@ -933,6 +970,7 @@ ArticleView * MainWindow::createNewTab( bool switchToIt,
escaped.replace( "&", "&&" );
ui.tabWidget->insertTab( index, view, escaped );
mruList.append(dynamic_cast<QWidget*>(view));
if ( switchToIt )
ui.tabWidget->setCurrentIndex( index );
@ -950,10 +988,29 @@ void MainWindow::tabCloseRequested( int x )
QWidget * w = ui.tabWidget->widget( x );
if (cfg.preferences.mruTabOrder)
{
//removeTab activates next tab and emits currentChannged SIGNAL
//This is not what we want for MRU, so disable the signal for a moment
disconnect( ui.tabWidget, SIGNAL( currentChanged( int ) ),
this, SLOT( tabSwitched( int ) ) );
}
ui.tabWidget->removeTab( x );
if (cfg.preferences.mruTabOrder)
{
connect( ui.tabWidget, SIGNAL( currentChanged( int ) ), this, SLOT( tabSwitched( int ) ) );
}
mruList.removeOne(w);
delete w;
//activate a tab in accordance with MRU
ui.tabWidget->setCurrentWidget(mruList.at(0));
// if everything is closed, add new tab
if ( ui.tabWidget->count() == 0 )
addNewTab();
@ -1008,6 +1065,16 @@ void MainWindow::switchToPrevTab()
ui.tabWidget->setCurrentIndex( ui.tabWidget->currentIndex() - 1 );
}
//emitted by tabListMenu when user releases Ctrl
void MainWindow::ctrlReleased()
{
if (tabListMenu->actions().size() > 1)
{
ui.tabWidget->setCurrentIndex(tabListMenu->activeAction()->data().toInt());
}
tabListMenu->hide();
}
void MainWindow::backClicked()
{
DPRINTF( "Back\n" );
@ -1072,6 +1139,10 @@ void MainWindow::tabSwitched( int )
updatePronounceAvailability();
updateFoundInDictsList();
updateWindowTitle();
if (mruList.size() > 1)
{
mruList.move(mruList.indexOf(ui.tabWidget->widget(ui.tabWidget->currentIndex())),0);
}
}
void MainWindow::tabMenuRequested(QPoint pos)
@ -1519,7 +1590,21 @@ bool MainWindow::eventFilter( QObject * obj, QEvent * ev )
return handleBackForwardMouseButtons( event );
}
if ( obj == ui.translateLine )
if (ev->type() == QEvent::KeyPress)
{
QKeyEvent *keyevent = static_cast<QKeyEvent*>(ev);
if (keyevent->modifiers() == Qt::ControlModifier && keyevent->key() == Qt::Key_Tab)
{
if (cfg.preferences.mruTabOrder)
{
ctrlTabPressed();
return true;
}
return false;
}
}
if ( obj == ui.translateLine )
{
if ( ev->type() == QEvent::KeyPress )
{
@ -1621,7 +1706,6 @@ bool MainWindow::eventFilter( QObject * obj, QEvent * ev )
}
}
}
else
return QMainWindow::eventFilter( obj, ev );
return false;

View file

@ -23,6 +23,7 @@
#include "history.hh"
#include "hotkeywrapper.hh"
#include "mainstatusbar.hh"
#include "mruqmenu.hh"
#ifdef Q_WS_X11
#include <fixx11h.h>
@ -80,7 +81,10 @@ private:
QAction * zoomIn, * zoomOut, * zoomBase;
QAction * wordsZoomIn, * wordsZoomOut, * wordsZoomBase;
QMenu trayIconMenu;
QMenu *tabListMenu, *tabMenu;
QMenu *tabMenu;
MRUQMenu *tabListMenu;
//List that contains indexes of tabs arranged in a most-recently-used order
QList<QWidget*> mruList;
QToolButton addTab, *tabListButton;
Config::Class & cfg;
Config::Events configEvents;
@ -165,6 +169,7 @@ private:
bool handleBackForwardMouseButtons(QMouseEvent *ev);
ArticleView * getCurrentArticleView();
void ctrlTabPressed();
private slots:
@ -194,6 +199,7 @@ private slots:
void closeRestTabs();
void switchToNextTab();
void switchToPrevTab();
void ctrlReleased();
// Handling of active tab list
void createTabList();

20
mruqmenu.cc Normal file
View file

@ -0,0 +1,20 @@
#include "mruqmenu.hh"
#include <QKeyEvent>
MRUQMenu::MRUQMenu(const QString title, QWidget *parent):
QMenu(title,parent)
{
installEventFilter(this);
}
bool MRUQMenu::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::KeyRelease){
QKeyEvent *keyevent = static_cast<QKeyEvent*>(event);
if (keyevent->key() == Qt::Key_Control){
emit ctrlReleased();
return true;
}
}
return false;
}

25
mruqmenu.hh Normal file
View file

@ -0,0 +1,25 @@
#ifndef MRUQMENU_HH
#define MRUQMENU_HH
#include <QMenu>
#include <QEvent>
//The only difference between this class and QMenu is that this class emits
//a signal when Ctrl button is released
class MRUQMenu: public QMenu
{
Q_OBJECT
public:
MRUQMenu(const QString title, QWidget *parent = 0);
private:
bool eventFilter (QObject*, QEvent*);
signals:
void ctrlReleased();
};
#endif // MRUQMENU_HH

View file

@ -89,6 +89,7 @@ Preferences::Preferences( QWidget * parent, Config::Preferences const & p ):
ui.newTabsOpenAfterCurrentOne->setChecked( p.newTabsOpenAfterCurrentOne );
ui.newTabsOpenInBackground->setChecked( p.newTabsOpenInBackground );
ui.hideSingleTab->setChecked( p.hideSingleTab );
ui.mruTabOrder->setChecked( p.mruTabOrder );
ui.enableTrayIcon->setChecked( p.enableTrayIcon );
ui.startToTray->setChecked( p.startToTray );
ui.closeToTray->setChecked( p.closeToTray );
@ -203,6 +204,7 @@ Config::Preferences Preferences::getPreferences()
p.newTabsOpenAfterCurrentOne = ui.newTabsOpenAfterCurrentOne->isChecked();
p.newTabsOpenInBackground = ui.newTabsOpenInBackground->isChecked();
p.hideSingleTab = ui.hideSingleTab->isChecked();
p.mruTabOrder = ui.mruTabOrder->isChecked();
p.enableTrayIcon = ui.enableTrayIcon->isChecked();
p.startToTray = ui.startToTray->isChecked();
p.closeToTray = ui.closeToTray->isChecked();

View file

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>572</width>
<height>357</height>
<height>376</height>
</rect>
</property>
<property name="windowTitle">
@ -94,6 +94,13 @@ be the last ones.</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QCheckBox" name="mruTabOrder">
<property name="text">
<string>Ctrl-Tab navigates tabs in MRU order</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>