22#include "icalimporter.h"
23#include "icalimporter_p.h"
26#include <akonadi/agentmanager.h>
27#include <akonadi/agentinstancecreatejob.h>
29#include <kcalcore/filestorage.h>
30#include <kcalcore/memorycalendar.h>
31#include <kcalcore/event.h>
32#include <kcalcore/todo.h>
33#include <kcalcore/journal.h>
36#include <KLocalizedString>
40#include <KIO/JobClasses>
41#include <KIO/Scheduler>
42#include <KTemporaryFile>
46#include <QDBusInterface>
48using namespace KCalCore;
51ICalImporter::Private::Private(IncidenceChanger *changer,
52 ICalImporter *qq) : QObject(), q(qq)
59 m_changer =
new IncidenceChanger(q);
61 connect(m_changer, SIGNAL(createFinished(
int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)),
62 SLOT(onIncidenceCreated(
int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)));
66ICalImporter::Private::~Private()
68 delete m_temporaryFile;
71void ICalImporter::Private::onIncidenceCreated(
int changeId,
72 const Akonadi::Item &,
73 Akonadi::IncidenceChanger::ResultCode resultCode,
74 const QString &errorString)
76 if (!m_pendingRequests.contains(changeId))
79 m_pendingRequests.removeAll(changeId);
81 if (resultCode != IncidenceChanger::ResultCodeSuccess) {
83 setErrorMessage(errorString);
84 m_pendingRequests.clear();
85 emit q->importIntoExistingFinished(
false, m_numIncidences);
86 }
else if (m_pendingRequests.isEmpty()) {
88 emit q->importIntoExistingFinished(
true, m_numIncidences);
92void ICalImporter::Private::setErrorMessage(
const QString &message)
94 m_lastErrorMessage = message;
98void ICalImporter::Private::resourceCreated(KJob *job)
100 Akonadi::AgentInstanceCreateJob *createjob = qobject_cast<Akonadi::AgentInstanceCreateJob*>(job);
103 if (createjob->error()) {
104 setErrorMessage(i18n(
"Error creating ical resource: %1", createjob->errorString()));
105 emit q->importIntoNewFinished(
false);
109 Akonadi::AgentInstance instance = createjob->
instance();
110 QDBusInterface iface(QString::fromLatin1(
"org.freedesktop.Akonadi.Resource.%1").arg(instance.
identifier()), QLatin1String(
"/Settings"));
112 if (!iface.isValid()) {
113 setErrorMessage(i18n(
"Failed to obtain D-Bus interface for remote configuration."));
114 emit q->importIntoNewFinished(
false);
118 const QString path = createjob->property(
"path").toString();
119 Q_ASSERT(!path.isEmpty());
121 iface.call(QLatin1String(
"setPath"), path);
124 emit q->importIntoNewFinished(
true);
127void ICalImporter::Private::remoteDownloadFinished(KIO::Job *job,
const QByteArray &data)
129 const bool success = job->error() == 0;
132 delete m_temporaryFile;
133 m_temporaryFile =
new KTemporaryFile();
134 m_temporaryFile->write(data.constData(), data.count());
135 q->importIntoExistingResource(QUrl(m_temporaryFile->fileName()), m_collection);
137 setErrorMessage(i18n(
"Could not download remote file."));
138 emit q->importIntoExistingFinished(
false, 0);
142ICalImporter::ICalImporter(Akonadi::IncidenceChanger *changer,
143 QObject *parent) : QObject(parent)
144 , d(new Private(changer, this))
148QString ICalImporter::errorMessage()
const
150 return d->m_lastErrorMessage;
153bool ICalImporter::importIntoNewResource(
const QString &filename)
155 d->m_lastErrorMessage.clear();
158 d->setErrorMessage(i18n(
"An import task is already in progress."));
165 Akonadi::AgentInstanceCreateJob *job =
new Akonadi::AgentInstanceCreateJob(type,
this);
166 job->setProperty(
"path", filename);
167 connect(job, SIGNAL(result(KJob*)), d, SLOT(resourceCreated(KJob*)));
173bool ICalImporter::importIntoExistingResource(
const QUrl &url, Akonadi::Collection collection)
175 d->m_lastErrorMessage.clear();
178 d->setErrorMessage(i18n(
"An import task is already in progress."));
183 d->setErrorMessage(i18n(
"Empty filename. Will not import ical file."));
187 if (!url.isValid()) {
188 d->setErrorMessage(i18n(
"Url to import is malformed."));
192 if (url.isLocalFile()) {
193 if (!QFile::exists(url.path())) {
194 d->setErrorMessage(i18n(
"The specified file doesn't exist, aborting import."));
197 MemoryCalendar::Ptr temporaryCalendar(
new MemoryCalendar(KDateTime::LocalZone));
198 FileStorage storage(temporaryCalendar);
199 storage.setFileName(url.path());
200 bool success = storage.load();
202 d->setErrorMessage(i18n(
"Failed to load ical file, check permissions."));
206 d->m_pendingRequests.clear();
207 Incidence::List incidences = temporaryCalendar->incidences();
209 if (incidences.isEmpty()) {
210 d->setErrorMessage(i18n(
"The ical file to merge is empty."));
214 if (!collection.isValid()) {
216 QStringList mimeTypes = QStringList() << KCalCore::Event::eventMimeType() << KCalCore::Todo::todoMimeType()
217 << KCalCore::Journal::journalMimeType();
218 collection = CalendarUtils::selectCollection(0, dialogCode , mimeTypes);
221 if (!collection.isValid()) {
223 d->setErrorMessage(QString());
227 const IncidenceChanger::DestinationPolicy policySaved = d->m_changer->destinationPolicy();
228 d->m_changer->startAtomicOperation(i18n(
"Merge ical file into existing calendar."));
229 d->m_changer->setDestinationPolicy(IncidenceChanger::DestinationPolicyNeverAsk);
230 foreach(
const Incidence::Ptr &incidence, incidences) {
234 const int requestId = d->m_changer->createIncidence(incidence, collection);
235 Q_ASSERT(requestId != -1);
237 d->m_pendingRequests << requestId;
239 d->m_changer->endAtomicOperation();
241 d->m_changer->setDestinationPolicy(policySaved);
242 d->m_numIncidences = incidences.count();
244 d->m_collection = collection;
245 KIO::StoredTransferJob *job = KIO::storedGet(KUrl(url));
246 connect(job, SIGNAL(data(KIO::Job*,QByteArray)), d, SLOT(remoteDownloadFinished(KIO::Job*,QByteArray)));
void start()
Starts the instance creation.
AgentInstance instance() const
Returns the AgentInstance object of the newly created agent instance.
QString identifier() const
Returns the unique identifier of the agent instance.
void reconfigure() const
Tell the agent that its configuration has been changed remotely via D-Bus.
AgentType type(const QString &identifier) const
Returns the agent type with the given identifier or an invalid agent type if the identifier does not ...
static AgentManager * self()
Returns the global instance of the agent manager.
FreeBusyManager::Singleton.