From kde-pim Mon Apr 28 03:44:29 2003 From: Mark Bucciarelli Date: Mon, 28 Apr 2003 03:44:29 +0000 To: kde-pim Subject: [Kde-pim] karm logging patch X-MARC-Message: https://marc.info/?l=kde-pim&m=105150234223473 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--Boundary-00=_dOKr+0xcNzIiMBy" --Boundary-00=_dOKr+0xcNzIiMBy Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline 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]"; --Boundary-00=_dOKr+0xcNzIiMBy Content-Type: text/x-diff; charset="us-ascii"; name="karmlogging.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="karmlogging.patch" ? 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 #include -#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 << "\n"; + return (s); +} + +// stop +StopEvent::StopEvent( Task *task ) { + loadCommonFields(task); +} + +QString StopEvent::toXML() { + QString s; + QTextStream ts( &s, IO_WriteOnly); + + ts << "\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 << "\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 << "" << 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 << "" << 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 << "\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 +#include 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(); } --Boundary-00=_dOKr+0xcNzIiMBy Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ 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/ --Boundary-00=_dOKr+0xcNzIiMBy--