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 Skrooge plugin for unit management.
8  *
9  * @author Stephane MANKOWSKI / Guillaume DE BURE
10  */
11 #include "skgunitpluginwidget.h"
12 
13 #include <klocalizedstring.h>
14 #include <kns3/downloaddialog.h>
15 #include <kns3/uploaddialog.h>
16 #include <krun.h>
17 #include <kzip.h>
18 
19 #include <qdir.h>
20 #include <qdom.h>
21 #include <qevent.h>
22 #include <qfile.h>
23 #include <qsortfilterproxymodel.h>
24 #include <qstandardpaths.h>
25 #include <qurl.h>
26 #include <qvalidator.h>
27 
28 #include "skgbankincludes.h"
29 #include "skgmainpanel.h"
30 #include "skgobjectmodel.h"
31 #include "skgservices.h"
32 #include "skgtraces.h"
33 #include "skgunit_settings.h"
34 
SKGUnitPluginWidget(QWidget * iParent,SKGDocumentBank * iDocument)35 SKGUnitPluginWidget::SKGUnitPluginWidget(QWidget* iParent, SKGDocumentBank* iDocument)
36     : SKGTabPage(iParent, iDocument), m_upload(nullptr), m_unitValueGraphCmb(nullptr)
37 {
38     SKGTRACEINFUNC(10)
39     if (iDocument == nullptr) {
40         return;
41     }
42 
43     ui.setupUi(this);
44     ui.kGraph->setShadowVisible(false);
45     m_unitValueGraphCmb = new SKGComboBox(this);
46     m_unitValueGraphCmb->addItem(i18nc("A mode of graph of unit values", "Unit values"));
47     m_unitValueGraphCmb->addItem(i18nc("A mode of graph of unit values", "Amount owned"));
48     connect(m_unitValueGraphCmb, static_cast<void (SKGComboBox::*)(int)>(&SKGComboBox::currentIndexChanged), this, &SKGUnitPluginWidget::onSelectionChanged);
49     ui.kGraph->graph()->addToolbarWidget(m_unitValueGraphCmb);
50 
51     ui.kNameLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_name"))));
52     ui.kDecimalLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("i_nbdecimal"))));
53     ui.kCountyLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_country"))));
54     ui.kSymbolLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_symbol"))));
55     ui.kTypeLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_type"))));
56     ui.kInternetLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_internet_code"))));
57     ui.kDateLabel->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("d_date"))));
58     ui.kAmountLabel->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("f_value"))));
59     ui.kUnitLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_UNIT"))));
60     ui.kUnitLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_UNIT"))));
61     ui.kDownloadSourceLbl->setText(i18n("%1:", iDocument->getDisplay(QStringLiteral("t_source"))));
62 
63     ui.kUnitTableViewEdition->getShowWidget()->addItem(QStringLiteral("all"), i18nc("Noun, items to display", "All"), QLatin1String(""),
64             QLatin1String(""),
65             QStringLiteral("currency;share;index;object"),  // Check when checked
66             QStringLiteral("highlighted"),  // Uncheck when checked
67             QLatin1String(""), QLatin1String(""),
68             Qt::META + Qt::Key_A);
69     ui.kUnitTableViewEdition->getShowWidget()->addItem(QStringLiteral("highlighted"), i18n("Highlighted only"), QStringLiteral("bookmarks"), QStringLiteral("t_bookmarked='Y'"), QLatin1String(""), QStringLiteral("all;currency;share;index;object"), QStringLiteral("all"), QLatin1String(""), Qt::META + Qt::Key_H);
70     ui.kUnitTableViewEdition->getShowWidget()->addSeparator();
71     ui.kUnitTableViewEdition->getShowWidget()->addItem(QStringLiteral("currency"), i18nc("Noun, a country's currency", "Currency"), QLatin1String(""),
72             QStringLiteral("t_type IN ('1','2','C')"),
73             QLatin1String(""),  // Check when checked
74             QStringLiteral("highlighted"),       // Uncheck when checked
75             QLatin1String(""),       // Check when unchecked
76             QStringLiteral("all"), Qt::META + Qt::Key_C);     // Uncheck when unchecked
77     ui.kUnitTableViewEdition->getShowWidget()->addItem(QStringLiteral("share"), i18nc("Noun, a financial share, as in a stock market", "Share"), QLatin1String(""),
78             QStringLiteral("t_type='S'"),
79             QLatin1String(""),
80             QStringLiteral("highlighted"),
81             QLatin1String(""),
82             QStringLiteral("all"), Qt::META + Qt::Key_S);
83     ui.kUnitTableViewEdition->getShowWidget()->addItem(QStringLiteral("index"), i18nc("Noun, a financial index like the Dow Jones, NASDAQ, CAC40...", "Index"), QLatin1String(""),
84             QStringLiteral("t_type='I'"),
85             QLatin1String(""),
86             QStringLiteral("highlighted"),
87             QLatin1String(""),
88             QStringLiteral("all;current"), Qt::META + Qt::Key_I);
89     ui.kUnitTableViewEdition->getShowWidget()->addItem(QStringLiteral("object"), i18nc("Noun, a physical object like a house or a car", "Object"), QLatin1String(""),
90             QStringLiteral("t_type='O'"),
91             QLatin1String(""),
92             QStringLiteral("highlighted"),
93             QLatin1String(""),
94             QStringLiteral("all"), Qt::META + Qt::Key_O);
95 
96     ui.kUnitTableViewEdition->getShowWidget()->setDefaultState(QStringLiteral("all;currency;share;index;object"));
97 
98     ui.kGraph->getShowWidget()->setState(QStringLiteral("\"graph\""));
99     ui.kGraph->setFilterVisibility(false);
100 
101     ui.kUnitCreatorUnit->setDocument(iDocument);
102     ui.kUnitCreatorUnit->setWhereClauseCondition(QStringLiteral("t_type IN ('1','2','C')"));
103 
104     // Add Standard KDE Icons to buttons to Accounts
105     ui.kUnitAdd->setIcon(SKGServices::fromTheme(QStringLiteral("list-add")));
106     ui.kUnitUpdate->setIcon(SKGServices::fromTheme(QStringLiteral("dialog-ok")));
107     ui.kUnitValueDownload->setIcon(SKGServices::fromTheme(QStringLiteral("download")));
108     ui.kDeleteSource->setIcon(SKGServices::fromTheme(QStringLiteral("edit-delete")));
109     ui.kGetNewHotStuff->setIcon(SKGServices::fromTheme(QStringLiteral("get-hot-new-stuff")));
110 
111     auto newValidator = new QRegularExpressionValidator(QRegularExpression(QStringLiteral("^[\\w\\s]+$")), this);
112     ui.kDownloadSource->setValidator(newValidator);
113 
114     QStringList overlays;
115     overlays.push_back(QStringLiteral("list-add"));
116     m_upload = new QAction(SKGServices::fromTheme(QStringLiteral("get-hot-new-stuff"), overlays), i18n("Upload"), this);
117     connect(m_upload, &QAction::triggered, this, &SKGUnitPluginWidget::onPutNewHotStuff);
118 
119     auto menu = new QMenu(this);
120     menu->addAction(m_upload);
121     ui.kGetNewHotStuff->setMenu(menu);
122 
123     ui.kUnitOpen->setIcon(SKGServices::fromTheme(QStringLiteral("quickopen")));
124     connect(ui.kUnitOpen, &QPushButton::clicked, this, &SKGUnitPluginWidget::onOpenURL);
125 
126     auto downloadLastAction = new QAction(SKGServices::fromTheme(QStringLiteral("download")), i18n("download last value only"), this);
127     downloadLastAction->setData(static_cast<int>(SKGUnitObject::LAST));
128     connect(downloadLastAction, &QAction::triggered, this, &SKGUnitPluginWidget::onDownloadUnitValue);
129 
130     auto downloadLastMonthlyAction = new QAction(SKGServices::fromTheme(QStringLiteral("download")), i18n("download monthly values since last known value"), this);
131     downloadLastMonthlyAction->setData(static_cast<int>(SKGUnitObject::LAST_MONTHLY));
132     connect(downloadLastMonthlyAction, &QAction::triggered, this, &SKGUnitPluginWidget::onDownloadUnitValue);
133 
134     auto downloadLastWeeklyAction = new QAction(SKGServices::fromTheme(QStringLiteral("download")), i18n("download weekly values since last known value"), this);
135     downloadLastWeeklyAction->setData(static_cast<int>(SKGUnitObject::LAST_WEEKLY));
136     connect(downloadLastWeeklyAction, &QAction::triggered, this, &SKGUnitPluginWidget::onDownloadUnitValue);
137 
138     auto downloadLastDailyAction = new QAction(SKGServices::fromTheme(QStringLiteral("download")), i18n("download daily values since last known value"), this);
139     downloadLastDailyAction->setData(static_cast<int>(SKGUnitObject::LAST_DAILY));
140     connect(downloadLastDailyAction, &QAction::triggered, this, &SKGUnitPluginWidget::onDownloadUnitValue);
141 
142     auto downloadMonthlyAction = new QAction(SKGServices::fromTheme(QStringLiteral("download")), i18n("download all monthly values"), this);
143     downloadMonthlyAction->setData(static_cast<int>(SKGUnitObject::ALL_MONTHLY));
144     connect(downloadMonthlyAction, &QAction::triggered, this, &SKGUnitPluginWidget::onDownloadUnitValue);
145 
146     auto downloadWeeklyAction = new QAction(SKGServices::fromTheme(QStringLiteral("download")), i18n("download all weekly values"), this);
147     downloadWeeklyAction->setData(static_cast<int>(SKGUnitObject::ALL_WEEKLY));
148     connect(downloadWeeklyAction, &QAction::triggered, this, &SKGUnitPluginWidget::onDownloadUnitValue);
149 
150     auto downloadDailyAction = new QAction(SKGServices::fromTheme(QStringLiteral("download")), i18n("download all daily values"), this);
151     downloadDailyAction->setData(static_cast<int>(SKGUnitObject::ALL_DAILY));
152     connect(downloadDailyAction, &QAction::triggered, this, &SKGUnitPluginWidget::onDownloadUnitValue);
153 
154     auto simplifyAction = new QAction(SKGServices::fromTheme(QStringLiteral("edit-delete")), i18n("simplify values"), this);
155     connect(simplifyAction, &QAction::triggered, this, &SKGUnitPluginWidget::onSimplify);
156 
157 
158     auto downloadMenu = new QMenu(this);
159     downloadMenu->addAction(downloadLastAction);
160     downloadMenu->addAction(downloadLastMonthlyAction);
161     downloadMenu->addAction(downloadLastWeeklyAction);
162     downloadMenu->addAction(downloadLastDailyAction);
163     downloadMenu->addAction(downloadMonthlyAction);
164     downloadMenu->addAction(downloadWeeklyAction);
165     downloadMenu->addAction(downloadDailyAction);
166 
167     downloadMenu->addAction(simplifyAction);
168     ui.kUnitValueDownload->setMenu(downloadMenu);
169     connect(ui.kUnitValueDownload, &QToolButton::clicked, this, &SKGUnitPluginWidget::onDownloadUnitValue);
170     {
171         SKGWidgetSelector::SKGListQWidget list;
172         list.push_back(ui.kStandardFrm);
173         list.push_back(ui.kBtnFrm);
174         ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("dialog-ok")), i18n("Standard"), i18n("Display the edit panel for standard units"), list);
175     }
176     {
177         SKGWidgetSelector::SKGListQWidget list;
178         list.push_back(ui.kManualFrm);
179         list.push_back(ui.kBtnFrm);
180         ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("user-properties")), i18n("Manual / Share"), i18n("Display the edit panel for manual units"), list);
181     }
182     {
183         SKGWidgetSelector::SKGListQWidget list;
184         list.push_back(ui.kValuesFrm);
185         list.push_back(ui.kBtnFrm);
186         ui.kWidgetSelector->addButton(SKGServices::fromTheme(QStringLiteral("taxes-finances")), i18n("Values"), i18n("Display the edit panel for values of units"), list);
187     }
188     connect(ui.kWidgetSelector, &SKGWidgetSelector::selectedModeChanged, this, &SKGUnitPluginWidget::onUnitCreatorModified);
189 
190     // Fill combo box for type
191     ui.kTypeCreatorUnit->addItem(i18nc("Noun", "Primary currency"), static_cast<int>(SKGUnitObject::PRIMARY));
192     ui.kTypeCreatorUnit->addItem(i18nc("Noun", "Secondary currency"), static_cast<int>(SKGUnitObject::SECONDARY));
193     ui.kTypeCreatorUnit->addItem(i18nc("Noun, a country's currency", "Currency"), static_cast<int>(SKGUnitObject::CURRENCY));
194     ui.kTypeCreatorUnit->addItem(i18nc("Noun, a financial share, as in a stock market", "Share"), static_cast<int>(SKGUnitObject::SHARE));
195     ui.kTypeCreatorUnit->addItem(i18nc("Noun, a financial index like the Dow Jones, NASDAQ, CAC40...", "Index"), static_cast<int>(SKGUnitObject::INDEX));
196     ui.kTypeCreatorUnit->addItem(i18nc("Noun, a physical object like a house or a car", "Object"), static_cast<int>(SKGUnitObject::OBJECT));
197     bool primaryUnit, secondaryUnit;
198     iDocument->existObjects(QStringLiteral("unit"), QStringLiteral("t_type='1'"), primaryUnit);
199     iDocument->existObjects(QStringLiteral("unit"), QStringLiteral("t_type='2'"), secondaryUnit);
200     if (primaryUnit) {
201         if (secondaryUnit) {
202             ui.kTypeCreatorUnit->setCurrentIndex(2);
203         } else {
204             ui.kTypeCreatorUnit->setCurrentIndex(1);
205         }
206     } else {
207         ui.kTypeCreatorUnit->setCurrentIndex(0);
208     }
209 
210     // Bind unit creation view
211     {
212         ui.kUnitTableViewEdition->setModel(new SKGObjectModel(qobject_cast<SKGDocumentBank*>(getDocument()), QStringLiteral("v_unit_display"), QLatin1String(""), this, QLatin1String(""), false));
213 
214         connect(ui.kUnitTableViewEdition->getView(), &SKGTreeView::clickEmptyArea, this, &SKGUnitPluginWidget::cleanEditor);
215         connect(ui.kUnitTableViewEdition->getView(), &SKGTreeView::doubleClicked, SKGMainPanel::getMainPanel()->getGlobalAction(QStringLiteral("open")).data(), &QAction::trigger);
216         connect(ui.kUnitTableViewEdition->getView(), &SKGTreeView::selectionChangedDelayed, this, [ = ] {this->onSelectionChanged();});
217     }
218 
219     // Bind unit creation view
220     {
221         auto objectModel2 = new SKGObjectModel(qobject_cast<SKGDocumentBank*>(getDocument()), QStringLiteral("v_unitvalue_display"), QStringLiteral("1=0"), this, QLatin1String(""), false);
222         ui.kUnitValueTableViewEdition->setModel(objectModel2);
223         connect(ui.kUnitValueTableViewEdition, &SKGTableView::selectionChangedDelayed, this, &SKGUnitPluginWidget::onSelectionValueChanged);
224     }
225 
226     // Refresh
227     connect(getDocument(), &SKGDocument::tableModified, this, &SKGUnitPluginWidget::dataModified, Qt::QueuedConnection);
228     ui.kWidgetSelector->setSelectedMode(0);
229 
230     // Fill combo box for reference currency
231     fillSourceList();
232     dataModified(QLatin1String(""), 0);
233 
234     // Set Event filters to catch CTRL+ENTER or SHIFT+ENTER
235     this->installEventFilter(this);
236 
237     // Synchronize zooms of both tables
238     connect(ui.kUnitTableViewEdition->getView(), &SKGTreeView::zoomChanged, ui.kUnitValueTableViewEdition, &SKGTreeView::setZoomPosition);
239     connect(ui.kUnitValueTableViewEdition, &SKGTreeView::zoomChanged, ui.kUnitTableViewEdition->getView(), &SKGTreeView::setZoomPosition);
240 
241     // Other connects
242     connect(ui.kNameCreatorUnit, &QLineEdit::textChanged, this, &SKGUnitPluginWidget::onUnitCreatorModified);
243     connect(ui.kUnitAdd, &QPushButton::clicked, this, &SKGUnitPluginWidget::onAddUnit);
244     connect(ui.kUnitUpdate, &QPushButton::clicked, this, &SKGUnitPluginWidget::onModifyUnit);
245     connect(ui.kInternetCreatorUnit, &QLineEdit::textChanged, this, &SKGUnitPluginWidget::onUnitCreatorModified);
246     connect(ui.kSymbolCreatorUnit, &QLineEdit::textChanged, this, &SKGUnitPluginWidget::onUnitCreatorModified);
247     connect(ui.kObsolete, &QCheckBox::toggled, this, &SKGUnitPluginWidget::refreshUnitList);
248     connect(ui.kAmountEdit, &SKGCalculatorEdit::textChanged, this, &SKGUnitPluginWidget::onUnitCreatorModified);
249     connect(ui.kDeleteSource, &QToolButton::clicked, this, &SKGUnitPluginWidget::onDeleteSource);
250     connect(ui.kDownloadSource, static_cast<void (SKGComboBox::*)()>(&SKGComboBox::returnPressed), this, &SKGUnitPluginWidget::onAddSource);
251     connect(ui.kDownloadSource, &SKGComboBox::editTextChanged, this, &SKGUnitPluginWidget::onSourceChanged);
252     connect(ui.kGetNewHotStuff, &QToolButton::clicked, this, &SKGUnitPluginWidget::onGetNewHotStuff);
253 
254     // Fill combo box for currency
255     m_timer.setSingleShot(true);
256     connect(&m_timer, &QTimer::timeout, this, &SKGUnitPluginWidget::refreshUnitList);
257     m_timer.start(500);
258 
259     onSourceChanged();
260 }
261 
~SKGUnitPluginWidget()262 SKGUnitPluginWidget::~SKGUnitPluginWidget()
263 {
264     SKGTRACEINFUNC(10)
265 }
266 
eventFilter(QObject * iObject,QEvent * iEvent)267 bool SKGUnitPluginWidget::eventFilter(QObject* iObject, QEvent* iEvent)
268 {
269     if ((iEvent != nullptr) && iEvent->type() == QEvent::KeyPress) {
270         auto* keyEvent = dynamic_cast<QKeyEvent*>(iEvent);
271         if (keyEvent && (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && iObject == this) {
272             if ((QApplication::keyboardModifiers() & Qt::ControlModifier) != 0u && ui.kUnitAdd->isEnabled()) {
273                 ui.kUnitAdd->click();
274             } else if ((QApplication::keyboardModifiers() & Qt::ShiftModifier) != 0u && ui.kUnitUpdate->isEnabled()) {
275                 ui.kUnitUpdate->click();
276             }
277         }
278     }
279 
280     return SKGTabPage::eventFilter(iObject, iEvent);
281 }
282 
fillSourceList()283 void SKGUnitPluginWidget::fillSourceList()
284 {
285     // Get previous selected item
286     QString current = ui.kDownloadSource->text();
287 
288     // Fill
289     ui.kDownloadSource->clear();
290     ui.kDownloadSource->addItems(SKGUnitObject::downloadSources());
291     ui.kDeleteSource->hide();
292 
293     // Set previous selected itemData
294     if (!current.isEmpty() && ui.kDownloadSource->contains(current)) {
295         ui.kDownloadSource->setCurrentItem(current);
296     }
297 }
298 
onSelectionChanged()299 void SKGUnitPluginWidget::onSelectionChanged()
300 {
301     SKGTRACEINFUNC(10)
302     // Mapping
303     SKGUnitObject unit;
304 
305     int nbSelect = ui.kUnitTableViewEdition->getView()->getNbSelectedObjects();
306     if (nbSelect == 1) {
307         unit = ui.kUnitTableViewEdition->getView()->getFirstSelectedObject();
308         ui.kNameCreatorUnit->setText(unit.getName());
309         ui.kSymbolCreatorUnit->setText(unit.getSymbol());
310         ui.kCountryCreatorUnit->setText(unit.getCountry());
311         ui.kTypeCreatorUnit->setCurrentIndex(ui.kTypeCreatorUnit->findData(static_cast<int>(unit.getType())));
312         ui.kInternetCreatorUnit->setText(unit.getInternetCode());
313         ui.kUnitCreatorUnit->setText(unit.getAttribute(QStringLiteral("t_UNIT")));
314         ui.kNbDecimal->setValue(unit.getNumberDecimal());
315         ui.kDownloadSource->setText(unit.getDownloadSource());
316     } else if (nbSelect > 1) {
317         ui.kNameCreatorUnit->setText(NOUPDATE);
318         ui.kSymbolCreatorUnit->setText(NOUPDATE);
319         ui.kCountryCreatorUnit->setText(NOUPDATE);
320         ui.kTypeCreatorUnit->setText(NOUPDATE);
321         ui.kInternetCreatorUnit->setText(NOUPDATE);
322         ui.kUnitCreatorUnit->setText(NOUPDATE);
323         ui.kDownloadSource->setText(NOUPDATE);
324     }
325     ui.kUnitValueFrame->setEnabled(nbSelect == 1);
326     ui.kUnitValueDownload->setEnabled(nbSelect > 0);
327     ui.kUnitOpen->setEnabled(nbSelect > 0);
328 
329     // Fill values
330     QString wc = "rd_unit_id=(select id from unit where t_name='" % SKGServices::stringToSqlString(ui.kNameCreatorUnit->text()) % "')";
331     auto* objectModel = qobject_cast<SKGObjectModel*>(ui.kUnitValueTableViewEdition->model());
332     if (objectModel != nullptr) {
333         objectModel->setFilter(QLatin1String(""));    // Correction 2299600: to be sure that refresh will be done
334         objectModel->setFilter(wc % " order by d_date desc");
335         objectModel->refresh();
336     }
337 
338     ui.kUnitOfUnitLbl->setText(ui.kUnitCreatorUnit->text());
339 
340     // Draw plot
341     SKGStringListList table;
342     getDocument()->getConsolidatedView(QStringLiteral("v_unitvalue_display"), QStringLiteral("d_date"), QStringLiteral("t_UNIT"),
343                                        m_unitValueGraphCmb->currentIndex() == 0 ? QStringLiteral("f_quantity") : QStringLiteral("f_AMOUNTOWNED"),
344                                        QStringLiteral("TOTAL"), wc % " AND d_date>(SELECT date('now', 'localtime', '-50 year')) AND d_date<(SELECT date('now', 'localtime', '+50 year'))", table, QLatin1String(""));
345 
346     SKGServices::SKGUnitInfo primaryUnit = qobject_cast<SKGDocumentBank*>(getDocument())->getPrimaryUnit();
347     SKGServices::SKGUnitInfo secondaryUnit = qobject_cast<SKGDocumentBank*>(getDocument())->getSecondaryUnit();
348     if (unit.getType() == SKGUnitObject::INDEX) {
349         primaryUnit.Symbol = QLatin1String("");
350         secondaryUnit.Symbol = QLatin1String("");
351     } else {
352         SKGUnitObject parentUnitObject;
353         unit.getUnit(parentUnitObject);
354         SKGServices::SKGUnitInfo parentUnit = parentUnitObject.getUnitInfo();
355         if (primaryUnit.Symbol != parentUnit.Symbol) {
356             secondaryUnit = primaryUnit;
357             primaryUnit = parentUnit;
358 
359             secondaryUnit.Value = 1.0 / primaryUnit.Value;
360             primaryUnit.Value = 1;
361         }
362     }
363     ui.kGraph->setData(table, primaryUnit, secondaryUnit, SKGTableWithGraph::LIMITS);
364 
365     // Correction bug 2299394 vvv
366     if (ui.kUnitValueTableViewEdition->isAutoResized()) {
367         ui.kUnitValueTableViewEdition->resizeColumnsToContentsDelayed();
368     }
369     // Correction bug 2299394 ^^^
370 
371     onUnitCreatorModified();
372     Q_EMIT selectionChanged();
373 }
374 
onSelectionValueChanged()375 void SKGUnitPluginWidget::onSelectionValueChanged()
376 {
377     SKGTRACEINFUNC(10)
378     // Mapping
379     QItemSelectionModel* selModel = ui.kUnitValueTableViewEdition->selectionModel();
380     if (selModel != nullptr) {
381         QModelIndexList indexes = selModel->selectedRows();
382         int nbSelect = indexes.count();
383         if (nbSelect != 0) {
384             QModelIndex idx = indexes[indexes.count() - 1];
385 
386             auto* model = qobject_cast<SKGObjectModel*>(ui.kUnitValueTableViewEdition->model());
387             if (model != nullptr) {
388                 SKGUnitValueObject unitValue(model->getObject(idx));
389                 SKGUnitObject unit;
390                 unitValue.getUnit(unit);
391 
392                 ui.kDateEdit->setDate(unitValue.getDate());
393                 ui.kAmountEdit->setText(SKGServices::toCurrencyString(SKGServices::stringToDouble(unitValue.getAttribute(QStringLiteral("f_quantity"))),
394                                         QLatin1String(""),
395                                         SKGServices::stringToInt(unit.getAttribute(QStringLiteral("i_nbdecimal")))));
396             }
397         } else {
398             ui.kDateEdit->setDate(QDate::currentDate());
399             ui.kAmountEdit->setText(QLatin1String(""));
400         }
401         Q_EMIT selectionChanged();
402     }
403 }
404 
onUnitCreatorModified()405 void SKGUnitPluginWidget::onUnitCreatorModified()
406 {
407     SKGTRACEINFUNC(10)
408 
409     bool activated = ui.kWidgetSelector->getSelectedMode() != -1 &&
410                      !ui.kNameCreatorUnit->text().isEmpty()  &&
411                      !ui.kSymbolCreatorUnit->text().isEmpty();
412 
413     int nbSelect = getNbSelectedObjects();
414 
415     ui.kUnitAdd->setEnabled((activated && (ui.kAmountEdit->valid() || ui.kWidgetSelector->getSelectedMode() != 2)) || ui.kWidgetSelector->getSelectedMode() == 0);
416     ui.kUnitUpdate->setEnabled(activated && nbSelect > 0 && ui.kWidgetSelector->getSelectedMode() == 1);
417 
418     ui.kWidgetSelector->setEnabledMode(2, nbSelect == 1);
419     if (!(activated && nbSelect > 0) && ui.kWidgetSelector->getSelectedMode() == 2) {
420         ui.kWidgetSelector->setSelectedMode(0);
421     }
422 }
423 
onAddUnit()424 void SKGUnitPluginWidget::onAddUnit()
425 {
426     SKGError err;
427     SKGTRACEINFUNCRC(10, err)
428     int mode = ui.kWidgetSelector->getSelectedMode();
429 
430     if (mode == 0) {
431         QString untiname = ui.kCurrencyList->text();
432         SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Unit creation '%1'", untiname), err)
433         SKGUnitObject oUnit;
434         err = SKGUnitObject::createCurrencyUnit(qobject_cast<SKGDocumentBank*>(getDocument()), ui.kCurrencyList->text(), oUnit);
435     } else if (mode == 1) {
436         QString untiname = ui.kNameCreatorUnit->text();
437         SKGUnitObject unitObj(getDocument());
438         {
439             SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Unit creation '%1'", untiname), err)
440 
441             // Create unit object
442             IFOKDO(err, unitObj.setName(untiname))
443             IFOKDO(err, unitObj.setSymbol(ui.kSymbolCreatorUnit->text()))
444             IFOKDO(err, unitObj.setCountry(ui.kCountryCreatorUnit->text()))
445             IFOKDO(err, unitObj.setInternetCode(ui.kInternetCreatorUnit->text()))
446             IFOKDO(err, unitObj.setType(static_cast<SKGUnitObject::UnitType>(ui.kTypeCreatorUnit->itemData(ui.kTypeCreatorUnit->currentIndex()).toInt())))
447             IFOKDO(err, unitObj.setNumberDecimal(ui.kNbDecimal->value()))
448             IFOKDO(err, unitObj.setUnit(ui.kUnitCreatorUnit->getUnit()))
449             IFOKDO(err, unitObj.setDownloadSource(ui.kDownloadSource->text()))
450             IFOKDO(err, unitObj.save())
451         }
452 
453         // status bar
454         IFOK(err) {
455             err = SKGError(0, i18nc("Successful message after an user action", "Unit '%1' created", untiname));
456             ui.kUnitTableViewEdition->getView()->selectObject(unitObj.getUniqueID());
457         } else {
458             err.addError(ERR_FAIL, i18nc("Error message", "Unit creation failed"));
459         }
460     } else if (mode == 2) {
461         QString untiname = ui.kNameCreatorUnit->text();
462         SKGUnitValueObject unitValueObject;
463         {
464             SKGBEGINTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Unit value creation for '%1'", untiname), err)
465             IFOKDO(err, qobject_cast<SKGDocumentBank*>(getDocument())->addOrModifyUnitValue(untiname, ui.kDateEdit->date(), ui.kAmountEdit->value(), &unitValueObject))
466         }
467         // status bar
468         IFOK(err) {
469             err = SKGError(0, i18nc("Successful message after an user action", "Unit value created for '%1'", untiname));
470             // BUG: doesn't work because of unit table is modified an refreshed
471             ui.kUnitValueTableViewEdition->selectObject(unitValueObject.getUniqueID());
472         } else {
473             err.addError(ERR_FAIL, i18nc("Error message", "Unit value creation failed"));
474         }
475     }
476 
477     // Display error
478     SKGMainPanel::displayErrorMessage(err, true);
479 }
480 
onModifyUnit()481 void SKGUnitPluginWidget::onModifyUnit()
482 {
483     SKGError err;
484     SKGTRACEINFUNCRC(10, err)
485     // Get Selection
486     SKGObjectBase::SKGListSKGObjectBase selection = ui.kUnitTableViewEdition->getView()->getSelectedObjects();
487 
488     int nb = selection.count();
489 
490     {
491         SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Unit update"), err, nb)
492         auto name = ui.kNameCreatorUnit->text();
493         if (name != NOUPDATE && !name.startsWith(QLatin1String("="))) {
494             // Is this name already existing?
495             bool messageSent = false;
496             SKGUnitObject p(getDocument());
497             p.setName(name);
498             IFOK(p.load()) {
499                 if (selection.indexOf(p) == -1) {
500                     // We will have to merge with the existing unit
501                     selection.insert(0, p);
502                     nb++;
503 
504                     getDocument()->sendMessage(i18nc("Information message", "You tried to modify names of selected units to an existing unit. Units have been merged."));
505                     messageSent = true;
506                 }
507             }
508 
509             // Is it a massive modification of payees to merge them ?
510             if (nb > 1) {
511                 if (!messageSent) {
512                     getDocument()->sendMessage(i18nc("Information message", "You tried to modify all names of selected units. Units have been merged."));
513                 }
514 
515                 // Do the merge
516                 SKGUnitObject unitObj1(selection[0]);
517                 for (int i = 1; !err && i < nb; ++i) {
518                     SKGUnitObject unitObj(selection.at(i));
519                     err = unitObj1.merge(unitObj);
520                 }
521 
522                 // Change selection for the rest of the operation
523                 selection.clear();
524                 selection.push_back(unitObj1);
525                 nb = 1;
526             }
527         }
528 
529         for (int i = 0; !err && i < nb; ++i) {
530             // Modification of unit object
531             SKGUnitObject unitObj(selection.at(i));
532             IFOKDO(err, unitObj.setName(name))
533             IFOKDO(err, unitObj.setSymbol(ui.kSymbolCreatorUnit->text()))
534             IFOKDO(err, unitObj.setCountry(ui.kCountryCreatorUnit->text()))
535             IFOKDO(err, unitObj.setInternetCode(ui.kInternetCreatorUnit->text()))
536             if (!err && ui.kTypeCreatorUnit->text() != NOUPDATE) {
537                 err = unitObj.setType(static_cast<SKGUnitObject::UnitType>(ui.kTypeCreatorUnit->itemData(ui.kTypeCreatorUnit->currentIndex()).toInt()));
538             }
539             IFOKDO(err, unitObj.setNumberDecimal(ui.kNbDecimal->value()))
540             if (!err && ui.kUnitCreatorUnit->text() != NOUPDATE) {
541                 err = unitObj.setUnit(ui.kUnitCreatorUnit->getUnit());
542             }
543             if (!err && ui.kDownloadSource->text() != NOUPDATE) {
544                 err = unitObj.setDownloadSource(ui.kDownloadSource->text());
545             }
546             IFOKDO(err, unitObj.save())
547 
548             // Send message
549             IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The unit '%1' has been updated", unitObj.getDisplayName()), SKGDocument::Hidden))
550 
551             IFOKDO(err, getDocument()->stepForward(i + 1))
552         }
553     }
554 
555     // status bar
556     IFOKDO(err, SKGError(0, i18nc("Message for successful user action", "Unit updated")))
557     else {
558         err.addError(ERR_FAIL, i18nc("Error message", "Unit update failed"));
559     }
560 
561     // Display error
562     SKGMainPanel::displayErrorMessage(err, true);
563 
564     // Set focus on table
565     ui.kUnitTableViewEdition->getView()->setFocus();
566 }
567 
getDownloadModeFromSettings()568 SKGUnitObject::UnitDownloadMode SKGUnitPluginWidget::getDownloadModeFromSettings()
569 {
570     SKGUnitObject::UnitDownloadMode mode = SKGUnitObject::LAST;
571     if (skgunit_settings::last()) {
572         mode = SKGUnitObject::LAST;
573     } else if (skgunit_settings::last_monthly()) {
574         mode = SKGUnitObject::LAST_MONTHLY;
575     } else if (skgunit_settings::last_weekly()) {
576         mode = SKGUnitObject::LAST_WEEKLY;
577     } else if (skgunit_settings::last_daily()) {
578         mode = SKGUnitObject::LAST_DAILY;
579     } else if (skgunit_settings::all_monthly()) {
580         mode = SKGUnitObject::ALL_MONTHLY;
581     } else if (skgunit_settings::all_weekly()) {
582         mode = SKGUnitObject::ALL_WEEKLY;
583     } else if (skgunit_settings::all_daily()) {
584         mode = SKGUnitObject::ALL_DAILY;
585     }
586     return mode;
587 }
588 
downloadUnitValue(const SKGUnitObject & iUnit,SKGUnitObject::UnitDownloadMode iMode)589 SKGError SKGUnitPluginWidget::downloadUnitValue(const SKGUnitObject& iUnit, SKGUnitObject::UnitDownloadMode iMode)
590 {
591     SKGError err;
592     SKGTRACEINFUNCRC(10, err)
593 
594     QString unitname = iUnit.getName();
595     QString code = iUnit.getInternetCode();
596     auto* doc = qobject_cast<SKGDocumentBank*>(iUnit.getDocument());
597     if (!code.isEmpty() && (doc != nullptr)) {
598         SKGBEGINTRANSACTION(*doc, i18nc("Noun, name of the user action", "Download values for [%1 (%2)]", unitname, code), err)
599         err = const_cast<SKGUnitObject*>(&iUnit)->downloadUnitValue(iMode, skgunit_settings::nb_loaded_values());
600     }
601 
602     return err;
603 }
604 
onDownloadUnitValue()605 void SKGUnitPluginWidget::onDownloadUnitValue()
606 {
607     SKGError err;
608     SKGTRACEINFUNCRC(10, err)
609 
610     SKGUnitObject::UnitDownloadMode mode = SKGUnitObject::LAST;
611     auto* act = qobject_cast<QAction*>(sender());
612     if (act != nullptr) {
613         mode = static_cast<SKGUnitObject::UnitDownloadMode>(act->data().toInt());
614     } else {
615         mode = SKGUnitPluginWidget::getDownloadModeFromSettings();
616     }
617 
618     SKGObjectBase::SKGListSKGObjectBase selection = ui.kUnitTableViewEdition->getView()->getSelectedObjects();
619     int nb = selection.count();
620     if (nb != 0) {
621         SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Download values"), err, nb)
622         for (int i = 0; !err && i < nb; ++i) {
623             SKGUnitObject unit(selection.at(i));
624             err = downloadUnitValue(unit, mode);
625 
626             // Send message
627             IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The unit '%1' has been downloaded", unit.getDisplayName()), SKGDocument::Hidden))
628 
629             IFOKDO(err, getDocument()->stepForward(i + 1))
630         }
631     }
632 
633     IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Download done")))
634     else {
635         err.addError(ERR_FAIL, i18nc("Error message", "Download failed"));
636     }
637 
638     // Display error
639     SKGMainPanel::displayErrorMessage(err);
640 }
641 
onSimplify()642 void SKGUnitPluginWidget::onSimplify()
643 {
644     SKGError err;
645     SKGTRACEINFUNCRC(10, err)
646 
647     SKGObjectBase::SKGListSKGObjectBase selection = ui.kUnitTableViewEdition->getView()->getSelectedObjects();
648     int nb = selection.count();
649     if (nb != 0) {
650         SKGBEGINPROGRESSTRANSACTION(*getDocument(), i18nc("Noun, name of the user action", "Simplify unit values"), err, nb)
651         for (int i = 0; !err && i < nb; ++i) {
652             SKGUnitObject unit(selection.at(i));
653             err = unit.simplify();
654 
655             // Send message
656             IFOKDO(err, getDocument()->sendMessage(i18nc("An information to the user", "The unit '%1' has been simplified", unit.getDisplayName()), SKGDocument::Hidden))
657 
658             IFOKDO(err, getDocument()->stepForward(i + 1))
659         }
660     }
661 
662     IFOKDO(err, SKGError(0, i18nc("Successful message after an user action", "Simplification done")))
663     else {
664         err.addError(ERR_FAIL, i18nc("Error message", "Simplification failed"));
665     }
666 
667     // Display error
668     SKGMainPanel::displayErrorMessage(err);
669 }
670 
getSelectedObjects()671 SKGObjectBase::SKGListSKGObjectBase SKGUnitPluginWidget::getSelectedObjects()
672 {
673     SKGObjectBase::SKGListSKGObjectBase output;
674     if (ui.kUnitValueTableViewEdition->hasFocus()) {
675         output = ui.kUnitValueTableViewEdition->getSelectedObjects();
676     }
677     if (output.isEmpty()) {
678         output = ui.kUnitTableViewEdition->getView()->getSelectedObjects();
679     }
680     return output;
681 }
682 
getNbSelectedObjects()683 int SKGUnitPluginWidget::getNbSelectedObjects()
684 {
685     int output = 0;
686     if (ui.kUnitValueTableViewEdition->hasFocus()) {
687         output = ui.kUnitValueTableViewEdition->getNbSelectedObjects();
688     }
689     if (output == 0) {
690         output = ui.kUnitTableViewEdition->getView()->getNbSelectedObjects();
691     }
692     return output;
693 }
694 
695 
getState()696 QString SKGUnitPluginWidget::getState()
697 {
698     SKGTRACEINFUNC(10)
699     QDomDocument doc(QStringLiteral("SKGML"));
700     QDomElement root = doc.createElement(QStringLiteral("parameters"));
701     doc.appendChild(root);
702 
703     root.setAttribute(QStringLiteral("splitter1State"), QString(ui.kMainSplitter->saveState().toHex()));
704     root.setAttribute(QStringLiteral("splitter2State"), QString(ui.kValuesSplitter->saveState().toHex()));
705 
706     // Memorize table settings
707     root.setAttribute(QStringLiteral("unitview"), ui.kUnitTableViewEdition->getState());
708     root.setAttribute(QStringLiteral("unitvalueview"), ui.kUnitValueTableViewEdition->getState());
709     root.setAttribute(QStringLiteral("currentPage"), SKGServices::intToString(ui.kWidgetSelector->getSelectedMode()));
710     root.setAttribute(QStringLiteral("obsolete"), ui.kObsolete->isChecked() ? QStringLiteral("Y") : QStringLiteral("N"));
711     root.setAttribute(QStringLiteral("graphSettings"), ui.kGraph->getState());
712     root.setAttribute(QStringLiteral("unitvaluegraphmode"), m_unitValueGraphCmb->currentIndex());
713 
714     return doc.toString();
715 }
716 
setState(const QString & iState)717 void SKGUnitPluginWidget::setState(const QString& iState)
718 {
719     SKGTRACEINFUNC(10)
720     QDomDocument doc(QStringLiteral("SKGML"));
721     doc.setContent(iState);
722     QDomElement root = doc.documentElement();
723 
724     QString splitter1State = root.attribute(QStringLiteral("splitter1State"));
725     QString splitter2State = root.attribute(QStringLiteral("splitter2State"));
726     QString currentPage = root.attribute(QStringLiteral("currentPage"));
727     QString obsolete = root.attribute(QStringLiteral("obsolete"));
728     QString unitvaluegraphmode = root.attribute(QStringLiteral("unitvaluegraphmode"));
729 
730 
731     if (currentPage.isEmpty()) {
732         currentPage = '0';
733     }
734 
735     if (!splitter1State.isEmpty()) {
736         ui.kMainSplitter->restoreState(QByteArray::fromHex(splitter1State.toLatin1()));
737     }
738     if (!splitter2State.isEmpty()) {
739         ui.kValuesSplitter->restoreState(QByteArray::fromHex(splitter2State.toLatin1()));
740     }
741     ui.kWidgetSelector->setSelectedMode(SKGServices::stringToInt(currentPage));
742     ui.kObsolete->setChecked(obsolete == QStringLiteral("Y"));
743 
744     ui.kUnitTableViewEdition->setState(root.attribute(QStringLiteral("unitview")));
745     ui.kUnitValueTableViewEdition->setState(root.attribute(QStringLiteral("unitvalueview")));
746     ui.kGraph->setState(root.attribute(QStringLiteral("graphSettings")));
747     ui.kGraph->setGraphType(SKGTableWithGraph::LINE);
748     if (!unitvaluegraphmode.isEmpty()) {
749         m_unitValueGraphCmb->setCurrentIndex(SKGServices::stringToInt(unitvaluegraphmode));
750     }
751 }
752 
getDefaultStateAttribute()753 QString SKGUnitPluginWidget::getDefaultStateAttribute()
754 {
755     return QStringLiteral("SKGUNIT_DEFAULT_PARAMETERS");
756 }
757 
dataModified(const QString & iTableName,int iIdTransaction)758 void SKGUnitPluginWidget::dataModified(const QString& iTableName, int iIdTransaction)
759 {
760     SKGTRACEINFUNC(10)
761     Q_UNUSED(iIdTransaction)
762 
763     if (iTableName == QStringLiteral("unitvalue") || iTableName.isEmpty()) {
764         // Correction bug 2299394 vvv
765         if (ui.kUnitValueTableViewEdition->isAutoResized()) {
766             ui.kUnitValueTableViewEdition->resizeColumnsToContentsDelayed();
767         }
768         // Correction bug 2299394 ^^^
769     }
770 }
771 
cleanEditor()772 void SKGUnitPluginWidget::cleanEditor()
773 {
774     if (getNbSelectedObjects() == 0) {
775         ui.kNameCreatorUnit->setText(QLatin1String(""));
776         ui.kSymbolCreatorUnit->setText(QLatin1String(""));
777         ui.kCountryCreatorUnit->setText(QLatin1String(""));
778         ui.kInternetCreatorUnit->setText(QLatin1String(""));
779         ui.kUnitCreatorUnit->setText(QLatin1String(""));
780     }
781 }
782 
isEditor()783 bool SKGUnitPluginWidget::isEditor()
784 {
785     return true;
786 }
787 
activateEditor()788 void SKGUnitPluginWidget::activateEditor()
789 {
790     if (ui.kWidgetSelector->getSelectedMode() == -1) {
791         ui.kWidgetSelector->setSelectedMode(0);
792     }
793     ui.kCurrencyList->setFocus();
794 }
795 
refreshUnitList()796 void SKGUnitPluginWidget::refreshUnitList()
797 {
798     QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
799     // Clean list
800     ui.kCurrencyList->clear();
801 
802     // Add items
803     QStringList list = SKGUnitObject::getListofKnownCurrencies(ui.kObsolete->isChecked());
804     ui.kCurrencyList->addItems(list);
805 
806     // Completion
807     KCompletion* comp = ui.kCurrencyList->completionObject();
808     if (comp != nullptr) {
809         comp->setIgnoreCase(true);
810         comp->setSoundsEnabled(true);
811         comp->clear();
812         comp->insertItems(list);
813     }
814     QApplication::restoreOverrideCursor();
815 }
816 
mainWidget()817 QWidget* SKGUnitPluginWidget::mainWidget()
818 {
819     if (ui.kUnitValueTableViewEdition->hasFocus()) {
820         return ui.kUnitValueTableViewEdition;
821     }
822     return ui.kUnitTableViewEdition->getView();
823 }
824 
onAddSource()825 void SKGUnitPluginWidget::onAddSource()
826 {
827     QString source = ui.kDownloadSource->text().trimmed();
828     if (!source.isEmpty() &&
829         (!SKGUnitObject::downloadSources().contains(source) || SKGUnitObject::isWritable(source))) {
830         // This is a new source
831         SKGError err = SKGUnitObject::addSource(source);
832         onSourceChanged();
833 
834         // Display error
835         SKGMainPanel::displayErrorMessage(err);
836     }
837 }
838 
onDeleteSource()839 void SKGUnitPluginWidget::onDeleteSource()
840 {
841     QString source = ui.kDownloadSource->text();
842     if (!source.isEmpty() && SKGUnitObject::downloadSources().contains(source)) {
843         // This is a new source
844         SKGError err = SKGUnitObject::deleteSource(source);
845         IFOK(err) ui.kDownloadSource->removeItem(ui.kDownloadSource->findText(source));
846 
847         // Display error
848         SKGMainPanel::displayErrorMessage(err);
849     }
850 }
851 
onSourceChanged()852 void SKGUnitPluginWidget::onSourceChanged()
853 {
854     QString source = ui.kDownloadSource->text().trimmed();
855     bool local = !source.isEmpty() && SKGUnitObject::isWritable(source);
856     ui.kDeleteSource->setVisible(local);
857     m_upload->setEnabled(local);
858 
859     static QString tooltipOrigin;
860     if (tooltipOrigin.isEmpty()) {
861         tooltipOrigin = ui.kInternetCreatorUnit->toolTip();
862     }
863 
864     QString tooltip = tooltipOrigin;
865     auto help = SKGUnitObject::getCommentFromSource(source);
866     if (!help.isEmpty()) {
867         tooltip += "<br/>" + i18nc("Help meeage in tooltip", "Here is the help for the selected source '%1':<br/>%2", source, help);
868     }
869     ui.kSourceHelp->setText(help);
870 
871     // Set tooltip on internet code
872     ui.kInternetCreatorUnit->setToolTip(tooltip);
873 }
874 
onGetNewHotStuff()875 void SKGUnitPluginWidget::onGetNewHotStuff()
876 {
877     QPointer<KNS3::DownloadDialog> dialog = new KNS3::DownloadDialog(QStringLiteral("skrooge_unit.knsrc"), this);
878     dialog->exec();
879 
880     fillSourceList();
881 }
882 
onPutNewHotStuff()883 void SKGUnitPluginWidget::onPutNewHotStuff()
884 {
885     QString source = ui.kDownloadSource->text().trimmed();
886 
887     // Create zip file
888     QString sourceFileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1Char('/') + QStringLiteral("skrooge/quotes/") % source % ".txt";
889     QString zipFileName = QDir::tempPath() % "/" % source % ".zip";
890     KZip zip(zipFileName);
891     if (zip.open(QIODevice::WriteOnly)) {
892         zip.addLocalFile(sourceFileName, source % ".txt");
893         zip.close();
894 
895         // Open dialog
896         QPointer<KNS3::UploadDialog> dialog = new KNS3::UploadDialog(QStringLiteral("skrooge_unit.knsrc"), this);
897 
898         dialog->setUploadFile(QUrl::fromLocalFile(zipFileName));
899         dialog->setUploadName(source);
900         dialog->setDescription(i18nc("Default description for the source", "My favorite source of download for units"));
901         dialog->setVersion(QStringLiteral("0.1"));
902         dialog->setChangelog(QStringLiteral("V0.1 - Initial version"));
903         dialog->exec();
904 
905         // Delete temporary files
906         QFile(zipFileName).remove();
907     }
908 }
909 
onOpenURL()910 void SKGUnitPluginWidget::onOpenURL()
911 {
912     SKGError err;
913     SKGTRACEINFUNCRC(10, err)
914 
915     SKGObjectBase::SKGListSKGObjectBase selection = ui.kUnitTableViewEdition->getView()->getSelectedObjects();
916     int nb = selection.count();
917     if (nb != 0) {
918         for (int i = 0; !err && i < nb; ++i) {
919             SKGUnitObject unit(selection.at(i));
920             err = unit.openURL();
921         }
922     }
923 
924     // Display error
925     SKGMainPanel::displayErrorMessage(err);
926 }
927 
928 
929