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 <qlabel.h>
00027 #include <qlayout.h>
00028 #include <qdatetime.h>
00029 #include <qcheckbox.h>
00030 #include <qwhatsthis.h>
00031
00032 #include <kdebug.h>
00033 #include <klocale.h>
00034 #include <kurlrequester.h>
00035 #include <kmessagebox.h>
00036 #include <kglobal.h>
00037 #include <kfiledialog.h>
00038 #include <kurl.h>
00039 #include <ktempfile.h>
00040 #include <kio/netaccess.h>
00041 #include <klineedit.h>
00042 #include <kactivelabel.h>
00043
00044 #include <libkcal/event.h>
00045 #include <libkcal/calendar.h>
00046 #include <libkcal/calendarlocal.h>
00047 #include <libkcal/filestorage.h>
00048
00049 #include <libkdepim/kdateedit.h>
00050
00051 #include "koprefs.h"
00052
00053 #include "archivedialog.h"
00054 #include "archivedialog.moc"
00055
00056 ArchiveDialog::ArchiveDialog(Calendar *cal,QWidget *parent, const char *name)
00057 : KDialogBase (Plain,i18n("Archive/Delete Past Appointments"),
00058 User1|Cancel,User1,parent,name,false,true,
00059 i18n("&Archive"))
00060 {
00061 mCalendar = cal;
00062
00063 QFrame *topFrame = plainPage();
00064 QVBoxLayout *topLayout = new QVBoxLayout(topFrame);
00065 topLayout->setSpacing(spacingHint());
00066
00067 KActiveLabel *descLabel = new KActiveLabel(
00068 i18n("Archiving saves old appointments into the given file and "
00069 "then deletes them in the current calendar. If the archive file "
00070 "already exists they will be added. "
00071 "(<a href=\"whatsthis:In order to add an archive "
00072 "to your calendar, use the "Merge Calendar" function. "
00073 "You can view an archive by opening it in KOrganizer like any "
00074 "other calendar. It is not saved in a special format, but as "
00075 "vCalendar.\">How to restore</a>)"),
00076 topFrame);
00077 topLayout->addWidget(descLabel);
00078
00079 QHBoxLayout *dateLayout = new QHBoxLayout(0);
00080 QLabel *dateLabel = new QLabel(i18n("A&ppointments older than:"),topFrame);
00081 dateLayout->addWidget(dateLabel);
00082 mDateEdit = new KDateEdit(topFrame);
00083 QWhatsThis::add(mDateEdit,
00084 i18n("The age of the appointments to archive. All older appointments "
00085 "will be saved and deleted, the newer will be kept."));
00086 dateLabel->setBuddy(mDateEdit);
00087 dateLayout->addWidget(mDateEdit);
00088 topLayout->addLayout(dateLayout);
00089
00090 QHBoxLayout *fileLayout = new QHBoxLayout(0);
00091 fileLayout->setSpacing(spacingHint());
00092 QLabel *l = new QLabel(i18n("Archive &file:"),topFrame);
00093 fileLayout->addWidget(l);
00094 mArchiveFile = new KURLRequester(KOPrefs::instance()->mArchiveFile,topFrame);
00095 mArchiveFile->setMode(KFile::File);
00096 mArchiveFile->setFilter(i18n("*.vcs|vCalendar Files"));
00097 QWhatsThis::add(mArchiveFile,
00098 i18n("The path of the archive. The appointments will be added to the "
00099 "archive file, so any appointments that are already in the file "
00100 "will not be modified or deleted. You can later load or merge the "
00101 "file like any other calendar. It is not saved in a special "
00102 "format, it uses the vCalendar format. "));
00103 l->setBuddy(mArchiveFile->lineEdit());
00104 fileLayout->addWidget(mArchiveFile);
00105 topLayout->addLayout(fileLayout);
00106
00107 mDeleteCb = new QCheckBox(i18n("&Delete only, do not save"),
00108 topFrame);
00109 QWhatsThis::add(mDeleteCb,
00110 i18n("Select this option to delete old appointments without saving them."
00111 "It is not possible to recover the appointments later."));
00112 topLayout->addWidget(mDeleteCb);
00113 connect(mDeleteCb, SIGNAL(toggled(bool)), mArchiveFile, SLOT(setDisabled(bool)));
00114 connect(mDeleteCb, SIGNAL(toggled(bool)), this, SLOT(slotEnableUser1()));
00115 connect(mArchiveFile->lineEdit(),SIGNAL(textChanged ( const QString & )),
00116 this,SLOT(slotEnableUser1()));
00117 enableButton(KDialogBase::User1,!mArchiveFile->lineEdit()->text().isEmpty());
00118 }
00119
00120 ArchiveDialog::~ArchiveDialog()
00121 {
00122 }
00123
00124 void ArchiveDialog::slotEnableUser1()
00125 {
00126 bool state = ( mDeleteCb->isChecked() ||
00127 !mArchiveFile->lineEdit()->text().isEmpty() );
00128 enableButton(KDialogBase::User1,state);
00129 }
00130
00131
00132 void ArchiveDialog::slotUser1()
00133 {
00134 if (mDeleteCb->isChecked()) {
00135 deleteOldEvents();
00136 return;
00137 }
00138
00139
00140 KURL destUrl ( mArchiveFile->url() );
00141 if ( !destUrl.isValid() ) {
00142 KMessageBox::sorry(this,i18n("The archive file name is not valid.\n"));
00143 return;
00144 }
00145
00146 QString filename = destUrl.fileName();
00147 if (filename.right(4) != ".vcs" && filename.right(4) != ".ics") {
00148 filename.append(".ics");
00149 destUrl.setFileName(filename);
00150 }
00151
00152
00153 Event::List events = mCalendar->events( QDate( 1800, 1, 1 ),
00154 mDateEdit->date().addDays( -1 ),
00155 true );
00156 if ( events.count() == 0 ) {
00157 KMessageBox::sorry(this,i18n("There are no events before %1")
00158 .arg(KGlobal::locale()->formatDate(mDateEdit->date())));
00159 return;
00160 }
00161
00162 FileStorage storage( mCalendar );
00163
00164
00165 KTempFile tmpFile;
00166 tmpFile.setAutoDelete(true);
00167 storage.setFileName( tmpFile.name() );
00168 if ( !storage.save() ) {
00169 kdDebug(5850) << "ArchiveDialog::slotUser1(): Can't save calendar to temp file" << endl;
00170 return;
00171 }
00172
00173
00174 CalendarLocal archiveCalendar( KOPrefs::instance()->mTimeZoneId );
00175
00176 FileStorage archiveStore( &archiveCalendar );
00177 archiveStore.setFileName( tmpFile.name() );
00178 if (!archiveStore.load()) {
00179 kdDebug(5850) << "ArchiveDialog::slotUser1(): Can't load calendar from temp file" << endl;
00180 return;
00181 }
00182
00183
00184
00185 Event::List activeEvents = archiveCalendar.events( mDateEdit->date(),
00186 QDate( 3000, 1, 1 ),
00187 false );
00188 Event::List::ConstIterator it;
00189 for( it = activeEvents.begin(); it != activeEvents.end(); ++it ) {
00190 archiveCalendar.deleteEvent( *it );
00191 }
00192
00193
00194 QString archiveFile;
00195
00196 if ( KIO::NetAccess::exists( destUrl, true, this ) ) {
00197 if( !KIO::NetAccess::download( destUrl, archiveFile, this ) ) {
00198 kdDebug(5850) << "ArchiveDialog::slotUser1(): Can't download archive file" << endl;
00199 return;
00200 }
00201
00202 archiveStore.setFileName( archiveFile );
00203 if ( !archiveStore.load() ) {
00204 kdDebug(5850) << "ArchiveDialog::slotUser1(): Can't merge with archive file" << endl;
00205 return;
00206 }
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 } else {
00218 archiveFile = tmpFile.name();
00219 }
00220
00221
00222 if ( !archiveStore.save() ) {
00223 KMessageBox::error(this,i18n("Cannot write archive file."));
00224 return;
00225 }
00226
00227
00228 KURL srcUrl;
00229 srcUrl.setPath(archiveFile);
00230 if (srcUrl != destUrl) {
00231 if ( !KIO::NetAccess::upload( archiveFile, destUrl, this ) ) {
00232 KMessageBox::error(this,i18n("Cannot write archive to final destination."));
00233 return;
00234 }
00235 }
00236
00237 KOPrefs::instance()->mArchiveFile = destUrl.url();
00238
00239 KIO::NetAccess::removeTempFile(archiveFile);
00240
00241
00242 for( it = events.begin(); it != events.end(); ++it ) {
00243 mCalendar->deleteEvent( *it );
00244 }
00245 emit eventsDeleted();
00246
00247 accept();
00248 }
00249
00250
00251 void ArchiveDialog::deleteOldEvents()
00252 {
00253 Event::List events = mCalendar->events( QDate( 1769, 12, 1 ),
00254 mDateEdit->date().addDays( -1 ),
00255 true );
00256
00257 if ( events.count() == 0 ) {
00258 KMessageBox::sorry(this,i18n("There are no events before %1")
00259 .arg(KGlobal::locale()->formatDate(mDateEdit->date())));
00260 return;
00261 }
00262
00263 QStringList eventStrs;
00264 Event::List::ConstIterator it;
00265 for( it = events.begin(); it != events.end(); ++it ) {
00266 eventStrs.append( (*it)->summary() );
00267 }
00268
00269 int result = KMessageBox::warningContinueCancelList(this,
00270 i18n("Delete all events before %1 without saving?\n"
00271 "The following events will be deleted:")
00272 .arg(KGlobal::locale()->formatDate(mDateEdit->date())),eventStrs,
00273 i18n("Delete old events"),i18n("&Delete"));
00274 if (result == KMessageBox::Continue) {
00275 for( it = events.begin(); it != events.end(); ++it ) {
00276 mCalendar->deleteEvent( *it );
00277 }
00278 emit eventsDeleted();
00279 accept();
00280 }
00281 }