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