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 TQt, and distribute the resulting executable,
00024     without including the source code for TQt in the source distribution.
00025 */
00026 
00027 #include <tqtooltip.h>
00028 #include <tqframe.h>
00029 #include <tqpixmap.h>
00030 #include <tqlayout.h>
00031 #include <tqdatetime.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, TQWidget *parent ) :
00055   KOIncidenceEditor( TQString(), 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, TQT_SIGNAL( dateTimeStrChanged( const TQString & ) ),
00072            mRecurrence, TQT_SLOT( setDateTimeStr( const TQString & ) ) );
00073   connect( mGeneral, TQT_SIGNAL( signalDateTimeChanged( const TQDateTime &, const TQDateTime & ) ),
00074            mRecurrence, TQT_SLOT( setDateTimes( const TQDateTime &, const TQDateTime & ) ) );
00075 
00076   connect( mGeneral, TQT_SIGNAL( openCategoryDialog() ),
00077            TQT_SIGNAL( editCategories() ) );
00078 
00079   connect( mDetails, TQT_SIGNAL(updateAttendeeSummary(int)),
00080            mGeneral, TQT_SLOT(updateAttendeeSummary(int)) );
00081 
00082   connect( mGeneral, TQT_SIGNAL(editRecurrence()),
00083            mRecurrenceDialog, TQT_SLOT(show()) );
00084   connect( mRecurrenceDialog, TQT_SIGNAL(okClicked()),
00085            TQT_SLOT(updateRecurrenceSummary()) );
00086 }
00087 
00088 void KOTodoEditor::reload()
00089 {
00090   if ( mTodo ) {
00091     readTodo( mTodo, mCalendar, TQDate() );
00092   }
00093 }
00094 
00095 void KOTodoEditor::setupGeneral()
00096 {
00097   mGeneral = new KOEditorGeneralTodo(TQT_TQOBJECT(this));
00098 
00099   if (KOPrefs::instance()->mCompactDialogs) {
00100     TQFrame *topFrame = addPage(i18n("General"));
00101 
00102     TQBoxLayout *topLayout = new TQVBoxLayout(topFrame);
00103     topLayout->setMargin(marginHint());
00104     topLayout->setSpacing(spacingHint());
00105 
00106     mGeneral->initHeader( topFrame, topLayout );
00107     mGeneral->initTime(topFrame,topLayout);
00108     TQHBoxLayout *priorityLayout = new TQHBoxLayout( topLayout );
00109     mGeneral->initPriority(topFrame,priorityLayout);
00110     topLayout->addStretch(1);
00111 
00112     TQFrame *topFrame2 = addPage(i18n("Details"));
00113 
00114     TQBoxLayout *topLayout2 = new TQVBoxLayout(topFrame2);
00115     topLayout2->setMargin(marginHint());
00116     topLayout2->setSpacing(spacingHint());
00117 
00118     TQHBoxLayout *completionLayout = new TQHBoxLayout( topLayout2 );
00119     mGeneral->initCompletion(topFrame2,completionLayout);
00120 
00121     mGeneral->initSecrecy( topFrame2, topLayout2 );
00122     mGeneral->initDescription(topFrame2,topLayout2);
00123   } else {
00124     TQFrame *topFrame = addPage(i18n("&General"));
00125 
00126     TQBoxLayout *topLayout = new TQVBoxLayout(topFrame);
00127     topLayout->setSpacing(spacingHint());
00128 
00129     mGeneral->initHeader( topFrame, topLayout );
00130     mGeneral->initTime(topFrame,topLayout);
00131     mGeneral->iniStatus(topFrame,topLayout);
00132     mGeneral->initDescription(topFrame,topLayout);
00133     mGeneral->initAttachments(topFrame,topLayout);
00134     connect( mGeneral, TQT_SIGNAL( openURL( const KURL& ) ),
00135              this, TQT_SLOT( openURL( const KURL& ) ) );
00136     connect( this, TQT_SIGNAL( signalAddAttachments( const TQStringList&, const TQStringList&, bool ) ),
00137              mGeneral, TQT_SLOT( addAttachments( const TQStringList&, const TQStringList&, 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 TQDate &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 TQString &summary, const TQString &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( TQDateTime::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       writeTodo( mTodo );
00214 
00215       KOGlobals::WhatChanged whatChanged;
00216 
00217       if ( !oldTodo->isCompleted() && todo->isCompleted() ) {
00218         whatChanged = KOGlobals::COMPLETION_MODIFIED;
00219       } else {
00220         whatChanged = KOGlobals::NOTHING_MODIFIED;
00221       }
00222 
00223       mChanger->changeIncidence( oldTodo, mTodo, whatChanged, this );
00224     }
00225     delete todo;
00226     delete oldTodo;
00227     return rc;
00228 
00229   } else {
00230     mTodo = new Todo;
00231     mTodo->setOrganizer( Person( KOPrefs::instance()->fullName(),
00232                          KOPrefs::instance()->email() ) );
00233 
00234     writeTodo( mTodo );
00235 
00236     if ( !mChanger->addIncidence( mTodo, mResource, mSubResource, this ) ) {
00237       delete mTodo;
00238       mTodo = 0;
00239       return false;
00240     }
00241   }
00242 
00243   return true;
00244 
00245 }
00246 
00247 void KOTodoEditor::deleteTodo()
00248 {
00249   if ( mTodo ) {
00250     emit deleteIncidenceSignal( mTodo );
00251   }
00252   emit dialogClose( mTodo );
00253   reject();
00254 }
00255 
00256 void KOTodoEditor::setDates( const TQDateTime &due, bool allDay, Todo *relatedEvent )
00257 {
00258   mRelatedTodo = relatedEvent;
00259 
00260   // inherit some properties from parent todo
00261   if ( mRelatedTodo ) {
00262     mGeneral->setCategories( mRelatedTodo->categories() );
00263   }
00264   if ( !due.isValid() && mRelatedTodo && mRelatedTodo->hasDueDate() ) {
00265     mGeneral->setDefaults( mRelatedTodo->dtDue(), allDay );
00266   } else {
00267     mGeneral->setDefaults( due, allDay );
00268   }
00269 
00270   mDetails->setDefaults();
00271   if ( mTodo ) {
00272     mRecurrence->setDefaults( mTodo->dtStart(), due, false );
00273   } else {
00274     mRecurrence->setDefaults( TQDateTime::currentDateTime(), due, false );
00275   }
00276 }
00277 
00278 void KOTodoEditor::readTodo( Todo *todo, Calendar *calendar, const TQDate &date )
00279 {
00280   if ( !todo ) {
00281     return;
00282   }
00283 //   mRelatedTodo = todo->relatedTo();
00284 
00285   mGeneral->readTodo( todo, calendar, date );
00286   mDetails->readEvent( todo );
00287   mRecurrence->readIncidence( todo );
00288 
00289   createEmbeddedURLPages( todo );
00290   readDesignerFields( todo );
00291 }
00292 
00293 void KOTodoEditor::writeTodo( Todo *todo )
00294 {
00295   Incidence *oldIncidence = todo->clone();
00296 
00297   mRecurrence->writeIncidence( todo );
00298   mGeneral->writeTodo( todo );
00299   mDetails->writeEvent( todo );
00300 
00301   if ( *(oldIncidence->recurrence()) != *(todo->recurrence() ) ) {
00302     todo->setDtDue( todo->dtDue(), true );
00303     if ( todo->hasStartDate() ) {
00304       todo->setDtStart( todo->dtStart() );
00305     }
00306   }
00307   writeDesignerFields( todo );
00308 
00309   // set related incidence, i.e. parent to-do in this case.
00310   if ( mRelatedTodo ) {
00311     todo->setRelatedTo( mRelatedTodo );
00312   }
00313 
00314   cancelRemovedAttendees( todo );
00315 }
00316 
00317 bool KOTodoEditor::validateInput()
00318 {
00319   if ( !mGeneral->validateInput() ) return false;
00320   if ( !mRecurrence->validateInput() ) return false;
00321   if ( !mDetails->validateInput() ) return false;
00322   return true;
00323 }
00324 
00325 int KOTodoEditor::msgItemDelete()
00326 {
00327   return KMessageBox::warningContinueCancel(this,
00328       i18n("This item will be permanently deleted."),
00329       i18n("KOrganizer Confirmation"), KStdGuiItem::del() );
00330 }
00331 
00332 void KOTodoEditor::modified()
00333 {
00334   // Play dump, just reload the todo. This dialog has become so complicated
00335   // that there is no point in trying to be smart here...
00336   reload();
00337 }
00338 
00339 void KOTodoEditor::loadTemplate( /*const*/ CalendarLocal& cal )
00340 {
00341   Todo::List todos = cal.todos();
00342   if ( todos.count() == 0 ) {
00343     KMessageBox::error( this,
00344         i18n("Template does not contain a valid to-do.") );
00345   } else {
00346     readTodo( todos.first(), 0, TQDate() );
00347   }
00348 }
00349 
00350 void KOTodoEditor::slotSaveTemplate( const TQString &templateName )
00351 {
00352   Todo *todo = new Todo;
00353   writeTodo( todo );
00354   saveAsTemplate( todo, templateName );
00355 }
00356 
00357 TQStringList& KOTodoEditor::templates() const
00358 {
00359   return KOPrefs::instance()->mTodoTemplates;
00360 }
00361 
00362 void KOTodoEditor::updateRecurrenceSummary()
00363 {
00364   Todo *todo = new Todo();
00365   writeTodo( todo );
00366   mGeneral->updateRecurrenceSummary( todo );
00367   delete todo;
00368 }
00369 
00370 #include "kotodoeditor.moc"