-rw-r--r-- | korganizer/kotodoview.cpp | 1028 |
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 @@ +/* + This file is part of KOrganizer. + Copyright (c) 2000,2001 Cornelius Schumacher <schumacher@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qlayout.h> +#include <qheader.h> +#include <qcursor.h> + +#include <qvbox.h> +#include <kdebug.h> +#include "koprefs.h" +#include <klocale.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <kmessagebox.h> + +#include <libkcal/icaldrag.h> +#include <libkcal/vcaldrag.h> +#include <libkcal/calfilter.h> +#include <libkcal/dndfactory.h> +#include <libkcal/calendarresources.h> +#include <libkcal/resourcecalendar.h> +#include <kresources/resourceselectdialog.h> +#ifndef DESKTOP_VERSION +#include <qpe/qpeapplication.h> +#else +#include <qapplication.h> +#endif +#ifndef KORG_NOPRINTER +#include "calprinter.h" +#endif +#include "docprefs.h" + +#include "kotodoview.h" +using namespace KOrg; +#include "kotodoview.moc" + +KOTodoListView::KOTodoListView(Calendar *calendar,QWidget *parent, + const char *name) : + KListView(parent,name) +{ + mCalendar = calendar; +#ifndef DESKTOP_VERSION + QPEApplication::setStylusOperation(viewport(), QPEApplication::RightOnHold ); +#endif + mOldCurrent = 0; + mMousePressed = false; + + setAcceptDrops(true); + viewport()->setAcceptDrops(true); + int size = 16; + if (qApp->desktop()->width() < 300 ) + size = 12; + setTreeStepSize( size + 6 ); + +} + +void KOTodoListView::contentsDragEnterEvent(QDragEnterEvent *e) +{ +#ifndef KORG_NODND +// kdDebug() << "KOTodoListView::contentsDragEnterEvent" << endl; + if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) && + !QTextDrag::canDecode( e ) ) { + e->ignore(); + return; + } + + mOldCurrent = currentItem(); +#endif +} + + +void KOTodoListView::contentsDragMoveEvent(QDragMoveEvent *e) +{ +#ifndef KORG_NODND +// kdDebug() << "KOTodoListView::contentsDragMoveEvent" << endl; + + if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) && + !QTextDrag::canDecode( e ) ) { + e->ignore(); + return; + } + + e->accept(); +#endif +} + +void KOTodoListView::contentsDragLeaveEvent(QDragLeaveEvent *) +{ +#ifndef KORG_NODND +// kdDebug() << "KOTodoListView::contentsDragLeaveEvent" << endl; + + setCurrentItem(mOldCurrent); + setSelected(mOldCurrent,true); +#endif +} + +void KOTodoListView::contentsDropEvent(QDropEvent *e) +{ +#ifndef KORG_NODND +// kdDebug() << "KOTodoListView::contentsDropEvent" << endl; + + if ( !ICalDrag::canDecode( e ) && !VCalDrag::canDecode( e ) && + !QTextDrag::canDecode( e ) ) { + e->ignore(); + return; + } + + DndFactory factory( mCalendar ); + Todo *todo = factory.createDropTodo(e); + + if (todo) { + e->acceptAction(); + + KOTodoViewItem *destination = + (KOTodoViewItem *)itemAt(contentsToViewport(e->pos())); + Todo *destinationEvent = 0; + if (destination) destinationEvent = destination->todo(); + + Todo *existingTodo = mCalendar->todo(todo->uid()); + + if(existingTodo) { +// kdDebug() << "Drop existing Todo" << endl; + Incidence *to = destinationEvent; + while(to) { + if (to->uid() == todo->uid()) { + KMessageBox::sorry(this, + i18n("Cannot move To-Do to itself or a child of itself"), + i18n("Drop To-Do")); + delete todo; + return; + } + to = to->relatedTo(); + } + existingTodo->setRelatedTo(destinationEvent); + emit todoDropped(todo); + delete todo; + } else { +// kdDebug() << "Drop new Todo" << endl; + todo->setRelatedTo(destinationEvent); + mCalendar->addTodo(todo); + + emit todoDropped(todo); + } + } + else { + QString text; + if (QTextDrag::decode(e,text)) { + //QListViewItem *qlvi = itemAt( contentsToViewport(e->pos()) ); + KOTodoViewItem *todoi = static_cast<KOTodoViewItem *>(itemAt( contentsToViewport(e->pos()) )); + kdDebug() << "Dropped : " << text << endl; + QStringList emails = QStringList::split(",",text); + for(QStringList::ConstIterator it = emails.begin();it!=emails.end();++it) { + kdDebug() << " Email: " << (*it) << endl; + int pos = (*it).find("<"); + QString name = (*it).left(pos); + QString email = (*it).mid(pos); + if (!email.isEmpty() && todoi) { + todoi->todo()->addAttendee(new Attendee(name,email)); + } + } + } + else { + kdDebug() << "KOTodoListView::contentsDropEvent(): Todo from drop not decodable" << endl; + e->ignore(); + } + } +#endif +} + +void KOTodoListView::contentsMousePressEvent(QMouseEvent* e) +{ + QListView::contentsMousePressEvent(e); +#ifndef KORG_NODND + QPoint p(contentsToViewport(e->pos())); + QListViewItem *i = itemAt(p); + if (i) { + // if the user clicked into the root decoration of the item, don't + // try to start a drag! + if (p.x() > header()->sectionPos(header()->mapToIndex(0)) + + treeStepSize() * (i->depth() + (rootIsDecorated() ? 1 : 0)) + + itemMargin() || + p.x() < header()->sectionPos(header()->mapToIndex(0))) { + if (e->button()==Qt::LeftButton) { + mPressPos = e->pos(); + mMousePressed = true; + } + } + } +#endif +} + +void KOTodoListView::contentsMouseMoveEvent(QMouseEvent* e) +{ +#ifndef KORG_NODND +// kdDebug() << "KOTodoListView::contentsMouseMoveEvent()" << endl; + QListView::contentsMouseMoveEvent(e); + if (mMousePressed && (mPressPos - e->pos()).manhattanLength() > + QApplication::startDragDistance()) { + mMousePressed = false; + QListViewItem *item = itemAt(contentsToViewport(mPressPos)); + if (item) { +// kdDebug() << "Start Drag for item " << item->text(0) << endl; + DndFactory factory( mCalendar ); + ICalDrag *vd = factory.createDragTodo( + ((KOTodoViewItem *)item)->todo(),viewport()); + if (vd->drag()) { + kdDebug() << "KOTodoListView::contentsMouseMoveEvent(): Delete drag source" << endl; + } +/* + QString source = fullPath(item); + if ( QFile::exists(source) ) { + QUriDrag* ud = new QUriDrag(viewport()); + ud->setFilenames( source ); + if ( ud->drag() ) + QMessageBox::information( this, "Drag source", + QString("Delete ")+source, "Not implemented" ); +*/ + } + } +#endif +} +void KOTodoListView::keyPressEvent ( QKeyEvent * e ) +{ + + QListViewItem* cn; + if ( e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter ) { + cn = currentItem(); + if ( cn ) { + KOTodoViewItem* ci = (KOTodoViewItem*)( cn ); + if ( ci ){ + if ( e->state() == ShiftButton ) + ci->setOn( false ); + else + ci->setOn( true ); + cn = cn->nextSibling(); + if ( cn ) { + setCurrentItem ( cn ); + ensureItemVisible ( cn ); + } + + } + } + + return; + } + + // qDebug("KOTodoListView::keyPressEvent "); + if ( e->state() == Qt::ControlButton || e->state() == Qt::ShiftButton || ( height() > 150 && width() > 200 ) ) { + switch ( e->key() ) { + case Qt::Key_Down: + case Qt::Key_Up: + QListView::keyPressEvent ( e ); + break; + default: + e->ignore(); + break; + } + return; + } + e->ignore(); +} +void KOTodoListView::contentsMouseReleaseEvent(QMouseEvent *e) +{ + QListView::contentsMouseReleaseEvent(e); + mMousePressed = false; +} + +void KOTodoListView::contentsMouseDoubleClickEvent(QMouseEvent *e) +{ + if (!e) return; + + QPoint vp = contentsToViewport(e->pos()); + + QListViewItem *item = itemAt(vp); + + emit double_Clicked(item); + if (!item) return; + + emit doubleClicked(item,vp,0); +} + +///////////////////////////////////////////////////////////////////////////// + +KOQuickTodo::KOQuickTodo(QWidget *parent) : + QLineEdit(parent) +{ + setText(i18n("Click to add a new Todo")); +} + +void KOQuickTodo::focusInEvent(QFocusEvent *ev) +{ + if ( text()==i18n("Click to add a new Todo") ) + setText(""); + QLineEdit::focusInEvent(ev); +} + +void KOQuickTodo::focusOutEvent(QFocusEvent *ev) +{ + setText(i18n("Click to add a new Todo")); + QLineEdit::focusOutEvent(ev); +} + +///////////////////////////////////////////////////////////////////////////// + +KOTodoView::KOTodoView(Calendar *calendar,QWidget* parent,const char* name) : + KOrg::BaseView(calendar,parent,name) +{ + QBoxLayout *topLayout = new QVBoxLayout(this); + mName = QString ( name ); + mBlockUpdate = false; + mQuickAdd = new KOQuickTodo(this); + topLayout->addWidget(mQuickAdd); + + if ( !KOPrefs::instance()->mEnableQuickTodo ) mQuickAdd->hide(); + + mTodoListView = new KOTodoListView(calendar,this); + topLayout->addWidget(mTodoListView); + //mTodoListView->header()->setMaximumHeight(30); + mTodoListView->setRootIsDecorated(true); + mTodoListView->setAllColumnsShowFocus(true); + + mTodoListView->setShowSortIndicator(true); + + mTodoListView->addColumn(i18n("Todo")); + mTodoListView->addColumn(i18n("Prio")); + mTodoListView->setColumnAlignment(1,AlignHCenter); + mTodoListView->addColumn(i18n("Complete")); + mTodoListView->setColumnAlignment(2,AlignHCenter); + mTodoListView->addColumn(i18n("Due Date")); + mTodoListView->setColumnAlignment(3,AlignLeft); + mTodoListView->addColumn(i18n("Due Time")); + mTodoListView->setColumnAlignment(4,AlignHCenter); + mTodoListView->addColumn(i18n("Cancelled")); + mTodoListView->addColumn(i18n("Categories")); +#if 0 + mTodoListView->addColumn(i18n("Sort Id")); + mTodoListView->setColumnAlignment(4,AlignHCenter); +#endif + + mTodoListView->setMinimumHeight( 60 ); + mTodoListView->setItemsRenameable( true ); + mTodoListView->setRenameable( 0 ); + mTodoListView->setColumnWidth( 0, 120 ); + mTodoListView->setColumnWidthMode(0, QListView::Manual); + mTodoListView->setColumnWidthMode(1, QListView::Manual); + mTodoListView->setColumnWidthMode(2, QListView::Manual); + mTodoListView->setColumnWidthMode(3, QListView::Manual); + mTodoListView->setColumnWidthMode(4, QListView::Manual); + mTodoListView->setColumnWidthMode(5, QListView::Manual); + mTodoListView->setColumnAlignment( 2, AlignCenter ); +#if 0 + mTodoListView->setColumnWidthMode(6, QListView::Manual); +#endif + + mPriorityPopupMenu = new QPopupMenu(this); + for (int i = 1; i <= 5; i++) { + QString label = QString ("%1").arg (i); + mPriority[mPriorityPopupMenu->insertItem (label)] = i; + } + connect (mPriorityPopupMenu, SIGNAL(activated (int)), SLOT (setNewPriority(int))); + + mPercentageCompletedPopupMenu = new QPopupMenu(this); + for (int i = 0; i <= 100; i+=20) { + QString label = QString ("%1 %").arg (i); + mPercentage[mPercentageCompletedPopupMenu->insertItem (label)] = i; + } + connect (mPercentageCompletedPopupMenu, SIGNAL (activated (int)), SLOT (setNewPercentage (int))); + + + + mItemPopupMenu = new QPopupMenu(this); + mItemPopupMenu->insertItem(i18n("Show..."), this, + SLOT (showTodo())); + mItemPopupMenu->insertItem(i18n("Edit..."), this, + SLOT (editTodo())); + mItemPopupMenu->insertItem( i18n("Delete"), this, + SLOT (deleteTodo())); + mItemPopupMenu->insertItem( i18n("Clone..."), this, + SLOT (cloneTodo())); + mItemPopupMenu->insertItem( i18n("Move..."), this, + SLOT (moveTodo())); + mItemPopupMenu->insertItem( i18n("Beam..."), this, + SLOT (beamTodo())); + mItemPopupMenu->insertItem( i18n("Toggle Cancel"), this, + SLOT (cancelTodo())); + mItemPopupMenu->insertSeparator(); + + mItemPopupMenu->insertItem( i18n("New Todo..."), this, + SLOT (newTodo())); + mItemPopupMenu->insertItem(i18n("New Sub-Todo..."), this, + SLOT (newSubTodo())); + mItemPopupMenu->insertItem(i18n("Unparent Todo"), this, + SLOT (unparentTodo())); + mItemPopupMenu->insertSeparator(); + mItemPopupMenu->insertItem(i18n("Delete completed To-Dos","Purge Completed"), + this, SLOT( purgeCompleted() ) ); + mItemPopupMenu->insertItem(i18n("toggle completed To-Dos","Show Completed"), + this, SLOT( toggleCompleted() ),0, 33 ); + mItemPopupMenu->insertItem(i18n("toggle quick todo","Show Quick Todo"), + this, SLOT( toggleQuickTodo() ),0, 34 ); + + mPopupMenu = new QPopupMenu(this); + mPopupMenu->insertItem(SmallIconSet("todo"), i18n("New Todo..."), this, + SLOT (newTodo()),0,1); + mPopupMenu->insertItem(i18n("delete completed To-Dos","Purge Completed"), + this, SLOT(purgeCompleted()),0,2); + mPopupMenu->insertItem(i18n("Show Completed"), + this, SLOT( toggleCompleted() ),0,3 ); + mPopupMenu->insertItem(i18n("toggle quick todo","Show Quick Todo"), + this, SLOT( toggleQuickTodo() ),0,4 ); + mDocPrefs = new DocPrefs( name ); + + mPopupMenu->setCheckable( true ); + mItemPopupMenu->setCheckable( true ); + // Double clicking conflicts with opening/closing the subtree + connect( mTodoListView, SIGNAL( doubleClicked( QListViewItem *) ), + SLOT( editItem( QListViewItem *) ) ); + connect( mTodoListView, SIGNAL( rightButtonClicked ( QListViewItem *, + const QPoint &,int ) ), + SLOT( popupMenu( QListViewItem *, const QPoint & ,int) ) ); + connect( mTodoListView, SIGNAL( clicked( QListViewItem * ) ), + SLOT( itemClicked( QListViewItem * ) ) ); + connect( mTodoListView, SIGNAL( double_Clicked( QListViewItem * ) ), + SLOT( itemDoubleClicked( QListViewItem * ) ) ); + connect( mTodoListView, SIGNAL( todoDropped( Todo * ) ), + SLOT( updateView() ) ); + connect( mTodoListView, SIGNAL( expanded( QListViewItem * ) ), + SLOT( itemStateChanged( QListViewItem * ) ) ); + connect( mTodoListView, SIGNAL( collapsed( QListViewItem * ) ), + SLOT( itemStateChanged( QListViewItem * ) ) ); + +#if 0 + connect(mTodoListView,SIGNAL(selectionChanged(QListViewItem *)), + SLOT(selectionChanged(QListViewItem *))); + connect(mTodoListView,SIGNAL(clicked(QListViewItem *)), + SLOT(selectionChanged(QListViewItem *))); + connect(mTodoListView,SIGNAL(pressed(QListViewItem *)), + SLOT(selectionChanged(QListViewItem *))); +#endif + connect( mTodoListView, SIGNAL(selectionChanged() ), + SLOT( processSelectionChange() ) ); + connect( mQuickAdd, SIGNAL( returnPressed () ), + SLOT( addQuickTodo() ) ); +// if ( QApplication::desktop()->width() < 480 ) { +// setNarrow(); + // mTodoListView->setColumnWidth( 0, 100 ); + + // } + +} + +KOTodoView::~KOTodoView() +{ + delete mDocPrefs; +} + +void KOTodoView::jumpToDate () +{ + // if (mActiveItem) { +// mActiveItem->todo()); +// if ( mActiveItem->todo()->hasDueDate() ) +// emit mActiveItem->todo()jumpToTime( mTodo->dtDue().date() ); +} + +void KOTodoView::setNarrow() +{ + //mTodoListView->setColumnWidth( 0, 120 ); + mTodoListView->setColumnWidth( 1, 35 ); + mTodoListView->setColumnWidth( 2, 40 ); + mTodoListView->setColumnWidth( 3, 80 ); + mTodoListView->setColumnWidth( 4, 40 ); + mTodoListView->setColumnWidth( 5, 90 ); + +} +void KOTodoView::updateView() +{ +// kdDebug() << "KOTodoView::updateView()" << endl; + QFont fo = KOPrefs::instance()->mTodoViewFont; + mTodoListView->clear(); + if ( mName == "todolistsmall" ) { + if ( KOPrefs::instance()->mTodoViewUsesSmallFont ) { + int ps = fo.pointSize() -2; + if ( ps > 12 ) + ps -= 2; + fo.setPointSize( ps ); + } + } + + mTodoListView->setFont( fo ); + // QFontMetrics fm ( KOPrefs::instance()->mTodoViewFont ); + //mTodoListView->header()->setMaximumHeight(fm.height()); + QPtrList<Todo> todoList = calendar()->todos(); + +/* + kdDebug() << "KOTodoView::updateView(): Todo List:" << endl; + Event *t; + for(t = todoList.first(); t; t = todoList.next()) { + kdDebug() << " " << t->getSummary() << endl; + + if (t->getRelatedTo()) { + kdDebug() << " (related to " << t->getRelatedTo()->getSummary() << ")" << endl; + } + + QPtrList<Event> l = t->getRelations(); + Event *c; + for(c=l.first();c;c=l.next()) { + kdDebug() << " - relation: " << c->getSummary() << endl; + } + } +*/ + + // Put for each Event a KOTodoViewItem in the list view. Don't rely on a + // specific order of events. That means that we have to generate parent items + // recursively for proper hierarchical display of Todos. + mTodoMap.clear(); + Todo *todo; + todo = todoList.first();// todo; todo = todoList.next()) { + while ( todo ) { + bool next = true; + // qDebug("todo %s ", todo->summary().latin1()); + Incidence *incidence = todo->relatedTo(); + while ( incidence ) { + if ( incidence->type() == "Todo") { + //qDebug("related %s ",incidence->summary().latin1() ); + if ( !(todoList.contains ( ((Todo* )incidence ) ) )) { + //qDebug("related not found "); + todoList.remove( ); + todo = todoList.current(); + next = false; + incidence = 0; + + } else { + //qDebug("related found "); + incidence = incidence->relatedTo(); + } + } else + incidence = 0; + } + if ( next ) + todo = todoList.next(); + } +// qDebug("again .... "); +// for(todo = todoList.first(); todo; todo = todoList.next()) { + +// qDebug("yytodo %s ", todo->summary().latin1()); +// } + //qDebug("for "); + for(todo = todoList.first(); todo; todo = todoList.next()) { + if (!mTodoMap.contains(todo) && ( KOPrefs::instance()->mShowCompletedTodo || !todo->isCompleted() ) ) + { + insertTodoItem(todo); + } + } + //qDebug("for end "); + // Restore opened/closed state + mTodoListView->blockSignals( true ); + if( mDocPrefs ) restoreItemState( mTodoListView->firstChild() ); + mTodoListView->blockSignals( false ); + mTodoListView->setFocus(); + processSelectionChange(); +} + +void KOTodoView::restoreItemState( QListViewItem *item ) +{ + while( item ) { + KOTodoViewItem *todoItem = (KOTodoViewItem *)item; + todoItem->setOpen( mDocPrefs->readBoolEntry( todoItem->todo()->uid() ) ); + if( item->childCount() > 0 ) restoreItemState( item->firstChild() ); + item = item->nextSibling(); + } +} + + +QMap<Todo *,KOTodoViewItem *>::ConstIterator + KOTodoView::insertTodoItem(Todo *todo) +{ +// kdDebug() << "KOTodoView::insertTodoItem(): " << todo->getSummary() << endl; + // TODO: Check, if dynmaic cast is necessary + + + Incidence *incidence = todo->relatedTo(); + if (incidence && incidence->type() == "Todo") { + Todo *relatedTodo = static_cast<Todo *>(incidence); + +// kdDebug() << " has Related" << endl; + QMap<Todo *,KOTodoViewItem *>::ConstIterator itemIterator; + itemIterator = mTodoMap.find(relatedTodo); + if (itemIterator == mTodoMap.end()) { +// kdDebug() << " related not yet in list" << endl; + itemIterator = insertTodoItem (relatedTodo); + } + // isn't this pretty stupid? We give one Todo to the KOTodoViewItem + // and one into the map. Sure finding is more easy but why? -zecke + KOTodoViewItem *todoItem = new KOTodoViewItem(*itemIterator,todo,this); + return mTodoMap.insert(todo,todoItem); + } else { +// kdDebug() << " no Related" << endl; + // see above -zecke + KOTodoViewItem *todoItem = new KOTodoViewItem(mTodoListView,todo,this); + return mTodoMap.insert(todo,todoItem); + } +} + + +void KOTodoView::updateConfig() +{ + updateView(); + mTodoListView->repaintContents(); +} + +QPtrList<Incidence> KOTodoView::selectedIncidences() +{ + QPtrList<Incidence> selected; + + KOTodoViewItem *item = (KOTodoViewItem *)(mTodoListView->selectedItem()); +// if (!item) item = mActiveItem; + if (item) selected.append(item->todo()); + + return selected; +} + +QPtrList<Todo> KOTodoView::selectedTodos() +{ + QPtrList<Todo> selected; + + KOTodoViewItem *item = (KOTodoViewItem *)(mTodoListView->selectedItem()); +// if (!item) item = mActiveItem; + if (item) selected.append(item->todo()); + + return selected; +} + +void KOTodoView::changeEventDisplay(Event *, int) +{ + updateView(); +} + +void KOTodoView::showDates(const QDate &, const QDate &) +{ +} + +void KOTodoView::showEvents(QPtrList<Event>) +{ + kdDebug() << "KOTodoView::selectEvents(): not yet implemented" << endl; +} + +void KOTodoView::printPreview(CalPrinter *calPrinter, const QDate &fd, + const QDate &td) +{ +#ifndef KORG_NOPRINTER + calPrinter->preview(CalPrinter::Todolist, fd, td); +#endif +} + +void KOTodoView::editItem(QListViewItem *item ) +{ + // qDebug("editItem(QListViewItem *item ) "); + emit editTodoSignal(((KOTodoViewItem *)item)->todo()); +} + +void KOTodoView::showItem(QListViewItem *item,const QPoint &,int) +{ + emit showTodoSignal(((KOTodoViewItem *)item)->todo()); +} + +void KOTodoView::popupMenu(QListViewItem *item,const QPoint &,int column) +{ + + mActiveItem = (KOTodoViewItem *)item; + if (item) { + switch (column){ + case 1: + mPriorityPopupMenu->popup(QCursor::pos ()); break; + case 2: + mPercentageCompletedPopupMenu->popup(QCursor::pos ()); break; + case 3: + moveTodo(); + break; + case 6: + getCategoryPopupMenu((KOTodoViewItem *)item)->popup(QCursor::pos ()); break; + default: + mItemPopupMenu->popup(QCursor::pos()); + } + } else mPopupMenu->popup(QCursor::pos()); +} +void KOTodoView::newTodo() +{ + emit newTodoSignal(); +} + +void KOTodoView::newSubTodo() +{ + if (mActiveItem) { + emit newSubTodoSignal(mActiveItem->todo()); + } +} +void KOTodoView::unparentTodo() +{ + if (mActiveItem) { + emit unparentTodoSignal(mActiveItem->todo()); + } +} +void KOTodoView::editTodo() +{ + if (mActiveItem) { + emit editTodoSignal(mActiveItem->todo()); + } +} +void KOTodoView::cloneTodo() +{ + if (mActiveItem) { + emit cloneTodoSignal((Incidence*)mActiveItem->todo()); + } +} +void KOTodoView::cancelTodo() +{ + if (mActiveItem) { + emit cancelTodoSignal((Incidence*)mActiveItem->todo()); + } +} +void KOTodoView::moveTodo() +{ + if (mActiveItem) { + emit moveTodoSignal((Incidence*)mActiveItem->todo()); + } +} +void KOTodoView::beamTodo() +{ + if (mActiveItem) { + emit beamTodoSignal((Incidence*)mActiveItem->todo()); + } +} + + +void KOTodoView::showTodo() +{ + if (mActiveItem) { + emit showTodoSignal(mActiveItem->todo()); + } +} + +void KOTodoView::deleteTodo() +{ + if (mActiveItem) { + if (mActiveItem->childCount()) { + KMessageBox::sorry(this,i18n("Cannot delete To-Do which has children."), + i18n("Delete To-Do")); + } else { + emit deleteTodoSignal(mActiveItem->todo()); + } + } +} + +void KOTodoView::setNewPriority(int index) +{ + if (mActiveItem && !mActiveItem->todo()->isReadOnly ()) { + mActiveItem->todo()->setPriority(mPriority[index]); + mActiveItem->construct(); + todoModified (mActiveItem->todo(), KOGlobals::PRIORITY_MODIFIED); + mActiveItem->todo()->setRevision( mActiveItem->todo()->revision()+1 ); + } +} + +void KOTodoView::setNewPercentage(int index) +{ + if (mActiveItem && !mActiveItem->todo()->isReadOnly ()) { + if (mPercentage[index] == 100) { + mActiveItem->todo()->setCompleted(QDateTime::currentDateTime()); + } else { + mActiveItem->todo()->setCompleted(false); + } + mActiveItem->todo()->setPercentComplete(mPercentage[index]); + mActiveItem->construct(); + todoModified (mActiveItem->todo (), KOGlobals::COMPLETION_MODIFIED); + mActiveItem->todo()->setRevision( mActiveItem->todo()->revision()+1 ); + } +} + + +QPopupMenu * KOTodoView::getCategoryPopupMenu (KOTodoViewItem *todoItem) +{ + QPopupMenu* tempMenu = new QPopupMenu (this); + QStringList checkedCategories = todoItem->todo()->categories (); + + tempMenu->setCheckable (true); + for (QStringList::Iterator it = KOPrefs::instance()->mCustomCategories.begin (); + it != KOPrefs::instance()->mCustomCategories.end (); + ++it) { + int index = tempMenu->insertItem (*it); + mCategory[index] = *it; + if (checkedCategories.find (*it) != checkedCategories.end ()) tempMenu->setItemChecked (index, true); + } + + connect (tempMenu, SIGNAL (activated (int)), SLOT (changedCategories (int))); + return tempMenu; + + +} +void KOTodoView::changedCategories(int index) +{ + if (mActiveItem && !mActiveItem->todo()->isReadOnly ()) { + QStringList categories = mActiveItem->todo()->categories (); + if (categories.find (mCategory[index]) != categories.end ()) + categories.remove (mCategory[index]); + else + categories.insert (categories.end(), mCategory[index]); + categories.sort (); + mActiveItem->todo()->setCategories (categories); + mActiveItem->construct(); + mActiveItem->todo()->setRevision( mActiveItem->todo()->revision()+1 ); + todoModified (mActiveItem->todo (), KOGlobals::CATEGORY_MODIFIED); + } +} +void KOTodoView::itemDoubleClicked(QListViewItem *item) +{ + if (!item) { + newTodo(); + return; + } + if ( KOPrefs::instance()->mEditOnDoubleClick ) + editItem( item ); + else + showItem( item , QPoint(), 0 ); +} +void KOTodoView::itemClicked(QListViewItem *item) +{ + if (!item) { + return; + } + + KOTodoViewItem *todoItem = (KOTodoViewItem *)item; + int completed = todoItem->todo()->isCompleted(); // Completed or not? + + if (todoItem->isOn()) { + if (!completed) { + todoItem->todo()->setCompleted(QDateTime::currentDateTime()); + } + } else { + if (completed) { + todoItem->todo()->setCompleted(false); + } + } +} + +void KOTodoView::setDocumentId( const QString &id ) +{ + kdDebug() << "KOTodoView::setDocumentId()" << endl; + + mDocPrefs->setDoc( id ); +} + +void KOTodoView::itemStateChanged( QListViewItem *item ) +{ + if (!item) return; + + KOTodoViewItem *todoItem = (KOTodoViewItem *)item; + +// kdDebug() << "KOTodoView::itemStateChanged(): " << todoItem->todo()->summary() << endl; + + if( mDocPrefs ) mDocPrefs->writeEntry( todoItem->todo()->uid(), todoItem->isOpen() ); +} + +void KOTodoView::saveLayout(KConfig *config, const QString &group) const +{ + mTodoListView->saveLayout(config,group); +} + +void KOTodoView::restoreLayout(KConfig *config, const QString &group) +{ + mTodoListView->restoreLayout(config,group); +} + +void KOTodoView::processSelectionChange() +{ +// kdDebug() << "KOTodoView::processSelectionChange()" << endl; + + KOTodoViewItem *item = + static_cast<KOTodoViewItem *>( mTodoListView->selectedItem() ); + + if ( !item ) { + emit incidenceSelected( 0 ); + } else { + emit incidenceSelected( item->todo() ); + } +} + +void KOTodoView::modified(bool b) +{ + emit isModified(b); +} +void KOTodoView::setTodoModified( Todo* todo ) +{ + todoModified( todo, KOGlobals::UNKNOWN_MODIFIED ); +} +void KOTodoView::clearSelection() +{ + mTodoListView->selectAll( false ); +} + +void KOTodoView::purgeCompleted() +{ + emit purgeCompletedSignal(); +} +void KOTodoView::toggleQuickTodo() +{ + if ( mQuickAdd->isVisible() ) { + mQuickAdd->hide(); + KOPrefs::instance()->mEnableQuickTodo = false; + } + else { + mQuickAdd->show(); + KOPrefs::instance()->mEnableQuickTodo = true; + } + mPopupMenu->setItemChecked(4,KOPrefs::instance()->mEnableQuickTodo); + mItemPopupMenu->setItemChecked( 34 , KOPrefs::instance()->mEnableQuickTodo ); +} +void KOTodoView::toggleCompleted() +{ + KOPrefs::instance()->mShowCompletedTodo = !KOPrefs::instance()->mShowCompletedTodo; + mPopupMenu->setItemChecked( 3,KOPrefs::instance()->mShowCompletedTodo ); + mItemPopupMenu->setItemChecked( 33 , KOPrefs::instance()->mShowCompletedTodo ); + updateView(); +} + +void KOTodoView::addQuickTodo() +{ + Todo *todo = new Todo(); + todo->setSummary(mQuickAdd->text()); + todo->setOrganizer(KOPrefs::instance()->email()); + CalFilter * cf = mCalendar->filter(); + if ( cf ) { + if ( cf->isEnabled()&& cf->showCategories()) { + todo->setCategories(cf->categoryList()); + } + if ( cf->isEnabled() ) + todo->setSecrecy( cf->getSecrecy()); + } + mCalendar->addTodo(todo); + mQuickAdd->setText(""); + todoModified (todo, KOGlobals::EVENTADDED ); + updateView(); +} +void KOTodoView::keyPressEvent ( QKeyEvent * e ) +{ + // e->ignore(); + //return; + switch ( e->key() ) { + case Qt::Key_Down: + QWidget::keyPressEvent ( e ); + break; + + case Qt::Key_Up: + QWidget::keyPressEvent ( e ); + break; + case Qt::Key_Q: + toggleQuickTodo(); + break; + + default: + e->ignore(); + } + + if ( e->state() == Qt::ControlButton || e->state() == Qt::ShiftButton || ( height() > 150 && width() > 200 ) ) { + if ( e->key() == Qt::Key_I ) { + KOTodoViewItem*cn = (KOTodoViewItem*)mTodoListView->currentItem(); + if ( cn ) { + mActiveItem = cn; + KOTodoViewItem* ci = (KOTodoViewItem*)( cn ); + if ( ci ){ + showTodo(); + cn = (KOTodoViewItem*)cn->itemBelow(); + if ( cn ) { + mTodoListView->setCurrentItem ( cn ); + mTodoListView->ensureItemVisible ( cn ); + } + + } + } + e->accept(); + + } + + } + +} +void KOTodoView::updateTodo( Todo * t, int type ) +{ + if ( mBlockUpdate) + return; + + QMap<Todo *,KOTodoViewItem *>::ConstIterator itemIterator; + itemIterator = mTodoMap.find(t); + if (itemIterator != mTodoMap.end()) { + (*itemIterator)->construct(); + } else { + if ( type == KOGlobals::EVENTADDED ) { + insertTodoItem( t ); + } + } + +} + +void KOTodoView::todoModified(Todo * t , int p ) +{ + mBlockUpdate = true; + emit todoModifiedSignal ( t, p ); + mBlockUpdate = false; +} |