GUI: Experimental: create a list of MIME types (compiled in for now: hwp) for which we prefer to use stored text for preview because extraction is slow

This commit is contained in:
Jean-Francois Dockes 2020-03-25 18:13:00 +01:00
parent ac5ff471f2
commit b677171fa8
7 changed files with 132 additions and 95 deletions

View File

@ -126,7 +126,7 @@ bool TextSplit::ko_to_words(Utf8Iter *itp, unsigned int *cp)
c = *it; c = *it;
if (!isHANGUL(c) && isalpha(c)) { if (!isHANGUL(c) && isalpha(c)) {
// Done with Korean stretch, process and go back to main routine // Done with Korean stretch, process and go back to main routine
std::cerr << "Broke on char " << (std::string)it << endl; //std::cerr << "Broke on char " << (std::string)it << endl;
break; break;
} else { } else {
it.appendchartostring(inputdata); it.appendchartostring(inputdata);

View File

@ -20,6 +20,7 @@
#include <string> #include <string>
#include <list> #include <list>
#include <vector> #include <vector>
#include <set>
#include <qstring.h> #include <qstring.h>
#include <qstringlist.h> #include <qstringlist.h>
@ -154,6 +155,11 @@ class PrefsPack {
std::string stemlang(); std::string stemlang();
// MIME types for which we prefer to use stored text from preview
// rather than extracting the possibly nicer HTML because the
// extractor is very slow. This is compiled in and there is no UI
// for now.
std::set<std::string> preferStoredTextMimes{"application/x-hwp"};
}; };
/** Global preferences record */ /** Global preferences record */

View File

@ -574,6 +574,90 @@ void Preview::emitWordSelect(QString word)
emit(wordSelect(word)); emit(wordSelect(word));
} }
// Display message dialog after load failed
void Preview::displayLoadError(
FileInterner::ErrorPossibleCause explain, bool canGetRawText)
{
// Note that we can't easily check for a readable file
// because it's possible that only a region is locked
// (e.g. on Windows for an ost file the first block is
// readable even if Outlook is running).
QString msg;
switch (explain) {
case FileInterner::FetchMissing:
msg = tr("Error loading the document: file missing.");
break;
case FileInterner::FetchPerm:
msg = tr("Error loading the document: no permission.");
break;
case FileInterner::FetchNoBackend:
msg =
tr("Error loading: backend not configured.");
break;
case FileInterner::InternfileOther:
#ifdef _WIN32
msg = tr("Error loading the document: "
"other handler error<br>"
"Maybe the application is locking the file ?");
#else
msg = tr("Error loading the document: other handler error.");
#endif
break;
}
if (canGetRawText) {
msg += tr("<br>Attempting to display from stored text.");
}
QMessageBox::warning(0, "Recoll", msg);
}
bool Preview::runLoadThread(LoadThread& lthr, QTimer& tT, QEventLoop& loop,
QProgressDialog& progress, bool canGetRawText)
{
lthr.start();
for (int i = 0;;i++) {
tT.start(1000);
loop.exec();
if (lthr.isFinished())
break;
if (progress.wasCanceled()) {
CancelCheck::instance().setCancel();
}
if (i == 1)
progress.show();
}
LOGDEB("loadDocInCurrentTab: after file load: cancel " <<
CancelCheck::instance().cancelState() << " status " << lthr.status <<
" text length " << lthr.fdoc.text.length() << "\n");
if (lthr.status == 0) {
return true;
}
if (CancelCheck::instance().cancelState())
return false;
QString explain;
if (!lthr.missing.empty()) {
explain = QString::fromUtf8("<br>") +
tr("Missing helper program: ") +
QString::fromLocal8Bit(lthr.missing.c_str());
QMessageBox::warning(0, "Recoll",
tr("Can't turn doc into internal "
"representation for ") +
lthr.fdoc.mimetype.c_str() + explain);
} else {
if (progress.wasCanceled()) {
QMessageBox::warning(0, "Recoll", tr("Canceled"));
} else {
progress.reset();
displayLoadError(lthr.explain, canGetRawText);
}
}
return false;
}
/* /*
Code for loading a file into an editor window. The operations that Code for loading a file into an editor window. The operations that
we call have no provision to indicate progression, and it would be we call have no provision to indicate progression, and it would be
@ -627,93 +711,42 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
connect(&tT, SIGNAL(timeout()), &loop, SLOT(quit())); connect(&tT, SIGNAL(timeout()), &loop, SLOT(quit()));
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Load and convert document // Load and convert document
// idoc came out of the index data (main text and some fields missing). // - idoc came out of the index data (main text and some fields missing).
// fdoc is the complete one what we are going to extract from storage. // - fdoc is the complete one what we are going to extract from storage.
//
// If the preference to use the stored text is set, we still
// create the LoadThread object for convenience (using its fdoc
// field, but don't start it.
LoadThread lthr(theconfig, idoc, prefs.previewHtml, this); LoadThread lthr(theconfig, idoc, prefs.previewHtml, this);
connect(&lthr, SIGNAL(finished()), &loop, SLOT(quit())); connect(&lthr, SIGNAL(finished()), &loop, SLOT(quit()));
lthr.start(); bool canGetRawText = rcldb && rcldb->storesDocText();
for (int i = 0;;i++) { auto it = prefs.preferStoredTextMimes.find(idoc.mimetype);
tT.start(1000); bool preferStoredText = (it != prefs.preferStoredTextMimes.end());
loop.exec(); bool loadok{false};
if (lthr.isFinished())
break; if (!preferStoredText || !canGetRawText) {
if (progress.wasCanceled()) { // Try load from actual document
CancelCheck::instance().setCancel(); loadok = runLoadThread(lthr, tT, loop, progress, canGetRawText);
}
if (!loadok && canGetRawText) {
// Preferring/able to use stored text or extern load failed
lthr.fdoc = idoc;
loadok = rcldb->getDocRawText(lthr.fdoc);
if (!loadok) {
QMessageBox::warning(0,"Recoll",tr("Could not fetch stored text"));
} }
if (i == 1)
progress.show();
} }
LOGDEB("loadDocInCurrentTab: after file load: cancel " << if (!loadok) {
CancelCheck::instance().cancelState() << " status " << lthr.status << // Everything failed.
" text length " << lthr.fdoc.text.length() << "\n"); progress.close();
if (CancelCheck::instance().cancelState())
return false; return false;
if (lthr.status != 0) {
bool canGetRawText = rcldb && rcldb->storesDocText();
QString explain;
if (!lthr.missing.empty()) {
explain = QString::fromUtf8("<br>") +
tr("Missing helper program: ") +
QString::fromLocal8Bit(lthr.missing.c_str());
QMessageBox::warning(0, "Recoll",
tr("Can't turn doc into internal "
"representation for ") +
lthr.fdoc.mimetype.c_str() + explain);
} else {
if (progress.wasCanceled()) {
QMessageBox::warning(0, "Recoll", tr("Canceled"));
} else {
progress.reset();
// Note that we can't easily check for a readable file
// because it's possible that only a region is locked
// (e.g. on Windows for an ost file the first block is
// readable even if Outlook is running).
QString msg;
switch (lthr.explain) {
case FileInterner::FetchMissing:
msg = tr("Error loading the document: file missing.");
break;
case FileInterner::FetchPerm:
msg = tr("Error loading the document: no permission.");
break;
case FileInterner::FetchNoBackend:
msg =
tr("Error loading: backend not configured.");
break;
case FileInterner::InternfileOther:
#ifdef _WIN32
msg = tr("Error loading the document: "
"other handler error<br>"
"Maybe the application is locking the file ?");
#else
msg = tr("Error loading the document: other handler error.");
#endif
break;
}
if (canGetRawText) {
msg += tr("<br>Attempting to display from stored text.");
}
QMessageBox::warning(0, "Recoll", msg);
}
}
if (canGetRawText) {
lthr.fdoc = idoc;
if (!rcldb->getDocRawText(lthr.fdoc)) {
QMessageBox::warning(0, "Recoll",
tr("Could not fetch stored text"));
progress.close();
return false;
}
} else {
progress.close();
}
} }
// Reset config just in case. // Reset config just in case.
theconfig->setKeyDir(""); theconfig->setKeyDir("");
@ -722,8 +755,8 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
// 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 '<'
// somehow slipped through previous processing. // somehow slipped through previous processing.
bool highlightTerms = lthr.fdoc.text.length() < bool highlightTerms = int(lthr.fdoc.text.length()) <
(unsigned long)prefs.maxhltextmbs * 1024 * 1024; prefs.maxhltextkbs * 1024;
// Final text is produced in chunks so that we can display the top // Final text is produced in chunks so that we can display the top
// while still inserting at bottom // while still inserting at bottom
@ -752,7 +785,6 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
QStringList qrichlst; QStringList qrichlst;
editor->m_plaintorich->set_activatelinks(prefs.previewActiveLinks); editor->m_plaintorich->set_activatelinks(prefs.previewActiveLinks);
#if 1
if (highlightTerms) { if (highlightTerms) {
progress.setLabelText(tr("Creating preview text")); progress.setLabelText(tr("Creating preview text"));
qApp->processEvents(); qApp->processEvents();
@ -815,17 +847,6 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
} }
} }
} }
#else // For testing qtextedit bugs...
highlightTerms = true;
const char *textlist[] =
{
"Du plain text avec un\n <termtag>termtag</termtag> fin de ligne:",
"texte apres le tag\n",
};
const int listl = sizeof(textlist) / sizeof(char*);
for (int i = 0 ; i < listl ; i++)
qrichlst.push_back(QString::fromUtf8(textlist[i]));
#endif
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////

View File

@ -44,9 +44,11 @@
#include "rcldb.h" #include "rcldb.h"
#include "plaintorich.h" #include "plaintorich.h"
#include "rclmain_w.h" #include "rclmain_w.h"
#include "internfile.h"
#include "ui_preview.h" #include "ui_preview.h"
class QTabWidget; class QTabWidget;
class QLabel; class QLabel;
class QPushButton; class QPushButton;
@ -55,6 +57,10 @@ class Preview;
class PlainToRichQtPreview; class PlainToRichQtPreview;
class QUrl; class QUrl;
class RclMain; class RclMain;
class LoadThread;
class QTimer;
class QEventLoop;
class QProgressDialog;
class PreviewTextEdit : public PREVIEW_PARENTCLASS { class PreviewTextEdit : public PREVIEW_PARENTCLASS {
Q_OBJECT; Q_OBJECT;
@ -185,6 +191,10 @@ private:
virtual PreviewTextEdit *currentEditor(); virtual PreviewTextEdit *currentEditor();
virtual PreviewTextEdit *addEditorTab(); virtual PreviewTextEdit *addEditorTab();
virtual bool loadDocInCurrentTab(const Rcl::Doc& idoc, int dnm); virtual bool loadDocInCurrentTab(const Rcl::Doc& idoc, int dnm);
void displayLoadError(
FileInterner::ErrorPossibleCause explain, bool canGetRawText);
bool runLoadThread(LoadThread& lthr, QTimer& tT, QEventLoop& loop,
QProgressDialog& progress, bool canGetRawText);
}; };
#endif /* _PREVIEW_W_H_INCLUDED_ */ #endif /* _PREVIEW_W_H_INCLUDED_ */

View File

@ -166,7 +166,7 @@ i18n/recoll_zh_CN.ts \
i18n/recoll_fr.ts \ i18n/recoll_fr.ts \
i18n/recoll_xx.ts \ i18n/recoll_xx.ts \
i18n/recoll_cs.ts \ i18n/recoll_cs.ts \
i18n/recoll_kr.ts \ i18n/recoll_ko.ts \
i18n/recoll_el.ts \ i18n/recoll_el.ts \
i18n/recoll_tr.ts i18n/recoll_tr.ts