mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-23 20:14:05 +00:00
History Pane rewrite.
The new History Pane features proper mouse and keyboard navigation, multiple selection and ability to remove the selected entries, plus a dynamic context menu. Additionaly, the History's size is now configurable in Preferences. Use Ctrl+H to show/hide the History Pane. History Pane's titlebar can be styled via #historyPaneTitleBar, e.g.: /* Colored header for the History Pane */ background: lightsteelblue; margin: 2px; } Closes #162: Make History sidebar independent from the Search Pane Closes #159: "Send to main window" button from Pop-Up window does nothing when History is shown Closes #158: Preserve History mode after restart Closes #157: History with new UI: New words are not added when History is shown Closes #156: History with new UI: Extra Groups widget in History is shown Closes #155: History with new UI: Arrow keys navigation in History doesn't work Closes #154: History with new UI: DEL key does not delete the current history entry
This commit is contained in:
parent
1fab8c8216
commit
3ed7772996
|
@ -10,6 +10,7 @@
|
|||
/// A widget holding the contents of the 'Dictionaries pane' docklet.
|
||||
class DictsPaneWidget: public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
DictsPaneWidget( QWidget * parent = 0 ): QWidget( parent )
|
||||
|
|
|
@ -208,7 +208,9 @@ HEADERS += folding.hh \
|
|||
zipsounds.hh \
|
||||
stylescombobox.hh \
|
||||
extlineedit.hh \
|
||||
translatebox.hh
|
||||
translatebox.hh \
|
||||
historypanewidget.hh
|
||||
|
||||
FORMS += groups.ui \
|
||||
dictgroupwidget.ui \
|
||||
mainwindow.ui \
|
||||
|
@ -307,7 +309,9 @@ SOURCES += folding.cc \
|
|||
zipsounds.cc \
|
||||
stylescombobox.cc \
|
||||
extlineedit.cc \
|
||||
translatebox.cc
|
||||
translatebox.cc \
|
||||
historypanewidget.cc
|
||||
|
||||
win32 {
|
||||
SOURCES += mouseover_win32/ThTypes.c \
|
||||
wordbyauto.cc \
|
||||
|
|
40
history.cc
40
history.cc
|
@ -5,6 +5,7 @@
|
|||
#include "config.hh"
|
||||
#include "atomic_rename.hh"
|
||||
#include <QFile>
|
||||
#include <QDebug>
|
||||
|
||||
History::History( unsigned size ): maxSize( size ),
|
||||
addingEnabled( true )
|
||||
|
@ -48,8 +49,18 @@ addingEnabled( true )
|
|||
}
|
||||
}
|
||||
|
||||
History::Item History::getItem( int index )
|
||||
{
|
||||
if ( index < 0 || index >= items.size() )
|
||||
{
|
||||
return Item();
|
||||
}
|
||||
return items.at( index );
|
||||
}
|
||||
|
||||
void History::addItem( Item const & item )
|
||||
{
|
||||
// qDebug() << "adding item " << item.word << ", enabled=" << enabled();
|
||||
if( !enabled() )
|
||||
return;
|
||||
|
||||
|
@ -70,12 +81,37 @@ void History::addItem( Item const & item )
|
|||
|
||||
items.push_front( item );
|
||||
|
||||
while( items.size() > (int)maxSize )
|
||||
items.pop_back();
|
||||
ensureSizeConstraints();
|
||||
|
||||
emit itemsChanged();
|
||||
}
|
||||
|
||||
bool History::ensureSizeConstraints()
|
||||
{
|
||||
bool changed = false;
|
||||
while( items.size() > (int)maxSize )
|
||||
{
|
||||
items.pop_back();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
void History::setMaxSize( unsigned maxSize_ )
|
||||
{
|
||||
maxSize = maxSize_;
|
||||
if ( ensureSizeConstraints() )
|
||||
{
|
||||
emit itemsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
int History::size() const
|
||||
{
|
||||
return items.size();
|
||||
}
|
||||
|
||||
bool History::save() const
|
||||
{
|
||||
QFile file( Config::getHistoryFileName() + ".tmp" );
|
||||
|
|
14
history.hh
14
history.hh
|
@ -55,9 +55,11 @@ public:
|
|||
/// item gets removed from the end of the list.
|
||||
void addItem( Item const & );
|
||||
|
||||
Item getItem( int index );
|
||||
|
||||
/// Remove item with given index from list
|
||||
void removeItem( int index )
|
||||
{ items.removeAt( index ); }
|
||||
{ items.removeAt( index ); emit itemsChanged(); }
|
||||
|
||||
/// Attempts saving history. Returns true if succeeded - false otherwise.
|
||||
/// Since history isn't really that valuable, failures can be ignored.
|
||||
|
@ -66,6 +68,9 @@ public:
|
|||
/// Clears history.
|
||||
void clear();
|
||||
|
||||
/// History size.
|
||||
int size() const;
|
||||
|
||||
/// Gets the current items. The first one is the newest one on the list.
|
||||
QList< Item > const & getItems() const
|
||||
{ return items; }
|
||||
|
@ -76,6 +81,8 @@ public:
|
|||
bool enabled()
|
||||
{ return addingEnabled; }
|
||||
|
||||
void setMaxSize( unsigned maxSize_ );
|
||||
|
||||
unsigned getMaxSize()
|
||||
{ return maxSize; }
|
||||
|
||||
|
@ -86,9 +93,14 @@ signals:
|
|||
|
||||
private:
|
||||
|
||||
/// Returns true if the items list has been modified
|
||||
/// in order to fit into the constraints.
|
||||
bool ensureSizeConstraints();
|
||||
|
||||
QList< Item > items;
|
||||
unsigned maxSize;
|
||||
bool addingEnabled;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
222
historypanewidget.cc
Normal file
222
historypanewidget.cc
Normal file
|
@ -0,0 +1,222 @@
|
|||
/* This file is (c) 2013 Tvangeste <i.4m.l33t@yandex.ru>
|
||||
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
|
||||
|
||||
#include <QDebug>
|
||||
#include <QApplication>
|
||||
#include <QDockWidget>
|
||||
#include <QKeyEvent>
|
||||
|
||||
#include "historypanewidget.hh"
|
||||
|
||||
void HistoryPaneWidget::setUp( Config::Class * cfg, History * history, QMenu * menu )
|
||||
{
|
||||
m_cfg = cfg;
|
||||
m_history = history;
|
||||
m_historyList = findChild<QListView*>( "historyList" );
|
||||
QDockWidget * historyPane = qobject_cast<QDockWidget*>( parentWidget() );
|
||||
|
||||
// Delete selected items action
|
||||
m_deleteSelectedAction = new QAction( this );
|
||||
m_deleteSelectedAction->setText( tr( "&Delete Selected" ) );
|
||||
m_deleteSelectedAction->setShortcut( QKeySequence( QKeySequence::Delete ) );
|
||||
m_deleteSelectedAction->setShortcutContext( Qt::WidgetWithChildrenShortcut );
|
||||
addAction( m_deleteSelectedAction );
|
||||
connect( m_deleteSelectedAction, SIGNAL( triggered() ),
|
||||
this, SLOT( deleteSelectedItems() ) );
|
||||
|
||||
// Handle context menu, reusing some of the top-level window's History menu
|
||||
m_historyMenu = new QMenu( this );
|
||||
m_separator = m_historyMenu->addSeparator();
|
||||
QListIterator<QAction *> actionsIter( menu->actions() );
|
||||
while ( actionsIter.hasNext() )
|
||||
m_historyMenu->addAction( actionsIter.next() );
|
||||
|
||||
// Make the history pane's titlebar
|
||||
|
||||
historyLabel.setText( tr( "History:" ) );
|
||||
historyLabel.setObjectName( "historyLabel" );
|
||||
historyCountLabel.setObjectName( "historyCountLabel" );
|
||||
if ( layoutDirection() == Qt::LeftToRight )
|
||||
{
|
||||
historyLabel.setAlignment( Qt::AlignLeft );
|
||||
historyCountLabel.setAlignment( Qt::AlignRight );
|
||||
}
|
||||
else
|
||||
{
|
||||
historyLabel.setAlignment( Qt::AlignRight );
|
||||
historyCountLabel.setAlignment( Qt::AlignLeft );
|
||||
}
|
||||
updateHistoryCounts();
|
||||
|
||||
historyPaneTitleBarLayout.addWidget( &historyLabel );
|
||||
historyPaneTitleBarLayout.addWidget( &historyCountLabel );
|
||||
historyPaneTitleBarLayout.setContentsMargins(5, 5, 5, 5);
|
||||
historyPaneTitleBar.setLayout( &historyPaneTitleBarLayout );
|
||||
historyPaneTitleBar.setObjectName("historyPaneTitleBar");
|
||||
historyPane->setTitleBarWidget( &historyPaneTitleBar );
|
||||
|
||||
// History list
|
||||
HistoryModel * historyModel = new HistoryModel( m_history, this );
|
||||
m_historyList->setModel( historyModel );
|
||||
m_historyList->setContextMenuPolicy( Qt::CustomContextMenu );
|
||||
// very important call, for performance reasons:
|
||||
m_historyList->setUniformItemSizes( true );
|
||||
m_historyList->setSelectionMode( QAbstractItemView::ExtendedSelection );
|
||||
m_historyList->installEventFilter( this );
|
||||
m_historyList->viewport()->installEventFilter( this );
|
||||
|
||||
// list selection and keyboard navigation
|
||||
connect( m_historyList, SIGNAL( clicked( QModelIndex const & ) ),
|
||||
this, SLOT( onItemClicked( QModelIndex const & ) ) );
|
||||
connect( m_history, SIGNAL( itemsChanged() ),
|
||||
this, SLOT( updateHistoryCounts() ) );
|
||||
connect ( m_historyList->selectionModel(), SIGNAL( selectionChanged ( QItemSelection const & , QItemSelection const & ) ),
|
||||
this, SLOT( onSelectionChanged( QItemSelection const & ) ) );
|
||||
|
||||
connect( m_historyList, SIGNAL( customContextMenuRequested( QPoint const & ) ),
|
||||
this, SLOT( showCustomMenu( QPoint const & ) ) );
|
||||
|
||||
}
|
||||
|
||||
void HistoryPaneWidget::deleteSelectedItems()
|
||||
{
|
||||
QModelIndexList selectedIdxs = m_historyList->selectionModel()->selectedIndexes();
|
||||
|
||||
if ( selectedIdxs.isEmpty() )
|
||||
{
|
||||
// nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
QList<int> idxsToDelete;
|
||||
|
||||
QListIterator<QModelIndex> i( m_historyList->selectionModel()->selectedIndexes() );
|
||||
while ( i.hasNext() )
|
||||
{
|
||||
idxsToDelete << i.next().row();
|
||||
}
|
||||
|
||||
// Need to sort indexes in the decreasing order so that
|
||||
// the first deletions won't affect the indexes for subsequent deletions.
|
||||
qSort( idxsToDelete.begin(), idxsToDelete.end(), qGreater<int>() );
|
||||
|
||||
QListIterator<int> idxs( idxsToDelete );
|
||||
while ( idxs.hasNext() )
|
||||
m_history->removeItem( idxs.next() );
|
||||
|
||||
if (idxsToDelete.size() == 1)
|
||||
{
|
||||
// We've just removed a single entry,
|
||||
// keep the selection at the same index.
|
||||
m_historyList->selectionModel()->select(
|
||||
selectedIdxs.front(), QItemSelectionModel::Select );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Too many deletions, better to reset the selection.
|
||||
m_historyList->selectionModel()->reset();
|
||||
}
|
||||
}
|
||||
|
||||
bool HistoryPaneWidget::eventFilter( QObject * obj, QEvent * ev )
|
||||
{
|
||||
// unused for now
|
||||
|
||||
return QWidget::eventFilter( obj, ev );
|
||||
}
|
||||
|
||||
void HistoryPaneWidget::showCustomMenu(QPoint const & pos)
|
||||
{
|
||||
bool selectionEmpty = m_historyList->selectionModel()->selection().empty();
|
||||
|
||||
m_historyMenu->removeAction( m_deleteSelectedAction );
|
||||
m_separator->setVisible( !selectionEmpty );
|
||||
|
||||
if ( !selectionEmpty )
|
||||
m_historyMenu->insertAction( m_separator, m_deleteSelectedAction );
|
||||
|
||||
|
||||
m_historyMenu->exec( m_historyList->mapToGlobal( pos ) );
|
||||
}
|
||||
|
||||
void HistoryPaneWidget::emitHistoryItemRequested( QModelIndex const & idx )
|
||||
{
|
||||
QVariant value = m_historyList->model()->data( idx );
|
||||
if ( !value.isNull() )
|
||||
{
|
||||
emit historyItemRequested( value.toString() );
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryPaneWidget::onSelectionChanged( QItemSelection const & selection )
|
||||
{
|
||||
// qDebug() << "selectionChanged";
|
||||
|
||||
if ( selection.empty() )
|
||||
return;
|
||||
|
||||
itemSelectionChanged = true;
|
||||
emitHistoryItemRequested( selection.front().bottomRight() );
|
||||
}
|
||||
|
||||
void HistoryPaneWidget::onItemClicked( QModelIndex const & idx )
|
||||
{
|
||||
// qDebug() << "clicked";
|
||||
|
||||
if ( !itemSelectionChanged )
|
||||
{
|
||||
emitHistoryItemRequested( idx );
|
||||
}
|
||||
itemSelectionChanged = false;
|
||||
}
|
||||
|
||||
void HistoryPaneWidget::updateHistoryCounts()
|
||||
{
|
||||
historyCountLabel.setText( tr( "%1/%2" ).
|
||||
arg( m_history->size() ).
|
||||
arg( m_cfg->preferences.maxStringsInHistory ) );
|
||||
historyCountLabel.setToolTip(
|
||||
tr( "History size: %1 entries out of maximum %2" ).
|
||||
arg( m_history->size() ).
|
||||
arg( m_cfg->preferences.maxStringsInHistory ));
|
||||
}
|
||||
|
||||
HistoryModel::HistoryModel( History * history, QObject * parent )
|
||||
: QAbstractListModel( parent ), m_history(history)
|
||||
{
|
||||
|
||||
connect( m_history, SIGNAL( itemsChanged() ),
|
||||
this, SLOT( historyChanged() ) );
|
||||
|
||||
}
|
||||
|
||||
int HistoryModel::rowCount( QModelIndex const & /*parent*/ ) const
|
||||
{
|
||||
return m_history->size();
|
||||
}
|
||||
|
||||
QVariant HistoryModel::data( QModelIndex const & index, int role ) const
|
||||
{
|
||||
// qDebug() << "data: " << index;
|
||||
|
||||
if ( !index.isValid() || index.row() >= m_history->size() )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if ( role == Qt::DisplayRole )
|
||||
{
|
||||
return m_history->getItem( index.row() ).word;
|
||||
}
|
||||
else
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
void HistoryModel::historyChanged()
|
||||
{
|
||||
// qDebug() << "History Changed!!";
|
||||
|
||||
reset();
|
||||
}
|
83
historypanewidget.hh
Normal file
83
historypanewidget.hh
Normal file
|
@ -0,0 +1,83 @@
|
|||
/* This file is (c) 2013 Tvangeste <i.4m.l33t@yandex.ru>
|
||||
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
|
||||
|
||||
#ifndef __HISTORYPANEWIDGET_HH_INCLUDED__
|
||||
#define __HISTORYPANEWIDGET_HH_INCLUDED__
|
||||
|
||||
#include <QWidget>
|
||||
#include <QSize>
|
||||
#include <QAbstractListModel>
|
||||
#include <QListView>
|
||||
#include <QLabel>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMenu>
|
||||
|
||||
#include <config.hh>
|
||||
#include "history.hh"
|
||||
|
||||
/// A widget holding the contents of the 'History' docklet.
|
||||
class HistoryPaneWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HistoryPaneWidget( QWidget * parent = 0 ): QWidget( parent ),
|
||||
itemSelectionChanged( false )
|
||||
{}
|
||||
|
||||
virtual QSize sizeHint() const
|
||||
{ return QSize( 204, 204 ); }
|
||||
|
||||
void setUp( Config::Class * cfg, History * history, QMenu * menu );
|
||||
|
||||
signals:
|
||||
void historyItemRequested( QString const & word );
|
||||
|
||||
public slots:
|
||||
void updateHistoryCounts();
|
||||
|
||||
private slots:
|
||||
void emitHistoryItemRequested(QModelIndex const &);
|
||||
void onSelectionChanged(QItemSelection const & selection);
|
||||
void onItemClicked(QModelIndex const & idx);
|
||||
void showCustomMenu(QPoint const & pos);
|
||||
void deleteSelectedItems();
|
||||
|
||||
private:
|
||||
virtual bool eventFilter( QObject *, QEvent * );
|
||||
|
||||
Config::Class * m_cfg ;
|
||||
History * m_history;
|
||||
QListView * m_historyList;
|
||||
QMenu * m_historyMenu;
|
||||
QAction * m_deleteSelectedAction;
|
||||
QAction * m_separator;
|
||||
|
||||
QWidget historyPaneTitleBar;
|
||||
QHBoxLayout historyPaneTitleBarLayout;
|
||||
QLabel historyLabel;
|
||||
QLabel historyCountLabel;
|
||||
|
||||
/// needed to avoid multiple notifications
|
||||
/// when selecting history items via mouse and keyboard
|
||||
bool itemSelectionChanged;
|
||||
|
||||
};
|
||||
|
||||
class HistoryModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit HistoryModel( History * history , QObject * parent = 0 );
|
||||
|
||||
int rowCount( QModelIndex const & parent = QModelIndex() ) const;
|
||||
|
||||
QVariant data( QModelIndex const & index, int role = Qt::DisplayRole ) const;
|
||||
|
||||
private slots:
|
||||
void historyChanged();
|
||||
|
||||
private:
|
||||
History * m_history;
|
||||
};
|
||||
|
||||
#endif // HISTORYPANEWIDGET_HH
|
211
mainwindow.cc
211
mainwindow.cc
|
@ -23,6 +23,7 @@
|
|||
#include "dictinfo.hh"
|
||||
#include "fsencoding.hh"
|
||||
#include <QProcess>
|
||||
#include "historypanewidget.hh"
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include "lionsupport.h"
|
||||
|
@ -45,7 +46,6 @@ using std::pair;
|
|||
|
||||
MainWindow::MainWindow( Config::Class & cfg_ ):
|
||||
commitDataCompleted( false ),
|
||||
showHistory( false ),
|
||||
trayIcon( 0 ),
|
||||
groupLabel( &searchPaneTitleBar ),
|
||||
foundInDictsLabel( &dictsPaneTitleBar ),
|
||||
|
@ -299,12 +299,14 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
|
|||
ui.centralWidget->addAction( &escAction );
|
||||
ui.dictsPane->addAction( &escAction );
|
||||
ui.searchPaneWidget->addAction( &escAction );
|
||||
ui.historyPane->addAction( &escAction );
|
||||
groupList->addAction( &escAction );
|
||||
translateBox->addAction( &escAction );
|
||||
|
||||
ui.centralWidget->addAction( &focusTranslateLineAction );
|
||||
ui.dictsPane->addAction( &focusTranslateLineAction );
|
||||
ui.searchPaneWidget->addAction( &focusTranslateLineAction );
|
||||
ui.historyPane->addAction( &focusTranslateLineAction );
|
||||
groupList->addAction( &focusTranslateLineAction );
|
||||
|
||||
addTabAction.setShortcutContext( Qt::WidgetWithChildrenShortcut );
|
||||
|
@ -407,10 +409,13 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
|
|||
// Populate 'View' menu
|
||||
|
||||
ui.menuView->addAction( &toggleMenuBarAction );
|
||||
ui.menuView->addSeparator();
|
||||
ui.menuView->addAction( ui.searchPane->toggleViewAction() );
|
||||
ui.searchPane->toggleViewAction()->setShortcut( QKeySequence( "Ctrl+S" ) );
|
||||
ui.menuView->addAction( ui.dictsPane->toggleViewAction() );
|
||||
ui.dictsPane->toggleViewAction()->setShortcut( QKeySequence( "Ctrl+R" ) );
|
||||
ui.menuView->addAction( ui.historyPane->toggleViewAction() );
|
||||
ui.historyPane->toggleViewAction()->setShortcut( QKeySequence( "Ctrl+H" ) );
|
||||
ui.menuView->addSeparator();
|
||||
ui.menuView->addAction( dictionaryBar.toggleViewAction() );
|
||||
ui.menuView->addAction( navToolbar->toggleViewAction() );
|
||||
|
@ -462,8 +467,18 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
|
|||
this, SLOT( showDictionaryInfo( QString const & ) ) );
|
||||
|
||||
// History
|
||||
ui.historyPaneWidget->setUp( &cfg, &history, ui.menuHistory );
|
||||
history.enableAdd( cfg.preferences.storeHistory );
|
||||
|
||||
connect( ui.historyPaneWidget, SIGNAL( historyItemRequested( QString const & ) ),
|
||||
this, SLOT( showHistoryItem( QString const & ) ) );
|
||||
|
||||
connect( ui.historyPane, SIGNAL( visibilityChanged( bool ) ),
|
||||
this, SLOT( updateHistoryMenu() ) );
|
||||
|
||||
connect( ui.menuHistory, SIGNAL( aboutToShow() ),
|
||||
this, SLOT( updateHistoryMenu() ) );
|
||||
|
||||
// Show tray icon early so the user would be happy. It won't be functional
|
||||
// though until the program inits fully.
|
||||
|
||||
|
@ -591,6 +606,8 @@ MainWindow::MainWindow( Config::Class & cfg_ ):
|
|||
//tabWidget doesn't propagate Ctrl+Tab to the parent widget unless event filter is installed
|
||||
ui.tabWidget->installEventFilter( this );
|
||||
|
||||
ui.historyList->installEventFilter( this );
|
||||
|
||||
if ( cfg.mainWindowGeometry.size() )
|
||||
restoreGeometry( cfg.mainWindowGeometry );
|
||||
|
||||
|
@ -1609,7 +1626,6 @@ void MainWindow::editPreferences()
|
|||
Config::Preferences p = preferences.getPreferences();
|
||||
|
||||
// These parameters are not set in dialog
|
||||
p.maxStringsInHistory = cfg.preferences.maxStringsInHistory;
|
||||
p.zoomFactor = cfg.preferences.zoomFactor;
|
||||
p.wordsZoomLevel = cfg.preferences.wordsZoomLevel;
|
||||
p.hideMenubar = cfg.preferences.hideMenubar;
|
||||
|
@ -1666,6 +1682,8 @@ void MainWindow::editPreferences()
|
|||
prepareNewReleaseChecks();
|
||||
|
||||
history.enableAdd( cfg.preferences.storeHistory );
|
||||
history.setMaxSize( cfg.preferences.maxStringsInHistory );
|
||||
ui.historyPaneWidget->updateHistoryCounts();
|
||||
|
||||
Config::save( cfg );
|
||||
}
|
||||
|
@ -1699,12 +1717,8 @@ void MainWindow::currentGroupChanged( QString const & )
|
|||
updateDictionaryBar();
|
||||
|
||||
// Update word search results
|
||||
|
||||
if( !showHistory )
|
||||
{
|
||||
translateInputChanged( translateLine->text() );
|
||||
translateInputFinished( false );
|
||||
}
|
||||
translateInputChanged( translateLine->text() );
|
||||
translateInputFinished( false );
|
||||
|
||||
updateCurrentGroupProperty();
|
||||
}
|
||||
|
@ -1829,6 +1843,11 @@ void MainWindow::focusTranslateLine()
|
|||
if ( ui.searchPane->isFloating() )
|
||||
ui.searchPane->activateWindow();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !isActiveWindow() )
|
||||
activateWindow();
|
||||
}
|
||||
|
||||
translateLine->setFocus();
|
||||
translateLine->selectAll();
|
||||
|
@ -1926,8 +1945,7 @@ void MainWindow::updateMatchResults( bool finished )
|
|||
void MainWindow::applyMutedDictionariesState()
|
||||
{
|
||||
// Redo the current search request
|
||||
if( !showHistory )
|
||||
translateInputChanged( translateLine->text() );
|
||||
translateInputChanged( translateLine->text() );
|
||||
|
||||
ArticleView *view = getCurrentArticleView();
|
||||
|
||||
|
@ -1955,6 +1973,17 @@ bool MainWindow::handleBackForwardMouseButtons ( QMouseEvent * event) {
|
|||
bool MainWindow::eventFilter( QObject * obj, QEvent * ev )
|
||||
{
|
||||
|
||||
// Handle Ctrl+H to show the History Pane.
|
||||
if ( ev->type() == QEvent::ShortcutOverride) {
|
||||
QKeyEvent * ke = static_cast<QKeyEvent*>( ev );
|
||||
if ( ke->key() == Qt::Key_H && ke->modifiers() == Qt::ControlModifier )
|
||||
{
|
||||
on_showHideHistory_triggered();
|
||||
ev->accept();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// when the main window is moved or resized, hide the word list suggestions
|
||||
if ( obj == this && ( ev->type() == QEvent::Move || ev->type() == QEvent::Resize ) )
|
||||
{
|
||||
|
@ -2052,24 +2081,6 @@ bool MainWindow::eventFilter( QObject * obj, QEvent * ev )
|
|||
return cfg.preferences.searchInDock;
|
||||
}
|
||||
|
||||
if( showHistory && keyEvent->matches( QKeySequence::Delete ) && ui.wordList->count() )
|
||||
{
|
||||
// Delete word from history
|
||||
|
||||
QList<QListWidgetItem *> selectedItems = ui.wordList->selectedItems();
|
||||
|
||||
if( selectedItems.size() )
|
||||
{
|
||||
int index = ui.wordList->row( selectedItems.at( 0 ) );
|
||||
history.removeItem( index );
|
||||
QListWidgetItem *item = ui.wordList->takeItem( index );
|
||||
if( item )
|
||||
delete item;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Handle typing events used to initiate new lookups
|
||||
// TODO: refactor to eliminate duplication (see below)
|
||||
|
||||
|
@ -2232,6 +2243,20 @@ void MainWindow::mutedDictionariesChanged()
|
|||
applyMutedDictionariesState();
|
||||
}
|
||||
|
||||
void MainWindow::showHistoryItem( QString const & word )
|
||||
{
|
||||
// qDebug() << "Showing history item" << word;
|
||||
|
||||
translateBox->setPopupEnabled( false );
|
||||
history.enableAdd( false );
|
||||
|
||||
translateLine->setText( word );
|
||||
showTranslationFor( word );
|
||||
|
||||
translateBox->setPopupEnabled( true );
|
||||
history.enableAdd( cfg.preferences.storeHistory );
|
||||
}
|
||||
|
||||
void MainWindow::showTranslationFor( QString const & inWord,
|
||||
unsigned inGroup )
|
||||
{
|
||||
|
@ -2711,9 +2736,6 @@ void MainWindow::on_clearHistory_triggered()
|
|||
{
|
||||
history.clear();
|
||||
history.save();
|
||||
|
||||
if( showHistory )
|
||||
ui.wordList->clear();
|
||||
}
|
||||
|
||||
void MainWindow::on_newTab_triggered()
|
||||
|
@ -3000,82 +3022,27 @@ ArticleView * MainWindow::getCurrentArticleView()
|
|||
|
||||
void MainWindow::wordReceived( const QString & word)
|
||||
{
|
||||
if( showHistory && cfg.preferences.searchInDock )
|
||||
return;
|
||||
|
||||
toggleMainWindow( true );
|
||||
translateLine->setText( word );
|
||||
translateInputFinished();
|
||||
}
|
||||
|
||||
void MainWindow::updateHistoryMenu()
|
||||
{
|
||||
if ( ui.historyPane->toggleViewAction()->isChecked() )
|
||||
{
|
||||
ui.showHideHistory->setText( tr( "&Hide" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
ui.showHideHistory->setText( tr( "&Show" ) );
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_showHideHistory_triggered()
|
||||
{
|
||||
static bool needHideSearchPane;
|
||||
if( showHistory )
|
||||
{
|
||||
if( needHideSearchPane )
|
||||
{
|
||||
ui.searchPane->hide();
|
||||
needHideSearchPane = false;
|
||||
ui.searchPane->toggleViewAction()->setChecked( false );
|
||||
}
|
||||
ui.searchPane->toggleViewAction()->setEnabled( true );
|
||||
|
||||
ui.showHideHistory->setText( tr( "&Show" ) );
|
||||
showHistory = false;
|
||||
|
||||
disconnect( &focusTranslateLineAction, SIGNAL( triggered() ),
|
||||
this, SLOT( focusWordList() ) );
|
||||
|
||||
connect( &focusTranslateLineAction, SIGNAL( triggered() ),
|
||||
this, SLOT( focusTranslateLine() ) );
|
||||
|
||||
connect( ui.translateLine, SIGNAL( textChanged( QString const & ) ),
|
||||
this, SLOT( translateInputChanged( QString const & ) ) );
|
||||
|
||||
ui.translateLine->clear();
|
||||
ui.translateLine->setEnabled( true );
|
||||
ui.translateLine->setProperty( "noResults", false );
|
||||
focusTranslateLine();
|
||||
setStyleSheet( styleSheet() );
|
||||
|
||||
ui.wordList->clear();
|
||||
|
||||
history.enableAdd( cfg.preferences.storeHistory );
|
||||
}
|
||||
else
|
||||
{
|
||||
history.enableAdd( false );
|
||||
|
||||
disconnect( ui.translateLine, SIGNAL( textChanged( QString const & ) ),
|
||||
this, SLOT( translateInputChanged( QString const & ) ) );
|
||||
|
||||
disconnect( &focusTranslateLineAction, SIGNAL( triggered() ),
|
||||
this, SLOT( focusTranslateLine() ) );
|
||||
|
||||
connect( &focusTranslateLineAction, SIGNAL( triggered() ),
|
||||
this, SLOT( focusWordList() ) );
|
||||
|
||||
if( !ui.searchPane->isVisible() )
|
||||
{
|
||||
ui.searchPane->show();
|
||||
ui.searchPane->toggleViewAction()->setChecked( true );
|
||||
needHideSearchPane = true;
|
||||
}
|
||||
ui.searchPane->toggleViewAction()->setEnabled( false );
|
||||
|
||||
ui.showHideHistory->setText( tr( "&Hide" ) );
|
||||
showHistory = true;
|
||||
|
||||
ui.translateLine->setEnabled( false );
|
||||
ui.translateLine->setText( tr( "History view mode" ) );
|
||||
ui.translateLine->setProperty( "noResults", true );
|
||||
setStyleSheet( styleSheet() );
|
||||
|
||||
fillWordListFromHistory();
|
||||
focusWordList();
|
||||
|
||||
}
|
||||
ui.historyPane->toggleViewAction()->trigger();
|
||||
ui.historyPane->raise(); // useful when the Pane is tabbed.
|
||||
}
|
||||
|
||||
void MainWindow::on_exportHistory_triggered()
|
||||
|
@ -3139,6 +3106,7 @@ void MainWindow::on_exportHistory_triggered()
|
|||
mainStatusBar->showMessage( errStr, 10000, QPixmap( ":/icons/error.png" ) );
|
||||
}
|
||||
|
||||
// TODO: consider moving parts of this method into History class.
|
||||
void MainWindow::on_importHistory_triggered()
|
||||
{
|
||||
QString importPath;
|
||||
|
@ -3189,16 +3157,11 @@ void MainWindow::on_importHistory_triggered()
|
|||
} while( !fileStream.atEnd() && itemList.size() < (int)history.getMaxSize() );
|
||||
|
||||
history.enableAdd( true );
|
||||
|
||||
for( QList< QString >::const_iterator i = itemList.constBegin(); i != itemList.constEnd(); ++i )
|
||||
history.addItem( History::Item( 1, *i ) );
|
||||
if( showHistory )
|
||||
{
|
||||
history.enableAdd( false );
|
||||
fillWordListFromHistory();
|
||||
ui.translateLine->setText( tr( "Imported from file: " ) + fileInfo.fileName() );
|
||||
}
|
||||
else
|
||||
history.enableAdd( cfg.preferences.storeHistory );
|
||||
|
||||
history.enableAdd( cfg.preferences.storeHistory );
|
||||
|
||||
if( file.error() != QFile::NoError )
|
||||
break;
|
||||
|
@ -3245,43 +3208,13 @@ void MainWindow::focusWordList()
|
|||
|
||||
void MainWindow::addWordToHistory( const QString & word )
|
||||
{
|
||||
if( !showHistory )
|
||||
{
|
||||
history.addItem( History::Item( 1, word.trimmed() ) );
|
||||
}
|
||||
history.addItem( History::Item( 1, word.trimmed() ) );
|
||||
}
|
||||
|
||||
void MainWindow::forceAddWordToHistory( const QString & word )
|
||||
{
|
||||
history.enableAdd( true );
|
||||
history.addItem( History::Item( 1, word.trimmed() ) );
|
||||
|
||||
if( showHistory )
|
||||
{
|
||||
int index = ui.wordList->currentRow();
|
||||
QListWidgetItem *item = ui.wordList->item( index );
|
||||
QString currentWord;
|
||||
if( item )
|
||||
currentWord = item->text();
|
||||
if( index < (int) history.getMaxSize() - 1 )
|
||||
index += 1;
|
||||
|
||||
fillWordListFromHistory();
|
||||
|
||||
if( index < 0 || index >= ui.wordList->count() )
|
||||
index = 0;
|
||||
if( index && currentWord.compare( ui.wordList->item( index )->text() ) != 0 )
|
||||
index = currentWord.compare( ui.wordList->item( index - 1 )->text() ) == 0 ? index - 1 : 0;
|
||||
|
||||
if( index )
|
||||
disconnect( ui.wordList, SIGNAL( itemSelectionChanged() ),
|
||||
this, SLOT( wordListSelectionChanged() ) );
|
||||
ui.wordList->setCurrentRow( index, QItemSelectionModel::Select );
|
||||
if( index )
|
||||
connect( ui.wordList, SIGNAL( itemSelectionChanged() ),
|
||||
this, SLOT( wordListSelectionChanged() ) );
|
||||
}
|
||||
|
||||
history.enableAdd( cfg.preferences.storeHistory );
|
||||
}
|
||||
|
||||
|
|
|
@ -76,8 +76,6 @@ private:
|
|||
void commitData();
|
||||
bool commitDataCompleted;
|
||||
|
||||
bool showHistory;
|
||||
|
||||
QSystemTrayIcon * trayIcon;
|
||||
|
||||
Ui::MainWindow ui;
|
||||
|
@ -339,6 +337,8 @@ private slots:
|
|||
|
||||
void showTranslationFor( QString const &, unsigned inGroup = 0 );
|
||||
|
||||
void showHistoryItem( QString const & );
|
||||
|
||||
void trayIconActivated( QSystemTrayIcon::ActivationReason );
|
||||
|
||||
void scanEnableToggled( bool );
|
||||
|
@ -379,6 +379,8 @@ private slots:
|
|||
|
||||
void updateSearchPaneAndBar( bool searchInDock );
|
||||
|
||||
void updateHistoryMenu();
|
||||
|
||||
/// Add word to history
|
||||
void addWordToHistory( const QString & word );
|
||||
/// Add word to history even if history is disabled in options
|
||||
|
|
|
@ -280,6 +280,36 @@
|
|||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QDockWidget" name="historyPane">
|
||||
<property name="windowTitle">
|
||||
<string>&History Pane</string>
|
||||
</property>
|
||||
<attribute name="dockWidgetArea">
|
||||
<number>2</number>
|
||||
</attribute>
|
||||
<widget class="HistoryPaneWidget" name="historyPaneWidget">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QListView" name="historyList"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<action name="dictionaries">
|
||||
<property name="icon">
|
||||
<iconset resource="resources.qrc">
|
||||
|
@ -478,6 +508,12 @@
|
|||
<header>maintabwidget.hh</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>HistoryPaneWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>historypanewidget.hh</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>translateLine</tabstop>
|
||||
|
|
|
@ -128,6 +128,7 @@ Preferences::Preferences( QWidget * parent, Config::Preferences const & p ):
|
|||
ui.scanPopupUseGDMessage->setChecked( p.scanPopupUseGDMessage );
|
||||
|
||||
ui.storeHistory->setChecked( p.storeHistory );
|
||||
ui.historyMaxSizeField->setValue( p.maxStringsInHistory );
|
||||
ui.alwaysExpandOptionalParts->setChecked( p.alwaysExpandOptionalParts );
|
||||
|
||||
// Different platforms have different keys available
|
||||
|
@ -256,6 +257,7 @@ Config::Preferences Preferences::getPreferences()
|
|||
p.scanPopupUseGDMessage = ui.scanPopupUseGDMessage->isChecked();
|
||||
|
||||
p.storeHistory = ui.storeHistory->isChecked();
|
||||
p.maxStringsInHistory = ui.historyMaxSizeField->text().toUInt();
|
||||
p.alwaysExpandOptionalParts = ui.alwaysExpandOptionalParts->isChecked();
|
||||
|
||||
p.pronounceOnLoadMain = ui.pronounceOnLoadMain->isChecked();
|
||||
|
|
|
@ -1119,7 +1119,7 @@ It is not needed to select this option if you don't use such programs.</string>
|
|||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_5">
|
||||
<widget class="QGroupBox" name="historyBox">
|
||||
<property name="title">
|
||||
<string>History</string>
|
||||
</property>
|
||||
|
@ -1132,8 +1132,54 @@ It is not needed to select this option if you don't use such programs.</string>
|
|||
<property name="text">
|
||||
<string>Store &history</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="historySizeLabel">
|
||||
<property name="toolTip">
|
||||
<string>Specify the maximum number of entries to keep in history.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Maximum history size:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="historyMaxSizeField">
|
||||
<property name="accelerated">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>9999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>500</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
MainWindow #searchPane #translateLine, MainWindow #searchPane #wordList, MainWindow #dictsPane #dictsList
|
||||
MainWindow #translateLine, MainWindow #searchPane #wordList, MainWindow #dictsPane #dictsList,
|
||||
MainWindow #historyPane #historyList
|
||||
{
|
||||
background: white;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
MainWindow #translateLine, MainWindow #wordList, MainWindow #dictsPane #dictsList
|
||||
MainWindow #translateLine, MainWindow #wordList, MainWindow #dictsPane #dictsList,
|
||||
MainWindow #historyPane #historyList
|
||||
{
|
||||
background: white;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
MainWindow #translateLine, MainWindow #wordList, MainWindow #dictsPane #dictsList
|
||||
MainWindow #translateLine, MainWindow #wordList, MainWindow #dictsPane #dictsList, MainWindow #historyPane #historyList
|
||||
{
|
||||
background: #fefdeb;
|
||||
color: black;
|
||||
|
|
|
@ -53,7 +53,7 @@ bool CompletionList::acceptCurrentEntry()
|
|||
}
|
||||
|
||||
TranslateBox::TranslateBox(QWidget *parent) : QWidget(parent),
|
||||
word_list(new CompletionList(this))
|
||||
word_list(new CompletionList(this)), m_popupEnabled(true)
|
||||
{
|
||||
// initially hidden
|
||||
word_list->hide();
|
||||
|
@ -185,6 +185,11 @@ bool TranslateBox::eventFilter(QObject *obj, QEvent *event)
|
|||
return QWidget::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
void TranslateBox::setPopupEnabled( bool enable )
|
||||
{
|
||||
m_popupEnabled = enable;
|
||||
}
|
||||
|
||||
void TranslateBox::showPopup()
|
||||
{
|
||||
// completer->setCompletionPrefix( m_fileLineEdit->text() );
|
||||
|
@ -202,6 +207,11 @@ void TranslateBox::showPopup()
|
|||
return;
|
||||
}
|
||||
|
||||
if ( !m_popupEnabled )
|
||||
{
|
||||
word_list->hide();
|
||||
return;
|
||||
}
|
||||
|
||||
const QSize size(width(), word_list->preferredHeight());
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ public:
|
|||
signals:
|
||||
|
||||
public slots:
|
||||
void setPopupEnabled(bool enable);
|
||||
|
||||
private slots:
|
||||
void showPopup();
|
||||
|
@ -51,6 +52,7 @@ private:
|
|||
bool eventFilter(QObject *obj, QEvent *event);
|
||||
CompletionList * word_list;
|
||||
ExtLineEdit * translate_line;
|
||||
bool m_popupEnabled;
|
||||
// QCompleter * completer; // disabled for now
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue