--- a
+++ b/src/qtgui/advshist.cpp
@@ -0,0 +1,253 @@
+/* Copyright (C) 2005 J.F.Dockes
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "autoconfig.h"
+
+#include "advshist.h"
+#include "guiutils.h"
+#include "debuglog.h"
+
+#include <QtXml/QXmlDefaultHandler>
+
+using namespace std;
+using namespace Rcl;
+
+class SDHXMLHandler : public QXmlDefaultHandler {
+public:
+ SDHXMLHandler()
+ : slack(0)
+ {
+ }
+ bool startElement(const QString & /* namespaceURI */,
+ const QString & /* localName */,
+ const QString &qName,
+ const QXmlAttributes &attributes);
+ bool endElement(const QString & /* namespaceURI */,
+ const QString & /* localName */,
+ const QString &qName);
+ bool characters(const QString &str)
+ {
+ currentText += str;
+ return true;
+ }
+
+ // The object we set up
+ RefCntr<SearchData> sd;
+
+private:
+ void resetTemps()
+ {
+ currentText = whatclause = "";
+ text.clear();
+ field.clear();
+ slack = 0;
+ d = m = y = di.d1 = di.m1 = di.y1 = di.d2 = di.m2 = di.y2 = 0;
+ hasdates = false;
+ }
+
+ // Temporary data while parsing.
+ QString currentText;
+ QString whatclause;
+ string field, text;
+ int slack;
+ int d, m, y;
+ DateInterval di;
+ bool hasdates;
+};
+
+bool SDHXMLHandler::startElement(const QString & /* namespaceURI */,
+ const QString & /* localName */,
+ const QString &qName,
+ const QXmlAttributes &)
+{
+ LOGDEB2(("SDHXMLHandler::startElement: name [%s]\n",
+ (const char *)qName.toAscii()));
+ if (qName == "SD") {
+ resetTemps();
+ // A new search descriptor. Allocate data structure
+ sd = RefCntr<SearchData>(new SearchData);
+ if (sd.isNull()) {
+ LOGERR(("SDHXMLHandler::startElement: out of memory\n"));
+ return false;
+ }
+ }
+ return true;
+}
+
+bool SDHXMLHandler::endElement(const QString & /* namespaceURI */,
+ const QString & /* localName */,
+ const QString &qName)
+{
+ LOGDEB2(("SDHXMLHandler::endElement: name [%s]\n",
+ (const char *)qName.toAscii()));
+
+ if (qName == "CLT") {
+ if (currentText == "OR") {
+ sd->setTp(SCLT_OR);
+ }
+ } else if (qName == "CT") {
+ whatclause = currentText.trimmed();
+ } else if (qName == "F") {
+ field = base64_decode(qs2utf8s(currentText.trimmed()));
+ } else if (qName == "T") {
+ text = base64_decode(qs2utf8s(currentText.trimmed()));
+ } else if (qName == "S") {
+ slack = atoi((const char *)currentText.toAscii());
+ } else if (qName == "C") {
+ SearchDataClauseSimple *c;
+ if (whatclause == "AND" || whatclause.isEmpty()) {
+ c = new SearchDataClauseSimple(SCLT_AND, text, field);
+ } else if (whatclause == "OR") {
+ c = new SearchDataClauseSimple(SCLT_OR, text, field);
+ } else if (whatclause == "EX") {
+ c = new SearchDataClauseSimple(SCLT_EXCL, text, field);
+ } else if (whatclause == "FN") {
+ c = new SearchDataClauseFilename(text);
+ } else if (whatclause == "PH") {
+ c = new SearchDataClauseDist(SCLT_PHRASE, text, slack, field);
+ } else if (whatclause == "NE") {
+ c = new SearchDataClauseDist(SCLT_NEAR, text, slack, field);
+ } else {
+ LOGERR(("Bad clause type [%s]\n", qs2utf8s(whatclause).c_str()));
+ return false;
+ }
+ sd->addClause(c);
+ whatclause = "";
+ text.clear();
+ field.clear();
+ slack = 0;
+ } else if (qName == "D") {
+ d = atoi((const char *)currentText.toAscii());
+ } else if (qName == "M") {
+ m = atoi((const char *)currentText.toAscii());
+ } else if (qName == "Y") {
+ y = atoi((const char *)currentText.toAscii());
+ } else if (qName == "DMI") {
+ di.d1 = d;
+ di.m1 = m;
+ di.y1 = y;
+ hasdates = true;
+ } else if (qName == "DMA") {
+ di.d2 = d;
+ di.m2 = m;
+ di.y2 = y;
+ hasdates = true;
+ } else if (qName == "MIS") {
+ sd->setMinSize(atoll((const char *)currentText.toAscii()));
+ } else if (qName == "MAS") {
+ sd->setMaxSize(atoll((const char *)currentText.toAscii()));
+ } else if (qName == "ST") {
+ string types = (const char *)currentText.toAscii();
+ vector<string> vt;
+ stringToTokens(types, vt);
+ for (unsigned int i = 0; i < vt.size(); i++)
+ sd->addFiletype(vt[i]);
+ } else if (qName == "IT") {
+ string types = (const char *)currentText.toAscii();
+ vector<string> vt;
+ stringToTokens(types, vt);
+ for (unsigned int i = 0; i < vt.size(); i++)
+ sd->remFiletype(vt[i]);
+ } else if (qName == "YD") {
+ string d;
+ base64_decode((const char*)currentText.trimmed().toAscii(), d);
+ sd->addDirSpec(d);
+ } else if (qName == "ND") {
+ string d;
+ base64_decode((const char*)currentText.trimmed().toAscii(), d);
+ sd->addDirSpec(d, true);
+ } else if (qName == "SD") {
+ // Closing current search descriptor. Finishing touches...
+ if (hasdates)
+ sd->setDateSpan(&di);
+ resetTemps();
+ }
+ currentText.clear();
+ return true;
+}
+
+
+AdvSearchHist::AdvSearchHist()
+{
+ read();
+ m_current = -1;
+}
+
+AdvSearchHist::~AdvSearchHist()
+{
+ for (vector<RefCntr<SearchData> >::iterator it = m_entries.begin();
+ it != m_entries.end(); it++) {
+ it->release();
+ }
+}
+
+RefCntr<Rcl::SearchData> AdvSearchHist::getolder()
+{
+ m_current++;
+ if (m_current >= int(m_entries.size())) {
+ m_current--;
+ return RefCntr<Rcl::SearchData>();
+ }
+ return m_entries[m_current];
+}
+
+RefCntr<Rcl::SearchData> AdvSearchHist::getnewer()
+{
+ if (m_current == -1 || m_current == 0 || m_entries.empty())
+ return RefCntr<Rcl::SearchData>();
+ return m_entries[--m_current];
+}
+
+bool AdvSearchHist::push(RefCntr<SearchData> sd)
+{
+ m_entries.insert(m_entries.begin(), sd);
+ if (m_current != -1)
+ m_current++;
+
+ string xml = sd->asXML();
+ g_dynconf->enterString(advSearchHistSk, xml, 100);
+ return true;
+}
+
+bool AdvSearchHist::read()
+{
+ if (!g_dynconf)
+ return false;
+ list<string> lxml = g_dynconf->getStringList(advSearchHistSk);
+
+ for (list<string>::const_iterator it = lxml.begin(); it != lxml.end();
+ it++) {
+ SDHXMLHandler handler;
+ QXmlSimpleReader reader;
+ reader.setContentHandler(&handler);
+ reader.setErrorHandler(&handler);
+ QXmlInputSource xmlInputSource;
+ xmlInputSource.setData(QString::fromUtf8(it->c_str()));
+ if (!reader.parse(xmlInputSource)) {
+ LOGERR(("AdvSearchHist::read: parse failed for [%s]\n",
+ it->c_str()));
+ return false;
+ }
+ m_entries.push_back(handler.sd);
+ }
+ return true;
+}
+
+void AdvSearchHist::clear()
+{
+ g_dynconf->eraseAll(advSearchHistSk);
+}