From fd328722184b4bf5e43668f0ee588f2b242beb65 Mon Sep 17 00:00:00 2001 From: Jean-Francois Dockes Date: Sat, 20 Jan 2018 11:59:00 +0100 Subject: [PATCH] Improve 'rebuild index' under Windows: this often failed because of some open files in the Xapian db (could not be deleted under windows). Now only fails if a preview has been opened, and a GUI restart fixes the situation. --- src/qtgui/rclm_idx.cpp | 31 ++++++++++++++++++++++++++++--- src/qtgui/rclm_wins.cpp | 15 +++++++++------ src/qtgui/rclmain_w.cpp | 6 +++--- src/qtgui/rclmain_w.h | 2 ++ src/qtgui/reslist.cpp | 2 ++ src/rcldb/rcldb.cpp | 10 ++++++++++ 6 files changed, 54 insertions(+), 12 deletions(-) diff --git a/src/qtgui/rclm_idx.cpp b/src/qtgui/rclm_idx.cpp index c5fe9186..be186dda 100644 --- a/src/qtgui/rclm_idx.cpp +++ b/src/qtgui/rclm_idx.cpp @@ -29,6 +29,7 @@ #include "rclmain_w.h" #include "specialindex.h" #include "readfile.h" +#include "snippets_w.h" using namespace std; @@ -291,8 +292,20 @@ void RclMain::toggleIndexing() } } +static void delay(int millisecondsWait) +{ + QEventLoop loop; + QTimer t; + t.connect(&t, &QTimer::timeout, &loop, &QEventLoop::quit); + t.start(millisecondsWait); + loop.exec(); +} + void RclMain::rebuildIndex() { + if (m_indexerState == IXST_UNKNOWN) { + delay(1500); + } switch (m_indexerState) { case IXST_UNKNOWN: case IXST_RUNNINGMINE: @@ -313,12 +326,24 @@ void RclMain::rebuildIndex() QMessageBox::NoButton); if (rep == QMessageBox::Ok) { #ifdef _WIN32 - // Under windows, it's necessary to close the db here, + // Under windows, it is necessary to close the db here, // else Xapian won't be able to do what it wants with the // (open) files. Of course if there are several GUI - // instances, this won't work... - if (rcldb) + // instances, this won't work... Also it's quite difficult + // to make sure that there are no more references to the + // db because, for example of the Enquire objects inside + // Query inside Docsource etc. + // + // !! At this moment, this does not work if a preview has + // !! been opened. Could not find the reason (mysterious + // !! Xapian::Database reference somewhere?). The indexing + // !! fails, leaving a partial index directory. Then need + // !! to restart the GUI to succeed in reindexing. + if (rcldb) { + resetSearch(); + deleteZ(m_snippets); rcldb->close(); + } #endif // _WIN32 // Could also mean that no helpers are missing, but then we // won't try to show a message anyway (which is what diff --git a/src/qtgui/rclm_wins.cpp b/src/qtgui/rclm_wins.cpp index 9594a72c..d506d6f5 100644 --- a/src/qtgui/rclm_wins.cpp +++ b/src/qtgui/rclm_wins.cpp @@ -451,13 +451,16 @@ void RclMain::newDupsW(const Rcl::Doc, const vector dups) void RclMain::showSnippets(Rcl::Doc doc) { - SnippetsW *sp = new SnippetsW(doc, m_source); - connect(sp, SIGNAL(startNativeViewer(Rcl::Doc, int, QString)), + if (m_snippets) { + deleteZ(m_snippets); + } + m_snippets = new SnippetsW(doc, m_source); + connect(m_snippets, SIGNAL(startNativeViewer(Rcl::Doc, int, QString)), this, SLOT(startNativeViewer(Rcl::Doc, int, QString))); - connect(new QShortcut(quitKeySeq, sp), SIGNAL (activated()), + connect(new QShortcut(quitKeySeq, m_snippets), SIGNAL (activated()), this, SLOT (fileExit())); - connect(new QShortcut(closeKeySeq, sp), SIGNAL (activated()), - sp, SLOT (close())); - sp->show(); + connect(new QShortcut(closeKeySeq, m_snippets), SIGNAL (activated()), + m_snippets, SLOT (close())); + m_snippets->show(); } diff --git a/src/qtgui/rclmain_w.cpp b/src/qtgui/rclmain_w.cpp index 41438f65..f61369ec 100644 --- a/src/qtgui/rclmain_w.cpp +++ b/src/qtgui/rclmain_w.cpp @@ -531,7 +531,7 @@ void RclMain::initDbOpen() connect(fidia.idxschedCLB, SIGNAL(clicked()), this, SLOT(execIndexSched())); connect(fidia.runidxPB, SIGNAL(clicked()), - this, SLOT(toggleIndexing())); + this, SLOT(rebuildIndex())); fidia.exec(); // Don't open adv search or run cmd line search in this case. return; @@ -788,6 +788,7 @@ void RclMain::initiateQuery() void RclMain::resetSearch() { + m_source = std::shared_ptr(); emit searchReset(); } @@ -974,8 +975,7 @@ void RclMain::docExpand(Rcl::Doc doc) void RclMain::showDocHistory() { LOGDEB("RclMain::showDocHistory\n"); - emit searchReset(); - m_source = std::shared_ptr(); + resetSearch(); curPreview = 0; string reason; diff --git a/src/qtgui/rclmain_w.h b/src/qtgui/rclmain_w.h index d7add82e..1eedfc0f 100644 --- a/src/qtgui/rclmain_w.h +++ b/src/qtgui/rclmain_w.h @@ -35,6 +35,7 @@ #include "guiutils.h" #include "rclutil.h" +class SnippetsW; class IdxSchedW; class ExecCmd; class Preview; @@ -202,6 +203,7 @@ protected: private: + SnippetsW *m_snippets{0}; Preview *curPreview; AdvSearch *asearchform; UIPrefsDialog *uiprefs; diff --git a/src/qtgui/reslist.cpp b/src/qtgui/reslist.cpp index 6dd430d3..15d668cf 100644 --- a/src/qtgui/reslist.cpp +++ b/src/qtgui/reslist.cpp @@ -407,6 +407,8 @@ void ResList::setDocSource(std::shared_ptr nsource) { LOGDEB("ResList::setDocSource()\n"); m_source = std::shared_ptr(new DocSource(theconfig, nsource)); + if (m_pager) + m_pager->setDocSource(m_source); } // A query was executed, or the filtering/sorting parameters changed, diff --git a/src/rcldb/rcldb.cpp b/src/rcldb/rcldb.cpp index 208775cf..0d47bf9b 100644 --- a/src/rcldb/rcldb.cpp +++ b/src/rcldb/rcldb.cpp @@ -58,6 +58,7 @@ using namespace std; #include "rclinit.h" #include "internfile.h" #include "utf8fn.h" +#include "wipedir.h" #ifdef RCL_USE_ASPELL #include "rclaspell.h" #endif @@ -793,6 +794,15 @@ bool Db::open(OpenMode mode, OpenError *error) case DbUpd: case DbTrunc: { + // Xapian is quite bad at erasing partial db which can + // occur because of open file deletion errors on + // Windows. + if (mode == DbTrunc) { + if (path_exists(path_cat(dir, "iamchert"))) { + wipedir(dir); + unlink(dir.c_str()); + } + } int action = (mode == DbUpd) ? Xapian::DB_CREATE_OR_OPEN : Xapian::DB_CREATE_OR_OVERWRITE; if (::access(dir.c_str(), 0) != 0) {