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)
103 if (createjob->error()) {
104 setErrorMessage(i18n(
"Error creating ical resource: %1", createjob->errorString()));
105 emit q->importIntoNewFinished(
false);
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."));
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)));
Job for creating new agent instances.
void start()
Starts the instance creation.
AgentInstance instance() const
Returns the AgentInstance object of the newly created agent instance.
A representation of an 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.
A representation of an agent type.
Represents a collection of PIM items.
FreeBusyManager::Singleton.