|
a/src/qtgui/preview_w.cpp |
|
b/src/qtgui/preview_w.cpp |
|
... |
|
... |
13 |
* along with this program; if not, write to the
|
13 |
* along with this program; if not, write to the
|
14 |
* Free Software Foundation, Inc.,
|
14 |
* Free Software Foundation, Inc.,
|
15 |
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
15 |
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
16 |
*/
|
16 |
*/
|
17 |
#include "autoconfig.h"
|
17 |
#include "autoconfig.h"
|
18 |
|
|
|
19 |
#include "safeunistd.h"
|
|
|
20 |
|
18 |
|
21 |
#include <list>
|
19 |
#include <list>
|
22 |
#include <utility>
|
20 |
#include <utility>
|
23 |
|
21 |
|
24 |
#include <qmessagebox.h>
|
22 |
#include <qmessagebox.h>
|
|
... |
|
... |
43 |
#include <qapplication.h>
|
41 |
#include <qapplication.h>
|
44 |
#include <qclipboard.h>
|
42 |
#include <qclipboard.h>
|
45 |
#include <qimage.h>
|
43 |
#include <qimage.h>
|
46 |
#include <qurl.h>
|
44 |
#include <qurl.h>
|
47 |
#include <QShortcut>
|
45 |
#include <QShortcut>
|
|
|
46 |
#include <QTimer>
|
48 |
|
47 |
|
49 |
#include "debuglog.h"
|
48 |
#include "debuglog.h"
|
50 |
#include "pathut.h"
|
49 |
#include "pathut.h"
|
51 |
#include "internfile.h"
|
50 |
#include "internfile.h"
|
52 |
#include "recoll.h"
|
51 |
#include "recoll.h"
|
|
... |
|
... |
68 |
// Subclass plainToRich to add <termtag>s and anchors to the preview text
|
67 |
// Subclass plainToRich to add <termtag>s and anchors to the preview text
|
69 |
class PlainToRichQtPreview : public PlainToRich {
|
68 |
class PlainToRichQtPreview : public PlainToRich {
|
70 |
public:
|
69 |
public:
|
71 |
|
70 |
|
72 |
PlainToRichQtPreview()
|
71 |
PlainToRichQtPreview()
|
73 |
: m_curanchor(1), m_lastanchor(0)
|
72 |
: m_curanchor(1), m_lastanchor(0) {
|
74 |
{
|
|
|
75 |
}
|
73 |
}
|
76 |
void clear() {
|
74 |
void clear() {
|
77 |
m_curanchor = 1;
|
75 |
m_curanchor = 1;
|
78 |
m_lastanchor = 0;
|
76 |
m_lastanchor = 0;
|
79 |
m_groupanchors.clear();
|
77 |
m_groupanchors.clear();
|
80 |
m_groupcuranchors.clear();
|
78 |
m_groupcuranchors.clear();
|
81 |
}
|
79 |
}
|
82 |
|
80 |
|
83 |
bool haveAnchors()
|
81 |
bool haveAnchors() {
|
84 |
{
|
|
|
85 |
return m_lastanchor != 0;
|
82 |
return m_lastanchor != 0;
|
86 |
}
|
83 |
}
|
87 |
|
84 |
|
88 |
virtual string header()
|
85 |
virtual string header() {
|
89 |
{
|
|
|
90 |
if (!m_inputhtml) {
|
86 |
if (!m_inputhtml) {
|
91 |
switch (prefs.previewPlainPre) {
|
87 |
switch (prefs.previewPlainPre) {
|
92 |
case PrefsPack::PP_BR:
|
88 |
case PrefsPack::PP_BR:
|
93 |
m_eolbr = true;
|
89 |
m_eolbr = true;
|
94 |
return "<qt><head><title></title></head><body>";
|
90 |
return "<qt><head><title></title></head><body>";
|
95 |
case PrefsPack::PP_PRE:
|
91 |
case PrefsPack::PP_PRE:
|
96 |
m_eolbr = false;
|
92 |
m_eolbr = false;
|
97 |
return "<qt><head><title></title></head><body><pre>";
|
93 |
return "<qt><head><title></title></head><body><pre>";
|
98 |
case PrefsPack::PP_PREWRAP:
|
94 |
case PrefsPack::PP_PREWRAP:
|
99 |
m_eolbr = false;
|
95 |
m_eolbr = false;
|
100 |
return "<qt><head><title></title></head><body>"
|
96 |
return "<qt><head><title></title></head><body>"
|
101 |
"<pre style=\"white-space: pre-wrap\">";
|
97 |
"<pre style=\"white-space: pre-wrap\">";
|
|
|
98 |
}
|
|
|
99 |
}
|
|
|
100 |
return cstr_null;
|
102 |
}
|
101 |
}
|
103 |
}
|
|
|
104 |
return cstr_null;
|
|
|
105 |
}
|
|
|
106 |
|
102 |
|
107 |
virtual string startMatch(unsigned int grpidx)
|
103 |
virtual string startMatch(unsigned int grpidx) {
|
108 |
{
|
|
|
109 |
LOGDEB2(("startMatch, grpidx %u\n", grpidx));
|
104 |
LOGDEB2(("startMatch, grpidx %u\n", grpidx));
|
110 |
grpidx = m_hdata->grpsugidx[grpidx];
|
105 |
grpidx = m_hdata->grpsugidx[grpidx];
|
111 |
LOGDEB2(("startMatch, ugrpidx %u\n", grpidx));
|
106 |
LOGDEB2(("startMatch, ugrpidx %u\n", grpidx));
|
112 |
m_groupanchors[grpidx].push_back(++m_lastanchor);
|
107 |
m_groupanchors[grpidx].push_back(++m_lastanchor);
|
113 |
m_groupcuranchors[grpidx] = 0;
|
108 |
m_groupcuranchors[grpidx] = 0;
|
114 |
return string("<span style='color: ").
|
109 |
return string("<span style='color: ").
|
115 |
append((const char *)(prefs.qtermcolor.toUtf8())).
|
110 |
append((const char *)(prefs.qtermcolor.toUtf8())).
|
116 |
append(";font-weight: bold;").
|
111 |
append(";font-weight: bold;").
|
117 |
append("'>").
|
112 |
append("'>").
|
118 |
append("<a name=\"").
|
113 |
append("<a name=\"").
|
119 |
append(termAnchorName(m_lastanchor)).
|
114 |
append(termAnchorName(m_lastanchor)).
|
120 |
append("\">");
|
115 |
append("\">");
|
121 |
}
|
116 |
}
|
122 |
|
117 |
|
123 |
virtual string endMatch()
|
118 |
virtual string endMatch() {
|
124 |
{
|
|
|
125 |
return string("</a></span>");
|
119 |
return string("</a></span>");
|
126 |
}
|
120 |
}
|
127 |
|
121 |
|
128 |
virtual string termAnchorName(int i) const
|
122 |
virtual string termAnchorName(int i) const {
|
129 |
{
|
|
|
130 |
static const char *termAnchorNameBase = "TRM";
|
123 |
static const char *termAnchorNameBase = "TRM";
|
131 |
char acname[sizeof(termAnchorNameBase) + 20];
|
124 |
char acname[sizeof(termAnchorNameBase) + 20];
|
132 |
sprintf(acname, "%s%d", termAnchorNameBase, i);
|
125 |
sprintf(acname, "%s%d", termAnchorNameBase, i);
|
133 |
return string(acname);
|
126 |
return string(acname);
|
134 |
}
|
127 |
}
|
135 |
|
128 |
|
136 |
virtual string startChunk()
|
129 |
virtual string startChunk() {
|
137 |
{
|
|
|
138 |
return "<pre>";
|
130 |
return "<pre>";
|
139 |
}
|
131 |
}
|
140 |
|
132 |
|
141 |
int nextAnchorNum(int grpidx)
|
133 |
int nextAnchorNum(int grpidx) {
|
142 |
{
|
|
|
143 |
LOGDEB2(("nextAnchorNum: group %d\n", grpidx));
|
134 |
LOGDEB2(("nextAnchorNum: group %d\n", grpidx));
|
144 |
map<unsigned int, unsigned int>::iterator curit =
|
135 |
map<unsigned int, unsigned int>::iterator curit =
|
145 |
m_groupcuranchors.find(grpidx);
|
136 |
m_groupcuranchors.find(grpidx);
|
146 |
map<unsigned int, vector<int> >::iterator vecit =
|
137 |
map<unsigned int, vector<int> >::iterator vecit =
|
147 |
m_groupanchors.find(grpidx);
|
138 |
m_groupanchors.find(grpidx);
|
148 |
if (grpidx == -1 || curit == m_groupcuranchors.end() ||
|
139 |
if (grpidx == -1 || curit == m_groupcuranchors.end() ||
|
149 |
vecit == m_groupanchors.end()) {
|
140 |
vecit == m_groupanchors.end()) {
|
150 |
if (m_curanchor >= m_lastanchor)
|
141 |
if (m_curanchor >= m_lastanchor)
|
151 |
m_curanchor = 1;
|
142 |
m_curanchor = 1;
|
152 |
else
|
143 |
else
|
153 |
m_curanchor++;
|
144 |
m_curanchor++;
|
154 |
} else {
|
145 |
} else {
|
155 |
if (curit->second >= vecit->second.size() -1)
|
146 |
if (curit->second >= vecit->second.size() -1)
|
156 |
m_groupcuranchors[grpidx] = 0;
|
147 |
m_groupcuranchors[grpidx] = 0;
|
157 |
else
|
148 |
else
|
158 |
m_groupcuranchors[grpidx]++;
|
149 |
m_groupcuranchors[grpidx]++;
|
159 |
m_curanchor = vecit->second[m_groupcuranchors[grpidx]];
|
150 |
m_curanchor = vecit->second[m_groupcuranchors[grpidx]];
|
160 |
LOGDEB2(("nextAnchorNum: curanchor now %d\n", m_curanchor));
|
151 |
LOGDEB2(("nextAnchorNum: curanchor now %d\n", m_curanchor));
|
161 |
}
|
152 |
}
|
162 |
return m_curanchor;
|
153 |
return m_curanchor;
|
163 |
}
|
154 |
}
|
164 |
|
155 |
|
165 |
int prevAnchorNum(int grpidx)
|
156 |
int prevAnchorNum(int grpidx) {
|
166 |
{
|
|
|
167 |
map<unsigned int, unsigned int>::iterator curit =
|
157 |
map<unsigned int, unsigned int>::iterator curit =
|
168 |
m_groupcuranchors.find(grpidx);
|
158 |
m_groupcuranchors.find(grpidx);
|
169 |
map<unsigned int, vector<int> >::iterator vecit =
|
159 |
map<unsigned int, vector<int> >::iterator vecit =
|
170 |
m_groupanchors.find(grpidx);
|
160 |
m_groupanchors.find(grpidx);
|
171 |
if (grpidx == -1 || curit == m_groupcuranchors.end() ||
|
161 |
if (grpidx == -1 || curit == m_groupcuranchors.end() ||
|
172 |
vecit == m_groupanchors.end()) {
|
162 |
vecit == m_groupanchors.end()) {
|
173 |
if (m_curanchor <= 1)
|
163 |
if (m_curanchor <= 1)
|
174 |
m_curanchor = m_lastanchor;
|
164 |
m_curanchor = m_lastanchor;
|
175 |
else
|
165 |
else
|
176 |
m_curanchor--;
|
166 |
m_curanchor--;
|
177 |
} else {
|
167 |
} else {
|
178 |
if (curit->second <= 0)
|
168 |
if (curit->second <= 0)
|
179 |
m_groupcuranchors[grpidx] = vecit->second.size() -1;
|
169 |
m_groupcuranchors[grpidx] = vecit->second.size() -1;
|
180 |
else
|
170 |
else
|
181 |
m_groupcuranchors[grpidx]--;
|
171 |
m_groupcuranchors[grpidx]--;
|
182 |
m_curanchor = vecit->second[m_groupcuranchors[grpidx]];
|
172 |
m_curanchor = vecit->second[m_groupcuranchors[grpidx]];
|
183 |
}
|
173 |
}
|
184 |
return m_curanchor;
|
174 |
return m_curanchor;
|
185 |
}
|
175 |
}
|
186 |
|
176 |
|
187 |
QString curAnchorName() const
|
177 |
QString curAnchorName() const {
|
188 |
{
|
|
|
189 |
return QString::fromUtf8(termAnchorName(m_curanchor).c_str());
|
178 |
return QString::fromUtf8(termAnchorName(m_curanchor).c_str());
|
190 |
}
|
179 |
}
|
191 |
|
180 |
|
192 |
private:
|
181 |
private:
|
193 |
int m_curanchor;
|
182 |
int m_curanchor;
|
194 |
int m_lastanchor;
|
183 |
int m_lastanchor;
|
|
... |
|
... |
225 |
searchTextCMB = new QComboBox(this);
|
214 |
searchTextCMB = new QComboBox(this);
|
226 |
searchTextCMB->setEditable(true);
|
215 |
searchTextCMB->setEditable(true);
|
227 |
searchTextCMB->setInsertPolicy(QComboBox::NoInsert);
|
216 |
searchTextCMB->setInsertPolicy(QComboBox::NoInsert);
|
228 |
searchTextCMB->setDuplicatesEnabled(false);
|
217 |
searchTextCMB->setDuplicatesEnabled(false);
|
229 |
for (unsigned int i = 0; i < m_hData.ugroups.size(); i++) {
|
218 |
for (unsigned int i = 0; i < m_hData.ugroups.size(); i++) {
|
230 |
QString s;
|
219 |
QString s;
|
231 |
for (unsigned int j = 0; j < m_hData.ugroups[i].size(); j++) {
|
220 |
for (unsigned int j = 0; j < m_hData.ugroups[i].size(); j++) {
|
232 |
s.append(QString::fromUtf8(m_hData.ugroups[i][j].c_str()));
|
221 |
s.append(QString::fromUtf8(m_hData.ugroups[i][j].c_str()));
|
233 |
if (j != m_hData.ugroups[i].size()-1)
|
222 |
if (j != m_hData.ugroups[i].size()-1)
|
234 |
s.append(" ");
|
223 |
s.append(" ");
|
235 |
}
|
224 |
}
|
236 |
searchTextCMB->addItem(s);
|
225 |
searchTextCMB->addItem(s);
|
237 |
}
|
226 |
}
|
238 |
searchTextCMB->setEditText("");
|
227 |
searchTextCMB->setEditText("");
|
239 |
searchTextCMB->setCompleter(0);
|
228 |
searchTextCMB->setCompleter(0);
|
240 |
|
229 |
|
241 |
layout3->addWidget(searchTextCMB);
|
230 |
layout3->addWidget(searchTextCMB);
|
|
... |
|
... |
268 |
QPushButton * bt = new QPushButton(tr("Close Tab"), this);
|
257 |
QPushButton * bt = new QPushButton(tr("Close Tab"), this);
|
269 |
pvTab->setCornerWidget(bt);
|
258 |
pvTab->setCornerWidget(bt);
|
270 |
|
259 |
|
271 |
(void)new HelpClient(this);
|
260 |
(void)new HelpClient(this);
|
272 |
HelpClient::installMap((const char *)objectName().toUtf8(),
|
261 |
HelpClient::installMap((const char *)objectName().toUtf8(),
|
273 |
"RCL.SEARCH.PREVIEW");
|
262 |
"RCL.SEARCH.PREVIEW");
|
274 |
|
263 |
|
275 |
// signals and slots connections
|
264 |
// signals and slots connections
|
276 |
connect(searchTextCMB, SIGNAL(activated(int)),
|
265 |
connect(searchTextCMB, SIGNAL(activated(int)),
|
277 |
this, SLOT(searchTextFromIndex(int)));
|
266 |
this, SLOT(searchTextFromIndex(int)));
|
278 |
connect(searchTextCMB, SIGNAL(editTextChanged(const QString&)),
|
267 |
connect(searchTextCMB, SIGNAL(editTextChanged(const QString&)),
|
279 |
this, SLOT(searchTextChanged(const QString&)));
|
268 |
this, SLOT(searchTextChanged(const QString&)));
|
280 |
connect(nextButton, SIGNAL(clicked()), this, SLOT(nextPressed()));
|
269 |
connect(nextButton, SIGNAL(clicked()), this, SLOT(nextPressed()));
|
281 |
connect(prevButton, SIGNAL(clicked()), this, SLOT(prevPressed()));
|
270 |
connect(prevButton, SIGNAL(clicked()), this, SLOT(prevPressed()));
|
282 |
connect(clearPB, SIGNAL(clicked()), searchTextCMB, SLOT(clearEditText()));
|
271 |
connect(clearPB, SIGNAL(clicked()), searchTextCMB, SLOT(clearEditText()));
|
283 |
connect(pvTab, SIGNAL(currentChanged(int)),
|
272 |
connect(pvTab, SIGNAL(currentChanged(int)),
|
284 |
this, SLOT(currentChanged(int)));
|
273 |
this, SLOT(currentChanged(int)));
|
285 |
connect(bt, SIGNAL(clicked()), this, SLOT(closeCurrentTab()));
|
274 |
connect(bt, SIGNAL(clicked()), this, SLOT(closeCurrentTab()));
|
286 |
|
275 |
|
287 |
connect(new QShortcut(closeKS, this), SIGNAL (activated()),
|
276 |
connect(new QShortcut(closeKS, this), SIGNAL (activated()),
|
288 |
this, SLOT (close()));
|
277 |
this, SLOT (close()));
|
289 |
connect(new QShortcut(nextDocInTabKS, this), SIGNAL (activated()),
|
278 |
connect(new QShortcut(nextDocInTabKS, this), SIGNAL (activated()),
|
290 |
this, SLOT (emitShowNext()));
|
279 |
this, SLOT (emitShowNext()));
|
291 |
connect(new QShortcut(prevDocInTabKS, this), SIGNAL (activated()),
|
280 |
connect(new QShortcut(prevDocInTabKS, this), SIGNAL (activated()),
|
292 |
this, SLOT (emitShowPrev()));
|
281 |
this, SLOT (emitShowPrev()));
|
293 |
connect(new QShortcut(closeTabKS, this), SIGNAL (activated()),
|
282 |
connect(new QShortcut(closeTabKS, this), SIGNAL (activated()),
|
294 |
this, SLOT (closeCurrentTab()));
|
283 |
this, SLOT (closeCurrentTab()));
|
295 |
connect(new QShortcut(printTabKS, this), SIGNAL (activated()),
|
284 |
connect(new QShortcut(printTabKS, this), SIGNAL (activated()),
|
296 |
this, SIGNAL (printCurrentPreviewRequest()));
|
285 |
this, SIGNAL (printCurrentPreviewRequest()));
|
297 |
|
286 |
|
298 |
m_dynSearchActive = false;
|
287 |
m_dynSearchActive = false;
|
299 |
m_canBeep = true;
|
288 |
m_canBeep = true;
|
300 |
if (prefs.pvwidth > 100) {
|
289 |
if (prefs.pvwidth > 100) {
|
301 |
resize(prefs.pvwidth, prefs.pvheight);
|
290 |
resize(prefs.pvwidth, prefs.pvheight);
|
302 |
}
|
291 |
}
|
303 |
m_loading = false;
|
292 |
m_loading = false;
|
304 |
currentChanged(pvTab->currentIndex());
|
293 |
currentChanged(pvTab->currentIndex());
|
305 |
m_justCreated = true;
|
294 |
m_justCreated = true;
|
306 |
}
|
295 |
}
|
307 |
|
296 |
|
308 |
void Preview::emitShowNext()
|
297 |
void Preview::emitShowNext()
|
309 |
{
|
298 |
{
|
310 |
if (m_loading)
|
299 |
if (m_loading)
|
311 |
return;
|
300 |
return;
|
312 |
PreviewTextEdit *edit = currentEditor();
|
301 |
PreviewTextEdit *edit = currentEditor();
|
313 |
if (edit) {
|
302 |
if (edit) {
|
314 |
emit(showNext(this, m_searchId, edit->m_docnum));
|
303 |
emit(showNext(this, m_searchId, edit->m_docnum));
|
315 |
}
|
304 |
}
|
316 |
}
|
305 |
}
|
317 |
|
306 |
|
318 |
void Preview::emitShowPrev()
|
307 |
void Preview::emitShowPrev()
|
319 |
{
|
308 |
{
|
320 |
if (m_loading)
|
309 |
if (m_loading)
|
321 |
return;
|
310 |
return;
|
322 |
PreviewTextEdit *edit = currentEditor();
|
311 |
PreviewTextEdit *edit = currentEditor();
|
323 |
if (edit) {
|
312 |
if (edit) {
|
324 |
emit(showPrev(this, m_searchId, edit->m_docnum));
|
313 |
emit(showPrev(this, m_searchId, edit->m_docnum));
|
325 |
}
|
314 |
}
|
326 |
}
|
315 |
}
|
327 |
|
316 |
|
328 |
void Preview::closeEvent(QCloseEvent *e)
|
317 |
void Preview::closeEvent(QCloseEvent *e)
|
329 |
{
|
318 |
{
|
330 |
LOGDEB(("Preview::closeEvent. m_loading %d\n", m_loading));
|
319 |
LOGDEB(("Preview::closeEvent. m_loading %d\n", m_loading));
|
331 |
if (m_loading) {
|
320 |
if (m_loading) {
|
332 |
CancelCheck::instance().setCancel();
|
321 |
CancelCheck::instance().setCancel();
|
333 |
e->ignore();
|
322 |
e->ignore();
|
334 |
return;
|
323 |
return;
|
335 |
}
|
324 |
}
|
336 |
prefs.pvwidth = width();
|
325 |
prefs.pvwidth = width();
|
337 |
prefs.pvheight = height();
|
326 |
prefs.pvheight = height();
|
338 |
|
327 |
|
339 |
/* Release all temporary files (but maybe none is actually set) */
|
328 |
/* Release all temporary files (but maybe none is actually set) */
|
340 |
for (int i = 0; i < pvTab->count(); i++) {
|
329 |
for (int i = 0; i < pvTab->count(); i++) {
|
341 |
QWidget *tw = pvTab->widget(i);
|
330 |
QWidget *tw = pvTab->widget(i);
|
342 |
if (tw) {
|
331 |
if (tw) {
|
343 |
PreviewTextEdit *edit =
|
332 |
PreviewTextEdit *edit =
|
344 |
tw->findChild<PreviewTextEdit*>("pvEdit");
|
333 |
tw->findChild<PreviewTextEdit*>("pvEdit");
|
345 |
if (edit) {
|
334 |
if (edit) {
|
346 |
forgetTempFile(edit->m_tmpfilename);
|
335 |
forgetTempFile(edit->m_tmpfilename);
|
347 |
}
|
336 |
}
|
348 |
}
|
337 |
}
|
349 |
}
|
338 |
}
|
350 |
emit previewExposed(this, m_searchId, -1);
|
339 |
emit previewExposed(this, m_searchId, -1);
|
351 |
emit previewClosed(this);
|
340 |
emit previewClosed(this);
|
|
... |
|
... |
356 |
|
345 |
|
357 |
bool Preview::eventFilter(QObject *target, QEvent *event)
|
346 |
bool Preview::eventFilter(QObject *target, QEvent *event)
|
358 |
{
|
347 |
{
|
359 |
if (event->type() != QEvent::KeyPress) {
|
348 |
if (event->type() != QEvent::KeyPress) {
|
360 |
#if 0
|
349 |
#if 0
|
361 |
LOGDEB(("Preview::eventFilter(): %s\n", eventTypeToStr(event->type())));
|
350 |
LOGDEB(("Preview::eventFilter(): %s\n", eventTypeToStr(event->type())));
|
362 |
if (event->type() == QEvent::MouseButtonRelease) {
|
351 |
if (event->type() == QEvent::MouseButtonRelease) {
|
363 |
QMouseEvent *mev = (QMouseEvent *)event;
|
352 |
QMouseEvent *mev = (QMouseEvent *)event;
|
364 |
LOGDEB(("Mouse: GlobalY %d y %d\n", mev->globalY(),
|
353 |
LOGDEB(("Mouse: GlobalY %d y %d\n", mev->globalY(),
|
365 |
mev->y()));
|
354 |
mev->y()));
|
366 |
}
|
355 |
}
|
367 |
#endif
|
356 |
#endif
|
368 |
return false;
|
357 |
return false;
|
369 |
}
|
358 |
}
|
370 |
|
359 |
|
371 |
PreviewTextEdit *edit = currentEditor();
|
360 |
PreviewTextEdit *edit = currentEditor();
|
372 |
QKeyEvent *keyEvent = (QKeyEvent *)event;
|
361 |
QKeyEvent *keyEvent = (QKeyEvent *)event;
|
373 |
|
362 |
|
374 |
if (m_dynSearchActive) {
|
363 |
if (m_dynSearchActive) {
|
375 |
if (keyEvent->key() == Qt::Key_F3) {
|
364 |
if (keyEvent->key() == Qt::Key_F3) {
|
376 |
LOGDEB2(("Preview::eventFilter: got F3\n"));
|
365 |
LOGDEB2(("Preview::eventFilter: got F3\n"));
|
377 |
doSearch(searchTextCMB->currentText(), true,
|
366 |
doSearch(searchTextCMB->currentText(), true,
|
378 |
(keyEvent->modifiers() & Qt::ShiftModifier) != 0);
|
367 |
(keyEvent->modifiers() & Qt::ShiftModifier) != 0);
|
379 |
return true;
|
368 |
return true;
|
380 |
}
|
369 |
}
|
381 |
if (target != searchTextCMB)
|
370 |
if (target != searchTextCMB)
|
382 |
return QApplication::sendEvent(searchTextCMB, event);
|
371 |
return QApplication::sendEvent(searchTextCMB, event);
|
383 |
} else {
|
372 |
} else {
|
384 |
if (edit &&
|
373 |
if (edit &&
|
385 |
(target == edit || target == edit->viewport())) {
|
374 |
(target == edit || target == edit->viewport())) {
|
386 |
if (keyEvent->key() == Qt::Key_Slash ||
|
375 |
if (keyEvent->key() == Qt::Key_Slash ||
|
387 |
(keyEvent->key() == Qt::Key_F &&
|
376 |
(keyEvent->key() == Qt::Key_F &&
|
388 |
(keyEvent->modifiers() & Qt::ControlModifier))) {
|
377 |
(keyEvent->modifiers() & Qt::ControlModifier))) {
|
389 |
LOGDEB2(("Preview::eventFilter: got / or C-F\n"));
|
378 |
LOGDEB2(("Preview::eventFilter: got / or C-F\n"));
|
390 |
searchTextCMB->setFocus();
|
379 |
searchTextCMB->setFocus();
|
391 |
m_dynSearchActive = true;
|
380 |
m_dynSearchActive = true;
|
392 |
return true;
|
381 |
return true;
|
393 |
} else if (keyEvent->key() == Qt::Key_Space) {
|
382 |
} else if (keyEvent->key() == Qt::Key_Space) {
|
394 |
LOGDEB2(("Preview::eventFilter: got Space\n"));
|
383 |
LOGDEB2(("Preview::eventFilter: got Space\n"));
|
395 |
int value = edit->verticalScrollBar()->value();
|
384 |
int value = edit->verticalScrollBar()->value();
|
396 |
value += edit->verticalScrollBar()->pageStep();
|
385 |
value += edit->verticalScrollBar()->pageStep();
|
397 |
edit->verticalScrollBar()->setValue(value);
|
386 |
edit->verticalScrollBar()->setValue(value);
|
398 |
return true;
|
387 |
return true;
|
399 |
} else if (keyEvent->key() == Qt::Key_Backspace) {
|
388 |
} else if (keyEvent->key() == Qt::Key_Backspace) {
|
400 |
LOGDEB2(("Preview::eventFilter: got Backspace\n"));
|
389 |
LOGDEB2(("Preview::eventFilter: got Backspace\n"));
|
401 |
int value = edit->verticalScrollBar()->value();
|
390 |
int value = edit->verticalScrollBar()->value();
|
402 |
value -= edit->verticalScrollBar()->pageStep();
|
391 |
value -= edit->verticalScrollBar()->pageStep();
|
403 |
edit->verticalScrollBar()->setValue(value);
|
392 |
edit->verticalScrollBar()->setValue(value);
|
404 |
return true;
|
393 |
return true;
|
405 |
}
|
394 |
}
|
406 |
}
|
395 |
}
|
407 |
}
|
396 |
}
|
408 |
|
397 |
|
409 |
return false;
|
398 |
return false;
|
410 |
}
|
399 |
}
|
411 |
|
400 |
|
412 |
void Preview::searchTextChanged(const QString & text)
|
401 |
void Preview::searchTextChanged(const QString & text)
|
413 |
{
|
402 |
{
|
414 |
LOGDEB1(("Search line text changed. text: '%s'\n",
|
403 |
LOGDEB1(("Search line text changed. text: '%s'\n",
|
415 |
(const char *)text.toUtf8()));
|
404 |
(const char *)text.toUtf8()));
|
416 |
m_searchTextFromIndex = -1;
|
405 |
m_searchTextFromIndex = -1;
|
417 |
if (text.isEmpty()) {
|
406 |
if (text.isEmpty()) {
|
418 |
m_dynSearchActive = false;
|
407 |
m_dynSearchActive = false;
|
419 |
clearPB->setEnabled(false);
|
408 |
clearPB->setEnabled(false);
|
420 |
} else {
|
409 |
} else {
|
421 |
m_dynSearchActive = true;
|
410 |
m_dynSearchActive = true;
|
422 |
clearPB->setEnabled(true);
|
411 |
clearPB->setEnabled(true);
|
423 |
doSearch(text, false, false);
|
412 |
doSearch(text, false, false);
|
424 |
}
|
413 |
}
|
425 |
}
|
414 |
}
|
426 |
|
415 |
|
427 |
void Preview::searchTextFromIndex(int idx)
|
416 |
void Preview::searchTextFromIndex(int idx)
|
428 |
{
|
417 |
{
|
|
... |
|
... |
434 |
{
|
423 |
{
|
435 |
LOGDEB2(("Preview::currentEditor()\n"));
|
424 |
LOGDEB2(("Preview::currentEditor()\n"));
|
436 |
QWidget *tw = pvTab->currentWidget();
|
425 |
QWidget *tw = pvTab->currentWidget();
|
437 |
PreviewTextEdit *edit = 0;
|
426 |
PreviewTextEdit *edit = 0;
|
438 |
if (tw) {
|
427 |
if (tw) {
|
439 |
edit = tw->findChild<PreviewTextEdit*>("pvEdit");
|
428 |
edit = tw->findChild<PreviewTextEdit*>("pvEdit");
|
440 |
}
|
429 |
}
|
441 |
return edit;
|
430 |
return edit;
|
442 |
}
|
431 |
}
|
443 |
|
432 |
|
444 |
// Save current document to file
|
433 |
// Save current document to file
|
445 |
void Preview::emitSaveDocToFile()
|
434 |
void Preview::emitSaveDocToFile()
|
446 |
{
|
435 |
{
|
447 |
PreviewTextEdit *ce = currentEditor();
|
436 |
PreviewTextEdit *ce = currentEditor();
|
448 |
if (ce && !ce->m_dbdoc.url.empty()) {
|
437 |
if (ce && !ce->m_dbdoc.url.empty()) {
|
449 |
emit saveDocToFile(ce->m_dbdoc);
|
438 |
emit saveDocToFile(ce->m_dbdoc);
|
450 |
}
|
439 |
}
|
451 |
}
|
440 |
}
|
452 |
|
441 |
|
453 |
// Perform text search. If next is true, we look for the next match of the
|
442 |
// Perform text search. If next is true, we look for the next match of the
|
454 |
// current search, trying to advance and possibly wrapping around. If next is
|
443 |
// current search, trying to advance and possibly wrapping around. If next is
|
455 |
// false, the search string has been modified, we search for the new string,
|
444 |
// false, the search string has been modified, we search for the new string,
|
456 |
// starting from the current position
|
445 |
// starting from the current position
|
457 |
void Preview::doSearch(const QString &_text, bool next, bool reverse,
|
446 |
void Preview::doSearch(const QString &_text, bool next, bool reverse,
|
458 |
bool wordOnly)
|
447 |
bool wordOnly)
|
459 |
{
|
448 |
{
|
460 |
LOGDEB(("Preview::doSearch: text [%s] idx %d next %d rev %d word %d\n",
|
449 |
LOGDEB(("Preview::doSearch: text [%s] idx %d next %d rev %d word %d\n",
|
461 |
(const char *)_text.toUtf8(), m_searchTextFromIndex, int(next),
|
450 |
(const char *)_text.toUtf8(), m_searchTextFromIndex, int(next),
|
462 |
int(reverse), int(wordOnly)));
|
451 |
int(reverse), int(wordOnly)));
|
463 |
QString text = _text;
|
452 |
QString text = _text;
|
464 |
|
453 |
|
465 |
bool matchCase = matchCheck->isChecked();
|
454 |
bool matchCase = matchCheck->isChecked();
|
466 |
PreviewTextEdit *edit = currentEditor();
|
455 |
PreviewTextEdit *edit = currentEditor();
|
467 |
if (edit == 0) {
|
456 |
if (edit == 0) {
|
468 |
// ??
|
457 |
// ??
|
469 |
return;
|
458 |
return;
|
470 |
}
|
459 |
}
|
471 |
|
460 |
|
472 |
if (text.isEmpty() || m_searchTextFromIndex != -1) {
|
461 |
if (text.isEmpty() || m_searchTextFromIndex != -1) {
|
473 |
if (!edit->m_plaintorich->haveAnchors()) {
|
462 |
if (!edit->m_plaintorich->haveAnchors()) {
|
474 |
LOGDEB(("NO ANCHORS\n"));
|
463 |
LOGDEB(("NO ANCHORS\n"));
|
475 |
return;
|
464 |
return;
|
476 |
}
|
465 |
}
|
477 |
// The combobox indices are equal to the search ugroup indices
|
466 |
// The combobox indices are equal to the search ugroup indices
|
478 |
// in hldata, that's how we built the list.
|
467 |
// in hldata, that's how we built the list.
|
479 |
if (reverse) {
|
468 |
if (reverse) {
|
480 |
edit->m_plaintorich->prevAnchorNum(m_searchTextFromIndex);
|
469 |
edit->m_plaintorich->prevAnchorNum(m_searchTextFromIndex);
|
481 |
} else {
|
470 |
} else {
|
482 |
edit->m_plaintorich->nextAnchorNum(m_searchTextFromIndex);
|
471 |
edit->m_plaintorich->nextAnchorNum(m_searchTextFromIndex);
|
483 |
}
|
472 |
}
|
484 |
QString aname = edit->m_plaintorich->curAnchorName();
|
473 |
QString aname = edit->m_plaintorich->curAnchorName();
|
485 |
LOGDEB(("Calling scrollToAnchor(%s)\n", (const char *)aname.toUtf8()));
|
474 |
LOGDEB(("Calling scrollToAnchor(%s)\n", (const char *)aname.toUtf8()));
|
486 |
edit->scrollToAnchor(aname);
|
475 |
edit->scrollToAnchor(aname);
|
487 |
// Position the cursor approximately at the anchor (top of
|
476 |
// Position the cursor approximately at the anchor (top of
|
488 |
// viewport) so that searches start from here
|
477 |
// viewport) so that searches start from here
|
489 |
QTextCursor cursor = edit->cursorForPosition(QPoint(0, 0));
|
478 |
QTextCursor cursor = edit->cursorForPosition(QPoint(0, 0));
|
490 |
edit->setTextCursor(cursor);
|
479 |
edit->setTextCursor(cursor);
|
491 |
return;
|
480 |
return;
|
492 |
}
|
481 |
}
|
493 |
|
482 |
|
494 |
// If next is false, the user added characters to the current
|
483 |
// If next is false, the user added characters to the current
|
495 |
// search string. We need to reset the cursor position to the
|
484 |
// search string. We need to reset the cursor position to the
|
496 |
// start of the previous match, else incremental search is going
|
485 |
// start of the previous match, else incremental search is going
|
497 |
// to look for the next occurrence instead of trying to lenghten
|
486 |
// to look for the next occurrence instead of trying to lenghten
|
498 |
// the current match
|
487 |
// the current match
|
499 |
if (!next) {
|
488 |
if (!next) {
|
500 |
QTextCursor cursor = edit->textCursor();
|
489 |
QTextCursor cursor = edit->textCursor();
|
501 |
cursor.setPosition(cursor.anchor(), QTextCursor::KeepAnchor);
|
490 |
cursor.setPosition(cursor.anchor(), QTextCursor::KeepAnchor);
|
502 |
edit->setTextCursor(cursor);
|
491 |
edit->setTextCursor(cursor);
|
503 |
}
|
492 |
}
|
504 |
Chrono chron;
|
493 |
Chrono chron;
|
505 |
LOGDEB(("Preview::doSearch: first find call\n"));
|
494 |
LOGDEB(("Preview::doSearch: first find call\n"));
|
506 |
QTextDocument::FindFlags flags = 0;
|
495 |
QTextDocument::FindFlags flags = 0;
|
507 |
if (reverse)
|
496 |
if (reverse)
|
508 |
flags |= QTextDocument::FindBackward;
|
497 |
flags |= QTextDocument::FindBackward;
|
509 |
if (wordOnly)
|
498 |
if (wordOnly)
|
510 |
flags |= QTextDocument::FindWholeWords;
|
499 |
flags |= QTextDocument::FindWholeWords;
|
511 |
if (matchCase)
|
500 |
if (matchCase)
|
512 |
flags |= QTextDocument::FindCaseSensitively;
|
501 |
flags |= QTextDocument::FindCaseSensitively;
|
513 |
bool found = edit->find(text, flags);
|
502 |
bool found = edit->find(text, flags);
|
514 |
LOGDEB(("Preview::doSearch: first find call return: found %d %.2f S\n",
|
503 |
LOGDEB(("Preview::doSearch: first find call return: found %d %.2f S\n",
|
515 |
found, chron.secs()));
|
504 |
found, chron.secs()));
|
516 |
// If not found, try to wrap around.
|
505 |
// If not found, try to wrap around.
|
517 |
if (!found) {
|
506 |
if (!found) {
|
518 |
LOGDEB(("Preview::doSearch: wrapping around\n"));
|
507 |
LOGDEB(("Preview::doSearch: wrapping around\n"));
|
519 |
if (reverse) {
|
508 |
if (reverse) {
|
520 |
edit->moveCursor (QTextCursor::End);
|
509 |
edit->moveCursor (QTextCursor::End);
|
521 |
} else {
|
510 |
} else {
|
522 |
edit->moveCursor (QTextCursor::Start);
|
511 |
edit->moveCursor (QTextCursor::Start);
|
523 |
}
|
512 |
}
|
524 |
LOGDEB(("Preview::doSearch: 2nd find call\n"));
|
513 |
LOGDEB(("Preview::doSearch: 2nd find call\n"));
|
525 |
chron.restart();
|
514 |
chron.restart();
|
526 |
found = edit->find(text, flags);
|
515 |
found = edit->find(text, flags);
|
527 |
LOGDEB(("Preview::doSearch: 2nd find call return found %d %.2f S\n",
|
516 |
LOGDEB(("Preview::doSearch: 2nd find call return found %d %.2f S\n",
|
528 |
found, chron.secs()));
|
517 |
found, chron.secs()));
|
529 |
}
|
518 |
}
|
530 |
|
519 |
|
531 |
if (found) {
|
520 |
if (found) {
|
532 |
m_canBeep = true;
|
521 |
m_canBeep = true;
|
533 |
} else {
|
522 |
} else {
|
534 |
if (m_canBeep)
|
523 |
if (m_canBeep)
|
535 |
QApplication::beep();
|
524 |
QApplication::beep();
|
536 |
m_canBeep = false;
|
525 |
m_canBeep = false;
|
537 |
}
|
526 |
}
|
538 |
LOGDEB(("Preview::doSearch: return\n"));
|
527 |
LOGDEB(("Preview::doSearch: return\n"));
|
539 |
}
|
528 |
}
|
540 |
|
529 |
|
541 |
void Preview::nextPressed()
|
530 |
void Preview::nextPressed()
|
|
... |
|
... |
554 |
void Preview::currentChanged(int index)
|
543 |
void Preview::currentChanged(int index)
|
555 |
{
|
544 |
{
|
556 |
LOGDEB2(("PreviewTextEdit::currentChanged\n"));
|
545 |
LOGDEB2(("PreviewTextEdit::currentChanged\n"));
|
557 |
QWidget *tw = pvTab->widget(index);
|
546 |
QWidget *tw = pvTab->widget(index);
|
558 |
PreviewTextEdit *edit =
|
547 |
PreviewTextEdit *edit =
|
559 |
tw->findChild<PreviewTextEdit*>("pvEdit");
|
548 |
tw->findChild<PreviewTextEdit*>("pvEdit");
|
560 |
LOGDEB1(("Preview::currentChanged(). Editor: %p\n", edit));
|
549 |
LOGDEB1(("Preview::currentChanged(). Editor: %p\n", edit));
|
561 |
|
550 |
|
562 |
if (edit == 0) {
|
551 |
if (edit == 0) {
|
563 |
LOGERR(("Editor child not found\n"));
|
552 |
LOGERR(("Editor child not found\n"));
|
564 |
return;
|
553 |
return;
|
565 |
}
|
554 |
}
|
566 |
edit->setFocus();
|
555 |
edit->setFocus();
|
567 |
// Disconnect the print signal and reconnect it to the current editor
|
556 |
// Disconnect the print signal and reconnect it to the current editor
|
568 |
LOGDEB(("Disconnecting reconnecting print signal\n"));
|
557 |
LOGDEB(("Disconnecting reconnecting print signal\n"));
|
569 |
disconnect(this, SIGNAL(printCurrentPreviewRequest()), 0, 0);
|
558 |
disconnect(this, SIGNAL(printCurrentPreviewRequest()), 0, 0);
|
|
... |
|
... |
576 |
|
565 |
|
577 |
void Preview::closeCurrentTab()
|
566 |
void Preview::closeCurrentTab()
|
578 |
{
|
567 |
{
|
579 |
LOGDEB1(("Preview::closeCurrentTab: m_loading %d\n", m_loading));
|
568 |
LOGDEB1(("Preview::closeCurrentTab: m_loading %d\n", m_loading));
|
580 |
if (m_loading) {
|
569 |
if (m_loading) {
|
581 |
CancelCheck::instance().setCancel();
|
570 |
CancelCheck::instance().setCancel();
|
582 |
return;
|
571 |
return;
|
583 |
}
|
572 |
}
|
584 |
PreviewTextEdit *e = currentEditor();
|
573 |
PreviewTextEdit *e = currentEditor();
|
585 |
if (e)
|
574 |
if (e)
|
586 |
forgetTempFile(e->m_tmpfilename);
|
575 |
forgetTempFile(e->m_tmpfilename);
|
587 |
if (pvTab->count() > 1) {
|
576 |
if (pvTab->count() > 1) {
|
588 |
pvTab->removeTab(pvTab->currentIndex());
|
577 |
pvTab->removeTab(pvTab->currentIndex());
|
589 |
} else {
|
578 |
} else {
|
590 |
close();
|
579 |
close();
|
591 |
}
|
580 |
}
|
592 |
}
|
581 |
}
|
593 |
|
582 |
|
594 |
PreviewTextEdit *Preview::addEditorTab()
|
583 |
PreviewTextEdit *Preview::addEditorTab()
|
595 |
{
|
584 |
{
|
|
... |
|
... |
609 |
{
|
598 |
{
|
610 |
LOGDEB1(("Preview::setCurTabProps\n"));
|
599 |
LOGDEB1(("Preview::setCurTabProps\n"));
|
611 |
QString title;
|
600 |
QString title;
|
612 |
string ctitle;
|
601 |
string ctitle;
|
613 |
if (doc.getmeta(Rcl::Doc::keytt, &ctitle) && !ctitle.empty()) {
|
602 |
if (doc.getmeta(Rcl::Doc::keytt, &ctitle) && !ctitle.empty()) {
|
614 |
title = QString::fromUtf8(ctitle.c_str(), ctitle.length());
|
603 |
title = QString::fromUtf8(ctitle.c_str(), ctitle.length());
|
615 |
} else {
|
604 |
} else {
|
616 |
title = QString::fromLocal8Bit(path_getsimple(doc.url).c_str());
|
605 |
title = QString::fromLocal8Bit(path_getsimple(doc.url).c_str());
|
617 |
}
|
606 |
}
|
618 |
if (title.length() > 20) {
|
607 |
if (title.length() > 20) {
|
619 |
title = title.left(10) + "..." + title.right(10);
|
608 |
title = title.left(10) + "..." + title.right(10);
|
620 |
}
|
609 |
}
|
621 |
int curidx = pvTab->currentIndex();
|
610 |
int curidx = pvTab->currentIndex();
|
622 |
pvTab->setTabText(curidx, title);
|
611 |
pvTab->setTabText(curidx, title);
|
623 |
|
612 |
|
624 |
char datebuf[100];
|
613 |
char datebuf[100];
|
625 |
datebuf[0] = 0;
|
614 |
datebuf[0] = 0;
|
626 |
if (!doc.fmtime.empty() || !doc.dmtime.empty()) {
|
615 |
if (!doc.fmtime.empty() || !doc.dmtime.empty()) {
|
627 |
time_t mtime = doc.dmtime.empty() ?
|
616 |
time_t mtime = doc.dmtime.empty() ?
|
628 |
atoll(doc.fmtime.c_str()) : atoll(doc.dmtime.c_str());
|
617 |
atoll(doc.fmtime.c_str()) : atoll(doc.dmtime.c_str());
|
629 |
struct tm *tm = localtime(&mtime);
|
618 |
struct tm *tm = localtime(&mtime);
|
630 |
strftime(datebuf, 99, "%Y-%m-%d %H:%M:%S", tm);
|
619 |
strftime(datebuf, 99, "%Y-%m-%d %H:%M:%S", tm);
|
631 |
}
|
620 |
}
|
632 |
LOGDEB(("Doc.url: [%s]\n", doc.url.c_str()));
|
621 |
LOGDEB(("Doc.url: [%s]\n", doc.url.c_str()));
|
633 |
string url;
|
622 |
string url;
|
634 |
printableUrl(theconfig->getDefCharset(), doc.url, url);
|
623 |
printableUrl(theconfig->getDefCharset(), doc.url, url);
|
635 |
string tiptxt = url + string("\n");
|
624 |
string tiptxt = url + string("\n");
|
636 |
tiptxt += doc.mimetype + " " + string(datebuf) + "\n";
|
625 |
tiptxt += doc.mimetype + " " + string(datebuf) + "\n";
|
637 |
if (!ctitle.empty())
|
626 |
if (!ctitle.empty())
|
638 |
tiptxt += ctitle + "\n";
|
627 |
tiptxt += ctitle + "\n";
|
639 |
pvTab->setTabToolTip(curidx,
|
628 |
pvTab->setTabToolTip(curidx,
|
640 |
QString::fromUtf8(tiptxt.c_str(), tiptxt.length()));
|
629 |
QString::fromUtf8(tiptxt.c_str(), tiptxt.length()));
|
641 |
|
630 |
|
642 |
PreviewTextEdit *e = currentEditor();
|
631 |
PreviewTextEdit *e = currentEditor();
|
643 |
if (e) {
|
632 |
if (e) {
|
644 |
e->m_url = doc.url;
|
633 |
e->m_url = doc.url;
|
645 |
e->m_ipath = doc.ipath;
|
634 |
e->m_ipath = doc.ipath;
|
646 |
e->m_docnum = docnum;
|
635 |
e->m_docnum = docnum;
|
647 |
}
|
636 |
}
|
648 |
}
|
637 |
}
|
649 |
|
638 |
|
650 |
bool Preview::makeDocCurrent(const Rcl::Doc& doc, int docnum, bool sametab)
|
639 |
bool Preview::makeDocCurrent(const Rcl::Doc& doc, int docnum, bool sametab)
|
651 |
{
|
640 |
{
|
652 |
LOGDEB(("Preview::makeDocCurrent: %s\n", doc.url.c_str()));
|
641 |
LOGDEB(("Preview::makeDocCurrent: %s\n", doc.url.c_str()));
|
653 |
|
642 |
|
654 |
if (m_loading) {
|
643 |
if (m_loading) {
|
655 |
LOGERR(("Already loading\n"));
|
644 |
LOGERR(("Already loading\n"));
|
656 |
return false;
|
645 |
return false;
|
657 |
}
|
646 |
}
|
658 |
|
647 |
|
659 |
/* Check if we already have this page */
|
648 |
/* Check if we already have this page */
|
660 |
for (int i = 0; i < pvTab->count(); i++) {
|
649 |
for (int i = 0; i < pvTab->count(); i++) {
|
661 |
QWidget *tw = pvTab->widget(i);
|
650 |
QWidget *tw = pvTab->widget(i);
|
662 |
if (tw) {
|
651 |
if (tw) {
|
663 |
PreviewTextEdit *edit =
|
652 |
PreviewTextEdit *edit =
|
664 |
tw->findChild<PreviewTextEdit*>("pvEdit");
|
653 |
tw->findChild<PreviewTextEdit*>("pvEdit");
|
665 |
if (edit && !edit->m_url.compare(doc.url) &&
|
654 |
if (edit && !edit->m_url.compare(doc.url) &&
|
666 |
!edit->m_ipath.compare(doc.ipath)) {
|
655 |
!edit->m_ipath.compare(doc.ipath)) {
|
667 |
pvTab->setCurrentIndex(i);
|
656 |
pvTab->setCurrentIndex(i);
|
668 |
return true;
|
657 |
return true;
|
669 |
}
|
658 |
}
|
670 |
}
|
659 |
}
|
671 |
}
|
660 |
}
|
672 |
|
661 |
|
673 |
// if just created the first tab was created during init
|
662 |
// if just created the first tab was created during init
|
674 |
if (!sametab && !m_justCreated && !addEditorTab()) {
|
663 |
if (!sametab && !m_justCreated && !addEditorTab()) {
|
675 |
return false;
|
664 |
return false;
|
676 |
}
|
665 |
}
|
677 |
m_justCreated = false;
|
666 |
m_justCreated = false;
|
678 |
if (!loadDocInCurrentTab(doc, docnum)) {
|
667 |
if (!loadDocInCurrentTab(doc, docnum)) {
|
679 |
closeCurrentTab();
|
668 |
closeCurrentTab();
|
680 |
return false;
|
669 |
return false;
|
681 |
}
|
670 |
}
|
682 |
raise();
|
671 |
raise();
|
683 |
return true;
|
672 |
return true;
|
684 |
}
|
673 |
}
|
685 |
void Preview::togglePlainPre()
|
674 |
void Preview::togglePlainPre()
|
686 |
{
|
675 |
{
|
687 |
switch (prefs.previewPlainPre) {
|
676 |
switch (prefs.previewPlainPre) {
|
688 |
case PrefsPack::PP_BR:
|
677 |
case PrefsPack::PP_BR:
|
689 |
prefs.previewPlainPre = PrefsPack::PP_PRE;
|
678 |
prefs.previewPlainPre = PrefsPack::PP_PRE;
|
690 |
break;
|
679 |
break;
|
691 |
case PrefsPack::PP_PRE:
|
680 |
case PrefsPack::PP_PRE:
|
692 |
prefs.previewPlainPre = PrefsPack::PP_BR;
|
681 |
prefs.previewPlainPre = PrefsPack::PP_BR;
|
693 |
break;
|
682 |
break;
|
694 |
case PrefsPack::PP_PREWRAP:
|
683 |
case PrefsPack::PP_PREWRAP:
|
695 |
default:
|
684 |
default:
|
696 |
prefs.previewPlainPre = PrefsPack::PP_PRE;
|
685 |
prefs.previewPlainPre = PrefsPack::PP_PRE;
|
697 |
break;
|
686 |
break;
|
698 |
}
|
687 |
}
|
699 |
|
688 |
|
700 |
PreviewTextEdit *editor = currentEditor();
|
689 |
PreviewTextEdit *editor = currentEditor();
|
701 |
if (editor)
|
690 |
if (editor)
|
702 |
loadDocInCurrentTab(editor->m_dbdoc, editor->m_docnum);
|
691 |
loadDocInCurrentTab(editor->m_dbdoc, editor->m_docnum);
|
703 |
}
|
692 |
}
|
704 |
|
693 |
|
705 |
void Preview::emitWordSelect(QString word)
|
694 |
void Preview::emitWordSelect(QString word)
|
706 |
{
|
695 |
{
|
707 |
emit(wordSelect(word));
|
696 |
emit(wordSelect(word));
|
|
... |
|
... |
727 |
class LoadThread : public QThread {
|
716 |
class LoadThread : public QThread {
|
728 |
int *statusp;
|
717 |
int *statusp;
|
729 |
Rcl::Doc& out;
|
718 |
Rcl::Doc& out;
|
730 |
const Rcl::Doc& idoc;
|
719 |
const Rcl::Doc& idoc;
|
731 |
int loglevel;
|
720 |
int loglevel;
|
732 |
public:
|
721 |
public:
|
733 |
string missing;
|
722 |
string missing;
|
734 |
TempFile imgtmp;
|
723 |
TempFile imgtmp;
|
735 |
|
724 |
|
736 |
LoadThread(int *stp, Rcl::Doc& odoc, const Rcl::Doc& idc)
|
725 |
LoadThread(int *stp, Rcl::Doc& odoc, const Rcl::Doc& idc)
|
737 |
: statusp(stp), out(odoc), idoc(idc)
|
726 |
: statusp(stp), out(odoc), idoc(idc)
|
738 |
{
|
727 |
{
|
739 |
loglevel = DebugLog::getdbl()->getlevel();
|
728 |
loglevel = DebugLog::getdbl()->getlevel();
|
740 |
}
|
729 |
}
|
741 |
~LoadThread() {
|
730 |
~LoadThread() {
|
742 |
}
|
731 |
}
|
743 |
virtual void run() {
|
732 |
virtual void run() {
|
744 |
DebugLog::getdbl()->setloglevel(loglevel);
|
733 |
DebugLog::getdbl()->setloglevel(loglevel);
|
745 |
|
|
|
746 |
FileInterner interner(idoc, theconfig, FileInterner::FIF_forPreview);
|
734 |
FileInterner interner(idoc, theconfig, FileInterner::FIF_forPreview);
|
747 |
FIMissingStore mst;
|
735 |
FIMissingStore mst;
|
748 |
interner.setMissingStore(&mst);
|
736 |
interner.setMissingStore(&mst);
|
749 |
// Even when previewHtml is set, we don't set the interner's
|
737 |
// Even when previewHtml is set, we don't set the interner's
|
750 |
// target mtype to html because we do want the html filter to
|
738 |
// target mtype to html because we do want the html filter to
|
751 |
// do its work: we won't use the text/plain, but we want the
|
739 |
// do its work: we won't use the text/plain, but we want the
|
752 |
// text/html to be converted to utf-8 (for highlight processing)
|
740 |
// text/html to be converted to utf-8 (for highlight processing)
|
753 |
try {
|
741 |
try {
|
754 |
string ipath = idoc.ipath;
|
742 |
string ipath = idoc.ipath;
|
755 |
FileInterner::Status ret = interner.internfile(out, ipath);
|
743 |
FileInterner::Status ret = interner.internfile(out, ipath);
|
756 |
if (ret == FileInterner::FIDone || ret == FileInterner::FIAgain) {
|
744 |
if (ret == FileInterner::FIDone || ret == FileInterner::FIAgain) {
|
757 |
// FIAgain is actually not nice here. It means that the record
|
745 |
// FIAgain is actually not nice here. It means that the record
|
758 |
// for the *file* of a multidoc was selected. Actually this
|
746 |
// for the *file* of a multidoc was selected. Actually this
|
759 |
// shouldn't have had a preview link at all, but we don't know
|
747 |
// shouldn't have had a preview link at all, but we don't know
|
760 |
// how to handle it now. Better to show the first doc than
|
748 |
// how to handle it now. Better to show the first doc than
|
761 |
// a mysterious error. Happens when the file name matches a
|
749 |
// a mysterious error. Happens when the file name matches a
|
762 |
// a search term.
|
750 |
// a search term.
|
763 |
*statusp = 0;
|
751 |
*statusp = 0;
|
764 |
// If we prefer html and it is available, replace the
|
752 |
// If we prefer html and it is available, replace the
|
765 |
// text/plain document text
|
753 |
// text/plain document text
|
766 |
if (prefs.previewHtml && !interner.get_html().empty()) {
|
754 |
if (prefs.previewHtml && !interner.get_html().empty()) {
|
767 |
out.text = interner.get_html();
|
755 |
out.text = interner.get_html();
|
768 |
out.mimetype = "text/html";
|
756 |
out.mimetype = "text/html";
|
769 |
}
|
757 |
}
|
770 |
imgtmp = interner.get_imgtmp();
|
758 |
imgtmp = interner.get_imgtmp();
|
771 |
} else {
|
759 |
} else {
|
772 |
out.mimetype = interner.getMimetype();
|
760 |
out.mimetype = interner.getMimetype();
|
773 |
mst.getMissingExternal(missing);
|
761 |
mst.getMissingExternal(missing);
|
774 |
*statusp = -1;
|
762 |
*statusp = -1;
|
775 |
}
|
763 |
}
|
776 |
} catch (CancelExcept) {
|
764 |
} catch (CancelExcept) {
|
777 |
*statusp = -1;
|
765 |
*statusp = -1;
|
778 |
}
|
766 |
}
|
779 |
}
|
767 |
}
|
780 |
};
|
768 |
};
|
781 |
|
769 |
|
782 |
|
770 |
|
783 |
// Insert into editor by chunks so that the top becomes visible
|
771 |
// Insert into editor by chunks so that the top becomes visible
|
|
... |
|
... |
790 |
string ∈
|
778 |
string ∈
|
791 |
const HighlightData &hdata;
|
779 |
const HighlightData &hdata;
|
792 |
list<string> &out;
|
780 |
list<string> &out;
|
793 |
int loglevel;
|
781 |
int loglevel;
|
794 |
PlainToRichQtPreview *ptr;
|
782 |
PlainToRichQtPreview *ptr;
|
795 |
public:
|
783 |
public:
|
796 |
ToRichThread(string &i, const HighlightData& hd, list<string> &o,
|
784 |
ToRichThread(string &i, const HighlightData& hd, list<string> &o,
|
797 |
PlainToRichQtPreview *_ptr)
|
785 |
PlainToRichQtPreview *_ptr)
|
798 |
: in(i), hdata(hd), out(o), ptr(_ptr)
|
786 |
: in(i), hdata(hd), out(o), ptr(_ptr)
|
799 |
{
|
787 |
{
|
800 |
loglevel = DebugLog::getdbl()->getlevel();
|
788 |
loglevel = DebugLog::getdbl()->getlevel();
|
801 |
}
|
789 |
}
|
802 |
virtual void run()
|
790 |
virtual void run()
|
803 |
{
|
791 |
{
|
804 |
DebugLog::getdbl()->setloglevel(loglevel);
|
792 |
DebugLog::getdbl()->setloglevel(loglevel);
|
805 |
try {
|
793 |
try {
|
806 |
ptr->plaintorich(in, out, hdata, CHUNKL);
|
794 |
ptr->plaintorich(in, out, hdata, CHUNKL);
|
807 |
} catch (CancelExcept) {
|
795 |
} catch (CancelExcept) {
|
808 |
}
|
796 |
}
|
809 |
}
|
797 |
}
|
810 |
};
|
798 |
};
|
811 |
|
799 |
|
812 |
class LoadGuard {
|
800 |
class LoadGuard {
|
813 |
bool *m_bp;
|
801 |
bool *m_bp;
|
814 |
public:
|
802 |
public:
|
|
... |
|
... |
824 |
CancelCheck::instance().setCancel(false);
|
812 |
CancelCheck::instance().setCancel(false);
|
825 |
|
813 |
|
826 |
setCurTabProps(idoc, docnum);
|
814 |
setCurTabProps(idoc, docnum);
|
827 |
|
815 |
|
828 |
QString msg = QString("Loading: %1 (size %2 bytes)")
|
816 |
QString msg = QString("Loading: %1 (size %2 bytes)")
|
829 |
.arg(QString::fromLocal8Bit(idoc.url.c_str()))
|
817 |
.arg(QString::fromLocal8Bit(idoc.url.c_str()))
|
830 |
.arg(QString::fromUtf8(idoc.fbytes.c_str()));
|
818 |
.arg(QString::fromUtf8(idoc.fbytes.c_str()));
|
831 |
|
819 |
|
832 |
// Create progress dialog and aux objects
|
|
|
833 |
const int nsteps = 20;
|
|
|
834 |
QProgressDialog progress(msg, tr("Cancel"), 0, nsteps, this);
|
820 |
QProgressDialog progress(msg, tr("Cancel"), 0, 0, this);
|
835 |
progress.setMinimumDuration(2000);
|
821 |
progress.setMinimumDuration(2000);
|
|
|
822 |
QEventLoop loop;
|
|
|
823 |
QTimer tT;
|
|
|
824 |
tT.setSingleShot(true);
|
|
|
825 |
connect(&tT, SIGNAL(timeout()), &loop, SLOT(quit()));
|
836 |
|
826 |
|
837 |
////////////////////////////////////////////////////////////////////////
|
827 |
////////////////////////////////////////////////////////////////////////
|
838 |
// Load and convert document
|
828 |
// Load and convert document
|
839 |
// idoc came out of the index data (main text and some fields missing).
|
829 |
// idoc came out of the index data (main text and some fields missing).
|
840 |
// fdoc is the complete one what we are going to extract from storage.
|
830 |
// fdoc is the complete one what we are going to extract from storage.
|
841 |
Rcl::Doc fdoc;
|
831 |
Rcl::Doc fdoc;
|
842 |
int status = 1;
|
832 |
int status = 1;
|
843 |
LoadThread lthr(&status, fdoc, idoc);
|
833 |
LoadThread lthr(&status, fdoc, idoc);
|
|
|
834 |
connect(<hr, SIGNAL(finished()), &loop, SLOT(quit()));
|
|
|
835 |
|
844 |
lthr.start();
|
836 |
lthr.start();
|
845 |
int prog;
|
837 |
for (int i = 0;;i++) {
|
846 |
for (prog = 1;;prog++) {
|
838 |
tT.start(1000);
|
847 |
if (lthr.wait(100))
|
839 |
loop.exec();
|
848 |
break;
|
840 |
if (lthr.isFinished())
|
849 |
progress.setValue(prog);
|
841 |
break;
|
850 |
qApp->processEvents();
|
|
|
851 |
if (progress.wasCanceled()) {
|
842 |
if (progress.wasCanceled()) {
|
852 |
CancelCheck::instance().setCancel();
|
843 |
CancelCheck::instance().setCancel();
|
853 |
}
|
844 |
}
|
854 |
if (prog >= 5)
|
845 |
if (i == 2)
|
855 |
sleep(1);
|
846 |
progress.show();
|
856 |
}
|
847 |
}
|
857 |
|
848 |
|
858 |
LOGDEB(("loadDocInCurrentTab: after file load: cancel %d status %d"
|
849 |
LOGDEB(("loadDocInCurrentTab: after file load: cancel %d status %d"
|
859 |
" text length %d\n",
|
850 |
" text length %d\n",
|
860 |
CancelCheck::instance().cancelState(), status, fdoc.text.length()));
|
851 |
CancelCheck::instance().cancelState(), status, fdoc.text.length()));
|
861 |
|
852 |
|
862 |
if (CancelCheck::instance().cancelState())
|
853 |
if (CancelCheck::instance().cancelState())
|
863 |
return false;
|
854 |
return false;
|
864 |
if (status != 0) {
|
855 |
if (status != 0) {
|
|
|
856 |
progress.close();
|
865 |
QString explain;
|
857 |
QString explain;
|
866 |
if (!lthr.missing.empty()) {
|
858 |
if (!lthr.missing.empty()) {
|
867 |
explain = QString::fromUtf8("<br>") +
|
859 |
explain = QString::fromUtf8("<br>") +
|
868 |
tr("Missing helper program: ") +
|
860 |
tr("Missing helper program: ") +
|
869 |
QString::fromLocal8Bit(lthr.missing.c_str());
|
861 |
QString::fromLocal8Bit(lthr.missing.c_str());
|
870 |
QMessageBox::warning(0, "Recoll",
|
862 |
QMessageBox::warning(0, "Recoll",
|
871 |
tr("Can't turn doc into internal "
|
863 |
tr("Can't turn doc into internal "
|
872 |
"representation for ") +
|
864 |
"representation for ") +
|
873 |
fdoc.mimetype.c_str() + explain);
|
865 |
fdoc.mimetype.c_str() + explain);
|
874 |
} else {
|
866 |
} else {
|
875 |
QMessageBox::warning(0, "Recoll",
|
867 |
QMessageBox::warning(0, "Recoll",
|
876 |
tr("Error while loading file"));
|
868 |
tr("Error while loading file"));
|
877 |
}
|
869 |
}
|
878 |
|
870 |
|
879 |
return false;
|
871 |
return false;
|
880 |
}
|
872 |
}
|
881 |
// Reset config just in case.
|
873 |
// Reset config just in case.
|
882 |
theconfig->setKeyDir("");
|
874 |
theconfig->setKeyDir("");
|
883 |
|
875 |
|
884 |
////////////////////////////////////////////////////////////////////////
|
876 |
////////////////////////////////////////////////////////////////////////
|
885 |
// Create preview text: highlight search terms
|
877 |
// Create preview text: highlight search terms
|
886 |
// We don't do the highlighting for very big texts: too long. We
|
878 |
// We don't do the highlighting for very big texts: too long. We
|
887 |
// should at least do special char escaping, in case a '&' or '<'
|
879 |
// should at least do special char escaping, in case a '&' or '<'
|
888 |
// somehow slipped through previous processing.
|
880 |
// somehow slipped through previous processing.
|
889 |
bool highlightTerms = fdoc.text.length() <
|
881 |
bool highlightTerms = fdoc.text.length() <
|
890 |
(unsigned long)prefs.maxhltextmbs * 1024 * 1024;
|
882 |
(unsigned long)prefs.maxhltextmbs * 1024 * 1024;
|
891 |
|
883 |
|
892 |
// Final text is produced in chunks so that we can display the top
|
884 |
// Final text is produced in chunks so that we can display the top
|
893 |
// while still inserting at bottom
|
885 |
// while still inserting at bottom
|
894 |
list<QString> qrichlst;
|
886 |
list<QString> qrichlst;
|
895 |
PreviewTextEdit *editor = currentEditor();
|
887 |
PreviewTextEdit *editor = currentEditor();
|
|
... |
|
... |
903 |
// relatively limited html support (text sometimes get hidden by
|
895 |
// relatively limited html support (text sometimes get hidden by
|
904 |
// images).
|
896 |
// images).
|
905 |
#if 0
|
897 |
#if 0
|
906 |
string path = fileurltolocalpath(idoc.url);
|
898 |
string path = fileurltolocalpath(idoc.url);
|
907 |
if (!path.empty()) {
|
899 |
if (!path.empty()) {
|
908 |
path = path_getfather(path);
|
900 |
path = path_getfather(path);
|
909 |
QStringList paths(QString::fromLocal8Bit(path.c_str()));
|
901 |
QStringList paths(QString::fromLocal8Bit(path.c_str()));
|
910 |
editor->setSearchPaths(paths);
|
902 |
editor->setSearchPaths(paths);
|
911 |
}
|
903 |
}
|
912 |
#endif
|
904 |
#endif
|
913 |
|
905 |
|
914 |
editor->setHtml("");
|
906 |
editor->setHtml("");
|
915 |
editor->m_format = Qt::RichText;
|
907 |
editor->m_format = Qt::RichText;
|
|
... |
|
... |
917 |
|
909 |
|
918 |
#if 0
|
910 |
#if 0
|
919 |
// For testing qtextedit bugs...
|
911 |
// For testing qtextedit bugs...
|
920 |
highlightTerms = true;
|
912 |
highlightTerms = true;
|
921 |
const char *textlist[] =
|
913 |
const char *textlist[] =
|
922 |
{
|
914 |
{
|
923 |
"Du plain text avec un\n <termtag>termtag</termtag> fin de ligne:",
|
915 |
"Du plain text avec un\n <termtag>termtag</termtag> fin de ligne:",
|
924 |
"texte apres le tag\n",
|
916 |
"texte apres le tag\n",
|
925 |
};
|
917 |
};
|
926 |
const int listl = sizeof(textlist) / sizeof(char*);
|
918 |
const int listl = sizeof(textlist) / sizeof(char*);
|
927 |
for (int i = 0 ; i < listl ; i++)
|
919 |
for (int i = 0 ; i < listl ; i++)
|
928 |
qrichlst.push_back(QString::fromUtf8(textlist[i]));
|
920 |
qrichlst.push_back(QString::fromUtf8(textlist[i]));
|
929 |
#else
|
921 |
#else
|
930 |
if (highlightTerms) {
|
922 |
if (highlightTerms) {
|
931 |
progress.setLabelText(tr("Creating preview text"));
|
923 |
progress.setLabelText(tr("Creating preview text"));
|
932 |
qApp->processEvents();
|
924 |
qApp->processEvents();
|
933 |
|
925 |
|
934 |
if (inputishtml) {
|
926 |
if (inputishtml) {
|
935 |
LOGDEB1(("Preview: got html %s\n", fdoc.text.c_str()));
|
927 |
LOGDEB1(("Preview: got html %s\n", fdoc.text.c_str()));
|
936 |
editor->m_plaintorich->set_inputhtml(true);
|
928 |
editor->m_plaintorich->set_inputhtml(true);
|
937 |
} else {
|
929 |
} else {
|
938 |
LOGDEB1(("Preview: got plain %s\n", fdoc.text.c_str()));
|
930 |
LOGDEB1(("Preview: got plain %s\n", fdoc.text.c_str()));
|
939 |
editor->m_plaintorich->set_inputhtml(false);
|
931 |
editor->m_plaintorich->set_inputhtml(false);
|
940 |
}
|
932 |
}
|
941 |
list<string> richlst;
|
933 |
list<string> richlst;
|
942 |
ToRichThread rthr(fdoc.text, m_hData, richlst, editor->m_plaintorich);
|
934 |
ToRichThread rthr(fdoc.text, m_hData, richlst, editor->m_plaintorich);
|
|
|
935 |
connect(&rthr, SIGNAL(finished()), &loop, SLOT(quit()));
|
943 |
rthr.start();
|
936 |
rthr.start();
|
944 |
|
937 |
|
945 |
for (;;prog++) {
|
938 |
for (;;) {
|
946 |
if (rthr.wait(100))
|
939 |
tT.start(1000);
|
947 |
break;
|
940 |
loop.exec();
|
948 |
progress.setValue(nsteps);
|
941 |
if (rthr.isFinished())
|
949 |
qApp->processEvents();
|
942 |
break;
|
950 |
if (progress.wasCanceled()) {
|
943 |
if (progress.wasCanceled()) {
|
951 |
CancelCheck::instance().setCancel();
|
944 |
CancelCheck::instance().setCancel();
|
952 |
}
|
945 |
}
|
953 |
if (prog >= 5)
|
946 |
}
|
954 |
sleep(1);
|
|
|
955 |
}
|
|
|
956 |
|
947 |
|
957 |
// Conversion to rich text done
|
948 |
// Conversion to rich text done
|
958 |
if (CancelCheck::instance().cancelState()) {
|
949 |
if (CancelCheck::instance().cancelState()) {
|
959 |
if (richlst.size() == 0 || richlst.front().length() == 0) {
|
950 |
if (richlst.size() == 0 || richlst.front().length() == 0) {
|
960 |
// We can't call closeCurrentTab here as it might delete
|
951 |
// We can't call closeCurrentTab here as it might delete
|
961 |
// the object which would be a nasty surprise to our
|
952 |
// the object which would be a nasty surprise to our
|
962 |
// caller.
|
953 |
// caller.
|
963 |
return false;
|
954 |
return false;
|
964 |
} else {
|
955 |
} else {
|
965 |
richlst.back() += "<b>Cancelled !</b>";
|
956 |
richlst.back() += "<b>Cancelled !</b>";
|
966 |
}
|
957 |
}
|
967 |
}
|
958 |
}
|
968 |
// Convert C++ string list to QString list
|
959 |
// Convert C++ string list to QString list
|
969 |
for (list<string>::iterator it = richlst.begin();
|
960 |
for (list<string>::iterator it = richlst.begin();
|
970 |
it != richlst.end(); it++) {
|
961 |
it != richlst.end(); it++) {
|
971 |
qrichlst.push_back(QString::fromUtf8(it->c_str(), it->length()));
|
962 |
qrichlst.push_back(QString::fromUtf8(it->c_str(), it->length()));
|
972 |
}
|
963 |
}
|
973 |
} else {
|
964 |
} else {
|
974 |
LOGDEB(("Preview: no hilighting\n"));
|
965 |
LOGDEB(("Preview: no hilighting\n"));
|
975 |
// No plaintorich() call. In this case, either the text is
|
966 |
// No plaintorich() call. In this case, either the text is
|
976 |
// html and the html quoting is hopefully correct, or it's
|
967 |
// html and the html quoting is hopefully correct, or it's
|
977 |
// plain-text and there is no need to escape special
|
968 |
// plain-text and there is no need to escape special
|
978 |
// characters. We'd still want to split in chunks (so that the
|
969 |
// characters. We'd still want to split in chunks (so that the
|
979 |
// top is displayed faster), but we must not cut tags, and
|
970 |
// top is displayed faster), but we must not cut tags, and
|
980 |
// it's too difficult on html. For text we do the splitting on
|
971 |
// it's too difficult on html. For text we do the splitting on
|
981 |
// a QString to avoid utf8 issues.
|
972 |
// a QString to avoid utf8 issues.
|
982 |
QString qr = QString::fromUtf8(fdoc.text.c_str(), fdoc.text.length());
|
973 |
QString qr = QString::fromUtf8(fdoc.text.c_str(), fdoc.text.length());
|
983 |
int l = 0;
|
974 |
int l = 0;
|
984 |
if (inputishtml) {
|
975 |
if (inputishtml) {
|
985 |
qrichlst.push_back(qr);
|
976 |
qrichlst.push_back(qr);
|
986 |
} else {
|
977 |
} else {
|
987 |
editor->setPlainText("");
|
978 |
editor->setPlainText("");
|
988 |
editor->m_format = Qt::PlainText;
|
979 |
editor->m_format = Qt::PlainText;
|
989 |
for (int pos = 0; pos < (int)qr.length(); pos += l) {
|
980 |
for (int pos = 0; pos < (int)qr.length(); pos += l) {
|
990 |
l = MIN(CHUNKL, qr.length() - pos);
|
981 |
l = MIN(CHUNKL, qr.length() - pos);
|
991 |
qrichlst.push_back(qr.mid(pos, l));
|
982 |
qrichlst.push_back(qr.mid(pos, l));
|
992 |
}
|
983 |
}
|
993 |
}
|
984 |
}
|
994 |
}
|
985 |
}
|
995 |
#endif
|
986 |
#endif
|
996 |
|
|
|
997 |
|
987 |
|
998 |
|
988 |
|
999 |
///////////////////////////////////////////////////////////
|
989 |
///////////////////////////////////////////////////////////
|
1000 |
// Load text into editor window.
|
990 |
// Load text into editor window.
|
1001 |
prog = 2 * nsteps / 3;
|
|
|
1002 |
progress.setLabelText(tr("Loading preview text into editor"));
|
991 |
progress.setLabelText(tr("Loading preview text into editor"));
|
1003 |
qApp->processEvents();
|
992 |
qApp->processEvents();
|
1004 |
int instep = 0;
|
|
|
1005 |
for (list<QString>::iterator it = qrichlst.begin();
|
993 |
for (list<QString>::iterator it = qrichlst.begin();
|
1006 |
it != qrichlst.end(); it++, prog++, instep++) {
|
994 |
it != qrichlst.end(); it++) {
|
1007 |
progress.setValue(prog);
|
|
|
1008 |
qApp->processEvents();
|
995 |
qApp->processEvents();
|
1009 |
|
996 |
|
1010 |
editor->append(*it);
|
997 |
editor->append(*it);
|
1011 |
// We need to save the rich text for printing, the editor does
|
998 |
// We need to save the rich text for printing, the editor does
|
1012 |
// not do it consistently for us.
|
999 |
// not do it consistently for us.
|
1013 |
editor->m_richtxt.append(*it);
|
1000 |
editor->m_richtxt.append(*it);
|
1014 |
|
1001 |
|
1015 |
if (progress.wasCanceled()) {
|
1002 |
if (progress.wasCanceled()) {
|
1016 |
editor->append("<b>Cancelled !</b>");
|
1003 |
editor->append("<b>Cancelled !</b>");
|
1017 |
LOGDEB(("loadDocInCurrentTab: cancelled in editor load\n"));
|
1004 |
LOGDEB(("loadDocInCurrentTab: cancelled in editor load\n"));
|
1018 |
break;
|
1005 |
break;
|
1019 |
}
|
1006 |
}
|
1020 |
}
|
1007 |
}
|
1021 |
|
1008 |
|
1022 |
progress.close();
|
1009 |
progress.close();
|
1023 |
editor->m_curdsp = PreviewTextEdit::PTE_DSPTXT;
|
1010 |
editor->m_curdsp = PreviewTextEdit::PTE_DSPTXT;
|
1024 |
|
1011 |
|
|
... |
|
... |
1036 |
if (textempty)
|
1023 |
if (textempty)
|
1037 |
editor->displayFields();
|
1024 |
editor->displayFields();
|
1038 |
|
1025 |
|
1039 |
// If this is an image, display it instead of the text.
|
1026 |
// If this is an image, display it instead of the text.
|
1040 |
if (!idoc.mimetype.compare(0, 6, "image/")) {
|
1027 |
if (!idoc.mimetype.compare(0, 6, "image/")) {
|
1041 |
string fn = fileurltolocalpath(idoc.url);
|
1028 |
string fn = fileurltolocalpath(idoc.url);
|
1042 |
|
1029 |
|
1043 |
// If the command wants a file but this is not a file url, or
|
1030 |
// If the command wants a file but this is not a file url, or
|
1044 |
// there is an ipath that it won't understand, we need a temp file:
|
1031 |
// there is an ipath that it won't understand, we need a temp file:
|
1045 |
theconfig->setKeyDir(path_getfather(fn));
|
1032 |
theconfig->setKeyDir(path_getfather(fn));
|
1046 |
if (fn.empty() || !idoc.ipath.empty()) {
|
1033 |
if (fn.empty() || !idoc.ipath.empty()) {
|
1047 |
TempFile temp = lthr.imgtmp;
|
1034 |
TempFile temp = lthr.imgtmp;
|
1048 |
if (temp) {
|
1035 |
if (temp) {
|
1049 |
LOGDEB1(("Preview: load: got temp file from internfile\n"));
|
1036 |
LOGDEB1(("Preview: load: got temp file from internfile\n"));
|
1050 |
} else if (!FileInterner::idocToFile(temp, string(),
|
1037 |
} else if (!FileInterner::idocToFile(temp, string(),
|
1051 |
theconfig, idoc)) {
|
1038 |
theconfig, idoc)) {
|
1052 |
temp.reset(); // just in case.
|
1039 |
temp.reset(); // just in case.
|
|
|
1040 |
}
|
|
|
1041 |
if (temp) {
|
|
|
1042 |
rememberTempFile(temp);
|
|
|
1043 |
fn = temp->filename();
|
|
|
1044 |
editor->m_tmpfilename = fn;
|
|
|
1045 |
} else {
|
|
|
1046 |
editor->m_tmpfilename.erase();
|
|
|
1047 |
fn.erase();
|
|
|
1048 |
}
|
|
|
1049 |
}
|
|
|
1050 |
|
|
|
1051 |
if (!fn.empty()) {
|
|
|
1052 |
editor->m_image = QImage(fn.c_str());
|
|
|
1053 |
if (!editor->m_image.isNull())
|
|
|
1054 |
editor->displayImage();
|
|
|
1055 |
}
|
1053 |
}
|
1056 |
}
|
1054 |
if (temp) {
|
|
|
1055 |
rememberTempFile(temp);
|
|
|
1056 |
fn = temp->filename();
|
|
|
1057 |
editor->m_tmpfilename = fn;
|
|
|
1058 |
} else {
|
|
|
1059 |
editor->m_tmpfilename.erase();
|
|
|
1060 |
fn.erase();
|
|
|
1061 |
}
|
|
|
1062 |
}
|
|
|
1063 |
|
|
|
1064 |
if (!fn.empty()) {
|
|
|
1065 |
editor->m_image = QImage(fn.c_str());
|
|
|
1066 |
if (!editor->m_image.isNull())
|
|
|
1067 |
editor->displayImage();
|
|
|
1068 |
}
|
|
|
1069 |
}
|
|
|
1070 |
|
1057 |
|
1071 |
|
1058 |
|
1072 |
// Position the editor so that the first search term is visible
|
1059 |
// Position the editor so that the first search term is visible
|
1073 |
if (searchTextCMB->currentText().length() != 0) {
|
1060 |
if (searchTextCMB->currentText().length() != 0) {
|
1074 |
// If there is a current search string, perform the search
|
1061 |
// If there is a current search string, perform the search
|
1075 |
m_canBeep = true;
|
1062 |
m_canBeep = true;
|
1076 |
doSearch(searchTextCMB->currentText(), true, false);
|
1063 |
doSearch(searchTextCMB->currentText(), true, false);
|
1077 |
} else {
|
1064 |
} else {
|
1078 |
// Position to the first query term
|
1065 |
// Position to the first query term
|
1079 |
if (editor->m_plaintorich->haveAnchors()) {
|
1066 |
if (editor->m_plaintorich->haveAnchors()) {
|
1080 |
QString aname = editor->m_plaintorich->curAnchorName();
|
1067 |
QString aname = editor->m_plaintorich->curAnchorName();
|
1081 |
LOGDEB2(("Call movetoanchor(%s)\n", (const char *)aname.toUtf8()));
|
1068 |
LOGDEB2(("Call movetoanchor(%s)\n", (const char *)aname.toUtf8()));
|
1082 |
editor->scrollToAnchor(aname);
|
1069 |
editor->scrollToAnchor(aname);
|
1083 |
// Position the cursor approximately at the anchor (top of
|
1070 |
// Position the cursor approximately at the anchor (top of
|
1084 |
// viewport) so that searches start from here
|
1071 |
// viewport) so that searches start from here
|
1085 |
QTextCursor cursor = editor->cursorForPosition(QPoint(0, 0));
|
1072 |
QTextCursor cursor = editor->cursorForPosition(QPoint(0, 0));
|
1086 |
editor->setTextCursor(cursor);
|
1073 |
editor->setTextCursor(cursor);
|
1087 |
}
|
1074 |
}
|
1088 |
}
|
1075 |
}
|
1089 |
|
1076 |
|
1090 |
|
1077 |
|
1091 |
// Enter document in document history
|
1078 |
// Enter document in document history
|
1092 |
string udi;
|
1079 |
string udi;
|
|
... |
|
... |
1106 |
m_dspflds(false), m_docnum(-1)
|
1093 |
m_dspflds(false), m_docnum(-1)
|
1107 |
{
|
1094 |
{
|
1108 |
setContextMenuPolicy(Qt::CustomContextMenu);
|
1095 |
setContextMenuPolicy(Qt::CustomContextMenu);
|
1109 |
setObjectName(nm);
|
1096 |
setObjectName(nm);
|
1110 |
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
|
1097 |
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
|
1111 |
this, SLOT(createPopupMenu(const QPoint&)));
|
1098 |
this, SLOT(createPopupMenu(const QPoint&)));
|
1112 |
setOpenExternalLinks(false);
|
1099 |
setOpenExternalLinks(false);
|
1113 |
setOpenLinks(false);
|
1100 |
setOpenLinks(false);
|
1114 |
}
|
1101 |
}
|
1115 |
|
1102 |
|
1116 |
PreviewTextEdit::~PreviewTextEdit()
|
1103 |
PreviewTextEdit::~PreviewTextEdit()
|
|
... |
|
... |
1122 |
{
|
1109 |
{
|
1123 |
LOGDEB1(("PreviewTextEdit::createPopupMenu()\n"));
|
1110 |
LOGDEB1(("PreviewTextEdit::createPopupMenu()\n"));
|
1124 |
QMenu *popup = new QMenu(this);
|
1111 |
QMenu *popup = new QMenu(this);
|
1125 |
switch (m_curdsp) {
|
1112 |
switch (m_curdsp) {
|
1126 |
case PTE_DSPTXT:
|
1113 |
case PTE_DSPTXT:
|
1127 |
popup->addAction(tr("Show fields"), this, SLOT(displayFields()));
|
1114 |
popup->addAction(tr("Show fields"), this, SLOT(displayFields()));
|
1128 |
if (!m_image.isNull())
|
1115 |
if (!m_image.isNull())
|
1129 |
popup->addAction(tr("Show image"), this, SLOT(displayImage()));
|
1116 |
popup->addAction(tr("Show image"), this, SLOT(displayImage()));
|
1130 |
break;
|
1117 |
break;
|
1131 |
case PTE_DSPFLDS:
|
1118 |
case PTE_DSPFLDS:
|
1132 |
popup->addAction(tr("Show main text"), this, SLOT(displayText()));
|
1119 |
popup->addAction(tr("Show main text"), this, SLOT(displayText()));
|
1133 |
if (!m_image.isNull())
|
1120 |
if (!m_image.isNull())
|
1134 |
popup->addAction(tr("Show image"), this, SLOT(displayImage()));
|
1121 |
popup->addAction(tr("Show image"), this, SLOT(displayImage()));
|
1135 |
break;
|
1122 |
break;
|
1136 |
case PTE_DSPIMG:
|
1123 |
case PTE_DSPIMG:
|
1137 |
default:
|
1124 |
default:
|
1138 |
popup->addAction(tr("Show fields"), this, SLOT(displayFields()));
|
1125 |
popup->addAction(tr("Show fields"), this, SLOT(displayFields()));
|
1139 |
popup->addAction(tr("Show main text"), this, SLOT(displayText()));
|
1126 |
popup->addAction(tr("Show main text"), this, SLOT(displayText()));
|
1140 |
break;
|
1127 |
break;
|
1141 |
}
|
1128 |
}
|
1142 |
popup->addAction(tr("Select All"), this, SLOT(selectAll()));
|
1129 |
popup->addAction(tr("Select All"), this, SLOT(selectAll()));
|
1143 |
popup->addAction(tr("Copy"), this, SLOT(copy()));
|
1130 |
popup->addAction(tr("Copy"), this, SLOT(copy()));
|
1144 |
popup->addAction(tr("Print"), this, SLOT(print()));
|
1131 |
popup->addAction(tr("Print"), this, SLOT(print()));
|
1145 |
if (prefs.previewPlainPre) {
|
1132 |
if (prefs.previewPlainPre) {
|
1146 |
popup->addAction(tr("Fold lines"), m_preview, SLOT(togglePlainPre()));
|
1133 |
popup->addAction(tr("Fold lines"), m_preview, SLOT(togglePlainPre()));
|
1147 |
} else {
|
1134 |
} else {
|
1148 |
popup->addAction(tr("Preserve indentation"),
|
1135 |
popup->addAction(tr("Preserve indentation"),
|
1149 |
m_preview, SLOT(togglePlainPre()));
|
1136 |
m_preview, SLOT(togglePlainPre()));
|
1150 |
}
|
1137 |
}
|
1151 |
// Need to check ipath until we fix the internfile bug that always
|
1138 |
// Need to check ipath until we fix the internfile bug that always
|
1152 |
// has it convert to html for top level docs
|
1139 |
// has it convert to html for top level docs
|
1153 |
if (!m_dbdoc.url.empty() && !m_dbdoc.ipath.empty())
|
1140 |
if (!m_dbdoc.url.empty() && !m_dbdoc.ipath.empty())
|
1154 |
popup->addAction(tr("Save document to file"),
|
1141 |
popup->addAction(tr("Save document to file"),
|
1155 |
m_preview, SLOT(emitSaveDocToFile()));
|
1142 |
m_preview, SLOT(emitSaveDocToFile()));
|
1156 |
popup->popup(mapToGlobal(pos));
|
1143 |
popup->popup(mapToGlobal(pos));
|
1157 |
}
|
1144 |
}
|
1158 |
|
1145 |
|
1159 |
// Display main text
|
1146 |
// Display main text
|
1160 |
void PreviewTextEdit::displayText()
|
1147 |
void PreviewTextEdit::displayText()
|
1161 |
{
|
1148 |
{
|
1162 |
LOGDEB1(("PreviewTextEdit::displayText()\n"));
|
1149 |
LOGDEB1(("PreviewTextEdit::displayText()\n"));
|
1163 |
if (m_format == Qt::PlainText)
|
1150 |
if (m_format == Qt::PlainText)
|
1164 |
setPlainText(m_richtxt);
|
1151 |
setPlainText(m_richtxt);
|
1165 |
else
|
1152 |
else
|
1166 |
setHtml(m_richtxt);
|
1153 |
setHtml(m_richtxt);
|
1167 |
m_curdsp = PTE_DSPTXT;
|
1154 |
m_curdsp = PTE_DSPTXT;
|
1168 |
}
|
1155 |
}
|
1169 |
|
1156 |
|
1170 |
// Display field values
|
1157 |
// Display field values
|
1171 |
void PreviewTextEdit::displayFields()
|
1158 |
void PreviewTextEdit::displayFields()
|
|
... |
|
... |
1173 |
LOGDEB1(("PreviewTextEdit::displayFields()\n"));
|
1160 |
LOGDEB1(("PreviewTextEdit::displayFields()\n"));
|
1174 |
|
1161 |
|
1175 |
QString txt = "<html><head></head><body>\n";
|
1162 |
QString txt = "<html><head></head><body>\n";
|
1176 |
txt += "<b>" + QString::fromLocal8Bit(m_url.c_str());
|
1163 |
txt += "<b>" + QString::fromLocal8Bit(m_url.c_str());
|
1177 |
if (!m_ipath.empty())
|
1164 |
if (!m_ipath.empty())
|
1178 |
txt += "|" + QString::fromUtf8(m_ipath.c_str());
|
1165 |
txt += "|" + QString::fromUtf8(m_ipath.c_str());
|
1179 |
txt += "</b><br><br>";
|
1166 |
txt += "</b><br><br>";
|
1180 |
txt += "<dl>\n";
|
1167 |
txt += "<dl>\n";
|
1181 |
for (map<string,string>::const_iterator it = m_fdoc.meta.begin();
|
1168 |
for (map<string,string>::const_iterator it = m_fdoc.meta.begin();
|
1182 |
it != m_fdoc.meta.end(); it++) {
|
1169 |
it != m_fdoc.meta.end(); it++) {
|
1183 |
if (!it->second.empty())
|
1170 |
if (!it->second.empty())
|
1184 |
txt += "<dt>" + QString::fromUtf8(it->first.c_str()) + "</dt> "
|
1171 |
txt += "<dt>" + QString::fromUtf8(it->first.c_str()) + "</dt> "
|
1185 |
+ "<dd>" + QString::fromUtf8(escapeHtml(it->second).c_str())
|
1172 |
+ "<dd>" + QString::fromUtf8(escapeHtml(it->second).c_str())
|
1186 |
+ "</dd>\n";
|
1173 |
+ "</dd>\n";
|
1187 |
}
|
1174 |
}
|
1188 |
txt += "</dl></body></html>";
|
1175 |
txt += "</dl></body></html>";
|
1189 |
setHtml(txt);
|
1176 |
setHtml(txt);
|
1190 |
m_curdsp = PTE_DSPFLDS;
|
1177 |
m_curdsp = PTE_DSPFLDS;
|
1191 |
}
|
1178 |
}
|
1192 |
|
1179 |
|
1193 |
void PreviewTextEdit::displayImage()
|
1180 |
void PreviewTextEdit::displayImage()
|
1194 |
{
|
1181 |
{
|
1195 |
LOGDEB1(("PreviewTextEdit::displayImage()\n"));
|
1182 |
LOGDEB1(("PreviewTextEdit::displayImage()\n"));
|
1196 |
if (m_image.isNull())
|
1183 |
if (m_image.isNull())
|
1197 |
displayText();
|
1184 |
displayText();
|
1198 |
|
1185 |
|
1199 |
setPlainText("");
|
1186 |
setPlainText("");
|
1200 |
if (m_image.width() > width() ||
|
1187 |
if (m_image.width() > width() ||
|
1201 |
m_image.height() > height()) {
|
1188 |
m_image.height() > height()) {
|
1202 |
m_image = m_image.scaled(width(), height(), Qt::KeepAspectRatio);
|
1189 |
m_image = m_image.scaled(width(), height(), Qt::KeepAspectRatio);
|
1203 |
}
|
1190 |
}
|
1204 |
document()->addResource(QTextDocument::ImageResource, QUrl("image"),
|
1191 |
document()->addResource(QTextDocument::ImageResource, QUrl("image"),
|
1205 |
m_image);
|
1192 |
m_image);
|
1206 |
QTextCursor cursor = textCursor();
|
1193 |
QTextCursor cursor = textCursor();
|
1207 |
cursor.insertImage("image");
|
1194 |
cursor.insertImage("image");
|
1208 |
m_curdsp = PTE_DSPIMG;
|
1195 |
m_curdsp = PTE_DSPIMG;
|
1209 |
}
|
1196 |
}
|
1210 |
|
1197 |
|
1211 |
void PreviewTextEdit::mouseDoubleClickEvent(QMouseEvent *event)
|
1198 |
void PreviewTextEdit::mouseDoubleClickEvent(QMouseEvent *event)
|
1212 |
{
|
1199 |
{
|
1213 |
LOGDEB2(("PreviewTextEdit::mouseDoubleClickEvent\n"));
|
1200 |
LOGDEB2(("PreviewTextEdit::mouseDoubleClickEvent\n"));
|
1214 |
QTextEdit::mouseDoubleClickEvent(event);
|
1201 |
QTextEdit::mouseDoubleClickEvent(event);
|
1215 |
if (textCursor().hasSelection() && m_preview)
|
1202 |
if (textCursor().hasSelection() && m_preview)
|
1216 |
m_preview->emitWordSelect(textCursor().selectedText());
|
1203 |
m_preview->emitWordSelect(textCursor().selectedText());
|
1217 |
}
|
1204 |
}
|
1218 |
|
1205 |
|
1219 |
void PreviewTextEdit::print()
|
1206 |
void PreviewTextEdit::print()
|
1220 |
{
|
1207 |
{
|
1221 |
LOGDEB(("PreviewTextEdit::print\n"));
|
1208 |
LOGDEB(("PreviewTextEdit::print\n"));
|
1222 |
if (!m_preview)
|
1209 |
if (!m_preview)
|
1223 |
return;
|
1210 |
return;
|
1224 |
|
1211 |
|
1225 |
#ifndef QT_NO_PRINTER
|
1212 |
#ifndef QT_NO_PRINTER
|
1226 |
QPrinter printer;
|
1213 |
QPrinter printer;
|
1227 |
QPrintDialog *dialog = new QPrintDialog(&printer, this);
|
1214 |
QPrintDialog *dialog = new QPrintDialog(&printer, this);
|
1228 |
dialog->setWindowTitle(tr("Print Current Preview"));
|
1215 |
dialog->setWindowTitle(tr("Print Current Preview"));
|
1229 |
if (dialog->exec() != QDialog::Accepted)
|
1216 |
if (dialog->exec() != QDialog::Accepted)
|