korganizer

kotodoeditor.cpp

00001 /*
00002     This file is part of KOrganizer.
00003 
00004     Copyright (c) 1997, 1998 Preston Brown <pbrown@kde.org>
00005     Copyright (c) 2000-2003 Cornelius Schumacher <schumacher@kde.org>
00006     Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00007 
00008     This program is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     This program is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with this program; if not, write to the Free Software
00020     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00021 
00022     As a special exception, permission is given to link this program
00023     with any edition of Qt, and distribute the resulting executable,
00024     without including the source code for Qt in the source distribution.
00025 */
00026 
00027 #include <qtooltip.h>
00028 #include <qframe.h>
00029 #include <qpixmap.h>
00030 #include <qlayout.h>
00031 #include <qdatetime.h>
00032 
00033 #include <kiconloader.h>
00034 #include <klocale.h>
00035 #include <kmessagebox.h>
00036 
00037 #include <libkcal/calendarlocal.h>
00038 #include <libkcal/calendarresources.h>
00039 #include <libkcal/resourcecalendar.h>
00040 
00041 #include "koprefs.h"
00042 #include "koeditorattachments.h"
00043 #include "kogroupware.h"
00044 #include "kodialogmanager.h"
00045 #include "incidencechanger.h"
00046 
00047 #include "koeditorgeneraltodo.h"
00048 #include "koeditordetails.h"
00049 #include "koeditorrecurrence.h"
00050 
00051 #include "kotodoeditor.h"
00052 #include "kocore.h"
00053 
00054 KOTodoEditor::KOTodoEditor( Calendar *calendar, QWidget *parent ) :
00055   KOIncidenceEditor( QString::null, calendar, parent ),
00056   mTodo( 0 ), mCalendar( 0 ), mRelatedTodo( 0 ), mGeneral( 0 ), mRecurrence( 0 )
00057 {
00058 }
00059 
00060 KOTodoEditor::~KOTodoEditor()
00061 {
00062   emit dialogClose( mTodo );
00063 }
00064 
00065 void KOTodoEditor::init()
00066 {
00067   setupGeneral();
00068   setupRecurrence();
00069   setupAttendeesTab();
00070 
00071   connect( mGeneral, SIGNAL( dateTimeStrChanged( const QString & ) ),
00072            mRecurrence, SLOT( setDateTimeStr( const QString & ) ) );
00073   connect( mGeneral, SIGNAL( signalDateTimeChanged( const QDateTime &, const QDateTime & ) ),
00074            mRecurrence, SLOT( setDateTimes( const QDateTime &, const QDateTime & ) ) );
00075 
00076   connect( mGeneral, SIGNAL( openCategoryDialog() ),
00077            SIGNAL( editCategories() ) );
00078 
00079   connect( mDetails, SIGNAL(updateAttendeeSummary(int)),
00080            mGeneral, SLOT(updateAttendeeSummary(int)) );
00081 
00082   connect( mGeneral, SIGNAL(editRecurrence()),
00083            mRecurrenceDialog, SLOT(show()) );
00084   connect( mRecurrenceDialog, SIGNAL(okClicked()),
00085            SLOT(updateRecurrenceSummary()) );
00086 }
00087 
00088 void KOTodoEditor::reload()
00089 {
00090   if ( mTodo ) {
00091     readTodo( mTodo, mCalendar, QDate() );
00092   }
00093 }
00094 
00095 void KOTodoEditor::setupGeneral()
00096 {
00097   mGeneral = new KOEditorGeneralTodo(this);
00098 
00099   if (KOPrefs::instance()->mCompactDialogs) {
00100     QFrame *topFrame = addPage(i18n("General"));
00101 
00102     QBoxLayout *topLayout = new QVBoxLayout(topFrame);
00103     topLayout->setMargin(marginHint());
00104     topLayout->setSpacing(spacingHint());
00105 
00106     mGeneral->initHeader( topFrame, topLayout );
00107     mGeneral->initTime(topFrame,topLayout);
00108     QHBoxLayout *priorityLayout = new QHBoxLayout( topLayout );
00109     mGeneral->initPriority(topFrame,priorityLayout);
00110     topLayout->addStretch(1);
00111 
00112     QFrame *topFrame2 = addPage(i18n("Details"));
00113 
00114     QBoxLayout *topLayout2 = new QVBoxLayout(topFrame2);
00115     topLayout2->setMargin(marginHint());
00116     topLayout2->setSpacing(spacingHint());
00117 
00118     QHBoxLayout *completionLayout = new QHBoxLayout( topLayout2 );
00119     mGeneral->initCompletion(topFrame2,completionLayout);
00120 
00121     mGeneral->initSecrecy( topFrame2, topLayout2 );
00122     mGeneral->initDescription(topFrame2,topLayout2);
00123   } else {
00124     QFrame *topFrame = addPage(i18n("&General"));
00125 
00126     QBoxLayout *topLayout = new QVBoxLayout(topFrame);
00127     topLayout->setSpacing(spacingHint());
00128 
00129     mGeneral->initHeader( topFrame, topLayout );
00130     mGeneral->initTime(topFrame,topLayout);
00131     mGeneral->initStatus(topFrame,topLayout);
00132     mGeneral->initDescription(topFrame,topLayout);
00133     mGeneral->initAttachments(topFrame,topLayout);
00134     connect( mGeneral, SIGNAL( openURL( const KURL& ) ),
00135              this, SLOT( openURL( const KURL& ) ) );
00136     connect( this, SIGNAL( signalAddAttachments( const QStringList&, const QStringList&, bool ) ),
00137              mGeneral, SLOT( addAttachments( const QStringList&, const QStringList&, bool ) ) );
00138   }
00139   mGeneral->finishSetup();
00140 }
00141 
00142 void KOTodoEditor::setupRecurrence()
00143 {
00144   mRecurrenceDialog = new KOEditorRecurrenceDialog( this );
00145   mRecurrenceDialog->hide();
00146   mRecurrence = mRecurrenceDialog->editor();
00147 }
00148 
00149 void KOTodoEditor::editIncidence( Incidence *incidence, const QDate &date, Calendar *calendar )
00150 {
00151   kdDebug(5850) << k_funcinfo << endl;
00152   Todo *todo = dynamic_cast<Todo*>( incidence );
00153   if ( todo )  {
00154     init();
00155     mTodo = todo;
00156     mCalendar = calendar;
00157     readTodo( mTodo, mCalendar, date );
00158   }
00159 
00160   setCaption( i18n("Edit To-do") );
00161 }
00162 
00163 void KOTodoEditor::newTodo()
00164 {
00165   kdDebug(5850) << k_funcinfo << endl;
00166   init();
00167   mTodo = 0;
00168   mCalendar = 0;
00169   setCaption( i18n("New To-do") );
00170   loadDefaults();
00171 }
00172 
00173 void KOTodoEditor::setTexts( const QString &summary, const QString &description )
00174 {
00175   if ( description.isEmpty() && summary.contains("\n") ) {
00176     mGeneral->setDescription( summary );
00177     int pos = summary.find( "\n" );
00178     mGeneral->setSummary( summary.left( pos ) );
00179   } else {
00180     mGeneral->setSummary( summary );
00181     mGeneral->setDescription( description );
00182   }
00183 }
00184 
00185 void KOTodoEditor::loadDefaults()
00186 {
00187   kdDebug(5850) << k_funcinfo << endl;
00188   setDates( QDateTime::currentDateTime().addDays( 7 ), true, 0 );
00189   mGeneral->toggleAlarm( KOPrefs::instance()->defaultTodoReminders() );
00190 }
00191 
00192 bool KOTodoEditor::processInput()
00193 {
00194   if ( !validateInput() ) {
00195     return false;
00196   }
00197 
00198   if ( mTodo ) {
00199     bool rc = true;
00200     Todo *oldTodo = mTodo->clone();
00201     Todo *todo = mTodo->clone();
00202 
00203     kdDebug(5850) << "KOTodoEditor::processInput() write event." << endl;
00204     writeTodo( todo );
00205     kdDebug(5850) << "KOTodoEditor::processInput() event written." << endl;
00206 
00207     if ( *mTodo == *todo ) {
00208       // Don't do anything
00209       kdDebug(5850) << "Todo not changed\n";
00210     } else {
00211       kdDebug(5850) << "Todo changed\n";
00212       //IncidenceChanger::assignIncidence( mTodo, todo );
00213       mTodo->startUpdates();
00214       writeTodo( mTodo );
00215 
00216       KOGlobals::WhatChanged whatChanged;
00217 
00218       if ( !oldTodo->isCompleted() && todo->isCompleted() ) {
00219         whatChanged = KOGlobals::COMPLETION_MODIFIED;
00220       } else {
00221         whatChanged = KOGlobals::NOTHING_MODIFIED;
00222       }
00223 
00224       const bool success = mChanger->changeIncidence( oldTodo, mTodo, whatChanged, this );
00225       if ( success ) {
00226         mTodo->endUpdates();
00227       } else {
00228         mTodo->cancelUpdates();
00229       }
00230     }
00231     delete todo;
00232     delete oldTodo;
00233     return rc;
00234 
00235   } else {
00236     mTodo = new Todo;
00237     mTodo->setOrganizer( Person( KOPrefs::instance()->fullName(),
00238                          KOPrefs::instance()->email() ) );
00239 
00240     writeTodo( mTodo );
00241 
00242     if ( !mChanger->addIncidence( mTodo, mResource, mSubResource, this ) ) {
00243       delete mTodo;
00244       mTodo = 0;
00245       return false;
00246     }
00247   }
00248 
00249   return true;
00250 
00251 }
00252 
00253 void KOTodoEditor::deleteTodo()
00254 {
00255   if ( mTodo ) {
00256     emit deleteIncidenceSignal( mTodo );
00257   }
00258   emit dialogClose( mTodo );
00259   reject();
00260 }
00261 
00262 void KOTodoEditor::setDates( const QDateTime &due, bool allDay, Todo *relatedEvent )
00263 {
00264   mRelatedTodo = relatedEvent;
00265 
00266   // inherit some properties from parent todo
00267   if ( mRelatedTodo ) {
00268     mGeneral->setCategories( mRelatedTodo->categories() );
00269   }
00270   if ( !due.isValid() && mRelatedTodo && mRelatedTodo->hasDueDate() ) {
00271     mGeneral->setDefaults( mRelatedTodo->dtDue(), allDay );
00272   } else {
00273     mGeneral->setDefaults( due, allDay );
00274   }
00275 
00276   mDetails->setDefaults();
00277   if ( mTodo ) {
00278     mRecurrence->setDefaults( mTodo->dtStart(), due, false );
00279   } else {
00280     mRecurrence->setDefaults( QDateTime::currentDateTime(), due, false );
00281   }
00282 }
00283 
00284 void KOTodoEditor::readTodo( Todo *todo, Calendar *calendar, const QDate &date )
00285 {
00286   if ( !todo ) {
00287     return;
00288   }
00289 //   mRelatedTodo = todo->relatedTo();
00290 
00291   mGeneral->readTodo( todo, calendar, date );
00292   mDetails->readEvent( todo );
00293   mRecurrence->readIncidence( todo );
00294 
00295   createEmbeddedURLPages( todo );
00296   readDesignerFields( todo );
00297 }
00298 
00299 void KOTodoEditor::writeTodo( Todo *todo )
00300 {
00301   Incidence *oldIncidence = todo->clone();
00302 
00303   mRecurrence->writeIncidence( todo );
00304   mGeneral->writeTodo( todo );
00305   mDetails->writeEvent( todo );
00306 
00307   if ( *(oldIncidence->recurrence()) != *(todo->recurrence() ) ) {
00308     todo->setDtDue( todo->dtDue(), true );
00309     if ( todo->hasStartDate() ) {
00310       todo->setDtStart( todo->dtStart() );
00311     }
00312   }
00313   writeDesignerFields( todo );
00314 
00315   // set related incidence, i.e. parent to-do in this case.
00316   if ( mRelatedTodo ) {
00317     todo->setRelatedTo( mRelatedTodo );
00318   }
00319 
00320   cancelRemovedAttendees( todo );
00321 }
00322 
00323 bool KOTodoEditor::validateInput()
00324 {
00325   Todo *todo = new Todo();
00326   writeTodo( todo );
00327 
00328   if ( !mGeneral->validateInput() ) return false;
00329   if ( !mRecurrence->validateInput( mTodo ) ) return false;
00330   if ( !mDetails->validateInput() ) return false;
00331   return true;
00332 }
00333 
00334 int KOTodoEditor::msgItemDelete()
00335 {
00336   return KMessageBox::warningContinueCancel(this,
00337       i18n("This item will be permanently deleted."),
00338       i18n("KOrganizer Confirmation"), KStdGuiItem::del() );
00339 }
00340 
00341 void KOTodoEditor::modified()
00342 {
00343   // Play dump, just reload the todo. This dialog has become so complicated
00344   // that there is no point in trying to be smart here...
00345   reload();
00346 }
00347 
00348 void KOTodoEditor::loadTemplate( /*const*/ CalendarLocal& cal )
00349 {
00350   Todo::List todos = cal.todos();
00351   if ( todos.count() == 0 ) {
00352     KMessageBox::error( this,
00353         i18n("Template does not contain a valid to-do.") );
00354   } else {
00355     readTodo( todos.first(), 0, QDate() );
00356   }
00357 }
00358 
00359 void KOTodoEditor::slotSaveTemplate( const QString &templateName )
00360 {
00361   Todo *todo = new Todo;
00362   writeTodo( todo );
00363   saveAsTemplate( todo, templateName );
00364 }
00365 
00366 QStringList& KOTodoEditor::templates() const
00367 {
00368   return KOPrefs::instance()->mTodoTemplates;
00369 }
00370 
00371 void KOTodoEditor::updateRecurrenceSummary()
00372 {
00373   Todo *todo = new Todo();
00374   writeTodo( todo );
00375   mGeneral->updateRecurrenceSummary( todo );
00376   delete todo;
00377 }
00378 
00379 #include "kotodoeditor.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys