diff --git a/src/index/subtreelist.cpp b/src/index/subtreelist.cpp index 65270a63..af50b3ff 100644 --- a/src/index/subtreelist.cpp +++ b/src/index/subtreelist.cpp @@ -25,7 +25,7 @@ #include "debuglog.h" bool subtreelist(RclConfig *config, const string& top, - vector& paths) + vector& paths) { LOGDEB(("subtreelist: top: [%s]\n", top.c_str())); Rcl::Db rcldb(config); @@ -38,7 +38,7 @@ bool subtreelist(RclConfig *config, const string& top, Rcl::SearchData *sd = new Rcl::SearchData(Rcl::SCLT_OR); RefCntr rq(sd); - rq->setTopdir(top); + rq->addDirSpec(top); Rcl::Query query(&rcldb); query.setQuery(rq); diff --git a/src/qtgui/advsearch_w.cpp b/src/qtgui/advsearch_w.cpp index 959936ae..12e05842 100644 --- a/src/qtgui/advsearch_w.cpp +++ b/src/qtgui/advsearch_w.cpp @@ -417,8 +417,8 @@ void AdvSearch::runSearch() if (!subtreeCMB->currentText().isEmpty()) { QString current = subtreeCMB->currentText(); - sdata->setTopdir((const char*)subtreeCMB->currentText().toUtf8(), - direxclCB->isChecked()); + sdata->addDirSpec((const char*)subtreeCMB->currentText().toUtf8(), + direxclCB->isChecked()); // Keep history clean and sorted. Maybe there would be a // simpler way to do this list entries; diff --git a/src/query/wasatorcl.cpp b/src/query/wasatorcl.cpp index ddc1faea..a180b519 100644 --- a/src/query/wasatorcl.cpp +++ b/src/query/wasatorcl.cpp @@ -102,8 +102,8 @@ static Rcl::SearchData *wasaQueryToRcl(RclConfig *config, WasaQuery *wasa, // Filtering on location if (!stringicmp("dir", (*it)->m_fieldspec)) { string dir = path_tildexpand((*it)->m_value); - sdata->setTopdir(dir, (*it)->m_op == WasaQuery::OP_EXCL, - (*it)->m_weight); + sdata->addDirSpec(dir, (*it)->m_op == WasaQuery::OP_EXCL, + (*it)->m_weight); continue; } diff --git a/src/rcldb/searchdata.cpp b/src/rcldb/searchdata.cpp index 2a3860ce..1c8d988b 100644 --- a/src/rcldb/searchdata.cpp +++ b/src/rcldb/searchdata.cpp @@ -320,29 +320,30 @@ bool SearchData::toNativeQuery(Rcl::Db &db, void *d) // Add the directory filtering clause. This is a phrase of terms // prefixed with the pathelt prefix XP - if (!m_topdir.empty()) { + for (vector::const_iterator dit = m_dirspecs.begin(); + dit != m_dirspecs.end(); dit++) { vector vpath; - stringToTokens(m_topdir, vpath, "/"); + stringToTokens(dit->dir, vpath, "/"); vector pvpath; - if (m_topdir[0] == '/') + if (dit->dir[0] == '/') pvpath.push_back(pathelt_prefix); - for (vector::const_iterator it = vpath.begin(); - it != vpath.end(); it++){ - pvpath.push_back(pathelt_prefix + *it); + for (vector::const_iterator pit = vpath.begin(); + pit != vpath.end(); pit++){ + pvpath.push_back(pathelt_prefix + *pit); } Xapian::Query::op tdop; - if (m_topdirweight == 1.0) { - tdop = m_topdirexcl ? + if (dit->weight == 1.0) { + tdop = dit->exclude ? Xapian::Query::OP_AND_NOT : Xapian::Query::OP_FILTER; } else { - tdop = m_topdirexcl ? + tdop = dit->exclude ? Xapian::Query::OP_AND_NOT : Xapian::Query::OP_AND_MAYBE; } Xapian::Query tdq = Xapian::Query(Xapian::Query::OP_PHRASE, pvpath.begin(), pvpath.end()); - if (m_topdirweight != 1.0) + if (dit->weight != 1.0) tdq = Xapian::Query(Xapian::Query::OP_SCALE_WEIGHT, - tdq, m_topdirweight); + tdq, dit->weight); xq = Xapian::Query(tdop, xq, tdq); } @@ -480,8 +481,7 @@ void SearchData::erase() { delete *it; m_query.clear(); m_filetypes.clear(); - m_topdir.erase(); - m_topdirexcl = false; + m_dirspecs.clear(); m_description.erase(); m_reason.erase(); m_haveDates = false; diff --git a/src/rcldb/searchdata.h b/src/rcldb/searchdata.h index 9d35e7f2..a619b098 100644 --- a/src/rcldb/searchdata.h +++ b/src/rcldb/searchdata.h @@ -71,8 +71,7 @@ class SearchDataClause; class SearchData { public: SearchData(SClType tp) - : m_tp(tp), m_topdirexcl(false), m_topdirweight(1.0), - m_haveDates(false), m_maxSize(size_t(-1)), + : m_tp(tp), m_haveDates(false), m_maxSize(size_t(-1)), m_minSize(size_t(-1)), m_haveWildCards(false) { if (m_tp != SCLT_OR && m_tp != SCLT_AND) @@ -105,11 +104,9 @@ public: bool maybeAddAutoPhrase(Rcl::Db &db, double threshold); /** Set/get top subdirectory for filtering results */ - void setTopdir(const std::string& t, bool excl = false, float w = 1.0) + void addDirSpec(const std::string& t, bool excl = false, float w = 1.0) { - m_topdir = t; - m_topdirexcl = excl; - m_topdirweight = w; + m_dirspecs.push_back(DirSpec(t, excl, w)); } void setMinSize(size_t size) {m_minSize = size;} @@ -148,10 +145,21 @@ private: std::vector m_filetypes; // Excluded set of file types if not empty std::vector m_nfiletypes; - // Restrict to subtree. - std::string m_topdir; - bool m_topdirexcl; // Invert meaning - float m_topdirweight; // affect weight instead of filter + + // Restrict to subtree or exclude one + class DirSpec { + public: + std::string dir; + bool exclude; + // For positive spec: affect weight instead of filter + float weight; + DirSpec(const std::string&d, bool x, float w) + : dir(d), exclude(x), weight(w) + { + } + }; + std::vector m_dirspecs; + bool m_haveDates; DateInterval m_dates; // Restrict to date interval size_t m_maxSize;