Switch to unified view

a/src/qtgui/ssearch_w.cpp b/src/qtgui/ssearch_w.cpp
...
...
60
60
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
}
66
}
66
67
67
void SSearch::searchTextChanged(const QString& text)
68
void SSearch::searchTextChanged(const QString& text)
68
{
69
{
69
    if (text.isEmpty()) {
70
    if (text.isEmpty()) {
70
    searchPB->setEnabled(false);
71
    searchPB->setEnabled(false);
71
    clearqPB->setEnabled(false);
72
    clearqPB->setEnabled(false);
73
  queryText->setFocus();
72
    emit clearSearch();
74
    emit clearSearch();
73
    } else {
75
    } else {
74
    searchPB->setEnabled(true);
76
    searchPB->setEnabled(true);
75
    clearqPB->setEnabled(true);
77
    clearqPB->setEnabled(true);
78
  if (prefs.autoSearchOnWS && !m_disableAutosearch) {
79
      m_disableAutosearch = true;
80
      LOGDEB(("Autosearch: current: [%s]\n", 
81
          qs2utf8s(queryText->currentText()).c_str()));
82
#if 1
83
      string s;
84
      int cs = partialWord(s);
85
      if (cs < 0) {
86
      startSimpleSearch();
87
      return;
88
      }
89
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
      }
99
      s = qs2utf8s(queryText->currentText());
100
      s += "*";
101
      startSimpleSearch(s);
102
#else
103
      startSimpleSearch();
104
#endif
105
  }
76
    }
106
    }
77
}
107
}
78
108
79
void SSearch::searchTypeChanged(int typ)
109
void SSearch::searchTypeChanged(int typ)
80
{
110
{
...
...
121
{
151
{
122
    if (queryText->currentText().length() == 0)
152
    if (queryText->currentText().length() == 0)
123
    return;
153
    return;
124
154
125
    string u8 = (const char *)queryText->currentText().toUtf8();
155
    string u8 = (const char *)queryText->currentText().toUtf8();
126
    LOGDEB(("SSearch::startSimpleSearch: [%s]\n", u8.c_str()));
127
156
128
    trimstring(u8);
157
    trimstring(u8);
129
    if (u8.length() == 0)
158
    if (u8.length() == 0)
130
    return;
159
    return;
131
160
161
    if (!startSimpleSearch(u8))
162
  return;
163
164
    LOGDEB(("startSimpleSearch: updating history\n"));
165
    // Search terms history:
166
    // 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 ? 
168
    // So do it by hand.
169
    QString txt = queryText->currentText();
170
    int index = queryText->findText(txt);
171
    if (index >= 0) 
172
  queryText->removeItem(index);
173
    queryText->insertItem(0, txt);
174
    queryText->setCurrentIndex(0);
175
    m_disableAutosearch = true;
176
177
    // Save the current state of the listbox list to the prefs (will
178
    // go to disk)
179
    prefs.ssearchHistory.clear();
180
    for (int index = 0; index < queryText->count(); index++) {
181
  prefs.ssearchHistory.push_back(queryText->itemText(index));
182
    }
183
}
184
185
bool SSearch::startSimpleSearch(const string& u8)
186
{
187
    LOGDEB(("SSearch::startSimpleSearch(%s)\n", u8.c_str()));
132
    string stemlang = prefs.stemlang();
188
    string stemlang = prefs.stemlang();
133
189
134
    SSearchType tp = (SSearchType)searchTypCMB->currentIndex();
190
    SSearchType tp = (SSearchType)searchTypCMB->currentIndex();
135
    Rcl::SearchData *sdata = 0;
191
    Rcl::SearchData *sdata = 0;
136
192
...
...
142
        else
198
        else
143
            sdata = wasaStringToRcl(theconfig, stemlang, u8, reason);
199
            sdata = wasaStringToRcl(theconfig, stemlang, u8, reason);
144
    if (sdata == 0) {
200
    if (sdata == 0) {
145
        QMessageBox::warning(0, "Recoll", tr("Bad query string") + ": " +
201
        QMessageBox::warning(0, "Recoll", tr("Bad query string") + ": " +
146
                 QString::fromAscii(reason.c_str()));
202
                 QString::fromAscii(reason.c_str()));
147
        return;
203
        return false;
148
    }
204
    }
149
    } else {
205
    } else {
150
    sdata = new Rcl::SearchData(Rcl::SCLT_OR, stemlang);
206
    sdata = new Rcl::SearchData(Rcl::SCLT_OR, stemlang);
151
    if (sdata == 0) {
207
    if (sdata == 0) {
152
        QMessageBox::warning(0, "Recoll", tr("Out of memory"));
208
        QMessageBox::warning(0, "Recoll", tr("Out of memory"));
153
        return;
209
        return false;
154
    }
210
    }
155
    Rcl::SearchDataClause *clp = 0;
211
    Rcl::SearchDataClause *clp = 0;
156
    if (tp == SST_FNM) {
212
    if (tp == SST_FNM) {
157
        clp = new Rcl::SearchDataClauseFilename(u8);
213
        clp = new Rcl::SearchDataClauseFilename(u8);
158
    } else if (!TextSplit::hasVisibleWhite(u8)) {
214
    } else if (!TextSplit::hasVisibleWhite(u8)) {
...
...
173
    if (prefs.ssearchAutoPhrase && rcldb) {
229
    if (prefs.ssearchAutoPhrase && rcldb) {
174
    sdata->maybeAddAutoPhrase(*rcldb, 
230
    sdata->maybeAddAutoPhrase(*rcldb, 
175
                  prefs.ssearchAutoPhraseThreshPC / 100.0);
231
                  prefs.ssearchAutoPhraseThreshPC / 100.0);
176
    }
232
    }
177
233
178
    // Search terms history
179
180
    // We want to have the new text at the top and any older identical
181
    // entry to be erased. There is no standard qt policy to do this ? 
182
    // So do it by hand.
183
    QString txt = queryText->currentText();
184
    int index = queryText->findText(txt);
185
    if (index >= 0) 
186
  queryText->removeItem(index);
187
    queryText->insertItem(0, txt);
188
    queryText->setCurrentIndex(0);
189
190
    // Save the current state of the listbox list to the prefs (will
191
    // go to disk)
192
    prefs.ssearchHistory.clear();
193
    for (int index = 0; index < queryText->count(); index++) {
194
  prefs.ssearchHistory.push_back(queryText->itemText(index));
195
    }
196
197
    RefCntr<Rcl::SearchData> rsdata(sdata);
234
    RefCntr<Rcl::SearchData> rsdata(sdata);
198
    emit startSearch(rsdata);
235
    emit startSearch(rsdata);
236
    return true;
199
}
237
}
200
238
201
void SSearch::setSearchString(const QString& txt)
239
void SSearch::setSearchString(const QString& txt)
202
{
240
{
241
    m_disableAutosearch = true;
203
    queryText->setEditText(txt);
242
    queryText->setEditText(txt);
204
}
243
}
205
244
206
bool SSearch::hasSearchString()
245
bool SSearch::hasSearchString()
207
{
246
{
...
...
232
    term = QString::fromUtf8(t.c_str());
271
    term = QString::fromUtf8(t.c_str());
233
272
234
    QString text = queryText->currentText();
273
    QString text = queryText->currentText();
235
    text += QString::fromLatin1(" ") + term;
274
    text += QString::fromLatin1(" ") + term;
236
    queryText->setEditText(text);
275
    queryText->setEditText(text);
276
    m_disableAutosearch = true;
237
}
277
}
238
278
239
void SSearch::onWordReplace(const QString& o, const QString& n)
279
void SSearch::onWordReplace(const QString& o, const QString& n)
240
{
280
{
281
    LOGDEB(("SSearch::onWordReplace: o [%s] n [%s]\n",
282
      qs2utf8s(o).c_str(), qs2utf8s(n).c_str()));
241
    QString txt = queryText->currentText();
283
    QString txt = queryText->currentText();
242
    QRegExp exp = QRegExp(QString("\\b") + o + QString("\\b"));
284
    QRegExp exp = QRegExp(QString("\\b") + o + QString("\\b"));
243
    exp.setCaseSensitivity(Qt::CaseInsensitive);
285
    exp.setCaseSensitivity(Qt::CaseInsensitive);
244
    txt.replace(exp, n);
286
    txt.replace(exp, n);
245
    queryText->setEditText(txt);
287
    queryText->setEditText(txt);
288
    m_disableAutosearch = true;
246
    Qt::KeyboardModifiers mods = QApplication::keyboardModifiers ();
289
    Qt::KeyboardModifiers mods = QApplication::keyboardModifiers ();
247
    if (mods == Qt::NoModifier)
290
    if (mods == Qt::NoModifier)
248
    startSimpleSearch();
291
    startSimpleSearch();
249
}
292
}
250
293
251
void SSearch::setAnyTermMode()
294
void SSearch::setAnyTermMode()
252
{
295
{
253
    searchTypCMB->setCurrentIndex(SST_ANY);
296
    searchTypCMB->setCurrentIndex(SST_ANY);
254
}
297
}
255
298
256
// Complete last word in input by querying db for all possible terms.
299
int SSearch::partialWord(string& s)
257
void SSearch::completion()
258
{
300
{
259
    if (!rcldb)
260
  return;
261
    if (searchTypCMB->currentIndex() == SST_FNM) {
262
  // Filename: no completion
263
  QApplication::beep();
264
  return;
265
    }
266
    // Extract last word in text
301
    // Extract last word in text
267
    QString txt = queryText->currentText();
302
    QString txt = queryText->currentText();
268
    int cs = txt.lastIndexOf(" ");
303
    int cs = txt.lastIndexOf(" ");
269
    if (cs == -1)
304
    if (cs == -1)
270
    cs = 0;
305
    cs = 0;
271
    else
306
    else
272
    cs++;
307
    cs++;
273
    if (txt.size() == 0 || cs == txt.size()) {
308
    if (txt.size() == 0 || cs == txt.size()) {
309
  return -1;
310
    }
311
    s = qs2utf8s(txt.right(txt.size() - cs));
312
    return cs;
313
}
314
315
int SSearch::completionList(string s, QStringList& lst, int max)
316
{
317
    if (!rcldb)
318
  return -1;
319
   // Query database for completions
320
    s += "*";
321
    Rcl::TermMatchResult tmres;
322
    if (!rcldb->termMatch(Rcl::Db::ET_WILD, "", s, tmres, max) || 
323
  tmres.entries.size() == 0) {
324
  return 0;
325
    }
326
    for (vector<Rcl::TermMatchEntry>::iterator it = tmres.entries.begin(); 
327
   it != tmres.entries.end(); it++) {
328
  lst.push_back(QString::fromUtf8(it->term.c_str()));
329
    }
330
    return lst.size();
331
}
332
333
// Complete last word in input by querying db for all possible terms.
334
void SSearch::completion()
335
{
336
    LOGDEB(("SSearch::completion\n"));
337
    if (!rcldb)
338
  return;
339
    if (searchTypCMB->currentIndex() == SST_FNM) {
340
  // Filename: no completion
274
    QApplication::beep();
341
    QApplication::beep();
275
    return;
342
    return;
276
    }
343
    }
277
344
345
    // Extract last word in text
346
    string s;
347
    int cs = partialWord(s);
348
    if (cs < 0) {
349
  QApplication::beep();
350
  return;
351
    }
352
278
    // Query database for completions
353
    // Query database for completions
279
    string s = qs2utf8s(txt.right(txt.size() - cs)) + "*";
354
    QStringList lst;
280
355
    if (completionList(s, lst, 100) <= 0) {
281
    const int max = 100;
282
    Rcl::TermMatchResult tmres;
283
284
    string stemLang = prefs.stemlang();
285
286
    if (!rcldb->termMatch(Rcl::Db::ET_WILD, stemLang, s, tmres, max) || 
287
  tmres.entries.size() == 0) {
288
    QApplication::beep();
356
    QApplication::beep();
289
    return;
357
    return;
290
    }
358
    }
291
    if (tmres.entries.size() == (unsigned int)max) {
359
    if (lst.size() == 100) {
292
    QMessageBox *warning = new QMessageBox;
360
    QMessageBox *warning = new QMessageBox;
293
    warning->setWindowTitle(tr("Recoll"));
361
    warning->setWindowTitle(tr("Recoll"));
294
    warning->setText(tr("Too many completions"));
362
    warning->setText(tr("Too many completions"));
295
    warning->show();
363
    warning->show();
296
    QTimer::singleShot(500, warning, SLOT(close()));
364
    QTimer::singleShot(500, warning, SLOT(close()));
297
    return;
365
    return;
298
    }
366
    }
299
367
300
    // If list from db is single word, insert it, else popup the listview
368
    // If list from db is single word, insert it, else popup the listview
369
    m_disableAutosearch = true;
301
    if (tmres.entries.size() == 1) {
370
    if (lst.size() == 1) {
302
  QString res = QString::fromUtf8(tmres.entries.begin()->term.c_str());
371
  QString txt = queryText->currentText();
303
    txt.truncate(cs);
372
    txt.truncate(cs);
304
    txt.append(res);
373
    txt.append(lst[0]);
305
    queryText->setEditText(txt);
374
    queryText->setEditText(txt);
306
    } else {
375
    } else {
307
  QStringList lst;
308
  for (vector<Rcl::TermMatchEntry>::iterator it = tmres.entries.begin(); 
309
       it != tmres.entries.end(); it++) {
310
      lst.push_back(QString::fromUtf8(it->term.c_str()));
311
  }
312
313
    m_savedEditText = queryText->currentText();
376
    m_savedEditText = queryText->currentText();
314
    m_displayingCompletions = true;
377
    m_displayingCompletions = true;
315
    m_chosenCompletion.clear();
378
    m_chosenCompletion.clear();
316
    m_completedWordStart = cs;
379
    m_completedWordStart = cs;
317
380
...
...
319
    queryText->addItems(lst);
382
    queryText->addItems(lst);
320
    queryText->showPopup();
383
    queryText->showPopup();
321
384
322
    connect(queryText, SIGNAL(activated(const QString&)), this,
385
    connect(queryText, SIGNAL(activated(const QString&)), this,
323
        SLOT(completionTermChosen(const QString&)));
386
        SLOT(completionTermChosen(const QString&)));
324
  
325
    }
387
    }
326
}
388
}
327
389
328
void SSearch::completionTermChosen(const QString& text)
390
void SSearch::completionTermChosen(const QString& text)
329
{
391
{
330
    m_chosenCompletion = text;
392
    m_chosenCompletion = text;
331
}
393
}
332
394
333
void SSearch::wrapupCompletion()
395
void SSearch::wrapupCompletion()
334
{
396
{
397
    LOGDEB(("SSearch::wrapupCompletion\n"));
335
    queryText->clear();
398
    queryText->clear();
336
    queryText->addItems(prefs.ssearchHistory);
399
    queryText->addItems(prefs.ssearchHistory);
337
    if (!m_chosenCompletion.isEmpty()) {
400
    if (!m_chosenCompletion.isEmpty()) {
338
    m_savedEditText.truncate(m_completedWordStart);
401
    m_savedEditText.truncate(m_completedWordStart);
339
    m_savedEditText.append(m_chosenCompletion);
402
    m_savedEditText.append(m_chosenCompletion);
340
    }
403
    }
341
    queryText->setEditText(m_savedEditText);
404
    queryText->setEditText(m_savedEditText);
405
    m_disableAutosearch = true;
342
    m_savedEditText.clear();
406
    m_savedEditText.clear();
343
    m_chosenCompletion.clear();
407
    m_chosenCompletion.clear();
408
    m_displayingCompletions = false;
344
    disconnect(queryText, SIGNAL(activated(const QString&)), this,
409
    disconnect(queryText, SIGNAL(activated(const QString&)), this,
345
           SLOT(completionTermChosen(const QString&)));
410
           SLOT(completionTermChosen(const QString&)));
346
}
411
}
347
412
348
#undef SHOWEVENTS
413
#undef SHOWEVENTS
...
...
502
    if (event->type() == QEvent::Hide) {
567
    if (event->type() == QEvent::Hide) {
503
        // List was closed. If we were displaying completions, need
568
        // List was closed. If we were displaying completions, need
504
        // to reset state.
569
        // to reset state.
505
        if (m_displayingCompletions) {
570
        if (m_displayingCompletions) {
506
        QTimer::singleShot(0, this, SLOT(wrapupCompletion()));
571
        QTimer::singleShot(0, this, SLOT(wrapupCompletion()));
507
      m_displayingCompletions = false;
508
        }
572
        }
509
    }
573
    }
510
    return false;
574
    return false;
511
    }
575
    }
512
576
...
...
523
        ke->accept();
587
        ke->accept();
524
        completion();
588
        completion();
525
        m_escape = false;
589
        m_escape = false;
526
        return true;
590
        return true;
527
    } else if (ke->key() == Qt::Key_Space) {
591
    } else if (ke->key() == Qt::Key_Space) {
528
        if (prefs.autoSearchOnWS)
592
//       if (prefs.autoSearchOnWS)
529
        startSimpleSearch();
593
//       startSimpleSearch();
530
    }
594
    }
531
    m_escape = false;
595
    m_escape = false;
596
  m_disableAutosearch = false;
532
    }
597
    }
533
    return false;
598
    return false;
534
}
599
}