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  });
107 
108  setLayout(layout);
109 }
110 
112 
113 void BtModelViewReadDisplay::setBibleReference(const QString& reference) {
114  m_parentWindow->setBibleReference(reference);
115 }
116 
118  int speed = 25 * (1 + std::abs(value/30));
119  int relative = value - m_scrollBarPosition;
120  m_quickWidget->scroll(relative * speed);
121  m_scrollBarPosition = value;
123 }
124 
126  m_scrollBarPosition = m_scrollBar->value();
127 }
128 
130  m_scrollBar->setValue(0);
132 }
133 
135 { QGuiApplication::clipboard()->setText(text(part)); }
136 
137 void BtModelViewReadDisplay::contextMenuEvent(QContextMenuEvent * event) {
138  auto const & activeLink = m_qmlInterface->activeLink();
141 
142  if (m_popup)
143  m_popup->exec(event->globalPos());
144 }
145 
147 { QGuiApplication::clipboard()->setText(qmlInterface()->getSelectedText()); }
148 
150  auto const & qml = *qmlInterface();
151  BtCopyByReferencesDialog dlg(qml.textModel(),
152  qml.selection(),
154  if (dlg.exec() != QDialog::Accepted)
155  return;
156 
157  auto const & result = dlg.result();
158  BT_ASSERT(result.module);
159  auto const & module = *result.module;
160  if (module.type() == CSwordModuleInfo::Bible
161  || module.type() == CSwordModuleInfo::Commentary)
162  {
163  qml.copyVerseRange(static_cast<CSwordVerseKey const &>(*result.key1),
164  static_cast<CSwordVerseKey const &>(*result.key2));
165  } else {
166  qml.copyRange(result.index1, result.index2);
167  }
168 }
169 
171  auto const filename =
172  QFileDialog::getSaveFileName(
173  nullptr,
174  QObject::tr("Save document ..."),
175  "",
176  QObject::tr("Text files") + " (*.txt);;"
177  + QObject::tr("All files") + " (*)");
178  if (!filename.isEmpty())
179  util::tool::savePlainFile(filename, text(part));
180 }
181 
183  DisplayOptions const & displayOptions,
184  FilterOptions const & filterOptions)
185 {
186  using CSBiMI = CSwordBibleModuleInfo;
187  CSwordKey* const key = m_parentWindow->key();
188  const CSwordModuleInfo *module = key->module();
189 
190  CExportManager mgr(false,
191  QString(),
194 
195  switch (type) {
196  case Document: {
197  if (module->type() == CSwordModuleInfo::Bible) {
198  CSwordVerseKey* vk = dynamic_cast<CSwordVerseKey*>(key);
199 
200  CSwordVerseKey startKey(*vk);
201  startKey.setVerse(1);
202 
203  CSwordVerseKey stopKey(*vk);
204 
205  const CSBiMI *bible = dynamic_cast<const CSBiMI*>(module);
206  if (bible) {
207  stopKey.setVerse(bible->verseCount(bible->bookNumber(startKey.bookName()), startKey.chapter()));
208  }
209 
210  mgr.printKey(module, startKey.key(), stopKey.key(), displayOptions, filterOptions);
211  }
212  else if (module->type() == CSwordModuleInfo::Lexicon || module->type() == CSwordModuleInfo::Commentary ) {
213  mgr.printKey(module, key->key(), key->key(), displayOptions, filterOptions);
214  }
215  else if (module->type() == CSwordModuleInfo::GenericBook) {
216  CSwordTreeKey* tree = dynamic_cast<CSwordTreeKey*>(key);
217 
218  CSwordTreeKey startKey(*tree);
219  // while (startKey.previousSibling()) { // go to first sibling on this level!
220  // }
221 
222  CSwordTreeKey stopKey(*tree);
223  // if (CSwordBookModuleInfo* book = dynamic_cast<CSwordBookModuleInfo*>(module)) {
224  // while ( stopKey.nextSibling() ) { //go to last displayed sibling!
225  // }
226  // }
227  mgr.printKey(module, startKey.key(), stopKey.key(), displayOptions, filterOptions);
228  }
229  break;
230  }
231 
232  case AnchorWithText: {
233  if (hasActiveAnchor()) {
234  mgr.printByHyperlink(m_activeAnchor, displayOptions, filterOptions );
235  }
236  break;
237  }
238 
239  default:
240  break;
241  }
242 }
243 
245  qmlInterface()->textModel()->reloadModules();
246 }
247 
248 QString
250  QString text;
251  switch (part) {
252  case Document: {
253  CSwordKey* const key = m_parentWindow->key();
254  const CSwordModuleInfo *module = key->module();
255  //This is never used for Bibles, so it is not implemented for
256  //them. If it should be, see CReadDisplay::print() for example
257  //code.
259  module->type() == CSwordModuleInfo::Commentary ||
260  module->type() == CSwordModuleInfo::GenericBook);
261  FilterOptions filterOptions;
262  CSwordBackend::instance().setFilterOptions(filterOptions);
263 
264  text = QStringLiteral("%1\n(%2, %3)")
265  .arg(key->strippedText(), key->key(), key->module()->name());
266  break;
267  }
268 
269  case AnchorOnly: {
270  if (auto const decodedLink =
272  return decodedLink->key;
273  return {};
274  }
275 
276  case AnchorTextOnly: {
277  auto const decodedLink(
279  if (decodedLink && decodedLink->module) {
280  std::unique_ptr<CSwordKey> key(decodedLink->module->createKey());
281  key->setKey(decodedLink->key);
282  return key->strippedText();
283  }
284  return {};
285  }
286 
287  case AnchorWithText: {
288  auto const decodedLink(
290  if (decodedLink && decodedLink->module) {
291  std::unique_ptr<CSwordKey> key(decodedLink->module->createKey());
292  key->setKey(decodedLink->key);
293 
294  FilterOptions filterOptions;
295  CSwordBackend::instance().setFilterOptions(filterOptions);
296 
297  return QStringLiteral("%1\n(%2, %3)")
298  .arg(key->strippedText(), key->key(), key->module()->name());
299  }
300  return {};
301  }
302  default:
303  break;
304  }
305  return QString();
306 
307 }
308 
310 
312  m_qmlInterface->textModel()->setDisplayOptions(displayOptions);
313 }
314 
315 void BtModelViewReadDisplay::setModules(const QStringList &modules) {
316  m_qmlInterface->setModules(modules);
317 }
318 
321 }
322 
324 
326  m_qmlInterface->setFilterOptions(filterOptions);
327 }
328 
331 }
332 
335 }
336 
338 
340 
341 void BtModelViewReadDisplay::highlightText(const QString& text, bool caseSensitive) {
342  m_qmlInterface->setHighlightWords(text, caseSensitive);
343 }
344 
345 void BtModelViewReadDisplay::findText(bool const backward)
346 { m_qmlInterface->findText(backward); }
347 
348 // Save the Lemma (Strongs number) attribute
349 void BtModelViewReadDisplay::setLemma(const QString& lemma) {
350  m_nodeInfo = lemma;
351 }
#define BT_ASSERT(...)
Definition: btassert.h:17
#define BT_CONNECT(...)
Definition: btconnect.h:20
QList< BookmarkItem > ItemList
Definition: BtMimeData.h:38
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
FilterOptions const & filterOptions() const
void lookupKey(QString const &key)
QToolBar * mainToolBar()
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