diff --git a/src/lib/Makefile b/src/lib/Makefile index ec15a09b..1f80b9ea 100644 --- a/src/lib/Makefile +++ b/src/lib/Makefile @@ -8,8 +8,8 @@ LIBS = librcl.a all: $(LIBS) -OBJS = rclaspell.o rclconfig.o rclinit.o textsplit.o unacpp.o csguess.o indexer.o mimetype.o htmlparse.o myhtmlparse.o mimehandler.o internfile.o mh_exec.o mh_html.o mh_mail.o mh_mbox.o mh_text.o docseq.o docseqdb.o docseqhist.o history.o recollq.o sortseq.o wasastringtoquery.o wasatorcl.o pathhash.o rcldb.o rcldoc.o rclquery.o searchdata.o stemdb.o stoplist.o base64.o conftree.o copyfile.o debuglog.o execmd.o fstreewalk.o idfile.o fileudi.o md5.o mimeparse.o pathut.o readfile.o smallut.o transcode.o wipedir.o x11mon.o -DEPS = rclaspell.dep.stamp rclconfig.dep.stamp rclinit.dep.stamp textsplit.dep.stamp unacpp.dep.stamp csguess.dep.stamp indexer.dep.stamp mimetype.dep.stamp htmlparse.dep.stamp myhtmlparse.dep.stamp mimehandler.dep.stamp internfile.dep.stamp mh_exec.dep.stamp mh_html.dep.stamp mh_mail.dep.stamp mh_mbox.dep.stamp mh_text.dep.stamp docseq.dep.stamp docseqdb.dep.stamp docseqhist.dep.stamp history.dep.stamp recollq.dep.stamp sortseq.dep.stamp wasastringtoquery.dep.stamp wasatorcl.dep.stamp pathhash.dep.stamp rcldb.dep.stamp rcldoc.dep.stamp rclquery.dep.stamp searchdata.dep.stamp stemdb.dep.stamp stoplist.dep.stamp base64.dep.stamp conftree.dep.stamp copyfile.dep.stamp debuglog.dep.stamp execmd.dep.stamp fstreewalk.dep.stamp idfile.dep.stamp fileudi.dep.stamp md5.dep.stamp mimeparse.dep.stamp pathut.dep.stamp readfile.dep.stamp smallut.dep.stamp transcode.dep.stamp wipedir.dep.stamp x11mon.dep.stamp +OBJS = rclaspell.o rclconfig.o rclinit.o textsplit.o unacpp.o csguess.o indexer.o mimetype.o htmlparse.o myhtmlparse.o mimehandler.o internfile.o mh_exec.o mh_html.o mh_mail.o mh_mbox.o mh_text.o docseq.o docseqdb.o docseqhist.o history.o recollq.o sortseq.o filtseq.o wasastringtoquery.o wasatorcl.o pathhash.o rcldb.o rcldoc.o rclquery.o searchdata.o stemdb.o stoplist.o base64.o conftree.o copyfile.o debuglog.o execmd.o fstreewalk.o idfile.o fileudi.o md5.o mimeparse.o pathut.o readfile.o smallut.o transcode.o wipedir.o x11mon.o +DEPS = rclaspell.dep.stamp rclconfig.dep.stamp rclinit.dep.stamp textsplit.dep.stamp unacpp.dep.stamp csguess.dep.stamp indexer.dep.stamp mimetype.dep.stamp htmlparse.dep.stamp myhtmlparse.dep.stamp mimehandler.dep.stamp internfile.dep.stamp mh_exec.dep.stamp mh_html.dep.stamp mh_mail.dep.stamp mh_mbox.dep.stamp mh_text.dep.stamp docseq.dep.stamp docseqdb.dep.stamp docseqhist.dep.stamp history.dep.stamp recollq.dep.stamp sortseq.dep.stamp filtseq.dep.stamp wasastringtoquery.dep.stamp wasatorcl.dep.stamp pathhash.dep.stamp rcldb.dep.stamp rcldoc.dep.stamp rclquery.dep.stamp searchdata.dep.stamp stemdb.dep.stamp stoplist.dep.stamp base64.dep.stamp conftree.dep.stamp copyfile.dep.stamp debuglog.dep.stamp execmd.dep.stamp fstreewalk.dep.stamp idfile.dep.stamp fileudi.dep.stamp md5.dep.stamp mimeparse.dep.stamp pathut.dep.stamp readfile.dep.stamp smallut.dep.stamp transcode.dep.stamp wipedir.dep.stamp x11mon.dep.stamp librcl.a : $(DEPS) $(OBJS) unac.o ar ru librcl.a $(OBJS) unac.o @@ -63,6 +63,8 @@ recollq.o : ../query/recollq.cpp $(CXX) $(ALL_CXXFLAGS) -c ../query/recollq.cpp sortseq.o : ../query/sortseq.cpp $(CXX) $(ALL_CXXFLAGS) -c ../query/sortseq.cpp +filtseq.o : ../query/filtseq.cpp + $(CXX) $(ALL_CXXFLAGS) -c ../query/filtseq.cpp wasastringtoquery.o : ../query/wasastringtoquery.cpp $(CXX) $(ALL_CXXFLAGS) -c ../query/wasastringtoquery.cpp wasatorcl.o : ../query/wasatorcl.cpp @@ -188,6 +190,9 @@ recollq.dep.stamp : ../query/recollq.cpp sortseq.dep.stamp : ../query/sortseq.cpp $(CXX) -M $(ALL_CXXFLAGS) ../query/sortseq.cpp > sortseq.dep touch sortseq.dep.stamp +filtseq.dep.stamp : ../query/filtseq.cpp + $(CXX) -M $(ALL_CXXFLAGS) ../query/filtseq.cpp > filtseq.dep + touch filtseq.dep.stamp wasastringtoquery.dep.stamp : ../query/wasastringtoquery.cpp $(CXX) -M $(ALL_CXXFLAGS) ../query/wasastringtoquery.cpp > wasastringtoquery.dep touch wasastringtoquery.dep.stamp @@ -286,6 +291,7 @@ include docseqhist.dep include history.dep include recollq.dep include sortseq.dep +include filtseq.dep include wasastringtoquery.dep include wasatorcl.dep include pathhash.dep diff --git a/src/lib/mkMake b/src/lib/mkMake index 96a2d8ac..38acc06e 100755 --- a/src/lib/mkMake +++ b/src/lib/mkMake @@ -27,6 +27,7 @@ ${depth}/query/docseqhist.cpp \ ${depth}/query/history.cpp \ ${depth}/query/recollq.cpp \ ${depth}/query/sortseq.cpp \ +${depth}/query/filtseq.cpp \ ${depth}/query/wasastringtoquery.cpp \ ${depth}/query/wasatorcl.cpp \ ${depth}/rcldb/pathhash.cpp \ diff --git a/src/qtgui/rclmain_w.cpp b/src/qtgui/rclmain_w.cpp index 464799df..3e21aa3f 100644 --- a/src/qtgui/rclmain_w.cpp +++ b/src/qtgui/rclmain_w.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: rclmain_w.cpp,v 1.51 2008-09-25 06:00:24 dockes Exp $ (C) 2005 J.F.Dockes"; +static char rcsid[] = "@(#$Id: rclmain_w.cpp,v 1.52 2008-09-28 07:40:56 dockes Exp $ (C) 2005 J.F.Dockes"; #endif /* * This program is free software; you can redistribute it and/or modify @@ -102,7 +102,6 @@ void RclMain::init() uiprefs = 0; indexConfig = 0; spellform = 0; - m_searchId = 0; m_idxStatusAck = false; // Set the focus to the search terms entry: @@ -155,8 +154,7 @@ void RclMain::init() connect(preferencesMenu, SIGNAL(aboutToShow()), this, SLOT(adjustPrefsMenu())); // signals and slots connections - connect(sSearch, SIGNAL(clearSearch()), - this, SLOT(resetSearch())); + connect(sSearch, SIGNAL(clearSearch()), this, SLOT(resetSearch())); connect(firstPageAction, SIGNAL(activated()), resList, SLOT(resultPageFirst())); connect(prevPageAction, SIGNAL(activated()), @@ -231,7 +229,7 @@ void RclMain::init() if (prefs.keepSort && prefs.sortActive) { SortForm sf(0); connect(&sf, SIGNAL(sortDataChanged(DocSeqSortSpec)), - this, SLOT(sortDataChanged(DocSeqSortSpec))); + resList, SLOT(sortDataChanged(DocSeqSortSpec))); // Have to call setdata again after sig connected... sf.setData(); } @@ -436,7 +434,7 @@ void RclMain::startSearch(RefCntr sdata) return; } - resList->resetSearch(); + resList->resetList(); int qopts = 0; if (!prefs.queryStemLang.length() == 0) @@ -459,34 +457,13 @@ void RclMain::startSearch(RefCntr sdata) DocSequenceDb *src = new DocSequenceDb(RefCntr(query), string(tr("Query results").utf8()), sdata); - m_docSource = RefCntr(src); - m_searchData = sdata; - setDocSequence(); + resList->setDocSource(RefCntr(src)); QApplication::restoreOverrideCursor(); } void RclMain::resetSearch() { - resList->resetSearch(); - m_searchData = RefCntr(); -} - -void RclMain::setDocSequence() -{ - if (m_searchData.getcnt() == 0) { - // Null refcntr ?? No current search data - return; - } - RefCntr docsource; - if (m_sortspecs.sortwidth > 0) { - docsource = RefCntr(new DocSeqSorted(m_docSource, - m_sortspecs, - string(tr("Query results (sorted)").utf8()))); - } else { - docsource = m_docSource; - } - m_searchId++; - resList->setDocSource(docsource); + resList->resetList(); } // Open advanced search dialog. @@ -509,16 +486,15 @@ void RclMain::showSortDialog() if (sortform == 0) { sortform = new SortForm(0); connect(sortform, SIGNAL(sortDataChanged(DocSeqSortSpec)), - this, SLOT(sortDataChanged(DocSeqSortSpec))); + resList, SLOT(sortDataChanged(DocSeqSortSpec))); connect(sortform, SIGNAL(applySortData()), - this, SLOT(setDocSequence())); + resList, SLOT(setDocSource())); sortform->show(); } else { // Close and reopen, in hope that makes us visible... sortform->close(); sortform->show(); } - } void RclMain::showSpellDialog() @@ -576,6 +552,13 @@ void RclMain::showExtIdxDialog() uiprefs->show(); } +void RclMain::showAboutDialog() +{ + string vstring = string("Recoll ") + rclversion + + "
" + "http://www.recoll.org"; + QMessageBox::information(this, tr("About Recoll"), vstring.c_str()); +} + // If a preview (toplevel) window gets closed by the user, we need to // clean up because there is no way to reopen it. And check the case // where the current one is closed @@ -602,9 +585,8 @@ void RclMain::startPreview(int docnum, int mod) { Rcl::Doc doc; if (!resList->getDoc(docnum, doc)) { - QMessageBox::warning(0, "Recoll", - tr("Cannot retrieve document info" - " from database")); + QMessageBox::warning(0, "Recoll", tr("Cannot retrieve document info" + " from database")); return; } @@ -622,8 +604,8 @@ void RclMain::startPreview(int docnum, int mod) } if (curPreview == 0) { HiliteData hdata; - m_searchData->getTerms(hdata.terms, hdata.groups, hdata.gslks); - curPreview = new Preview(m_searchId, hdata); + resList->getTerms(hdata.terms, hdata.groups, hdata.gslks); + curPreview = new Preview(resList->searchId(), hdata); if (curPreview == 0) { QMessageBox::warning(0, tr("Warning"), tr("Can't create preview window"), @@ -693,13 +675,13 @@ void RclMain::previewPrevInTab(Preview * w, int sid, int docnum) // Combined next/prev from result list in current preview tab void RclMain::previewPrevOrNextInTab(Preview * w, int sid, int docnum, bool nxt) { - LOGDEB(("RclMain::previewNextInTab sid %d docnum %d, m_sid %d\n", - sid, docnum, m_searchId)); + LOGDEB(("RclMain::previewNextInTab sid %d docnum %d, searchId %d\n", + sid, docnum, resList->searchId())); if (w == 0) // ?? return; - if (sid != m_searchId) { + if (sid != resList->searchId()) { QMessageBox::warning(0, "Recoll", tr("This search is not active any more")); return; @@ -733,13 +715,13 @@ void RclMain::previewPrevOrNextInTab(Preview * w, int sid, int docnum, bool nxt) w->makeDocCurrent(fn, st.st_size, doc, docnum, true); } -// Preview tab exposed: possibly tell reslist (to color the paragraph) +// Preview tab exposed: if the preview comes from the currently +// displayed result list, tell reslist (to color the paragraph) void RclMain::previewExposed(Preview *, int sid, int docnum) { LOGDEB2(("RclMain::previewExposed: sid %d docnum %d, m_sid %d\n", - sid, docnum, m_searchId)); - - if (sid != m_searchId) { + sid, docnum, resList->searchId())); + if (sid != resList->searchId()) { return; } resList->previewExposed(docnum); @@ -897,14 +879,6 @@ void RclMain::startNativeViewer(Rcl::Doc doc) system(ncmd.c_str()); } - -void RclMain::showAboutDialog() -{ - string vstring = string("Recoll ") + rclversion + - "
" + "http://www.recoll.org"; - QMessageBox::information(this, tr("About Recoll"), vstring.c_str()); -} - void RclMain::startManual() { QString msg = tr("Starting help browser "); @@ -914,7 +888,8 @@ void RclMain::startManual() startHelpBrowser(); } -// Search for document 'like' the selected one. +// Search for document 'like' the selected one. We ask rcldb/xapian to find +// significant terms, and add them to the simple search entry. void RclMain::docExpand(int docnum) { if (!rcldb) @@ -923,8 +898,7 @@ void RclMain::docExpand(int docnum) if (!resList->getDoc(docnum, doc)) return; list terms; - if (!m_docSource.isNull()) - terms = m_docSource->expand(doc); + terms = resList->expand(doc); if (terms.empty()) return; // Do we keep the original query. I think we'd better not. @@ -944,7 +918,7 @@ void RclMain::docExpand(int docnum) void RclMain::showDocHistory() { LOGDEB(("RclMain::showDocHistory\n")); - resList->resetSearch(); + resList->resetList(); curPreview = 0; string reason; @@ -953,36 +927,27 @@ void RclMain::showDocHistory() return; } // Construct a bogus SearchData structure - m_searchData = + RefCntrsearchdata = RefCntr(new Rcl::SearchData(Rcl::SCLT_AND)); - m_searchData->setDescription((const char *)tr("History data").utf8()); + searchdata->setDescription((const char *)tr("History data").utf8()); - m_searchId++; // If you change the title, also change it in eraseDocHistory() DocSequenceHistory *src = new DocSequenceHistory(rcldb, g_dynconf, string(tr("Document history").utf8())); src->setDescription((const char *)tr("History data").utf8()); - m_docSource = RefCntr(src); - setDocSequence(); + resList->setDocSource(RefCntr(src)); } +// Erase all memory of documents viewed void RclMain::eraseDocHistory() { + // Clear file storage g_dynconf->eraseAll(RclHistory::docSubkey); - // We want to reset the displayed history if it is currently shown. Using - // the title value is an ugly hack - if (m_docSource->title() == - string((const char *)tr("Document history").utf8())) { + // Clear possibly displayed history + if (resList->displayingHistory()) showDocHistory(); - } -} - -void RclMain::sortDataChanged(DocSeqSortSpec spec) -{ - LOGDEB(("RclMain::sortDataChanged\n")); - m_sortspecs = spec; } // Called when the uiprefs dialog is ok'd @@ -1009,4 +974,3 @@ void RclMain::enablePrevPage(bool yesno) prevPageAction->setEnabled(yesno); firstPageAction->setEnabled(yesno); } - diff --git a/src/qtgui/rclmain_w.h b/src/qtgui/rclmain_w.h index 52cf7ec3..65239460 100644 --- a/src/qtgui/rclmain_w.h +++ b/src/qtgui/rclmain_w.h @@ -77,7 +77,6 @@ public slots: virtual void periodic100(); virtual void toggleIndexing(); virtual void startSearch(RefCntr sdata); - virtual void setDocSequence(); virtual void previewClosed(Preview *w); virtual void showAdvSearchDialog(); virtual void showSortDialog(); @@ -86,7 +85,6 @@ public slots: virtual void startManual(); virtual void showDocHistory(); virtual void showExtIdxDialog(); - virtual void sortDataChanged(DocSeqSortSpec spec); virtual void showUIPrefs(); virtual void showIndexConfig(); virtual void setUIPrefs(); @@ -115,25 +113,18 @@ protected: virtual void closeEvent( QCloseEvent * ); private: - Preview *curPreview; - AdvSearch *asearchform; - SortForm *sortform; - UIPrefsDialog *uiprefs; - ConfIndexW *indexConfig; - SpellW *spellform; + Preview *curPreview; + AdvSearch *asearchform; + SortForm *sortform; + UIPrefsDialog *uiprefs; + ConfIndexW *indexConfig; + SpellW *spellform; - RefCntr m_searchData; - DocSeqSortSpec m_sortspecs; - RefCntr m_docSource; - - vector m_tempfiles; - // Serial number of current search for this process. - // Used to match to preview windows - int m_searchId; - map m_stemLangToId; - int m_idNoStem; - int m_idAllStem; - bool m_idxStatusAck; // Did we act on last status? + vector m_tempfiles; + map m_stemLangToId; + int m_idNoStem; + int m_idAllStem; + bool m_idxStatusAck; // Did we act on last status? virtual void init(); virtual void previewPrevOrNextInTab(Preview *, int sid, int docnum, diff --git a/src/qtgui/reslist.cpp b/src/qtgui/reslist.cpp index bc1dcad1..0255ff25 100644 --- a/src/qtgui/reslist.cpp +++ b/src/qtgui/reslist.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: reslist.cpp,v 1.43 2008-09-25 06:00:24 dockes Exp $ (C) 2005 J.F.Dockes"; +static char rcsid[] = "@(#$Id: reslist.cpp,v 1.44 2008-09-28 07:40:56 dockes Exp $ (C) 2005 J.F.Dockes"; #endif #include @@ -81,15 +81,59 @@ ResList::ResList(QWidget* parent, const char* name) m_winfirst = -1; m_curPvDoc = -1; m_lstClckMod = 0; + m_searchId = 0; } ResList::~ResList() { } +int ResList::newSearchId() +{ + static int id; + return ++id; +} + extern "C" int XFlush(void *); -void ResList::resetSearch() +void ResList::setDocSource(RefCntr ndocsource) +{ + resetList(); + m_searchId = newSearchId(); + m_baseDocSource = ndocsource; + if (m_sortspecs.sortwidth > 0) { + m_docSource = RefCntr(new DocSeqSorted(ndocsource, + m_sortspecs, + string(tr("Query results (sorted)").utf8()))); + } else { + m_docSource = m_baseDocSource; + } + resultPageNext(); +} + +// Reapply parameters. Sort params probably changed +void ResList::setDocSource() +{ + resetList(); + m_searchId = newSearchId(); + RefCntr docsource; + if (m_sortspecs.sortwidth > 0) { + m_docSource = RefCntr(new DocSeqSorted(m_baseDocSource, + m_sortspecs, + string(tr("Query results (sorted)").utf8()))); + } else { + m_docSource = m_baseDocSource; + } + resultPageNext(); +} + +void ResList::sortDataChanged(DocSeqSortSpec spec) +{ + LOGDEB(("RclMain::sortDataChanged\n")); + m_sortspecs = spec; +} + +void ResList::resetList() { m_winfirst = -1; m_curPvDoc = -1; @@ -110,17 +154,31 @@ void ResList::resetSearch() #endif } +bool ResList::displayingHistory() +{ + // We want to reset the displayed history if it is currently shown. Using + // the title value is an ugly hack + return m_docSource->title() == + string((const char *)tr("Document history").utf8()); +} + void ResList::languageChange() { setCaption(tr("Result list")); } -// Acquire new docsource -void ResList::setDocSource(RefCntr docsource) +bool ResList::getTerms(vector& terms, + vector >& groups, vector& gslks) { - resetSearch(); - m_docSource = docsource; - resultPageNext(); + // We could just + return m_baseDocSource->getTerms(terms, groups, gslks); +} + +list ResList::expand(Rcl::Doc& doc) +{ + if (m_baseDocSource.isNull()) + return list(); + return m_baseDocSource->expand(doc); } // Get document number from paragraph number @@ -214,7 +272,7 @@ void ResList::contentsMouseReleaseEvent(QMouseEvent *e) // Return total result list count int ResList::getResCnt() { - if (m_docSource.getcnt() == 0) + if (m_docSource.isNull()) return -1; return m_docSource->getResCnt(); } @@ -296,8 +354,7 @@ void ResList::append(const QString &text) // Fill up result list window with next screen of hits void ResList::resultPageNext() { - // This checks that the RefCntr pseudo-pointer is not holding a null. - if (m_docSource.getcnt() == 0) + if (m_docSource.isNull()) return; int resCnt = m_docSource->getResCnt(); diff --git a/src/qtgui/reslist.h b/src/qtgui/reslist.h index 80ca9cf5..c0a89941 100644 --- a/src/qtgui/reslist.h +++ b/src/qtgui/reslist.h @@ -1,6 +1,6 @@ #ifndef _RESLIST_H_INCLUDED_ #define _RESLIST_H_INCLUDED_ -/* @(#$Id: reslist.h,v 1.13 2007-08-02 06:33:35 dockes Exp $ (C) 2005 J.F.Dockes */ +/* @(#$Id: reslist.h,v 1.14 2008-09-28 07:40:56 dockes Exp $ (C) 2005 J.F.Dockes */ #include @@ -21,7 +21,9 @@ class Q3PopupMenu; #endif #include "docseq.h" +#include "sortseq.h" #include "refcntr.h" +#include "rcldoc.h" class ResList : public QTEXTBROWSER { @@ -35,14 +37,20 @@ class ResList : public QTEXTBROWSER // the docseq here. This has also the side-effect of making the // entry current (visible and highlighted), and only work if the // num is inside the current page or its immediate neighbours. - virtual bool getDoc(int docnum, Rcl::Doc &); + bool getDoc(int docnum, Rcl::Doc &); - virtual void setDocSource(RefCntr source); - virtual QString getDescription(); // Printable actual query performed on db - virtual int getResCnt(); // Return total result list size + QString getDescription(); // Printable actual query performed on db + int getResCnt(); // Return total result list size + void setDocSource(RefCntr ndocsource); + bool displayingHistory(); + bool getTerms(vector& terms, + vector >& groups, vector& gslks); + list expand(Rcl::Doc& doc); + int searchId() const {return m_searchId;} public slots: - virtual void resetSearch(); + // Erase list and forget current search + virtual void resetList(); virtual void doubleClicked(int, int); virtual void resPageUpOrBack(); // Page up pressed virtual void resPageDownOrNext(); // Page down pressed @@ -59,6 +67,8 @@ class ResList : public QTEXTBROWSER virtual void append(const QString &text); // Only used for qt ver >=4 but seems we cant undef it virtual void selecChanged(); + virtual void setDocSource(); + virtual void sortDataChanged(DocSeqSortSpec spec); signals: void nextPageAvailable(bool); @@ -82,14 +92,24 @@ class ResList : public QTEXTBROWSER virtual void showQueryDetails(); private: - std::map m_pageParaToReldocnums; - RefCntr m_docSource; - std::vector m_curDocs; + // Raw doc source + RefCntr m_baseDocSource; + // Possibly filtered/sorted docsource (the one displayed) + RefCntr m_docSource; + // Current sort parameters + DocSeqSortSpec m_sortspecs; + // Docs for current page + std::vector m_curDocs; + // First docnum (in m_docSource sequence) for current page int m_winfirst; + // Translate from textedit paragraph number to relative + // docnum. Built while we insert text into the qtextedit + std::map m_pageParaToReldocnums; int m_popDoc; // Docnum for the popup menu. int m_curPvDoc;// Docnum for current preview int m_lstClckMod; // Last click modifier. list m_selDocs; + int m_searchId; virtual int docnumfromparnum(int); virtual int parnumfromdocnum(int); @@ -99,6 +119,7 @@ class ResList : public QTEXTBROWSER emit linkClicked(s, m_lstClckMod); }; virtual RCLPOPUP *createPopupMenu(const QPoint& pos); + static int newSearchId(); }; diff --git a/src/query/docseq.h b/src/query/docseq.h index e23a83db..7b67ffcd 100644 --- a/src/query/docseq.h +++ b/src/query/docseq.h @@ -16,7 +16,7 @@ */ #ifndef _DOCSEQ_H_INCLUDED_ #define _DOCSEQ_H_INCLUDED_ -/* @(#$Id: docseq.h,v 1.14 2008-09-08 16:49:10 dockes Exp $ (C) 2004 J.F.Dockes */ +/* @(#$Id: docseq.h,v 1.15 2008-09-28 07:40:56 dockes Exp $ (C) 2004 J.F.Dockes */ #include #include #include @@ -86,7 +86,8 @@ class DocSequence { * may have no associated search terms. Implement this for them. */ virtual bool getTerms(vector& terms, vector >& groups, - vector& gslks) const { + vector& gslks) + { terms.clear(); groups.clear(); gslks.clear(); return true; } virtual list expand(Rcl::Doc &) {list e; return e;} diff --git a/src/query/docseqdb.cpp b/src/query/docseqdb.cpp index 5435d048..1db607a8 100644 --- a/src/query/docseqdb.cpp +++ b/src/query/docseqdb.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: docseqdb.cpp,v 1.5 2008-09-08 16:49:10 dockes Exp $ (C) 2005 J.F.Dockes"; +static char rcsid[] = "@(#$Id: docseqdb.cpp,v 1.6 2008-09-28 07:40:56 dockes Exp $ (C) 2005 J.F.Dockes"; #endif /* * This program is free software; you can redistribute it and/or modify @@ -35,9 +35,9 @@ DocSequenceDb::~DocSequenceDb() bool DocSequenceDb::getTerms(vector& terms, vector >& groups, - vector& gslks) const + vector& gslks) { - return m_sdata.getptr()->getTerms(terms, groups, gslks); + return m_sdata->getTerms(terms, groups, gslks); } string DocSequenceDb::getDescription() diff --git a/src/query/docseqdb.h b/src/query/docseqdb.h index a0c0be4e..6a3ae067 100644 --- a/src/query/docseqdb.h +++ b/src/query/docseqdb.h @@ -16,7 +16,7 @@ */ #ifndef _DOCSEQDB_H_INCLUDED_ #define _DOCSEQDB_H_INCLUDED_ -/* @(#$Id: docseqdb.h,v 1.3 2008-06-13 18:22:46 dockes Exp $ (C) 2004 J.F.Dockes */ +/* @(#$Id: docseqdb.h,v 1.4 2008-09-28 07:40:56 dockes Exp $ (C) 2004 J.F.Dockes */ #include "docseq.h" #include "refcntr.h" @@ -34,7 +34,7 @@ class DocSequenceDb : public DocSequence { virtual int getResCnt(); virtual bool getTerms(vector& terms, vector >& groups, - vector& gslks) const; + vector& gslks); virtual string getAbstract(Rcl::Doc &doc); virtual string getDescription(); virtual list expand(Rcl::Doc &doc); diff --git a/src/query/filtseq.cpp b/src/query/filtseq.cpp new file mode 100644 index 00000000..71714ca2 --- /dev/null +++ b/src/query/filtseq.cpp @@ -0,0 +1,84 @@ +#ifndef lint +static char rcsid[] = "@(#$Id: filtseq.cpp,v 1.1 2008-09-28 07:40:56 dockes Exp $ (C) 2005 J.F.Dockes"; +#endif +/* + * 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 + +#include "debuglog.h" +#include "filtseq.h" + +using std::string; + +static bool filter(const DocSeqFiltSpec& fs, const Rcl::Doc *x) +{ + // Compare using each criterion in term. We're doing an or: + // 1st ok ends + for (unsigned int i = 0; i < fs.crits.size(); i++) { + switch (fs.crits[i]) { + case DocSeqFiltSpec::DSFS_MIMETYPE: + LOGDEB1((" MIMETYPE\n")); + if (x->mimetype == fs.values[i]) + return 1; + } + } + // Did all comparisons + return 0; +} + +DocSeqFiltered::DocSeqFiltered(RefCntr iseq, + DocSeqFiltSpec &filtspec, + const std::string &t) + : DocSequence(t), m_seq(iseq), m_spec(filtspec) +{ +} + +bool DocSeqFiltered::getDoc(int idx, Rcl::Doc &doc, int *percent, 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 + // fail + m_dbindices.reserve(idx+1); + + // First backend seq doc we fetch is the one after last stored + int backend_idx = m_dbindices.size() > 0 ? m_dbindices.back() + 1 : 0; + + // Loop until we get enough docs + Rcl::Doc tdoc; + int pc; + int i = 0; + while (idx >= (int)m_dbindices.size()) { + if (!m_seq->getDoc(backend_idx, tdoc, &pc)) + return false; + if (filter(m_spec, &tdoc)) { + m_dbindices.push_back(backend_idx); + } + backend_idx++; + } + + if (percent) + *percent = pc; + doc = tdoc; + } else { + // The corresponding backend indice is already known + if (!m_seq->getDoc(m_dbindices[idx], doc, percent)) + return false; + } + return true; +} diff --git a/src/query/filtseq.h b/src/query/filtseq.h new file mode 100644 index 00000000..4b3e83ec --- /dev/null +++ b/src/query/filtseq.h @@ -0,0 +1,61 @@ +/* + * 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 _FILTSEQ_H_INCLUDED_ +#define _FILTSEQ_H_INCLUDED_ +/* @(#$Id: filtseq.h,v 1.1 2008-09-28 07:40:56 dockes Exp $ (C) 2004 J.F.Dockes */ + +#include +#include + +#include "refcntr.h" +#include "docseq.h" + +class DocSeqFiltSpec { + public: + DocSeqFiltSpec() {} + enum Crit {DSFS_MIMETYPE}; + void orCrit(Crit crit, const string& value) { + crits.push_back(crit); + values.push_back(value); + } + std::vector crits; + std::vector values; +}; + +/** + * A filtered sequence is created from another one by selecting entries + * according to the given criteria. + */ +class DocSeqFiltered : public DocSequence { + public: + DocSeqFiltered(RefCntr iseq, DocSeqFiltSpec &filtspec, + const std::string &t); + virtual ~DocSeqFiltered() {} + virtual bool getDoc(int num, Rcl::Doc &doc, int *percent, string *sh = 0); + virtual int getResCnt() {return m_seq->getResCnt();} + virtual string getAbstract(Rcl::Doc& doc) { + return m_seq->getAbstract(doc); + } + virtual string getDescription() {return m_seq->getDescription();} + + private: + RefCntr m_seq; + DocSeqFiltSpec m_spec; + vector m_dbindices; +}; + +#endif /* _FILTSEQ_H_INCLUDED_ */