00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <qtooltip.h>
00026 #include <qframe.h>
00027 #include <qguardedptr.h>
00028 #include <qpixmap.h>
00029 #include <qlayout.h>
00030 #include <qwidgetstack.h>
00031 #include <qdatetime.h>
00032 #include <qwhatsthis.h>
00033
00034 #include <kdebug.h>
00035 #include <klocale.h>
00036 #include <kstandarddirs.h>
00037 #include <kmessagebox.h>
00038 #include <kinputdialog.h>
00039 #include <kio/netaccess.h>
00040 #include <kabc/addressee.h>
00041
00042 #include <libkdepim/designerfields.h>
00043 #include <libkdepim/embeddedurlpage.h>
00044
00045 #include <libkcal/calendarlocal.h>
00046 #include <libkcal/incidence.h>
00047 #include <libkcal/icalformat.h>
00048 #include <libkcal/resourcecalendar.h>
00049
00050 #include "koprefs.h"
00051 #include "koglobals.h"
00052 #include "koeditordetails.h"
00053 #include "koeditoralarms.h"
00054 #include "urihandler.h"
00055 #include "koincidenceeditor.h"
00056 #include "templatemanagementdialog.h"
00057
00058 KOIncidenceEditor::KOIncidenceEditor( const QString &caption,
00059 Calendar *calendar, QWidget *parent )
00060 : KDialogBase( Tabbed, caption, Ok | Apply | Cancel | Default, Ok,
00061 parent, 0, false, false ),
00062 mAttendeeEditor( 0 ), mResource( 0 ), mIsCounter( false ), mIsCreateTask( false ),
00063 mRecurIncidence( 0 ), mRecurIncidenceAfterDissoc( 0 )
00064 {
00065
00066
00067 setWFlags( getWFlags() | WGroupLeader );
00068
00069 mCalendar = calendar;
00070
00071 if ( KOPrefs::instance()->mCompactDialogs ) {
00072 showButton( Apply, false );
00073 showButton( Default, false );
00074 } else {
00075 setButtonText( Default, i18n("&Templates...") );
00076 }
00077
00078 connect( this, SIGNAL( defaultClicked() ), SLOT( slotManageTemplates() ) );
00079 connect( this, SIGNAL( finished() ), SLOT( delayedDestruct() ) );
00080 }
00081
00082 KOIncidenceEditor::~KOIncidenceEditor()
00083 {
00084 }
00085
00086 void KOIncidenceEditor::setupAttendeesTab()
00087 {
00088 QFrame *topFrame = addPage( i18n("Atte&ndees") );
00089 QWhatsThis::add( topFrame,
00090 i18n("The Attendees tab allows you to Add or Remove "
00091 "Attendees to/from this event or to-do.") );
00092
00093 QBoxLayout *topLayout = new QVBoxLayout( topFrame );
00094
00095 mAttendeeEditor = mDetails = new KOEditorDetails( spacingHint(), topFrame );
00096 topLayout->addWidget( mDetails );
00097 }
00098
00099 void KOIncidenceEditor::slotApply()
00100 {
00101 processInput();
00102 }
00103
00104 void KOIncidenceEditor::slotOk()
00105 {
00106
00107
00108
00109 QGuardedPtr<QWidget> ptr( this );
00110 if ( processInput() && ptr ) accept();
00111 }
00112
00113 void KOIncidenceEditor::slotCancel()
00114 {
00115 processCancel();
00116 reject();
00117 }
00118
00119 void KOIncidenceEditor::cancelRemovedAttendees( Incidence *incidence )
00120 {
00121 if ( !incidence ) return;
00122
00123
00124
00125 if ( KOPrefs::instance()->thatIsMe( incidence->organizer().email() ) ) {
00126 Incidence *ev = incidence->clone();
00127 ev->registerObserver( 0 );
00128 mAttendeeEditor->cancelAttendeeEvent( ev );
00129 if ( ev->attendeeCount() > 0 ) {
00130 emit deleteAttendee( ev );
00131 }
00132 delete( ev );
00133 }
00134
00135 }
00136
00137 void KOIncidenceEditor::slotManageTemplates()
00138 {
00139 kdDebug(5850) << "KOIncidenceEditor::manageTemplates()" << endl;
00140
00141 TemplateManagementDialog * const d = new TemplateManagementDialog( this, templates() );
00142 connect( d, SIGNAL( loadTemplate( const QString& ) ),
00143 this, SLOT( slotLoadTemplate( const QString& ) ) );
00144 connect( d, SIGNAL( templatesChanged( const QStringList& ) ),
00145 this, SLOT( slotTemplatesChanged( const QStringList& ) ) );
00146 connect( d, SIGNAL( saveTemplate( const QString& ) ),
00147 this, SLOT( slotSaveTemplate( const QString& ) ) );
00148 d->exec();
00149 return;
00150 }
00151
00152 void KOIncidenceEditor::saveAsTemplate( Incidence *incidence,
00153 const QString &templateName )
00154 {
00155 if ( !incidence || templateName.isEmpty() ) return;
00156
00157 QString fileName = "templates/" + incidence->type();
00158 fileName.append( "/" + templateName );
00159 fileName = locateLocal( "data", "korganizer/" + fileName );
00160
00161 CalendarLocal cal( KOPrefs::instance()->mTimeZoneId );
00162 cal.addIncidence( incidence );
00163 ICalFormat format;
00164 format.save( &cal, fileName );
00165 }
00166
00167 void KOIncidenceEditor::slotLoadTemplate( const QString& templateName )
00168 {
00169 CalendarLocal cal( KOPrefs::instance()->mTimeZoneId );
00170 QString fileName = locateLocal( "data", "korganizer/templates/" + type() + "/" +
00171 templateName );
00172
00173 if ( fileName.isEmpty() ) {
00174 KMessageBox::error( this, i18n("Unable to find template '%1'.")
00175 .arg( fileName ) );
00176 } else {
00177 ICalFormat format;
00178 if ( !format.load( &cal, fileName ) ) {
00179 KMessageBox::error( this, i18n("Error loading template file '%1'.")
00180 .arg( fileName ) );
00181 return;
00182 }
00183 }
00184 loadTemplate( cal );
00185 }
00186
00187 void KOIncidenceEditor::slotTemplatesChanged( const QStringList& newTemplates )
00188 {
00189 templates() = newTemplates;
00190 }
00191
00192 void KOIncidenceEditor::setupDesignerTabs( const QString &type )
00193 {
00194 QStringList activePages = KOPrefs::instance()->activeDesignerFields();
00195
00196 QStringList list = KGlobal::dirs()->findAllResources( "data",
00197 "korganizer/designer/" + type + "/*.ui", true, true );
00198 for ( QStringList::iterator it = list.begin(); it != list.end(); ++it ) {
00199 const QString &fn = (*it).mid( (*it).findRev('/') + 1 );
00200 if ( activePages.find( fn ) != activePages.end() ) {
00201 addDesignerTab( *it );
00202 }
00203 }
00204 }
00205
00206 QWidget *KOIncidenceEditor::addDesignerTab( const QString &uifile )
00207 {
00208 kdDebug(5850) << "Designer tab: " << uifile << endl;
00209
00210 KPIM::DesignerFields *wid = new KPIM::DesignerFields( uifile, 0 );
00211 mDesignerFields.append( wid );
00212
00213 QFrame *topFrame = addPage( wid->title() );
00214
00215 QBoxLayout *topLayout = new QVBoxLayout( topFrame );
00216
00217 wid->reparent( topFrame, 0, QPoint() );
00218 topLayout->addWidget( wid );
00219 mDesignerFieldForWidget[ topFrame ] = wid;
00220
00221 return topFrame;
00222 }
00223
00224 class KCalStorage : public KPIM::DesignerFields::Storage
00225 {
00226 public:
00227 KCalStorage( Incidence *incidence )
00228 : mIncidence( incidence )
00229 {
00230 }
00231
00232 QStringList keys()
00233 {
00234 QStringList keys;
00235
00236 QMap<QCString, QString> props = mIncidence->customProperties();
00237 QMap<QCString, QString>::ConstIterator it;
00238 for( it = props.begin(); it != props.end(); ++it ) {
00239 QString customKey = it.key();
00240 QStringList parts = QStringList::split( "-", customKey );
00241 if ( parts.count() != 4 ) continue;
00242 if ( parts[ 2 ] != "KORGANIZER" ) continue;
00243 keys.append( parts[ 3 ] );
00244 }
00245
00246 return keys;
00247 }
00248
00249 QString read( const QString &key )
00250 {
00251 return mIncidence->customProperty( "KORGANIZER", key.utf8() );
00252 }
00253
00254 void write( const QString &key, const QString &value )
00255 {
00256 mIncidence->setCustomProperty( "KORGANIZER", key.utf8(), value );
00257 }
00258
00259 private:
00260 Incidence *mIncidence;
00261 };
00262
00263 void KOIncidenceEditor::readDesignerFields( Incidence *i )
00264 {
00265 KCalStorage storage( i );
00266 KPIM::DesignerFields *fields;
00267 for( fields = mDesignerFields.first(); fields;
00268 fields = mDesignerFields.next() ) {
00269 fields->load( &storage );
00270 }
00271 }
00272
00273 void KOIncidenceEditor::writeDesignerFields( Incidence *i )
00274 {
00275 kdDebug(5850) << "KOIncidenceEditor::writeDesignerFields()" << endl;
00276
00277 KCalStorage storage( i );
00278 KPIM::DesignerFields *fields;
00279 for( fields = mDesignerFields.first(); fields;
00280 fields = mDesignerFields.next() ) {
00281 kdDebug(5850) << "Write Field " << fields->title() << endl;
00282 fields->save( &storage );
00283 }
00284 }
00285
00286
00287 void KOIncidenceEditor::setupEmbeddedURLPage( const QString &label,
00288 const QString &url, const QString &mimetype )
00289 {
00290 kdDebug(5850) << "KOIncidenceEditor::setupEmbeddedURLPage()" << endl;
00291 kdDebug(5850) << "label=" << label << ", url=" << url << ", mimetype=" << mimetype << endl;
00292 QFrame *topFrame = addPage( label );
00293 QBoxLayout *topLayout = new QVBoxLayout( topFrame );
00294
00295 KPIM::EmbeddedURLPage *wid = new KPIM::EmbeddedURLPage( url, mimetype,
00296 topFrame );
00297 topLayout->addWidget( wid );
00298 mEmbeddedURLPages.append( topFrame );
00299 connect( wid, SIGNAL( openURL( const KURL & ) ) ,
00300 this, SLOT( openURL( const KURL & ) ) );
00301
00302 wid->loadContents();
00303 }
00304
00305 void KOIncidenceEditor::createEmbeddedURLPages( Incidence *i )
00306 {
00307 kdDebug(5850) << "KOIncidenceEditor::createEmbeddedURLPages()" << endl;
00308
00309 if ( !i ) return;
00310 if ( !mEmbeddedURLPages.isEmpty() ) {
00311 kdDebug(5850) << "mEmbeddedURLPages are not empty, clearing it!" << endl;
00312 mEmbeddedURLPages.setAutoDelete( true );
00313 mEmbeddedURLPages.clear();
00314 mEmbeddedURLPages.setAutoDelete( false );
00315 }
00316 if ( !mAttachedDesignerFields.isEmpty() ) {
00317 for ( QPtrList<QWidget>::Iterator it = mAttachedDesignerFields.begin();
00318 it != mAttachedDesignerFields.end(); ++it ) {
00319 if ( mDesignerFieldForWidget.contains( *it ) ) {
00320 mDesignerFields.remove( mDesignerFieldForWidget[ *it ] );
00321 }
00322 }
00323 mAttachedDesignerFields.setAutoDelete( true );
00324 mAttachedDesignerFields.clear();
00325 mAttachedDesignerFields.setAutoDelete( false );
00326 }
00327
00328 Attachment::List att = i->attachments();
00329 for ( Attachment::List::Iterator it = att.begin(); it != att.end(); ++it ) {
00330 Attachment *a = (*it);
00331 kdDebug(5850) << "Iterating over the attachments " << endl;
00332 kdDebug(5850) << "label=" << a->label() << ", url=" << a->uri() << ", mimetype=" << a->mimeType() << endl;
00333 if ( a && a->showInline() && a->isUri() ) {
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 if ( a->mimeType() == "text/html" )
00344 {
00345 setupEmbeddedURLPage( a->label(), a->uri(), a->mimeType() );
00346 }
00347 }
00348 }
00349 }
00350
00351 void KOIncidenceEditor::openURL( const KURL &url )
00352 {
00353 QString uri = url.url();
00354 UriHandler::process( uri );
00355 }
00356
00357 void KOIncidenceEditor::addAttachments( const QStringList &attachments,
00358 const QStringList &mimeTypes,
00359 bool inlineAttachments )
00360 {
00361 emit signalAddAttachments( attachments, mimeTypes, inlineAttachments );
00362 }
00363
00364 void KOIncidenceEditor::addAttendees( const QStringList &attendees )
00365 {
00366 QStringList::ConstIterator it;
00367 for ( it = attendees.begin(); it != attendees.end(); ++it ) {
00368 QString name, email;
00369 KABC::Addressee::parseEmailAddress( *it, name, email );
00370 mAttendeeEditor->insertAttendee( new Attendee( name, email, true, Attendee::NeedsAction ) );
00371 }
00372 }
00373
00374 void KOIncidenceEditor::setResource( ResourceCalendar *res, const QString &subRes )
00375 {
00376 QString label;
00377 if ( res ) {
00378 if ( !res->subresources().isEmpty() && !subRes.isEmpty() ) {
00379 label = res->labelForSubresource( subRes );
00380 } else {
00381 label = res->resourceName();
00382 }
00383 }
00384
00385 mResource = res;
00386 mSubResource = subRes;
00387 }
00388
00389
00390 void KOIncidenceEditor::selectCreateTask( bool enable )
00391 {
00392 mIsCreateTask = enable;
00393 if ( mIsCreateTask ) {
00394 setCaption( i18n( "Create to-do" ) );
00395 setButtonOK( i18n( "Create to-do" ) );
00396 showButtonApply( false );
00397 }
00398 }
00399
00400 void KOIncidenceEditor::selectInvitationCounterProposal(bool enable)
00401 {
00402 mIsCounter = enable;
00403 if ( mIsCounter ) {
00404 setCaption( i18n( "Counter proposal" ) );
00405 setButtonOK( i18n( "Counter proposal" ) );
00406 showButtonApply( false );
00407 }
00408 }
00409
00410 void KOIncidenceEditor::setRecurringIncidence ( Incidence *originalIncidence,
00411 Incidence *incAfterDissociation )
00412 {
00413 mRecurIncidence = originalIncidence;
00414 mRecurIncidenceAfterDissoc = incAfterDissociation;
00415 }
00416
00417
00418 #include "koincidenceeditor.moc"