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