From 04a926456a21a2db99762894b0c6ea0094c8b27a Mon Sep 17 00:00:00 2001 From: dockes Date: Mon, 17 Oct 2005 13:36:53 +0000 Subject: [PATCH] implemented dialog/glue for advanced search --- src/common/rclconfig.cpp | 23 +- src/common/rclconfig.h | 5 +- src/qtgui/advsearch.ui | 672 ++++++++++++++++++--------------- src/qtgui/advsearch.ui.h | 93 ++++- src/qtgui/preview/preview.ui | 4 + src/qtgui/preview/preview.ui.h | 6 + src/qtgui/preview/pvmain.cpp | 4 +- src/qtgui/recoll.h | 15 +- src/qtgui/recollmain.ui | 73 ++-- src/qtgui/recollmain.ui.h | 86 ++++- src/utils/Makefile | 16 +- 11 files changed, 626 insertions(+), 371 deletions(-) diff --git a/src/common/rclconfig.cpp b/src/common/rclconfig.cpp index a9f9d7af..c26f86eb 100644 --- a/src/common/rclconfig.cpp +++ b/src/common/rclconfig.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: rclconfig.cpp,v 1.7 2005-03-31 10:04:07 dockes Exp $ (C) 2004 J.F.Dockes"; +static char rcsid[] = "@(#$Id: rclconfig.cpp,v 1.8 2005-10-17 13:36:53 dockes Exp $ (C) 2004 J.F.Dockes"; #endif #include @@ -72,6 +72,26 @@ RclConfig::RclConfig() return; } +static ConfSimple::WalkerCode mtypesWalker(void *l, + const char *nm, const char *value) +{ + std::list *lst = (std::list *)l; + if (nm && nm[0] == '.') + lst->push_back(value); + return ConfSimple::WALK_CONTINUE; +} + +std::list RclConfig::getAllMimeTypes() +{ + std::list lst; + if (mimemap == 0) + return lst; + mimemap->sortwalk(mtypesWalker, &lst); + lst.sort(); + lst.unique(); + return lst; +} + // Look up an executable filter. // We look in RECOLL_BINDIR, RECOLL_CONFDIR, then let the system use // the PATH @@ -96,3 +116,4 @@ string find_filter(RclConfig *conf, const string &icmd) } return icmd; } + diff --git a/src/common/rclconfig.h b/src/common/rclconfig.h index f59a06d2..73c72df6 100644 --- a/src/common/rclconfig.h +++ b/src/common/rclconfig.h @@ -1,6 +1,8 @@ #ifndef _RCLCONFIG_H_INCLUDED_ #define _RCLCONFIG_H_INCLUDED_ -/* @(#$Id: rclconfig.h,v 1.4 2005-02-04 09:39:44 dockes Exp $ (C) 2004 J.F.Dockes */ +/* @(#$Id: rclconfig.h,v 1.5 2005-10-17 13:36:53 dockes Exp $ (C) 2004 J.F.Dockes */ + +#include #include "conftree.h" @@ -50,6 +52,7 @@ class RclConfig { const string &getDefCharset() {return defcharset;} const string &getDefLang() {return deflang;} bool getGuessCharset() {return guesscharset;} + std::list getAllMimeTypes(); }; std::string find_filter(RclConfig *conf, const string& cmd); diff --git a/src/qtgui/advsearch.ui b/src/qtgui/advsearch.ui index f748aac6..b7b5f292 100644 --- a/src/qtgui/advsearch.ui +++ b/src/qtgui/advsearch.ui @@ -8,8 +8,8 @@ 0 0 - 600 - 480 + 563 + 560 @@ -18,332 +18,357 @@ true - + - textLabel1_3 + unnamed - - - 120 - 20 - 110 - 20 - - - - Complex search - - - - - searchPB - - - - 380 - 20 - 90 - 30 - - - - Search - - - - - line1 - - - - 22 - 58 - 550 - 16 - - - - HLine - - - Sunken - - - Horizontal - - - - - layout6 - - - - 100 - 100 - 470 - 112 - - - + - unnamed + layout28 - + - layout2 + unnamed - + - unnamed + layout15 - + - andWordsTL + unnamed - - NoFrame + + 10 - - Plain + + 10 - - All these words - - - - - andWordsLE - - - - - - - layout2_2 - - + + + textLabel2 + + + Search For + + + + + layout14 + + + + unnamed + + + + andWordsTL + + + NoFrame + + + Plain + + + All these words + + + + + andWordsLE + + + + 250 + 0 + + + + + + phraseTL + + + This exact phrase + + + + + phraseLE + + + + + orWordsTL + + + Any of these words + + + + + orWordsLE + + + + + noWordsTL + + + None of these words + + + + + noWordsLE + + + + + + + + + + - unnamed + line2 - - - phraseTL - - - This exact phrase - - - - - phraseLE - - - - - - - layout4 - - + + HLine + + + Sunken + + + Horizontal + + + - unnamed + layout19 - + - orWordsTL + unnamed - - Any of these words - - - - - orWordsLE - - - - - - - layout5 - - + + + restrictFtCB + + + Restrict file types + + + + + layout11 + + + + unnamed + + + + layout9 + + + + unnamed + + + + textLabel2_2 + + + Searched file types + + + + + yesFiltypsLB + + + false + + + + 200 + 100 + + + + Extended + + + + + + + layout11 + + + + unnamed + + + + delFiltypPB + + + false + + + --------> + + + + + addFiltypPB + + + false + + + <--------- + + + + + + + layout10 + + + + unnamed + + + + textLabel3 + + + Ignored file types + + + + + noFiltypsLB + + + false + + + + 200 + 100 + + + + Extended + + + + + + + + + - unnamed + line3 - + + HLine + + + Sunken + + + Horizontal + + + + + layout18 + + - noWordsTL + unnamed - - None of these words - - - + + + subtreeLE + + + + 300 + 0 + + + + + + browsePB + + + Browse + + + + + textLabel1 + + + Restrict results to files in subtree: + + + + + + + line1 + + + HLine + + + Sunken + + + Horizontal + + + + + layout25 + + - noWordsLE + unnamed - - - - - - - - textLabel2 - - - - 10 - 100 - 64 - 112 - - - - Search For - - - - - line2 - - - - 10 - 220 - 560 - 20 - - - - HLine - - - Sunken - - - Horizontal - - - - - layout10 - - - - 440 - 250 - 102 - 170 - - - - - unnamed - - - - textLabel3 - - - Ignored file types - - - - - - New Item - - - - noFiltypsLB - - - false - - - - - - - layout9 - - - - 100 - 250 - 111 - 170 - - - - - unnamed - - - - textLabel2_2 - - - Searched file types - - - - - - New Item - - - - yesFiltypsLB - - - false - - - - - - - layout11 - - - - 270 - 300 - 82 - 68 - - - - - unnamed - - - - delFiltypPB - - - false - - - --------> - - - - - addFiltypPB - - - false - - - <--------- - - - - + + + searchPB + + + Start Search + + + + + dismissPB + + + Dismiss + + + + + + + @@ -352,26 +377,53 @@ advsearch delFiltypPB_clicked() - - addFiltypPB - clicked() - advsearch - addFiltypPB_clicked() - searchPB clicked() advsearch searchPB_clicked() + + restrictFtCB + toggled(bool) + advsearch + restrictFtCB_toggled(bool) + + + dismissPB + clicked() + advsearch + close() + + + browsePB + clicked() + advsearch + browsePB_clicked() + + + addFiltypPB + clicked() + advsearch + addFiltypPB_clicked() + + recoll.h advsearch.ui.h + + startSearch(AdvSearchData) + delFiltypPB_clicked() addFiltypPB_clicked() + restrictFtCB_toggled( bool on ) searchPB_clicked() + browsePB_clicked() + + init() + diff --git a/src/qtgui/advsearch.ui.h b/src/qtgui/advsearch.ui.h index d48098b9..e1dda969 100644 --- a/src/qtgui/advsearch.ui.h +++ b/src/qtgui/advsearch.ui.h @@ -10,20 +10,107 @@ ** destructor. *****************************************************************************/ +#include +#include +#include + +using std::list; +using std::string; + +#include "recoll.h" +#include "rclconfig.h" +#include "debuglog.h" + + +extern RclConfig *rclconfig; + +// Constructor/initialization +void advsearch::init() +{ + list types = rclconfig->getAllMimeTypes(); + QStringList ql; + for (list::iterator it = types.begin(); it != types.end(); it++) { + ql.append(it->c_str()); + } + yesFiltypsLB->insertStringList(ql); +} + +// Move selected file types from the searched to the ignored box void advsearch::delFiltypPB_clicked() { - + list trl; + QStringList moved; + for (unsigned int i = 0; i < yesFiltypsLB->count();i++) { + QListBoxItem *item = yesFiltypsLB->item(i); + if (item && item->isSelected()) { + moved.push_back(item->text()); + trl.push_front(i); + } + } + if (!moved.empty()) { + noFiltypsLB->insertStringList(moved); + for (list::iterator it = trl.begin();it != trl.end(); it++) + yesFiltypsLB->removeItem(*it); + } + yesFiltypsLB->sort(); + noFiltypsLB->sort(); } +// Move selected file types from the ignored to the searched box void advsearch::addFiltypPB_clicked() { - + list trl; + QStringList moved; + for (unsigned int i = 0; i < noFiltypsLB->count(); i++) { + QListBoxItem *item = noFiltypsLB->item(i); + if (item && item->isSelected()) { + moved.push_back(item->text()); + trl.push_front(i); + } + } + if (!moved.empty()) { + yesFiltypsLB->insertStringList(moved); + for (list::iterator it = trl.begin();it != trl.end(); it++) + noFiltypsLB->removeItem(*it); + } + yesFiltypsLB->sort(); + noFiltypsLB->sort(); } +// Activate file type selection +void advsearch::restrictFtCB_toggled(bool on) +{ + yesFiltypsLB->setEnabled(on); + delFiltypPB->setEnabled(on); + addFiltypPB->setEnabled(on); + noFiltypsLB->setEnabled(on); +} + void advsearch::searchPB_clicked() { - + AdvSearchData mydata; + mydata.allwords = string((const char*)(andWordsLE->text().utf8())); + mydata.phrase = string((const char*)(phraseLE->text().utf8())); + mydata.orwords = string((const char*)(orWordsLE->text().utf8())); + mydata.nowords = string((const char*)(noWordsLE->text().utf8())); + if (restrictFtCB->isOn() && noFiltypsLB->count() > 0) { + for (unsigned int i = 0; i < yesFiltypsLB->count(); i++) { + QCString ctext = noFiltypsLB->item(i)->text().utf8(); + mydata.filetypes.push_back(string((const char *)ctext)); + } + } + if (!subtreeLE->text().isEmpty()) { + mydata.topdir = string((const char*)(subtreeLE->text().utf8())); + } + emit startSearch(mydata); +} + + +void advsearch::browsePB_clicked() +{ + QString dir = QFileDialog::getExistingDirectory(); + subtreeLE->setText(dir); } diff --git a/src/qtgui/preview/preview.ui b/src/qtgui/preview/preview.ui index 4eca274c..f927cc21 100644 --- a/src/qtgui/preview/preview.ui +++ b/src/qtgui/preview/preview.ui @@ -172,6 +172,9 @@ bool dynSearchActive; bool canBeep; + + previewClosed(Preview *) + searchTextLine_textChanged( const QString & text ) doSearch( bool next, bool reverse ) @@ -181,6 +184,7 @@ init() + closeEvent( QCloseEvent * e) eventFilter( QObject * target, QEvent * event ) diff --git a/src/qtgui/preview/preview.ui.h b/src/qtgui/preview/preview.ui.h index d533ca7d..e721d0e1 100644 --- a/src/qtgui/preview/preview.ui.h +++ b/src/qtgui/preview/preview.ui.h @@ -21,6 +21,12 @@ void Preview::init() canBeep = true; } +void Preview::closeEvent(QCloseEvent *e) +{ + emit previewClosed(this); + QWidget::closeEvent(e); +} + extern int recollNeedsExit; bool Preview::eventFilter(QObject *target, QEvent *event) diff --git a/src/qtgui/preview/pvmain.cpp b/src/qtgui/preview/pvmain.cpp index 9cf7f5b5..70925288 100644 --- a/src/qtgui/preview/pvmain.cpp +++ b/src/qtgui/preview/pvmain.cpp @@ -1,5 +1,5 @@ #ifndef lint -static char rcsid[] = "@(#$Id: pvmain.cpp,v 1.2 2005-10-10 12:29:43 dockes Exp $ (C) 2005 J.F.Dockes"; +static char rcsid[] = "@(#$Id: pvmain.cpp,v 1.3 2005-10-17 13:36:53 dockes Exp $ (C) 2005 J.F.Dockes"; #endif #include @@ -22,7 +22,7 @@ using std::pair; #include "readfile.h" const char *filename = "/home/dockes/tmp/tstpv-utf8.txt"; - +int recollNeedsExit; int main( int argc, char ** argv ) { QApplication a(argc, argv); diff --git a/src/qtgui/recoll.h b/src/qtgui/recoll.h index f607c79b..66f37cbe 100644 --- a/src/qtgui/recoll.h +++ b/src/qtgui/recoll.h @@ -1,7 +1,8 @@ #ifndef _RECOLL_H_INCLUDED_ #define _RECOLL_H_INCLUDED_ -/* @(#$Id: recoll.h,v 1.2 2005-02-09 12:07:30 dockes Exp $ (C) 2004 J.F.Dockes */ - +/* @(#$Id: recoll.h,v 1.3 2005-10-17 13:36:53 dockes Exp $ (C) 2004 J.F.Dockes */ +#include +#include #include "rclconfig.h" #include "rcldb.h" #include "idxthread.h" @@ -15,4 +16,14 @@ extern string tmpdir; extern int recollNeedsExit; +// Holder for data collected by the advanced search dialog +struct AdvSearchData { + std::string allwords; + std::string phrase; + std::string orwords; + std::string nowords; + std::list filetypes; // restrict to types. Empty if inactive + std::string topdir; // restrict to subtree. Empty if inactive +}; + #endif /* _RECOLL_H_INCLUDED_ */ diff --git a/src/qtgui/recollmain.ui b/src/qtgui/recollmain.ui index 4b6a01c7..4643b202 100644 --- a/src/qtgui/recollmain.ui +++ b/src/qtgui/recollmain.ui @@ -8,8 +8,8 @@ 0 0 - 549 - 750 + 590 + 810 @@ -22,7 +22,7 @@ - 549 + 590 160 @@ -35,7 +35,7 @@ - layout8 + layout30 @@ -43,7 +43,7 @@ - layout9 + layout29 @@ -109,14 +109,6 @@ Next page - - - advSearchPB - - - Adv. search - - spacer1 @@ -129,11 +121,33 @@ - 346 + 42 20 + + + line4 + + + VLine + + + Sunken + + + Vertical + + + + + advSearchPB + + + Advanced search + + @@ -173,10 +187,6 @@ - - - - @@ -206,17 +216,6 @@ Start Indexing - - - helpQuick_startAction - - - Quick start - - - Quick start - - @@ -231,12 +230,6 @@ RecollMain fileStart_IndexingAction_activated() - - helpQuick_startAction - activated() - RecollMain - helpQuick_startAction_activated() - Search clicked() @@ -279,9 +272,16 @@ RecollMain clearqPB_clicked() + + advSearchPB + clicked() + RecollMain + advSearchPB_clicked() + preview/.ui/preview.h + recoll.h recollmain.ui.h @@ -302,8 +302,9 @@ clearqPB_clicked() listPrevPB_clicked() listNextPB_clicked() - helpQuick_startAction_activated() advSearchPB_clicked() + previewClosed( Preview * w ) + startAdvSearch( AdvSearchData sdata ) init() diff --git a/src/qtgui/recollmain.ui.h b/src/qtgui/recollmain.ui.h index eaa2845b..a509752c 100644 --- a/src/qtgui/recollmain.ui.h +++ b/src/qtgui/recollmain.ui.h @@ -31,14 +31,14 @@ using std::pair; #include "internfile.h" #include "smallut.h" #include "plaintorich.h" - - #include "unacpp.h" #ifndef MIN #define MIN(A,B) ((A) < (B) ? (A) : (B)) #endif +// Number of abstracts in a result page. This will avoid scrollbars +// with the default window size and font, most of the time. static const int respagesize = 8; @@ -47,6 +47,7 @@ void RecollMain::init() curPreview = 0; } +// We want to catch ^Q everywhere to mean quit. bool RecollMain::eventFilter( QObject * target, QEvent * event ) { if (event->type() == QEvent::KeyPress) { @@ -68,6 +69,7 @@ void RecollMain::fileExit() // things apart from a need to exit void RecollMain::checkExit() { + // Check if indexing thread done if (indexingstatus) { indexingstatus = false; // Make sure we reopen the db to get the results. @@ -84,13 +86,13 @@ void RecollMain::fileStart_IndexingAction_activated() startindexing = 1; } - +// Note that all our 'urls' are like : file://... static string urltolocalpath(string url) { return url.substr(7, string::npos); } -// Use external viewer to display file +// Double click in result list: use external viewer to display file void RecollMain::reslistTE_doubleClicked(int par, int) { LOGDEB(("RecollMain::reslistTE_doubleClicked: par %d\n", par)); @@ -154,7 +156,7 @@ void RecollMain::reslistTE_clicked(int par, int car) reslistTE->setParagraphBackgroundColor(par, color); int reldocnum = par - 1; - if (reslist_current == reldocnum) + if (curPreview && reslist_current == reldocnum) return; reslist_current = reldocnum; @@ -185,6 +187,8 @@ void RecollMain::reslistTE_clicked(int par, int car) if (curPreview == 0) { curPreview = new Preview(0, "Preview"); curPreview->setCaption(queryText->text()); + connect(curPreview, SIGNAL(previewClosed(Preview *)), + this, SLOT(previewClosed(Preview *))); if (curPreview == 0) { QMessageBox::warning(0, "Warning", "Can't create preview window", @@ -204,13 +208,40 @@ void RecollMain::reslistTE_clicked(int par, int car) curPreview->pvTab->addTab(anon, "Tab"); curPreview->pvTab->showPage(anon); } + string tabname; + if (!doc.title.empty()) { + tabname = doc.title; + } else { + tabname = path_getsimple(doc.url); + } + if (tabname.length() > 20) { + tabname = tabname.substr(0, 10) + "..." + + tabname.substr(tabname.length()-10); + } curPreview->pvTab->changeTab(curPreview->pvTab->currentPage(), - QString::fromUtf8(doc.title.c_str(), - doc.title.length())); + QString::fromUtf8(tabname.c_str(), + tabname.length())); + + if (doc.title.empty()) + doc.title = path_getsimple(doc.url); + char datebuf[100]; + datebuf[0] = 0; + if (!doc.mtime.empty()) { + time_t mtime = atol(doc.mtime.c_str()); + struct tm *tm = localtime(&mtime); + strftime(datebuf, 99, "%F %T", tm); + } + string tiptxt = doc.url + string("\n"); + tiptxt += doc.mimetype + " " + + (doc.mtime.empty() ? "\n" : string(datebuf) + "\n"); + if (!doc.title.empty()) + tiptxt += doc.title + "\n"; + curPreview->pvTab->setTabToolTip(curPreview->pvTab->currentPage(), + QString::fromUtf8(tiptxt.c_str(), + tiptxt.length())); QStyleSheetItem *item = - new QStyleSheetItem(editor->styleSheet(), - "termtag" ); + new QStyleSheetItem(editor->styleSheet(), "termtag" ); item->setColor("blue"); item->setFontWeight(QFont::Bold); @@ -388,15 +419,22 @@ void RecollMain::listNextPB_clicked() } } - - - -void RecollMain::helpQuick_startAction_activated() +// 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 +void RecollMain::previewClosed(Preview *w) { - + if (w == curPreview) { + LOGDEB(("Active preview closed\n")); + curPreview = 0; + } else { + LOGDEB(("Old preview closed\n")); + } + delete w; } + #include "advsearch.h" advsearch *asearchform; @@ -409,12 +447,32 @@ void RecollMain::advSearchPB_clicked() WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu); asearchform->setSizeGripEnabled(FALSE); + connect(asearchform, SIGNAL(startSearch(AdvSearchData)), + this, SLOT(startAdvSearch(AdvSearchData))); asearchform->show(); } else { asearchform->show(); } } +void RecollMain::startAdvSearch(AdvSearchData sdata) +{ + LOGDEB(("RecollMain::startAdvSearch\n")); + LOGDEB((" allwords: %s\n", sdata.allwords.c_str())); + LOGDEB((" phrase: %s\n", sdata.phrase.c_str())); + LOGDEB((" orwords: %s\n", sdata.orwords.c_str())); + LOGDEB((" nowords: %s\n", sdata.nowords.c_str())); + string ft; + for (list::iterator it = sdata.filetypes.begin(); + it != sdata.filetypes.end(); it++) { + ft += *it + " "; + } + if (!ft.empty()) + LOGDEB(("Searched file types: %s\n", ft.c_str())); + if (!sdata.topdir.empty()) + LOGDEB(("Restricted to: %s\n", sdata.topdir.c_str())); + +} diff --git a/src/utils/Makefile b/src/utils/Makefile index 8c0545a8..5fb384fb 100644 --- a/src/utils/Makefile +++ b/src/utils/Makefile @@ -2,8 +2,8 @@ include ../mk/sysconf BIGLIB = ../lib/librcl.a -PROGS = wipedir smallut trfstreewalk trpathut transcode trmimeparse \ - trexecmd utf8iter idfile +PROGS = trconftree wipedir smallut trfstreewalk trpathut transcode \ + trmimeparse trexecmd utf8iter idfile all: $(PROGS) @@ -67,5 +67,17 @@ utf8iter : $(UTF8ITER_OBJS) trutf8iter.o : ../utils/utf8iter.cpp utf8iter.h $(CXX) $(CXXFLAGS) -DTEST_UTF8ITER -c -o trutf8iter.o \ utf8iter.cpp + + + +CONFTREE_OBJS= trconftree.o $(BIGLIB) +trconftree : $(CONFTREE_OBJS) + $(CXX) $(CXXFLAGS) -o trconftree $(CONFTREE_OBJS) +trconftree.o : ../utils/conftree.cpp + $(CXX) $(CXXFLAGS) -DTEST_CONFTREE -c -o trconftree.o \ + conftree.cpp + + + clean: rm -f *.o $(PROGS)