From d46e4dc77bee6f2bd956f80c47ddaf3e05099c85 Mon Sep 17 00:00:00 2001 From: Tvangeste Date: Mon, 27 Jun 2011 20:54:15 +0200 Subject: [PATCH] Chrome-style statusbar for GoldenDict. * Small pop-up window at the bottom of the main winodw instead of traditional status bar, that consumes lots of space. * API, similar to standard Qt's status bar. * The status bar hides itself after specified amount of time. * Clicking on the status bar also hides it. * Properly behavies on resizes/moves/focus/etc. * Tested on Linux and Windows. --- goldendict.pro | 6 ++- mainstatusbar.cc | 105 +++++++++++++++++++++++++++++++++++++++++++++++ mainstatusbar.hh | 37 +++++++++++++++++ mainwindow.cc | 36 ++++++++++------ mainwindow.hh | 2 + mainwindow.ui | 6 ++- 6 files changed, 176 insertions(+), 16 deletions(-) create mode 100644 mainstatusbar.cc create mode 100644 mainstatusbar.hh diff --git a/goldendict.pro b/goldendict.pro index 5ca5b282..ec58f41e 100644 --- a/goldendict.pro +++ b/goldendict.pro @@ -166,7 +166,8 @@ HEADERS += folding.hh \ parsecmdline.hh \ dictspanewidget.hh \ maintabwidget.hh \ - dprintf.hh + dprintf.hh \ + mainstatusbar.hh FORMS += groups.ui \ dictgroupwidget.ui \ mainwindow.ui \ @@ -251,7 +252,8 @@ SOURCES += folding.cc \ about.cc \ programs.cc \ parsecmdline.cc \ - maintabwidget.cc + maintabwidget.cc \ + mainstatusbar.cc win32 { SOURCES += mouseover_win32/ThTypes.c HEADERS += mouseover_win32/ThTypes.h diff --git a/mainstatusbar.cc b/mainstatusbar.cc new file mode 100644 index 00000000..0b1e60df --- /dev/null +++ b/mainstatusbar.cc @@ -0,0 +1,105 @@ +/* This file is (c) 2011 Tvangeste + * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ + +#include "mainstatusbar.hh" + +#include +#include +#include +#include +#include + +MainStatusBar::MainStatusBar(QWidget *parent) : QFrame(parent) +{ + // style + setWindowFlags( Qt::Tool | Qt::X11BypassWindowManagerHint | Qt::FramelessWindowHint ); + setFrameStyle( QFrame::Box | QFrame::Plain ); + setLineWidth(0); + + // components + label = new QLabel(QString(), this); + label->setTextFormat(Qt::PlainText); + timer = new QTimer(this); + + // layout + QVBoxLayout * layout = new QVBoxLayout; + layout->addWidget(label); + layout->setSizeConstraint(QLayout::SetFixedSize); + layout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); + layout->setMargin(4); + setLayout(layout); + + parentWidget()->installEventFilter( this ); + + connect( timer, SIGNAL( timeout() ), SLOT( clearMessage() ) ); +} + +void MainStatusBar::clearMessage() +{ + message = QString(); + label->setText(message); + timer->stop(); + refresh(); +} + +QString MainStatusBar::currentMessage() const +{ + return message; +} + +void MainStatusBar::showMessage(const QString & str, int timeout) +{ + message = str; + + if ( timeout > 0 ) + { + timer->start( timeout ); + } + + refresh(); +} + +void MainStatusBar::refresh() +{ + + if ( !message.isEmpty() ) + { + QRect pGeom = parentWidget()->geometry(); + + int maxLabelLength = pGeom.width() - 2 * layout()->margin(); + label->setText( label->fontMetrics().elidedText( message, Qt::ElideRight, maxLabelLength ) ); + + adjustSize(); + + move(pGeom.left(), pGeom.bottom() - size().height() + 1 ); + show(); + } + else + { + hide(); + } + +} + +void MainStatusBar::mousePressEvent ( QMouseEvent * ) +{ + clearMessage(); +} + +bool MainStatusBar::eventFilter(QObject *, QEvent * event) +{ + switch ( event->type() ) { + case QEvent::Move: + case QEvent::Resize: + case QEvent::FocusOut: + case QEvent::WindowDeactivate: + case QEvent::Hide: + case QEvent::WindowActivate: + refresh(); + break; + default: + break; + }; + + return false; +} diff --git a/mainstatusbar.hh b/mainstatusbar.hh new file mode 100644 index 00000000..c06e3c62 --- /dev/null +++ b/mainstatusbar.hh @@ -0,0 +1,37 @@ +/* This file is (c) 2011 Tvangeste + * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ + +#ifndef MAINSTATUSBAR_HH +#define MAINSTATUSBAR_HH + +#include +#include +#include +#include + +class MainStatusBar : public QFrame +{ + Q_OBJECT + +public: + explicit MainStatusBar(QWidget * parent); + QString currentMessage() const; + +signals: + +public slots: + void showMessage(const QString & text, int timeout = 0); + void clearMessage(); + +protected: + virtual void mousePressEvent(QMouseEvent * event); + +private: + QLabel * label; + QTimer * timer; + QString message; + bool eventFilter(QObject *obj, QEvent * event); + void refresh(); +}; + +#endif // MAINSTATUSBAR_HH diff --git a/mainwindow.cc b/mainwindow.cc index 58345ae4..eb80f3aa 100644 --- a/mainwindow.cc +++ b/mainwindow.cc @@ -16,6 +16,7 @@ #include #include #include "dprintf.hh" +#include using std::set; using std::wstring; @@ -55,6 +56,10 @@ MainWindow::MainWindow( Config::Class & cfg_ ): ui.setupUi( this ); + // use our own, cutsom statusbar + setStatusBar(0); + mainStatusBar = new MainStatusBar( this ); + wordListDefaultFont = ui.wordList->font(); translateLineDefaultFont = ui.translateLine->font(); @@ -465,6 +470,8 @@ MainWindow::MainWindow( Config::Class & cfg_ ): // makeDictionaries() didn't do deferred init - we do it here, at the end. doDeferredInit( dictionaries ); + + updateStatusLine(); } void MainWindow::mousePressEvent( QMouseEvent *event) @@ -684,9 +691,9 @@ void MainWindow::updateStatusLine() wordCount += dictionaries[ x ]->getWordCount(); } - statusBar()->showMessage( tr( "%1 dictionaries, %2 articles, %3 words" ). + mainStatusBar->showMessage( tr( "%1 dictionaries, %2 articles, %3 words" ). arg( dictionaries.size() ).arg( articleCount ). - arg( wordCount ) ); + arg( wordCount ), 10000 ); } void MainWindow::updateGroupList() @@ -1244,8 +1251,10 @@ void MainWindow::translateInputChanged( QString const & newValue ) { // If there's some status bar message present, clear it since it may be // about the previous search that has failed. - if ( !statusBar()->currentMessage().isEmpty() ) - statusBar()->clearMessage(); + if ( !mainStatusBar->currentMessage().isEmpty() ) + { + mainStatusBar->clearMessage(); + } // If some word is selected in the word list, unselect it. This prevents // triggering a set of spurious activation signals when the list changes. @@ -1401,7 +1410,7 @@ void MainWindow::updateMatchResults( bool finished ) } if ( !wordFinder.getErrorString().isEmpty() ) - statusBar()->showMessage( tr( "WARNING: %1" ).arg( wordFinder.getErrorString() ) ); + mainStatusBar->showMessage( tr( "WARNING: %1" ).arg( wordFinder.getErrorString() ), 20000 ); } } @@ -2024,14 +2033,17 @@ void MainWindow::toggleMenuBarTriggered(bool announce) { cfg.preferences.hideMenubar = menuBar()->isVisible(); - if ( announce && cfg.preferences.hideMenubar ) + if ( announce ) { - statusBar()->showMessage( - tr( "You have chosen to hide a menubar. Use %1 to show it back." ).arg( tr( "Ctl+M" ) ), 10000 ); - } - else - { - statusBar()->clearMessage(); + if ( cfg.preferences.hideMenubar ) + { + mainStatusBar->showMessage( + tr( "You have chosen to hide a menubar. Use %1 to show it back." ).arg( tr( "Ctrl+M" ) ), 10000 ); + } + else + { + mainStatusBar->clearMessage(); + } } // Obtain from the menubar all the actions with shortcuts diff --git a/mainwindow.hh b/mainwindow.hh index 55e813b6..d41eebd4 100644 --- a/mainwindow.hh +++ b/mainwindow.hh @@ -22,6 +22,7 @@ #include "dictionarybar.hh" #include "history.hh" #include "hotkeywrapper.hh" +#include "mainstatusbar.hh" #ifdef Q_WS_X11 #include @@ -73,6 +74,7 @@ private: switchToNextTabAction, switchToPrevTabAction, showDictBarNamesAction, useSmallIconsInToolbarsAction, toggleMenuBarAction; QToolBar * navToolbar; + MainStatusBar * mainStatusBar; QAction * navBack, * navForward, * navPronounce, * enableScanPopup, * scanPopupSeparator; QAction * zoomIn, * zoomOut, * zoomBase; QAction * wordsZoomIn, * wordsZoomOut, * wordsZoomBase; diff --git a/mainwindow.ui b/mainwindow.ui index e5a5ee09..f5104587 100644 --- a/mainwindow.ui +++ b/mainwindow.ui @@ -18,11 +18,14 @@ 1 + + 2 + 1 - 1 + 0 @@ -118,7 +121,6 @@ - Search Pane