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