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 
00043 #include "korganizeriface_stub.h"
00044 
00045 #include "core.h"
00046 #include "plugin.h"
00047 #include "korganizerplugin.h"
00048 
00049 #include "korganizer/stdcalendar.h"
00050 
00051 #include "summarywidget.h"
00052 
00053 SummaryWidget::SummaryWidget( KOrganizerPlugin *plugin, QWidget *parent,
00054                               const char *name )
00055   : Kontact::Summary( parent, name ), mPlugin( plugin ), mCalendar( 0 )
00056 {
00057   QVBoxLayout *mainLayout = new QVBoxLayout( this, 3, 3 );
00058 
00059   QPixmap icon = KGlobal::iconLoader()->loadIcon( "kontact_date",
00060                    KIcon::Desktop, KIcon::SizeMedium );
00061   QWidget *header = createHeader( this, icon, i18n( "Calendar" ) );
00062   mainLayout->addWidget( header );
00063 
00064   mLayout = new QGridLayout( mainLayout, 7, 5, 3 );
00065   mLayout->setRowStretch( 6, 1 );
00066 
00067   mCalendar = KOrg::StdCalendar::self();
00068 
00069   connect( mCalendar, SIGNAL( calendarChanged() ), SLOT( updateView() ) );
00070   connect( mPlugin->core(), SIGNAL( dayChanged( const QDate& ) ),
00071            SLOT( updateView() ) );
00072 
00073   updateView();
00074 }
00075 
00076 SummaryWidget::~SummaryWidget()
00077 {
00078 }
00079 
00080 void SummaryWidget::updateView()
00081 {
00082   mLabels.setAutoDelete( true );
00083   mLabels.clear();
00084   mLabels.setAutoDelete( false );
00085 
00086   KIconLoader loader( "kdepim" );
00087 
00088   KConfig config( "kcmkorgsummaryrc" );
00089 
00090   config.setGroup( "Calendar" );
00091   int days = config.readNumEntry( "DaysToShow", 1 );
00092 
00093   QLabel *label = 0;
00094   int counter = 0;
00095   QPixmap pm = loader.loadIcon( "appointment", KIcon::Small );
00096   QPixmap pmb = loader.loadIcon( "calendarbirthday", KIcon::Small );
00097   QPixmap pma = loader.loadIcon( "calendaranniversary", KIcon::Small );
00098 
00099   QDate dt;
00100   QDate currentDate = QDate::currentDate();
00101   for ( dt=currentDate;
00102         dt<=currentDate.addDays( days - 1 );
00103         dt=dt.addDays(1) ) {
00104 
00105     KCal::Event::List events = mCalendar->events( dt );
00106 
00107     // sort the events for this date by summary
00108     events = KCal::Calendar::sortEvents( &events,
00109                                          KCal::EventSortSummary,
00110                                          KCal::SortDirectionAscending );
00111     // sort the events for this date by start date
00112     events = KCal::Calendar::sortEvents( &events,
00113                                          KCal::EventSortStartDate,
00114                                          KCal::SortDirectionAscending );
00115 
00116     KCal::Event::List::ConstIterator it = events.begin();
00117     for ( it=events.begin(); it!=events.end(); ++it ) {
00118       KCal::Event *ev = *it;
00119 
00120       // Count number of days remaining in multiday event
00121       int span=1; int dayof=1;
00122       if ( ev->isMultiDay() ) {
00123         QDate d = ev->dtStart().date();
00124         if ( d < currentDate ) {
00125           d = currentDate;
00126         }
00127         while ( d < ev->dtEnd().date() ) {
00128           if ( d < dt ) {
00129             dayof++;
00130           }
00131           span++;
00132           d=d.addDays( 1 );
00133         }
00134       }
00135 
00136       // If this date is part of a floating, multiday event, then we
00137       // only make a print for the first day of the event.
00138       if ( ev->isMultiDay() && ev->doesFloat() && dayof != 1 ) continue;
00139 
00140       // Fill Appointment Pixmap Field
00141       label = new QLabel( this );
00142       if ( ev->categories().contains( "Birthday" ) ) {
00143         label->setPixmap( pmb );
00144       } else if ( ev->categories().contains( "Anniversary" ) ) {
00145         label->setPixmap( pma );
00146       } else {
00147         label->setPixmap( pm );
00148       }
00149       label->setMaximumWidth( label->minimumSizeHint().width() );
00150       label->setAlignment( AlignVCenter );
00151       mLayout->addWidget( label, counter, 0 );
00152       mLabels.append( label );
00153 
00154       // Fill Event Date Field
00155       bool makeBold = false;
00156       QString datestr;
00157 
00158       // Modify event date for printing
00159       QDate sD = QDate::QDate( dt.year(), dt.month(), dt.day() );
00160       if ( ( sD.month() == currentDate.month() ) &&
00161            ( sD.day()   == currentDate.day() ) ) {
00162         datestr = i18n( "Today" );
00163         makeBold = true;
00164       } else if ( ( sD.month() == currentDate.addDays( 1 ).month() ) &&
00165                   ( sD.day()   == currentDate.addDays( 1 ).day() ) ) {
00166         datestr = i18n( "Tomorrow" );
00167       } else {
00168         datestr = KGlobal::locale()->formatDate( sD );
00169       }
00170 
00171       // Print the date span for multiday, floating events, for the
00172       // first day of the event only.
00173       if ( ev->isMultiDay() && ev->doesFloat() && dayof == 1 && span > 1 ) {
00174         datestr = KGlobal::locale()->formatDate( ev->dtStart().date() );
00175         datestr += " -\n " +
00176                    KGlobal::locale()->formatDate( sD.addDays( span-1 ) );
00177       }
00178 
00179       label = new QLabel( datestr, this );
00180       label->setAlignment( AlignLeft | AlignVCenter );
00181       if ( makeBold ) {
00182         QFont font = label->font();
00183         font.setBold( true );
00184         label->setFont( font );
00185       }
00186       mLayout->addWidget( label, counter, 1 );
00187       mLabels.append( label );
00188 
00189       // Fill Event Summary Field
00190       QString newtext = ev->summary();
00191       if ( ev->isMultiDay() &&  !ev->doesFloat() ) {
00192         newtext.append( QString(" (%1/%2)").arg( dayof ).arg( span ) );
00193       }
00194 
00195       KURLLabel *urlLabel = new KURLLabel( this );
00196       urlLabel->setText( newtext );
00197       urlLabel->setURL( ev->uid() );
00198       urlLabel->installEventFilter( this );
00199       urlLabel->setAlignment( urlLabel->alignment() | Qt::WordBreak );
00200       mLayout->addWidget( urlLabel, counter, 2 );
00201       mLabels.append( urlLabel );
00202 
00203       connect( urlLabel, SIGNAL( leftClickedURL( const QString& ) ),
00204                this, SLOT( viewEvent( const QString& ) ) );
00205       connect( urlLabel, SIGNAL( rightClickedURL( const QString& ) ),
00206                this, SLOT( popupMenu( const QString& ) ) );
00207 
00208       QString tipText( KCal::IncidenceFormatter::toolTipStr( mCalendar, ev, dt, true ) );
00209       if ( !tipText.isEmpty() ) {
00210         QToolTip::add( urlLabel, tipText );
00211       }
00212 
00213       // Fill Event Time Range Field (only for non-floating Events)
00214       if ( !ev->doesFloat() ) {
00215         QTime sST = ev->dtStart().time();
00216         QTime sET = ev->dtEnd().time();
00217         if ( ev->isMultiDay() ) {
00218           if ( ev->dtStart().date() < dt ) {
00219             sST = QTime::QTime( 0, 0 );
00220           }
00221           if ( ev->dtEnd().date() > dt ) {
00222             sET = QTime::QTime( 23, 59 );
00223           }
00224         }
00225         datestr = i18n( "Time from - to", "%1 - %2" )
00226                   .arg( KGlobal::locale()->formatTime( sST ) )
00227                   .arg( KGlobal::locale()->formatTime( sET ) );
00228         label = new QLabel( datestr, this );
00229         label->setAlignment( AlignLeft | AlignVCenter );
00230         mLayout->addWidget( label, counter, 3 );
00231         mLabels.append( label );
00232       }
00233 
00234       counter++;
00235     }
00236   }
00237 
00238   if ( !counter ) {
00239     QLabel *noEvents = new QLabel(
00240       i18n( "No appointments pending within the next day",
00241             "No appointments pending within the next %n days",
00242             days ), this, "nothing to see" );
00243     noEvents->setAlignment( AlignHCenter | AlignVCenter );
00244     mLayout->addWidget( noEvents, 0, 2 );
00245     mLabels.append( noEvents );
00246   }
00247 
00248   for ( label = mLabels.first(); label; label = mLabels.next() )
00249     label->show();
00250 }
00251 
00252 void SummaryWidget::viewEvent( const QString &uid )
00253 {
00254   mPlugin->core()->selectPlugin( "kontact_korganizerplugin" ); //ensure loaded
00255   KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" );
00256   iface.editIncidence( uid );
00257 }
00258 
00259 void SummaryWidget::removeEvent( const QString &uid )
00260 {
00261   mPlugin->core()->selectPlugin( "kontact_korganizerplugin" ); //ensure loaded
00262   KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" );
00263   iface.deleteIncidence( uid, false );
00264 }
00265 
00266 void SummaryWidget::popupMenu( const QString &uid )
00267 {
00268   KPopupMenu popup( this );
00269   QToolTip::remove( this );
00270   popup.insertItem( i18n( "&Edit Appointment..." ), 0 );
00271   popup.insertItem( KGlobal::iconLoader()->loadIcon( "editdelete", KIcon::Small),
00272                     i18n( "&Delete Appointment" ), 1 );
00273 
00274   switch ( popup.exec( QCursor::pos() ) ) {
00275     case 0:
00276       viewEvent( uid );
00277       break;
00278     case 1:
00279       removeEvent( uid );
00280       break;
00281   }
00282 }
00283 
00284 bool SummaryWidget::eventFilter( QObject *obj, QEvent* e )
00285 {
00286   if ( obj->inherits( "KURLLabel" ) ) {
00287     KURLLabel* label = static_cast<KURLLabel*>( obj );
00288     if ( e->type() == QEvent::Enter )
00289       emit message( i18n( "Edit Appointment: \"%1\"" ).arg( label->text() ) );
00290     if ( e->type() == QEvent::Leave )
00291       emit message( QString::null );
00292   }
00293 
00294   return Kontact::Summary::eventFilter( obj, e );
00295 }
00296 
00297 QStringList SummaryWidget::configModules() const
00298 {
00299   return QStringList( "kcmkorgsummary.desktop" );
00300 }
00301 
00302 #include "summarywidget.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys