Switch to unified view

a/src/qtgui/spell_w.cpp b/src/qtgui/spell_w.cpp
...
...
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
18
19
#include <stdio.h>
20
#include <unistd.h>
21
19
#include <algorithm>
22
#include <algorithm>
20
21
#include <unistd.h>
22
23
#include <list>
23
#include <list>
24
#include <map>
24
#include <stdio.h>
25
#include <string>
26
using std::list;
27
using std::multimap;
28
using std::string;
25
29
26
#include <qmessagebox.h>
30
#include <qmessagebox.h>
27
#include <qpushbutton.h>
31
#include <qpushbutton.h>
28
#include <qlabel.h>
32
#include <qlabel.h>
29
#include <qlineedit.h>
33
#include <qlineedit.h>
...
...
38
#include "debuglog.h"
42
#include "debuglog.h"
39
#include "recoll.h"
43
#include "recoll.h"
40
#include "spell_w.h"
44
#include "spell_w.h"
41
#include "guiutils.h"
45
#include "guiutils.h"
42
#include "rcldb.h"
46
#include "rcldb.h"
47
#include "searchdata.h"
48
#include "rclquery.h"
43
#include "rclhelp.h"
49
#include "rclhelp.h"
50
#include "wasatorcl.h"
51
#include "execmd.h"
44
52
45
#ifdef RCL_USE_ASPELL
53
#ifdef RCL_USE_ASPELL
46
#include "rclaspell.h"
54
#include "rclaspell.h"
47
#endif
55
#endif
48
56
49
void SpellW::init()
57
void SpellW::init()
50
{
58
{
51
    // Don't change the order, or fix the rest of the code...
59
    m_c2t.clear();
52
    /*0*/expTypeCMB->addItem(tr("Wildcards"));
60
    expTypeCMB->addItem(tr("Wildcards"));
61
    m_c2t.push_back(TYPECMB_WILD);
53
    /*1*/expTypeCMB->addItem(tr("Regexp"));
62
    expTypeCMB->addItem(tr("Regexp"));
63
    m_c2t.push_back(TYPECMB_REG);
54
    /*2*/expTypeCMB->addItem(tr("Stem expansion"));
64
    expTypeCMB->addItem(tr("Stem expansion"));
65
    m_c2t.push_back(TYPECMB_STEM);
55
#ifdef RCL_USE_ASPELL
66
#ifdef RCL_USE_ASPELL
56
    bool noaspell = false;
67
    bool noaspell = false;
57
    theconfig->getConfParam("noaspell", &noaspell);
68
    theconfig->getConfParam("noaspell", &noaspell);
58
    if (!noaspell)
69
    if (!noaspell) {
59
    /*3*/expTypeCMB->addItem(tr("Spelling/Phonetic"));
70
    expTypeCMB->addItem(tr("Spelling/Phonetic"));
71
  m_c2t.push_back(TYPECMB_ASPELL);
72
    }
60
#endif
73
#endif
74
    expTypeCMB->addItem(tr("Show index statistics"));
75
    m_c2t.push_back(TYPECMB_STATS);
61
76
62
    int typ = prefs.termMatchType;
77
    int typ = prefs.termMatchType;
63
    if (typ < 0 || typ > expTypeCMB->count())
78
    vector<comboboxchoice>::const_iterator it = 
64
  typ = 0;
79
  std::find(m_c2t.begin(), m_c2t.end(), typ);
80
    if (it == m_c2t.end())
81
  it = m_c2t.begin();
82
    int cmbidx = it - m_c2t.begin();
83
65
    expTypeCMB->setCurrentIndex(typ);
84
    expTypeCMB->setCurrentIndex(cmbidx);
66
85
67
    // Stemming language combobox
86
    // Stemming language combobox
68
    stemLangCMB->clear();
87
    stemLangCMB->clear();
69
    vector<string> langs;
88
    vector<string> langs;
70
    if (!getStemLangs(langs)) {
89
    if (!getStemLangs(langs)) {
...
...
74
    for (vector<string>::const_iterator it = langs.begin(); 
93
    for (vector<string>::const_iterator it = langs.begin(); 
75
     it != langs.end(); it++) {
94
     it != langs.end(); it++) {
76
    stemLangCMB->
95
    stemLangCMB->
77
        addItem(QString::fromAscii(it->c_str(), it->length()));
96
        addItem(QString::fromAscii(it->c_str(), it->length()));
78
    }
97
    }
79
    stemLangCMB->setEnabled(expTypeCMB->currentIndex()==2);
80
98
81
    (void)new HelpClient(this);
99
    (void)new HelpClient(this);
82
    HelpClient::installMap((const char *)this->objectName().toUtf8(), 
100
    HelpClient::installMap((const char *)this->objectName().toUtf8(), 
83
               "RCL.SEARCH.TERMEXPLORER");
101
               "RCL.SEARCH.TERMEXPLORER");
84
102
...
...
88
    connect(baseWordLE, SIGNAL(returnPressed()), this, SLOT(doExpand()));
106
    connect(baseWordLE, SIGNAL(returnPressed()), this, SLOT(doExpand()));
89
    connect(expandPB, SIGNAL(clicked()), this, SLOT(doExpand()));
107
    connect(expandPB, SIGNAL(clicked()), this, SLOT(doExpand()));
90
    connect(dismissPB, SIGNAL(clicked()), this, SLOT(close()));
108
    connect(dismissPB, SIGNAL(clicked()), this, SLOT(close()));
91
    connect(expTypeCMB, SIGNAL(activated(int)), this, SLOT(modeSet(int)));
109
    connect(expTypeCMB, SIGNAL(activated(int)), this, SLOT(modeSet(int)));
92
110
93
    QStringList labels(tr("Term"));
94
    labels.push_back(tr("Doc. / Tot."));
95
    resTW->setHorizontalHeaderLabels(labels);
96
    resTW->setShowGrid(0);
111
    resTW->setShowGrid(0);
97
    resTW->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
112
    resTW->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
98
    resTW->verticalHeader()->setDefaultSectionSize(20); 
113
    resTW->verticalHeader()->setDefaultSectionSize(20); 
99
    connect(resTW,
114
    connect(resTW,
100
       SIGNAL(cellDoubleClicked(int, int)),
115
       SIGNAL(cellDoubleClicked(int, int)),
101
            this, SLOT(textDoubleClicked(int, int)));
116
            this, SLOT(textDoubleClicked(int, int)));
102
117
103
    resTW->setColumnWidth(0, 200);
118
    resTW->setColumnWidth(0, 200);
104
    resTW->setColumnWidth(1, 150);
119
    resTW->setColumnWidth(1, 150);
105
    resTW->installEventFilter(this);
120
    resTW->installEventFilter(this);
121
122
    modeSet(cmbidx);
106
}
123
}
107
124
108
static const int maxexpand = 10000;
125
static const int maxexpand = 10000;
109
126
110
/* Expand term according to current mode */
127
/* Expand term according to current mode */
111
void SpellW::doExpand()
128
void SpellW::doExpand()
112
{
129
{
130
    int idx = expTypeCMB->currentIndex();
131
    if (idx < 0 || idx >= int(m_c2t.size()))
132
  idx = 0;
133
    comboboxchoice mode = m_c2t[idx];
134
113
    // Can't clear qt4 table widget: resets column headers too
135
    // Can't clear qt4 table widget: resets column headers too
114
    resTW->setRowCount(0);
136
    resTW->setRowCount(0);
115
    if (baseWordLE->text().isEmpty()) 
137
    if (baseWordLE->text().isEmpty() && mode != TYPECMB_STATS) 
116
    return;
138
    return;
117
139
118
    string reason;
140
    string reason;
119
    if (!maybeOpenDb(reason)) {
141
    if (!maybeOpenDb(reason)) {
120
    QMessageBox::critical(0, "Recoll", QString(reason.c_str()));
142
    QMessageBox::critical(0, "Recoll", QString(reason.c_str()));
121
    LOGDEB(("SpellW::doExpand: db error: %s\n", reason.c_str()));
143
    LOGDEB(("SpellW::doExpand: db error: %s\n", reason.c_str()));
122
    return;
144
    return;
123
    }
145
    }
124
146
147
    Rcl::Db::MatchType mt;
148
    switch(mode) {
149
    case TYPECMB_WILD: mt = Rcl::Db::ET_WILD; break;
150
    case TYPECMB_REG: mt = Rcl::Db::ET_REGEXP; break;
151
    case TYPECMB_STEM: mt = Rcl::Db::ET_STEM; break;
152
    default: mt = Rcl::Db::ET_WILD;
153
    }
154
155
    Rcl::TermMatchResult res;
125
    string expr = string((const char *)baseWordLE->text().toUtf8());
156
    string expr = string((const char *)baseWordLE->text().toUtf8());
126
    list<string> suggs;
127
157
128
    prefs.termMatchType = expTypeCMB->currentIndex();
158
    switch (mode) {
129
159
    case TYPECMB_WILD: 
130
    Rcl::Db::MatchType mt = Rcl::Db::ET_WILD;
160
    default:
131
    switch(expTypeCMB->currentIndex()) {
161
    case TYPECMB_REG:
132
    case 0: mt = Rcl::Db::ET_WILD; break;
162
    case TYPECMB_STEM:
133
    case 1:mt = Rcl::Db::ET_REGEXP; break;
134
    case 2:mt = Rcl::Db::ET_STEM; break;
135
    }
163
    {
136
137
    Rcl::TermMatchResult res;
138
    switch (expTypeCMB->currentIndex()) {
139
    case 0: 
140
    case 1:
141
    case 2: 
142
    {
143
    string l_stemlang = (const char*)stemLangCMB->currentText().toAscii();
164
    string l_stemlang = qs2utf8s(stemLangCMB->currentText());
144
165
145
    if (!rcldb->termMatch(mt, l_stemlang, expr, res, maxexpand)) {
166
    if (!rcldb->termMatch(mt, l_stemlang, expr, res, maxexpand)) {
146
        LOGERR(("SpellW::doExpand:rcldb::termMatch failed\n"));
167
        LOGERR(("SpellW::doExpand:rcldb::termMatch failed\n"));
147
        return;
168
        return;
148
    }
169
    }
...
...
150
                 "%3 results")
171
                 "%3 results")
151
                          .arg(res.dbdoccount).arg(res.dbavgdoclen, 0, 'f', 1)
172
                          .arg(res.dbdoccount).arg(res.dbavgdoclen, 0, 'f', 1)
152
              .arg(res.entries.size()));
173
              .arg(res.entries.size()));
153
    }
174
    }
154
        
175
        
155
  break;
176
    break;
156
177
157
#ifdef RCL_USE_ASPELL
178
#ifdef RCL_USE_ASPELL
158
    case 3: {
179
    case TYPECMB_ASPELL: 
180
    {
159
    LOGDEB(("SpellW::doExpand: aspelling\n"));
181
    LOGDEB(("SpellW::doExpand: aspelling\n"));
160
    if (!aspell) {
182
    if (!aspell) {
161
        QMessageBox::warning(0, "Recoll",
183
        QMessageBox::warning(0, "Recoll",
162
                 tr("Aspell init failed. "
184
                 tr("Aspell init failed. "
163
                    "Aspell not installed?"));
185
                    "Aspell not installed?"));
...
...
180
        res.entries.push_back(Rcl::TermMatchEntry(rclsugg));
202
        res.entries.push_back(Rcl::TermMatchEntry(rclsugg));
181
    }
203
    }
182
#endif // TESTING_XAPIAN_SPELL
204
#endif // TESTING_XAPIAN_SPELL
183
        statsLBL->setText(tr("%1 results").arg(res.entries.size()));
205
        statsLBL->setText(tr("%1 results").arg(res.entries.size()));
184
    }
206
    }
185
#endif
207
    break;
208
#endif // RCL_USE_ASPELL
209
210
    case TYPECMB_STATS: 
211
    {
212
  showStats();
213
  return;
214
    }
215
    break;
186
    }
216
    }
187
217
188
218
189
    if (res.entries.empty()) {
219
    if (res.entries.empty()) {
190
        resTW->setItem(0, 0, new QTableWidgetItem(tr("No expansion found")));
220
        resTW->setItem(0, 0, new QTableWidgetItem(tr("No expansion found")));
...
...
222
                             new QTableWidgetItem(QString::fromAscii(num)));
252
                             new QTableWidgetItem(QString::fromAscii(num)));
223
    }
253
    }
224
    }
254
    }
225
}
255
}
226
256
257
void SpellW::showStats()
258
{
259
    statsLBL->setText("");
260
    int row = 0;
261
262
    Rcl::TermMatchResult res;
263
    if (!rcldb->termMatch(Rcl::Db::ET_WILD, "", "azbogusaz", res, 1)) {
264
  LOGERR(("SpellW::doExpand:rcldb::termMatch failed\n"));
265
  return;
266
    }
267
268
    resTW->setRowCount(row+1);
269
    resTW->setItem(row, 0,
270
         new QTableWidgetItem(tr("Number of documents")));
271
    resTW->setItem(row++, 1, new QTableWidgetItem(
272
             QString::number(res.dbdoccount)));
273
274
    resTW->setRowCount(row+1);
275
    resTW->setItem(row, 0,
276
         new QTableWidgetItem(tr("Average terms per document")));
277
    resTW->setItem(row++, 1, new QTableWidgetItem(
278
             QString::number(res.dbavgdoclen)));
279
280
    resTW->setRowCount(row+1);
281
    resTW->setItem(row, 0,
282
         new QTableWidgetItem(tr("Smallest document length")));
283
    resTW->setItem(row++, 1, new QTableWidgetItem(
284
             QString::number(res.mindoclen)));
285
286
    resTW->setRowCount(row+1);
287
    resTW->setItem(row, 0,
288
         new QTableWidgetItem(tr("Longest document length")));
289
    resTW->setItem(row++, 1, new QTableWidgetItem(
290
             QString::number(res.maxdoclen)));
291
292
    if (!thestableconfig)
293
  return;
294
295
    ExecCmd cmd;
296
    vector<string> args; 
297
    int status;
298
    args.push_back("-sk");
299
    args.push_back(thestableconfig->getDbDir());
300
    string output;
301
    status = cmd.doexec("du", args, 0, &output);
302
    int dbkbytes = 0;
303
    if (!status) {
304
  dbkbytes = atoi(output.c_str());
305
    }
306
    resTW->setRowCount(row+1);
307
    resTW->setItem(row, 0,
308
         new QTableWidgetItem(tr("Database directory size")));
309
    resTW->setItem(row++, 1, new QTableWidgetItem(
310
             QString::fromUtf8(
311
             displayableBytes(dbkbytes*1024).c_str())));
312
313
    vector<string> allmimetypes = thestableconfig->getAllMimeTypes();
314
    multimap<int, string> mtbycnt;
315
    for (vector<string>::const_iterator it = allmimetypes.begin();
316
   it != allmimetypes.end(); it++) {
317
  string reason;
318
  string q = string("mime:") + *it;
319
  Rcl::SearchData *sd =
320
      wasaStringToRcl(thestableconfig, "", q, reason);
321
  RefCntr<Rcl::SearchData> rq(sd);
322
  Rcl::Query query(rcldb);
323
  if (!query.setQuery(rq)) {
324
      LOGERR(("Query setup failed: %s",query.getReason().c_str()));
325
      return;
326
  }
327
  int cnt = query.getResCnt();
328
  mtbycnt.insert(pair<int,string>(cnt,*it));
329
    }
330
    resTW->setRowCount(row+1);
331
    resTW->setItem(row, 0, new QTableWidgetItem(tr("MIME types:")));
332
    resTW->setItem(row++, 1, new QTableWidgetItem(""));
333
334
    for (multimap<int, string>::const_reverse_iterator it = mtbycnt.rbegin();
335
   it != mtbycnt.rend(); it++) {
336
  resTW->setRowCount(row+1);
337
  resTW->setItem(row, 0, new QTableWidgetItem(
338
             QString::fromUtf8(it->second.c_str())));
339
  resTW->setItem(row++, 1, new QTableWidgetItem(
340
             QString::number(it->first)));
341
    }
342
}
343
227
void SpellW::wordChanged(const QString &text)
344
void SpellW::wordChanged(const QString &text)
228
{
345
{
229
    if (text.isEmpty()) {
346
    if (text.isEmpty()) {
230
    expandPB->setEnabled(false);
347
    expandPB->setEnabled(false);
231
        resTW->setRowCount(0);
348
        resTW->setRowCount(0);
...
...
240
    QTableWidgetItem *item = resTW->item(row, 0);
357
    QTableWidgetItem *item = resTW->item(row, 0);
241
    if (item)
358
    if (item)
242
        emit(wordSelect(item->text()));
359
        emit(wordSelect(item->text()));
243
}
360
}
244
361
245
void SpellW::modeSet(int mode)
362
void SpellW::modeSet(int idx)
246
{
363
{
247
    if (mode == 2)
364
    if (idx < 0 || idx > int(m_c2t.size()))
365
  return;
366
    comboboxchoice mode = m_c2t[idx]; 
367
    resTW->setRowCount(0);
368
   
369
    if (mode == TYPECMB_STEM)
248
    stemLangCMB->setEnabled(true);
370
    stemLangCMB->setEnabled(true);
249
    else
371
    else
250
    stemLangCMB->setEnabled(false);
372
    stemLangCMB->setEnabled(false);
373
    if (mode == TYPECMB_STATS)
374
  baseWordLE->setEnabled(false);
375
    else
376
  baseWordLE->setEnabled(true);
377
378
379
    if (mode == TYPECMB_STATS) {
380
  QStringList labels(tr("Item"));
381
  labels.push_back(tr("Value"));
382
  resTW->setHorizontalHeaderLabels(labels);
383
  doExpand();
384
    } else {
385
  QStringList labels(tr("Term"));
386
  labels.push_back(tr("Doc. / Tot."));
387
  resTW->setHorizontalHeaderLabels(labels);
388
  prefs.termMatchType = mode;
389
    }
251
}
390
}
252
391
253
void SpellW::copy()
392
void SpellW::copy()
254
{
393
{
255
  QItemSelectionModel * selection = resTW->selectionModel();
394
  QItemSelectionModel * selection = resTW->selectionModel();