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  * A skrooge plugin to track operations.
8  *
9  * @author Stephane MANKOWSKI
10  */
11 #include "skgtrackerpluginwidget.h"
12 
13 #include <qdom.h>
14 #include <qevent.h>
15 
16 #include "skgdocumentbank.h"
17 #include "skgmainpanel.h"
18 #include "skgobjectmodel.h"
19 #include "skgtraces.h"
20 #include "skgtrackerobject.h"
21 #include "skgtransactionmng.h"
22 
SKGTrackerPluginWidget(QWidget * iParent,SKGDocument * iDocument)23 SKGTrackerPluginWidget::SKGTrackerPluginWidget(QWidget* iParent, SKGDocument* iDocument)
24     : SKGTabPage(iParent, iDocument)
25 {
26     SKGTRACEINFUNC(1)
27     if (iDocument == nullptr) {
28         return;
29     }
30 
31     ui.setupUi(this);
32 
33     // Set show widget
34     ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("all"), i18n("All"), QLatin1String(""), QLatin1String(""), QLatin1String(""), Qt::META + Qt::Key_A);
35     ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("opened"), i18n("Opened"), QStringLiteral("vcs-normal"), QStringLiteral("t_close='N'"), QLatin1String(""), Qt::META + Qt::Key_O);
36     ui.kView->getShowWidget()->addGroupedItem(QStringLiteral("closed"), i18n("Closed"), QStringLiteral("vcs-conflicting"), QStringLiteral("t_close='Y'"), QLatin1String(""), Qt::META + Qt::Key_C);
37     ui.kView->getShowWidget()->setDefaultState(QStringLiteral("opened"));
38 
39     ui.kNameLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_name"))));
40     ui.kCommentLabel->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_comment"))));
41 
42     ui.kAddButton->setIcon(SKGServices::fromTheme(QStringLiteral("list-add")));
43     ui.kModifyButton->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-ok")));
44 
45     ui.kView->setModel(new SKGObjectModel(qobject_cast<SKGDocumentBank*>(getDocument()), QStringLiteral("v_refund_display"), QStringLiteral("1=0"), this, QLatin1String(""), false));
46 
47     ui.kView->getView()->resizeColumnToContents(0);
48 
49     connect(getDocument(), &SKGDocument::tableModified, this, &SKGTrackerPluginWidget::dataModified, Qt::QueuedConnection);
50     connect(ui.kView->getView(), &SKGTreeView::clickEmptyArea, this, &SKGTrackerPluginWidget::cleanEditor);
51     connect(ui.kView->getView(), &SKGTreeView::doubleClicked, SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("open")).data(), &QAction::trigger);
52     connect(ui.kView->getView(), &SKGTreeView::selectionChangedDelayed, this, [ = ] {this->onSelectionChanged();});
53 
54     connect(ui.kAddButton, &QPushButton::clicked, this, &SKGTrackerPluginWidget::onAddTracker);
55     connect(ui.kModifyButton, &QPushButton::clicked, this, &SKGTrackerPluginWidget::onModifyTracker);
56     connect(ui.kNameInput, &QLineEdit::textChanged, this, &SKGTrackerPluginWidget::onEditorModified);
57 
58     // Set Event filters to catch CTRL+ENTER or SHIFT+ENTER
59     this->installEventFilter(this);
60 
61     dataModified(QLatin1String(""), 0);
62 }
63 
64 SKGTrackerPluginWidget::~SKGTrackerPluginWidget() = default;
65 
eventFilter(QObject * iObject,QEvent * iEvent)66 bool SKGTrackerPluginWidget::eventFilter(QObject* iObject, QEvent* iEvent)
67 {
68     if ((iEvent != nullptr) && iEvent->type() == QEvent::KeyPress) {
69         auto* keyEvent = dynamic_cast<QKeyEvent*>(iEvent);
70         if (keyEvent && (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && iObject == this) {
71             if ((QApplication::keyboardModifiers() & Qt::ControlModifier) != 0u && ui.kAddButton->isEnabled()) {
72                 ui.kAddButton->click();
73             } else if ((QApplication::keyboardModifiers() &Qt::ShiftModifier) != 0u && ui.kModifyButton->isEnabled()) {
74                 ui.kModifyButton->click();
75             }
76         }
77     }
78 
79     return SKGTabPage::eventFilter(iObject, iEvent);
80 }
81 
onSelectionChanged()82 void SKGTrackerPluginWidget::onSelectionChanged()
83 {
84     SKGTRACEINFUNC(10)
85 
86     int nbSelect = ui.kView->getView()->getNbSelectedObjects();
87     if (nbSelect == 1) {
88         SKGTrackerObject obj(ui.kView->getView()->getFirstSelectedObject());
89 
90         ui.kNameInput->setText(obj.getName());
91         ui.kCommentEdit->setText(obj.getComment());
92     } else if (nbSelect > 1) {
93         ui.kNameInput->setText(NOUPDATE);
94         ui.kCommentEdit->setText(NOUPDATE);
95     }
96 
97     onEditorModified();
98     Q_EMIT selectionChanged();
99 }
100 
getState()101 QString SKGTrackerPluginWidget::getState()
102 {
103     SKGTRACEINFUNC(10)
104     QDomDocument doc(QStringLiteral("SKGML"));
105     QDomElement root = doc.createElement(QStringLiteral("parameters"));
106     doc.appendChild(root);
107     root.setAttribute(QStringLiteral("view"), ui.kView->getState());
108     return doc.toString();
109 }
110 
setState(const QString & iState)111 void SKGTrackerPluginWidget::setState(const QString& iState)
112 {
113     SKGTRACEINFUNC(10)
114     QDomDocument doc(QStringLiteral("SKGML"));
115     doc.setContent(iState);
116     QDomElement root = doc.documentElement();
117     ui.kView->setState(root.attribute(QStringLiteral("view")));
118 }
119 
getDefaultStateAttribute()120 QString SKGTrackerPluginWidget::getDefaultStateAttribute()
121 {
122     return QStringLiteral("SKGREFUND_DEFAULT_PARAMETERS");
123 }
124 
mainWidget()125 QWidget* SKGTrackerPluginWidget::mainWidget()
126 {
127     return ui.kView->getView();
128 }
129 
onEditorModified()130 void SKGTrackerPluginWidget::onEditorModified()
131 {
132     _SKGTRACEINFUNC(10)
133     int nb = ui.kView->getView()->getNbSelectedObjects();
134     ui.kModifyButton->setEnabled(!ui.kNameInput->text().isEmpty() && nb >= 1);
135     ui.kAddButton->setEnabled(!ui.kNameInput->text().isEmpty() &&
136                               !ui.kNameInput->text().startsWith(QLatin1Char('=')));
137 }
138 
dataModified(const QString & iTableName,int iIdTransaction,bool iLightTransaction)139 void SKGTrackerPluginWidget::dataModified(const QString& iTableName, int iIdTransaction, bool iLightTransaction)
140 {
141     SKGTRACEINFUNC(10)
142     Q_UNUSED(iIdTransaction)
143 
144     if (!iLightTransaction) {
145         if (iTableName == QStringLiteral("refund") || iTableName.isEmpty()) {
146             // Set completions
147             SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kNameInput, getDocument(), QStringLiteral("refund"), QStringLiteral("t_name"), QLatin1String(""), true);
148             SKGMainPanel::fillWithDistinctValue(QList<QWidget*>() << ui.kCommentEdit, getDocument(), QStringLiteral("refund"), QStringLiteral("t_comment"), QLatin1String(""), true);
149         }
150     }
151 }
152 
onAddTracker()153 void SKGTrackerPluginWidget::onAddTracker()
154 {
155     SKGError err;
156     _SKGTRACEINFUNCRC(10, err)
157 
158     QString name = ui.kNameInput->text();
159     SKGTrackerObject tracker;
160     {
161         SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Tracker creation '%1'", name), err)
162 
163         err = SKGTrackerObject::createTracker(qobject_cast<SKGDocumentBank*>(getDocument()), name, tracker);
164         IFOKDO(err, tracker.setComment(ui.kCommentEdit->text()))
165         IFOKDO(err, tracker.save())
166 
167         // Send message
168         IFOKDO(err, tracker.getDocument()->sendMessage(i18nc("An information to the user", "The tracker '%1' have been added", tracker.getDisplayName()), SKGDocument::Hidden))
169     }
170 
171     // status bar
172     IFOK(err) {
173         err = SKGError(0, i18nc("Successful message after an user action", "Tracker '%1' created", name));
174         ui.kView->getView()->selectObject(tracker.getUniqueID());
175     } else {
176         err.addError(ERR_FAIL, i18nc("Error message", "Tracker creation failed"));
177     }
178 
179     // Display error
180     SKGMainPanel::displayErrorMessage(err, true);
181 }
182 
onModifyTracker()183 void SKGTrackerPluginWidget::onModifyTracker()
184 {
185     SKGError err;
186     _SKGTRACEINFUNCRC(10, err)
187     // Get Selection
188     SKGObjectBase::SKGListSKGObjectBase selection = getSelectedObjects();
189 
190     int nb = selection.count();
191     {
192         SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Tracker update"), err, nb)
193         for (int i = 0; !err && i < nb; ++i) {
194             // Modification of object
195             SKGTrackerObject tracker(selection.at(i));
196             err = tracker.setName(ui.kNameInput->text());
197             IFOKDO(err, tracker.setComment(ui.kCommentEdit->text()))
198             IFOKDO(err, tracker.save())
199 
200             // Send message
201             IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The tracker '%1' has been updated", tracker.getDisplayName()), SKGDocument::Hidden))
202 
203             IFOKDO(err, getDocument()->stepForward(i + 1))
204         }
205     }
206     // status bar
207     IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Tracker updated")))
208     else {
209         err.addError(ERR_FAIL, i18nc("Error message", "Tracker update failed"));
210     }
211 
212     // Display error
213     SKGMainPanel::displayErrorMessage(err, true);
214 
215     // Set focus on table
216     ui.kView->getView()->setFocus();
217 }
218 
cleanEditor()219 void SKGTrackerPluginWidget::cleanEditor()
220 {
221     if (getNbSelectedObjects() == 0) {
222         ui.kNameInput->setText(QLatin1String(""));
223         ui.kCommentEdit->setText(QLatin1String(""));
224     }
225 }
226 
activateEditor()227 void SKGTrackerPluginWidget::activateEditor()
228 {
229     ui.kNameInput->setFocus();
230 }
231 
isEditor()232 bool SKGTrackerPluginWidget::isEditor()
233 {
234     return true;
235 }
236 
237 
238