korganizer

koincidenceeditor.cpp

00001 /*
00002     This file is part of KOrganizer.
00003 
00004     Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
00005     Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00006 
00007     This program is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or
00010     (at your option) any later version.
00011     This program is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014     GNU General Public License for more details.
00015 
00016     You should have received a copy of the GNU General Public License
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019 
00020     As a special exception, permission is given to link this program
00021     with any edition of Qt, and distribute the resulting executable,
00022     without including the source code for Qt in the source distribution.
00023 */
00024 
00025 #include <qtooltip.h>
00026 #include <qframe.h>
00027 #include <qpixmap.h>
00028 #include <qlayout.h>
00029 #include <qwidgetstack.h>
00030 #include <qdatetime.h>
00031 #include <qwhatsthis.h>
00032 
00033 #include <kdebug.h>
00034 #include <klocale.h>
00035 #include <kstandarddirs.h>
00036 #include <kmessagebox.h>
00037 #include <kinputdialog.h>
00038 #include <kio/netaccess.h>
00039 
00040 #include <libkdepim/categoryselectdialog.h>
00041 #include <libkdepim/designerfields.h>
00042 #include <libkdepim/embeddedurlpage.h>
00043 
00044 #include <libkcal/calendarlocal.h>
00045 #include <libkcal/incidence.h>
00046 #include <libkcal/icalformat.h>
00047 
00048 #include "koprefs.h"
00049 #include "koglobals.h"
00050 #include "koeditordetails.h"
00051 #include "koeditorattachments.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     mDetails( 0 ), mAttachments( 0 )
00062 {
00063   // Set this to be the group leader for all subdialogs - this means
00064   // modal subdialogs will only affect this dialog, not the other windows
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   mCategoryDialog = new KPIM::CategorySelectDialog( KOPrefs::instance(), this );
00077   KOGlobals::fitDialogToScreen( mCategoryDialog );
00078 
00079   connect( mCategoryDialog, SIGNAL( editCategories() ),
00080            SIGNAL( editCategories() ) );
00081 
00082   connect( this, SIGNAL( defaultClicked() ), SLOT( slotManageTemplates() ) );
00083   connect( this, SIGNAL( finished() ), SLOT( delayedDestruct() ) );
00084 }
00085 
00086 KOIncidenceEditor::~KOIncidenceEditor()
00087 {
00088   delete mCategoryDialog;
00089 }
00090 
00091 void KOIncidenceEditor::setupAttendeesTab()
00092 {
00093   QFrame *topFrame = addPage( i18n("Atte&ndees") );
00094   QWhatsThis::add( topFrame,
00095                    i18n("The Attendees tab allows you to Add or Remove "
00096                         "Attendees to/from this event or to-do.") );
00097 
00098   QBoxLayout *topLayout = new QVBoxLayout( topFrame );
00099 
00100   mDetails = new KOEditorDetails( spacingHint(), topFrame );
00101   topLayout->addWidget( mDetails );
00102 }
00103 
00104 void KOIncidenceEditor::setupAttachmentsTab()
00105 {
00106   QFrame *topFrame = addPage( i18n("Attach&ments") );
00107   QWhatsThis::add( topFrame,
00108                    i18n("The Attachments tab allows you to add or remove "
00109                         "files, emails, contacts, and other items "
00110                         "associated with this event or to-do.") );
00111 
00112   QBoxLayout *topLayout = new QVBoxLayout( topFrame );
00113 
00114   mAttachments = new KOEditorAttachments( spacingHint(), topFrame );
00115   connect( mAttachments, SIGNAL( openURL( const KURL & ) ) ,
00116            this, SLOT( openURL( const KURL & ) ) );
00117   topLayout->addWidget( mAttachments );
00118 }
00119 
00120 void KOIncidenceEditor::slotApply()
00121 {
00122   processInput();
00123 }
00124 
00125 void KOIncidenceEditor::slotOk()
00126 {
00127   if ( processInput() ) accept();
00128 }
00129 
00130 void KOIncidenceEditor::updateCategoryConfig()
00131 {
00132   mCategoryDialog->updateCategoryConfig();
00133 }
00134 
00135 void KOIncidenceEditor::slotCancel()
00136 {
00137   processCancel();
00138   reject();
00139 }
00140 
00141 void KOIncidenceEditor::cancelRemovedAttendees( Incidence *incidence )
00142 {
00143   if ( !incidence ) return;
00144 
00145   // cancelAttendeeEvent removes all attendees from the incidence,
00146   // and then only adds those that need to be cancelled (i.e. a mail needs to be sent to them).
00147   if ( KOPrefs::instance()->thatIsMe( incidence->organizer().email() ) ) {
00148     Incidence *ev = incidence->clone();
00149     ev->registerObserver( 0 );
00150     mDetails->cancelAttendeeEvent( ev );
00151     if ( ev->attendeeCount() > 0 ) {
00152       emit deleteAttendee( ev );
00153     }
00154     delete( ev );
00155   }
00156 
00157 }
00158 
00159 void KOIncidenceEditor::slotManageTemplates()
00160 {
00161   kdDebug(5850) << "KOIncidenceEditor::manageTemplates()" << endl;
00162 
00163   QString tp = type();
00164 
00165   TemplateManagementDialog * const d = new TemplateManagementDialog( this, templates() );
00166   connect( d, SIGNAL( loadTemplate( const QString& ) ),
00167            this, SLOT( slotLoadTemplate( const QString& ) ) );
00168   connect( d, SIGNAL( templatesChanged( const QStringList& ) ),
00169            this, SLOT( slotTemplatesChanged( const QStringList& ) ) );
00170   connect( d, SIGNAL( saveTemplate( const QString& ) ),
00171            this, SLOT( slotSaveTemplate( const QString& ) ) );
00172   d->exec();
00173   return;
00174 }
00175 
00176 void KOIncidenceEditor::saveAsTemplate( Incidence *incidence,
00177                                         const QString &templateName )
00178 {
00179   if ( !incidence || templateName.isEmpty() ) return;
00180 
00181   QString fileName = "templates/" + incidence->type();
00182   fileName.append( "/" + templateName );
00183   fileName = locateLocal( "data", "korganizer/" + fileName );
00184 
00185   CalendarLocal cal( KOPrefs::instance()->mTimeZoneId );
00186   cal.addIncidence( incidence );
00187   ICalFormat format;
00188   format.save( &cal, fileName );
00189 }
00190 
00191 void KOIncidenceEditor::slotLoadTemplate( const QString& templateName )
00192 {
00193   CalendarLocal cal( KOPrefs::instance()->mTimeZoneId );
00194   QString fileName = locateLocal( "data", "korganizer/templates/" + type() + "/" +
00195       templateName );
00196 
00197   if ( fileName.isEmpty() ) {
00198     KMessageBox::error( this, i18n("Unable to find template '%1'.")
00199         .arg( fileName ) );
00200   } else {
00201     ICalFormat format;
00202     if ( !format.load( &cal, fileName ) ) {
00203       KMessageBox::error( this, i18n("Error loading template file '%1'.")
00204           .arg( fileName ) );
00205       return;
00206     }
00207   }
00208   loadTemplate( cal );
00209 }
00210 
00211 void KOIncidenceEditor::slotTemplatesChanged( const QStringList& newTemplates )
00212 {
00213   templates() = newTemplates;
00214 }
00215 
00216 void KOIncidenceEditor::setupDesignerTabs( const QString &type )
00217 {
00218   QStringList activePages = KOPrefs::instance()->activeDesignerFields();
00219 
00220   QStringList list = KGlobal::dirs()->findAllResources( "data",
00221     "korganizer/designer/" + type + "/*.ui", true, true );
00222   for ( QStringList::iterator it = list.begin(); it != list.end(); ++it ) {
00223     const QString &fn = (*it).mid( (*it).findRev('/') + 1 );
00224     if ( activePages.find( fn ) != activePages.end() ) {
00225       addDesignerTab( *it );
00226     }
00227   }
00228 }
00229 
00230 QWidget *KOIncidenceEditor::addDesignerTab( const QString &uifile )
00231 {
00232   kdDebug() << "Designer tab: " << uifile << endl;
00233 
00234   KPIM::DesignerFields *wid = new KPIM::DesignerFields( uifile, 0 );
00235   mDesignerFields.append( wid );
00236 
00237   QFrame *topFrame = addPage( wid->title() );
00238 
00239   QBoxLayout *topLayout = new QVBoxLayout( topFrame );
00240 
00241   wid->reparent( topFrame, 0, QPoint() );
00242   topLayout->addWidget( wid );
00243   mDesignerFieldForWidget[ topFrame ] = wid;
00244 
00245   return topFrame;
00246 }
00247 
00248 class KCalStorage : public KPIM::DesignerFields::Storage
00249 {
00250   public:
00251     KCalStorage( Incidence *incidence )
00252       : mIncidence( incidence )
00253     {
00254     }
00255 
00256     QStringList keys()
00257     {
00258       QStringList keys;
00259 
00260       QMap<QCString, QString> props = mIncidence->customProperties();
00261       QMap<QCString, QString>::ConstIterator it;
00262       for( it = props.begin(); it != props.end(); ++it ) {
00263         QString customKey = it.key();
00264         QStringList parts = QStringList::split( "-", customKey );
00265         if ( parts.count() != 4 ) continue;
00266         if ( parts[ 2 ] != "KORGANIZER" ) continue;
00267         keys.append( parts[ 3 ] );
00268       }
00269 
00270       return keys;
00271     }
00272 
00273     QString read( const QString &key )
00274     {
00275       return mIncidence->customProperty( "KORGANIZER", key.utf8() );
00276     }
00277 
00278     void write( const QString &key, const QString &value )
00279     {
00280       mIncidence->setCustomProperty( "KORGANIZER", key.utf8(), value );
00281     }
00282 
00283   private:
00284     Incidence *mIncidence;
00285 };
00286 
00287 void KOIncidenceEditor::readDesignerFields( Incidence *i )
00288 {
00289   KCalStorage storage( i );
00290   KPIM::DesignerFields *fields;
00291   for( fields = mDesignerFields.first(); fields;
00292        fields = mDesignerFields.next() ) {
00293     fields->load( &storage );
00294   }
00295 }
00296 
00297 void KOIncidenceEditor::writeDesignerFields( Incidence *i )
00298 {
00299   kdDebug() << "KOIncidenceEditor::writeDesignerFields()" << endl;
00300 
00301   KCalStorage storage( i );
00302   KPIM::DesignerFields *fields;
00303   for( fields = mDesignerFields.first(); fields;
00304        fields = mDesignerFields.next() ) {
00305     kdDebug() << "Write Field " << fields->title() << endl;
00306     fields->save( &storage );
00307   }
00308 }
00309 
00310 
00311 void KOIncidenceEditor::setupEmbeddedURLPage( const QString &label,
00312                                  const QString &url, const QString &mimetype )
00313 {
00314   kdDebug() << "KOIncidenceEditor::setupEmbeddedURLPage()" << endl;
00315   kdDebug() << "label=" << label << ", url=" << url << ", mimetype=" << mimetype << endl;
00316   QFrame *topFrame = addPage( label );
00317   QBoxLayout *topLayout = new QVBoxLayout( topFrame );
00318 
00319   KPIM::EmbeddedURLPage *wid = new KPIM::EmbeddedURLPage( url, mimetype,
00320                                                           topFrame );
00321   topLayout->addWidget( wid );
00322   mEmbeddedURLPages.append( topFrame );
00323   connect( wid, SIGNAL( openURL( const KURL & ) ) ,
00324            this, SLOT( openURL( const KURL & ) ) );
00325   // TODO: Call this method only when the tab is actually activated!
00326   wid->loadContents();
00327 }
00328 
00329 void KOIncidenceEditor::createEmbeddedURLPages( Incidence *i )
00330 {
00331   kdDebug() << "KOIncidenceEditor::createEmbeddedURLPages()" << endl;
00332 
00333   if ( !i ) return;
00334   if ( !mEmbeddedURLPages.isEmpty() ) {
00335 kdDebug() << "mEmbeddedURLPages are not empty, clearing it!" << endl;
00336     mEmbeddedURLPages.setAutoDelete( true );
00337     mEmbeddedURLPages.clear();
00338     mEmbeddedURLPages.setAutoDelete( false );
00339   }
00340   if ( !mAttachedDesignerFields.isEmpty() ) {
00341     for ( QPtrList<QWidget>::Iterator it = mAttachedDesignerFields.begin();
00342           it != mAttachedDesignerFields.end(); ++it ) {
00343       if ( mDesignerFieldForWidget.contains( *it ) ) {
00344         mDesignerFields.remove( mDesignerFieldForWidget[ *it ] );
00345       }
00346     }
00347     mAttachedDesignerFields.setAutoDelete( true );
00348     mAttachedDesignerFields.clear();
00349     mAttachedDesignerFields.setAutoDelete( false );
00350   }
00351 
00352   Attachment::List att = i->attachments();
00353   for ( Attachment::List::Iterator it = att.begin(); it != att.end(); ++it ) {
00354     Attachment *a = (*it);
00355     kdDebug() << "Iterating over the attachments " << endl;
00356     kdDebug() << "label=" << a->label() << ", url=" << a->uri() << ", mimetype=" << a->mimeType() << endl;
00357     if ( a && a->showInline() && a->isUri() ) {
00358       // TODO: Allow more mime-types, but add security checks!
00359 /*      if ( a->mimeType() == "application/x-designer" ) {
00360         QString tmpFile;
00361         if ( KIO::NetAccess::download( a->uri(), tmpFile, this ) ) {
00362           mAttachedDesignerFields.append( addDesignerTab( tmpFile ) );
00363           KIO::NetAccess::removeTempFile( tmpFile );
00364         }
00365       } else*/
00366       // TODO: Enable that check again!
00367       if ( a->mimeType() == "text/html" )
00368       {
00369         setupEmbeddedURLPage( a->label(), a->uri(), a->mimeType() );
00370       }
00371     }
00372   }
00373 }
00374 
00375 void KOIncidenceEditor::openURL( const KURL &url )
00376 {
00377   QString uri = url.url();
00378   UriHandler::process( uri );
00379 }
00380 
00381 #include "koincidenceeditor.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys