/*
This file is part of KOrganizer .
Copyright ( c ) 2001 , 2002 , 2003 Cornelius Schumacher < schumacher @ kde . org >
Copyright ( C ) 2003 - 2004 Reinhold Kainhofer < reinhold @ kainhofer . com >
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
As a special exception , permission is given to link this program
with any edition of TQt , and distribute the resulting executable ,
without including the source code for TQt in the source distribution .
*/
# include <tqtooltip.h>
# include <tqframe.h>
# include <tqpixmap.h>
# include <tqlayout.h>
# include <tqwidgetstack.h>
# include <tqwhatsthis.h>
# include <kiconloader.h>
# include <kdebug.h>
# include <tdelocale.h>
# include <tdemessagebox.h>
# include <libkcal/calendarresources.h>
# include <libkcal/resourcecalendar.h>
# include <libkcal/incidenceformatter.h>
# include <libkcal/calendarlocal.h>
# include "koprefs.h"
# include "koeditorgeneralevent.h"
# include "koeditorrecurrence.h"
# include "koeditordetails.h"
# include "koeditorfreebusy.h"
# include "kogroupware.h"
# include "kodialogmanager.h"
# include "incidencechanger.h"
# include "koeventeditor.h"
KOEventEditor : : KOEventEditor ( Calendar * calendar , TQWidget * parent )
: KOIncidenceEditor ( TQString ( ) , calendar , parent ) ,
mEvent ( 0 ) , mCalendar ( 0 ) , mGeneral ( 0 ) , mRecurrence ( 0 ) , mFreeBusy ( 0 )
{
}
KOEventEditor : : ~ KOEventEditor ( )
{
if ( ! mIsCounter )
emit dialogClose ( mEvent ) ;
}
void KOEventEditor : : init ( )
{
setupGeneral ( ) ;
setupRecurrence ( ) ;
setupFreeBusy ( ) ;
setupDesignerTabs ( " event " ) ;
// Propagate date time settings to recurrence tab
connect ( mGeneral , TQ_SIGNAL ( dateTimesChanged ( const TQDateTime & , const TQDateTime & ) ) ,
mRecurrence , TQ_SLOT ( setDateTimes ( const TQDateTime & , const TQDateTime & ) ) ) ;
connect ( mGeneral , TQ_SIGNAL ( dateTimeStrChanged ( const TQString & ) ) ,
mRecurrence , TQ_SLOT ( setDateTimeStr ( const TQString & ) ) ) ;
connect ( mFreeBusy , TQ_SIGNAL ( dateTimesChanged ( const TQDateTime & , const TQDateTime & ) ) ,
mRecurrence , TQ_SLOT ( setDateTimes ( const TQDateTime & , const TQDateTime & ) ) ) ;
// Propagate date time settings to gantt tab and back
connect ( mGeneral , TQ_SIGNAL ( dateTimesChanged ( const TQDateTime & , const TQDateTime & ) ) ,
mFreeBusy , TQ_SLOT ( slotUpdateGanttView ( const TQDateTime & , const TQDateTime & ) ) ) ;
connect ( mFreeBusy , TQ_SIGNAL ( dateTimesChanged ( const TQDateTime & , const TQDateTime & ) ) ,
mGeneral , TQ_SLOT ( setDateTimes ( const TQDateTime & , const TQDateTime & ) ) ) ;
connect ( mGeneral , TQ_SIGNAL ( focusReceivedSignal ( ) ) ,
TQ_SIGNAL ( focusReceivedSignal ( ) ) ) ;
connect ( mGeneral , TQ_SIGNAL ( openCategoryDialog ( ) ) ,
TQ_SIGNAL ( editCategories ( ) ) ) ;
connect ( this , TQ_SIGNAL ( updateCategoryConfig ( ) ) ,
mGeneral , TQ_SIGNAL ( updateCategoryConfig ( ) ) ) ;
connect ( mFreeBusy , TQ_SIGNAL ( updateAttendeeSummary ( int ) ) ,
mGeneral , TQ_SLOT ( updateAttendeeSummary ( int ) ) ) ;
connect ( mGeneral , TQ_SIGNAL ( editRecurrence ( ) ) ,
mRecurrenceDialog , TQ_SLOT ( show ( ) ) ) ;
connect ( mRecurrenceDialog , TQ_SIGNAL ( okClicked ( ) ) ,
TQ_SLOT ( updateRecurrenceSummary ( ) ) ) ;
connect ( mGeneral , TQ_SIGNAL ( acceptInvitation ( ) ) ,
mFreeBusy , TQ_SLOT ( acceptForMe ( ) ) ) ;
connect ( mGeneral , TQ_SIGNAL ( declineInvitation ( ) ) ,
mFreeBusy , TQ_SLOT ( declineForMe ( ) ) ) ;
}
void KOEventEditor : : reload ( )
{
kdDebug ( 5850 ) < < " KOEventEditor::reload() " < < endl ;
if ( mEvent ) {
readEvent ( mEvent , mCalendar , TQDate ( ) ) ;
}
}
void KOEventEditor : : setupGeneral ( )
{
mGeneral = new KOEditorGeneralEvent ( this ) ;
if ( KOPrefs : : instance ( ) - > mCompactDialogs ) {
TQFrame * topFrame = addPage ( i18n ( " General " ) ) ;
TQWhatsThis : : add ( topFrame ,
i18n ( " The General tab allows you to set the most common "
" options for the event. " ) ) ;
TQBoxLayout * topLayout = new TQVBoxLayout ( topFrame ) ;
topLayout - > setSpacing ( spacingHint ( ) ) ;
mGeneral - > initHeader ( topFrame , topLayout ) ;
mGeneral - > initTime ( topFrame , topLayout ) ;
topLayout - > addStretch ( 1 ) ;
TQFrame * topFrame2 = addPage ( i18n ( " Details " ) ) ;
TQBoxLayout * topLayout2 = new TQVBoxLayout ( topFrame2 ) ;
topLayout2 - > setSpacing ( spacingHint ( ) ) ;
mGeneral - > initClass ( topFrame2 , topLayout2 ) ;
mGeneral - > initSecrecy ( topFrame2 , topLayout2 ) ;
mGeneral - > initDescription ( topFrame2 , topLayout2 ) ;
} else {
TQFrame * topFrame = addPage ( i18n ( " &General " ) ) ;
TQWhatsThis : : add ( topFrame ,
i18n ( " The General tab allows you to set the most common "
" options for the event. " ) ) ;
TQBoxLayout * topLayout = new TQVBoxLayout ( topFrame ) ;
topLayout - > setSpacing ( spacingHint ( ) ) ;
mGeneral - > initInvitationBar ( topFrame , topLayout ) ;
mGeneral - > initHeader ( topFrame , topLayout ) ;
mGeneral - > initTime ( topFrame , topLayout ) ;
mGeneral - > initDescription ( topFrame , topLayout ) ;
mGeneral - > initAttachments ( topFrame , topLayout ) ;
connect ( mGeneral , TQ_SIGNAL ( openURL ( const KURL & ) ) ,
this , TQ_SLOT ( openURL ( const KURL & ) ) ) ;
connect ( this , TQ_SIGNAL ( signalAddAttachments ( const TQStringList & , const TQStringList & , bool ) ) ,
mGeneral , TQ_SLOT ( addAttachments ( const TQStringList & , const TQStringList & , bool ) ) ) ;
}
mGeneral - > finishSetup ( ) ;
}
void KOEventEditor : : modified ( )
{
// Play dumb, just reload the event. This dialog has become so complicated
// that there is no point in trying to be smart here...
reload ( ) ;
}
void KOEventEditor : : setupRecurrence ( )
{
mRecurrenceDialog = new KOEditorRecurrenceDialog ( this ) ;
mRecurrenceDialog - > hide ( ) ;
mRecurrence = mRecurrenceDialog - > editor ( ) ;
}
void KOEventEditor : : setupFreeBusy ( )
{
TQFrame * freeBusyPage = addPage ( i18n ( " &Attendees " ) ) ;
TQWhatsThis : : add ( freeBusyPage ,
i18n ( " The Free/Busy tab allows you to see whether "
" other attendees are free or busy during your event. " ) ) ;
TQBoxLayout * topLayout = new TQVBoxLayout ( freeBusyPage ) ;
mAttendeeEditor = mFreeBusy = new KOEditorFreeBusy ( spacingHint ( ) , freeBusyPage ) ;
topLayout - > addWidget ( mFreeBusy ) ;
}
void KOEventEditor : : editIncidence ( Incidence * incidence ,
const TQDate & date ,
Calendar * calendar )
{
Event * event = dynamic_cast < Event * > ( incidence ) ;
if ( event ) {
init ( ) ;
mEvent = event ;
mCalendar = calendar ;
const TQDate & dt = mRecurIncidence & & date . isValid ( ) ? date : incidence - > dtStart ( ) . date ( ) ;
readEvent ( mEvent , mCalendar , dt ) ;
}
setCaption ( i18n ( " Edit Event " ) ) ;
}
void KOEventEditor : : newEvent ( )
{
init ( ) ;
mEvent = 0 ;
loadDefaults ( ) ;
setCaption ( i18n ( " New Event " ) ) ;
}
void KOEventEditor : : setDates ( const TQDateTime & from , const TQDateTime & to , bool allDay )
{
mGeneral - > setDefaults ( from , to , allDay ) ;
mRecurrence - > setDefaults ( from , to , allDay ) ;
if ( mFreeBusy ) {
if ( allDay )
mFreeBusy - > setDateTimes ( from , to . addDays ( 1 ) ) ;
else
mFreeBusy - > setDateTimes ( from , to ) ;
}
}
void KOEventEditor : : setTexts ( const TQString & summary , const TQString & description )
{
if ( description . isEmpty ( ) & & summary . contains ( " \n " ) ) {
mGeneral - > setDescription ( summary ) ;
int pos = summary . find ( " \n " ) ;
mGeneral - > setSummary ( summary . left ( pos ) ) ;
} else {
mGeneral - > setSummary ( summary ) ;
mGeneral - > setDescription ( description ) ;
}
}
void KOEventEditor : : loadDefaults ( )
{
TQDateTime from ( TQDate : : currentDate ( ) , KOPrefs : : instance ( ) - > mStartTime . time ( ) ) ;
int addSecs = ( KOPrefs : : instance ( ) - > mDefaultDuration . time ( ) . hour ( ) * 3600 ) +
( KOPrefs : : instance ( ) - > mDefaultDuration . time ( ) . minute ( ) * 60 ) ;
TQDateTime to ( from . addSecs ( addSecs ) ) ;
setDates ( from , to , false ) ;
}
bool KOEventEditor : : processInput ( )
{
kdDebug ( 5850 ) < < " KOEventEditor::processInput(); event is " < < mEvent < < endl ;
if ( ! validateInput ( ) | | ! mChanger ) {
kdDebug ( 5850 ) < < " mChanger is " < < mChanger < < endl ;
return false ;
}
TQGuardedPtr < KOEditorFreeBusy > freeBusy ( mFreeBusy ) ;
if ( mEvent ) {
bool rc = true ;
Event * oldEvent = mEvent - > clone ( ) ;
Event * event = mEvent - > clone ( ) ;
kdDebug ( 5850 ) < < " KOEventEditor::processInput() write event. " < < endl ;
writeEvent ( event ) ;
kdDebug ( 5850 ) < < " KOEventEditor::processInput() event written. " < < endl ;
if ( * event = = * mEvent ) {
// Don't do anything
kdDebug ( 5850 ) < < " Event not changed " < < endl ;
if ( mIsCounter ) {
KMessageBox : : information ( this , i18n ( " You didn't change the event, thus no counter proposal has been sent to the organizer. " ) , i18n ( " No changes " ) ) ;
}
} else {
kdDebug ( 5850 ) < < " Event changed " < < endl ;
//IncidenceChanger::assignIncidence( mEvent, event );
writeEvent ( mEvent ) ;
if ( mIsCounter ) {
KOGroupware : : instance ( ) - > sendCounterProposal ( mCalendar , oldEvent , mEvent ) ;
// add dummy event at the position of the counter proposal
Event * event = mEvent - > clone ( ) ;
event - > clearAttendees ( ) ;
event - > setSummary ( i18n ( " My counter proposal for: %1 " ) . arg ( mEvent - > summary ( ) ) ) ;
mChanger - > addIncidence ( event , mResource , mSubResource , this ) ;
} else {
if ( mRecurIncidence & & mRecurIncidenceAfterDissoc ) {
mChanger - > addIncidence ( mEvent , mResource , mSubResource , this ) ;
mChanger - > changeIncidence ( mRecurIncidence , mRecurIncidenceAfterDissoc ,
KOGlobals : : RECURRENCE_MODIFIED_ALL_FUTURE , this ) ;
} else {
mChanger - > changeIncidence ( oldEvent , mEvent , KOGlobals : : NOTHING_MODIFIED , this ) ;
}
}
}
delete event ;
delete oldEvent ;
return rc ;
} else {
mEvent = new Event ;
mEvent - > setOrganizer ( Person ( KOPrefs : : instance ( ) - > fullName ( ) ,
KOPrefs : : instance ( ) - > email ( ) ) ) ;
writeEvent ( mEvent ) ;
// NOTE: triggered by addIncidence, the kolab resource might open a non-modal dialog (parent is not available in the resource) to select a resource folder. Thus the user can close this dialog before addIncidence() returns.
if ( ! mChanger - > addIncidence ( mEvent , mResource , mSubResource , this ) ) {
delete mEvent ;
mEvent = 0 ;
return false ;
}
}
// if "this" was deleted, freeBusy is 0 (being a guardedptr)
if ( freeBusy ) {
freeBusy - > cancelReload ( ) ;
}
return true ;
}
void KOEventEditor : : processCancel ( )
{
kdDebug ( 5850 ) < < " KOEventEditor::processCancel() " < < endl ;
if ( mFreeBusy ) mFreeBusy - > cancelReload ( ) ;
if ( mRecurIncidence & & mRecurIncidenceAfterDissoc ) {
* mRecurIncidenceAfterDissoc = * mRecurIncidence ;
}
}
void KOEventEditor : : deleteEvent ( )
{
kdDebug ( 5850 ) < < " Delete event " < < endl ;
if ( mEvent )
emit deleteIncidenceSignal ( mEvent ) ;
emit dialogClose ( mEvent ) ;
reject ( ) ;
}
void KOEventEditor : : readEvent ( Event * event , Calendar * calendar , const TQDate & date , bool tmpl )
{
mGeneral - > readEvent ( event , calendar , date , tmpl ) ;
mRecurrence - > readIncidence ( event ) ;
if ( mFreeBusy ) {
mFreeBusy - > readEvent ( event ) ;
mFreeBusy - > triggerReload ( ) ;
}
createEmbeddedURLPages ( event ) ;
readDesignerFields ( event ) ;
if ( mIsCounter )
mGeneral - > invitationBar ( ) - > hide ( ) ;
}
void KOEventEditor : : writeEvent ( Event * event )
{
mGeneral - > writeEvent ( event ) ;
if ( mFreeBusy )
mFreeBusy - > writeEvent ( event ) ;
cancelRemovedAttendees ( event ) ;
mRecurrence - > writeIncidence ( event ) ;
writeDesignerFields ( event ) ;
}
bool KOEventEditor : : validateInput ( )
{
if ( ! mGeneral - > validateInput ( ) | |
! mDetails - > validateInput ( ) | |
! mRecurrence - > validateInput ( ) ) {
kdDebug ( 5850 ) < < " ValidateInput returns false " < < endl ;
return false ;
} else {
return true ;
}
}
int KOEventEditor : : msgItemDelete ( )
{
return KMessageBox : : warningContinueCancel ( this ,
i18n ( " This item will be permanently deleted. " ) ,
Bring filenew, fileopen, fileprint, filequickprint, filesave, filesaveas, fileclose, editclear, editcopy, editcut, editdelete, editpaste, folder_new, and gohome icons into XDG compliance
10 years ago
i18n ( " KOrganizer Confirmation " ) , KGuiItem ( i18n ( " Delete " ) , " edit-delete " ) ) ;
}
void KOEventEditor : : loadTemplate ( /*const*/ CalendarLocal & cal )
{
const Event : : List events = cal . events ( ) ;
if ( events . count ( ) = = 0 ) {
KMessageBox : : error ( this ,
i18n ( " Template does not contain a valid event. " ) ) ;
} else {
kdDebug ( 5850 ) < < " KOEventEditor::slotLoadTemplate(): readTemplate " < < endl ;
readEvent ( events . first ( ) , 0 , TQDate ( ) , true ) ;
}
}
TQStringList & KOEventEditor : : templates ( ) const
{
return KOPrefs : : instance ( ) - > mEventTemplates ;
}
void KOEventEditor : : slotSaveTemplate ( const TQString & templateName )
{
kdDebug ( 5006 ) < < " SlotSaveTemplate " < < endl ;
Event * event = new Event ;
writeEvent ( event ) ;
saveAsTemplate ( event , templateName ) ;
}
TQObject * KOEventEditor : : typeAheadReceiver ( ) const
{
return mGeneral - > typeAheadReceiver ( ) ;
}
void KOEventEditor : : updateRecurrenceSummary ( )
{
Event * ev = new Event ( ) ;
writeEvent ( ev ) ;
mGeneral - > updateRecurrenceSummary ( ev ) ;
delete ev ;
}
void KOEventEditor : : selectInvitationCounterProposal ( bool enable )
{
KOIncidenceEditor : : selectInvitationCounterProposal ( enable ) ;
if ( enable )
mGeneral - > invitationBar ( ) - > hide ( ) ;
}
# include "koeventeditor.moc"