summaryrefslogtreecommitdiffabout
path: root/korganizer/kotodoview.cpp
Unidiff
Diffstat (limited to 'korganizer/kotodoview.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--korganizer/kotodoview.cpp1028
1 files changed, 1028 insertions, 0 deletions
diff --git a/korganizer/kotodoview.cpp b/korganizer/kotodoview.cpp
new file mode 100644
index 0000000..0708a69
--- a/dev/null
+++ b/korganizer/kotodoview.cpp
@@ -0,0 +1,1028 @@
1/*
2 This file is part of KOrganizer.
3 Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 As a special exception, permission is given to link this program
20 with any edition of Qt, and distribute the resulting executable,
21 without including the source code for Qt in the source distribution.
22*/
23
24#include <qlayout.h>
25#include <qheader.h>
26#include <qcursor.h>
27
28#include <qvbox.h>
29#include <kdebug.h>
30#include "koprefs.h"
31#include <klocale.h>
32#include <kglobal.h>
33#include <kiconloader.h>
34#include <kmessagebox.h>
35
36#include <libkcal/icaldrag.h>
37#include <libkcal/vcaldrag.h>
38#include <libkcal/calfilter.h>
39#include <libkcal/dndfactory.h>
40#include <libkcal/calendarresources.h>
41#include <libkcal/resourcecalendar.h>
42#include <kresources/resourceselectdialog.h>
43#ifndef DESKTOP_VERSION
44#include <qpe/qpeapplication.h>
45#else
46#include <qapplication.h>
47#endif
48#ifndef KORG_NOPRINTER
49#include "calprinter.h"
50#endif
51#include "docprefs.h"
52
53#include "kotodoview.h"
54using namespace KOrg;
55#include "kotodoview.moc"
56
57KOTodoListView::KOTodoListView(Calendar *calendar,QWidget *parent,
58 const char *name) :
59 KListView(parent,name)
60{
61 mCalendar = calendar;
62#ifndef DESKTOP_VERSION
63 QPEApplication::setStylusOperation(viewport(), QPEApplication::RightOnHold );
64#endif
65 mOldCurrent = 0;
66 mMousePressed = false;
67
68 setAcceptDrops(true);
69 viewport()->setAcceptDrops(true);
70 int size = 16;
71 if (qApp->desktop()->width() < 300 )
72 size = 12;
73 setTreeStepSize( size + 6 );
74
75}
76
77void KOTodoListView::contentsDragEnterEvent(QDragEnterEvent *e)
78{
79#ifndef KORG_NODND
80// kdDebug() << "KOTodoListView::contentsDragEnterEvent" << endl;
81 if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) &&
82 !QTextDrag::canDecode( e ) ) {
83 e->ignore();
84 return;
85 }
86
87 mOldCurrent = currentItem();
88#endif
89}
90
91
92void KOTodoListView::contentsDragMoveEvent(QDragMoveEvent *e)
93{
94#ifndef KORG_NODND
95// kdDebug() << "KOTodoListView::contentsDragMoveEvent" << endl;
96
97 if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) &&
98 !QTextDrag::canDecode( e ) ) {
99 e->ignore();
100 return;
101 }
102
103 e->accept();
104#endif
105}
106
107void KOTodoListView::contentsDragLeaveEvent(QDragLeaveEvent *)
108{
109#ifndef KORG_NODND
110// kdDebug() << "KOTodoListView::contentsDragLeaveEvent" << endl;
111
112 setCurrentItem(mOldCurrent);
113 setSelected(mOldCurrent,true);
114#endif
115}
116
117void KOTodoListView::contentsDropEvent(QDropEvent *e)
118{
119#ifndef KORG_NODND
120// kdDebug() << "KOTodoListView::contentsDropEvent" << endl;
121
122 if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) &&
123 !QTextDrag::canDecode( e ) ) {
124 e->ignore();
125 return;
126 }
127
128 DndFactory factory( mCalendar );
129 Todo *todo = factory.createDropTodo(e);
130
131 if (todo) {
132 e->acceptAction();
133
134 KOTodoViewItem *destination =
135 (KOTodoViewItem *)itemAt(contentsToViewport(e->pos()));
136 Todo *destinationEvent = 0;
137 if (destination) destinationEvent = destination->todo();
138
139 Todo *existingTodo = mCalendar->todo(todo->uid());
140
141 if(existingTodo) {
142// kdDebug() << "Drop existing Todo" << endl;
143 Incidence *to = destinationEvent;
144 while(to) {
145 if (to->uid() == todo->uid()) {
146 KMessageBox::sorry(this,
147 i18n("Cannot move To-Do to itself or a child of itself"),
148 i18n("Drop To-Do"));
149 delete todo;
150 return;
151 }
152 to = to->relatedTo();
153 }
154 existingTodo->setRelatedTo(destinationEvent);
155 emit todoDropped(todo);
156 delete todo;
157 } else {
158// kdDebug() << "Drop new Todo" << endl;
159 todo->setRelatedTo(destinationEvent);
160 mCalendar->addTodo(todo);
161
162 emit todoDropped(todo);
163 }
164 }
165 else {
166 QString text;
167 if (QTextDrag::decode(e,text)) {
168 //QListViewItem *qlvi = itemAt( contentsToViewport(e->pos()) );
169 KOTodoViewItem *todoi = static_cast<KOTodoViewItem *>(itemAt( contentsToViewport(e->pos()) ));
170 kdDebug() << "Dropped : " << text << endl;
171 QStringList emails = QStringList::split(",",text);
172 for(QStringList::ConstIterator it = emails.begin();it!=emails.end();++it) {
173 kdDebug() << " Email: " << (*it) << endl;
174 int pos = (*it).find("<");
175 QString name = (*it).left(pos);
176 QString email = (*it).mid(pos);
177 if (!email.isEmpty() && todoi) {
178 todoi->todo()->addAttendee(new Attendee(name,email));
179 }
180 }
181 }
182 else {
183 kdDebug() << "KOTodoListView::contentsDropEvent(): Todo from drop not decodable" << endl;
184 e->ignore();
185 }
186 }
187#endif
188}
189
190void KOTodoListView::contentsMousePressEvent(QMouseEvent* e)
191{
192 QListView::contentsMousePressEvent(e);
193#ifndef KORG_NODND
194 QPoint p(contentsToViewport(e->pos()));
195 QListViewItem *i = itemAt(p);
196 if (i) {
197 // if the user clicked into the root decoration of the item, don't
198 // try to start a drag!
199 if (p.x() > header()->sectionPos(header()->mapToIndex(0)) +
200 treeStepSize() * (i->depth() + (rootIsDecorated() ? 1 : 0)) +
201 itemMargin() ||
202 p.x() < header()->sectionPos(header()->mapToIndex(0))) {
203 if (e->button()==Qt::LeftButton) {
204 mPressPos = e->pos();
205 mMousePressed = true;
206 }
207 }
208 }
209#endif
210}
211
212void KOTodoListView::contentsMouseMoveEvent(QMouseEvent* e)
213{
214#ifndef KORG_NODND
215// kdDebug() << "KOTodoListView::contentsMouseMoveEvent()" << endl;
216 QListView::contentsMouseMoveEvent(e);
217 if (mMousePressed && (mPressPos - e->pos()).manhattanLength() >
218 QApplication::startDragDistance()) {
219 mMousePressed = false;
220 QListViewItem *item = itemAt(contentsToViewport(mPressPos));
221 if (item) {
222// kdDebug() << "Start Drag for item " << item->text(0) << endl;
223 DndFactory factory( mCalendar );
224 ICalDrag *vd = factory.createDragTodo(
225 ((KOTodoViewItem *)item)->todo(),viewport());
226 if (vd->drag()) {
227 kdDebug() << "KOTodoListView::contentsMouseMoveEvent(): Delete drag source" << endl;
228 }
229/*
230 QString source = fullPath(item);
231 if ( QFile::exists(source) ) {
232 QUriDrag* ud = new QUriDrag(viewport());
233 ud->setFilenames( source );
234 if ( ud->drag() )
235 QMessageBox::information( this, "Drag source",
236 QString("Delete ")+source, "Not implemented" );
237*/
238 }
239 }
240#endif
241}
242void KOTodoListView::keyPressEvent ( QKeyEvent * e )
243{
244
245 QListViewItem* cn;
246 if ( e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter ) {
247 cn = currentItem();
248 if ( cn ) {
249 KOTodoViewItem* ci = (KOTodoViewItem*)( cn );
250 if ( ci ){
251 if ( e->state() == ShiftButton )
252 ci->setOn( false );
253 else
254 ci->setOn( true );
255 cn = cn->nextSibling();
256 if ( cn ) {
257 setCurrentItem ( cn );
258 ensureItemVisible ( cn );
259 }
260
261 }
262 }
263
264 return;
265 }
266
267 // qDebug("KOTodoListView::keyPressEvent ");
268 if ( e->state() == Qt::ControlButton || e->state() == Qt::ShiftButton || ( height() > 150 && width() > 200 ) ) {
269 switch ( e->key() ) {
270 case Qt::Key_Down:
271 case Qt::Key_Up:
272 QListView::keyPressEvent ( e );
273 break;
274 default:
275 e->ignore();
276 break;
277 }
278 return;
279 }
280 e->ignore();
281}
282void KOTodoListView::contentsMouseReleaseEvent(QMouseEvent *e)
283{
284 QListView::contentsMouseReleaseEvent(e);
285 mMousePressed = false;
286}
287
288void KOTodoListView::contentsMouseDoubleClickEvent(QMouseEvent *e)
289{
290 if (!e) return;
291
292 QPoint vp = contentsToViewport(e->pos());
293
294 QListViewItem *item = itemAt(vp);
295
296 emit double_Clicked(item);
297 if (!item) return;
298
299 emit doubleClicked(item,vp,0);
300}
301
302/////////////////////////////////////////////////////////////////////////////
303
304KOQuickTodo::KOQuickTodo(QWidget *parent) :
305 QLineEdit(parent)
306{
307 setText(i18n("Click to add a new Todo"));
308}
309
310void KOQuickTodo::focusInEvent(QFocusEvent *ev)
311{
312 if ( text()==i18n("Click to add a new Todo") )
313 setText("");
314 QLineEdit::focusInEvent(ev);
315}
316
317void KOQuickTodo::focusOutEvent(QFocusEvent *ev)
318{
319 setText(i18n("Click to add a new Todo"));
320 QLineEdit::focusOutEvent(ev);
321}
322
323/////////////////////////////////////////////////////////////////////////////
324
325KOTodoView::KOTodoView(Calendar *calendar,QWidget* parent,const char* name) :
326 KOrg::BaseView(calendar,parent,name)
327{
328 QBoxLayout *topLayout = new QVBoxLayout(this);
329 mName = QString ( name );
330 mBlockUpdate = false;
331 mQuickAdd = new KOQuickTodo(this);
332 topLayout->addWidget(mQuickAdd);
333
334 if ( !KOPrefs::instance()->mEnableQuickTodo ) mQuickAdd->hide();
335
336 mTodoListView = new KOTodoListView(calendar,this);
337 topLayout->addWidget(mTodoListView);
338 //mTodoListView->header()->setMaximumHeight(30);
339 mTodoListView->setRootIsDecorated(true);
340 mTodoListView->setAllColumnsShowFocus(true);
341
342 mTodoListView->setShowSortIndicator(true);
343
344 mTodoListView->addColumn(i18n("Todo"));
345 mTodoListView->addColumn(i18n("Prio"));
346 mTodoListView->setColumnAlignment(1,AlignHCenter);
347 mTodoListView->addColumn(i18n("Complete"));
348 mTodoListView->setColumnAlignment(2,AlignHCenter);
349 mTodoListView->addColumn(i18n("Due Date"));
350 mTodoListView->setColumnAlignment(3,AlignLeft);
351 mTodoListView->addColumn(i18n("Due Time"));
352 mTodoListView->setColumnAlignment(4,AlignHCenter);
353 mTodoListView->addColumn(i18n("Cancelled"));
354 mTodoListView->addColumn(i18n("Categories"));
355#if 0
356 mTodoListView->addColumn(i18n("Sort Id"));
357 mTodoListView->setColumnAlignment(4,AlignHCenter);
358#endif
359
360 mTodoListView->setMinimumHeight( 60 );
361 mTodoListView->setItemsRenameable( true );
362 mTodoListView->setRenameable( 0 );
363 mTodoListView->setColumnWidth( 0, 120 );
364 mTodoListView->setColumnWidthMode(0, QListView::Manual);
365 mTodoListView->setColumnWidthMode(1, QListView::Manual);
366 mTodoListView->setColumnWidthMode(2, QListView::Manual);
367 mTodoListView->setColumnWidthMode(3, QListView::Manual);
368 mTodoListView->setColumnWidthMode(4, QListView::Manual);
369 mTodoListView->setColumnWidthMode(5, QListView::Manual);
370 mTodoListView->setColumnAlignment( 2, AlignCenter );
371#if 0
372 mTodoListView->setColumnWidthMode(6, QListView::Manual);
373#endif
374
375 mPriorityPopupMenu = new QPopupMenu(this);
376 for (int i = 1; i <= 5; i++) {
377 QString label = QString ("%1").arg (i);
378 mPriority[mPriorityPopupMenu->insertItem (label)] = i;
379 }
380 connect (mPriorityPopupMenu, SIGNAL(activated (int)), SLOT (setNewPriority(int)));
381
382 mPercentageCompletedPopupMenu = new QPopupMenu(this);
383 for (int i = 0; i <= 100; i+=20) {
384 QString label = QString ("%1 %").arg (i);
385 mPercentage[mPercentageCompletedPopupMenu->insertItem (label)] = i;
386 }
387 connect (mPercentageCompletedPopupMenu, SIGNAL (activated (int)), SLOT (setNewPercentage (int)));
388
389
390
391 mItemPopupMenu = new QPopupMenu(this);
392 mItemPopupMenu->insertItem(i18n("Show..."), this,
393 SLOT (showTodo()));
394 mItemPopupMenu->insertItem(i18n("Edit..."), this,
395 SLOT (editTodo()));
396 mItemPopupMenu->insertItem( i18n("Delete"), this,
397 SLOT (deleteTodo()));
398 mItemPopupMenu->insertItem( i18n("Clone..."), this,
399 SLOT (cloneTodo()));
400 mItemPopupMenu->insertItem( i18n("Move..."), this,
401 SLOT (moveTodo()));
402 mItemPopupMenu->insertItem( i18n("Beam..."), this,
403 SLOT (beamTodo()));
404 mItemPopupMenu->insertItem( i18n("Toggle Cancel"), this,
405 SLOT (cancelTodo()));
406 mItemPopupMenu->insertSeparator();
407
408 mItemPopupMenu->insertItem( i18n("New Todo..."), this,
409 SLOT (newTodo()));
410 mItemPopupMenu->insertItem(i18n("New Sub-Todo..."), this,
411 SLOT (newSubTodo()));
412 mItemPopupMenu->insertItem(i18n("Unparent Todo"), this,
413 SLOT (unparentTodo()));
414 mItemPopupMenu->insertSeparator();
415 mItemPopupMenu->insertItem(i18n("Delete completed To-Dos","Purge Completed"),
416 this, SLOT( purgeCompleted() ) );
417 mItemPopupMenu->insertItem(i18n("toggle completed To-Dos","Show Completed"),
418 this, SLOT( toggleCompleted() ),0, 33 );
419 mItemPopupMenu->insertItem(i18n("toggle quick todo","Show Quick Todo"),
420 this, SLOT( toggleQuickTodo() ),0, 34 );
421
422 mPopupMenu = new QPopupMenu(this);
423 mPopupMenu->insertItem(SmallIconSet("todo"), i18n("New Todo..."), this,
424 SLOT (newTodo()),0,1);
425 mPopupMenu->insertItem(i18n("delete completed To-Dos","Purge Completed"),
426 this, SLOT(purgeCompleted()),0,2);
427 mPopupMenu->insertItem(i18n("Show Completed"),
428 this, SLOT( toggleCompleted() ),0,3 );
429 mPopupMenu->insertItem(i18n("toggle quick todo","Show Quick Todo"),
430 this, SLOT( toggleQuickTodo() ),0,4 );
431 mDocPrefs = new DocPrefs( name );
432
433 mPopupMenu->setCheckable( true );
434 mItemPopupMenu->setCheckable( true );
435 // Double clicking conflicts with opening/closing the subtree
436 connect( mTodoListView, SIGNAL( doubleClicked( QListViewItem *) ),
437 SLOT( editItem( QListViewItem *) ) );
438 connect( mTodoListView, SIGNAL( rightButtonClicked ( QListViewItem *,
439 const QPoint &,int ) ),
440 SLOT( popupMenu( QListViewItem *, const QPoint & ,int) ) );
441 connect( mTodoListView, SIGNAL( clicked( QListViewItem * ) ),
442 SLOT( itemClicked( QListViewItem * ) ) );
443 connect( mTodoListView, SIGNAL( double_Clicked( QListViewItem * ) ),
444 SLOT( itemDoubleClicked( QListViewItem * ) ) );
445 connect( mTodoListView, SIGNAL( todoDropped( Todo * ) ),
446 SLOT( updateView() ) );
447 connect( mTodoListView, SIGNAL( expanded( QListViewItem * ) ),
448 SLOT( itemStateChanged( QListViewItem * ) ) );
449 connect( mTodoListView, SIGNAL( collapsed( QListViewItem * ) ),
450 SLOT( itemStateChanged( QListViewItem * ) ) );
451
452#if 0
453 connect(mTodoListView,SIGNAL(selectionChanged(QListViewItem *)),
454 SLOT(selectionChanged(QListViewItem *)));
455 connect(mTodoListView,SIGNAL(clicked(QListViewItem *)),
456 SLOT(selectionChanged(QListViewItem *)));
457 connect(mTodoListView,SIGNAL(pressed(QListViewItem *)),
458 SLOT(selectionChanged(QListViewItem *)));
459#endif
460 connect( mTodoListView, SIGNAL(selectionChanged() ),
461 SLOT( processSelectionChange() ) );
462 connect( mQuickAdd, SIGNAL( returnPressed () ),
463 SLOT( addQuickTodo() ) );
464// if ( QApplication::desktop()->width() < 480 ) {
465// setNarrow();
466 // mTodoListView->setColumnWidth( 0, 100 );
467
468 // }
469
470}
471
472KOTodoView::~KOTodoView()
473{
474 delete mDocPrefs;
475}
476
477void KOTodoView::jumpToDate ()
478{
479 // if (mActiveItem) {
480// mActiveItem->todo());
481// if ( mActiveItem->todo()->hasDueDate() )
482// emit mActiveItem->todo()jumpToTime( mTodo->dtDue().date() );
483}
484
485void KOTodoView::setNarrow()
486{
487 //mTodoListView->setColumnWidth( 0, 120 );
488 mTodoListView->setColumnWidth( 1, 35 );
489 mTodoListView->setColumnWidth( 2, 40 );
490 mTodoListView->setColumnWidth( 3, 80 );
491 mTodoListView->setColumnWidth( 4, 40 );
492 mTodoListView->setColumnWidth( 5, 90 );
493
494}
495void KOTodoView::updateView()
496{
497// kdDebug() << "KOTodoView::updateView()" << endl;
498 QFont fo = KOPrefs::instance()->mTodoViewFont;
499 mTodoListView->clear();
500 if ( mName == "todolistsmall" ) {
501 if ( KOPrefs::instance()->mTodoViewUsesSmallFont ) {
502 int ps = fo.pointSize() -2;
503 if ( ps > 12 )
504 ps -= 2;
505 fo.setPointSize( ps );
506 }
507 }
508
509 mTodoListView->setFont( fo );
510 // QFontMetrics fm ( KOPrefs::instance()->mTodoViewFont );
511 //mTodoListView->header()->setMaximumHeight(fm.height());
512 QPtrList<Todo> todoList = calendar()->todos();
513
514/*
515 kdDebug() << "KOTodoView::updateView(): Todo List:" << endl;
516 Event *t;
517 for(t = todoList.first(); t; t = todoList.next()) {
518 kdDebug() << " " << t->getSummary() << endl;
519
520 if (t->getRelatedTo()) {
521 kdDebug() << " (related to " << t->getRelatedTo()->getSummary() << ")" << endl;
522 }
523
524 QPtrList<Event> l = t->getRelations();
525 Event *c;
526 for(c=l.first();c;c=l.next()) {
527 kdDebug() << " - relation: " << c->getSummary() << endl;
528 }
529 }
530*/
531
532 // Put for each Event a KOTodoViewItem in the list view. Don't rely on a
533 // specific order of events. That means that we have to generate parent items
534 // recursively for proper hierarchical display of Todos.
535 mTodoMap.clear();
536 Todo *todo;
537 todo = todoList.first();// todo; todo = todoList.next()) {
538 while ( todo ) {
539 bool next = true;
540 // qDebug("todo %s ", todo->summary().latin1());
541 Incidence *incidence = todo->relatedTo();
542 while ( incidence ) {
543 if ( incidence->type() == "Todo") {
544 //qDebug("related %s ",incidence->summary().latin1() );
545 if ( !(todoList.contains ( ((Todo* )incidence ) ) )) {
546 //qDebug("related not found ");
547 todoList.remove( );
548 todo = todoList.current();
549 next = false;
550 incidence = 0;
551
552 } else {
553 //qDebug("related found ");
554 incidence = incidence->relatedTo();
555 }
556 } else
557 incidence = 0;
558 }
559 if ( next )
560 todo = todoList.next();
561 }
562// qDebug("again .... ");
563// for(todo = todoList.first(); todo; todo = todoList.next()) {
564
565// qDebug("yytodo %s ", todo->summary().latin1());
566// }
567 //qDebug("for ");
568 for(todo = todoList.first(); todo; todo = todoList.next()) {
569 if (!mTodoMap.contains(todo) && ( KOPrefs::instance()->mShowCompletedTodo || !todo->isCompleted() ) )
570 {
571 insertTodoItem(todo);
572 }
573 }
574 //qDebug("for end ");
575 // Restore opened/closed state
576 mTodoListView->blockSignals( true );
577 if( mDocPrefs ) restoreItemState( mTodoListView->firstChild() );
578 mTodoListView->blockSignals( false );
579 mTodoListView->setFocus();
580 processSelectionChange();
581}
582
583void KOTodoView::restoreItemState( QListViewItem *item )
584{
585 while( item ) {
586 KOTodoViewItem *todoItem = (KOTodoViewItem *)item;
587 todoItem->setOpen( mDocPrefs->readBoolEntry( todoItem->todo()->uid() ) );
588 if( item->childCount() > 0 ) restoreItemState( item->firstChild() );
589 item = item->nextSibling();
590 }
591}
592
593
594QMap<Todo *,KOTodoViewItem *>::ConstIterator
595 KOTodoView::insertTodoItem(Todo *todo)
596{
597// kdDebug() << "KOTodoView::insertTodoItem(): " << todo->getSummary() << endl;
598 // TODO: Check, if dynmaic cast is necessary
599
600
601 Incidence *incidence = todo->relatedTo();
602 if (incidence && incidence->type() == "Todo") {
603 Todo *relatedTodo = static_cast<Todo *>(incidence);
604
605// kdDebug() << " has Related" << endl;
606 QMap<Todo *,KOTodoViewItem *>::ConstIterator itemIterator;
607 itemIterator = mTodoMap.find(relatedTodo);
608 if (itemIterator == mTodoMap.end()) {
609// kdDebug() << " related not yet in list" << endl;
610 itemIterator = insertTodoItem (relatedTodo);
611 }
612 // isn't this pretty stupid? We give one Todo to the KOTodoViewItem
613 // and one into the map. Sure finding is more easy but why? -zecke
614 KOTodoViewItem *todoItem = new KOTodoViewItem(*itemIterator,todo,this);
615 return mTodoMap.insert(todo,todoItem);
616 } else {
617// kdDebug() << " no Related" << endl;
618 // see above -zecke
619 KOTodoViewItem *todoItem = new KOTodoViewItem(mTodoListView,todo,this);
620 return mTodoMap.insert(todo,todoItem);
621 }
622}
623
624
625void KOTodoView::updateConfig()
626{
627 updateView();
628 mTodoListView->repaintContents();
629}
630
631QPtrList<Incidence> KOTodoView::selectedIncidences()
632{
633 QPtrList<Incidence> selected;
634
635 KOTodoViewItem *item = (KOTodoViewItem *)(mTodoListView->selectedItem());
636// if (!item) item = mActiveItem;
637 if (item) selected.append(item->todo());
638
639 return selected;
640}
641
642QPtrList<Todo> KOTodoView::selectedTodos()
643{
644 QPtrList<Todo> selected;
645
646 KOTodoViewItem *item = (KOTodoViewItem *)(mTodoListView->selectedItem());
647// if (!item) item = mActiveItem;
648 if (item) selected.append(item->todo());
649
650 return selected;
651}
652
653void KOTodoView::changeEventDisplay(Event *, int)
654{
655 updateView();
656}
657
658void KOTodoView::showDates(const QDate &, const QDate &)
659{
660}
661
662void KOTodoView::showEvents(QPtrList<Event>)
663{
664 kdDebug() << "KOTodoView::selectEvents(): not yet implemented" << endl;
665}
666
667void KOTodoView::printPreview(CalPrinter *calPrinter, const QDate &fd,
668 const QDate &td)
669{
670#ifndef KORG_NOPRINTER
671 calPrinter->preview(CalPrinter::Todolist, fd, td);
672#endif
673}
674
675void KOTodoView::editItem(QListViewItem *item )
676{
677 // qDebug("editItem(QListViewItem *item ) ");
678 emit editTodoSignal(((KOTodoViewItem *)item)->todo());
679}
680
681void KOTodoView::showItem(QListViewItem *item,const QPoint &,int)
682{
683 emit showTodoSignal(((KOTodoViewItem *)item)->todo());
684}
685
686void KOTodoView::popupMenu(QListViewItem *item,const QPoint &,int column)
687{
688
689 mActiveItem = (KOTodoViewItem *)item;
690 if (item) {
691 switch (column){
692 case 1:
693 mPriorityPopupMenu->popup(QCursor::pos ()); break;
694 case 2:
695 mPercentageCompletedPopupMenu->popup(QCursor::pos ()); break;
696 case 3:
697 moveTodo();
698 break;
699 case 6:
700 getCategoryPopupMenu((KOTodoViewItem *)item)->popup(QCursor::pos ()); break;
701 default:
702 mItemPopupMenu->popup(QCursor::pos());
703 }
704 } else mPopupMenu->popup(QCursor::pos());
705}
706void KOTodoView::newTodo()
707{
708 emit newTodoSignal();
709}
710
711void KOTodoView::newSubTodo()
712{
713 if (mActiveItem) {
714 emit newSubTodoSignal(mActiveItem->todo());
715 }
716}
717void KOTodoView::unparentTodo()
718{
719 if (mActiveItem) {
720 emit unparentTodoSignal(mActiveItem->todo());
721 }
722}
723void KOTodoView::editTodo()
724{
725 if (mActiveItem) {
726 emit editTodoSignal(mActiveItem->todo());
727 }
728}
729void KOTodoView::cloneTodo()
730{
731 if (mActiveItem) {
732 emit cloneTodoSignal((Incidence*)mActiveItem->todo());
733 }
734}
735void KOTodoView::cancelTodo()
736{
737 if (mActiveItem) {
738 emit cancelTodoSignal((Incidence*)mActiveItem->todo());
739 }
740}
741void KOTodoView::moveTodo()
742{
743 if (mActiveItem) {
744 emit moveTodoSignal((Incidence*)mActiveItem->todo());
745 }
746}
747void KOTodoView::beamTodo()
748{
749 if (mActiveItem) {
750 emit beamTodoSignal((Incidence*)mActiveItem->todo());
751 }
752}
753
754
755void KOTodoView::showTodo()
756{
757 if (mActiveItem) {
758 emit showTodoSignal(mActiveItem->todo());
759 }
760}
761
762void KOTodoView::deleteTodo()
763{
764 if (mActiveItem) {
765 if (mActiveItem->childCount()) {
766 KMessageBox::sorry(this,i18n("Cannot delete To-Do which has children."),
767 i18n("Delete To-Do"));
768 } else {
769 emit deleteTodoSignal(mActiveItem->todo());
770 }
771 }
772}
773
774void KOTodoView::setNewPriority(int index)
775{
776 if (mActiveItem && !mActiveItem->todo()->isReadOnly ()) {
777 mActiveItem->todo()->setPriority(mPriority[index]);
778 mActiveItem->construct();
779 todoModified (mActiveItem->todo(), KOGlobals::PRIORITY_MODIFIED);
780 mActiveItem->todo()->setRevision( mActiveItem->todo()->revision()+1 );
781 }
782}
783
784void KOTodoView::setNewPercentage(int index)
785{
786 if (mActiveItem && !mActiveItem->todo()->isReadOnly ()) {
787 if (mPercentage[index] == 100) {
788 mActiveItem->todo()->setCompleted(QDateTime::currentDateTime());
789 } else {
790 mActiveItem->todo()->setCompleted(false);
791 }
792 mActiveItem->todo()->setPercentComplete(mPercentage[index]);
793 mActiveItem->construct();
794 todoModified (mActiveItem->todo (), KOGlobals::COMPLETION_MODIFIED);
795 mActiveItem->todo()->setRevision( mActiveItem->todo()->revision()+1 );
796 }
797}
798
799
800QPopupMenu * KOTodoView::getCategoryPopupMenu (KOTodoViewItem *todoItem)
801{
802 QPopupMenu* tempMenu = new QPopupMenu (this);
803 QStringList checkedCategories = todoItem->todo()->categories ();
804
805 tempMenu->setCheckable (true);
806 for (QStringList::Iterator it = KOPrefs::instance()->mCustomCategories.begin ();
807 it != KOPrefs::instance()->mCustomCategories.end ();
808 ++it) {
809 int index = tempMenu->insertItem (*it);
810 mCategory[index] = *it;
811 if (checkedCategories.find (*it) != checkedCategories.end ()) tempMenu->setItemChecked (index, true);
812 }
813
814 connect (tempMenu, SIGNAL (activated (int)), SLOT (changedCategories (int)));
815 return tempMenu;
816
817
818}
819void KOTodoView::changedCategories(int index)
820{
821 if (mActiveItem && !mActiveItem->todo()->isReadOnly ()) {
822 QStringList categories = mActiveItem->todo()->categories ();
823 if (categories.find (mCategory[index]) != categories.end ())
824 categories.remove (mCategory[index]);
825 else
826 categories.insert (categories.end(), mCategory[index]);
827 categories.sort ();
828 mActiveItem->todo()->setCategories (categories);
829 mActiveItem->construct();
830 mActiveItem->todo()->setRevision( mActiveItem->todo()->revision()+1 );
831 todoModified (mActiveItem->todo (), KOGlobals::CATEGORY_MODIFIED);
832 }
833}
834void KOTodoView::itemDoubleClicked(QListViewItem *item)
835{
836 if (!item) {
837 newTodo();
838 return;
839 }
840 if ( KOPrefs::instance()->mEditOnDoubleClick )
841 editItem( item );
842 else
843 showItem( item , QPoint(), 0 );
844}
845void KOTodoView::itemClicked(QListViewItem *item)
846{
847 if (!item) {
848 return;
849 }
850
851 KOTodoViewItem *todoItem = (KOTodoViewItem *)item;
852 int completed = todoItem->todo()->isCompleted(); // Completed or not?
853
854 if (todoItem->isOn()) {
855 if (!completed) {
856 todoItem->todo()->setCompleted(QDateTime::currentDateTime());
857 }
858 } else {
859 if (completed) {
860 todoItem->todo()->setCompleted(false);
861 }
862 }
863}
864
865void KOTodoView::setDocumentId( const QString &id )
866{
867 kdDebug() << "KOTodoView::setDocumentId()" << endl;
868
869 mDocPrefs->setDoc( id );
870}
871
872void KOTodoView::itemStateChanged( QListViewItem *item )
873{
874 if (!item) return;
875
876 KOTodoViewItem *todoItem = (KOTodoViewItem *)item;
877
878// kdDebug() << "KOTodoView::itemStateChanged(): " << todoItem->todo()->summary() << endl;
879
880 if( mDocPrefs ) mDocPrefs->writeEntry( todoItem->todo()->uid(), todoItem->isOpen() );
881}
882
883void KOTodoView::saveLayout(KConfig *config, const QString &group) const
884{
885 mTodoListView->saveLayout(config,group);
886}
887
888void KOTodoView::restoreLayout(KConfig *config, const QString &group)
889{
890 mTodoListView->restoreLayout(config,group);
891}
892
893void KOTodoView::processSelectionChange()
894{
895// kdDebug() << "KOTodoView::processSelectionChange()" << endl;
896
897 KOTodoViewItem *item =
898 static_cast<KOTodoViewItem *>( mTodoListView->selectedItem() );
899
900 if ( !item ) {
901 emit incidenceSelected( 0 );
902 } else {
903 emit incidenceSelected( item->todo() );
904 }
905}
906
907void KOTodoView::modified(bool b)
908{
909 emit isModified(b);
910}
911void KOTodoView::setTodoModified( Todo* todo )
912{
913 todoModified( todo, KOGlobals::UNKNOWN_MODIFIED );
914}
915void KOTodoView::clearSelection()
916{
917 mTodoListView->selectAll( false );
918}
919
920void KOTodoView::purgeCompleted()
921{
922 emit purgeCompletedSignal();
923}
924void KOTodoView::toggleQuickTodo()
925{
926 if ( mQuickAdd->isVisible() ) {
927 mQuickAdd->hide();
928 KOPrefs::instance()->mEnableQuickTodo = false;
929 }
930 else {
931 mQuickAdd->show();
932 KOPrefs::instance()->mEnableQuickTodo = true;
933 }
934 mPopupMenu->setItemChecked(4,KOPrefs::instance()->mEnableQuickTodo);
935 mItemPopupMenu->setItemChecked( 34 , KOPrefs::instance()->mEnableQuickTodo );
936}
937void KOTodoView::toggleCompleted()
938{
939 KOPrefs::instance()->mShowCompletedTodo = !KOPrefs::instance()->mShowCompletedTodo;
940 mPopupMenu->setItemChecked( 3,KOPrefs::instance()->mShowCompletedTodo );
941 mItemPopupMenu->setItemChecked( 33 , KOPrefs::instance()->mShowCompletedTodo );
942 updateView();
943}
944
945void KOTodoView::addQuickTodo()
946{
947 Todo *todo = new Todo();
948 todo->setSummary(mQuickAdd->text());
949 todo->setOrganizer(KOPrefs::instance()->email());
950 CalFilter * cf = mCalendar->filter();
951 if ( cf ) {
952 if ( cf->isEnabled()&& cf->showCategories()) {
953 todo->setCategories(cf->categoryList());
954 }
955 if ( cf->isEnabled() )
956 todo->setSecrecy( cf->getSecrecy());
957 }
958 mCalendar->addTodo(todo);
959 mQuickAdd->setText("");
960 todoModified (todo, KOGlobals::EVENTADDED );
961 updateView();
962}
963void KOTodoView::keyPressEvent ( QKeyEvent * e )
964{
965 // e->ignore();
966 //return;
967 switch ( e->key() ) {
968 case Qt::Key_Down:
969 QWidget::keyPressEvent ( e );
970 break;
971
972 case Qt::Key_Up:
973 QWidget::keyPressEvent ( e );
974 break;
975 case Qt::Key_Q:
976 toggleQuickTodo();
977 break;
978
979 default:
980 e->ignore();
981 }
982
983 if ( e->state() == Qt::ControlButton || e->state() == Qt::ShiftButton || ( height() > 150 && width() > 200 ) ) {
984 if ( e->key() == Qt::Key_I ) {
985 KOTodoViewItem*cn = (KOTodoViewItem*)mTodoListView->currentItem();
986 if ( cn ) {
987 mActiveItem = cn;
988 KOTodoViewItem* ci = (KOTodoViewItem*)( cn );
989 if ( ci ){
990 showTodo();
991 cn = (KOTodoViewItem*)cn->itemBelow();
992 if ( cn ) {
993 mTodoListView->setCurrentItem ( cn );
994 mTodoListView->ensureItemVisible ( cn );
995 }
996
997 }
998 }
999 e->accept();
1000
1001 }
1002
1003 }
1004
1005}
1006void KOTodoView::updateTodo( Todo * t, int type )
1007{
1008 if ( mBlockUpdate)
1009 return;
1010
1011 QMap<Todo *,KOTodoViewItem *>::ConstIterator itemIterator;
1012 itemIterator = mTodoMap.find(t);
1013 if (itemIterator != mTodoMap.end()) {
1014 (*itemIterator)->construct();
1015 } else {
1016 if ( type == KOGlobals::EVENTADDED ) {
1017 insertTodoItem( t );
1018 }
1019 }
1020
1021}
1022
1023void KOTodoView::todoModified(Todo * t , int p )
1024{
1025 mBlockUpdate = true;
1026 emit todoModifiedSignal ( t, p );
1027 mBlockUpdate = false;
1028}