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
+61 -10
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);
}
}
+7 -3
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;
};
+6
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();
}
};
/**
-1
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);