BibleTime
btsearchresultarea.cpp
Go to the documentation of this file.
1 /*********
2 *
3 * In the name of the Father, and of the Son, and of the Holy Spirit.
4 *
5 * This file is part of BibleTime's source code, https://bibletime.info/
6 *
7 * Copyright 1999-2021 by the BibleTime developers.
8 * The BibleTime source code is licensed under the GNU General Public License
9 * version 2.0.
10 *
11 **********/
12 
13 #include "btsearchresultarea.h"
14 
15 #include <QApplication>
16 #include <QFrame>
17 #include <QMenu>
18 #include <QPushButton>
19 #include <QSize>
20 #include <QSplitter>
21 #include <QStringList>
22 #include <QVBoxLayout>
23 #include <QWidget>
24 #include "../../backend/config/btconfig.h"
25 #include "../../backend/drivers/cswordmoduleinfo.h"
26 #include "../../backend/managers/colormanager.h"
27 #include "../../backend/keys/cswordversekey.h"
28 #include "../../backend/rendering/cdisplayrendering.h"
29 #include "../../util/btassert.h"
30 #include "../../util/btconnect.h"
31 #include "../../util/tool.h"
32 #include "cmoduleresultview.h"
33 #include "csearchresultview.h"
34 
35 // Sword includes:
36 #pragma GCC diagnostic push
37 #pragma GCC diagnostic ignored "-Wextra-semi"
38 #pragma GCC diagnostic ignored "-Wsuggest-override"
39 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
40 #include <swmodule.h>
41 #pragma GCC diagnostic pop
42 
43 
44 namespace {
46  QStringLiteral("GUI/SearchDialog/SearchResultsArea/mainSplitterSizes");
48  QStringLiteral(
49  "GUI/SearchDialog/SearchResultsArea/resultSplitterSizes");
50 } // anonymous namespace
51 
52 namespace Search {
53 
55  : QWidget(parent)
56 {
57  QVBoxLayout *mainLayout;
58  QWidget *resultListsWidget;
59  QVBoxLayout *resultListsWidgetLayout;
60 
61  //Size is calculated from the font rather than set in pixels,
62  // maybe this is better in different kinds of displays?
63  auto const mWidth = util::tool::mWidth(*this, 1);
64  this->setMinimumSize(QSize(mWidth*40, mWidth*15));
65  mainLayout = new QVBoxLayout(this);
66  m_mainSplitter = new QSplitter(this);
67  m_mainSplitter->setOrientation(Qt::Horizontal);
68 
69  resultListsWidget = new QWidget(m_mainSplitter);
70 
71  resultListsWidgetLayout = new QVBoxLayout(resultListsWidget);
72  resultListsWidgetLayout->setContentsMargins(0, 0, 0, 0);
73 
74  //Splitter for two result lists
75  m_resultListSplitter = new QSplitter(resultListsWidget);
76  m_resultListSplitter->setOrientation(Qt::Vertical);
79 
90  resultListsWidgetLayout->addWidget(m_resultListSplitter);
91 
92  m_mainSplitter->addWidget(resultListsWidget);
93 
94  //Preview ("info") area
96  m_displayFrame->setFrameShape(QFrame::NoFrame);
97  m_displayFrame->setFrameShadow(QFrame::Plain);
98  m_mainSplitter->addWidget(m_displayFrame);
99 
100  mainLayout->addWidget(m_mainSplitter);
101 
102  m_contextMenu = new QMenu(this);
103  m_selectAllAction = new QAction(tr("Select all"), this);
104  m_selectAllAction->setShortcut(QKeySequence::SelectAll);
105  m_contextMenu->addAction(m_selectAllAction);
106 
107  m_copyAction = new QAction(tr("Copy"));
108  m_copyAction->setShortcut(QKeySequence::Copy);
109  m_contextMenu->addAction(m_copyAction);
110 
111  QVBoxLayout* frameLayout = new QVBoxLayout(m_displayFrame);
112  frameLayout->setContentsMargins(0, 0, 0, 0);
113  m_previewDisplay = new BtTextBrowser(this);
114  m_previewDisplay->setOpenLinks(false);
115  m_previewDisplay->setToolTip(tr("Text of the selected search result item"));
116  m_previewDisplay->setContextMenuPolicy(Qt::CustomContextMenu);
117  BT_CONNECT(m_selectAllAction, &QAction::triggered,
118  m_previewDisplay, &QTextBrowser::selectAll);
119  BT_CONNECT(m_copyAction, &QAction::triggered,
120  m_previewDisplay, &QTextBrowser::copy);
122  m_previewDisplay, &QTextBrowser::clear);
123  BT_CONNECT(m_previewDisplay, &QTextBrowser::customContextMenuRequested,
124  [this](QPoint const & loc) { m_contextMenu->exec(loc); });
125  frameLayout->addWidget(m_previewDisplay);
126 
128 }
129 
130 void BtSearchResultArea::setSearchResult(QString searchedText,
132 {
133  reset(); //clear current modules
134 
135  m_searchedText = std::move(searchedText);
136  m_results = std::move(results);
137 
138  // Populate listbox:
139  m_moduleListBox->setupTree(m_results, searchedText);
140 
141  // Pre-select the first module in the list:
142  m_moduleListBox->setCurrentItem(m_moduleListBox->topLevelItem(0), 0);
143 }
144 
146  m_moduleListBox->clear();
147  m_resultListBox->clear();
148  clearPreview();
149 }
150 
152  m_previewDisplay->setText(
153  QStringLiteral("<html><head/><body></body></html>"));
154 }
155 
156 void BtSearchResultArea::updatePreview(const QString& key) {
157  using namespace Rendering;
158 
160  if ( module ) {
161  QString text;
162  CDisplayRendering render;
163 
164  BtConstModuleList modules;
165  modules.append(module);
166 
168 
169  //for bibles render 5 context verses
170  if (module->type() == CSwordModuleInfo::Bible) {
171  CSwordVerseKey vk(module);
172  vk.setIntros(true);
173  vk.setKey(key);
174 
175  // HACK: enable headings for VerseKeys:
176  static_cast<sword::VerseKey *>(module->swordModule().getKey())
177  ->setIntros(true);
178 
179  //first go back and then go forward the keys to be in context
180  vk.previous();
181  vk.previous();
182 
183  //include Headings in display, they are indexed and searched too
184  if (vk.verse() == 1) {
185  if (vk.chapter() == 1) {
186  vk.setChapter(0);
187  }
188  vk.setVerse(0);
189  }
190 
191  auto const startKey = vk;
192 
193  vk.setKey(key);
194 
195  vk.next();
196  vk.next();
197 
198  settings.keyRenderingFace = CTextRendering::KeyTreeItem::Settings::CompleteShort;
199  text = render.renderKeyRange(startKey, vk, modules, key, settings);
200  }
201  //for commentaries only one verse, but with heading
202  else if (module->type() == CSwordModuleInfo::Commentary) {
203  CSwordVerseKey vk(module);
204  vk.setIntros(true);
205  vk.setKey(key);
206 
207  // HACK: enable headings for VerseKeys:
208  static_cast<sword::VerseKey *>(module->swordModule().getKey())
209  ->setIntros(true);
210 
211  //include Headings in display, they are indexed and searched too
212  if (vk.verse() == 1) {
213  if (vk.chapter() == 1) {
214  vk.setChapter(0);
215  }
216  vk.setVerse(0);
217  }
218  auto const startKey = vk;
219 
220  vk.setKey(key);
221 
222  settings.keyRenderingFace = CTextRendering::KeyTreeItem::Settings::NoKey;
223  text = render.renderKeyRange(startKey, vk, modules, key, settings);
224  }
225  else {
226  text = render.renderSingleKey(key, modules, settings);
227  }
228 
229  if (modules.count() > 0)
230  setBrowserFont(modules.at(0));
231 
232  QString text2 =
234  text2.replace(QStringLiteral("#CHAPTERTITLE#"), QString());
235  text2.replace(QStringLiteral("#TEXT_ALIGN#"), QStringLiteral("left"));
236  text2 = ColorManager::replaceColors(text2);
237  m_previewDisplay->setText(text2);
238  m_previewDisplay->scrollToAnchor( CDisplayRendering::keyToHTMLAnchor(key) );
239  }
240 }
241 
243  if (module) {
244  auto const lang = module->language();
245  m_previewDisplay->setFont(btConfig().getFontForLanguage(*lang).second);
246  } else {
247  m_previewDisplay->setFont(btConfig().getDefaultFont());
248  }
249 }
250 
251 /**
252 * Load the settings from the resource file
253 */
255  QList<int> mainSplitterSizes = btConfig().value< QList<int> >(MainSplitterSizesKey, QList<int>());
256  if (mainSplitterSizes.count() > 0)
257  m_mainSplitter->setSizes(mainSplitterSizes);
258  else
259  {
260  int w = this->size().width();
261  int w2 = m_moduleListBox->sizeHint().width();
262  mainSplitterSizes << w2 << w - w2;
263  m_mainSplitter->setSizes(mainSplitterSizes);
264  }
265 
266  QList<int> resultSplitterSizes = btConfig().value< QList<int> >(ResultSplitterSizesKey, QList<int>());
267  if (resultSplitterSizes.count() > 0)
268  m_resultListSplitter->setSizes(resultSplitterSizes);
269 }
270 
271 /**
272 * Save the settings to the resource file
273 */
277 }
278 
279 } //namespace Search
BtConfig & btConfig()
This is a shortchand for BtConfig::getInstance().
Definition: btconfig.h:305
#define BT_CONNECT(...)
Definition: btconnect.h:20
QList< CSwordModuleInfo const * > BtConstModuleList
Definition: btmodulelist.h:21
T value(QString const &key, T const &defaultValue=T()) const
Returns the settings value for the given global key.
Definition: btconfigcore.h:50
void setValue(QString const &key, T const &value)
Sets a value for a key.
Definition: btconfigcore.h:73
A QTextBrowser subclass which adds the ability to start drags for references.
Definition: bttextbrowser.h:24
std::shared_ptr< Language const > language() const
ModuleType type() const
sword::SWModule & swordModule() const
CSwordKey implementation for Sword's VerseKey.
void setChapter(int v)
void setIntros(bool v)
bool next(const JumpType type=JumpType::UseVerse)
bool previous(const JumpType type=JumpType::UseVerse)
bool setKey(const QString &key) final override
int verse() const
int chapter() const
void setVerse(int v)
Rendering for the html display widget.
QString renderSingleKey(const QString &key, const BtConstModuleList &modules, const KeyTreeItem::Settings &settings=KeyTreeItem::Settings())
QString renderKeyRange(CSwordVerseKey const &lowerBound, CSwordVerseKey const &upperBound, const BtConstModuleList &modules, const QString &hightlightKey=QString(), const KeyTreeItem::Settings &settings=KeyTreeItem::Settings())
CSearchResultView * m_resultListBox
BtSearchResultArea(QWidget *parent=nullptr)
CModuleResultView * m_moduleListBox
void updatePreview(const QString &key)
void setBrowserFont(const CSwordModuleInfo *const module)
void setSearchResult(QString searchedText, CSwordModuleSearch::Results results)
CSwordModuleSearch::Results m_results
CSwordModuleInfo * activeModule()
QSize sizeHint() const override
void strongsSelected(CSwordModuleInfo *, const QStringList &)
void setupTree(const CSwordModuleSearch::Results &results, const QString &searchedText)
void moduleSelected(CSwordModuleInfo const *, CSwordModuleSearch::ModuleResultList const &)
void setupStrongsTree(CSwordModuleInfo *, const QStringList &)
void keySelected(const QString &)
void setupTree(CSwordModuleInfo const *m, CSwordModuleSearch::ModuleResultList const &results)
QString highlightSearchedText(QString const &content, QString const &searchedText, bool plainSearchedText)
std::vector< ModuleSearchResult > Results
QString replaceColors(QString content)
int mWidth(QWidget const &widget, int const mCount)
Calculates a maximum rendered text width for a widget and a string with the a given length.
Definition: tool.cpp:155