summaryrefslogtreecommitdiff
path: root/src/main-view/FindPanel.cpp
diff options
context:
space:
mode:
authorJedidiah Barber <contact@jedbarber.id.au>2021-07-14 11:49:10 +1200
committerJedidiah Barber <contact@jedbarber.id.au>2021-07-14 11:49:10 +1200
commitd24f813f3f2a05c112e803e4256b53535895fc98 (patch)
tree601e6ae9a1cd44bcfdcf91739a5ca36aedd827c9 /src/main-view/FindPanel.cpp
Initial mirror commitHEADmaster
Diffstat (limited to 'src/main-view/FindPanel.cpp')
-rw-r--r--src/main-view/FindPanel.cpp258
1 files changed, 258 insertions, 0 deletions
diff --git a/src/main-view/FindPanel.cpp b/src/main-view/FindPanel.cpp
new file mode 100644
index 0000000..755fa50
--- /dev/null
+++ b/src/main-view/FindPanel.cpp
@@ -0,0 +1,258 @@
+#include "FindPanel.h"
+
+#include <QHBoxLayout>
+#include <QAction>
+#include <QLineEdit>
+#include <QKeyEvent>
+
+#include "DictTableView.h"
+#include "MainWindow.h"
+
+FindPanel::FindPanel( MainWindow* aMainWindow ):
+ QWidget( aMainWindow ),
+ m_mainWindow( aMainWindow ), m_direction( 1 ), m_foundOnce(false)
+ {
+ m_closeButton = new QToolButton;
+ m_closeButton->setAutoRaise(true);
+ m_closeButton->setIcon(QIcon(":/images/gray-cross.png"));
+ m_closeButton->setToolTip(tr("Close"));
+
+ QLabel* textLabel = new QLabel(tr("Find:", "Title of the find pane"));
+
+ m_textEdit = new QComboBox;
+ textLabel->setBuddy(m_textEdit);
+ m_textEdit->setEditable(true);
+ m_textEdit->setInsertPolicy( QComboBox::NoInsert );
+ m_textEdit->setMaxCount( ComboBoxMaxItems );
+ m_textEdit->setMinimumWidth( TextEditMinWidth );
+ m_textEdit->setFocus();
+
+ m_findBackwardBtn = new QToolButton;
+ m_findBackwardBtn->resize(32, 32);
+ m_findBackwardBtn->setObjectName("backward");
+ m_findBackwardBtn->setIcon(QIcon(":/images/1leftarrow.png"));
+ m_findBackwardBtn->setToolTip(tr("Find previous"));
+ m_findBackwardBtn->setEnabled(false);
+
+ m_findForwardBtn = new QToolButton;
+ m_findForwardBtn->setObjectName("forward");
+ m_findForwardBtn->setIcon(QIcon(":/images/1rightarrow.png"));
+ m_findForwardBtn->setToolTip(tr("Find next"));
+ m_findForwardBtn->setEnabled(false);
+
+ m_caseSensitiveBtn = new QToolButton;
+ m_caseSensitiveBtn->setAutoRaise(true);
+ m_caseSensitiveBtn->setCheckable( true );
+ m_caseSensitiveBtn->setIcon(QIcon(":/images/Aa.png"));
+ m_caseSensitiveBtn->setToolTip(tr("Case sensitive"));
+
+ m_wholeWordsBtn = new QToolButton;
+ m_wholeWordsBtn->setAutoRaise(true);
+ m_wholeWordsBtn->setCheckable( true );
+ m_wholeWordsBtn->setIcon(QIcon(":/images/whole-words.png"));
+ m_wholeWordsBtn->setToolTip(tr("Whole words"));
+
+ m_regExpBtn = new QToolButton;
+ m_regExpBtn->setAutoRaise(true);
+ m_regExpBtn->setCheckable( true );
+ m_regExpBtn->setIcon(QIcon(":/images/RX.png"));
+ m_regExpBtn->setToolTip(tr("Regular expression"));
+
+ m_inSelectionBtn = new QToolButton;
+ m_inSelectionBtn->setAutoRaise(true);
+ m_inSelectionBtn->setCheckable( true );
+ m_inSelectionBtn->setIcon(QIcon(":/images/selection.png"));
+ m_inSelectionBtn->setToolTip(tr("In selection"));
+
+ QLabel* infoIconLbl = new QLabel;
+ infoIconLbl->setPixmap( QPixmap(":/images/warning.png").scaled(
+ 16, 16, Qt::KeepAspectRatio, Qt::SmoothTransformation ) );
+ m_infoLbl = new QLabel(tr("String is not found"));
+ QHBoxLayout* infoLt = new QHBoxLayout;
+ infoLt->setContentsMargins( QMargins() );
+ infoLt->addWidget( infoIconLbl );
+ infoLt->addWidget( m_infoLbl );
+ m_infoPane = new QWidget;
+ m_infoPane->setLayout( infoLt );
+ m_infoPane->hide();
+
+ QHBoxLayout* mainLayout = new QHBoxLayout;
+ mainLayout->addWidget( m_closeButton );
+ mainLayout->addWidget( textLabel );
+ mainLayout->addWidget( m_textEdit );
+ mainLayout->addWidget( m_findBackwardBtn );
+ mainLayout->addWidget( m_findForwardBtn );
+ mainLayout->addWidget( m_caseSensitiveBtn );
+ mainLayout->addWidget( m_wholeWordsBtn );
+ mainLayout->addWidget( m_regExpBtn );
+ mainLayout->addWidget( m_inSelectionBtn );
+ mainLayout->addSpacing( 50 );
+ mainLayout->addWidget( m_infoPane );
+ mainLayout->addStretch();
+ mainLayout->setContentsMargins( QMargins() );
+ setLayout( mainLayout );
+
+ connect( m_inSelectionBtn, SIGNAL(toggled(bool)), SLOT(updateFindButtons()) );
+ connect( m_textEdit, SIGNAL(editTextChanged(const QString&)), SLOT(updateFindButtons()) );
+ connect( m_textEdit, SIGNAL(editTextChanged(const QString&)), m_infoPane, SLOT(hide()) );
+ connect( m_findForwardBtn, SIGNAL(clicked()), this, SLOT(find()) );
+ connect( m_findBackwardBtn, SIGNAL(clicked()), this, SLOT(find()) );
+ connect( m_closeButton, SIGNAL(clicked()), this, SLOT(hide()) );
+ }
+
+void FindPanel::show()
+ {
+ m_textEdit->setFocus();
+ m_textEdit->lineEdit()->selectAll();
+ QWidget::show();
+ }
+
+void FindPanel::keyPressEvent( QKeyEvent* event )
+ {
+ if( event->key() == Qt::Key_Return )
+ find();
+ else
+ QWidget::keyPressEvent( event );
+ }
+
+/**
+ @arg aDirection 1 = forward; -1 = backward; 0 = previous direction
+ */
+void FindPanel::find()
+ {
+ // Check controls
+ QString searchText = m_textEdit->currentText();
+ if( searchText.isEmpty() )
+ return;
+
+ DictTableView* tableView = const_cast<DictTableView*>( m_mainWindow->getCurDictView() );
+ QModelIndexList rows = tableView->selectionModel()->selectedRows();
+ if( rows.size() <= 1 && m_inSelectionBtn->isChecked() )
+ m_inSelectionBtn->setChecked( false );
+
+ // Process search parameters
+ bool inSelection = m_inSelectionBtn->isChecked();
+ bool fromCursor = true;
+ if( inSelection || (rows.size() == 1 && rows.first().row() == 0 ) )
+ fromCursor = false;
+
+ // Process direction
+ if( sender() )
+ {
+ if( sender()->objectName() == "forward" )
+ m_direction = 1;
+ else if( sender()->objectName() == "backward" )
+ m_direction = -1;
+ }
+ // For "find again" case, the direction stays the same
+
+ // Save the entered text to combobox
+ int textIndex = m_textEdit->findText( searchText );
+ if( textIndex != 0 ) // Don't re-add the same text at the first line
+ {
+ if( textIndex > -1 ) // Remove duplicates
+ m_textEdit->removeItem( textIndex );
+ m_textEdit->insertItem( 0, searchText );
+ }
+
+ // Create the search regular expression
+ QString searchRegExpStr;
+ if( !m_regExpBtn->isChecked() )
+ searchRegExpStr = QRegExp::escape( searchText );
+ else
+ searchRegExpStr = searchText;
+ if( m_wholeWordsBtn->isChecked() )
+ searchRegExpStr = "\\b" + searchText + "\\b";
+
+ QRegExp searchRegExp = QRegExp( searchRegExpStr,
+ m_caseSensitiveBtn->isChecked()? Qt::CaseSensitive : Qt::CaseInsensitive);
+
+ // Get sorted search range
+ QModelIndexList searchRange;
+ if( inSelection )
+ {
+ searchRange = tableView->selectionModel()->selectedIndexes();
+ qSort( searchRange );
+ }
+ else // all indexes
+ {
+ QAbstractItemModel* tableModel = tableView->model();
+ for(int r=0; r < tableModel->rowCount(); r++)
+ for(int c=0; c < tableModel->columnCount(); c++)
+ searchRange << tableModel->index(r, c);
+ }
+
+ // Get the starting search point (iterator)
+ QListIterator<QModelIndex> startingPoint( searchRange );
+ if( fromCursor )
+ {
+ bool ok = startingPoint.findNext( tableView->currentIndex() );
+ if( !ok )
+ startingPoint.toFront();
+ if( ok && m_direction < 0 )
+ startingPoint.previous(); // Go one item backwards
+ }
+ else
+ if( m_direction < 0 )
+ startingPoint.toBack();
+
+ // Try to find the regexp
+ bool found = findRegExp( searchRegExp, startingPoint );
+ if ( !found && fromCursor )
+ {
+ // Continue searching
+ m_mainWindow->showContinueSearch();
+ if( m_direction > 0 )
+ startingPoint.toFront();
+ else
+ startingPoint.toBack();
+ if( findRegExp( searchRegExp, startingPoint ) )
+ found = true;
+ }
+ if( !found )
+ m_infoPane->show();
+ }
+
+bool FindPanel::findRegExp( const QRegExp& aSearchRegExp, QListIterator<QModelIndex> aStartingPoint )
+ {
+ DictTableView* tableView = const_cast<DictTableView*>( m_mainWindow->getCurDictView() );
+ QModelIndex foundIndex;
+ while( (m_direction > 0)? aStartingPoint.hasNext() : aStartingPoint.hasPrevious() )
+ {
+ QModelIndex index = (m_direction > 0)? aStartingPoint.next() : aStartingPoint.previous();
+ QString valueStr = index.data( Qt::EditRole ).toString(); // Search in display, not edit, strings. Matters for <img>.
+ if( valueStr.contains( aSearchRegExp ) )
+ {
+ foundIndex = index;
+ break;
+ }
+ }
+ if( foundIndex.isValid() )
+ {
+ tableView->setFocus();
+ tableView->setCurrentIndex( foundIndex );
+ return true;
+ }
+ else
+ return false;
+ }
+
+void FindPanel::updateFindButtons()
+ {
+ m_findForwardBtn->setEnabled( !m_textEdit->currentText().isEmpty() );
+ m_findBackwardBtn->setEnabled( !m_textEdit->currentText().isEmpty() && !m_inSelectionBtn->isChecked() );
+ }
+
+bool FindPanel::canFindAgain()
+ {
+ if( !m_foundOnce )
+ return false;
+ const DictTableView* tableView = m_mainWindow->getCurDictView();
+ if( tableView && !m_textEdit->currentText().isEmpty() )
+ return true;
+ else
+ return false;
+ }
+
+
+