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