summaryrefslogtreecommitdiff
path: root/src/frontend/searchdialog/btsearchresultarea.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/searchdialog/btsearchresultarea.cpp')
-rw-r--r--src/frontend/searchdialog/btsearchresultarea.cpp332
1 files changed, 26 insertions, 306 deletions
diff --git a/src/frontend/searchdialog/btsearchresultarea.cpp b/src/frontend/searchdialog/btsearchresultarea.cpp
index 262ff23..6a82a4f 100644
--- a/src/frontend/searchdialog/btsearchresultarea.cpp
+++ b/src/frontend/searchdialog/btsearchresultarea.cpp
@@ -2,7 +2,7 @@
*
* This file is part of BibleTime's source code, http://www.bibletime.info/.
*
-* Copyright 1999-2011 by the BibleTime developers.
+* Copyright 1999-2014 by the BibleTime developers.
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
*
**********/
@@ -10,7 +10,6 @@
#include "frontend/searchdialog/btsearchresultarea.h"
#include <QApplication>
-#include <QDebug>
#include <QFrame>
#include <QMenu>
#include <QProgressDialog>
@@ -22,13 +21,19 @@
#include <QWidget>
#include "backend/keys/cswordversekey.h"
#include "backend/rendering/cdisplayrendering.h"
-#include "frontend/display/cdisplay.h"
+#include "backend/config/btconfig.h"
+#include "frontend/display/bthtmlreaddisplay.h"
#include "frontend/searchdialog/cmoduleresultview.h"
#include "frontend/searchdialog/csearchdialog.h"
#include "frontend/searchdialog/csearchresultview.h"
#include "util/tool.h"
+namespace {
+const QString MainSplitterSizesKey = "GUI/SearchDialog/SearchResultsArea/mainSplitterSizes";
+const QString ResultSplitterSizesKey = "GUI/SearchDialog/SearchResultsArea/resultSplitterSizes";
+} // anonymous namespace
+
namespace Search {
BtSearchResultArea::BtSearchResultArea(QWidget *parent)
@@ -76,7 +81,7 @@ void BtSearchResultArea::initView() {
QVBoxLayout* frameLayout = new QVBoxLayout(m_displayFrame);
frameLayout->setContentsMargins(0, 0, 0, 0);
- m_previewDisplay = CDisplay::createReadInstance(0, m_displayFrame);
+ m_previewDisplay = new BtHtmlReadDisplay(0, m_displayFrame);
m_previewDisplay->view()->setToolTip(tr("Text of the selected search result item"));
frameLayout->addWidget(m_previewDisplay->view());
@@ -143,10 +148,10 @@ void BtSearchResultArea::updatePreview(const QString& key) {
//for bibles render 5 context verses
if (module->type() == CSwordModuleInfo::Bible) {
CSwordVerseKey vk(module);
- vk.Headings(1);
+ vk.setIntros(true);
vk.setKey(key);
- ((sword::VerseKey*)(module->module()->getKey()))->Headings(1); //HACK: enable headings for VerseKeys
+ ((sword::VerseKey*)(module->module()->getKey()))->setIntros(true); //HACK: enable headings for VerseKeys
//first go back and then go forward the keys to be in context
vk.previous(CSwordVerseKey::UseVerse);
@@ -174,10 +179,10 @@ void BtSearchResultArea::updatePreview(const QString& key) {
//for commentaries only one verse, but with heading
else if (module->type() == CSwordModuleInfo::Commentary) {
CSwordVerseKey vk(module);
- vk.Headings(1);
+ vk.setIntros(true);
vk.setKey(key);
- ((sword::VerseKey*)(module->module()->getKey()))->Headings(1); //HACK: enable headings for VerseKeys
+ ((sword::VerseKey*)(module->module()->getKey()))->setIntros(true); //HACK: enable headings for VerseKeys
//include Headings in display, they are indexed and searched too
if (vk.getVerse() == 1) {
@@ -198,295 +203,11 @@ void BtSearchResultArea::updatePreview(const QString& key) {
text = render.renderSingleKey(key, modules, settings);
}
- m_previewDisplay->setText( highlightSearchedText(text, searchedText) );
+ m_previewDisplay->setText( CSwordModuleSearch::highlightSearchedText(text, searchedText) );
m_previewDisplay->moveToAnchor( CDisplayRendering::keyToHTMLAnchor(key) );
}
}
-QStringList BtSearchResultArea::queryParser(const QString& queryString) {
- QString token;
- QStringList tokenList;
- int cnt, pos;
-
- token = "";
- cnt = 0;
- while (cnt < queryString.length()) {
- // add to token
- if ((queryString[cnt]).isLetterOrNumber() || (queryString[cnt] == '*')) {
- token = token + queryString[cnt];
- cnt++;
- }
- else if ((queryString[cnt]).isLetterOrNumber() || (queryString[cnt] == '?')) {
- token = token + queryString[cnt];
- cnt++;
- }
- // token break
- else if (queryString[cnt] == ' ') {
- token = token.simplified();
- if ((token != "*") && (token != ""))
- tokenList.append(token);
- token = "";
- cnt++;
- }
- // clucene appears to ignore quoted strings in the sence
- // that it treats all the words within quoted strings as
- // regular tokens and not as a single token.
- else if (queryString[cnt] == '"') {
- cnt++;
- }
- // wild card - treat as a special token break
- //else if (queryString[cnt] == '*') {
- // token = token + queryString[cnt];
- // token = token.simplified();
- // if ((token != "*") && (token != ""))
- // tokenList.append(token);
- // // start next token with wildcard (kin*m -> kin* *m)
- // token = "*";
- // cnt++;
- //}
- // the ! token is also a token break
- else if (queryString[cnt] == '!') {
- // store away current token
- token = token.simplified();
- if ((token != "*") && (token != ""))
- tokenList.append(token);
- // add the ! token
- tokenList.append("!");
- token = "";
- cnt++;
- }
- // the - token is also a token break
- else if (queryString[cnt] == '-') {
- // store away current token
- token = token.simplified();
- if ((token != "*") && (token != ""))
- tokenList.append(token);
- // add the ! token
- tokenList.append("-");
- token = "";
- cnt++;
- }
- // the + token is also a token break
- else if (queryString[cnt] == '+') {
- // store away current token
- token = token.simplified();
- if ((token != "*") && (token != ""))
- tokenList.append(token);
- // add the + token
- tokenList.append("+");
- token = "";
- cnt++;
- }
- // the || token is also a token break
- else if ((queryString[cnt] == '|') && (queryString[cnt+1] == '|')) {
- // store away current token
- token = token.simplified();
- if ((token != "*") && (token != ""))
- tokenList.append(token);
- // add the || token
- tokenList.append("||");
- token = "";
- cnt += 2;
- }
- // the && token is also a token break
- else if ((queryString[cnt] == '&') && (queryString[cnt+1] == '&')) {
- // store away current token
- token = token.simplified();
- if ((token != "*") && (token != ""))
- tokenList.append(token);
- // add the || token
- tokenList.append("&&");
- token = "";
- cnt += 2;
- }
- else cnt++;
- }
- token = token.simplified();
- if ((token != "*") && (token != ""))
- tokenList.append(token);
-
- cnt = 0;
- QStringList::iterator it;
- for ( it = tokenList.begin(); it != tokenList.end(); it++ ) {
- //-----------------------------------------------------------
- // remove all the NOT(!) tokens - these do not need to be
- // highlighted in the highlighter
- //-----------------------------------------------------------
- if (((*it) == "!") || ((*it) == "NOT") || ((*it) == "-")) {
- it = tokenList.erase(it);
- if (it == tokenList.end())
- break;
- it = tokenList.erase(it);
- if (it == tokenList.end())
- break;
- it--;
- }
- //-----------------------------------------------------------
- // remove all the operator tokens - these do not need to be
- // highlighted in the highlighter
- //-----------------------------------------------------------
- else if ( ((*it) == "||") || ((*it) == "OR") || ((*it) == "+") ||
- ((*it) == "AND") || ((*it) == "&&") ) {
- it = tokenList.erase(it);
- if (it == tokenList.end())
- break;
- it--;
- }
- // if the token contains a ^ then trim the remainder of the
- // token from the ^
- //What??? error: invalid conversion from ‘const void*’ to ‘int’
- // and how come "contains" returns bool but is used as int?
- //else if ( (pos = (*it).contains("^")) >= 0 ) {
- else if ( (pos = (*it).indexOf("^") ) >= 0 ) {
- (*it) = (*it).left(pos - 1);
- }
- // if the token contains a ~ then trim the remainder of the
- // token from the ~
- else if ( (pos = (*it).indexOf("~") ) >= 0 ) {
- (*it) = (*it).left(pos - 2) + "*";
- }
- }
- return(tokenList);
-}
-
-QString BtSearchResultArea::highlightSearchedText(const QString& content, const QString& searchedText) {
- QString ret = content;
-
- const Qt::CaseSensitivity cs = Qt::CaseInsensitive;
-
- // int index = 0;
- int index = ret.indexOf("<body", 0);
- int matchLen = 0;
- int length = searchedText.length();
-
- // Highlighting constants -
- // \todo We need to make the highlight color configurable.
- const QString rep1("<span style=\"background-color:#FFFF66;\">");
- const QString rep2("</span>");
- const unsigned int repLength = rep1.length() + rep1.length();
- const QString rep3("style=\"background-color:#FFFF66;\" ");
- const unsigned int rep3Length = rep3.length();
-
-
- QString newSearchText;
-
- newSearchText = searchedText;
-
- // find the strongs search lemma and highlight it
- // search the searched text for "strong:" until it is not found anymore
- QStringList list;
-
- // split the search string - some possibilities are "\\s|\\|", "\\s|\\+", or "\\s|\\|\\+"
- // \todo find all possible seperators
- QString regExp = "\\s";
- list = searchedText.split(QRegExp(regExp));
- foreach (QString newSearchText, list) {
- int sstIndex; // strong search text index for finding "strong:"
- int idx1, idx2;
- QString sNumber, lemmaText;
-
- sstIndex = newSearchText.indexOf("strong:");
- if (sstIndex == -1)
- continue;
-
- // set the start index to the start of <body>
- int strongIndex = index;
-
- // Get the strongs number from the search text.
- // First, find the first space after "strong:"
- sstIndex = sstIndex + 7;
- // get the strongs number -> the text following "strong:" to the end of the string.
- sNumber = newSearchText.mid(sstIndex, -1);
- // find all the "lemma=" inside the the content
- while ((strongIndex = ret.indexOf("lemma=", strongIndex, cs)) != -1) {
- // get the strongs number after the lemma and compare it with the
- // strongs number we are looking for
- idx1 = ret.indexOf("\"", strongIndex) + 1;
- idx2 = ret.indexOf("\"", idx1 + 1);
- lemmaText = ret.mid(idx1, idx2 - idx1);
-
- // this is interesting because we could have a strongs number like: G3218|G300
- // To handle this we will use some extra cpu cycles and do a partial match against
- // the lemmaText
- if (lemmaText.contains(sNumber)) {
- // strongs number is found now we need to highlight it
- // I believe the easiest way is to insert rep3 just before "lemma="
- ret = ret.insert(strongIndex, rep3);
- strongIndex += rep3Length;
- }
- strongIndex += 6; // 6 is the length of "lemma="
- }
- }
- //---------------------------------------------------------------------
- // now that the strong: stuff is out of the way continue with
- // other search options
- //---------------------------------------------------------------------
-
- // try to figure out how to use the lucene query parser
-
- //using namespace lucene::queryParser;
- //using namespace lucene::search;
- //using namespace lucene::analysis;
- //using namespace lucene::util;
-
- //wchar_t *buf;
- //char buf8[1000];
- //standard::WhitespaceAnalyzer analyzer;
- //lucene_utf8towcs(m_wcharBuffer, searchedText.utf8(), MAX_CONV_SIZE);
- //QSharedPointer<Query> q( QueryParser::parse(m_wcharBuffer, _T("content"), &analyzer) );
- //StringReader reader(m_wcharBuffer);
- //TokenStream* tokenStream = analyzer.tokenStream( _T("field"), &reader);
- //Token token;
- //while(tokenStream->next(&token) != 0) {
- // lucene_wcstoutf8(buf8, token.termText(), 1000);
- // printf("%s\n", buf8);
- //}
-
- //===========================================================
- // since I could not figure out the lucene query parser, I
- // made a simple parser.
- //===========================================================
- QStringList words = queryParser(newSearchText);
- qDebug() << "btsearchresultarea.cpp: " << __LINE__ << ": " << words << '\n';
- foreach (QString word, words) { //search for every word in the list
- QRegExp findExp;
- if (word.contains("*")) {
- length = word.length() - 1;
- word.replace('*', "\\S*"); //match within a word
- findExp = QRegExp(word);
- findExp.setMinimal(true);
- }
- else if (word.contains("?")) {
- length = word.length() - 1;
- word.replace('?', "\\S?"); //match within a word
- findExp = QRegExp(word);
- findExp.setMinimal(true);
- }
- else {
- length = word.length();
- findExp = QRegExp("\\b" + word + "\\b");
- }
-
- // index = 0; //for every word start at the beginning
- index = ret.indexOf("<body", 0);
- findExp.setCaseSensitivity(cs);
- //while ( (index = ret.find(findExp, index)) != -1 ) { //while we found the word
- while ( (index = findExp.indexIn(ret, index)) != -1 ) { //while we found the word
- matchLen = findExp.matchedLength();
- if (!util::tool::inHTMLTag(index, ret)) {
- length = matchLen;
- ret = ret.insert( index + length, rep2 );
- ret = ret.insert( index, rep1 );
- index += repLength;
- }
- index += length;
- }
- }
- qDebug() << "btsearchresultarea.cpp: " << __LINE__ << ": " << words << '\n';
- //qWarning("\n\n\n%s", ret.latin1());
- return ret;
-}
-
/** Initializes the signal slot conections of the child widgets, */
void BtSearchResultArea::initConnections() {
connect(m_resultListBox, SIGNAL(keySelected(const QString&)), this, SLOT(updatePreview(const QString&)));
@@ -506,26 +227,28 @@ void BtSearchResultArea::initConnections() {
* Load the settings from the resource file
*/
void BtSearchResultArea::loadDialogSettings() {
- QList<int> mainSplitterSizes = CBTConfig::get(CBTConfig::searchMainSplitterSizes);
- if (mainSplitterSizes.count() > 0) {
+ QList<int> mainSplitterSizes = btConfig().value< QList<int> >(MainSplitterSizesKey, QList<int>());
+ if (mainSplitterSizes.count() > 0)
m_mainSplitter->setSizes(mainSplitterSizes);
- }
- else {
+ else
+ {
int w = this->size().width();
int w2 = m_moduleListBox->sizeHint().width();
mainSplitterSizes << w2 << w - w2;
m_mainSplitter->setSizes(mainSplitterSizes);
}
- QList<int> resultSplitterSizes = CBTConfig::get(CBTConfig::searchResultSplitterSizes);
- if (resultSplitterSizes.count() > 0) m_resultListSplitter->setSizes(resultSplitterSizes);
+
+ QList<int> resultSplitterSizes = btConfig().value< QList<int> >(ResultSplitterSizesKey, QList<int>());
+ if (resultSplitterSizes.count() > 0)
+ m_resultListSplitter->setSizes(resultSplitterSizes);
}
/**
* Save the settings to the resource file
*/
void BtSearchResultArea::saveDialogSettings() const {
- CBTConfig::set(CBTConfig::searchMainSplitterSizes, m_mainSplitter->sizes());
- CBTConfig::set(CBTConfig::searchResultSplitterSizes, m_resultListSplitter->sizes());
+ btConfig().setValue(MainSplitterSizesKey, m_mainSplitter->sizes());
+ btConfig().setValue(ResultSplitterSizesKey, m_resultListSplitter->sizes());
}
/******************************************************************************
@@ -533,15 +256,12 @@ void BtSearchResultArea::saveDialogSettings() const {
******************************************************************************/
StrongsResultList::StrongsResultList(const CSwordModuleInfo *module,
- const sword::ListKey &results,
+ const sword::ListKey & result,
const QString &strongsNumber)
{
using namespace Rendering;
- /// \warning This is a workaround for Sword constness
- sword::ListKey result = results;
-
- int count = result.Count();
+ int count = result.getCount();
if (!count)
return;