Switch to unified view

a/src/qtgui/reslist.cpp b/src/qtgui/reslist.cpp
...
...
18
#include "autoconfig.h"
18
#include "autoconfig.h"
19
19
20
#include <time.h>
20
#include <time.h>
21
#include <stdlib.h>
21
#include <stdlib.h>
22
22
23
#include <memory>
24
23
#include <qapplication.h>
25
#include <qapplication.h>
24
#include <qvariant.h>
26
#include <qvariant.h>
25
#include <qevent.h>
27
#include <qevent.h>
26
#include <qmenu.h>
28
#include <qmenu.h>
27
#include <qpushbutton.h>
29
#include <qpushbutton.h>
...
...
32
#include <qmessagebox.h>
34
#include <qmessagebox.h>
33
#include <qimage.h>
35
#include <qimage.h>
34
#include <qscrollbar.h>
36
#include <qscrollbar.h>
35
#include <QTextBlock>
37
#include <QTextBlock>
36
#include <QShortcut>
38
#include <QShortcut>
37
#ifndef __APPLE__
38
//#include <qx11info_x11.h>
39
#endif
40
39
41
#include "log.h"
40
#include "log.h"
42
#include "smallut.h"
41
#include "smallut.h"
43
#include "recoll.h"
42
#include "recoll.h"
44
#include "guiutils.h"
43
#include "guiutils.h"
45
#include "pathut.h"
44
#include "pathut.h"
46
#include "docseq.h"
45
#include "docseq.h"
47
#include "pathut.h"
46
#include "pathut.h"
48
#include "mimehandler.h"
47
#include "mimehandler.h"
49
#include "plaintorich.h"
48
#include "plaintorich.h"
50
#include <memory>
51
#include "internfile.h"
49
#include "internfile.h"
52
#include "indexer.h"
50
#include "indexer.h"
53
#include "snippets_w.h"
51
#include "snippets_w.h"
54
#include "listdialog.h"
52
#include "listdialog.h"
55
#include "reslist.h"
53
#include "reslist.h"
56
#include "moc_reslist.cpp"
54
#include "moc_reslist.cpp"
57
#include "rclhelp.h"
55
#include "rclhelp.h"
58
#include "appformime.h"
56
#include "appformime.h"
59
#include "respopup.h"
57
#include "respopup.h"
58
#include "reslistpager.h"
60
59
61
static const QKeySequence quitKeySeq("Ctrl+q");
60
static const QKeySequence quitKeySeq("Ctrl+q");
62
static const QKeySequence closeKeySeq("Ctrl+w");
61
static const QKeySequence closeKeySeq("Ctrl+w");
63
62
64
#ifndef RESLIST_TEXTBROWSER
63
#if defined(USING_WEBKIT)
65
#include <QWebFrame>
64
#include <QWebFrame>
66
#include <QWebElement>
65
#include <QWebElement>
67
#include <QWebSettings>
66
#include <QWebSettings>
68
#endif
67
#endif
69
68
...
...
75
#undef SETFONT_WITH_HEADSTYLE
74
#undef SETFONT_WITH_HEADSTYLE
76
75
77
class QtGuiResListPager : public ResListPager {
76
class QtGuiResListPager : public ResListPager {
78
public:
77
public:
79
    QtGuiResListPager(ResList *p, int ps) 
78
    QtGuiResListPager(ResList *p, int ps) 
80
  : ResListPager(ps), m_reslist(p) 
79
        : ResListPager(ps), m_reslist(p) 
81
    {}
80
        {}
82
    virtual bool append(const string& data);
81
    virtual bool append(const string& data);
83
    virtual bool append(const string& data, int idx, const Rcl::Doc& doc);
82
    virtual bool append(const string& data, int idx, const Rcl::Doc& doc);
84
    virtual string trans(const string& in);
83
    virtual string trans(const string& in);
85
    virtual string detailsLink();
84
    virtual string detailsLink();
86
    virtual const string &parFormat();
85
    virtual const string &parFormat();
87
    virtual const string &dateFormat();
86
    virtual const string &dateFormat();
88
    virtual string nextUrl();
87
    virtual string nextUrl();
89
    virtual string prevUrl();
88
    virtual string prevUrl();
90
    virtual string headerContent();
89
    virtual string headerContent();
91
    virtual void suggest(const vector<string>uterms, 
90
    virtual void suggest(const vector<string>uterms, 
92
           map<string, vector<string> >& sugg);
91
                         map<string, vector<string> >& sugg);
93
    virtual string absSep() {return (const char *)(prefs.abssep.toUtf8());}
92
    virtual string absSep() {return (const char *)(prefs.abssep.toUtf8());}
94
    virtual string iconUrl(RclConfig *, Rcl::Doc& doc);
93
    virtual string iconUrl(RclConfig *, Rcl::Doc& doc);
95
private:
94
private:
96
    ResList *m_reslist;
95
    ResList *m_reslist;
97
};
96
};
...
...
99
#if 0
98
#if 0
100
FILE *fp;
99
FILE *fp;
101
void logdata(const char *data)
100
void logdata(const char *data)
102
{
101
{
103
    if (fp == 0)
102
    if (fp == 0)
104
  fp = fopen("/tmp/recolltoto.html", "a");
103
        fp = fopen("/tmp/recolltoto.html", "a");
105
    if (fp)
104
    if (fp)
106
  fprintf(fp, "%s", data);
105
        fprintf(fp, "%s", data);
107
}
106
}
108
#else
107
#else
109
#define logdata(X)
108
#define logdata(X)
110
#endif
109
#endif
111
110
...
...
118
    m_reslist->append(QString::fromUtf8(data.c_str()));
117
    m_reslist->append(QString::fromUtf8(data.c_str()));
119
    return true;
118
    return true;
120
}
119
}
121
120
122
bool QtGuiResListPager::append(const string& data, int docnum, 
121
bool QtGuiResListPager::append(const string& data, int docnum, 
123
                 const Rcl::Doc&)
122
                               const Rcl::Doc&)
124
{
123
{
125
    LOGDEB2("QtGuiReslistPager::appendDoc: blockCount " <<
124
    LOGDEB2("QtGuiReslistPager::appendDoc: blockCount " <<
126
            m_reslist->document()->blockCount() << ", " << data << "\n");
125
            m_reslist->document()->blockCount() << ", " << data << "\n");
127
    logdata(data.c_str());
126
    logdata(data.c_str());
128
#ifdef RESLIST_TEXTBROWSER
127
#if defined(USING_WEBKIT)
128
    QString sdoc = QString("<div class=\"rclresult\" rcldocnum=\"%1\">").arg(docnum);
129
    m_reslist->append(sdoc);
130
    m_reslist->append(QString::fromUtf8(data.c_str()));
131
    m_reslist->append("</div>");
132
#else
129
    int blkcnt0 = m_reslist->document()->blockCount();
133
    int blkcnt0 = m_reslist->document()->blockCount();
130
    m_reslist->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
134
    m_reslist->moveCursor(QTextCursor::End, QTextCursor::MoveAnchor);
131
    m_reslist->textCursor().insertBlock();
135
    m_reslist->textCursor().insertBlock();
132
    m_reslist->insertHtml(QString::fromUtf8(data.c_str()));
136
    m_reslist->insertHtml(QString::fromUtf8(data.c_str()));
133
    m_reslist->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
137
    m_reslist->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
134
    m_reslist->ensureCursorVisible();
138
    m_reslist->ensureCursorVisible();
135
    int blkcnt1 = m_reslist->document()->blockCount();
139
    int blkcnt1 = m_reslist->document()->blockCount();
136
    for (int block = blkcnt0; block < blkcnt1; block++) {
140
    for (int block = blkcnt0; block < blkcnt1; block++) {
137
  m_reslist->m_pageParaToReldocnums[block] = docnum;
141
        m_reslist->m_pageParaToReldocnums[block] = docnum;
138
    }
142
    }
139
#else
140
    QString sdoc = QString("<div class=\"rclresult\" rcldocnum=\"%1\">").arg(docnum);
141
    m_reslist->append(sdoc);
142
    m_reslist->append(QString::fromUtf8(data.c_str()));
143
    m_reslist->append("</div>");
144
#endif
143
#endif
145
    return true;
144
    return true;
146
}
145
}
147
146
148
string QtGuiResListPager::trans(const string& in)
147
string QtGuiResListPager::trans(const string& in)
...
...
194
    out += qs2utf8s(prefs.reslistheadertext);
193
    out += qs2utf8s(prefs.reslistheadertext);
195
    return out;
194
    return out;
196
}
195
}
197
196
198
void QtGuiResListPager::suggest(const vector<string>uterms, 
197
void QtGuiResListPager::suggest(const vector<string>uterms, 
199
              map<string, vector<string> >& sugg)
198
                                map<string, vector<string> >& sugg)
200
{
199
{
201
    sugg.clear();
200
    sugg.clear();
202
    bool issimple = m_reslist && m_reslist->m_rclmain && 
201
    bool issimple = m_reslist && m_reslist->m_rclmain && 
203
  m_reslist->m_rclmain->lastSearchSimple();
202
        m_reslist->m_rclmain->lastSearchSimple();
204
203
205
    for (const auto& uit : uterms) {
204
    for (const auto& uit : uterms) {
206
        vector<string> tsuggs;
205
        vector<string> tsuggs;
207
206
208
  // If the term is in the dictionary, Aspell::suggest won't
207
        // If the term is in the dictionary, Aspell::suggest won't
209
  // list alternatives. In fact we may want to check the
208
        // list alternatives. In fact we may want to check the
210
  // frequencies and propose something anyway if a possible
209
        // frequencies and propose something anyway if a possible
211
  // variation is much more common (as google does) ?
210
        // variation is much more common (as google does) ?
212
        if (!rcldb->getSpellingSuggestions(uit, tsuggs)) {
211
        if (!rcldb->getSpellingSuggestions(uit, tsuggs)) {
213
            continue;
212
            continue;
214
        }
213
        }
215
  // We should check that the term stems differently from the
214
        // We should check that the term stems differently from the
216
  // base word (else it's not useful to expand the search). Or
215
        // base word (else it's not useful to expand the search). Or
217
  // is it ? This should depend if stemming is turned on or not
216
        // is it ? This should depend if stemming is turned on or not
218
217
219
        if (!tsuggs.empty()) {
218
        if (!tsuggs.empty()) {
220
            sugg[uit] = vector<string>(tsuggs.begin(), tsuggs.end());
219
            sugg[uit] = vector<string>(tsuggs.begin(), tsuggs.end());
221
      if (sugg[uit].size() > 5)
220
            if (sugg[uit].size() > 5)
222
      sugg[uit].resize(5);
221
                sugg[uit].resize(5);
223
      // Set up the links as a <href="Sold|new">. 
222
            // Set up the links as a <href="Sold|new">. 
224
      for (auto& it : sugg[uit]) {
223
            for (auto& it : sugg[uit]) {
225
      if (issimple) {
224
                if (issimple) {
226
          it = string("<a href=\"S") + uit + "|" + it + "\">" +
225
                    it = string("<a href=\"S") + uit + "|" + it + "\">" +
227
          it + "</a>";
226
                        it + "</a>";
228
      }
227
                }
229
      }
228
            }
230
        }
229
        }
231
    }
230
    }
232
}
231
}
233
232
234
string QtGuiResListPager::iconUrl(RclConfig *config, Rcl::Doc& doc)
233
string QtGuiResListPager::iconUrl(RclConfig *config, Rcl::Doc& doc)
235
{
234
{
236
    if (doc.ipath.empty()) {
235
    if (doc.ipath.empty()) {
237
  vector<Rcl::Doc> docs;
236
        vector<Rcl::Doc> docs;
238
  docs.push_back(doc);
237
        docs.push_back(doc);
239
  vector<string> paths;
238
        vector<string> paths;
240
  Rcl::docsToPaths(docs, paths);
239
        Rcl::docsToPaths(docs, paths);
241
  if (!paths.empty()) {
240
        if (!paths.empty()) {
242
      string path;
241
            string path;
243
      LOGDEB2("ResList::iconUrl: source path [" << paths[0] << "]\n");
242
            LOGDEB2("ResList::iconUrl: source path [" << paths[0] << "]\n");
244
      if (thumbPathForUrl(cstr_fileu + paths[0], 128, path)) {
243
            if (thumbPathForUrl(cstr_fileu + paths[0], 128, path)) {
245
      LOGDEB2("ResList::iconUrl: icon path [" << path << "]\n");
244
                LOGDEB2("ResList::iconUrl: icon path [" << path << "]\n");
246
      return cstr_fileu + path;
245
                return cstr_fileu + path;
247
      } else {
246
            } else {
248
      LOGDEB2("ResList::iconUrl: no icon: path [" << path << "]\n");
247
                LOGDEB2("ResList::iconUrl: no icon: path [" << path << "]\n");
249
      }
248
            }
250
  } else {
249
        } else {
251
      LOGDEB("ResList::iconUrl: docsToPaths failed\n");
250
            LOGDEB("ResList::iconUrl: docsToPaths failed\n");
252
  }
251
        }
253
    }
252
    }
254
    return ResListPager::iconUrl(config, doc);
253
    return ResListPager::iconUrl(config, doc);
255
}
254
}
256
255
257
/////// /////// End reslistpager methods
256
/////// /////// End reslistpager methods
258
257
259
class PlainToRichQtReslist : public PlainToRich {
258
class PlainToRichQtReslist : public PlainToRich {
260
public:
259
public:
261
    virtual string startMatch(unsigned int idx)
260
    virtual string startMatch(unsigned int idx)
262
    {
261
        {
263
  if (0 && m_hdata) {
262
            if (0 && m_hdata) {
264
      string s1, s2;
263
                string s1, s2;
265
      stringsToString<vector<string> >(m_hdata->groups[idx], s1); 
264
                stringsToString<vector<string> >(m_hdata->groups[idx], s1); 
266
      stringsToString<vector<string> >(m_hdata->ugroups[m_hdata->grpsugidx[idx]], s2);
265
                stringsToString<vector<string> >(m_hdata->ugroups[m_hdata->grpsugidx[idx]], s2);
267
      LOGDEB2("Reslist startmatch: group " << s1 << " user group " <<
266
                LOGDEB2("Reslist startmatch: group " << s1 << " user group " <<
268
                    s2 << "\n");
267
                        s2 << "\n");
269
  }
268
            }
270
      
269
                
271
  return string("<span class='rclmatch' style='")
270
            return string("<span class='rclmatch' style='")
272
      + qs2utf8s(prefs.qtermstyle) + string("'>");
271
                + qs2utf8s(prefs.qtermstyle) + string("'>");
273
    }
272
        }
274
    virtual string endMatch() 
273
    virtual string endMatch() 
275
    {
274
        {
276
  return string("</span>");
275
            return string("</span>");
277
    }
276
        }
278
};
277
};
279
static PlainToRichQtReslist g_hiliter;
278
static PlainToRichQtReslist g_hiliter;
280
279
281
/////////////////////////////////////
280
/////////////////////////////////////
282
281
283
ResList::ResList(QWidget* parent, const char* name)
282
ResList::ResList(QWidget* parent, const char* name)
284
    : RESLIST_PARENTCLASS(parent), m_curPvDoc(-1), m_lstClckMod(0), 
283
    : RESLIST_PARENTCLASS(parent)
285
      m_listId(0), m_rclmain(0), m_ismainres(true)
286
{
284
{
287
    if (!name)
285
    if (!name)
288
  setObjectName("resList");
286
        setObjectName("resList");
289
    else 
287
    else 
290
  setObjectName(name);
288
        setObjectName(name);
291
#ifdef RESLIST_TEXTBROWSER
289
#if defined(USING_WEBKIT)
290
    LOGDEB("Reslist: using Webkit\n");
291
    // signals and slots connections
292
    connect(this, SIGNAL(linkClicked(const QUrl &)), 
293
            this, SLOT(linkWasClicked(const QUrl &)));
294
    page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
295
    settings()->setAttribute(QWebSettings::JavascriptEnabled, true);
296
#else
292
    LOGDEB("Reslist: using QTextBrowser\n");
297
    LOGDEB("Reslist: using QTextBrowser\n");
293
    setReadOnly(true);
298
    setReadOnly(true);
294
    setUndoRedoEnabled(false);
299
    setUndoRedoEnabled(false);
295
    setOpenLinks(false);
300
    setOpenLinks(false);
296
    setTabChangesFocus(true);
301
    setTabChangesFocus(true);
297
    // signals and slots connections
302
    // signals and slots connections
298
    connect(this, SIGNAL(anchorClicked(const QUrl &)), 
303
    connect(this, SIGNAL(anchorClicked(const QUrl &)), 
299
      this, SLOT(linkWasClicked(const QUrl &)));
304
            this, SLOT(linkWasClicked(const QUrl &)));
300
#else
301
    LOGDEB("Reslist: using QWebView\n");
302
    // signals and slots connections
303
    connect(this, SIGNAL(linkClicked(const QUrl &)), 
304
      this, SLOT(linkWasClicked(const QUrl &)));
305
    page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
306
    settings()->setAttribute(QWebSettings::JavascriptEnabled, true);
307
#endif
305
#endif
308
306
309
    setFont();
307
    setFont();
310
    languageChange();
308
    languageChange();
311
309
...
...
314
                           "RCL.SEARCH.GUI.RESLIST");
312
                           "RCL.SEARCH.GUI.RESLIST");
315
313
316
#if 0
314
#if 0
317
    // See comments in "highlighted
315
    // See comments in "highlighted
318
    connect(this, SIGNAL(highlighted(const QString &)), 
316
    connect(this, SIGNAL(highlighted(const QString &)), 
319
      this, SLOT(highlighted(const QString &)));
317
            this, SLOT(highlighted(const QString &)));
320
#endif
318
#endif
321
319
322
    setContextMenuPolicy(Qt::CustomContextMenu);
320
    setContextMenuPolicy(Qt::CustomContextMenu);
323
    connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
321
    connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
324
      this, SLOT(createPopupMenu(const QPoint&)));
322
            this, SLOT(createPopupMenu(const QPoint&)));
325
323
326
    m_pager = new QtGuiResListPager(this, prefs.respagesize);
324
    m_pager = new QtGuiResListPager(this, prefs.respagesize);
327
    m_pager->setHighLighter(&g_hiliter);
325
    m_pager->setHighLighter(&g_hiliter);
328
}
326
}
329
327
...
...
331
{
329
{
332
    // These have to exist somewhere for translations to work
330
    // These have to exist somewhere for translations to work
333
#ifdef __GNUC__
331
#ifdef __GNUC__
334
    __attribute__((unused))
332
    __attribute__((unused))
335
#endif
333
#endif
336
    static const char* strings[] = {
334
        static const char* strings[] = {
337
  QT_TR_NOOP("<p><b>No results found</b><br>"),
335
        QT_TR_NOOP("<p><b>No results found</b><br>"),
338
  QT_TR_NOOP("Documents"),
336
        QT_TR_NOOP("Documents"),
339
  QT_TR_NOOP("out of at least"),
337
        QT_TR_NOOP("out of at least"),
340
  QT_TR_NOOP("for"),
338
        QT_TR_NOOP("for"),
341
  QT_TR_NOOP("Previous"),
339
        QT_TR_NOOP("Previous"),
342
  QT_TR_NOOP("Next"),
340
        QT_TR_NOOP("Next"),
343
  QT_TR_NOOP("Unavailable document"),
341
        QT_TR_NOOP("Unavailable document"),
344
  QT_TR_NOOP("Preview"),
342
        QT_TR_NOOP("Preview"),
345
  QT_TR_NOOP("Open"),
343
        QT_TR_NOOP("Open"),
346
  QT_TR_NOOP("Snippets"),
344
        QT_TR_NOOP("Snippets"),
347
  QT_TR_NOOP("(show query)"),
345
        QT_TR_NOOP("(show query)"),
348
        QT_TR_NOOP("<p><i>Alternate spellings (accents suppressed): </i>"),
346
        QT_TR_NOOP("<p><i>Alternate spellings (accents suppressed): </i>"),
349
        QT_TR_NOOP("<p><i>Alternate spellings: </i>"),
347
        QT_TR_NOOP("<p><i>Alternate spellings: </i>"),
350
    };
348
    };
351
}
349
}
352
350
353
void ResList::setRclMain(RclMain *m, bool ismain) 
351
void ResList::setRclMain(RclMain *m, bool ismain) 
354
{
352
{
355
    m_rclmain = m;
353
    m_rclmain = m;
356
    m_ismainres = ismain;
354
    m_ismainres = ismain;
357
    if (!m_ismainres) {
355
    if (!m_ismainres) {
358
  connect(new QShortcut(closeKeySeq, this), SIGNAL (activated()), 
356
        connect(new QShortcut(closeKeySeq, this), SIGNAL (activated()), 
359
      this, SLOT (close()));
357
                this, SLOT (close()));
360
  connect(new QShortcut(quitKeySeq, this), SIGNAL (activated()), 
358
        connect(new QShortcut(quitKeySeq, this), SIGNAL (activated()), 
361
      m_rclmain, SLOT (fileExit()));
359
                m_rclmain, SLOT (fileExit()));
362
  connect(this, SIGNAL(previewRequested(Rcl::Doc)), 
360
        connect(this, SIGNAL(previewRequested(Rcl::Doc)), 
363
      m_rclmain, SLOT(startPreview(Rcl::Doc)));
361
                m_rclmain, SLOT(startPreview(Rcl::Doc)));
364
  connect(this, SIGNAL(docSaveToFileClicked(Rcl::Doc)), 
362
        connect(this, SIGNAL(docSaveToFileClicked(Rcl::Doc)), 
365
      m_rclmain, SLOT(saveDocToFile(Rcl::Doc)));
363
                m_rclmain, SLOT(saveDocToFile(Rcl::Doc)));
366
  connect(this, SIGNAL(editRequested(Rcl::Doc)), 
364
        connect(this, SIGNAL(editRequested(Rcl::Doc)), 
367
      m_rclmain, SLOT(startNativeViewer(Rcl::Doc)));
365
                m_rclmain, SLOT(startNativeViewer(Rcl::Doc)));
368
    }
366
    }
369
}
367
}
370
368
371
void ResList::setFont()
369
void ResList::setFont()
372
{
370
{
373
#ifdef RESLIST_TEXTBROWSER
371
#if defined(USING_WEBKIT)
374
    if (prefs.reslistfontfamily.length()) {
375
  QFont nfont(prefs.reslistfontfamily, prefs.reslistfontsize);
376
  QTextBrowser::setFont(nfont);
377
    } else {
378
  QTextBrowser::setFont(QFont());
379
    }
380
#else
381
#ifndef SETFONT_WITH_HEADSTYLE
372
#ifndef SETFONT_WITH_HEADSTYLE
382
    QWebSettings *websettings = settings();
373
    QWebSettings *websettings = settings();
383
    if (prefs.reslistfontfamily.length()) {
374
    if (prefs.reslistfontfamily.length()) {
384
        // For some reason there is (12-2014) an offset of 3 between what
375
        // For some reason there is (12-2014) an offset of 3 between what
385
        // we request from webkit and what we get.
376
        // we request from webkit and what we get.
386
  websettings->setFontSize(QWebSettings::DefaultFontSize, 
377
        websettings->setFontSize(QWebSettings::DefaultFontSize, 
387
               prefs.reslistfontsize + 3);
378
                                 prefs.reslistfontsize + 3);
388
  websettings->setFontFamily(QWebSettings::StandardFont, 
379
        websettings->setFontFamily(QWebSettings::StandardFont, 
389
                 prefs.reslistfontfamily);
380
                                   prefs.reslistfontfamily);
390
    } else {
381
    } else {
391
  websettings->resetFontSize(QWebSettings::DefaultFontSize);
382
        websettings->resetFontSize(QWebSettings::DefaultFontSize);
392
  websettings->resetFontFamily(QWebSettings::StandardFont);
383
        websettings->resetFontFamily(QWebSettings::StandardFont);
393
    }
384
    }
394
#endif
385
#endif
386
#else
387
    if (prefs.reslistfontfamily.length()) {
388
        QFont nfont(prefs.reslistfontfamily, prefs.reslistfontsize);
389
        QTextBrowser::setFont(nfont);
390
    } else {
391
        QTextBrowser::setFont(QFont());
392
    }
395
#endif
393
#endif
396
}
394
}
397
395
398
int ResList::newListId()
396
int ResList::newListId()
399
{
397
{
...
...
416
void ResList::readDocSource()
414
void ResList::readDocSource()
417
{
415
{
418
    LOGDEB("ResList::readDocSource()\n");
416
    LOGDEB("ResList::readDocSource()\n");
419
    resetView();
417
    resetView();
420
    if (!m_source)
418
    if (!m_source)
421
  return;
419
        return;
422
    m_listId = newListId();
420
    m_listId = newListId();
423
421
424
    // Reset the page size in case the preference was changed
422
    // Reset the page size in case the preference was changed
425
    m_pager->setPageSize(prefs.respagesize);
423
    m_pager->setPageSize(prefs.respagesize);
426
    m_pager->setDocSource(m_source);
424
    m_pager->setDocSource(m_source);
...
...
441
    // There should be a progress bar for long searches but there isn't 
439
    // There should be a progress bar for long searches but there isn't 
442
    // We really want the old result list to go away, otherwise, for a
440
    // We really want the old result list to go away, otherwise, for a
443
    // slow search, the user will wonder if anything happened. The
441
    // slow search, the user will wonder if anything happened. The
444
    // following helps making sure that the textedit is really
442
    // following helps making sure that the textedit is really
445
    // blank. Else, there are often icons or text left around
443
    // blank. Else, there are often icons or text left around
446
#ifdef RESLIST_TEXTBROWSER
444
#if defined(USING_WEBKIT)
445
    m_text = "";
446
    setHtml("<html><body></body></html>");
447
#else
447
    m_pageParaToReldocnums.clear();
448
    m_pageParaToReldocnums.clear();
448
    clear();
449
    clear();
449
    QTextBrowser::append(".");
450
    QTextBrowser::append(".");
450
    clear();
451
    clear();
451
#ifndef __APPLE__
452
//    XFlush(QX11Info::display());
453
#endif
454
#else
455
    m_text = "";
456
    setHtml("<html><body></body></html>");
457
#endif
452
#endif
458
453
459
}
454
}
460
455
461
bool ResList::displayingHistory()
456
bool ResList::displayingHistory()
462
{
457
{
463
    // We want to reset the displayed history if it is currently
458
    // We want to reset the displayed history if it is currently
464
    // shown. Using the title value is an ugly hack
459
    // shown. Using the title value is an ugly hack
465
    string htstring = string((const char *)tr("Document history").toUtf8());
460
    string htstring = string((const char *)tr("Document history").toUtf8());
466
    if (!m_source || m_source->title().empty())
461
    if (!m_source || m_source->title().empty())
467
  return false;
462
        return false;
468
    return m_source->title().find(htstring) == 0;
463
    return m_source->title().find(htstring) == 0;
469
}
464
}
470
465
471
void ResList::languageChange()
466
void ResList::languageChange()
472
{
467
{
473
    setWindowTitle(tr("Result list"));
468
    setWindowTitle(tr("Result list"));
474
}
469
}
475
470
476
#ifdef RESLIST_TEXTBROWSER    
471
#if !defined(USING_WEBKIT) && !defined(USING_WEBENGINE)
477
// Get document number from text block number
472
// Get document number from text block number
478
int ResList::docnumfromparnum(int block)
473
int ResList::docnumfromparnum(int block)
479
{
474
{
480
    if (m_pager->pageNumber() < 0)
475
    if (m_pager->pageNumber() < 0)
481
  return -1;
476
        return -1;
482
477
483
    // Try to find the first number < input and actually in the map
478
    // Try to find the first number < input and actually in the map
484
    // (result blocks can be made of several text blocks)
479
    // (result blocks can be made of several text blocks)
485
    std::map<int,int>::iterator it;
480
    std::map<int,int>::iterator it;
486
    do {
481
    do {
487
  it = m_pageParaToReldocnums.find(block);
482
        it = m_pageParaToReldocnums.find(block);
488
  if (it != m_pageParaToReldocnums.end())
483
        if (it != m_pageParaToReldocnums.end())
489
      return pageFirstDocNum() + it->second;
484
            return pageFirstDocNum() + it->second;
490
    } while (--block >= 0);
485
    } while (--block >= 0);
491
    return -1;
486
    return -1;
492
}
487
}
493
488
494
// Get range of paragraph numbers which make up the result for document number
489
// Get range of paragraph numbers which make up the result for document number
495
pair<int,int> ResList::parnumfromdocnum(int docnum)
490
pair<int,int> ResList::parnumfromdocnum(int docnum)
496
{
491
{
497
    LOGDEB("parnumfromdocnum: docnum " << docnum << "\n");
492
    LOGDEB("parnumfromdocnum: docnum " << docnum << "\n");
498
    if (m_pager->pageNumber() < 0) {
493
    if (m_pager->pageNumber() < 0) {
499
  LOGDEB("parnumfromdocnum: no page return -1,-1\n");
494
        LOGDEB("parnumfromdocnum: no page return -1,-1\n");
500
  return pair<int,int>(-1,-1);
495
        return pair<int,int>(-1,-1);
501
    }
496
    }
502
    int winfirst = pageFirstDocNum();
497
    int winfirst = pageFirstDocNum();
503
    if (docnum - winfirst < 0) {
498
    if (docnum - winfirst < 0) {
504
  LOGDEB("parnumfromdocnum: docnum " << docnum << " < winfirst " <<
499
        LOGDEB("parnumfromdocnum: docnum " << docnum << " < winfirst " <<
505
               winfirst << " return -1,-1\n");
500
               winfirst << " return -1,-1\n");
506
  return pair<int,int>(-1,-1);
501
        return pair<int,int>(-1,-1);
507
    }
502
    }
508
    docnum -= winfirst;
503
    docnum -= winfirst;
509
    for (std::map<int,int>::iterator it = m_pageParaToReldocnums.begin();
504
    for (std::map<int,int>::iterator it = m_pageParaToReldocnums.begin();
510
   it != m_pageParaToReldocnums.end(); it++) {
505
         it != m_pageParaToReldocnums.end(); it++) {
511
  if (docnum == it->second) {
506
        if (docnum == it->second) {
512
      int first = it->first;
507
            int first = it->first;
513
      int last = first+1;
508
            int last = first+1;
514
      std::map<int,int>::iterator it1;
509
            std::map<int,int>::iterator it1;
515
      while ((it1 = m_pageParaToReldocnums.find(last)) != 
510
            while ((it1 = m_pageParaToReldocnums.find(last)) != 
516
         m_pageParaToReldocnums.end() && it1->second == docnum) {
511
                   m_pageParaToReldocnums.end() && it1->second == docnum) {
517
      last++;
512
                last++;
518
      }
513
            }
519
      LOGDEB("parnumfromdocnum: return " << first << "," << last << "\n");
514
            LOGDEB("parnumfromdocnum: return " << first << "," << last << "\n");
520
      return pair<int,int>(first, last);
515
            return pair<int,int>(first, last);
521
  }
516
        }
522
    }
517
    }
523
    LOGDEB("parnumfromdocnum: not found return -1,-1\n");
518
    LOGDEB("parnumfromdocnum: not found return -1,-1\n");
524
    return pair<int,int>(-1,-1);
519
    return pair<int,int>(-1,-1);
525
}
520
}
526
#endif // TEXTBROWSER
521
#endif // TEXTBROWSER
...
...
534
    LOGDEB("ResList::getDoc: docnum " << docnum << " winfirst " <<
529
    LOGDEB("ResList::getDoc: docnum " << docnum << " winfirst " <<
535
           pageFirstDocNum() << "\n");
530
           pageFirstDocNum() << "\n");
536
    int winfirst = pageFirstDocNum();
531
    int winfirst = pageFirstDocNum();
537
    int winlast = m_pager->pageLastDocNum();
532
    int winlast = m_pager->pageLastDocNum();
538
    if (docnum < 0 ||  winfirst < 0 || winlast < 0)
533
    if (docnum < 0 ||  winfirst < 0 || winlast < 0)
539
  return false;
534
        return false;
540
535
541
    // Is docnum in current page ? Then all Ok
536
    // Is docnum in current page ? Then all Ok
542
    if (docnum >= winfirst && docnum <= winlast) {
537
    if (docnum >= winfirst && docnum <= winlast) {
543
  return m_pager->getDoc(docnum, doc);
538
        return m_pager->getDoc(docnum, doc);
544
    }
539
    }
545
540
546
    // Else we accept to page down or up but not further
541
    // Else we accept to page down or up but not further
547
    if (docnum < winfirst && docnum >= winfirst - prefs.respagesize) {
542
    if (docnum < winfirst && docnum >= winfirst - prefs.respagesize) {
548
  resultPageBack();
543
        resultPageBack();
549
    } else if (docnum < winlast + 1 + prefs.respagesize) {
544
    } else if (docnum < winlast + 1 + prefs.respagesize) {
550
  resultPageNext();
545
        resultPageNext();
551
    }
546
    }
552
    winfirst = pageFirstDocNum();
547
    winfirst = pageFirstDocNum();
553
    winlast = m_pager->pageLastDocNum();
548
    winlast = m_pager->pageLastDocNum();
554
    if (docnum >= winfirst && docnum <= winlast) {
549
    if (docnum >= winfirst && docnum <= winlast) {
555
  return m_pager->getDoc(docnum, doc);
550
        return m_pager->getDoc(docnum, doc);
556
    }
551
    }
557
    return false;
552
    return false;
558
}
553
}
559
554
560
void ResList::keyPressEvent(QKeyEvent * e)
555
void ResList::keyPressEvent(QKeyEvent * e)
561
{
556
{
562
    if ((e->modifiers() & Qt::ShiftModifier)) {
557
    if ((e->modifiers() & Qt::ShiftModifier)) {
563
  if (e->key() == Qt::Key_PageUp) {
558
        if (e->key() == Qt::Key_PageUp) {
564
      // Shift-PageUp -> first page of results
559
            // Shift-PageUp -> first page of results
565
      resultPageFirst();
560
            resultPageFirst();
566
      return;
561
            return;
567
  } 
562
        } 
568
    } else {
563
    } else {
569
  if (e->key() == Qt::Key_PageUp || e->key() == Qt::Key_Backspace) {
564
        if (e->key() == Qt::Key_PageUp || e->key() == Qt::Key_Backspace) {
570
      resPageUpOrBack();
565
            resPageUpOrBack();
571
      return;
566
            return;
572
  } else if (e->key() == Qt::Key_PageDown || e->key() == Qt::Key_Space) {
567
        } else if (e->key() == Qt::Key_PageDown || e->key() == Qt::Key_Space) {
573
      resPageDownOrNext();
568
            resPageDownOrNext();
574
      return;
569
            return;
575
  }
570
        }
576
    }
571
    }
577
    RESLIST_PARENTCLASS::keyPressEvent(e);
572
    RESLIST_PARENTCLASS::keyPressEvent(e);
578
}
573
}
579
574
580
void ResList::mouseReleaseEvent(QMouseEvent *e)
575
void ResList::mouseReleaseEvent(QMouseEvent *e)
581
{
576
{
582
    m_lstClckMod = 0;
577
    m_lstClckMod = 0;
583
    if (e->modifiers() & Qt::ControlModifier) {
578
    if (e->modifiers() & Qt::ControlModifier) {
584
  m_lstClckMod |= Qt::ControlModifier;
579
        m_lstClckMod |= Qt::ControlModifier;
585
    } 
580
    } 
586
    if (e->modifiers() & Qt::ShiftModifier) {
581
    if (e->modifiers() & Qt::ShiftModifier) {
587
  m_lstClckMod |= Qt::ShiftModifier;
582
        m_lstClckMod |= Qt::ShiftModifier;
588
    }
583
    }
589
    RESLIST_PARENTCLASS::mouseReleaseEvent(e);
584
    RESLIST_PARENTCLASS::mouseReleaseEvent(e);
590
}
585
}
591
586
592
void ResList::highlighted(const QString& )
587
void ResList::highlighted(const QString& )
...
...
599
// Page Up/Down: we don't try to check if current paragraph is last or
594
// Page Up/Down: we don't try to check if current paragraph is last or
600
// first. We just page up/down and check if viewport moved. If it did,
595
// first. We just page up/down and check if viewport moved. If it did,
601
// fair enough, else we go to next/previous result page.
596
// fair enough, else we go to next/previous result page.
602
void ResList::resPageUpOrBack()
597
void ResList::resPageUpOrBack()
603
{
598
{
604
#ifdef RESLIST_TEXTBROWSER
599
#if defined(USING_WEBKIT)
600
    if (scrollIsAtTop()) {
601
        resultPageBack();
602
    } else {
603
        QWebFrame *frame = page()->mainFrame();
604
        frame->scroll(0, -int(0.9*geometry().height()));
605
    }
606
    setupArrows();
607
#else
605
    int vpos = verticalScrollBar()->value();
608
    int vpos = verticalScrollBar()->value();
606
    verticalScrollBar()->triggerAction(QAbstractSlider::SliderPageStepSub);
609
    verticalScrollBar()->triggerAction(QAbstractSlider::SliderPageStepSub);
607
    if (vpos == verticalScrollBar()->value())
610
    if (vpos == verticalScrollBar()->value())
608
  resultPageBack();
611
        resultPageBack();
609
#else
612
#endif
613
}
614
615
void ResList::resPageDownOrNext()
616
{
617
#if defined(USING_WEBKIT)
610
    if (scrollIsAtTop()) {
618
    if (scrollIsAtBottom()) {
611
  resultPageBack();
619
        resultPageNext();
612
    } else {
620
    } else {
613
  QWebFrame *frame = page()->mainFrame();
621
        QWebFrame *frame = page()->mainFrame();
614
  frame->scroll(0, -int(0.9*geometry().height()));
622
        frame->scroll(0, int(0.9*geometry().height()));
615
    }
623
    }
616
    setupArrows();
624
    setupArrows();
617
#endif
625
#else
618
}
619
620
void ResList::resPageDownOrNext()
621
{
622
#ifdef RESLIST_TEXTBROWSER
623
    int vpos = verticalScrollBar()->value();
626
    int vpos = verticalScrollBar()->value();
624
    verticalScrollBar()->triggerAction(QAbstractSlider::SliderPageStepAdd);
627
    verticalScrollBar()->triggerAction(QAbstractSlider::SliderPageStepAdd);
625
    LOGDEB("ResList::resPageDownOrNext: vpos before " << vpos << ", after "
628
    LOGDEB("ResList::resPageDownOrNext: vpos before " << vpos << ", after "
626
           << verticalScrollBar()->value() << "\n");
629
           << verticalScrollBar()->value() << "\n");
627
    if (vpos == verticalScrollBar()->value()) 
630
    if (vpos == verticalScrollBar()->value()) 
628
  resultPageNext();
631
        resultPageNext();
629
#else
630
    if (scrollIsAtBottom()) {
631
  resultPageNext();
632
    } else {
633
  QWebFrame *frame = page()->mainFrame();
634
  frame->scroll(0, int(0.9*geometry().height()));
635
    }
636
    setupArrows();
637
#endif
632
#endif
638
}
633
}
639
634
640
void ResList::setupArrows()
635
void ResList::setupArrows()
641
{
636
{
...
...
643
    emit nextPageAvailable(m_pager->hasNext() || !scrollIsAtBottom());
638
    emit nextPageAvailable(m_pager->hasNext() || !scrollIsAtBottom());
644
}
639
}
645
640
646
bool ResList::scrollIsAtBottom()
641
bool ResList::scrollIsAtBottom()
647
{
642
{
648
#ifdef RESLIST_TEXTBROWSER
643
#if defined(USING_WEBKIT)
649
    return false;
650
#else
651
    QWebFrame *frame = page()->mainFrame();
644
    QWebFrame *frame = page()->mainFrame();
652
    bool ret;
645
    bool ret;
653
    if (!frame || frame->scrollBarGeometry(Qt::Vertical).isEmpty()) {
646
    if (!frame || frame->scrollBarGeometry(Qt::Vertical).isEmpty()) {
654
  ret = true;
647
        ret = true;
655
    } else {
648
    } else {
656
  int max = frame->scrollBarMaximum(Qt::Vertical);
649
        int max = frame->scrollBarMaximum(Qt::Vertical);
657
  int cur = frame->scrollBarValue(Qt::Vertical); 
650
        int cur = frame->scrollBarValue(Qt::Vertical); 
658
  ret = (max != 0) && (cur == max);
651
        ret = (max != 0) && (cur == max);
659
  LOGDEB2("Scrollatbottom: cur " << cur << " max " << max << "\n");
652
        LOGDEB2("Scrollatbottom: cur " << cur << " max " << max << "\n");
660
    }
653
    }
661
    LOGDEB2("scrollIsAtBottom: returning " << ret << "\n");
654
    LOGDEB2("scrollIsAtBottom: returning " << ret << "\n");
662
    return ret;
655
    return ret;
656
#else
657
    return false;
663
#endif
658
#endif
664
}
659
}
665
660
666
bool ResList::scrollIsAtTop()
661
bool ResList::scrollIsAtTop()
667
{
662
{
668
#ifdef RESLIST_TEXTBROWSER
663
#if defined(USING_WEBKIT)
669
    return false;
670
#else
671
    QWebFrame *frame = page()->mainFrame();
664
    QWebFrame *frame = page()->mainFrame();
672
    bool ret;
665
    bool ret;
673
    if (!frame || frame->scrollBarGeometry(Qt::Vertical).isEmpty()) {
666
    if (!frame || frame->scrollBarGeometry(Qt::Vertical).isEmpty()) {
674
  ret = true;
667
        ret = true;
675
    } else {
668
    } else {
676
  int cur = frame->scrollBarValue(Qt::Vertical);
669
        int cur = frame->scrollBarValue(Qt::Vertical);
677
  int min = frame->scrollBarMinimum(Qt::Vertical);
670
        int min = frame->scrollBarMinimum(Qt::Vertical);
678
  LOGDEB("Scrollattop: cur " << cur << " min " << min << "\n");
671
        LOGDEB("Scrollattop: cur " << cur << " min " << min << "\n");
679
  ret = (cur == min);
672
        ret = (cur == min);
680
    }
673
    }
681
    LOGDEB2("scrollIsAtTop: returning " << ret << "\n");
674
    LOGDEB2("scrollIsAtTop: returning " << ret << "\n");
682
    return ret;
675
    return ret;
676
#else
677
    return false;
683
#endif
678
#endif
684
}
679
}
685
680
686
// Show previous page of results. We just set the current number back
681
// Show previous page of results. We just set the current number back
687
// 2 pages and show next page.
682
// 2 pages and show next page.
688
void ResList::resultPageBack()
683
void ResList::resultPageBack()
689
{
684
{
690
    if (m_pager->hasPrev()) {
685
    if (m_pager->hasPrev()) {
691
  m_pager->resultPageBack();
686
        m_pager->resultPageBack();
692
  displayPage();
687
        displayPage();
693
    }
688
    }
694
}
689
}
695
690
696
// Go to the first page
691
// Go to the first page
697
void ResList::resultPageFirst()
692
void ResList::resultPageFirst()
...
...
704
699
705
// Fill up result list window with next screen of hits
700
// Fill up result list window with next screen of hits
706
void ResList::resultPageNext()
701
void ResList::resultPageNext()
707
{
702
{
708
    if (m_pager->hasNext()) {
703
    if (m_pager->hasNext()) {
709
  m_pager->resultPageNext();
704
        m_pager->resultPageNext();
710
  displayPage();
705
        displayPage();
711
    }
706
    }
712
}
707
}
713
708
714
void ResList::resultPageFor(int docnum)
709
void ResList::resultPageFor(int docnum)
715
{
710
{
...
...
718
}
713
}
719
714
720
void ResList::append(const QString &text)
715
void ResList::append(const QString &text)
721
{
716
{
722
    LOGDEB2("QtGuiReslistPager::appendQString : " << qs2utf8s(text) << "\n");
717
    LOGDEB2("QtGuiReslistPager::appendQString : " << qs2utf8s(text) << "\n");
723
#ifdef RESLIST_TEXTBROWSER
718
#if defined(USING_WEBKIT)
719
    m_text += text;
720
#else
724
    QTextBrowser::append(text);
721
    QTextBrowser::append(text);
725
#else
726
    m_text += text;
727
#endif
722
#endif
728
}
723
}
729
724
730
void ResList::displayPage()
725
void ResList::displayPage()
731
{
726
{
732
    resetView();
727
    resetView();
733
728
734
    m_pager->displayPage(theconfig);
729
    m_pager->displayPage(theconfig);
735
730
736
#ifndef RESLIST_TEXTBROWSER
731
#if defined(USING_WEBENGINE) || defined(USING_WEBKIT)
737
    setHtml(m_text);
732
    setHtml(m_text);
738
#endif
733
#endif
739
734
740
    LOGDEB0("ResList::displayPg: hasNext " << m_pager->hasNext() <<
735
    LOGDEB0("ResList::displayPg: hasNext " << m_pager->hasNext() <<
741
            " atBot " << scrollIsAtBottom() << " hasPrev " <<
736
            " atBot " << scrollIsAtBottom() << " hasPrev " <<
...
...
751
{
746
{
752
    LOGDEB("ResList::previewExposed: doc " << docnum << "\n");
747
    LOGDEB("ResList::previewExposed: doc " << docnum << "\n");
753
748
754
    // Possibly erase old one to white
749
    // Possibly erase old one to white
755
    if (m_curPvDoc != -1) {
750
    if (m_curPvDoc != -1) {
756
#ifdef RESLIST_TEXTBROWSER
751
#if defined(USING_WEBKIT)
757
  pair<int,int> blockrange = parnumfromdocnum(m_curPvDoc);
758
  if (blockrange.first != -1) {
759
      for (int blockn = blockrange.first;
760
       blockn < blockrange.second; blockn++) {
761
      QTextBlock block = document()->findBlockByNumber(blockn);
762
      QTextCursor cursor(block);
763
      QTextBlockFormat format = cursor.blockFormat();
764
      format.clearBackground();
765
      cursor.setBlockFormat(format);
766
      }
767
  }
768
#else
769
  QString sel = 
752
        QString sel = 
770
     QString("div[rcldocnum=\"%1\"]").arg(m_curPvDoc - pageFirstDocNum());
753
            QString("div[rcldocnum=\"%1\"]").arg(m_curPvDoc - pageFirstDocNum());
771
  LOGDEB2("Searching for element, selector: [" << qs2utf8s(sel) << "]\n");
754
        LOGDEB2("Searching for element, selector: [" << qs2utf8s(sel) << "]\n");
772
  QWebElement elt = page()->mainFrame()->findFirstElement(sel);
755
        QWebElement elt = page()->mainFrame()->findFirstElement(sel);
773
  if (!elt.isNull()) {
756
        if (!elt.isNull()) {
774
      LOGDEB2("Found\n");
757
            LOGDEB2("Found\n");
775
      elt.removeAttribute("style");
758
            elt.removeAttribute("style");
776
  } else {
759
        } else {
777
      LOGDEB2("Not Found\n");
760
            LOGDEB2("Not Found\n");
778
  }
761
        }
762
#else
763
        pair<int,int> blockrange = parnumfromdocnum(m_curPvDoc);
764
        if (blockrange.first != -1) {
765
            for (int blockn = blockrange.first;
766
                 blockn < blockrange.second; blockn++) {
767
                QTextBlock block = document()->findBlockByNumber(blockn);
768
                QTextCursor cursor(block);
769
                QTextBlockFormat format = cursor.blockFormat();
770
                format.clearBackground();
771
                cursor.setBlockFormat(format);
772
            }
773
        }
779
#endif
774
#endif
780
  m_curPvDoc = -1;
775
        m_curPvDoc = -1;
781
    }
776
    }
782
777
783
    // Set background for active preview's doc entry
778
    // Set background for active preview's doc entry
784
    m_curPvDoc = docnum;
779
    m_curPvDoc = docnum;
785
780
786
#ifdef RESLIST_TEXTBROWSER
781
#if defined(USING_WEBKIT)
782
    QString sel = 
783
        QString("div[rcldocnum=\"%1\"]").arg(docnum - pageFirstDocNum());
784
    LOGDEB2("Searching for element, selector: [" << qs2utf8s(sel) << "]\n");
785
    QWebElement elt = page()->mainFrame()->findFirstElement(sel);
786
    if (!elt.isNull()) {
787
        LOGDEB2("Found\n");
788
        elt.setAttribute("style", "background: LightBlue;}");
789
    } else {
790
        LOGDEB2("Not Found\n");
791
    }
792
#else
787
    pair<int,int>  blockrange = parnumfromdocnum(docnum);
793
    pair<int,int>  blockrange = parnumfromdocnum(docnum);
788
794
789
    // Maybe docnum is -1 or not in this window, 
795
    // Maybe docnum is -1 or not in this window, 
790
    if (blockrange.first < 0)
796
    if (blockrange.first < 0)
791
  return;
797
        return;
792
    // Color the new active paragraph
798
    // Color the new active paragraph
793
    QColor color("LightBlue");
799
    QColor color("LightBlue");
794
    for (int blockn = blockrange.first+1;
800
    for (int blockn = blockrange.first+1;
795
   blockn < blockrange.second; blockn++) {
801
         blockn < blockrange.second; blockn++) {
796
  QTextBlock block = document()->findBlockByNumber(blockn);
802
        QTextBlock block = document()->findBlockByNumber(blockn);
797
  QTextCursor cursor(block);
803
        QTextCursor cursor(block);
798
  QTextBlockFormat format;
804
        QTextBlockFormat format;
799
  format.setBackground(QBrush(color));
805
        format.setBackground(QBrush(color));
800
  cursor.mergeBlockFormat(format);
806
        cursor.mergeBlockFormat(format);
801
  setTextCursor(cursor);
807
        setTextCursor(cursor);
802
  ensureCursorVisible();
808
        ensureCursorVisible();
803
    }
804
#else
805
    QString sel = 
806
  QString("div[rcldocnum=\"%1\"]").arg(docnum - pageFirstDocNum());
807
    LOGDEB2("Searching for element, selector: [" << qs2utf8s(sel) << "]\n");
808
    QWebElement elt = page()->mainFrame()->findFirstElement(sel);
809
    if (!elt.isNull()) {
810
  LOGDEB2("Found\n");
811
  elt.setAttribute("style", "background: LightBlue;}");
812
    } else {
813
  LOGDEB2("Not Found\n");
814
    }
809
    }
815
#endif
810
#endif
816
}
811
}
817
812
818
// Double click in res list: add selection to simple search
813
// Double click in res list: add selection to simple search
819
void ResList::mouseDoubleClickEvent(QMouseEvent *event)
814
void ResList::mouseDoubleClickEvent(QMouseEvent *event)
820
{
815
{
821
    RESLIST_PARENTCLASS::mouseDoubleClickEvent(event);
816
    RESLIST_PARENTCLASS::mouseDoubleClickEvent(event);
822
#ifdef RESLIST_TEXTBROWSER
817
#if defined(USING_WEBKIT)
818
    emit(wordSelect(selectedText()));
819
#else
823
    if (textCursor().hasSelection())
820
    if (textCursor().hasSelection())
824
  emit(wordSelect(textCursor().selectedText()));
821
        emit(wordSelect(textCursor().selectedText()));
825
#else
826
    emit(wordSelect(selectedText()));
827
#endif
822
#endif
828
}
823
}
829
824
830
void ResList::showQueryDetails()
825
void ResList::showQueryDetails()
831
{
826
{
832
    if (!m_source)
827
    if (!m_source)
833
  return;
828
        return;
834
    string oq = breakIntoLines(m_source->getDescription(), 100, 50);
829
    string oq = breakIntoLines(m_source->getDescription(), 100, 50);
835
    QString str;
830
    QString str;
836
    QString desc = tr("Result count (est.)") + ": " + 
831
    QString desc = tr("Result count (est.)") + ": " + 
837
  str.setNum(m_source->getResCnt()) + "<br>";
832
        str.setNum(m_source->getResCnt()) + "<br>";
838
    desc += tr("Query details") + ": " + QString::fromUtf8(oq.c_str());
833
    desc += tr("Query details") + ": " + QString::fromUtf8(oq.c_str());
839
    QMessageBox::information(this, tr("Query details"), desc);
834
    QMessageBox::information(this, tr("Query details"), desc);
840
}
835
}
841
836
842
void ResList::linkWasClicked(const QUrl &url)
837
void ResList::linkWasClicked(const QUrl &url)
...
...
849
    LOGDEB("ResList::linkWasClicked: [" << strurl << "]\n");
844
    LOGDEB("ResList::linkWasClicked: [" << strurl << "]\n");
850
845
851
    int what = strurl[0];
846
    int what = strurl[0];
852
    switch (what) {
847
    switch (what) {
853
848
854
    // Open abstract/snippets window
849
        // Open abstract/snippets window
855
    case 'A':
850
    case 'A':
856
    {
851
    {
857
  if (!m_source) 
852
        if (!m_source) 
858
      return;
853
            return;
859
  int i = atoi(strurl.c_str()+1) - 1;
854
        int i = atoi(strurl.c_str()+1) - 1;
860
  Rcl::Doc doc;
855
        Rcl::Doc doc;
861
  if (!getDoc(i, doc)) {
856
        if (!getDoc(i, doc)) {
862
      LOGERR("ResList::linkWasClicked: can't get doc for " << i << "\n");
857
            LOGERR("ResList::linkWasClicked: can't get doc for " << i << "\n");
863
      return;
858
            return;
864
  }
859
        }
865
  emit(showSnippets(doc));
860
        emit(showSnippets(doc));
866
    }
861
    }
867
    break;
862
    break;
868
863
869
    // Show duplicates
864
    // Show duplicates
870
    case 'D':
865
    case 'D':
871
    {
866
    {
872
  if (!m_source) 
867
        if (!m_source) 
873
      return;
868
            return;
874
  int i = atoi(strurl.c_str()+1) - 1;
869
        int i = atoi(strurl.c_str()+1) - 1;
875
  Rcl::Doc doc;
870
        Rcl::Doc doc;
876
  if (!getDoc(i, doc)) {
871
        if (!getDoc(i, doc)) {
877
      LOGERR("ResList::linkWasClicked: can't get doc for " << i << "\n");
872
            LOGERR("ResList::linkWasClicked: can't get doc for " << i << "\n");
878
      return;
873
            return;
879
  }
874
        }
880
  vector<Rcl::Doc> dups;
875
        vector<Rcl::Doc> dups;
881
  if (m_source->docDups(doc, dups) && m_rclmain) {
876
        if (m_source->docDups(doc, dups) && m_rclmain) {
882
      m_rclmain->newDupsW(doc, dups);
877
            m_rclmain->newDupsW(doc, dups);
883
  }
878
        }
884
    }
879
    }
885
    break;
880
    break;
886
881
887
    // Open parent folder
882
    // Open parent folder
888
    case 'F':
883
    case 'F':
889
    {
884
    {
890
  int i = atoi(strurl.c_str()+1) - 1;
885
        int i = atoi(strurl.c_str()+1) - 1;
891
  Rcl::Doc doc;
886
        Rcl::Doc doc;
892
  if (!getDoc(i, doc)) {
887
        if (!getDoc(i, doc)) {
893
      LOGERR("ResList::linkWasClicked: can't get doc for " << i << "\n");
888
            LOGERR("ResList::linkWasClicked: can't get doc for " << i << "\n");
894
      return;
889
            return;
895
  }
890
        }
896
        emit editRequested(ResultPopup::getParent(std::shared_ptr<DocSequence>(),
891
        emit editRequested(ResultPopup::getParent(std::shared_ptr<DocSequence>(),
897
                                                  doc));
892
                                                  doc));
898
    }
893
    }
899
    break;
894
    break;
900
895
901
    // Show query details
896
    // Show query details
902
    case 'H': 
897
    case 'H': 
903
    {
898
    {
904
  showQueryDetails();
899
        showQueryDetails();
905
  break;
900
        break;
906
    }
901
    }
907
902
908
    // Preview and edit
903
    // Preview and edit
909
    case 'P': 
904
    case 'P': 
910
    case 'E': 
905
    case 'E': 
911
    {
906
    {
912
  int i = atoi(strurl.c_str()+1) - 1;
907
        int i = atoi(strurl.c_str()+1) - 1;
913
  Rcl::Doc doc;
908
        Rcl::Doc doc;
914
  if (!getDoc(i, doc)) {
909
        if (!getDoc(i, doc)) {
915
      LOGERR("ResList::linkWasClicked: can't get doc for " << i << "\n");
910
            LOGERR("ResList::linkWasClicked: can't get doc for " << i << "\n");
916
      return;
911
            return;
917
  }
912
        }
918
  if (what == 'P') {
913
        if (what == 'P') {
919
      if (m_ismainres) {
914
            if (m_ismainres) {
920
      emit docPreviewClicked(i, doc, m_lstClckMod);
915
                emit docPreviewClicked(i, doc, m_lstClckMod);
916
            } else {
917
                emit previewRequested(doc);
918
            }
921
      } else {
919
        } else {
922
      emit previewRequested(doc);
923
      }
924
  } else {
925
      emit editRequested(doc);
920
            emit editRequested(doc);
926
  }
921
        }
927
    }
922
    }
928
    break;
923
    break;
929
924
930
    // Next/prev page
925
    // Next/prev page
931
    case 'n':
926
    case 'n':
932
  resultPageNext();
927
        resultPageNext();
933
  break;
928
        break;
934
    case 'p':
929
    case 'p':
935
  resultPageBack();
930
        resultPageBack();
936
  break;
931
        break;
937
932
938
  // Run script. Link format Rnn|Script Name
933
        // Run script. Link format Rnn|Script Name
939
    case 'R':
934
    case 'R':
940
    {
935
    {
941
  int i = atoi(strurl.c_str() + 1) - 1;
936
        int i = atoi(strurl.c_str() + 1) - 1;
942
  QString s = url.toString();
937
        QString s = url.toString();
943
  int bar = s.indexOf("|");
938
        int bar = s.indexOf("|");
944
  if (bar == -1 || bar >= s.size()-1)
939
        if (bar == -1 || bar >= s.size()-1)
945
            break;
940
            break;
946
        string cmdname = qs2utf8s(s.right(s.size() - (bar + 1)));
941
        string cmdname = qs2utf8s(s.right(s.size() - (bar + 1)));
947
        DesktopDb ddb(path_cat(theconfig->getConfDir(), "scripts"));
942
        DesktopDb ddb(path_cat(theconfig->getConfDir(), "scripts"));
948
        DesktopDb::AppDef app;
943
        DesktopDb::AppDef app;
949
        if (ddb.appByName(cmdname, app)) {
944
        if (ddb.appByName(cmdname, app)) {
...
...
954
            menuOpenWith(&act);
949
            menuOpenWith(&act);
955
        }
950
        }
956
    }
951
    }
957
    break;
952
    break;
958
953
959
  // Spelling: replacement suggestion clicked
954
    // Spelling: replacement suggestion clicked
960
    case 'S':
955
    case 'S':
961
    {
956
    {
962
        string s;
957
        string s;
963
  if (!strurl.empty())
958
        if (!strurl.empty())
964
      s = strurl.substr(1);
959
            s = strurl.substr(1);
965
        string::size_type bar = s.find_first_of("|");
960
        string::size_type bar = s.find_first_of("|");
966
  if (bar != string::npos && bar < s.size() - 1) {
961
        if (bar != string::npos && bar < s.size() - 1) {
967
      string o = s.substr(0, bar);
962
            string o = s.substr(0, bar);
968
      string n = s.substr(bar+1);
963
            string n = s.substr(bar+1);
969
            LOGDEB2("Emitting wordreplace " << o << " -> " << n << std::endl);
964
            LOGDEB2("Emitting wordreplace " << o << " -> " << n << std::endl);
970
      emit wordReplace(u8s2qs(o), u8s2qs(n));
965
            emit wordReplace(u8s2qs(o), u8s2qs(n));
971
  }
966
        }
972
    }
967
    }
973
    break;
968
    break;
974
969
975
    default: 
970
    default: 
976
  LOGERR("ResList::linkWasClicked: bad link [" << strurl << "]\n");
971
        LOGERR("ResList::linkWasClicked: bad link [" << strurl << "]\n");
977
  break;// ?? 
972
        break;// ?? 
978
    }
973
    }
979
}
974
}
980
975
981
void ResList::createPopupMenu(const QPoint& pos)
976
void ResList::createPopupMenu(const QPoint& pos)
982
{
977
{
983
    LOGDEB("ResList::createPopupMenu(" << pos.x() << ", " << pos.y() << ")\n");
978
    LOGDEB("ResList::createPopupMenu(" << pos.x() << ", " << pos.y() << ")\n");
984
#ifdef RESLIST_TEXTBROWSER
979
#if defined(USING_WEBKIT)
980
    QWebHitTestResult htr = page()->mainFrame()->hitTestContent(pos);
981
    if (htr.isNull())
982
        return;
983
    QWebElement el = htr.enclosingBlockElement();
984
    while (!el.isNull() && !el.hasAttribute("rcldocnum"))
985
        el = el.parent();
986
    if (el.isNull())
987
        return;
988
    QString snum = el.attribute("rcldocnum");
989
    m_popDoc = pageFirstDocNum() + snum.toInt();
990
#else
985
    QTextCursor cursor = cursorForPosition(pos);
991
    QTextCursor cursor = cursorForPosition(pos);
986
    int blocknum = cursor.blockNumber();
992
    int blocknum = cursor.blockNumber();
987
    LOGDEB("ResList::createPopupMenu(): block " << blocknum << "\n");
993
    LOGDEB("ResList::createPopupMenu(): block " << blocknum << "\n");
988
    m_popDoc = docnumfromparnum(blocknum);
994
    m_popDoc = docnumfromparnum(blocknum);
989
#else
990
    QWebHitTestResult htr = page()->mainFrame()->hitTestContent(pos);
991
    if (htr.isNull())
992
  return;
993
    QWebElement el = htr.enclosingBlockElement();
994
    while (!el.isNull() && !el.hasAttribute("rcldocnum"))
995
  el = el.parent();
996
    if (el.isNull())
997
  return;
998
    QString snum = el.attribute("rcldocnum");
999
    m_popDoc = pageFirstDocNum() + snum.toInt();
1000
#endif
995
#endif
1001
996
1002
    if (m_popDoc < 0) 
997
    if (m_popDoc < 0) 
1003
  return;
998
        return;
1004
    Rcl::Doc doc;
999
    Rcl::Doc doc;
1005
    if (!getDoc(m_popDoc, doc))
1000
    if (!getDoc(m_popDoc, doc))
1006
  return;
1001
        return;
1007
1002
1008
    int options =  ResultPopup::showSaveOne;
1003
    int options =  ResultPopup::showSaveOne;
1009
    if (m_ismainres)
1004
    if (m_ismainres)
1010
  options |= ResultPopup::isMain;
1005
        options |= ResultPopup::isMain;
1011
    QMenu *popup = ResultPopup::create(this, options, m_source, doc);
1006
    QMenu *popup = ResultPopup::create(this, options, m_source, doc);
1012
    popup->popup(mapToGlobal(pos));
1007
    popup->popup(mapToGlobal(pos));
1013
}
1008
}
1014
1009
1015
void ResList::menuPreview()
1010
void ResList::menuPreview()
1016
{
1011
{
1017
    Rcl::Doc doc;
1012
    Rcl::Doc doc;
1018
    if (getDoc(m_popDoc, doc)) {
1013
    if (getDoc(m_popDoc, doc)) {
1019
  if (m_ismainres) {
1014
        if (m_ismainres) {
1020
      emit docPreviewClicked(m_popDoc, doc, 0);
1015
            emit docPreviewClicked(m_popDoc, doc, 0);
1021
  } else {
1016
        } else {
1022
      emit previewRequested(doc);
1017
            emit previewRequested(doc);
1023
  }
1018
        }
1024
    }
1019
    }
1025
}
1020
}
1026
1021
1027
void ResList::menuSaveToFile()
1022
void ResList::menuSaveToFile()
1028
{
1023
{
1029
    Rcl::Doc doc;
1024
    Rcl::Doc doc;
1030
    if (getDoc(m_popDoc, doc))
1025
    if (getDoc(m_popDoc, doc))
1031
  emit docSaveToFileClicked(doc);
1026
        emit docSaveToFileClicked(doc);
1032
}
1027
}
1033
1028
1034
void ResList::menuPreviewParent()
1029
void ResList::menuPreviewParent()
1035
{
1030
{
1036
    Rcl::Doc doc;
1031
    Rcl::Doc doc;
1037
    if (getDoc(m_popDoc, doc) && m_source)  {
1032
    if (getDoc(m_popDoc, doc) && m_source)  {
1038
  Rcl::Doc pdoc = ResultPopup::getParent(m_source, doc);
1033
        Rcl::Doc pdoc = ResultPopup::getParent(m_source, doc);
1039
  if (pdoc.mimetype == "inode/directory") {
1034
        if (pdoc.mimetype == "inode/directory") {
1040
      emit editRequested(pdoc);
1035
            emit editRequested(pdoc);
1041
  } else {
1036
        } else {
1042
      emit previewRequested(pdoc);
1037
            emit previewRequested(pdoc);
1043
  }
1038
        }
1044
    }
1039
    }
1045
}
1040
}
1046
1041
1047
void ResList::menuOpenParent()
1042
void ResList::menuOpenParent()
1048
{
1043
{
1049
    Rcl::Doc doc;
1044
    Rcl::Doc doc;
1050
    if (getDoc(m_popDoc, doc) && m_source) 
1045
    if (getDoc(m_popDoc, doc) && m_source) 
1051
  emit editRequested(ResultPopup::getParent(m_source, doc));
1046
        emit editRequested(ResultPopup::getParent(m_source, doc));
1052
}
1047
}
1053
1048
1054
void ResList::menuShowSnippets()
1049
void ResList::menuShowSnippets()
1055
{
1050
{
1056
    Rcl::Doc doc;
1051
    Rcl::Doc doc;
1057
    if (getDoc(m_popDoc, doc))
1052
    if (getDoc(m_popDoc, doc))
1058
  emit showSnippets(doc);
1053
        emit showSnippets(doc);
1059
}
1054
}
1060
1055
1061
void ResList::menuShowSubDocs()
1056
void ResList::menuShowSubDocs()
1062
{
1057
{
1063
    Rcl::Doc doc;
1058
    Rcl::Doc doc;
1064
    if (getDoc(m_popDoc, doc)) 
1059
    if (getDoc(m_popDoc, doc)) 
1065
  emit showSubDocs(doc);
1060
        emit showSubDocs(doc);
1066
}
1061
}
1067
1062
1068
void ResList::menuEdit()
1063
void ResList::menuEdit()
1069
{
1064
{
1070
    Rcl::Doc doc;
1065
    Rcl::Doc doc;
1071
    if (getDoc(m_popDoc, doc))
1066
    if (getDoc(m_popDoc, doc))
1072
  emit editRequested(doc);
1067
        emit editRequested(doc);
1073
}
1068
}
1074
void ResList::menuOpenWith(QAction *act)
1069
void ResList::menuOpenWith(QAction *act)
1075
{
1070
{
1076
    if (act == 0)
1071
    if (act == 0)
1077
        return;
1072
        return;
1078
    string cmd = qs2utf8s(act->data().toString());
1073
    string cmd = qs2utf8s(act->data().toString());
1079
    Rcl::Doc doc;
1074
    Rcl::Doc doc;
1080
    if (getDoc(m_popDoc, doc))
1075
    if (getDoc(m_popDoc, doc))
1081
  emit openWithRequested(doc, cmd);
1076
        emit openWithRequested(doc, cmd);
1082
}
1077
}
1083
1078
1084
void ResList::menuCopyFN()
1079
void ResList::menuCopyFN()
1085
{
1080
{
1086
    Rcl::Doc doc;
1081
    Rcl::Doc doc;
1087
    if (getDoc(m_popDoc, doc))
1082
    if (getDoc(m_popDoc, doc))
1088
  ResultPopup::copyFN(doc);
1083
        ResultPopup::copyFN(doc);
1089
}
1084
}
1090
1085
1091
void ResList::menuCopyURL()
1086
void ResList::menuCopyURL()
1092
{
1087
{
1093
    Rcl::Doc doc;
1088
    Rcl::Doc doc;
1094
    if (getDoc(m_popDoc, doc))
1089
    if (getDoc(m_popDoc, doc))
1095
  ResultPopup::copyURL(doc);
1090
        ResultPopup::copyURL(doc);
1096
}
1091
}
1097
1092
1098
void ResList::menuExpand()
1093
void ResList::menuExpand()
1099
{
1094
{
1100
    Rcl::Doc doc;
1095
    Rcl::Doc doc;
1101
    if (getDoc(m_popDoc, doc))
1096
    if (getDoc(m_popDoc, doc))
1102
  emit docExpand(doc);
1097
        emit docExpand(doc);
1103
}
1098
}
1099
1104
int ResList::pageFirstDocNum()
1100
int ResList::pageFirstDocNum()
1105
{
1101
{
1106
    return m_pager->pageFirstDocNum();
1102
    return m_pager->pageFirstDocNum();
1107
}
1103
}
1108