Move sort/filtering code out of reslist
This commit is contained in:
parent
c6b771ca99
commit
c79410da94
@ -732,8 +732,6 @@ Query_fetchone(recoll_QueryObject* self, PyObject *, PyObject *)
|
||||
printableUrl(rclconfig->getDefCharset(), doc->url,
|
||||
doc->meta[Rcl::Doc::keyurl]);
|
||||
doc->meta[Rcl::Doc::keytp] = doc->mimetype;
|
||||
doc->meta[Rcl::Doc::keymt] = doc->dmtime.empty() ?
|
||||
doc->fmtime : doc->dmtime;
|
||||
doc->meta[Rcl::Doc::keyipt] = doc->ipath;
|
||||
doc->meta[Rcl::Doc::keyfs] = doc->fbytes;
|
||||
doc->meta[Rcl::Doc::keyds] = doc->dbytes;
|
||||
|
||||
@ -27,7 +27,7 @@ def doquery(db, q):
|
||||
while query.next >= 0 and query.next < nres:
|
||||
doc = query.fetchone()
|
||||
print query.next, ":",
|
||||
for k in ("title", "url"):
|
||||
for k in ("title", "url", "mtime"):
|
||||
print k, ":", getattr(doc, k).encode('utf-8')
|
||||
abs = db.makeDocAbstract(doc, query).encode('utf-8')
|
||||
print abs
|
||||
|
||||
@ -88,7 +88,8 @@ void RclMain::init()
|
||||
QT_TR_NOOP("spreadsheet"), QT_TR_NOOP("text"),
|
||||
QT_TR_NOOP("sorted"), QT_TR_NOOP("filtered")
|
||||
};
|
||||
|
||||
DocSource::set_translations((const char *)tr("sorted").toUtf8(),
|
||||
(const char *)tr("filtered").toUtf8());
|
||||
curPreview = 0;
|
||||
asearchform = 0;
|
||||
uiprefs = 0;
|
||||
@ -258,7 +259,7 @@ void RclMain::init()
|
||||
connect(this, SIGNAL(sortDataChanged(DocSeqSortSpec)),
|
||||
resList, SLOT(setSortParams(DocSeqSortSpec)));
|
||||
connect(resList, SIGNAL(hasResults(int)), this, SLOT(resultCount(int)));
|
||||
connect(this, SIGNAL(applySortData()), resList, SLOT(setDocSource()));
|
||||
connect(this, SIGNAL(applySortData()), resList, SLOT(readDocSource()));
|
||||
if (prefs.keepSort && prefs.sortActive) {
|
||||
if (prefs.sortDesc)
|
||||
actionSortByDateDesc->setChecked(true);
|
||||
@ -542,13 +543,13 @@ void RclMain::startSearch(RefCntr<Rcl::SearchData> sdata)
|
||||
|
||||
Rcl::Query *query = new Rcl::Query(rcldb);
|
||||
query->setCollapseDuplicates(prefs.collapseDuplicates);
|
||||
|
||||
if (!query || !query->setQuery(sdata)) {
|
||||
QMessageBox::warning(0, "Recoll", tr("Can't start query: ") +
|
||||
QString::fromAscii(query->getReason().c_str()));
|
||||
QApplication::restoreOverrideCursor();
|
||||
return;
|
||||
}
|
||||
|
||||
curPreview = 0;
|
||||
DocSequenceDb *src =
|
||||
new DocSequenceDb(RefCntr<Rcl::Query>(query),
|
||||
@ -557,6 +558,9 @@ void RclMain::startSearch(RefCntr<Rcl::SearchData> sdata)
|
||||
prefs.queryReplaceAbstract);
|
||||
|
||||
resList->setDocSource(RefCntr<DocSequence>(src));
|
||||
resList->setSortParams(m_sortspec);
|
||||
resList->setFilterParams(m_filtspec);
|
||||
resList->readDocSource();
|
||||
QApplication::restoreOverrideCursor();
|
||||
}
|
||||
|
||||
@ -795,21 +799,21 @@ void RclMain::previewExposed(Preview *, int sid, int docnum)
|
||||
void RclMain::onSortDataChanged()
|
||||
{
|
||||
LOGDEB(("RclMain::onSortDataChanged()\n"));
|
||||
DocSeqSortSpec spec;
|
||||
m_sortspec.reset();
|
||||
if (actionSortByDateAsc->isChecked()) {
|
||||
spec.addCrit(DocSeqSortSpec::RCLFLD_MTIME, false);
|
||||
spec.sortdepth = 1000000;
|
||||
m_sortspec.addCrit(DocSeqSortSpec::RCLFLD_MTIME, false);
|
||||
m_sortspec.sortdepth = 1000000;
|
||||
prefs.sortActive = true;
|
||||
prefs.sortDesc = false;
|
||||
} else if (actionSortByDateDesc->isChecked()) {
|
||||
spec.addCrit(DocSeqSortSpec::RCLFLD_MTIME, true);
|
||||
spec.sortdepth = 1000000;
|
||||
m_sortspec.addCrit(DocSeqSortSpec::RCLFLD_MTIME, true);
|
||||
m_sortspec.sortdepth = 1000000;
|
||||
prefs.sortActive = true;
|
||||
prefs.sortDesc = true;
|
||||
} else {
|
||||
prefs.sortActive = prefs.sortDesc = false;
|
||||
}
|
||||
emit sortDataChanged(spec);
|
||||
emit sortDataChanged(m_sortspec);
|
||||
emit applySortData();
|
||||
}
|
||||
|
||||
@ -1158,6 +1162,9 @@ void RclMain::showDocHistory()
|
||||
string(tr("Document history").toUtf8()));
|
||||
src->setDescription((const char *)tr("History data").toUtf8());
|
||||
resList->setDocSource(RefCntr<DocSequence>(src));
|
||||
resList->setSortParams(m_sortspec);
|
||||
resList->setFilterParams(m_filtspec);
|
||||
resList->readDocSource();
|
||||
}
|
||||
|
||||
// Erase all memory of documents viewed
|
||||
@ -1204,7 +1211,7 @@ void RclMain::catgFilter(int id)
|
||||
if (id < 0 || id >= int(m_catgbutvec.size()))
|
||||
return;
|
||||
|
||||
DocSeqFiltSpec spec;
|
||||
m_filtspec.reset();
|
||||
|
||||
if (id != 0) {
|
||||
string catg = m_catgbutvec[id];
|
||||
@ -1212,11 +1219,11 @@ void RclMain::catgFilter(int id)
|
||||
rclconfig->getMimeCatTypes(catg, tps);
|
||||
for (list<string>::const_iterator it = tps.begin();
|
||||
it != tps.end(); it++)
|
||||
spec.orCrit(DocSeqFiltSpec::DSFS_MIMETYPE, *it);
|
||||
m_filtspec.orCrit(DocSeqFiltSpec::DSFS_MIMETYPE, *it);
|
||||
}
|
||||
|
||||
resList->setFilterParams(spec);
|
||||
resList->setDocSource();
|
||||
resList->setFilterParams(m_filtspec);
|
||||
resList->readDocSource();
|
||||
}
|
||||
|
||||
void RclMain::toggleFullScreen()
|
||||
|
||||
@ -120,6 +120,8 @@ private:
|
||||
QAction * m_idNoStem;
|
||||
QAction * m_idAllStem;
|
||||
bool m_idxStatusAck; // Did we act on last status?
|
||||
DocSeqFiltSpec m_filtspec;
|
||||
DocSeqSortSpec m_sortspec;
|
||||
|
||||
virtual void init();
|
||||
virtual void previewPrevOrNextInTab(Preview *, int sid, int docnum,
|
||||
|
||||
@ -40,6 +40,7 @@ SOURCES += \
|
||||
FORMS = \
|
||||
advsearch.ui \
|
||||
rclmain.ui \
|
||||
restable.ui \
|
||||
spell.ui \
|
||||
ssearchb.ui \
|
||||
uiprefs.ui \
|
||||
|
||||
@ -268,65 +268,34 @@ int ResList::newListId()
|
||||
|
||||
extern "C" int XFlush(void *);
|
||||
|
||||
void ResList::setDocSource(RefCntr<DocSequence> ndocsource)
|
||||
void ResList::setDocSource(RefCntr<DocSequence> nsource)
|
||||
{
|
||||
m_baseDocSource = ndocsource;
|
||||
setDocSource();
|
||||
m_source = RefCntr<DocSequence>(new DocSource(nsource));
|
||||
}
|
||||
|
||||
// Reapply parameters. Sort params probably changed
|
||||
void ResList::setDocSource()
|
||||
void ResList::readDocSource()
|
||||
{
|
||||
LOGDEB(("ResList::setDocSource\n"));
|
||||
if (m_baseDocSource.isNull())
|
||||
if (m_source.isNull())
|
||||
return;
|
||||
resetList();
|
||||
m_listId = newListId();
|
||||
m_docSource = m_baseDocSource;
|
||||
|
||||
// Filtering must be done before sorting, (which usually
|
||||
// truncates the original list)
|
||||
if (m_baseDocSource->canFilter()) {
|
||||
m_baseDocSource->setFiltSpec(m_filtspecs);
|
||||
} else {
|
||||
if (m_filtspecs.isNotNull()) {
|
||||
string title = m_baseDocSource->title() + " (" +
|
||||
string((const char*)tr("filtered").toUtf8()) + ")";
|
||||
m_docSource =
|
||||
RefCntr<DocSequence>(new DocSeqFiltered(m_docSource,m_filtspecs,
|
||||
title));
|
||||
}
|
||||
}
|
||||
|
||||
if (m_docSource->canSort()) {
|
||||
m_docSource->setSortSpec(m_sortspecs);
|
||||
} else {
|
||||
if (m_sortspecs.isNotNull()) {
|
||||
LOGDEB(("Reslist: sortspecs not Null\n"));
|
||||
string title = m_baseDocSource->title() + " (" +
|
||||
string((const char *)tr("sorted").toUtf8()) + ")";
|
||||
m_docSource = RefCntr<DocSequence>(new DocSeqSorted(m_docSource,
|
||||
m_sortspecs,
|
||||
title));
|
||||
}
|
||||
}
|
||||
// Reset the page size in case the preference was changed
|
||||
m_pager->setPageSize(prefs.respagesize);
|
||||
m_pager->setDocSource(m_docSource);
|
||||
m_pager->setDocSource(m_source);
|
||||
resultPageNext();
|
||||
emit hasResults(getResCnt());
|
||||
}
|
||||
|
||||
void ResList::setSortParams(DocSeqSortSpec spec)
|
||||
{
|
||||
LOGDEB(("ResList::setSortParams: %s\n", spec.isNotNull() ? "notnull":"null"));
|
||||
m_sortspecs = spec;
|
||||
m_source->setSortSpec(spec);
|
||||
}
|
||||
|
||||
void ResList::setFilterParams(const DocSeqFiltSpec& spec)
|
||||
{
|
||||
LOGDEB(("ResList::setFilterParams\n"));
|
||||
m_filtspecs = spec;
|
||||
m_source->setFiltSpec(spec);
|
||||
}
|
||||
|
||||
void ResList::resetList()
|
||||
@ -350,9 +319,9 @@ bool ResList::displayingHistory()
|
||||
// We want to reset the displayed history if it is currently
|
||||
// shown. Using the title value is an ugly hack
|
||||
string htstring = string((const char *)tr("Document history").toUtf8());
|
||||
if (m_docSource.isNull() || m_docSource->title().empty())
|
||||
if (m_source.isNull() || m_source->title().empty())
|
||||
return false;
|
||||
return m_docSource->title().find(htstring) == 0;
|
||||
return m_source->title().find(htstring) == 0;
|
||||
}
|
||||
|
||||
void ResList::languageChange()
|
||||
@ -363,14 +332,14 @@ void ResList::languageChange()
|
||||
bool ResList::getTerms(vector<string>& terms,
|
||||
vector<vector<string> >& groups, vector<int>& gslks)
|
||||
{
|
||||
return m_baseDocSource->getTerms(terms, groups, gslks);
|
||||
return m_source->getTerms(terms, groups, gslks);
|
||||
}
|
||||
|
||||
list<string> ResList::expand(Rcl::Doc& doc)
|
||||
{
|
||||
if (m_baseDocSource.isNull())
|
||||
if (m_source.isNull())
|
||||
return list<string>();
|
||||
return m_baseDocSource->expand(doc);
|
||||
return m_source->expand(doc);
|
||||
}
|
||||
|
||||
// Get document number from paragraph number
|
||||
@ -492,9 +461,9 @@ void ResList::mouseReleaseEvent(QMouseEvent *e)
|
||||
// Return total result list count
|
||||
int ResList::getResCnt()
|
||||
{
|
||||
if (m_docSource.isNull())
|
||||
if (m_source.isNull())
|
||||
return -1;
|
||||
return m_docSource->getResCnt();
|
||||
return m_source->getResCnt();
|
||||
}
|
||||
|
||||
void ResList::highlighted(const QString& )
|
||||
@ -706,10 +675,10 @@ void ResList::menuSaveToFile()
|
||||
void ResList::menuPreviewParent()
|
||||
{
|
||||
Rcl::Doc doc;
|
||||
if (!getDoc(m_popDoc, doc) || m_baseDocSource.isNull())
|
||||
if (!getDoc(m_popDoc, doc) || m_source.isNull())
|
||||
return;
|
||||
Rcl::Doc pdoc;
|
||||
if (m_baseDocSource->getEnclosing(doc, pdoc)) {
|
||||
if (m_source->getEnclosing(doc, pdoc)) {
|
||||
emit previewRequested(pdoc);
|
||||
} else {
|
||||
// No parent doc: show enclosing folder with app configured for
|
||||
@ -723,10 +692,10 @@ void ResList::menuPreviewParent()
|
||||
void ResList::menuOpenParent()
|
||||
{
|
||||
Rcl::Doc doc;
|
||||
if (!getDoc(m_popDoc, doc) || m_baseDocSource.isNull())
|
||||
if (!getDoc(m_popDoc, doc) || m_source.isNull())
|
||||
return;
|
||||
Rcl::Doc pdoc;
|
||||
if (m_baseDocSource->getEnclosing(doc, pdoc)) {
|
||||
if (m_source->getEnclosing(doc, pdoc)) {
|
||||
emit editRequested(pdoc);
|
||||
} else {
|
||||
// No parent doc: show enclosing folder with app configured for
|
||||
@ -783,13 +752,13 @@ void ResList::menuExpand()
|
||||
|
||||
QString ResList::getDescription()
|
||||
{
|
||||
return QString::fromUtf8(m_docSource->getDescription().c_str());
|
||||
return QString::fromUtf8(m_source->getDescription().c_str());
|
||||
}
|
||||
|
||||
/** Show detailed expansion of a query */
|
||||
void ResList::showQueryDetails()
|
||||
{
|
||||
string oq = breakIntoLines(m_docSource->getDescription(), 100, 50);
|
||||
string oq = breakIntoLines(m_source->getDescription(), 100, 50);
|
||||
QString desc = tr("Query details") + ": " + QString::fromUtf8(oq.c_str());
|
||||
QMessageBox::information(this, tr("Query details"), desc);
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ class ResList : public QTextBrowser
|
||||
|
||||
QString getDescription(); // Printable actual query performed on db
|
||||
int getResCnt(); // Return total result list size
|
||||
void setDocSource(RefCntr<DocSequence> ndocsource);
|
||||
void setDocSource(RefCntr<DocSequence> nsource);
|
||||
bool displayingHistory();
|
||||
bool getTerms(vector<string>& terms,
|
||||
vector<vector<string> >& groups, vector<int>& gslks);
|
||||
@ -73,7 +73,7 @@ class ResList : public QTextBrowser
|
||||
virtual void menuOpenParent();
|
||||
virtual void previewExposed(int);
|
||||
virtual void append(const QString &text);
|
||||
virtual void setDocSource();
|
||||
virtual void readDocSource();
|
||||
virtual void setSortParams(DocSeqSortSpec spec);
|
||||
virtual void setFilterParams(const DocSeqFiltSpec &spec);
|
||||
virtual void highlighted(const QString& link);
|
||||
@ -104,16 +104,9 @@ class ResList : public QTextBrowser
|
||||
virtual void showQueryDetails();
|
||||
|
||||
private:
|
||||
QtGuiResListPager *m_pager;
|
||||
// Raw doc source
|
||||
RefCntr<DocSequence> m_baseDocSource;
|
||||
// Possibly filtered/sorted docsource (the one displayed)
|
||||
RefCntr<DocSequence> m_docSource;
|
||||
// Current sort and filtering parameters
|
||||
DocSeqSortSpec m_sortspecs;
|
||||
DocSeqFiltSpec m_filtspecs;
|
||||
// Docs for current page
|
||||
std::vector<Rcl::Doc> m_curDocs;
|
||||
QtGuiResListPager *m_pager;
|
||||
RefCntr<DocSequence> m_source;
|
||||
std::vector<Rcl::Doc> m_curDocs; // Docs for current page
|
||||
|
||||
// Translate from textedit paragraph number to relative
|
||||
// docnum. Built while we insert text into the qtextedit
|
||||
@ -122,8 +115,7 @@ class ResList : public QTextBrowser
|
||||
int m_curPvDoc;// Docnum for current preview
|
||||
int m_lstClckMod; // Last click modifier.
|
||||
list<int> m_selDocs;
|
||||
int m_listId;
|
||||
|
||||
int m_listId; // query Id for matching with preview windows
|
||||
|
||||
virtual int docnumfromparnum(int);
|
||||
virtual pair<int,int> parnumfromdocnum(int);
|
||||
|
||||
28
src/qtgui/restable.cpp
Normal file
28
src/qtgui/restable.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#$Id: reslist.cpp,v 1.52 2008-12-17 15:12:08 dockes Exp $ (C) 2005 J.F.Dockes";
|
||||
#endif
|
||||
|
||||
#include "autoconfig.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "restable.h"
|
||||
|
||||
class RecollModel : public QAbstractTableModel {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RecollModel(QObject *parent = 0)
|
||||
: QAbstractTableModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
void ResTable::init()
|
||||
{
|
||||
|
||||
// Set up the columns according to the list of fields we are displaying
|
||||
}
|
||||
45
src/qtgui/restable.h
Normal file
45
src/qtgui/restable.h
Normal file
@ -0,0 +1,45 @@
|
||||
#ifndef _RESTABLE_H_INCLUDED_
|
||||
#define _RESTABLE_H_INCLUDED_
|
||||
/* @(#$Id: spell_w.h,v 1.7 2006-12-22 11:01:28 dockes Exp $ (C) 2006 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 "ui_restable.h"
|
||||
|
||||
class ResTable : public Ui::ResTable
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ResTable(QWidget* parent = 0)
|
||||
: QWidget(parent)
|
||||
{
|
||||
setupUi(this);
|
||||
init();
|
||||
}
|
||||
|
||||
~ResTable(){}
|
||||
|
||||
public slots:
|
||||
|
||||
signals:
|
||||
|
||||
private:
|
||||
void init();
|
||||
};
|
||||
|
||||
|
||||
#endif /* _RESTABLE_H_INCLUDED_ */
|
||||
59
src/qtgui/restable.ui
Normal file
59
src/qtgui/restable.ui
Normal file
@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ResTable</class>
|
||||
<widget class="QWidget" name="ResTable">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>520</width>
|
||||
<height>291</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QTableView" name="tableView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>10</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="editTriggers">
|
||||
<set>QAbstractItemView::NoEditTriggers</set>
|
||||
</property>
|
||||
<property name="sortingEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="cornerButtonEnabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QTextBrowser" name="textBrowser">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@ -17,10 +17,10 @@ static char rcsid[] = "@(#$Id: docseq.cpp,v 1.11 2008-09-29 08:59:20 dockes Exp
|
||||
* Free Software Foundation, Inc.,
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "docseq.h"
|
||||
#include "filtseq.h"
|
||||
#include "sortseq.h"
|
||||
#include "debuglog.h"
|
||||
|
||||
int DocSequence::getSeqSlice(int offs, int cnt, vector<ResListEntry>& result)
|
||||
{
|
||||
@ -35,3 +35,75 @@ int DocSequence::getSeqSlice(int offs, int cnt, vector<ResListEntry>& result)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void DocSource::unwind()
|
||||
{
|
||||
RefCntr<DocSequence> base = m_seq;
|
||||
while (!m_seq.isNull() && !(m_seq->getSourceSeq()).isNull()) {
|
||||
base = m_seq->getSourceSeq();
|
||||
}
|
||||
m_seq = base;
|
||||
}
|
||||
|
||||
bool DocSource::buildStack()
|
||||
{
|
||||
LOGDEB2(("DocSource::buildStack()\n"));
|
||||
unwind();
|
||||
|
||||
if (m_seq.isNull())
|
||||
return false;
|
||||
|
||||
// Filtering must be done before sorting, (which may
|
||||
// truncates the original list)
|
||||
if (m_seq->canFilter()) {
|
||||
if (!m_seq->setFiltSpec(m_fspec)) {
|
||||
LOGERR(("DocSource::buildStack: setfiltspec failed\n"));
|
||||
}
|
||||
} else {
|
||||
if (m_fspec.isNotNull()) {
|
||||
m_seq =
|
||||
RefCntr<DocSequence>(new DocSeqFiltered(m_seq, m_fspec));
|
||||
}
|
||||
}
|
||||
|
||||
if (m_seq->canSort()) {
|
||||
if (!m_seq->setSortSpec(m_sspec)) {
|
||||
LOGERR(("DocSource::buildStack: setsortspec failed\n"));
|
||||
}
|
||||
} else {
|
||||
if (m_sspec.isNotNull()) {
|
||||
m_seq = RefCntr<DocSequence>(new DocSeqSorted(m_seq, m_sspec));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
string DocSource::o_sort_trans;
|
||||
string DocSource::o_filt_trans;
|
||||
|
||||
string DocSource::title()
|
||||
{
|
||||
string qual;
|
||||
if (m_fspec.isNotNull() && !m_sspec.isNotNull())
|
||||
qual = string(" (") + o_filt_trans + string(")");
|
||||
else if (!m_fspec.isNotNull() && m_sspec.isNotNull())
|
||||
qual = string(" (") + o_sort_trans + string(")");
|
||||
else if (m_fspec.isNotNull() && m_sspec.isNotNull())
|
||||
qual = string(" (") + o_sort_trans + string(",") + o_filt_trans + string(")");
|
||||
return m_seq->title() + qual;
|
||||
}
|
||||
|
||||
bool DocSource::setFiltSpec(const DocSeqFiltSpec &f)
|
||||
{
|
||||
LOGDEB2(("DocSource::setFiltSpec\n"));
|
||||
m_fspec = f;
|
||||
buildStack();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DocSource::setSortSpec(const DocSeqSortSpec &s)
|
||||
{
|
||||
LOGDEB2(("DocSource::setSortSpec\n"));
|
||||
m_sspec = s;
|
||||
buildStack();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -44,8 +44,8 @@ class DocSeqSortSpec {
|
||||
crits.push_back(fld);
|
||||
dirs.push_back(desc);
|
||||
}
|
||||
bool isNotNull() {return sortdepth > 0;}
|
||||
|
||||
bool isNotNull() const {return sortdepth > 0;}
|
||||
void reset() {crits.clear(); dirs.clear();sortdepth = 0;}
|
||||
int sortdepth; // We only re-sort the first sortdepth most relevant docs
|
||||
std::vector<Field> crits;
|
||||
std::vector<bool> dirs;
|
||||
@ -64,7 +64,7 @@ class DocSeqFiltSpec {
|
||||
std::vector<Crit> crits;
|
||||
std::vector<string> values;
|
||||
void reset() {crits.clear(); values.clear();}
|
||||
bool isNotNull() {return crits.size() != 0;}
|
||||
bool isNotNull() const {return crits.size() != 0;}
|
||||
};
|
||||
|
||||
/** Interface for a list of documents coming from some source.
|
||||
@ -94,7 +94,7 @@ class DocSequence {
|
||||
virtual bool getDoc(int num, Rcl::Doc &doc, string *sh = 0) = 0;
|
||||
|
||||
/** Get next page of documents. This accumulates entries into the result
|
||||
* list (doesn't reset it). */
|
||||
* list parameter (doesn't reset it). */
|
||||
virtual int getSeqSlice(int offs, int cnt, vector<ResListEntry>& result);
|
||||
|
||||
/** Get abstract for document. This is special because it may take time.
|
||||
@ -130,14 +130,15 @@ class DocSequence {
|
||||
}
|
||||
virtual list<string> expand(Rcl::Doc &) {return list<string>();}
|
||||
|
||||
/** Optional functionality. Yeah, not nice */
|
||||
/** Optional functionality. */
|
||||
virtual bool canFilter() {return false;}
|
||||
virtual bool setFiltSpec(DocSeqFiltSpec &) {return false;}
|
||||
virtual bool canSort() {return false;}
|
||||
virtual bool setSortSpec(DocSeqSortSpec &) {return false;}
|
||||
virtual bool setFiltSpec(const DocSeqFiltSpec &) {return false;}
|
||||
virtual bool setSortSpec(const DocSeqSortSpec &) {return false;}
|
||||
virtual RefCntr<DocSequence> getSourceSeq() {return RefCntr<DocSequence>();}
|
||||
|
||||
private:
|
||||
string m_title;
|
||||
string m_title;
|
||||
};
|
||||
|
||||
/** A modifier has a child sequence which does the real work and does
|
||||
@ -145,8 +146,8 @@ class DocSequence {
|
||||
*/
|
||||
class DocSeqModifier : public DocSequence {
|
||||
public:
|
||||
DocSeqModifier(const string &t, RefCntr<DocSequence> iseq)
|
||||
: DocSequence(t), m_seq(iseq)
|
||||
DocSeqModifier(RefCntr<DocSequence> iseq)
|
||||
: DocSequence(""), m_seq(iseq)
|
||||
{}
|
||||
virtual ~DocSeqModifier() {}
|
||||
|
||||
@ -168,10 +169,45 @@ public:
|
||||
{
|
||||
m_seq->getUTerms(terms);
|
||||
}
|
||||
virtual string title() {return m_seq->title();}
|
||||
virtual RefCntr<DocSequence> getSourceSeq() {return m_seq;}
|
||||
|
||||
protected:
|
||||
RefCntr<DocSequence> m_seq;
|
||||
};
|
||||
|
||||
// A DocSource can juggle docseqs of different kinds to implement
|
||||
// sorting and filtering in ways depending on the base seqs capabilities
|
||||
class DocSource : public DocSeqModifier {
|
||||
public:
|
||||
DocSource(RefCntr<DocSequence> iseq)
|
||||
: DocSeqModifier(iseq)
|
||||
{}
|
||||
virtual bool canFilter() {return true;}
|
||||
virtual bool canSort() {return true;}
|
||||
virtual bool setFiltSpec(const DocSeqFiltSpec &);
|
||||
virtual bool setSortSpec(const DocSeqSortSpec &);
|
||||
virtual bool getDoc(int num, Rcl::Doc &doc, string *sh = 0)
|
||||
{
|
||||
return m_seq->getDoc(num, doc, sh);
|
||||
}
|
||||
virtual int getResCnt()
|
||||
{
|
||||
return m_seq->getResCnt();
|
||||
}
|
||||
static void set_translations(const string& sort, const string& filt)
|
||||
{
|
||||
o_sort_trans = sort;
|
||||
o_filt_trans = filt;
|
||||
}
|
||||
virtual string title();
|
||||
private:
|
||||
bool buildStack();
|
||||
void unwind();
|
||||
DocSeqFiltSpec m_fspec;
|
||||
DocSeqSortSpec m_sspec;
|
||||
static string o_sort_trans;
|
||||
static string o_filt_trans;
|
||||
};
|
||||
|
||||
#endif /* _DOCSEQ_H_INCLUDED_ */
|
||||
|
||||
@ -28,7 +28,7 @@ static char rcsid[] = "@(#$Id: docseqdb.cpp,v 1.9 2008-11-13 10:57:46 dockes Exp
|
||||
DocSequenceDb::DocSequenceDb(RefCntr<Rcl::Query> q, const string &t,
|
||||
RefCntr<Rcl::SearchData> sdata)
|
||||
: DocSequence(t), m_q(q), m_sdata(sdata), m_fsdata(sdata),
|
||||
m_rescnt(-1), m_filt(false),
|
||||
m_rescnt(-1),
|
||||
m_queryBuildAbstract(true),
|
||||
m_queryReplaceAbstract(false)
|
||||
{
|
||||
@ -98,39 +98,31 @@ list<string> DocSequenceDb::expand(Rcl::Doc &doc)
|
||||
return m_q->expand(doc);
|
||||
}
|
||||
|
||||
bool DocSequenceDb::setFiltSpec(DocSeqFiltSpec &fs)
|
||||
bool DocSequenceDb::setFiltSpec(const DocSeqFiltSpec &fs)
|
||||
{
|
||||
if (!fs.isNotNull()) {
|
||||
m_fsdata = m_sdata;
|
||||
m_filt = false;
|
||||
return m_q->setQuery(m_sdata);
|
||||
}
|
||||
|
||||
// We build a search spec by adding a filtering layer to the base one.
|
||||
m_fsdata = RefCntr<Rcl::SearchData>(new Rcl::SearchData(Rcl::SCLT_AND));
|
||||
Rcl::SearchDataClauseSub *cl =
|
||||
new Rcl::SearchDataClauseSub(Rcl::SCLT_SUB, m_sdata);
|
||||
m_fsdata->addClause(cl);
|
||||
LOGDEB(("DocSequenceDb::setFiltSpec\n"));
|
||||
if (fs.isNotNull()) {
|
||||
// We build a search spec by adding a filtering layer to the base one.
|
||||
m_fsdata = RefCntr<Rcl::SearchData>(new Rcl::SearchData(Rcl::SCLT_AND));
|
||||
Rcl::SearchDataClauseSub *cl =
|
||||
new Rcl::SearchDataClauseSub(Rcl::SCLT_SUB, m_sdata);
|
||||
m_fsdata->addClause(cl);
|
||||
|
||||
for (unsigned int i = 0; i < fs.crits.size(); i++) {
|
||||
switch (fs.crits[i]) {
|
||||
case DocSeqFiltSpec::DSFS_MIMETYPE:
|
||||
m_fsdata->addFiletype(fs.values[i]);
|
||||
for (unsigned int i = 0; i < fs.crits.size(); i++) {
|
||||
switch (fs.crits[i]) {
|
||||
case DocSeqFiltSpec::DSFS_MIMETYPE:
|
||||
m_fsdata->addFiletype(fs.values[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_fsdata = m_sdata;
|
||||
}
|
||||
m_filt = true;
|
||||
return m_q->setQuery(m_fsdata);
|
||||
}
|
||||
|
||||
// Need a way to access the translations for filtered ...
|
||||
string DocSequenceDb::title()
|
||||
{
|
||||
LOGDEB(("DOcSequenceDb::title()\n"));
|
||||
return m_filt ? DocSequence::title() + " (filtered)" : DocSequence::title();
|
||||
}
|
||||
|
||||
bool DocSequenceDb::setSortSpec(DocSeqSortSpec &sortspec)
|
||||
bool DocSequenceDb::setSortSpec(const DocSeqSortSpec &sortspec)
|
||||
{
|
||||
LOGDEB(("DocSequenceDb::setSortSpec\n"));
|
||||
if (sortspec.isNotNull()) {
|
||||
bool ascending = false;
|
||||
for (unsigned int i = 0; i < sortspec.crits.size(); i++) {
|
||||
@ -149,3 +141,7 @@ bool DocSequenceDb::setSortSpec(DocSeqSortSpec &sortspec)
|
||||
return m_q->setQuery(m_fsdata);
|
||||
}
|
||||
|
||||
bool DocSequenceDb::setQuery()
|
||||
{
|
||||
return m_q->setQuery(m_fsdata);
|
||||
}
|
||||
|
||||
@ -41,10 +41,10 @@ class DocSequenceDb : public DocSequence {
|
||||
virtual string getDescription();
|
||||
virtual list<string> expand(Rcl::Doc &doc);
|
||||
virtual bool canFilter() {return true;}
|
||||
virtual bool setFiltSpec(DocSeqFiltSpec &filtspec);
|
||||
virtual bool setFiltSpec(const DocSeqFiltSpec &filtspec);
|
||||
virtual bool canSort() {return true;}
|
||||
virtual bool setSortSpec(DocSeqSortSpec &sortspec);
|
||||
virtual string title();
|
||||
virtual bool setSortSpec(const DocSeqSortSpec &sortspec);
|
||||
virtual bool setQuery();
|
||||
virtual void setAbstractParams(bool qba, bool qra)
|
||||
{
|
||||
m_queryBuildAbstract = qba;
|
||||
@ -56,7 +56,6 @@ class DocSequenceDb : public DocSequence {
|
||||
RefCntr<Rcl::SearchData> m_sdata;
|
||||
RefCntr<Rcl::SearchData> m_fsdata; // Filtered
|
||||
int m_rescnt;
|
||||
bool m_filt;
|
||||
bool m_queryBuildAbstract;
|
||||
bool m_queryReplaceAbstract;
|
||||
};
|
||||
|
||||
@ -40,13 +40,6 @@ static bool filter(const DocSeqFiltSpec& fs, const Rcl::Doc *x)
|
||||
return 0;
|
||||
}
|
||||
|
||||
DocSeqFiltered::DocSeqFiltered(RefCntr<DocSequence> iseq,
|
||||
DocSeqFiltSpec &filtspec,
|
||||
const std::string &t)
|
||||
: DocSeqModifier(t, iseq), m_spec(filtspec)
|
||||
{
|
||||
}
|
||||
|
||||
bool DocSeqFiltered::setFiltSpec(DocSeqFiltSpec &filtspec)
|
||||
{
|
||||
m_spec = filtspec;
|
||||
@ -59,7 +52,7 @@ bool DocSeqFiltered::getDoc(int idx, Rcl::Doc &doc, string *)
|
||||
LOGDEB1(("DocSeqFiltered: fetching %d\n", idx));
|
||||
|
||||
if (idx >= (int)m_dbindices.size()) {
|
||||
// Have to fetch xapian docs and filter until we get enough or
|
||||
// Have to fetch docs and filter until we get enough or
|
||||
// fail
|
||||
m_dbindices.reserve(idx+1);
|
||||
|
||||
|
||||
@ -30,9 +30,10 @@
|
||||
* according to the given criteria.
|
||||
*/
|
||||
class DocSeqFiltered : public DocSeqModifier {
|
||||
public:
|
||||
DocSeqFiltered(RefCntr<DocSequence> iseq, DocSeqFiltSpec &filtspec,
|
||||
const std::string &t);
|
||||
public:
|
||||
DocSeqFiltered(RefCntr<DocSequence> iseq, DocSeqFiltSpec &filtspec)
|
||||
: DocSeqModifier(iseq), m_spec(filtspec)
|
||||
{}
|
||||
virtual ~DocSeqFiltered() {}
|
||||
virtual bool canFilter() {return true;}
|
||||
virtual bool setFiltSpec(DocSeqFiltSpec &filtspec);
|
||||
|
||||
@ -68,13 +68,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
DocSeqSorted::DocSeqSorted(RefCntr<DocSequence> iseq, DocSeqSortSpec &sortspec,
|
||||
const std::string &t)
|
||||
: DocSeqModifier(t, iseq)
|
||||
{
|
||||
setSortSpec(sortspec);
|
||||
}
|
||||
|
||||
bool DocSeqSorted::setSortSpec(DocSeqSortSpec &sortspec)
|
||||
{
|
||||
m_spec = sortspec;
|
||||
|
||||
@ -30,8 +30,11 @@
|
||||
*/
|
||||
class DocSeqSorted : public DocSeqModifier {
|
||||
public:
|
||||
DocSeqSorted(RefCntr<DocSequence> iseq, DocSeqSortSpec &sortspec,
|
||||
const std::string &t);
|
||||
DocSeqSorted(RefCntr<DocSequence> iseq, DocSeqSortSpec &sortspec)
|
||||
: DocSeqModifier(iseq)
|
||||
{
|
||||
setSortSpec(sortspec);
|
||||
}
|
||||
virtual ~DocSeqSorted() {}
|
||||
virtual bool canSort() {return true;}
|
||||
virtual bool setSortSpec(DocSeqSortSpec &sortspec);
|
||||
|
||||
@ -253,7 +253,7 @@ string Db::Native::makeAbstract(Xapian::docid docid, Query *query)
|
||||
for (list<string>::const_iterator qit = qterms.begin();
|
||||
qit != qterms.end(); qit++) {
|
||||
query->m_nq->termfreqs[*qit] = xrdb.get_termfreq(*qit) / doccnt;
|
||||
LOGDEB(("makeAbstract: [%s] db freq %.1e\n", qit->c_str(),
|
||||
LOGABS(("makeAbstract: [%s] db freq %.1e\n", qit->c_str(),
|
||||
query->m_nq->termfreqs[*qit]));
|
||||
}
|
||||
LOGABS(("makeAbstract:%d: got termfreqs\n", chron.ms()));
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user