• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepimlibs API Reference
  • KDE Home
  • Contact Us
 

akonadi

  • sources
  • kde-4.12
  • kdepimlibs
  • akonadi
  • calendar
icalimporter.cpp
1 
22 #include "icalimporter.h"
23 #include "icalimporter_p.h"
24 #include "utils_p.h"
25 
26 #include <akonadi/agentmanager.h>
27 #include <akonadi/agentinstancecreatejob.h>
28 
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>
34 
35 #include <KJob>
36 #include <KLocale>
37 #include <KDebug>
38 #include <KDateTime>
39 #include <KUrl>
40 #include <KIO/JobClasses>
41 #include <KIO/Scheduler>
42 #include <KTemporaryFile>
43 
44 #include <QUrl>
45 #include <QFile>
46 #include <QMetaObject>
47 #include <QDBusInterface>
48 
49 using namespace KCalCore;
50 using namespace Akonadi;
51 
52 ICalImporter::Private::Private(IncidenceChanger *changer,
53  ICalImporter *qq) : QObject(), q(qq)
54  , m_changer(changer)
55  , m_numIncidences(0)
56  , m_working(false)
57  , m_temporaryFile(0)
58 {
59  if (!changer) {
60  m_changer = new IncidenceChanger(q);
61  }
62  connect(m_changer, SIGNAL(createFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)),
63  SLOT(onIncidenceCreated(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)));
64 
65 }
66 
67 ICalImporter::Private::~Private()
68 {
69  delete m_temporaryFile;
70 }
71 
72 void ICalImporter::Private::onIncidenceCreated(int changeId,
73  const Akonadi::Item &,
74  Akonadi::IncidenceChanger::ResultCode resultCode,
75  const QString &errorString)
76 {
77  if (!m_pendingRequests.contains(changeId))
78  return; // Not ours
79 
80  m_pendingRequests.removeAll(changeId);
81 
82  if (resultCode != IncidenceChanger::ResultCodeSuccess) {
83  m_working = false;
84  setErrorMessage(errorString);
85  m_pendingRequests.clear();
86  emit q->importIntoExistingFinished(false, m_numIncidences);
87  } else if (m_pendingRequests.isEmpty()) {
88  m_working = false;
89  emit q->importIntoExistingFinished(true, m_numIncidences);
90  }
91 }
92 
93 void ICalImporter::Private::setErrorMessage(const QString &message)
94 {
95  m_lastErrorMessage = message;
96  kError() << message;
97 }
98 
99 void ICalImporter::Private::resourceCreated(KJob *job)
100 {
101  Akonadi::AgentInstanceCreateJob *createjob = qobject_cast<Akonadi::AgentInstanceCreateJob*>(job);
102  Q_ASSERT(createjob);
103  m_working = false;
104  if (createjob->error()) {
105  setErrorMessage(i18n("Error creating ical resource: %1", createjob->errorString()));
106  emit q->importIntoNewFinished(false);
107  return;
108  }
109 
110  Akonadi::AgentInstance instance = createjob->instance();
111  QDBusInterface iface(QString::fromLatin1("org.freedesktop.Akonadi.Resource.%1").arg(instance.identifier()), QLatin1String("/Settings"));
112 
113  if (!iface.isValid()) {
114  setErrorMessage(i18n("Failed to obtain D-Bus interface for remote configuration."));
115  emit q->importIntoNewFinished(false);
116  return;
117  }
118 
119  const QString path = createjob->property("path").toString();
120  Q_ASSERT(!path.isEmpty());
121 
122  iface.call(QLatin1String("setPath"), path);
123  instance.reconfigure();
124 
125  emit q->importIntoNewFinished(true);
126 }
127 
128 void ICalImporter::Private::remoteDownloadFinished(KIO::Job *job, const QByteArray &data)
129 {
130  const bool success = job->error() == 0;
131  m_working = false;
132  if (success) {
133  delete m_temporaryFile;
134  m_temporaryFile = new KTemporaryFile();
135  m_temporaryFile->write(data.constData(), data.count());
136  q->importIntoExistingResource(QUrl(m_temporaryFile->fileName()), m_collection);
137  } else {
138  setErrorMessage(i18n("Could not download remote file."));
139  emit q->importIntoExistingFinished(false, 0);
140  }
141 }
142 
143 ICalImporter::ICalImporter(Akonadi::IncidenceChanger *changer,
144  QObject *parent) : QObject(parent)
145  , d(new Private(changer, this))
146 {
147 }
148 
149 QString ICalImporter::errorMessage() const
150 {
151  return d->m_lastErrorMessage;
152 }
153 
154 bool ICalImporter::importIntoNewResource(const QString &filename)
155 {
156  d->m_lastErrorMessage.clear();
157 
158  if (d->m_working) {
159  d->setErrorMessage(i18n("An import task is already in progress."));
160  return false;
161  }
162 
163  d->m_working = true;
164 
165  Akonadi::AgentType type = Akonadi::AgentManager::self()->type(QLatin1String("akonadi_ical_resource"));
166  Akonadi::AgentInstanceCreateJob *job = new Akonadi::AgentInstanceCreateJob(type, this);
167  job->setProperty("path", filename);
168  connect(job, SIGNAL(result(KJob*)), d, SLOT(resourceCreated(KJob*)));
169  job->start();
170 
171  return true;
172 }
173 
174 bool ICalImporter::importIntoExistingResource(const QUrl &url, Akonadi::Collection collection)
175 {
176  d->m_lastErrorMessage.clear();
177 
178  if (d->m_working) {
179  d->setErrorMessage(i18n("An import task is already in progress."));
180  return false;
181  }
182 
183  if (url.isEmpty()) {
184  d->setErrorMessage(i18n("Empty filename. Will not import ical file."));
185  return false;
186  }
187 
188  if (!url.isValid()) {
189  d->setErrorMessage(i18n("Url to import is malformed."));
190  return false;
191  }
192 
193  if (url.isLocalFile()) {
194  if (!QFile::exists(url.path())) {
195  d->setErrorMessage(i18n("The specified file doesn't exist, aborting import."));
196  return false;
197  }
198  MemoryCalendar::Ptr temporaryCalendar(new MemoryCalendar(KDateTime::LocalZone));
199  FileStorage storage(temporaryCalendar);
200  storage.setFileName(url.path());
201  bool success = storage.load();
202  if (!success) {
203  d->setErrorMessage(i18n("Failed to load ical file, check permissions."));
204  return false;
205  }
206 
207  d->m_pendingRequests.clear();
208  Incidence::List incidences = temporaryCalendar->incidences();
209 
210  if (incidences.isEmpty()) {
211  d->setErrorMessage(i18n("The ical file to merge is empty."));
212  return false;
213  }
214 
215  if (!collection.isValid()) {
216  int dialogCode;
217  QStringList mimeTypes = QStringList() << KCalCore::Event::eventMimeType() << KCalCore::Todo::todoMimeType()
218  << KCalCore::Journal::journalMimeType();
219  collection = CalendarUtils::selectCollection(0, dialogCode /*by-ref*/, mimeTypes);
220  }
221 
222  if (!collection.isValid()) {
223  // user canceled
224  d->setErrorMessage(QString());
225  return false;
226  }
227 
228  const IncidenceChanger::DestinationPolicy policySaved = d->m_changer->destinationPolicy();
229  d->m_changer->startAtomicOperation(i18n("Merge ical file into existing calendar."));
230  d->m_changer->setDestinationPolicy(IncidenceChanger::DestinationPolicyNeverAsk);
231  foreach(const Incidence::Ptr &incidence, incidences) {
232  Q_ASSERT(incidence);
233  if (!incidence)
234  continue;
235  const int requestId = d->m_changer->createIncidence(incidence, collection);
236  Q_ASSERT(requestId != -1); // -1 only happens with invalid incidences
237  if (requestId != -1)
238  d->m_pendingRequests << requestId;
239  }
240  d->m_changer->endAtomicOperation();
241 
242  d->m_changer->setDestinationPolicy(policySaved); // restore
243  d->m_numIncidences = incidences.count();
244  } else {
245  d->m_collection = collection;
246  KIO::StoredTransferJob *job = KIO::storedGet(KUrl(url));
247  connect(job, SIGNAL(data(KIO::Job*,QByteArray)), d, SLOT(remoteDownloadFinished(KIO::Job*,QByteArray)));
248  }
249 
250  d->m_working = true;
251  return true;
252 }
Akonadi::Collection
Represents a collection of PIM items.
Definition: collection.h:75
Akonadi::AgentInstance::identifier
QString identifier() const
Returns the unique identifier of the agent instance.
Definition: agentinstance.cpp:55
Akonadi::AgentType
A representation of an agent type.
Definition: agenttype.h:58
Akonadi::AgentManager::type
AgentType type(const QString &identifier) const
Returns the agent type with the given identifier or an invalid agent type if the identifier does not ...
Definition: agentmanager.cpp:394
Akonadi::AgentInstanceCreateJob
Job for creating new agent instances.
Definition: agentinstancecreatejob.h:71
Akonadi::AgentManager::self
static AgentManager * self()
Returns the global instance of the agent manager.
Definition: agentmanager.cpp:380
Akonadi::AgentInstance
A representation of an agent instance.
Definition: agentinstance.h:62
Akonadi::Entity::isValid
bool isValid() const
Returns whether the entity is valid.
Definition: entity.cpp:97
Akonadi::AgentInstanceCreateJob::start
void start()
Starts the instance creation.
Definition: agentinstancecreatejob.cpp:175
Akonadi::AgentInstance::reconfigure
void reconfigure() const
Tell the agent that its configuration has been changed remotely via D-Bus.
Definition: agentinstance.cpp:149
Akonadi::AgentInstanceCreateJob::instance
AgentInstance instance() const
Returns the AgentInstance object of the newly created agent instance.
Definition: agentinstancecreatejob.cpp:170
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:00:27 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

Skip menu "akonadi"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Modules
  • Related Pages

kdepimlibs API Reference

Skip menu "kdepimlibs API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kldap
  • kmbox
  • kmime
  • kpimidentities
  • kpimtextedit
  • kresources
  • ktnef
  • kxmlrpcclient
  • microblog

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal