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