krop's commit fixes my problem in a better way, reverting
[kdepim.git] / korganizer / kotodoeditor.cpp
blob6134b490663d3fce473de8e2ba0a6ece6c9a4340
1 /*
2 This file is part of KOrganizer.
4 Copyright (c) 1997, 1998 Preston Brown <pbrown@kde.org>
5 Copyright (c) 2000-2003 Cornelius Schumacher <schumacher@kde.org>
6 Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 As a special exception, permission is given to link this program
23 with any edition of Qt, and distribute the resulting executable,
24 without including the source code for Qt in the source distribution.
26 #include "kotodoeditor.h"
27 #include "kocore.h"
28 #include "koeditorgeneraltodo.h"
29 #include "koeditordetails.h"
30 #include "koeditorrecurrence.h"
31 #include "koprefs.h"
32 #include "koeditorattachments.h"
33 #include "kogroupware.h"
34 #include "kohelper.h"
35 #include "kodialogmanager.h"
36 #include "incidencechanger.h"
38 #include <kcal/calendarlocal.h>
39 #include <kcal/calendarresources.h>
40 #include <kcal/resourcecalendar.h>
41 #include <KCal/IncidenceFormatter>
43 #include <kiconloader.h>
44 #include <klocale.h>
45 #include <kmessagebox.h>
47 #include <QFrame>
48 #include <QPixmap>
49 #include <QLayout>
50 #include <QDateTime>
51 #include <QVBoxLayout>
52 #include <QHBoxLayout>
53 #include <QBoxLayout>
55 KOTodoEditor::KOTodoEditor( Calendar *calendar, QWidget *parent )
56 : KOIncidenceEditor( QString(), calendar, parent ),
57 mTodo( 0 ), mCalendar( 0 ), mRelatedTodo( 0 )
61 KOTodoEditor::~KOTodoEditor()
63 emit dialogClose( mTodo );
66 bool KOTodoEditor::incidenceModified()
68 Todo *newTodo = 0;
69 Todo *oldTodo = 0;
70 bool modified;
72 if ( mTodo ) { // modification
73 oldTodo = mTodo->clone();
74 } else { // new one
75 // don't remove .clone(), it's on purpose, clone() strips relation attributes
76 // if you compare a non-cloned parent to-do with a cloned to-do you will always
77 // get false, so we use clone() in both cases.
78 oldTodo = mInitialTodo.clone();
81 newTodo = oldTodo->clone();
82 fillTodo( newTodo );
84 modified = !( *newTodo == *oldTodo );
86 delete newTodo;
87 delete oldTodo;
89 return modified;
92 void KOTodoEditor::init()
94 setupGeneral();
95 setupRecurrence();
96 setupAttendeesTab();
98 connect( mGeneral, SIGNAL(dateTimeStrChanged(const QString&)),
99 mRecurrence, SLOT(setDateTimeStr(const QString&)) );
100 connect( mGeneral, SIGNAL(signalDateTimeChanged(const QDateTime&,const QDateTime&)),
101 mRecurrence, SLOT(setDateTimes(const QDateTime&,const QDateTime&)) );
103 connect( mGeneral, SIGNAL(openCategoryDialog()),
104 SIGNAL(editCategories()) );
105 connect( this, SIGNAL(updateCategoryConfig()),
106 mGeneral, SIGNAL(updateCategoryConfig()) );
108 connect( mDetails, SIGNAL(updateAttendeeSummary(int)),
109 mGeneral, SLOT(updateAttendeeSummary(int)) );
112 void KOTodoEditor::reload()
114 if ( mTodo ) {
115 readTodo( mTodo, true );
119 void KOTodoEditor::setupGeneral()
121 mGeneral = new KOEditorGeneralTodo( mCalendar, this );
123 if ( KOPrefs::instance()->mCompactDialogs ) {
124 QFrame *topFrame = new QFrame();
125 addPage( topFrame, i18nc( "@title:tab general to-do settings","General" ) );
127 QBoxLayout *topLayout = new QVBoxLayout( topFrame );
128 topLayout->setMargin( marginHint() );
129 topLayout->setSpacing( spacingHint() );
131 mGeneral->initHeader( topFrame, topLayout );
132 mGeneral->initTime( topFrame, topLayout );
133 QHBoxLayout *priorityLayout = new QHBoxLayout();
134 topLayout->addItem( priorityLayout );
135 mGeneral->initPriority( topFrame, priorityLayout );
136 topLayout->addStretch( 1 );
138 QFrame *topFrame2 = new QFrame();
139 addPage( topFrame2, i18nc( "@title:tab", "Details" ) );
141 QBoxLayout *topLayout2 = new QVBoxLayout( topFrame2 );
142 topLayout2->setMargin( marginHint() );
143 topLayout2->setSpacing( spacingHint() );
145 QHBoxLayout *completionLayout = new QHBoxLayout();
146 topLayout2->addItem( completionLayout );
147 mGeneral->initCompletion( topFrame2, completionLayout );
149 mGeneral->initAlarm( topFrame, topLayout );
151 mGeneral->initSecrecy( topFrame2, topLayout2 );
152 mGeneral->initDescription( topFrame2, topLayout2 );
153 } else {
154 QFrame *topFrame = new QFrame();
155 addPage( topFrame, i18nc( "@title:tab general to-do settings", "&General" ) );
157 QBoxLayout *topLayout = new QVBoxLayout( topFrame );
158 topLayout->setSpacing( spacingHint() );
160 mGeneral->initHeader( topFrame, topLayout );
161 mGeneral->initTime( topFrame, topLayout );
162 mGeneral->initStatus( topFrame, topLayout );
164 QBoxLayout *alarmLineLayout = new QHBoxLayout();
165 alarmLineLayout->setSpacing( spacingHint() );
166 topLayout->addItem( alarmLineLayout );
167 mGeneral->initAlarm( topFrame, alarmLineLayout );
168 alarmLineLayout->addStretch( 1 );
170 mGeneral->initDescription( topFrame, topLayout );
172 mGeneral->initAttachments( topFrame, topLayout );
173 connect( mGeneral, SIGNAL(openURL(const KUrl&)),
174 this, SLOT(openURL(const KUrl&)) );
175 connect( this, SIGNAL(signalAddAttachments(const QStringList&,const QStringList&,bool)),
176 mGeneral, SLOT(addAttachments(const QStringList&,const QStringList&,bool)) );
178 mGeneral->enableAlarm( true );
180 mGeneral->finishSetup();
183 void KOTodoEditor::setupRecurrence()
185 QFrame *topFrame = new QFrame();
186 addPage( topFrame, i18nc( "@title:tab", "Rec&urrence" ) );
188 QBoxLayout *topLayout = new QVBoxLayout( topFrame );
190 mRecurrence = new KOEditorRecurrence( topFrame );
191 topLayout->addWidget( mRecurrence );
193 mRecurrence->setEnabled( false );
194 connect( mGeneral,SIGNAL(dueDateEditToggle(bool)),
195 mRecurrence, SLOT(setEnabled(bool)) );
198 void KOTodoEditor::editIncidence( Incidence *incidence, Calendar *calendar )
200 Todo *todo = dynamic_cast<Todo*>( incidence );
201 if ( todo ) {
202 init();
204 mTodo = todo;
205 mCalendar = calendar;
206 readTodo( mTodo, false );
209 setCaption( i18nc( "@title:window",
210 "Edit To-do: %1",
211 IncidenceFormatter::resourceString( calendar, incidence ) ) );
214 void KOTodoEditor::newTodo()
216 init();
217 mTodo = 0;
218 mCalendar = 0;
219 setCaption( i18nc( "@title:window", "New To-do" ) );
220 loadDefaults();
223 void KOTodoEditor::setTexts( const QString &summary, const QString &description,
224 bool richDescription )
226 if ( description.isEmpty() && summary.contains( "\n" ) ) {
227 mGeneral->setDescription( summary, richDescription );
228 int pos = summary.indexOf( "\n" );
229 mGeneral->setSummary( summary.left( pos ) );
230 } else {
231 mGeneral->setSummary( summary );
232 mGeneral->setDescription( description, richDescription );
236 void KOTodoEditor::loadDefaults()
238 setDates( QDateTime::currentDateTime().addDays(7), true, 0 );
239 mGeneral->toggleAlarm( KOPrefs::instance()->defaultTodoReminders() );
242 bool KOTodoEditor::processInput()
244 if ( !validateInput() ) {
245 return false;
248 if ( mTodo ) {
249 bool rc = true;
250 Todo *oldTodo = mTodo->clone();
251 Todo *todo = mTodo->clone();
253 fillTodo( todo );
255 if( *mTodo == *todo ) {
256 // Don't do anything
257 } else {
258 fillTodo( mTodo );
259 rc = mChanger->changeIncidence( oldTodo, mTodo );
261 delete todo;
262 delete oldTodo;
263 return rc;
264 } else {
265 mTodo = new Todo;
266 mTodo->setOrganizer( Person( KOPrefs::instance()->fullName(),
267 KOPrefs::instance()->email() ) );
269 fillTodo( mTodo );
271 if ( !mChanger->addIncidence( mTodo, this ) ) {
272 delete mTodo;
273 mTodo = 0;
274 return false;
278 return true;
282 void KOTodoEditor::deleteTodo()
284 if ( mTodo ) {
285 emit deleteIncidenceSignal( mTodo );
287 emit dialogClose( mTodo );
288 reject();
291 void KOTodoEditor::setDates( const QDateTime &due, bool allDay, Todo *relatedEvent )
293 mRelatedTodo = relatedEvent;
294 KDateTime::Spec timeSpec = KOPrefs::instance()->timeSpec();
296 // inherit some properties from parent todo
297 if ( mRelatedTodo ) {
298 mGeneral->setCategories( mRelatedTodo->categories() );
300 if ( !due.isValid() && mRelatedTodo && mRelatedTodo->hasDueDate() ) {
301 mGeneral->setDefaults( mRelatedTodo->dtDue().toTimeSpec( timeSpec ).dateTime(), allDay );
302 } else {
303 mGeneral->setDefaults( due, allDay );
306 mDetails->setDefaults();
307 if ( mTodo ) {
308 mRecurrence->setDefaults(
309 mTodo->dtStart().toTimeSpec( timeSpec ).dateTime(), due, false );
310 } else {
311 mRecurrence->setDefaults(
312 KDateTime::currentUtcDateTime().toTimeSpec( timeSpec ).dateTime(), due, false );
316 void KOTodoEditor::readTodo( Todo *todo, bool tmpl )
318 if ( !todo ) {
319 return;
322 mGeneral->readTodo( todo, tmpl );
323 mDetails->readIncidence( todo );
324 mRecurrence->readIncidence( todo );
326 createEmbeddedURLPages( todo );
327 readDesignerFields( todo );
330 void KOTodoEditor::fillTodo( Todo *todo )
332 Incidence *oldIncidence = todo->clone();
334 mGeneral->fillTodo( todo );
335 mDetails->fillIncidence( todo );
336 mRecurrence->fillIncidence( todo );
338 if ( *( oldIncidence->recurrence() ) != *( todo->recurrence() ) ) {
339 todo->setDtDue( todo->dtDue(), true );
340 if ( todo->hasStartDate() ) {
341 todo->setDtStart( todo->dtStart() );
344 writeDesignerFields( todo );
346 // set related incidence, i.e. parent to-do in this case.
347 if ( mRelatedTodo ) {
348 todo->setRelatedTo( mRelatedTodo );
351 cancelRemovedAttendees( todo );
354 bool KOTodoEditor::validateInput()
356 if ( !mGeneral->validateInput() ) {
357 return false;
359 if ( !mRecurrence->validateInput() ) {
360 return false;
362 if ( !mDetails->validateInput() ) {
363 return false;
365 return true;
368 void KOTodoEditor::modified( int modification )
370 Q_UNUSED( modification );
372 // Play dumb, just reload the todo. This dialog has become so complicated
373 // that there is no point in trying to be smart here...
374 reload();
377 void KOTodoEditor::loadTemplate( CalendarLocal &cal )
379 Todo::List todos = cal.todos();
380 if ( todos.count() == 0 ) {
381 KMessageBox::error( this, i18nc( "@info", "Template does not contain a valid to-do." ) );
382 } else {
383 readTodo( todos.first(), true );
387 void KOTodoEditor::slotSaveTemplate( const QString &templateName )
389 Todo *todo = new Todo;
390 fillTodo( todo );
391 saveAsTemplate( todo, templateName );
394 QStringList &KOTodoEditor::templates() const
396 return KOPrefs::instance()->mTodoTemplates;
399 void KOTodoEditor::show()
401 fillTodo( &mInitialTodo );
402 KOIncidenceEditor::show();
405 #include "kotodoeditor.moc"