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 TQt, and distribute the resulting executable,
00021     without including the source code for TQt in the source distribution.
00022 */
00023 
00024 #include <tqcursor.h>
00025 #include <tqlabel.h>
00026 #include <tqlayout.h>
00027 #include <tqtooltip.h>
00028 
00029 #include <kdialog.h>
00030 #include <tdeglobal.h>
00031 #include <kiconloader.h>
00032 #include <tdelocale.h>
00033 #include <tdeparts/part.h>
00034 #include <tdepopupmenu.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 <libtdepim/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, TQWidget *parent,
00054                               const char *name )
00055   : Kontact::Summary( parent, name ), mPlugin( plugin ), mCalendar( 0 )
00056 {
00057   TQVBoxLayout *mainLayout = new TQVBoxLayout( this, 3, 3 );
00058 
00059   TQPixmap icon = TDEGlobal::iconLoader()->loadIcon( "kontact_date",
00060                    TDEIcon::Desktop, TDEIcon::SizeMedium );
00061   TQWidget *header = createHeader( this, icon, i18n( "Calendar" ) );
00062   mainLayout->addWidget( header );
00063 
00064   mLayout = new TQGridLayout( mainLayout, 7, 5, 3 );
00065   mLayout->setRowStretch( 6, 1 );
00066 
00067   mCalendar = KOrg::StdCalendar::self();
00068 
00069   connect( mCalendar, TQT_SIGNAL( calendarChanged() ), TQT_SLOT( updateView() ) );
00070   connect( mPlugin->core(), TQT_SIGNAL( dayChanged( const TQDate& ) ),
00071            TQT_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   TDEIconLoader loader( "tdepim" );
00087 
00088   TDEConfig config( "kcmkorgsummaryrc" );
00089 
00090   config.setGroup( "Calendar" );
00091   int days = config.readNumEntry( "DaysToShow", 1 );
00092 
00093   TQLabel *label = 0;
00094   int counter = 0;
00095   TQPixmap pm = loader.loadIcon( "appointment", TDEIcon::Small );
00096   TQPixmap pmb = loader.loadIcon( "calendarbirthday", TDEIcon::Small );
00097   TQPixmap pma = loader.loadIcon( "calendaranniversary", TDEIcon::Small );
00098 
00099   TQDate dt;
00100   TQDate currentDate = TQDate::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::sortEventsForDate( &events,
00109                                                 dt,
00110                                                 KCal::EventSortSummary,
00111                                                 KCal::SortDirectionAscending );
00112     // sort the events for this date by start date
00113     events = KCal::Calendar::sortEventsForDate( &events,
00114                                                 dt,
00115                                                 KCal::EventSortStartDate,
00116                                                 KCal::SortDirectionAscending );
00117 
00118     KCal::Event::List::ConstIterator it = events.begin();
00119     for ( it=events.begin(); it!=events.end(); ++it ) {
00120       KCal::Event *ev = *it;
00121 
00122       // Count number of days remaining in multiday event
00123       int span=1; int dayof=1;
00124       if ( ev->isMultiDay() ) {
00125         TQDate d = ev->dtStart().date();
00126         if ( d < currentDate ) {
00127           d = currentDate;
00128         }
00129         while ( d < ev->dtEnd().date() ) {
00130           if ( d < dt ) {
00131             dayof++;
00132           }
00133           span++;
00134           d=d.addDays( 1 );
00135         }
00136       }
00137 
00138       // If this date is part of a floating, multiday event, then we
00139       // only make a print for the first day of the event.
00140       if ( ev->isMultiDay() && ev->doesFloat() && dayof != 1 ) continue;
00141 
00142       // Fill Appointment Pixmap Field
00143       label = new TQLabel( this );
00144       if ( ev->categories().contains( "Birthday" ) ) {
00145         label->setPixmap( pmb );
00146       } else if ( ev->categories().contains( "Anniversary" ) ) {
00147         label->setPixmap( pma );
00148       } else {
00149         label->setPixmap( pm );
00150       }
00151       label->setMaximumWidth( label->minimumSizeHint().width() );
00152       label->setAlignment( AlignVCenter );
00153       mLayout->addWidget( label, counter, 0 );
00154       mLabels.append( label );
00155 
00156       // Fill Event Date Field
00157       bool makeBold = false;
00158       TQString datestr;
00159 
00160       // Modify event date for printing
00161       TQDate sD = TQDate( dt.year(), dt.month(), dt.day() );
00162       if ( ( sD.month() == currentDate.month() ) &&
00163            ( sD.day()   == currentDate.day() ) ) {
00164         datestr = i18n( "Today" );
00165         makeBold = true;
00166       } else if ( ( sD.month() == currentDate.addDays( 1 ).month() ) &&
00167                   ( sD.day()   == currentDate.addDays( 1 ).day() ) ) {
00168         datestr = i18n( "Tomorrow" );
00169       } else {
00170         datestr = TDEGlobal::locale()->formatDate( sD );
00171       }
00172 
00173       // Print the date span for multiday, floating events, for the
00174       // first day of the event only.
00175       if ( ev->isMultiDay() && ev->doesFloat() && dayof == 1 && span > 1 ) {
00176         datestr = TDEGlobal::locale()->formatDate( ev->dtStart().date() );
00177         datestr += " -\n " +
00178                    TDEGlobal::locale()->formatDate( sD.addDays( span-1 ) );
00179       }
00180 
00181       label = new TQLabel( datestr, this );
00182       label->setAlignment( AlignLeft | AlignVCenter );
00183       if ( makeBold ) {
00184         TQFont font = label->font();
00185         font.setBold( true );
00186         label->setFont( font );
00187       }
00188       mLayout->addWidget( label, counter, 1 );
00189       mLabels.append( label );
00190 
00191       // Fill Event Summary Field
00192       TQString newtext = ev->summary();
00193       if ( ev->isMultiDay() &&  !ev->doesFloat() ) {
00194         newtext.append( TQString(" (%1/%2)").arg( dayof ).arg( span ) );
00195       }
00196 
00197       KURLLabel *urlLabel = new KURLLabel( this );
00198       urlLabel->setText( newtext );
00199       urlLabel->setURL( ev->uid() );
00200       urlLabel->installEventFilter( this );
00201       urlLabel->setAlignment( urlLabel->alignment() | TQt::WordBreak );
00202       mLayout->addWidget( urlLabel, counter, 2 );
00203       mLabels.append( urlLabel );
00204 
00205       connect( urlLabel, TQT_SIGNAL( leftClickedURL( const TQString& ) ),
00206                this, TQT_SLOT( viewEvent( const TQString& ) ) );
00207       connect( urlLabel, TQT_SIGNAL( rightClickedURL( const TQString& ) ),
00208                this, TQT_SLOT( popupMenu( const TQString& ) ) );
00209 
00210       TQString tipText( KCal::IncidenceFormatter::toolTipStr( mCalendar, ev, dt, true ) );
00211       if ( !tipText.isEmpty() ) {
00212         TQToolTip::add( urlLabel, tipText );
00213       }
00214 
00215       // Fill Event Time Range Field (only for non-floating Events)
00216       if ( !ev->doesFloat() ) {
00217         TQTime sST = ev->dtStart().time();
00218         TQTime sET = ev->dtEnd().time();
00219         if ( ev->isMultiDay() ) {
00220           if ( ev->dtStart().date() < dt ) {
00221             sST = TQTime( 0, 0 );
00222           }
00223           if ( ev->dtEnd().date() > dt ) {
00224             sET = TQTime( 23, 59 );
00225           }
00226         }
00227         datestr = i18n( "Time from - to", "%1 - %2" )
00228                   .arg( TDEGlobal::locale()->formatTime( sST ) )
00229                   .arg( TDEGlobal::locale()->formatTime( sET ) );
00230         label = new TQLabel( datestr, this );
00231         label->setAlignment( AlignLeft | AlignVCenter );
00232         mLayout->addWidget( label, counter, 3 );
00233         mLabels.append( label );
00234       }
00235 
00236       counter++;
00237     }
00238   }
00239 
00240   if ( !counter ) {
00241     TQLabel *noEvents = new TQLabel(
00242       i18n( "No appointments pending within the next day",
00243             "No appointments pending within the next %n days",
00244             days ), this, "nothing to see" );
00245     noEvents->setAlignment( AlignHCenter | AlignVCenter );
00246     mLayout->addWidget( noEvents, 0, 2 );
00247     mLabels.append( noEvents );
00248   }
00249 
00250   for ( label = mLabels.first(); label; label = mLabels.next() )
00251     label->show();
00252 }
00253 
00254 void SummaryWidget::viewEvent( const TQString &uid )
00255 {
00256   mPlugin->core()->selectPlugin( "kontact_korganizerplugin" ); //ensure loaded
00257   KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" );
00258   iface.editIncidence( uid );
00259 }
00260 
00261 void SummaryWidget::removeEvent( const TQString &uid )
00262 {
00263   mPlugin->core()->selectPlugin( "kontact_korganizerplugin" ); //ensure loaded
00264   KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" );
00265   iface.deleteIncidence( uid, false );
00266 }
00267 
00268 void SummaryWidget::popupMenu( const TQString &uid )
00269 {
00270   TDEPopupMenu popup( this );
00271   TQToolTip::remove( this );
00272   popup.insertItem( i18n( "&Edit Appointment..." ), 0 );
00273   popup.insertItem( TDEGlobal::iconLoader()->loadIcon( "edit-delete", TDEIcon::Small),
00274                     i18n( "&Delete Appointment" ), 1 );
00275 
00276   switch ( popup.exec( TQCursor::pos() ) ) {
00277     case 0:
00278       viewEvent( uid );
00279       break;
00280     case 1:
00281       removeEvent( uid );
00282       break;
00283   }
00284 }
00285 
00286 bool SummaryWidget::eventFilter( TQObject *obj, TQEvent* e )
00287 {
00288   if ( obj->inherits( "KURLLabel" ) ) {
00289     KURLLabel* label = static_cast<KURLLabel*>( TQT_TQWIDGET(obj) );
00290     if ( e->type() == TQEvent::Enter )
00291       emit message( i18n( "Edit Appointment: \"%1\"" ).arg( label->text() ) );
00292     if ( e->type() == TQEvent::Leave )
00293       emit message( TQString() );
00294   }
00295 
00296   return Kontact::Summary::eventFilter( obj, e );
00297 }
00298 
00299 TQStringList SummaryWidget::configModules() const
00300 {
00301   return TQStringList( "kcmkorgsummary.desktop" );
00302 }
00303 
00304 #include "summarywidget.moc"