added saveToFile menu entry to reslist

This commit is contained in:
dockes 2009-01-21 16:42:26 +00:00
parent 229645a0e2
commit bc207a3986
6 changed files with 81 additions and 22 deletions

View File

@ -648,7 +648,7 @@ FileInterner::Status FileInterner::internfile(Rcl::Doc& doc, string& ipath)
return FIAgain; return FIAgain;
} }
// Automatic cleanup of iDocTempFile's temp dir // Automatic cleanup of iDocToFile's temp dir
class DirWiper { class DirWiper {
public: public:
string dir; string dir;
@ -671,14 +671,15 @@ class DirWiper {
// return by the DirWiper object // return by the DirWiper object
// - The output temporary file which is held in a reference-counted // - The output temporary file which is held in a reference-counted
// object and will be deleted when done with. // object and will be deleted when done with.
bool FileInterner::idocTempFile(TempFile& otemp, RclConfig *cnf, bool FileInterner::idocToFile(TempFile& otemp, const string& tofile,
const string& fn, RclConfig *cnf,
const string& ipath, const string& fn,
const string& mtype) const string& ipath,
const string& mtype)
{ {
struct stat st; struct stat st;
if (stat(fn.c_str(), &st) < 0) { if (stat(fn.c_str(), &st) < 0) {
LOGERR(("FileInterner::idocTempFile: can't stat [%s]\n", fn.c_str())); LOGERR(("FileInterner::idocToFile: can't stat [%s]\n", fn.c_str()));
return false; return false;
} }
@ -693,29 +694,39 @@ bool FileInterner::idocTempFile(TempFile& otemp, RclConfig *cnf,
string mipath = ipath; string mipath = ipath;
Status ret = interner.internfile(doc, mipath); Status ret = interner.internfile(doc, mipath);
if (ret == FileInterner::FIError) { if (ret == FileInterner::FIError) {
LOGERR(("FileInterner::idocTempFile: internfile() failed\n")); LOGERR(("FileInterner::idocToFile: internfile() failed\n"));
return false; return false;
} }
TempFile temp(new TempFileInternal(cnf->getSuffixFromMimeType(mtype)));
if (!temp->ok()) { string filename;
LOGERR(("FileInterner::idocTempFile: cannot create temporary file")); TempFile temp;
return false; if (tofile.empty()) {
TempFile temp1(new TempFileInternal(cnf->getSuffixFromMimeType(mtype)));
temp = temp1;
if (!temp->ok()) {
LOGERR(("FileInterner::idocToFile: cant create temporary file"));
return false;
}
filename = temp->filename();
} else {
filename = tofile;
} }
int fd = open(temp->filename(), O_WRONLY); int fd = open(filename.c_str(), O_WRONLY|O_CREAT, 0600);
if (fd < 0) { if (fd < 0) {
LOGERR(("FileInterner::idocTempFile: open(%s) failed errno %d\n", LOGERR(("FileInterner::idocToFile: open(%s) failed errno %d\n",
temp->filename(), errno)); filename.c_str(), errno));
return false; return false;
} }
const string& dt = doc.text; const string& dt = doc.text;
if (write(fd, dt.c_str(), dt.length()) != (int)dt.length()) { if (write(fd, dt.c_str(), dt.length()) != (int)dt.length()) {
close(fd); close(fd);
LOGERR(("FileInterner::idocTempFile: write to %s failed errno %d\n", LOGERR(("FileInterner::idocToFile: write to %s failed errno %d\n",
temp->filename(), errno)); filename.c_str(), errno));
return false; return false;
} }
close(fd); close(fd);
otemp = temp; if (tofile.empty())
otemp = temp;
return true; return true;
} }

View File

@ -102,19 +102,21 @@ class FileInterner {
/* In case we see an html version, it's set aside and can be recovered */ /* In case we see an html version, it's set aside and can be recovered */
const string& get_html() {return m_html;} const string& get_html() {return m_html;}
/** Utility function: extract internal document into temporary file. /** Extract internal document into temporary file.
* This is used mainly for starting an external viewer for a * This is used mainly for starting an external viewer for a
* subdocument (ie: mail attachment). * subdocument (ie: mail attachment).
* @return true for success. * @return true for success.
* @param temp output reference-counted temp file object (goes * @param temp output reference-counted temp file object (goes
* away magically) * away magically). Only used if tofile.empty()
* @param tofile output file if not null
* @param cnf The recoll config * @param cnf The recoll config
* @param fn The main document from which to extract * @param fn The main document from which to extract
* @param ipath The internal path to the subdoc * @param ipath The internal path to the subdoc
* @param mtype The target mime type (we don't want to decode to text!) * @param mtype The target mime type (we don't want to decode to text!)
*/ */
static bool idocTempFile(TempFile& temp, RclConfig *cnf, const string& fn, static bool idocToFile(TempFile& temp, const string& tofile,
const string& ipath, const string& mtype); RclConfig *cnf, const string& fn,
const string& ipath, const string& mtype);
const string& getReason() const {return m_reason;} const string& getReason() const {return m_reason;}
static void getMissingExternal(string& missing); static void getMissingExternal(string& missing);

View File

@ -33,12 +33,18 @@ using std::pair;
#include <qapplication.h> #include <qapplication.h>
#include <qmessagebox.h> #include <qmessagebox.h>
#if (QT_VERSION < 0x040000) #if (QT_VERSION < 0x040000)
#include <qcstring.h> #include <qcstring.h>
#include <qpopupmenu.h> #include <qpopupmenu.h>
#include <qradiobutton.h> #include <qradiobutton.h>
#include <qbuttongroup.h> #include <qbuttongroup.h>
#include <qfiledialog.h>
#else
#include <q3filedialog.h>
#define QFileDialog Q3FileDialog
#endif #endif
#include <qtabwidget.h> #include <qtabwidget.h>
#include <qtimer.h> #include <qtimer.h>
#include <qstatusbar.h> #include <qstatusbar.h>
@ -196,6 +202,8 @@ void RclMain::init()
this, SLOT(enablePrevPage(bool))); this, SLOT(enablePrevPage(bool)));
connect(resList, SIGNAL(docEditClicked(int)), connect(resList, SIGNAL(docEditClicked(int)),
this, SLOT(startNativeViewer(int))); this, SLOT(startNativeViewer(int)));
connect(resList, SIGNAL(docSaveToFileClicked(int)),
this, SLOT(saveDocToFile(int)));
connect(resList, SIGNAL(editRequested(Rcl::Doc)), connect(resList, SIGNAL(editRequested(Rcl::Doc)),
this, SLOT(startNativeViewer(Rcl::Doc))); this, SLOT(startNativeViewer(Rcl::Doc)));
@ -793,6 +801,32 @@ void RclMain::ssearchAddTerm(QString term)
sSearch->queryText->setEditText(text); sSearch->queryText->setEditText(text);
} }
void RclMain::saveDocToFile(int docnum)
{
Rcl::Doc doc;
if (!resList->getDoc(docnum, doc)) {
QMessageBox::warning(0, "Recoll",
tr("Cannot retrieve document info"
" from database"));
return;
}
string fn = urltolocalpath(doc.url);
QString s =
QFileDialog::getSaveFileName(path_home().c_str(),
"", this,
tr("Save file dialog"),
tr("Choose a file name to save under"));
string tofile((const char *)s.toLocal8Bit());
TempFile temp; // not used
if (!FileInterner::idocToFile(temp, tofile, rclconfig, fn,
doc.ipath, doc.mimetype)) {
QMessageBox::warning(0, "Recoll",
tr("Cannot extract document or create "
"temporary file"));
return;
}
}
void RclMain::startNativeViewer(int docnum) void RclMain::startNativeViewer(int docnum)
{ {
Rcl::Doc doc; Rcl::Doc doc;
@ -879,7 +913,7 @@ void RclMain::startNativeViewer(Rcl::Doc doc)
// There is an ipath and the command does not know about // There is an ipath and the command does not know about
// them. We need a temp file. // them. We need a temp file.
TempFile temp; TempFile temp;
if (!FileInterner::idocTempFile(temp, rclconfig, fn, if (!FileInterner::idocToFile(temp, string(), rclconfig, fn,
doc.ipath, doc.mimetype)) { doc.ipath, doc.mimetype)) {
QMessageBox::warning(0, "Recoll", QMessageBox::warning(0, "Recoll",
tr("Cannot extract document or create " tr("Cannot extract document or create "

View File

@ -97,6 +97,7 @@ public slots:
virtual void startPreview(Rcl::Doc doc); virtual void startPreview(Rcl::Doc doc);
virtual void startNativeViewer(int docnum); virtual void startNativeViewer(int docnum);
virtual void startNativeViewer(Rcl::Doc doc); virtual void startNativeViewer(Rcl::Doc doc);
virtual void saveDocToFile(int docnum);
virtual void previewNextInTab(Preview *, int sid, int docnum); virtual void previewNextInTab(Preview *, int sid, int docnum);
virtual void previewPrevInTab(Preview *, int sid, int docnum); virtual void previewPrevInTab(Preview *, int sid, int docnum);
virtual void previewExposed(Preview *, int sid, int docnum); virtual void previewExposed(Preview *, int sid, int docnum);

View File

@ -530,6 +530,11 @@ RCLPOPUP *ResList::createPopupMenu(const QPoint& pos)
popup->insertItem(tr("&Edit"), this, SLOT(menuEdit())); popup->insertItem(tr("&Edit"), this, SLOT(menuEdit()));
popup->insertItem(tr("Copy &File Name"), this, SLOT(menuCopyFN())); popup->insertItem(tr("Copy &File Name"), this, SLOT(menuCopyFN()));
popup->insertItem(tr("Copy &URL"), this, SLOT(menuCopyURL())); 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("Find &similar documents"), this, SLOT(menuExpand())); popup->insertItem(tr("Find &similar documents"), this, SLOT(menuExpand()));
popup->insertItem(tr("P&arent document/folder"), popup->insertItem(tr("P&arent document/folder"),
this, SLOT(menuSeeParent())); this, SLOT(menuSeeParent()));
@ -540,6 +545,10 @@ void ResList::menuPreview()
{ {
emit docPreviewClicked(m_popDoc, 0); emit docPreviewClicked(m_popDoc, 0);
} }
void ResList::menuSaveToFile()
{
emit docSaveToFileClicked(m_popDoc);
}
void ResList::menuSeeParent() void ResList::menuSeeParent()
{ {

View File

@ -90,6 +90,7 @@ class ResList : public QTEXTBROWSER
virtual void resultPageNext(); // Next (or first) page of results virtual void resultPageNext(); // Next (or first) page of results
virtual void displayPage(); // Display current page virtual void displayPage(); // Display current page
virtual void menuPreview(); virtual void menuPreview();
virtual void menuSaveToFile();
virtual void menuEdit(); virtual void menuEdit();
virtual void menuCopyFN(); virtual void menuCopyFN();
virtual void menuCopyURL(); virtual void menuCopyURL();
@ -108,6 +109,7 @@ class ResList : public QTEXTBROWSER
void prevPageAvailable(bool); void prevPageAvailable(bool);
void docEditClicked(int); void docEditClicked(int);
void docPreviewClicked(int, int); void docPreviewClicked(int, int);
void docSaveToFileClicked(int);
void previewRequested(Rcl::Doc); void previewRequested(Rcl::Doc);
void editRequested(Rcl::Doc); void editRequested(Rcl::Doc);
void headerClicked(); void headerClicked();