[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-pim
Subject: [Kde-pim] karm logging patch
From: Mark Bucciarelli <mark () easymailings ! com>
Date: 2003-04-28 3:44:29
[Download RAW message or body]
The attached path makes it possible to (almost) reconstruct task
history from the karm log file. It:
(1) logs task renames
(2) logs the change in time when someone resets total or session time.
It's a lot of code, mainly because I decided to create a KarmEvent
base class and then implement subclasses for each type of event that
gets logged. It's over-designed, but that's probably because I'm
just getting warmed up with c++.
Anyway, it's a cleaner design. If the events are ever supposed to
trigger something other than an XML log entry, you can just add a new
toSomething() method to each event. Also, new events (for example,
delete_task, add_task) will not touch any existing code, just require
a new subclass.
I also made a few mods to the TODO list based on what I read in the
sources.
I'll wait to hear from Tomas before applying.
Mark
P.S. How come the following code doesn't compile?
QString s = "something about " + "binary operator and const char[17]";
["karmlogging.patch" (text/x-diff)]
? karmlogging.patch
Index: TODO
===================================================================
RCS file: /home/kde/kdepim/karm/TODO,v
retrieving revision 1.6
diff -u -p -r1.6 TODO
--- TODO 13 Jan 2003 01:40:44 -0000 1.6
+++ TODO 28 Apr 2003 03:50:40 -0000
@@ -1,4 +1,5 @@
-* times can be negative - does that make any sense?
+$Id: $
+
* one can adjust subtask *and* task times which has the effect that times
won't add up any more - does that make sense?
* add notes to logentries
@@ -10,6 +11,11 @@
* mainwindow: move tray signals into tray.cpp
* formatTime has nothing to do in TaskView?
* "#ifndef header"s are inconsistent
+* mainwindow.cpp: before loading view, check whether the file exists
+ and if not, create a blank one and ask wheter we want to add a task.
+* add mouse double-click action (start new timer, stop old) to "Configure
+ Shortcuts" dialog.
+
* Willi:
--------
* If one starts karm and installs some desktop tracking tasks nothing
Index: logging.cpp
===================================================================
RCS file: /home/kde/kdepim/karm/logging.cpp,v
retrieving revision 1.2
diff -u -p -r1.2 logging.cpp
--- logging.cpp 13 Jan 2003 01:49:51 -0000 1.2
+++ logging.cpp 28 Apr 2003 03:50:41 -0000
@@ -8,11 +8,134 @@
#include <qregexp.h>
#include <iostream>
-#define LOG_START 1
-#define LOG_STOP 2
-#define LOG_NEW_TOTAL_TIME 3
-#define LOG_NEW_SESSION_TIME 4
+#define QS(c) QString::fromLatin1(c)
+
+//
+// E V E N T S
+//
+QString KarmEvent::escapeXML( QString string ) {
+
+ QString result = QString(string);
+ result.replace( QRegExp(QS("&")), QS("&") );
+ result.replace( QRegExp(QS("<")), QS("<") );
+ result.replace( QRegExp(QS(">")), QS(">") );
+ result.replace( QRegExp(QS("'")), QS("'") );
+ result.replace( QRegExp(QS("\"")), QS(""") );
+ // protect also our task-separator
+ result.replace( QRegExp(QS("/")), QS("&slash;") );
+
+ return result;
+}
+
+// common stuff
+void KarmEvent::loadCommonFields( Task *task) {
+ eventTime = QDateTime::currentDateTime();
+
+ QListViewItem *item = task;
+ fullName = escapeXML(task->name());
+ while( ( item = item->parent() ) )
+ {
+ fullName = escapeXML(((Task *)item)->name())
+ + fullName.prepend('/');
+ }
+}
+
+// start
+StartEvent::StartEvent( Task *task ) {
+ loadCommonFields(task);
+}
+
+QString StartEvent::toXML() {
+ // There's got to be an easier way to concatenate strings ...
+ QString s;
+ QTextStream ts( &s, IO_WriteOnly);
+
+ ts << "<starting"
+ << " task=\"" << fullName << "\""
+ << " date=\"" << eventTime.toString() << "\""
+ << " />\n";
+ return (s);
+}
+
+// stop
+StopEvent::StopEvent( Task *task ) {
+ loadCommonFields(task);
+}
+
+QString StopEvent::toXML() {
+ QString s;
+ QTextStream ts( &s, IO_WriteOnly);
+
+ ts << "<stopping"
+ << " task=\"" << fullName << "\""
+ << " date=\"" << eventTime.toString() << "\""
+ << " />\n";
+ return (s);
+}
+
+// rename
+RenameEvent::RenameEvent( Task *task, QString& old ) {
+ loadCommonFields(task);
+ oldName = old;
+}
+
+QString RenameEvent::toXML() {
+ QString s;
+ QTextStream ts( &s, IO_WriteOnly);
+
+ ts << "<renaming"
+ << " task=\"" << fullName << "\""
+ << " date=\"" << eventTime.toString() << "\""
+ << " old_name=\"" << oldName << "\""
+ << " />\n";
+ return (s);
+}
+
+// set session
+SessionTimeEvent::SessionTimeEvent( Task *task, long total, long change) {
+ loadCommonFields(task);
+ delta = change;
+ newTotal = total;
+}
+
+QString SessionTimeEvent::toXML() {
+ QString s;
+ QTextStream ts( &s, IO_WriteOnly);
+
+ ts << "<new_session_time"
+ << " task=\"" << fullName << "\""
+ << " date=\"" << eventTime.toString() << "\""
+ << " new_total=\"" << newTotal << "\""
+ << " change=\"" << delta << "\""
+ << " />" << endl;
+ return (s);
+}
+
+// set total
+TotalTimeEvent::TotalTimeEvent( Task *task, long total, long change) {
+ loadCommonFields(task);
+ delta = change;
+ newTotal = total;
+}
+
+QString TotalTimeEvent::toXML() {
+ QString s;
+ QTextStream ts( &s, IO_WriteOnly);
+
+ ts << "<new_total_time"
+ << " task=\"" << fullName << "\""
+ << " date=\"" << eventTime.toString() << "\""
+ << " new_total=\"" << newTotal << "\""
+ << " change=\"" << delta << "\""
+ << " />" << endl;
+
+ return (s);
+}
+
+//
+// L O G G I N G
+//
Logging *Logging::_instance = 0;
Logging::Logging()
@@ -20,27 +143,31 @@ Logging::Logging()
_preferences = Preferences::instance();
}
-void Logging::start( Task * task)
-{
- log(task, LOG_START);
+void Logging::start( Task *task) {
+ KarmEvent* event = new StartEvent(task);
+ log(event);
+}
+void Logging::stop( Task *task) {
+ KarmEvent* event = new StopEvent(task);
+ log(event);
}
-void Logging::stop( Task * task)
-{
- log(task, LOG_STOP);
+void Logging::newTotalTime( Task *task, long minutes, long change) {
+ KarmEvent* event = new TotalTimeEvent(task, minutes, change);
+ log(event);
}
-// when time is reset...
-void Logging::newTotalTime( Task * task, long minutes)
-{
- log(task, LOG_NEW_TOTAL_TIME, minutes);
+void Logging::newSessionTime( Task *task, long minutes, long change) {
+ KarmEvent* event = new SessionTimeEvent(task, minutes, change);
+ log(event);
}
-void Logging::newSessionTime( Task * task, long minutes)
-{
- log(task, LOG_NEW_SESSION_TIME, minutes);
+
+void Logging::rename( Task *task, QString& oldName) {
+ KarmEvent* event = new RenameEvent(task, oldName);
+ log(event);
}
-void Logging::log( Task * task, short type, long minutes)
+void Logging::log( KarmEvent* event)
{
if(_preferences->timeLogging()) {
@@ -48,28 +175,7 @@ void Logging::log( Task * task, short ty
if ( f.open( IO_WriteOnly | IO_Append) ) {
QTextStream out( &f ); // use a text stream
-
- if( type == LOG_START) {
- out << "<starting ";
- } else if( type == LOG_STOP ) {
- out << "<stopping ";
- } else if( type == LOG_NEW_TOTAL_TIME) {
- out << "<new_total_time ";
- } else if( type == LOG_NEW_SESSION_TIME) {
- out << "<new_session_time ";
- } else {
- std::cerr << "Programming error!";
- }
-
- out << "task=\"" << constructTaskName(task) << "\" "
- << "date=\"" << QDateTime::currentDateTime().toString() << "\" ";
-
- if ( type == LOG_NEW_TOTAL_TIME || type == LOG_NEW_SESSION_TIME) {
- out << "new_total=\"" << minutes << "\" ";
- }
-
- out << "/>\n";
-
+ out << event->toXML();
f.close();
} else {
std::cerr << "Couldn't write to time-log file";
@@ -85,36 +191,7 @@ Logging *Logging::instance()
return _instance;
}
-QString Logging::constructTaskName(Task *task)
-{
- QListViewItem *item = task;
-
- QString name = escapeXML(task->name());
-
- while( ( item = item->parent() ) )
- {
- name = escapeXML(((Task *)item)->name()) + name.prepend('/');
- }
-
- return name;
-}
-
-// why the hell do I need to do this?!?
-#define QS(c) QString::fromLatin1(c)
-
-QString Logging::escapeXML( QString string)
-{
- QString result = QString(string);
- result.replace( QRegExp(QS("&")), QS("&") );
- result.replace( QRegExp(QS("<")), QS("<") );
- result.replace( QRegExp(QS(">")), QS(">") );
- result.replace( QRegExp(QS("'")), QS("'") );
- result.replace( QRegExp(QS("\"")), QS(""") );
- // protect also our task-separator
- result.replace( QRegExp(QS("/")), QS("&slash;") );
-
- return result;
-}
Logging::~Logging() {
}
+
Index: logging.h
===================================================================
RCS file: /home/kde/kdepim/karm/logging.h,v
retrieving revision 1.2
diff -u -p -r1.2 logging.h
--- logging.h 13 Jan 2003 01:49:51 -0000 1.2
+++ logging.h 28 Apr 2003 03:50:41 -0000
@@ -3,19 +3,70 @@
#include "preferences.h"
#include <qstring.h>
+#include <qdatetime.h>
class Task;
-/**
- * Log changes to a file.
- */
+class KarmEvent {
+protected:
+ QString name;
+ // full name includes all parents
+ QString fullName;
+ QDateTime eventTime;
+ void loadCommonFields( Task *task);
+
+ // this really doesn't belong here ...
+ QString escapeXML( QString string);
+public:
+ virtual QString toXML(void) =0;
+ // needed to avoid compiler warnings about subclasses having
+ // "virtual functions but non-virtual destructor."
+ virtual ~KarmEvent () {};
+};
+
+class StartEvent: public KarmEvent {
+public:
+ StartEvent( Task *task);
+ QString toXML();
+};
+
+class StopEvent: public KarmEvent {
+public:
+ StopEvent ( Task *task);
+ QString toXML();
+};
+
+class RenameEvent: public KarmEvent {
+private:
+ QString oldName;
+public:
+ RenameEvent( Task *task, QString& old);
+ QString toXML();
+};
+
+class SessionTimeEvent: public KarmEvent {
+private:
+ long newTotal, delta;
+public:
+ SessionTimeEvent( Task *task, long newTotal, long delta);
+ QString toXML();
+};
+
+class TotalTimeEvent: public KarmEvent {
+private:
+ long newTotal, delta;
+public:
+ TotalTimeEvent( Task *task, long newTotal, long delta );
+ QString toXML();
+};
+
class Logging {
private:
Preferences *_preferences;
static Logging *_instance;
- void log( Task *task, short type, long minutes = 0);
+ void log( KarmEvent* event );
public:
static Logging *instance();
@@ -23,14 +74,10 @@ public:
~Logging();
void start( Task *task);
void stop( Task *task);
- void newTotalTime( Task *task, long minutes);
- void newSessionTime( Task *task, long minutes);
- QString constructTaskName(Task *task);
- QString escapeXML( QString string);
-
+ void rename( Task *task, QString& oldName);
+ void newTotalTime( Task *task, long minutes, long change);
+ void newSessionTime( Task *task, long minutes, long change);
};
-#endif
-
-
+#endif
Index: task.cpp
===================================================================
RCS file: /home/kde/kdepim/karm/task.cpp,v
retrieving revision 1.19
diff -u -p -r1.19 task.cpp
--- task.cpp 24 Jan 2003 04:44:37 -0000 1.19
+++ task.cpp 28 Apr 2003 03:50:43 -0000
@@ -95,23 +95,27 @@ bool Task::isRunning() const
void Task::setName( const QString& name )
{
+ QString oldname = _name;
_name = name;
+ _logging->rename( this, oldname );
update();
}
void Task::setTotalTime ( long minutes )
{
+ long oldtime = _totalTime;
_totalTime = minutes;
noNegativeTimes();
- _logging->newTotalTime( this, _totalTime );
+ _logging->newTotalTime( this, _totalTime, (_totalTime - oldtime) );
update();
}
void Task::setSessionTime ( long minutes )
{
+ long oldtime = _sessionTime;
_sessionTime = minutes;
noNegativeTimes();
- _logging->newSessionTime( this, _sessionTime );
+ _logging->newSessionTime( this, _sessionTime, (_sessionTime - oldtime) );
update();
}
_______________________________________________
kde-pim mailing list
kde-pim@mail.kde.org
http://mail.kde.org/mailman/listinfo/kde-pim
kde-pim home page at http://pim.kde.org/
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic