diff --git a/src/qtgui/rclmain_w.cpp b/src/qtgui/rclmain_w.cpp index 41267c82..b7a15780 100644 --- a/src/qtgui/rclmain_w.cpp +++ b/src/qtgui/rclmain_w.cpp @@ -529,6 +529,9 @@ void RclMain::startSearch(RefCntr sdata) DocSequenceDb *src = new DocSequenceDb(RefCntr(query), string(tr("Query results").utf8()), sdata); + src->setAbstractParams(prefs.queryBuildAbstract, + prefs.queryReplaceAbstract); + resList->setDocSource(RefCntr(src)); QApplication::restoreOverrideCursor(); } diff --git a/src/query/docseqdb.cpp b/src/query/docseqdb.cpp index 0e677bc4..2512fa82 100644 --- a/src/query/docseqdb.cpp +++ b/src/query/docseqdb.cpp @@ -27,7 +27,9 @@ static char rcsid[] = "@(#$Id: docseqdb.cpp,v 1.9 2008-11-13 10:57:46 dockes Exp DocSequenceDb::DocSequenceDb(RefCntr q, const string &t, RefCntr sdata) : DocSequence(t), m_q(q), m_sdata(sdata), m_fsdata(sdata), - m_rescnt(-1), m_filt(false) + m_rescnt(-1), m_filt(false), + m_queryBuildAbstract(true), + m_queryReplaceAbstract(false) { } @@ -66,7 +68,13 @@ string DocSequenceDb::getAbstract(Rcl::Doc &doc) if (!m_q->whatDb()) return doc.meta[Rcl::Doc::keyabs]; string abstract; - m_q->whatDb()->makeDocAbstract(doc, m_q.getptr(), abstract); + + if (m_queryBuildAbstract && (doc.syntabs || m_queryReplaceAbstract)) { + m_q->whatDb()->makeDocAbstract(doc, m_q.getptr(), abstract); + } else { + abstract = doc.meta[Rcl::Doc::keyabs]; + } + return abstract.empty() ? doc.meta[Rcl::Doc::keyabs] : abstract; } diff --git a/src/query/docseqdb.h b/src/query/docseqdb.h index 981a2ac9..d7fa224e 100644 --- a/src/query/docseqdb.h +++ b/src/query/docseqdb.h @@ -43,12 +43,20 @@ class DocSequenceDb : public DocSequence { virtual bool canSort() {return false;} virtual bool setSortSpec(DocSeqSortSpec &sortspec); virtual string title(); + virtual void setAbstractParams(bool qba, bool qra) + { + m_queryBuildAbstract = qba; + m_queryReplaceAbstract = qra; + } + private: RefCntr m_q; RefCntr m_sdata; RefCntr m_fsdata; // Filtered int m_rescnt; bool m_filt; + bool m_queryBuildAbstract; + bool m_queryReplaceAbstract; }; #endif /* _DOCSEQDB_H_INCLUDED_ */ diff --git a/src/query/reslistpager.cpp b/src/query/reslistpager.cpp index 13a90a60..537a7c69 100644 --- a/src/query/reslistpager.cpp +++ b/src/query/reslistpager.cpp @@ -201,12 +201,8 @@ void ResListPager::displayPage() sizebuf = displayableBytes(fsize); } - string abstract; - if (m_queryBuildAbstract && (doc.syntabs || m_queryReplaceAbstract)) { - abstract = m_docSource->getAbstract(doc); - } else { - abstract = doc.meta[Rcl::Doc::keyabs]; - } + string abstract = m_docSource->getAbstract(doc); + // No need to call escapeHtml(), plaintorich handles it list lr; m_hiliter->set_inputhtml(false); @@ -237,20 +233,23 @@ void ResListPager::displayPage() chunk += "

"; // Configurable stuff - map subs; - subs['A'] = !richabst.empty() ? richabst + "
" : ""; - subs['D'] = datebuf; - subs['I'] = iconpath; - subs['i'] = doc.ipath; - subs['K'] = !doc.meta[Rcl::Doc::keykw].empty() ? + map subs; + subs["A"] = !richabst.empty() ? richabst + "
" : ""; + subs["D"] = datebuf; + subs["I"] = iconpath; + subs["i"] = doc.ipath; + subs["K"] = !doc.meta[Rcl::Doc::keykw].empty() ? escapeHtml(doc.meta[Rcl::Doc::keykw]) + "
" : ""; - subs['L'] = linksbuf; - subs['N'] = numbuf; - subs['M'] = doc.mimetype; - subs['R'] = perbuf; - subs['S'] = sizebuf; - subs['T'] = escapeHtml(doc.meta[Rcl::Doc::keytt]); - subs['U'] = url; + subs["L"] = linksbuf; + subs["N"] = numbuf; + subs["M"] = doc.mimetype; + subs["R"] = perbuf; + subs["S"] = sizebuf; + subs["T"] = escapeHtml(doc.meta[Rcl::Doc::keytt]); + subs["U"] = url; + + // Let %(xx) access all metadata. + subs.insert(doc.meta.begin(), doc.meta.end()); string formatted; pcSubst(parFormat(), formatted, subs); @@ -281,10 +280,13 @@ void ResListPager::displayPage() append(chunk); } +// Default implementations for things that should be implemented by +// specializations string ResListPager::nextUrl() { return "n-1"; } + string ResListPager::prevUrl() { return "p-1"; @@ -298,7 +300,6 @@ string ResListPager::iconPath(const string& mtype) return iconpath; } -// Default implementations for things that should be re-implemented by our user. bool ResListPager::append(const string& data) { fprintf(stderr, "%s", data.c_str()); diff --git a/src/query/reslistpager.h b/src/query/reslistpager.h index 648f2572..fddb6000 100644 --- a/src/query/reslistpager.h +++ b/src/query/reslistpager.h @@ -16,12 +16,6 @@ class PlainToRich; class ResListPager { public: ResListPager(int pagesize=10) : m_pagesize(pagesize) {initall();} - ResListPager(RefCntr src, int pagesize) - : m_pagesize(pagesize) - { - initall(); - m_docSource = src; - } virtual ~ResListPager() {} void setHighLighter(PlainToRich *ptr) {m_hiliter = ptr;} @@ -79,8 +73,6 @@ private: m_winfirst = -1; m_hasNext = false; m_respage.clear(); - m_queryBuildAbstract = true; - m_queryReplaceAbstract = false; m_hiliter = 0; } @@ -91,8 +83,6 @@ private: bool m_hasNext; vector m_respage; - bool m_queryBuildAbstract; - bool m_queryReplaceAbstract; PlainToRich *m_hiliter; }; diff --git a/src/utils/Makefile b/src/utils/Makefile index dfc8542b..a1b09a58 100644 --- a/src/utils/Makefile +++ b/src/utils/Makefile @@ -72,12 +72,14 @@ trmimeparse.o : mimeparse.cpp $(CXX) $(ALL_CXXFLAGS) -DTEST_MIMEPARSE -c -o trmimeparse.o \ mimeparse.cpp -SMALLUT_OBJS= trsmallut.o $(BIGLIB) -smallut : $(SMALLUT_OBJS) +SMALLUT_OBJS= trsmallut.o ../lib/smallut.o +smallut : $(SMALLUT_OBJS) smallut.h $(CXX) $(ALL_CXXFLAGS) -o smallut $(SMALLUT_OBJS) $(LIBICONV) -trsmallut.o : smallut.cpp +trsmallut.o : smallut.cpp smallut.h $(CXX) $(ALL_CXXFLAGS) -DTEST_SMALLUT -c -o trsmallut.o \ smallut.cpp +../lib/smallut.o: smallut.cpp smallut.h + cd ../lib;make smallut.o WIPEDIR_OBJS= trwipedir.o $(BIGLIB) wipedir : $(WIPEDIR_OBJS) diff --git a/src/utils/smallut.cpp b/src/utils/smallut.cpp index 2b3193a5..2dc00185 100644 --- a/src/utils/smallut.cpp +++ b/src/utils/smallut.cpp @@ -492,7 +492,8 @@ bool pcSubst(const string& in, string& out, map& subs) if ((tr = subs.find(*it)) != subs.end()) { out += tr->second; } else { - out += *it; + // We used to do "out += *it;" here but this does not make + // sense } } else { out += *it; @@ -501,6 +502,52 @@ bool pcSubst(const string& in, string& out, map& subs) return true; } +bool pcSubst(const string& in, string& out, map& subs) +{ + out.erase(); + string::size_type i; + for (i = 0; i < in.size(); i++) { + if (in[i] == '%') { + if (++i == in.size()) { + out += '%'; + break; + } + if (in[i] == '%') { + out += '%'; + continue; + } + string key = ""; + if (in[i] == '(') { + if (++i == in.size()) { + out += string("%("); + break; + } + string::size_type j = in.find_first_of(")", i); + if (j == string::npos) { + // ??concatenate remaining part and stop + out += in.substr(i-2); + break; + } + key = in.substr(i, j-i); + i = j; + } else { + key = in[i]; + } + map::iterator tr; + if ((tr = subs.find(key)) != subs.end()) { + out += tr->second; + } else { + // Substitute to nothing, that's the reasonable thing to do + // instead of keeping the %(key) + // out += key.size()==1? key : string("(") + key + string(")"); + } + } else { + out += in[i]; + } + } + return true; +} + // Convert byte count into unit (KB/MB...) appropriate for display string displayableBytes(long size) { @@ -712,11 +759,34 @@ int main(int argc, char **argv) utf8truncate(testit, sz); cout << testit << endl; } -#elif 1 +#elif 0 std::string testit("ligne\ndeuxieme ligne\r3eme ligne\r\n"); cout << "[" << neutchars(testit, "\r\n") << "]" << endl; string i, o; cout << "neutchars(null) is [" << neutchars(i, "\r\n") << "]" << endl; +#elif 1 + map substs; + substs["a"] = "A_SUBST"; + substs["title"] = "TITLE_SUBST"; + string in = "a: %a title: %(title) pcpc: %% %"; + string out; + pcSubst(in, out, substs); + cout << in << " => " << out << endl; + + in = "unfinished: %(unfinished"; + pcSubst(in, out, substs); + cout << in << " => " << out << endl; + in = "unfinished: %("; + pcSubst(in, out, substs); + cout << in << " => " << out << endl; + in = "empty: %()"; + pcSubst(in, out, substs); + cout << in << " => " << out << endl; + substs.clear(); + in = "a: %a title: %(title) pcpc: %% %"; + pcSubst(in, out, substs); + cout << "After map clear: " << in << " => " << out << endl; + #endif } diff --git a/src/utils/smallut.h b/src/utils/smallut.h index 84504051..1b499f56 100644 --- a/src/utils/smallut.h +++ b/src/utils/smallut.h @@ -102,6 +102,8 @@ string breakIntoLines(const string& in, unsigned int ll = 100, unsigned int maxlines= 50); /** Small utility to substitute printf-like percents cmds in a string */ bool pcSubst(const string& in, string& out, map& subs); +/** Substitute printf-like percents and also %(key) */ +bool pcSubst(const string& in, string& out, map& subs); class Chrono { public: