2 Copyright (c) 2010 Bertjan Broeksema <broeksema@kde.org>
3 Copyright (c) 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
5 This library is free software; you can redistribute it and/or modify it
6 under the terms of the GNU Library General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or (at your
8 option) any later version.
10 This library is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 License for more details.
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #include "eventortododialog.h"
22 #include "combinedincidenceeditor.h"
23 #include "editorconfig.h"
24 #include "incidencealarm.h"
25 #include "incidenceattachment.h"
26 #include "incidenceattendee.h"
27 #include "incidencecategories.h"
28 #include "incidencecompletionpriority.h"
29 #include "incidencedatetime.h"
30 #include "incidencedescription.h"
31 #include "incidencerecurrence.h"
32 #include "incidencesecrecy.h"
33 #include "incidencewhatwhere.h"
34 #include "invitationdispatcher.h"
35 #include "templatemanagementdialog.h"
36 #include "ui_eventortododesktop.h"
38 #include <calendarsupport/kcalprefs.h>
39 #include <calendarsupport/utils.h>
41 #include <Akonadi/CollectionComboBox>
42 #include <Akonadi/Item>
44 #include <KCalCore/ICalFormat>
45 #include <KCalCore/MemoryCalendar>
46 #include <KCalUtils/Stringify>
48 #include <KMessageBox>
49 #include <KStandardDirs>
50 #include <KSystemTimeZones>
52 using namespace IncidenceEditorNG
;
54 namespace IncidenceEditorNG
{
64 class EventOrTodoDialogPrivate
: public ItemEditorUi
66 EventOrTodoDialog
*q_ptr
;
67 Q_DECLARE_PUBLIC( EventOrTodoDialog
)
70 Ui::EventOrTodoDesktop
*mUi
;
71 Akonadi::CollectionComboBox
*mCalSelector
;
74 EditorItemManager
*mItemManager
;
75 InvitationDispatcher
*mInvitationDispatcher
;
77 CombinedIncidenceEditor
*mEditor
;
78 IncidenceDateTime
*mIeDateTime
;
79 IncidenceAttendee
*mIeAttendee
;
80 IncidenceRecurrence
*mIeRecurrence
;
83 QString
typeToString( const int type
) const;
86 EventOrTodoDialogPrivate( EventOrTodoDialog
*qq
);
87 ~EventOrTodoDialogPrivate();
90 void handleAlarmCountChange( int newCount
);
91 void handleRecurrenceChange( IncidenceEditorNG::RecurrenceType type
);
92 void loadTemplate( const QString
&templateName
);
93 void manageTemplates();
94 void saveTemplate( const QString
&templateName
);
95 void storeTemplatesInConfig( const QStringList
&newTemplates
);
96 void updateAttachmentCount( int newCount
);
97 void updateAttendeeCount( int newCount
);
98 void updateButtonStatus( bool isDirty
);
100 /// ItemEditorUi methods
101 virtual bool containsPayloadIdentifiers( const QSet
<QByteArray
> &partIdentifiers
) const;
102 void handleItemSaveFinish( EditorItemManager::SaveAction
);
103 void handleItemSaveFail( EditorItemManager::SaveAction
, const QString
&errorMessage
);
104 virtual bool hasSupportedPayload( const Akonadi::Item
&item
) const;
105 virtual bool isDirty() const;
106 virtual bool isValid() const;
107 virtual void load( const Akonadi::Item
&item
);
108 virtual Akonadi::Item
save( const Akonadi::Item
&item
);
109 virtual Akonadi::Collection
selectedCollection() const;
110 void slotButtonClicked( int button
);
112 virtual void reject( RejectReason reason
, const QString
&errorMessage
= QString() );
117 EventOrTodoDialogPrivate::EventOrTodoDialogPrivate( EventOrTodoDialog
*qq
)
119 mUi( new Ui::EventOrTodoDesktop
),
120 mCalSelector( new Akonadi::CollectionComboBox
),
121 mCloseOnSave( false ),
122 mItemManager( new EditorItemManager( this ) ),
123 mInvitationDispatcher( 0 ),
124 mEditor( new CombinedIncidenceEditor
),
125 mInitiallyDirty( false )
127 Q_Q( EventOrTodoDialog
);
128 mUi
->setupUi( q
->mainWidget() );
129 QGridLayout
*layout
= new QGridLayout( mUi
->mCalSelectorPlaceHolder
);
130 layout
->setSpacing( 0 );
131 layout
->addWidget( mCalSelector
);
133 mCalSelector
->setAccessRightsFilter( Akonadi::Collection::CanCreateItem
);
135 q
->connect( mCalSelector
, SIGNAL(currentChanged(Akonadi::Collection
)),
136 SLOT(handleSelectedCollectionChange(Akonadi::Collection
)) );
138 if ( CalendarSupport::KCalPrefs::instance()->useGroupwareCommunication() ) {
139 mInvitationDispatcher
= new InvitationDispatcher( 0, q
);
140 mInvitationDispatcher
->setItemManager( mItemManager
);
143 // Now instantiate the logic of the dialog. These editors update the ui, validate
144 // fields and load/store incidences in the ui.
145 IncidenceWhatWhere
*ieGeneral
= new IncidenceWhatWhere( mUi
);
146 mEditor
->combine( ieGeneral
);
148 IncidenceCategories
*ieCategories
= new IncidenceCategories( mUi
);
149 mEditor
->combine( ieCategories
);
151 mIeDateTime
= new IncidenceDateTime( mUi
);
152 mEditor
->combine( mIeDateTime
);
154 IncidenceCompletionPriority
*ieCompletionPriority
= new IncidenceCompletionPriority( mUi
);
155 mEditor
->combine( ieCompletionPriority
);
157 IncidenceDescription
*ieDescription
= new IncidenceDescription( mUi
);
158 mEditor
->combine( ieDescription
);
160 IncidenceAlarm
*ieAlarm
= new IncidenceAlarm( mIeDateTime
, mUi
);
161 mEditor
->combine( ieAlarm
);
163 IncidenceAttachment
*ieAttachments
= new IncidenceAttachment( mUi
);
164 mEditor
->combine( ieAttachments
);
166 mIeRecurrence
= new IncidenceRecurrence( mIeDateTime
, mUi
);
167 mEditor
->combine( mIeRecurrence
);
169 IncidenceSecrecy
*ieSecrecy
= new IncidenceSecrecy( mUi
);
170 mEditor
->combine( ieSecrecy
);
172 mIeAttendee
= new IncidenceAttendee( qq
, mIeDateTime
, mUi
);
173 mEditor
->combine( mIeAttendee
);
175 q
->connect( mEditor
, SIGNAL(dirtyStatusChanged(bool)),
176 SLOT(updateButtonStatus(bool)) );
177 q
->connect( mItemManager
,
178 SIGNAL(itemSaveFinished(IncidenceEditorNG::EditorItemManager::SaveAction
)),
179 SLOT(handleItemSaveFinish(IncidenceEditorNG::EditorItemManager::SaveAction
)));
180 q
->connect( mItemManager
,
181 SIGNAL(itemSaveFailed(IncidenceEditorNG::EditorItemManager::SaveAction
,QString
)),
182 SLOT(handleItemSaveFail(IncidenceEditorNG::EditorItemManager::SaveAction
,QString
)));
183 q
->connect( ieAlarm
, SIGNAL(alarmCountChanged(int)),
184 SLOT(handleAlarmCountChange(int)) );
185 q
->connect( mIeRecurrence
, SIGNAL(recurrenceChanged(IncidenceEditorNG::RecurrenceType
)),
186 SLOT(handleRecurrenceChange(IncidenceEditorNG::RecurrenceType
)) );
187 q
->connect( ieAttachments
, SIGNAL(attachmentCountChanged(int)),
188 SLOT(updateAttachmentCount(int)) );
189 q
->connect( mIeAttendee
, SIGNAL(attendeeCountChanged(int)),
190 SLOT(updateAttendeeCount(int)) );
193 EventOrTodoDialogPrivate::~EventOrTodoDialogPrivate()
200 void EventOrTodoDialogPrivate::handleAlarmCountChange( int newCount
)
203 if ( newCount
> 0 ) {
205 i18nc( "@title:tab Tab to configure the reminders of an event or todo",
206 "Reminder (%1)", newCount
);
209 i18nc( "@title:tab Tab to configure the reminders of an event or todo",
213 mUi
->mTabWidget
->setTabText( AlarmsTab
, tabText
);
216 void EventOrTodoDialogPrivate::handleRecurrenceChange( IncidenceEditorNG::RecurrenceType type
)
219 i18nc( "@title:tab Tab to configure the recurrence of an event or todo",
222 // Keep this numbers in sync with the items in mUi->mRecurrenceTypeCombo. I
223 // tried adding an enum to IncidenceRecurrence but for whatever reason I could
224 // Qt not play nice with namespaced enums in signal/slot connections.
225 // Anyways, I don't expect these values to change.
227 case RecurrenceTypeNone
:
229 case RecurrenceTypeDaily
:
230 tabText
+= i18nc( "@title:tab Daily recurring event, capital first letter only", " (D)" );
232 case RecurrenceTypeWeekly
:
233 tabText
+= i18nc( "@title:tab Weekly recurring event, capital first letter only", " (W)" );
235 case RecurrenceTypeMonthly
:
236 tabText
+= i18nc( "@title:tab Monthly recurring event, capital first letter only", " (M)" );
238 case RecurrenceTypeYearly
:
239 tabText
+= i18nc( "@title:tab Yearly recurring event, capital first letter only", " (Y)" );
242 Q_ASSERT_X( false, "handleRecurrenceChange", "Fix your program" );
245 mUi
->mTabWidget
->setTabText( RecurrenceTab
, tabText
);
248 QString
EventOrTodoDialogPrivate::typeToString( const int type
) const
252 case KCalCore::Incidence::TypeEvent
:
254 case KCalCore::Incidence::TypeTodo
:
256 case KCalCore::Incidence::TypeJournal
:
263 void EventOrTodoDialogPrivate::loadTemplate( const QString
&templateName
)
265 Q_Q( EventOrTodoDialog
);
267 KCalCore::MemoryCalendar::Ptr
cal( new KCalCore::MemoryCalendar( KSystemTimeZones::local() ) );
269 const QString fileName
= KStandardDirs::locateLocal(
271 "korganizer/templates/" +
272 typeToString( mEditor
->type() ) + '/' +
275 if ( fileName
.isEmpty() ) {
278 i18nc( "@info", "Unable to find template '%1'.", fileName
) );
282 KCalCore::ICalFormat format
;
283 if ( !format
.load( cal
, fileName
) ) {
286 i18nc( "@info", "Error loading template file '%1'.", fileName
) );
290 KCalCore::Incidence::List incidences
= cal
->incidences();
291 if ( incidences
.isEmpty() ) {
294 i18nc( "@info", "Template does not contain a valid incidence." ) );
298 mIeDateTime
->setActiveDate( QDate() );
299 KCalCore::Incidence::Ptr newInc
= KCalCore::Incidence::Ptr( incidences
.first()->clone() );
300 newInc
->setUid( KCalCore::CalFormat::createUniqueId() );
301 mEditor
->load( newInc
);
304 void EventOrTodoDialogPrivate::manageTemplates()
306 Q_Q( EventOrTodoDialog
);
308 QStringList
&templates
=
309 IncidenceEditorNG::EditorConfig::instance()->templates( mEditor
->type() );
311 QPointer
<IncidenceEditorNG::TemplateManagementDialog
> dialog(
312 new IncidenceEditorNG::TemplateManagementDialog(
313 q
, templates
, KCalUtils::Stringify::incidenceType( mEditor
->type() ) ) );
315 q
->connect( dialog
, SIGNAL(loadTemplate(QString
)),
316 SLOT(loadTemplate(QString
)) );
317 q
->connect( dialog
, SIGNAL(templatesChanged(QStringList
)),
318 SLOT(storeTemplatesInConfig(QStringList
)) );
319 q
->connect( dialog
, SIGNAL(saveTemplate(QString
)),
320 SLOT(saveTemplate(QString
)) );
325 void EventOrTodoDialogPrivate::saveTemplate( const QString
&templateName
)
327 Q_ASSERT( ! templateName
.isEmpty() );
329 KCalCore::MemoryCalendar::Ptr
cal( new KCalCore::MemoryCalendar( KSystemTimeZones::local() ) );
331 switch( mEditor
->type() ) {
332 case KCalCore::Incidence::TypeEvent
:
334 KCalCore::Event::Ptr
event( new KCalCore::Event() );
335 mEditor
->save( event
);
336 cal
->addEvent( KCalCore::Event::Ptr( event
->clone() ) );
339 case KCalCore::Incidence::TypeTodo
:
341 KCalCore::Todo::Ptr
todo( new KCalCore::Todo
);
342 mEditor
->save( todo
);
343 cal
->addTodo( KCalCore::Todo::Ptr( todo
->clone() ) );
346 case KCalCore::Incidence::TypeJournal
:
348 KCalCore::Journal::Ptr
journal( new KCalCore::Journal
);
349 mEditor
->save( journal
);
350 cal
->addJournal( KCalCore::Journal::Ptr( journal
->clone() ) );
354 Q_ASSERT_X( false, "saveTemplate", "Fix your program" );
357 const QString fileName
= KStandardDirs::locateLocal(
359 "korganizer/templates/" +
360 typeToString( mEditor
->type() ) + '/' +
363 KCalCore::ICalFormat format
;
364 format
.save( cal
, fileName
);
367 void EventOrTodoDialogPrivate::storeTemplatesInConfig( const QStringList
&templateNames
)
369 // I find this somewhat broken. templates() returns a reference, maybe it should
370 // be changed by adding a setTemplates method.
371 IncidenceEditorNG::EditorConfig::instance()->templates( mEditor
->type() ) = templateNames
;
372 IncidenceEditorNG::EditorConfig::instance()->config()->writeConfig();
375 void EventOrTodoDialogPrivate::updateAttachmentCount( int newCount
)
377 if ( newCount
> 0 ) {
378 mUi
->mTabWidget
->setTabText(
380 i18nc( "@title:tab Tab to modify attachments of an event or todo",
381 "Attac&hments (%1)", newCount
) );
383 mUi
->mTabWidget
->setTabText(
385 i18nc( "@title:tab Tab to modify attachments of an event or todo",
390 void EventOrTodoDialogPrivate::updateAttendeeCount( int newCount
)
392 if ( newCount
> 0 ) {
393 mUi
->mTabWidget
->setTabText(
395 i18nc( "@title:tab Tab to modify attendees of an event or todo",
396 "&Attendees (%1)", newCount
) );
398 mUi
->mTabWidget
->setTabText(
400 i18nc( "@title:tab Tab to modify attendees of an event or todo",
405 void EventOrTodoDialogPrivate::updateButtonStatus( bool isDirty
)
407 Q_Q( EventOrTodoDialog
);
408 q
->enableButton( KDialog::Apply
, isDirty
|| mInitiallyDirty
);
411 bool EventOrTodoDialogPrivate::containsPayloadIdentifiers(
412 const QSet
<QByteArray
> &partIdentifiers
) const
414 return partIdentifiers
.contains( QByteArray( "PLD:RFC822" ) );
417 void EventOrTodoDialogPrivate::handleItemSaveFail( EditorItemManager::SaveAction
,
418 const QString
&errorMessage
)
420 Q_Q( EventOrTodoDialog
);
424 if ( !errorMessage
.isEmpty() ) {
425 const QString message
= i18nc( "@info",
426 "Unable to store the incidence in the calendar. Try again?\n\n "
427 "Reason: %1", errorMessage
);
428 retry
= ( KMessageBox::warningYesNo( q
, message
) == KMessageBox::Yes
);
432 mItemManager
->save();
434 updateButtonStatus( isDirty() );
435 q
->enableButtonOk( true );
436 q
->enableButtonCancel( true );
440 void EventOrTodoDialogPrivate::handleItemSaveFinish( EditorItemManager::SaveAction
)
442 Q_Q( EventOrTodoDialog
);
444 if ( mCloseOnSave
) {
447 const Akonadi::Item item
= mItemManager
->item();
448 Q_ASSERT( item
.isValid() );
449 Q_ASSERT( item
.hasPayload() );
450 Q_ASSERT( item
.hasPayload
<KCalCore::Incidence::Ptr
>() );
451 // Now the item is succesfull saved, reload it in the editor in order to
452 // reset the dirty status of the editor.
453 mEditor
->load( item
.payload
<KCalCore::Incidence::Ptr
>() );
455 // Set the buttons to a reasonable state as well (ok and apply should be
456 // disabled at this point).
457 q
->enableButtonOk( true );
458 q
->enableButtonCancel( true );
459 q
->enableButtonApply( isDirty() );
463 bool EventOrTodoDialogPrivate::hasSupportedPayload( const Akonadi::Item
&item
) const
465 return CalendarSupport::incidence( item
);
468 bool EventOrTodoDialogPrivate::isDirty() const
470 if ( mItem
.isValid() ) {
471 return mEditor
->isDirty() ||
472 mCalSelector
->currentCollection().id() != mItem
.storageCollectionId();
474 return mEditor
->isDirty();
478 bool EventOrTodoDialogPrivate::isValid() const
480 if ( mEditor
->isValid() ) {
481 // Check if there's a selected collection.
482 if ( mCalSelector
->currentCollection().isValid() ) {
485 kWarning() << "Select a collection first";
492 void EventOrTodoDialogPrivate::load( const Akonadi::Item
&item
)
494 Q_Q( EventOrTodoDialog
);
496 Q_ASSERT( hasSupportedPayload( item
) );
498 if ( CalendarSupport::hasJournal( item
) ) {
499 //mUi->mTabWidget->removeTab( 5 );
500 mUi
->mTabWidget
->removeTab( AttachmentsTab
);
501 mUi
->mTabWidget
->removeTab( RecurrenceTab
);
502 mUi
->mTabWidget
->removeTab( AlarmsTab
);
505 mEditor
->load( CalendarSupport::incidence( item
) );
507 const KCalCore::Incidence::Ptr incidence
= CalendarSupport::incidence( item
);
508 const QStringList allEmails
= IncidenceEditorNG::EditorConfig::instance()->allEmails();
509 KCalCore::Attendee::Ptr me
= incidence
->attendeeByMails( allEmails
);
511 if ( incidence
->attendeeCount() > 1 && // >1 because you won't drink alone
512 me
&& ( me
->status() == KCalCore::Attendee::NeedsAction
||
513 me
->status() == KCalCore::Attendee::Tentative
||
514 me
->status() == KCalCore::Attendee::InProcess
) ) {
515 // Show the invitation bar: "You are invited [accept] [decline]"
516 mUi
->mInvitationBar
->show();
518 mUi
->mInvitationBar
->hide();
521 kDebug() << "Loading item " << item
.id() << "; parent " << item
.parentCollection().id()
522 << "; storage " << item
.storageCollectionId();
524 if ( item
.parentCollection().isValid() ) {
525 mCalSelector
->setDefaultCollection( item
.parentCollection() );
528 if ( !mCalSelector
->mimeTypeFilter().contains( "text/calendar" ) ||
529 !mCalSelector
->mimeTypeFilter().contains( incidence
->mimeType() ) )
531 mCalSelector
->setMimeTypeFilter( QStringList() << incidence
->mimeType() << "text/calendar" );
534 if ( mEditor
->type() == KCalCore::Incidence::TypeTodo
) {
535 q
->setWindowIcon( SmallIcon( "view-calendar-tasks" ) );
536 } else if ( mEditor
->type() == KCalCore::Incidence::TypeEvent
) {
537 q
->setWindowIcon( SmallIcon( "view-calendar-day" ) );
538 } else if ( mEditor
->type() == KCalCore::Incidence::TypeJournal
) {
539 q
->setWindowIcon( SmallIcon( "view-pim-journal" ) );
542 // Initialize tab's titles
543 updateAttachmentCount( incidence
->attachments().size() );
544 handleRecurrenceChange( mIeRecurrence
->currentRecurrenceType() );
545 handleAlarmCountChange( incidence
->alarms().count() );
552 Akonadi::Item
EventOrTodoDialogPrivate::save( const Akonadi::Item
&item
)
554 Q_ASSERT( mEditor
->incidence
<KCalCore::Incidence
>() );
556 KCalCore::Incidence::Ptr incidenceInEditor
= mEditor
->incidence
<KCalCore::Incidence
>();
557 KCalCore::Incidence::Ptr
newIncidence( incidenceInEditor
->clone() );
559 Akonadi::Item result
= item
;
560 result
.setMimeType( newIncidence
->mimeType() );
562 // There's no editor that has the relatedTo property. We must set it here, by hand.
563 // Otherwise it gets lost.
564 // FIXME: Why don't we clone() incidenceInEditor then pass the clone to save(),
565 // I wonder if we're not leaking other properties.
566 newIncidence
->setRelatedTo( incidenceInEditor
->relatedTo() );
568 mEditor
->save( newIncidence
);
570 // TODO: Remove this once we support moving of events/todo's
571 mCalSelector
->setEnabled( false );
573 // Make sure that we don't loose uid for existing incidence
574 newIncidence
->setUid( mEditor
->incidence
<KCalCore::Incidence
>()->uid() );
576 // Mark the incidence as changed
577 if ( mItem
.isValid() ) {
578 newIncidence
->setRevision( newIncidence
->revision() + 1 );
581 result
.setPayload
<KCalCore::Incidence::Ptr
>( newIncidence
);
585 Akonadi::Collection
EventOrTodoDialogPrivate::selectedCollection() const
587 return mCalSelector
->currentCollection();
590 void EventOrTodoDialogPrivate::reject( RejectReason reason
, const QString
&errorMessage
)
594 Q_Q( EventOrTodoDialog
);
595 kError() << "Rejecting:" << errorMessage
;
599 /// EventOrTodoDialog
601 EventOrTodoDialog::EventOrTodoDialog( QWidget
*parent
, Qt::WFlags flags
)
602 : IncidenceDialog( parent
, flags
), d_ptr( new EventOrTodoDialogPrivate( this ) )
604 Q_D( EventOrTodoDialog
);
606 resize( QSize( 600, 500 ).expandedTo( minimumSizeHint() ) );
607 d
->mUi
->mTabWidget
->setCurrentIndex( 0 );
608 d
->mUi
->mSummaryEdit
->setFocus();
610 setButtons( KDialog::Ok
| KDialog::Apply
| KDialog::Cancel
| KDialog::Default
);
611 setButtonToolTip( KDialog::Apply
,
612 i18nc( "@info:tooltip", "Save current changes" ) );
613 setButtonToolTip( KDialog::Ok
,
614 i18nc( "@action:button", "Save changes and close dialog" ) );
615 setButtonToolTip( KDialog::Cancel
,
616 i18nc( "@action:button", "Discard changes and close dialog" ) );
617 setDefaultButton( Ok
);
618 enableButton( Apply
, false );
620 setButtonText( Default
, i18nc( "@action:button", "Manage &Templates..." ) );
621 setButtonToolTip( Default
,
622 i18nc( "@info:tooltip",
623 "Apply or create templates for this item" ) );
624 setButtonWhatsThis( Default
,
625 i18nc( "@info:whatsthis",
626 "Push this button to run a tool that helps "
627 "you manage a set of templates. Templates "
628 "can make creating new items easier and faster "
629 "by putting your favorite default values into "
630 "the editor automatically." ) );
633 showButtonSeparator( false );
635 connect( d
->mUi
->mAcceptInvitationButton
, SIGNAL(clicked()),
636 d
->mIeAttendee
, SLOT(acceptForMe()) );
637 connect( d
->mUi
->mAcceptInvitationButton
, SIGNAL(clicked()),
638 d
->mUi
->mInvitationBar
, SLOT(hide()) );
639 connect( d
->mUi
->mDeclineInvitationButton
, SIGNAL(clicked()),
640 d
->mIeAttendee
, SLOT(declineForMe()) );
641 connect( d
->mUi
->mDeclineInvitationButton
, SIGNAL(clicked()),
642 d
->mUi
->mInvitationBar
, SLOT(hide()) );
645 EventOrTodoDialog::~EventOrTodoDialog()
650 void EventOrTodoDialog::load( const Akonadi::Item
&item
, const QDate
&activeDate
)
652 Q_D( EventOrTodoDialog
);
653 d
->mIeDateTime
->setActiveDate( activeDate
);
654 if ( item
.isValid() ) { // We're editing
655 d
->mItemManager
->load( item
);
656 // TODO: Remove this once we support moving of events/todo's
657 d
->mCalSelector
->setEnabled( false );
658 } else { // We're creating
659 Q_ASSERT( d
->hasSupportedPayload( item
) );
665 void EventOrTodoDialog::selectCollection( const Akonadi::Collection
&collection
)
667 Q_D( EventOrTodoDialog
);
668 if ( collection
.isValid() ) {
669 d
->mCalSelector
->setDefaultCollection( collection
);
671 d
->mCalSelector
->setCurrentIndex( 0 );
675 void EventOrTodoDialog::setIsCounterProposal( bool isCounterProposal
)
677 Q_D( EventOrTodoDialog
);
678 d
->mInvitationDispatcher
->setIsCounterProposal( isCounterProposal
);
681 QObject
*EventOrTodoDialog::typeAheadReceiver() const
683 Q_D( const EventOrTodoDialog
);
684 return d
->mUi
->mSummaryEdit
;
687 void EventOrTodoDialog::slotButtonClicked( int button
)
689 Q_D( EventOrTodoDialog
);
694 if ( d
->isDirty() || d
->mInitiallyDirty
) {
695 enableButtonOk( false );
696 enableButtonCancel( false );
697 enableButtonApply( false );
698 d
->mCloseOnSave
= true;
699 d
->mInitiallyDirty
= false;
700 d
->mItemManager
->save();
708 enableButtonOk( false );
709 enableButtonCancel( false );
710 enableButtonApply( false );
712 d
->mCloseOnSave
= false;
713 d
->mInitiallyDirty
= false;
714 d
->mItemManager
->save();
717 case KDialog::Cancel
:
719 KMessageBox::questionYesNo(
721 i18nc( "@info", "Do you really want to cancel?" ),
722 i18nc( "@title:window", "KOrganizer Confirmation" ) ) == KMessageBox::Yes
) {
723 KDialog::reject(); // Discard current changes
724 } else if ( !d
->isDirty() ) {
725 KDialog::reject(); // No pending changes, just close the dialog.
726 } // else { // the user wasn't finished editting after all }
728 case KDialog::Default
:
729 d
->manageTemplates();
732 Q_ASSERT( false ); // Shouldn't happen
737 void EventOrTodoDialog::setInitiallyDirty( bool initiallyDirty
)
739 Q_D( EventOrTodoDialog
);
740 d
->mInitiallyDirty
= initiallyDirty
;
743 void EventOrTodoDialog::handleSelectedCollectionChange( const Akonadi::Collection
&collection
)
745 Q_D( EventOrTodoDialog
);
746 if ( d
->mItem
.parentCollection().isValid() ) {
747 enableButton( Apply
, collection
.id() != d
->mItem
.parentCollection().id() );
751 #include "eventortododialog.moc"