00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <qlayout.h>
00026 #include <qheader.h>
00027 #include <qcursor.h>
00028 #include <qlabel.h>
00029 #include <qtimer.h>
00030
00031 #include <kdebug.h>
00032 #include <klocale.h>
00033 #include <kglobal.h>
00034 #include <kiconloader.h>
00035 #include <kmessagebox.h>
00036
00037 #include <libkcal/icaldrag.h>
00038 #include <libkcal/vcaldrag.h>
00039 #include <libkcal/dndfactory.h>
00040 #include <libkcal/calendarresources.h>
00041 #include <libkcal/resourcecalendar.h>
00042 #include <libkcal/calfilter.h>
00043
00044 #include <libkdepim/clicklineedit.h>
00045 #include <libkdepim/kdatepickerpopup.h>
00046
00047 #ifndef KORG_NOPRINTER
00048 #include "calprinter.h"
00049 #endif
00050 #include "docprefs.h"
00051
00052 #include "koincidencetooltip.h"
00053 #include "kodialogmanager.h"
00054 #include "kotodoview.h"
00055 #include "koprefs.h"
00056 #include "koglobals.h"
00057 using namespace KOrg;
00058 #include "kohelper.h"
00059 #include "kotodoviewitem.h"
00060 #include "kotodoview.moc"
00061
00062 const int KOTodoView::POPUP_UNSUBTODO=1234;
00063
00064 KOTodoListViewToolTip::KOTodoListViewToolTip (QWidget* parent,
00065 KOTodoListView* lv )
00066 :QToolTip(parent)
00067 {
00068 todolist=lv;
00069 }
00070
00071 void KOTodoListViewToolTip::maybeTip( const QPoint & pos)
00072 {
00073 QRect r;
00074 int headerPos;
00075 int col=todolist->header()->sectionAt(todolist->contentsX() + pos.x());
00076 KOTodoViewItem *i=(KOTodoViewItem *)todolist->itemAt(pos);
00077
00078
00079 if( i && KOPrefs::instance()->mEnableToolTips )
00080 {
00081
00082
00083 r=todolist->itemRect(i);
00084 headerPos = todolist->header()->sectionPos(col)-todolist->contentsX();
00085 r.setLeft( (headerPos < 0 ? 0 : headerPos) );
00086 r.setRight(headerPos + todolist->header()->sectionSize(col));
00087
00088
00089 QString tipText;
00090 ToolTipVisitor<KOTodoViewItem> v;
00091 if (v.act(i, &tipText, true)) {
00092 tip(r, tipText);
00093 }
00094 }
00095
00096 }
00097
00098
00099
00100 KOTodoListView::KOTodoListView( QWidget *parent, const char *name )
00101 : KListView( parent, name ), mCalendar( 0 )
00102 {
00103 mOldCurrent = 0;
00104 mMousePressed = false;
00105
00106
00107 tooltip = new KOTodoListViewToolTip( viewport(), this );
00108 }
00109
00110 KOTodoListView::~KOTodoListView()
00111 {
00112 delete tooltip;
00113 }
00114
00115 void KOTodoListView::setCalendar( Calendar *cal )
00116 {
00117 mCalendar = cal;
00118 setAcceptDrops( mCalendar );
00119 viewport()->setAcceptDrops( mCalendar );
00120 }
00121
00122 bool KOTodoListView::event(QEvent *e)
00123 {
00124 int tmp=0;
00125 KOTodoViewItem *i;
00126
00127
00128
00129 if(e->type()==QEvent::ApplicationPaletteChange)
00130 {
00131
00132 KListView::event(e);
00133 i=(KOTodoViewItem *)itemAtIndex(tmp);
00134
00135 while(i!=0)
00136 {
00137 i->construct();
00138 tmp++;
00139 i=(KOTodoViewItem *)itemAtIndex(tmp);
00140 }
00141
00142 }
00143
00144 return (KListView::event(e) || e->type()==QEvent::ApplicationPaletteChange);
00145 }
00146
00147 void KOTodoListView::contentsDragEnterEvent(QDragEnterEvent *e)
00148 {
00149 #ifndef KORG_NODND
00150
00151 if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) &&
00152 !QTextDrag::canDecode( e ) ) {
00153 e->ignore();
00154 return;
00155 }
00156
00157 mOldCurrent = currentItem();
00158 #endif
00159 }
00160
00161
00162 void KOTodoListView::contentsDragMoveEvent(QDragMoveEvent *e)
00163 {
00164 #ifndef KORG_NODND
00165
00166
00167 if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) &&
00168 !QTextDrag::canDecode( e ) ) {
00169 e->ignore();
00170 return;
00171 }
00172
00173 e->accept();
00174 #endif
00175 }
00176
00177 void KOTodoListView::contentsDragLeaveEvent( QDragLeaveEvent * )
00178 {
00179 #ifndef KORG_NODND
00180
00181
00182 setCurrentItem(mOldCurrent);
00183 setSelected(mOldCurrent,true);
00184 #endif
00185 }
00186
00187 void KOTodoListView::contentsDropEvent( QDropEvent *e )
00188 {
00189 #ifndef KORG_NODND
00190
00191
00192 if ( !mCalendar ||
00193 ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) &&
00194 !QTextDrag::canDecode( e ) ) ) {
00195 e->ignore();
00196 return;
00197 }
00198
00199 DndFactory factory( mCalendar );
00200 Todo *todo = factory.createDropTodo(e);
00201
00202 if (todo) {
00203 e->acceptAction();
00204
00205 KOTodoViewItem *destination =
00206 (KOTodoViewItem *)itemAt(contentsToViewport(e->pos()));
00207 Todo *destinationEvent = 0;
00208 if (destination) destinationEvent = destination->todo();
00209
00210 Todo *existingTodo = mCalendar->todo(todo->uid());
00211
00212 if(existingTodo) {
00213
00214 Incidence *to = destinationEvent;
00215 while(to) {
00216 if (to->uid() == todo->uid()) {
00217 KMessageBox::sorry(this,
00218 i18n("Cannot move To-Do to itself or a child of itself."),
00219 i18n("Drop To-Do"));
00220 delete todo;
00221 return;
00222 }
00223 to = to->relatedTo();
00224 }
00225 Todo*oldTodo = existingTodo->clone();
00226 existingTodo->setRelatedTo(destinationEvent);
00227
00228 emit incidenceChanged( oldTodo, existingTodo );
00229 delete oldTodo;
00230 delete todo;
00231 } else {
00232
00233 todo->setRelatedTo(destinationEvent);
00234 if ( !mCalendar->addTodo( todo ) ) {
00235 KODialogManager::errorSaveTodo( this );
00236 return;
00237 }
00238
00239 emit incidenceAdded( todo );
00240 }
00241 }
00242 else {
00243 QString text;
00244 KOTodoViewItem *todoi = dynamic_cast<KOTodoViewItem *>(itemAt( contentsToViewport(e->pos()) ));
00245 if ( ! todoi ) {
00246
00247 e->ignore();
00248 kdDebug( 5850 ) << "KOTodoListView::contentsDropEvent(): Not dropped on a todo item" << endl;
00249 kdDebug( 5850 ) << "TODO: Create a new todo with the given data" << endl;
00250
00251 } else if ( QTextDrag::decode(e, text) ) {
00252
00253 kdDebug(5850) << "Dropped : " << text << endl;
00254 QStringList emails = QStringList::split(",",text);
00255 Todo*newtodo = todoi->todo();
00256 Todo*oldtodo = newtodo->clone();
00257 for(QStringList::ConstIterator it = emails.begin();it!=emails.end();++it) {
00258 kdDebug(5850) << " Email: " << (*it) << endl;
00259 int pos = (*it).find("<");
00260 QString name = (*it).left(pos);
00261 QString email = (*it).mid(pos);
00262 if (!email.isEmpty() && todoi) {
00263 newtodo->addAttendee(new Attendee(name,email));
00264 }
00265 }
00266 emit incidenceChanged( oldtodo, newtodo );
00267 }
00268 else {
00269 kdDebug(5850) << "KOTodoListView::contentsDropEvent(): Todo from drop not decodable" << endl;
00270 e->ignore();
00271 }
00272 }
00273 #endif
00274 }
00275
00276 void KOTodoListView::contentsMousePressEvent(QMouseEvent* e)
00277 {
00278 QListView::contentsMousePressEvent(e);
00279 QPoint p(contentsToViewport(e->pos()));
00280 QListViewItem *i = itemAt(p);
00281 if (i) {
00282
00283
00284 if (p.x() > header()->sectionPos(header()->mapToIndex(0)) +
00285 treeStepSize() * (i->depth() + (rootIsDecorated() ? 1 : 0)) +
00286 itemMargin() ||
00287 p.x() < header()->sectionPos(header()->mapToIndex(0))) {
00288 if (e->button()==Qt::LeftButton) {
00289 mPressPos = e->pos();
00290 mMousePressed = true;
00291 }
00292 }
00293 }
00294 }
00295
00296 void KOTodoListView::contentsMouseMoveEvent(QMouseEvent* e)
00297 {
00298 #ifndef KORG_NODND
00299
00300 QListView::contentsMouseMoveEvent(e);
00301 if (mMousePressed && (mPressPos - e->pos()).manhattanLength() >
00302 QApplication::startDragDistance()) {
00303 mMousePressed = false;
00304 QListViewItem *item = itemAt(contentsToViewport(mPressPos));
00305 if ( item && mCalendar ) {
00306
00307 DndFactory factory( mCalendar );
00308 ICalDrag *vd = factory.createDrag(
00309 ((KOTodoViewItem *)item)->todo(),viewport());
00310 if (vd->drag()) {
00311 kdDebug(5850) << "KOTodoListView::contentsMouseMoveEvent(): Delete drag source" << endl;
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 }
00324 }
00325 #endif
00326 }
00327
00328 void KOTodoListView::contentsMouseReleaseEvent(QMouseEvent *e)
00329 {
00330 QListView::contentsMouseReleaseEvent(e);
00331 mMousePressed = false;
00332 }
00333
00334 void KOTodoListView::contentsMouseDoubleClickEvent(QMouseEvent *e)
00335 {
00336 if (!e) return;
00337
00338 QPoint vp = contentsToViewport(e->pos());
00339
00340 QListViewItem *item = itemAt(vp);
00341
00342 if (!item) return;
00343
00344 emit doubleClicked(item,vp,0);
00345 }
00346
00348
00349 KOTodoView::KOTodoView( Calendar *calendar, QWidget *parent, const char* name)
00350 : KOrg::BaseView( calendar, parent, name )
00351 {
00352 QBoxLayout *topLayout = new QVBoxLayout( this );
00353
00354 QLabel *title = new QLabel( i18n("To-do items:"), this );
00355 title->setFrameStyle( QFrame::Panel | QFrame::Raised );
00356 topLayout->addWidget( title );
00357
00358 mQuickAdd = new KPIM::ClickLineEdit( this, i18n( "Click to add a new Todo" ) );
00359 topLayout->addWidget( mQuickAdd );
00360
00361 if ( !KOPrefs::instance()->mEnableQuickTodo ) mQuickAdd->hide();
00362
00363 mTodoListView = new KOTodoListView( this );
00364 topLayout->addWidget( mTodoListView );
00365
00366 mTodoListView->setRootIsDecorated( true );
00367 mTodoListView->setAllColumnsShowFocus( true );
00368
00369 mTodoListView->setShowSortIndicator( true );
00370
00371 mTodoListView->addColumn( i18n("Summary") );
00372 mTodoListView->addColumn( i18n("Recurs") );
00373 mTodoListView->addColumn( i18n("Priority") );
00374 mTodoListView->setColumnAlignment( 2, AlignHCenter );
00375 mTodoListView->addColumn( i18n("Complete") );
00376 mTodoListView->setColumnAlignment( 3, AlignRight );
00377 mTodoListView->addColumn( i18n("Due Date/Time") );
00378 mTodoListView->setColumnAlignment( 4, AlignLeft );
00379 mTodoListView->addColumn( i18n("Categories") );
00380 #if 0
00381 mTodoListView->addColumn( i18n("Sort Id") );
00382 mTodoListView->setColumnAlignment( 4, AlignHCenter );
00383 #endif
00384
00385 mTodoListView->setMinimumHeight( 60 );
00386 mTodoListView->setItemsRenameable( true );
00387 mTodoListView->setRenameable( 0 );
00388
00389 mTodoListView->setColumnWidthMode( 0, QListView::Manual );
00390 mTodoListView->setColumnWidthMode( 1, QListView::Manual );
00391 mTodoListView->setColumnWidthMode( 2, QListView::Manual );
00392 mTodoListView->setColumnWidthMode( 3, QListView::Manual );
00393 mTodoListView->setColumnWidthMode( 4, QListView::Manual );
00394 mTodoListView->setColumnWidthMode( 5, QListView::Manual );
00395 #if 0
00396 mTodoListView->setColumnWidthMode( 6, QListView::Manual );
00397 #endif
00398
00399 mPriorityPopupMenu = new QPopupMenu( this );
00400 for ( int i = 1; i <= 5; i++ ) {
00401 QString label = QString ("%1").arg( i );
00402 mPriority[ mPriorityPopupMenu->insertItem( label ) ] = i;
00403 }
00404 connect( mPriorityPopupMenu, SIGNAL( activated( int ) ),
00405 SLOT( setNewPriority( int ) ));
00406
00407 mPercentageCompletedPopupMenu = new QPopupMenu(this);
00408 for (int i = 0; i <= 100; i+=10) {
00409 QString label = QString ("%1 %").arg (i);
00410 mPercentage[mPercentageCompletedPopupMenu->insertItem (label)] = i;
00411 }
00412 connect( mPercentageCompletedPopupMenu, SIGNAL( activated( int ) ),
00413 SLOT( setNewPercentage( int ) ) );
00414
00415 mMovePopupMenu = new KDatePickerPopup(
00416 KDatePickerPopup::NoDate |
00417 KDatePickerPopup::DatePicker |
00418 KDatePickerPopup::Words );
00419 mCopyPopupMenu = new KDatePickerPopup(
00420 KDatePickerPopup::NoDate |
00421 KDatePickerPopup::DatePicker |
00422 KDatePickerPopup::Words );
00423
00424
00425 connect( mMovePopupMenu, SIGNAL( dateChanged( QDate )),
00426 SLOT( setNewDate( QDate ) ) );
00427 connect( mCopyPopupMenu, SIGNAL( dateChanged( QDate )),
00428 SLOT( copyTodoToDate( QDate ) ) );
00429
00430 mItemPopupMenu = new QPopupMenu(this);
00431 mItemPopupMenu->insertItem(i18n("Show"), this,
00432 SLOT (showTodo()));
00433 mItemPopupMenu->insertItem(i18n("Edit..."), this,
00434 SLOT (editTodo()));
00435 mItemPopupMenu->insertItem(KOGlobals::self()->smallIconSet("editdelete"), i18n("Delete"), this,
00436 SLOT (deleteTodo()));
00437 mItemPopupMenu->insertSeparator();
00438 mItemPopupMenu->insertItem(KOGlobals::self()->smallIconSet("todo"), i18n("New To-Do..."), this,
00439 SLOT (newTodo()));
00440 mItemPopupMenu->insertItem(i18n("New Sub-To-Do..."), this,
00441 SLOT (newSubTodo()));
00442 mItemPopupMenu->insertItem( i18n("Make Sub-To-Do Independent"), this,
00443 SIGNAL( unSubTodoSignal() ), 0, POPUP_UNSUBTODO );
00444 mItemPopupMenu->insertSeparator();
00445 mItemPopupMenu->insertItem( i18n("Copy To"), mCopyPopupMenu );
00446 mItemPopupMenu->insertItem(i18n("Move To"), mMovePopupMenu);
00447 mItemPopupMenu->insertSeparator();
00448 mItemPopupMenu->insertItem(i18n("delete completed To-Dos","Purge Completed"),
00449 this, SLOT( purgeCompleted() ) );
00450
00451 connect( mMovePopupMenu, SIGNAL( dateChanged( QDate ) ),
00452 mItemPopupMenu, SLOT( hide() ) );
00453 connect( mCopyPopupMenu, SIGNAL( dateChanged( QDate ) ),
00454 mItemPopupMenu, SLOT( hide() ) );
00455
00456 mPopupMenu = new QPopupMenu(this);
00457 mPopupMenu->insertItem(KOGlobals::self()->smallIconSet("todo"), i18n("New To-Do..."), this,
00458 SLOT (newTodo()));
00459 mPopupMenu->insertItem(i18n("delete completed To-Dos","Purge Completed"),
00460 this, SLOT(purgeCompleted()));
00461
00462 mDocPrefs = new DocPrefs( name );
00463
00464
00465 connect( mTodoListView, SIGNAL( doubleClicked( QListViewItem *,
00466 const QPoint &, int ) ),
00467 SLOT( editItem( QListViewItem *, const QPoint &, int ) ) );
00468 connect( mTodoListView, SIGNAL( returnPressed( QListViewItem * ) ),
00469 SLOT( editItem( QListViewItem * ) ) );
00470 connect( mTodoListView, SIGNAL( contextMenuRequested( QListViewItem *,
00471 const QPoint &, int ) ),
00472 SLOT( popupMenu( QListViewItem *, const QPoint &, int ) ) );
00473 connect( mTodoListView, SIGNAL( expanded( QListViewItem * ) ),
00474 SLOT( itemStateChanged( QListViewItem * ) ) );
00475 connect( mTodoListView, SIGNAL( collapsed( QListViewItem * ) ),
00476 SLOT( itemStateChanged( QListViewItem * ) ) );
00477
00478 #if 0
00479 connect(mTodoListView,SIGNAL(selectionChanged(QListViewItem *)),
00480 SLOT(selectionChanged(QListViewItem *)));
00481 connect(mTodoListView,SIGNAL(clicked(QListViewItem *)),
00482 SLOT(selectionChanged(QListViewItem *)));
00483 connect(mTodoListView,SIGNAL(pressed(QListViewItem *)),
00484 SLOT(selectionChanged(QListViewItem *)));
00485 #endif
00486 connect( mTodoListView, SIGNAL(selectionChanged() ),
00487 SLOT( processSelectionChange() ) );
00488 connect( mQuickAdd, SIGNAL( returnPressed () ),
00489 SLOT( addQuickTodo() ) );
00490
00491 connect( mTodoListView, SIGNAL( incidenceAdded( Incidence* ) ),
00492 SIGNAL( incidenceAdded( Incidence* ) ) );
00493 connect( mTodoListView, SIGNAL( incidenceChanged( Incidence*, Incidence* ) ),
00494 SIGNAL( incidenceChanged( Incidence*, Incidence* ) ) );
00495 connect( mTodoListView, SIGNAL( incidenceToBeDeleted( Incidence* ) ),
00496 SIGNAL( incidenceToBeDeleted( Incidence* ) ) );
00497 connect( mTodoListView, SIGNAL( incidenceDeleted( Incidence* ) ),
00498 SIGNAL( incidenceDeleted( Incidence* ) ) );
00499 }
00500
00501 KOTodoView::~KOTodoView()
00502 {
00503 delete mDocPrefs;
00504 }
00505
00506 void KOTodoView::setCalendar( Calendar *cal )
00507 {
00508 BaseView::setCalendar( cal );
00509 mTodoListView->setCalendar( cal );
00510 }
00511
00512 void KOTodoView::updateView()
00513 {
00514
00515 int oldPos = mTodoListView->contentsY();
00516 mItemsToDelete.clear();
00517 mTodoListView->clear();
00518
00519 Todo::List todoList = calendar()->todos();
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542 mTodoMap.clear();
00543 Todo::List::ConstIterator it;
00544 for( it = todoList.begin(); it != todoList.end(); ++it ) {
00545 if ( !mTodoMap.contains( *it ) ) {
00546 insertTodoItem( *it );
00547 }
00548 }
00549
00550
00551 mTodoListView->blockSignals( true );
00552 if( mDocPrefs ) restoreItemState( mTodoListView->firstChild() );
00553 mTodoListView->blockSignals( false );
00554
00555 mTodoListView->setContentsPos( 0, oldPos );
00556
00557 processSelectionChange();
00558 }
00559
00560 void KOTodoView::restoreItemState( QListViewItem *item )
00561 {
00562 while( item ) {
00563 KOTodoViewItem *todoItem = (KOTodoViewItem *)item;
00564 todoItem->setOpen( mDocPrefs->readBoolEntry( todoItem->todo()->uid() ) );
00565 if( item->childCount() > 0 ) restoreItemState( item->firstChild() );
00566 item = item->nextSibling();
00567 }
00568 }
00569
00570
00571 QMap<Todo *,KOTodoViewItem *>::ConstIterator
00572 KOTodoView::insertTodoItem(Todo *todo)
00573 {
00574
00575 Incidence *incidence = todo->relatedTo();
00576 if (incidence && incidence->type() == "Todo") {
00577
00578 Todo *relatedTodo = dynamic_cast<Todo *>(incidence);
00579
00580
00581 QMap<Todo *,KOTodoViewItem *>::ConstIterator itemIterator;
00582 itemIterator = mTodoMap.find(relatedTodo);
00583 if (itemIterator == mTodoMap.end()) {
00584
00585 itemIterator = insertTodoItem (relatedTodo);
00586 }
00587
00588
00589 KOTodoViewItem *todoItem = new KOTodoViewItem(*itemIterator,todo,this);
00590 todoItem->setResourceColor( KOHelper::resourceColor( mTodoListView->calendar(), incidence ) );
00591 return mTodoMap.insert(todo,todoItem);
00592 } else {
00593
00594
00595 KOTodoViewItem *todoItem = new KOTodoViewItem(mTodoListView,todo,this);
00596 todoItem->setResourceColor( KOHelper::resourceColor( mTodoListView->calendar(), todo ) );
00597 return mTodoMap.insert(todo,todoItem);
00598 }
00599 }
00600
00601 void KOTodoView::removeTodoItems()
00602 {
00603 KOTodoViewItem *item;
00604 for ( item = mItemsToDelete.first(); item; item = mItemsToDelete.next() ) {
00605 Todo *todo = item->todo();
00606 if ( todo && mTodoMap.contains( todo ) ) {
00607 mTodoMap.remove( todo );
00608 }
00609 delete item;
00610 }
00611 mItemsToDelete.clear();
00612 }
00613
00614
00615 bool KOTodoView::scheduleRemoveTodoItem( KOTodoViewItem *todoItem )
00616 {
00617 if ( todoItem ) {
00618 mItemsToDelete.append( todoItem );
00619 QTimer::singleShot( 0, this, SLOT( removeTodoItems() ) );
00620 return true;
00621 } else
00622 return false;
00623 }
00624
00625 void KOTodoView::updateConfig()
00626 {
00627 mTodoListView->repaintContents();
00628 }
00629
00630 Incidence::List KOTodoView::selectedIncidences()
00631 {
00632 Incidence::List selected;
00633
00634 KOTodoViewItem *item = (KOTodoViewItem *)(mTodoListView->selectedItem());
00635
00636 if (item) selected.append(item->todo());
00637
00638 return selected;
00639 }
00640
00641 Todo::List KOTodoView::selectedTodos()
00642 {
00643 Todo::List selected;
00644
00645 KOTodoViewItem *item = (KOTodoViewItem *)(mTodoListView->selectedItem());
00646
00647 if (item) selected.append(item->todo());
00648
00649 return selected;
00650 }
00651
00652 void KOTodoView::changeIncidenceDisplay(Incidence *incidence, int action)
00653 {
00654
00655 if ( incidence->type() != "Todo" )
00656 return;
00657 bool isFiltered = !calendar()->filter()->filterIncidence( incidence );
00658 Todo *todo = static_cast<Todo *>(incidence);
00659 if ( todo ) {
00660 KOTodoViewItem *todoItem = 0;
00661 if ( mTodoMap.contains( todo ) ) {
00662 todoItem = mTodoMap[todo];
00663 }
00664 switch ( action ) {
00665 case KOGlobals::INCIDENCEADDED:
00666 case KOGlobals::INCIDENCEEDITED:
00667
00668 if ( todoItem ) {
00669 if ( isFiltered ) {
00670 scheduleRemoveTodoItem( todoItem );
00671 } else {
00672
00673 Todo*parent = dynamic_cast<Todo*>( todo->relatedTo() );
00674 KOTodoViewItem*parentItem = 0;
00675 if ( parent && mTodoMap.contains(parent) ) {
00676 parentItem = mTodoMap[ parent ];
00677 }
00678 if ( todoItem->parent() != parentItem ) {
00679
00680 if ( parentItem ) {
00681 parentItem->insertItem( todoItem );
00682 } else {
00683 mTodoListView->insertItem( todoItem );
00684 }
00685 }
00686 todoItem->construct();
00687 }
00688 } else {
00689 if ( !isFiltered ) {
00690 insertTodoItem( todo );
00691 }
00692 }
00693 break;
00694 case KOGlobals::INCIDENCEDELETED:
00695 if ( todoItem ) {
00696 scheduleRemoveTodoItem( todoItem );
00697 }
00698 break;
00699 default:
00700 QTimer::singleShot( 0, this, SLOT( updateView() ) );
00701 }
00702 } else {
00703
00704
00705
00706 QTimer::singleShot(0,this,SLOT(updateView()));
00707 }
00708 }
00709
00710 void KOTodoView::showDates(const QDate &, const QDate &)
00711 {
00712 }
00713
00714 void KOTodoView::showIncidences( const Incidence::List & )
00715 {
00716 kdDebug(5850) << "KOTodoView::showIncidences( const Incidence::List & ): not yet implemented" << endl;
00717 }
00718
00719 void KOTodoView::printPreview(CalPrinter *calPrinter, const QDate &fd,
00720 const QDate &td)
00721 {
00722 #ifndef KORG_NOPRINTER
00723 calPrinter->preview(CalPrinter::Todolist, fd, td);
00724 #endif
00725 }
00726
00727 CalPrinter::PrintType KOTodoView::printType()
00728 {
00729 return CalPrinter::Todolist;
00730 }
00731
00732 void KOTodoView::editItem( QListViewItem *item )
00733 {
00734 if (item)
00735 emit editIncidenceSignal( static_cast<KOTodoViewItem *>( item )->todo() );
00736 }
00737
00738 void KOTodoView::editItem( QListViewItem *item, const QPoint &, int )
00739 {
00740 editItem( item );
00741 }
00742
00743 void KOTodoView::showItem( QListViewItem *item )
00744 {
00745 if (item)
00746 emit showIncidenceSignal( static_cast<KOTodoViewItem *>( item )->todo() );
00747 }
00748
00749 void KOTodoView::showItem( QListViewItem *item, const QPoint &, int )
00750 {
00751 showItem( item );
00752 }
00753
00754 void KOTodoView::popupMenu( QListViewItem *item, const QPoint &, int column )
00755 {
00756 mActiveItem = static_cast<KOTodoViewItem *>( item );
00757 if ( mActiveItem && !mActiveItem->todo()->isReadOnly() ) {
00758 QDate date = mActiveItem->todo()->dtDue().date();
00759 if ( mActiveItem->todo()->hasDueDate () ) {
00760 mMovePopupMenu->datePicker()->setDate( date );
00761 } else {
00762 mMovePopupMenu->datePicker()->setDate( QDate::currentDate() );
00763 }
00764 switch ( column ) {
00765 case 2:
00766 mPriorityPopupMenu->popup( QCursor::pos() );
00767 break;
00768 case 3: {
00769 mPercentageCompletedPopupMenu->popup( QCursor::pos() );
00770 break;
00771 }
00772 case 4:
00773 mMovePopupMenu->popup( QCursor::pos() );
00774 break;
00775 case 5:
00776 getCategoryPopupMenu( mActiveItem )->popup( QCursor::pos() );
00777 break;
00778 default:
00779 mCopyPopupMenu->datePicker()->setDate( date );
00780 mCopyPopupMenu->datePicker()->setDate( QDate::currentDate() );
00781 mItemPopupMenu->setItemEnabled( POPUP_UNSUBTODO,
00782 mActiveItem->todo()->relatedTo() );
00783 mItemPopupMenu->popup( QCursor::pos() );
00784 }
00785 } else mPopupMenu->popup( QCursor::pos() );
00786 }
00787
00788 void KOTodoView::newTodo()
00789 {
00790 emit newTodoSignal( QDate::currentDate().addDays(7) );
00791 }
00792
00793 void KOTodoView::newSubTodo()
00794 {
00795 if (mActiveItem) {
00796 emit newSubTodoSignal(mActiveItem->todo());
00797 }
00798 }
00799
00800 void KOTodoView::editTodo()
00801 {
00802 editItem( mActiveItem );
00803 }
00804
00805 void KOTodoView::showTodo()
00806 {
00807 showItem( mActiveItem );
00808 }
00809
00810 void KOTodoView::deleteTodo()
00811 {
00812 if (mActiveItem) {
00813 if (mActiveItem->childCount()) {
00814 KMessageBox::sorry(this,i18n("Cannot delete To-Do which has children."),
00815 i18n("Delete To-Do"));
00816 } else {
00817 emit deleteIncidenceSignal(mActiveItem->todo());
00818 }
00819 }
00820 }
00821
00822 void KOTodoView::setNewPriority(int index)
00823 {
00824 if (mActiveItem && !mActiveItem->todo()->isReadOnly ()) {
00825 Todo *todo = mActiveItem->todo();
00826 Todo *oldTodo = todo->clone();
00827 todo->setPriority(mPriority[index]);
00828 mActiveItem->construct();
00829 emit incidenceChanged( oldTodo, todo, KOGlobals::PRIORITY_MODIFIED );
00830 delete oldTodo;
00831 }
00832 }
00833
00834 void KOTodoView::setNewPercentage(int index)
00835 {
00836 if ( mActiveItem && !mActiveItem->todo()->isReadOnly () ) {
00837 Todo *todo = mActiveItem->todo();
00838 Todo *oldTodo = todo->clone();
00839
00840 if (mPercentage[index] == 100) {
00841 emit todoCompleted( todo );
00842 } else {
00843 todo->setCompleted(false);
00844 }
00845 todo->setPercentComplete(mPercentage[index]);
00846 mActiveItem->construct();
00847 emit incidenceChanged( oldTodo, todo, KOGlobals::COMPLETION_MODIFIED );
00848 delete oldTodo;
00849 }
00850 }
00851
00852 void KOTodoView::setNewDate(QDate date)
00853 {
00854 if ( mActiveItem && !mActiveItem->todo()->isReadOnly()) {
00855 Todo *todo = mActiveItem->todo();
00856
00857 QDateTime dt;
00858 dt.setDate( date );
00859
00860 if ( !todo->doesFloat() )
00861 dt.setTime( todo->dtDue().time() );
00862
00863 Todo *oldTodo = todo->clone();
00864
00865 if ( date.isNull() )
00866 todo->setHasDueDate( false );
00867 else if ( !todo->hasDueDate() )
00868 todo->setHasDueDate( true );
00869 todo->setDtDue( dt );
00870 todo->setRevision( todo->revision() + 1 );
00871
00872 mActiveItem->construct();
00873 emit incidenceChanged( oldTodo, todo, KOGlobals::DATE_MODIFIED );
00874 delete oldTodo;
00875 }
00876 }
00877
00878 void KOTodoView::copyTodoToDate( QDate date )
00879 {
00880 QDateTime dt;
00881 dt.setDate( date );
00882
00883 if ( mActiveItem ) {
00884 Todo *newTodo = mActiveItem->todo()->clone();
00885 newTodo->recreate();
00886
00887 if ( date.isNull() )
00888 newTodo->setHasDueDate( false );
00889 newTodo->setDtDue( dt );
00890 newTodo->setPercentComplete( 0 );
00891
00892
00893 if ( newTodo->doesRecur() )
00894 newTodo->recurrence()->unsetRecurs();
00895
00896 calendar()->addTodo( newTodo );
00897 emit incidenceAdded( newTodo );
00898 }
00899 }
00900
00901 QPopupMenu *KOTodoView::getCategoryPopupMenu( KOTodoViewItem *todoItem )
00902 {
00903 QPopupMenu *tempMenu = new QPopupMenu( this );
00904 QStringList checkedCategories = todoItem->todo()->categories();
00905
00906 tempMenu->setCheckable( true );
00907 QStringList::Iterator it;
00908 for ( it = KOPrefs::instance()->mCustomCategories.begin();
00909 it != KOPrefs::instance()->mCustomCategories.end();
00910 ++it ) {
00911 int index = tempMenu->insertItem( *it );
00912 mCategory[ index ] = *it;
00913 if ( checkedCategories.find( *it ) != checkedCategories.end() )
00914 tempMenu->setItemChecked( index, true );
00915 }
00916
00917 connect ( tempMenu, SIGNAL( activated( int ) ),
00918 SLOT( changedCategories( int ) ) );
00919 return tempMenu;
00920 }
00921
00922 void KOTodoView::changedCategories(int index)
00923 {
00924 if (mActiveItem && !mActiveItem->todo()->isReadOnly ()) {
00925 Todo*todo = mActiveItem->todo();
00926 Todo*oldTodo = todo->clone();
00927 QStringList categories = todo->categories ();
00928 if (categories.find (mCategory[index]) != categories.end ())
00929 categories.remove (mCategory[index]);
00930 else
00931 categories.insert (categories.end(), mCategory[index]);
00932 categories.sort ();
00933 todo->setCategories (categories);
00934 mActiveItem->construct();
00935 emit incidenceChanged( oldTodo, todo, KOGlobals::CATEGORY_MODIFIED);
00936 delete oldTodo;
00937 }
00938 }
00939
00940 void KOTodoView::setDocumentId( const QString &id )
00941 {
00942 kdDebug(5850) << "KOTodoView::setDocumentId()" << endl;
00943
00944 mDocPrefs->setDoc( id );
00945 }
00946
00947 void KOTodoView::itemStateChanged( QListViewItem *item )
00948 {
00949 if (!item) return;
00950
00951 KOTodoViewItem *todoItem = (KOTodoViewItem *)item;
00952
00953
00954
00955 if( mDocPrefs ) mDocPrefs->writeEntry( todoItem->todo()->uid(), todoItem->isOpen() );
00956 }
00957
00958 void KOTodoView::saveLayout(KConfig *config, const QString &group) const
00959 {
00960 mTodoListView->saveLayout(config,group);
00961 }
00962
00963 void KOTodoView::restoreLayout(KConfig *config, const QString &group)
00964 {
00965 mTodoListView->restoreLayout(config,group);
00966 }
00967
00968 void KOTodoView::processSelectionChange()
00969 {
00970
00971
00972 KOTodoViewItem *item =
00973 static_cast<KOTodoViewItem *>( mTodoListView->selectedItem() );
00974
00975 if ( !item ) {
00976 emit incidenceSelected( 0 );
00977 } else {
00978 emit incidenceSelected( item->todo() );
00979 }
00980 }
00981
00982 void KOTodoView::clearSelection()
00983 {
00984 mTodoListView->selectAll( false );
00985 }
00986
00987 void KOTodoView::purgeCompleted()
00988 {
00989 emit purgeCompletedSignal();
00990 }
00991
00992 void KOTodoView::addQuickTodo()
00993 {
00994 if ( ! mQuickAdd->text().stripWhiteSpace().isEmpty() ) {
00995 Todo *todo = new Todo();
00996 todo->setSummary( mQuickAdd->text() );
00997 todo->setOrganizer( Person( KOPrefs::instance()->fullName(),
00998 KOPrefs::instance()->email() ) );
00999 if ( !calendar()->addTodo( todo ) ) {
01000 KODialogManager::errorSaveTodo( this );
01001 return;
01002 }
01003 mQuickAdd->setText( QString::null );
01004 emit incidenceAdded( todo );
01005 updateView();
01006 }
01007 }
01008
01009 void KOTodoView::emitCompletedSignal( Todo *todo )
01010 {
01011 emit todoCompleted( todo );
01012 }