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