BibleTime
btmodelviewreaddisplay.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 "btmodelviewreaddisplay.h"
14 
15 #include <memory>
16 #include <QClipboard>
17 #include <QDebug>
18 #include <QDrag>
19 #include <QFileDialog>
20 #include <QGuiApplication>
21 #include <QHBoxLayout>
22 #include <QMenu>
23 #include <QQuickItem>
24 #include <QScrollBar>
25 #include <QString>
26 #include <QTimer>
27 #include <QToolBar>
28 #include "../../backend/keys/cswordkey.h"
29 #include "../../backend/drivers/cswordbiblemoduleinfo.h"
30 #include "../../backend/managers/cswordbackend.h"
31 #include "../../backend/managers/referencemanager.h"
32 #include "../../util/btassert.h"
33 #include "../../util/btconnect.h"
34 #include "../../util/tool.h"
35 #include "../bibletime.h"
36 #include "../btcopybyreferencesdialog.h"
37 #include "../BtMimeData.h"
38 #include "../cexportmanager.h"
39 #include "../displaywindow/cdisplaywindow.h"
40 #include "../keychooser/ckeychooser.h"
43 
44 
46  CDisplayWindow * const displayWindow,
47  QWidget * const parentWidget)
48  : QWidget(parentWidget)
49  , m_parentWindow(displayWindow)
50  , m_quickWidget(new BtQuickWidget(this))
51  , m_qmlInterface(m_quickWidget->qmlInterface())
52  , m_scrollBar(new QScrollBar(this))
53 {
54  auto * const layout = new QHBoxLayout(this);
55  layout->setContentsMargins(0, 0, 0, 0);
56 
57  m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView);
58  m_quickWidget->show();
60  [this](QString const & reference) { /// \todo Fix me
61  auto key(m_parentWindow->key());
62  key->setKey(reference);
63  m_parentWindow->lookupKey(reference);
64  });
65  layout->addWidget(m_quickWidget);
66 
67  m_scrollBar->setRange(-100,100);
68  m_scrollBar->setValue(0);
69  BT_CONNECT(m_scrollBar, &QScrollBar::sliderMoved,
71  BT_CONNECT(m_scrollBar, &QScrollBar::sliderPressed,
73  BT_CONNECT(m_scrollBar, &QScrollBar::sliderReleased,
75  layout->addWidget(m_scrollBar);
76 
78  [this](QString const & reference) {
79  auto * const key = m_parentWindow->key();
80  key->setKey(reference);
81  m_parentWindow->keyChooser()->updateKey(key);
83  });
85  [this](const QString& moduleName, const QString& keyName) {
86  auto & drag = *new QDrag(this);
87  auto mimedata =
88  std::make_unique<BTMimeData>(
89  BTMimeData::ItemList{{moduleName, keyName, {}}});
90  //add real Bible text from module/key
91  if (auto * const module =
92  CSwordBackend::instance().findModuleByName(moduleName))
93  {
94  drag.setPixmap(
95  module->moduleIcon().pixmap(
96  m_parentWindow->mainToolBar()->iconSize()));
97  std::unique_ptr<CSwordKey> key(module->createKey());
98  key->setKey(keyName);
99  // This works across applications:
100  mimedata->setText(key->strippedText());
101  }
102  drag.setMimeData(mimedata.release());
103  drag.exec(Qt::CopyAction, Qt::CopyAction);
104  });
109 
110  setLayout(layout);
111 }
112 
114 
115 void BtModelViewReadDisplay::setBibleReference(const QString& reference) {
116  m_parentWindow->setBibleReference(reference);
117 }
118 
120  int speed = 25 * (1 + std::abs(value/30));
121  int relative = value - m_scrollBarPosition;
122  m_quickWidget->scroll(relative * speed);
123  m_scrollBarPosition = value;
125 }
126 
128  m_scrollBarPosition = m_scrollBar->value();
129 }
130 
132  m_scrollBar->setValue(0);
134 }
135 
137 { QGuiApplication::clipboard()->setText(text(part)); }
138 
139 void BtModelViewReadDisplay::contextMenuEvent(QContextMenuEvent * event) {
140  auto const & activeLink = m_qmlInterface->activeLink();
143 
144  if (m_popup)
145  m_popup->exec(event->globalPos());
146 }
147 
149 { QGuiApplication::clipboard()->setText(qmlInterface()->getSelectedText()); }
150 
152  auto const & qml = *qmlInterface();
153  BtCopyByReferencesDialog dlg(qml.textModel(),
154  qml.selection(),
156  if (dlg.exec() != QDialog::Accepted)
157  return;
158 
159  auto const & result = dlg.result();
160  BT_ASSERT(result.module);
161  auto const & module = *result.module;
162  if (module.type() == CSwordModuleInfo::Bible
163  || module.type() == CSwordModuleInfo::Commentary)
164  {
165  qml.copyVerseRange(static_cast<CSwordVerseKey const &>(*result.key1),
166  static_cast<CSwordVerseKey const &>(*result.key2));
167  } else {
168  qml.copyRange(result.index1, result.index2);
169  }
170 }
171 
173  auto const filename =
174  QFileDialog::getSaveFileName(
175  nullptr,
176  QObject::tr("Save document ..."),
177  "",
178  QObject::tr("Text files") + " (*.txt);;"
179  + QObject::tr("All files") + " (*)");
180  if (!filename.isEmpty())
181  util::tool::savePlainFile(filename, text(part));
182 }
183 
185  DisplayOptions const & displayOptions,
186  FilterOptions const & filterOptions)
187 {
188  using CSBiMI = CSwordBibleModuleInfo;
189  CSwordKey* const key = m_parentWindow->key();
190  const CSwordModuleInfo *module = key->module();
191 
192  CExportManager mgr(false,
193  QString(),
196 
197  switch (type) {
198  case Document: {
199  if (module->type() == CSwordModuleInfo::Bible) {
200  CSwordVerseKey* vk = dynamic_cast<CSwordVerseKey*>(key);
201 
202  CSwordVerseKey startKey(*vk);
203  startKey.setVerse(1);
204 
205  CSwordVerseKey stopKey(*vk);
206 
207  const CSBiMI *bible = dynamic_cast<const CSBiMI*>(module);
208  if (bible) {
209  stopKey.setVerse(bible->verseCount(bible->bookNumber(startKey.bookName()), startKey.chapter()));
210  }
211 
212  mgr.printKey(module, startKey.key(), stopKey.key(), displayOptions, filterOptions);
213  }
214  else if (module->type() == CSwordModuleInfo::Lexicon || module->type() == CSwordModuleInfo::Commentary ) {
215  mgr.printKey(module, key->key(), key->key(), displayOptions, filterOptions);
216  }
217  else if (module->type() == CSwordModuleInfo::GenericBook) {
218  CSwordTreeKey* tree = dynamic_cast<CSwordTreeKey*>(key);
219 
220  CSwordTreeKey startKey(*tree);
221  // while (startKey.previousSibling()) { // go to first sibling on this level!
222  // }
223 
224  CSwordTreeKey stopKey(*tree);
225  // if (CSwordBookModuleInfo* book = dynamic_cast<CSwordBookModuleInfo*>(module)) {
226  // while ( stopKey.nextSibling() ) { //go to last displayed sibling!
227  // }
228  // }
229  mgr.printKey(module, startKey.key(), stopKey.key(), displayOptions, filterOptions);
230  }
231  break;
232  }
233 
234  case AnchorWithText: {
235  if (hasActiveAnchor()) {
236  mgr.printByHyperlink(m_activeAnchor, displayOptions, filterOptions );
237  }
238  break;
239  }
240 
241  default:
242  break;
243  }
244 }
245 
247  qmlInterface()->textModel()->reloadModules();
248 }
249 
250 QString
252  QString text;
253  switch (part) {
254  case Document: {
255  CSwordKey* const key = m_parentWindow->key();
256  const CSwordModuleInfo *module = key->module();
257  //This is never used for Bibles, so it is not implemented for
258  //them. If it should be, see CReadDisplay::print() for example
259  //code.
261  module->type() == CSwordModuleInfo::Commentary ||
262  module->type() == CSwordModuleInfo::GenericBook);
263  FilterOptions filterOptions;
264  CSwordBackend::instance().setFilterOptions(filterOptions);
265 
266  text = QStringLiteral("%1\n(%2, %3)")
267  .arg(key->strippedText(), key->key(), key->module()->name());
268  break;
269  }
270 
271  case AnchorOnly: {
272  if (auto const decodedLink =
274  return decodedLink->key;
275  return {};
276  }
277 
278  case AnchorTextOnly: {
279  auto const decodedLink(
281  if (decodedLink && decodedLink->module) {
282  std::unique_ptr<CSwordKey> key(decodedLink->module->createKey());
283  key->setKey(decodedLink->key);
284  return key->strippedText();
285  }
286  return {};
287  }
288 
289  case AnchorWithText: {
290  auto const decodedLink(
292  if (decodedLink && decodedLink->module) {
293  std::unique_ptr<CSwordKey> key(decodedLink->module->createKey());
294  key->setKey(decodedLink->key);
295 
296  FilterOptions filterOptions;
297  CSwordBackend::instance().setFilterOptions(filterOptions);
298 
299  return QStringLiteral("%1\n(%2, %3)")
300  .arg(key->strippedText(), key->key(), key->module()->name());
301  }
302  return {};
303  }
304  default:
305  break;
306  }
307  return QString();
308 
309 }
310 
312 
314  m_qmlInterface->textModel()->setDisplayOptions(displayOptions);
315 }
316 
317 void BtModelViewReadDisplay::setModules(const QStringList &modules) {
318  m_qmlInterface->setModules(modules);
319 }
320 
323 }
324 
326 
328  m_qmlInterface->setFilterOptions(filterOptions);
329 }
330 
333 }
334 
337 }
338 
340 
342 
343 void BtModelViewReadDisplay::highlightText(const QString& text, bool caseSensitive) {
344  m_qmlInterface->setHighlightWords(text, caseSensitive);
345 }
346 
347 void BtModelViewReadDisplay::findText(bool const backward)
348 { m_qmlInterface->findText(backward); }
349 
350 // Save the Lemma (Strongs number) attribute
351 void BtModelViewReadDisplay::setLemma(const QString& lemma) {
352  m_nodeInfo = lemma;
353 }
#define BT_ASSERT(...)
Definition: btassert.h:17
#define BT_CONNECT(...)
Definition: btconnect.h:20
QList< BookmarkItem > ItemList
Definition: BtMimeData.h:38
void colorThemeChanged()
static BibleTime * instance() noexcept
Definition: bibletime.h:143
void autoScrollStop()
Result const & result() const noexcept
BtQmlInterface * qmlInterface() const noexcept
void findText(bool const backward)
void highlightText(const QString &text, bool caseSensitive)
void copySelectedText()
Copies the currently selected text.
void scrollToKey(CSwordKey *key)
void setLemma(const QString &lemma)
void setModules(QStringList const &modules)
QString text(TextPart const part=Document)
void copyAsPlainText(TextPart const part)
void copyByReferences()
Copies the given text specified by asking user for first and last references.
void save(TextPart const part)
Saves the given text with the specified format into the applications clipboard.
BtQuickWidget *const m_quickWidget
BtQmlInterface *const m_qmlInterface
BtModelViewReadDisplay(CDisplayWindow *displayWindow, QWidget *parent=nullptr)
void setDisplayOptions(const DisplayOptions &displayOptions)
void print(TextPart const, DisplayOptions const &displayOptions, FilterOptions const &filterOptions)
void contextMenuEvent(QContextMenuEvent *event) final override
void setFilterOptions(FilterOptions filterOptions)
void setBibleReference(const QString &reference)
~BtModelViewReadDisplay() override
void scrollToSwordKey(CSwordKey *key)
QString getBibleUrlFromLink(const QString &url)
void dragOccuring(const QString &moduleName, const QString &keyName)
QVariant textModel
void setBibleReference(const QString &reference)
void updateReference(const QString &reference)
void setModules(const QStringList &modules)
void setHighlightWords(const QString &words, bool caseSensitivy)
void setFilterOptions(FilterOptions filterOptions)
QString const & activeLink() const noexcept
void findText(bool backward)
QString getLemmaFromLink(const QString &url)
void referenceDropped(const QString &reference)
void scroll(int pixels)
void updateReferenceText()
The base class for all display windows of BibleTime.
DisplayOptions const & displayOptions() const
CKeyChooser * keyChooser() const
QToolBar * mainToolBar() const noexcept
FilterOptions const & filterOptions() const
void lookupKey(QString const &key)
CSwordKey * key() const
void setBibleReference(const QString &reference)
bool printKey(CSwordKey const *const key, DisplayOptions const &displayOptions, FilterOptions const &filterOptions)
bool printByHyperlink(QString const &hyperlink, DisplayOptions const &displayOptions, FilterOptions const &filterOptions)
Prints a key using the hyperlink created by CReferenceManager.
static CSwordBackend & instance() noexcept
Definition: cswordbackend.h:98
void setFilterOptions(const FilterOptions &options)
Implementation for Sword Bibles.
QString strippedText()
Definition: cswordkey.cpp:118
CSwordModuleInfo const * module() const
Definition: cswordkey.h:68
virtual bool setKey(const QString &key)=0
virtual QString key() const =0
ModuleType type() const
QString const & name() const
CSwordKey implementation for Sword's TreeKey.
Definition: cswordtreekey.h:43
QString key() const final override
CSwordKey implementation for Sword's VerseKey.
QString bookName() const
QString key() const final override
int chapter() const
void setVerse(int v)
std::optional< DecodedHyperlink > decodeHyperlink(QString const &hyperlink)
bool savePlainFile(const QString &filename, void(&writer)(QTextStream &, void *), void *userPtr)
Definition: tool.cpp:35