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