BibleTime
btquickwidget.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-2025 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 "btquickwidget.h"
14#include "../../bibletime.h"
15
16#include <QCursor>
17#include <QGuiApplication>
18#include <QMimeData>
19#include <QMouseEvent>
20#include <QQmlContext>
21#include <QQmlEngine>
22#include <QQuickItem>
23#include <Qt>
24#include <QWheelEvent>
25#include "../../../backend/drivers/cswordmoduleinfo.h"
26#include "../../../backend/managers/cswordbackend.h"
27#include "../../../util/btassert.h"
28#include "../../BtMimeData.h"
29#include "btqmlinterface.h"
30
31
33 : QQuickWidget(parent)
34 , m_qmlInterface(
35 engine()->singletonInstance<BtQmlInterface *>(BtQmlInterface::typeId))
36{
38
39 setAcceptDrops(true);
40
41 engine()->addImportPath(QStringLiteral("qrc:/qt/qml"));
42 setSource(QUrl(QStringLiteral("qrc:/qt/qml/DisplayView.qml")));
43
44 m_scrollTimer.setInterval(100);
45 m_scrollTimer.setSingleShot(false);
46 connect(&m_scrollTimer, &QTimer::timeout, this,
47 [this]{
48 int y = mapFromGlobal(QCursor::pos()).y();
49 if ((y >= 0) & (y-height() < 0))
50 return;
51 if (y < 0) {
52 scroll(-8);
53 } else {
54 scroll(8);
55 }
56 int y2 = y * y;
57 if (y2 > 100)
58 y2 = 100;
59 m_scrollTimer.setInterval(500 / y2);
60 });
61}
62
63void BtQuickWidget::dragEnterEvent(QDragEnterEvent * const e) {
64 if (auto const * const btmimedata =
65 qobject_cast<BTMimeData const *>(e->mimeData()))
66 {
67 auto const & item = btmimedata->bookmarks().first();
68 auto * const m =
70 BT_ASSERT(m);
71
72 // Is bible reference bookmark compatible with the module type?
73 CSwordModuleInfo::ModuleType bookmarkType = m->type();
74 if ((bookmarkType == CSwordModuleInfo::Bible
75 || bookmarkType == CSwordModuleInfo::Commentary)
77 {
78 e->acceptProposedAction();
79 } else {
80 QQuickWidget::dragEnterEvent(e);
81 }
82 }
83}
84
85void BtQuickWidget::dropEvent(QDropEvent * const e) {
86 if (auto const * const btmimedata =
87 qobject_cast<BTMimeData const *>(e->mimeData()))
88 {
89 BookmarkItem item = btmimedata->bookmarks().first();
90 Q_EMIT referenceDropped(item.key());
91 e->acceptProposedAction();
92 return;
93 }
94}
95
96// Reimplementation from QQuickWidget
97void BtQuickWidget::dragMoveEvent( QDragMoveEvent* e ) {
98 if (e->mimeData()->hasFormat(QStringLiteral("BibleTime/Bookmark"))) {
99 e->acceptProposedAction();
100 return;
101 }
102 //don't accept the action!
103 e->ignore();
104}
105
106void BtQuickWidget::updateReferenceText() { callQml("updateReferenceText"); }
107
108void BtQuickWidget::pageDown() { callQml("pageDown"); }
109
110void BtQuickWidget::pageUp() { callQml("pageUp"); }
111
115
116void BtQuickWidget::scroll(int const pixels) { callQml("scroll", pixels); }
117
118// Catch Leave event here insteaded of leaveEvent(e), because
119// QMdiSubwindow does not pass leaveEvent on down.
120bool BtQuickWidget::event(QEvent* e) {
121 if (e->type() == QEvent::Leave)
123 return QQuickWidget::event(e);
124}
125
126void BtQuickWidget::mouseDoubleClickEvent(QMouseEvent *event) {
127 event->accept();
128 return;
129}
130
131void BtQuickWidget::mousePressEvent(QMouseEvent *event) {
132 if (event->button() == Qt::LeftButton) {
133 auto const position = event->position().toPoint();
134 callQml("leftMousePress", position.x(), position.y());
135 event->accept();
136 return;
137 }
138 QQuickWidget::mousePressEvent(event);
139}
140
141void BtQuickWidget::mouseMoveEvent(QMouseEvent *event) {
142 if ((event->buttons() & Qt::LeftButton) == Qt::LeftButton) {
143 auto const position = event->position().toPoint();
144 auto const y = position.y();
145 if (y < 0 || y > height()) {
146 if (!m_scrollTimer.isActive())
147 m_scrollTimer.start();
148 } else {
149 m_scrollTimer.stop();
150 }
151
152 callQml("leftMouseMove", position.x(), y);
153 event->accept();
154 return;
155 }
156 return QQuickWidget::mouseMoveEvent(event);
157}
158
159void BtQuickWidget::mouseReleaseEvent(QMouseEvent *event) {
160 if (event->button() == Qt::LeftButton) {
161 m_scrollTimer.stop();
162 auto const position = event->position().toPoint();
163 callQml("leftMouseRelease", position.x(), position.y());
164 event->accept();
165 return;
166 }
167 return QQuickWidget::mouseReleaseEvent(event);
168}
169
170void BtQuickWidget::wheelEvent(QWheelEvent * event) {
172 QQuickWidget::wheelEvent(event);
173}
#define BT_ASSERT(...)
Definition btassert.h:17
static BibleTime * instance() noexcept
Definition bibletime.h:222
void autoScrollStop()
QString const & key() const noexcept
CSwordKey * getMouseClickedKey() const
BtQuickWidget(QWidget *const parent=nullptr)
void dropEvent(QDropEvent *e) override
void callQml(char const *const method, Args &&... args)
void referenceDropped(const QString &reference)
void dragEnterEvent(QDragEnterEvent *e) override
virtual void mouseMoveEvent(QMouseEvent *event) override
virtual void mousePressEvent(QMouseEvent *event) override
void scroll(int pixels)
virtual void mouseReleaseEvent(QMouseEvent *event) override
virtual bool event(QEvent *e) override
virtual void wheelEvent(QWheelEvent *event) override
virtual void mouseDoubleClickEvent(QMouseEvent *event) override
CSwordKey * getMouseClickedKey()
void dragMoveEvent(QDragMoveEvent *event) override
BtQmlInterface *const m_qmlInterface
QTimer m_scrollTimer
void updateReferenceText()
CSwordModuleInfo * findModuleByName(const QString &name) const
Searches for a module with the given name.
static CSwordBackend & instance() noexcept