allow paging through results inside a preview window with shift-up shift-down
This commit is contained in:
parent
cfea7fd245
commit
2f319431f9
@ -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>
|
||||||
|
|||||||
@ -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));
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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_ */
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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>
|
||||||
@ -16,20 +16,26 @@ class RclResList : public QTextBrowser
|
|||||||
public:
|
public:
|
||||||
RclResList(QWidget* parent = 0, const char* name = 0);
|
RclResList(QWidget* parent = 0, const char* name = 0);
|
||||||
virtual ~RclResList();
|
virtual ~RclResList();
|
||||||
|
|
||||||
|
// 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 bool getDoc( int, 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);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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();
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user