Gui: misc event/signals cleanups. No functional changes

This commit is contained in:
Jean-Francois Dockes 2010-12-22 18:07:18 +01:00
parent 107e02b74a
commit 0a6063542f
15 changed files with 263 additions and 139 deletions

View File

@ -65,8 +65,6 @@ void AdvSearch::init()
HelpClient::installMap((const char *)objectName().toUtf8(), HelpClient::installMap((const char *)objectName().toUtf8(),
"RCL.SEARCH.COMPLEX"); "RCL.SEARCH.COMPLEX");
this->installEventFilter(this);
// signals and slots connections // signals and slots connections
connect(delFiltypPB, SIGNAL(clicked()), this, SLOT(delFiltypPB_clicked())); connect(delFiltypPB, SIGNAL(clicked()), this, SLOT(delFiltypPB_clicked()));
connect(searchPB, SIGNAL(clicked()), this, SLOT(runSearch())); connect(searchPB, SIGNAL(clicked()), this, SLOT(runSearch()));
@ -146,20 +144,6 @@ void AdvSearch::init()
cat_rtranslations[tr("other")] = QString::fromUtf8("other"); cat_rtranslations[tr("other")] = QString::fromUtf8("other");
} }
bool AdvSearch::eventFilter(QObject *, QEvent *event)
{
// LOGDEB(("AdvSearch::eventFilter. Type %d\n", (int)event->type()));
if (event->type() == QEvent::KeyPress ||
event->type() == QEvent::ShortcutOverride) {
QKeyEvent *ke = static_cast<QKeyEvent *>(event);
if (ke->key() == Qt::Key_Q && (ke->modifiers() & Qt::ControlModifier)) {
recollNeedsExit = 1;
return true;
}
}
return false;
}
void AdvSearch::saveCnf() void AdvSearch::saveCnf()
{ {
// Save my state // Save my state

View File

@ -42,7 +42,6 @@ public:
init(); init();
} }
~AdvSearch(){} ~AdvSearch(){}
virtual bool eventFilter(QObject *target, QEvent *event);
public slots: public slots:
virtual void delFiltypPB_clicked(); virtual void delFiltypPB_clicked();

View File

@ -208,6 +208,7 @@ void rwSettings(bool writing)
if (prefs.restableFields.empty()) { if (prefs.restableFields.empty()) {
prefs.restableFields.push_back("filename"); prefs.restableFields.push_back("filename");
prefs.restableFields.push_back("title"); prefs.restableFields.push_back("title");
prefs.restableFields.push_back("date");
prefs.restableFields.push_back("url"); prefs.restableFields.push_back("url");
} }
} }

View File

@ -169,7 +169,9 @@ int main(int argc, char **argv)
QApplication app(argc, argv); QApplication app(argc, argv);
// fprintf(stderr, "Application created\n"); QCoreApplication::setOrganizationName("Recoll.org");
QCoreApplication::setApplicationName("recoll");
string a_config; string a_config;
string question; string question;

View File

@ -239,11 +239,7 @@ bool Preview::eventFilter(QObject *target, QEvent *event)
PreviewTextEdit *edit = currentEditor(); PreviewTextEdit *edit = currentEditor();
QKeyEvent *keyEvent = (QKeyEvent *)event; QKeyEvent *keyEvent = (QKeyEvent *)event;
if (keyEvent->key() == Qt::Key_Q && if (keyEvent->key() == Qt::Key_Escape) {
(keyEvent->modifiers() & Qt::ControlModifier)) {
recollNeedsExit = 1;
return true;
} else if (keyEvent->key() == Qt::Key_Escape) {
close(); close();
return true; return true;
} else if (keyEvent->key() == Qt::Key_Down && } else if (keyEvent->key() == Qt::Key_Down &&

View File

@ -80,6 +80,7 @@ using namespace confgui;
extern "C" int XFlush(void *); extern "C" int XFlush(void *);
QString g_stringAllStem, g_stringNoStem; QString g_stringAllStem, g_stringNoStem;
static const QKeySequence quitKeySeq("Ctrl+q");
void RclMain::init() void RclMain::init()
{ {
@ -200,17 +201,18 @@ void RclMain::init()
// A shortcut to get the focus back to the search entry. // A shortcut to get the focus back to the search entry.
QKeySequence seq("Ctrl+Shift+s"); QKeySequence seq("Ctrl+Shift+s");
QShortcut *sc = new QShortcut(seq, this); QShortcut *sc = new QShortcut(seq, this);
connect(sc, SIGNAL (activated()), connect(sc, SIGNAL (activated()),
this, SLOT (focusToSearch())); this, SLOT (focusToSearch()));
connect(sSearch, SIGNAL(startSearch(RefCntr<Rcl::SearchData>)), connect(sSearch, SIGNAL(startSearch(RefCntr<Rcl::SearchData>)),
this, SLOT(startSearch(RefCntr<Rcl::SearchData>))); this, SLOT(startSearch(RefCntr<Rcl::SearchData>)));
connect(sSearch, SIGNAL(clearSearch()),
this, SLOT(resetSearch()));
connect(preferencesMenu, SIGNAL(triggered(QAction*)), connect(preferencesMenu, SIGNAL(triggered(QAction*)),
this, SLOT(setStemLang(QAction*))); this, SLOT(setStemLang(QAction*)));
connect(preferencesMenu, SIGNAL(aboutToShow()), connect(preferencesMenu, SIGNAL(aboutToShow()),
this, SLOT(adjustPrefsMenu())); this, SLOT(adjustPrefsMenu()));
connect(sSearch, SIGNAL(clearSearch()),
this, SLOT(resetSearch()));
connect(fileExitAction, SIGNAL(activated() ), connect(fileExitAction, SIGNAL(activated() ),
this, SLOT(fileExit() ) ); this, SLOT(fileExit() ) );
connect(fileToggleIndexingAction, SIGNAL(activated()), connect(fileToggleIndexingAction, SIGNAL(activated()),
@ -243,14 +245,20 @@ void RclMain::init()
connect(periodictimer, SIGNAL(timeout()), connect(periodictimer, SIGNAL(timeout()),
this, SLOT(periodic100())); this, SLOT(periodic100()));
sc = new QShortcut(quitKeySeq, restable);
connect(sc, SIGNAL (activated()),
this, SLOT (fileExit()));
connect(this, SIGNAL(docSourceChanged(RefCntr<DocSequence>)), connect(this, SIGNAL(docSourceChanged(RefCntr<DocSequence>)),
restable, SLOT(setDocSource(RefCntr<DocSequence>))); restable, SLOT(setDocSource(RefCntr<DocSequence>)));
connect(this, SIGNAL(searchReset()), connect(this, SIGNAL(searchReset()),
restable, SLOT(resetSource())); restable, SLOT(resetSource()));
connect(restable, SIGNAL(sortDataChanged(DocSeqSortSpec)),
this, SLOT(onResTableSortBy(DocSeqSortSpec)));
connect(this, SIGNAL(applyFiltSortData()), connect(this, SIGNAL(applyFiltSortData()),
restable, SLOT(readDocSource())); restable, SLOT(readDocSource()));
connect(this, SIGNAL(sortDataChanged(DocSeqSortSpec)),
restable, SLOT(onSortDataChanged(DocSeqSortSpec)));
connect(restable->getModel(), SIGNAL(sortDataChanged(DocSeqSortSpec)),
this, SLOT(onResTableSortBy(DocSeqSortSpec)));
connect(this, SIGNAL(docSourceChanged(RefCntr<DocSequence>)), connect(this, SIGNAL(docSourceChanged(RefCntr<DocSequence>)),
reslist, SLOT(setDocSource(RefCntr<DocSequence>))); reslist, SLOT(setDocSource(RefCntr<DocSequence>)));
@ -289,6 +297,8 @@ void RclMain::init()
this, SLOT(startPreview(int, Rcl::Doc, int))); this, SLOT(startPreview(int, Rcl::Doc, int)));
connect(reslist, SIGNAL(previewRequested(Rcl::Doc)), connect(reslist, SIGNAL(previewRequested(Rcl::Doc)),
this, SLOT(startPreview(Rcl::Doc))); this, SLOT(startPreview(Rcl::Doc)));
connect(reslist, SIGNAL(headerClicked()),
this, SLOT(showQueryDetails()));
// Start timer on a slow period (used for checking ^C). Will be // Start timer on a slow period (used for checking ^C). Will be
// speeded up during indexing // speeded up during indexing
@ -440,6 +450,8 @@ void RclMain::fileExit()
prefs.mainwidth = width(); prefs.mainwidth = width();
prefs.mainheight = height(); prefs.mainheight = height();
} }
restable->saveSizeState();
prefs.ssearchTyp = sSearch->searchTypCMB->currentIndex(); prefs.ssearchTyp = sSearch->searchTypCMB->currentIndex();
if (asearchform) if (asearchform)
delete asearchform; delete asearchform;
@ -551,6 +563,7 @@ void RclMain::startSearch(RefCntr<Rcl::SearchData> sdata)
LOGDEB(("RclMain::startSearch. Indexing %s\n", LOGDEB(("RclMain::startSearch. Indexing %s\n",
idxthread_getStatus() == IDXTS_NULL?"on":"off")); idxthread_getStatus() == IDXTS_NULL?"on":"off"));
emit searchReset(); emit searchReset();
m_source = RefCntr<DocSequence>();
// The db may have been closed at the end of indexing // The db may have been closed at the end of indexing
string reason; string reason;
@ -583,8 +596,8 @@ void RclMain::startSearch(RefCntr<Rcl::SearchData> sdata)
string(tr("Query results").toUtf8()), sdata); string(tr("Query results").toUtf8()), sdata);
src->setAbstractParams(prefs.queryBuildAbstract, src->setAbstractParams(prefs.queryBuildAbstract,
prefs.queryReplaceAbstract); prefs.queryReplaceAbstract);
m_source = RefCntr<DocSequence>(src);
emit docSourceChanged(RefCntr<DocSequence>(src)); emit docSourceChanged(m_source);
emit sortDataChanged(m_sortspec); emit sortDataChanged(m_sortspec);
emit filtDataChanged(m_filtspec); emit filtDataChanged(m_filtspec);
emit applyFiltSortData(); emit applyFiltSortData();
@ -601,6 +614,9 @@ void RclMain::showAdvSearchDialog()
{ {
if (asearchform == 0) { if (asearchform == 0) {
asearchform = new AdvSearch(0); asearchform = new AdvSearch(0);
connect(new QShortcut(quitKeySeq, asearchform), SIGNAL (activated()),
this, SLOT (fileExit()));
connect(asearchform, SIGNAL(startSearch(RefCntr<Rcl::SearchData>)), connect(asearchform, SIGNAL(startSearch(RefCntr<Rcl::SearchData>)),
this, SLOT(startSearch(RefCntr<Rcl::SearchData>))); this, SLOT(startSearch(RefCntr<Rcl::SearchData>)));
asearchform->show(); asearchform->show();
@ -615,6 +631,8 @@ void RclMain::showSpellDialog()
{ {
if (spellform == 0) { if (spellform == 0) {
spellform = new SpellW(0); spellform = new SpellW(0);
connect(new QShortcut(quitKeySeq, spellform), SIGNAL (activated()),
this, SLOT (fileExit()));
connect(spellform, SIGNAL(wordSelect(QString)), connect(spellform, SIGNAL(wordSelect(QString)),
sSearch, SLOT(addTerm(QString))); sSearch, SLOT(addTerm(QString)));
spellform->show(); spellform->show();
@ -631,7 +649,8 @@ void RclMain::showIndexConfig()
LOGDEB(("showIndexConfig()\n")); LOGDEB(("showIndexConfig()\n"));
if (indexConfig == 0) { if (indexConfig == 0) {
indexConfig = new ConfIndexW(0, rclconfig); indexConfig = new ConfIndexW(0, rclconfig);
LOGDEB(("showIndexConfig(): confindexW created\n")); connect(new QShortcut(quitKeySeq, indexConfig), SIGNAL (activated()),
this, SLOT (fileExit()));
} else { } else {
// Close and reopen, in hope that makes us visible... // Close and reopen, in hope that makes us visible...
indexConfig->close(); indexConfig->close();
@ -643,6 +662,8 @@ void RclMain::showUIPrefs()
{ {
if (uiprefs == 0) { if (uiprefs == 0) {
uiprefs = new UIPrefsDialog(0); uiprefs = new UIPrefsDialog(0);
connect(new QShortcut(quitKeySeq, uiprefs), SIGNAL (activated()),
this, SLOT (fileExit()));
connect(uiprefs, SIGNAL(uiprefsDone()), this, SLOT(setUIPrefs())); connect(uiprefs, SIGNAL(uiprefsDone()), this, SLOT(setUIPrefs()));
connect(this, SIGNAL(stemLangChanged(const QString&)), connect(this, SIGNAL(stemLangChanged(const QString&)),
uiprefs, SLOT(setStemLang(const QString&))); uiprefs, SLOT(setStemLang(const QString&)));
@ -657,6 +678,8 @@ void RclMain::showExtIdxDialog()
{ {
if (uiprefs == 0) { if (uiprefs == 0) {
uiprefs = new UIPrefsDialog(0); uiprefs = new UIPrefsDialog(0);
connect(new QShortcut(quitKeySeq, uiprefs), SIGNAL (activated()),
this, SLOT (fileExit()));
connect(uiprefs, SIGNAL(uiprefsDone()), this, SLOT(setUIPrefs())); connect(uiprefs, SIGNAL(uiprefsDone()), this, SLOT(setUIPrefs()));
} else { } else {
// Close and reopen, in hope that makes us visible... // Close and reopen, in hope that makes us visible...
@ -673,6 +696,7 @@ void RclMain::showAboutDialog()
string("<br> http://www.xapian.org"); string("<br> http://www.xapian.org");
QMessageBox::information(this, tr("About Recoll"), vstring.c_str()); QMessageBox::information(this, tr("About Recoll"), vstring.c_str());
} }
void RclMain::showMissingHelpers() void RclMain::showMissingHelpers()
{ {
string miss = rclconfig->getMissingHelperDesc(); string miss = rclconfig->getMissingHelperDesc();
@ -719,6 +743,7 @@ void RclMain::startPreview(int docnum, Rcl::Doc doc, int mod)
HiliteData hdata; HiliteData hdata;
reslist->getTerms(hdata.terms, hdata.groups, hdata.gslks); reslist->getTerms(hdata.terms, hdata.groups, hdata.gslks);
curPreview = new Preview(reslist->listId(), hdata); curPreview = new Preview(reslist->listId(), hdata);
if (curPreview == 0) { if (curPreview == 0) {
QMessageBox::warning(0, tr("Warning"), QMessageBox::warning(0, tr("Warning"),
tr("Can't create preview window"), tr("Can't create preview window"),
@ -726,6 +751,8 @@ void RclMain::startPreview(int docnum, Rcl::Doc doc, int mod)
QMessageBox::NoButton); QMessageBox::NoButton);
return; return;
} }
connect(new QShortcut(quitKeySeq, curPreview), SIGNAL (activated()),
this, SLOT (fileExit()));
connect(curPreview, SIGNAL(previewClosed(Preview *)), connect(curPreview, SIGNAL(previewClosed(Preview *)),
this, SLOT(previewClosed(Preview *))); this, SLOT(previewClosed(Preview *)));
connect(curPreview, SIGNAL(wordSelect(QString)), connect(curPreview, SIGNAL(wordSelect(QString)),
@ -736,7 +763,7 @@ void RclMain::startPreview(int docnum, Rcl::Doc doc, int mod)
this, SLOT(previewPrevInTab(Preview *, int, int))); this, SLOT(previewPrevInTab(Preview *, int, int)));
connect(curPreview, SIGNAL(previewExposed(Preview *, int, int)), connect(curPreview, SIGNAL(previewExposed(Preview *, int, int)),
this, SLOT(previewExposed(Preview *, int, int))); this, SLOT(previewExposed(Preview *, int, int)));
curPreview->setWindowTitle(reslist->getDescription()); curPreview->setWindowTitle(getQueryDescription());
curPreview->show(); curPreview->show();
} }
curPreview->makeDocCurrent(doc, docnum); curPreview->makeDocCurrent(doc, docnum);
@ -759,6 +786,8 @@ void RclMain::startPreview(Rcl::Doc doc)
QMessageBox::NoButton); QMessageBox::NoButton);
return; return;
} }
connect(new QShortcut(quitKeySeq, preview), SIGNAL (activated()),
this, SLOT (fileExit()));
connect(preview, SIGNAL(wordSelect(QString)), connect(preview, SIGNAL(wordSelect(QString)),
sSearch, SLOT(addTerm(QString))); sSearch, SLOT(addTerm(QString)));
preview->show(); preview->show();
@ -796,7 +825,7 @@ void RclMain::previewPrevOrNextInTab(Preview * w, int sid, int docnum, bool nxt)
docnum++; docnum++;
else else
docnum--; docnum--;
if (docnum < 0 || docnum >= reslist->getResCnt()) { if (docnum < 0 || m_source.isNull() || docnum >= m_source->getResCnt()) {
QApplication::beep(); QApplication::beep();
return; return;
} }
@ -825,6 +854,9 @@ void RclMain::previewExposed(Preview *, int sid, int docnum)
void RclMain::onSortCtlChanged() void RclMain::onSortCtlChanged()
{ {
if (m_sortspecnochange)
return;
LOGDEB(("RclMain::onCtlDataChanged()\n")); LOGDEB(("RclMain::onCtlDataChanged()\n"));
m_sortspec.reset(); m_sortspec.reset();
if (actionSortByDateAsc->isChecked()) { if (actionSortByDateAsc->isChecked()) {
@ -845,9 +877,13 @@ void RclMain::onSortCtlChanged()
emit applyFiltSortData(); emit applyFiltSortData();
} }
void RclMain::onResTableSortBy(DocSeqSortSpec) void RclMain::onResTableSortBy(DocSeqSortSpec spec)
{ {
// TOBEDONE: do something about the up down arrows ! m_sortspecnochange = true;
actionSortByDateDesc->setChecked(false);
actionSortByDateAsc->setChecked(false);
m_sortspecnochange = false;
m_sortspec = spec;
emit applyFiltSortData(); emit applyFiltSortData();
} }
@ -1177,7 +1213,7 @@ void RclMain::showDocHistory()
{ {
LOGDEB(("RclMain::showDocHistory\n")); LOGDEB(("RclMain::showDocHistory\n"));
emit searchReset(); emit searchReset();
m_source = RefCntr<DocSequence>();
curPreview = 0; curPreview = 0;
string reason; string reason;
@ -1196,7 +1232,8 @@ void RclMain::showDocHistory()
new DocSequenceHistory(rcldb, g_dynconf, new DocSequenceHistory(rcldb, g_dynconf,
string(tr("Document history").toUtf8())); string(tr("Document history").toUtf8()));
src->setDescription((const char *)tr("History data").toUtf8()); src->setDescription((const char *)tr("History data").toUtf8());
reslist->setDocSource(RefCntr<DocSequence>(src)); m_source = RefCntr<DocSequence>(src);
emit docSourceChanged(m_source);
emit sortDataChanged(m_sortspec); emit sortDataChanged(m_sortspec);
emit filtDataChanged(m_filtspec); emit filtDataChanged(m_filtspec);
emit applyFiltSortData(); emit applyFiltSortData();
@ -1239,6 +1276,23 @@ void RclMain::enablePrevPage(bool yesno)
firstPageAction->setEnabled(yesno); firstPageAction->setEnabled(yesno);
} }
QString RclMain::getQueryDescription()
{
if (m_source.isNull())
return "";
return QString::fromUtf8(m_source->getDescription().c_str());
}
/** Show detailed expansion of a query */
void RclMain::showQueryDetails()
{
if (m_source.isNull())
return;
string oq = breakIntoLines(m_source->getDescription(), 100, 50);
QString desc = tr("Query details") + ": " + QString::fromUtf8(oq.c_str());
QMessageBox::information(this, tr("Query details"), desc);
}
// User pressed a category button: set filter params in reslist // User pressed a category button: set filter params in reslist
void RclMain::catgFilter(int id) void RclMain::catgFilter(int id)
{ {

View File

@ -48,13 +48,14 @@ class RclMain : public QMainWindow, public Ui::RclMainBase
public: public:
RclMain(QWidget * parent = 0) RclMain(QWidget * parent = 0)
: QMainWindow(parent) : QMainWindow(parent), m_sortspecnochange(false)
{ {
setupUi(this); setupUi(this);
init(); init();
} }
~RclMain() {} ~RclMain() {}
virtual bool eventFilter(QObject *target, QEvent *event); virtual bool eventFilter(QObject *target, QEvent *event);
QString getQueryDescription();
public slots: public slots:
virtual bool close(); virtual bool close();
@ -96,8 +97,9 @@ public slots:
virtual void focusToSearch(); virtual void focusToSearch();
virtual void on_actionSortByDateAsc_toggled(bool on); virtual void on_actionSortByDateAsc_toggled(bool on);
virtual void on_actionSortByDateDesc_toggled(bool on); virtual void on_actionSortByDateDesc_toggled(bool on);
virtual void resultCount(int);
virtual void onResTableSortBy(DocSeqSortSpec); virtual void onResTableSortBy(DocSeqSortSpec);
virtual void resultCount(int);
virtual void showQueryDetails();
signals: signals:
void docSourceChanged(RefCntr<DocSequence>); void docSourceChanged(RefCntr<DocSequence>);
@ -127,7 +129,9 @@ private:
QAction * m_idAllStem; QAction * m_idAllStem;
bool m_idxStatusAck; // Did we act on last status? bool m_idxStatusAck; // Did we act on last status?
DocSeqFiltSpec m_filtspec; DocSeqFiltSpec m_filtspec;
bool m_sortspecnochange;
DocSeqSortSpec m_sortspec; DocSeqSortSpec m_sortspec;
RefCntr<DocSequence> m_source;
virtual void init(); virtual void init();
virtual void previewPrevOrNextInTab(Preview *, int sid, int docnum, virtual void previewPrevOrNextInTab(Preview *, int sid, int docnum,

View File

@ -91,13 +91,12 @@ bool QtGuiResListPager::append(const string& data)
} }
bool QtGuiResListPager::append(const string& data, int docnum, bool QtGuiResListPager::append(const string& data, int docnum,
const Rcl::Doc& doc) const Rcl::Doc&)
{ {
LOGDEB2(("QtGuiReslistPager::appendDoc: blockCount %d, %s\n", LOGDEB2(("QtGuiReslistPager::appendDoc: blockCount %d, %s\n",
m_parent->document()->blockCount(), data.c_str())); m_parent->document()->blockCount(), data.c_str()));
logdata(data.c_str()); logdata(data.c_str());
int blkcnt0 = m_parent->document()->blockCount(); int blkcnt0 = m_parent->document()->blockCount();
m_parent->m_curDocs.push_back(doc);
m_parent->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor); m_parent->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
m_parent->textCursor().insertBlock(); m_parent->textCursor().insertBlock();
m_parent->insertHtml(QString::fromUtf8(data.c_str())); m_parent->insertHtml(QString::fromUtf8(data.c_str()));
@ -223,7 +222,6 @@ ResList::ResList(QWidget* parent, const char* name)
connect(this, SIGNAL(highlighted(const QString &)), connect(this, SIGNAL(highlighted(const QString &)),
this, SLOT(highlighted(const QString &))); this, SLOT(highlighted(const QString &)));
#endif #endif
connect(this, SIGNAL(headerClicked()), this, SLOT(showQueryDetails()));
setContextMenuPolicy(Qt::CustomContextMenu); setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
this, SLOT(createPopupMenu(const QPoint&))); this, SLOT(createPopupMenu(const QPoint&)));
@ -286,7 +284,7 @@ void ResList::readDocSource()
m_pager->setPageSize(prefs.respagesize); m_pager->setPageSize(prefs.respagesize);
m_pager->setDocSource(m_source); m_pager->setDocSource(m_source);
resultPageNext(); resultPageNext();
emit hasResults(getResCnt()); emit hasResults(m_source->getResCnt());
} }
void ResList::setSortParams(DocSeqSortSpec spec) void ResList::setSortParams(DocSeqSortSpec spec)
@ -409,37 +407,33 @@ bool ResList::getDoc(int docnum, Rcl::Doc &doc)
{ {
LOGDEB(("ResList::getDoc: docnum %d winfirst %d\n", docnum, LOGDEB(("ResList::getDoc: docnum %d winfirst %d\n", docnum,
m_pager->pageNumber() * prefs.respagesize)); m_pager->pageNumber() * prefs.respagesize));
if (docnum < 0) int winfirst = m_pager->pageFirstDocNum();
int winlast = m_pager->pageLastDocNum();
if (docnum < 0 || winfirst < 0 || winlast < 0)
return false; return false;
if (m_pager->pageNumber() < 0)
return false;
int winfirst = m_pager->pageNumber() * prefs.respagesize;
// Is docnum in current page ? Then all Ok // Is docnum in current page ? Then all Ok
if (docnum >= winfirst && docnum < winfirst + int(m_curDocs.size())) { if (docnum >= winfirst && docnum <= winlast) {
doc = m_curDocs[docnum - winfirst]; return m_source->getDoc(docnum, doc);
return true;
} }
// Else we accept to page down or up but not further // Else we accept to page down or up but not further
if (docnum < winfirst && docnum >= winfirst - prefs.respagesize) { if (docnum < winfirst && docnum >= winfirst - prefs.respagesize) {
resultPageBack(); resultPageBack();
} else if (docnum < winfirst + int(m_curDocs.size()) + prefs.respagesize) { } else if (docnum < winlast + 1 + prefs.respagesize) {
resultPageNext(); resultPageNext();
} }
winfirst = m_pager->pageNumber() * prefs.respagesize; winfirst = m_pager->pageFirstDocNum();
if (docnum >= winfirst && docnum < winfirst + int(m_curDocs.size())) { winlast = m_pager->pageLastDocNum();
doc = m_curDocs[docnum - winfirst]; if (docnum >= winfirst && docnum <= winlast) {
return true; return m_source->getDoc(docnum, doc);
} }
return false; return false;
} }
void ResList::keyPressEvent(QKeyEvent * e) void ResList::keyPressEvent(QKeyEvent * e)
{ {
if (e->key() == Qt::Key_Q && (e->modifiers() & Qt::ControlModifier)) { if (e->key() == Qt::Key_PageUp || e->key() == Qt::Key_Backspace) {
recollNeedsExit = 1;
return;
} else if (e->key() == Qt::Key_PageUp || e->key() == Qt::Key_Backspace) {
resPageUpOrBack(); resPageUpOrBack();
return; return;
} else if (e->key() == Qt::Key_PageDown || e->key() == Qt::Key_Space) { } else if (e->key() == Qt::Key_PageDown || e->key() == Qt::Key_Space) {
@ -461,14 +455,6 @@ void ResList::mouseReleaseEvent(QMouseEvent *e)
QTextBrowser::mouseReleaseEvent(e); QTextBrowser::mouseReleaseEvent(e);
} }
// Return total result list count
int ResList::getResCnt()
{
if (m_source.isNull())
return -1;
return m_source->getResCnt();
}
void ResList::highlighted(const QString& ) void ResList::highlighted(const QString& )
{ {
// This is supposedly called when a link is preactivated (hover or tab // This is supposedly called when a link is preactivated (hover or tab
@ -530,7 +516,6 @@ void ResList::resultPageNext()
void ResList::displayPage() void ResList::displayPage()
{ {
m_curDocs.clear();
m_pageParaToReldocnums.clear(); m_pageParaToReldocnums.clear();
clear(); clear();
m_pager->displayPage(); m_pager->displayPage();
@ -587,7 +572,6 @@ void ResList::previewExposed(int docnum)
} }
} }
// Double click in res list: add selection to simple search // Double click in res list: add selection to simple search
void ResList::mouseDoubleClickEvent(QMouseEvent *event) void ResList::mouseDoubleClickEvent(QMouseEvent *event)
{ {
@ -668,6 +652,7 @@ void ResList::menuPreview()
if (getDoc(m_popDoc, doc)) if (getDoc(m_popDoc, doc))
emit docPreviewClicked(m_popDoc, doc, 0); emit docPreviewClicked(m_popDoc, doc, 0);
} }
void ResList::menuSaveToFile() void ResList::menuSaveToFile()
{ {
Rcl::Doc doc; Rcl::Doc doc;
@ -715,6 +700,7 @@ void ResList::menuEdit()
if (getDoc(m_popDoc, doc)) if (getDoc(m_popDoc, doc))
emit docEditClicked(doc); emit docEditClicked(doc);
} }
void ResList::menuCopyFN() void ResList::menuCopyFN()
{ {
LOGDEB(("menuCopyFN\n")); LOGDEB(("menuCopyFN\n"));
@ -734,6 +720,7 @@ void ResList::menuCopyFN()
QApplication::clipboard()->setText(qfn, QClipboard::Clipboard); QApplication::clipboard()->setText(qfn, QClipboard::Clipboard);
} }
} }
void ResList::menuCopyURL() void ResList::menuCopyURL()
{ {
Rcl::Doc doc; Rcl::Doc doc;
@ -752,16 +739,3 @@ void ResList::menuExpand()
if (getDoc(m_popDoc, doc)) if (getDoc(m_popDoc, doc))
emit docExpand(doc); emit docExpand(doc);
} }
QString ResList::getDescription()
{
return QString::fromUtf8(m_source->getDescription().c_str());
}
/** Show detailed expansion of a query */
void ResList::showQueryDetails()
{
string oq = breakIntoLines(m_source->getDescription(), 100, 50);
QString desc = tr("Query details") + ": " + QString::fromUtf8(oq.c_str());
QMessageBox::information(this, tr("Query details"), desc);
}

View File

@ -44,12 +44,9 @@ class ResList : public QTextBrowser
// Return document for given docnum. We act as an intermediary to // Return document for given docnum. We act as an intermediary to
// the docseq here. This has also the side-effect of making the // the docseq here. This has also the side-effect of making the
// entry current (visible and highlighted), and only work if the // entry current (visible and highlighted), and only works if the
// num is inside the current page or its immediate neighbours. // num is inside the current page or its immediate neighbours.
bool getDoc(int docnum, Rcl::Doc &); bool getDoc(int docnum, Rcl::Doc &);
QString getDescription(); // Printable actual query performed on db
int getResCnt(); // Return total result list size
bool displayingHistory(); bool displayingHistory();
bool getTerms(vector<string>& terms, bool getTerms(vector<string>& terms,
vector<vector<string> >& groups, vector<int>& gslks); vector<vector<string> >& groups, vector<int>& gslks);
@ -103,16 +100,15 @@ class ResList : public QTextBrowser
protected slots: protected slots:
virtual void languageChange(); virtual void languageChange();
virtual void linkWasClicked(const QUrl &); virtual void linkWasClicked(const QUrl &);
virtual void showQueryDetails();
private: private:
QtGuiResListPager *m_pager; QtGuiResListPager *m_pager;
RefCntr<DocSequence> m_source; RefCntr<DocSequence> m_source;
std::vector<Rcl::Doc> m_curDocs; // Docs for current page
// Translate from textedit paragraph number to relative // Translate from textedit paragraph number to relative
// docnum. Built while we insert text into the qtextedit // docnum. Built while we insert text into the qtextedit
std::map<int,int> m_pageParaToReldocnums; std::map<int,int> m_pageParaToReldocnums;
int m_popDoc; // Docnum for the popup menu. int m_popDoc; // Docnum for the popup menu.
int m_curPvDoc;// Docnum for current preview int m_curPvDoc;// Docnum for current preview
int m_lstClckMod; // Last click modifier. int m_lstClckMod; // Last click modifier.

View File

@ -5,9 +5,12 @@ static char rcsid[] = "@(#$Id: reslist.cpp,v 1.52 2008-12-17 15:12:08 dockes Exp
#include "autoconfig.h" #include "autoconfig.h"
#include <stdlib.h> #include <stdlib.h>
#include <time.h>
#include <Qt> #include <Qt>
#include <QShortcut>
#include <QAbstractTableModel> #include <QAbstractTableModel>
#include <QSettings>
#include "refcntr.h" #include "refcntr.h"
#include "docseq.h" #include "docseq.h"
@ -65,17 +68,63 @@ string ResTablePager::iconPath(const string& mtype)
////////////////////////////////////////////// //////////////////////////////////////////////
//// Data model methods //// Data model methods
//// ////
static string gengetter(const string& fld, const Rcl::Doc& doc)
{
map<string, string>::const_iterator it = doc.meta.find(fld);
if (it == doc.meta.end()) {
return string();
}
return it->second;
}
static string dategetter(const string&, const Rcl::Doc& doc)
{
char datebuf[100];
datebuf[0] = 0;
if (!doc.dmtime.empty() || !doc.fmtime.empty()) {
time_t mtime = doc.dmtime.empty() ?
atol(doc.fmtime.c_str()) : atol(doc.dmtime.c_str());
struct tm *tm = localtime(&mtime);
strftime(datebuf, 99, "%x", tm);
}
return datebuf;
}
static string datetimegetter(const string&, const Rcl::Doc& doc)
{
char datebuf[100];
datebuf[0] = 0;
if (!doc.dmtime.empty() || !doc.fmtime.empty()) {
time_t mtime = doc.dmtime.empty() ?
atol(doc.fmtime.c_str()) : atol(doc.dmtime.c_str());
struct tm *tm = localtime(&mtime);
#ifndef sun
strftime(datebuf, 99, "%Y-%m-%d %H:%M:%S %z", tm);
#else
strftime(datebuf, 99, "%c", tm);
#endif
}
return datebuf;
}
RecollModel::RecollModel(const QStringList fields, QObject *parent) RecollModel::RecollModel(const QStringList fields, QObject *parent)
: QAbstractTableModel(parent) : QAbstractTableModel(parent)
{ {
for (QStringList::const_iterator it = fields.begin(); for (QStringList::const_iterator it = fields.begin();
it != fields.end(); it++) it != fields.end(); it++) {
m_fields.push_back((const char *)(it->toUtf8())); m_fields.push_back((const char *)(it->toUtf8()));
if (!stringlowercmp("date", m_fields[m_fields.size()-1]))
m_getters.push_back(dategetter);
else if (!stringlowercmp("datetime", m_fields[m_fields.size()-1]))
m_getters.push_back(datetimegetter);
else
m_getters.push_back(gengetter);
}
} }
int RecollModel::rowCount(const QModelIndex&) const int RecollModel::rowCount(const QModelIndex&) const
{ {
LOGDEB(("RecollModel::rowCount\n")); LOGDEB2(("RecollModel::rowCount\n"));
if (m_source.isNull()) if (m_source.isNull())
return 0; return 0;
return m_source->getResCnt(); return m_source->getResCnt();
@ -83,7 +132,7 @@ int RecollModel::rowCount(const QModelIndex&) const
int RecollModel::columnCount(const QModelIndex&) const int RecollModel::columnCount(const QModelIndex&) const
{ {
LOGDEB(("RecollModel::columnCount\n")); LOGDEB2(("RecollModel::columnCount\n"));
return m_fields.size(); return m_fields.size();
} }
@ -106,41 +155,57 @@ bool RecollModel::getdoc(int index, Rcl::Doc &doc)
return m_source->getDoc(index, doc); return m_source->getDoc(index, doc);
} }
QVariant RecollModel::headerData(int col, Qt::Orientation orientation, QVariant RecollModel::headerData(int idx, Qt::Orientation orientation,
int role) const int role) const
{ {
LOGDEB(("RecollModel::headerData: col %d\n", col)); LOGDEB2(("RecollModel::headerData: idx %d\n", idx));
if (orientation != Qt::Horizontal || role != Qt::DisplayRole || if (orientation == Qt::Vertical && role == Qt::DisplayRole) {
col >= int(m_fields.size())) { return idx;
return QVariant();
} }
return QString::fromUtf8(m_fields[col].c_str()); if (orientation == Qt::Horizontal && role == Qt::DisplayRole &&
idx < int(m_fields.size())) {
return QString::fromUtf8(m_fields[idx].c_str());
}
return QVariant();
} }
QVariant RecollModel::data(const QModelIndex& index, int role) const QVariant RecollModel::data(const QModelIndex& index, int role) const
{ {
LOGDEB(("RecollModel::data: row %d col %d\n", index.row(), LOGDEB2(("RecollModel::data: row %d col %d\n", index.row(),
index.column())); index.column()));
if (m_source.isNull() || role != Qt::DisplayRole || !index.isValid() || if (m_source.isNull() || role != Qt::DisplayRole || !index.isValid() ||
index.column() >= int(m_fields.size())) { index.column() >= int(m_fields.size())) {
return QVariant(); return QVariant();
} }
Rcl::Doc doc; Rcl::Doc doc;
if (!m_source->getDoc(index.row(), doc)) { if (!m_source->getDoc(index.row(), doc)) {
return QVariant(); return QVariant();
} }
map<string, string>::const_iterator it =
doc.meta.find(m_fields[index.column()]); // Have to handle the special cases here. Some fields are
if (it == doc.meta.end()) { // synthetic and their name is hard-coded. Only date and datetime
return QVariant(); // for now.
} string colname = m_fields[index.column()];
return QString::fromUtf8(it->second.c_str()); return QString::fromUtf8(m_getters[index.column()](colname, doc).c_str());
} }
// This is called when the column headers are clicked
void RecollModel::sort(int column, Qt::SortOrder order) void RecollModel::sort(int column, Qt::SortOrder order)
{ {
LOGDEB(("RecollModel::sort(%d, %d)\n", column, int(order))); LOGDEB(("RecollModel::sort(%d, %d)\n", column, int(order)));
if (column >= 0 && column < int(m_fields.size())) {
DocSeqSortSpec spec;
spec.field = m_fields[column];
if (!stringlowercmp("date", spec.field) ||
!stringlowercmp("datetime", spec.field))
spec.field = "mtime";
spec.desc = order == Qt::AscendingOrder ? false : true;
m_source->setSortSpec(spec);
setDocSource(m_source);
emit sortDataChanged(spec);
}
} }
@ -151,7 +216,9 @@ void ResTable::init()
if (!(m_model = new RecollModel(prefs.restableFields))) if (!(m_model = new RecollModel(prefs.restableFields)))
return; return;
tableView->setModel(m_model); tableView->setModel(m_model);
m_pager = new ResTablePager(this); tableView->setMouseTracking(true);
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
tableView->setSelectionMode(QAbstractItemView::SingleSelection);
QHeaderView *header = tableView->horizontalHeader(); QHeaderView *header = tableView->horizontalHeader();
if (header) { if (header) {
@ -164,14 +231,34 @@ void ResTable::init()
header->setSortIndicator(-1, Qt::AscendingOrder); header->setSortIndicator(-1, Qt::AscendingOrder);
connect(header, SIGNAL(sectionResized(int,int,int)), connect(header, SIGNAL(sectionResized(int,int,int)),
this, SLOT(saveColWidths())); this, SLOT(saveColWidths()));
connect(header, SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)),
this, SLOT(sortByColumn(int, Qt::SortOrder)));
} }
header = tableView->verticalHeader();
if (header) {
header->setDefaultSectionSize(22);
}
QKeySequence seq("Esc");
QShortcut *sc = new QShortcut(seq, this);
connect(sc, SIGNAL (activated()),
tableView->selectionModel(), SLOT (clear()));
connect(tableView->selectionModel(), SIGNAL(currentChanged(const QModelIndex&, const QModelIndex &)),
this, SLOT(onTableView_currentChanged(const QModelIndex&)));
m_pager = new ResTablePager(this);
QSettings settings;
splitter->restoreState(settings.value("resTableSplitterSizes").toByteArray());
} }
void ResTable::on_tableView_clicked(const QModelIndex& index) void ResTable::saveSizeState()
{ {
LOGDEB(("ResTable::on_tableView_clicked(%d, %d)\n", QSettings settings;
settings.setValue("resTableSplitterSizes", splitter->saveState());
}
void ResTable::onTableView_currentChanged(const QModelIndex& index)
{
LOGDEB(("ResTable::onTableView_currentChanged(%d, %d)\n",
index.row(), index.column())); index.row(), index.column()));
if (!m_model || m_model->m_source.isNull()) if (!m_model || m_model->m_source.isNull())
@ -186,6 +273,14 @@ void ResTable::on_tableView_clicked(const QModelIndex& index)
} }
} }
void ResTable::on_tableView_entered(const QModelIndex& index)
{
LOGDEB(("ResTable::on_tableView_entered(%d, %d)\n",
index.row(), index.column()));
if (!tableView->selectionModel()->hasSelection())
onTableView_currentChanged(index);
}
void ResTable::setDocSource(RefCntr<DocSequence> nsource) void ResTable::setDocSource(RefCntr<DocSequence> nsource)
{ {
LOGDEB(("ResTable::setDocSource\n")); LOGDEB(("ResTable::setDocSource\n"));
@ -215,18 +310,13 @@ void ResTable::saveColWidths()
} }
} }
void ResTable::sortByColumn(int column, Qt::SortOrder order) // This is called when the sort order is changed from another widget
void ResTable::onSortDataChanged(DocSeqSortSpec)
{ {
LOGDEB(("ResTable::sortByColumn(%d,%d)\n", column, int(order))); QHeaderView *header = tableView->horizontalHeader();
if (!header)
if (column >= 0 && m_model && column < int(m_model->m_fields.size())) { return;
DocSeqSortSpec spec; header->setSortIndicator(-1, Qt::AscendingOrder);
spec.field = m_model->m_fields[column];
spec.desc = order == Qt::AscendingOrder ? false : true;
m_model->m_source->setSortSpec(spec);
readDocSource();
emit sortDataChanged(spec);
}
} }
void ResTable::readDocSource() void ResTable::readDocSource()

View File

@ -26,6 +26,8 @@
class ResTable; class ResTable;
typedef string (FieldGetter)(const string& fldname, const Rcl::Doc& doc);
class RecollModel : public QAbstractTableModel { class RecollModel : public QAbstractTableModel {
Q_OBJECT Q_OBJECT
@ -45,9 +47,14 @@ public:
virtual bool getdoc(int index, Rcl::Doc &doc); virtual bool getdoc(int index, Rcl::Doc &doc);
friend class ResTable; friend class ResTable;
signals:
void sortDataChanged(DocSeqSortSpec);
private: private:
mutable RefCntr<DocSequence> m_source; mutable RefCntr<DocSequence> m_source;
vector<string> m_fields; vector<string> m_fields;
vector<FieldGetter*> m_getters;
}; };
class ResTablePager; class ResTablePager;
@ -66,18 +73,17 @@ public:
} }
virtual ~ResTable() {} virtual ~ResTable() {}
virtual RecollModel *getModel() {return m_model;}
virtual void saveSizeState();
public slots: public slots:
virtual void on_tableView_clicked(const QModelIndex&); virtual void onTableView_currentChanged(const QModelIndex&);
virtual void on_tableView_entered(const QModelIndex& index);
virtual void saveColWidths(); virtual void saveColWidths();
virtual void sortByColumn(int column, Qt::SortOrder order);
virtual void setDocSource(RefCntr<DocSequence> nsource); virtual void setDocSource(RefCntr<DocSequence> nsource);
virtual void resetSource(); virtual void resetSource();
virtual void readDocSource(); virtual void readDocSource();
virtual void onSortDataChanged(DocSeqSortSpec);
signals:
void sortDataChanged(DocSeqSortSpec);
friend class ResTablePager; friend class ResTablePager;
private: private:

View File

@ -26,15 +26,24 @@
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>10</verstretch> <verstretch>2</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="editTriggers"> <property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set> <set>QAbstractItemView::NoEditTriggers</set>
</property> </property>
<property name="alternatingRowColors">
<bool>false</bool>
</property>
<property name="showGrid">
<bool>true</bool>
</property>
<property name="sortingEnabled"> <property name="sortingEnabled">
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="cornerButtonEnabled"> <property name="cornerButtonEnabled">
<bool>false</bool> <bool>false</bool>
</property> </property>
@ -49,7 +58,7 @@
<property name="sizePolicy"> <property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred"> <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch> <horstretch>0</horstretch>
<verstretch>1</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
</widget> </widget>

View File

@ -120,11 +120,12 @@ bool DocSequenceDb::setFiltSpec(const DocSeqFiltSpec &fs)
return m_q->setQuery(m_fsdata); return m_q->setQuery(m_fsdata);
} }
bool DocSequenceDb::setSortSpec(const DocSeqSortSpec &sortspec) bool DocSequenceDb::setSortSpec(const DocSeqSortSpec &spec)
{ {
LOGDEB(("DocSequenceDb::setSortSpec\n")); LOGDEB(("DocSequenceDb::setSortSpec: fld [%s] %s\n",
if (sortspec.isNotNull()) { spec.field.c_str(), spec.desc ? "desc" : "asc"));
m_q->setSortBy(sortspec.field, !sortspec.desc); if (spec.isNotNull()) {
m_q->setSortBy(spec.field, !spec.desc);
} else { } else {
m_q->setSortBy(string(), true); m_q->setSortBy(string(), true);
} }

View File

@ -41,6 +41,14 @@ public:
return -1; return -1;
return m_winfirst / m_pagesize; return m_winfirst / m_pagesize;
} }
int pageFirstDocNum() {
return m_winfirst;
}
int pageLastDocNum() {
if (m_winfirst < 0 || m_respage.size() == 0)
return -1;
return m_winfirst + m_respage.size() - 1;
}
virtual int pageSize() const {return m_pagesize;} virtual int pageSize() const {return m_pagesize;}
void pageNext(); void pageNext();
bool hasNext() {return m_hasNext;} bool hasNext() {return m_hasNext;}

View File

@ -142,7 +142,7 @@ static const string keycap("caption");
bool Db::Native::dbDataToRclDoc(Xapian::docid docid, std::string &data, bool Db::Native::dbDataToRclDoc(Xapian::docid docid, std::string &data,
Doc &doc, int percent) Doc &doc, int percent)
{ {
LOGDEB0(("Db::dbDataToRclDoc: data:\n %s\n", data.c_str())); LOGDEB2(("Db::dbDataToRclDoc: data:\n%s\n", data.c_str()));
ConfSimple parms(data); ConfSimple parms(data);
if (!parms.ok()) if (!parms.ok())
return false; return false;
@ -225,7 +225,7 @@ static void listList(const string& what, const list<string>&l)
string Db::Native::makeAbstract(Xapian::docid docid, Query *query) string Db::Native::makeAbstract(Xapian::docid docid, Query *query)
{ {
Chrono chron; Chrono chron;
LOGDEB(("makeAbstract:%d: maxlen %d wWidth %d\n", chron.ms(), LOGDEB0(("makeAbstract:%d: maxlen %d wWidth %d\n", chron.ms(),
m_rcldb->m_synthAbsLen, m_rcldb->m_synthAbsWordCtxLen)); m_rcldb->m_synthAbsLen, m_rcldb->m_synthAbsWordCtxLen));
list<string> terms; list<string> terms;
@ -433,7 +433,7 @@ string Db::Native::makeAbstract(Xapian::docid docid, Query *query)
if ('A' <= (*term).at(0) && (*term).at(0) <= 'Z') if ('A' <= (*term).at(0) && (*term).at(0) <= 'Z')
continue; continue;
if (cutoff-- < 0) { if (cutoff-- < 0) {
LOGDEB(("makeAbstract: max term count cutoff\n")); LOGDEB0(("makeAbstract: max term count cutoff\n"));
break; break;
} }
@ -441,7 +441,7 @@ string Db::Native::makeAbstract(Xapian::docid docid, Query *query)
for (pos = xrdb.positionlist_begin(docid, *term); for (pos = xrdb.positionlist_begin(docid, *term);
pos != xrdb.positionlist_end(docid, *term); pos++) { pos != xrdb.positionlist_end(docid, *term); pos++) {
if (cutoff-- < 0) { if (cutoff-- < 0) {
LOGDEB(("makeAbstract: max term count cutoff\n")); LOGDEB0(("makeAbstract: max term count cutoff\n"));
break; break;
} }
map<unsigned int, string>::iterator vit; map<unsigned int, string>::iterator vit;
@ -504,7 +504,7 @@ string Db::Native::makeAbstract(Xapian::docid docid, Query *query)
if (!abstract.compare("... ")) if (!abstract.compare("... "))
abstract.clear(); abstract.clear();
LOGDEB(("makeAbtract: done in %d mS\n", chron.millis())); LOGDEB0(("makeAbtract: done in %d mS\n", chron.millis()));
return abstract; return abstract;
} }