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, IncidenceFormatter::dateToString( e->dtEnd(), true ) );
00132   mItem->setSortKey( 5, e->dtEnd().toString(Qt::ISODate));
00133   if ( e->doesFloat() ) {
00134     mItem->setText(6, "---");
00135   } else {
00136     mItem->setText( 6, IncidenceFormatter::timeToString(e->dtEnd(), true ) );
00137     mItem->setSortKey( 6, e->dtEnd().time().toString(Qt::ISODate));
00138   }
00139   mItem->setText( 7,e->categoriesStr());
00140 
00141   return true;
00142 }
00143 
00144 bool KOListView::ListItemVisitor::visit(Todo *t)
00145 {
00146   static const QPixmap todoPxmp = KOGlobals::self()->smallIcon( "todo" );
00147   static const QPixmap todoDonePxmp = KOGlobals::self()->smallIcon( "checkedbox" );
00148   mItem->setPixmap(0, t->isCompleted() ? todoDonePxmp : todoPxmp );
00149   mItem->setText(0,t->summary());
00150   if ( t->isAlarmEnabled() ) {
00151     static const QPixmap alarmPxmp = KOGlobals::self()->smallIcon( "bell" );
00152     mItem->setPixmap(1,alarmPxmp);
00153     mItem->setSortKey(1, "1");
00154   }
00155   else
00156     mItem->setSortKey(1, "0");
00157 
00158   if ( t->doesRecur() ) {
00159     static const QPixmap recurPxmp = KOGlobals::self()->smallIcon( "recur" );
00160     mItem->setPixmap(2,recurPxmp);
00161     mItem->setSortKey(2, "1");
00162   }
00163   else
00164     mItem->setSortKey(2, "0");
00165 
00166   if (t->hasStartDate()) {
00167     mItem->setText(3,t->dtStartDateStr());
00168     mItem->setSortKey(3,t->dtStart().toString(Qt::ISODate));
00169     if (t->doesFloat()) {
00170       mItem->setText(4,"---");
00171     } else {
00172       mItem->setText(4,t->dtStartTimeStr());
00173       mItem->setSortKey( 4, t->dtStart().time().toString(Qt::ISODate) );
00174     }
00175   } else {
00176     mItem->setText(3,"---");
00177     mItem->setText(4,"---");
00178   }
00179 
00180   if (t->hasDueDate()) {
00181     mItem->setText(5, IncidenceFormatter::dateToString( t->dtDue(), true ) );
00182     mItem->setSortKey( 5, t->dtDue().toString(Qt::ISODate) );
00183     if (t->doesFloat()) {
00184       mItem->setText(6,"---");
00185     } else {
00186       mItem->setText(6, IncidenceFormatter::timeToString( t->dtDue(), true ) );
00187       mItem->setSortKey( 6, t->dtDue().time().toString(Qt::ISODate) );
00188     }
00189   } else {
00190     mItem->setText(5,"---");
00191     mItem->setText(6,"---");
00192   }
00193   mItem->setText(7,t->categoriesStr());
00194 
00195 
00196   return true;
00197 }
00198 
00199 bool KOListView::ListItemVisitor::visit(Journal *t)
00200 {
00201   static const QPixmap jrnalPxmp = KOGlobals::self()->smallIcon( "journal" );
00202   mItem->setPixmap(0,jrnalPxmp);
00203   // Just use the first line
00204   mItem->setText( 0, t->description().section( "\n", 0, 0 ) );
00205   mItem->setText( 3, t->dtStartDateStr() );
00206   mItem->setSortKey( 3, t->dtStart().toString(Qt::ISODate) );
00207 
00208   return true;
00209 }
00210 
00211 KOListView::KOListView( Calendar *calendar, QWidget *parent,
00212                         const char *name)
00213   : KOEventView(calendar, parent, name)
00214 {
00215   mActiveItem = 0;
00216 
00217   mListView = new KListView(this);
00218   mListView->addColumn(i18n("Summary"));
00219   mListView->addColumn(i18n("Reminder")); // alarm set?
00220   mListView->addColumn(i18n("Recurs")); // recurs?
00221   mListView->addColumn(i18n("Start Date"));
00222   mListView->setColumnAlignment(3,AlignHCenter);
00223   mListView->addColumn(i18n("Start Time"));
00224   mListView->setColumnAlignment(4,AlignHCenter);
00225   mListView->addColumn(i18n("End Date"));
00226   mListView->setColumnAlignment(5,AlignHCenter);
00227   mListView->addColumn(i18n("End Time"));
00228   mListView->setColumnAlignment(6,AlignHCenter);
00229   mListView->addColumn(i18n("Categories"));
00230 
00231   QBoxLayout *layoutTop = new QVBoxLayout(this);
00232   layoutTop->addWidget(mListView);
00233 
00234   mPopupMenu = eventPopup();
00235 /*
00236   mPopupMenu->insertSeparator();
00237   mPopupMenu->insertItem(i18n("Show Dates"), this,
00238                       SLOT(showDates()));
00239   mPopupMenu->insertItem(i18n("Hide Dates"), this,
00240                       SLOT(hideDates()));
00241 */
00242 
00243   QObject::connect( mListView, SIGNAL( doubleClicked( QListViewItem * ) ),
00244                     SLOT( defaultItemAction( QListViewItem * ) ) );
00245   QObject::connect( mListView, SIGNAL( returnPressed( QListViewItem * ) ),
00246                     SLOT( defaultItemAction( QListViewItem * ) ) );
00247   QObject::connect( mListView, SIGNAL( rightButtonClicked ( QListViewItem *,
00248                                                             const QPoint &,
00249                                                             int ) ),
00250                     SLOT( popupMenu( QListViewItem *, const QPoint &, int ) ) );
00251   QObject::connect( mListView, SIGNAL( selectionChanged() ),
00252                     SLOT( processSelectionChange() ) );
00253 
00254 //  setMinimumSize(100,100);
00255   mListView->restoreLayout(KOGlobals::self()->config(),"KOListView Layout");
00256 
00257   new KOListViewToolTip( mListView->viewport(), calendar, mListView );
00258 
00259   mSelectedDates.append( QDate::currentDate() );
00260 }
00261 
00262 KOListView::~KOListView()
00263 {
00264   delete mPopupMenu;
00265 }
00266 
00267 int KOListView::maxDatesHint()
00268 {
00269   return 0;
00270 }
00271 
00272 int KOListView::currentDateCount()
00273 {
00274   return mSelectedDates.count();
00275 }
00276 
00277 Incidence::List KOListView::selectedIncidences()
00278 {
00279   Incidence::List eventList;
00280 
00281   QListViewItem *item = mListView->selectedItem();
00282   if (item) eventList.append(((KOListViewItem *)item)->data());
00283 
00284   return eventList;
00285 }
00286 
00287 DateList KOListView::selectedIncidenceDates()
00288 {
00289   return mSelectedDates;
00290 }
00291 
00292 void KOListView::showDates(bool show)
00293 {
00294   // Shouldn't we set it to a value greater 0? When showDates is called with
00295   // show == true at first, then the columnwidths are set to zero.
00296   static int oldColWidth1 = 0;
00297   static int oldColWidth3 = 0;
00298 
00299   if (!show) {
00300     oldColWidth1 = mListView->columnWidth(1);
00301     oldColWidth3 = mListView->columnWidth(3);
00302     mListView->setColumnWidth(1, 0);
00303     mListView->setColumnWidth(3, 0);
00304   } else {
00305     mListView->setColumnWidth(1, oldColWidth1);
00306     mListView->setColumnWidth(3, oldColWidth3);
00307   }
00308   mListView->repaint();
00309 }
00310 
00311 void KOListView::showDates()
00312 {
00313   showDates(true);
00314 }
00315 
00316 void KOListView::hideDates()
00317 {
00318   showDates(false);
00319 }
00320 
00321 void KOListView::updateView()
00322 {
00323   kdDebug(5850) << "KOListView::updateView() does nothing" << endl;
00324 }
00325 
00326 void KOListView::showDates(const QDate &start, const QDate &end)
00327 {
00328   clear();
00329 
00330   QDate date = start;
00331   while( date <= end ) {
00332     addIncidences( calendar()->incidences(date), date );
00333     mSelectedDates.append( date );
00334     date = date.addDays( 1 );
00335   }
00336 
00337   emit incidenceSelected( 0, QDate() );
00338 }
00339 
00340 void KOListView::addIncidences( const Incidence::List &incidenceList, const QDate &date )
00341 {
00342   Incidence::List::ConstIterator it;
00343   for( it = incidenceList.begin(); it != incidenceList.end(); ++it ) {
00344     addIncidence( *it, date );
00345   }
00346 }
00347 
00348 void KOListView::addIncidence(Incidence *incidence, const QDate &date)
00349 {
00350   if ( mUidDict.find( incidence->uid() ) ) return;
00351 
00352   mDateList[incidence->uid()] = date;
00353   mUidDict.insert( incidence->uid(), incidence );
00354 
00355   KOListViewItem *item = new KOListViewItem( incidence, mListView );
00356   ListItemVisitor v(item);
00357   if (incidence->accept(v)) return;
00358   else delete item;
00359 }
00360 
00361 void KOListView::showIncidences( const Incidence::List &incidenceList, const QDate &date )
00362 {
00363   clear();
00364 
00365   addIncidences( incidenceList, date );
00366 
00367   // After new creation of list view no events are selected.
00368   emit incidenceSelected( 0, date );
00369 }
00370 
00371 void KOListView::changeIncidenceDisplay(Incidence *incidence, int action)
00372 {
00373   KOListViewItem *item;
00374   QDate f = mSelectedDates.first();
00375   QDate l = mSelectedDates.last();
00376 
00377   QDate date;
00378   if ( incidence->type() == "Todo" )
00379     date = static_cast<Todo *>(incidence)->dtDue().date();
00380   else
00381     date = incidence->dtStart().date();
00382 
00383   switch(action) {
00384     case KOGlobals::INCIDENCEADDED: {
00385       if ( date >= f && date <= l )
00386         addIncidence( incidence, date );
00387       break;
00388     }
00389     case KOGlobals::INCIDENCEEDITED: {
00390       item = getItemForIncidence(incidence);
00391       if (item) {
00392         delete item;
00393         mUidDict.remove( incidence->uid() );
00394         mDateList.remove( incidence->uid() );
00395       }
00396       if ( date >= f && date <= l )
00397         addIncidence( incidence, date );
00398     }
00399     break;
00400     case KOGlobals::INCIDENCEDELETED: {
00401       item = getItemForIncidence(incidence);
00402       if (item)
00403         delete item;
00404       break;
00405     }
00406     default:
00407       kdDebug(5850) << "KOListView::changeIncidenceDisplay(): Illegal action " << action << endl;
00408   }
00409 }
00410 
00411 KOListViewItem *KOListView::getItemForIncidence(Incidence *incidence)
00412 {
00413   KOListViewItem *item = (KOListViewItem *)mListView->firstChild();
00414   while (item) {
00415 //    kdDebug(5850) << "Item " << item->text(0) << " found" << endl;
00416     if (item->data() == incidence) return item;
00417     item = (KOListViewItem *)item->nextSibling();
00418   }
00419   return 0;
00420 }
00421 
00422 void KOListView::defaultItemAction(QListViewItem *i)
00423 {
00424   KOListViewItem *item = static_cast<KOListViewItem *>( i );
00425   if ( item ) defaultAction( item->data() );
00426 }
00427 
00428 void KOListView::popupMenu(QListViewItem *item,const QPoint &,int)
00429 {
00430   mActiveItem = (KOListViewItem *)item;
00431   if (mActiveItem) {
00432     Incidence *incidence = mActiveItem->data();
00433     // FIXME: For recurring incidences we don't know the date of this
00434     // occurrence, there's no reference to it at all!
00435     mPopupMenu->showIncidencePopup( calendar(), incidence, QDate() );
00436   }
00437   else {
00438     showNewEventPopup();
00439   }
00440 }
00441 
00442 void KOListView::readSettings(KConfig *config)
00443 {
00444   mListView->restoreLayout(config,"KOListView Layout");
00445 }
00446 
00447 void KOListView::writeSettings(KConfig *config)
00448 {
00449   mListView->saveLayout(config,"KOListView Layout");
00450 }
00451 
00452 void KOListView::processSelectionChange()
00453 {
00454   kdDebug(5850) << "KOListView::processSelectionChange()" << endl;
00455 
00456   KOListViewItem *item =
00457     static_cast<KOListViewItem *>( mListView->selectedItem() );
00458 
00459   if ( !item ) {
00460     emit incidenceSelected( 0, QDate() );
00461   } else {
00462     Incidence *incidence = static_cast<Incidence *>( item->data() );
00463     emit incidenceSelected( incidence, mDateList[incidence->uid()] );
00464   }
00465 }
00466 
00467 void KOListView::clearSelection()
00468 {
00469   mListView->selectAll( false );
00470 }
00471 
00472 void KOListView::clear()
00473 {
00474   mSelectedDates.clear();
00475   mListView->clear();
00476   mUidDict.clear();
00477   mDateList.clear();
00478 }
KDE Home | KDE Accessibility Home | Description of Access Keys