korganizer

kolistview.cpp

00001 /*
00002     This file is part of KOrganizer.
00003 
00004     Copyright (c) 1999 Preston Brown <pbrown@kde.org>
00005     Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
00006     Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00007 
00008     This program is free software; you can redistribute it and/or modify
00009     it under the terms of the GNU General Public License as published by
00010     the Free Software Foundation; either version 2 of the License, or
00011     (at your option) any later version.
00012 
00013     This program is distributed in the hope that it will be useful,
00014     but WITHOUT ANY WARRANTY; without even the implied warranty of
00015     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016     GNU General Public License for more details.
00017 
00018     You should have received a copy of the GNU General Public License
00019     along with this program; if not, write to the Free Software
00020     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00021 
00022     As a special exception, permission is given to link this program
00023     with any edition of Qt, and distribute the resulting executable,
00024     without including the source code for Qt in the source distribution.
00025 */
00026 
00027 #include <qlistview.h>
00028 #include <qlayout.h>
00029 #include <qpopupmenu.h>
00030 #include <qcursor.h>
00031 
00032 #include <klocale.h>
00033 #include <kdebug.h>
00034 #include <kiconloader.h>
00035 #include <kglobal.h>
00036 
00037 #include <libkcal/calendar.h>
00038 #include <libkcal/incidenceformatter.h>
00039 
00040 #include "koglobals.h"
00041 #include "koprefs.h"
00042 #include "koincidencetooltip.h"
00043 #include "koeventpopupmenu.h"
00044 
00045 #include "kolistview.h"
00046 #include "kolistview.moc"
00047 
00048 
00049 KOListViewToolTip::KOListViewToolTip( QWidget* parent,
00050                                       Calendar *calendar,
00051                                       KListView* lv )
00052   :QToolTip(parent), mCalendar( calendar )
00053 {
00054   eventlist=lv;
00055 }
00056 
00057 void KOListViewToolTip::maybeTip( const QPoint & pos)
00058 {
00059   QRect r;
00060   QListViewItem *it = eventlist->itemAt(pos);
00061   KOListViewItem *i = static_cast<KOListViewItem*>(it);
00062 
00063   if( i && KOPrefs::instance()->mEnableToolTips ) {
00064     /* Calculate the rectangle. */
00065     r=eventlist->itemRect( it );
00066     /* Show the tip */
00067     QString tipText( IncidenceFormatter::toolTipStr( mCalendar, i->data() ) );
00068     if ( !tipText.isEmpty() ) {
00069       tip(r, tipText);
00070     }
00071   }
00072 
00073 }
00074 
00079 class KOListView::ListItemVisitor : public IncidenceBase::Visitor
00080 {
00081   public:
00082     ListItemVisitor( KOListViewItem *item ) : mItem( item ) {}
00083     ~ListItemVisitor() {}
00084 
00085     bool visit( Event * );
00086     bool visit( Todo * );
00087     bool visit( Journal * );
00088 
00089   private:
00090     KOListViewItem *mItem;
00091 };
00092 
00093 bool KOListView::ListItemVisitor::visit( Event *e )
00094 {
00095   mItem->setText(0,e->summary());
00096   if ( e->isAlarmEnabled() ) {
00097     static const QPixmap alarmPxmp = KOGlobals::self()->smallIcon( "bell" );
00098     mItem->setPixmap(1,alarmPxmp);
00099     mItem->setSortKey(1,"1");
00100   }
00101   else
00102     mItem->setSortKey(1,"0");
00103 
00104   if ( e->doesRecur() ) {
00105     static const QPixmap recurPxmp = KOGlobals::self()->smallIcon( "recur" );
00106     mItem->setPixmap(2,recurPxmp);
00107     mItem->setSortKey(2,"1");
00108   }
00109   else
00110     mItem->setSortKey(2,"0");
00111 
00112   QPixmap eventPxmp;
00113   if ( e->customProperty( "KABC", "BIRTHDAY" ) == "YES" ) {
00114     if ( e->customProperty( "KABC", "ANNIVERSARY" ) == "YES" ) {
00115       eventPxmp = KOGlobals::self()->smallIcon( "calendaranniversary" );
00116     } else {
00117       eventPxmp = KOGlobals::self()->smallIcon( "calendarbirthday" );
00118     }
00119   } else {
00120     eventPxmp = KOGlobals::self()->smallIcon( "appointment" );
00121   }
00122 
00123   mItem->setPixmap(0, eventPxmp);
00124 
00125   mItem->setText( 3,e->dtStartDateStr());
00126   mItem->setSortKey( 3, e->dtStart().toString(Qt::ISODate));
00127   if (e->doesFloat()) mItem->setText(4, "---"); else {
00128     mItem->setText( 4, e->dtStartTimeStr() );
00129     mItem->setSortKey( 4,e->dtStart().time().toString(Qt::ISODate));
00130   }
00131   mItem->setText( 5,e->dtEndDateStr());
00132   mItem->setSortKey( 5, e->dtEnd().toString(Qt::ISODate));
00133   if (e->doesFloat()) mItem->setText(6, "---"); else {
00134     mItem->setText( 6, e->dtEndTimeStr() );
00135     mItem->setSortKey( 6, e->dtEnd().time().toString(Qt::ISODate));
00136   }
00137   mItem->setText( 7,e->categoriesStr());
00138 
00139   return true;
00140 }
00141 
00142 bool KOListView::ListItemVisitor::visit(Todo *t)
00143 {
00144   static const QPixmap todoPxmp = KOGlobals::self()->smallIcon( "todo" );
00145   static const QPixmap todoDonePxmp = KOGlobals::self()->smallIcon( "checkedbox" );
00146   mItem->setPixmap(0, t->isCompleted() ? todoDonePxmp : todoPxmp );
00147   mItem->setText(0,t->summary());
00148   if ( t->isAlarmEnabled() ) {
00149     static const QPixmap alarmPxmp = KOGlobals::self()->smallIcon( "bell" );
00150     mItem->setPixmap(1,alarmPxmp);
00151     mItem->setSortKey(1, "1");
00152   }
00153   else
00154     mItem->setSortKey(1, "0");
00155 
00156   if ( t->doesRecur() ) {
00157     static const QPixmap recurPxmp = KOGlobals::self()->smallIcon( "recur" );
00158     mItem->setPixmap(2,recurPxmp);
00159     mItem->setSortKey(2, "1");
00160   }
00161   else
00162     mItem->setSortKey(2, "0");
00163 
00164   if (t->hasStartDate()) {
00165     mItem->setText(3,t->dtStartDateStr());
00166     mItem->setSortKey(3,t->dtStart().toString(Qt::ISODate));
00167     if (t->doesFloat()) {
00168       mItem->setText(4,"---");
00169     } else {
00170       mItem->setText(4,t->dtStartTimeStr());
00171       mItem->setSortKey( 4, t->dtStart().time().toString(Qt::ISODate) );
00172     }
00173   } else {
00174     mItem->setText(3,"---");
00175     mItem->setText(4,"---");
00176   }
00177 
00178   if (t->hasDueDate()) {
00179     mItem->setText(5,t->dtDueDateStr());
00180     mItem->setSortKey( 5, t->dtDue().toString(Qt::ISODate) );
00181     if (t->doesFloat()) {
00182       mItem->setText(6,"---");
00183     } else {
00184       mItem->setText(6,t->dtDueTimeStr());
00185       mItem->setSortKey( 6, t->dtDue().time().toString(Qt::ISODate) );
00186     }
00187   } else {
00188     mItem->setText(5,"---");
00189     mItem->setText(6,"---");
00190   }
00191   mItem->setText(7,t->categoriesStr());
00192 
00193 
00194   return true;
00195 }
00196 
00197 bool KOListView::ListItemVisitor::visit(Journal *t)
00198 {
00199   static const QPixmap jrnalPxmp = KOGlobals::self()->smallIcon( "journal" );
00200   mItem->setPixmap(0,jrnalPxmp);
00201   // Just use the first line
00202   mItem->setText( 0, t->description().section( "\n", 0, 0 ) );
00203   mItem->setText( 3, t->dtStartDateStr() );
00204   mItem->setSortKey( 3, t->dtStart().toString(Qt::ISODate) );
00205 
00206   return true;
00207 }
00208 
00209 KOListView::KOListView( Calendar *calendar, QWidget *parent,
00210                         const char *name)
00211   : KOEventView(calendar, parent, name)
00212 {
00213   mActiveItem = 0;
00214 
00215   mListView = new KListView(this);
00216   mListView->addColumn(i18n("Summary"));
00217   mListView->addColumn(i18n("Reminder")); // alarm set?
00218   mListView->addColumn(i18n("Recurs")); // recurs?
00219   mListView->addColumn(i18n("Start Date"));
00220   mListView->setColumnAlignment(3,AlignHCenter);
00221   mListView->addColumn(i18n("Start Time"));
00222   mListView->setColumnAlignment(4,AlignHCenter);
00223   mListView->addColumn(i18n("End Date"));
00224   mListView->setColumnAlignment(5,AlignHCenter);
00225   mListView->addColumn(i18n("End Time"));
00226   mListView->setColumnAlignment(6,AlignHCenter);
00227   mListView->addColumn(i18n("Categories"));
00228 
00229   QBoxLayout *layoutTop = new QVBoxLayout(this);
00230   layoutTop->addWidget(mListView);
00231 
00232   mPopupMenu = eventPopup();
00233 /*
00234   mPopupMenu->insertSeparator();
00235   mPopupMenu->insertItem(i18n("Show Dates"), this,
00236                       SLOT(showDates()));
00237   mPopupMenu->insertItem(i18n("Hide Dates"), this,
00238                       SLOT(hideDates()));
00239 */
00240 
00241   QObject::connect( mListView, SIGNAL( doubleClicked( QListViewItem * ) ),
00242                     SLOT( defaultItemAction( QListViewItem * ) ) );
00243   QObject::connect( mListView, SIGNAL( returnPressed( QListViewItem * ) ),
00244                     SLOT( defaultItemAction( QListViewItem * ) ) );
00245   QObject::connect( mListView, SIGNAL( rightButtonClicked ( QListViewItem *,
00246                                                             const QPoint &,
00247                                                             int ) ),
00248                     SLOT( popupMenu( QListViewItem *, const QPoint &, int ) ) );
00249   QObject::connect( mListView, SIGNAL( selectionChanged() ),
00250                     SLOT( processSelectionChange() ) );
00251 
00252 //  setMinimumSize(100,100);
00253   mListView->restoreLayout(KOGlobals::self()->config(),"KOListView Layout");
00254 
00255   new KOListViewToolTip( mListView->viewport(), calendar, mListView );
00256 
00257   mSelectedDates.append( QDate::currentDate() );
00258 }
00259 
00260 KOListView::~KOListView()
00261 {
00262   delete mPopupMenu;
00263 }
00264 
00265 int KOListView::maxDatesHint()
00266 {
00267   return 0;
00268 }
00269 
00270 int KOListView::currentDateCount()
00271 {
00272   return mSelectedDates.count();
00273 }
00274 
00275 Incidence::List KOListView::selectedIncidences()
00276 {
00277   Incidence::List eventList;
00278 
00279   QListViewItem *item = mListView->selectedItem();
00280   if (item) eventList.append(((KOListViewItem *)item)->data());
00281 
00282   return eventList;
00283 }
00284 
00285 DateList KOListView::selectedDates()
00286 {
00287   return mSelectedDates;
00288 }
00289 
00290 void KOListView::showDates(bool show)
00291 {
00292   // Shouldn't we set it to a value greater 0? When showDates is called with
00293   // show == true at first, then the columnwidths are set to zero.
00294   static int oldColWidth1 = 0;
00295   static int oldColWidth3 = 0;
00296 
00297   if (!show) {
00298     oldColWidth1 = mListView->columnWidth(1);
00299     oldColWidth3 = mListView->columnWidth(3);
00300     mListView->setColumnWidth(1, 0);
00301     mListView->setColumnWidth(3, 0);
00302   } else {
00303     mListView->setColumnWidth(1, oldColWidth1);
00304     mListView->setColumnWidth(3, oldColWidth3);
00305   }
00306   mListView->repaint();
00307 }
00308 
00309 void KOListView::showDates()
00310 {
00311   showDates(true);
00312 }
00313 
00314 void KOListView::hideDates()
00315 {
00316   showDates(false);
00317 }
00318 
00319 void KOListView::updateView()
00320 {
00321   kdDebug(5850) << "KOListView::updateView() does nothing" << endl;
00322 }
00323 
00324 void KOListView::showDates(const QDate &start, const QDate &end)
00325 {
00326   clear();
00327 
00328   QDate date = start;
00329   while( date <= end ) {
00330     addIncidences( calendar()->incidences(date) );
00331     mSelectedDates.append( date );
00332     date = date.addDays( 1 );
00333   }
00334 
00335   emit incidenceSelected( 0 );
00336 }
00337 
00338 void KOListView::addIncidences( const Incidence::List &incidenceList )
00339 {
00340   Incidence::List::ConstIterator it;
00341   for( it = incidenceList.begin(); it != incidenceList.end(); ++it ) {
00342     addIncidence( *it );
00343   }
00344 }
00345 
00346 void KOListView::addIncidence(Incidence *incidence)
00347 {
00348   if ( mUidDict.find( incidence->uid() ) ) return;
00349 
00350   mUidDict.insert( incidence->uid(), incidence );
00351 
00352   KOListViewItem *item = new KOListViewItem( incidence, mListView );
00353   ListItemVisitor v(item);
00354   if (incidence->accept(v)) return;
00355   else delete item;
00356 }
00357 
00358 void KOListView::showIncidences( const Incidence::List &incidenceList )
00359 {
00360   clear();
00361 
00362   addIncidences( incidenceList );
00363 
00364   // After new creation of list view no events are selected.
00365   emit incidenceSelected( 0 );
00366 }
00367 
00368 void KOListView::changeIncidenceDisplay(Incidence *incidence, int action)
00369 {
00370   KOListViewItem *item;
00371   QDate f = mSelectedDates.first();
00372   QDate l = mSelectedDates.last();
00373 
00374   QDate date;
00375   if ( incidence->type() == "Todo" )
00376     date = static_cast<Todo *>(incidence)->dtDue().date();
00377   else
00378     date = incidence->dtStart().date();
00379 
00380   switch(action) {
00381     case KOGlobals::INCIDENCEADDED: {
00382       if ( date >= f && date <= l )
00383         addIncidence( incidence );
00384       break;
00385     }
00386     case KOGlobals::INCIDENCEEDITED: {
00387       item = getItemForIncidence(incidence);
00388       if (item) {
00389         delete item;
00390         mUidDict.remove( incidence->uid() );
00391       }
00392       if ( date >= f && date <= l )
00393         addIncidence( incidence );
00394     }
00395     break;
00396     case KOGlobals::INCIDENCEDELETED: {
00397       item = getItemForIncidence(incidence);
00398       if (item)
00399         delete item;
00400       break;
00401     }
00402     default:
00403       kdDebug(5850) << "KOListView::changeIncidenceDisplay(): Illegal action " << action << endl;
00404   }
00405 }
00406 
00407 KOListViewItem *KOListView::getItemForIncidence(Incidence *incidence)
00408 {
00409   KOListViewItem *item = (KOListViewItem *)mListView->firstChild();
00410   while (item) {
00411 //    kdDebug(5850) << "Item " << item->text(0) << " found" << endl;
00412     if (item->data() == incidence) return item;
00413     item = (KOListViewItem *)item->nextSibling();
00414   }
00415   return 0;
00416 }
00417 
00418 void KOListView::defaultItemAction(QListViewItem *i)
00419 {
00420   KOListViewItem *item = static_cast<KOListViewItem *>( i );
00421   if ( item ) defaultAction( item->data() );
00422 }
00423 
00424 void KOListView::popupMenu(QListViewItem *item,const QPoint &,int)
00425 {
00426   mActiveItem = (KOListViewItem *)item;
00427   if (mActiveItem) {
00428     Incidence *incidence = mActiveItem->data();
00429     // FIXME: For recurring incidences we don't know the date of this
00430     // occurrence, there's no reference to it at all!
00431     mPopupMenu->showIncidencePopup( incidence, QDate() );
00432   }
00433   else {
00434     showNewEventPopup();
00435   }
00436 }
00437 
00438 void KOListView::readSettings(KConfig *config)
00439 {
00440   mListView->restoreLayout(config,"KOListView Layout");
00441 }
00442 
00443 void KOListView::writeSettings(KConfig *config)
00444 {
00445   mListView->saveLayout(config,"KOListView Layout");
00446 }
00447 
00448 void KOListView::processSelectionChange()
00449 {
00450   kdDebug(5850) << "KOListView::processSelectionChange()" << endl;
00451 
00452   KOListViewItem *item =
00453     static_cast<KOListViewItem *>( mListView->selectedItem() );
00454 
00455   if ( !item ) {
00456     emit incidenceSelected( 0 );
00457   } else {
00458     emit incidenceSelected( item->data() );
00459   }
00460 }
00461 
00462 void KOListView::clearSelection()
00463 {
00464   mListView->selectAll( false );
00465 }
00466 
00467 void KOListView::clear()
00468 {
00469   mSelectedDates.clear();
00470   mListView->clear();
00471   mUidDict.clear();
00472 }
KDE Home | KDE Accessibility Home | Description of Access Keys