korganizer/summarywidget.cpp
1 /*
2  This file is part of Kontact.
3  Copyright (c) 2003 Tobias Koenig <tokoe@kde.org>
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 
19  As a special exception, permission is given to link this program
20  with any edition of TQt, and distribute the resulting executable,
21  without including the source code for TQt in the source distribution.
22 */
23 
24 #include <tqcursor.h>
25 #include <tqlabel.h>
26 #include <tqlayout.h>
27 #include <tqtooltip.h>
28 
29 #include <kdialog.h>
30 #include <tdeglobal.h>
31 #include <kiconloader.h>
32 #include <tdelocale.h>
33 #include <tdeparts/part.h>
34 #include <tdepopupmenu.h>
35 #include <kstandarddirs.h>
36 #include <kurllabel.h>
37 #include <libkcal/event.h>
38 #include <libkcal/resourcecalendar.h>
39 #include <libkcal/resourcelocal.h>
40 #include <libkcal/incidenceformatter.h>
41 #include <libtdepim/kpimprefs.h>
42 
43 #include "korganizeriface_stub.h"
44 
45 #include "core.h"
46 #include "plugin.h"
47 #include "korganizerplugin.h"
48 
49 #include "korganizer/stdcalendar.h"
50 
51 #include "summarywidget.h"
52 
53 SummaryWidget::SummaryWidget( KOrganizerPlugin *plugin, TQWidget *parent,
54  const char *name )
55  : Kontact::Summary( parent, name ), mPlugin( plugin ), mCalendar( 0 )
56 {
57  TQVBoxLayout *mainLayout = new TQVBoxLayout( this, 3, 3 );
58 
59  TQPixmap icon = TDEGlobal::iconLoader()->loadIcon( "kontact_date",
60  TDEIcon::Desktop, TDEIcon::SizeMedium );
61  TQWidget *header = createHeader( this, icon, i18n( "Calendar" ) );
62  mainLayout->addWidget( header );
63 
64  mLayout = new TQGridLayout( mainLayout, 7, 5, 3 );
65  mLayout->setRowStretch( 6, 1 );
66 
67  mCalendar = KOrg::StdCalendar::self();
68 
69  connect( mCalendar, TQ_SIGNAL( calendarChanged() ), TQ_SLOT( updateView() ) );
70  connect( mPlugin->core(), TQ_SIGNAL( dayChanged( const TQDate& ) ),
71  TQ_SLOT( updateView() ) );
72 
73  updateView();
74 }
75 
76 SummaryWidget::~SummaryWidget()
77 {
78 }
79 
80 void SummaryWidget::updateView()
81 {
82  mLabels.setAutoDelete( true );
83  mLabels.clear();
84  mLabels.setAutoDelete( false );
85 
86  TDEIconLoader loader( "tdepim" );
87 
88  TDEConfig config( "kcmkorgsummaryrc" );
89 
90  config.setGroup( "Calendar" );
91  int days = config.readNumEntry( "DaysToShow", 1 );
92 
93  TQLabel *label = 0;
94  int counter = 0;
95  TQPixmap pm = loader.loadIcon( "appointment", TDEIcon::Small );
96  TQPixmap pmb = loader.loadIcon( "calendarbirthday", TDEIcon::Small );
97  TQPixmap pma = loader.loadIcon( "calendaranniversary", TDEIcon::Small );
98 
99  TQDate dt;
100  TQDate currentDate = TQDate::currentDate();
101  for ( dt=currentDate;
102  dt<=currentDate.addDays( days - 1 );
103  dt=dt.addDays(1) ) {
104 
105  KCal::Event::List events = mCalendar->events( dt );
106 
107  // sort the events for this date by summary
108  events = KCal::Calendar::sortEventsForDate( &events,
109  dt,
110  KCal::EventSortSummary,
111  KCal::SortDirectionAscending );
112  // sort the events for this date by start date
113  events = KCal::Calendar::sortEventsForDate( &events,
114  dt,
115  KCal::EventSortStartDate,
116  KCal::SortDirectionAscending );
117 
118  KCal::Event::List::ConstIterator it = events.begin();
119  for ( it=events.begin(); it!=events.end(); ++it ) {
120  KCal::Event *ev = *it;
121 
122  // Count number of days remaining in multiday event
123  int span=1; int dayof=1;
124  if ( ev->isMultiDay() ) {
125  TQDate d = ev->dtStart().date();
126  if ( d < currentDate ) {
127  d = currentDate;
128  }
129  while ( d < ev->dtEnd().date() ) {
130  if ( d < dt ) {
131  dayof++;
132  }
133  span++;
134  d=d.addDays( 1 );
135  }
136  }
137 
138  // If this date is part of a floating, multiday event, then we
139  // only make a print for the first day of the event.
140  if ( ev->isMultiDay() && ev->doesFloat() && dayof != 1 ) continue;
141 
142  // Fill Appointment Pixmap Field
143  label = new TQLabel( this );
144  if ( ev->categories().contains( "Birthday" ) ) {
145  label->setPixmap( pmb );
146  } else if ( ev->categories().contains( "Anniversary" ) ) {
147  label->setPixmap( pma );
148  } else {
149  label->setPixmap( pm );
150  }
151  label->setMaximumWidth( label->minimumSizeHint().width() );
152  label->setAlignment( AlignVCenter );
153  mLayout->addWidget( label, counter, 0 );
154  mLabels.append( label );
155 
156  // Fill Event Date Field
157  bool makeBold = false;
158  TQString datestr;
159 
160  // Modify event date for printing
161  TQDate sD = TQDate( dt.year(), dt.month(), dt.day() );
162  if ( ( sD.month() == currentDate.month() ) &&
163  ( sD.day() == currentDate.day() ) ) {
164  datestr = i18n( "Today" );
165  makeBold = true;
166  } else if ( ( sD.month() == currentDate.addDays( 1 ).month() ) &&
167  ( sD.day() == currentDate.addDays( 1 ).day() ) ) {
168  datestr = i18n( "Tomorrow" );
169  } else {
170  datestr = TDEGlobal::locale()->formatDate( sD );
171  }
172 
173  // Print the date span for multiday, floating events, for the
174  // first day of the event only.
175  if ( ev->isMultiDay() && ev->doesFloat() && dayof == 1 && span > 1 ) {
176  datestr = TDEGlobal::locale()->formatDate( ev->dtStart().date() );
177  datestr += " -\n " +
178  TDEGlobal::locale()->formatDate( sD.addDays( span-1 ) );
179  }
180 
181  label = new TQLabel( datestr, this );
182  label->setAlignment( AlignLeft | AlignVCenter );
183  if ( makeBold ) {
184  TQFont font = label->font();
185  font.setBold( true );
186  label->setFont( font );
187  }
188  mLayout->addWidget( label, counter, 1 );
189  mLabels.append( label );
190 
191  // Fill Event Summary Field
192  TQString newtext = ev->summary();
193  if ( ev->isMultiDay() && !ev->doesFloat() ) {
194  newtext.append( TQString(" (%1/%2)").arg( dayof ).arg( span ) );
195  }
196 
197  KURLLabel *urlLabel = new KURLLabel( this );
198  urlLabel->setText( newtext );
199  urlLabel->setURL( ev->uid() );
200  urlLabel->installEventFilter( this );
201  urlLabel->setAlignment( urlLabel->alignment() | TQt::WordBreak );
202  mLayout->addWidget( urlLabel, counter, 2 );
203  mLabels.append( urlLabel );
204 
205  connect( urlLabel, TQ_SIGNAL( leftClickedURL( const TQString& ) ),
206  this, TQ_SLOT( viewEvent( const TQString& ) ) );
207  connect( urlLabel, TQ_SIGNAL( rightClickedURL( const TQString& ) ),
208  this, TQ_SLOT( popupMenu( const TQString& ) ) );
209 
210  TQString tipText( KCal::IncidenceFormatter::toolTipStr( mCalendar, ev, dt, true ) );
211  if ( !tipText.isEmpty() ) {
212  TQToolTip::add( urlLabel, tipText );
213  }
214 
215  // Fill Event Time Range Field (only for non-floating Events)
216  if ( !ev->doesFloat() ) {
217  TQTime sST = ev->dtStart().time();
218  TQTime sET = ev->dtEnd().time();
219  if ( ev->isMultiDay() ) {
220  if ( ev->dtStart().date() < dt ) {
221  sST = TQTime( 0, 0 );
222  }
223  if ( ev->dtEnd().date() > dt ) {
224  sET = TQTime( 23, 59 );
225  }
226  }
227  datestr = i18n( "Time from - to", "%1 - %2" )
228  .arg( TDEGlobal::locale()->formatTime( sST ) )
229  .arg( TDEGlobal::locale()->formatTime( sET ) );
230  label = new TQLabel( datestr, this );
231  label->setAlignment( AlignLeft | AlignVCenter );
232  mLayout->addWidget( label, counter, 3 );
233  mLabels.append( label );
234  }
235 
236  counter++;
237  }
238  }
239 
240  if ( !counter ) {
241  TQLabel *noEvents = new TQLabel(
242  i18n( "No appointments pending within the next day",
243  "No appointments pending within the next %n days",
244  days ), this, "nothing to see" );
245  noEvents->setAlignment( AlignHCenter | AlignVCenter );
246  mLayout->addWidget( noEvents, 0, 2 );
247  mLabels.append( noEvents );
248  }
249 
250  for ( label = mLabels.first(); label; label = mLabels.next() )
251  label->show();
252 }
253 
254 void SummaryWidget::viewEvent( const TQString &uid )
255 {
256  mPlugin->core()->selectPlugin( "kontact_korganizerplugin" ); //ensure loaded
257  KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" );
258  iface.editIncidence( uid );
259 }
260 
261 void SummaryWidget::removeEvent( const TQString &uid )
262 {
263  mPlugin->core()->selectPlugin( "kontact_korganizerplugin" ); //ensure loaded
264  KOrganizerIface_stub iface( "korganizer", "KOrganizerIface" );
265  iface.deleteIncidence( uid, false );
266 }
267 
268 void SummaryWidget::popupMenu( const TQString &uid )
269 {
270  TDEPopupMenu popup( this );
271  TQToolTip::remove( this );
272  popup.insertItem( i18n( "&Edit Appointment..." ), 0 );
273  popup.insertItem( TDEGlobal::iconLoader()->loadIcon( "edit-delete", TDEIcon::Small),
274  i18n( "&Delete Appointment" ), 1 );
275 
276  switch ( popup.exec( TQCursor::pos() ) ) {
277  case 0:
278  viewEvent( uid );
279  break;
280  case 1:
281  removeEvent( uid );
282  break;
283  }
284 }
285 
286 bool SummaryWidget::eventFilter( TQObject *obj, TQEvent* e )
287 {
288  if ( obj->inherits( "KURLLabel" ) ) {
289  KURLLabel* label = static_cast<KURLLabel*>( obj );
290  if ( e->type() == TQEvent::Enter )
291  emit message( i18n( "Edit Appointment: \"%1\"" ).arg( label->text() ) );
292  if ( e->type() == TQEvent::Leave )
293  emit message( TQString() );
294  }
295 
296  return Kontact::Summary::eventFilter( obj, e );
297 }
298 
299 TQStringList SummaryWidget::configModules() const
300 {
301  return TQStringList( "kcmkorgsummary.desktop" );
302 }
303 
304 #include "summarywidget.moc"
static Event::List sortEventsForDate(Event::List *eventList, const TQDate &date, EventSortField sortField, SortDirection sortDirection)
virtual TQDateTime dtEnd() const
bool isMultiDay() const
bool doesFloat() const
TQString uid() const
virtual TQDateTime dtStart() const
TQStringList categories() const
TQString summary() const