implement cancellation in preview loading
This commit is contained in:
parent
c8213f76d3
commit
3809fdc235
@ -1,5 +1,5 @@
|
|||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char rcsid[] = "@(#$Id: plaintorich.cpp,v 1.8 2006-01-23 13:32:05 dockes Exp $ (C) 2005 J.F.Dockes";
|
static char rcsid[] = "@(#$Id: plaintorich.cpp,v 1.9 2006-01-27 13:42:02 dockes Exp $ (C) 2005 J.F.Dockes";
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@ -22,9 +22,11 @@ static char rcsid[] = "@(#$Id: plaintorich.cpp,v 1.8 2006-01-23 13:32:05 dockes
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
#include <set>
|
||||||
#ifndef NO_NAMESPACES
|
#ifndef NO_NAMESPACES
|
||||||
using std::list;
|
using std::list;
|
||||||
using std::pair;
|
using std::pair;
|
||||||
|
using std::set;
|
||||||
#endif /* NO_NAMESPACES */
|
#endif /* NO_NAMESPACES */
|
||||||
|
|
||||||
#include "rcldb.h"
|
#include "rcldb.h"
|
||||||
@ -34,17 +36,24 @@ using std::pair;
|
|||||||
#include "utf8iter.h"
|
#include "utf8iter.h"
|
||||||
#include "transcode.h"
|
#include "transcode.h"
|
||||||
#include "smallut.h"
|
#include "smallut.h"
|
||||||
|
#include "plaintorich.h"
|
||||||
|
#include "cancelcheck.h"
|
||||||
|
|
||||||
// Text splitter callback used to take note of the position of query terms
|
// Text splitter callback used to take note of the position of query terms
|
||||||
// inside the result text. This is then used to post highlight tags.
|
// inside the result text. This is then used to post highlight tags.
|
||||||
class myTextSplitCB : public TextSplitCB {
|
class myTextSplitCB : public TextSplitCB {
|
||||||
public:
|
public:
|
||||||
const list<string> *terms; // in: query terms
|
set<string> terms; // in: user query terms
|
||||||
list<pair<int, int> > tboffs; // out: begin and end positions of
|
list<pair<int, int> > tboffs; // out: begin and end positions of
|
||||||
// query terms in text
|
// query terms in text
|
||||||
|
|
||||||
myTextSplitCB(const list<string>& terms)
|
myTextSplitCB(const list<string>& its) {
|
||||||
: terms(&terms) {
|
for (list<string>::const_iterator it = its.begin(); it != its.end();
|
||||||
|
it++) {
|
||||||
|
string s;
|
||||||
|
Rcl::dumb_string(*it, s);
|
||||||
|
terms.insert(s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback called by the text-to-words breaker for each word
|
// Callback called by the text-to-words breaker for each word
|
||||||
@ -53,14 +62,9 @@ class myTextSplitCB : public TextSplitCB {
|
|||||||
Rcl::dumb_string(term, dumb);
|
Rcl::dumb_string(term, dumb);
|
||||||
//LOGDEB(("Input dumbbed term: '%s' %d %d %d\n", dumb.c_str(),
|
//LOGDEB(("Input dumbbed term: '%s' %d %d %d\n", dumb.c_str(),
|
||||||
// pos, bts, bte));
|
// pos, bts, bte));
|
||||||
for (list<string>::const_iterator it = terms->begin();
|
if (terms.find(dumb) != terms.end())
|
||||||
it != terms->end(); it++) {
|
tboffs.push_back(pair<int, int>(bts, bte));
|
||||||
if (!stringlowercmp(*it, dumb)) {
|
CancelCheck::instance().checkCancel();
|
||||||
tboffs.push_back(pair<int, int>(bts, bte));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -72,12 +76,13 @@ class myTextSplitCB : public TextSplitCB {
|
|||||||
// duplicate whitespace etc...). This is tricky business and it might
|
// duplicate whitespace etc...). This is tricky business and it might
|
||||||
// be better to insert the text char by char, taking note of where qt
|
// be better to insert the text char by char, taking note of where qt
|
||||||
// thinks it is at each term.
|
// thinks it is at each term.
|
||||||
string plaintorich(const string &in, const list<string>& terms,
|
bool plaintorich(const string& in, string& out, const list<string>& terms,
|
||||||
list<pair<int, int> >&termoffsets)
|
list<pair<int, int> >&termoffsets)
|
||||||
{
|
{
|
||||||
|
Chrono chron;
|
||||||
LOGDEB(("plaintorich: terms: %s\n",
|
LOGDEB(("plaintorich: terms: %s\n",
|
||||||
stringlistdisp(terms).c_str()));
|
stringlistdisp(terms).c_str()));
|
||||||
|
out.erase();
|
||||||
termoffsets.erase(termoffsets.begin(), termoffsets.end());
|
termoffsets.erase(termoffsets.begin(), termoffsets.end());
|
||||||
|
|
||||||
// We first use the text splitter to break the text into words,
|
// We first use the text splitter to break the text into words,
|
||||||
@ -89,11 +94,10 @@ string plaintorich(const string &in, const list<string>& terms,
|
|||||||
// character offset
|
// character offset
|
||||||
splitter.text_to_words(in);
|
splitter.text_to_words(in);
|
||||||
|
|
||||||
LOGDEB(("Split done\n"));
|
LOGDEB(("plaintorich: split done %d mS\n", chron.millis()));
|
||||||
|
|
||||||
|
|
||||||
// Rich text output
|
// Rich text output
|
||||||
string out = "<qt><head><title></title></head><body><p>";
|
out = "<qt><head><title></title></head><body><p>";
|
||||||
|
|
||||||
// Iterator for the list of input term positions. We use it to
|
// Iterator for the list of input term positions. We use it to
|
||||||
// output highlight tags and to compute term positions in the
|
// output highlight tags and to compute term positions in the
|
||||||
@ -112,7 +116,10 @@ string plaintorich(const string &in, const list<string>& terms,
|
|||||||
// consecutive blank chars
|
// consecutive blank chars
|
||||||
int atblank = 0;
|
int atblank = 0;
|
||||||
for (string::size_type pos = 0; pos != string::npos; pos = chariter++) {
|
for (string::size_type pos = 0; pos != string::npos; pos = chariter++) {
|
||||||
// If we still have terms, check (byte) position
|
if (pos && (pos % 1000) == 0) {
|
||||||
|
CancelCheck::instance().checkCancel();
|
||||||
|
}
|
||||||
|
// If we still have terms positions, check (byte) position
|
||||||
if (it != cb.tboffs.end()) {
|
if (it != cb.tboffs.end()) {
|
||||||
int ibyteidx = chariter.getBpos();
|
int ibyteidx = chariter.getBpos();
|
||||||
if (ibyteidx == it->first) {
|
if (ibyteidx == it->first) {
|
||||||
@ -148,7 +155,7 @@ string plaintorich(const string &in, const list<string>& terms,
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// We don't change the eol status for whitespace, want a real line
|
// We don't change the eol status for whitespace, want a real line
|
||||||
if (*chariter == ' ' || *chariter == ' ') {
|
if (*chariter == ' ' || *chariter == '\t') {
|
||||||
if (!atblank)
|
if (!atblank)
|
||||||
outcpos++;
|
outcpos++;
|
||||||
atblank = 1;
|
atblank = 1;
|
||||||
@ -167,5 +174,6 @@ string plaintorich(const string &in, const list<string>& terms,
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return out;
|
LOGDEB(("plaintorich: done %d mS\n", chron.millis()));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
#ifndef _PLAINTORICH_H_INCLUDED_
|
#ifndef _PLAINTORICH_H_INCLUDED_
|
||||||
#define _PLAINTORICH_H_INCLUDED_
|
#define _PLAINTORICH_H_INCLUDED_
|
||||||
/* @(#$Id: plaintorich.h,v 1.3 2006-01-19 12:01:43 dockes Exp $ (C) 2004 J.F.Dockes */
|
/* @(#$Id: plaintorich.h,v 1.4 2006-01-27 13:42:02 dockes Exp $ (C) 2004 J.F.Dockes */
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -14,8 +14,8 @@
|
|||||||
* @param terms list of query terms
|
* @param terms list of query terms
|
||||||
* @param termoffsets output: character offsets where we find terms.
|
* @param termoffsets output: character offsets where we find terms.
|
||||||
*/
|
*/
|
||||||
extern string plaintorich(const string &in,
|
extern bool plaintorich(const string &in, string &out,
|
||||||
const list<string>& terms,
|
const list<string>& terms,
|
||||||
list<pair<int, int> >&termoffsets);
|
list<pair<int, int> >& termoffsets);
|
||||||
|
|
||||||
#endif /* _PLAINTORICH_H_INCLUDED_ */
|
#endif /* _PLAINTORICH_H_INCLUDED_ */
|
||||||
|
|||||||
@ -198,7 +198,7 @@
|
|||||||
<variable>void *tabData;</variable>
|
<variable>void *tabData;</variable>
|
||||||
</variables>
|
</variables>
|
||||||
<signals>
|
<signals>
|
||||||
<signal>previewClosed(Preview *)</signal>
|
<signal>previewClosed(QWidget *)</signal>
|
||||||
</signals>
|
</signals>
|
||||||
<slots>
|
<slots>
|
||||||
<slot>searchTextLine_textChanged( const QString & text )</slot>
|
<slot>searchTextLine_textChanged( const QString & text )</slot>
|
||||||
@ -208,7 +208,6 @@
|
|||||||
<slot>currentChanged( QWidget * tw )</slot>
|
<slot>currentChanged( QWidget * tw )</slot>
|
||||||
<slot>closeCurrentTab()</slot>
|
<slot>closeCurrentTab()</slot>
|
||||||
<slot>setCurTabProps( const string & fn, const Rcl::Doc & doc )</slot>
|
<slot>setCurTabProps( const string & fn, const Rcl::Doc & doc )</slot>
|
||||||
<slot>loadFileInCurrentTab( string fn, size_t sz, const Rcl::Doc & idoc )</slot>
|
|
||||||
</slots>
|
</slots>
|
||||||
<functions>
|
<functions>
|
||||||
<function access="private" specifier="non virtual">init()</function>
|
<function access="private" specifier="non virtual">init()</function>
|
||||||
@ -218,6 +217,7 @@
|
|||||||
<function returnType="QTextEdit *">getCurrentEditor()</function>
|
<function returnType="QTextEdit *">getCurrentEditor()</function>
|
||||||
<function returnType="QTextEdit *">addEditorTab()</function>
|
<function returnType="QTextEdit *">addEditorTab()</function>
|
||||||
<function access="private">destroy()</function>
|
<function access="private">destroy()</function>
|
||||||
|
<function access="public" returnType="bool">loadFileInCurrentTab( string fn, size_t sz, const Rcl::Doc & idoc )</function>
|
||||||
</functions>
|
</functions>
|
||||||
<layoutdefaults spacing="6" margin="11"/>
|
<layoutdefaults spacing="6" margin="11"/>
|
||||||
</UI>
|
</UI>
|
||||||
|
|||||||
@ -29,6 +29,7 @@ using std::pair;
|
|||||||
#include "plaintorich.h"
|
#include "plaintorich.h"
|
||||||
#include "smallut.h"
|
#include "smallut.h"
|
||||||
#include "wipedir.h"
|
#include "wipedir.h"
|
||||||
|
#include "cancelcheck.h"
|
||||||
|
|
||||||
// We keep a list of data associated to each tab
|
// We keep a list of data associated to each tab
|
||||||
class TabData {
|
class TabData {
|
||||||
@ -59,7 +60,7 @@ void Preview::destroy()
|
|||||||
|
|
||||||
void Preview::closeEvent(QCloseEvent *e)
|
void Preview::closeEvent(QCloseEvent *e)
|
||||||
{
|
{
|
||||||
emit previewClosed(this);
|
emit previewClosed((QWidget *)this);
|
||||||
QWidget::closeEvent(e);
|
QWidget::closeEvent(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,15 +202,15 @@ void Preview::prevPressed()
|
|||||||
|
|
||||||
void Preview::currentChanged(QWidget * tw)
|
void Preview::currentChanged(QWidget * tw)
|
||||||
{
|
{
|
||||||
QObject *o = tw->child("pvEdit");
|
QWidget *edit = (QWidget *)tw->child("pvEdit");
|
||||||
LOGDEB1(("Preview::currentChanged(). Edit %p\n", o));
|
LOGDEB1(("Preview::currentChanged(). Editor: %p\n", edit));
|
||||||
|
|
||||||
if (o == 0) {
|
if (edit == 0) {
|
||||||
LOGERR(("Editor child not found\n"));
|
LOGERR(("Editor child not found\n"));
|
||||||
} else {
|
} else {
|
||||||
tw->installEventFilter(this);
|
tw->installEventFilter(this);
|
||||||
o->installEventFilter(this);
|
edit->installEventFilter(this);
|
||||||
((QWidget*)o)->setFocus();
|
edit->setFocus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,7 +318,9 @@ bool Preview::makeDocCurrent(const string &fn, const Rcl::Doc &doc)
|
|||||||
be even more complicated, and we probably don't want the user to click on
|
be even more complicated, and we probably don't want the user to click on
|
||||||
things during this time anyway.
|
things during this time anyway.
|
||||||
|
|
||||||
No cancel button is implemented, but this could conceivably be done
|
It might be possible, but complicated (need modifications in
|
||||||
|
handler) to implement a kind of bucket brigade, to have the
|
||||||
|
beginning of the text displayed faster
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* A thread to to the file reading / format conversion */
|
/* A thread to to the file reading / format conversion */
|
||||||
@ -348,10 +351,14 @@ class LoadThread : public QThread {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
FileInterner interner(filename, rclconfig, tmpdir, mtype);
|
FileInterner interner(filename, rclconfig, tmpdir, mtype);
|
||||||
if (interner.internfile(*out, ipath) != FileInterner::FIDone) {
|
try {
|
||||||
|
if (interner.internfile(*out, ipath) != FileInterner::FIDone) {
|
||||||
|
*statusp = -1;
|
||||||
|
} else {
|
||||||
|
*statusp = 0;
|
||||||
|
}
|
||||||
|
} catch (CancelExcept) {
|
||||||
*statusp = -1;
|
*statusp = -1;
|
||||||
} else {
|
|
||||||
*statusp = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -370,7 +377,11 @@ class ToRichThread : public QThread {
|
|||||||
virtual void run()
|
virtual void run()
|
||||||
{
|
{
|
||||||
DebugLog::getdbl()->setloglevel(DEBDEB1);
|
DebugLog::getdbl()->setloglevel(DEBDEB1);
|
||||||
string rich = plaintorich(in, terms, termoffsets);
|
string rich;
|
||||||
|
try {
|
||||||
|
plaintorich(in, rich, terms, termoffsets);
|
||||||
|
} catch (CancelExcept) {
|
||||||
|
}
|
||||||
out = QString::fromUtf8(rich.c_str(), rich.length());
|
out = QString::fromUtf8(rich.c_str(), rich.length());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -385,9 +396,15 @@ class WaiterThread : public QThread {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc)
|
#define CHUNKL 50*1000
|
||||||
|
#ifndef MIN
|
||||||
|
#define MIN(A,B) ((A)<(B)?(A):(B))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc)
|
||||||
{
|
{
|
||||||
Rcl::Doc doc = idoc;
|
Rcl::Doc doc = idoc;
|
||||||
|
bool cancel = false;
|
||||||
|
|
||||||
if (doc.title.empty())
|
if (doc.title.empty())
|
||||||
doc.title = path_getsimple(doc.url);
|
doc.title = path_getsimple(doc.url);
|
||||||
@ -401,11 +418,8 @@ void Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc)
|
|||||||
.arg(csz);
|
.arg(csz);
|
||||||
|
|
||||||
// Create progress dialog and aux objects
|
// Create progress dialog and aux objects
|
||||||
const int nsteps = 10;
|
const int nsteps = 20;
|
||||||
QProgressDialog progress( msg, "", nsteps, this, "Loading", TRUE );
|
QProgressDialog progress(msg, tr("Cancel"), nsteps, this, "Loading", FALSE);
|
||||||
QPushButton *pb = new QPushButton("", this);
|
|
||||||
pb->setEnabled(false);
|
|
||||||
progress.setCancelButton(pb);
|
|
||||||
progress.setMinimumDuration(1000);
|
progress.setMinimumDuration(1000);
|
||||||
WaiterThread waiter(100);
|
WaiterThread waiter(100);
|
||||||
|
|
||||||
@ -416,46 +430,64 @@ void Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc)
|
|||||||
int status = 1;
|
int status = 1;
|
||||||
LoadThread lthr(&status, &fdoc, fn, doc.ipath, &doc.mimetype);
|
LoadThread lthr(&status, &fdoc, fn, doc.ipath, &doc.mimetype);
|
||||||
lthr.start();
|
lthr.start();
|
||||||
int i;
|
int prog;
|
||||||
for (i = 1;;i++) {
|
for (prog = 1;;prog++) {
|
||||||
waiter.start();
|
waiter.start();
|
||||||
waiter.wait();
|
waiter.wait();
|
||||||
if (lthr.finished())
|
if (lthr.finished())
|
||||||
break;
|
break;
|
||||||
progress.setProgress(i , i <= nsteps-1 ? nsteps : i+1);
|
progress.setProgress(prog , prog <= nsteps-1 ? nsteps : prog+1);
|
||||||
qApp->processEvents();
|
qApp->processEvents();
|
||||||
if (i >= 5)
|
if (progress.wasCanceled()) {
|
||||||
|
CancelCheck::instance().setCancel();
|
||||||
|
cancel = true;
|
||||||
|
}
|
||||||
|
if (prog >= 5)
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
|
if (cancel)
|
||||||
|
return false;
|
||||||
if (status != 0) {
|
if (status != 0) {
|
||||||
QMessageBox::warning(0, "Recoll",
|
QMessageBox::warning(0, "Recoll",
|
||||||
tr("Can't turn doc into internal rep for ") +
|
tr("Can't turn doc into internal rep for ") +
|
||||||
doc.mimetype.c_str());
|
doc.mimetype.c_str());
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
// Reset config just in case.
|
// Reset config just in case.
|
||||||
rclconfig->setKeyDir("");
|
rclconfig->setKeyDir("");
|
||||||
|
|
||||||
// Highlight search terms:
|
// Create preview text: highlight search terms:
|
||||||
progress.setLabelText(tr("Creating preview text"));
|
progress.setLabelText(tr("Creating preview text"));
|
||||||
list<string> terms;
|
list<string> terms;
|
||||||
rcldb->getQueryTerms(terms);
|
rcldb->getQueryTerms(terms);
|
||||||
list<pair<int, int> > termoffsets;
|
list<pair<int, int> > termoffsets;
|
||||||
QString str;
|
QString richTxt;
|
||||||
ToRichThread rthr(fdoc.text, terms, termoffsets, str);
|
ToRichThread rthr(fdoc.text, terms, termoffsets, richTxt);
|
||||||
rthr.start();
|
rthr.start();
|
||||||
|
|
||||||
for (;;i++) {
|
for (;;prog++) {
|
||||||
waiter.start();
|
waiter.start(); waiter.wait();
|
||||||
waiter.wait();
|
|
||||||
if (rthr.finished())
|
if (rthr.finished())
|
||||||
break;
|
break;
|
||||||
progress.setProgress(i , i <= nsteps-1 ? nsteps : i+1);
|
progress.setProgress(prog , prog <= nsteps-1 ? nsteps : prog+1);
|
||||||
qApp->processEvents();
|
qApp->processEvents();
|
||||||
if (i >= 5)
|
if (progress.wasCanceled()) {
|
||||||
|
CancelCheck::instance().setCancel();
|
||||||
|
cancel = true;
|
||||||
|
}
|
||||||
|
if (prog >= 5)
|
||||||
sleep(1);
|
sleep(1);
|
||||||
}
|
}
|
||||||
LOGDEB(("Plaintorich done\n"));
|
if (cancel) {
|
||||||
|
if (richTxt.length() == 0) {
|
||||||
|
// We cant call closeCurrentTab here as it might delete
|
||||||
|
// the object which would be a nasty surprise to our
|
||||||
|
// caller.
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
richTxt += "<b>Cancelled !</b>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Load into editor
|
// Load into editor
|
||||||
QTextEdit *editor = getCurrentEditor();
|
QTextEdit *editor = getCurrentEditor();
|
||||||
@ -464,9 +496,37 @@ void Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc)
|
|||||||
item->setColor("blue");
|
item->setColor("blue");
|
||||||
item->setFontWeight(QFont::Bold);
|
item->setFontWeight(QFont::Bold);
|
||||||
|
|
||||||
|
prog = 2 * nsteps / 3;
|
||||||
progress.setLabelText(tr("Loading preview text into editor"));
|
progress.setLabelText(tr("Loading preview text into editor"));
|
||||||
qApp->processEvents();
|
qApp->processEvents();
|
||||||
editor->setText(str);
|
// Do it in several chunks
|
||||||
|
int l = 0;
|
||||||
|
for (unsigned int pos = 0; pos < richTxt.length(); pos += l, prog++) {
|
||||||
|
progress.setProgress(prog , prog <= nsteps-1 ? nsteps : prog+1);
|
||||||
|
qApp->processEvents();
|
||||||
|
|
||||||
|
l = MIN(CHUNKL, richTxt.length() - pos);
|
||||||
|
// Avoid breaking inside a tag. Our tags are short (ie: <br>)
|
||||||
|
for (int i = -4; i < 0; i++) {
|
||||||
|
if (richTxt[pos+l+i] == '<') {
|
||||||
|
l = l+i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
editor->append(richTxt.mid(pos, l));
|
||||||
|
// Stay at top
|
||||||
|
if (pos < 5) {
|
||||||
|
editor->setCursorPosition(0,0);
|
||||||
|
editor->ensureCursorVisible();
|
||||||
|
}
|
||||||
|
if (progress.wasCanceled()) {
|
||||||
|
cancel = true;
|
||||||
|
editor->append("<b>Cancelled !</b>");
|
||||||
|
LOGDEB(("Cancelled\n"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
int para = 0, index = 1;
|
int para = 0, index = 1;
|
||||||
if (!termoffsets.empty()) {
|
if (!termoffsets.empty()) {
|
||||||
index = (termoffsets.begin())->first;
|
index = (termoffsets.begin())->first;
|
||||||
@ -479,6 +539,5 @@ void Preview::loadFileInCurrentTab(string fn, size_t sz, const Rcl::Doc &idoc)
|
|||||||
|
|
||||||
LOGDEB(("PREVIEW len %d paragraphs: %d. Cpos: %d %d\n",
|
LOGDEB(("PREVIEW len %d paragraphs: %d. Cpos: %d %d\n",
|
||||||
editor->length(), editor->paragraphs(), para, index));
|
editor->length(), editor->paragraphs(), para, index));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char rcsid[] = "@(#$Id: rclmain.cpp,v 1.9 2006-01-26 14:02:01 dockes Exp $ (C) 2005 J.F.Dockes";
|
static char rcsid[] = "@(#$Id: rclmain.cpp,v 1.10 2006-01-27 13:42:02 dockes Exp $ (C) 2005 J.F.Dockes";
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
@ -53,7 +53,6 @@ using std::pair;
|
|||||||
#include "mimehandler.h"
|
#include "mimehandler.h"
|
||||||
#include "pathut.h"
|
#include "pathut.h"
|
||||||
#include "smallut.h"
|
#include "smallut.h"
|
||||||
#include "plaintorich.h"
|
|
||||||
#include "advsearch.h"
|
#include "advsearch.h"
|
||||||
#include "rclversion.h"
|
#include "rclversion.h"
|
||||||
#include "sortseq.h"
|
#include "sortseq.h"
|
||||||
@ -435,7 +434,8 @@ void RclMain::startPreview(int docnum)
|
|||||||
(void)curPreview->addEditorTab();
|
(void)curPreview->addEditorTab();
|
||||||
}
|
}
|
||||||
m_history->enterDocument(fn, doc.ipath);
|
m_history->enterDocument(fn, doc.ipath);
|
||||||
curPreview->loadFileInCurrentTab(fn, st.st_size, doc);
|
if (!curPreview->loadFileInCurrentTab(fn, st.st_size, doc))
|
||||||
|
curPreview->closeCurrentTab();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RclMain::startNativeViewer(int docnum)
|
void RclMain::startNativeViewer(int docnum)
|
||||||
@ -556,10 +556,40 @@ void RclMain::enablePrevPage(bool yesno)
|
|||||||
prevPageAction->setEnabled(yesno);
|
prevPageAction->setEnabled(yesno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Show detailed expansion of a query */
|
||||||
void RclMain::showQueryDetails()
|
void RclMain::showQueryDetails()
|
||||||
{
|
{
|
||||||
// Bad number: must have clicked on header. Show details of query
|
// Break query into lines of reasonable length, avoid cutting words!
|
||||||
|
const int ll = 80;
|
||||||
|
string query = currentQueryData.description;
|
||||||
|
string oq;
|
||||||
|
while (query.length() > 0) {
|
||||||
|
string ss = query.substr(0, ll);
|
||||||
|
if (ss.length() == ll) {
|
||||||
|
string::size_type pos = ss.find_last_of(" ");
|
||||||
|
if (pos == string::npos) {
|
||||||
|
pos = query.find_first_of(" ");
|
||||||
|
if (pos != string::npos)
|
||||||
|
ss = query.substr(0, pos+1);
|
||||||
|
else
|
||||||
|
ss = query;
|
||||||
|
} else {
|
||||||
|
ss = ss.substr(0, pos+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// This cant happen, but anyway. Be very sure to avoid an infinite loop
|
||||||
|
if (ss.length() == 0) {
|
||||||
|
LOGDEB(("showQueryDetails: Internal error!\n"));
|
||||||
|
oq = query;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
oq += ss + "\n";
|
||||||
|
query= query.substr(ss.length());
|
||||||
|
LOGDEB1(("oq [%s]\n, query [%s]\n, ss [%s]\n",
|
||||||
|
oq.c_str(), query.c_str(), ss.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
QString desc = tr("Query details") + ": " +
|
QString desc = tr("Query details") + ": " +
|
||||||
QString::fromUtf8(currentQueryData.description.c_str());
|
QString::fromUtf8(oq.c_str());
|
||||||
QMessageBox::information(this, tr("Query details"), desc);
|
QMessageBox::information(this, tr("Query details"), desc);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user