diff --git a/src/models/sourcecodemodel.cpp b/src/models/sourcecodemodel.cpp index 2570521f..69b6b4ab 100644 --- a/src/models/sourcecodemodel.cpp +++ b/src/models/sourcecodemodel.cpp @@ -230,3 +230,41 @@ void SourceCodeModel::setSysroot(const QString& sysroot) { m_sysroot = sysroot; } + +void SourceCodeModel::findForward(const QString& search, const QModelIndex& start) +{ + for (int i = 1; i < m_numLines; i++) { + // start searching at start and wrap around when you reach the end + int lineIndex = i + (start.isValid() ? start.row() : 0); + lineIndex %= m_numLines; + + const auto block = m_document->findBlockByLineNumber(lineIndex + m_startLine); + if (!block.isValid()) + continue; + + if (block.text().contains(search)) { + emit searchResultFound(index(lineIndex, SourceCodeColumn)); + return; + } + } + emit noSearchResult(); +} + +void SourceCodeModel::findBackwards(const QString& search, const QModelIndex& start) +{ + for (int i = m_numLines - 1; i > 0; i--) { + // same as above but we move in the other direction + int lineIndex = i + (start.isValid() ? start.row() : 0); + lineIndex %= m_numLines; + + const auto block = m_document->findBlockByLineNumber(lineIndex + m_startLine); + if (!block.isValid()) + continue; + + if (block.text().contains(search)) { + emit searchResultFound(index(lineIndex, SourceCodeColumn)); + return; + } + } + emit noSearchResult(); +} diff --git a/src/models/sourcecodemodel.h b/src/models/sourcecodemodel.h index 4d86e998..5b58cc8b 100644 --- a/src/models/sourcecodemodel.h +++ b/src/models/sourcecodemodel.h @@ -66,10 +66,17 @@ class SourceCodeModel : public QAbstractTableModel FileLineRole, }; +signals: + void searchResultFound(const QModelIndex& index); + void noSearchResult(); + public slots: void updateHighlighting(int line); void setSysroot(const QString& sysroot); + void findForward(const QString& search, const QModelIndex& start); + void findBackwards(const QString& search, const QModelIndex& start); + private: QString m_sysroot; QSet m_validLineNumbers; diff --git a/src/resultsdisassemblypage.cpp b/src/resultsdisassemblypage.cpp index 727750f3..545d7e33 100644 --- a/src/resultsdisassemblypage.cpp +++ b/src/resultsdisassemblypage.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -168,6 +169,37 @@ ResultsDisassemblyPage::ResultsDisassemblyPage(CostContextMenu* costContextMenu, showDisassembly(); }); + auto searchShortcut = new QShortcut(QKeySequence::Find, this); + connect(searchShortcut, &QShortcut::activated, this, [this] { + ui->searchWidget->setVisible(true); + ui->searchEdit->setFocus(); + }); + + connect(ui->closeSearch, &QPushButton::pressed, this, [this] { ui->searchWidget->setVisible(false); }); + + connect(ui->nextSearchResult, &QPushButton::pressed, this, + [this] { m_sourceCodeModel->findForward(ui->searchEdit->text(), m_searchResultIndex); }); + + connect(ui->prevSearchResult, &QPushButton::pressed, this, + [this] { m_sourceCodeModel->findBackwards(ui->searchEdit->text(), m_searchResultIndex); }); + + connect(m_sourceCodeModel, &SourceCodeModel::searchResultFound, this, [this](const QModelIndex& index) { + m_searchResultIndex = index; + ui->sourceCodeView->scrollTo(m_searchResultIndex, QAbstractItemView::ScrollHint::PositionAtCenter); + ui->searchResultWarning->hide(); + }); + + // search if enter is pressed + connect(ui->searchEdit, &QLineEdit::returnPressed, ui->nextSearchResult, &QPushButton::pressed); + + // I don't know how to show an error so I use a warning widget + // kate, ... set the backgroundcolor to red but I don't know how they do this + // google say ->setStylesheet("background: red"); + connect(m_sourceCodeModel, &SourceCodeModel::noSearchResult, this, [this] { + ui->searchResultWarning->setText(tr("%1 was not found").arg(ui->searchEdit->text())); + ui->searchResultWarning->show(); + }); + #if KF5SyntaxHighlighting_FOUND QStringList schemes; @@ -258,6 +290,12 @@ void ResultsDisassemblyPage::showDisassembly() return isArm ? QStringLiteral("arm-linux-gnueabi-objdump") : QStringLiteral("objdump"); }; + // hide search + ui->searchWidget->hide(); + ui->searchResultWarning->hide(); + ui->searchEdit->clear(); + m_searchResultIndex = {}; + showDisassembly(DisassemblyOutput::disassemble(objdump(), m_arch, m_symbolStack[m_stackIndex])); } diff --git a/src/resultsdisassemblypage.h b/src/resultsdisassemblypage.h index 3ec2916f..06b92ca1 100644 --- a/src/resultsdisassemblypage.h +++ b/src/resultsdisassemblypage.h @@ -83,6 +83,8 @@ class ResultsDisassemblyPage : public QWidget CodeDelegate* m_disassemblyDelegate; CodeDelegate* m_sourceCodeDelegate; + QModelIndex m_searchResultIndex = {}; + QVector m_symbolStack; int m_stackIndex = 0; }; diff --git a/src/resultsdisassemblypage.ui b/src/resultsdisassemblypage.ui index 22e7da49..765b51f3 100644 --- a/src/resultsdisassemblypage.ui +++ b/src/resultsdisassemblypage.ui @@ -80,7 +80,8 @@ - + + .. @@ -97,7 +98,8 @@ - + + .. @@ -140,6 +142,16 @@ 0 + + + + true + + + KMessageWidget::Warning + + + @@ -153,6 +165,63 @@ + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + .. + + + + + + + + + + + .. + + + + + + + + + + + .. + + + + + +