|
a/src/qtgui/ssearch_w.cpp |
|
b/src/qtgui/ssearch_w.cpp |
|
... |
|
... |
61 |
queryText->installEventFilter(this);
|
61 |
queryText->installEventFilter(this);
|
62 |
queryText->view()->installEventFilter(this);
|
62 |
queryText->view()->installEventFilter(this);
|
63 |
m_displayingCompletions = false;
|
63 |
m_displayingCompletions = false;
|
64 |
m_escape = false;
|
64 |
m_escape = false;
|
65 |
m_disableAutosearch = true;
|
65 |
m_disableAutosearch = true;
|
|
|
66 |
m_stroketimeout = new QTimer(this);
|
|
|
67 |
m_stroketimeout->setSingleShot(true);
|
|
|
68 |
connect(m_stroketimeout, SIGNAL(timeout()), this, SLOT(timerDone()));
|
|
|
69 |
m_keystroke = false;
|
|
|
70 |
}
|
|
|
71 |
|
|
|
72 |
void SSearch::timerDone()
|
|
|
73 |
{
|
|
|
74 |
QString qs = queryText->currentText();
|
|
|
75 |
LOGINFO(("TIMER DONE. qstring [%s]\n", qs2utf8s(qs).c_str()));
|
|
|
76 |
searchTextChanged(qs);
|
66 |
}
|
77 |
}
|
67 |
|
78 |
|
68 |
void SSearch::searchTextChanged(const QString& text)
|
79 |
void SSearch::searchTextChanged(const QString& text)
|
69 |
{
|
80 |
{
|
|
|
81 |
QString qs = queryText->currentText();
|
|
|
82 |
LOGINFO(("SEARCHTEXTCHANGED. ks %d text [%s]\n",
|
|
|
83 |
m_keystroke, qs2utf8s(text).c_str()));
|
70 |
if (text.isEmpty()) {
|
84 |
if (text.isEmpty()) {
|
71 |
searchPB->setEnabled(false);
|
85 |
searchPB->setEnabled(false);
|
72 |
clearqPB->setEnabled(false);
|
86 |
clearqPB->setEnabled(false);
|
73 |
queryText->setFocus();
|
87 |
queryText->setFocus();
|
74 |
emit clearSearch();
|
88 |
emit clearSearch();
|
75 |
} else {
|
89 |
} else {
|
76 |
searchPB->setEnabled(true);
|
90 |
searchPB->setEnabled(true);
|
77 |
clearqPB->setEnabled(true);
|
91 |
clearqPB->setEnabled(true);
|
|
|
92 |
if (m_keystroke) {
|
|
|
93 |
m_tstartqs = qs;
|
|
|
94 |
}
|
78 |
if (prefs.autoSearchOnWS && !m_disableAutosearch) {
|
95 |
if (prefs.autoSearchOnWS && !m_disableAutosearch &&
|
|
|
96 |
!m_keystroke && m_tstartqs == qs) {
|
79 |
m_disableAutosearch = true;
|
97 |
m_disableAutosearch = true;
|
80 |
LOGDEB(("Autosearch: current: [%s]\n",
|
98 |
LOGINFO(("Autosearch: current: [%s]\n", qs2utf8s(qs).c_str()));
|
81 |
qs2utf8s(queryText->currentText()).c_str()));
|
|
|
82 |
#if 1
|
|
|
83 |
string s;
|
99 |
string s;
|
84 |
int cs = partialWord(s);
|
100 |
int cs = partialWord(s);
|
85 |
if (cs < 0) {
|
101 |
if (cs < 0) {
|
86 |
startSimpleSearch();
|
102 |
startSimpleSearch();
|
87 |
return;
|
103 |
} else if (!m_stroketimeout->isActive()) {
|
|
|
104 |
s = qs2utf8s(queryText->currentText());
|
|
|
105 |
s += "*";
|
|
|
106 |
startSimpleSearch(s, 20);
|
88 |
}
|
107 |
}
|
89 |
|
108 |
}
|
90 |
// Query database for completions
|
|
|
91 |
QStringList lst;
|
|
|
92 |
const int maxcompsize = 40;
|
|
|
93 |
completionList(s, lst, maxcompsize);
|
|
|
94 |
if (lst.size() >= maxcompsize) {
|
|
|
95 |
LOGDEB(("Autosearch: completion list too big: %d\n",
|
|
|
96 |
lst.size()));
|
|
|
97 |
return;
|
|
|
98 |
}
|
109 |
}
|
99 |
s = qs2utf8s(queryText->currentText());
|
110 |
m_keystroke = false;
|
100 |
s += "*";
|
|
|
101 |
startSimpleSearch(s);
|
|
|
102 |
#else
|
|
|
103 |
startSimpleSearch();
|
|
|
104 |
#endif
|
|
|
105 |
}
|
|
|
106 |
}
|
|
|
107 |
}
|
111 |
}
|
108 |
|
112 |
|
109 |
void SSearch::searchTypeChanged(int typ)
|
113 |
void SSearch::searchTypeChanged(int typ)
|
110 |
{
|
114 |
{
|
111 |
LOGDEB(("Search type now %d\n", typ));
|
115 |
LOGDEB(("Search type now %d\n", typ));
|
|
... |
|
... |
147 |
}
|
151 |
}
|
148 |
}
|
152 |
}
|
149 |
|
153 |
|
150 |
void SSearch::startSimpleSearch()
|
154 |
void SSearch::startSimpleSearch()
|
151 |
{
|
155 |
{
|
152 |
if (queryText->currentText().length() == 0)
|
156 |
QString qs = queryText->currentText();
|
|
|
157 |
LOGINFO(("startSimpleSearch qs [%s]\n", qs2utf8s(qs).c_str()));
|
|
|
158 |
if (qs.length() == 0)
|
153 |
return;
|
159 |
return;
|
154 |
|
160 |
|
155 |
string u8 = (const char *)queryText->currentText().toUtf8();
|
161 |
string u8 = (const char *)queryText->currentText().toUtf8();
|
156 |
|
162 |
|
157 |
trimstring(u8);
|
163 |
trimstring(u8);
|
|
... |
|
... |
166 |
// We want to have the new text at the top and any older identical
|
172 |
// We want to have the new text at the top and any older identical
|
167 |
// entry to be erased. There is no standard qt policy to do this ?
|
173 |
// entry to be erased. There is no standard qt policy to do this ?
|
168 |
// So do it by hand.
|
174 |
// So do it by hand.
|
169 |
QString txt = queryText->currentText();
|
175 |
QString txt = queryText->currentText();
|
170 |
int index = queryText->findText(txt);
|
176 |
int index = queryText->findText(txt);
|
171 |
if (index >= 0)
|
177 |
if (index > 0) {
|
172 |
queryText->removeItem(index);
|
178 |
queryText->removeItem(index);
|
|
|
179 |
}
|
173 |
queryText->insertItem(0, txt);
|
180 |
queryText->insertItem(0, txt);
|
174 |
queryText->setCurrentIndex(0);
|
181 |
queryText->setCurrentIndex(0);
|
175 |
m_disableAutosearch = true;
|
182 |
m_disableAutosearch = true;
|
|
|
183 |
m_stroketimeout->stop();
|
176 |
|
184 |
|
177 |
// Save the current state of the listbox list to the prefs (will
|
185 |
// Save the current state of the listbox list to the prefs (will
|
178 |
// go to disk)
|
186 |
// go to disk)
|
179 |
prefs.ssearchHistory.clear();
|
187 |
prefs.ssearchHistory.clear();
|
180 |
for (int index = 0; index < queryText->count(); index++) {
|
188 |
for (int index = 0; index < queryText->count(); index++) {
|
181 |
prefs.ssearchHistory.push_back(queryText->itemText(index));
|
189 |
prefs.ssearchHistory.push_back(queryText->itemText(index));
|
182 |
}
|
190 |
}
|
183 |
}
|
191 |
}
|
184 |
|
192 |
|
185 |
bool SSearch::startSimpleSearch(const string& u8)
|
193 |
bool SSearch::startSimpleSearch(const string& u8, int maxexp)
|
186 |
{
|
194 |
{
|
187 |
LOGDEB(("SSearch::startSimpleSearch(%s)\n", u8.c_str()));
|
195 |
LOGINFO(("SSearch::startSimpleSearch(%s)\n", u8.c_str()));
|
188 |
string stemlang = prefs.stemlang();
|
196 |
string stemlang = prefs.stemlang();
|
189 |
|
197 |
|
190 |
SSearchType tp = (SSearchType)searchTypCMB->currentIndex();
|
198 |
SSearchType tp = (SSearchType)searchTypCMB->currentIndex();
|
191 |
Rcl::SearchData *sdata = 0;
|
199 |
Rcl::SearchData *sdata = 0;
|
192 |
|
200 |
|
|
... |
|
... |
228 |
|
236 |
|
229 |
if (prefs.ssearchAutoPhrase && rcldb) {
|
237 |
if (prefs.ssearchAutoPhrase && rcldb) {
|
230 |
sdata->maybeAddAutoPhrase(*rcldb,
|
238 |
sdata->maybeAddAutoPhrase(*rcldb,
|
231 |
prefs.ssearchAutoPhraseThreshPC / 100.0);
|
239 |
prefs.ssearchAutoPhraseThreshPC / 100.0);
|
232 |
}
|
240 |
}
|
233 |
|
241 |
if (maxexp != -1) {
|
|
|
242 |
sdata->setMaxExpand(maxexp);
|
|
|
243 |
}
|
234 |
RefCntr<Rcl::SearchData> rsdata(sdata);
|
244 |
RefCntr<Rcl::SearchData> rsdata(sdata);
|
235 |
emit startSearch(rsdata);
|
245 |
emit startSearch(rsdata);
|
236 |
return true;
|
246 |
return true;
|
237 |
}
|
247 |
}
|
238 |
|
248 |
|
239 |
void SSearch::setSearchString(const QString& txt)
|
249 |
void SSearch::setSearchString(const QString& txt)
|
240 |
{
|
250 |
{
|
241 |
m_disableAutosearch = true;
|
251 |
m_disableAutosearch = true;
|
|
|
252 |
m_stroketimeout->stop();
|
242 |
queryText->setEditText(txt);
|
253 |
queryText->setEditText(txt);
|
243 |
}
|
254 |
}
|
244 |
|
255 |
|
245 |
bool SSearch::hasSearchString()
|
256 |
bool SSearch::hasSearchString()
|
246 |
{
|
257 |
{
|
|
... |
|
... |
272 |
|
283 |
|
273 |
QString text = queryText->currentText();
|
284 |
QString text = queryText->currentText();
|
274 |
text += QString::fromLatin1(" ") + term;
|
285 |
text += QString::fromLatin1(" ") + term;
|
275 |
queryText->setEditText(text);
|
286 |
queryText->setEditText(text);
|
276 |
m_disableAutosearch = true;
|
287 |
m_disableAutosearch = true;
|
|
|
288 |
m_stroketimeout->stop();
|
277 |
}
|
289 |
}
|
278 |
|
290 |
|
279 |
void SSearch::onWordReplace(const QString& o, const QString& n)
|
291 |
void SSearch::onWordReplace(const QString& o, const QString& n)
|
280 |
{
|
292 |
{
|
281 |
LOGDEB(("SSearch::onWordReplace: o [%s] n [%s]\n",
|
293 |
LOGDEB(("SSearch::onWordReplace: o [%s] n [%s]\n",
|
|
... |
|
... |
284 |
QRegExp exp = QRegExp(QString("\\b") + o + QString("\\b"));
|
296 |
QRegExp exp = QRegExp(QString("\\b") + o + QString("\\b"));
|
285 |
exp.setCaseSensitivity(Qt::CaseInsensitive);
|
297 |
exp.setCaseSensitivity(Qt::CaseInsensitive);
|
286 |
txt.replace(exp, n);
|
298 |
txt.replace(exp, n);
|
287 |
queryText->setEditText(txt);
|
299 |
queryText->setEditText(txt);
|
288 |
m_disableAutosearch = true;
|
300 |
m_disableAutosearch = true;
|
|
|
301 |
m_stroketimeout->stop();
|
289 |
Qt::KeyboardModifiers mods = QApplication::keyboardModifiers ();
|
302 |
Qt::KeyboardModifiers mods = QApplication::keyboardModifiers ();
|
290 |
if (mods == Qt::NoModifier)
|
303 |
if (mods == Qt::NoModifier)
|
291 |
startSimpleSearch();
|
304 |
startSimpleSearch();
|
292 |
}
|
305 |
}
|
293 |
|
306 |
|
|
... |
|
... |
332 |
|
345 |
|
333 |
// Complete last word in input by querying db for all possible terms.
|
346 |
// Complete last word in input by querying db for all possible terms.
|
334 |
void SSearch::completion()
|
347 |
void SSearch::completion()
|
335 |
{
|
348 |
{
|
336 |
LOGDEB(("SSearch::completion\n"));
|
349 |
LOGDEB(("SSearch::completion\n"));
|
|
|
350 |
|
|
|
351 |
m_disableAutosearch = true;
|
|
|
352 |
m_stroketimeout->stop();
|
|
|
353 |
|
337 |
if (!rcldb)
|
354 |
if (!rcldb)
|
338 |
return;
|
355 |
return;
|
339 |
if (searchTypCMB->currentIndex() == SST_FNM) {
|
356 |
if (searchTypCMB->currentIndex() == SST_FNM) {
|
340 |
// Filename: no completion
|
357 |
// Filename: no completion
|
341 |
QApplication::beep();
|
358 |
QApplication::beep();
|
|
... |
|
... |
350 |
return;
|
367 |
return;
|
351 |
}
|
368 |
}
|
352 |
|
369 |
|
353 |
// Query database for completions
|
370 |
// Query database for completions
|
354 |
QStringList lst;
|
371 |
QStringList lst;
|
|
|
372 |
const int maxdpy = 80;
|
|
|
373 |
const int maxwalked = 10000;
|
355 |
if (completionList(s, lst, 100) <= 0) {
|
374 |
if (completionList(s, lst, maxwalked) <= 0) {
|
356 |
QApplication::beep();
|
375 |
QApplication::beep();
|
357 |
return;
|
376 |
return;
|
358 |
}
|
377 |
}
|
359 |
if (lst.size() == 100) {
|
378 |
if (lst.size() >= maxdpy) {
|
360 |
QMessageBox *warning = new QMessageBox;
|
379 |
LOGINFO(("TRUNCATING COMPLETION\n"));
|
361 |
warning->setWindowTitle(tr("Recoll"));
|
380 |
lst = lst.mid(0, maxdpy);
|
362 |
warning->setText(tr("Too many completions"));
|
381 |
lst.append("[...]");
|
363 |
warning->show();
|
|
|
364 |
QTimer::singleShot(500, warning, SLOT(close()));
|
|
|
365 |
return;
|
|
|
366 |
}
|
382 |
}
|
367 |
|
383 |
|
368 |
// If list from db is single word, insert it, else popup the listview
|
384 |
// If list from db is single word, insert it, else popup the listview
|
369 |
m_disableAutosearch = true;
|
|
|
370 |
if (lst.size() == 1) {
|
385 |
if (lst.size() == 1) {
|
371 |
QString txt = queryText->currentText();
|
386 |
QString txt = queryText->currentText();
|
372 |
txt.truncate(cs);
|
387 |
txt.truncate(cs);
|
373 |
txt.append(lst[0]);
|
388 |
txt.append(lst[0]);
|
374 |
queryText->setEditText(txt);
|
389 |
queryText->setEditText(txt);
|
|
... |
|
... |
387 |
}
|
402 |
}
|
388 |
}
|
403 |
}
|
389 |
|
404 |
|
390 |
void SSearch::completionTermChosen(const QString& text)
|
405 |
void SSearch::completionTermChosen(const QString& text)
|
391 |
{
|
406 |
{
|
|
|
407 |
if (text != "[...]")
|
392 |
m_chosenCompletion = text;
|
408 |
m_chosenCompletion = text;
|
|
|
409 |
else
|
|
|
410 |
m_chosenCompletion.clear();
|
393 |
}
|
411 |
}
|
394 |
|
412 |
|
395 |
void SSearch::wrapupCompletion()
|
413 |
void SSearch::wrapupCompletion()
|
396 |
{
|
414 |
{
|
397 |
LOGDEB(("SSearch::wrapupCompletion\n"));
|
415 |
LOGDEB(("SSearch::wrapupCompletion\n"));
|
|
|
416 |
|
398 |
queryText->clear();
|
417 |
queryText->clear();
|
399 |
queryText->addItems(prefs.ssearchHistory);
|
418 |
queryText->addItems(prefs.ssearchHistory);
|
400 |
if (!m_chosenCompletion.isEmpty()) {
|
419 |
if (!m_chosenCompletion.isEmpty()) {
|
401 |
m_savedEditText.truncate(m_completedWordStart);
|
420 |
m_savedEditText.truncate(m_completedWordStart);
|
402 |
m_savedEditText.append(m_chosenCompletion);
|
421 |
m_savedEditText.append(m_chosenCompletion);
|
|
... |
|
... |
579 |
LOGDEB1(("SSearch::eventFilter: keyPress (m_escape %d) key %d\n",
|
598 |
LOGDEB1(("SSearch::eventFilter: keyPress (m_escape %d) key %d\n",
|
580 |
m_escape, ke->key()));
|
599 |
m_escape, ke->key()));
|
581 |
if (ke->key() == Qt::Key_Escape) {
|
600 |
if (ke->key() == Qt::Key_Escape) {
|
582 |
LOGDEB(("Escape\n"));
|
601 |
LOGDEB(("Escape\n"));
|
583 |
m_escape = true;
|
602 |
m_escape = true;
|
|
|
603 |
m_disableAutosearch = true;
|
|
|
604 |
m_stroketimeout->stop();
|
584 |
return true;
|
605 |
return true;
|
585 |
} else if (m_escape && ke->key() == Qt::Key_Space) {
|
606 |
} else if (m_escape && ke->key() == Qt::Key_Space) {
|
586 |
LOGDEB(("Escape space\n"));
|
607 |
LOGDEB(("Escape space\n"));
|
587 |
ke->accept();
|
608 |
ke->accept();
|
588 |
completion();
|
609 |
completion();
|
589 |
m_escape = false;
|
610 |
m_escape = false;
|
|
|
611 |
m_disableAutosearch = true;
|
|
|
612 |
m_stroketimeout->stop();
|
590 |
return true;
|
613 |
return true;
|
591 |
} else if (ke->key() == Qt::Key_Space) {
|
614 |
} else if (ke->key() == Qt::Key_Space) {
|
592 |
// if (prefs.autoSearchOnWS)
|
615 |
// if (prefs.autoSearchOnWS)
|
593 |
// startSimpleSearch();
|
616 |
// startSimpleSearch();
|
594 |
}
|
617 |
}
|
595 |
m_escape = false;
|
618 |
m_escape = false;
|
|
|
619 |
m_keystroke = true;
|
|
|
620 |
if (prefs.autoSearchOnWS) {
|
596 |
m_disableAutosearch = false;
|
621 |
m_disableAutosearch = false;
|
|
|
622 |
QString qs = queryText->currentText();
|
|
|
623 |
LOGINFO(("STARTING TIMER, qs [%s]\n", qs2utf8s(qs).c_str()));
|
|
|
624 |
m_stroketimeout->start(500);
|
|
|
625 |
}
|
597 |
}
|
626 |
}
|
598 |
return false;
|
627 |
return false;
|
599 |
}
|
628 |
}
|