allow paging through results inside a preview window with shift-up shift-down

This commit is contained in:
dockes 2006-09-12 10:11:36 +00:00
parent cfea7fd245
commit 2f319431f9
10 changed files with 281 additions and 87 deletions

View File

@ -384,10 +384,10 @@
<number>20</number> <number>20</number>
</property> </property>
<property name="insertionPolicy"> <property name="insertionPolicy">
<enum>AtTop</enum> <enum>NoInsertion</enum>
</property> </property>
<property name="duplicatesEnabled"> <property name="duplicatesEnabled">
<bool>true</bool> <bool>false</bool>
</property> </property>
<property name="toolTip" stdset="0"> <property name="toolTip" stdset="0">
<string>Enter top directory for search</string> <string>Enter top directory for search</string>

View File

@ -1,5 +1,5 @@
#ifndef lint #ifndef lint
static char rcsid[] = "@(#$Id: advsearch_w.cpp,v 1.2 2006-09-11 12:05:38 dockes Exp $ (C) 2005 J.F.Dockes"; static char rcsid[] = "@(#$Id: advsearch_w.cpp,v 1.3 2006-09-12 10:11:36 dockes Exp $ (C) 2005 J.F.Dockes";
#endif #endif
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -188,9 +188,14 @@ void AdvSearch::searchPB_clicked()
if (!subtreeCMB->currentText().isEmpty()) { if (!subtreeCMB->currentText().isEmpty()) {
mydata.topdir = mydata.topdir =
string((const char*)(subtreeCMB->currentText().utf8())); string((const char*)(subtreeCMB->currentText().utf8()));
// If this was started by clicking, need to insert the new entry // The listbox is set for no insertion, do it. Have to check
if (subtreeCMB->text(0) != subtreeCMB->currentText()) // for dups as the internal feature seems to only work for
// user-inserted strings
if (!subtreeCMB->listBox()->findItem(subtreeCMB->currentText(),
Qt::CaseSensitive|Qt::ExactMatch))
subtreeCMB->insertItem(subtreeCMB->currentText(), 0); subtreeCMB->insertItem(subtreeCMB->currentText(), 0);
// And keep it sorted
subtreeCMB->listBox()->sort();
prefs.asearchSubdirHist.clear(); prefs.asearchSubdirHist.clear();
for (int index = 0; index < subtreeCMB->count(); index++) for (int index = 0; index < subtreeCMB->count(); index++)
prefs.asearchSubdirHist.push_back(subtreeCMB->text(index)); prefs.asearchSubdirHist.push_back(subtreeCMB->text(index));

View File

@ -1,5 +1,5 @@
#ifndef lint #ifndef lint
static char rcsid[] = "@(#$Id: preview_w.cpp,v 1.1 2006-09-04 15:13:01 dockes Exp $ (C) 2005 J.F.Dockes"; static char rcsid[] = "@(#$Id: preview_w.cpp,v 1.2 2006-09-12 10:11:36 dockes Exp $ (C) 2005 J.F.Dockes";
#endif #endif
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -55,17 +55,6 @@ using std::pair;
#define wasCanceled wasCancelled #define wasCanceled wasCancelled
#endif #endif
// We keep a list of data associated to each tab
class TabData {
public:
string fn; // filename for this tab
string ipath; // Internal doc path inside file
QWidget *w; // widget for setCurrent
TabData(QWidget *wi) : w(wi) {}
};
#define TABDATA ((list<TabData> *)tabData)
void Preview::init() void Preview::init()
{ {
// signals and slots connections // signals and slots connections
@ -80,14 +69,12 @@ void Preview::init()
searchTextLine->installEventFilter(this); searchTextLine->installEventFilter(this);
dynSearchActive = false; dynSearchActive = false;
canBeep = true; canBeep = true;
tabData = new list<TabData>; tabData.push_back(TabData(pvTab->currentPage()));
TABDATA->push_back(TabData(pvTab->currentPage()));
currentW = 0; currentW = 0;
} }
void Preview::destroy() void Preview::destroy()
{ {
delete TABDATA;
} }
void Preview::closeEvent(QCloseEvent *e) void Preview::closeEvent(QCloseEvent *e)
@ -109,6 +96,20 @@ bool Preview::eventFilter(QObject *target, QEvent *event)
} else if (keyEvent->key() == Key_Escape) { } else if (keyEvent->key() == Key_Escape) {
close(); close();
return true; return true;
} else if (keyEvent->key() == Qt::Key_Down &&
(keyEvent->state() & ShiftButton)) {
// LOGDEB(("Preview::eventFilter: got Shift-Up\n"));
TabData *d = tabDataForCurrent();
if (d)
emit(showNext(m_searchId, d->docnum));
return true;
} else if (keyEvent->key() == Qt::Key_Up &&
(keyEvent->state() & ShiftButton)) {
// LOGDEB(("Preview::eventFilter: got Shift-Down\n"));
TabData *d = tabDataForCurrent();
if (d)
emit(showPrev(m_searchId, d->docnum));
return true;
} else if (keyEvent->key() == Key_W && } else if (keyEvent->key() == Key_W &&
(keyEvent->state() & ControlButton)) { (keyEvent->state() & ControlButton)) {
// LOGDEB(("Preview::eventFilter: got ^W\n")); // LOGDEB(("Preview::eventFilter: got ^W\n"));
@ -154,7 +155,7 @@ void Preview::searchTextLine_textChanged(const QString & text)
} }
} }
QTextEdit * Preview::getCurrentEditor() QTextEdit *Preview::getCurrentEditor()
{ {
QWidget *tw = pvTab->currentPage(); QWidget *tw = pvTab->currentPage();
QTextEdit *edit = 0; QTextEdit *edit = 0;
@ -235,7 +236,7 @@ void Preview::prevPressed()
doSearch(searchTextLine->text(), true, true); doSearch(searchTextLine->text(), true, true);
} }
// Called when user clicks on tab
void Preview::currentChanged(QWidget * tw) void Preview::currentChanged(QWidget * tw)
{ {
QWidget *edit = (QWidget *)tw->child("pvEdit"); QWidget *edit = (QWidget *)tw->child("pvEdit");
@ -274,12 +275,10 @@ void Preview::closeCurrentTab()
return; return;
pvTab->removePage(tw); pvTab->removePage(tw);
// Have to remove from tab data list // Have to remove from tab data list
if (tabData == 0) for (list<TabData>::iterator it = tabData.begin();
return; it != tabData.end(); it++) {
for (list<TabData>::iterator it = TABDATA->begin();
it != TABDATA->end(); it++) {
if (it->w == tw) { if (it->w == tw) {
TABDATA->erase(it); tabData.erase(it);
return; return;
} }
} }
@ -299,12 +298,12 @@ QTextEdit *Preview::addEditorTab()
anonLayout->addWidget(editor); anonLayout->addWidget(editor);
pvTab->addTab(anon, "Tab"); pvTab->addTab(anon, "Tab");
pvTab->showPage(anon); pvTab->showPage(anon);
if (tabData) tabData.push_back(TabData(anon));
TABDATA->push_back(TabData(anon));
return editor; return editor;
} }
void Preview::setCurTabProps(const string &fn, const Rcl::Doc &doc) void Preview::setCurTabProps(const string &fn, const Rcl::Doc &doc,
int docnum)
{ {
QString title = QString::fromUtf8(doc.title.c_str(), QString title = QString::fromUtf8(doc.title.c_str(),
doc.title.length()); doc.title.length());
@ -328,21 +327,36 @@ void Preview::setCurTabProps(const string &fn, const Rcl::Doc &doc)
tiptxt += doc.title + "\n"; tiptxt += doc.title + "\n";
pvTab->setTabToolTip(w,QString::fromUtf8(tiptxt.c_str(), tiptxt.length())); pvTab->setTabToolTip(w,QString::fromUtf8(tiptxt.c_str(), tiptxt.length()));
for (list<TabData>::iterator it = TABDATA->begin(); for (list<TabData>::iterator it = tabData.begin();
it != TABDATA->end(); it++) { it != tabData.end(); it++) {
if (it->w == w) { if (it->w == w) {
it->fn = fn; it->fn = fn;
it->ipath = doc.ipath; it->ipath = doc.ipath;
it->docnum = docnum;
break; break;
} }
} }
} }
TabData *Preview::tabDataForCurrent()
{
QWidget *w = pvTab->currentPage();
if (w == 0)
return 0;
for (list<TabData>::iterator it = tabData.begin();
it != tabData.end(); it++) {
if (it->w == w) {
return &(*it);
}
}
return 0;
}
bool Preview::makeDocCurrent(const string &fn, const Rcl::Doc &doc) bool Preview::makeDocCurrent(const string &fn, const Rcl::Doc &doc)
{ {
LOGDEB(("Preview::makeFileCurrent: %s\n", fn.c_str())); LOGDEB(("Preview::makeFileCurrent: %s\n", fn.c_str()));
for (list<TabData>::iterator it = TABDATA->begin(); for (list<TabData>::iterator it = tabData.begin();
it != TABDATA->end(); it++) { it != tabData.end(); it++) {
LOGDEB2(("Preview::makeFileCurrent: compare to w %p, file %s\n", LOGDEB2(("Preview::makeFileCurrent: compare to w %p, file %s\n",
it->w, it->fn.c_str())); it->w, it->fn.c_str()));
if (!it->fn.compare(fn) && !it->ipath.compare(doc.ipath)) { if (!it->fn.compare(fn) && !it->ipath.compare(doc.ipath)) {
@ -457,7 +471,8 @@ class WaiterThread : public QThread {
#define MIN(A,B) ((A)<(B)?(A):(B)) #define MIN(A,B) ((A)<(B)?(A):(B))
#endif #endif
bool Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc) bool Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc,
int docnum)
{ {
Rcl::Doc doc = idoc; Rcl::Doc doc = idoc;
bool cancel = false; bool cancel = false;
@ -465,7 +480,7 @@ bool Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc)
if (doc.title.empty()) if (doc.title.empty())
doc.title = path_getsimple(doc.url); doc.title = path_getsimple(doc.url);
setCurTabProps(fn, doc); setCurTabProps(fn, doc, docnum);
char csz[20]; char csz[20];
sprintf(csz, "%lu", (unsigned long)sz); sprintf(csz, "%lu", (unsigned long)sz);
@ -553,6 +568,7 @@ bool Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc)
// Load into editor // Load into editor
// Do it in several chunks // Do it in several chunks
QTextEdit *editor = getCurrentEditor(); QTextEdit *editor = getCurrentEditor();
editor->setText("");
if (highlightTerms) { if (highlightTerms) {
QStyleSheetItem *item = QStyleSheetItem *item =
new QStyleSheetItem(editor->styleSheet(), "termtag" ); new QStyleSheetItem(editor->styleSheet(), "termtag" );
@ -592,11 +608,16 @@ bool Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc)
} }
} }
if (!firstTerm.empty()) { if (searchTextLine->text().length() != 0) {
bool wasC = matchCheck->isChecked(); canBeep = true;
matchCheck->setChecked(false); doSearch(searchTextLine->text(), true, false);
doSearch(QString::fromUtf8(terms.begin()->c_str()), true, false); } else {
matchCheck->setChecked(wasC); if (!firstTerm.empty()) {
bool wasC = matchCheck->isChecked();
matchCheck->setChecked(false);
doSearch(QString::fromUtf8(terms.begin()->c_str()), true, false);
matchCheck->setChecked(wasC);
}
} }
return true; return true;
} }

View File

@ -1,6 +1,6 @@
#ifndef _PREVIEW_W_H_INCLUDED_ #ifndef _PREVIEW_W_H_INCLUDED_
#define _PREVIEW_W_H_INCLUDED_ #define _PREVIEW_W_H_INCLUDED_
/* @(#$Id: preview_w.h,v 1.1 2006-09-04 15:13:01 dockes Exp $ (C) 2006 J.F.Dockes */ /* @(#$Id: preview_w.h,v 1.2 2006-09-12 10:11:36 dockes Exp $ (C) 2006 J.F.Dockes */
/* /*
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -23,23 +23,36 @@
#include "rcldb.h" #include "rcldb.h"
#include "preview.h" #include "preview.h"
// We keep a list of data associated to each tab
class TabData {
public:
string fn; // filename for this tab
string ipath; // Internal doc path inside file
QWidget *w; // widget for setCurrent
int docnum; // Index of doc in db search results.
TabData(QWidget *wi) : w(wi) {}
};
class Preview : public PreviewBase class Preview : public PreviewBase
{ {
Q_OBJECT Q_OBJECT
public: public:
Preview( QWidget* parent = 0, const char* name = 0, WFlags fl = 0 ) : Preview(QWidget* parent = 0, const char* name = 0, WFlags fl = 0) :
PreviewBase(parent,name,fl) {init();} PreviewBase(parent,name,fl) {init();}
~Preview(){} ~Preview(){}
virtual void closeEvent( QCloseEvent * e ); virtual void setSId(int sid) {m_searchId = sid;}
virtual bool eventFilter( QObject * target, QEvent * event ); virtual void closeEvent( QCloseEvent *e );
virtual bool eventFilter( QObject *target, QEvent *event );
virtual bool makeDocCurrent( const string & fn, const Rcl::Doc & doc ); virtual bool makeDocCurrent( const string & fn, const Rcl::Doc & doc );
virtual QTextEdit * getCurrentEditor(); virtual QTextEdit *getCurrentEditor();
virtual QTextEdit * addEditorTab(); virtual QTextEdit *addEditorTab();
virtual bool loadFileInCurrentTab(string fn, size_t sz, virtual bool loadFileInCurrentTab(string fn, size_t sz,
const Rcl::Doc & idoc ); const Rcl::Doc& idoc, int dnm);
public slots: public slots:
virtual void searchTextLine_textChanged( const QString & text ); virtual void searchTextLine_textChanged( const QString & text );
@ -48,24 +61,31 @@ public slots:
virtual void prevPressed(); virtual void prevPressed();
virtual void currentChanged( QWidget * tw ); virtual void currentChanged( QWidget * tw );
virtual void closeCurrentTab(); virtual void closeCurrentTab();
virtual void setCurTabProps( const string & fn, const Rcl::Doc & doc ); virtual void setCurTabProps(const string & fn, const Rcl::Doc & doc,
int docnum);
virtual void textDoubleClicked(int, int); virtual void textDoubleClicked(int, int);
signals: signals:
void previewClosed(QWidget *); void previewClosed(QWidget *);
void wordSelect(QString); void wordSelect(QString);
void showNext(int sid, int docnum);
void showPrev(int sid, int docnum);
protected: protected:
int m_searchId; // Identifier of search in main window. This is so that
// we make sense when requesting the next document when
// browsing successive search results in a tab.
int matchIndex; int matchIndex;
int matchPara; int matchPara;
bool dynSearchActive; bool dynSearchActive;
bool canBeep; bool canBeep;
void *tabData; list<TabData> tabData;
QWidget *currentW; QWidget *currentW;
private: private:
void init(); void init();
virtual void destroy(); virtual void destroy();
TabData *tabDataForCurrent(); // Return auxiliary data pointer for cur tab
}; };
#endif /* _PREVIEW_W_H_INCLUDED_ */ #endif /* _PREVIEW_W_H_INCLUDED_ */

View File

@ -1,5 +1,5 @@
#ifndef lint #ifndef lint
static char rcsid[] = "@(#$Id: rclmain.cpp,v 1.29 2006-09-11 09:08:44 dockes Exp $ (C) 2005 J.F.Dockes"; static char rcsid[] = "@(#$Id: rclmain.cpp,v 1.30 2006-09-12 10:11:36 dockes Exp $ (C) 2005 J.F.Dockes";
#endif #endif
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -82,7 +82,7 @@ void RclMain::init()
asearchform = 0; asearchform = 0;
sortform = 0; sortform = 0;
uiprefs = 0; uiprefs = 0;
m_searchId = 0;
// Set the focus to the search terms entry: // Set the focus to the search terms entry:
sSearch->queryText->setFocus(); sSearch->queryText->setFocus();
@ -100,11 +100,20 @@ void RclMain::init()
connect(prevPageAction, SIGNAL(activated()), connect(prevPageAction, SIGNAL(activated()),
resList, SLOT(resultPageBack())); resList, SLOT(resultPageBack()));
connect(nextPageAction, SIGNAL(activated()), connect(nextPageAction, SIGNAL(activated()),
resList, SLOT(showResultPage())); resList, SLOT(resultPageNext()));
connect(resList, SIGNAL(docExpand(int)), this, SLOT(docExpand(int))); connect(resList, SIGNAL(docExpand(int)), this, SLOT(docExpand(int)));
connect(resList, SIGNAL(wordSelect(QString)), connect(resList, SIGNAL(wordSelect(QString)),
this, SLOT(ssearchAddTerm(QString))); this, SLOT(ssearchAddTerm(QString)));
connect(resList, SIGNAL(nextPageAvailable(bool)),
this, SLOT(enableNextPage(bool)));
connect(resList, SIGNAL(prevPageAvailable(bool)),
this, SLOT(enablePrevPage(bool)));
connect(resList, SIGNAL(docEditClicked(int)),
this, SLOT(startNativeViewer(int)));
connect(resList, SIGNAL(docPreviewClicked(int)),
this, SLOT(startPreview(int)));
connect(fileExitAction, SIGNAL(activated() ), this, SLOT(fileExit() ) ); connect(fileExitAction, SIGNAL(activated() ), this, SLOT(fileExit() ) );
connect(fileStart_IndexingAction, SIGNAL(activated()), connect(fileStart_IndexingAction, SIGNAL(activated()),
this, SLOT(startIndexing())); this, SLOT(startIndexing()));
@ -119,14 +128,6 @@ void RclMain::init()
this, SLOT(showSortDialog())); this, SLOT(showSortDialog()));
connect(preferencesQuery_PrefsAction, SIGNAL(activated()), connect(preferencesQuery_PrefsAction, SIGNAL(activated()),
this, SLOT(showUIPrefs())); this, SLOT(showUIPrefs()));
connect(resList, SIGNAL(nextPageAvailable(bool)),
this, SLOT(enableNextPage(bool)));
connect(resList, SIGNAL(prevPageAvailable(bool)),
this, SLOT(enablePrevPage(bool)));
connect(resList, SIGNAL(docEditClicked(int)),
this, SLOT(startNativeViewer(int)));
connect(resList, SIGNAL(docPreviewClicked(int)),
this, SLOT(startPreview(int)));
nextPageAction->setIconSet(createIconSet("nextpage.png")); nextPageAction->setIconSet(createIconSet("nextpage.png"));
prevPageAction->setIconSet(createIconSet("prevpage.png")); prevPageAction->setIconSet(createIconSet("prevpage.png"));
@ -340,6 +341,7 @@ void RclMain::startAdvSearch(Rcl::AdvSearchData sdata)
} else { } else {
docsource = new DocSequenceDb(rcldb, string(tr("Query results").utf8())); docsource = new DocSequenceDb(rcldb, string(tr("Query results").utf8()));
} }
m_searchId++;
resList->setDocSource(docsource, sdata); resList->setDocSource(docsource, sdata);
} }
@ -440,11 +442,16 @@ void RclMain::startPreview(int docnum)
QMessageBox::NoButton); QMessageBox::NoButton);
return; return;
} }
curPreview->setSId(m_searchId);
curPreview->setCaption(resList->getDescription()); curPreview->setCaption(resList->getDescription());
connect(curPreview, SIGNAL(previewClosed(QWidget *)), connect(curPreview, SIGNAL(previewClosed(QWidget *)),
this, SLOT(previewClosed(QWidget *))); this, SLOT(previewClosed(QWidget *)));
connect(curPreview, SIGNAL(wordSelect(QString)), connect(curPreview, SIGNAL(wordSelect(QString)),
this, SLOT(ssearchAddTerm(QString))); this, SLOT(ssearchAddTerm(QString)));
connect(curPreview, SIGNAL(showNext(int, int)),
this, SLOT(previewNextInTab(int, int)));
connect(curPreview, SIGNAL(showPrev(int, int)),
this, SLOT(previewPrevInTab(int, int)));
curPreview->show(); curPreview->show();
} else { } else {
if (curPreview->makeDocCurrent(fn, doc)) { if (curPreview->makeDocCurrent(fn, doc)) {
@ -453,8 +460,84 @@ void RclMain::startPreview(int docnum)
} }
(void)curPreview->addEditorTab(); (void)curPreview->addEditorTab();
} }
// Enter document in document history
g_dynconf->enterDoc(fn, doc.ipath); g_dynconf->enterDoc(fn, doc.ipath);
if (!curPreview->loadFileInCurrentTab(fn, st.st_size, doc)) if (!curPreview->loadFileInCurrentTab(fn, st.st_size, doc, docnum))
curPreview->closeCurrentTab();
}
// Show next document from result list in current preview tab
void RclMain::previewNextInTab(int sid, int docnum)
{
LOGDEB(("RclMain::previewNextInTab sid %d docnum %d, m_sid %d\n",
sid, docnum, m_searchId));
if (sid != m_searchId) {
QMessageBox::warning(0, "Recoll",
tr("This search is not active any more"));
return;
}
docnum++;
if (docnum >= resList->getResCnt()) {
QApplication::beep();
return;
}
Rcl::Doc doc;
if (!resList->getDoc(docnum, doc)) {
QMessageBox::warning(0, "Recoll",
tr("Cannot retrieve document info"
" from database"));
return;
}
// Check that file exists in file system
string fn = urltolocalpath(doc.url);
struct stat st;
if (stat(fn.c_str(), &st) < 0) {
QMessageBox::warning(0, "Recoll", tr("Cannot access document file: ") +
fn.c_str());
return;
}
if (!curPreview->loadFileInCurrentTab(fn, st.st_size, doc, docnum))
curPreview->closeCurrentTab();
}
// Show previous document from result list in current preview tab
void RclMain::previewPrevInTab(int sid, int docnum)
{
LOGDEB(("RclMain::previewPrevInTab sid %d docnum %d, m_sid %d\n",
sid, docnum, m_searchId));
if (sid != m_searchId) {
QMessageBox::warning(0, "Recoll",
tr("This search is not active any more"));
return;
}
if (docnum <= 0) {
QApplication::beep();
return;
}
docnum--;
Rcl::Doc doc;
if (!resList->getDoc(docnum, doc)) {
QMessageBox::warning(0, "Recoll",
tr("Cannot retrieve document info"
" from database"));
return;
}
// Check that the file exists in the file system
string fn = urltolocalpath(doc.url);
struct stat st;
if (stat(fn.c_str(), &st) < 0) {
QMessageBox::warning(0, "Recoll", tr("Cannot access document file: ") +
fn.c_str());
return;
}
if (!curPreview->loadFileInCurrentTab(fn, st.st_size, doc, docnum))
curPreview->closeCurrentTab(); curPreview->closeCurrentTab();
} }
@ -560,6 +643,7 @@ void RclMain::startManual()
startHelpBrowser(); startHelpBrowser();
} }
// Search for document 'like' the selected one.
void RclMain::docExpand(int docnum) void RclMain::docExpand(int docnum)
{ {
Rcl::Doc doc; Rcl::Doc doc;
@ -606,6 +690,7 @@ void RclMain::showDocHistory()
} }
Rcl::AdvSearchData sdata; Rcl::AdvSearchData sdata;
sdata.description = tr("History data").utf8(); sdata.description = tr("History data").utf8();
m_searchId++;
resList->setDocSource(docsource, sdata); resList->setDocSource(docsource, sdata);
} }

View File

@ -64,6 +64,8 @@ public slots:
virtual void ssearchAddTerm(QString); virtual void ssearchAddTerm(QString);
virtual void startPreview(int docnum); virtual void startPreview(int docnum);
virtual void startNativeViewer(int docnum); virtual void startNativeViewer(int docnum);
virtual void previewNextInTab(int sid, int docnum);
virtual void previewPrevInTab(int sid, int docnum);
private: private:
Preview *curPreview; Preview *curPreview;
@ -71,6 +73,8 @@ private:
SortForm *sortform; SortForm *sortform;
UIPrefsDialog *uiprefs; UIPrefsDialog *uiprefs;
RclSortSpec sortspecs; RclSortSpec sortspecs;
int m_searchId; // Serial number of current search for this process.
// Used to match to preview windows
virtual void init(); virtual void init();
}; };

View File

@ -1,5 +1,5 @@
#ifndef lint #ifndef lint
static char rcsid[] = "@(#$Id: rclreslist.cpp,v 1.17 2006-05-09 07:56:07 dockes Exp $ (C) 2005 J.F.Dockes"; static char rcsid[] = "@(#$Id: rclreslist.cpp,v 1.18 2006-09-12 10:11:36 dockes Exp $ (C) 2005 J.F.Dockes";
#endif #endif
#include <time.h> #include <time.h>
@ -72,7 +72,7 @@ void RclResList::setDocSource(DocSequence *docsource, Rcl::AdvSearchData& sdt)
delete m_docsource; delete m_docsource;
m_docsource = docsource; m_docsource = docsource;
m_queryData = sdt; m_queryData = sdt;
showResultPage(); resultPageNext();
} }
// Get document number from paragraph number // Get document number from paragraph number
@ -90,14 +90,58 @@ int RclResList::docnumfromparnum(int par)
return dn; return dn;
} }
// Get paragraph number from document number
int RclResList::parnumfromdocnum(int docnum)
{
if (m_winfirst == -1 || docnum - m_winfirst < 0)
return -1;
docnum -= m_winfirst;
for (std::map<int,int>::iterator it = m_pageParaToReldocnums.begin();
it != m_pageParaToReldocnums.end(); it++) {
if (docnum == it->second)
return it->first;
}
return -1;
}
// Return doc from current or adjacent result pages
bool RclResList::getDoc(int docnum, Rcl::Doc &doc) bool RclResList::getDoc(int docnum, Rcl::Doc &doc)
{ {
if (docnum >= 0 && docnum >= int(m_winfirst) && if (docnum < 0)
return false;
// Is docnum in current page ? Then all Ok
if (docnum >= int(m_winfirst) &&
docnum < int(m_winfirst + m_curDocs.size())) { docnum < int(m_winfirst + m_curDocs.size())) {
doc = m_curDocs[docnum - m_winfirst]; doc = m_curDocs[docnum - m_winfirst];
return true; goto found;
}
// Else we accept to page down or up but not further
if (docnum < int(m_winfirst) &&
docnum >= int(m_winfirst) - prefs.respagesize) {
resultPageBack();
} else if (docnum <
int(m_winfirst + m_curDocs.size()) + prefs.respagesize) {
resultPageNext();
}
if (docnum >= int(m_winfirst) &&
docnum < int(m_winfirst + m_curDocs.size())) {
doc = m_curDocs[docnum - m_winfirst];
goto found;
} }
return false; return false;
found:
if (docnum != m_docnum) {
int par = parnumfromdocnum(docnum);
if (par >= 0) {
setCursorPosition(par, 1);
ensureCursorVisible();
clicked(par, 1);
m_docnum = docnum;
}
}
return true;
} }
void RclResList::keyPressEvent( QKeyEvent * e ) void RclResList::keyPressEvent( QKeyEvent * e )
@ -115,6 +159,14 @@ void RclResList::keyPressEvent( QKeyEvent * e )
QTextBrowser::keyPressEvent(e); QTextBrowser::keyPressEvent(e);
} }
// Return total result list count
int RclResList::getResCnt()
{
if (!m_docsource)
return -1;
return m_docsource->getResCnt();
}
// Page Up/Down: we don't try to check if current paragraph is last or // Page Up/Down: we don't try to check if current paragraph is last or
// first. We just page up/down and check if viewport moved. If it did, // first. We just page up/down and check if viewport moved. If it did,
// fair enough, else we go to next/previous result page. // fair enough, else we go to next/previous result page.
@ -126,7 +178,6 @@ void RclResList::resPageUpOrBack()
resultPageBack(); resultPageBack();
} }
void RclResList::resPageDownOrNext() void RclResList::resPageDownOrNext()
{ {
int vpos = contentsY(); int vpos = contentsY();
@ -134,7 +185,7 @@ void RclResList::resPageDownOrNext()
LOGDEB(("RclResList::resPageDownOrNext: vpos before %d, after %d\n", LOGDEB(("RclResList::resPageDownOrNext: vpos before %d, after %d\n",
vpos, contentsY())); vpos, contentsY()));
if (vpos == contentsY()) if (vpos == contentsY())
showResultPage(); resultPageNext();
} }
// Show previous page of results. We just set the current number back // Show previous page of results. We just set the current number back
@ -144,7 +195,7 @@ void RclResList::resultPageBack()
if (m_winfirst <= 0) if (m_winfirst <= 0)
return; return;
m_winfirst -= 2 * prefs.respagesize; m_winfirst -= 2 * prefs.respagesize;
showResultPage(); resultPageNext();
} }
// Convert byte count into unit (KB/MB...) appropriate for display // Convert byte count into unit (KB/MB...) appropriate for display
@ -165,7 +216,7 @@ static string displayableBytes(long size)
} }
// Fill up result list window with next screen of hits // Fill up result list window with next screen of hits
void RclResList::showResultPage() void RclResList::resultPageNext()
{ {
if (!m_docsource) if (!m_docsource)
return; return;
@ -176,7 +227,7 @@ void RclResList::showResultPage()
int resCnt = m_docsource->getResCnt(); int resCnt = m_docsource->getResCnt();
m_pageParaToReldocnums.clear(); m_pageParaToReldocnums.clear();
LOGDEB(("showResultPage: rescnt %d, winfirst %d\n", resCnt, LOGDEB(("resultPageNext: rescnt %d, winfirst %d\n", resCnt,
m_winfirst)); m_winfirst));
// If we are already on the last page, nothing to do: // If we are already on the last page, nothing to do:
@ -436,7 +487,7 @@ void RclResList::linkWasClicked(const QString &s)
emit docEditClicked(i); emit docEditClicked(i);
break; break;
case 'n': case 'n':
showResultPage(); resultPageNext();
break; break;
case 'p': case 'p':
resultPageBack(); resultPageBack();

View File

@ -1,6 +1,6 @@
#ifndef _RCLRESLIST_H_INCLUDED_ #ifndef _RCLRESLIST_H_INCLUDED_
#define _RCLRESLIST_H_INCLUDED_ #define _RCLRESLIST_H_INCLUDED_
/* @(#$Id: rclreslist.h,v 1.8 2006-04-26 11:29:10 dockes Exp $ (C) 2005 J.F.Dockes */ /* @(#$Id: rclreslist.h,v 1.9 2006-09-12 10:11:36 dockes Exp $ (C) 2005 J.F.Dockes */
#include <qtextbrowser.h> #include <qtextbrowser.h>
#include <qpopupmenu.h> #include <qpopupmenu.h>
@ -17,19 +17,25 @@ class RclResList : public QTextBrowser
RclResList(QWidget* parent = 0, const char* name = 0); RclResList(QWidget* parent = 0, const char* name = 0);
virtual ~RclResList(); virtual ~RclResList();
virtual bool getDoc( int, Rcl::Doc & ); // Return document for given docnum. We act as an intermediary to
// 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 &);
virtual void setDocSource(DocSequence *, Rcl::AdvSearchData& qdata); virtual void setDocSource(DocSequence *, Rcl::AdvSearchData& qdata);
virtual QPopupMenu *createPopupMenu(const QPoint& pos); virtual QPopupMenu *createPopupMenu(const QPoint& pos);
virtual QString getDescription(); virtual QString getDescription(); // Printable actual query performed on db
virtual int getResCnt(); // Return total result list size
public slots: public slots:
virtual void resetSearch() {m_winfirst = -1;clear();} virtual void resetSearch() {m_winfirst = -1;clear();}
virtual void clicked(int, int); virtual void clicked(int, int);
virtual void doubleClicked(int, int); virtual void doubleClicked(int, int);
virtual void resPageUpOrBack(); virtual void resPageUpOrBack(); // Page up pressed
virtual void resPageDownOrNext(); virtual void resPageDownOrNext(); // Page down pressed
virtual void resultPageBack(); virtual void resultPageBack(); // Display previous page of results
virtual void showResultPage(); virtual void resultPageNext(); // Display next (or first) page of results
virtual void menuPreview(); virtual void menuPreview();
virtual void menuEdit(); virtual void menuEdit();
virtual void menuCopyFN(); virtual void menuCopyFN();
@ -59,9 +65,10 @@ class RclResList : public QTextBrowser
DocSequence *m_docsource; DocSequence *m_docsource;
std::vector<Rcl::Doc> m_curDocs; std::vector<Rcl::Doc> m_curDocs;
int m_winfirst; int m_winfirst;
int m_docnum; // Docnum matching the int m_docnum; // Docnum matching the currently active para
virtual int docnumfromparnum(int); virtual int docnumfromparnum(int);
virtual int parnumfromdocnum(int);
void emitLinkClicked(const QString &s) { void emitLinkClicked(const QString &s) {
emit linkClicked(s); emit linkClicked(s);
}; };

View File

@ -1,5 +1,5 @@
#ifndef lint #ifndef lint
static char rcsid[] = "@(#$Id: ssearch_w.cpp,v 1.3 2006-09-11 12:05:38 dockes Exp $ (C) 2006 J.F.Dockes"; static char rcsid[] = "@(#$Id: ssearch_w.cpp,v 1.4 2006-09-12 10:11:36 dockes Exp $ (C) 2006 J.F.Dockes";
#endif #endif
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
@ -92,16 +92,17 @@ void SSearch::startSimpleSearch()
bool changed; bool changed;
do { do {
changed = false; changed = false;
for (int index = 1; index < queryText->count(); index++) { for (int index = 0; index < queryText->count(); index++) {
if (queryText->text(index) == queryText->currentText()) { if (queryText->text(index).length() == 0 ||
queryText->text(index) == queryText->currentText()) {
queryText->removeItem(index); queryText->removeItem(index);
changed = true; changed = true;
break; break;
} }
} }
} while (changed); } while (changed);
if (queryText->text(0) != queryText->currentText()) // The combobox is set for no insertion, insert here:
queryText->insertItem(queryText->currentText(), 0); queryText->insertItem(queryText->currentText(), 0);
// Save the current state of the listbox list to file // Save the current state of the listbox list to file
prefs.ssearchHistory.clear(); prefs.ssearchHistory.clear();

View File

@ -94,13 +94,13 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="sizeLimit"> <property name="sizeLimit">
<number>20</number> <number>10</number>
</property> </property>
<property name="maxCount"> <property name="maxCount">
<number>30</number> <number>30</number>
</property> </property>
<property name="insertionPolicy"> <property name="insertionPolicy">
<enum>AtTop</enum> <enum>NoInsertion</enum>
</property> </property>
<property name="duplicatesEnabled"> <property name="duplicatesEnabled">
<bool>false</bool> <bool>false</bool>