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