allow indexing individual files. Fix pb with preview and charsets (local defcharset ignored)
This commit is contained in:
parent
315f8cdb33
commit
be485e8059
@ -1,10 +1,10 @@
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#$Id: indexer.cpp,v 1.19 2005-11-30 09:46:25 dockes Exp $ (C) 2004 J.F.Dockes";
|
||||
static char rcsid[] = "@(#$Id: indexer.cpp,v 1.20 2005-12-14 11:00:48 dockes Exp $ (C) 2004 J.F.Dockes";
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include <iostream>
|
||||
@ -33,63 +33,24 @@ using namespace std;
|
||||
#define deleteZ(X) {delete X;X = 0;}
|
||||
#endif
|
||||
|
||||
/// A class to index a list of top directories into one database.
|
||||
///
|
||||
/// Inherits FsTreeWalkerCB so that its processone() method is
|
||||
/// called by the file-system tree walk code for each file and
|
||||
/// directory, and keeps all state used while indexing a
|
||||
/// directory tree.
|
||||
class DbIndexer : public FsTreeWalkerCB {
|
||||
FsTreeWalker walker;
|
||||
RclConfig *config;
|
||||
string dbdir;
|
||||
list<string> *topdirs;
|
||||
Rcl::Db db;
|
||||
string tmpdir;
|
||||
public:
|
||||
/// Constructor does nothing but store parameters
|
||||
DbIndexer(RclConfig *cnf, const string &dbd, list<string> *top)
|
||||
: config(cnf), dbdir(dbd), topdirs(top) {}
|
||||
|
||||
virtual ~DbIndexer() {
|
||||
// Maybe clean up temporary directory
|
||||
if (tmpdir.length()) {
|
||||
wipedir(tmpdir);
|
||||
if (rmdir(tmpdir.c_str()) < 0) {
|
||||
LOGERR(("DbIndexer::~DbIndexer: cant clear temp dir %s\n",
|
||||
tmpdir.c_str()));
|
||||
}
|
||||
DbIndexer::~DbIndexer() {
|
||||
// Maybe clean up temporary directory
|
||||
if (tmpdir.length()) {
|
||||
wipedir(tmpdir);
|
||||
if (rmdir(tmpdir.c_str()) < 0) {
|
||||
LOGERR(("DbIndexer::~DbIndexer: cannot clear temp dir %s\n",
|
||||
tmpdir.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
/// Start indexing.
|
||||
bool index(bool resetbefore);
|
||||
|
||||
/// Tree walker callback method
|
||||
FsTreeWalker::Status
|
||||
processone(const std::string &, const struct stat *, FsTreeWalker::CbFlag);
|
||||
};
|
||||
db.close();
|
||||
}
|
||||
|
||||
|
||||
/// Top level file system tree index method for updating a given database.
|
||||
///
|
||||
/// We create the temporary directory, open the database, then call a
|
||||
/// file system walk for each top-level directory.
|
||||
/// When walking is done, we create the stem databases and close the
|
||||
/// main db.
|
||||
bool DbIndexer::index(bool resetbefore)
|
||||
bool DbIndexer::indexDb(bool resetbefore, list<string> *topdirs)
|
||||
{
|
||||
string tdir;
|
||||
if (!init(resetbefore))
|
||||
return false;
|
||||
|
||||
if (!maketmpdir(tmpdir)) {
|
||||
LOGERR(("DbIndexer: cant create temp directory\n"));
|
||||
return false;
|
||||
}
|
||||
if (!db.open(dbdir, resetbefore ? Rcl::Db::DbTrunc : Rcl::Db::DbUpd)) {
|
||||
LOGERR(("DbIndexer::index: error opening database in %s\n",
|
||||
dbdir.c_str()));
|
||||
return false;
|
||||
}
|
||||
for (list<string>::const_iterator it = topdirs->begin();
|
||||
it != topdirs->end(); it++) {
|
||||
LOGDEB(("DbIndexer::index: Indexing %s into %s\n", it->c_str(),
|
||||
@ -118,7 +79,6 @@ bool DbIndexer::index(bool resetbefore)
|
||||
if (walker.walk(*it, *this) != FsTreeWalker::FtwOk) {
|
||||
LOGERR(("DbIndexer::index: error while indexing %s\n",
|
||||
it->c_str()));
|
||||
db.close();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -138,6 +98,7 @@ bool DbIndexer::index(bool resetbefore)
|
||||
}
|
||||
}
|
||||
|
||||
// The close would be done in our destructor, but we want status here
|
||||
if (!db.close()) {
|
||||
LOGERR(("DbIndexer::index: error closing database in %s\n",
|
||||
dbdir.c_str()));
|
||||
@ -146,6 +107,52 @@ bool DbIndexer::index(bool resetbefore)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DbIndexer::init(bool resetbefore)
|
||||
{
|
||||
if (!maketmpdir(tmpdir)) {
|
||||
LOGERR(("DbIndexer: cannot create temporary directory\n"));
|
||||
return false;
|
||||
}
|
||||
if (!db.open(dbdir, resetbefore ? Rcl::Db::DbTrunc : Rcl::Db::DbUpd)) {
|
||||
LOGERR(("DbIndexer: error opening database in %s\n", dbdir.c_str()));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool DbIndexer::indexFiles(const list<string> &filenames)
|
||||
{
|
||||
if (!init())
|
||||
return false;
|
||||
|
||||
list<string>::const_iterator it;
|
||||
for (it = filenames.begin(); it != filenames.end();it++) {
|
||||
config->setKeyDir(path_getfather(*it));
|
||||
struct stat stb;
|
||||
if (stat(it->c_str(), &stb) != 0) {
|
||||
LOGERR(("DbIndexer::indexFiles: stat(%s): %s", it->c_str(),
|
||||
strerror(errno)));
|
||||
continue;
|
||||
}
|
||||
if (!S_ISREG(stb.st_mode)) {
|
||||
LOGERR(("DbIndexer::indexFiles: %s: not a regular file\n",
|
||||
it->c_str()));
|
||||
continue;
|
||||
}
|
||||
if (processone(*it, &stb, FsTreeWalker::FtwRegular) !=
|
||||
FsTreeWalker::FtwOk) {
|
||||
LOGERR(("DbIndexer::indexFiles: Database error\n"));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// The close would be done in our destructor, but we want status here
|
||||
if (!db.close()) {
|
||||
LOGERR(("DbIndexer::indexfiles: error closing database in %s\n",
|
||||
dbdir.c_str()));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// This method gets called for every file and directory found by the
|
||||
/// tree walker.
|
||||
@ -257,6 +264,7 @@ bool ConfIndexer::index(bool resetbefore)
|
||||
}
|
||||
config->setKeyDir("");
|
||||
|
||||
// The dbmap now has dbdir as key and directory lists as values.
|
||||
// Index each directory group in turn
|
||||
for (dbit = dbmap.begin(); dbit != dbmap.end(); dbit++) {
|
||||
//cout << dbit->first << " -> ";
|
||||
@ -265,8 +273,8 @@ bool ConfIndexer::index(bool resetbefore)
|
||||
// cout << *dit << " ";
|
||||
//}
|
||||
//cout << endl;
|
||||
dbindexer = new DbIndexer(config, dbit->first, &dbit->second);
|
||||
if (!dbindexer->index(resetbefore)) {
|
||||
dbindexer = new DbIndexer(config, dbit->first);
|
||||
if (!dbindexer->indexDb(resetbefore, &dbit->second)) {
|
||||
deleteZ(dbindexer);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1,32 +1,84 @@
|
||||
#ifndef _INDEXER_H_INCLUDED_
|
||||
#define _INDEXER_H_INCLUDED_
|
||||
/* @(#$Id: indexer.h,v 1.7 2005-11-30 09:46:25 dockes Exp $ (C) 2004 J.F.Dockes */
|
||||
/* @(#$Id: indexer.h,v 1.8 2005-12-14 11:00:48 dockes Exp $ (C) 2004 J.F.Dockes */
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
|
||||
#include "rclconfig.h"
|
||||
#include "fstreewalk.h"
|
||||
#include "rcldb.h"
|
||||
|
||||
/**
|
||||
* An internal class to process all directories indexed into the same database.
|
||||
*/
|
||||
/* Forward decl for lower level indexing object */
|
||||
class DbIndexer;
|
||||
|
||||
/**
|
||||
* The file system indexing object. Processes the configuration, then invokes
|
||||
* file system walking to populate/update the database(s).
|
||||
*
|
||||
* Multiple top-level directories can be listed in the
|
||||
* configuration. Each can be indexed to a different
|
||||
* database. Directories are first grouped by database, then an
|
||||
* internal class (DbIndexer) is used to process each group.
|
||||
*/
|
||||
The top level indexing object. Processes the configuration, then invokes
|
||||
file system walking to populate/update the database(s).
|
||||
|
||||
Multiple top-level directories can be listed in the
|
||||
configuration. Each can be indexed to a different
|
||||
database. Directories are first grouped by database, then an
|
||||
internal class (DbIndexer) is used to process each group.
|
||||
*/
|
||||
class ConfIndexer {
|
||||
RclConfig *config;
|
||||
DbIndexer *dbindexer; // Object to process directories for a given db
|
||||
public:
|
||||
enum runStatus {IndexerOk, IndexerError};
|
||||
ConfIndexer(RclConfig *cnf) : config(cnf), dbindexer(0) {}
|
||||
virtual ~ConfIndexer();
|
||||
/** Worker function: doe the actual indexing */
|
||||
bool index(bool resetbefore = false);
|
||||
virtual ~ConfIndexer();
|
||||
/** Worker function: doe the actual indexing */
|
||||
bool index(bool resetbefore = false);
|
||||
private:
|
||||
RclConfig *config;
|
||||
DbIndexer *dbindexer; // Object to process directories for a given db
|
||||
};
|
||||
|
||||
/** Index things into one database
|
||||
|
||||
Tree indexing: we inherits FsTreeWalkerCB so that, the processone()
|
||||
method is called by the file-system tree walk code for each file and
|
||||
directory. We keep all state needed while indexing, and finally call
|
||||
the methods to purge the db of stale entries and create the stemming
|
||||
databases.
|
||||
|
||||
Single file(s) indexing: no database purging or stem db updating.
|
||||
*/
|
||||
class DbIndexer : public FsTreeWalkerCB {
|
||||
public:
|
||||
/** Constructor does nothing but store parameters */
|
||||
DbIndexer(RclConfig *cnf, const std::string &dbd)
|
||||
: config(cnf), dbdir(dbd) {
|
||||
}
|
||||
|
||||
virtual ~DbIndexer();
|
||||
|
||||
/** Top level file system tree index method for updating a
|
||||
given database.
|
||||
|
||||
The list is supposed to have all the filename space for the
|
||||
db, and we shall purge entries for non-existing files at the
|
||||
end. We create the temporary directory, open the database,
|
||||
then call a file system walk for each top-level directory.
|
||||
When walking is done, we create the stem databases and close
|
||||
the main db.
|
||||
*/
|
||||
bool indexDb(bool resetbefore, std::list<std::string> *topdirs);
|
||||
|
||||
/** Index a list of files. No db cleaning or stemdb updating */
|
||||
bool indexFiles(const std::list<std::string> &files);
|
||||
|
||||
/** Tree walker callback method */
|
||||
FsTreeWalker::Status
|
||||
processone(const std::string &, const struct stat *,
|
||||
FsTreeWalker::CbFlag);
|
||||
|
||||
private:
|
||||
FsTreeWalker walker;
|
||||
RclConfig *config;
|
||||
std::string dbdir;
|
||||
Rcl::Db db;
|
||||
std::string tmpdir;
|
||||
bool init(bool rst = false);
|
||||
};
|
||||
|
||||
#endif /* _INDEXER_H_INCLUDED_ */
|
||||
|
||||
@ -1,20 +1,53 @@
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#$Id: recollindex.cpp,v 1.12 2005-11-30 09:46:25 dockes Exp $ (C) 2004 J.F.Dockes";
|
||||
static char rcsid[] = "@(#$Id: recollindex.cpp,v 1.13 2005-12-14 11:00:48 dockes Exp $ (C) 2004 J.F.Dockes";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "debuglog.h"
|
||||
#include "rclinit.h"
|
||||
#include "indexer.h"
|
||||
#include "smallut.h"
|
||||
#include "pathut.h"
|
||||
|
||||
ConfIndexer *indexer;
|
||||
|
||||
ConfIndexer *confindexer;
|
||||
DbIndexer *dbindexer;
|
||||
|
||||
bool indexfiles(RclConfig *config, const list<string> &filenames)
|
||||
{
|
||||
if (filenames.empty())
|
||||
return true;
|
||||
|
||||
// Note that we do not bother to check for multiple databases,
|
||||
// which are currently a fiction anyway.
|
||||
config->setKeyDir(path_getfather(*filenames.begin()));
|
||||
string dbdir;
|
||||
if (!config->getConfParam("dbdir", dbdir)) {
|
||||
LOGERR(("indexfiles: no database directory in "
|
||||
"configuration for %s\n", filenames.begin()->c_str()));
|
||||
return false;
|
||||
}
|
||||
dbdir = path_tildexpand(dbdir);
|
||||
|
||||
dbindexer = new DbIndexer(config, dbdir);
|
||||
return dbindexer->indexFiles(filenames);
|
||||
}
|
||||
|
||||
static void cleanup()
|
||||
{
|
||||
delete indexer;
|
||||
indexer = 0;
|
||||
delete confindexer;
|
||||
confindexer = 0;
|
||||
delete dbindexer;
|
||||
dbindexer = 0;
|
||||
}
|
||||
|
||||
static void sigcleanup(int sig)
|
||||
@ -29,12 +62,16 @@ static int op_flags;
|
||||
#define OPT_MOINS 0x1
|
||||
#define OPT_z 0x2
|
||||
#define OPT_h 0x4
|
||||
#define OPT_i 0x8
|
||||
|
||||
static const char usage [] =
|
||||
" recollindex [-hz]\n"
|
||||
" recollindex [-hz] \n"
|
||||
" recollindex -i <filename [filename ...]>\n"
|
||||
"Options:\n"
|
||||
" -h : print this message\n"
|
||||
" -z : reset database before starting indexation\n\n"
|
||||
" -i <filename [filename ...]> : index individual files. No db purge or stem\n"
|
||||
" database updates in this case\n"
|
||||
;
|
||||
|
||||
static void
|
||||
@ -59,22 +96,43 @@ int main(int argc, const char **argv)
|
||||
switch (*(*argv)++) {
|
||||
case 'z': op_flags |= OPT_z; break;
|
||||
case 'h': op_flags |= OPT_h; break;
|
||||
case 'i': op_flags |= OPT_i; break;
|
||||
default: Usage(); break;
|
||||
}
|
||||
b1: argc--; argv++;
|
||||
}
|
||||
if (op_flags & OPT_h)
|
||||
Usage();
|
||||
if ((op_flags & OPT_z) && (op_flags & OPT_i))
|
||||
Usage();
|
||||
|
||||
string reason;
|
||||
RclConfig *config = recollinit(cleanup, sigcleanup, reason);
|
||||
|
||||
if (config == 0 || !config->ok()) {
|
||||
string str = "Configuration problem: ";
|
||||
str += reason;
|
||||
fprintf(stderr, "%s\n", str.c_str());
|
||||
cerr << "Configuration problem: " << reason << endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
indexer = new ConfIndexer(config);
|
||||
|
||||
exit(!indexer->index((op_flags & OPT_z) != 0));
|
||||
|
||||
if (op_flags & OPT_i) {
|
||||
list<string> filenames;
|
||||
if (argc == 0) {
|
||||
// Read from stdin
|
||||
char line[1024];
|
||||
while (fgets(line, 1023, stdin)) {
|
||||
string sl(line);
|
||||
trimstring(sl, "\n\r");
|
||||
filenames.push_back(sl);
|
||||
}
|
||||
} else {
|
||||
while (argc--) {
|
||||
filenames.push_back(*argv++);
|
||||
}
|
||||
}
|
||||
exit(!indexfiles(config, filenames));
|
||||
} else {
|
||||
confindexer = new ConfIndexer(config);
|
||||
bool rezero(op_flags & OPT_z);
|
||||
exit(!confindexer->index(rezero));
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,9 +112,7 @@ MimeHandlerHtml::mkDoc(RclConfig *conf, const string &,
|
||||
charset.c_str(),result.doccharset.c_str()));
|
||||
if (!result.doccharset.empty() &&
|
||||
!samecharset(result.doccharset, result.ocharset)) {
|
||||
LOGDEB(("textHtmlToDoc: charset '%s' doc charset '%s',"
|
||||
"reparse\n", charset.c_str(),
|
||||
result.doccharset.c_str()));
|
||||
LOGDEB(("textHtmlToDoc: reparse for charsets\n"));
|
||||
charset = result.doccharset;
|
||||
} else {
|
||||
LOGERR(("textHtmlToDoc:: error: non charset exception\n"));
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#$Id: mh_text.cpp,v 1.2 2005-11-24 07:16:15 dockes Exp $ (C) 2005 J.F.Dockes";
|
||||
static char rcsid[] = "@(#$Id: mh_text.cpp,v 1.3 2005-12-14 11:00:48 dockes Exp $ (C) 2005 J.F.Dockes";
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
@ -30,12 +30,14 @@ MimeHandler::Status MimeHandlerText::mkDoc(RclConfig *conf, const string &fn,
|
||||
charset = csguess(otext, conf->getDefCharset());
|
||||
} else
|
||||
charset = conf->getDefCharset();
|
||||
string utf8;
|
||||
LOGDEB1(("textPlainToDoc: transcod from %s to %s\n", charset, "UTF-8"));
|
||||
|
||||
LOGDEB1(("MimeHandlerText::mkDoc: transcod from %s to utf-8\n",
|
||||
charset.c_str()));
|
||||
|
||||
string utf8;
|
||||
if (!transcode(otext, utf8, charset, "UTF-8")) {
|
||||
cerr << "textPlainToDoc: transcode failed: charset '" << charset
|
||||
<< "' to UTF-8: "<< utf8 << endl;
|
||||
LOGERR(("MimeHandlerText::mkDoc: transcode to utf-8 failed "
|
||||
"for charset [%s]\n", charset.c_str()));
|
||||
otext.erase();
|
||||
return MimeHandler::MHError;
|
||||
}
|
||||
|
||||
@ -399,6 +399,8 @@ void Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc)
|
||||
|
||||
// Load and convert file
|
||||
Rcl::Doc fdoc;
|
||||
// Need to setup config to retrieve possibly local parameters
|
||||
rclconfig->setKeyDir(path_getfather(fn));
|
||||
int status = 1;
|
||||
LoadThread lthr(&status, &fdoc, fn, doc.ipath, &doc.mimetype);
|
||||
lthr.start();
|
||||
@ -419,6 +421,8 @@ void Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc)
|
||||
doc.mimetype.c_str());
|
||||
return;
|
||||
}
|
||||
// Reset config just in case.
|
||||
rclconfig->setKeyDir("");
|
||||
|
||||
// Highlight search terms:
|
||||
progress.setLabelText(tr("Creating preview text"));
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>466</width>
|
||||
<width>362</width>
|
||||
<height>190</height>
|
||||
</size>
|
||||
</property>
|
||||
@ -62,6 +62,9 @@
|
||||
<property name="accel">
|
||||
<string>Ctrl+S</string>
|
||||
</property>
|
||||
<property name="toolTip" stdset="0">
|
||||
<string>Erase search entry</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton">
|
||||
<property name="name">
|
||||
@ -73,6 +76,9 @@
|
||||
<property name="text">
|
||||
<string>Search</string>
|
||||
</property>
|
||||
<property name="toolTip" stdset="0">
|
||||
<string>Start query</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox">
|
||||
<property name="name">
|
||||
@ -84,6 +90,12 @@
|
||||
<property name="accel">
|
||||
<string>Alt+A</string>
|
||||
</property>
|
||||
<property name="toolTip" stdset="0">
|
||||
<string>Do documents have to contain all terms in query?</string>
|
||||
</property>
|
||||
<property name="whatsThis" stdset="0">
|
||||
<string>If this is set, each returned document will contain all the terms in the query. Else documents will be ordered by relevance, but may not contain all the terms.</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit">
|
||||
<property name="name">
|
||||
@ -109,6 +121,9 @@
|
||||
<property name="frameShadow">
|
||||
<enum>Sunken</enum>
|
||||
</property>
|
||||
<property name="toolTip" stdset="0">
|
||||
<string>Enter search terms here</string>
|
||||
</property>
|
||||
</widget>
|
||||
</hbox>
|
||||
</widget>
|
||||
@ -181,6 +196,14 @@
|
||||
<action name="prevPageAction"/>
|
||||
<action name="nextPageAction"/>
|
||||
</toolbar>
|
||||
<toolbar dock="2">
|
||||
<property name="name">
|
||||
<cstring>HelpToolbar</cstring>
|
||||
</property>
|
||||
<property name="label">
|
||||
<string>Toolbar_2</string>
|
||||
</property>
|
||||
</toolbar>
|
||||
</toolbars>
|
||||
<actions>
|
||||
<action>
|
||||
@ -224,10 +247,13 @@
|
||||
<iconset>history</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Doc History</string>
|
||||
<string>Document &History</string>
|
||||
</property>
|
||||
<property name="menuText">
|
||||
<string>Doc &History</string>
|
||||
<string>Document &History</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Document History</string>
|
||||
</property>
|
||||
</action>
|
||||
<action>
|
||||
@ -241,7 +267,10 @@
|
||||
<string>Advanced Search</string>
|
||||
</property>
|
||||
<property name="menuText">
|
||||
<string>Advanced Search</string>
|
||||
<string>&Advanced Search</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Advanced/complex Search</string>
|
||||
</property>
|
||||
</action>
|
||||
<action>
|
||||
@ -252,9 +281,12 @@
|
||||
<iconset>sortparms</iconset>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Sort parameters</string>
|
||||
<string>&Sort parameters</string>
|
||||
</property>
|
||||
<property name="menuText">
|
||||
<string>&Sort parameters</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Sort parameters</string>
|
||||
</property>
|
||||
</action>
|
||||
@ -262,7 +294,7 @@
|
||||
<property name="name">
|
||||
<cstring>nextPageAction</cstring>
|
||||
</property>
|
||||
<property name="enabled">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="iconSet">
|
||||
@ -271,12 +303,15 @@
|
||||
<property name="text">
|
||||
<string>Next page</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Next page of results</string>
|
||||
</property>
|
||||
</action>
|
||||
<action>
|
||||
<property name="name">
|
||||
<cstring>prevPageAction</cstring>
|
||||
</property>
|
||||
<property name="enabled">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="iconSet">
|
||||
@ -285,6 +320,9 @@
|
||||
<property name="text">
|
||||
<string>Previous page</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Previous page of results</string>
|
||||
</property>
|
||||
</action>
|
||||
</actions>
|
||||
<connections>
|
||||
@ -383,7 +421,6 @@
|
||||
</includes>
|
||||
<variables>
|
||||
<variable>int reslist_winfirst;</variable>
|
||||
<variable>int reslist_current;</variable>
|
||||
<variable>bool reslist_mouseDrag;</variable>
|
||||
<variable>bool reslist_mouseDown;</variable>
|
||||
<variable>int reslist_par;</variable>
|
||||
@ -425,8 +462,9 @@
|
||||
<function access="private">init()</function>
|
||||
<function returnType="bool">close( bool )</function>
|
||||
<function access="private" returnType="bool">eventFilter( QObject * target, QEvent * event )</function>
|
||||
<function access="private">startPreview( int docnum )</function>
|
||||
<function access="private" returnType="int">reldocnumfromparnum( int parnum )</function>
|
||||
<function access="private">startPreview( int docnum )</function>
|
||||
<function access="private">startNativeViewer( int docnum )</function>
|
||||
</functions>
|
||||
<pixmapinproject/>
|
||||
<layoutdefaults spacing="6" margin="11"/>
|
||||
|
||||
@ -54,7 +54,6 @@ static const int respagesize = 8;
|
||||
void RecollMain::init()
|
||||
{
|
||||
reslist_winfirst = -1;
|
||||
reslist_current = -1;
|
||||
reslist_mouseDrag = false;
|
||||
reslist_mouseDown = false;
|
||||
reslist_par = -1;
|
||||
@ -73,6 +72,8 @@ void RecollMain::init()
|
||||
reslistTE->viewport()->installEventFilter(this);
|
||||
// reslistTE->viewport()->setFocusPolicy(QWidget::NoFocus);
|
||||
|
||||
// Set the focus to the search terms entry:
|
||||
queryText->setFocus();
|
||||
}
|
||||
|
||||
// We also want to get rid of the advanced search form and previews
|
||||
@ -279,53 +280,10 @@ void RecollMain::reslistTE_doubleClicked(int par, int)
|
||||
{
|
||||
LOGDEB(("RecollMain::reslistTE_doubleClicked: par %d\n", par));
|
||||
reslist_dblclck = true;
|
||||
|
||||
Rcl::Doc doc;
|
||||
int reldocnum = reldocnumfromparnum(par);
|
||||
if (!docsource->getDoc(reslist_winfirst + reldocnum, doc, 0, 0))
|
||||
if (reldocnum < 0)
|
||||
return;
|
||||
|
||||
// Look for appropriate viewer
|
||||
string cmd = rclconfig->getMimeViewerDef(doc.mimetype);
|
||||
if (cmd.length() == 0) {
|
||||
QMessageBox::warning(0, "Recoll",
|
||||
tr("No external viewer configured for mime type ")
|
||||
+ doc.mimetype.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
string fn = urltolocalpath(doc.url);
|
||||
|
||||
// Substitute %u (url) and %f (file name) inside prototype command
|
||||
string ncmd;
|
||||
string::const_iterator it1;
|
||||
for (it1 = cmd.begin(); it1 != cmd.end();it1++) {
|
||||
if (*it1 == '%') {
|
||||
if (++it1 == cmd.end()) {
|
||||
ncmd += '%';
|
||||
break;
|
||||
}
|
||||
if (*it1 == '%')
|
||||
ncmd += '%';
|
||||
if (*it1 == 'u')
|
||||
ncmd += "'" + doc.url + "'";
|
||||
if (*it1 == 'f')
|
||||
ncmd += "'" + fn + "'";
|
||||
} else {
|
||||
ncmd += *it1;
|
||||
}
|
||||
}
|
||||
|
||||
ncmd += " &";
|
||||
QStatusBar *stb = statusBar();
|
||||
if (stb) {
|
||||
QString msg = tr("Executing: [") + ncmd.c_str() + "]";
|
||||
stb->message(msg, 5000);
|
||||
stb->repaint(false);
|
||||
XFlush(qt_xdisplay());
|
||||
}
|
||||
history->enterDocument(fn, doc.ipath);
|
||||
system(ncmd.c_str());
|
||||
startNativeViewer(reslist_winfirst + reldocnum);
|
||||
}
|
||||
|
||||
|
||||
@ -337,7 +295,7 @@ void RecollMain::reslistTE_clicked(int par, int car)
|
||||
{
|
||||
if (reslist_waitingdbl)
|
||||
return;
|
||||
LOGDEB(("RecollMain::reslistTE_clckd:winfirst %d par %d char %d drg %d\n",
|
||||
LOGDEB(("RecollMain::reslistTE_clicked:wfirst %d par %d char %d drg %d\n",
|
||||
reslist_winfirst, par, car, reslist_mouseDrag));
|
||||
if (reslist_winfirst == -1 || reslist_mouseDrag)
|
||||
return;
|
||||
@ -356,28 +314,32 @@ void RecollMain::reslistTE_clicked(int par, int car)
|
||||
// requested a native viewer by double-clicking
|
||||
void RecollMain::reslistTE_delayedclick()
|
||||
{
|
||||
LOGDEB(("RecollMain::reslistTE_delayedclick:\n"));
|
||||
reslist_waitingdbl = false;
|
||||
if (reslist_dblclck) {
|
||||
LOGDEB1(("RecollMain::reslistTE_delayedclick: dbleclick\n"));
|
||||
reslist_dblclck = false;
|
||||
return;
|
||||
}
|
||||
|
||||
int par = reslist_par;
|
||||
|
||||
// Erase everything back to white
|
||||
{
|
||||
QColor color("white");
|
||||
for (int i = 1; i < reslistTE->paragraphs(); i++)
|
||||
reslistTE->setParagraphBackgroundColor(i, color);
|
||||
}
|
||||
|
||||
// Color the new active paragraph
|
||||
QColor color("lightblue");
|
||||
reslistTE->setParagraphBackgroundColor(par, color);
|
||||
|
||||
// Document number
|
||||
int reldocnum = reldocnumfromparnum(par);
|
||||
if (curPreview && reslist_current == reldocnum)
|
||||
// Bad number or already displayed. Forget it
|
||||
if (reldocnum < 0)
|
||||
return;
|
||||
|
||||
reslist_current = reldocnum;
|
||||
startPreview(reslist_winfirst + reldocnum);
|
||||
}
|
||||
|
||||
@ -412,7 +374,6 @@ void RecollMain::startAdvSearch(Rcl::AdvSearchData sdata)
|
||||
if (stemlang.empty())
|
||||
getQueryStemming(dostem, stemlang);
|
||||
|
||||
reslist_current = -1;
|
||||
reslist_winfirst = -1;
|
||||
|
||||
if (!rcldb->setQuery(sdata, dostem ?
|
||||
@ -594,8 +555,6 @@ void RecollMain::showResultPage()
|
||||
pageParaToReldocnums[reslistTE->paragraphs()-1] = i;
|
||||
}
|
||||
|
||||
reslist_current = -1;
|
||||
|
||||
if (gotone) {
|
||||
reslistTE->append("</body></qt>");
|
||||
reslistTE->setCursorPosition(0,0);
|
||||
@ -702,8 +661,7 @@ void RecollMain::startPreview(int docnum)
|
||||
string fn = urltolocalpath(doc.url);
|
||||
struct stat st;
|
||||
if (stat(fn.c_str(), &st) < 0) {
|
||||
QMessageBox::warning(0, "Recoll",
|
||||
tr("Cannot access document file: ") +
|
||||
QMessageBox::warning(0, "Recoll", tr("Cannot access document file: ") +
|
||||
fn.c_str());
|
||||
return;
|
||||
}
|
||||
@ -733,6 +691,59 @@ void RecollMain::startPreview(int docnum)
|
||||
curPreview->loadFileInCurrentTab(fn, st.st_size, doc);
|
||||
}
|
||||
|
||||
void RecollMain::startNativeViewer(int docnum)
|
||||
{
|
||||
Rcl::Doc doc;
|
||||
if (!docsource->getDoc(docnum, doc, 0, 0)) {
|
||||
QMessageBox::warning(0, "Recoll",
|
||||
tr("Cannot retrieve document info"
|
||||
" from database"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Look for appropriate viewer
|
||||
string cmd = rclconfig->getMimeViewerDef(doc.mimetype);
|
||||
if (cmd.length() == 0) {
|
||||
QMessageBox::warning(0, "Recoll",
|
||||
tr("No external viewer configured for mime type ")
|
||||
+ doc.mimetype.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
string fn = urltolocalpath(doc.url);
|
||||
|
||||
// Substitute %u (url) and %f (file name) inside prototype command
|
||||
string ncmd;
|
||||
string::const_iterator it1;
|
||||
for (it1 = cmd.begin(); it1 != cmd.end();it1++) {
|
||||
if (*it1 == '%') {
|
||||
if (++it1 == cmd.end()) {
|
||||
ncmd += '%';
|
||||
break;
|
||||
}
|
||||
if (*it1 == '%')
|
||||
ncmd += '%';
|
||||
if (*it1 == 'u')
|
||||
ncmd += "'" + doc.url + "'";
|
||||
if (*it1 == 'f')
|
||||
ncmd += "'" + fn + "'";
|
||||
} else {
|
||||
ncmd += *it1;
|
||||
}
|
||||
}
|
||||
|
||||
ncmd += " &";
|
||||
QStatusBar *stb = statusBar();
|
||||
if (stb) {
|
||||
QString msg = tr("Executing: [") + ncmd.c_str() + "]";
|
||||
stb->message(msg, 5000);
|
||||
stb->repaint(false);
|
||||
XFlush(qt_xdisplay());
|
||||
}
|
||||
history->enterDocument(fn, doc.ipath);
|
||||
system(ncmd.c_str());
|
||||
}
|
||||
|
||||
|
||||
void RecollMain::showAboutDialog()
|
||||
{
|
||||
@ -745,7 +756,6 @@ void RecollMain::showAboutDialog()
|
||||
void RecollMain::showDocHistory()
|
||||
{
|
||||
LOGDEB(("RecollMain::showDocHistory\n"));
|
||||
reslist_current = -1;
|
||||
reslist_winfirst = -1;
|
||||
curPreview = 0;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
|
||||
PROGS = trhist qtry qxtry xadump
|
||||
PROGS = xadump #trhist qtry qxtry
|
||||
all: $(PROGS)
|
||||
|
||||
XADUMP_OBJS= xadump.o $(BIGLIB)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user