libkcal

resourcelocaldir.cpp
1 /*
2  This file is part of libkcal.
3 
4  Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later version.
10 
11  This library is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  Library General Public License for more details.
15 
16  You should have received a copy of the GNU Library General Public License
17  along with this library; see the file COPYING.LIB. If not, write to
18  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  Boston, MA 02110-1301, USA.
20 */
21 
22 #include <typeinfo>
23 #include <stdlib.h>
24 
25 #include <tqdatetime.h>
26 #include <tqfileinfo.h>
27 #include <tqstring.h>
28 #include <tqptrlist.h>
29 
30 #include <kdebug.h>
31 #include <tdelocale.h>
32 #include <kurl.h>
33 #include <tdeconfig.h>
34 #include <kstandarddirs.h>
35 
36 #include "vcaldrag.h"
37 #include "vcalformat.h"
38 #include "icalformat.h"
39 #include "exceptions.h"
40 #include "calendarlocal.h"
41 #include "incidence.h"
42 #include "event.h"
43 #include "todo.h"
44 #include "journal.h"
45 #include "filestorage.h"
46 
47 #include <tderesources/configwidget.h>
48 
49 #include "resourcelocaldirconfig.h"
50 
51 #include "resourcelocaldir.h"
52 
53 using namespace KCal;
54 
55 ResourceLocalDir::ResourceLocalDir( const TDEConfig* config )
56  : ResourceCached( config ), mLock( 0 )
57 {
58  if ( config ) {
59  readConfig( config );
60  }
61 
62  init();
63 }
64 
65 ResourceLocalDir::ResourceLocalDir( const TQString& dirName )
66  : ResourceCached( 0 )
67 {
68  mURL = KURL( dirName );
69 
70  init();
71 }
72 
73 
74 void ResourceLocalDir::readConfig( const TDEConfig *config )
75 {
76  TQString url = config->readPathEntry( "CalendarURL" );
77  mURL = KURL( url );
78 }
79 
80 void ResourceLocalDir::writeConfig( TDEConfig *config )
81 {
82  kdDebug(5800) << "ResourceLocalDir::writeConfig()" << endl;
83 
84  ResourceCalendar::writeConfig( config );
85 
86  config->writePathEntry( "CalendarURL", mURL.prettyURL() );
87 }
88 
89 void ResourceLocalDir::init()
90 {
91  setType( "dir" );
92 
93  setSavePolicy( SaveDelayed );
94 
95  connect( &mDirWatch, TQ_SIGNAL( dirty( const TQString & ) ),
96  TQ_SLOT( reload( const TQString & ) ) );
97  connect( &mDirWatch, TQ_SIGNAL( created( const TQString & ) ),
98  TQ_SLOT( reload( const TQString & ) ) );
99  connect( &mDirWatch, TQ_SIGNAL( deleted( const TQString & ) ),
100  TQ_SLOT( reload( const TQString & ) ) );
101 
102  mLock = new TDEABC::Lock( mURL.path() );
103 
104  mDirWatch.addDir( mURL.path(), true );
105  mDirWatch.startScan();
106 }
107 
108 
109 ResourceLocalDir::~ResourceLocalDir()
110 {
111  close();
112 
113  delete mLock;
114 }
115 
116 bool ResourceLocalDir::doOpen()
117 {
118  TQFileInfo dirInfo( mURL.path() );
119  return dirInfo.isDir() && dirInfo.isReadable() &&
120  ( dirInfo.isWritable() || readOnly() );
121 }
122 
123 bool ResourceLocalDir::doLoad()
124 {
125  kdDebug(5800) << "ResourceLocalDir::load()" << endl;
126 
127  mCalendar.close();
128  TQString dirName = mURL.path();
129 
130  if ( !( TDEStandardDirs::exists( dirName ) || TDEStandardDirs::exists( dirName + "/") ) ) {
131  kdDebug(5800) << "ResourceLocalDir::load(): Directory '" << dirName
132  << "' doesn't exist yet. Creating it..." << endl;
133  // Create the directory. Use 0775 to allow group-writable if the umask
134  // allows it (permissions will be 0775 & ~umask). This is desired e.g. for
135  // group-shared directories!
136  return TDEStandardDirs::makeDir( dirName, 0775 );
137  }
138 
139  // The directory exists. Now try to open (the files in) it.
140  kdDebug(5800) << "ResourceLocalDir::load(): '" << dirName << "'" << endl;
141  TQFileInfo dirInfo( dirName );
142  if ( !( dirInfo.isDir() && dirInfo.isReadable() &&
143  ( dirInfo.isWritable() || readOnly() ) ) )
144  return false;
145 
146  TQDir dir( dirName );
147  TQStringList entries = dir.entryList( TQDir::Files | TQDir::Readable );
148 
149  bool success = true;
150  TQStringList::ConstIterator it;
151  for( it = entries.constBegin(); it != entries.constEnd(); ++it ) {
152  if ( (*it).endsWith( "~" ) ) // is backup file, ignore it
153  continue;
154 
155  TQString fileName = dirName + "/" + *it;
156  kdDebug(5800) << " read '" << fileName << "'" << endl;
157  CalendarLocal cal( mCalendar.timeZoneId() );
158  if ( !doFileLoad( cal, fileName ) ) {
159  success = false;
160  }
161  }
162 
163  return success;
164 }
165 
166 bool ResourceLocalDir::doFileLoad( CalendarLocal &cal, const TQString &fileName )
167 {
168  if ( !cal.load( fileName ) )
169  return false;
170  Incidence::List incidences = cal.rawIncidences();
171  Incidence::List::ConstIterator it;
172  for ( it = incidences.constBegin(); it != incidences.constEnd(); ++it ) {
173  Incidence *i = *it;
174  if ( i ) mCalendar.addIncidence( i->clone() );
175  }
176  return true;
177 }
178 
179 bool ResourceLocalDir::doSave()
180 {
181  Incidence::List list;
182  bool success = true;
183 
184  list = addedIncidences();
185  list += changedIncidences();
186 
187  for ( Incidence::List::iterator it = list.begin(); it != list.end(); ++it )
188  if ( !doSave( *it ) )
189  success = false;
190 
191  return success;
192 }
193 
194 bool ResourceLocalDir::doSave( Incidence *incidence )
195 {
196  if ( mDeletedIncidences.contains( incidence ) ) {
197  mDeletedIncidences.remove( incidence );
198  return true;
199  }
200 
201  mDirWatch.stopScan(); // do prohibit the dirty() signal and a following reload()
202 
203  TQString fileName = mURL.path() + "/" + incidence->uid();
204  kdDebug(5800) << "writing '" << fileName << "'" << endl;
205 
206  CalendarLocal cal( mCalendar.timeZoneId() );
207  cal.addIncidence( incidence->clone() );
208  const bool ret = cal.save( fileName );
209 
210  mDirWatch.startScan();
211 
212  return ret;
213 }
214 
215 TDEABC::Lock *ResourceLocalDir::lock()
216 {
217  return mLock;
218 }
219 
220 void ResourceLocalDir::reload( const TQString &file )
221 {
222  kdDebug(5800) << "ResourceLocalDir::reload()" << endl;
223 
224  if ( !isOpen() )
225  return;
226 
227  kdDebug(5800) << " File: '" << file << "'" << endl;
228 
229  mCalendar.close();
230  load();
231 
232  emit resourceChanged( this );
233 }
234 
235 
236 bool ResourceLocalDir::deleteEvent(Event *event)
237 {
238  kdDebug(5800) << "ResourceLocalDir::deleteEvent" << endl;
239  if ( deleteIncidenceFile(event) ) {
240  if ( mCalendar.deleteEvent( event ) ) {
241  mDeletedIncidences.append( event );
242  return true;
243  } else {
244  return false;
245  }
246  } else {
247  return false;
248  }
249 }
250 
251 
252 bool ResourceLocalDir::deleteTodo(Todo *todo)
253 {
254  if ( deleteIncidenceFile(todo) ) {
255  if ( mCalendar.deleteTodo( todo ) ) {
256  mDeletedIncidences.append( todo );
257  return true;
258  } else {
259  return false;
260  }
261  } else {
262  return false;
263  }
264 }
265 
266 
267 bool ResourceLocalDir::deleteJournal( Journal *journal )
268 {
269  if ( deleteIncidenceFile( journal ) ) {
270  if ( mCalendar.deleteJournal( journal ) ) {
271  mDeletedIncidences.append( journal );
272  return true;
273  } else {
274  return false;
275  }
276  } else {
277  return false;
278  }
279 }
280 
281 
282 void ResourceLocalDir::dump() const
283 {
284  ResourceCalendar::dump();
285  kdDebug(5800) << " Url: " << mURL.url() << endl;
286 }
287 
288 bool ResourceLocalDir::deleteIncidenceFile(Incidence *incidence)
289 {
290  TQFile file( mURL.path() + "/" + incidence->uid() );
291  if ( !file.exists() )
292  return true;
293 
294  mDirWatch.stopScan();
295  bool removed = file.remove();
296  mDirWatch.startScan();
297  return removed;
298 }
299 
300 #include "resourcelocaldir.moc"
This class provides a calendar stored as a local file.
Definition: calendarlocal.h:37
bool load(const TQString &fileName, CalFormat *format=0)
Loads a calendar on disk in vCalendar or iCalendar format into the current calendar.
bool save(const TQString &fileName, CalFormat *format=0)
Writes out the calendar to disk in the specified format.
virtual bool addIncidence(Incidence *incidence)
Insert an Incidence into the Calendar.
Definition: calendar.cpp:466
virtual Incidence::List rawIncidences()
Return an unfiltered list of all Incidences for this Calendar.
Definition: calendar.cpp:183
This class provides an Event in the sense of RFC2445.
Definition: event.h:33
TQString uid() const
Return the unique id for the event.
This class provides the base class common to all calendar components.
Definition: incidence.h:48
virtual Incidence * clone()=0
Return copy of this object.
This class provides a Journal in the sense of RFC2445.
Definition: journal.h:34
This class provides a calendar resource using a local CalendarLocal object to cache the calendar data...
This class provides a Todo in the sense of RFC2445.
Definition: todo.h:32
Namespace KCal is for global classes, objects and/or functions in libkcal.
Definition: alarm.h:38