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