Bibletime – a bible study tool
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

csearchanalysis.cpp 18KB

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