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
|
#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
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -33,63 +33,24 @@ using namespace std;
|
|||||||
#define deleteZ(X) {delete X;X = 0;}
|
#define deleteZ(X) {delete X;X = 0;}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// A class to index a list of top directories into one database.
|
DbIndexer::~DbIndexer() {
|
||||||
///
|
// Maybe clean up temporary directory
|
||||||
/// Inherits FsTreeWalkerCB so that its processone() method is
|
if (tmpdir.length()) {
|
||||||
/// called by the file-system tree walk code for each file and
|
wipedir(tmpdir);
|
||||||
/// directory, and keeps all state used while indexing a
|
if (rmdir(tmpdir.c_str()) < 0) {
|
||||||
/// directory tree.
|
LOGERR(("DbIndexer::~DbIndexer: cannot clear temp dir %s\n",
|
||||||
class DbIndexer : public FsTreeWalkerCB {
|
tmpdir.c_str()));
|
||||||
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()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
db.close();
|
||||||
/// Start indexing.
|
}
|
||||||
bool index(bool resetbefore);
|
|
||||||
|
|
||||||
/// Tree walker callback method
|
|
||||||
FsTreeWalker::Status
|
|
||||||
processone(const std::string &, const struct stat *, FsTreeWalker::CbFlag);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/// Top level file system tree index method for updating a given database.
|
bool DbIndexer::indexDb(bool resetbefore, list<string> *topdirs)
|
||||||
///
|
|
||||||
/// 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)
|
|
||||||
{
|
{
|
||||||
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();
|
for (list<string>::const_iterator it = topdirs->begin();
|
||||||
it != topdirs->end(); it++) {
|
it != topdirs->end(); it++) {
|
||||||
LOGDEB(("DbIndexer::index: Indexing %s into %s\n", it->c_str(),
|
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) {
|
if (walker.walk(*it, *this) != FsTreeWalker::FtwOk) {
|
||||||
LOGERR(("DbIndexer::index: error while indexing %s\n",
|
LOGERR(("DbIndexer::index: error while indexing %s\n",
|
||||||
it->c_str()));
|
it->c_str()));
|
||||||
db.close();
|
|
||||||
return false;
|
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()) {
|
if (!db.close()) {
|
||||||
LOGERR(("DbIndexer::index: error closing database in %s\n",
|
LOGERR(("DbIndexer::index: error closing database in %s\n",
|
||||||
dbdir.c_str()));
|
dbdir.c_str()));
|
||||||
@ -146,6 +107,52 @@ bool DbIndexer::index(bool resetbefore)
|
|||||||
return true;
|
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
|
/// This method gets called for every file and directory found by the
|
||||||
/// tree walker.
|
/// tree walker.
|
||||||
@ -257,6 +264,7 @@ bool ConfIndexer::index(bool resetbefore)
|
|||||||
}
|
}
|
||||||
config->setKeyDir("");
|
config->setKeyDir("");
|
||||||
|
|
||||||
|
// The dbmap now has dbdir as key and directory lists as values.
|
||||||
// Index each directory group in turn
|
// Index each directory group in turn
|
||||||
for (dbit = dbmap.begin(); dbit != dbmap.end(); dbit++) {
|
for (dbit = dbmap.begin(); dbit != dbmap.end(); dbit++) {
|
||||||
//cout << dbit->first << " -> ";
|
//cout << dbit->first << " -> ";
|
||||||
@ -265,8 +273,8 @@ bool ConfIndexer::index(bool resetbefore)
|
|||||||
// cout << *dit << " ";
|
// cout << *dit << " ";
|
||||||
//}
|
//}
|
||||||
//cout << endl;
|
//cout << endl;
|
||||||
dbindexer = new DbIndexer(config, dbit->first, &dbit->second);
|
dbindexer = new DbIndexer(config, dbit->first);
|
||||||
if (!dbindexer->index(resetbefore)) {
|
if (!dbindexer->indexDb(resetbefore, &dbit->second)) {
|
||||||
deleteZ(dbindexer);
|
deleteZ(dbindexer);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,32 +1,84 @@
|
|||||||
#ifndef _INDEXER_H_INCLUDED_
|
#ifndef _INDEXER_H_INCLUDED_
|
||||||
#define _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 "rclconfig.h"
|
||||||
|
#include "fstreewalk.h"
|
||||||
|
#include "rcldb.h"
|
||||||
|
|
||||||
/**
|
/* Forward decl for lower level indexing object */
|
||||||
* An internal class to process all directories indexed into the same database.
|
|
||||||
*/
|
|
||||||
class DbIndexer;
|
class DbIndexer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The file system indexing object. Processes the configuration, then invokes
|
The top level indexing object. Processes the configuration, then invokes
|
||||||
* file system walking to populate/update the database(s).
|
file system walking to populate/update the database(s).
|
||||||
*
|
|
||||||
* Multiple top-level directories can be listed in the
|
Multiple top-level directories can be listed in the
|
||||||
* configuration. Each can be indexed to a different
|
configuration. Each can be indexed to a different
|
||||||
* database. Directories are first grouped by database, then an
|
database. Directories are first grouped by database, then an
|
||||||
* internal class (DbIndexer) is used to process each group.
|
internal class (DbIndexer) is used to process each group.
|
||||||
*/
|
*/
|
||||||
class ConfIndexer {
|
class ConfIndexer {
|
||||||
RclConfig *config;
|
|
||||||
DbIndexer *dbindexer; // Object to process directories for a given db
|
|
||||||
public:
|
public:
|
||||||
enum runStatus {IndexerOk, IndexerError};
|
enum runStatus {IndexerOk, IndexerError};
|
||||||
ConfIndexer(RclConfig *cnf) : config(cnf), dbindexer(0) {}
|
ConfIndexer(RclConfig *cnf) : config(cnf), dbindexer(0) {}
|
||||||
virtual ~ConfIndexer();
|
virtual ~ConfIndexer();
|
||||||
/** Worker function: doe the actual indexing */
|
/** Worker function: doe the actual indexing */
|
||||||
bool index(bool resetbefore = false);
|
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_ */
|
#endif /* _INDEXER_H_INCLUDED_ */
|
||||||
|
|||||||
@ -1,20 +1,53 @@
|
|||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <list>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
#include "debuglog.h"
|
#include "debuglog.h"
|
||||||
#include "rclinit.h"
|
#include "rclinit.h"
|
||||||
#include "indexer.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()
|
static void cleanup()
|
||||||
{
|
{
|
||||||
delete indexer;
|
delete confindexer;
|
||||||
indexer = 0;
|
confindexer = 0;
|
||||||
|
delete dbindexer;
|
||||||
|
dbindexer = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sigcleanup(int sig)
|
static void sigcleanup(int sig)
|
||||||
@ -29,12 +62,16 @@ static int op_flags;
|
|||||||
#define OPT_MOINS 0x1
|
#define OPT_MOINS 0x1
|
||||||
#define OPT_z 0x2
|
#define OPT_z 0x2
|
||||||
#define OPT_h 0x4
|
#define OPT_h 0x4
|
||||||
|
#define OPT_i 0x8
|
||||||
|
|
||||||
static const char usage [] =
|
static const char usage [] =
|
||||||
" recollindex [-hz]\n"
|
" recollindex [-hz] \n"
|
||||||
|
" recollindex -i <filename [filename ...]>\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
" -h : print this message\n"
|
" -h : print this message\n"
|
||||||
" -z : reset database before starting indexation\n\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
|
static void
|
||||||
@ -59,22 +96,43 @@ int main(int argc, const char **argv)
|
|||||||
switch (*(*argv)++) {
|
switch (*(*argv)++) {
|
||||||
case 'z': op_flags |= OPT_z; break;
|
case 'z': op_flags |= OPT_z; break;
|
||||||
case 'h': op_flags |= OPT_h; break;
|
case 'h': op_flags |= OPT_h; break;
|
||||||
|
case 'i': op_flags |= OPT_i; break;
|
||||||
default: Usage(); break;
|
default: Usage(); break;
|
||||||
}
|
}
|
||||||
|
b1: argc--; argv++;
|
||||||
}
|
}
|
||||||
if (op_flags & OPT_h)
|
if (op_flags & OPT_h)
|
||||||
Usage();
|
Usage();
|
||||||
|
if ((op_flags & OPT_z) && (op_flags & OPT_i))
|
||||||
|
Usage();
|
||||||
|
|
||||||
string reason;
|
string reason;
|
||||||
RclConfig *config = recollinit(cleanup, sigcleanup, reason);
|
RclConfig *config = recollinit(cleanup, sigcleanup, reason);
|
||||||
|
|
||||||
if (config == 0 || !config->ok()) {
|
if (config == 0 || !config->ok()) {
|
||||||
string str = "Configuration problem: ";
|
cerr << "Configuration problem: " << reason << endl;
|
||||||
str += reason;
|
|
||||||
fprintf(stderr, "%s\n", str.c_str());
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
indexer = new ConfIndexer(config);
|
if (op_flags & OPT_i) {
|
||||||
|
list<string> filenames;
|
||||||
exit(!indexer->index((op_flags & OPT_z) != 0));
|
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()));
|
charset.c_str(),result.doccharset.c_str()));
|
||||||
if (!result.doccharset.empty() &&
|
if (!result.doccharset.empty() &&
|
||||||
!samecharset(result.doccharset, result.ocharset)) {
|
!samecharset(result.doccharset, result.ocharset)) {
|
||||||
LOGDEB(("textHtmlToDoc: charset '%s' doc charset '%s',"
|
LOGDEB(("textHtmlToDoc: reparse for charsets\n"));
|
||||||
"reparse\n", charset.c_str(),
|
|
||||||
result.doccharset.c_str()));
|
|
||||||
charset = result.doccharset;
|
charset = result.doccharset;
|
||||||
} else {
|
} else {
|
||||||
LOGERR(("textHtmlToDoc:: error: non charset exception\n"));
|
LOGERR(("textHtmlToDoc:: error: non charset exception\n"));
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -30,12 +30,14 @@ MimeHandler::Status MimeHandlerText::mkDoc(RclConfig *conf, const string &fn,
|
|||||||
charset = csguess(otext, conf->getDefCharset());
|
charset = csguess(otext, conf->getDefCharset());
|
||||||
} else
|
} else
|
||||||
charset = conf->getDefCharset();
|
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")) {
|
if (!transcode(otext, utf8, charset, "UTF-8")) {
|
||||||
cerr << "textPlainToDoc: transcode failed: charset '" << charset
|
LOGERR(("MimeHandlerText::mkDoc: transcode to utf-8 failed "
|
||||||
<< "' to UTF-8: "<< utf8 << endl;
|
"for charset [%s]\n", charset.c_str()));
|
||||||
otext.erase();
|
otext.erase();
|
||||||
return MimeHandler::MHError;
|
return MimeHandler::MHError;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -399,6 +399,8 @@ void Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc)
|
|||||||
|
|
||||||
// Load and convert file
|
// Load and convert file
|
||||||
Rcl::Doc fdoc;
|
Rcl::Doc fdoc;
|
||||||
|
// Need to setup config to retrieve possibly local parameters
|
||||||
|
rclconfig->setKeyDir(path_getfather(fn));
|
||||||
int status = 1;
|
int status = 1;
|
||||||
LoadThread lthr(&status, &fdoc, fn, doc.ipath, &doc.mimetype);
|
LoadThread lthr(&status, &fdoc, fn, doc.ipath, &doc.mimetype);
|
||||||
lthr.start();
|
lthr.start();
|
||||||
@ -419,6 +421,8 @@ void Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc)
|
|||||||
doc.mimetype.c_str());
|
doc.mimetype.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// Reset config just in case.
|
||||||
|
rclconfig->setKeyDir("");
|
||||||
|
|
||||||
// Highlight search terms:
|
// Highlight search terms:
|
||||||
progress.setLabelText(tr("Creating preview text"));
|
progress.setLabelText(tr("Creating preview text"));
|
||||||
|
|||||||
@ -22,7 +22,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<property name="minimumSize">
|
<property name="minimumSize">
|
||||||
<size>
|
<size>
|
||||||
<width>466</width>
|
<width>362</width>
|
||||||
<height>190</height>
|
<height>190</height>
|
||||||
</size>
|
</size>
|
||||||
</property>
|
</property>
|
||||||
@ -62,6 +62,9 @@
|
|||||||
<property name="accel">
|
<property name="accel">
|
||||||
<string>Ctrl+S</string>
|
<string>Ctrl+S</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="toolTip" stdset="0">
|
||||||
|
<string>Erase search entry</string>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QPushButton">
|
<widget class="QPushButton">
|
||||||
<property name="name">
|
<property name="name">
|
||||||
@ -73,6 +76,9 @@
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Search</string>
|
<string>Search</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="toolTip" stdset="0">
|
||||||
|
<string>Start query</string>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QCheckBox">
|
<widget class="QCheckBox">
|
||||||
<property name="name">
|
<property name="name">
|
||||||
@ -84,6 +90,12 @@
|
|||||||
<property name="accel">
|
<property name="accel">
|
||||||
<string>Alt+A</string>
|
<string>Alt+A</string>
|
||||||
</property>
|
</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>
|
||||||
<widget class="QLineEdit">
|
<widget class="QLineEdit">
|
||||||
<property name="name">
|
<property name="name">
|
||||||
@ -109,6 +121,9 @@
|
|||||||
<property name="frameShadow">
|
<property name="frameShadow">
|
||||||
<enum>Sunken</enum>
|
<enum>Sunken</enum>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="toolTip" stdset="0">
|
||||||
|
<string>Enter search terms here</string>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</hbox>
|
</hbox>
|
||||||
</widget>
|
</widget>
|
||||||
@ -181,6 +196,14 @@
|
|||||||
<action name="prevPageAction"/>
|
<action name="prevPageAction"/>
|
||||||
<action name="nextPageAction"/>
|
<action name="nextPageAction"/>
|
||||||
</toolbar>
|
</toolbar>
|
||||||
|
<toolbar dock="2">
|
||||||
|
<property name="name">
|
||||||
|
<cstring>HelpToolbar</cstring>
|
||||||
|
</property>
|
||||||
|
<property name="label">
|
||||||
|
<string>Toolbar_2</string>
|
||||||
|
</property>
|
||||||
|
</toolbar>
|
||||||
</toolbars>
|
</toolbars>
|
||||||
<actions>
|
<actions>
|
||||||
<action>
|
<action>
|
||||||
@ -224,10 +247,13 @@
|
|||||||
<iconset>history</iconset>
|
<iconset>history</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Doc History</string>
|
<string>Document &History</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="menuText">
|
<property name="menuText">
|
||||||
<string>Doc &History</string>
|
<string>Document &History</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Document History</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action>
|
<action>
|
||||||
@ -241,7 +267,10 @@
|
|||||||
<string>Advanced Search</string>
|
<string>Advanced Search</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="menuText">
|
<property name="menuText">
|
||||||
<string>Advanced Search</string>
|
<string>&Advanced Search</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Advanced/complex Search</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action>
|
<action>
|
||||||
@ -252,9 +281,12 @@
|
|||||||
<iconset>sortparms</iconset>
|
<iconset>sortparms</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Sort parameters</string>
|
<string>&Sort parameters</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="menuText">
|
<property name="menuText">
|
||||||
|
<string>&Sort parameters</string>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
<string>Sort parameters</string>
|
<string>Sort parameters</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
@ -262,7 +294,7 @@
|
|||||||
<property name="name">
|
<property name="name">
|
||||||
<cstring>nextPageAction</cstring>
|
<cstring>nextPageAction</cstring>
|
||||||
</property>
|
</property>
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSet">
|
<property name="iconSet">
|
||||||
@ -271,12 +303,15 @@
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Next page</string>
|
<string>Next page</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Next page of results</string>
|
||||||
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action>
|
<action>
|
||||||
<property name="name">
|
<property name="name">
|
||||||
<cstring>prevPageAction</cstring>
|
<cstring>prevPageAction</cstring>
|
||||||
</property>
|
</property>
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="iconSet">
|
<property name="iconSet">
|
||||||
@ -285,6 +320,9 @@
|
|||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Previous page</string>
|
<string>Previous page</string>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Previous page of results</string>
|
||||||
|
</property>
|
||||||
</action>
|
</action>
|
||||||
</actions>
|
</actions>
|
||||||
<connections>
|
<connections>
|
||||||
@ -383,7 +421,6 @@
|
|||||||
</includes>
|
</includes>
|
||||||
<variables>
|
<variables>
|
||||||
<variable>int reslist_winfirst;</variable>
|
<variable>int reslist_winfirst;</variable>
|
||||||
<variable>int reslist_current;</variable>
|
|
||||||
<variable>bool reslist_mouseDrag;</variable>
|
<variable>bool reslist_mouseDrag;</variable>
|
||||||
<variable>bool reslist_mouseDown;</variable>
|
<variable>bool reslist_mouseDown;</variable>
|
||||||
<variable>int reslist_par;</variable>
|
<variable>int reslist_par;</variable>
|
||||||
@ -425,8 +462,9 @@
|
|||||||
<function access="private">init()</function>
|
<function access="private">init()</function>
|
||||||
<function returnType="bool">close( bool )</function>
|
<function returnType="bool">close( bool )</function>
|
||||||
<function access="private" returnType="bool">eventFilter( QObject * target, QEvent * event )</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" returnType="int">reldocnumfromparnum( int parnum )</function>
|
||||||
|
<function access="private">startPreview( int docnum )</function>
|
||||||
|
<function access="private">startNativeViewer( int docnum )</function>
|
||||||
</functions>
|
</functions>
|
||||||
<pixmapinproject/>
|
<pixmapinproject/>
|
||||||
<layoutdefaults spacing="6" margin="11"/>
|
<layoutdefaults spacing="6" margin="11"/>
|
||||||
|
|||||||
@ -54,7 +54,6 @@ static const int respagesize = 8;
|
|||||||
void RecollMain::init()
|
void RecollMain::init()
|
||||||
{
|
{
|
||||||
reslist_winfirst = -1;
|
reslist_winfirst = -1;
|
||||||
reslist_current = -1;
|
|
||||||
reslist_mouseDrag = false;
|
reslist_mouseDrag = false;
|
||||||
reslist_mouseDown = false;
|
reslist_mouseDown = false;
|
||||||
reslist_par = -1;
|
reslist_par = -1;
|
||||||
@ -73,6 +72,8 @@ void RecollMain::init()
|
|||||||
reslistTE->viewport()->installEventFilter(this);
|
reslistTE->viewport()->installEventFilter(this);
|
||||||
// reslistTE->viewport()->setFocusPolicy(QWidget::NoFocus);
|
// 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
|
// 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));
|
LOGDEB(("RecollMain::reslistTE_doubleClicked: par %d\n", par));
|
||||||
reslist_dblclck = true;
|
reslist_dblclck = true;
|
||||||
|
|
||||||
Rcl::Doc doc;
|
|
||||||
int reldocnum = reldocnumfromparnum(par);
|
int reldocnum = reldocnumfromparnum(par);
|
||||||
if (!docsource->getDoc(reslist_winfirst + reldocnum, doc, 0, 0))
|
if (reldocnum < 0)
|
||||||
return;
|
return;
|
||||||
|
startNativeViewer(reslist_winfirst + reldocnum);
|
||||||
// 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());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -337,7 +295,7 @@ void RecollMain::reslistTE_clicked(int par, int car)
|
|||||||
{
|
{
|
||||||
if (reslist_waitingdbl)
|
if (reslist_waitingdbl)
|
||||||
return;
|
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));
|
reslist_winfirst, par, car, reslist_mouseDrag));
|
||||||
if (reslist_winfirst == -1 || reslist_mouseDrag)
|
if (reslist_winfirst == -1 || reslist_mouseDrag)
|
||||||
return;
|
return;
|
||||||
@ -356,28 +314,32 @@ void RecollMain::reslistTE_clicked(int par, int car)
|
|||||||
// requested a native viewer by double-clicking
|
// requested a native viewer by double-clicking
|
||||||
void RecollMain::reslistTE_delayedclick()
|
void RecollMain::reslistTE_delayedclick()
|
||||||
{
|
{
|
||||||
|
LOGDEB(("RecollMain::reslistTE_delayedclick:\n"));
|
||||||
reslist_waitingdbl = false;
|
reslist_waitingdbl = false;
|
||||||
if (reslist_dblclck) {
|
if (reslist_dblclck) {
|
||||||
|
LOGDEB1(("RecollMain::reslistTE_delayedclick: dbleclick\n"));
|
||||||
reslist_dblclck = false;
|
reslist_dblclck = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int par = reslist_par;
|
int par = reslist_par;
|
||||||
|
|
||||||
|
// Erase everything back to white
|
||||||
{
|
{
|
||||||
QColor color("white");
|
QColor color("white");
|
||||||
for (int i = 1; i < reslistTE->paragraphs(); i++)
|
for (int i = 1; i < reslistTE->paragraphs(); i++)
|
||||||
reslistTE->setParagraphBackgroundColor(i, color);
|
reslistTE->setParagraphBackgroundColor(i, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Color the new active paragraph
|
||||||
QColor color("lightblue");
|
QColor color("lightblue");
|
||||||
reslistTE->setParagraphBackgroundColor(par, color);
|
reslistTE->setParagraphBackgroundColor(par, color);
|
||||||
|
|
||||||
|
// Document number
|
||||||
int reldocnum = reldocnumfromparnum(par);
|
int reldocnum = reldocnumfromparnum(par);
|
||||||
if (curPreview && reslist_current == reldocnum)
|
// Bad number or already displayed. Forget it
|
||||||
|
if (reldocnum < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
reslist_current = reldocnum;
|
|
||||||
startPreview(reslist_winfirst + reldocnum);
|
startPreview(reslist_winfirst + reldocnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,7 +374,6 @@ void RecollMain::startAdvSearch(Rcl::AdvSearchData sdata)
|
|||||||
if (stemlang.empty())
|
if (stemlang.empty())
|
||||||
getQueryStemming(dostem, stemlang);
|
getQueryStemming(dostem, stemlang);
|
||||||
|
|
||||||
reslist_current = -1;
|
|
||||||
reslist_winfirst = -1;
|
reslist_winfirst = -1;
|
||||||
|
|
||||||
if (!rcldb->setQuery(sdata, dostem ?
|
if (!rcldb->setQuery(sdata, dostem ?
|
||||||
@ -594,8 +555,6 @@ void RecollMain::showResultPage()
|
|||||||
pageParaToReldocnums[reslistTE->paragraphs()-1] = i;
|
pageParaToReldocnums[reslistTE->paragraphs()-1] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
reslist_current = -1;
|
|
||||||
|
|
||||||
if (gotone) {
|
if (gotone) {
|
||||||
reslistTE->append("</body></qt>");
|
reslistTE->append("</body></qt>");
|
||||||
reslistTE->setCursorPosition(0,0);
|
reslistTE->setCursorPosition(0,0);
|
||||||
@ -702,8 +661,7 @@ void RecollMain::startPreview(int docnum)
|
|||||||
string fn = urltolocalpath(doc.url);
|
string fn = urltolocalpath(doc.url);
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(fn.c_str(), &st) < 0) {
|
if (stat(fn.c_str(), &st) < 0) {
|
||||||
QMessageBox::warning(0, "Recoll",
|
QMessageBox::warning(0, "Recoll", tr("Cannot access document file: ") +
|
||||||
tr("Cannot access document file: ") +
|
|
||||||
fn.c_str());
|
fn.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -733,6 +691,59 @@ void RecollMain::startPreview(int docnum)
|
|||||||
curPreview->loadFileInCurrentTab(fn, st.st_size, doc);
|
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()
|
void RecollMain::showAboutDialog()
|
||||||
{
|
{
|
||||||
@ -745,7 +756,6 @@ void RecollMain::showAboutDialog()
|
|||||||
void RecollMain::showDocHistory()
|
void RecollMain::showDocHistory()
|
||||||
{
|
{
|
||||||
LOGDEB(("RecollMain::showDocHistory\n"));
|
LOGDEB(("RecollMain::showDocHistory\n"));
|
||||||
reslist_current = -1;
|
|
||||||
reslist_winfirst = -1;
|
reslist_winfirst = -1;
|
||||||
curPreview = 0;
|
curPreview = 0;
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
PROGS = trhist qtry qxtry xadump
|
PROGS = xadump #trhist qtry qxtry
|
||||||
all: $(PROGS)
|
all: $(PROGS)
|
||||||
|
|
||||||
XADUMP_OBJS= xadump.o $(BIGLIB)
|
XADUMP_OBJS= xadump.o $(BIGLIB)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user