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