Switch to unified view

a/src/qtgui/preview_w.cpp b/src/qtgui/preview_w.cpp
...
...
33
#include <qvariant.h>
33
#include <qvariant.h>
34
#include <qpushbutton.h>
34
#include <qpushbutton.h>
35
#include <qtabwidget.h>
35
#include <qtabwidget.h>
36
#include <qprinter.h>
36
#include <qprinter.h>
37
#include <qprintdialog.h>
37
#include <qprintdialog.h>
38
#include <qscrollbar.h>
38
39
39
#if (QT_VERSION < 0x040000)
40
#include <qmenu.h>
40
#include <qtextedit.h>
41
#include <qtextedit.h>
41
#include <qpopupmenu.h>
42
#include <qprogressdialog.h>
42
#include <qprogressdialog.h>
43
#define THRFINISHED finished
44
#include <qpaintdevicemetrics.h>
45
#include <qsimplerichtext.h>
46
#else
47
#include <q3popupmenu.h>
48
#include <q3textedit.h>
49
#include <q3progressdialog.h>
50
#include <q3stylesheet.h>
51
#include <q3paintdevicemetrics.h>
52
#define QPaintDeviceMetrics Q3PaintDeviceMetrics
53
#include <q3simplerichtext.h>
54
#define QSimpleRichText Q3SimpleRichText
55
#define THRFINISHED isFinished
56
#endif
57
58
#include <qevent.h>
43
#include <qevent.h>
59
#include <qlabel.h>
44
#include <qlabel.h>
60
#include <qlineedit.h>
45
#include <qlineedit.h>
61
#include <qcheckbox.h>
46
#include <qcheckbox.h>
62
#include <qlayout.h>
47
#include <qlayout.h>
...
...
74
#include "wipedir.h"
59
#include "wipedir.h"
75
#include "cancelcheck.h"
60
#include "cancelcheck.h"
76
#include "preview_w.h"
61
#include "preview_w.h"
77
#include "guiutils.h"
62
#include "guiutils.h"
78
#include "docseqhist.h"
63
#include "docseqhist.h"
79
80
#if (QT_VERSION < 0x030300)
81
#define wasCanceled wasCancelled
82
#endif
83
84
#if (QT_VERSION < 0x040000)
85
#include <qtextedit.h>
86
#include <private/qrichtext_p.h>
87
#define QTEXTEDIT QTextEdit
88
#define QTEXTCURSOR QTextCursor
89
#define QTEXTPARAGRAPH QTextParagraph
90
#define QTEXTSTRINGCHAR QTextStringChar
91
#else
92
#include <q3textedit.h>
93
#include "q3richtext_p.h"
94
#define QTEXTEDIT Q3TextEdit
95
#define QTEXTCURSOR Q3TextCursor
96
#define QTEXTPARAGRAPH Q3TextParagraph
97
#define QTEXTSTRINGCHAR Q3TextStringChar
98
#endif
99
100
#include "rclhelp.h"
64
#include "rclhelp.h"
101
65
102
#ifndef MIN
66
#ifndef MIN
103
#define MIN(A,B) ((A)<(B)?(A):(B))
67
#define MIN(A,B) ((A)<(B)?(A):(B))
104
#endif
68
#endif
105
69
106
// QTextEdit's scrollToAnchor() is supposed to make the anchor visible, but
70
// Subclass plainToRich to add <termtag>s and anchors to the preview text
107
// actually, it only moves to the top of the paragraph containing the anchor.
71
class PlainToRichQtPreview : public PlainToRich {
108
// As we only have one paragraph, this doesnt' help a lot (qt3 and qt4)
72
public:
109
//
73
    int lastanchor;
110
// So, had to write a different function, inspired from what 
74
    PlainToRichQtPreview() 
111
// qtextedit::find() does, instead. This ones actually moves the
112
// cursor, which is probably not necessary, but does what we need.
113
//
114
// Problem is, it uses the sem-private qrichtext_p.h, which is not
115
// even installed under qt4. We use a local copy, which is not nice.
116
void PreviewTextEdit::moveToAnchor(const QString& name)
117
{
118
    LOGDEB0(("PreviewTextEdit::moveToAnchor\n"));
119
    if (name.isEmpty())
120
  return;
121
    sync();
122
    QTEXTCURSOR l_cursor(document());
123
    QTEXTPARAGRAPH* last = document()->lastParagraph();
124
    for (;;) {
125
  QTEXTSTRINGCHAR* c = l_cursor.paragraph()->at(l_cursor.index());
126
  if(c->isAnchor()) {
127
      QString a = c->anchorName();
128
      if ( a == name ||
129
       (a.contains( '#' ) && 
130
        QStringList::split('#', a).contains(name))) {
131
      
132
      *(textCursor())  = l_cursor;
133
      ensureCursorVisible();
134
      break;
135
      }
136
  }
137
  if (l_cursor.paragraph() == last && l_cursor.atParagEnd())
138
      break;
139
  l_cursor.gotoNextLetter();
140
    }
75
    {
141
}
76
  lastanchor = 0;
142
77
    }    
143
78
    virtual ~PlainToRichQtPreview() {}
144
#if (QT_VERSION >= 0x040000)
79
    virtual string header() {
145
80
  if (m_inputhtml) {
146
// Had to reimplement Qtextdocument::find() by duplicating the qt3
81
      return snull;
147
// version.  The version in qt4 qt3support was modified for some
148
// unknown reason and exhibits quadratic behaviour, and is totally
149
// unusable on big documents
150
static bool QTextDocument_find(Q3TextDocument *doc, Q3TextCursor& cursor, 
151
                               const QString &expr, bool cs, bool wo, 
152
                               bool forward)
153
{
154
    Qt::CaseSensitivity caseSensitive = cs ? Qt::CaseSensitive : 
155
        Qt::CaseInsensitive;
156
157
    doc->removeSelection(Q3TextDocument::Standard);
158
    Q3TextParagraph *p = 0;
159
    if ( expr.isEmpty() )
160
  return FALSE;
161
    for (;;) {
162
  if ( p != cursor.paragraph() ) {
163
      p = cursor.paragraph();
164
      QString s = cursor.paragraph()->string()->toString();
165
      int start = cursor.index();
166
      for ( ;; ) {
167
      int res = forward ? s.indexOf(expr, start, caseSensitive ) : 
168
                    s.lastIndexOf(expr, start, caseSensitive);
169
      int end = res + expr.length();
170
      if ( res == -1 || ( !forward && start <= res ) )
171
          break;
172
      if (!wo || ((res == 0||s[res - 1].isSpace() || 
173
                             s[res - 1].isPunct()) &&
174
                            (end == (int)s.length() || s[end].isSpace() || 
175
                             s[end].isPunct()))) {
176
          doc->removeSelection(Q3TextDocument::Standard);
177
          cursor.setIndex( forward ? end : res );
178
          doc->setSelectionStart(Q3TextDocument::Standard, cursor);
179
          cursor.setIndex( forward ? res : end );
180
          doc->setSelectionEnd(Q3TextDocument::Standard, cursor);
181
          if ( !forward )
182
          cursor.setIndex( res );
183
          return TRUE;
184
      }
185
      start = res + (forward ? 1 : -1);
186
      }
187
  }
188
  if ( forward ) {
189
      if ( cursor.paragraph() == doc->lastParagraph() && 
190
                 cursor.atParagEnd() )
191
       break;
192
      cursor.gotoNextLetter();
193
    } else {
82
    } else {
194
      if ( cursor.paragraph() == doc->firstParagraph() && 
83
      return string("<qt><head><title></title></head><body><pre>");
195
                 cursor.atParagStart() )
196
       break;
197
      cursor.gotoPreviousLetter();
198
    }
84
    }
85
    }
86
    virtual string startMatch() 
199
    }
87
    {
200
    return FALSE;
88
  return string("<span style='color: ")
89
      + string((const char *)(prefs.qtermcolor.utf8()))
90
      + string(";font-weight: bold;")
91
      + string("'>");
92
    }
93
    virtual string endMatch() {return string("</span>");}
94
    virtual string termAnchorName(int i) {
95
  static const char *termAnchorNameBase = "TRM";
96
  char acname[sizeof(termAnchorNameBase) + 20];
97
  sprintf(acname, "%s%d", termAnchorNameBase, i);
98
  if (i > lastanchor)
99
      lastanchor = i;
100
  return string(acname);
101
    }
201
102
103
    virtual string startAnchor(int i) {
104
  return string("<a name=\"") + termAnchorName(i) + "\">";
105
    }
106
    virtual string endAnchor() {
107
  return string("</a>");
108
    }
109
    virtual string startChunk() { return "<pre>";}
202
}
110
};
203
111
204
bool PreviewTextEdit::find(const QString &expr, bool cs, bool wo,
112
PreviewTextEdit::PreviewTextEdit(QWidget* parent,const char* name, Preview *pv) 
205
                           bool forward, int *para, int *index)
113
    : QTextEdit(parent, name), m_preview(pv), m_dspflds(false)
206
{
114
{
207
    drawCursor(false);
115
    setContextMenuPolicy(Qt::CustomContextMenu);
208
#ifndef QT_NO_CURSOR
116
    connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
209
    viewport()->setCursor(isReadOnly() ? Qt::ArrowCursor : Qt::IBeamCursor);
117
      this, SLOT(createPopupMenu(const QPoint&)));
210
#endif
118
    m_plaintorich = new PlainToRichQtPreview();
211
    Q3TextCursor findcur = *textCursor();
212
    if (para && index) {
213
        if (document()->paragAt(*para))
214
            findcur.gotoPosition(document()->paragAt(*para), *index);
215
        else
216
            findcur.gotoEnd();
217
    } else if (document()->hasSelection(Q3TextDocument::Standard)){
218
        // maks sure we do not find the same selection again
219
        if (forward)
220
            findcur.gotoNextLetter();
221
        else
222
            findcur.gotoPreviousLetter();
223
    } else if (!forward && findcur.index() == 0 && findcur.paragraph() == findcur.topParagraph()) {
224
        findcur.gotoEnd();
225
    }
226
    removeSelection(Q3TextDocument::Standard);
227
    bool found = QTextDocument_find(document(), findcur, expr, cs, wo, forward);
228
    if (found) {
229
        if (para)
230
            *para = findcur.paragraph()->paragId();
231
        if (index)
232
            *index = findcur.index();
233
        *textCursor() = findcur;
234
        repaintChanged();
235
        ensureCursorVisible();
236
    }
237
    drawCursor(true);
238
    if (found) {
239
        emit cursorPositionChanged(textCursor());
240
        emit cursorPositionChanged(textCursor()->paragraph()->paragId(), 
241
                                   textCursor()->index());
242
    }
243
    return found;
244
}
119
}
245
120
246
#endif
121
PreviewTextEdit::~PreviewTextEdit()
122
{
123
    delete m_plaintorich;
124
}
247
125
248
void Preview::init()
126
void Preview::init()
249
{
127
{
250
    setName("Preview");
128
    setName("Preview");
251
    setSizePolicy( QSizePolicy((QSizePolicy::SizeType)5, 
129
    setSizePolicy( QSizePolicy((QSizePolicy::SizeType)5, 
...
...
298
    nextButton->setText(tr("&Next"));
176
    nextButton->setText(tr("&Next"));
299
    prevButton->setText(tr("&Previous"));
177
    prevButton->setText(tr("&Previous"));
300
    clearPB->setText(tr("Clear"));
178
    clearPB->setText(tr("Clear"));
301
    matchCheck->setText(tr("Match &Case"));
179
    matchCheck->setText(tr("Match &Case"));
302
180
303
#if 0
304
    // Couldn't get a small button really in the corner. stays on the left of
305
    // the button area and looks ugly
306
    QPixmap px = QPixmap::fromMimeSource("cancel.png");
307
    QPushButton * bt = new QPushButton(px, "", this);
308
    bt->setFixedSize(px.size());
309
#else
310
    QPushButton * bt = new QPushButton(tr("Close Tab"), this);
181
    QPushButton * bt = new QPushButton(tr("Close Tab"), this);
311
#endif
312
313
    pvTab->setCornerWidget(bt);
182
    pvTab->setCornerWidget(bt);
314
183
315
    (void)new HelpClient(this);
184
    (void)new HelpClient(this);
316
    HelpClient::installMap(this->name(), "RCL.SEARCH.PREVIEW");
185
    HelpClient::installMap(this->name(), "RCL.SEARCH.PREVIEW");
317
186
...
...
351
    emit previewExposed(this, m_searchId, -1);
220
    emit previewExposed(this, m_searchId, -1);
352
    emit previewClosed(this);
221
    emit previewClosed(this);
353
    QWidget::closeEvent(e);
222
    QWidget::closeEvent(e);
354
}
223
}
355
224
225
extern const char *eventTypeToStr(int tp);
226
356
bool Preview::eventFilter(QObject *target, QEvent *event)
227
bool Preview::eventFilter(QObject *target, QEvent *event)
357
{
228
{
358
    LOGDEB2(("Preview::eventFilter()\n"));
359
    if (event->type() != QEvent::KeyPress) 
229
    if (event->type() != QEvent::KeyPress) {
230
#if 0
231
    LOGDEB(("Preview::eventFilter(): %s\n", eventTypeToStr(event->type())));
232
  if (event->type() == QEvent::MouseButtonRelease) {
233
      QMouseEvent *mev = (QMouseEvent *)event;
234
      LOGDEB(("Mouse: GlobalY %d y %d\n", mev->globalY(),
235
          mev->y()));
236
  }
237
#endif
360
    return false;
238
    return false;
239
    }
361
    
240
    
362
    LOGDEB2(("Preview::eventFilter: keyEvent\n"));
241
    LOGDEB2(("Preview::eventFilter: keyEvent\n"));
363
242
364
    PreviewTextEdit *edit = currentEditor();
243
    PreviewTextEdit *edit = currentEditor();
365
    QKeyEvent *keyEvent = (QKeyEvent *)event;
244
    QKeyEvent *keyEvent = (QKeyEvent *)event;
...
...
370
    } else if (keyEvent->key() == Qt::Key_Escape) {
249
    } else if (keyEvent->key() == Qt::Key_Escape) {
371
    close();
250
    close();
372
    return true;
251
    return true;
373
    } else if (keyEvent->key() == Qt::Key_Down &&
252
    } else if (keyEvent->key() == Qt::Key_Down &&
374
           (keyEvent->state() & Qt::ShiftButton)) {
253
           (keyEvent->state() & Qt::ShiftButton)) {
375
    // LOGDEB(("Preview::eventFilter: got Shift-Up\n"));
254
    LOGDEB2(("Preview::eventFilter: got Shift-Up\n"));
376
    if (edit) 
255
    if (edit) 
377
        emit(showNext(this, m_searchId, edit->m_data.docnum));
256
        emit(showNext(this, m_searchId, edit->m_data.docnum));
378
    return true;
257
    return true;
379
    } else if (keyEvent->key() == Qt::Key_Up &&
258
    } else if (keyEvent->key() == Qt::Key_Up &&
380
           (keyEvent->state() & Qt::ShiftButton)) {
259
           (keyEvent->state() & Qt::ShiftButton)) {
381
    // LOGDEB(("Preview::eventFilter: got Shift-Down\n"));
260
    LOGDEB2(("Preview::eventFilter: got Shift-Down\n"));
382
    if (edit) 
261
    if (edit) 
383
        emit(showPrev(this, m_searchId, edit->m_data.docnum));
262
        emit(showPrev(this, m_searchId, edit->m_data.docnum));
384
    return true;
263
    return true;
385
    } else if (keyEvent->key() == Qt::Key_W &&
264
    } else if (keyEvent->key() == Qt::Key_W &&
386
           (keyEvent->state() & Qt::ControlButton)) {
265
           (keyEvent->state() & Qt::ControlButton)) {
387
    // LOGDEB(("Preview::eventFilter: got ^W\n"));
266
    LOGDEB2(("Preview::eventFilter: got ^W\n"));
388
    closeCurrentTab();
267
    closeCurrentTab();
389
    return true;
268
    return true;
390
    } else if (keyEvent->key() == Qt::Key_P &&
269
    } else if (keyEvent->key() == Qt::Key_P &&
391
           (keyEvent->state() & Qt::ControlButton)) {
270
           (keyEvent->state() & Qt::ControlButton)) {
392
    // LOGDEB(("Preview::eventFilter: got ^P\n"));
271
    LOGDEB2(("Preview::eventFilter: got ^P\n"));
393
    emit(printCurrentPreviewRequest());
272
    emit(printCurrentPreviewRequest());
394
    return true;
273
    return true;
395
    } else if (m_dynSearchActive) {
274
    } else if (m_dynSearchActive) {
396
    if (keyEvent->key() == Qt::Key_F3) {
275
    if (keyEvent->key() == Qt::Key_F3) {
276
      LOGDEB2(("Preview::eventFilter: got F3\n"));
397
        doSearch(searchTextLine->text(), true, false);
277
        doSearch(searchTextLine->text(), true, false);
398
        return true;
278
        return true;
399
    }
279
    }
400
    if (target != searchTextLine)
280
    if (target != searchTextLine)
401
        return QApplication::sendEvent(searchTextLine, event);
281
        return QApplication::sendEvent(searchTextLine, event);
402
    } else {
282
    } else {
403
  if (edit && target == edit) {
283
  if (edit && 
284
      (target == edit || target == edit->viewport())) {
404
        if (keyEvent->key() == Qt::Key_Slash) {
285
        if (keyEvent->key() == Qt::Key_Slash) {
286
      LOGDEB2(("Preview::eventFilter: got /\n"));
405
        searchTextLine->setFocus();
287
        searchTextLine->setFocus();
406
        m_dynSearchActive = true;
288
        m_dynSearchActive = true;
407
        return true;
289
        return true;
408
        } else if (keyEvent->key() == Qt::Key_Space) {
290
        } else if (keyEvent->key() == Qt::Key_Space) {
409
      edit->scrollBy(0, edit->visibleHeight());
291
      LOGDEB2(("Preview::eventFilter: got Space\n"));
292
      int value = edit->verticalScrollBar()->value();
293
      value += edit->verticalScrollBar()->pageStep();
294
      edit->verticalScrollBar()->setValue(value);
410
        return true;
295
        return true;
411
        } else if (keyEvent->key() == Qt::Key_BackSpace) {
296
        } else if (keyEvent->key() == Qt::Key_BackSpace) {
412
      edit->scrollBy(0, -edit->visibleHeight());
297
      LOGDEB2(("Preview::eventFilter: got Backspace\n"));
298
      int value = edit->verticalScrollBar()->value();
299
      value -= edit->verticalScrollBar()->pageStep();
300
      edit->verticalScrollBar()->setValue(value);
413
        return true;
301
        return true;
414
        }
302
        }
415
    }
303
    }
416
    }
304
    }
417
305
...
...
433
    clearPB->setEnabled(true);
321
    clearPB->setEnabled(true);
434
    doSearch(text, false, false);
322
    doSearch(text, false, false);
435
    }
323
    }
436
}
324
}
437
325
438
#if (QT_VERSION >= 0x040000)
439
#define QProgressDialog Q3ProgressDialog
440
#define QStyleSheetItem Q3StyleSheetItem
441
#endif
442
443
PreviewTextEdit *Preview::currentEditor()
326
PreviewTextEdit *Preview::currentEditor()
444
{
327
{
445
    LOGDEB2(("Preview::currentEditor()\n"));
328
    LOGDEB2(("Preview::currentEditor()\n"));
446
    QWidget *tw = pvTab->currentPage();
329
    QWidget *tw = pvTab->currentPage();
447
    PreviewTextEdit *edit = 0;
330
    PreviewTextEdit *edit = 0;
...
...
469
    // ??
352
    // ??
470
    return;
353
    return;
471
    }
354
    }
472
355
473
    if (text.isEmpty()) {
356
    if (text.isEmpty()) {
474
    if (m_haveAnchors == false)
357
    if (m_haveAnchors == false) {
358
      LOGDEB(("NO ANCHORS\n"));
475
        return;
359
        return;
360
  }
476
    if (reverse) {
361
    if (reverse) {
477
        if (m_curAnchor == 1)
362
        if (m_curAnchor == 1)
478
        m_curAnchor = m_plaintorich.lastanchor;
363
        m_curAnchor = edit->m_plaintorich->lastanchor;
479
        else
364
        else
480
        m_curAnchor--;
365
        m_curAnchor--;
481
    } else {
366
    } else {
482
        if (m_curAnchor == m_plaintorich.lastanchor)
367
        if (m_curAnchor == edit->m_plaintorich->lastanchor)
483
        m_curAnchor = 1;
368
        m_curAnchor = 1;
484
        else
369
        else
485
        m_curAnchor++;
370
        m_curAnchor++;
486
    }
371
    }
372
  LOGDEB(("m_curAnchor: %d\n", m_curAnchor));
487
    QString aname = 
373
    QString aname = 
488
       QString::fromUtf8(m_plaintorich.termAnchorName(m_curAnchor).c_str());
374
       QString::fromUtf8(edit->m_plaintorich->termAnchorName(m_curAnchor).c_str());
375
  LOGDEB(("Calling scrollToAnchor(%s)\n", (const char *)aname.utf8()));
489
    edit->moveToAnchor(aname);
376
    edit->scrollToAnchor(aname);
377
  // Position the cursor approximately at the anchor (top of
378
  // viewport) so that searches start from here
379
  QTextCursor cursor = edit->cursorForPosition(QPoint(0, 0));
380
  edit->setTextCursor(cursor);
490
    return;
381
    return;
491
    }
382
    }
492
383
493
    // If next is false, the user added characters to the current
384
    // If next is false, the user added characters to the current
494
    // search string.  We need to reset the cursor position to the
385
    // search string.  We need to reset the cursor position to the
495
    // start of the previous match, else incremental search is going
386
    // start of the previous match, else incremental search is going
496
    // to look for the next occurrence instead of trying to lenghten
387
    // to look for the next occurrence instead of trying to lenghten
497
    // the current match
388
    // the current match
498
    if (!next) {
389
    if (!next) {
499
  int ps, is, pe, ie;
390
  QTextCursor cursor = edit->textCursor();
500
  edit->getSelection(&ps, &is, &pe, &ie);
391
  cursor.setPosition(cursor.anchor(), QTextCursor::KeepAnchor);
501
  if (is > 0)
392
  edit->setTextCursor(cursor);
502
      is--;
503
  else if (ps > 0)
504
      ps--;
505
  LOGDEB(("Preview::doSearch: setting cursor to %d %d\n", ps, is));
506
  edit->setCursorPosition(ps, is);
507
    }
393
    }
508
    Chrono chron;
394
    Chrono chron;
509
    LOGDEB(("Preview::doSearch: first find call\n"));
395
    LOGDEB(("Preview::doSearch: first find call\n"));
510
    bool found = edit->find(text, matchCase, wordOnly, !reverse, 0, 0);
396
    QTextDocument::FindFlags flags = 0;
397
    if (reverse)
398
  flags |= QTextDocument::FindBackward;
399
    if (wordOnly)
400
  flags |= QTextDocument::FindWholeWords;
401
    if (matchCase)
402
  flags |= QTextDocument::FindCaseSensitively;
403
    bool found = edit->find(text, flags);
511
    LOGDEB(("Preview::doSearch: first find call return: %.2f S\n", 
404
    LOGDEB(("Preview::doSearch: first find call return: found %d %.2f S\n", 
512
            chron.secs()));
405
            found, chron.secs()));
513
    // If not found, try to wrap around. 
406
    // If not found, try to wrap around. 
514
    if (!found && next) { 
407
    if (!found) { 
515
    LOGDEB(("Preview::doSearch: wrapping around\n"));
408
    LOGDEB(("Preview::doSearch: wrapping around\n"));
516
  int mspara, msindex;
517
    if (reverse) {
409
    if (reverse) {
518
      mspara = edit->paragraphs();
410
      edit->moveCursor (QTextCursor::End);
519
      msindex = edit->paragraphLength(mspara);
520
    } else {
411
    } else {
521
      mspara = msindex = 0;
412
      edit->moveCursor (QTextCursor::Start);
522
    }
413
    }
523
    LOGDEB(("Preview::doSearch: 2nd find call\n"));
414
    LOGDEB(("Preview::doSearch: 2nd find call\n"));
524
        chron.restart();
415
        chron.restart();
525
  found = edit->find(text,matchCase, false, !reverse, &mspara, &msindex);
416
  found = edit->find(text, flags);
526
    LOGDEB(("Preview::doSearch: 2nd find call return %.2f S\n",
417
    LOGDEB(("Preview::doSearch: 2nd find call return found %d %.2f S\n",
527
                chron.secs()));
418
                found, chron.secs()));
528
    }
419
    }
529
420
530
    if (found) {
421
    if (found) {
531
    m_canBeep = true;
422
    m_canBeep = true;
532
    } else {
423
    } else {
...
...
564
    }
455
    }
565
    edit->setFocus();
456
    edit->setFocus();
566
    // Connect doubleclick but cleanup first just in case this was
457
    // Connect doubleclick but cleanup first just in case this was
567
    // already connected.
458
    // already connected.
568
    disconnect(edit, SIGNAL(doubleClicked(int, int)), this, 0);
459
    disconnect(edit, SIGNAL(doubleClicked(int, int)), this, 0);
569
    connect(edit, SIGNAL(doubleClicked(int, int)), 
570
      this, SLOT(textDoubleClicked(int, int)));
571
    // Disconnect the print signal and reconnect it to the current editor
460
    // Disconnect the print signal and reconnect it to the current editor
572
    LOGDEB(("Disconnecting reconnecting print signal\n"));
461
    LOGDEB(("Disconnecting reconnecting print signal\n"));
573
    disconnect(this, SIGNAL(printCurrentPreviewRequest()), 0, 0);
462
    disconnect(this, SIGNAL(printCurrentPreviewRequest()), 0, 0);
574
    connect(this, SIGNAL(printCurrentPreviewRequest()), edit, SLOT(print()));
463
    connect(this, SIGNAL(printCurrentPreviewRequest()), edit, SLOT(print()));
575
#if (QT_VERSION >= 0x040000)
576
    connect(edit, SIGNAL(selectionChanged()), this, SLOT(selecChanged()));
577
#endif
578
    tw->installEventFilter(this);
579
    edit->installEventFilter(this);
464
    edit->installEventFilter(this);
465
    edit->viewport()->installEventFilter(this);
466
    searchTextLine->installEventFilter(this);
580
    emit(previewExposed(this, m_searchId, edit->m_data.docnum));
467
    emit(previewExposed(this, m_searchId, edit->m_data.docnum));
581
}
582
583
#if (QT_VERSION >= 0x040000)
584
// I have absolutely no idea why this nonsense is needed to get
585
// q3textedit to copy to x11 primary selection when text is
586
// selected. This used to be automatic, and, looking at the code, it
587
// should happen inside q3textedit (the code here is copied from the
588
// private copyToClipboard method). To be checked again with a later
589
// qt version.
590
void Preview::selecChanged()
591
{
592
    LOGDEB1(("Preview::selecChanged\n"));
593
    if (!m_currentW)
594
  return;
595
    PreviewTextEdit *edit = (PreviewTextEdit*)m_currentW->child("pvEdit");
596
    if (edit == 0) {
597
  LOGERR(("Editor child not found\n"));
598
  return;
599
    }
600
    QClipboard *clipboard = QApplication::clipboard();
601
    if (edit->hasSelectedText()) {
602
  LOGDEB1(("Copying [%s] to primary selection.Clipboard sel supp: %d\n", 
603
      (const char *)edit->selectedText().ascii(),
604
      clipboard->supportsSelection()));
605
        disconnect(QApplication::clipboard(), SIGNAL(selectionChanged()), 
606
         edit, 0);
607
  clipboard->setText(edit->selectedText(), QClipboard::Selection);
608
        connect(QApplication::clipboard(), SIGNAL(selectionChanged()),
609
      edit, SLOT(clipboardChanged()));
610
    }
611
}
612
#else 
613
void Preview::selecChanged(){}
614
#endif
615
616
void Preview::textDoubleClicked(int, int)
617
{
618
    LOGDEB2(("Preview::textDoubleClicked\n"));
619
    if (!m_currentW)
620
  return;
621
    PreviewTextEdit *edit = (PreviewTextEdit *)m_currentW->child("pvEdit");
622
    if (edit == 0) {
623
  LOGERR(("Editor child not found\n"));
624
  return;
625
    }
626
    if (edit->hasSelectedText())
627
  emit(wordSelect(edit->selectedText()));
628
}
468
}
629
469
630
void Preview::closeCurrentTab()
470
void Preview::closeCurrentTab()
631
{
471
{
632
    LOGDEB1(("Preview::closeCurrentTab: m_loading %d\n", m_loading));
472
    LOGDEB1(("Preview::closeCurrentTab: m_loading %d\n", m_loading));
...
...
705
{
545
{
706
    LOGDEB(("Preview::makeDocCurrent: %s\n", doc.url.c_str()));
546
    LOGDEB(("Preview::makeDocCurrent: %s\n", doc.url.c_str()));
707
547
708
    /* Check if we already have this page */
548
    /* Check if we already have this page */
709
    for (int i = 0; i < pvTab->count(); i++) {
549
    for (int i = 0; i < pvTab->count(); i++) {
710
#if (QT_VERSION < 0x040000)
711
        QWidget *tw = pvTab->page(i);
712
#else
713
        QWidget *tw = pvTab->widget(i);
550
        QWidget *tw = pvTab->widget(i);
714
#endif
715
        if (tw) {
551
        if (tw) {
716
            PreviewTextEdit *edit = 
552
            PreviewTextEdit *edit = 
717
                dynamic_cast<PreviewTextEdit*>(tw->child("pvEdit"));
553
                dynamic_cast<PreviewTextEdit*>(tw->child("pvEdit"));
718
            if (edit && !edit->m_data.url.compare(doc.url) && 
554
            if (edit && !edit->m_data.url.compare(doc.url) && 
719
                !edit->m_data.ipath.compare(doc.ipath)) {
555
                !edit->m_data.ipath.compare(doc.ipath)) {
...
...
732
    closeCurrentTab();
568
    closeCurrentTab();
733
    return false;
569
    return false;
734
    }
570
    }
735
    raise();
571
    raise();
736
    return true;
572
    return true;
573
}
574
575
void Preview::emitWordSelect(QString word)
576
{
577
    emit(wordSelect(word));
737
}
578
}
738
579
739
/*
580
/*
740
  Code for loading a file into an editor window. The operations that
581
  Code for loading a file into an editor window. The operations that
741
  we call have no provision to indicate progression, and it would be
582
  we call have no provision to indicate progression, and it would be
...
...
820
        *statusp = -1;
661
        *statusp = -1;
821
    }
662
    }
822
    }
663
    }
823
};
664
};
824
665
666
825
// Insert into editor by chunks so that the top becomes visible
667
// Insert into editor by chunks so that the top becomes visible
826
// earlier for big texts. This provokes some artifacts (adds empty line),
668
// earlier for big texts. This provokes some artifacts (adds empty line),
827
// so we can't set it too low.
669
// so we can't set it too low.
828
#define CHUNKL 500*1000
670
#define CHUNKL 500*1000
829
671
...
...
831
class ToRichThread : public QThread {
673
class ToRichThread : public QThread {
832
    string &in;
674
    string &in;
833
    const HiliteData &hdata;
675
    const HiliteData &hdata;
834
    list<string> &out;
676
    list<string> &out;
835
    int loglevel;
677
    int loglevel;
836
    PlainToRichQtPreview& ptr;
678
    PlainToRichQtPreview *ptr;
837
 public:
679
 public:
838
    ToRichThread(string &i, const HiliteData& hd, list<string> &o, 
680
    ToRichThread(string &i, const HiliteData& hd, list<string> &o, 
839
         PlainToRichQtPreview& _ptr)
681
         PlainToRichQtPreview *_ptr)
840
    : in(i), hdata(hd), out(o), ptr(_ptr)
682
    : in(i), hdata(hd), out(o), ptr(_ptr)
841
    {
683
    {
842
        loglevel = DebugLog::getdbl()->getlevel();
684
        loglevel = DebugLog::getdbl()->getlevel();
843
    }
685
    }
844
    virtual void run()
686
    virtual void run()
845
    {
687
    {
846
    DebugLog::getdbl()->setloglevel(loglevel);
688
    DebugLog::getdbl()->setloglevel(loglevel);
847
    try {
689
    try {
848
        ptr.plaintorich(in, out, hdata, CHUNKL);
690
        ptr->plaintorich(in, out, hdata, CHUNKL);
849
    } catch (CancelExcept) {
691
    } catch (CancelExcept) {
850
    }
692
    }
851
    }
693
    }
852
};
694
};
853
695
...
...
887
    .arg(QString::fromLocal8Bit(idoc.url.c_str()))
729
    .arg(QString::fromLocal8Bit(idoc.url.c_str()))
888
    .arg(QString::fromAscii(idoc.fbytes.c_str()));
730
    .arg(QString::fromAscii(idoc.fbytes.c_str()));
889
731
890
    // Create progress dialog and aux objects
732
    // Create progress dialog and aux objects
891
    const int nsteps = 20;
733
    const int nsteps = 20;
892
    QProgressDialog progress(msg, tr("Cancel"), nsteps, this, "Loading", FALSE);
734
    QProgressDialog progress(msg, tr("Cancel"), 0, nsteps, this);
893
    progress.setMinimumDuration(2000);
735
    progress.setMinimumDuration(2000);
894
    WaiterThread waiter(100);
736
    WaiterThread waiter(100);
895
737
896
    // Load and convert document
738
    // Load and convert document
897
    // idoc came out of the index data (main text and other fields missing). 
739
    // idoc came out of the index data (main text and other fields missing). 
...
...
902
    lthr.start();
744
    lthr.start();
903
    int prog;
745
    int prog;
904
    for (prog = 1;;prog++) {
746
    for (prog = 1;;prog++) {
905
    waiter.start();
747
    waiter.start();
906
    waiter.wait();
748
    waiter.wait();
907
  if (lthr.THRFINISHED ())
749
  if (lthr.isFinished())
908
        break;
750
        break;
909
  progress.setProgress(prog , prog <= nsteps-1 ? nsteps : prog+1);
751
  progress.setValue(prog);
910
    qApp->processEvents();
752
    qApp->processEvents();
911
    if (progress.wasCanceled()) {
753
    if (progress.wasCanceled()) {
912
        CancelCheck::instance().setCancel();
754
        CancelCheck::instance().setCancel();
913
    }
755
    }
914
    if (prog >= 5)
756
    if (prog >= 5)
...
...
964
    const int listl = sizeof(textlist) / sizeof(char*);
806
    const int listl = sizeof(textlist) / sizeof(char*);
965
    for (int i = 0 ; i < listl ; i++)
807
    for (int i = 0 ; i < listl ; i++)
966
        qrichlst.push_back(QString::fromUtf8(textlist[i]));
808
        qrichlst.push_back(QString::fromUtf8(textlist[i]));
967
#else
809
#else
968
    if (highlightTerms) {
810
    if (highlightTerms) {
969
  QStyleSheetItem *item = 
970
      new QStyleSheetItem(editor->styleSheet(), "termtag" );
971
  item->setColor(prefs.qtermcolor);
972
  item->setFontWeight(QFont::Bold);
973
    progress.setLabelText(tr("Creating preview text"));
811
    progress.setLabelText(tr("Creating preview text"));
974
    qApp->processEvents();
812
    qApp->processEvents();
975
813
976
    if (inputishtml) {
814
    if (inputishtml) {
977
        LOGDEB1(("Preview: got html %s\n", fdoc.text.c_str()));
815
        LOGDEB1(("Preview: got html %s\n", fdoc.text.c_str()));
978
        m_plaintorich.set_inputhtml(true);
816
        editor->m_plaintorich->set_inputhtml(true);
979
    } else {
817
    } else {
980
        LOGDEB1(("Preview: got plain %s\n", fdoc.text.c_str()));
818
        LOGDEB1(("Preview: got plain %s\n", fdoc.text.c_str()));
981
        m_plaintorich.set_inputhtml(false);
819
        editor->m_plaintorich->set_inputhtml(false);
982
    }
820
    }
983
    list<string> richlst;
821
    list<string> richlst;
984
    ToRichThread rthr(fdoc.text, m_hData, richlst, m_plaintorich);
822
    ToRichThread rthr(fdoc.text, m_hData, richlst, editor->m_plaintorich);
985
    rthr.start();
823
    rthr.start();
986
824
987
    for (;;prog++) {
825
    for (;;prog++) {
988
        waiter.start(); waiter.wait();
826
        waiter.start(); waiter.wait();
989
      if (rthr.THRFINISHED ())
827
      if (rthr.isFinished())
990
        break;
828
        break;
991
      progress.setProgress(prog , prog <= nsteps-1 ? nsteps : prog+1);
829
      progress.setValue(nsteps);
992
        qApp->processEvents();
830
        qApp->processEvents();
993
        if (progress.wasCanceled()) {
831
        if (progress.wasCanceled()) {
994
        CancelCheck::instance().setCancel();
832
        CancelCheck::instance().setCancel();
995
        }
833
        }
996
        if (prog >= 5)
834
        if (prog >= 5)
...
...
1041
    progress.setLabelText(tr("Loading preview text into editor"));
879
    progress.setLabelText(tr("Loading preview text into editor"));
1042
    qApp->processEvents();
880
    qApp->processEvents();
1043
    int instep = 0;
881
    int instep = 0;
1044
    for (list<QString>::iterator it = qrichlst.begin(); 
882
    for (list<QString>::iterator it = qrichlst.begin(); 
1045
     it != qrichlst.end(); it++, prog++, instep++) {
883
     it != qrichlst.end(); it++, prog++, instep++) {
1046
  progress.setProgress(prog , prog <= nsteps-1 ? nsteps : prog+1);
884
  progress.setValue(prog);
1047
    qApp->processEvents();
885
    qApp->processEvents();
1048
886
1049
    editor->append(*it);
887
    editor->append(*it);
1050
        // We need to save the rich text for printing, the editor does
888
        // We need to save the rich text for printing, the editor does
1051
        // not do it consistently for us.
889
        // not do it consistently for us.
1052
        editor->m_data.richtxt.append(*it);
890
        editor->m_data.richtxt.append(*it);
1053
1054
  // Stay at top
1055
  if (instep < 5) {
1056
      editor->setCursorPosition(0,0);
1057
      editor->ensureCursorVisible();
1058
  }
1059
891
1060
    if (progress.wasCanceled()) {
892
    if (progress.wasCanceled()) {
1061
            editor->append("<b>Cancelled !</b>");
893
            editor->append("<b>Cancelled !</b>");
1062
        LOGDEB(("LoadFileInCurrentTab: cancelled in editor load\n"));
894
        LOGDEB(("LoadFileInCurrentTab: cancelled in editor load\n"));
1063
        break;
895
        break;
...
...
1073
        fdoc.text.clear(); 
905
        fdoc.text.clear(); 
1074
    editor->m_data.fdoc = fdoc;
906
    editor->m_data.fdoc = fdoc;
1075
    if (textempty)
907
    if (textempty)
1076
        editor->toggleFields();
908
        editor->toggleFields();
1077
909
1078
    m_haveAnchors = m_plaintorich.lastanchor != 0;
910
    m_haveAnchors = editor->m_plaintorich->lastanchor != 0;
1079
    if (searchTextLine->text().length() != 0) {
911
    if (searchTextLine->text().length() != 0) {
1080
    // If there is a current search string, perform the search
912
    // If there is a current search string, perform the search
1081
    m_canBeep = true;
913
    m_canBeep = true;
1082
    doSearch(searchTextLine->text(), true, false);
914
    doSearch(searchTextLine->text(), true, false);
1083
    } else {
915
    } else {
1084
    // Position to the first query term
916
    // Position to the first query term
1085
    if (m_haveAnchors) {
917
    if (m_haveAnchors) {
1086
        QString aname = 
918
        QString aname = 
1087
        QString::fromUtf8(m_plaintorich.termAnchorName(1).c_str());
919
        QString::fromUtf8(editor->m_plaintorich->termAnchorName(1).c_str());
1088
        LOGDEB2(("Call movetoanchor(%s)\n", (const char *)aname.utf8()));
920
        LOGDEB2(("Call movetoanchor(%s)\n", (const char *)aname.utf8()));
1089
        editor->moveToAnchor(aname);
921
        editor->scrollToAnchor(aname);
922
      // Position the cursor approximately at the anchor (top of
923
      // viewport) so that searches start from here
924
      QTextCursor cursor = editor->cursorForPosition(QPoint(0, 0));
925
      editor->setTextCursor(cursor);
1090
        m_curAnchor = 1;
926
        m_curAnchor = 1;
1091
    }
927
    }
1092
    }
928
    }
1093
929
1094
    // Enter document in document history
930
    // Enter document in document history
...
...
1103
    emit(previewExposed(this, m_searchId, docnum));
939
    emit(previewExposed(this, m_searchId, docnum));
1104
    LOGDEB(("LoadFileInCurrentTab: returning true\n"));
940
    LOGDEB(("LoadFileInCurrentTab: returning true\n"));
1105
    return true;
941
    return true;
1106
}
942
}
1107
943
1108
RCLPOPUP *PreviewTextEdit::createPopupMenu(const QPoint&)
944
void PreviewTextEdit::createPopupMenu(const QPoint& pos)
1109
{
945
{
1110
    LOGDEB1(("PreviewTextEdit::createPopupMenu()\n"));
946
    LOGDEB1(("PreviewTextEdit::createPopupMenu()\n"));
1111
    RCLPOPUP *popup = new RCLPOPUP(this);
947
    QMenu *popup = new QMenu(this);
1112
    if (!m_dspflds) {
948
    if (!m_dspflds) {
1113
    popup->insertItem(tr("Show fields"), this, SLOT(toggleFields()));
949
    popup->addAction(tr("Show fields"), this, SLOT(toggleFields()));
1114
    } else {
950
    } else {
1115
    popup->insertItem(tr("Show main text"), this, SLOT(toggleFields()));
951
    popup->addAction(tr("Show main text"), this, SLOT(toggleFields()));
1116
    }
952
    }
1117
    popup->insertItem(tr("Print"), this, SLOT(print()));
953
    popup->addAction(tr("Print"), this, SLOT(print()));
1118
    return popup;
954
    popup->popup(mapToGlobal(pos));
1119
}
955
}
1120
956
1121
// Either display document fields or main text
957
// Either display document fields or main text
1122
void PreviewTextEdit::toggleFields()
958
void PreviewTextEdit::toggleFields()
1123
{
959
{
...
...
1148
    }
984
    }
1149
    txt += "</dl></body></html>";
985
    txt += "</dl></body></html>";
1150
    setText(txt);
986
    setText(txt);
1151
}
987
}
1152
988
989
void PreviewTextEdit::mouseDoubleClickEvent(QMouseEvent *event)
990
{
991
    LOGDEB2(("PreviewTextEdit::mouseDoubleClickEvent\n"));
992
    QTextEdit::mouseDoubleClickEvent(event);
993
    if (hasSelectedText() && m_preview)
994
  m_preview->emitWordSelect(selectedText());
995
}
996
1153
void PreviewTextEdit::print()
997
void PreviewTextEdit::print()
1154
{
998
{
1155
    LOGDEB1(("PreviewTextEdit::print\n"));
999
    LOGDEB(("PreviewTextEdit::print\n"));
1156
    if (!m_preview)
1000
    if (!m_preview)
1157
        return;
1001
        return;
1158
    
1002
    
1159
#ifndef QT_NO_PRINTER
1003
#ifndef QT_NO_PRINTER
1160
    QPrinter printer;
1004
    QPrinter printer;
1161
    QPrintDialog *dialog = new QPrintDialog(&printer, this);
1005
    QPrintDialog *dialog = new QPrintDialog(&printer, this);
1162
#if (QT_VERSION >= 0x040000)
1163
    dialog->setWindowTitle(tr("Print Current Preview"));
1006
    dialog->setWindowTitle(tr("Print Current Preview"));
1164
#endif
1165
    if (dialog->exec() != QDialog::Accepted)
1007
    if (dialog->exec() != QDialog::Accepted)
1166
        return;
1008
        return;
1167
1009
    QTextEdit::print(&printer);
1168
    // A qt4 version of this would just be :
1169
    // document()->print(&printer); But as we are using a
1170
    // q3textedit, we have to do the q3 printing dance, even under
1171
    // qt4. The following code is taken from
1172
    // qt3/examples/textdrawing/qtextedit.cpp
1173
    printer.setFullPage(TRUE);
1174
    QPaintDeviceMetrics screen( this );
1175
    printer.setResolution( screen.logicalDpiY() );
1176
    QPainter p( &printer );
1177
    QPaintDeviceMetrics metrics( p.device() );
1178
    int dpix = metrics.logicalDpiX();
1179
    int dpiy = metrics.logicalDpiY();
1180
    const int margin = 72; // pt
1181
    QRect body( margin * dpix / 72, margin * dpiy / 72,
1182
                metrics.width() - margin * dpix / 72 * 2,
1183
                metrics.height() - margin * dpiy / 72 * 2 );
1184
    QFont font( "times", 10 );
1185
    // Dont want to use text() here, this is the plain text. We 
1186
    // want the rich text. For some reason we don't need this for fields??
1187
    const QString &richtxt  = m_dspflds ? text() : m_data.richtxt;
1188
    QSimpleRichText richText(richtxt, font, this->context(), 
1189
                             this->styleSheet(),
1190
                             this->mimeSourceFactory(), body.height() );
1191
    richText.setWidth( &p, body.width() );
1192
    QRect view( body );
1193
    int page = 1;
1194
    do {
1195
        richText.draw( &p, body.left(), body.top(), view, colorGroup() );
1196
        view.moveBy( 0, body.height() );
1197
        p.translate( 0 , -body.height() );
1198
        p.setFont( font );
1199
        p.drawText( view.right() - p.fontMetrics().width( QString::number( page ) ),
1200
                    view.bottom() + p.fontMetrics().ascent() + 5, QString::number( page ) );
1201
        if ( view.top()  >= richText.height() )
1202
            break;
1203
        printer.newPage();
1204
        page++;
1205
    } while (TRUE);
1206
#endif
1010
#endif
1207
}
1011
}
1208