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-2026 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/btconnect.h"
30#include "../../util/tool.h"
31#include "cmoduleresultview.h"
32#include "csearchresultview.h"
33
34// Sword includes:
35#ifdef __GNUC__
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#endif
41#include <swmodule.h>
42#ifdef __GNUC__
43#pragma GCC diagnostic pop
44#endif
45
46
47namespace {
49 QStringLiteral("GUI/SearchDialog/SearchResultsArea/mainSplitterSizes");
51 QStringLiteral(
52 "GUI/SearchDialog/SearchResultsArea/resultSplitterSizes");
53} // anonymous namespace
54
55namespace Search {
56
58 : QWidget(parent)
59{
60 QVBoxLayout *mainLayout;
61 QWidget *resultListsWidget;
62 QVBoxLayout *resultListsWidgetLayout;
63
64 //Size is calculated from the font rather than set in pixels,
65 // maybe this is better in different kinds of displays?
66 auto const mWidth = util::tool::mWidth(*this, 1);
67 this->setMinimumSize(QSize(mWidth*40, mWidth*15));
68 mainLayout = new QVBoxLayout(this);
69 m_mainSplitter = new QSplitter(this);
70 m_mainSplitter->setOrientation(Qt::Horizontal);
71
72 resultListsWidget = new QWidget(m_mainSplitter);
73
74 resultListsWidgetLayout = new QVBoxLayout(resultListsWidget);
75 resultListsWidgetLayout->setContentsMargins(0, 0, 0, 0);
76
77 //Splitter for two result lists
78 m_resultListSplitter = new QSplitter(resultListsWidget);
79 m_resultListSplitter->setOrientation(Qt::Vertical);
82
93 resultListsWidgetLayout->addWidget(m_resultListSplitter);
94
95 m_mainSplitter->addWidget(resultListsWidget);
96
97 //Preview ("info") area
99 m_displayFrame->setFrameShape(QFrame::NoFrame);
100 m_displayFrame->setFrameShadow(QFrame::Plain);
101 m_mainSplitter->addWidget(m_displayFrame);
102
103 mainLayout->addWidget(m_mainSplitter);
104
105 m_contextMenu = new QMenu(this);
106 m_selectAllAction = new QAction(tr("Select all"), this);
107 m_selectAllAction->setShortcut(QKeySequence::SelectAll);
109
110 m_copyAction = new QAction(tr("Copy"));
111 m_copyAction->setShortcut(QKeySequence::Copy);
112 m_contextMenu->addAction(m_copyAction);
113
114 QVBoxLayout* frameLayout = new QVBoxLayout(m_displayFrame);
115 frameLayout->setContentsMargins(0, 0, 0, 0);
117 m_previewDisplay->setOpenLinks(false);
118 m_previewDisplay->setToolTip(tr("Text of the selected search result item"));
119 m_previewDisplay->setContextMenuPolicy(Qt::CustomContextMenu);
120 BT_CONNECT(m_selectAllAction, &QAction::triggered,
121 m_previewDisplay, &QTextBrowser::selectAll);
122 BT_CONNECT(m_copyAction, &QAction::triggered,
123 m_previewDisplay, &QTextBrowser::copy);
125 m_previewDisplay, &QTextBrowser::clear);
126 BT_CONNECT(m_previewDisplay, &QTextBrowser::customContextMenuRequested,
127 [this](QPoint const & loc)
128 { m_contextMenu->exec(m_previewDisplay->mapToGlobal(loc)); });
129 frameLayout->addWidget(m_previewDisplay);
130
132}
133
134void BtSearchResultArea::setSearchResult(QString searchedText,
136{
137 reset(); //clear current modules
138
139 m_searchedText = std::move(searchedText);
140 m_results = std::move(results);
141
142 // Populate listbox:
143 m_moduleListBox->setupTree(m_results, searchedText);
144
145 // Pre-select the first module in the list:
146 m_moduleListBox->setCurrentItem(m_moduleListBox->topLevelItem(0), 0);
147}
148
150 m_moduleListBox->clear();
151 m_resultListBox->clear();
152 clearPreview();
153}
154
156 m_previewDisplay->setText(
157 QStringLiteral("<html><head/><body></body></html>"));
158}
159
160void BtSearchResultArea::updatePreview(const QString& key) {
161 using namespace Rendering;
162
163 CSwordModuleInfo* module = m_moduleListBox->activeModule();
164 if ( module ) {
165 QString text;
166 CDisplayRendering render;
167
168 BtConstModuleList modules;
169 modules.append(module);
170
172
173 //for bibles render 5 context verses
174 if (module->type() == CSwordModuleInfo::Bible) {
175 CSwordVerseKey vk(module);
176 vk.setIntros(true);
177 vk.setKey(key);
178
179 // HACK: enable headings for VerseKeys:
180 static_cast<sword::VerseKey *>(module->swordModule().getKey())
181 ->setIntros(true);
182
183 //first go back and then go forward the keys to be in context
184 vk.previous();
185 vk.previous();
186
187 //include Headings in display, they are indexed and searched too
188 if (vk.verse() == 1) {
189 if (vk.chapter() == 1) {
190 vk.setChapter(0);
191 }
192 vk.setVerse(0);
193 }
194
195 auto const startKey = vk;
196
197 vk.setKey(key);
198
199 vk.next();
200 vk.next();
201
202 settings.keyRenderingFace = CTextRendering::KeyTreeItem::Settings::CompleteShort;
203 text = render.renderKeyRange(startKey, vk, modules, key, settings);
204 }
205 //for commentaries only one verse, but with heading
206 else if (module->type() == CSwordModuleInfo::Commentary) {
207 CSwordVerseKey vk(module);
208 vk.setIntros(true);
209 vk.setKey(key);
210
211 // HACK: enable headings for VerseKeys:
212 static_cast<sword::VerseKey *>(module->swordModule().getKey())
213 ->setIntros(true);
214
215 //include Headings in display, they are indexed and searched too
216 if (vk.verse() == 1) {
217 if (vk.chapter() == 1) {
218 vk.setChapter(0);
219 }
220 vk.setVerse(0);
221 }
222 auto const startKey = vk;
223
224 vk.setKey(key);
225
226 settings.keyRenderingFace = CTextRendering::KeyTreeItem::Settings::NoKey;
227 text = render.renderKeyRange(startKey, vk, modules, key, settings);
228 }
229 else {
230 text = render.renderSingleKey(key, modules, settings);
231 }
232
233 if (modules.count() > 0)
234 setBrowserFont(modules.at(0));
235
236 QString text2 =
238 text2.replace(QStringLiteral("#CHAPTERTITLE#"), QString());
239 text2.replace(QStringLiteral("#TEXT_ALIGN#"), QStringLiteral("left"));
240 text2 = ColorManager::replaceColors(text2);
241 m_previewDisplay->setText(text2);
242 m_previewDisplay->scrollToAnchor( CDisplayRendering::keyToHTMLAnchor(key) );
243 }
244}
245
247 if (module) {
248 auto const lang = module->language();
249 m_previewDisplay->setFont(btConfig().getFontForLanguage(*lang).second);
250 } else {
251 m_previewDisplay->setFont(btConfig().getDefaultFont());
252 }
253}
254
255/**
256* Load the settings from the resource file
257*/
259 QList<int> mainSplitterSizes = btConfig().value< QList<int> >(MainSplitterSizesKey, QList<int>());
260 if (mainSplitterSizes.count() > 0)
261 m_mainSplitter->setSizes(mainSplitterSizes);
262 else
263 {
264 int w = this->size().width();
265 int w2 = m_moduleListBox->sizeHint().width();
266 mainSplitterSizes << w2 << w - w2;
267 m_mainSplitter->setSizes(mainSplitterSizes);
268 }
269
270 QList<int> resultSplitterSizes = btConfig().value< QList<int> >(ResultSplitterSizesKey, QList<int>());
271 if (resultSplitterSizes.count() > 0)
272 m_resultListSplitter->setSizes(resultSplitterSizes);
273}
274
275/**
276* Save the settings to the resource file
277*/
279 btConfig().setValue(MainSplitterSizesKey, m_mainSplitter->sizes());
280 btConfig().setValue(ResultSplitterSizesKey, m_resultListSplitter->sizes());
281}
282
283} //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
T value(QString const &key, T const &defaultValue=T()) const
Returns the settings value for the given global key.
void setValue(QString const &key, T const &value)
Sets a value for a key.
A QTextBrowser subclass which adds the ability to start drags for references.
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
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:117