summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--korganizer/kotodoview.cpp56
-rw-r--r--korganizer/kotodoview.h18
-rw-r--r--korganizer/kotodoviewitem.cpp2
-rw-r--r--libkcal/todo.cpp10
-rw-r--r--libkcal/todo.h1
5 files changed, 81 insertions, 6 deletions
diff --git a/korganizer/kotodoview.cpp b/korganizer/kotodoview.cpp
index b2ff33b..99e6a3a 100644
--- a/korganizer/kotodoview.cpp
+++ b/korganizer/kotodoview.cpp
@@ -1,188 +1,231 @@
/*
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 <qwhatsthis.h>
+#include <qdialog.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
#include <qinputdialog.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>
#include <libkcal/kincidenceformatter.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;
+KOStopTodoPrefs::KOStopTodoPrefs( Todo* todo, QWidget *parent, const char *name ) :
+ QDialog( parent, name, true )
+{
+ mTodo = todo;
+ setCaption( i18n("Stop todo") );
+ QVBoxLayout* lay = new QVBoxLayout( this );
+ lay->setSpacing( 3 );
+ lay->setMargin( 3 );
+ QLabel * lab = new QLabel( i18n("%1\nis running!").arg( todo->summary() ), this );
+ lay->addWidget( lab );
+ lab->setAlignment( AlignHCenter );
+
+ QPushButton * ok = new QPushButton( i18n("Stop and save"), this );
+ lay->addWidget( ok );
+ QPushButton * cancel = new QPushButton( i18n("Continue running"), this );
+ lay->addWidget( cancel );
+ connect ( ok,SIGNAL(clicked() ),this , SLOT ( accept() ) );
+ connect (cancel, SIGNAL(clicked() ), this, SLOT ( reject()) );
+ ok = new QPushButton( i18n("Stop - do not save"), this );
+ connect ( ok,SIGNAL(clicked() ),this , SLOT ( doNotSave() ) );
+ lay->addWidget( ok );
+ resize( 200, 200 );
+}
+
+void KOStopTodoPrefs::accept()
+{
+ qDebug("KOStopTodoPrefs::accept() ");
+ QDialog::accept();
+}
+void KOStopTodoPrefs::doNotSave()
+{
+
+ int result = KMessageBox::warningContinueCancel(this,
+ i18n("Do you really want to set\nthe state to stopped\nwithout saving the data?"),mTodo->summary() );
+ if (result != KMessageBox::Continue) return;
+ mTodo->stopRunning();
+ QDialog::accept();
+}
+
+
class KOTodoViewWhatsThis :public QWhatsThis
{
public:
KOTodoViewWhatsThis( QWidget *wid, KOTodoView* view ) : QWhatsThis( wid ), _wid(wid),_view (view) { };
protected:
virtual QString text( const QPoint& p)
{
return _view->getWhatsThisText(p) ;
}
private:
QWidget* _wid;
KOTodoView * _view;
};
KOTodoListView::KOTodoListView(Calendar *calendar,QWidget *parent,
const char *name) :
KListView(parent,name)
{
mName = QString ( 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) {
Incidence *to = destinationEvent;
while(to) {
if (to->uid() == todo->uid()) {
KMessageBox::sorry(this,
i18n("Cannot move Todo to itself\nor a child of itself"),
i18n("Drop Todo"));
delete todo;
return;
}
to = to->relatedTo();
}
internalDrop = true;
if ( destinationEvent )
reparentTodoSignal( destinationEvent, existingTodo );
else
unparentTodoSignal(existingTodo);
delete todo;
} else {
mCalendar->addTodo(todo);
emit todoDropped(todo, KOGlobals::EVENTADDED);
if ( destinationEvent )
reparentTodoSignal( destinationEvent, todo );
}
}
else {
QString text;
if (QTextDrag::decode(e,text)) {
@@ -1002,271 +1045,276 @@ void KOTodoView::beamTodo()
void KOTodoView::showTodo()
{
if (mActiveItem) {
emit showTodoSignal(mActiveItem->todo());
}
}
void KOTodoView::deleteTodo()
{
if (mActiveItem) {
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->isOn() ) {
mActiveItem->setOn( true );
return;
} else if ( mPercentage[index] != 100 && mActiveItem->isOn() ) {
KOTodoViewItem* par = (static_cast<KOTodoViewItem*>(mActiveItem->parent()));
if ( par && par->isOn() )
par->setOn( false );
}
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 ();
QString colcat = categories.first();
if (categories.find (mCategory[index]) != categories.end ())
categories.remove (mCategory[index]);
else
categories.insert (categories.end(), mCategory[index]);
categories.sort ();
if ( !colcat.isEmpty() ) {
if ( categories.find ( colcat ) != categories.end () ) {
categories.remove( colcat );
categories.prepend( colcat );
}
}
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 ( pendingSubtodo != 0 ) {
topLevelWidget()->setCaption(i18n("Reparenting aborted!"));
}
pendingSubtodo = 0;
//int row = mTodoListView->header()->sectionAt ( mTodoListView->header()->mapFromGlobal( QCursor::pos()).x() );
int row = mTodoListView->header()->sectionAt ( mTodoListView->viewportToContents(mTodoListView->viewport()->mapFromGlobal( QCursor::pos())) .x() );
//qDebug("ROW %d ", row);
if (!item) {
newTodo();
return;
} else {
if ( row == 2 || row == 1 ) {
mActiveItem = (KOTodoViewItem *) item;
newSubTodo();
return;
}
if ( row == 5 || row == 6 ) {
mActiveItem = (KOTodoViewItem *) item;
toggleRunningItem();
return;
}
}
if ( KOPrefs::instance()->mEditOnDoubleClick )
editItem( item );
else
showItem( item , QPoint(), 0 );
}
void KOTodoView::toggleRunningItem()
{
// qDebug("KOTodoView::toggleRunning() ");
if ( ! mActiveItem )
return;
Todo * t = mActiveItem->todo();
if ( t->isRunning() ) {
-#if 0
- int result = KMessageBox::warningContinueCancel(this,
- i18n("The todo\n%1\nis started.\nDo you want to set\nthe state to stopped?").arg(mActiveItem->text(0).left( 25 ) ),i18n("Todo is started"),i18n("Stop todo"),i18n("Cancel"), true);
-#endif
+
+ KOStopTodoPrefs tp ( t, this );
+ tp.exec();
+
+
+#if 0
int result = KMessageBox::warningYesNoCancel(this,
i18n("The todo\n%1\nis started.\nDo you want to set\nthe state to stopped?").arg(mActiveItem->text(0).left( 25 ) ),i18n("Todo is started"),i18n("Stop"),i18n("Stop+note"));
if (result == KMessageBox::Cancel) return;
if ( result == KMessageBox::No ) {
QString comment = QInputDialog::getText(mActiveItem->text(0).left( 25 ),i18n("Comment for todo:") );
t->setRunningFalse( comment );
} else {
t->setRunning( false );
}
mActiveItem->construct();
+
+
+#endif
} else {
int result = KMessageBox::warningContinueCancel(this,
i18n("The todo\n%1\nis stopped.\nDo you want to set\nthe state to started?").arg(mActiveItem->text(0).left( 25 ) ),i18n("Todo is stopped"),i18n("Start todo"),i18n("Cancel"), true);
if (result != KMessageBox::Continue) return;
t->setRunning( true );
mActiveItem->construct();
}
}
void KOTodoView::itemClicked(QListViewItem *item)
{
//qDebug("KOTodoView::itemClicked %d", item);
if (!item) {
if ( pendingSubtodo != 0 ) {
topLevelWidget()->setCaption(i18n("Reparenting aborted!"));
}
pendingSubtodo = 0;
return;
}
KOTodoViewItem *todoItem = (KOTodoViewItem *)item;
if ( pendingSubtodo != 0 ) {
bool allowReparent = true;
QListViewItem *par = item;
while ( par ) {
if ( par == pendingSubtodo ) {
allowReparent = false;
break;
}
par = par->parent();
}
if ( !allowReparent ) {
topLevelWidget()->setCaption(i18n("Recursive reparenting not possible!"));
pendingSubtodo = 0;
} else {
Todo* newParent = todoItem->todo();
Todo* newSub = pendingSubtodo->todo();
pendingSubtodo = 0;
emit reparentTodoSignal( newParent,newSub );
return;
}
}
}
void KOTodoView::setDocumentId( const QString &id )
{
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::setAllOpen()
{
if ( isFlatDisplay ) {
isFlatDisplay = false;
mPopupMenu->setItemChecked( 8,false );
updateView();
} else {
storeCurrentItem();
}
setOpen(mTodoListView->firstChild(), true);
resetCurrentItem();
}
void KOTodoView::setAllClose()
{
if ( isFlatDisplay ) {
isFlatDisplay = false;
mPopupMenu->setItemChecked( 8,false );
updateView();
} else {
storeCurrentItem();
}
setOpen(mTodoListView->firstChild(), false);
resetCurrentItem();
}
void KOTodoView::setOpen( QListViewItem* item, bool setOpenI)
{
while ( item ) {
setOpen( item->firstChild(), setOpenI );
item->setOpen( setOpenI );
item = item->nextSibling();
diff --git a/korganizer/kotodoview.h b/korganizer/kotodoview.h
index 1ffc34a..ceabdba 100644
--- a/korganizer/kotodoview.h
+++ b/korganizer/kotodoview.h
@@ -1,183 +1,201 @@
/*
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.
*/
#ifndef KOTODOVIEW_H
#define KOTODOVIEW_H
#include <qfont.h>
#include <qfontmetrics.h>
#include <qlineedit.h>
#include <qptrlist.h>
#include <qstrlist.h>
#include <qlistbox.h>
#include <qpopupmenu.h>
#include <qlabel.h>
#include <qmap.h>
+#include <qdialog.h>
+#include <qlabel.h>
#include <qlistview.h>
#include <klistview.h>
#include <libkcal/calendar.h>
#include <libkcal/todo.h>
#include <korganizer/baseview.h>
#include "kotodoviewitem.h"
#include "koprefs.h"
#include "koglobals.h"
#include "datenavigator.h"
class QDragEnterEvent;
class QDragMoveEvent;
class QDragLeaveEvent;
class QDropEvent;
class KOTodoViewWhatsThis;
class DocPrefs;
+
+class KOStopTodoPrefs : public QDialog
+{
+ Q_OBJECT
+ public:
+ KOStopTodoPrefs( Todo* todo, QWidget *parent=0, const char *name=0 ) ;
+
+
+private slots:
+ void doNotSave();
+ void accept();
+private:
+ Todo* mTodo;
+
+};
+
class KOTodoListView : public KListView
{
Q_OBJECT
public:
KOTodoListView(Calendar *,QWidget *parent=0,const char *name=0);
virtual ~KOTodoListView() {}
signals:
void paintNeeded();
void todoDropped(Todo *, int);
void double_Clicked(QListViewItem *item);
void reparentTodoSignal( Todo *,Todo * );
void unparentTodoSignal(Todo *);
void deleteTodo( Todo * );
protected:
void wheelEvent (QWheelEvent *e);
void contentsDragEnterEvent(QDragEnterEvent *);
void contentsDragMoveEvent(QDragMoveEvent *);
void contentsDragLeaveEvent(QDragLeaveEvent *);
void contentsDropEvent(QDropEvent *);
void contentsMousePressEvent(QMouseEvent *);
void contentsMouseMoveEvent(QMouseEvent *);
void contentsMouseReleaseEvent(QMouseEvent *);
void contentsMouseDoubleClickEvent(QMouseEvent *);
private:
void paintEvent(QPaintEvent * pevent);
bool internalDrop;
QString mName;
Calendar *mCalendar;
QPoint mPressPos;
bool mMousePressed;
QListViewItem *mOldCurrent;
bool mFlagKeyPressed;
void keyPressEvent ( QKeyEvent * ) ;
void keyReleaseEvent ( QKeyEvent * ) ;
};
/**
This is the line-edit on top of the todoview for fast addition of new todos
*/
class KOQuickTodo : public QLineEdit
{
public:
KOQuickTodo(QWidget *parent=0);
protected:
void focusInEvent(QFocusEvent *ev);
void focusOutEvent(QFocusEvent *ev);
};
/**
This class provides a multi-column list view of todo events.
@short multi-column list view of todo events.
@author Cornelius Schumacher <schumacher@kde.org>
*/
class KOTodoView : public KOrg::BaseView
{
Q_OBJECT
public:
KOTodoView(Calendar *, QWidget* parent=0, const char* name=0 );
~KOTodoView();
QPtrList<Incidence> selectedIncidences();
QPtrList<Todo> selectedTodos();
DateList selectedDates()
{DateList q;
return q;}
/** Return number of shown dates. TodoView does not show dates, */
int currentDateCount() { return 0; }
void printPreview(CalPrinter *calPrinter, const QDate &fd, const QDate &td);
void setDocumentId( const QString & );
void saveLayout(KConfig *config, const QString &group) const;
void restoreLayout(KConfig *config, const QString &group);
/** Create a popup menu to set categories */
QPopupMenu *getCategoryPopupMenu (KOTodoViewItem *todoItem);
void setNavigator( DateNavigator* nav ) {mNavigator = nav;}
QString getWhatsThisText(QPoint p);
void clearList() {mTodoListView->clear(); }
public slots:
void updateView();
void updateConfig();
void changeEventDisplay(Event *, int);
void showDates(const QDate &start, const QDate &end);
void showEvents(QPtrList<Event> eventList);
void clearSelection();
void jumpToDate ();
void editItem(QListViewItem *item);
void showItem(QListViewItem *item,const QPoint &,int);
void popupMenu(QListViewItem *item,const QPoint &,int);
void newTodo();
void newSubTodo();
void unparentTodo();
void reparentTodo();
void showTodo();
void editTodo();
void cloneTodo();
void cancelTodo();
void moveTodo();
void beamTodo();
void deleteTodo();
void setNewPriority(int);
void setNewPercentage(int);
void changedCategories(int);
void setAllOpen();
void setAllClose();
void setAllFlat();
void displayAllFlat();
void purgeCompleted();
void toggleCompleted();
void toggleRunning();
void toggleQuickTodo();
diff --git a/korganizer/kotodoviewitem.cpp b/korganizer/kotodoviewitem.cpp
index f62aab8..0cf6e4c 100644
--- a/korganizer/kotodoviewitem.cpp
+++ b/korganizer/kotodoviewitem.cpp
@@ -235,257 +235,257 @@ void KOTodoViewItem::stateChange(bool state)
}
QString keyd = "==";
QString keyt = "==";
//qDebug("KOTodoViewItem::stateChange %s ", text(0).latin1());
if ( mTodo->doesRecur() ){
QDateTime start = mTodo->dtStart();
mTodo->setCompleted(state);
if ( start != mTodo->dtStart() ) {
if ( state && !mTodo->isCompleted() ) {
setOn( false );
state = false;
}
}
} else
mTodo->setCompleted(state);
if (state) mTodo->setCompleted(QDateTime::currentDateTime());
if (mTodo->hasDueDate()) {
setText(3, mTodo->dtDueDateStr());
QDate d = mTodo->dtDue().date();
keyd.sprintf("%04d%02d%02d",d.year(),d.month(),d.day());
setSortKey(3,keyd);
if (mTodo->doesFloat()) {
setText(4,"");
}
else {
setText(4,mTodo->dtDueTimeStr());
QTime t = mTodo->dtDue().time();
keyt.sprintf("%02d%02d",t.hour(),t.minute());
setSortKey(4,keyt);
}
}
if (mTodo->hasStartDate()) {
QString skeyt = "==";
QString skeyd = "==";
setText(5, mTodo->dtStartDateStr());
QDate d = mTodo->dtStart().date();
skeyd.sprintf("%04d%02d%02d",d.year(),d.month(),d.day());
if (mTodo->doesFloat()) {
setText(6,"");
}
else {
setText(6,mTodo->dtStartTimeStr());
QTime t = mTodo->dtStart().time();
skeyt.sprintf("%02d%02d",t.hour(),t.minute());
}
setSortKey(5,skeyd);
setSortKey(6,skeyt);
}
if (mTodo->isCompleted()) setSortKey(1,QString::number(9)+keyd+keyt);
else setSortKey(1,QString::number(mTodo->priority())+keyd+keyt);
setText(2,i18n("%1 %").arg(QString::number(mTodo->percentComplete())));
if (mTodo->percentComplete()<100) {
if (mTodo->isCompleted()) setSortKey(2,QString::number(999));
else setSortKey(2,QString::number(mTodo->percentComplete()));
}
else {
if (mTodo->isCompleted()) setSortKey(2,QString::number(999));
else setSortKey(2,QString::number(99));
}
if ( state ) {
QListViewItem * myChild = firstChild();
KOTodoViewItem *item;
while( myChild ) {
//qDebug("stateCH ");
item = static_cast<KOTodoViewItem*>(myChild);
item->stateChange(state);
myChild = myChild->nextSibling();
}
} else {
QListViewItem * myChild = parent();
if ( myChild )
(static_cast<KOTodoViewItem*>(myChild))->stateChange(state);
}
mTodoView->modified(true);
setMyPixmap();
mTodoView->setTodoModified( mTodo );
}
bool KOTodoViewItem::isAlternate()
{
KOTodoListView *lv = static_cast<KOTodoListView *>(listView());
if (lv && lv->alternateBackground().isValid())
{
KOTodoViewItem *above = 0;
above = static_cast<KOTodoViewItem *>(itemAbove());
m_known = above ? above->m_known : true;
if (m_known)
{
m_odd = above ? !above->m_odd : false;
}
else
{
KOTodoViewItem *item;
bool previous = true;
if (QListViewItem::parent())
{
item = static_cast<KOTodoViewItem *>(QListViewItem::parent());
if (item)
previous = item->m_odd;
item = static_cast<KOTodoViewItem *>(QListViewItem::parent()->firstChild());
}
else
{
item = static_cast<KOTodoViewItem *>(lv->firstChild());
}
while(item)
{
item->m_odd = previous = !previous;
item->m_known = true;
item = static_cast<KOTodoViewItem *>(item->nextSibling());
}
}
return m_odd;
}
return false;
}
void KOTodoViewItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment)
{
QColorGroup _cg = cg;
QColorGroup::ColorRole role;
- if ( KOPrefs::instance()->mTodoViewUsesForegroundColor )
+ if ( KOPrefs::instance()->mTodoViewUsesForegroundColor && !mTodo->isRunning())
role = QColorGroup::Text;
else
role = QColorGroup::Base;
//#ifndef KORG_NOLVALTERNATION
if (isAlternate())
_cg.setColor(QColorGroup::Base, static_cast< KOTodoListView* >(listView())->alternateBackground());
bool setColor = KOPrefs::instance()->mTodoViewUsesCatColors;
QColor colorToSet;
if ( column == 0 && mTodo->calID() > 1 ) {
setColor = true;
colorToSet = KOPrefs::instance()->defaultColor( mTodo->calID() );
} else if ( setColor ) {
QStringList categories = mTodo->categories();
QString cat = categories.first();
if ( !cat.isEmpty()) {
colorToSet = *(KOPrefs::instance()->categoryColor(cat) );
} else
setColor = false;
}
bool openMode = !isOpen();
// maybe we are in flat-display-mode
if ( !firstChild() )
openMode = false;
bool colorRunning = mTodo->isRunning();
if ( ! colorRunning && openMode )
colorRunning = mTodo->hasRunningSub();
if ( colorRunning ) {
setColor = true;
colorToSet = KOPrefs::instance()->mTodoRunColor;
} else {
int odue = mTodo->hasDueSubTodo( openMode );
if (odue == 2) {
colorToSet = KOPrefs::instance()->mTodoOverdueColor;
setColor = true;
} else if ( odue == 1 ) {
colorToSet = KOPrefs::instance()->mTodoDueTodayColor;
setColor = true;
}
}
if ( setColor ) {
_cg.setColor(role,colorToSet );
if ( role == QColorGroup::Base) {
int rgb = colorToSet.red();
rgb += colorToSet.blue()/2;
rgb += colorToSet.green();
if ( rgb < 200 )
_cg.setColor(QColorGroup::Text,Qt::white );
}
}
//#endif
if ( column > 0 ){
if ( column == 2 && !KOPrefs::instance()->mTodoViewShowsPercentage ) {
p->save();
int progress = (int)(( (width-6)*mTodo->percentComplete())/100.0 + 0.5);
p->fillRect( 0, 0, width, height(), _cg.base() ); // background
// p->setPen(Qt::black ); //border
// p->setBrush( KOPrefs::instance()->mHighlightColorKGlobalSettings::baseColor() ); //filling
QColor fc = KOPrefs::instance()->mHighlightColor;
if ( mTodo->percentComplete() == 100 )
fc = darkGreen;
p->drawRect( 2, 2, width-4, height()-4);
p->fillRect( 3, 3, progress, height()-6,
fc );
p->restore();
} else {
QCheckListItem::paintCell(p, _cg, column, width, alignment);
}
return;
}
int align = alignment;
if ( !p )
return;
p->fillRect( 0, 0, width, height(), _cg.brush( QColorGroup::Base ) );
QListView *lv = listView();
if ( !lv )
return;
int marg = 2;//lv->itemMargin();
int r = 0;
QCheckListItem::Type myType = QCheckListItem::CheckBox;
int BoxSize = 20;
int boxOffset = 2;
int xOffset = 2;
if (qApp->desktop()->width() < 300 ) {
BoxSize = 14;
boxOffset = -1;
xOffset = 1;
// marg = 0;
}
if ( height() < BoxSize ) {
boxOffset = boxOffset - ((BoxSize - height())/2) ;
// qDebug("boxOffset %d height %d", boxOffset, height() );
BoxSize = height();
}
//bool winStyle = lv->style() == WindowsStyle;
int lineStart = 5;
if ( myType == Controller ) {
if ( !pixmap( 0 ) )
r += BoxSize + 4;
} else {
ASSERT( lv ); //###
// QFontMetrics fm( lv->font() );
// int d = fm.height();
int x = 0;
int y = (height() - BoxSize) / 2;
// p->setPen( QPen( _cg.text(), winStyle ? 2 : 1 ) );
if ( myType == CheckBox ) {
if ( isEnabled() )
p->setPen( QPen( _cg.text(), 1 ) );
else
p->setPen( QPen( listView()->palette().color( QPalette::Disabled, QColorGroup::Text ), 1 ) );
p->drawRect( x+marg, y+2, BoxSize-4, BoxSize-4 );
lineStart = x+marg;
/////////////////////
x++;
y++;
if ( isOn() ) {
QPointArray a( 7*2 );
int i, xx, yy;
xx = x+xOffset+marg+(boxOffset/2);
diff --git a/libkcal/todo.cpp b/libkcal/todo.cpp
index e98af3c..d062492 100644
--- a/libkcal/todo.cpp
+++ b/libkcal/todo.cpp
@@ -1,226 +1,234 @@
/*
This file is part of libkcal.
Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#include <kglobal.h>
#include <kglobalsettings.h>
#include <klocale.h>
#include <kdebug.h>
#include <qregexp.h>
#include <qfileinfo.h>
#include "calendarlocal.h"
#include "icalformat.h"
#include "todo.h"
using namespace KCal;
Todo::Todo(): QObject(), Incidence()
{
// mStatus = TENTATIVE;
mHasDueDate = false;
setHasStartDate( false );
mCompleted = getEvenTime(QDateTime::currentDateTime());
mHasCompletedDate = false;
mPercentComplete = 0;
mRunning = false;
mRunSaveTimer = 0;
}
Todo::Todo(const Todo &t) : QObject(),Incidence(t)
{
mDtDue = t.mDtDue;
mHasDueDate = t.mHasDueDate;
mCompleted = t.mCompleted;
mHasCompletedDate = t.mHasCompletedDate;
mPercentComplete = t.mPercentComplete;
mRunning = false;
mRunSaveTimer = 0;
}
Todo::~Todo()
{
setRunning( false );
//qDebug("Todo::~Todo() ");
}
void Todo::setRunningFalse( QString s )
{
if ( ! mRunning )
return;
mRunning = false;
mRunSaveTimer->stop();
saveRunningInfoToFile( s );
}
+void Todo::stopRunning()
+{
+ if ( !mRunning )
+ return;
+ if ( mRunSaveTimer )
+ mRunSaveTimer->stop();
+ mRunning = false;
+}
void Todo::setRunning( bool run )
{
if ( run == mRunning )
return;
//qDebug("Todo::setRunning %d ", run);
if ( !mRunSaveTimer ) {
mRunSaveTimer = new QTimer ( this );
connect ( mRunSaveTimer, SIGNAL( timeout() ), this , SLOT ( saveRunningInfoToFile() ) );
}
mRunning = run;
if ( mRunning ) {
mRunSaveTimer->start( 1000 * 60 * 5 ); // 5 min
mRunStart = QDateTime::currentDateTime();
} else {
mRunSaveTimer->stop();
saveRunningInfoToFile();
}
}
void Todo::saveRunningInfoToFile()
{
saveRunningInfoToFile( QString::null );
}
void Todo::saveRunningInfoToFile( QString comment )
{
//qDebug("Todo::saveRunningInfoToFile() %s", summary().latin1());
- if ( mRunStart.secsTo ( QDateTime::currentDateTime() ) < 30 ) {
+ if ( mRunStart.secsTo ( QDateTime::currentDateTime() ) < 10 ) {
qDebug("Running time < 30 seconds. Skipped. ");
return;
}
QString dir = KGlobalSettings::timeTrackerDir();
//qDebug("%s ", dir.latin1());
QString file = "%1%2%3-%4%5%6-";
file = file.arg( mRunStart.date().year(), 4).arg( mRunStart.date().month(),2 ).arg( mRunStart.date().day(), 2 ).arg( mRunStart.time().hour(),2 ).arg( mRunStart.time().minute(),2 ).arg( mRunStart.time().second(),2 );
file.replace ( QRegExp (" "), "0" );
file += uid();
//qDebug("File %s ",file.latin1() );
CalendarLocal cal;
cal.setLocalTime();
Todo * to = (Todo*) clone();
to->setFloats( false );
to->setDtStart( mRunStart );
to->setHasStartDate( true );
to->setDtDue( QDateTime::currentDateTime() );
to->setHasDueDate( true );
to->setUid( file );
if ( !comment.isEmpty() ) {
QString des = to->description();
if ( des.isEmpty () )
to->setDescription( "TT-Note: " + comment );
else
to->setDescription( "TT-Note: " + comment +"\n" + des );
}
cal.addIncidence( to );
ICalFormat format;
file = dir +"/" +file +".ics";
format.save( &cal, file );
saveParents();
}
void Todo::saveParents()
{
if (!relatedTo() )
return;
Incidence * inc = relatedTo();
if ( inc->typeID() != todoID )
return;
Todo* to = (Todo*)inc;
bool saveTodo = false;
QString file = KGlobalSettings::timeTrackerDir() + "/"+ to->uid() + ".ics";
QFileInfo fi ( file );
if ( fi.exists() ) {
if ( fi.lastModified () < to->lastModified ())
saveTodo = true;
} else {
saveTodo = true;
}
if ( saveTodo ) {
CalendarLocal cal;
cal.setLocalTime();
Todo * par = (Todo *) to->clone();
cal.addIncidence( par );
ICalFormat format;
format.save( &cal, file );
}
to->saveParents();
}
int Todo::runTime()
{
if ( !mRunning )
return 0;
return mRunStart.secsTo( QDateTime::currentDateTime() );
}
bool Todo::hasRunningSub()
{
if ( mRunning )
return true;
Incidence *aTodo;
for (aTodo = mRelations.first(); aTodo; aTodo = mRelations.next()) {
if ( ((Todo*)aTodo)->hasRunningSub() )
return true;
}
return false;
}
Incidence *Todo::clone()
{
return new Todo(*this);
}
bool Todo::contains ( Todo* from )
{
if ( !from->summary().isEmpty() )
if ( !summary().startsWith( from->summary() ))
return false;
if ( from->hasStartDate() ) {
if ( !hasStartDate() )
return false;
if ( from->dtStart() != dtStart())
return false;
}
if ( from->hasDueDate() ){
if ( !hasDueDate() )
return false;
if ( from->dtDue() != dtDue())
return false;
}
if ( !from->location().isEmpty() )
if ( !location().startsWith( from->location() ) )
return false;
if ( !from->description().isEmpty() )
if ( !description().startsWith( from->description() ))
return false;
if ( from->alarms().count() ) {
Alarm *a = from->alarms().first();
if ( a->enabled() ){
if ( !alarms().count() )
return false;
Alarm *b = alarms().first();
if( ! b->enabled() )
return false;
if ( ! (a->offset() == b->offset() ))
return false;
}
}
QStringList cat = categories();
QStringList catFrom = from->categories();
QString nCat;
unsigned int iii;
for ( iii = 0; iii < catFrom.count();++iii ) {
nCat = catFrom[iii];
if ( !nCat.isEmpty() )
if ( !cat.contains( nCat )) {
diff --git a/libkcal/todo.h b/libkcal/todo.h
index 6fc4d4b..42db025 100644
--- a/libkcal/todo.h
+++ b/libkcal/todo.h
@@ -1,152 +1,153 @@
/*
This file is part of libkcal.
Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
*/
#ifndef TODO_H
#define TODO_H
//
// Todo component, representing a VTODO object
//
#include "incidence.h"
#include <qtimer.h>
namespace KCal {
/**
This class provides a Todo in the sense of RFC2445.
*/
class Todo : public QObject,public Incidence
{
Q_OBJECT
public:
Todo();
Todo(const Todo &);
~Todo();
typedef ListBase<Todo> List;
QCString type() const { return "Todo"; }
IncTypeID typeID() const { return todoID; }
/** Return an exact copy of this todo. */
Incidence *clone();
QDateTime getNextAlarmDateTime( bool * ok, int * offset, QDateTime start_dt ) const;
/** for setting the todo's due date/time with a QDateTime. */
void setDtDue(const QDateTime &dtDue);
/** returns an event's Due date/time as a QDateTime. */
QDateTime dtDue() const;
/** returns an event's due time as a string formatted according to the
users locale settings */
QString dtDueTimeStr() const;
/** returns an event's due date as a string formatted according to the
users locale settings */
QString dtDueDateStr(bool shortfmt=true) const;
/** returns an event's due date and time as a string formatted according
to the users locale settings */
QString dtDueStr(bool shortfmt=true) const;
/** returns TRUE or FALSE depending on whether the todo has a due date */
bool hasDueDate() const;
/** sets the event's hasDueDate value. */
void setHasDueDate(bool f);
/*
Looks for a subtodo (including itself ) which is not complete and is
- overdue, or
- due today.
It returns 0 for nothing found,
1 for found a todo which is due today and no overdue found
2 for found a overdue todo
*/
int hasDueSubTodo( bool checkSubtodos = true );
/* same as above, but a specific date can be specified*/
int hasDueSubTodoForDate( const QDate & date, bool checkSubtodos );
/** sets the event's status to the string specified. The string
* must be a recognized value for the status field, i.e. a string
* equivalent of the possible status enumerations previously described. */
// void setStatus(const QString &statStr);
/** sets the event's status to the value specified. See the enumeration
* above for possible values. */
// void setStatus(int);
/** return the event's status. */
// int status() const;
/** return the event's status in string format. */
// QString statusStr() const;
/** return, if this todo is completed */
bool isCompleted() const;
/** set completed state of this todo */
void setCompleted(bool);
/**
Return how many percent of the task are completed. Returns a value
between 0 and 100.
*/
int percentComplete() const;
/**
Set how many percent of the task are completed. Valid values are in the
range from 0 to 100.
*/
void setPercentComplete(int);
/** return date and time when todo was completed */
QDateTime completed() const;
QString completedStr(bool shortF = true) const;
/** set date and time of completion */
void setCompleted(const QDateTime &completed);
/** Return true, if todo has a date associated with completion */
bool hasCompletedDate() const;
bool contains ( Todo*);
void checkSetCompletedFalse();
bool setRecurDates();
bool isRunning() {return mRunning;}
bool hasRunningSub();
void setRunning( bool );
void setRunningFalse( QString );
+ void stopRunning();
int runTime();
QDateTime runStart () const { return mRunStart;}
public slots:
void saveRunningInfoToFile( QString st );
void saveRunningInfoToFile( );
void saveParents();
private:
bool mRunning;
QTimer * mRunSaveTimer;
QDateTime mRunStart;
bool accept(Visitor &v) { return v.visit(this); }
QDateTime mDtDue; // due date of todo
bool mHasDueDate; // if todo has associated due date
// int mStatus; // confirmed/delegated/tentative/etc
QDateTime mCompleted;
bool mHasCompletedDate;
int mPercentComplete;
};
bool operator==( const Todo&, const Todo& );
}
#endif