GUI: show image rather than metadata when previewing an image doc. Metadata still accessible through popup menu

This commit is contained in:
Jean-Francois Dockes 2011-05-09 07:07:46 +02:00
parent 631121e24e
commit 2f6328fb47
6 changed files with 221 additions and 127 deletions

View File

@ -57,7 +57,34 @@ void snapshotConfig()
thestableconfig = new RclConfig(*theconfig); thestableconfig = new RclConfig(*theconfig);
} }
PTMutexInit thetempfileslock;
static vector<TempFile> o_tempfiles;
/* Keep an array of temporary files for deletion at exit. It happens that we
erase some of them before exiting (ie: when closing a preview tab), we don't
reuse the array holes for now */
void rememberTempFile(TempFile temp)
{
PTMutexLocker locker(thetempfileslock);
o_tempfiles.push_back(temp);
}
void forgetTempFile(string &fn)
{
if (fn.empty())
return;
PTMutexLocker locker(thetempfileslock);
for (vector<TempFile>::iterator it = o_tempfiles.begin();
it != o_tempfiles.end(); it++) {
if ((*it).isNotNull() && !fn.compare((*it)->filename())) {
it->release();
}
}
fn.erase();
}
Rcl::Db *rcldb; Rcl::Db *rcldb;
#ifdef RCL_USE_ASPELL #ifdef RCL_USE_ASPELL
Aspell *aspell; Aspell *aspell;
#endif #endif
@ -119,9 +146,14 @@ static void recollCleanup()
deleteZ(rcldb); deleteZ(rcldb);
deleteZ(theconfig); deleteZ(theconfig);
// deleteZ(thestableconfig); // deleteZ(thestableconfig);
PTMutexLocker locker(thetempfileslock);
o_tempfiles.clear();
#ifdef RCL_USE_ASPELL #ifdef RCL_USE_ASPELL
deleteZ(aspell); deleteZ(aspell);
#endif #endif
LOGDEB2(("recollCleanup: done\n")); LOGDEB2(("recollCleanup: done\n"));
} }
@ -322,4 +354,3 @@ int main(int argc, char **argv)
} }
return app.exec(); return app.exec();
} }

View File

@ -33,7 +33,6 @@ using std::pair;
#include <qprinter.h> #include <qprinter.h>
#include <qprintdialog.h> #include <qprintdialog.h>
#include <qscrollbar.h> #include <qscrollbar.h>
#include <qmenu.h> #include <qmenu.h>
#include <qtextedit.h> #include <qtextedit.h>
#include <qprogressdialog.h> #include <qprogressdialog.h>
@ -46,6 +45,8 @@ using std::pair;
#include <qwhatsthis.h> #include <qwhatsthis.h>
#include <qapplication.h> #include <qapplication.h>
#include <qclipboard.h> #include <qclipboard.h>
#include <qimage.h>
#include <qurl.h>
#include "debuglog.h" #include "debuglog.h"
#include "pathut.h" #include "pathut.h"
@ -112,21 +113,6 @@ public:
virtual string startChunk() { return "<pre>";} virtual string startChunk() { return "<pre>";}
}; };
PreviewTextEdit::PreviewTextEdit(QWidget* parent,const char* name, Preview *pv)
: QTextEdit(parent), m_preview(pv), m_dspflds(false)
{
setContextMenuPolicy(Qt::CustomContextMenu);
setObjectName(name);
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
this, SLOT(createPopupMenu(const QPoint&)));
m_plaintorich = new PlainToRichQtPreview();
}
PreviewTextEdit::~PreviewTextEdit()
{
delete m_plaintorich;
}
void Preview::init() void Preview::init()
{ {
setObjectName("Preview"); setObjectName("Preview");
@ -217,6 +203,18 @@ void Preview::closeEvent(QCloseEvent *e)
} }
prefs.pvwidth = width(); prefs.pvwidth = width();
prefs.pvheight = height(); prefs.pvheight = height();
/* Release all temporary files (but maybe none is actually set) */
for (int i = 0; i < pvTab->count(); i++) {
QWidget *tw = pvTab->widget(i);
if (tw) {
PreviewTextEdit *edit =
tw->findChild<PreviewTextEdit*>("pvEdit");
if (edit) {
forgetTempFile(edit->m_tmpfilename);
}
}
}
emit previewExposed(this, m_searchId, -1); emit previewExposed(this, m_searchId, -1);
emit previewClosed(this); emit previewClosed(this);
QWidget::closeEvent(e); QWidget::closeEvent(e);
@ -249,13 +247,13 @@ bool Preview::eventFilter(QObject *target, QEvent *event)
(keyEvent->modifiers() & Qt::ShiftModifier)) { (keyEvent->modifiers() & Qt::ShiftModifier)) {
LOGDEB2(("Preview::eventFilter: got Shift-Up\n")); LOGDEB2(("Preview::eventFilter: got Shift-Up\n"));
if (edit) if (edit)
emit(showNext(this, m_searchId, edit->m_data.docnum)); emit(showNext(this, m_searchId, edit->m_docnum));
return true; return true;
} else if (keyEvent->key() == Qt::Key_Up && } else if (keyEvent->key() == Qt::Key_Up &&
(keyEvent->modifiers() & Qt::ShiftModifier)) { (keyEvent->modifiers() & Qt::ShiftModifier)) {
LOGDEB2(("Preview::eventFilter: got Shift-Down\n")); LOGDEB2(("Preview::eventFilter: got Shift-Down\n"));
if (edit) if (edit)
emit(showPrev(this, m_searchId, edit->m_data.docnum)); emit(showPrev(this, m_searchId, edit->m_docnum));
return true; return true;
} else if (keyEvent->key() == Qt::Key_W && } else if (keyEvent->key() == Qt::Key_W &&
(keyEvent->modifiers() & Qt::ControlModifier)) { (keyEvent->modifiers() & Qt::ControlModifier)) {
@ -459,7 +457,7 @@ void Preview::currentChanged(QWidget * tw)
edit->installEventFilter(this); edit->installEventFilter(this);
edit->viewport()->installEventFilter(this); edit->viewport()->installEventFilter(this);
searchTextLine->installEventFilter(this); searchTextLine->installEventFilter(this);
emit(previewExposed(this, m_searchId, edit->m_data.docnum)); emit(previewExposed(this, m_searchId, edit->m_docnum));
} }
void Preview::closeCurrentTab() void Preview::closeCurrentTab()
@ -469,6 +467,9 @@ void Preview::closeCurrentTab()
CancelCheck::instance().setCancel(); CancelCheck::instance().setCancel();
return; return;
} }
PreviewTextEdit *e = currentEditor();
if (e)
forgetTempFile(e->m_tmpfilename);
if (pvTab->count() > 1) { if (pvTab->count() > 1) {
pvTab->removeTab(pvTab->currentIndex()); pvTab->removeTab(pvTab->currentIndex());
} else { } else {
@ -528,9 +529,9 @@ void Preview::setCurTabProps(const Rcl::Doc &doc, int docnum)
PreviewTextEdit *e = currentEditor(); PreviewTextEdit *e = currentEditor();
if (e) { if (e) {
e->m_data.url = doc.url; e->m_url = doc.url;
e->m_data.ipath = doc.ipath; e->m_ipath = doc.ipath;
e->m_data.docnum = docnum; e->m_docnum = docnum;
} }
} }
@ -549,8 +550,8 @@ bool Preview::makeDocCurrent(const Rcl::Doc& doc, int docnum, bool sametab)
if (tw) { if (tw) {
PreviewTextEdit *edit = PreviewTextEdit *edit =
tw->findChild<PreviewTextEdit*>("pvEdit"); tw->findChild<PreviewTextEdit*>("pvEdit");
if (edit && !edit->m_data.url.compare(doc.url) && if (edit && !edit->m_url.compare(doc.url) &&
!edit->m_data.ipath.compare(doc.ipath)) { !edit->m_ipath.compare(doc.ipath)) {
pvTab->setCurrentIndex(i); pvTab->setCurrentIndex(i);
return true; return true;
} }
@ -586,11 +587,6 @@ void Preview::emitWordSelect(QString word)
threads and we update a progress indicator while they proceed (but we have threads and we update a progress indicator while they proceed (but we have
no estimate of their total duration). no estimate of their total duration).
An auxiliary thread object is used for short waits. Another option would be
to use signals/slots and return to the event-loop instead, but this would
be even more complicated, and we probably don't want the user to click on
things during this time anyway.
It might be possible, but complicated (need modifications in It might be possible, but complicated (need modifications in
handler) to implement a kind of bucket brigade, to have the handler) to implement a kind of bucket brigade, to have the
beginning of the text displayed faster beginning of the text displayed faster
@ -601,11 +597,12 @@ class LoadThread : public QThread {
int *statusp; int *statusp;
Rcl::Doc& out; Rcl::Doc& out;
const Rcl::Doc& idoc; const Rcl::Doc& idoc;
string filename;
TempDir tmpdir; TempDir tmpdir;
int loglevel; int loglevel;
public: public:
string missing; string missing;
TempFile imgtmp;
LoadThread(int *stp, Rcl::Doc& odoc, const Rcl::Doc& idc) LoadThread(int *stp, Rcl::Doc& odoc, const Rcl::Doc& idc)
: statusp(stp), out(odoc), idoc(idc) : statusp(stp), out(odoc), idoc(idc)
{ {
@ -624,8 +621,6 @@ class LoadThread : public QThread {
return; return;
} }
// QMessageBox::critical(0, "Recoll", Preview::tr("File does not exist"));
FileInterner interner(idoc, theconfig, tmpdir, FileInterner interner(idoc, theconfig, tmpdir,
FileInterner::FIF_forPreview); FileInterner::FIF_forPreview);
FIMissingStore mst; FIMissingStore mst;
@ -651,6 +646,7 @@ class LoadThread : public QThread {
out.text = interner.get_html(); out.text = interner.get_html();
out.mimetype = "text/html"; out.mimetype = "text/html";
} }
imgtmp = interner.get_imgtmp();
} else { } else {
out.mimetype = interner.getMimetype(); out.mimetype = interner.getMimetype();
interner.getMissingExternal(&mst, missing); interner.getMissingExternal(&mst, missing);
@ -692,16 +688,6 @@ class ToRichThread : public QThread {
} }
}; };
/* A thread to implement short waiting. There must be a better way ! */
class WaiterThread : public QThread {
int ms;
public:
WaiterThread(int millis) : ms(millis) {}
virtual void run() {
msleep(ms);
}
};
class LoadGuard { class LoadGuard {
bool *m_bp; bool *m_bp;
public: public:
@ -728,8 +714,8 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
const int nsteps = 20; const int nsteps = 20;
QProgressDialog progress(msg, tr("Cancel"), 0, nsteps, this); QProgressDialog progress(msg, tr("Cancel"), 0, nsteps, this);
progress.setMinimumDuration(2000); progress.setMinimumDuration(2000);
WaiterThread waiter(100);
////////////////////////////////////////////////////////////////////////
// Load and convert document // Load and convert document
// idoc came out of the index data (main text and other fields missing). // idoc came out of the index data (main text and other fields missing).
// foc is the complete one what we are going to extract from storage. // foc is the complete one what we are going to extract from storage.
@ -739,9 +725,7 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
lthr.start(); lthr.start();
int prog; int prog;
for (prog = 1;;prog++) { for (prog = 1;;prog++) {
waiter.start(); if (lthr.wait(100))
waiter.wait();
if (lthr.isFinished())
break; break;
progress.setValue(prog); progress.setValue(prog);
qApp->processEvents(); qApp->processEvents();
@ -774,6 +758,7 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
// Reset config just in case. // Reset config just in case.
theconfig->setKeyDir(""); theconfig->setKeyDir("");
////////////////////////////////////////////////////////////////////////
// Create preview text: highlight search terms // Create preview text: highlight search terms
// We don't do the highlighting for very big texts: too long. We // We don't do the highlighting for very big texts: too long. We
// should at least do special char escaping, in case a '&' or '<' // should at least do special char escaping, in case a '&' or '<'
@ -786,7 +771,7 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
list<QString> qrichlst; list<QString> qrichlst;
PreviewTextEdit *editor = currentEditor(); PreviewTextEdit *editor = currentEditor();
editor->setHtml(""); editor->setHtml("");
editor->m_data.format = Qt::RichText; editor->m_format = Qt::RichText;
bool inputishtml = !fdoc.mimetype.compare("text/html"); bool inputishtml = !fdoc.mimetype.compare("text/html");
#if 0 #if 0
@ -817,8 +802,7 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
rthr.start(); rthr.start();
for (;;prog++) { for (;;prog++) {
waiter.start(); waiter.wait(); if (rthr.wait(100))
if (rthr.isFinished())
break; break;
progress.setValue(nsteps); progress.setValue(nsteps);
qApp->processEvents(); qApp->processEvents();
@ -832,7 +816,7 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
// Conversion to rich text done // Conversion to rich text done
if (CancelCheck::instance().cancelState()) { if (CancelCheck::instance().cancelState()) {
if (richlst.size() == 0 || richlst.front().length() == 0) { if (richlst.size() == 0 || richlst.front().length() == 0) {
// We cant call closeCurrentTab here as it might delete // We can't call closeCurrentTab here as it might delete
// the object which would be a nasty surprise to our // the object which would be a nasty surprise to our
// caller. // caller.
return false; return false;
@ -860,7 +844,7 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
qrichlst.push_back(qr); qrichlst.push_back(qr);
} else { } else {
editor->setPlainText(""); editor->setPlainText("");
editor->m_data.format = Qt::PlainText; editor->m_format = Qt::PlainText;
for (int pos = 0; pos < (int)qr.length(); pos += l) { for (int pos = 0; pos < (int)qr.length(); pos += l) {
l = MIN(CHUNKL, qr.length() - pos); l = MIN(CHUNKL, qr.length() - pos);
qrichlst.push_back(qr.mid(pos, l)); qrichlst.push_back(qr.mid(pos, l));
@ -869,6 +853,10 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
} }
#endif #endif
///////////////////////////////////////////////////////////
// Load text into editor window.
prog = 2 * nsteps / 3; prog = 2 * nsteps / 3;
progress.setLabelText(tr("Loading preview text into editor")); progress.setLabelText(tr("Loading preview text into editor"));
qApp->processEvents(); qApp->processEvents();
@ -881,7 +869,7 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
editor->append(*it); editor->append(*it);
// We need to save the rich text for printing, the editor does // We need to save the rich text for printing, the editor does
// not do it consistently for us. // not do it consistently for us.
editor->m_data.richtxt.append(*it); editor->m_richtxt.append(*it);
if (progress.wasCanceled()) { if (progress.wasCanceled()) {
editor->append("<b>Cancelled !</b>"); editor->append("<b>Cancelled !</b>");
@ -891,16 +879,54 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
} }
progress.close(); progress.close();
editor->m_curdsp = PreviewTextEdit::PTE_DSPTXT;
////////////////////////////////////////////////////////////////////////
// Finishing steps
// Maybe the text was actually empty ? Switch to fields then. Else free-up // Maybe the text was actually empty ? Switch to fields then. Else free-up
// the text memory. // the text memory in the loaded document. We still have a copy of the text
// in editor->m_richtxt
bool textempty = fdoc.text.empty(); bool textempty = fdoc.text.empty();
if (!textempty) if (!textempty)
fdoc.text.clear(); fdoc.text.clear();
editor->m_data.fdoc = fdoc; editor->m_fdoc = fdoc;
if (textempty) if (textempty)
editor->toggleFields(); editor->displayFields();
// If this is an image, display it instead of the text.
if (!idoc.mimetype.compare(0, 6, "image/")) {
string fn = fileurltolocalpath(idoc.url);
// If the command wants a file but this is not a file url, or
// there is an ipath that it won't understand, we need a temp file:
theconfig->setKeyDir(path_getfather(fn));
if (fn.empty() || !idoc.ipath.empty()) {
TempFile temp = lthr.imgtmp;
if (temp.isNotNull()) {
LOGDEB1(("Preview: load: got temp file from internfile\n"));
} else if (!FileInterner::idocToFile(temp, string(),
theconfig, idoc)) {
temp.release(); // just in case.
}
if (temp.isNotNull()) {
rememberTempFile(temp);
fn = temp->filename();
editor->m_tmpfilename = fn;
} else {
editor->m_tmpfilename.erase();
fn.erase();
}
}
if (!fn.empty()) {
editor->m_image = QImage(fn.c_str());
editor->displayImage();
}
}
// Position the editor so that the first search term is visible
m_haveAnchors = editor->m_plaintorich->lastanchor != 0; m_haveAnchors = editor->m_plaintorich->lastanchor != 0;
if (searchTextLine->text().length() != 0) { if (searchTextLine->text().length() != 0) {
// If there is a current search string, perform the search // If there is a current search string, perform the search
@ -921,6 +947,7 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
} }
} }
// Enter document in document history // Enter document in document history
map<string,string>::const_iterator udit = idoc.meta.find(Rcl::Doc::keyudi); map<string,string>::const_iterator udit = idoc.meta.find(Rcl::Doc::keyudi);
if (udit != idoc.meta.end()) if (udit != idoc.meta.end())
@ -932,50 +959,98 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
return true; return true;
} }
PreviewTextEdit::PreviewTextEdit(QWidget* parent,const char* name, Preview *pv)
: QTextEdit(parent), m_preview(pv), m_dspflds(false), m_docnum(-1)
{
setContextMenuPolicy(Qt::CustomContextMenu);
setObjectName(name);
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
this, SLOT(createPopupMenu(const QPoint&)));
m_plaintorich = new PlainToRichQtPreview();
}
PreviewTextEdit::~PreviewTextEdit()
{
delete m_plaintorich;
}
void PreviewTextEdit::createPopupMenu(const QPoint& pos) void PreviewTextEdit::createPopupMenu(const QPoint& pos)
{ {
LOGDEB1(("PreviewTextEdit::createPopupMenu()\n")); LOGDEB1(("PreviewTextEdit::createPopupMenu()\n"));
QMenu *popup = new QMenu(this); QMenu *popup = new QMenu(this);
if (!m_dspflds) { switch (m_curdsp) {
popup->addAction(tr("Show fields"), this, SLOT(toggleFields())); case PTE_DSPTXT:
} else { popup->addAction(tr("Show fields"), this, SLOT(displayFields()));
popup->addAction(tr("Show main text"), this, SLOT(toggleFields())); if (!m_image.isNull())
popup->addAction(tr("Show image"), this, SLOT(displayImage()));
break;
case PTE_DSPFLDS:
popup->addAction(tr("Show main text"), this, SLOT(displayText()));
if (!m_image.isNull())
popup->addAction(tr("Show image"), this, SLOT(displayImage()));
break;
case PTE_DSPIMG:
default:
popup->addAction(tr("Show fields"), this, SLOT(displayFields()));
popup->addAction(tr("Show main text"), this, SLOT(displayText()));
break;
} }
popup->addAction(tr("Select All"), this, SLOT(selectAll()));
popup->addAction(tr("Copy"), this, SLOT(copy()));
popup->addAction(tr("Print"), this, SLOT(print())); popup->addAction(tr("Print"), this, SLOT(print()));
popup->popup(mapToGlobal(pos)); popup->popup(mapToGlobal(pos));
} }
// Either display document fields or main text // Display main text
void PreviewTextEdit::toggleFields() void PreviewTextEdit::displayText()
{ {
LOGDEB1(("PreviewTextEdit::toggleFields()\n")); LOGDEB1(("PreviewTextEdit::displayText()\n"));
if (m_format == Qt::PlainText)
setPlainText(m_richtxt);
else
setHtml(m_richtxt);
m_curdsp = PTE_DSPTXT;
}
// If currently displaying fields, switch to body text // Display field values
if (m_dspflds) { void PreviewTextEdit::displayFields()
if (m_data.format == Qt::PlainText) {
setPlainText(m_data.richtxt); LOGDEB1(("PreviewTextEdit::displayFields()\n"));
else
setHtml(m_data.richtxt);
m_dspflds = false;
return;
}
// Else display fields
m_dspflds = true;
QString txt = "<html><head></head><body>\n"; QString txt = "<html><head></head><body>\n";
txt += "<b>" + QString::fromLocal8Bit(m_data.url.c_str()); txt += "<b>" + QString::fromLocal8Bit(m_url.c_str());
if (!m_data.ipath.empty()) if (!m_ipath.empty())
txt += "|" + QString::fromUtf8(m_data.ipath.c_str()); txt += "|" + QString::fromUtf8(m_ipath.c_str());
txt += "</b><br><br>"; txt += "</b><br><br>";
txt += "<dl>\n"; txt += "<dl>\n";
for (map<string,string>::const_iterator it = m_data.fdoc.meta.begin(); for (map<string,string>::const_iterator it = m_fdoc.meta.begin();
it != m_data.fdoc.meta.end(); it++) { it != m_fdoc.meta.end(); it++) {
txt += "<dt>" + QString::fromUtf8(it->first.c_str()) + "</dt> " if (!it->second.empty())
+ "<dd>" + QString::fromUtf8(escapeHtml(it->second).c_str()) txt += "<dt>" + QString::fromUtf8(it->first.c_str()) + "</dt> "
+ "</dd>\n"; + "<dd>" + QString::fromUtf8(escapeHtml(it->second).c_str())
+ "</dd>\n";
} }
txt += "</dl></body></html>"; txt += "</dl></body></html>";
setHtml(txt); setHtml(txt);
m_curdsp = PTE_DSPFLDS;
}
void PreviewTextEdit::displayImage()
{
LOGDEB1(("PreviewTextEdit::displayImage()\n"));
if (m_image.isNull())
displayText();
setPlainText("");
if (m_image.width() > width() ||
m_image.height() > height()) {
m_image = m_image.scaled(width(), height(), Qt::KeepAspectRatio);
}
document()->addResource(QTextDocument::ImageResource, QUrl("image"),
m_image);
QTextCursor cursor = textCursor();
cursor.insertImage("image");
m_curdsp = PTE_DSPIMG;
} }
void PreviewTextEdit::mouseDoubleClickEvent(QMouseEvent *event) void PreviewTextEdit::mouseDoubleClickEvent(QMouseEvent *event)

View File

@ -22,49 +22,33 @@
#include <qvariant.h> #include <qvariant.h>
#include <qwidget.h> #include <qwidget.h>
#include <qtextedit.h> #include <qtextedit.h>
#include <qimage.h>
#include "rcldb.h" #include "rcldb.h"
#include "refcntr.h" #include "refcntr.h"
#include "plaintorich.h" #include "plaintorich.h"
#include "rclmain_w.h"
class QTabWidget; class QTabWidget;
class QLabel; class QLabel;
class QLineEdit; class QLineEdit;
class QPushButton; class QPushButton;
class QCheckBox; class QCheckBox;
class PreviewTextEdit;
class Preview;
// We keep a list of data associated to each tab
class TabData {
public:
string url; // filename for this tab
string ipath; // Internal doc path inside file
int docnum; // Index of doc in db search results.
// doc out of internfile (previous fields come from the index) with
// main text erased (for space).
Rcl::Doc fdoc;
// Saved rich (or plain actually) text: the textedit seems to
// sometimes (but not always) return its text stripped of tags, so
// this is needed (for printing for example)
QString richtxt;
Qt::TextFormat format;
TabData()
: docnum(-1)
{}
};
class Preview; class Preview;
class PlainToRichQtPreview; class PlainToRichQtPreview;
class PreviewTextEdit : public QTextEdit { class PreviewTextEdit : public QTextEdit {
Q_OBJECT Q_OBJECT;
public: public:
PreviewTextEdit(QWidget* parent, const char* name, Preview *pv); PreviewTextEdit(QWidget* parent, const char* name, Preview *pv);
virtual ~PreviewTextEdit(); virtual ~PreviewTextEdit();
void moveToAnchor(const QString& name); void moveToAnchor(const QString& name);
enum DspType {PTE_DSPTXT, PTE_DSPFLDS, PTE_DSPIMG};
public slots: public slots:
virtual void toggleFields(); virtual void displayFields();
virtual void displayText();
virtual void displayImage();
virtual void print(); virtual void print();
virtual void createPopupMenu(const QPoint& pos); virtual void createPopupMenu(const QPoint& pos);
friend class Preview; friend class Preview;
@ -74,8 +58,25 @@ protected:
private: private:
PlainToRichQtPreview *m_plaintorich; PlainToRichQtPreview *m_plaintorich;
Preview *m_preview; Preview *m_preview;
TabData m_data;
bool m_dspflds; bool m_dspflds;
string m_url; // filename for this tab
string m_ipath; // Internal doc path inside file
int m_docnum; // Index of doc in db search results.
// doc out of internfile (previous fields come from the index) with
// main text erased (for space).
Rcl::Doc m_fdoc;
// Saved rich (or plain actually) text: the textedit seems to
// sometimes (but not always) return its text stripped of tags, so
// this is needed (for printing for example)
QString m_richtxt;
Qt::TextFormat m_format;
// Temporary file name (possibly, if displaying image). The
// TempFile itself is kept inside main.cpp (because that's where
// signal cleanup happens), but we use its name to ask for release
// when the tab is closed.
string m_tmpfilename;
QImage m_image;
DspType m_curdsp;
}; };

View File

@ -475,7 +475,6 @@ bool RclMain::close()
void RclMain::fileExit() void RclMain::fileExit()
{ {
LOGDEB(("RclMain: fileExit\n")); LOGDEB(("RclMain: fileExit\n"));
m_tempfiles.clear();
// Don't save geometry if we're currently fullscreened // Don't save geometry if we're currently fullscreened
if (!isFullScreen()) { if (!isFullScreen()) {
prefs.mainwidth = width(); prefs.mainwidth = width();
@ -996,7 +995,7 @@ void RclMain::saveDocToFile(Rcl::Doc doc)
QString::fromLocal8Bit(path_home().c_str()) QString::fromLocal8Bit(path_home().c_str())
); );
string tofile((const char *)s.toLocal8Bit()); string tofile((const char *)s.toLocal8Bit());
TempFile temp; // not used TempFile temp; // not used because tofile is set.
if (!FileInterner::idocToFile(temp, tofile, theconfig, doc)) { if (!FileInterner::idocToFile(temp, tofile, theconfig, doc)) {
QMessageBox::warning(0, "Recoll", QMessageBox::warning(0, "Recoll",
tr("Cannot extract document or create " tr("Cannot extract document or create "
@ -1028,20 +1027,6 @@ static bool lookForHtmlBrowser(string &exefile)
return false; return false;
} }
// Convert to file path if url is like file://
static string fileurltolocalpath(string url)
{
if (url.find("file://") == 0)
url = url.substr(7, string::npos);
else
return string();
string::size_type pos;
if ((pos = url.find_last_of("#")) != string::npos) {
url.erase(pos);
}
return url;
}
void RclMain::startNativeViewer(Rcl::Doc doc) void RclMain::startNativeViewer(Rcl::Doc doc)
{ {
// Look for appropriate viewer // Look for appropriate viewer
@ -1151,7 +1136,7 @@ void RclMain::startNativeViewer(Rcl::Doc doc)
return; return;
} }
istempfile = true; istempfile = true;
m_tempfiles.push_back(temp); rememberTempFile(temp);
fn = temp->filename(); fn = temp->filename();
url = string("file://") + fn; url = string("file://") + fn;
} }
@ -1176,7 +1161,7 @@ void RclMain::startNativeViewer(Rcl::Doc doc)
} }
} }
if (!temp.isNull()) { if (!temp.isNull()) {
m_tempfiles.push_back(temp); rememberTempFile(temp);
fn = temp->filename(); fn = temp->filename();
url = string("file://") + fn; url = string("file://") + fn;
} }

View File

@ -19,6 +19,7 @@
#include <qvariant.h> #include <qvariant.h>
#include <qmainwindow.h> #include <qmainwindow.h>
#include "sortseq.h" #include "sortseq.h"
#include "preview_w.h" #include "preview_w.h"
#include "recoll.h" #include "recoll.h"
@ -122,7 +123,6 @@ private:
QTimer *periodictimer; QTimer *periodictimer;
ResTable *restable; ResTable *restable;
vector<TempFile> m_tempfiles;
vector<ExecCmd*> m_viewers; vector<ExecCmd*> m_viewers;
map<QString, QAction*> m_stemLangToId; map<QString, QAction*> m_stemLangToId;
vector<string> m_catgbutvec; vector<string> m_catgbutvec;

View File

@ -36,6 +36,8 @@ extern RclConfig *theconfig;
extern RclConfig *thestableconfig; extern RclConfig *thestableconfig;
extern PTMutexInit thestableconfiglock; extern PTMutexInit thestableconfiglock;
extern void snapshotConfig(); extern void snapshotConfig();
extern void rememberTempFile(TempFile);
extern void forgetTempFile(string &fn);
extern Rcl::Db *rcldb; extern Rcl::Db *rcldb;
extern int recollNeedsExit; extern int recollNeedsExit;