allow opening parent/enclosing doc with native editor in reslist

This commit is contained in:
dockes 2009-11-06 11:33:32 +00:00
parent 8ae11e4125
commit 96dba3a3ee
13 changed files with 116 additions and 40 deletions

View File

@ -44,6 +44,8 @@ using namespace std;
#include "wipedir.h"
#include "rclconfig.h"
#include "mh_html.h"
#include "fileudi.h"
#ifdef RCL_USE_XATTR
#include "pxattr.h"
#endif // RCL_USE_XATTR
@ -85,7 +87,7 @@ void FileInterner::reapXAttrs(const string& path)
// This is used when the user wants to retrieve a search result doc's parent
// (ie message having a given attachment)
bool FileInterner::getEnclosing(const string &url, const string &ipath,
string &eurl, string &eipath)
string &eurl, string &eipath, string& udi)
{
eurl = url;
eipath = ipath;
@ -98,6 +100,8 @@ bool FileInterner::getEnclosing(const string &url, const string &ipath,
} else {
eipath.erase();
}
make_udi(url_gpath(eurl), eipath, udi);
LOGDEB(("FileInterner::getEnclosing() after: [%s]\n", eipath.c_str()));
return true;
}

View File

@ -53,7 +53,7 @@ class FileInterner {
* with Rcl::Db::addOrUpdate(). The latter is generally the enclosing file.
*/
static bool getEnclosing(const string &url, const string &ipath,
string &eurl, string &eipath);
string &eurl, string &eipath, string& udi);
/**
* Identify and possibly decompress file, create adequate
* handler. The mtype parameter is only set when the object is

View File

@ -929,8 +929,8 @@ void RclMain::startNativeViewer(Rcl::Doc doc)
if (cmd.length() == 0) {
QMessageBox::warning(0, "Recoll",
tr("No external viewer configured for mime type ")
+ doc.mimetype.c_str());
tr("No external viewer configured for mime type [")
+ doc.mimetype.c_str() + "]");
return;
}

View File

@ -91,6 +91,22 @@ ResList::ResList(QWidget* parent, const char* name)
ResList::~ResList()
{
// These have to exist somewhere for translations to work
#ifdef __GNUC__
__attribute__((unused))
#endif
static const char* strings[] = {
QT_TR_NOOP("<p><b>No results found</b><br>"),
QT_TR_NOOP("Documents <b>%d-%d</b> out of at least <b>%d</b> for "),
QT_TR_NOOP("Documents <b>%d-%d</b> for "),
QT_TR_NOOP("Previous"),
QT_TR_NOOP("Next"),
QT_TR_NOOP("Unavailable document"),
QT_TR_NOOP("Preview"),
QT_TR_NOOP("Open"),
QT_TR_NOOP("(show query)"),
};
}
int ResList::newListId()
@ -346,18 +362,6 @@ void ResList::resultPageFirst()
void ResList::append(const QString &text)
{
// These has to go somewhere for translations to work
static const char* strings[] = {
QT_TR_NOOP("<p><b>No results found</b><br>"),
QT_TR_NOOP("Documents <b>%d-%d</b> out of at least <b>%d</b> for "),
QT_TR_NOOP("Documents <b>%d-%d</b> for "),
QT_TR_NOOP("Previous"),
QT_TR_NOOP("Next"),
QT_TR_NOOP("Unavailable document"),
QT_TR_NOOP("Preview"),
QT_TR_NOOP("Open"),
QT_TR_NOOP("(show query)"),
};
QTEXTBROWSER::append(text);
#if 0
{
@ -565,12 +569,14 @@ RCLPOPUP *ResList::createPopupMenu(const QPoint& pos)
popup->insertItem(tr("Copy &URL"), this, SLOT(menuCopyURL()));
Rcl::Doc doc;
if (getDoc(m_popDoc, doc) && !doc.ipath.empty()) {
popup->insertItem(tr("Save to File"), this, SLOT(menuSaveToFile()));
popup->insertItem(tr("&Write to File"), this, SLOT(menuSaveToFile()));
}
popup->insertItem(tr("Find &similar documents"), this, SLOT(menuExpand()));
popup->insertItem(tr("P&arent document/folder"),
this, SLOT(menuSeeParent()));
popup->insertItem(tr("Preview P&arent document/folder"),
this, SLOT(menuPreviewParent()));
popup->insertItem(tr("&Open Parent document/folder"),
this, SLOT(menuOpenParent()));
return popup;
}
@ -583,20 +589,37 @@ void ResList::menuSaveToFile()
emit docSaveToFileClicked(m_popDoc);
}
void ResList::menuSeeParent()
void ResList::menuPreviewParent()
{
Rcl::Doc doc;
if (!getDoc(m_popDoc, doc))
if (!getDoc(m_popDoc, doc) || m_baseDocSource.isNull())
return;
Rcl::Doc doc1;
if (FileInterner::getEnclosing(doc.url, doc.ipath, doc1.url, doc1.ipath)) {
emit previewRequested(doc1);
Rcl::Doc pdoc;
if (m_baseDocSource->getEnclosing(doc, pdoc)) {
emit previewRequested(pdoc);
} else {
// No parent doc: show enclosing folder with app configured for
// directories
doc1.url = path_getfather(doc.url);
doc1.mimetype = "application/x-fsdirectory";
emit editRequested(doc1);
pdoc.url = path_getfather(doc.url);
pdoc.mimetype = "application/x-fsdirectory";
emit editRequested(pdoc);
}
}
void ResList::menuOpenParent()
{
Rcl::Doc doc;
if (!getDoc(m_popDoc, doc) || m_baseDocSource.isNull())
return;
Rcl::Doc pdoc;
if (m_baseDocSource->getEnclosing(doc, pdoc)) {
emit editRequested(pdoc);
} else {
// No parent doc: show enclosing folder with app configured for
// directories
pdoc.url = path_getfather(doc.url);
pdoc.mimetype = "application/x-fsdirectory";
emit editRequested(pdoc);
}
}

View File

@ -95,7 +95,8 @@ class ResList : public QTEXTBROWSER
virtual void menuCopyFN();
virtual void menuCopyURL();
virtual void menuExpand();
virtual void menuSeeParent();
virtual void menuPreviewParent();
virtual void menuOpenParent();
virtual void previewExposed(int);
virtual void append(const QString &text);
// Only used for qt ver >=4 but seems we cant undef it

View File

@ -104,6 +104,8 @@ class DocSequence {
return doc.meta[Rcl::Doc::keyabs];
}
virtual bool getEnclosing(Rcl::Doc&, Rcl::Doc&) {return false;}
/** Get estimated total count in results */
virtual int getResCnt() = 0;

View File

@ -23,6 +23,7 @@ static char rcsid[] = "@(#$Id: docseqdb.cpp,v 1.9 2008-11-13 10:57:46 dockes Exp
#include "docseqdb.h"
#include "rcldb.h"
#include "debuglog.h"
#include "internfile.h"
DocSequenceDb::DocSequenceDb(RefCntr<Rcl::Query> q, const string &t,
RefCntr<Rcl::SearchData> sdata)
@ -78,6 +79,15 @@ string DocSequenceDb::getAbstract(Rcl::Doc &doc)
return abstract.empty() ? doc.meta[Rcl::Doc::keyabs] : abstract;
}
bool DocSequenceDb::getEnclosing(Rcl::Doc& doc, Rcl::Doc& pdoc)
{
string udi;
if (!FileInterner::getEnclosing(doc.url, doc.ipath, pdoc.url, pdoc.ipath,
udi))
return false;
return m_q->whatDb()->getDoc(udi, pdoc);
}
list<string> DocSequenceDb::expand(Rcl::Doc &doc)
{
return m_q->expand(doc);

View File

@ -36,6 +36,7 @@ class DocSequenceDb : public DocSequence {
vector<vector<string> >& groups,
vector<int>& gslks);
virtual string getAbstract(Rcl::Doc &doc);
virtual bool getEnclosing(Rcl::Doc& doc, Rcl::Doc& pdoc);
virtual string getDescription();
virtual list<string> expand(Rcl::Doc &doc);
virtual bool canFilter() {return true;}

View File

@ -24,6 +24,7 @@ static char rcsid[] = "@(#$Id: docseqhist.cpp,v 1.4 2008-09-29 08:59:20 dockes E
#include "docseqhist.h"
#include "rcldb.h"
#include "fileudi.h"
#include "internfile.h"
bool DocSequenceHistory::getDoc(int num, Rcl::Doc &doc, string *sh)
{
@ -66,6 +67,15 @@ bool DocSequenceHistory::getDoc(int num, Rcl::Doc &doc, string *sh)
return ret;
}
bool DocSequenceHistory::getEnclosing(Rcl::Doc& doc, Rcl::Doc& pdoc)
{
string udi;
if (!FileInterner::getEnclosing(doc.url, doc.ipath, pdoc.url, pdoc.ipath,
udi))
return false;
return m_db->getDoc(udi, pdoc);
}
int DocSequenceHistory::getResCnt()
{
if (m_hlist.empty())

View File

@ -35,6 +35,7 @@ class DocSequenceHistory : public DocSequence {
virtual ~DocSequenceHistory() {}
virtual bool getDoc(int num, Rcl::Doc &doc, string *sh = 0);
virtual bool getEnclosing(Rcl::Doc& doc, Rcl::Doc& pdoc);
virtual int getResCnt();
virtual string getDescription() {return m_description;}
void setDescription(const string& desc) {m_description = desc;}

View File

@ -24,9 +24,8 @@ using std::string;
// indexer). Document Ids are built from a concatenation of the file
// path and the internal path (ie: email number inside
// folder/attachment number/etc.) As the size of Xapian terms is
// limited, the path is truncated to a maximum length, and completed
// by a hash of the remainder. So the unique id looks like:
// /some/truncated/paHASHVALUE|ipath
// limited, the Id path is truncated to a maximum length, and completed
// by a hash of the remainder (including the ipath)
extern void make_udi(const string& fn, const string& ipath, string &udi);

View File

@ -176,13 +176,13 @@ TempFileInternal::~TempFileInternal()
}
void path_catslash(std::string &s) {
void path_catslash(string &s) {
if (s.empty() || s[s.length() - 1] != '/')
s += '/';
}
std::string path_cat(const std::string &s1, const std::string &s2) {
std::string res = s1;
string path_cat(const string &s1, const string &s2) {
string res = s1;
path_catslash(res);
res += s2;
return res;
@ -274,7 +274,7 @@ extern string path_tildexpand(const string &s)
return o;
}
extern std::string path_absolute(const std::string &is)
extern string path_absolute(const string &is)
{
if (is.length() == 0)
return is;
@ -290,7 +290,7 @@ extern std::string path_absolute(const std::string &is)
}
#include <smallut.h>
extern std::string path_canon(const std::string &is)
extern string path_canon(const string &is)
{
if (is.length() == 0)
return is;
@ -330,8 +330,8 @@ extern std::string path_canon(const std::string &is)
#include <glob.h>
#include <sys/stat.h>
list<std::string> path_dirglob(const std::string &dir,
const std::string pattern)
list<string> path_dirglob(const string &dir,
const string pattern)
{
list<string> res;
glob_t mglob;
@ -356,7 +356,7 @@ bool path_isdir(const string& path)
return false;
}
std::string url_encode(const std::string url, string::size_type offs)
string url_encode(const string& url, string::size_type offs)
{
string out = url.substr(0, offs);
const char *cp = url.c_str();
@ -392,6 +392,26 @@ std::string url_encode(const std::string url, string::size_type offs)
return out;
}
string url_gpath(const string& url)
{
// Remove the access schema part (or whatever it's called)
string::size_type colon = url.find_first_of(":");
if (colon == string::npos || colon == url.size() - 1)
return url;
// If there are non-alphanum chars before the ':', then there
// probably is no scheme. Whatever...
for (string::size_type i = 0; i < colon; i++) {
if (!isalnum(url.at(i)))
return url;
}
// In addition we canonize the path to remove empty host parts
// (for compatibility with older versions of recoll where file://
// was hardcoded, but the local path was used for doc
// identification.
return path_canon(url.substr(colon+1));
}
// Printable url: this is used to transcode from the system charset
// into either utf-8 if transcoding succeeds, or url-encoded
bool printableUrl(const string &fcharset, const string &in, string &out)

View File

@ -50,11 +50,16 @@ extern string path_canon(const string &s);
extern list<string> path_dirglob(const string &dir,
const string pattern);
/// Encode according to rfc 1738
extern string url_encode(const string url,
extern string url_encode(const string& url,
string::size_type offs = 0);
/// Transcode to utf-8 if possible or url encoding, for display.
extern bool printableUrl(const string &fcharset,
const string &in, string &out);
/// Return the host+path part of an url. This is not a general
/// routine, it does the right thing only in the recoll context
extern string url_gpath(const string& url);
/// Stat parameter and check if it's a directory
extern bool path_isdir(const string& path);