preliminary implementation for the snippets "open to page" popup window

This commit is contained in:
Jean-Francois Dockes 2012-09-20 13:51:40 +02:00
parent ab85754757
commit c2dab20d7e
15 changed files with 349 additions and 35 deletions

View file

@ -25,6 +25,7 @@
#include <stdio.h> #include <stdio.h>
#include <QComboBox>
#include <qvariant.h> #include <qvariant.h>
#include <qwidget.h> #include <qwidget.h>

View file

@ -301,6 +301,7 @@ void RclMain::init()
connect(restable, SIGNAL(docSaveToFileClicked(Rcl::Doc)), connect(restable, SIGNAL(docSaveToFileClicked(Rcl::Doc)),
this, SLOT(saveDocToFile(Rcl::Doc))); this, SLOT(saveDocToFile(Rcl::Doc)));
reslist->setRclMain(this);
connect(this, SIGNAL(docSourceChanged(RefCntr<DocSequence>)), connect(this, SIGNAL(docSourceChanged(RefCntr<DocSequence>)),
reslist, SLOT(setDocSource(RefCntr<DocSequence>))); reslist, SLOT(setDocSource(RefCntr<DocSequence>)));
connect(firstPageAction, SIGNAL(activated()), connect(firstPageAction, SIGNAL(activated()),
@ -1501,8 +1502,9 @@ static bool lookForHtmlBrowser(string &exefile)
return false; return false;
} }
void RclMain::startNativeViewer(Rcl::Doc doc) void RclMain::startNativeViewer(Rcl::Doc doc, int pagenum)
{ {
LOGDEB(("RclMain::startNativeViewer: page %d\n", pagenum));
// Look for appropriate viewer // Look for appropriate viewer
string cmdplusattr; string cmdplusattr;
if (prefs.useDesktopOpen) { if (prefs.useDesktopOpen) {
@ -1520,11 +1522,13 @@ void RclMain::startNativeViewer(Rcl::Doc doc)
return; return;
} }
int pagenum = 1; if (pagenum == -1) {
if (m_source.isNotNull())
pagenum = m_source->getFirstMatchPage(doc);
if (pagenum == -1)
pagenum = 1; pagenum = 1;
if (m_source.isNotNull())
pagenum = m_source->getFirstMatchPage(doc);
if (pagenum == -1)
pagenum = 1;
}
char cpagenum[20]; char cpagenum[20];
sprintf(cpagenum, "%d", pagenum); sprintf(cpagenum, "%d", pagenum);

View file

@ -119,7 +119,7 @@ public slots:
virtual void docExpand(Rcl::Doc); virtual void docExpand(Rcl::Doc);
virtual void startPreview(int docnum, Rcl::Doc doc, int keymods); virtual void startPreview(int docnum, Rcl::Doc doc, int keymods);
virtual void startPreview(Rcl::Doc); virtual void startPreview(Rcl::Doc);
virtual void startNativeViewer(Rcl::Doc); virtual void startNativeViewer(Rcl::Doc, int pagenum = -1);
virtual void saveDocToFile(Rcl::Doc); virtual void saveDocToFile(Rcl::Doc);
virtual void previewNextInTab(Preview *, int sid, int docnum); virtual void previewNextInTab(Preview *, int sid, int docnum);
virtual void previewPrevInTab(Preview *, int sid, int docnum); virtual void previewPrevInTab(Preview *, int sid, int docnum);

View file

@ -25,6 +25,7 @@ HEADERS += \
restable.h \ restable.h \
rtitool.h \ rtitool.h \
searchclause_w.h \ searchclause_w.h \
snippets_w.h \
spell_w.h \ spell_w.h \
ssearch_w.h \ ssearch_w.h \
uiprefs_w.h \ uiprefs_w.h \
@ -46,6 +47,7 @@ SOURCES += \
restable.cpp \ restable.cpp \
rtitool.cpp \ rtitool.cpp \
searchclause_w.cpp \ searchclause_w.cpp \
snippets_w.cpp \
spell_w.cpp \ spell_w.cpp \
ssearch_w.cpp \ ssearch_w.cpp \
uiprefs_w.cpp \ uiprefs_w.cpp \
@ -64,6 +66,7 @@ FORMS = \
restable.ui \ restable.ui \
rtitool.ui \ rtitool.ui \
spell.ui \ spell.ui \
snippets.ui \
ssearchb.ui \ ssearchb.ui \
uiprefs.ui \ uiprefs.ui \
viewaction.ui \ viewaction.ui \

View file

@ -50,6 +50,7 @@
#include "refcntr.h" #include "refcntr.h"
#include "internfile.h" #include "internfile.h"
#include "indexer.h" #include "indexer.h"
#include "snippets_w.h"
#include "reslist.h" #include "reslist.h"
#include "moc_reslist.cpp" #include "moc_reslist.cpp"
@ -272,7 +273,7 @@ static PlainToRichQtReslist g_hiliter;
///////////////////////////////////// /////////////////////////////////////
ResList::ResList(QWidget* parent, const char* name) ResList::ResList(QWidget* parent, const char* name)
: RESLIST_PARENTCLASS(parent) : RESLIST_PARENTCLASS(parent), m_parent(0)
{ {
if (!name) if (!name)
setObjectName("resList"); setObjectName("resList");
@ -892,6 +893,8 @@ void ResList::createPopupMenu(const QPoint& pos)
this, SLOT(menuPreviewParent())); this, SLOT(menuPreviewParent()));
popup->addAction(tr("&Open Parent document/folder"), popup->addAction(tr("&Open Parent document/folder"),
this, SLOT(menuOpenParent())); this, SLOT(menuOpenParent()));
popup->addAction(tr("Open &Snippets window"),
this, SLOT(menuOpenSnippets()));
popup->popup(mapToGlobal(pos)); popup->popup(mapToGlobal(pos));
} }
@ -943,6 +946,20 @@ void ResList::menuOpenParent()
} }
} }
void ResList::menuOpenSnippets()
{
Rcl::Doc doc;
if (!getDoc(m_popDoc, doc) || m_source.isNull())
return;
SnippetsW *sp = new SnippetsW(doc, m_source);
if (m_parent) {
connect(sp, SIGNAL(startNativeViewer(Rcl::Doc, int)),
m_parent, SLOT(startNativeViewer(Rcl::Doc, int)));
}
sp->show();
}
void ResList::menuEdit() void ResList::menuEdit()
{ {
Rcl::Doc doc; Rcl::Doc doc;

View file

@ -41,6 +41,7 @@ using std::pair;
#include "rcldoc.h" #include "rcldoc.h"
#include "reslistpager.h" #include "reslistpager.h"
class RclMain;
class QtGuiResListPager; class QtGuiResListPager;
/** /**
@ -66,7 +67,10 @@ class ResList : public RESLIST_PARENTCLASS
int listId() const {return m_listId;} int listId() const {return m_listId;}
int pageFirstDocNum(); int pageFirstDocNum();
void setFont(); void setFont();
void setRclMain(RclMain *m)
{
m_parent = m;
}
public slots: public slots:
virtual void setDocSource(RefCntr<DocSequence> nsource); virtual void setDocSource(RefCntr<DocSequence> nsource);
virtual void resetList(); // Erase current list virtual void resetList(); // Erase current list
@ -84,6 +88,7 @@ class ResList : public RESLIST_PARENTCLASS
virtual void menuExpand(); virtual void menuExpand();
virtual void menuPreviewParent(); virtual void menuPreviewParent();
virtual void menuOpenParent(); virtual void menuOpenParent();
virtual void menuOpenSnippets();
virtual void previewExposed(int); virtual void previewExposed(int);
virtual void append(const QString &text); virtual void append(const QString &text);
virtual void readDocSource(); virtual void readDocSource();
@ -132,6 +137,7 @@ class ResList : public RESLIST_PARENTCLASS
// so we store the page and display it when done. // so we store the page and display it when done.
QString m_text; QString m_text;
#endif #endif
RclMain *m_parent;
virtual void displayPage(); // Display current page virtual void displayPage(); // Display current page
static int newListId(); static int newListId();

67
src/qtgui/snippets.ui Normal file
View file

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Snippets</class>
<widget class="QDialog" name="Snippets">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>516</width>
<height>395</height>
</rect>
</property>
<property name="windowTitle">
<string>Snippets</string>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QWebView" name="webView">
<property name="url">
<url>
<string>about:blank</string>
</url>
</property>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Close</set>
</property>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QWebView</class>
<extends>QWidget</extends>
<header>QtWebKit/QWebView</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>clicked(QAbstractButton*)</signal>
<receiver>Snippets</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>257</x>
<y>369</y>
</hint>
<hint type="destinationlabel">
<x>257</x>
<y>197</y>
</hint>
</hints>
</connection>
</connections>
</ui>

109
src/qtgui/snippets_w.cpp Normal file
View file

@ -0,0 +1,109 @@
/* Copyright (C) 2012 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 <unistd.h>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std;
#include "debuglog.h"
#include "recoll.h"
#include "snippets_w.h"
#include "guiutils.h"
#include "rcldb.h"
#include "rclhelp.h"
#include "plaintorich.h"
class PlainToRichQtSnippets : public PlainToRich {
public:
virtual string startMatch(unsigned int)
{
return string("<span class='rclmatch' style='color: ")
+ string((const char *)prefs.qtermcolor.toAscii()) + string("'>");
}
virtual string endMatch()
{
return string("</span>");
}
};
static PlainToRichQtSnippets g_hiliter;
void SnippetsW::init()
{
if (m_source.isNull())
return;
vector<pair<int, string> > vpabs;
m_source->getAbstract(m_doc, vpabs);
HighlightData hdata;
m_source->getTerms(hdata);
QString html = QString::fromAscii(
"<html><head>"
"<meta http-equiv=\"content-type\" "
"content=\"text/html; charset=utf-8\"></head>"
"<body style='overflow-x: scroll; white-space: nowrap'>");
g_hiliter.set_inputhtml(false);
for (vector<pair<int, string> >::const_iterator it = vpabs.begin();
it != vpabs.end(); it++) {
if (it->first > 0) {
char buf[100];
sprintf(buf, "P. %d", it->first);
html += "<a href=\"";
html += buf;
html += "\">";
html += buf;
html += "</a> ";
}
list<string> lr;
g_hiliter.plaintorich(it->second, lr, hdata);
html.append(QString::fromUtf8(lr.front().c_str()));
html.append("<br>\n");
}
html.append("</body></html>");
webView->setHtml(html);
connect(webView, SIGNAL(linkClicked(const QUrl &)),
this, SLOT(linkWasClicked(const QUrl &)));
webView->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
}
void SnippetsW::linkWasClicked(const QUrl &url)
{
string ascurl = (const char *)url.toString().toAscii();;
LOGDEB(("Snippets::linkWasClicked: [%s]\n", ascurl.c_str()));
if (ascurl.size() > 3) {
int what = ascurl[0];
switch (what) {
case 'P':
{
int page = atoi(ascurl.c_str()+2);
emit startNativeViewer(m_doc, page);
return;
}
}
}
LOGERR(("Snippets::linkWasClicked: bad link [%s]\n", ascurl.c_str()));
}

50
src/qtgui/snippets_w.h Normal file
View file

@ -0,0 +1,50 @@
/* Copyright (C) 2012 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.
*/
#ifndef _SNIPPETS_W_H_INCLUDED_
#define _SNIPPETS_W_H_INCLUDED_
#include "rcldoc.h"
#include "refcntr.h"
#include "docseq.h"
#include "rclmain_w.h"
#include "ui_snippets.h"
class SnippetsW : public QWidget, public Ui::Snippets
{
Q_OBJECT
public:
SnippetsW(Rcl::Doc doc, RefCntr<DocSequence> source, QWidget* parent = 0)
: QWidget(parent), m_doc(doc), m_source(source)
{
setupUi((QDialog*)this);
init();
}
protected slots:
virtual void linkWasClicked(const QUrl &);
signals:
void startNativeViewer(Rcl::Doc, int pagenum);
private:
void init();
Rcl::Doc m_doc;
RefCntr<DocSequence> m_source;
};
#endif /* _SNIPPETS_W_H_INCLUDED_ */

View file

@ -95,6 +95,14 @@ class DocSequence {
abs.push_back(doc.meta[Rcl::Doc::keyabs]); abs.push_back(doc.meta[Rcl::Doc::keyabs]);
return true; return true;
} }
virtual bool getAbstract(Rcl::Doc& doc,
std::vector<std::pair<int, std::string> >& abs)
{
fprintf(stderr, "DocSequence::getAbstract/pair\n");
abs.push_back(std::pair<int, std::string>(0,
doc.meta[Rcl::Doc::keyabs]));
return true;
}
virtual int getFirstMatchPage(Rcl::Doc&) virtual int getFirstMatchPage(Rcl::Doc&)
{ {
return -1; return -1;
@ -157,6 +165,13 @@ public:
return false; return false;
return m_seq->getAbstract(doc, abs); return m_seq->getAbstract(doc, abs);
} }
virtual bool getAbstract(Rcl::Doc& doc,
std::vector<std::pair<int, std::string> >& abs)
{
if (m_seq.isNull())
return false;
return m_seq->getAbstract(doc, abs);
}
virtual std::string getDescription() virtual std::string getDescription()
{ {
if (m_seq.isNull()) if (m_seq.isNull())

View file

@ -65,6 +65,19 @@ int DocSequenceDb::getResCnt()
return m_rescnt; return m_rescnt;
} }
bool DocSequenceDb::getAbstract(Rcl::Doc &doc,
vector<pair<int, string> >& vpabs)
{
LOGDEB(("DocSequenceDb::getAbstract/pair\n"));
setQuery();
if (m_q->whatDb() &&
m_queryBuildAbstract && (doc.syntabs || m_queryReplaceAbstract)) {
m_q->whatDb()->makeDocAbstract(doc, m_q.getptr(), vpabs);
}
if (vpabs.empty())
vpabs.push_back(pair<int, string>(0, doc.meta[Rcl::Doc::keyabs]));
return true;
}
bool DocSequenceDb::getAbstract(Rcl::Doc &doc, vector<string>& vabs) bool DocSequenceDb::getAbstract(Rcl::Doc &doc, vector<string>& vabs)
{ {
setQuery(); setQuery();

View file

@ -31,6 +31,7 @@ class DocSequenceDb : public DocSequence {
virtual bool getDoc(int num, Rcl::Doc &doc, string * = 0); virtual bool getDoc(int num, Rcl::Doc &doc, string * = 0);
virtual int getResCnt(); virtual int getResCnt();
virtual void getTerms(HighlightData& hld); virtual void getTerms(HighlightData& hld);
virtual bool getAbstract(Rcl::Doc &doc, vector<pair<int, string> >&);
virtual bool getAbstract(Rcl::Doc &doc, vector<string>&); virtual bool getAbstract(Rcl::Doc &doc, vector<string>&);
virtual int getFirstMatchPage(Rcl::Doc&); virtual int getFirstMatchPage(Rcl::Doc&);
virtual bool getEnclosing(Rcl::Doc& doc, Rcl::Doc& pdoc); virtual bool getEnclosing(Rcl::Doc& doc, Rcl::Doc& pdoc);

View file

@ -415,7 +415,8 @@ int Db::Native::getFirstMatchPage(Xapian::docid docid, Query *query)
// //
// DatabaseModified and other general exceptions are catched and // DatabaseModified and other general exceptions are catched and
// possibly retried by our caller // possibly retried by our caller
vector<string> Db::Native::makeAbstract(Xapian::docid docid, Query *query) bool Db::Native::makeAbstract(Xapian::docid docid, Query *query,
vector<pair<int, string> >& vabs)
{ {
Chrono chron; Chrono chron;
LOGDEB2(("makeAbstract:%d: maxlen %d wWidth %d\n", chron.ms(), LOGDEB2(("makeAbstract:%d: maxlen %d wWidth %d\n", chron.ms(),
@ -429,7 +430,7 @@ vector<string> Db::Native::makeAbstract(Xapian::docid docid, Query *query)
noPrefixList(iterms, matchedTerms); noPrefixList(iterms, matchedTerms);
if (matchedTerms.empty()) { if (matchedTerms.empty()) {
LOGDEB(("makeAbstract::Empty term list\n")); LOGDEB(("makeAbstract::Empty term list\n"));
return vector<string>(); return false;
} }
} }
listList("Match terms: ", matchedTerms); listList("Match terms: ", matchedTerms);
@ -452,7 +453,7 @@ vector<string> Db::Native::makeAbstract(Xapian::docid docid, Query *query)
// This can't happen, but would crash us // This can't happen, but would crash us
if (totalweight == 0.0) { if (totalweight == 0.0) {
LOGERR(("makeAbstract: totalweight == 0.0 !\n")); LOGERR(("makeAbstract: totalweight == 0.0 !\n"));
return vector<string>(); return false;
} }
/////////////////// ///////////////////
@ -466,7 +467,7 @@ vector<string> Db::Native::makeAbstract(Xapian::docid docid, Query *query)
map<unsigned int, string> sparseDoc; map<unsigned int, string> sparseDoc;
// Total number of occurences for all terms. We stop when we have too much // Total number of occurences for all terms. We stop when we have too much
int totaloccs = 0; unsigned int totaloccs = 0;
// Limit the total number of slots we populate. The 7 is taken as // Limit the total number of slots we populate. The 7 is taken as
// average word size. It was a mistake to have the user max // average word size. It was a mistake to have the user max
@ -563,7 +564,7 @@ vector<string> Db::Native::makeAbstract(Xapian::docid docid, Query *query)
// etc. but not elsewhere ? // etc. but not elsewhere ?
if (totaloccs == 0) { if (totaloccs == 0) {
LOGDEB1(("makeAbstract: no occurrences\n")); LOGDEB1(("makeAbstract: no occurrences\n"));
return vector<string>(); return false;
} }
// Walk all document's terms position lists and populate slots // Walk all document's terms position lists and populate slots
@ -632,21 +633,19 @@ vector<string> Db::Native::makeAbstract(Xapian::docid docid, Query *query)
LOGABS(("makeAbstract:%d: extracting. Got %u pages\n", chron.millis(), LOGABS(("makeAbstract:%d: extracting. Got %u pages\n", chron.millis(),
vpbreaks.size())); vpbreaks.size()));
// Finally build the abstract by walking the map (in order of position) // Finally build the abstract by walking the map (in order of position)
vector<string> vabs; vabs.clear();
string chunk; string chunk;
bool incjk = false; bool incjk = false;
int page = 0;
for (map<unsigned int, string>::const_iterator it = sparseDoc.begin(); for (map<unsigned int, string>::const_iterator it = sparseDoc.begin();
it != sparseDoc.end(); it++) { it != sparseDoc.end(); it++) {
LOGDEB2(("Abtract:output %u -> [%s]\n", it->first,it->second.c_str())); LOGDEB2(("Abtract:output %u -> [%s]\n", it->first,it->second.c_str()));
if (!occupiedmarker.compare(it->second)) if (!occupiedmarker.compare(it->second))
continue; continue;
if (chunk.empty() && !vpbreaks.empty()) { if (chunk.empty() && !vpbreaks.empty()) {
int pnum = getPageNumberForPosition(vpbreaks, it->first); page = getPageNumberForPosition(vpbreaks, it->first);
if (pnum > 0) { if (page < 0)
ostringstream ss; page = 0;
ss << pnum;
chunk += string(" [p ") + ss.str() + "] ";
}
} }
Utf8Iter uit(it->second); Utf8Iter uit(it->second);
bool newcjk = false; bool newcjk = false;
@ -656,17 +655,17 @@ vector<string> Db::Native::makeAbstract(Xapian::docid docid, Query *query)
chunk += " "; chunk += " ";
incjk = newcjk; incjk = newcjk;
if (it->second == cstr_ellipsis) { if (it->second == cstr_ellipsis) {
vabs.push_back(chunk); vabs.push_back(pair<int,string>(page, chunk));
chunk.clear(); chunk.clear();
} else { } else {
chunk += it->second; chunk += it->second;
} }
} }
if (!chunk.empty()) if (!chunk.empty())
vabs.push_back(chunk); vabs.push_back(pair<int, string>(page, chunk));
LOGDEB2(("makeAbtract: done in %d mS\n", chron.millis())); LOGDEB2(("makeAbtract: done in %d mS\n", chron.millis()));
return vabs; return true;
} }
/* Rcl::Db methods ///////////////////////////////// */ /* Rcl::Db methods ///////////////////////////////// */
@ -2120,31 +2119,54 @@ bool Db::stemDiffers(const string& lang, const string& word,
return true; return true;
} }
bool Db::makeDocAbstract(Doc &doc, Query *query, vector<string>& abstract) bool Db::makeDocAbstract(Doc &doc, Query *query,
vector<pair<int, string> >& abstract)
{ {
LOGDEB1(("Db::makeDocAbstract: exti %d\n", exti));
if (!m_ndb || !m_ndb->m_isopen) { if (!m_ndb || !m_ndb->m_isopen) {
LOGERR(("Db::makeDocAbstract: no db\n")); LOGERR(("Db::makeDocAbstract: no db\n"));
return false; return false;
} }
XAPTRY(abstract = m_ndb->makeAbstract(doc.xdocid, query), bool ret = false;
XAPTRY(ret = m_ndb->makeAbstract(doc.xdocid, query, abstract),
m_ndb->xrdb, m_reason); m_ndb->xrdb, m_reason);
return m_reason.empty() ? true : false; return (ret && m_reason.empty()) ? true : false;
}
bool Db::makeDocAbstract(Doc &doc, Query *query, vector<string>& abstract)
{
if (!m_ndb || !m_ndb->m_isopen) {
LOGERR(("Db::makeDocAbstract: no db\n"));
return false;
}
vector<pair<int, string> > vpabs;
if (!makeDocAbstract(doc, query, vpabs))
return false;
for (vector<pair<int, string> >::const_iterator it = vpabs.begin();
it != vpabs.end(); it++) {
string chunk;
if (it->first > 0) {
ostringstream ss;
ss << it->first;
chunk += string(" [p ") + ss.str() + "] ";
}
chunk += it->second;
abstract.push_back(chunk);
}
return true;
} }
bool Db::makeDocAbstract(Doc &doc, Query *query, string& abstract) bool Db::makeDocAbstract(Doc &doc, Query *query, string& abstract)
{ {
LOGDEB1(("Db::makeDocAbstract: exti %d\n", exti));
if (!m_ndb || !m_ndb->m_isopen) { if (!m_ndb || !m_ndb->m_isopen) {
LOGERR(("Db::makeDocAbstract: no db\n")); LOGERR(("Db::makeDocAbstract: no db\n"));
return false; return false;
} }
vector<string> vab; vector<pair<int, string> > vpabs;
XAPTRY(vab = m_ndb->makeAbstract(doc.xdocid, query), if (!makeDocAbstract(doc, query, vpabs))
m_ndb->xrdb, m_reason); return false;
for (vector<string>::const_iterator it = vab.begin(); for (vector<pair<int, string> >::const_iterator it = vpabs.begin();
it != vab.end(); it++) { it != vpabs.end(); it++) {
abstract.append(*it); abstract.append(it->second);
abstract.append(cstr_ellipsis); abstract.append(cstr_ellipsis);
} }
return m_reason.empty() ? true : false; return m_reason.empty() ? true : false;

View file

@ -223,8 +223,13 @@ class Db {
/** Build synthetic abstract for document, extracting chunks relevant for /** Build synthetic abstract for document, extracting chunks relevant for
* the input query. This uses index data only (no access to the file) */ * the input query. This uses index data only (no access to the file) */
// Abstract return as one string
bool makeDocAbstract(Doc &doc, Query *query, string& abstract); bool makeDocAbstract(Doc &doc, Query *query, string& abstract);
// Returned as a snippets vector
bool makeDocAbstract(Doc &doc, Query *query, vector<string>& abstract); bool makeDocAbstract(Doc &doc, Query *query, vector<string>& abstract);
// Returned as a vector of page,snippet page is 0 if unknown
bool makeDocAbstract(Doc &doc, Query *query,
vector<pair<int, string> >& abstract);
/** Retrieve detected page breaks positions */ /** Retrieve detected page breaks positions */
int getFirstMatchPage(Doc &doc, Query *query); int getFirstMatchPage(Doc &doc, Query *query);

View file

@ -89,7 +89,8 @@ class Db::Native {
const vector<string>& terms, const vector<string>& terms,
std::multimap<double, string>& byQ); std::multimap<double, string>& byQ);
void setDbWideQTermsFreqs(Query *query); void setDbWideQTermsFreqs(Query *query);
vector<string> makeAbstract(Xapian::docid id, Query *query); bool makeAbstract(Xapian::docid id, Query *query,
vector<pair<int, string> >&);
bool getPagePositions(Xapian::docid docid, vector<int>& vpos); bool getPagePositions(Xapian::docid docid, vector<int>& vpos);
int getFirstMatchPage(Xapian::docid docid, Query *query); int getFirstMatchPage(Xapian::docid docid, Query *query);
int getPageNumberForPosition(const vector<int>& pbreaks, unsigned int pos); int getPageNumberForPosition(const vector<int>& pbreaks, unsigned int pos);