~vcs-imports/bibletime/trunk

« back to all changes in this revision

Viewing changes to bibletime/frontend/searchdialog/csearchanalysis.cpp

  • Committer: mgruner
  • Date: 2007-05-08 15:51:07 UTC
  • Revision ID: vcs-imports@canonical.com-20070508155107-0rj7jdmm5ivf8685
-imported source and data files to new svn module
-this is where KDE4-based development will take place

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*********
 
2
*
 
3
* This file is part of BibleTime's source code, http://www.bibletime.info/.
 
4
*
 
5
* Copyright 1999-2006 by the BibleTime developers.
 
6
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
 
7
*
 
8
**********/
 
9
 
 
10
 
 
11
 
 
12
#include "csearchanalysis.h"
 
13
#include "csearchdialog.h"
 
14
 
 
15
#include "backend/cswordkey.h"
 
16
#include "backend/cswordversekey.h"
 
17
 
 
18
#include "frontend/cbtconfig.h"
 
19
 
 
20
#include "util/cresmgr.h"
 
21
#include "util/ctoolclass.h"
 
22
 
 
23
//Qt includes
 
24
#include <qhbox.h>
 
25
#include <qvbox.h>
 
26
#include <qptrlist.h>
 
27
#include <qpainter.h>
 
28
#include <qlayout.h>
 
29
#include <qmap.h>
 
30
#include <qlineedit.h>
 
31
#include <qtextedit.h>
 
32
#include <qlabel.h>
 
33
#include <qsizepolicy.h>
 
34
#include <qpushbutton.h>
 
35
#include <qheader.h>
 
36
#include <qregexp.h>
 
37
#include <qmessagebox.h>
 
38
 
 
39
//KDE includes
 
40
#include <kapplication.h>
 
41
#include <kfiledialog.h>
 
42
#include <klocale.h>
 
43
#include <kiconloader.h>
 
44
 
 
45
namespace Search {
 
46
        namespace Analysis {
 
47
        
 
48
const int SPACE_BETWEEN_PARTS = 5;
 
49
const int RIGHT_BORDER = 15;
 
50
const int LEFT_BORDER = 15;
 
51
const int LOWER_BORDER = 10;
 
52
const int UPPER_BORDER = 10;
 
53
 
 
54
const int ITEM_TEXT_SIZE = 8;
 
55
const int LABEL_TEXT_SIZE = 6;
 
56
 
 
57
//used for the shift between the bars
 
58
const int BAR_DELTAX = 4;
 
59
const int BAR_DELTAY = 2;
 
60
const int BAR_WIDTH  = 2 + (2*BAR_DELTAX);  //should be equal or bigger than the label font size
 
61
// Used for the text below the bars
 
62
const int BAR_LOWER_BORDER = 100;
 
63
 
 
64
const int LEGEND_INNER_BORDER = 5;
 
65
const int LEGEND_DELTAY = 4;
 
66
const int LEGEND_WIDTH = 85;
 
67
 
 
68
/****************************/
 
69
 
 
70
CSearchAnalysisDialog::CSearchAnalysisDialog( ListCSwordModuleInfo modules, QWidget* parentDialog ) : KDialogBase(Plain, i18n("Search analysis"), Close, Close, parentDialog, 0, true) {
 
71
        initView();
 
72
        initConnections();
 
73
        m_analysis->reset();
 
74
        m_analysis->analyse(modules);
 
75
        showMaximized();
 
76
};
 
77
 
 
78
CSearchAnalysisDialog::~CSearchAnalysisDialog() {}
 
79
;
 
80
 
 
81
/** Initializes this dialog. */
 
82
void CSearchAnalysisDialog::initView() {
 
83
        QVBoxLayout* layout = new QVBoxLayout(plainPage(),0);
 
84
 
 
85
        QPushButton* button = new QPushButton(plainPage(), "button");
 
86
        button->setIconSet(SmallIconSet("filesave"));
 
87
        button->setText(i18n("Save search analysis as HTML"));
 
88
        button->setFixedSize(button->sizeHint());
 
89
        layout->addWidget(button);
 
90
        layout->addSpacing(10);
 
91
 
 
92
        m_analysis = new CSearchAnalysis(plainPage());
 
93
        m_analysisView = new CSearchAnalysisView(m_analysis, plainPage());
 
94
        m_analysisView->show();
 
95
        layout->addWidget(m_analysisView);
 
96
 
 
97
        connect(button, SIGNAL(clicked()), m_analysis, SLOT(saveAsHTML()));
 
98
}
 
99
 
 
100
/** Initializes the widgets SIGNAL and SLOT connections,. */
 
101
void CSearchAnalysisDialog::initConnections() {}
 
102
 
 
103
/****************************/
 
104
/*  CSearchAnalysis         */
 
105
/****************************/
 
106
 
 
107
CSearchAnalysis::CSearchAnalysis(QObject *parent, const char *name )
 
108
: QCanvas(parent,name) {
 
109
 
 
110
        m_scaleFactor = 0.0;
 
111
        m_legend = 0;
 
112
        setBackgroundColor(Qt::white);
 
113
        m_canvasItemList.resize(67);
 
114
        m_canvasItemList.setAutoDelete(true);
 
115
        resize(1,1);
 
116
        connect(this, SIGNAL(resized()), SLOT(slotResized()));
 
117
}
 
118
 
 
119
CSearchAnalysis::~CSearchAnalysis() {}
 
120
 
 
121
QDict<CSearchAnalysisItem>* CSearchAnalysis::getSearchAnalysisItemList() {
 
122
        // Returns pointer to the search analysis items
 
123
        return &m_canvasItemList;
 
124
}
 
125
 
 
126
/** Starts the analysis of the search result. This should be called only once because QCanvas handles the updates automatically. */
 
127
void CSearchAnalysis::analyse(ListCSwordModuleInfo modules) {
 
128
        /**
 
129
        * Steps of analysing our search result;
 
130
        * -Create the items for all available books ("Genesis" - "Revelation")
 
131
        * -Iterate through all modules we analyse
 
132
        *  -Go through all books of this module
 
133
        *   -Find out how many times we found the book
 
134
        *   -Set the count to the items which belongs to the book
 
135
        */
 
136
        setModules(modules);
 
137
 
 
138
        m_lastPosList.clear();
 
139
        const int numberOfModules = m_moduleList.count();
 
140
        if (!numberOfModules)
 
141
                return;
 
142
        m_legend = new CSearchAnalysisLegendItem(this, &m_moduleList);
 
143
        m_legend->setX(LEFT_BORDER);
 
144
        m_legend->setY(UPPER_BORDER);
 
145
        m_legend->setSize(LEGEND_WIDTH,
 
146
                                          LEGEND_INNER_BORDER*2 + ITEM_TEXT_SIZE*numberOfModules + LEGEND_DELTAY*(numberOfModules-1));
 
147
        m_legend->show();
 
148
 
 
149
        int xPos = LEFT_BORDER + m_legend->width() + SPACE_BETWEEN_PARTS;
 
150
        int moduleIndex = 0;
 
151
        m_maxCount = 0;
 
152
        int count = 0;
 
153
        CSwordVerseKey key(0);
 
154
        key.key("Genesis 1:1");
 
155
 
 
156
        CSearchAnalysisItem* analysisItem = m_canvasItemList[key.book()];
 
157
        bool ok = true;
 
158
        while (ok && analysisItem) {
 
159
                //   for (moduleIndex = 0,m_moduleList.first(); m_moduleList.current(); m_moduleList.next(),++moduleIndex) {
 
160
                moduleIndex = 0;
 
161
                ListCSwordModuleInfo::iterator end_it = m_moduleList.end();
 
162
                for (ListCSwordModuleInfo::iterator it(m_moduleList.begin()); it != end_it; ++it) {
 
163
                        KApplication::kApplication()->processEvents( 10 ); //10 ms only
 
164
                        if (!m_lastPosList.contains(*it)) {
 
165
                                m_lastPosList.insert(*it,0);
 
166
                        }
 
167
 
 
168
                        analysisItem->setCountForModule(moduleIndex, (count = getCount(key.book(), *it)));
 
169
                        m_maxCount = (count > m_maxCount) ? count : m_maxCount;
 
170
 
 
171
                        ++moduleIndex;
 
172
                }
 
173
                analysisItem->setX(xPos);
 
174
                analysisItem->setY(UPPER_BORDER);
 
175
                analysisItem->show();
 
176
 
 
177
                xPos += (int)analysisItem->width() + SPACE_BETWEEN_PARTS;
 
178
                ok = key.next(CSwordVerseKey::UseBook);
 
179
                analysisItem = m_canvasItemList[key.book()];
 
180
        }
 
181
        resize(xPos+BAR_WIDTH+(m_moduleList.count()-1)*BAR_DELTAX+RIGHT_BORDER, height() );
 
182
        slotResized();
 
183
}
 
184
 
 
185
/** Sets te module list used for the analysis. */
 
186
void CSearchAnalysis::setModules(ListCSwordModuleInfo modules) {
 
187
        m_moduleList.clear();
 
188
        //  for (modules.first(); modules.current(); modules.next()) {
 
189
        ListCSwordModuleInfo::iterator end_it = modules.end();
 
190
        for (ListCSwordModuleInfo::iterator it(modules.begin()); it != end_it; ++it) {
 
191
                if ( ((*it)->type() == CSwordModuleInfo::Bible) || ((*it)->type() == CSwordModuleInfo::Commentary) ) { //a Bible or an commentary
 
192
                        m_moduleList.append(*it);
 
193
                }
 
194
        }
 
195
 
 
196
        m_canvasItemList.clear();
 
197
        CSearchAnalysisItem* analysisItem = 0;
 
198
        CSwordVerseKey key(0);
 
199
        key.key("Genesis 1:1");
 
200
        do {
 
201
                analysisItem = new CSearchAnalysisItem(this, m_moduleList.count(), key.book(), &m_scaleFactor, &m_moduleList);
 
202
                analysisItem->hide();
 
203
                m_canvasItemList.insert(key.book(), analysisItem);
 
204
        }
 
205
        while (key.next(CSwordVerseKey::UseBook));
 
206
        update();
 
207
}
 
208
 
 
209
/** Sets back the items and deletes things to cleanup */
 
210
void CSearchAnalysis::reset() {
 
211
        m_scaleFactor = 0.0;
 
212
 
 
213
        QDictIterator<CSearchAnalysisItem> it( m_canvasItemList ); // iterator for items
 
214
        while ( it.current() ) {
 
215
                it.current()->hide();
 
216
                ++it;
 
217
        }
 
218
        m_lastPosList.clear();
 
219
 
 
220
        if (m_legend) {
 
221
                m_legend->hide();
 
222
        }
 
223
 
 
224
        delete m_legend;
 
225
        m_legend = 0;
 
226
 
 
227
        update();
 
228
}
 
229
 
 
230
/** No descriptions */
 
231
void CSearchAnalysis::slotResized() {
 
232
        m_scaleFactor = (double)( (double)(height()-UPPER_BORDER-LOWER_BORDER-BAR_LOWER_BORDER-(m_moduleList.count()-1)*BAR_DELTAY)
 
233
                                                          /(double)m_maxCount);
 
234
        QDictIterator<CSearchAnalysisItem> it( m_canvasItemList );
 
235
        while ( it.current() ) {
 
236
                it.current()->setSize(BAR_WIDTH + (m_moduleList.count()-1)*BAR_DELTAX, height()-UPPER_BORDER-LOWER_BORDER);
 
237
                it.current()->setY(UPPER_BORDER);
 
238
                ++it;
 
239
        }
 
240
        update();
 
241
}
 
242
 
 
243
/** This function returns a color for each module */
 
244
QColor CSearchAnalysis::getColor(int index) {
 
245
        switch (index) {
 
246
                case  0:
 
247
                return Qt::red;
 
248
                case  1:
 
249
                return Qt::darkGreen;
 
250
                case  2:
 
251
                return Qt::blue;
 
252
                case  3:
 
253
                return Qt::cyan;
 
254
                case  4:
 
255
                return Qt::magenta;
 
256
                case  5:
 
257
                return Qt::darkRed;
 
258
                case  6:
 
259
                return Qt::darkGray;
 
260
                case  7:
 
261
                return Qt::black;
 
262
                case  8:
 
263
                return Qt::darkCyan;
 
264
                case  9:
 
265
                return Qt::darkMagenta;
 
266
                default:
 
267
                return Qt::red;
 
268
        }
 
269
}
 
270
 
 
271
/** Returns the count of the book in the module */
 
272
const unsigned int CSearchAnalysis::getCount( const QString book, CSwordModuleInfo* module ) {
 
273
        sword::ListKey& result = module->searchResult();
 
274
        const int length = book.length();
 
275
        unsigned int i = m_lastPosList[module];
 
276
        unsigned int count = 0;
 
277
        const unsigned int resultCount = result.Count();
 
278
        while (i < resultCount) {
 
279
                if ( strncmp(book.utf8(), (const char*)*result.GetElement(i), length) )
 
280
                        break;
 
281
                i++;
 
282
                ++count;
 
283
        }
 
284
        m_lastPosList.contains(module) ? m_lastPosList.replace(module,i) : m_lastPosList.insert(module,i);
 
285
 
 
286
        return count;
 
287
}
 
288
 
 
289
 
 
290
//------------------------------------------------------------------
 
291
//------------------------------------------------------------------
 
292
 
 
293
CSearchAnalysisItem::CSearchAnalysisItem(QCanvas *parent, const int moduleCount, const QString &bookname, double *scaleFactor, ListCSwordModuleInfo* modules)
 
294
: QCanvasRectangle(parent),
 
295
m_moduleList( modules ),
 
296
m_scaleFactor(scaleFactor),
 
297
m_bookName(bookname),
 
298
m_moduleCount(moduleCount),
 
299
m_bufferPixmap(0) {
 
300
        m_resultCountArray.resize(m_moduleCount);
 
301
        int index = 0;
 
302
        for (index = 0; index < m_moduleCount; ++index)
 
303
                m_resultCountArray[index] = 0;
 
304
}
 
305
 
 
306
CSearchAnalysisItem::~CSearchAnalysisItem() {
 
307
        delete m_bufferPixmap;
 
308
}
 
309
 
 
310
/** Sets the resultcount of this item for the given module */
 
311
void CSearchAnalysisItem::setCountForModule( const int moduleIndex, const int count) {
 
312
        m_resultCountArray[moduleIndex] = count;
 
313
}
 
314
 
 
315
/** Returns the resultcount of this item for the given module */
 
316
int CSearchAnalysisItem::getCountForModule( const int moduleIndex) {
 
317
        return m_resultCountArray[moduleIndex];
 
318
}
 
319
 
 
320
/** Reimplementation. Draws the content of this item. */
 
321
void CSearchAnalysisItem::draw(QPainter& painter) {
 
322
        QFont f = painter.font();
 
323
        f.setPointSize(ITEM_TEXT_SIZE);
 
324
        painter.setFont(f);
 
325
 
 
326
        setPen(QPen(black,1));
 
327
        setBrush(Qt::red);
 
328
        /**
 
329
        * We have to paint so many bars as we have modules available (we use m_moduleCount)
 
330
        * We paint inside the area which is given by height and width of this rectangle item
 
331
        */
 
332
        int index = 0;
 
333
        int drawn = 0;
 
334
        int Value = 0;
 
335
 
 
336
        //find out the biggest value
 
337
        for (index=0;index < m_moduleCount; index++) {
 
338
                if (m_resultCountArray[index] > Value) {
 
339
                        Value = m_resultCountArray[index];
 
340
                }
 
341
        };
 
342
 
 
343
        while (drawn < m_moduleCount) {
 
344
                for (index = 0; index < m_moduleCount; index++) {
 
345
                        if (m_resultCountArray[index] == Value) {
 
346
                                QPoint p1((int)x() + (m_moduleCount-drawn-1)*BAR_DELTAX,
 
347
                                                  (int)height() + (int)y() - BAR_LOWER_BORDER - (m_moduleCount-drawn)*BAR_DELTAY);
 
348
                                QPoint p2(p1.x() + BAR_WIDTH,
 
349
                                                  p1.y() - (int)( !m_resultCountArray[index] ? 0 : ((m_resultCountArray[index])*(*m_scaleFactor))) );
 
350
                                QRect r(p1, p2);
 
351
                                painter.fillRect(r, QBrush(CSearchAnalysis::getColor(index)) );
 
352
                                painter.drawRect(r);
 
353
                                drawn++;
 
354
                        }
 
355
                }
 
356
                //finds the next smaller value
 
357
                int newValue = 0;
 
358
                for (index=0;index < m_moduleCount; index++)
 
359
                        if (m_resultCountArray[index] < Value && m_resultCountArray[index] >= newValue)
 
360
                                newValue = m_resultCountArray[index];
 
361
                Value = newValue;
 
362
        }
 
363
        if (!m_bufferPixmap) {
 
364
                m_bufferPixmap = new QPixmap();
 
365
                m_bufferPixmap->resize(width(),BAR_LOWER_BORDER);
 
366
                m_bufferPixmap->fill();
 
367
                QPainter p(m_bufferPixmap);
 
368
                f = p.font();
 
369
                f.setPointSize(ITEM_TEXT_SIZE);
 
370
                p.setFont(f);
 
371
                p.rotate(90);
 
372
                p.drawText(QPoint(5,0), m_bookName);
 
373
        }
 
374
        painter.drawPixmap(QPoint(int(x()),int(height()+y()-BAR_LOWER_BORDER)), *m_bufferPixmap);
 
375
}
 
376
 
 
377
/** Returns the width of this item. */
 
378
int CSearchAnalysisItem::width() {
 
379
        return m_moduleCount*(m_moduleCount>1 ? BAR_DELTAX : 0) + BAR_WIDTH;
 
380
}
 
381
 
 
382
/** Returns the tooltip for this item. */
 
383
const QString CSearchAnalysisItem::getToolTip() {
 
384
        QString ret = QString("<center><b>%1</b></center><hr/>").arg(m_bookName);
 
385
        ret += "<table cellspacing=\"0\" cellpadding=\"3\" width=\"100%\" height=\"100%\" align=\"center\">";
 
386
 
 
387
        //ToDo: Fix that loop
 
388
        int i = 0;
 
389
        ListCSwordModuleInfo::iterator end_it = m_moduleList->end();
 
390
 
 
391
        for (ListCSwordModuleInfo::iterator it(m_moduleList->begin()); it != end_it; ++it) {
 
392
                //  for (int i = 0; i < m_moduleCount; ++i) {
 
393
                CSwordModuleInfo* info = (*it);
 
394
                const QColor c = CSearchAnalysis::getColor(i);
 
395
 
 
396
                ret.append(
 
397
                        QString("<tr bgcolor=\"white\"><td><b><font color=\"#%1\">%2</font></b></td><td>%3 (%4%)</td></tr>")
 
398
                        .arg(QString().sprintf("%02X%02X%02X",c.red(),c.green(),c.blue()))
 
399
                        .arg(info ? info->name() : QString::null)
 
400
                        .arg( m_resultCountArray[i] )
 
401
                        .arg( (info && m_resultCountArray[i])? ((double)m_resultCountArray[i] / (double)info->searchResult().Count())*(double)100 : 0.0, 0, 'g', 2)
 
402
                );
 
403
                ++i;
 
404
        }
 
405
 
 
406
        ret += "</table>";
 
407
 
 
408
        return ret;
 
409
}
 
410
 
 
411
//------------------------------------------------------------------
 
412
//------------------------------------------------------------------
 
413
 
 
414
CSearchAnalysisView::CSearchAnalysisView(QCanvas* canvas, QWidget* parent)
 
415
: QCanvasView(canvas, parent) {
 
416
        setFocusPolicy(QWidget::WheelFocus);
 
417
        m_toolTip = new ToolTip(this);
 
418
        resize(sizeHint());
 
419
}
 
420
 
 
421
/** Returns the sizeHint for this view */
 
422
QSize CSearchAnalysisView::sizeHint() {
 
423
        if ( parentWidget() )
 
424
                return parentWidget()->sizeHint();
 
425
        return QCanvasView::sizeHint();
 
426
}
 
427
 
 
428
/** No descriptions */
 
429
void CSearchAnalysisView::resizeEvent( QResizeEvent* e) {
 
430
        QCanvasView::resizeEvent(e);
 
431
        canvas()->resize( canvas()->width(), viewport()->height() );
 
432
}
 
433
 
 
434
CSearchAnalysisView::ToolTip::ToolTip(QWidget* parent) : QToolTip(parent) {}
 
435
 
 
436
void CSearchAnalysisView::ToolTip::maybeTip(const QPoint& p) {
 
437
        CSearchAnalysisView* view = dynamic_cast<CSearchAnalysisView*>(parentWidget());
 
438
        if (!view)
 
439
                return;
 
440
        QPoint point(p);
 
441
        point = view->viewport()->mapFrom(view, point);
 
442
        CSearchAnalysisItem* i = view->itemAt( view->viewportToContents(point) );
 
443
        if (!i)
 
444
                return;
 
445
 
 
446
        //get type of item and display correct text
 
447
        QString text = i->getToolTip();
 
448
        if (text.isEmpty())
 
449
                return;
 
450
 
 
451
        QPoint p1 = view->viewport()->mapTo(view, view->contentsToViewport(i->rect().topLeft()));
 
452
        p1.setY(0);
 
453
        QPoint p2 = view->viewport()->mapTo(view, view->contentsToViewport(i->rect().bottomRight()));
 
454
        p2.setY(view->height());
 
455
        QRect r = QRect( p1, p2 );
 
456
        if (r.contains(p))
 
457
                tip(r, text);
 
458
}
 
459
 
 
460
 
 
461
/** Returns the item at position p. If there no item at that point return 0. */
 
462
CSearchAnalysisItem* CSearchAnalysisView::itemAt( const QPoint& p ) {
 
463
        QCanvasItemList l = canvas()->collisions(p);
 
464
        if (!l.count())
 
465
                return 0;
 
466
        return dynamic_cast<CSearchAnalysisItem*>(l.first());
 
467
}
 
468
 
 
469
//------------------------------------------------------------------
 
470
//------------------------------------------------------------------
 
471
 
 
472
CSearchAnalysisLegendItem::CSearchAnalysisLegendItem(QCanvas *parent, ListCSwordModuleInfo *list )
 
473
: QCanvasRectangle(parent) {
 
474
        m_moduleList = list;
 
475
}
 
476
 
 
477
/** Reimplementation. Draws the content of this item. */
 
478
void CSearchAnalysisLegendItem::draw (QPainter& painter) {
 
479
        painter.save();
 
480
 
 
481
        setPen( QPen(black,2) );
 
482
        setBrush( Qt::white );
 
483
        //the outer rectangle
 
484
        QPoint p1( (int)x(), (int)y() );
 
485
        QPoint p2( (int)x()+width(), (int)y() + height() );
 
486
        QRect r(p1, p2);
 
487
        r.normalize();
 
488
        painter.drawRect(r);
 
489
 
 
490
        QFont f = painter.font();
 
491
        f.setPointSize(ITEM_TEXT_SIZE);
 
492
        painter.setFont(f);
 
493
 
 
494
        //   for (unsigned int index=0; index < m_moduleList->count(); index++){
 
495
        int moduleIndex = 0;
 
496
        ListCSwordModuleInfo::iterator end_it = m_moduleList->end();
 
497
        for (ListCSwordModuleInfo::iterator it(m_moduleList->begin()); it != end_it; ++it) {
 
498
                // the module color indicators
 
499
                QPoint p1( (int)x() + LEGEND_INNER_BORDER, (int)y() + LEGEND_INNER_BORDER + moduleIndex*(LEGEND_DELTAY + ITEM_TEXT_SIZE) );
 
500
                QPoint p2(p1.x() + ITEM_TEXT_SIZE, p1.y() + ITEM_TEXT_SIZE);
 
501
                QRect r(p1,p2);
 
502
                painter.fillRect(r, QBrush(CSearchAnalysis::getColor(moduleIndex)) );
 
503
                r.normalize();
 
504
                painter.drawRect(r);
 
505
 
 
506
                QPoint p3( p2.x() + LEGEND_INNER_BORDER, p2.y() );
 
507
                painter.drawText(p3, (*it)->name() );
 
508
 
 
509
                ++moduleIndex;
 
510
        }
 
511
        painter.restore();
 
512
}
 
513
 
 
514
/** No descriptions */
 
515
void CSearchAnalysis::saveAsHTML() {
 
516
        const QString file = KFileDialog::getSaveFileName(QString::null,
 
517
                                                 QString("*.html | %1").arg(i18n("HTML files")),
 
518
                                                 0,
 
519
                                                 i18n("Save Search Analysis"));
 
520
        if (file.isNull()) {
 
521
                return;
 
522
        }
 
523
 
 
524
        int moduleIndex = 0;
 
525
        int count = 0;
 
526
        QString countStr = "";
 
527
        QString m_searchAnalysisHTML = "";
 
528
        QString tableTitle = "";
 
529
        QString tableTotals = "";
 
530
        QString VerseRange = "";
 
531
        const QString txtCSS = QString("<style type=\"text/css\">\ntd {border:1px solid black;}\nth {font-size: 130%; text-align:left; vertical-align:top;}\n</style>\n");
 
532
        const QString metaEncoding = QString("<META http-equiv=Content-Type content=\"text/html; charset=utf-8\">");
 
533
        CSwordVerseKey key(0);
 
534
        sword::ListKey searchResult;
 
535
 
 
536
        key.key("Genesis 1:1");
 
537
 
 
538
        CSearchAnalysisItem* analysisItem = m_canvasItemList.find( key.book() );
 
539
 
 
540
        QString text = "<html>\n<head>\n<title>" + i18n("BibleTime Search Analysis") + "</title>\n" + txtCSS + metaEncoding + "</head>\n<body>\n";
 
541
        text += "<table>\n<tr><th>" + i18n("Search text :") + "</th><th>" + CSearchDialog::getSearchDialog()->searchText() + "</th></tr>\n";
 
542
 
 
543
        tableTitle = "<tr><th align=\"left\">" + i18n("Book") + "</th>";
 
544
        tableTotals = "<tr><td align=\"left\">" + i18n("Total hits") + "</td>";
 
545
        //   for (moduleIndex = 0,m_moduleList.first(); m_moduleList.current(); m_moduleList.next(),++moduleIndex) {
 
546
        moduleIndex = 0;
 
547
        ListCSwordModuleInfo::iterator end_it = m_moduleList.end();
 
548
        for (ListCSwordModuleInfo::iterator it(m_moduleList.begin()); it != end_it; ++it) {
 
549
                tableTitle += QString("<th align=\"left\">") + (*it)->name() + QString("</th>");
 
550
                searchResult = (*it)->searchResult();
 
551
                countStr.setNum(searchResult.Count());
 
552
 
 
553
                tableTotals += QString("<td align=\"right\">") + countStr + QString("</td>");
 
554
                ++moduleIndex;
 
555
        }
 
556
        tableTitle += QString("</tr>\n");
 
557
        tableTotals += QString("</tr>\n");
 
558
 
 
559
        m_searchAnalysisHTML = "";
 
560
        bool ok = true;
 
561
        while (ok) {
 
562
                m_searchAnalysisHTML += QString("<tr><td>") + key.book() + QString("</td>");
 
563
                analysisItem = m_canvasItemList.find( key.book() );
 
564
 
 
565
                //    for (moduleIndex = 0, m_moduleList.first(); m_moduleList.current(); m_moduleList.next(), ++moduleIndex) {
 
566
                moduleIndex = 0;
 
567
                ListCSwordModuleInfo::iterator end_it = m_moduleList.end();
 
568
                for (ListCSwordModuleInfo::iterator it(m_moduleList.begin()); it != end_it; ++it) {
 
569
                        count = analysisItem->getCountForModule(moduleIndex);
 
570
                        countStr.setNum(count);
 
571
                        m_searchAnalysisHTML += QString("<td align=\"right\">") + countStr + QString("</td>");
 
572
 
 
573
                        ++moduleIndex;
 
574
                }
 
575
                m_searchAnalysisHTML += QString("</tr>\n");
 
576
                ok = key.next(CSwordVerseKey::UseBook);
 
577
        }
 
578
 
 
579
        text += QString("<table>\n") + tableTitle + tableTotals + m_searchAnalysisHTML + QString("</table>\n");
 
580
        text += QString("<center>") + i18n("Created by") + QString(" <a href=\"http://www.bibletime.info/\">BibleTime</a></center>");
 
581
        text += QString("</body></html>");
 
582
 
 
583
        CToolClass::savePlainFile(file, text, false, QTextStream::UnicodeUTF8);
 
584
}
 
585
 
 
586
        } //end of namespace Search::Analysis
 
587
} //end of namespace Search