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