00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "eventarchiver.h"
00027 #include <kglobal.h>
00028 #include <klocale.h>
00029 #include <ktempfile.h>
00030 #include <kio/netaccess.h>
00031 #include <kglobal.h>
00032 #include <libkcal/filestorage.h>
00033 #include <libkcal/calendarlocal.h>
00034 #include <libkcal/calendar.h>
00035 #include <kmessagebox.h>
00036 #include <kdebug.h>
00037 #include "koprefs.h"
00038
00039 EventArchiver::EventArchiver( TQObject* parent, const char* name )
00040 : TQObject( parent, name )
00041 {
00042 }
00043
00044 EventArchiver::~EventArchiver()
00045 {
00046 }
00047
00048 void EventArchiver::runOnce( Calendar* calendar, const TQDate& limitDate, TQWidget* widget )
00049 {
00050 run( calendar, limitDate, widget, true, true );
00051 }
00052
00053 void EventArchiver::runAuto( Calendar* calendar, TQWidget* widget, bool withGUI )
00054 {
00055 TQDate limitDate( TQDate::currentDate() );
00056 int expiryTime = KOPrefs::instance()->mExpiryTime;
00057 switch (KOPrefs::instance()->mExpiryUnit) {
00058 case KOPrefs::UnitDays:
00059 limitDate = limitDate.addDays( -expiryTime );
00060 break;
00061 case KOPrefs::UnitWeeks:
00062 limitDate = limitDate.addDays( -expiryTime*7 );
00063 break;
00064 case KOPrefs::UnitMonths:
00065 limitDate = limitDate.addMonths( -expiryTime );
00066 break;
00067 default:
00068 return;
00069 }
00070 run( calendar, limitDate, widget, withGUI, false );
00071 }
00072
00073 void EventArchiver::run( Calendar* calendar, const TQDate& limitDate, TQWidget* widget, bool withGUI,
00074 bool errorIfNone )
00075 {
00076
00077 Incidence::List incidences;
00078 Event::List events;
00079 Todo::List todos;
00080 Journal::List journals;
00081
00082 if ( KOPrefs::instance()->mArchiveEvents ) {
00083 events = calendar->rawEvents(
00084 TQDate( 1769, 12, 1 ),
00085
00086 limitDate.addDays( -1 ),
00087 true );
00088 }
00089 if ( KOPrefs::instance()->mArchiveTodos ) {
00090 Todo::List t = calendar->rawTodos();
00091 Todo::List::ConstIterator it;
00092 for( it = t.begin(); it != t.end(); ++it ) {
00093 const bool todoComplete = (*it) &&
00094 (*it)->isCompleted() &&
00095 ( (*it)->completed().date() < limitDate );
00096
00097 if ( todoComplete && !isSubTreeComplete( *it, limitDate ) ) {
00098
00099 KMessageBox::information(
00100 widget,
00101 i18n( "Unable to archive to-do \"%1\" because at least one of its "
00102 "sub-to-dos does not meet the archival requirements." ).arg( (*it)->summary() ),
00103 i18n( "Archive To-do" ),
00104 "UncompletedChildrenArchiveTodos" );
00105 } else if ( todoComplete ) {
00106 todos.append( *it );
00107 }
00108 }
00109 }
00110
00111 incidences = Calendar::mergeIncidenceList( events, todos, journals );
00112
00113
00114 kdDebug(5850) << "EventArchiver: archiving incidences before " << limitDate << " -> "
00115 << incidences.count() << " incidences found." << endl;
00116 if ( incidences.isEmpty() ) {
00117 if ( withGUI && errorIfNone ) {
00118 KMessageBox::information(
00119 widget,
00120 i18n( "There are no incidences available to archive before the specified cut-off date %1. "
00121 "Archiving will not be performed." ).arg( KGlobal::locale()->formatDate( limitDate ) ),
00122 "ArchiverNoIncidences" );
00123 }
00124 return;
00125 }
00126
00127
00128 switch ( KOPrefs::instance()->mArchiveAction ) {
00129 case KOPrefs::actionDelete:
00130 deleteIncidences( calendar, limitDate, widget, incidences, withGUI );
00131 break;
00132 case KOPrefs::actionArchive:
00133 archiveIncidences( calendar, limitDate, widget, incidences, withGUI );
00134 break;
00135 }
00136 }
00137
00138 void EventArchiver::deleteIncidences( Calendar* calendar, const TQDate& limitDate, TQWidget* widget, const Incidence::List& incidences, bool withGUI )
00139 {
00140 TQStringList incidenceStrs;
00141 Incidence::List::ConstIterator it;
00142 for( it = incidences.begin(); it != incidences.end(); ++it ) {
00143 incidenceStrs.append( (*it)->summary() );
00144 }
00145
00146 if ( withGUI ) {
00147 int result = KMessageBox::warningContinueCancelList(
00148 widget, i18n("Delete all items before %1 without saving?\n"
00149 "The following items will be deleted:")
00150 .arg(KGlobal::locale()->formatDate(limitDate)), incidenceStrs,
00151 i18n("Delete Old Items"),KStdGuiItem::del());
00152 if (result != KMessageBox::Continue)
00153 return;
00154 }
00155 for( it = incidences.begin(); it != incidences.end(); ++it ) {
00156 calendar->deleteIncidence( *it );
00157 }
00158 emit eventsDeleted();
00159 }
00160
00161 void EventArchiver::archiveIncidences( Calendar* calendar, const TQDate& , TQWidget* widget, const Incidence::List& incidences, bool )
00162 {
00163 FileStorage storage( calendar );
00164
00165
00166 KTempFile tmpFile;
00167 tmpFile.setAutoDelete(true);
00168 storage.setFileName( tmpFile.name() );
00169 if ( !storage.save() ) {
00170 kdDebug(5850) << "EventArchiver::archiveEvents(): Can't save calendar to temp file" << endl;
00171 return;
00172 }
00173
00174
00175 CalendarLocal archiveCalendar( KOPrefs::instance()->mTimeZoneId );
00176
00177 FileStorage archiveStore( &archiveCalendar );
00178 archiveStore.setFileName( tmpFile.name() );
00179 if (!archiveStore.load()) {
00180 kdDebug(5850) << "EventArchiver::archiveEvents(): Can't load calendar from temp file" << endl;
00181 return;
00182 }
00183
00184
00185
00186 TQStringList uids;
00187 Incidence::List allIncidences = archiveCalendar.rawIncidences();
00188 Incidence::List::ConstIterator it;
00189 for( it = incidences.begin(); it != incidences.end(); ++it ) {
00190 uids << (*it)->uid();
00191 }
00192 for( it = allIncidences.begin(); it != allIncidences.end(); ++it ) {
00193 if ( !uids.contains( (*it)->uid() ) ) {
00194 archiveCalendar.deleteIncidence( *it );
00195 }
00196 }
00197
00198
00199 KURL archiveURL( KOPrefs::instance()->mArchiveFile );
00200 TQString archiveFile;
00201
00202 if ( KIO::NetAccess::exists( archiveURL, true, widget ) ) {
00203 if( !KIO::NetAccess::download( archiveURL, archiveFile, widget ) ) {
00204 kdDebug(5850) << "EventArchiver::archiveEvents(): Can't download archive file" << endl;
00205 return;
00206 }
00207
00208 archiveStore.setFileName( archiveFile );
00209 if ( !archiveStore.load() ) {
00210 kdDebug(5850) << "EventArchiver::archiveEvents(): Can't merge with archive file" << endl;
00211 return;
00212 }
00213 } else {
00214 archiveFile = tmpFile.name();
00215 }
00216
00217
00218 if ( !archiveStore.save() ) {
00219 KMessageBox::error(widget,i18n("Cannot write archive file %1.").arg( archiveStore.fileName() ));
00220 return;
00221 }
00222
00223
00224 KURL srcUrl;
00225 srcUrl.setPath(archiveFile);
00226 if (srcUrl != archiveURL) {
00227 if ( !KIO::NetAccess::upload( archiveFile, archiveURL, widget ) ) {
00228 KMessageBox::error(widget,i18n("Cannot write archive to final destination."));
00229 return;
00230 }
00231 }
00232
00233 KIO::NetAccess::removeTempFile(archiveFile);
00234
00235
00236 for( it = incidences.begin(); it != incidences.end(); ++it ) {
00237 calendar->deleteIncidence( *it );
00238 }
00239 emit eventsDeleted();
00240 }
00241
00242 bool EventArchiver::isSubTreeComplete( const Todo *todo, const TQDate &limitDate,
00243 TQStringList checkedUids ) const
00244 {
00245 if ( !todo || !todo->isCompleted() || todo->completed().date() >= limitDate ) {
00246 return false;
00247 }
00248
00249
00250 if ( checkedUids.contains( todo->uid() ) ) {
00251
00252 kdWarning() << "To-do hierarchy loop detected!";
00253 return false;
00254 }
00255
00256 checkedUids.append( todo->uid() );
00257
00258 Incidence::List::ConstIterator it;
00259 const Incidence::List relations = todo->relations();
00260
00261 for( it = relations.begin(); it != relations.end(); ++it ) {
00262 if ( (*it)->type() == "Todo" ) {
00263 const Todo *t = static_cast<const Todo*>( *it );
00264 if ( !isSubTreeComplete( t, limitDate, checkedUids ) ) {
00265 return false;
00266 }
00267 }
00268 }
00269
00270 return true;
00271 }
00272
00273 #include "eventarchiver.moc"