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), date );
00331     mSelectedDates.append( date );
00332     date = date.addDays( 1 );
00333   }
00334 
00335   emit incidenceSelected( 0, QDate() );
00336 }
00337 
00338 void KOListView::addIncidences( const Incidence::List &incidenceList, const QDate &date )
00339 {
00340   Incidence::List::ConstIterator it;
00341   for( it = incidenceList.begin(); it != incidenceList.end(); ++it ) {
00342     addIncidence( *it, date );
00343   }
00344 }
00345 
00346 void KOListView::addIncidence(Incidence *incidence, const QDate &date)
00347 {
00348   if ( mUidDict.find( incidence->uid() ) ) return;
00349 
00350   mDateList[incidence->uid()] = date;
00351   mUidDict.insert( incidence->uid(), incidence );
00352 
00353   KOListViewItem *item = new KOListViewItem( incidence, mListView );
00354   ListItemVisitor v(item);
00355   if (incidence->accept(v)) return;
00356   else delete item;
00357 }
00358 
00359 void KOListView::showIncidences( const Incidence::List &incidenceList, const QDate &date )
00360 {
00361   clear();
00362 
00363   addIncidences( incidenceList, date );
00364 
00365   // After new creation of list view no events are selected.
00366   emit incidenceSelected( 0, date );
00367 }
00368 
00369 void KOListView::changeIncidenceDisplay(Incidence *incidence, int action)
00370 {
00371   KOListViewItem *item;
00372   QDate f = mSelectedDates.first();
00373   QDate l = mSelectedDates.last();
00374 
00375   QDate date;
00376   if ( incidence->type() == "Todo" )
00377     date = static_cast<Todo *>(incidence)->dtDue().date();
00378   else
00379     date = incidence->dtStart().date();
00380 
00381   switch(action) {
00382     case KOGlobals::INCIDENCEADDED: {
00383       if ( date >= f && date <= l )
00384         addIncidence( incidence, date );
00385       break;
00386     }
00387     case KOGlobals::INCIDENCEEDITED: {
00388       item = getItemForIncidence(incidence);
00389       if (item) {
00390         delete item;
00391         mUidDict.remove( incidence->uid() );
00392         mDateList.remove( incidence->uid() );
00393       }
00394       if ( date >= f && date <= l )
00395         addIncidence( incidence, date );
00396     }
00397     break;
00398     case KOGlobals::INCIDENCEDELETED: {
00399       item = getItemForIncidence(incidence);
00400       if (item)
00401         delete item;
00402       break;
00403     }
00404     default:
00405       kdDebug(5850) << "KOListView::changeIncidenceDisplay(): Illegal action " << action << endl;
00406   }
00407 }
00408 
00409 KOListViewItem *KOListView::getItemForIncidence(Incidence *incidence)
00410 {
00411   KOListViewItem *item = (KOListViewItem *)mListView->firstChild();
00412   while (item) {
00413 //    kdDebug(5850) << "Item " << item->text(0) << " found" << endl;
00414     if (item->data() == incidence) return item;
00415     item = (KOListViewItem *)item->nextSibling();
00416   }
00417   return 0;
00418 }
00419 
00420 void KOListView::defaultItemAction(QListViewItem *i)
00421 {
00422   KOListViewItem *item = static_cast<KOListViewItem *>( i );
00423   if ( item ) defaultAction( item->data() );
00424 }
00425 
00426 void KOListView::popupMenu(QListViewItem *item,const QPoint &,int)
00427 {
00428   mActiveItem = (KOListViewItem *)item;
00429   if (mActiveItem) {
00430     Incidence *incidence = mActiveItem->data();
00431     // FIXME: For recurring incidences we don't know the date of this
00432     // occurrence, there's no reference to it at all!
00433     mPopupMenu->showIncidencePopup( calendar(), incidence, QDate() );
00434   }
00435   else {
00436     showNewEventPopup();
00437   }
00438 }
00439 
00440 void KOListView::readSettings(KConfig *config)
00441 {
00442   mListView->restoreLayout(config,"KOListView Layout");
00443 }
00444 
00445 void KOListView::writeSettings(KConfig *config)
00446 {
00447   mListView->saveLayout(config,"KOListView Layout");
00448 }
00449 
00450 void KOListView::processSelectionChange()
00451 {
00452   kdDebug(5850) << "KOListView::processSelectionChange()" << endl;
00453 
00454   KOListViewItem *item =
00455     static_cast<KOListViewItem *>( mListView->selectedItem() );
00456 
00457   if ( !item ) {
00458     emit incidenceSelected( 0, QDate() );
00459   } else {
00460     Incidence *incidence = static_cast<Incidence *>( item->data() );
00461     emit incidenceSelected( incidence, mDateList[incidence->uid()] );
00462   }
00463 }
00464 
00465 void KOListView::clearSelection()
00466 {
00467   mListView->selectAll( false );
00468 }
00469 
00470 void KOListView::clear()
00471 {
00472   mSelectedDates.clear();
00473   mListView->clear();
00474   mUidDict.clear();
00475   mDateList.clear();
00476 }
KDE Home | KDE Accessibility Home | Description of Access Keys