Gui restable: add/remove columns
This commit is contained in:
parent
1e6fde221d
commit
3bd39d893e
@ -56,17 +56,6 @@ const char *v114reslistformat = "<img src=\"%I\" align=\"left\">"
|
||||
"%A %K";
|
||||
|
||||
|
||||
bool getStemLangs(list<string>& langs)
|
||||
{
|
||||
string reason;
|
||||
if (!maybeOpenDb(reason)) {
|
||||
LOGERR(("getStemLangs: %s\n", reason.c_str()));
|
||||
return false;
|
||||
}
|
||||
langs = rcldb->getStemLangs();
|
||||
return true;
|
||||
}
|
||||
|
||||
// The global preferences structure
|
||||
PrefsPack prefs;
|
||||
|
||||
@ -77,8 +66,8 @@ PrefsPack prefs;
|
||||
if (writing) { \
|
||||
settings.setValue(nm , var); \
|
||||
} else { \
|
||||
var = settings.value(nm, def).to##tp \
|
||||
(); \
|
||||
var = settings.value(nm, def).to##tp \
|
||||
(); \
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -49,13 +49,6 @@ using std::list;
|
||||
using std::vector;
|
||||
#endif
|
||||
|
||||
/** Retrieve configured stemming languages */
|
||||
bool getStemLangs(list<string>& langs);
|
||||
|
||||
/** Start a browser on the help document */
|
||||
extern bool startHelpBrowser(const string& url = "");
|
||||
|
||||
|
||||
/** Holder for preferences (gets saved to user Qt prefs) */
|
||||
class PrefsPack {
|
||||
public:
|
||||
|
||||
@ -96,6 +96,17 @@ bool maybeOpenDb(string &reason, bool force)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool getStemLangs(list<string>& langs)
|
||||
{
|
||||
string reason;
|
||||
if (!maybeOpenDb(reason)) {
|
||||
LOGERR(("getStemLangs: %s\n", reason.c_str()));
|
||||
return false;
|
||||
}
|
||||
langs = rcldb->getStemLangs();
|
||||
return true;
|
||||
}
|
||||
|
||||
static void recollCleanup()
|
||||
{
|
||||
LOGDEB(("recollCleanup: writing settings\n"));
|
||||
|
||||
@ -456,7 +456,7 @@ void RclMain::fileExit()
|
||||
prefs.mainwidth = width();
|
||||
prefs.mainheight = height();
|
||||
}
|
||||
restable->saveSizeState();
|
||||
restable->saveColState();
|
||||
|
||||
prefs.ssearchTyp = sSearch->searchTypCMB->currentIndex();
|
||||
if (asearchform)
|
||||
@ -923,8 +923,8 @@ void RclMain::saveDocToFile(Rcl::Doc doc)
|
||||
{
|
||||
QString s =
|
||||
QFileDialog::getSaveFileName(this, //parent
|
||||
tr("Save file"), // caption
|
||||
QString::fromLocal8Bit(path_home().c_str()) //dir
|
||||
tr("Save file"),
|
||||
QString::fromLocal8Bit(path_home().c_str())
|
||||
);
|
||||
string tofile((const char *)s.toLocal8Bit());
|
||||
TempFile temp; // not used
|
||||
@ -1295,7 +1295,9 @@ 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());
|
||||
QString str;
|
||||
QString desc = tr("Result count (est.)") + ": " + str.setNum(m_source->getResCnt()) + "<br>";
|
||||
desc += tr("Query details") + ": " + QString::fromUtf8(oq.c_str());
|
||||
QMessageBox::information(this, tr("Query details"), desc);
|
||||
}
|
||||
|
||||
|
||||
@ -78,7 +78,7 @@ public slots:
|
||||
virtual void enableNextPage(bool);
|
||||
virtual void enablePrevPage(bool);
|
||||
virtual void docExpand(Rcl::Doc);
|
||||
virtual void startPreview(int doc, Rcl::Doc doc, int keymods);
|
||||
virtual void startPreview(int docnum, Rcl::Doc doc, int keymods);
|
||||
virtual void startPreview(Rcl::Doc);
|
||||
virtual void startNativeViewer(Rcl::Doc);
|
||||
virtual void saveDocToFile(Rcl::Doc);
|
||||
@ -87,9 +87,7 @@ public slots:
|
||||
virtual void previewExposed(Preview *, int sid, int docnum);
|
||||
virtual void resetSearch();
|
||||
virtual void eraseDocHistory();
|
||||
// Callback for setting the stemming language through the prefs menu
|
||||
virtual void setStemLang(QAction *id);
|
||||
// Prefs menu about to show, set the checked lang entry
|
||||
virtual void adjustPrefsMenu();
|
||||
virtual void catgFilter(int);
|
||||
virtual void initDbOpen();
|
||||
|
||||
@ -29,6 +29,9 @@
|
||||
// Open the database if needed. We now force a close/open by default
|
||||
extern bool maybeOpenDb(std::string &reason, bool force = true);
|
||||
|
||||
/** Retrieve configured stemming languages */
|
||||
bool getStemLangs(list<string>& langs);
|
||||
|
||||
extern RclConfig *rclconfig;
|
||||
extern Rcl::Db *rcldb;
|
||||
extern int recollNeedsExit;
|
||||
|
||||
@ -7,10 +7,13 @@ static char rcsid[] = "@(#$Id: reslist.cpp,v 1.52 2008-12-17 15:12:08 dockes Exp
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <Qt>
|
||||
#include <QShortcut>
|
||||
#include <QAbstractTableModel>
|
||||
#include <QSettings>
|
||||
#include <QMenu>
|
||||
|
||||
#include "refcntr.h"
|
||||
#include "docseq.h"
|
||||
@ -23,7 +26,7 @@ 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 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:
|
||||
@ -68,6 +71,9 @@ string ResTablePager::iconPath(const string& mtype)
|
||||
//////////////////////////////////////////////
|
||||
//// Data model methods
|
||||
////
|
||||
|
||||
// Routines used to extract named data from an Rcl::Doc. The basic one just uses the meta map. Others
|
||||
// (ie: the date ones) need to do a little processing
|
||||
static string gengetter(const string& fld, const Rcl::Doc& doc)
|
||||
{
|
||||
map<string, string>::const_iterator it = doc.meta.find(fld);
|
||||
@ -107,18 +113,60 @@ static string datetimegetter(const string&, const Rcl::Doc& doc)
|
||||
return datebuf;
|
||||
}
|
||||
|
||||
// Static map to translate from internal column names to displayable ones
|
||||
map<string, string> RecollModel::o_displayableFields =
|
||||
create_map<string, string>
|
||||
("abstract", QT_TR_NOOP("Abstract"))
|
||||
("author", QT_TR_NOOP("Author"))
|
||||
("dbytes", QT_TR_NOOP("Document size"))
|
||||
("dmtime", QT_TR_NOOP("Document date"))
|
||||
("fbytes", QT_TR_NOOP("File size"))
|
||||
("filename", QT_TR_NOOP("File name"))
|
||||
("fmtime", QT_TR_NOOP("File date"))
|
||||
("ipath", QT_TR_NOOP(" Ipath"))
|
||||
("keywords", QT_TR_NOOP("Keywords"))
|
||||
("mtype", QT_TR_NOOP("Mime type"))
|
||||
("origcharset", QT_TR_NOOP("Original character set"))
|
||||
("relevancyrating", QT_TR_NOOP("Relevancy rating"))
|
||||
("title", QT_TR_NOOP("Title"))
|
||||
("url", QT_TR_NOOP("URL"))
|
||||
("mtime", QT_TR_NOOP("Mtime"))
|
||||
("date", QT_TR_NOOP("Date"))
|
||||
("datetime", QT_TR_NOOP("Date and time"))
|
||||
;
|
||||
|
||||
FieldGetter *RecollModel::chooseGetter(const string& field)
|
||||
{
|
||||
if (!stringlowercmp("date", field))
|
||||
return dategetter;
|
||||
else if (!stringlowercmp("datetime", field))
|
||||
return datetimegetter;
|
||||
else
|
||||
return gengetter;
|
||||
}
|
||||
|
||||
RecollModel::RecollModel(const QStringList fields, QObject *parent)
|
||||
: QAbstractTableModel(parent)
|
||||
{
|
||||
// Add dynamic "stored" fields to the full column list. This
|
||||
// could be protected to be done only once, but it's no real
|
||||
// problem
|
||||
RclConfig *config = RclConfig::getMainConfig();
|
||||
if (config) {
|
||||
const set<string>& stored = config->getStoredFields();
|
||||
for (set<string>::const_iterator it = stored.begin();
|
||||
it != stored.end(); it++) {
|
||||
if (o_displayableFields.find(*it) == o_displayableFields.end()) {
|
||||
o_displayableFields[*it] = *it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the actual list of column names
|
||||
for (QStringList::const_iterator it = fields.begin();
|
||||
it != fields.end(); it++) {
|
||||
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);
|
||||
m_getters.push_back(chooseGetter(m_fields[m_fields.size()-1]));
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,6 +184,12 @@ int RecollModel::columnCount(const QModelIndex&) const
|
||||
return m_fields.size();
|
||||
}
|
||||
|
||||
void RecollModel::readDocSource()
|
||||
{
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void RecollModel::setDocSource(RefCntr<DocSequence> nsource)
|
||||
{
|
||||
LOGDEB(("RecollModel::setDocSource\n"));
|
||||
@ -143,16 +197,37 @@ void RecollModel::setDocSource(RefCntr<DocSequence> nsource)
|
||||
m_source = RefCntr<DocSequence>();
|
||||
else
|
||||
m_source = RefCntr<DocSequence>(new DocSource(nsource));
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
readDocSource();
|
||||
}
|
||||
|
||||
bool RecollModel::getdoc(int index, Rcl::Doc &doc)
|
||||
void RecollModel::deleteColumn(int col)
|
||||
{
|
||||
LOGDEB(("RecollModel::getDoc\n"));
|
||||
if (m_source.isNull())
|
||||
return false;
|
||||
return m_source->getDoc(index, doc);
|
||||
if (col > 0 && col < int(m_fields.size())) {
|
||||
vector<string>::iterator it = m_fields.begin();
|
||||
it += col;
|
||||
m_fields.erase(it);
|
||||
vector<FieldGetter*>::iterator it1 = m_getters.begin();
|
||||
it1 += col;
|
||||
m_getters.erase(it1);
|
||||
readDocSource();
|
||||
}
|
||||
}
|
||||
|
||||
void RecollModel::addColumn(int col, const string& field)
|
||||
{
|
||||
LOGDEB(("AddColumn: col %d fld [%s]\n", col, field.c_str()));
|
||||
if (col >= 0 && col < int(m_fields.size())) {
|
||||
col++;
|
||||
vector<string>::iterator it = m_fields.begin();
|
||||
vector<FieldGetter*>::iterator it1 = m_getters.begin();
|
||||
if (col) {
|
||||
it += col;
|
||||
it1 += col;
|
||||
}
|
||||
m_fields.insert(it, field);
|
||||
m_getters.insert(it1, chooseGetter(field));
|
||||
readDocSource();
|
||||
}
|
||||
}
|
||||
|
||||
QVariant RecollModel::headerData(int idx, Qt::Orientation orientation,
|
||||
@ -164,7 +239,12 @@ QVariant RecollModel::headerData(int idx, Qt::Orientation orientation,
|
||||
}
|
||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole &&
|
||||
idx < int(m_fields.size())) {
|
||||
return QString::fromUtf8(m_fields[idx].c_str());
|
||||
map<string, string>::const_iterator it =
|
||||
o_displayableFields.find(m_fields[idx]);
|
||||
if (it == o_displayableFields.end())
|
||||
return QString::fromUtf8(m_fields[idx].c_str());
|
||||
else
|
||||
return QString::fromUtf8(it->second.c_str());
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
@ -195,7 +275,7 @@ void RecollModel::sort(int column, Qt::SortOrder order)
|
||||
{
|
||||
LOGDEB(("RecollModel::sort(%d, %d)\n", column, int(order)));
|
||||
|
||||
if (column >= 0 && column < int(m_fields.size())) {
|
||||
if (m_source.isNotNull() && column >= 0 && column < int(m_fields.size())) {
|
||||
DocSeqSortSpec spec;
|
||||
spec.field = m_fields[column];
|
||||
if (!stringlowercmp("date", spec.field) ||
|
||||
@ -203,12 +283,11 @@ void RecollModel::sort(int column, Qt::SortOrder order)
|
||||
spec.field = "mtime";
|
||||
spec.desc = order == Qt::AscendingOrder ? false : true;
|
||||
m_source->setSortSpec(spec);
|
||||
setDocSource(m_source);
|
||||
readDocSource();
|
||||
emit sortDataChanged(spec);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////
|
||||
// ResTable panel methods
|
||||
void ResTable::init()
|
||||
@ -229,9 +308,13 @@ void ResTable::init()
|
||||
}
|
||||
header->setSortIndicatorShown(true);
|
||||
header->setSortIndicator(-1, Qt::AscendingOrder);
|
||||
header->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
connect(header, SIGNAL(sectionResized(int,int,int)),
|
||||
this, SLOT(saveColWidths()));
|
||||
connect(header, SIGNAL(customContextMenuRequested(const QPoint&)),
|
||||
this, SLOT(createHeaderPopupMenu(const QPoint&)));
|
||||
}
|
||||
header->setMovable(true);
|
||||
|
||||
header = tableView->verticalHeader();
|
||||
if (header) {
|
||||
@ -257,10 +340,45 @@ void ResTable::init()
|
||||
|
||||
}
|
||||
|
||||
void ResTable::saveSizeState()
|
||||
// This is called by rclmain_w prior to exiting
|
||||
void ResTable::saveColState()
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue("resTableSplitterSizes", splitter->saveState());
|
||||
|
||||
QHeaderView *header = tableView->horizontalHeader();
|
||||
if (header && header->sectionsMoved()) {
|
||||
// Remember the current column order. Walk in visual order and
|
||||
// create new list
|
||||
QStringList newfields;
|
||||
vector<int> newwidths;
|
||||
for (int vi = 0; vi < header->count(); vi++) {
|
||||
int li = header->logicalIndex(vi);
|
||||
newfields.push_back(prefs.restableFields.at(li));
|
||||
newwidths.push_back(header->sectionSize(li));
|
||||
}
|
||||
prefs.restableFields = newfields;
|
||||
prefs.restableColWidths = newwidths;
|
||||
} else {
|
||||
const vector<string>& vf = m_model->getFields();
|
||||
prefs.restableFields.clear();
|
||||
for (int i = 0; i < int(vf.size()); i++) {
|
||||
prefs.restableFields.push_back(QString::fromUtf8(vf[i].c_str()));
|
||||
}
|
||||
saveColWidths();
|
||||
}
|
||||
}
|
||||
|
||||
void ResTable::saveColWidths()
|
||||
{
|
||||
LOGDEB(("ResTable::saveColWidths()\n"));
|
||||
QHeaderView *header = tableView->horizontalHeader();
|
||||
if (!header)
|
||||
return;
|
||||
prefs.restableColWidths.clear();
|
||||
for (int i = 0; i < header->count(); i++) {
|
||||
prefs.restableColWidths.push_back(header->sectionSize(i));
|
||||
}
|
||||
}
|
||||
|
||||
void ResTable::onTableView_currentChanged(const QModelIndex& index)
|
||||
@ -268,12 +386,12 @@ void ResTable::onTableView_currentChanged(const QModelIndex& index)
|
||||
LOGDEB(("ResTable::onTableView_currentChanged(%d, %d)\n",
|
||||
index.row(), index.column()));
|
||||
|
||||
if (!m_model || m_model->m_source.isNull())
|
||||
if (!m_model || m_model->getDocSource().isNull())
|
||||
return;
|
||||
HiliteData hdata;
|
||||
m_model->m_source->getTerms(hdata.terms, hdata.groups, hdata.gslks);
|
||||
m_model->getDocSource()->getTerms(hdata.terms, hdata.groups, hdata.gslks);
|
||||
Rcl::Doc doc;
|
||||
if (m_model->getdoc(index.row(), doc)) {
|
||||
if (m_model->getDocSource()->getDoc(index.row(), doc)) {
|
||||
textBrowser->clear();
|
||||
m_detaildocnum = index.row();
|
||||
m_pager->displayDoc(index.row(), doc, hdata);
|
||||
@ -305,18 +423,6 @@ void ResTable::resetSource()
|
||||
setDocSource(RefCntr<DocSequence>());
|
||||
}
|
||||
|
||||
void ResTable::saveColWidths()
|
||||
{
|
||||
LOGDEB(("ResTable::saveColWidths()\n"));
|
||||
QHeaderView *header = tableView->horizontalHeader();
|
||||
if (!header)
|
||||
return;
|
||||
prefs.restableColWidths.clear();
|
||||
for (int i = 0; i < header->count(); i++) {
|
||||
prefs.restableColWidths.push_back(header->sectionSize(i));
|
||||
}
|
||||
}
|
||||
|
||||
// This is called when the sort order is changed from another widget
|
||||
void ResTable::onSortDataChanged(DocSeqSortSpec)
|
||||
{
|
||||
@ -328,11 +434,14 @@ void ResTable::onSortDataChanged(DocSeqSortSpec)
|
||||
|
||||
void ResTable::readDocSource()
|
||||
{
|
||||
m_model->setDocSource(m_model->m_source);
|
||||
m_model->readDocSource();
|
||||
textBrowser->clear();
|
||||
}
|
||||
|
||||
void ResTable::linkWasClicked(const QUrl &url)
|
||||
{
|
||||
if (!m_model || m_model->getDocSource().isNull())
|
||||
return;
|
||||
QString s = url.toString();
|
||||
const char *ascurl = s.toAscii();
|
||||
LOGDEB(("ResTable::linkWasClicked: [%s]\n", ascurl));
|
||||
@ -344,7 +453,7 @@ void ResTable::linkWasClicked(const QUrl &url)
|
||||
case 'E':
|
||||
{
|
||||
Rcl::Doc doc;
|
||||
if (!m_model->getdoc(i, doc)) {
|
||||
if (!m_model->getDocSource()->getDoc(i, doc)) {
|
||||
LOGERR(("ResTable::linkWasClicked: can't get doc for %d\n", i));
|
||||
return;
|
||||
}
|
||||
@ -359,3 +468,50 @@ void ResTable::linkWasClicked(const QUrl &url)
|
||||
break;// ??
|
||||
}
|
||||
}
|
||||
|
||||
void ResTable::createHeaderPopupMenu(const QPoint& pos)
|
||||
{
|
||||
LOGDEB(("ResTable::createHeaderPopupMenu(%d, %d)\n", pos.x(), pos.y()));
|
||||
QHeaderView *header = tableView->horizontalHeader();
|
||||
if (!header || !m_model)
|
||||
return;
|
||||
|
||||
m_popcolumn = header->logicalIndexAt(pos);
|
||||
if (m_popcolumn < 0)
|
||||
return;
|
||||
|
||||
const map<string, string>& allfields = m_model->getAllFields();
|
||||
const vector<string>& fields = m_model->getFields();
|
||||
QMenu *popup = new QMenu(this);
|
||||
popup->addAction(tr("&Delete column"), this, SLOT(deleteColumn()));
|
||||
QAction *act;
|
||||
for (map<string, string>::const_iterator it = allfields.begin();
|
||||
it != allfields.end(); it++) {
|
||||
if (std::find(fields.begin(), fields.end(), it->first) != fields.end())
|
||||
continue;
|
||||
act = new QAction(tr("Add ") + tr(it->second.c_str()), popup);
|
||||
act->setData(QString::fromUtf8(it->first.c_str()));
|
||||
connect(act, SIGNAL(triggered(bool)), this , SLOT(addColumn()));
|
||||
popup->addAction(act);
|
||||
}
|
||||
popup->popup(mapToGlobal(pos));
|
||||
}
|
||||
|
||||
void ResTable::deleteColumn()
|
||||
{
|
||||
if (m_model)
|
||||
m_model->deleteColumn(m_popcolumn);
|
||||
}
|
||||
|
||||
void ResTable::addColumn()
|
||||
{
|
||||
if (!m_model)
|
||||
return;
|
||||
QAction *action = (QAction *)sender();
|
||||
LOGDEB(("addColumn: text %s, data %s\n",
|
||||
(const char *)action->text().toUtf8(),
|
||||
(const char *)action->data().toString().toUtf8()
|
||||
));
|
||||
string field((const char *)action->data().toString().toUtf8());
|
||||
m_model->addColumn(m_popcolumn, field);
|
||||
}
|
||||
|
||||
@ -34,19 +34,27 @@ class RecollModel : public QAbstractTableModel {
|
||||
|
||||
public:
|
||||
RecollModel(const QStringList fields, QObject *parent = 0);
|
||||
|
||||
// Reimplemented methods
|
||||
virtual int rowCount (const QModelIndex& = QModelIndex()) const;
|
||||
virtual int columnCount(const QModelIndex& = QModelIndex()) const;
|
||||
virtual QVariant headerData (int col,
|
||||
Qt::Orientation orientation,
|
||||
virtual QVariant headerData (int col, Qt::Orientation orientation,
|
||||
int role = Qt::DisplayRole ) const;
|
||||
virtual QVariant data(const QModelIndex& index,
|
||||
int role = Qt::DisplayRole ) const;
|
||||
virtual void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
|
||||
|
||||
// Specific methods
|
||||
virtual void readDocSource();
|
||||
virtual void setDocSource(RefCntr<DocSequence> nsource);
|
||||
virtual bool getdoc(int index, Rcl::Doc &doc);
|
||||
|
||||
friend class ResTable;
|
||||
virtual RefCntr<DocSequence> getDocSource() {return m_source;}
|
||||
virtual void deleteColumn(int);
|
||||
virtual const vector<string>& getFields() {return m_fields;}
|
||||
virtual const map<string, string>& getAllFields()
|
||||
{
|
||||
return o_displayableFields;
|
||||
}
|
||||
virtual void addColumn(int, const string&);
|
||||
|
||||
signals:
|
||||
void sortDataChanged(DocSeqSortSpec);
|
||||
@ -55,6 +63,8 @@ private:
|
||||
mutable RefCntr<DocSequence> m_source;
|
||||
vector<string> m_fields;
|
||||
vector<FieldGetter*> m_getters;
|
||||
static map<string, string> o_displayableFields;
|
||||
FieldGetter* chooseGetter(const string&);
|
||||
};
|
||||
|
||||
class ResTablePager;
|
||||
@ -75,7 +85,7 @@ public:
|
||||
|
||||
virtual ~ResTable() {}
|
||||
virtual RecollModel *getModel() {return m_model;}
|
||||
virtual void saveSizeState();
|
||||
virtual void saveColState();
|
||||
|
||||
public slots:
|
||||
virtual void onTableView_currentChanged(const QModelIndex&);
|
||||
@ -86,6 +96,9 @@ public slots:
|
||||
virtual void readDocSource();
|
||||
virtual void onSortDataChanged(DocSeqSortSpec);
|
||||
virtual void linkWasClicked(const QUrl&);
|
||||
virtual void createHeaderPopupMenu(const QPoint&);
|
||||
virtual void deleteColumn();
|
||||
virtual void addColumn();
|
||||
|
||||
signals:
|
||||
void docPreviewClicked(int, Rcl::Doc, int);
|
||||
@ -97,6 +110,7 @@ private:
|
||||
RecollModel *m_model;
|
||||
ResTablePager *m_pager;
|
||||
int m_detaildocnum;
|
||||
int m_popcolumn;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -104,7 +104,14 @@ class Db::Native {
|
||||
inline const string& docfToDatf(const string& df)
|
||||
{
|
||||
static const string keycap("caption");
|
||||
return df.compare(Doc::keytt) ? df : keycap;
|
||||
static const string keydmtime("dmtime");
|
||||
if (!df.compare(Doc::keytt)) {
|
||||
return keycap;
|
||||
} else if (!df.compare(Doc::keymt)) {
|
||||
return keydmtime;
|
||||
} else {
|
||||
return df;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ static char rcsid[] = "@(#$Id: rclquery.cpp,v 1.11 2008-12-19 09:55:36 dockes Ex
|
||||
#include "smallut.h"
|
||||
#include "searchdata.h"
|
||||
#include "rclconfig.h"
|
||||
#include "unacpp.h"
|
||||
|
||||
#ifndef NO_NAMESPACES
|
||||
namespace Rcl {
|
||||
@ -30,10 +31,7 @@ public:
|
||||
QSorter(const string& f)
|
||||
: m_fld(docfToDatf(f) + "=")
|
||||
{
|
||||
m_ismtime = !m_fld.compare("mtime=");
|
||||
if (m_ismtime) {
|
||||
m_fld = "dmtime=";
|
||||
}
|
||||
m_ismtime = !m_fld.compare("dmtime=");
|
||||
}
|
||||
|
||||
virtual std::string operator()(const Xapian::Document& xdoc) const
|
||||
@ -61,7 +59,27 @@ public:
|
||||
i2 = data.find_first_of("\n\r", i1);
|
||||
if (i2 == string::npos)
|
||||
return string();
|
||||
return data.substr(i1, i2-i1);
|
||||
|
||||
// Process data for better sorting. We should actually do the
|
||||
// unicode thing
|
||||
// (http://unicode.org/reports/tr10/#Introduction), but just
|
||||
// removing accents and majuscules will remove the most
|
||||
// glaring weirdnesses (or not, depending on your national
|
||||
// approach to collating...)
|
||||
string term = data.substr(i1, i2-i1);
|
||||
string sortterm;
|
||||
// We're not even sure the term is utf8 here (ie: url)
|
||||
if (!unacmaybefold(term, sortterm, "UTF-8", true)) {
|
||||
sortterm = term;
|
||||
}
|
||||
// Also remove some common uninteresting starting characters
|
||||
i1 = sortterm.find_first_not_of(" \t\\\"([*+,");
|
||||
if (i1 != 0 && i1 != string::npos) {
|
||||
sortterm = sortterm.substr(i1, sortterm.size()-i1);
|
||||
}
|
||||
|
||||
LOGDEB2(("QSorter: [%s] -> [%s]\n", term.c_str(), sortterm.c_str()));
|
||||
return sortterm;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@ -186,4 +186,31 @@ struct TempBuf {
|
||||
#define deleteZ(X) {delete X;X = 0;}
|
||||
#endif
|
||||
|
||||
// Code for static initialization of an stl map. Somewhat like Boost.assign.
|
||||
// Ref: http://stackoverflow.com/questions/138600/initializing-a-static-stdmapint-int-in-c
|
||||
// Example use: map<int, int> m = map_list_of (1,2) (3,4) (5,6) (7,8);
|
||||
|
||||
template <typename T, typename U>
|
||||
class create_map
|
||||
{
|
||||
private:
|
||||
std::map<T, U> m_map;
|
||||
public:
|
||||
create_map(const T& key, const U& val)
|
||||
{
|
||||
m_map[key] = val;
|
||||
}
|
||||
|
||||
create_map<T, U>& operator()(const T& key, const U& val)
|
||||
{
|
||||
m_map[key] = val;
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator std::map<T, U>()
|
||||
{
|
||||
return m_map;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _SMALLUT_H_INCLUDED_ */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user