mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-12-19 03:54:07 +00:00
b5349478cf
The next commit will add `.git-blame-ignore-revs` https://docs.github.com/en/repositories/working-with-files/using-files/viewing-a-file#ignore-commits-in-the-blame-view
247 lines
7.9 KiB
C++
247 lines
7.9 KiB
C++
/* This file is (c) 2013 Tvangeste <i.4m.l33t@yandex.ru>
|
|
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
|
|
|
|
#include <QApplication>
|
|
#include <QDockWidget>
|
|
#include <QKeyEvent>
|
|
#include <QClipboard>
|
|
#include <algorithm>
|
|
#include <functional>
|
|
|
|
#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, &QAction::triggered, this, &HistoryPaneWidget::deleteSelectedItems );
|
|
|
|
// Copy selected items to clipboard
|
|
m_copySelectedToClipboard = new QAction( this );
|
|
m_copySelectedToClipboard->setText( tr( "Copy Selected" ) );
|
|
m_copySelectedToClipboard->setShortcut( QKeySequence( QKeySequence::Copy ) );
|
|
m_copySelectedToClipboard->setShortcutContext( Qt::WidgetWithChildrenShortcut );
|
|
addAction( m_copySelectedToClipboard );
|
|
connect( m_copySelectedToClipboard, &QAction::triggered, this, &HistoryPaneWidget::copySelectedItems );
|
|
|
|
|
|
// 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, &QAbstractItemView::clicked, this, &HistoryPaneWidget::onItemClicked );
|
|
connect( m_history, &History::itemsChanged, this, &HistoryPaneWidget::updateHistoryCounts );
|
|
connect( m_historyList->selectionModel(),
|
|
&QItemSelectionModel::selectionChanged,
|
|
this,
|
|
&HistoryPaneWidget::onSelectionChanged );
|
|
|
|
connect( m_historyList, &QWidget::customContextMenuRequested, this, &HistoryPaneWidget::showCustomMenu );
|
|
|
|
listItemDelegate = new WordListItemDelegate( m_historyList->itemDelegate() );
|
|
m_historyList->setItemDelegate( listItemDelegate );
|
|
}
|
|
|
|
HistoryPaneWidget::~HistoryPaneWidget()
|
|
{
|
|
if ( listItemDelegate )
|
|
delete listItemDelegate;
|
|
}
|
|
|
|
void HistoryPaneWidget::copySelectedItems()
|
|
{
|
|
QModelIndexList selectedIdxs = m_historyList->selectionModel()->selectedIndexes();
|
|
|
|
if ( selectedIdxs.isEmpty() ) {
|
|
// nothing to do
|
|
return;
|
|
}
|
|
|
|
QStringList selectedStrings;
|
|
QListIterator< QModelIndex > i( selectedIdxs );
|
|
while ( i.hasNext() ) {
|
|
selectedStrings << m_historyList->model()->data( i.next() ).toString();
|
|
}
|
|
|
|
QApplication::clipboard()->setText( selectedStrings.join( QString::fromLatin1( "\n" ) ) );
|
|
}
|
|
|
|
void HistoryPaneWidget::deleteSelectedItems()
|
|
{
|
|
QModelIndexList selectedIdxs = m_historyList->selectionModel()->selectedIndexes();
|
|
|
|
if ( selectedIdxs.isEmpty() ) {
|
|
// nothing to do
|
|
return;
|
|
}
|
|
|
|
QList< int > idxsToDelete;
|
|
|
|
QListIterator< QModelIndex > i( selectedIdxs );
|
|
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.
|
|
std::sort( idxsToDelete.begin(), idxsToDelete.end(), std::greater< 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->setCurrentIndex( selectedIdxs.front() );
|
|
m_historyList->selectionModel()->select( selectedIdxs.front(), QItemSelectionModel::SelectCurrent );
|
|
}
|
|
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_copySelectedToClipboard );
|
|
m_historyMenu->removeAction( m_deleteSelectedAction );
|
|
|
|
m_separator->setVisible( !selectionEmpty );
|
|
|
|
if ( !selectionEmpty ) {
|
|
m_historyMenu->insertAction( m_separator, m_copySelectedToClipboard );
|
|
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( const QItemSelection & selection, const QItemSelection & deselected )
|
|
{
|
|
Q_UNUSED( deselected );
|
|
|
|
if ( selection.empty() )
|
|
return;
|
|
|
|
itemSelectionChanged = true;
|
|
emitHistoryItemRequested( selection.front().topLeft() );
|
|
}
|
|
|
|
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, &History::itemsChanged, this, &HistoryModel::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 || role == Qt::ToolTipRole ) {
|
|
return m_history->getItem( index.row() ).word;
|
|
}
|
|
else {
|
|
return QVariant();
|
|
}
|
|
}
|
|
|
|
void HistoryModel::historyChanged()
|
|
{
|
|
// qDebug() << "History Changed!!";
|
|
|
|
beginResetModel();
|
|
endResetModel();
|
|
}
|