diff --git a/src/qtgui/advshist.cpp b/src/qtgui/advshist.cpp index 4666913d..b3517804 100644 --- a/src/qtgui/advshist.cpp +++ b/src/qtgui/advshist.cpp @@ -79,10 +79,12 @@ bool AdvSearchHist::read() { if (!g_dynconf) return false; - list lxml = g_dynconf->getStringList(advSearchHistSk); - - for (list::const_iterator it = lxml.begin(); it != lxml.end(); - it++) { + + // getStringEntries() return the entries in order (lower key + // first), but we want most recent first, so revert + vector lxml = + g_dynconf->getStringEntries(advSearchHistSk); + for (auto it = lxml.rbegin(); it != lxml.rend(); it++) { std::shared_ptr sd = xmlToSearchData(*it); if (sd) m_entries.push_back(sd); diff --git a/src/qtgui/guiutils.cpp b/src/qtgui/guiutils.cpp index bf395127..d5b0a12b 100644 --- a/src/qtgui/guiutils.cpp +++ b/src/qtgui/guiutils.cpp @@ -316,19 +316,17 @@ void rwSettings(bool writing) // as they are likely to depend on RECOLL_CONFDIR. if (writing) { g_dynconf->eraseAll(allEdbsSk); - for (list::const_iterator it = prefs.allExtraDbs.begin(); - it != prefs.allExtraDbs.end(); it++) { - g_dynconf->enterString(allEdbsSk, *it); + for (const auto& dbdir : prefs.allExtraDbs) { + g_dynconf->enterString(allEdbsSk, dbdir); } g_dynconf->eraseAll(actEdbsSk); - for (list::const_iterator it = prefs.activeExtraDbs.begin(); - it != prefs.activeExtraDbs.end(); it++) { - g_dynconf->enterString(actEdbsSk, *it); + for (const auto& dbdir : prefs.activeExtraDbs) { + g_dynconf->enterString(actEdbsSk, dbdir); } } else { - prefs.allExtraDbs = g_dynconf->getStringList(allEdbsSk); + prefs.allExtraDbs = g_dynconf->getStringEntries(allEdbsSk); const char *cp; if ((cp = getenv("RECOLL_EXTRA_DBS")) != 0) { vector dbl; @@ -337,17 +335,18 @@ void rwSettings(bool writing) dit++) { string dbdir = path_canon(*dit); path_catslash(dbdir); - if (std::find(prefs.allExtraDbs.begin(), - prefs.allExtraDbs.end(), dbdir) != + if (std::find(prefs.allExtraDbs.begin(), + prefs.allExtraDbs.end(), dbdir) != prefs.allExtraDbs.end()) continue; bool stripped; if (!Rcl::Db::testDbDir(dbdir, &stripped)) { - LOGERR("Not a xapian index: [" << (dbdir) << "]\n" ); + LOGERR("Not a xapian index: [" << dbdir << "]\n"); continue; } if (stripped != o_index_stripchars) { - LOGERR("Incompatible character stripping: [" << (dbdir) << "]\n" ); + LOGERR("Incompatible character stripping: [" << dbdir << + "]\n"); continue; } prefs.allExtraDbs.push_back(dbdir); @@ -355,16 +354,17 @@ void rwSettings(bool writing) } // Get the remembered "active external indexes": - prefs.activeExtraDbs = g_dynconf->getStringList(actEdbsSk); + prefs.activeExtraDbs = g_dynconf->getStringEntries(actEdbsSk); // Clean up the list: remove directories which are not // actually there: useful for removable volumes. - for (list::iterator it = prefs.activeExtraDbs.begin(); - it != prefs.activeExtraDbs.end();) { + for (auto it = prefs.activeExtraDbs.begin(); + it != prefs.activeExtraDbs.end();) { bool stripped; if (!Rcl::Db::testDbDir(*it, &stripped) || stripped != o_index_stripchars) { - LOGINFO("Not a Xapian index or char stripping differs: [" << *it << "]\n" ); + LOGINFO("Not a Xapian index or char stripping differs: [" << + *it << "]\n"); it = prefs.activeExtraDbs.erase(it); } else { it++; @@ -418,14 +418,14 @@ void rwSettings(bool writing) while (prefs.asearchSubdirHist.size() > 20) prefs.asearchSubdirHist.pop_back(); g_dynconf->eraseAll(asbdSk); - for (QStringList::iterator it = prefs.asearchSubdirHist.begin(); - it != prefs.asearchSubdirHist.end(); it++) { - g_dynconf->enterString(asbdSk, (const char *)((*it).toUtf8())); + for (const auto& qdbd : prefs.asearchSubdirHist) { + g_dynconf->enterString(asbdSk, qs2utf8s(qdbd)); } } else { - list tl = g_dynconf->getStringList(asbdSk); - for (list::iterator it = tl.begin(); it != tl.end(); it++) - prefs.asearchSubdirHist.push_front(QString::fromUtf8(it->c_str())); + vector tl = g_dynconf->getStringEntries(asbdSk); + for (const auto& dbd: tl) { + prefs.asearchSubdirHist.push_back(u8s2qs(dbd.c_str())); + } } if (!writing) havereadsettings = true; diff --git a/src/qtgui/guiutils.h b/src/qtgui/guiutils.h index cdb5453f..93b38b5b 100644 --- a/src/qtgui/guiutils.h +++ b/src/qtgui/guiutils.h @@ -99,8 +99,8 @@ class PrefsPack { bool showResultsAsTable; // Extra query indexes. This are stored in the history file, not qt prefs - list allExtraDbs; - list activeExtraDbs; + vector allExtraDbs; + vector activeExtraDbs; // Advanced search subdir restriction: we don't activate the last value // but just remember previously entered values QStringList asearchSubdirHist; diff --git a/src/qtgui/main.cpp b/src/qtgui/main.cpp index e30c3ac9..86d976f0 100644 --- a/src/qtgui/main.cpp +++ b/src/qtgui/main.cpp @@ -101,10 +101,9 @@ bool maybeOpenDb(string &reason, bool force, bool *maindberror) if (force) rcldb->close(); rcldb->rmQueryDb(""); - for (list::const_iterator it = prefs.activeExtraDbs.begin(); - it != prefs.activeExtraDbs.end(); it++) { - LOGDEB("main: adding [" << *it << "]\n" ); - rcldb->addQueryDb(*it); + for (const auto& dbdir : prefs.activeExtraDbs) { + LOGDEB("main: adding [" << dbdir << "]\n"); + rcldb->addQueryDb(dbdir); } Rcl::Db::OpenError error; if (!rcldb->isopen() && !rcldb->open(Rcl::Db::DbRO, &error)) { diff --git a/src/qtgui/ssearch_w.cpp b/src/qtgui/ssearch_w.cpp index 2d0c97c2..145e7c27 100644 --- a/src/qtgui/ssearch_w.cpp +++ b/src/qtgui/ssearch_w.cpp @@ -300,9 +300,8 @@ bool SSearch::startSimpleSearch(const string& u8, int maxexp) sdata->setMaxExpand(maxexp); } - for (list::const_iterator it = prefs.activeExtraDbs.begin(); - it != prefs.activeExtraDbs.end(); it++) { - xml << " " << base64_encode(*it) << ""; + for (const auto& dbdir : prefs.activeExtraDbs) { + xml << " " << base64_encode(dbdir) << ""; } xml << "\n"; diff --git a/src/qtgui/uiprefs_w.cpp b/src/qtgui/uiprefs_w.cpp index 1669c4d0..e090b5f7 100644 --- a/src/qtgui/uiprefs_w.cpp +++ b/src/qtgui/uiprefs_w.cpp @@ -231,22 +231,18 @@ void UIPrefsDialog::setFromPrefs() // Initialize the extra indexes listboxes idxLV->clear(); - for (list::iterator it = prefs.allExtraDbs.begin(); - it != prefs.allExtraDbs.end(); it++) { + for (const auto& dbdir : prefs.allExtraDbs) { QListWidgetItem *item = - new QListWidgetItem(QString::fromLocal8Bit(it->c_str()), - idxLV); + new QListWidgetItem(QString::fromLocal8Bit(dbdir.c_str()), idxLV); if (item) item->setCheckState(Qt::Unchecked); } - for (list::iterator it = prefs.activeExtraDbs.begin(); - it != prefs.activeExtraDbs.end(); it++) { - QListitems = - idxLV->findItems (QString::fromLocal8Bit(it->c_str()), - Qt::MatchFixedString|Qt::MatchCaseSensitive); - for (QList::iterator it = items.begin(); - it != items.end(); it++) { - (*it)->setCheckState(Qt::Checked); + for (const auto& dbdir : prefs.activeExtraDbs) { + auto items = + idxLV->findItems (QString::fromLocal8Bit(dbdir.c_str()), + Qt::MatchFixedString|Qt::MatchCaseSensitive); + for (auto& entry : items) { + entry->setCheckState(Qt::Checked); } } idxLV->sortItems(); diff --git a/src/query/docseqhist.cpp b/src/query/docseqhist.cpp index 4a3d40e6..fda4ded2 100644 --- a/src/query/docseqhist.cpp +++ b/src/query/docseqhist.cpp @@ -14,15 +14,15 @@ * Free Software Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "docseqhist.h" + #include #include #include #include -#include -using std::list; +using std::vector; -#include "docseqhist.h" #include "rcldb.h" #include "fileudi.h" #include "base64.h" @@ -77,7 +77,7 @@ bool RclDHistoryEntry::decode(const string &value) // Old style entry found, make an udi, using the fs udi maker make_udi(fn, ipath, udi); } - LOGDEB1("RclDHistoryEntry::decode: udi [" << (udi) << "]\n" ); + LOGDEB1("RclDHistoryEntry::decode: udi [" << udi << "]\n"); return true; } @@ -89,54 +89,46 @@ bool RclDHistoryEntry::equal(const DynConfEntry& other) bool historyEnterDoc(RclDynConf *dncf, const string& udi) { - LOGDEB1("historyEnterDoc: [" << (udi) << "] into " << (dncf->getFilename()) << "\n" ); + LOGDEB1("historyEnterDoc: [" << udi << "] into " << dncf->getFilename() << + "\n"); RclDHistoryEntry ne(time(0), udi); RclDHistoryEntry scratch; return dncf->insertNew(docHistSubKey, ne, scratch, 200); } -list getDocHistory(RclDynConf* dncf) +vector getDocHistory(RclDynConf* dncf) { - return dncf->getList(docHistSubKey); + return dncf->getEntries(docHistSubKey); } - bool DocSequenceHistory::getDoc(int num, Rcl::Doc &doc, string *sh) { // Retrieve history list if (!m_hist) return false; - if (m_hlist.empty()) - m_hlist = getDocHistory(m_hist); + if (m_history.empty()) + m_history = getDocHistory(m_hist); - if (num < 0 || num >= (int)m_hlist.size()) + if (num < 0 || num >= (int)m_history.size()) return false; - int skip; - if (m_prevnum >= 0 && num >= m_prevnum) { - skip = num - m_prevnum; - } else { - skip = num; - m_it = m_hlist.begin(); - m_prevtime = -1; - } - m_prevnum = num; - while (skip--) - m_it++; + // We get the history oldest first, but our users expect newest first + RclDHistoryEntry& hentry = m_history[m_history.size() - 1 - num]; if (sh) { if (m_prevtime < 0 || - abs (float(m_prevtime) - float(m_it->unixtime)) > 86400) { - m_prevtime = m_it->unixtime; - time_t t = (time_t)(m_it->unixtime); + abs (float(m_prevtime) - float(hentry.unixtime)) > 86400) { + m_prevtime = hentry.unixtime; + time_t t = (time_t)(hentry.unixtime); *sh = string(ctime(&t)); // Get rid of the final \n in ctime sh->erase(sh->length()-1); - } else + } else { sh->erase(); + } } // For now history does not store an index id. Use empty doc as ref. Rcl::Doc idxdoc; - bool ret = m_db->getDoc(m_it->udi, idxdoc, doc); + bool ret = m_db->getDoc(hentry.udi, idxdoc, doc); if (!ret || doc.pc == -1) { doc.url = "UNKNOWN"; doc.ipath = ""; @@ -156,8 +148,8 @@ Rcl::Db *DocSequenceHistory::getDb() int DocSequenceHistory::getResCnt() { - if (m_hlist.empty()) - m_hlist = getDocHistory(m_hist); - return int(m_hlist.size()); + if (m_history.empty()) + m_history = getDocHistory(m_hist); + return int(m_history.size()); } diff --git a/src/query/docseqhist.h b/src/query/docseqhist.h index 2f2f5abc..344b4a48 100644 --- a/src/query/docseqhist.h +++ b/src/query/docseqhist.h @@ -18,6 +18,8 @@ #define _DOCSEQHIST_H_INCLUDED_ #include +#include + #include "docseq.h" #include "dynconf.h" @@ -45,7 +47,7 @@ class RclDHistoryEntry : public DynConfEntry { class DocSequenceHistory : public DocSequence { public: DocSequenceHistory(Rcl::Db *d, RclDynConf *h, const string &t) - : DocSequence(t), m_db(d), m_hist(h), m_prevnum(-1), m_prevtime(-1) {} + : DocSequence(t), m_db(d), m_hist(h) {} virtual ~DocSequenceHistory() {} virtual bool getDoc(int num, Rcl::Doc &doc, string *sh = 0); @@ -57,11 +59,9 @@ protected: private: Rcl::Db *m_db; RclDynConf *m_hist; - int m_prevnum; - time_t m_prevtime; + time_t m_prevtime{-1}; std::string m_description; // This is just an nls translated 'doc history' - std::list m_hlist; - std::list::const_iterator m_it; + std::vector m_history; }; extern bool historyEnterDoc(RclDynConf *dncf, const string& udi); diff --git a/src/query/dynconf.cpp b/src/query/dynconf.cpp index 3b273628..31f21497 100644 --- a/src/query/dynconf.cpp +++ b/src/query/dynconf.cpp @@ -60,13 +60,13 @@ bool RclDynConf::insertNew(const string &sk, DynConfEntry &n, DynConfEntry &s, for (it = names.begin(); it != names.end(); it++) { string oval; if (!m_data.get(*it, oval, sk)) { - LOGDEB("No data for " << ((*it)) << "\n" ); + LOGDEB("No data for " << *it << "\n"); continue; } s.decode(oval); if (s.equal(n)) { - LOGDEB("Erasing old entry\n" ); + LOGDEB("Erasing old entry\n"); m_data.erase(*it, sk); changed = true; } @@ -96,9 +96,9 @@ bool RclDynConf::insertNew(const string &sk, DynConfEntry &n, DynConfEntry &s, string value; n.encode(value); - LOGDEB1("Encoded value [" << (value) << "] (" << (value.size()) << ")\n" ); + LOGDEB1("Encoded value [" << value << "] (" << value.size() << ")\n"); if (!m_data.set(string(nname), value, sk)) { - LOGERR("RclDHistory::insertNew: set failed\n" ); + LOGERR("RclDHistory::insertNew: set failed\n"); return false; } return true; @@ -110,15 +110,12 @@ bool RclDynConf::eraseAll(const string &sk) LOGDEB("RclDynConf::eraseAll: not writable\n"); return false; } - vector names = m_data.getNames(sk); - vector::const_iterator it; - for (it = names.begin(); it != names.end(); it++) { - m_data.erase(*it, sk); + for (const auto& nm : m_data.getNames(sk)) { + m_data.erase(nm, sk); } return true; } - // Specialization for plain strings /////////////////////////////////// bool RclDynConf::enterString(const string sk, const string value, int maxlen) @@ -132,16 +129,6 @@ bool RclDynConf::enterString(const string sk, const string value, int maxlen) return insertNew(sk, ne, scratch, maxlen); } -list RclDynConf::getStringList(const string sk) -{ - list el = getList(sk); - list sl; - for (list::const_iterator it = el.begin(); - it != el.end(); it++) - sl.push_back(it->value); - return sl; -} - #else #include diff --git a/src/query/dynconf.h b/src/query/dynconf.h index 1374b37f..c458ba4b 100644 --- a/src/query/dynconf.h +++ b/src/query/dynconf.h @@ -41,6 +41,7 @@ #include #include +#include #include "conftree.h" #include "base64.h" @@ -110,34 +111,55 @@ class RclDynConf { */ bool insertNew(const std::string& sk, DynConfEntry &n, DynConfEntry &s, int maxlen = -1); - template std::list getList(const std::string& sk); - // Specialized methods for simple string lists, designated by the - // subkey value + // General method to extract entries. Maybe there would be a way to + // express the fact that Type should derive from DynConfEntry, not + // too sure how. We are just certain (further down) that it does + // have a decode() method. It's up to the user that they call + // insertNew() and getEntries() for the same type... + template