diff --git a/apps/opencs/view/tools/reporttable.hpp b/apps/opencs/view/tools/reporttable.hpp index 25f8d1b017..20bed8e233 100644 --- a/apps/opencs/view/tools/reporttable.hpp +++ b/apps/opencs/view/tools/reporttable.hpp @@ -86,6 +86,9 @@ namespace CSVTools /// \return rows in the original model std::vector getReplaceIndices(bool selection) const; + /// \return underlying report model + CSMTools::ReportModel* getReportModel() const { return mModel; } + /// \param index row in the original model void flagAsReplaced(int index); diff --git a/apps/opencs/view/tools/searchbox.cpp b/apps/opencs/view/tools/searchbox.cpp index a2871b5489..c632de99eb 100644 --- a/apps/opencs/view/tools/searchbox.cpp +++ b/apps/opencs/view/tools/searchbox.cpp @@ -8,28 +8,38 @@ #include "../../model/tools/search.hpp" -void CSVTools::SearchBox::updateSearchButton() +void CSVTools::SearchBox::updateSearchButtons() { + mReplace.setEnabled(false); if (!mSearchEnabled) - mSearch.setEnabled(false); - else { - switch (mMode.currentIndex()) + mSearch.setEnabled(false); + return; + } + + const CSMTools::Search::Type type = static_cast(mMode.currentIndex()); + if (type == CSMTools::Search::Type_RecordState) + { + mSearch.setEnabled(true); + return; + } + + bool canSearch = false; + QString style; + if (!mText.text().isEmpty()) + { + canSearch = true; + if (type == CSMTools::Search::Type_TextRegEx || type == CSMTools::Search::Type_IdRegEx) { - case 0: - case 1: - case 2: - case 3: - - mSearch.setEnabled(!mText.text().isEmpty()); - break; - - case 4: - - mSearch.setEnabled(true); - break; + canSearch = QRegularExpression(mText.text()).isValid(); + if (!canSearch) + style = "QLineEdit { color: red; }"; } } + + mText.setStyleSheet(style); + mSearch.setEnabled(canSearch); + mReplace.setEnabled(mAllowReplace && mSearchResultCount > 0); } CSVTools::SearchBox::SearchBox(QWidget* parent) @@ -76,6 +86,7 @@ CSVTools::SearchBox::SearchBox(QWidget* parent) mLayout->addWidget(&mReplaceInput, 1, 1); mLayout->addWidget(&mReplace, 1, 3); + mReplace.setEnabled(false); // layout adjustments mLayout->setColumnMinimumWidth(2, 50); @@ -88,13 +99,29 @@ CSVTools::SearchBox::SearchBox(QWidget* parent) // update modeSelected(0); - updateSearchButton(); + updateSearchButtons(); +} + +void CSVTools::SearchBox::setEditLock(bool locked) +{ + mAllowReplace = !locked; + updateSearchButtons(); } void CSVTools::SearchBox::setSearchMode(bool enabled) { mSearchEnabled = enabled; - updateSearchButton(); + updateSearchButtons(); +} + +void CSVTools::SearchBox::setSearchResultCount(int resultCount) +{ + int priorResultCount = mSearchResultCount; + mSearchResultCount = resultCount; + + // Update search buttons only if we're changing between zero and non-zero + if ((priorResultCount == 0) != (mSearchResultCount == 0)) + updateSearchButtons(); } CSMTools::Search CSVTools::SearchBox::getSearch() const @@ -146,11 +173,6 @@ std::string CSVTools::SearchBox::getReplaceText() const } } -void CSVTools::SearchBox::setEditLock(bool locked) -{ - mReplace.setEnabled(!locked); -} - void CSVTools::SearchBox::focus() { mInput.currentWidget()->setFocus(); @@ -177,12 +199,12 @@ void CSVTools::SearchBox::modeSelected(int index) mInput.currentWidget()->setFocus(); - updateSearchButton(); + updateSearchButtons(); } void CSVTools::SearchBox::textChanged(const QString& text) { - updateSearchButton(); + updateSearchButtons(); } void CSVTools::SearchBox::startSearch(bool checked) diff --git a/apps/opencs/view/tools/searchbox.hpp b/apps/opencs/view/tools/searchbox.hpp index 76712fee4b..69490f34bd 100644 --- a/apps/opencs/view/tools/searchbox.hpp +++ b/apps/opencs/view/tools/searchbox.hpp @@ -30,25 +30,30 @@ namespace CSVTools QGridLayout* mLayout; QComboBox mMode; bool mSearchEnabled; + bool mAllowReplace{ false }; QStackedWidget mReplaceInput; QLineEdit mReplaceText; QLabel mReplacePlaceholder; QPushButton mReplace; private: - void updateSearchButton(); + int mSearchResultCount = 0; + + void updateSearchButtons(); public: SearchBox(QWidget* parent = nullptr); + void setEditLock(bool locked); + void setSearchMode(bool enabled); + void setSearchResultCount(int resultCount); + CSMTools::Search getSearch() const; std::string getReplaceText() const; - void setEditLock(bool locked); - void focus(); private slots: diff --git a/apps/opencs/view/tools/searchsubview.cpp b/apps/opencs/view/tools/searchsubview.cpp index 98fd97e7ae..dc8269490e 100644 --- a/apps/opencs/view/tools/searchsubview.cpp +++ b/apps/opencs/view/tools/searchsubview.cpp @@ -22,14 +22,16 @@ void CSVTools::SearchSubView::replace(bool selection) { - if (mLocked) + if (!mAllowReplace) return; std::vector indices = mTable->getReplaceIndices(selection); + if (indices.empty()) + return; std::string replace = mSearchBox.getReplaceText(); - const CSMTools::ReportModel& model = dynamic_cast(*mTable->model()); + const CSMTools::ReportModel* model = mTable->getReportModel(); bool autoDelete = CSMPrefs::get()["Search & Replace"]["auto-delete"].isTrue(); @@ -40,7 +42,7 @@ void CSVTools::SearchSubView::replace(bool selection) // in a single string. for (std::vector::const_reverse_iterator iter(indices.rbegin()); iter != indices.rend(); ++iter) { - const CSMWorld::UniversalId& id = model.getUniversalId(*iter); + const CSMWorld::UniversalId& id = model->getUniversalId(*iter); CSMWorld::UniversalId::Type type = CSMWorld::UniversalId::getParentType(id.getType()); @@ -52,7 +54,7 @@ void CSVTools::SearchSubView::replace(bool selection) currentTable = table; } - std::string hint = model.getHint(*iter); + std::string hint = model->getHint(*iter); if (search.verify(mDocument, table, id, hint)) { @@ -74,7 +76,6 @@ void CSVTools::SearchSubView::showEvent(QShowEvent* event) CSVTools::SearchSubView::SearchSubView(const CSMWorld::UniversalId& id, CSMDoc::Document& document) : CSVDoc::SubView(id) , mDocument(document) - , mLocked(false) { QVBoxLayout* layout = new QVBoxLayout; @@ -112,7 +113,7 @@ CSVTools::SearchSubView::SearchSubView(const CSMWorld::UniversalId& id, CSMDoc:: void CSVTools::SearchSubView::setEditLock(bool locked) { - mLocked = locked; + mAllowReplace = !locked; mSearchBox.setEditLock(locked); } @@ -149,7 +150,9 @@ void CSVTools::SearchSubView::replaceAllRequest() void CSVTools::SearchSubView::tableSizeUpdate() { - mBottom->tableSizeChanged(mDocument.getReport(getUniversalId())->rowCount(), 0, 0); + int resultCount = mDocument.getReport(getUniversalId())->rowCount(); + mBottom->tableSizeChanged(resultCount, 0, 0); + mSearchBox.setSearchResultCount(resultCount); } void CSVTools::SearchSubView::operationDone(int type, bool failed) diff --git a/apps/opencs/view/tools/searchsubview.hpp b/apps/opencs/view/tools/searchsubview.hpp index 270706d7aa..86017ba3c1 100644 --- a/apps/opencs/view/tools/searchsubview.hpp +++ b/apps/opencs/view/tools/searchsubview.hpp @@ -31,7 +31,7 @@ namespace CSVTools SearchBox mSearchBox; CSMDoc::Document& mDocument; CSMTools::Search mSearch; - bool mLocked; + bool mAllowReplace{ false }; CSVWorld::TableBottomBox* mBottom; private: