add option to have clickable links inside the preview windows

This commit is contained in:
Jean-Francois Dockes 2018-04-16 10:47:52 +02:00
parent 2be261e00b
commit 2176d81e60
10 changed files with 166 additions and 148 deletions

View File

@ -2834,17 +2834,23 @@
version instead. </para> version instead. </para>
</listitem> </listitem>
<listitem><para><guilabel>Plain text to HTML line style</guilabel>: <listitem><para><guilabel>Activate links in
when displaying plain text inside the preview window, &RCL; preview</guilabel> if set, Recoll will turn HTTP links found
tries to preserve some of the original text line breaks and inside plain text into proper HTML anchors, and clicking a
indentation. It can either use PRE HTML tags, which will link inside a preview window will start the default browser
well preserve the indentation but will force horizontal on the link target.</para> </listitem>
scrolling for long lines, or use BR tags to break at the
original line breaks, which will let the editor introduce <listitem><para><guilabel>Plain text to HTML line
other line breaks according to the window width, but will style</guilabel>: when displaying plain text inside the
lose some of the original indentation. The third option has preview window, &RCL; tries to preserve some of the original
been available in recent releases and is probably now the best text line breaks and indentation. It can either use PRE HTML
one: use PRE tags with line wrapping.</para> tags, which will well preserve the indentation but will force
horizontal scrolling for long lines, or use BR tags to break
at the original line breaks, which will let the editor
introduce other line breaks according to the window width,
but will lose some of the original indentation. The third
option has been available in recent releases and is probably
now the best one: use PRE tags with line wrapping.</para>
</listitem> </listitem>
<listitem><para><guilabel>Choose editor <listitem><para><guilabel>Choose editor

View File

@ -88,6 +88,8 @@ void rwSettings(bool writing)
SETTING_RW(prefs.startWithAdvSearchOpen, SETTING_RW(prefs.startWithAdvSearchOpen,
"/Recoll/prefs/startWithAdvSearchOpen", Bool, false); "/Recoll/prefs/startWithAdvSearchOpen", Bool, false);
SETTING_RW(prefs.previewHtml, "/Recoll/prefs/previewHtml", Bool, true); SETTING_RW(prefs.previewHtml, "/Recoll/prefs/previewHtml", Bool, true);
SETTING_RW(prefs.previewActiveLinks,
"/Recoll/prefs/previewActiveLinks", Bool, false);
QString advSearchClauses; QString advSearchClauses;
const int maxclauselistsize = 20; const int maxclauselistsize = 20;

View File

@ -90,6 +90,7 @@ class PrefsPack {
bool startWithAdvSearchOpen; bool startWithAdvSearchOpen;
// Try to display html if it exists in the internfile stack. // Try to display html if it exists in the internfile stack.
bool previewHtml; bool previewHtml;
bool previewActiveLinks;
// Use <pre> tag to display highlighted text/plain inside html (else // Use <pre> tag to display highlighted text/plain inside html (else
// we use <br> at end of lines, which lets textedit wrap lines). // we use <br> at end of lines, which lets textedit wrap lines).
enum PlainPre {PP_BR, PP_PRE, PP_PREWRAP}; enum PlainPre {PP_BR, PP_PRE, PP_PREWRAP};

View File

@ -59,6 +59,7 @@
#include "rclhelp.h" #include "rclhelp.h"
#include "preview_load.h" #include "preview_load.h"
#include "preview_plaintorich.h" #include "preview_plaintorich.h"
#include "rclmain_w.h"
static const QKeySequence closeKS(Qt::Key_Escape); static const QKeySequence closeKS(Qt::Key_Escape);
static const QKeySequence nextDocInTabKS(Qt::ShiftModifier+Qt::Key_Down); static const QKeySequence nextDocInTabKS(Qt::ShiftModifier+Qt::Key_Down);
@ -163,14 +164,10 @@ void Preview::init()
connect(new QShortcut(printTabKS, this), SIGNAL (activated()), connect(new QShortcut(printTabKS, this), SIGNAL (activated()),
this, SIGNAL (printCurrentPreviewRequest())); this, SIGNAL (printCurrentPreviewRequest()));
m_dynSearchActive = false;
m_canBeep = true;
if (prefs.pvwidth > 100) { if (prefs.pvwidth > 100) {
resize(prefs.pvwidth, prefs.pvheight); resize(prefs.pvwidth, prefs.pvheight);
} }
m_loading = false;
currentChanged(pvTab->currentIndex()); currentChanged(pvTab->currentIndex());
m_justCreated = true;
} }
void Preview::emitShowNext() void Preview::emitShowNext()
@ -195,7 +192,7 @@ void Preview::emitShowPrev()
void Preview::closeEvent(QCloseEvent *e) void Preview::closeEvent(QCloseEvent *e)
{ {
LOGDEB("Preview::closeEvent. m_loading " << (m_loading) << "\n" ); LOGDEB("Preview::closeEvent. m_loading " << m_loading << "\n");
if (m_loading) { if (m_loading) {
CancelCheck::instance().setCancel(); CancelCheck::instance().setCancel();
e->ignore(); e->ignore();
@ -226,10 +223,12 @@ bool Preview::eventFilter(QObject *target, QEvent *event)
{ {
if (event->type() != QEvent::KeyPress) { if (event->type() != QEvent::KeyPress) {
#if 0 #if 0
LOGDEB("Preview::eventFilter(): " << (eventTypeToStr(event->type())) << "\n" ); LOGDEB("Preview::eventFilter(): " << eventTypeToStr(event->type()) <<
"\n");
if (event->type() == QEvent::MouseButtonRelease) { if (event->type() == QEvent::MouseButtonRelease) {
QMouseEvent *mev = (QMouseEvent *)event; QMouseEvent *mev = (QMouseEvent *)event;
LOGDEB("Mouse: GlobalY " << (mev->globalY()) << " y " << (mev->y()) << "\n" ); LOGDEB("Mouse: GlobalY " << mev->globalY() << " y " << mev->y() <<
"\n");
} }
#endif #endif
return false; return false;
@ -278,7 +277,7 @@ bool Preview::eventFilter(QObject *target, QEvent *event)
void Preview::searchTextChanged(const QString & text) void Preview::searchTextChanged(const QString & text)
{ {
LOGDEB1("Search line text changed. text: '" << ((const char *)text.toUtf8()) << "'\n" ); LOGDEB1("Search line text changed. text: '" << qs2utf8s(text) << "'\n");
m_searchTextFromIndex = -1; m_searchTextFromIndex = -1;
if (text.isEmpty()) { if (text.isEmpty()) {
m_dynSearchActive = false; m_dynSearchActive = false;
@ -292,7 +291,7 @@ void Preview::searchTextChanged(const QString & text)
void Preview::searchTextFromIndex(int idx) void Preview::searchTextFromIndex(int idx)
{ {
LOGDEB1("search line from index " << (idx) << "\n" ); LOGDEB1("search line from index " << idx << "\n");
m_searchTextFromIndex = idx; m_searchTextFromIndex = idx;
} }
@ -323,7 +322,9 @@ void Preview::emitSaveDocToFile()
void Preview::doSearch(const QString &_text, bool next, bool reverse, void Preview::doSearch(const QString &_text, bool next, bool reverse,
bool wordOnly) bool wordOnly)
{ {
LOGDEB("Preview::doSearch: text [" << ((const char *)_text.toUtf8()) << "] idx " << (m_searchTextFromIndex) << " next " << (int(next)) << " rev " << (int(reverse)) << " word " << (int(wordOnly)) << "\n" ); LOGDEB("Preview::doSearch: text [" << qs2utf8s(_text) << "] idx " <<
m_searchTextFromIndex << " next " << next << " rev " << reverse <<
" word " << wordOnly << "\n");
QString text = _text; QString text = _text;
bool matchCase = matchCheck->isChecked(); bool matchCase = matchCheck->isChecked();
@ -346,7 +347,7 @@ void Preview::doSearch(const QString &_text, bool next, bool reverse,
edit->m_plaintorich->nextAnchorNum(m_searchTextFromIndex); edit->m_plaintorich->nextAnchorNum(m_searchTextFromIndex);
} }
QString aname = edit->m_plaintorich->curAnchorName(); QString aname = edit->m_plaintorich->curAnchorName();
LOGDEB("Calling scrollToAnchor(" << ((const char *)aname.toUtf8()) << ")\n" ); LOGDEB("Calling scrollToAnchor(" << qs2utf8s(aname) << ")\n");
edit->scrollToAnchor(aname); edit->scrollToAnchor(aname);
// Position the cursor approximately at the anchor (top of // Position the cursor approximately at the anchor (top of
// viewport) so that searches start from here // viewport) so that searches start from here
@ -375,7 +376,8 @@ void Preview::doSearch(const QString &_text, bool next, bool reverse,
if (matchCase) if (matchCase)
flags |= QTextDocument::FindCaseSensitively; flags |= QTextDocument::FindCaseSensitively;
bool found = edit->find(text, flags); bool found = edit->find(text, flags);
LOGDEB("Preview::doSearch: first find call return: found " << (found) << " " << (chron.secs()) << " S\n" ); LOGDEB("Preview::doSearch: first find call return: found " << found <<
" " << chron.secs() << " S\n");
// If not found, try to wrap around. // If not found, try to wrap around.
if (!found) { if (!found) {
LOGDEB("Preview::doSearch: wrapping around\n"); LOGDEB("Preview::doSearch: wrapping around\n");
@ -387,7 +389,8 @@ void Preview::doSearch(const QString &_text, bool next, bool reverse,
LOGDEB("Preview::doSearch: 2nd find call\n"); LOGDEB("Preview::doSearch: 2nd find call\n");
chron.restart(); chron.restart();
found = edit->find(text, flags); found = edit->find(text, flags);
LOGDEB("Preview::doSearch: 2nd find call return found " << (found) << " " << (chron.secs()) << " S\n" ); LOGDEB("Preview::doSearch: 2nd find call return found " << found <<
" " << chron.secs() << " S\n");
} }
if (found) { if (found) {
@ -419,7 +422,7 @@ void Preview::currentChanged(int index)
QWidget *tw = pvTab->widget(index); QWidget *tw = pvTab->widget(index);
PreviewTextEdit *edit = PreviewTextEdit *edit =
tw->findChild<PreviewTextEdit*>("pvEdit"); tw->findChild<PreviewTextEdit*>("pvEdit");
LOGDEB1("Preview::currentChanged(). Editor: " << (edit) << "\n" ); LOGDEB1("Preview::currentChanged(). Editor: " << edit << "\n");
if (edit == 0) { if (edit == 0) {
LOGERR("Editor child not found\n"); LOGERR("Editor child not found\n");
@ -438,7 +441,7 @@ void Preview::currentChanged(int index)
void Preview::closeCurrentTab() void Preview::closeCurrentTab()
{ {
LOGDEB1("Preview::closeCurrentTab: m_loading " << (m_loading) << "\n" ); LOGDEB1("Preview::closeCurrentTab: m_loading " << m_loading << "\n");
if (m_loading) { if (m_loading) {
CancelCheck::instance().setCancel(); CancelCheck::instance().setCancel();
return; return;
@ -491,7 +494,7 @@ void Preview::setCurTabProps(const Rcl::Doc &doc, int docnum)
struct tm *tm = localtime(&mtime); struct tm *tm = localtime(&mtime);
strftime(datebuf, 99, "%Y-%m-%d %H:%M:%S", tm); strftime(datebuf, 99, "%Y-%m-%d %H:%M:%S", tm);
} }
LOGDEB("Doc.url: [" << (doc.url) << "]\n" ); LOGDEB("Doc.url: [" << doc.url << "]\n");
string url; string url;
printableUrl(theconfig->getDefCharset(), doc.url, url); printableUrl(theconfig->getDefCharset(), doc.url, url);
string tiptxt = url + string("\n"); string tiptxt = url + string("\n");
@ -511,7 +514,7 @@ void Preview::setCurTabProps(const Rcl::Doc &doc, int docnum)
bool Preview::makeDocCurrent(const Rcl::Doc& doc, int docnum, bool sametab) bool Preview::makeDocCurrent(const Rcl::Doc& doc, int docnum, bool sametab)
{ {
LOGDEB("Preview::makeDocCurrent: " << (doc.url) << "\n" ); LOGDEB("Preview::makeDocCurrent: " << doc.url << "\n");
if (m_loading) { if (m_loading) {
LOGERR("Already loading\n"); LOGERR("Already loading\n");
@ -641,7 +644,9 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
progress.show(); progress.show();
} }
LOGDEB("loadDocInCurrentTab: after file load: cancel " << (CancelCheck::instance().cancelState()) << " status " << (lthr.status) << " text length " << (lthr.fdoc.text.length()) << "\n" ); LOGDEB("loadDocInCurrentTab: after file load: cancel " <<
CancelCheck::instance().cancelState() << " status " << lthr.status <<
" text length " << lthr.fdoc.text.length() << "\n");
if (CancelCheck::instance().cancelState()) if (CancelCheck::instance().cancelState())
return false; return false;
@ -703,6 +708,7 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
editor->m_format = Qt::RichText; editor->m_format = Qt::RichText;
bool inputishtml = !lthr.fdoc.mimetype.compare("text/html"); bool inputishtml = !lthr.fdoc.mimetype.compare("text/html");
QStringList qrichlst; QStringList qrichlst;
editor->m_plaintorich->set_activatelinks(prefs.previewActiveLinks);
#if 1 #if 1
if (highlightTerms) { if (highlightTerms) {
@ -710,10 +716,10 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
qApp->processEvents(); qApp->processEvents();
if (inputishtml) { if (inputishtml) {
LOGDEB1("Preview: got html " << (lthr.fdoc.text) << "\n" ); LOGDEB1("Preview: got html " << lthr.fdoc.text << "\n");
editor->m_plaintorich->set_inputhtml(true); editor->m_plaintorich->set_inputhtml(true);
} else { } else {
LOGDEB1("Preview: got plain " << (lthr.fdoc.text) << "\n" ); LOGDEB1("Preview: got plain " << lthr.fdoc.text << "\n");
editor->m_plaintorich->set_inputhtml(false); editor->m_plaintorich->set_inputhtml(false);
} }
@ -744,7 +750,8 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
} }
} }
} else { } else {
LOGDEB("Preview: no hilighting, loading " << (int(lthr.fdoc.text.size())) << " bytes\n" ); LOGDEB("Preview: no hilighting, loading " << lthr.fdoc.text.size() <<
" bytes\n");
// No plaintorich() call. In this case, either the text is // No plaintorich() call. In this case, either the text is
// html and the html quoting is hopefully correct, or it's // html and the html quoting is hopefully correct, or it's
// plain-text and there is no need to escape special // plain-text and there is no need to escape special
@ -858,7 +865,7 @@ bool Preview::loadDocInCurrentTab(const Rcl::Doc &idoc, int docnum)
// Position to the first query term // Position to the first query term
if (editor->m_plaintorich->haveAnchors()) { if (editor->m_plaintorich->haveAnchors()) {
QString aname = editor->m_plaintorich->curAnchorName(); QString aname = editor->m_plaintorich->curAnchorName();
LOGDEB2("Call movetoanchor(" << ((const char *)aname.toUtf8()) << ")\n" ); LOGDEB2("Call movetoanchor(" << qs2utf8s(aname) << ")\n");
editor->scrollToAnchor(aname); editor->scrollToAnchor(aname);
// Position the cursor approximately at the anchor (top of // Position the cursor approximately at the anchor (top of
// viewport) so that searches start from here // viewport) so that searches start from here
@ -889,10 +896,24 @@ PreviewTextEdit::PreviewTextEdit(QWidget* parent, const char* nm, Preview *pv)
setObjectName(nm); setObjectName(nm);
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
this, SLOT(createPopupMenu(const QPoint&))); this, SLOT(createPopupMenu(const QPoint&)));
connect(this, SIGNAL(anchorClicked(const QUrl &)),
this, SLOT(onAnchorClicked(const QUrl&)));
setOpenExternalLinks(false); setOpenExternalLinks(false);
setOpenLinks(false); setOpenLinks(false);
} }
void PreviewTextEdit::onAnchorClicked(const QUrl& url)
{
LOGDEB("PreviewTextEdit::onAnchorClicked: " << qs2utf8s(url.toString())
<< std::endl);
if (prefs.previewActiveLinks && m_preview->m_rclmain) {
Rcl::Doc doc;
doc.url = qs2utf8s(url.toString()).c_str();
doc.mimetype = "text/html";
m_preview->m_rclmain->startNativeViewer(doc);
}
}
void PreviewTextEdit::createPopupMenu(const QPoint& pos) void PreviewTextEdit::createPopupMenu(const QPoint& pos)
{ {
LOGDEB1("PreviewTextEdit::createPopupMenu()\n"); LOGDEB1("PreviewTextEdit::createPopupMenu()\n");

View File

@ -51,6 +51,8 @@ class QPushButton;
class QCheckBox; class QCheckBox;
class Preview; class Preview;
class PlainToRichQtPreview; class PlainToRichQtPreview;
class QUrl;
class RclMain;
class PreviewTextEdit : public PREVIEW_PARENTCLASS { class PreviewTextEdit : public PREVIEW_PARENTCLASS {
Q_OBJECT; Q_OBJECT;
@ -65,6 +67,7 @@ public slots:
virtual void displayImage(); virtual void displayImage();
virtual void print(); virtual void print();
virtual void createPopupMenu(const QPoint& pos); virtual void createPopupMenu(const QPoint& pos);
void onAnchorClicked(const QUrl& url);
friend class Preview; friend class Preview;
@ -104,15 +107,12 @@ private:
class Preview : public QWidget { class Preview : public QWidget {
Q_OBJECT;
Q_OBJECT
public: public:
Preview(int sid, // Search Id Preview(RclMain *m, int sid, // Search Id
const HighlightData& hdata) // Search terms etc. for highlighting const HighlightData& hdata) // Search terms etc. for highlighting
: QWidget(0), m_searchId(sid), m_searchTextFromIndex(-1), m_hData(hdata) : QWidget(0), m_rclmain(m), m_searchId(sid), m_hData(hdata) {
{
init(); init();
} }
@ -158,27 +158,28 @@ signals:
void saveDocToFile(Rcl::Doc); void saveDocToFile(Rcl::Doc);
private: private:
RclMain *m_rclmain{0};
// Identifier of search in main window. This is used to check that // Identifier of search in main window. This is used to check that
// we make sense when requesting the next document when browsing // we make sense when requesting the next document when browsing
// successive search results in a tab. // successive search results in a tab.
int m_searchId; int m_searchId;
bool m_dynSearchActive; bool m_dynSearchActive{false};
// Index value the search text comes from. -1 if text was edited // Index value the search text comes from. -1 if text was edited
int m_searchTextFromIndex; int m_searchTextFromIndex{-1};
bool m_canBeep; bool m_canBeep{true};
bool m_loading; bool m_loading{false};
HighlightData m_hData; HighlightData m_hData;
bool m_justCreated; // First tab create is different bool m_justCreated{true}; // First tab create is different
QTabWidget* pvTab; QTabWidget* pvTab{0};
QLabel* searchLabel; QLabel* searchLabel{0};
QComboBox *searchTextCMB; QComboBox *searchTextCMB{0};
QPushButton* nextButton; QPushButton* nextButton{0};
QPushButton* prevButton; QPushButton* prevButton{0};
QPushButton* clearPB; QPushButton* clearPB{0};
QCheckBox* matchCheck; QCheckBox* matchCheck{0};
void init(); void init();
virtual void setCurTabProps(const Rcl::Doc& doc, int docnum); virtual void setCurTabProps(const Rcl::Doc& doc, int docnum);

View File

@ -150,7 +150,7 @@ void RclMain::startPreview(int docnum, Rcl::Doc doc, int mod)
if (curPreview == 0) { if (curPreview == 0) {
HighlightData hdata; HighlightData hdata;
m_source->getTerms(hdata); m_source->getTerms(hdata);
curPreview = new Preview(reslist->listId(), hdata); curPreview = new Preview(this, reslist->listId(), hdata);
if (curPreview == 0) { if (curPreview == 0) {
QMessageBox::warning(0, tr("Warning"), QMessageBox::warning(0, tr("Warning"),
@ -188,7 +188,7 @@ void RclMain::startPreview(int docnum, Rcl::Doc doc, int mod)
*/ */
void RclMain::startPreview(Rcl::Doc doc) void RclMain::startPreview(Rcl::Doc doc)
{ {
Preview *preview = new Preview(0, HighlightData()); Preview *preview = new Preview(this, 0, HighlightData());
if (preview == 0) { if (preview == 0) {
QMessageBox::warning(0, tr("Warning"), QMessageBox::warning(0, tr("Warning"),
tr("Can't create preview window"), tr("Can't create preview window"),

View File

@ -479,7 +479,8 @@ void RclMain::startManual(const string& index)
webhelp = path_cat(webhelp, "index.html"); webhelp = path_cat(webhelp, "index.html");
bool has_wh = path_exists(webhelp); bool has_wh = path_exists(webhelp);
LOGDEB("RclMain::startManual: help index is " << (index.empty()?"(null)":index) << "\n" ); LOGDEB("RclMain::startManual: help index is " <<
(index.empty() ? "(null)" : index) << "\n");
bool indexempty = index.empty(); bool indexempty = index.empty();
#ifdef _WIN32 #ifdef _WIN32

View File

@ -61,34 +61,7 @@ class RclMain : public QMainWindow, public Ui::RclMainBase {
public: public:
RclMain(QWidget * parent = 0) RclMain(QWidget * parent = 0)
: QMainWindow(parent), : QMainWindow(parent) {
curPreview(0),
asearchform(0),
uiprefs(0),
indexConfig(0),
indexSched(0),
cronTool(0),
rtiTool(0),
spellform(0),
fragbuts(0),
specidx(0),
periodictimer(0),
webcache(0),
restable(0),
displayingTable(0),
m_idNoStem(0),
m_idAllStem(0),
m_toolsTB(0), m_resTB(0),
m_filtFRM(0), m_filtCMB(0), m_filtBGRP(0), m_filtMN(0),
m_idxproc(0),
m_idxkilled(false),
m_catgbutvecidx(0),
m_sortspecnochange(false),
m_indexerState(IXST_UNKNOWN),
m_queryActive(false),
m_firstIndexing(false),
m_searchIsSimple(false),
m_pidfile(0) {
setupUi(this); setupUi(this);
init(); init();
} }
@ -207,53 +180,51 @@ protected:
private: private:
SnippetsW *m_snippets{0}; SnippetsW *m_snippets{0};
Preview *curPreview; Preview *curPreview{0};
AdvSearch *asearchform; AdvSearch *asearchform{0};
UIPrefsDialog *uiprefs; UIPrefsDialog *uiprefs{0};
ConfIndexW *indexConfig; ConfIndexW *indexConfig{0};
IdxSchedW *indexSched; IdxSchedW *indexSched{0};
CronToolW *cronTool; CronToolW *cronTool{0};
RTIToolW *rtiTool; RTIToolW *rtiTool{0};
SpellW *spellform; SpellW *spellform{0};
FragButs *fragbuts; FragButs *fragbuts{0};
SpecIdxW *specidx; SpecIdxW *specidx{0};
QTimer *periodictimer; QTimer *periodictimer{0};
WebcacheEdit *webcache; WebcacheEdit *webcache{0};
ResTable *restable; ResTable *restable{0};
bool displayingTable; bool displayingTable{false};
QAction *m_idNoStem; QAction *m_idNoStem{0};
QAction *m_idAllStem; QAction *m_idAllStem{0};
QToolBar *m_toolsTB; QToolBar *m_toolsTB{0};
QToolBar *m_resTB; QToolBar *m_resTB{0};
QFrame *m_filtFRM; QFrame *m_filtFRM{0};
QComboBox *m_filtCMB; QComboBox *m_filtCMB{0};
QButtonGroup *m_filtBGRP; QButtonGroup *m_filtBGRP{0};
QMenu *m_filtMN; QMenu *m_filtMN{0};
QFileSystemWatcher m_watcher; QFileSystemWatcher m_watcher;
vector<ExecCmd*> m_viewers; vector<ExecCmd*> m_viewers;
ExecCmd *m_idxproc; // Indexing process ExecCmd *m_idxproc{0}; // Indexing process
bool m_idxkilled; // Killed my process bool m_idxkilled{false}; // Killed my process
TempFileInternal *m_idxreasontmp{nullptr}; TempFileInternal *m_idxreasontmp{nullptr};
map<QString, QAction*> m_stemLangToId; map<QString, QAction*> m_stemLangToId;
vector<string> m_catgbutvec; vector<string> m_catgbutvec;
int m_catgbutvecidx; int m_catgbutvecidx{0};
DocSeqFiltSpec m_filtspec; DocSeqFiltSpec m_filtspec;
bool m_sortspecnochange; bool m_sortspecnochange{false};
DocSeqSortSpec m_sortspec; DocSeqSortSpec m_sortspec;
std::shared_ptr<DocSequence> m_source; std::shared_ptr<DocSequence> m_source;
IndexerState m_indexerState; IndexerState m_indexerState{IXST_UNKNOWN};
bool m_queryActive; bool m_queryActive{false};
bool m_firstIndexing; bool m_firstIndexing{false};
bool m_searchIsSimple; // Last search was started from simple // Last search was started from simple
bool m_searchIsSimple{false};
// If set on init, will be displayed either through ext app, or // If set on init, will be displayed either through ext app, or
// preview (if no ext app set) // preview (if no ext app set)
QString m_urltoview; QString m_urltoview;
RclTrayIcon *m_trayicon{0};
RclTrayIcon *m_trayicon;
// We sometimes take the indexer lock (e.g.: when editing the webcache) // We sometimes take the indexer lock (e.g.: when editing the webcache)
Pidfile *m_pidfile; Pidfile *m_pidfile{0};
virtual void init(); virtual void init();
virtual void setupResTB(bool combo); virtual void setupResTB(bool combo);

View File

@ -132,6 +132,19 @@
</property> </property>
</widget> </widget>
</item> </item>
<item>
<widget class="QCheckBox" name="previewActiveLinksCB">
<property name="text">
<string>Activate links in preview.</string>
</property>
<property name="toolTip">
<string>Make links inside the preview window clickable, and start an external browser when they are clicked.</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout"> <layout class="QHBoxLayout" name="horizontalLayout">
<item> <item>

View File

@ -145,6 +145,7 @@ void UIPrefsDialog::setFromPrefs()
closeToTrayCB->setChecked(prefs.closeToTray); closeToTrayCB->setChecked(prefs.closeToTray);
showTempFileWarningCB->setChecked(prefs.showTempFileWarning == -1); showTempFileWarningCB->setChecked(prefs.showTempFileWarning == -1);
previewHtmlCB->setChecked(prefs.previewHtml); previewHtmlCB->setChecked(prefs.previewHtml);
previewActiveLinksCB->setChecked(prefs.previewActiveLinks);
switch (prefs.previewPlainPre) { switch (prefs.previewPlainPre) {
case PrefsPack::PP_BR: case PrefsPack::PP_BR:
plainBRRB->setChecked(1); plainBRRB->setChecked(1);
@ -330,6 +331,7 @@ void UIPrefsDialog::accept()
prefs.showTempFileWarning = showTempFileWarningCB->isChecked() ? prefs.showTempFileWarning = showTempFileWarningCB->isChecked() ?
-1 : 1024; -1 : 1024;
prefs.previewHtml = previewHtmlCB->isChecked(); prefs.previewHtml = previewHtmlCB->isChecked();
prefs.previewActiveLinks = previewActiveLinksCB->isChecked();
if (plainBRRB->isChecked()) { if (plainBRRB->isChecked()) {
prefs.previewPlainPre = PrefsPack::PP_BR; prefs.previewPlainPre = PrefsPack::PP_BR;