restable: highlight match terms

This commit is contained in:
Jean-Francois Dockes 2011-01-28 12:28:27 +01:00
parent 131c0189f4
commit 50238d5577
5 changed files with 75 additions and 15 deletions

View File

@ -15,6 +15,9 @@ static char rcsid[] = "@(#$Id: reslist.cpp,v 1.52 2008-12-17 15:12:08 dockes Exp
#include <QSettings>
#include <QMenu>
#include <QScrollBar>
#include <QStyledItemDelegate>
#include <QTextDocument>
#include <QPainter>
#include "refcntr.h"
#include "docseq.h"
@ -27,7 +30,8 @@ static char rcsid[] = "@(#$Id: reslist.cpp,v 1.52 2008-12-17 15:12:08 dockes Exp
#include "plaintorich.h"
//////////////////////////////////
// Restable "pager". We use it to display a single doc details in the detail area
// Restable "pager". We use it to display a single doc details in the
// detail area
///
class ResTablePager : public ResListPager {
public:
@ -42,6 +46,21 @@ private:
ResTable *m_parent;
};
//////////////////////////
// Restable hiliter: to highlight search term in the table. This is actually
// the same as reslist's, could be shared.
class PlainToRichQtReslist : public PlainToRich {
public:
virtual ~PlainToRichQtReslist() {}
virtual string startMatch() {
return string("<span style='color: ")
+ string((const char *)prefs.qtermcolor.toAscii()) + string("'>");
}
virtual string endMatch() {return string("</span>");}
};
static PlainToRichQtReslist g_hiliter;
/////////////////////////////////////
bool ResTablePager::append(const string& data, int docnum, const Rcl::Doc&)
{
m_parent->textBrowser->moveCursor(QTextCursor::End,
@ -177,6 +196,8 @@ RecollModel::RecollModel(const QStringList fields, QObject *parent)
m_fields.push_back((const char *)(it->toUtf8()));
m_getters.push_back(chooseGetter(m_fields[m_fields.size()-1]));
}
g_hiliter.set_inputhtml(false);
}
int RecollModel::rowCount(const QModelIndex&) const
@ -203,10 +224,13 @@ void RecollModel::readDocSource()
void RecollModel::setDocSource(RefCntr<DocSequence> nsource)
{
LOGDEB(("RecollModel::setDocSource\n"));
if (nsource.isNull())
if (nsource.isNull()) {
m_source = RefCntr<DocSequence>();
else
} else {
m_source = RefCntr<DocSequence>(new DocSource(nsource));
m_hdata.reset();
m_source->getTerms(m_hdata.terms, m_hdata.groups, m_hdata.gslks);
}
readDocSource();
}
@ -273,11 +297,11 @@ QVariant RecollModel::data(const QModelIndex& index, int role) const
return QVariant();
}
// Have to handle the special cases here. Some fields are
// synthetic and their name is hard-coded. Only date and datetime
// for now.
string colname = m_fields[index.column()];
return QString::fromUtf8(m_getters[index.column()](colname, doc).c_str());
list<string> lr;
g_hiliter.plaintorich(m_getters[index.column()](colname, doc), lr, m_hdata);
return QString::fromUtf8(lr.front().c_str());
}
// This gets called when the column headers are clicked
@ -300,6 +324,34 @@ void RecollModel::sort(int column, Qt::SortOrder order)
///////////////////////////
// ResTable panel methods
// We use a custom delegate to display the cells because the base
// tableview's can't handle rich text to highlight the match terms
class ResTableDelegate: public QStyledItemDelegate {
public:
ResTableDelegate(QObject *parent) : QStyledItemDelegate(parent) {}
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QVariant value = index.data(Qt::DisplayRole);
if (value.isValid() && !value.isNull()) {
// We might possibly want to optimize by passing the data
// to the base method if the text does not contain any
// term matches. Would need a modif to plaintorich to
// return the match count (easy), and a way to pass an
// indicator from data(), a bit more difficult. Anyway,
// the display seems fast enough as is.
QTextDocument document;
document.setHtml(value.toString());
painter->save();
painter->setClipRect(option.rect);
painter->translate(option.rect.topLeft());
document.drawContents(painter);
painter->restore();
}
}
};
void ResTable::init()
{
if (!(m_model = new RecollModel(prefs.restableFields)))
@ -308,6 +360,7 @@ void ResTable::init()
tableView->setMouseTracking(true);
tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
tableView->setSelectionMode(QAbstractItemView::SingleSelection);
tableView->setItemDelegate(new ResTableDelegate(this));
QHeaderView *header = tableView->horizontalHeader();
if (header) {
@ -407,13 +460,11 @@ void ResTable::onTableView_currentChanged(const QModelIndex& index)
if (!m_model || m_model->getDocSource().isNull())
return;
HiliteData hdata;
m_model->getDocSource()->getTerms(hdata.terms, hdata.groups, hdata.gslks);
Rcl::Doc doc;
if (m_model->getDocSource()->getDoc(index.row(), doc)) {
textBrowser->clear();
m_detaildocnum = index.row();
m_pager->displayDoc(index.row(), doc, hdata);
m_pager->displayDoc(index.row(), doc, m_model->m_hdata);
}
}

View File

@ -23,6 +23,7 @@
#include "ui_restable.h"
#include "refcntr.h"
#include "docseq.h"
#include "plaintorich.h"
class ResTable;
@ -62,6 +63,8 @@ public:
// Ignore sort() call because
virtual void setIgnoreSort(bool onoff) {m_ignoreSort = onoff;}
friend class ResTable;
signals:
void sortColumnChanged(DocSeqSortSpec);
@ -72,6 +75,7 @@ private:
static map<string, string> o_displayableFields;
bool m_ignoreSort;
FieldGetter* chooseGetter(const string&);
HiliteData m_hdata;
};
class ResTablePager;
@ -114,10 +118,10 @@ signals:
friend class ResTablePager;
private:
void init();
RecollModel *m_model;
ResTablePager *m_pager;
RecollModel *m_model;
ResTablePager *m_pager;
int m_detaildocnum;
int m_popcolumn;
int m_popcolumn;
};

View File

@ -33,6 +33,12 @@ struct HiliteData {
// Group slacks (number of permitted non-matched words).
// Parallel vector to the above 'groups'
vector<int> gslks;
void reset()
{
terms.clear();
groups.clear();
gslks.clear();
}
};
/**

View File

@ -362,7 +362,6 @@ bool Query::getDoc(int xapi, Doc &doc)
doc.pc = pc;
char buf[200];
if (collapsecount>0) {
LOGDEB(("COLLAPSECOUNET %d\n", collapsecount));
sprintf(buf,"%3d%% (%d)", pc, collapsecount+1);
} else {
sprintf(buf,"%3d%%", pc);

View File

@ -205,7 +205,7 @@
manager to install or update Recoll and Xapian. To avoid
messages about signature errors, if not done at the previous step,
you may have to explicitely import the
Recoll and Xapian public keys (as root): <pre><tt>
Recoll and Xapian public keys: <pre><tt>
gpg --keyserver keyserver.ubuntu.com --recv 9DA85604
gpg --export --armor 9DA85604 | sudo apt-key add -
gpg --keyserver keyserver.ubuntu.com --recv A0735AD0