1 /***************************************************************************
2 * SPDX-FileCopyrightText: 2021 S. MANKOWSKI stephane@mankowski.fr
3 * SPDX-FileCopyrightText: 2021 G. DE BURE support@mankowski.fr
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 ***************************************************************************/
6 /** @file
7 * This file is a class managing widget.
8 *
9 * @author Stephane MANKOWSKI / Guillaume DE BURE
10 */
11 #include "skgtabpage.h"
12
13 #include <klocalizedstring.h>
14 #include <kmessagebox.h>
15
16 #include <qwidget.h>
17 #ifdef SKG_WEBENGINE
18 #include <qwebengineview.h>
19 #endif
20 #ifdef SKG_WEBKIT
21 #include <qwebview.h>
22 #endif
23 #if !defined(SKG_WEBENGINE) && !defined(SKG_WEBKIT)
24 #include <qlabel.h>
25 #endif
26 #include <qmath.h>
27
28 #include <cmath>
29
30 #include "skgdocument.h"
31 #include "skghtmlboardwidget.h"
32 #include "skgmainpanel.h"
33 #include "skgnodeobject.h"
34 #include "skgservices.h"
35 #include "skgtraces.h"
36 #include "skgtransactionmng.h"
37 #include "skgtreeview.h"
38
SKGTabPage(QWidget * iParent,SKGDocument * iDocument)39 SKGTabPage::SKGTabPage(QWidget* iParent, SKGDocument* iDocument)
40 : SKGWidget(iParent, iDocument), m_pin(false)
41 {
42 SKGTRACEINFUNC(5)
43
44 // Save original size
45 m_fontOriginalPointSize = this->font().pointSize(); // Use this instead of zoomableWidget()
46 }
47
~SKGTabPage()48 SKGTabPage::~SKGTabPage()
49 {
50 SKGTRACEINFUNC(5)
51 }
52
close(bool iForce)53 bool SKGTabPage::close(bool iForce)
54 {
55 SKGTRACEINFUNC(5)
56 int conf = KMessageBox::Yes;
57 if (!iForce && isPin()) {
58 QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
59 conf = KMessageBox::questionYesNo(this,
60 i18nc("Question", "Do you really want to close this pinned page?"),
61 i18nc("Question", "Pinned page"),
62 KStandardGuiItem::yes(),
63 KStandardGuiItem::no(),
64 QStringLiteral("closepinnedpage"));
65 QApplication::restoreOverrideCursor();
66 }
67 overwrite();
68 if (conf == KMessageBox::No) {
69 return false;
70 }
71 return QWidget::close();
72 }
73
setBookmarkID(const QString & iId)74 void SKGTabPage::setBookmarkID(const QString& iId)
75 {
76 m_bookmarkID = iId;
77 }
78
getBookmarkID()79 QString SKGTabPage::getBookmarkID()
80 {
81 return m_bookmarkID;
82 }
getPreviousPages()83 SKGTabPage::SKGPageHistoryItemList SKGTabPage::getPreviousPages()
84 {
85 return m_previousPages;
86 }
87
setPreviousPages(const SKGTabPage::SKGPageHistoryItemList & iPages)88 void SKGTabPage::setPreviousPages(const SKGTabPage::SKGPageHistoryItemList& iPages)
89 {
90 m_previousPages = iPages;
91 }
92
getNextPages()93 SKGTabPage::SKGPageHistoryItemList SKGTabPage::getNextPages()
94 {
95 return m_nextPages;
96 }
97
setNextPages(const SKGTabPage::SKGPageHistoryItemList & iPages)98 void SKGTabPage::setNextPages(const SKGTabPage::SKGPageHistoryItemList& iPages)
99 {
100 m_nextPages = iPages;
101 }
102
isOverwriteNeeded()103 bool SKGTabPage::isOverwriteNeeded()
104 {
105 // Is this widget linked to a bookmark ?
106 if (!m_bookmarkID.isEmpty()) {
107 // Yes. Is state modified ?
108 SKGNodeObject node(getDocument(), SKGServices::stringToInt(m_bookmarkID));
109 if (node.exist()) {
110 QStringList d = SKGServices::splitCSVLine(node.getData());
111 if (d.count() > 2) {
112 QString currentState = getState().trimmed();
113 QString oldState = d[2].trimmed();
114 currentState.remove('\n');
115 oldState.remove('\n');
116 SKGTRACEL(20) << "oldState =[" << oldState << ']' << SKGENDL;
117 SKGTRACEL(20) << "currentState =[" << currentState << ']' << SKGENDL;
118 SKGTRACEL(20) << "Bookmark diff =" << (currentState != oldState ? "TRUE" : "FALSE") << SKGENDL;
119 return (currentState != oldState);
120 }
121 }
122 } else {
123 // No. It is a page opened from context or from another page
124 QString name = getDefaultStateAttribute();
125 if (!name.isEmpty()) {
126 QString currentState = getState().trimmed();
127 QString oldState = getDocument()->getParameter(name);
128 currentState.remove('\n');
129 oldState.remove('\n');
130 SKGTRACEL(20) << "oldState =[" << oldState << ']' << SKGENDL;
131 SKGTRACEL(20) << "currentState =[" << currentState << ']' << SKGENDL;
132 SKGTRACEL(20) << "Page diff =" << (currentState != oldState ? "TRUE" : "FALSE") << SKGENDL;
133 return (currentState != oldState);
134 }
135 }
136 return false;
137 }
138
overwrite(bool iUserConfirmation)139 void SKGTabPage::overwrite(bool iUserConfirmation)
140 {
141 SKGTRACEINFUNC(10)
142 // Is this widget linked to a bookmark ?
143 if (!m_bookmarkID.isEmpty()) {
144 // Yes. Is state modified ?
145 SKGNodeObject node(getDocument(), SKGServices::stringToInt(m_bookmarkID));
146 if (node.exist()) {
147 QStringList d = SKGServices::splitCSVLine(node.getData());
148 QString fullname = node.getFullName();
149 if (d.count() > 2) {
150 QString currentState = getState().trimmed();
151 QString oldState = d[2].trimmed();
152 currentState.remove('\n');
153 oldState.remove('\n');
154 SKGTRACEL(20) << "oldState =[" << oldState << ']' << SKGENDL;
155 SKGTRACEL(20) << "currentState =[" << currentState << ']' << SKGENDL;
156 if (currentState != oldState) {
157 QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
158 int conf = KMessageBox::Yes;
159 KMessageBox::ButtonCode button;
160 SKGTRACEL(10) << (KMessageBox::shouldBeShownYesNo(QStringLiteral("updateBookmarkOnClose"), button) ? "updateBookmarkOnClose: Ask confirmation" : "updateBookmarkOnClose: Do not ask confirmation") << SKGENDL;
161 if (iUserConfirmation && !oldState.isEmpty()) {
162 conf = KMessageBox::questionYesNo(this,
163 i18nc("Question", "Bookmark '%1' has been modified. Do you want to update it with the current state?", fullname),
164 i18nc("Question", "Bookmark has been modified"),
165 KStandardGuiItem::yes(),
166 KStandardGuiItem::no(),
167 QStringLiteral("updateBookmarkOnClose"));
168 }
169 QApplication::restoreOverrideCursor();
170 if (conf == KMessageBox::Yes) {
171 SKGError err;
172 {
173 SKGBEGINLIGHTTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Bookmark update '%1'", fullname), err)
174 d[2] = currentState;
175 IFOKDO(err, node.setData(SKGServices::stringsToCsv(d)))
176 IFOKDO(err, node.save())
177 }
178 IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Bookmark updated")))
179 SKGMainPanel::displayErrorMessage(err);
180 }
181 }
182 }
183 }
184 } else {
185 // No. It is a page opened from context or from another page
186 QString name = getDefaultStateAttribute();
187 if (!name.isEmpty()) {
188 QString currentState = getState().trimmed();
189 QString oldState = getDocument()->getParameter(name);
190 SKGTRACEL(20) << "oldState =[" << oldState << ']' << SKGENDL;
191 SKGTRACEL(20) << "currentState =[" << currentState << ']' << SKGENDL;
192 currentState.remove('\n');
193 oldState.remove('\n');
194 if (currentState != oldState) {
195 QApplication::setOverrideCursor(QCursor(Qt::ArrowCursor));
196 int conf = KMessageBox::Yes;
197 KMessageBox::ButtonCode button;
198 SKGTRACEL(10) << (KMessageBox::shouldBeShownYesNo(QStringLiteral("updateContextOnClose"), button) ? "updateBookmarkOnClose: Ask confirmation" : "updateBookmarkOnClose: Do not ask confirmation") << SKGENDL;
199
200 if (iUserConfirmation && !oldState.isEmpty()) {
201 conf = KMessageBox::questionYesNo(this,
202 i18nc("Question", "Page has been modified. Do you want to update it with the current state?"),
203 i18nc("Question", "Page has been modified"),
204 KStandardGuiItem::yes(),
205 KStandardGuiItem::no(),
206 QStringLiteral("updateContextOnClose"));
207 }
208 QApplication::restoreOverrideCursor();
209 if (conf == KMessageBox::Yes) {
210 SKGError err;
211 {
212 SKGBEGINLIGHTTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Save default state"), err)
213 err = getDocument()->setParameter(name, currentState);
214 }
215 IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Default state saved")))
216 SKGMainPanel::displayErrorMessage(err);
217 }
218 }
219 }
220 }
221 }
222
223
isEditor()224 bool SKGTabPage::isEditor()
225 {
226 return false;
227 }
228
activateEditor()229 void SKGTabPage::activateEditor() {}
230
zoomableWidget()231 QWidget* SKGTabPage::zoomableWidget()
232 {
233 return mainWidget();
234 }
235
printableWidgets()236 QList< QWidget* > SKGTabPage::printableWidgets()
237 {
238 QList< QWidget* > output;
239 output.push_back(mainWidget());
240 return output;
241 }
242
isZoomable()243 bool SKGTabPage::isZoomable()
244 {
245 return (zoomableWidget() != nullptr);
246 }
247
setZoomPosition(int iValue)248 void SKGTabPage::setZoomPosition(int iValue)
249 {
250 QWidget* widget = zoomableWidget();
251 auto* treeView = qobject_cast<SKGTreeView*>(widget);
252 if (treeView != nullptr) {
253 treeView->setZoomPosition(iValue);
254 } else {
255 #ifdef SKG_WEBENGINE
256 auto webView = qobject_cast<QWebEngineView*>(widget);
257 #endif
258 #ifdef SKG_WEBKIT
259 auto webView = qobject_cast<QWebView*>(widget);
260 #endif
261 #if defined(SKG_WEBENGINE) || defined(SKG_WEBKIT)
262 if (webView != nullptr) {
263 webView->setZoomFactor(qPow(10, static_cast<qreal>(iValue) / 30.0));
264 } else {
265 int pointSize = qMax(1, m_fontOriginalPointSize + iValue);
266 QFont f = widget->font();
267 f.setPointSize(pointSize);
268 widget->setFont(f);
269
270 auto cs = widget->findChildren<SKGHtmlBoardWidget*>();
271 for (auto c : qAsConst(cs)) {
272 c->setPointSize(pointSize);
273 }
274 }
275 #endif
276 }
277 }
278
zoomPosition()279 int SKGTabPage::zoomPosition()
280 {
281 int output = 0;
282 QWidget* widget = zoomableWidget();
283 auto* treeView = qobject_cast<SKGTreeView*>(widget);
284 if (treeView != nullptr) {
285 output = treeView->zoomPosition();
286 } else {
287 #ifdef SKG_WEBENGINE
288 auto webView = qobject_cast<QWebEngineView*>(widget);
289 #endif
290 #ifdef SKG_WEBKIT
291 auto webView = qobject_cast<QWebView*>(widget);
292 #endif
293 #if defined(SKG_WEBENGINE) || defined(SKG_WEBKIT)
294 if (webView != nullptr) {
295 output = qRound(30.0 * log10(webView->zoomFactor()));
296 } else if (widget != nullptr) {
297 output = widget->font().pointSize() - m_fontOriginalPointSize;
298 }
299 #endif
300 }
301 return output;
302 }
303
parentTabPage(QWidget * iWidget)304 SKGTabPage* SKGTabPage::parentTabPage(QWidget* iWidget)
305 {
306 auto* output = qobject_cast< SKGTabPage* >(iWidget);
307 if ((output == nullptr) && (iWidget != nullptr)) {
308 QWidget* iParent = iWidget->parentWidget();
309 if (iParent != nullptr) {
310 output = SKGTabPage::parentTabPage(iParent);
311 }
312 }
313 return output;
314 }
315
isPin() const316 bool SKGTabPage::isPin() const
317 {
318 return m_pin;
319 }
320
setPin(bool iPin)321 void SKGTabPage::setPin(bool iPin)
322 {
323 m_pin = iPin;
324 }
325
326
327