korganizer

kolistview.cpp
1 /*
2  This file is part of KOrganizer.
3 
4  Copyright (c) 1999 Preston Brown <pbrown@kde.org>
5  Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
6  Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
7 
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 
22  As a special exception, permission is given to link this program
23  with any edition of TQt, and distribute the resulting executable,
24  without including the source code for TQt in the source distribution.
25 */
26 
27 #include <tqlistview.h>
28 #include <tqlayout.h>
29 #include <tqpopupmenu.h>
30 #include <tqcursor.h>
31 #include <tqstyle.h>
32 
33 #include <tdelocale.h>
34 #include <kdebug.h>
35 #include <kiconloader.h>
36 #include <tdeglobal.h>
37 
38 #include <libkcal/calendar.h>
39 #include <libkcal/incidenceformatter.h>
40 
41 #include "koglobals.h"
42 #include "koprefs.h"
43 #include "koincidencetooltip.h"
44 #include "koeventpopupmenu.h"
45 
46 #include "kolistview.h"
47 #include "kolistview.moc"
48 
49 enum {
50  Summary_Column = 0,
51  Reminder_Column,
52  Recurs_Column,
53  StartDateTime_Column,
54  EndDateTime_Column,
55  Categories_Column
56 };
57 
58 
59 KOListViewToolTip::KOListViewToolTip( TQWidget* parent,
60  Calendar *calendar,
61  TDEListView *lv )
62  :TQToolTip( parent ), mCalendar( calendar )
63 {
64  eventlist = lv;
65 }
66 
67 void KOListViewToolTip::maybeTip( const TQPoint &pos )
68 {
69  TQRect r;
70  TQListViewItem *it = eventlist->itemAt( pos );
71  KOListViewItem *i = static_cast<KOListViewItem*>( it );
72 
73  if ( i && KOPrefs::instance()->mEnableToolTips ) {
74  /* Calculate the rectangle. */
75  r = eventlist->itemRect( it );
76  /* Show the tip */
77  TQString tipText( IncidenceFormatter::toolTipStr( mCalendar, i->data() ) );
78  if ( !tipText.isEmpty() ) {
79  tip( r, tipText );
80  }
81  }
82 }
83 
88 class KOListView::ListItemVisitor : public IncidenceBase::Visitor
89 {
90  public:
91  ListItemVisitor( KOListViewItem *item ) : mItem( item ) {}
92  ~ListItemVisitor() {}
93 
94  bool visit( Event * );
95  bool visit( Todo * );
96  bool visit( Journal * );
97 
98  private:
99  KOListViewItem *mItem;
100 };
101 
103 {
104  mItem->setText( Summary_Column, e->summary() );
105  if ( e->isAlarmEnabled() ) {
106  static const TQPixmap alarmPxmp = KOGlobals::self()->smallIcon( "bell" );
107  mItem->setPixmap( Reminder_Column, alarmPxmp );
108  mItem->setSortKey( Reminder_Column, "1" );
109  } else {
110  mItem->setSortKey( Reminder_Column, "0" );
111  }
112 
113  if ( e->doesRecur() ) {
114  static const TQPixmap recurPxmp = KOGlobals::self()->smallIcon( "recur" );
115  mItem->setPixmap( Recurs_Column, recurPxmp );
116  mItem->setSortKey( Recurs_Column, "1" );
117  } else {
118  mItem->setSortKey( Recurs_Column, "0" );
119  }
120 
121  TQPixmap eventPxmp;
122  if ( e->customProperty( "KABC", "BIRTHDAY" ) == "YES" ) {
123  if ( e->customProperty( "KABC", "ANNIVERSARY" ) == "YES" ) {
124  eventPxmp = KOGlobals::self()->smallIcon( "calendaranniversary" );
125  } else {
126  eventPxmp = KOGlobals::self()->smallIcon( "calendarbirthday" );
127  }
128  } else {
129  eventPxmp = KOGlobals::self()->smallIcon( "appointment" );
130  }
131 
132  mItem->setPixmap( Summary_Column, eventPxmp );
133 
134  TQString startDateTime;
135  TQString endDateTime;
136 
137  mItem->setText( StartDateTime_Column, IncidenceFormatter::dateTimeToString( e->dtStart(), e->doesFloat() ) );
138  mItem->setSortKey( StartDateTime_Column, e->dtStart().toString( TQt::ISODate ) );
139  mItem->setText( EndDateTime_Column, IncidenceFormatter::dateTimeToString( e->dtEnd(), e->doesFloat() ) );
140  mItem->setSortKey( EndDateTime_Column, e->dtEnd().toString( TQt::ISODate ) );
141  mItem->setText( Categories_Column, e->categoriesStr() );
142 
143  return true;
144 }
145 
147 {
148  static const TQPixmap todoPxmp = KOGlobals::self()->smallIcon( "todo" );
149  static const TQPixmap todoDonePxmp = KOGlobals::self()->smallIcon( "checkedbox" );
150  mItem->setPixmap(Summary_Column, t->isCompleted() ? todoDonePxmp : todoPxmp );
151  mItem->setText(Summary_Column, t->summary());
152  if ( t->isAlarmEnabled() ) {
153  static const TQPixmap alarmPxmp = KOGlobals::self()->smallIcon( "bell" );
154  mItem->setPixmap( Reminder_Column, alarmPxmp );
155  mItem->setSortKey( Reminder_Column, "1" );
156  } else {
157  mItem->setSortKey( Reminder_Column, "0" );
158  }
159 
160  if ( t->doesRecur() ) {
161  static const TQPixmap recurPxmp = KOGlobals::self()->smallIcon( "recur" );
162  mItem->setPixmap( Recurs_Column, recurPxmp );
163  mItem->setSortKey( Recurs_Column, "1" );
164  } else {
165  mItem->setSortKey( Recurs_Column, "0" );
166  }
167 
168  if ( t->hasStartDate() ) {
169  mItem->setText( StartDateTime_Column, IncidenceFormatter::dateTimeToString( t->dtStart(), t->doesFloat() ) );
170  mItem->setSortKey( StartDateTime_Column, t->dtStart().toString( TQt::ISODate ) );
171  } else {
172  mItem->setText( StartDateTime_Column, "---" );
173  }
174 
175  if ( t->hasDueDate() ) {
176  mItem->setText( EndDateTime_Column, IncidenceFormatter::dateTimeToString( t->dtDue(), t->doesFloat() ) );
177  mItem->setSortKey( EndDateTime_Column, t->dtDue().toString( TQt::ISODate ) );
178  } else {
179  mItem->setText( EndDateTime_Column, "---" );
180  }
181  mItem->setText( Categories_Column, t->categoriesStr() );
182 
183  return true;
184 }
185 
187 {
188  static const TQPixmap jornalPxmp = KOGlobals::self()->smallIcon( "journal" );
189  mItem->setPixmap( Summary_Column, jornalPxmp );
190  // Just use the first line
191  mItem->setText( Summary_Column, j->description().section( "\n", 0, 0 ) );
192  mItem->setText( StartDateTime_Column, IncidenceFormatter::dateTimeToString( j->dtStart(), j->doesFloat() ) );
193  mItem->setSortKey( StartDateTime_Column, j->dtStart().toString( TQt::ISODate ) );
194 
195  return true;
196 }
197 
198 KOListView::KOListView( Calendar *calendar,
199  TQWidget *parent,
200  const char *name,
201  bool nonInteractive )
202  : KOEventView( calendar, parent, name )
203 {
204  mActiveItem = 0;
205  mIsNonInteractive = nonInteractive;
206 
207  mListView = new TDEListView( this );
208  mListView->addColumn( i18n("Summary") );
209  mListView->addColumn( i18n("Reminder") ); // alarm set?
210  mListView->setColumnAlignment( Reminder_Column, AlignHCenter );
211 
212  mListView->addColumn( i18n("Recurs") ); // recurs?
213  mListView->setColumnAlignment( Recurs_Column, AlignHCenter );
214 
215  mListView->addColumn( i18n("Start Date/Time") );
216  mListView->setColumnAlignment( StartDateTime_Column, AlignHCenter );
217 
218  mListView->addColumn( i18n("End Date/Time") );
219  mListView->setColumnAlignment( EndDateTime_Column, AlignHCenter );
220 
221  mListView->addColumn( i18n("Categories") );
222 
223  TQBoxLayout *layoutTop = new TQVBoxLayout( this );
224  layoutTop->addWidget( mListView );
225 
226  mPopupMenu = eventPopup();
227 /*
228  mPopupMenu->insertSeparator();
229  mPopupMenu->insertItem(i18n("Show Dates"), this,
230  TQ_SLOT(showDates()));
231  mPopupMenu->insertItem(i18n("Hide Dates"), this,
232  TQ_SLOT(hideDates()));
233 */
234 
235  connect( mListView, TQ_SIGNAL( doubleClicked( TQListViewItem * ) ),
236  TQ_SLOT( defaultItemAction( TQListViewItem * ) ) );
237  connect( mListView, TQ_SIGNAL( returnPressed( TQListViewItem * ) ),
238  TQ_SLOT( defaultItemAction( TQListViewItem * ) ) );
239  connect( mListView, TQ_SIGNAL( rightButtonClicked ( TQListViewItem *,
240  const TQPoint &,
241  int ) ),
242  TQ_SLOT( popupMenu( TQListViewItem *, const TQPoint &, int ) ) );
243  connect( mListView, TQ_SIGNAL( selectionChanged() ),
244  TQ_SLOT( processSelectionChange() ) );
245 
246 // setMinimumSize(100,100);
247  mListView->restoreLayout( KOGlobals::self()->config(), "KOListView Layout" );
248 
249  new KOListViewToolTip( mListView->viewport(), calendar, mListView );
250 
251  mSelectedDates.append( TQDate::currentDate() );
252 }
253 
254 KOListView::~KOListView()
255 {
256  delete mPopupMenu;
257 }
258 
260 {
261  return 0;
262 }
263 
265 {
266  return mSelectedDates.count();
267 }
268 
270 {
271  Incidence::List eventList;
272 
273  TQListViewItem *item = mListView->selectedItem();
274  if ( item ) {
275  eventList.append( static_cast<KOListViewItem *>( item )->data() );
276  }
277 
278  return eventList;
279 }
280 
282 {
283  return mSelectedDates;
284 }
285 
286 void KOListView::showDates( bool show )
287 {
288  // Shouldn't we set it to a value greater 0? When showDates is called with
289  // show == true at first, then the columnwidths are set to zero.
290  static int oldColWidth1 = 0;
291  static int oldColWidth3 = 0;
292 
293  if ( !show ) {
294  oldColWidth1 = mListView->columnWidth( 1 );
295  oldColWidth3 = mListView->columnWidth( 3 );
296  mListView->setColumnWidth( 1, 0 );
297  mListView->setColumnWidth( 3, 0 );
298  } else {
299  mListView->setColumnWidth( 1, oldColWidth1 );
300  mListView->setColumnWidth( 3, oldColWidth3 );
301  }
302  mListView->repaint();
303 }
304 
305 void KOListView::showDates()
306 {
307  showDates( true );
308 }
309 
310 void KOListView::hideDates()
311 {
312  showDates( false );
313 }
314 
315 void KOListView::updateView()
316 {
317  kdDebug(5850) << "KOListView::updateView() does nothing" << endl;
318 }
319 
320 void KOListView::showDates( const TQDate &start, const TQDate &end )
321 {
322  clear();
323 
324  TQDate date = start;
325  while( date <= end ) {
326  addIncidences( calendar()->incidences( date ), date );
327  mSelectedDates.append( date );
328  date = date.addDays( 1 );
329  }
330 
331  emit incidenceSelected( 0, TQDate() );
332 }
333 
334 void KOListView::showAll()
335 {
336  Incidence::List incidenceList = calendar()->incidences();
337 
338  Incidence::List::ConstIterator it;
339  for( it = incidenceList.begin(); it != incidenceList.end(); ++it ) {
340  // we don't need the date, using showAll in non interactive mode for now
341  addIncidence( *it, TQDate() );
342  }
343 }
344 
345 void KOListView::addIncidences( const Incidence::List &incidenceList, const TQDate &date )
346 {
347  Incidence::List::ConstIterator it;
348  for( it = incidenceList.begin(); it != incidenceList.end(); ++it ) {
349  addIncidence( *it, date );
350  }
351 }
352 
353 void KOListView::addIncidence( Incidence *incidence, const TQDate &date )
354 {
355  if ( mUidDict.find( incidence->uid() ) ) {
356  return;
357  }
358 
359  mDateList[incidence->uid()] = date;
360  mUidDict.insert( incidence->uid(), incidence );
361 
362  KOListViewItem *item = new KOListViewItem( incidence, mListView );
363  ListItemVisitor v( item );
364  if (incidence->accept( v ) ) {
365  return;
366  } else {
367  delete item;
368  }
369 }
370 
371 void KOListView::showIncidences( const Incidence::List &incidenceList, const TQDate &date )
372 {
373  clear();
374 
375  addIncidences( incidenceList, date );
376 
377  // After new creation of list view no events are selected.
378  emit incidenceSelected( 0, date );
379 }
380 
381 void KOListView::changeIncidenceDisplay( Incidence *incidence, int action )
382 {
383  KOListViewItem *item;
384  TQDate f = mSelectedDates.first();
385  TQDate l = mSelectedDates.last();
386 
387  TQDate date;
388  if ( incidence->type() == "Todo" ) {
389  date = static_cast<Todo *>( incidence )->dtDue().date();
390  } else {
391  date = incidence->dtStart().date();
392  }
393 
394  switch( action ) {
395  case KOGlobals::INCIDENCEADDED: {
396  if ( date >= f && date <= l )
397  addIncidence( incidence, date );
398  break;
399  }
400  case KOGlobals::INCIDENCEEDITED: {
401  item = getItemForIncidence( incidence );
402  if ( item ) {
403  delete item;
404  mUidDict.remove( incidence->uid() );
405  mDateList.remove( incidence->uid() );
406  }
407  if ( date >= f && date <= l ) {
408  addIncidence( incidence, date );
409  }
410  }
411  break;
412  case KOGlobals::INCIDENCEDELETED: {
413  item = getItemForIncidence( incidence );
414  if ( item ) {
415  delete item;
416  }
417  break;
418  }
419  default:
420  kdDebug(5850) << "KOListView::changeIncidenceDisplay(): Illegal action " << action << endl;
421  }
422 }
423 
424 KOListViewItem *KOListView::getItemForIncidence( Incidence *incidence )
425 {
426  KOListViewItem *item = static_cast<KOListViewItem *>( mListView->firstChild() );
427  while ( item ) {
428 // kdDebug(5850) << "Item " << item->text(0) << " found" << endl;
429  if ( item->data() == incidence ) {
430  return item;
431  }
432  item = static_cast<KOListViewItem *>( item->nextSibling() );
433  }
434  return 0;
435 }
436 
437 void KOListView::defaultItemAction( TQListViewItem *i )
438 {
439  if ( !mIsNonInteractive ) {
440  KOListViewItem *item = static_cast<KOListViewItem *>( i );
441  if ( item ) {
442  defaultAction( item->data() );
443  }
444  }
445 }
446 
447 void KOListView::popupMenu( TQListViewItem *item,const TQPoint &, int )
448 {
449  if ( !mIsNonInteractive ) {
450  mActiveItem = static_cast<KOListViewItem *>( item );
451  if ( mActiveItem ) {
452  Incidence *incidence = mActiveItem->data();
453  // FIXME: For recurring incidences we don't know the date of this
454  // occurrence, there's no reference to it at all!
455  mPopupMenu->showIncidencePopup( calendar(), incidence, TQDate() );
456  } else {
457  showNewEventPopup();
458  }
459  }
460 }
461 
462 void KOListView::readSettings( TDEConfig *config )
463 {
464  mListView->restoreLayout( config,"KOListView Layout" );
465 }
466 
467 void KOListView::writeSettings( TDEConfig *config )
468 {
469  mListView->saveLayout( config, "KOListView Layout" );
470 }
471 
472 void KOListView::processSelectionChange()
473 {
474  if ( !mIsNonInteractive ) {
475  kdDebug(5850) << "KOListView::processSelectionChange()" << endl;
476 
477  KOListViewItem *item =
478  static_cast<KOListViewItem *>( mListView->selectedItem() );
479 
480  if ( !item ) {
481  emit incidenceSelected( 0, TQDate() );
482  } else {
483  Incidence *incidence = static_cast<Incidence *>( item->data() );
484  emit incidenceSelected( incidence, mDateList[incidence->uid()] );
485  }
486  }
487 }
488 
489 void KOListView::clearSelection()
490 {
491  mListView->selectAll( false );
492 }
493 
494 void KOListView::clear()
495 {
496  mSelectedDates.clear();
497  mListView->clear();
498  mUidDict.clear();
499  mDateList.clear();
500 }
501 
502 TQSize KOListView::sizeHint() const
503 {
504  const TQSize s = KOEventView::sizeHint();
505  return TQSize( s.width() + style().pixelMetric( TQStyle::PM_ScrollBarExtent ) + 1,
506  s.height() );
507 }
virtual Incidence::List incidences()
TQString customProperty(const TQCString &app, const TQCString &key) const
virtual TQDateTime dtEnd() const
virtual bool visit(FreeBusy *)
virtual bool visit(Event *)
bool doesFloat() const
TQString uid() const
virtual TQDateTime dtStart() const
virtual bool accept(Visitor &)
TQString description() const
bool doesRecur() const
bool isAlarmEnabled() const
TQString categoriesStr() const
TQString summary() const
bool hasDueDate() const
bool isCompleted() const
bool hasStartDate() const
TQDateTime dtStart(bool first=false) const
TQDateTime dtDue(bool first=false) const
KOEventView is the abstract base class from which all other calendar views for event data are derived...
Definition: koeventview.h:56
void defaultAction(Incidence *)
Perform the default action for an incidence, e.g.
virtual int currentDateCount()
Return number of currently shown dates.
Definition: kolistview.cpp:264
virtual DateList selectedIncidenceDates()
Definition: kolistview.cpp:281
virtual int maxDatesHint()
provides a hint back to the caller on the maximum number of dates that the view supports.
Definition: kolistview.cpp:259
virtual Incidence::List selectedIncidences()
Definition: kolistview.cpp:269
virtual Calendar * calendar()
Return calendar object of this view.
Definition: baseview.h:89