diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index eb83b14d5..f27231c5a 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -40,7 +40,7 @@ opencs_units (model/tools opencs_units_noqt (model/tools mandatoryid skillcheck classcheck factioncheck racecheck soundcheck regioncheck birthsigncheck spellcheck referencecheck referenceablecheck scriptcheck bodypartcheck - startscriptcheck search + startscriptcheck search searchoperation searchstage ) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index a06eb0ebf..cb3b4ba18 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2380,6 +2380,11 @@ CSMWorld::UniversalId CSMDoc::Document::newSearch() return mTools.newSearch(); } +void CSMDoc::Document::runSearch (const CSMWorld::UniversalId& searchId, const CSMTools::Search& search) +{ + return mTools.runSearch (searchId, search); +} + void CSMDoc::Document::abortOperation (int type) { if (type==State_Saving) diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 4300a9c64..6b1a1fc1e 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -121,6 +121,8 @@ namespace CSMDoc CSMWorld::UniversalId verify(); CSMWorld::UniversalId newSearch(); + + void runSearch (const CSMWorld::UniversalId& searchId, const CSMTools::Search& search); void abortOperation (int type); diff --git a/apps/opencs/model/tools/searchoperation.cpp b/apps/opencs/model/tools/searchoperation.cpp new file mode 100644 index 000000000..134b83b72 --- /dev/null +++ b/apps/opencs/model/tools/searchoperation.cpp @@ -0,0 +1,33 @@ + +#include "searchoperation.hpp" + +#include "../doc/state.hpp" +#include "../doc/document.hpp" + +#include "../world/data.hpp" +#include "../world/idtablebase.hpp" + +#include "searchstage.hpp" + +CSMTools::SearchOperation::SearchOperation (CSMDoc::Document& document) +: CSMDoc::Operation (CSMDoc::State_Searching, false) +{ +appendStage (new SearchStage (&dynamic_cast (*document.getData().getTableModel (CSMWorld::UniversalId::Type_Cells)))); + +} + +void CSMTools::SearchOperation::configure (const Search& search) +{ + mSearch = search; +} + +void CSMTools::SearchOperation::appendStage (SearchStage *stage) +{ + CSMDoc::Operation::appendStage (stage); + stage->setOperation (this); +} + +const CSMTools::Search& CSMTools::SearchOperation::getSearch() const +{ + return mSearch; +} diff --git a/apps/opencs/model/tools/searchoperation.hpp b/apps/opencs/model/tools/searchoperation.hpp new file mode 100644 index 000000000..fbbb38898 --- /dev/null +++ b/apps/opencs/model/tools/searchoperation.hpp @@ -0,0 +1,38 @@ +#ifndef CSM_TOOLS_SEARCHOPERATION_H +#define CSM_TOOLS_SEARCHOPERATION_H + +#include "../doc/operation.hpp" + +#include "search.hpp" + +namespace CSMDoc +{ + class Document; +} + +namespace CSMTools +{ + class SearchStage; + + class SearchOperation : public CSMDoc::Operation + { + Search mSearch; + + public: + + SearchOperation (CSMDoc::Document& document); + + /// \attention Do not call this function while a search is running. + void configure (const Search& search); + + void appendStage (SearchStage *stage); + ///< The ownership of \a stage is transferred to *this. + /// + /// \attention Do no call this function while this Operation is running. + + const Search& getSearch() const; + + }; +} + +#endif diff --git a/apps/opencs/model/tools/searchstage.cpp b/apps/opencs/model/tools/searchstage.cpp new file mode 100644 index 000000000..17859d930 --- /dev/null +++ b/apps/opencs/model/tools/searchstage.cpp @@ -0,0 +1,30 @@ + +#include "searchstage.hpp" + +#include "../world/idtablebase.hpp" + +#include "searchoperation.hpp" + +CSMTools::SearchStage::SearchStage (const CSMWorld::IdTableBase *model) +: mModel (model), mOperation (0) +{} + +int CSMTools::SearchStage::setup() +{ + if (mOperation) + mSearch = mOperation->getSearch(); + + mSearch.configure (mModel); + + return mModel->rowCount(); +} + +void CSMTools::SearchStage::perform (int stage, CSMDoc::Messages& messages) +{ + mSearch.searchRow (mModel, stage, messages); +} + +void CSMTools::SearchStage::setOperation (const SearchOperation *operation) +{ + mOperation = operation; +} diff --git a/apps/opencs/model/tools/searchstage.hpp b/apps/opencs/model/tools/searchstage.hpp new file mode 100644 index 000000000..073487c0d --- /dev/null +++ b/apps/opencs/model/tools/searchstage.hpp @@ -0,0 +1,37 @@ +#ifndef CSM_TOOLS_SEARCHSTAGE_H +#define CSM_TOOLS_SEARCHSTAGE_H + +#include "../doc/stage.hpp" + +#include "search.hpp" + +namespace CSMWorld +{ + class IdTableBase; +} + +namespace CSMTools +{ + class SearchOperation; + + class SearchStage : public CSMDoc::Stage + { + const CSMWorld::IdTableBase *mModel; + Search mSearch; + const SearchOperation *mOperation; + + public: + + SearchStage (const CSMWorld::IdTableBase *model); + + virtual int setup(); + ///< \return number of steps + + virtual void perform (int stage, CSMDoc::Messages& messages); + ///< Messages resulting from this stage will be appended to \a messages. + + void setOperation (const SearchOperation *operation); + }; +} + +#endif diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index 07bd4205b..957e20296 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -25,6 +25,7 @@ #include "bodypartcheck.hpp" #include "referencecheck.hpp" #include "startscriptcheck.hpp" +#include "searchoperation.hpp" CSMDoc::OperationHolder *CSMTools::Tools::get (int type) { @@ -108,6 +109,12 @@ CSMTools::Tools::Tools (CSMDoc::Document& document) // index 0: load error log mReports.insert (std::make_pair (mNextReportNumber++, new ReportModel)); mActiveReports.insert (std::make_pair (CSMDoc::State_Loading, 0)); + + connect (&mSearch, SIGNAL (progress (int, int, int)), this, SIGNAL (progress (int, int, int))); + connect (&mSearch, SIGNAL (done (int, bool)), this, SIGNAL (done (int, bool))); + connect (&mSearch, + SIGNAL (reportMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int)), + this, SLOT (verifierMessage (const CSMWorld::UniversalId&, const std::string&, const std::string&, int))); } CSMTools::Tools::~Tools() @@ -145,6 +152,21 @@ CSMWorld::UniversalId CSMTools::Tools::newSearch() return CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Search, mNextReportNumber-1); } +void CSMTools::Tools::runSearch (const CSMWorld::UniversalId& searchId, const Search& search) +{ + mActiveReports[CSMDoc::State_Searching] = searchId.getIndex(); + + if (!mSearchOperation) + { + mSearchOperation = new SearchOperation (mDocument); + mSearch.setOperation (mSearchOperation); + } + + mSearchOperation->configure (search); + + mSearch.start(); +} + void CSMTools::Tools::abortOperation (int type) { if (CSMDoc::OperationHolder *operation = get (type)) diff --git a/apps/opencs/model/tools/tools.hpp b/apps/opencs/model/tools/tools.hpp index bd27767a6..0f9e57044 100644 --- a/apps/opencs/model/tools/tools.hpp +++ b/apps/opencs/model/tools/tools.hpp @@ -22,6 +22,8 @@ namespace CSMDoc namespace CSMTools { class ReportModel; + class Search; + class SearchOperation; class Tools : public QObject { @@ -31,7 +33,7 @@ namespace CSMTools CSMWorld::Data& mData; CSMDoc::Operation *mVerifierOperation; CSMDoc::OperationHolder mVerifier; - CSMDoc::Operation *mSearchOperation; + SearchOperation *mSearchOperation; CSMDoc::OperationHolder mSearch; std::map mReports; int mNextReportNumber; @@ -60,6 +62,8 @@ namespace CSMTools /// Return ID of the report for this search. CSMWorld::UniversalId newSearch(); + + void runSearch (const CSMWorld::UniversalId& searchId, const Search& search); void abortOperation (int type); ///< \attention The operation is not aborted immediately. diff --git a/apps/opencs/view/doc/operation.cpp b/apps/opencs/view/doc/operation.cpp index 6977d7953..95cbf012d 100644 --- a/apps/opencs/view/doc/operation.cpp +++ b/apps/opencs/view/doc/operation.cpp @@ -18,6 +18,7 @@ void CSVDoc::Operation::updateLabel (int threads) { case CSMDoc::State_Saving: name = "saving"; break; case CSMDoc::State_Verifying: name = "verifying"; break; + case CSMDoc::State_Searching: name = "searching"; break; } std::ostringstream stream; diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 533cab049..e7eb28337 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -447,7 +447,7 @@ void CSVDoc::View::updateDocumentState() static const int operations[] = { - CSMDoc::State_Saving, CSMDoc::State_Verifying, + CSMDoc::State_Saving, CSMDoc::State_Verifying, CSMDoc::State_Searching, -1 // end marker }; diff --git a/apps/opencs/view/tools/searchsubview.cpp b/apps/opencs/view/tools/searchsubview.cpp index bc818df07..b4a0f893a 100644 --- a/apps/opencs/view/tools/searchsubview.cpp +++ b/apps/opencs/view/tools/searchsubview.cpp @@ -9,7 +9,7 @@ #include "searchbox.hpp" CSVTools::SearchSubView::SearchSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) -: CSVDoc::SubView (id) +: CSVDoc::SubView (id), mDocument (document) { QVBoxLayout *layout = new QVBoxLayout; @@ -32,6 +32,9 @@ CSVTools::SearchSubView::SearchSubView (const CSMWorld::UniversalId& id, CSMDoc: connect (&document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (stateChanged (int, CSMDoc::Document *))); + + connect (&mSearchBox, SIGNAL (startSearch (const CSMTools::Search&)), + this, SLOT (startSearch (const CSMTools::Search&))); } void CSVTools::SearchSubView::setEditLock (bool locked) @@ -48,3 +51,8 @@ void CSVTools::SearchSubView::stateChanged (int state, CSMDoc::Document *documen { mSearchBox.setSearchMode (!(state & CSMDoc::State_Searching)); } + +void CSVTools::SearchSubView::startSearch (const CSMTools::Search& search) +{ + mDocument.runSearch (getUniversalId(), search); +} diff --git a/apps/opencs/view/tools/searchsubview.hpp b/apps/opencs/view/tools/searchsubview.hpp index b389805bb..d17f7a340 100644 --- a/apps/opencs/view/tools/searchsubview.hpp +++ b/apps/opencs/view/tools/searchsubview.hpp @@ -23,6 +23,7 @@ namespace CSVTools ReportTable *mTable; SearchBox mSearchBox; + CSMDoc::Document& mDocument; public: @@ -35,6 +36,8 @@ namespace CSVTools private slots: void stateChanged (int state, CSMDoc::Document *document); + + void startSearch (const CSMTools::Search& search); }; }