diff --git a/src/query/reslistpager.cpp b/src/query/reslistpager.cpp index a12d151b..1d8e26bb 100644 --- a/src/query/reslistpager.cpp +++ b/src/query/reslistpager.cpp @@ -27,6 +27,15 @@ public: }; static PlainToRichHtReslist g_hiliter; +ResListPager::ResListPager(int pagesize) + : m_pagesize(pagesize), + m_newpagesize(pagesize), + m_winfirst(-1), + m_hasNext(false), + m_hiliter(&g_hiliter) +{ +} + void ResListPager::resultPageNext() { if (m_docSource.isNull()) { @@ -69,6 +78,136 @@ void ResListPager::resultPageNext() m_respage = npage; } +void ResListPager::displayDoc(int i, Rcl::Doc& doc, const HiliteData& hdata, + const string& sh) +{ + ostringstream chunk; + int percent; + if (doc.pc == -1) { + percent = 0; + // Document not available, maybe other further, will go on. + doc.meta[Rcl::Doc::keyabs] = string(trans("Unavailable document")); + } else { + percent = doc.pc; + } + // Percentage of 'relevance' + char perbuf[20]; + sprintf(perbuf, "%3d%% ", percent); + + // Determine icon to display if any + string iconpath = iconPath(doc.mimetype); + + // Printable url: either utf-8 if transcoding succeeds, or url-encoded + string url; + printableUrl(RclConfig::getMainConfig()->getDefCharset(), doc.url, url); + + // Make title out of file name if none yet + if (doc.meta[Rcl::Doc::keytt].empty()) { + doc.meta[Rcl::Doc::keytt] = path_getsimple(url); + } + + // Result number + char numbuf[20]; + int docnumforlinks = m_winfirst + 1 + i; + sprintf(numbuf, "%d", docnumforlinks); + + // Document date: either doc or file modification time + char datebuf[100]; + datebuf[0] = 0; + if (!doc.dmtime.empty() || !doc.fmtime.empty()) { + time_t mtime = doc.dmtime.empty() ? + atol(doc.fmtime.c_str()) : atol(doc.dmtime.c_str()); + struct tm *tm = localtime(&mtime); +#ifndef sun + strftime(datebuf, 99, " %Y-%m-%d %H:%M:%S %z", tm); +#else + strftime(datebuf, 99, " %Y-%m-%d %H:%M:%S %Z", tm); +#endif + } + + // Size information. We print both doc and file if they differ a lot + long fsize = -1, dsize = -1; + if (!doc.dbytes.empty()) + dsize = atol(doc.dbytes.c_str()); + if (!doc.fbytes.empty()) + fsize = atol(doc.fbytes.c_str()); + string sizebuf; + if (dsize > 0) { + sizebuf = displayableBytes(dsize); + if (fsize > 10 * dsize && fsize - dsize > 1000) + sizebuf += string(" / ") + displayableBytes(fsize); + } else if (fsize >= 0) { + sizebuf = displayableBytes(fsize); + } + + string abstract; + if (m_docSource.isNotNull()) + abstract = m_docSource->getAbstract(doc); + + // No need to call escapeHtml(), plaintorich handles it + list lr; + m_hiliter->set_inputhtml(false); + m_hiliter->plaintorich(abstract, lr, hdata); + string richabst = lr.front(); + + // Links; + ostringstream linksbuf; + if (canIntern(doc.mimetype, RclConfig::getMainConfig())) { + linksbuf << "" + << trans("Preview") << "  "; + } + + string apptag; + map::const_iterator it; + if ((it = doc.meta.find(Rcl::Doc::keyapptg)) != doc.meta.end()) + apptag = it->second; + + if (!RclConfig::getMainConfig()->getMimeViewerDef(doc.mimetype, apptag).empty()) { + linksbuf << "" + << trans("Open") << ""; + } + + // Build the result list paragraph: + + // Subheader: this is used by history + if (!sh.empty()) + chunk << "

" << sh << "

\n

"; + else + 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() ? + string("[") + escapeHtml(doc.meta[Rcl::Doc::keykw]) + "]" : ""; + subs["L"] = linksbuf.rdbuf()->str(); + 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); + chunk << formatted; + + chunk << "

" << endl; + // This was to force qt 4.x to clear the margins (which it should do + // anyway because of the paragraph's style), but we finally took + // the table approach for 1.15 for now (in guiutils.cpp) +// chunk << "
" << endl; + + LOGDEB2(("Chunk: [%s]\n", (const char *)chunk.rdbuf()->str().c_str())); + append(chunk.rdbuf()->str(), i, doc); +} + void ResListPager::displayPage() { LOGDEB(("ResListPager::displayPage\n")); @@ -80,8 +219,6 @@ void ResListPager::displayPage() LOGDEB(("ResListPager::displayPage: sequence error: winfirst < 0\n")); return; } - if (m_hiliter == 0) - m_hiliter = &g_hiliter; ostringstream chunk; @@ -160,132 +297,9 @@ void ResListPager::displayPage() // Emit data for result entry paragraph. Do it in chunks that make sense // html-wise, else our client may get confused for (int i = 0; i < (int)m_respage.size(); i++) { - Rcl::Doc &doc(m_respage[i].doc); string& sh(m_respage[i].subHeader); - int percent; - if (doc.pc == -1) { - percent = 0; - // Document not available, maybe other further, will go on. - doc.meta[Rcl::Doc::keyabs] = string(trans("Unavailable document")); - } else { - percent = doc.pc; - } - // Percentage of 'relevance' - char perbuf[20]; - sprintf(perbuf, "%3d%% ", percent); - - // Determine icon to display if any - string iconpath = iconPath(doc.mimetype); - - // Printable url: either utf-8 if transcoding succeeds, or url-encoded - string url; - printableUrl(RclConfig::getMainConfig()->getDefCharset(), doc.url, url); - - // Make title out of file name if none yet - if (doc.meta[Rcl::Doc::keytt].empty()) { - doc.meta[Rcl::Doc::keytt] = path_getsimple(url); - } - - // Result number - char numbuf[20]; - int docnumforlinks = m_winfirst + 1 + i; - sprintf(numbuf, "%d", docnumforlinks); - - // Document date: either doc or file modification time - char datebuf[100]; - datebuf[0] = 0; - if (!doc.dmtime.empty() || !doc.fmtime.empty()) { - time_t mtime = doc.dmtime.empty() ? - atol(doc.fmtime.c_str()) : atol(doc.dmtime.c_str()); - struct tm *tm = localtime(&mtime); -#ifndef sun - strftime(datebuf, 99, " %Y-%m-%d %H:%M:%S %z", tm); -#else - strftime(datebuf, 99, " %Y-%m-%d %H:%M:%S %Z", tm); -#endif - } - - // Size information. We print both doc and file if they differ a lot - long fsize = -1, dsize = -1; - if (!doc.dbytes.empty()) - dsize = atol(doc.dbytes.c_str()); - if (!doc.fbytes.empty()) - fsize = atol(doc.fbytes.c_str()); - string sizebuf; - if (dsize > 0) { - sizebuf = displayableBytes(dsize); - if (fsize > 10 * dsize && fsize - dsize > 1000) - sizebuf += string(" / ") + displayableBytes(fsize); - } else if (fsize >= 0) { - sizebuf = displayableBytes(fsize); - } - - string abstract = m_docSource->getAbstract(doc); - - // No need to call escapeHtml(), plaintorich handles it - list lr; - m_hiliter->set_inputhtml(false); - m_hiliter->plaintorich(abstract, lr, hdata); - string richabst = lr.front(); - - // Links; - ostringstream linksbuf; - if (canIntern(doc.mimetype, RclConfig::getMainConfig())) { - linksbuf << "" - << trans("Preview") << "  "; - } - - string apptag; - map::const_iterator it; - if ((it = doc.meta.find(Rcl::Doc::keyapptg)) != doc.meta.end()) - apptag = it->second; - - if (!RclConfig::getMainConfig()->getMimeViewerDef(doc.mimetype, apptag).empty()) { - linksbuf << "" - << trans("Open") << ""; - } - - // Build the result list paragraph: - - // Subheader: this is used by history - if (!sh.empty()) - chunk << "

" << sh << "

\n

"; - else - 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() ? - string("[") + escapeHtml(doc.meta[Rcl::Doc::keykw]) + "]" : ""; - subs["L"] = linksbuf.rdbuf()->str(); - 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); - chunk << formatted; - - chunk << "

" << endl; - // This was to force qt 4.x to clear the margins (which it should do - // anyway because of the paragraph's style), but we finally took - // the table approach for 1.15 for now (in guiutils.cpp) -// chunk << "
" << endl; - - LOGDEB2(("Chunk: [%s]\n", (const char *)chunk.rdbuf()->str().c_str())); - append(chunk.rdbuf()->str(), i, doc); - chunk.rdbuf()->str(""); + displayDoc(i, doc, hdata, sh); } // Footer diff --git a/src/query/reslistpager.h b/src/query/reslistpager.h index 25b530a6..c274587e 100644 --- a/src/query/reslistpager.h +++ b/src/query/reslistpager.h @@ -9,20 +9,14 @@ using std::vector; #include "docseq.h" class PlainToRich; +class HiliteData; /** * Manage a paged HTML result list. */ class ResListPager { public: - ResListPager(int pagesize=10) : - m_pagesize(pagesize), - m_newpagesize(pagesize), - m_winfirst(-1), - m_hasNext(false), - m_hiliter(0) - { - } + ResListPager(int pagesize=10); virtual ~ResListPager() {} void setHighLighter(PlainToRich *ptr) @@ -64,6 +58,8 @@ public: } void resultPageNext(); void displayPage(); + void displayDoc(int idx, Rcl::Doc& doc, const HiliteData& hdata, + const string& sh = ""); bool pageEmpty() {return m_respage.size() == 0;} string queryDescription() {return m_docSource.isNull() ? "" :