#include "FindPanel.h" #include #include #include #include #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( 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 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 aStartingPoint ) { DictTableView* tableView = const_cast( 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 . 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; }