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 akonadi resource.
8 *
9 * @author Stephane MANKOWSKI / Guillaume DE BURE
10 */
11 #include "skroogeakonadiresource.h"
12
13 #ifdef SKG_DBUS
14 #include <qdbusconnection.h>
15 #endiff
16
17 #include <kdirwatch.h>
18 #include <klocalizedstring.h>
19
20 #include <akonadicore/entitydisplayattribute.h>
21 #include <kcalcore/todo.h>
22 #include <kpassworddialog.h>
23 #include <qfiledialog.h>
24
25 #include "settings.h"
26 #include "settingsadaptor.h"
27 #include "skgcategoryobject.h"
28 #include "skgdocumentbank.h"
29 #include "skgoperationobject.h"
30 #include "skgrecurrentoperationobject.h"
31
skroogeakonadiResource(const QString & id)32 skroogeakonadiResource::skroogeakonadiResource(const QString& id) : ResourceBase(id)
33 {
34 setObjectName(QStringLiteral("SkroogeResource"));
35 setNeedsNetwork(false);
36
37 new SettingsAdaptor(Settings::self());
38 #ifdef SKG_DBUS
39 QDBusConnection::sessionBus().registerObject(QStringLiteral("/Settings"),
40 Settings::self(), QDBusConnection::ExportAdaptors);
41 #endif
42
43 if (!KDirWatch::self()->contains(Settings::self()->path())) {
44 KDirWatch::self()->addFile(Settings::self()->path());
45 }
46 QObject::connect(KDirWatch::self(), &KDirWatch::dirty, this, &skroogeakonadiResource::refresh);
47
48 synchronize();
49 }
50
51 skroogeakonadiResource::~skroogeakonadiResource() = default;
52
retrieveCollections()53 void skroogeakonadiResource::retrieveCollections()
54 {
55 Akonadi::Collection c;
56 c.setRemoteId(Settings::self()->path());
57 c.setName(i18nc("Name of a collection akonadi", "Skrooge scheduled operations"));
58 c.setRights(Akonadi::Collection::ReadOnly);
59 c.setParentCollection(Akonadi::Collection::root());
60 c.setContentMimeTypes(QStringList() << QStringLiteral("application/x-vnd.akonadi.calendar.todo"));
61
62 Akonadi::EntityDisplayAttribute* const attribute = new Akonadi::EntityDisplayAttribute();
63 attribute->setIconName("skrooge");
64 c.addAttribute(attribute);
65
66 collectionsRetrieved(Akonadi::Collection::List() << c);
67
68 if (!KDirWatch::self()->contains(Settings::self()->path())) {
69 KDirWatch::self()->addFile(Settings::self()->path());
70 }
71 }
72
retrieveItems(const Akonadi::Collection & collection)73 void skroogeakonadiResource::retrieveItems(const Akonadi::Collection& collection)
74 {
75 Akonadi::Item::List items;
76
77 // Open the document
78 SKGDocumentBank doc;
79 SKGError err = doc.load(collection.remoteId(), Settings::self()->password(), false, true);
80 IFOK(err) {
81 SKGObjectBase::SKGListSKGObjectBase objs;
82 err = doc.getObjects(QStringLiteral("v_recurrentoperation_display"), QStringLiteral("i_nb_times!=0 ORDER BY d_date"), objs);
83 IFOK(err) {
84 int nb = objs.count();
85 if (nb) {
86 for (int i = 0; i < nb; ++i) {
87 Akonadi::Item item(QStringLiteral("application/x-vnd.akonadi.calendar.todo"));
88 item.setRemoteId(collection.remoteId() % ";" % SKGServices::intToString(objs.at(i).getID()));
89
90 items << item;
91 }
92 }
93 }
94 }
95 doc.close();
96
97 itemsRetrieved(items);
98 }
99
retrieveItem(const Akonadi::Item & item,const QSet<QByteArray> & parts)100 bool skroogeakonadiResource::retrieveItem(const Akonadi::Item& item, const QSet<QByteArray>& parts)
101 {
102 Q_UNUSED(parts)
103 QStringList params = SKGServices::splitCSVLine(item.remoteId(), ';');
104
105 bool output = false;
106 SKGDocumentBank doc;
107 SKGError err = doc.load(params.at(0), Settings::self()->password(), false, true);
108 IFOK(err) {
109 SKGRecurrentOperationObject obj(&doc, SKGServices::stringToInt(params.at(1)));
110 SKGOperationObject op;
111 obj.getParentOperation(op);
112
113 KCalCore::auto akonadiItem = new KCalCore::Todo();
114 KCalCore::Todo::Ptr akonadiItemPtr(akonadiItem);
115 akonadiItem->setDtDue(KDateTime(obj.getDate()));
116 akonadiItem->setDescription(op.getDisplayName().right(op.getDisplayName().count() - 11));
117 if (!obj.hasTimeLimit() || obj.getTimeLimit() > 1) {
118 akonadiItem->setDtRecurrence(KDateTime(obj.getNextDate()));
119 }
120
121 SKGOperationObject ope;
122 obj.getParentOperation(ope);
123 akonadiItem->setCategories(QStringList() << ope.getAttribute(QStringLiteral("t_CATEGORY")));
124
125 Akonadi::Item newItem(item);
126 newItem.setMimeType(QStringLiteral("application/x-vnd.akonadi.calendar.todo"));
127 newItem.setPayload<KCalCore::Incidence::Ptr>(akonadiItemPtr);
128
129 itemRetrieved(newItem);
130 output = true;
131 }
132 doc.close();
133
134 return output;
135 }
136
configure(WId windowId)137 void skroogeakonadiResource::configure(WId windowId)
138 {
139 Q_UNUSED(windowId)
140
141 // Get the old path
142 const QString oldPath = Settings::self()->path();
143 QUrl url;
144 if (!oldPath.isEmpty()) {
145 url = QUrl::fromLocalFile(oldPath);
146 } else {
147 url = QUrl::fromLocalFile(QDir::homePath());
148 }
149
150 const QString newPath = QFileDialog::getOpenFileName("Skrooge document", 0, url, "*.skg|" % i18nc("A file format", "Skrooge document"), 0, i18nc("@title:window", "Select Skrooge document"));
151
152 if (newPath.isEmpty() || oldPath == newPath) {
153 return;
154 }
155
156 // Password dialog
157 QString password;
158 QPointer<KPasswordDialog> dlg = new KPasswordDialog();
159 dlg->setPrompt(i18nc("Question", "If the file is protected.\nPlease enter the password."));
160 if (dlg->exec() == QDialog::Accepted) {
161 password = dlg->password();
162 }
163 delete dlg;
164
165 // Save settings
166 Settings::self()->setPath(newPath);
167 Settings::self()->setPassword(password);
168 Settings::self()->save();
169
170 KDirWatch::self()->removeDir(oldPath);
171 KDirWatch::self()->addFile(newPath);
172
173 synchronize();
174 }
175
refresh()176 void skroogeakonadiResource::refresh()
177 {
178 invalidateCache(currentCollection());
179 synchronize();
180 }
181
182 AKONADI_RESOURCE_MAIN(skroogeakonadiResource)
183
184
185