kontact

summarywidget.cpp

00001 /*
00002     This file is part of Kontact.
00003     Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
00004 
00005     This program is free software; you can redistribute it and/or modify
00006     it under the terms of the GNU General Public License as published by
00007     the Free Software Foundation; either version 2 of the License, or
00008     (at your option) any later version.
00009 
00010     This program is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013     GNU General Public License for more details.
00014 
00015     You should have received a copy of the GNU General Public License
00016     along with this program; if not, write to the Free Software
00017     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018 
00019     As a special exception, permission is given to link this program
00020     with any edition of Qt, and distribute the resulting executable,
00021     without including the source code for Qt in the source distribution.
00022 */
00023 
00024 #include <qcursor.h>
00025 #include <qlabel.h>
00026 #include <qlayout.h>
00027 #include <qtooltip.h>
00028 
00029 #include <kdialog.h>
00030 #include <kglobal.h>
00031 #include <kiconloader.h>
00032 #include <klocale.h>
00033 #include <kparts/part.h>
00034 #include <kpopupmenu.h>
00035 #include <kstandarddirs.h>
00036 #include <kurllabel.h>
00037 #include <libkcal/event.h>
00038 #include <libkcal/resourcecalendar.h>
00039 #include <libkcal/resourcelocal.h>
00040 #include <libkcal/incidenceformatter.h>
00041 #include <libkdepim/kpimprefs.h>
00042 #include <libkdepim/stdcalendar.h>
00043 
00044 #include "korganizeriface_stub.h"
00045 
00046 #include "core.h"
00047 #include "plugin.h"
00048 #include "korganizerplugin.h"
00049 
00050 #include "summarywidget.h"
00051 
00052 SummaryWidget::SummaryWidget( KOrganizerPlugin *plugin, QWidget *parent,
00053                               const char *name )
00054   : Kontact::Summary( parent, name ), mPlugin( plugin ), mCalendar( 0 )
00055 {
00056   QVBoxLayout *mainLayout = new QVBoxLayout( this, 3, 3 );
00057 
00058   QPixmap icon = KGlobal::iconLoader()->loadIcon( "kontact_date",
00059                    KIcon::Desktop, KIcon::SizeMedium );
00060   QWidget *header = createHeader( this, icon, i18n( "Calendar" ) );
00061   mainLayout->addWidget( header );
00062 
00063   mLayout = new QGridLayout( mainLayout, 7, 5, 3 );
00064   mLayout->setRowStretch( 6, 1 );
00065 
00066   mCalendar = KCal::StdCalendar::self();
00067 
00068   connect( mCalendar, SIGNAL( calendarChanged() ), SLOT( updateView() ) );
00069   connect( mPlugin->core(), SIGNAL( dayChanged( const QDate& ) ),
00070            SLOT( updateView() ) );
00071 
00072   updateView();
00073 }
00074 
00075 SummaryWidget::~SummaryWidget()
00076 {
00077 }
00078 
00079 void SummaryWidget::updateView()
00080 {
00081   mLabels.setAutoDelete( true );
00082   mLabels.clear();
00083   mLabels.setAutoDelete( false );
00084 
00085   KIconLoader loader( "kdepim" );
00086 
00087   KConfig config( "kcmkorgsummaryrc" );
00088 
00089   config.setGroup( "Calendar" );
00090   int days = config.readNumEntry( "DaysToShow", 1 );
00091 
00092   QLabel *label = 0;
00093   int counter = 0;
00094   QPixmap pm = loader.loadIcon( "appointment", KIcon::Small );
00095   QPixmap pmb = loader.loadIcon( "calendarbirthday", KIcon::Small );
00096   QPixmap pma = loader.loadIcon( "calendaranniversary", KIcon::Small );
00097 
00098   QDate dt;
00099   QDate currentDate = QDate::currentDate();
00100   for ( dt=currentDate;
00101         dt<=currentDate.addDays( days - 1 );
00102         dt=dt.addDays(1) ) {
00103 
00104     KCal::Event::List events = mCalendar->events( dt );
00105 
00106     // sort the events for this date by summary
00107     events = KCal::Calendar::sortEventsForDate( &events,
00108                                                 dt,
00109                                                 KCal::EventSortSummary,
00110                                                 KCal::SortDirectionAscending );
00111     // sort the events for this date by start date
00112     events = KCal::Calendar::sortEventsForDate( &events,
00113                                                 dt,
00114                                                 KCal::EventSortStartDate,
00115                                                 KCal::SortDirectionAscending );
00116 
00117     KCal::Event::List::ConstIterator it = events.begin();
00118     for ( it=events.begin(); it!=events.end(); ++it ) {
00119       KCal::Event *ev = *it;
00120 
00121       // Count number of days remaining in multiday event
00122       int span=1; int dayof=1;
00123       if ( ev->isMultiDay() ) {
00124         QDate d = ev->dtStart().date();
00125         if ( d < currentDate ) {
00126           d = currentDate;
00127         }
00128         while ( d < ev->dtEnd().date() ) {
00129           if ( d < dt ) {
00130             dayof++;
00131           }
00132           span++;
00133           d=d.addDays( 1 );
00134         }
00135       }
00136 
00137       // If this date is part of a floating, multiday event, then we
00138       // only make a print for the first day of the event.
00139       if ( ev->isMultiDay() && ev->doesFloat() && dayof != 1 ) continue;
00140 
00141       // Fill Appointment Pixmap Field
00142       label = new QLabel( this );
00143       if ( ev->categories().contains( "Birthday" ) ) {
00144         label->setPixmap( pmb );
00145       } else if ( ev->categories().contains( "Anniversary" ) ) {
00146         label->setPixmap( pma );
00147       } else {
00148         label->setPixmap( pm );
00149       }
00150       label->setMaximumWidth( label->minimumSizeHint().width() );
00151       label->setAlignment( AlignVCenter );
00152       mLayout->addWidget( label, counter, 0 );
00153       mLabels.append( label );
00154 
00155       // Fill Event Date Field
00156       bool makeBold = false;
00157       QString datestr;
00158 
00159       // Modify event date for printing
00160       QDate sD = QDate( dt.year(), dt.month(), dt.day() );
00161       if ( ( sD.month() == currentDate.month() ) &&
00162            ( sD.day()   == currentDate.day() ) ) {
00163         datestr = i18n( "Today" );
00164         makeBold = true;
00165       } else if ( ( sD.month() == currentDate.addDays( 1 ).month() ) &&
00166                   ( sD.day()   == currentDate.addDays( 1 ).day() ) ) {
00167         datestr = i18n( "Tomorrow" );
00168       } else {
00169         datestr = KGlobal::locale()->formatDate( sD );
00170       }
00171 
00172       // Print the date span for multiday, floating events, for the
00173       // first day of the event only.
00174       if ( ev->isMultiDay() && ev->doesFloat() && dayof == 1 && span > 1 ) {
00175         datestr = KGlobal::locale()->formatDate( ev->dtStart().date() );
00176         datestr += " -\n " +
00177                    KGlobal::locale()->formatDate( sD.addDays( span-1 ) );
00178       }
00179 
00180       label = new QLabel( datestr, this );
00181       label->setAlignment( AlignLeft | AlignVCenter );
00182       if ( makeBold ) {
00183         QFont font = label->font();
00184         font.setBold( true );
00185         label->setFont( font );
00186       }
00187       mLayout->addWidget( label, counter, 1 );
00188       mLabels.append( label );
00189 
00190       // Fill Event Summary Field
00191       QString newtext = ev->summary();
00192       if ( ev->isMultiDay() &&  !ev->doesFloat() ) {
00193         newtext.append( QString(" (%1/%2)").arg( dayof ).arg( span ) );
00194       }
00195 
00196       KURLLabel *urlLabel = new KURLLabel( this );
00197       urlLabel->setText( newtext );
00198       urlLabel->setURL( ev->uid() );
00199       urlLabel->installEventFilter( this );
00200       urlLabel->setAlignment( urlLabel->alignment() | Qt::WordBreak );
00201       mLayout->addWidget( urlLabel, counter, 2 );
00202       mLabels.append( urlLabel );
00203 
00204       connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ),
00205                this, SLOT( viewEvent( const QString& ) ) );
00206       connect( urlLabel, SIGNAL( rightClickedURL( const QString& ) ),
00207                this, SLOT( popupMenu( const QString& ) ) );
00208 
00209       QString tipText( KCal::IncidenceFormatter::toolTipStr( mCalendar, ev, dt, true ) );
00210       if ( !tipText.isEmpty() ) {
00211         QToolTip::add( urlLabel, tipText );
00212       }
00213 
00214       // Fill Event Time Range Field (only for non-floating Events)
00215       if ( !ev->doesFloat() ) {
00216         QTime sST = ev->dtStart().time();
00217         QTime sET = ev->dtEnd().time();
00218         if ( ev->isMultiDay() ) {
00219           if ( ev->dtStart().date() < dt ) {
00220             sST = QTime( 0, 0 );
00221           }
00222           if ( ev->dtEnd().date() > dt ) {
00223             sET = QTime( 23, 59 );
00224           }
00225         }
00226         datestr = i18n( "Time from - to", "%1 - %2" )
00227                   .arg( KGlobal::locale()->formatTime( sST ) )
00228                   .arg( KGlobal::locale()->formatTime( sET ) );
00229         label = new QLabel( datestr, this );
00230         label->setAlignment( AlignLeft | AlignVCenter );
00231         mLayout->addWidget( label, counter, 3 );
00232         mLabels.append( label );
00233       }
00234 
00235       counter++;
00236     }
00237   }
00238 
00239   if ( !counter ) {
00240     QLabel *noEvents = new QLabel(
00241       i18n( "No appointments pending within the next day",
00242             "No appointments pending within the next %n days",
00243             days ), this, "nothing to see" );
00244     noEvents->setAlignment( AlignHCenter | AlignVCenter );
00245     mLayout->addWidget( noEvents, 0, 2 );
00246     mLabels.append( noEvents );
00247   }
00248 
00249   for ( label = mLabels.first(); label; label = mLabels.next() )
00250     label->show();
00251 }
00252 
00253 void SummaryWidget::viewEvent( const QString &uid )
00254 {
00255   mPlugin->core()->selectPlugin( "kontact_korganizerplugin" ); //ensure loaded
00256   KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" );
00257   iface.editIncidence( uid );
00258 }
00259 
00260 void SummaryWidget::removeEvent( const QString &uid )
00261 {
00262   mPlugin->core()->selectPlugin( "kontact_korganizerplugin" ); //ensure loaded
00263   KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" );
00264   iface.deleteIncidence( uid, false );
00265 }
00266 
00267 void SummaryWidget::popupMenu( const QString &uid )
00268 {
00269   KPopupMenu popup( this );
00270   QToolTip::remove( this );
00271   popup.insertItem( i18n( "&Edit Appointment..." ), 0 );
00272   popup.insertItem( KGlobal::iconLoader()->loadIcon( "editdelete", KIcon::Small),
00273                     i18n( "&Delete Appointment" ), 1 );
00274 
00275   switch ( popup.exec( QCursor::pos() ) ) {
00276     case 0:
00277       viewEvent( uid );
00278       break;
00279     case 1:
00280       removeEvent( uid );
00281       break;
00282   }
00283 }
00284 
00285 bool SummaryWidget::eventFilter( QObject *obj, QEvent* e )
00286 {
00287   if ( obj->inherits( "KURLLabel" ) ) {
00288     KURLLabel* label = static_cast<KURLLabel*>( obj );
00289     if ( e->type() == QEvent::Enter )
00290       emit message( i18n( "Edit Appointment: \"%1\"" ).arg( label->text() ) );
00291     if ( e->type() == QEvent::Leave )
00292       emit message( QString::null );
00293   }
00294 
00295   return Kontact::Summary::eventFilter( obj, e );
00296 }
00297 
00298 QStringList SummaryWidget::configModules() const
00299 {
00300   return QStringList( "kcmkorgsummary.desktop" );
00301 }
00302 
00303 #include "summarywidget.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys