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

KCal Library

  • sources
  • kde-4.12
  • kdepimlibs
  • kcal
resourcelocaldir.cpp
1 /*
2  This file is part of the kcal library.
3 
4  Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
5  Copyright (c) 2009 Sergio Martins <iamsergio@gmail.com>
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Library General Public
9  License as published by the Free Software Foundation; either
10  version 2 of the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Library General Public License for more details.
16 
17  You should have received a copy of the GNU Library General Public License
18  along with this library; see the file COPYING.LIB. If not, write to
19  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  Boston, MA 02110-1301, USA.
21 */
22 
23 #include "resourcelocaldir.h"
24 #include "resourcelocaldir_p.h"
25 #include "calendarlocal.h"
26 #include "incidence.h"
27 #include "event.h"
28 #include "todo.h"
29 #include "journal.h"
30 
31 #include "kresources/configwidget.h"
32 
33 #include <kcal/assignmentvisitor.h>
34 #include <kcal/comparisonvisitor.h>
35 #include <kdebug.h>
36 #include <klocalizedstring.h>
37 #include <kconfig.h>
38 #include <kstandarddirs.h>
39 #include <kconfiggroup.h>
40 
41 #include <QtCore/QString>
42 #include <QtCore/QDir>
43 #include <QtCore/QFileInfo>
44 
45 #include <typeinfo>
46 #include <stdlib.h>
47 
48 #include "moc_resourcelocaldir.cpp"
49 #include "moc_resourcelocaldir_p.cpp"
50 
51 using namespace KCal;
52 
53 ResourceLocalDir::ResourceLocalDir()
54  : ResourceCached(), d( new KCal::ResourceLocalDir::Private( this ) )
55 {
56  d->init();
57 }
58 
59 ResourceLocalDir::ResourceLocalDir( const KConfigGroup &group )
60  : ResourceCached( group ), d( new KCal::ResourceLocalDir::Private( this ) )
61 {
62  readConfig( group );
63  d->init();
64 }
65 
66 ResourceLocalDir::ResourceLocalDir( const QString &dirName )
67  : ResourceCached(), d( new KCal::ResourceLocalDir::Private( dirName, this ) )
68 {
69  d->init();
70 }
71 
72 void ResourceLocalDir::readConfig( const KConfigGroup &group )
73 {
74  QString url = group.readPathEntry( "CalendarURL", QString() );
75  d->mURL = KUrl( url );
76 }
77 
78 void ResourceLocalDir::writeConfig( KConfigGroup &group )
79 {
80  kDebug();
81 
82  ResourceCalendar::writeConfig( group );
83 
84  group.writePathEntry( "CalendarURL", d->mURL.prettyUrl() );
85 }
86 
87 //@cond PRIVATE
88 void ResourceLocalDir::Private::init()
89 {
90  mResource->setType( "dir" );
91 
92  mResource->setSavePolicy( SaveDelayed );
93 
94  connect( &mDirWatch, SIGNAL(dirty(QString)),
95  this, SLOT(updateIncidenceInCalendar(QString)) );
96  connect( &mDirWatch, SIGNAL(created(QString)),
97  this, SLOT(addIncidenceToCalendar(QString)) );
98  connect( &mDirWatch, SIGNAL(deleted(QString)),
99  this, SLOT(deleteIncidenceFromCalendar(QString)) );
100 
101  connect ( this, SIGNAL(resourceChanged(ResourceCalendar*)),
102  mResource, SIGNAL(resourceChanged(ResourceCalendar*)) );
103 
104  mLock = new KABC::Lock( mURL.path() );
105 
106  mDirWatch.addDir( mURL.path(), KDirWatch::WatchFiles );
107  mDirWatch.startScan();
108 }
109 //@endcond
110 
111 ResourceLocalDir::~ResourceLocalDir()
112 {
113  close();
114 
115  delete d->mLock;
116  delete d;
117 }
118 
119 bool ResourceLocalDir::doOpen()
120 {
121  QFileInfo dirInfo( d->mURL.path() );
122  return dirInfo.isDir() && dirInfo.isReadable() &&
123  ( dirInfo.isWritable() || readOnly() );
124 }
125 
126 bool ResourceLocalDir::doLoad( bool )
127 {
128  kDebug();
129 
130  calendar()->close();
131  QString dirName = d->mURL.path();
132 
133  if ( !( KStandardDirs::exists( dirName ) || KStandardDirs::exists( dirName + '/' ) ) ) {
134  kDebug() << "Directory '" << dirName << "' doesn't exist yet. Creating it.";
135 
136  // Create the directory. Use 0775 to allow group-writable if the umask
137  // allows it (permissions will be 0775 & ~umask). This is desired e.g. for
138  // group-shared directories!
139  return KStandardDirs::makeDir( dirName, 0775 );
140  }
141 
142  // The directory exists. Now try to open (the files in) it.
143  kDebug() << dirName;
144  QFileInfo dirInfo( dirName );
145  if ( !( dirInfo.isDir() && dirInfo.isReadable() &&
146  ( dirInfo.isWritable() || readOnly() ) ) ) {
147  return false;
148  }
149 
150  QDir dir( dirName );
151  const QStringList entries = dir.entryList( QDir::Files | QDir::Readable );
152 
153  bool success = true;
154 
155  foreach ( const QString &entry, entries ) {
156  if ( d->isTempFile( entry ) ) {
157  continue; // backup or temporary file, ignore it
158  }
159 
160  const QString fileName = dirName + '/' + entry;
161  kDebug() << " read '" << fileName << "'";
162  CalendarLocal cal( calendar()->timeSpec() );
163  if ( !doFileLoad( cal, fileName ) ) {
164  success = false;
165  }
166  }
167 
168  return success;
169 }
170 
171 bool ResourceLocalDir::doFileLoad( CalendarLocal &cal, const QString &fileName )
172 {
173  return d->doFileLoad( cal, fileName, false );
174 }
175 
176 bool ResourceLocalDir::doSave( bool syncCache )
177 {
178  Q_UNUSED( syncCache );
179  Incidence::List list;
180  bool success = true;
181 
182  list = addedIncidences();
183  list += changedIncidences();
184 
185  for ( Incidence::List::iterator it = list.begin(); it != list.end(); ++it ) {
186  if ( !doSave( *it ) ) {
187  success = false;
188  }
189  }
190 
191  return success;
192 }
193 
194 bool ResourceLocalDir::doSave( bool, Incidence *incidence )
195 {
196  if ( d->mDeletedIncidences.contains( incidence ) ) {
197  d->mDeletedIncidences.removeAll( incidence );
198  return true;
199  }
200 
201  d->mDirWatch.stopScan(); // do prohibit the dirty() signal and a following reload()
202 
203  QString fileName = d->mURL.path() + '/' + incidence->uid();
204  kDebug() << "writing '" << fileName << "'";
205 
206  CalendarLocal cal( calendar()->timeSpec() );
207  cal.addIncidence( incidence->clone() );
208  const bool ret = cal.save( fileName );
209 
210  d->mDirWatch.startScan();
211 
212  return ret;
213 }
214 
215 KABC::Lock *ResourceLocalDir::lock()
216 {
217  return d->mLock;
218 }
219 
220 void ResourceLocalDir::reload( const QString &file )
221 {
222  Q_UNUSED( file );
223 }
224 
225 bool ResourceLocalDir::deleteEvent( Event *event )
226 {
227  kDebug();
228  if ( d->deleteIncidenceFile( event ) ) {
229  if ( calendar()->deleteEvent( event ) ) {
230  d->mDeletedIncidences.append( event );
231  return true;
232  } else {
233  return false;
234  }
235  } else {
236  return false;
237  }
238 }
239 
240 void ResourceLocalDir::deleteAllEvents()
241 {
242  calendar()->deleteAllEvents();
243 }
244 
245 bool ResourceLocalDir::deleteTodo( Todo *todo )
246 {
247  if ( d->deleteIncidenceFile( todo ) ) {
248  if ( calendar()->deleteTodo( todo ) ) {
249  d->mDeletedIncidences.append( todo );
250  return true;
251  } else {
252  return false;
253  }
254  } else {
255  return false;
256  }
257 }
258 
259 void ResourceLocalDir::deleteAllTodos()
260 {
261  calendar()->deleteAllTodos();
262 }
263 
264 bool ResourceLocalDir::deleteJournal( Journal *journal )
265 {
266  if ( d->deleteIncidenceFile( journal ) ) {
267  if ( calendar()->deleteJournal( journal ) ) {
268  d->mDeletedIncidences.append( journal );
269  return true;
270  } else {
271  return false;
272  }
273  } else {
274  return false;
275  }
276 }
277 
278 void ResourceLocalDir::deleteAllJournals()
279 {
280  calendar()->deleteAllJournals();
281 }
282 
283 void ResourceLocalDir::dump() const
284 {
285  ResourceCalendar::dump();
286  kDebug() << " Url:" << d->mURL.url();
287 }
288 
289 //@cond PRIVATE
290 bool ResourceLocalDir::Private::deleteIncidenceFile( Incidence *incidence )
291 {
292  QFile file( mURL.path() + '/' + incidence->uid() );
293  if ( !file.exists() ) {
294  return true;
295  }
296 
297  mDirWatch.stopScan();
298  bool removed = file.remove();
299  mDirWatch.startScan();
300  return removed;
301 }
302 
303 bool ResourceLocalDir::Private::isTempFile( const QString &fileName ) const
304 {
305  return
306  fileName.contains( QRegExp( "(~|\\.new|\\.tmp)$" ) ) ||
307  QFileInfo( fileName ).fileName().startsWith( QLatin1String( "qt_temp." ) ) ||
308  fileName == mURL.path();
309 }
310 
311 void ResourceLocalDir::Private::addIncidenceToCalendar( const QString &file )
312 {
313 
314  if ( mResource->isOpen() &&
315  !isTempFile( file ) &&
316  !mResource->calendar()->incidence( getUidFromFileName( file ) ) ) {
317 
318  CalendarLocal cal( mResource->calendar()->timeSpec() );
319  if ( doFileLoad( cal, file, true ) ) {
320  emit resourceChanged( mResource );
321  }
322  }
323 }
324 
325 void ResourceLocalDir::Private::updateIncidenceInCalendar( const QString &file )
326 {
327  if ( mResource->isOpen() && !isTempFile( file ) ) {
328  CalendarLocal cal( mResource->calendar()->timeSpec() );
329  if ( doFileLoad( cal, file, true ) ) {
330  emit resourceChanged( mResource );
331  }
332  }
333 }
334 
335 QString ResourceLocalDir::Private::getUidFromFileName( const QString &fileName )
336 {
337  return QFileInfo( fileName ).fileName();
338 }
339 
340 void ResourceLocalDir::Private::deleteIncidenceFromCalendar( const QString &file )
341 {
342 
343  if ( mResource->isOpen() && !isTempFile( file ) ) {
344  Incidence *inc = mResource->calendar()->incidence( getUidFromFileName( file ) );
345 
346  if ( inc ) {
347  mResource->calendar()->deleteIncidence( inc );
348  emit resourceChanged( mResource );
349  }
350  }
351 }
352 
353 bool ResourceLocalDir::Private::doFileLoad( CalendarLocal &cal,
354  const QString &fileName,
355  const bool replace )
356 {
357  if ( !cal.load( fileName ) ) {
358  return false;
359  }
360  Incidence::List incidences = cal.rawIncidences();
361  Incidence::List::ConstIterator it;
362  Incidence *inc;
363  ComparisonVisitor compVisitor;
364  AssignmentVisitor assVisitor;
365  for ( it = incidences.constBegin(); it != incidences.constEnd(); ++it ) {
366  Incidence *i = *it;
367  if ( i ) {
368  // should we replace, and does the incidence exist in calendar?
369  if ( replace && ( inc = mResource->calendar()->incidence( i->uid() ) ) ) {
370  if ( compVisitor.compare( i, inc ) ) {
371  // no need to do anything
372  return false;
373  } else {
374  inc->startUpdates();
375 
376  bool assignResult = assVisitor.assign( inc, i );
377 
378  if ( assignResult ) {
379  if ( !inc->relatedToUid().isEmpty() ) {
380  QString uid = inc->relatedToUid();
381  inc->setRelatedTo( mResource->calendar()->incidence( uid ) );
382  }
383  inc->updated();
384  inc->endUpdates();
385  } else {
386  inc->endUpdates();
387  kWarning() << "Incidence (uid=" << inc->uid()
388  << ", summary=" << inc->summary()
389  << ") changed type. Replacing it.";
390 
391  mResource->calendar()->deleteIncidence( inc );
392  delete inc;
393  mResource->calendar()->addIncidence( i->clone() );
394  }
395  }
396  } else {
397  mResource->calendar()->addIncidence( i->clone() );
398  }
399  }
400  }
401  return true;
402 }
403 //@endcond
KCal::CalendarLocal::save
bool save()
Writes the calendar to disk.
Definition: calendarlocal.cpp:132
calendarlocal.h
This file is part of the API for handling calendar data and defines the CalendarLocal class...
KCal::CalendarLocal::deleteAllTodos
void deleteAllTodos()
Definition: calendarlocal.cpp:277
KCal::AssignmentVisitor
Helper for type correct assignment of incidences via pointers.
Definition: assignmentvisitor.h:54
KCal::ResourceLocalDir::lock
KABC::Lock * lock()
Return object for locking the resource.
Definition: resourcelocaldir.cpp:215
KCal::Todo
Provides a To-do in the sense of RFC2445.
Definition: todo.h:44
KCal::Incidence::relatedToUid
QString relatedToUid() const
Returns a UID string for the incidence that is related to this one.
Definition: incidence.cpp:492
KCal::ResourceCached::timeSpec
KDateTime::Spec timeSpec() const
Get the viewing time specification (time zone etc.) for the calendar.
Definition: resourcecached.cpp:355
KCal::IncidenceBase::updated
void updated()
Call this to notify the observers after the IncidenceBase object has changed.
Definition: incidencebase.cpp:475
KCal::ResourceLocalDir::doLoad
virtual bool doLoad(bool syncCache)
Do the actual loading of the resource data.
Definition: resourcelocaldir.cpp:126
KCal::CalendarLocal::deleteJournal
bool deleteJournal(Journal *journal)
Definition: calendarlocal.cpp:583
KCal::CalendarLocal::load
bool load(const QString &fileName, CalFormat *format=0)
Loads a calendar on disk in vCalendar or iCalendar format into the current calendar.
Definition: calendarlocal.cpp:115
KCal::Event
This class provides an Event in the sense of RFC2445.
Definition: event.h:41
KCal::ResourceLocalDir::doSave
virtual bool doSave(bool syncCache)
Do the actual saving of the resource data.
Definition: resourcelocaldir.cpp:176
KRES::Resource::dump
virtual void dump() const
KCal::CalendarLocal::deleteTodo
bool deleteTodo(Todo *todo)
Definition: calendarlocal.cpp:258
KCal::IncidenceBase::uid
QString uid() const
Returns the unique id (uid) for the incidence.
Definition: incidencebase.cpp:184
KCal::CalendarLocal
This class provides a calendar stored as a local file.
Definition: calendarlocal.h:43
KCal::CalendarLocal::deleteAllEvents
void deleteAllEvents()
Definition: calendarlocal.cpp:202
configwidget.h
KCal::ResourceCalendar
This class provides the interfaces for a calendar resource.
Definition: resourcecalendar.h:50
KCal::ResourceLocalDir::doOpen
bool doOpen()
Opens the resource.
Definition: resourcelocaldir.cpp:119
KCal::ComparisonVisitor::compare
bool compare(IncidenceBase *incidence, const IncidenceBase *reference)
Compares the incidence referenced by incidence to the incidence referenced by reference.
Definition: comparisonvisitor.cpp:46
KCal::ResourceLocalDir::deleteEvent
bool deleteEvent(Event *event)
deletes an event from this calendar.
Definition: resourcelocaldir.cpp:225
KCal::AssignmentVisitor::assign
bool assign(IncidenceBase *target, const IncidenceBase *source)
Assigns the incidence referenced by source to the incidence referenced by target, first ensuring that...
Definition: assignmentvisitor.cpp:49
todo.h
This file is part of the API for handling calendar data and defines the Todo class.
KCal::Incidence
Provides the abstract base class common to non-FreeBusy (Events, To-dos, Journals) calendar component...
Definition: incidence.h:68
KCal::ListBase
This class provides a template for lists of pointers.
Definition: listbase.h:44
KCal::CalendarLocal::close
void close()
Clears out the current calendar, freeing all used memory etc.
Definition: calendarlocal.cpp:158
KCal::ComparisonVisitor
Helper for type correct comparison of incidences via pointers.
Definition: comparisonvisitor.h:53
KCal::ResourceLocalDir::deleteAllJournals
void deleteAllJournals()
Removes all journals from this calendar.
Definition: resourcelocaldir.cpp:278
KCal::Journal
Provides a Journal in the sense of RFC2445.
Definition: journal.h:43
KCal::CalendarLocal::deleteEvent
bool deleteEvent(Event *event)
Definition: calendarlocal.cpp:185
KRES::Resource::readOnly
virtual bool readOnly() const
KCal::Incidence::setRelatedTo
void setRelatedTo(Incidence *incidence)
Relates another incidence to this one.
Definition: incidence.cpp:497
journal.h
This file is part of the API for handling calendar data and defines the Journal class.
KCal::IncidenceBase::startUpdates
void startUpdates()
Call this when a group of updates is going to be made.
Definition: incidencebase.cpp:488
KCal::ResourceLocalDir::deleteAllEvents
void deleteAllEvents()
Removes all Events from this calendar.
Definition: resourcelocaldir.cpp:240
KCal::CalendarLocal::deleteAllJournals
void deleteAllJournals()
Definition: calendarlocal.cpp:597
KCal::Calendar::addIncidence
virtual bool addIncidence(Incidence *incidence)
Inserts an Incidence into the calendar.
Definition: calendar.cpp:573
KCal::ResourceLocalDir::deleteJournal
bool deleteJournal(Journal *journal)
Remove a journal from the journallist.
Definition: resourcelocaldir.cpp:264
event.h
This file is part of the API for handling calendar data and defines the Event class.
incidence.h
This file is part of the API for handling calendar data and defines the Incidence class...
KCal::ResourceLocalDir::deleteAllTodos
void deleteAllTodos()
Removes all todos from this calendar.
Definition: resourcelocaldir.cpp:259
KCal::ResourceCached
This class provides a calendar resource using a local CalendarLocal object to cache the calendar data...
Definition: resourcecached.h:43
KCal::Calendar::rawIncidences
virtual Incidence::List rawIncidences()
Returns an unfiltered list of all Incidences for this Calendar.
Definition: calendar.cpp:287
KCal::ResourceLocalDir
This class provides a calendar stored as a file per incidence in a directory.
Definition: resourcelocaldir.h:33
KCal::IncidenceBase::endUpdates
void endUpdates()
Call this when a group of updates is complete, to notify observers that the instance has changed...
Definition: incidencebase.cpp:493
KCal::Incidence::clone
virtual Incidence * clone()=0
Returns an exact copy of this incidence.
KCal::ResourceLocalDir::deleteTodo
bool deleteTodo(Todo *todo)
Remove a todo from the todolist.
Definition: resourcelocaldir.cpp:245
KCal::Incidence::summary
QString summary() const
Returns the incidence summary.
Definition: incidence.cpp:424
KRES::Resource::close
void close()
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:00:58 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KCal Library

Skip menu "KCal Library"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • 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