From 572eb5b57d2ae591c392e7a357227b4949b01e83 Mon Sep 17 00:00:00 2001 From: Jean-Francois Dockes Date: Fri, 1 Dec 2017 17:40:01 +0100 Subject: [PATCH] Index config GUI: fix bug where the +- forms of skippedNames and noContentSuffixes were not taken into account --- src/common/rclconfig.cpp | 99 ++++++++++++++---------- src/common/rclconfig.h | 12 +++ src/qtgui/confgui/confguiindex.cpp | 117 ++++++++++++++++++++++++++++- 3 files changed, 185 insertions(+), 43 deletions(-) diff --git a/src/common/rclconfig.cpp b/src/common/rclconfig.cpp index 5667c429..7b687ac6 100644 --- a/src/common/rclconfig.cpp +++ b/src/common/rclconfig.cpp @@ -65,27 +65,34 @@ bool o_uptodate_test_use_mtime = false; string RclConfig::o_localecharset; string RclConfig::o_origcwd; -// Compute the difference of 1st to 2nd set and return as -// plus/minus strings -static void setPlusMinus(const set& base, const set& upd, - string& plus, string& minus) +// Compute the difference of 1st to 2nd sets and return as plus/minus +// sets. Some args are std::set and some others stringToString() +// strings for convenience +void RclConfig::setPlusMinus(const string& sbase, const set& upd, + string& splus, string& sminus) { + set base; + stringToStrings(sbase, base); + vector diff; auto it = set_difference(base.begin(), base.end(), upd.begin(), upd.end(), std::inserter(diff, diff.begin())); - minus = stringsToString(diff); + sminus = stringsToString(diff); diff.clear(); it = set_difference(upd.begin(), upd.end(), base.begin(), base.end(), std::inserter(diff, diff.begin())); - plus = stringsToString(diff); + splus = stringsToString(diff); } +/* Compute result of substracting strminus and adding strplus to base string. + All string represent sets of values to be computed with stringToStrings() */ static void computeBasePlusMinus(set& res, const string& strbase, const string& strplus, const string& strminus) { set plus, minus; + res.clear(); stringToStrings(strbase, res); stringToStrings(strplus, plus); stringToStrings(strminus, minus); @@ -660,41 +667,54 @@ public: return 0; } }; -typedef multiset SuffixStore; +typedef multiset SuffixStore; #define STOPSUFFIXES ((SuffixStore *)m_stopsuffixes) +vector& RclConfig::getStopSuffixes() +{ + bool needrecompute = m_stpsuffstate.needrecompute(); + needrecompute = m_oldstpsuffstate.needrecompute() || needrecompute; + if (needrecompute || m_stopsuffixes == 0) { + // Need to initialize the suffixes + + // Let the old customisation have priority: if recoll_noindex from + // mimemap is set, it the user's (the default value is gone). Else + // use the new variable + if (!m_oldstpsuffstate.getvalue(0).empty()) { + stringToStrings(m_oldstpsuffstate.getvalue(0), m_stopsuffvec); + } else { + std::set ss; + computeBasePlusMinus(ss, m_stpsuffstate.getvalue(0), + m_stpsuffstate.getvalue(1), + m_stpsuffstate.getvalue(2)); + m_stopsuffvec = vector(ss.begin(), ss.end()); + } + + // Compute the special suffixes store + delete STOPSUFFIXES; + if ((m_stopsuffixes = new SuffixStore) == 0) { + LOGERR("RclConfig::inStopSuffixes: out of memory\n"); + return m_stopsuffvec; + } + m_maxsufflen = 0; + for (const auto& entry : m_stopsuffvec) { + STOPSUFFIXES->insert(SfString(stringtolower(entry))); + if (m_maxsufflen < entry.length()) + m_maxsufflen = int(entry.length()); + } + } + LOGDEB1("RclConfig::getStopSuffixes: ->" << + stringsToString(m_stopsuffvec) << endl); + return m_stopsuffvec; +} + bool RclConfig::inStopSuffixes(const string& fni) { LOGDEB2("RclConfig::inStopSuffixes(" << fni << ")\n"); - // Beware: both needrecompute() need to be called always hence the - // bizarre way we do things - bool needrecompute = m_stpsuffstate.needrecompute(); - needrecompute = m_oldstpsuffstate.needrecompute() || needrecompute; - if (needrecompute || m_stopsuffixes == 0) { - // Need to initialize the suffixes - delete STOPSUFFIXES; - if ((m_stopsuffixes = new SuffixStore) == 0) { - LOGERR("RclConfig::inStopSuffixes: out of memory\n"); - return false; - } - // Let the old customisation have priority: if recoll_noindex - // from mimemap is set, it the user's (the default value is - // gone). Else use the new variable - set stoplist; - if (!m_oldstpsuffstate.getvalue(0).empty()) { - stringToStrings(m_oldstpsuffstate.getvalue(0), stoplist); - } else { - computeBasePlusMinus(stoplist, m_stpsuffstate.getvalue(0), - m_stpsuffstate.getvalue(1), - m_stpsuffstate.getvalue(2)); - } - for (auto& it : stoplist) { - STOPSUFFIXES->insert(SfString(stringtolower(it))); - if (m_maxsufflen < it.length()) - m_maxsufflen = int(it.length()); - } - } + + // Call getStopSuffixes() to possibly update state, ignore result + getStopSuffixes(); // Only need a tail as long as the longest suffix. int pos = MAX(0, int(fni.length() - m_maxsufflen)); @@ -1097,13 +1117,11 @@ bool RclConfig::setMimeViewerAllEx(const set& allex) if (mimeview == 0) return false; - string s; - mimeview->get("xallexcepts", s, ""); - set base; - stringToStrings(s, base); + string sbase; + mimeview->get("xallexcepts", sbase, ""); string splus, sminus; - setPlusMinus(base, allex, splus, sminus); + setPlusMinus(sbase, allex, splus, sminus); if (!mimeview->set("xallexcepts-", sminus, "")) { m_reason = string("RclConfig:: cant set value. Readonly?"); @@ -1619,6 +1637,7 @@ void RclConfig::initFrom(const RclConfig& r) m_xattrtofld = r.m_xattrtofld; m_maxsufflen = r.m_maxsufflen; m_skpnlist = r.m_skpnlist; + m_stopsuffixes = r.m_stopsuffixes; m_defcharset = r.m_defcharset; m_restrictMTypes = r.m_restrictMTypes; m_excludeMTypes = r.m_excludeMTypes; diff --git a/src/common/rclconfig.h b/src/common/rclconfig.h index 330c290a..a4539468 100644 --- a/src/common/rclconfig.h +++ b/src/common/rclconfig.h @@ -213,6 +213,10 @@ class RclConfig { Doesn't depend on the keydir */ vector getDaemSkippedPaths() const; + /** Return list of no content suffixes. Used by confgui, indexing uses + inStopSuffixes() for testing suffixes */ + std::vector& getStopSuffixes(); + /** * mimemap: Check if file name should be ignored because of suffix * @@ -247,6 +251,13 @@ class RclConfig { static bool valueSplitAttributes(const string& whole, string& value, ConfSimple& attrs) ; + /** Compute difference between 'base' and 'changed', as elements to be + * added and substracted from base. Input and output strings are in + * stringToStrings() format. */ + static void setPlusMinus( + const std::string& base, const std::set& changed, + std::string& plus, std::string& minus); + /** Return the locale's character set */ static const std::string& getLocaleCharset(); @@ -369,6 +380,7 @@ class RclConfig { unsigned int m_maxsufflen; ParamStale m_oldstpsuffstate; // Values from user mimemap, now obsolete ParamStale m_stpsuffstate; + vector m_stopsuffvec; ParamStale m_skpnstate; vector m_skpnlist; diff --git a/src/qtgui/confgui/confguiindex.cpp b/src/qtgui/confgui/confguiindex.cpp index 1f580157..ea206ee1 100644 --- a/src/qtgui/confgui/confguiindex.cpp +++ b/src/qtgui/confgui/confguiindex.cpp @@ -29,7 +29,11 @@ #include #include +#include +#include using std::list; +using std::set; +using std::string; #include "confgui.h" #include "recoll.h" @@ -37,7 +41,6 @@ using std::list; #include "smallut.h" #include "log.h" #include "rcldb.h" -#include "conflinkrcl.h" #include "execmd.h" #include "rclconfig.h" @@ -45,6 +48,110 @@ namespace confgui { static const int spacing = 3; static const int margin = 3; +/** + * A Gui-to-Data link class for ConfTree + * Has a subkey pointer member which makes it easy to change the + * current subkey for a number at a time. + */ +class ConfLinkRclRep : public ConfLinkRep { +public: + ConfLinkRclRep(ConfNull *conf, const string& nm, + string *sk = 0) + : m_conf(conf), m_nm(nm), m_sk(sk) /* KEEP THE POINTER, shared data */ + { + } + virtual ~ConfLinkRclRep() {} + + virtual bool set(const string& val) + { + if (!m_conf) + return false; + LOGDEB1("Setting [" << m_nm << "] value to [" << val << "]\n"); + bool ret = m_conf->set(m_nm, val, getSk()); + if (!ret) + LOGERR("Value set failed\n" ); + return ret; + } + virtual bool get(string& val) + { + if (!m_conf) + return false; + bool ret = m_conf->get(m_nm, val, getSk()); + LOGDEB1("ConfLinkRcl::get: [" << m_nm << "] sk [" << + getSk() << "] -> [" << (ret ? val : "no value") << "]\n" ); + return ret; + } +private: + string getSk() { + return m_sk ? *m_sk : string(); + } + ConfNull *m_conf; + const string m_nm; + const string *m_sk; +}; + + +typedef std::function()> RclConfVecValueGetter; + +/* Special link for skippedNames and noContentSuffixes which are + computed as set differences */ +class ConfLinkPlusMinus : public ConfLinkRep { +public: + ConfLinkPlusMinus(RclConfig *rclconf, ConfNull *conf, + const string& basename, RclConfVecValueGetter getter, + string *sk = 0) + : m_rclconf(rclconf), m_conf(conf), + m_basename(basename), m_getter(getter), + m_sk(sk) /* KEEP THE POINTER, shared data */ + { + } + virtual ~ConfLinkPlusMinus() {} + + virtual bool set(const string& snval) { + if (!m_conf || !m_rclconf) + return false; + + string sbase; + m_conf->get(m_basename, sbase, getSk()); + std::set nval; + stringToStrings(snval, nval); + string splus, sminus; + RclConfig::setPlusMinus(sbase, nval, splus, sminus); + LOGDEB1("ConfLinkPlusMinus: base [" << sbase << "] nvalue [" << snval << + "] splus [" << splus << "] sminus [" << sminus << "]\n"); + if (!m_conf->set(m_basename + "-", sminus, getSk())) { + return false; + } + if (!m_conf->set(m_basename + "+", splus, getSk())) { + return false; + } + return true; + } + + virtual bool get(string& val) { + if (!m_conf || !m_rclconf) + return false; + + m_rclconf->setKeyDir(getSk()); + vector vval = m_getter(); + val = stringsToString(vval); + LOGDEB1("ConfLinkPlusMinus: "< " << val <