[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    karm: Patch for time loging
From:       "T.Pospisek's MailLists" <tpo2 () spin ! ch>
Date:       2001-05-31 15:26:31
[Download RAW message or body]

The attached patch adds to karm a runtime-configurable option to to enable
logging of times. The following events are logged:

* starting of a task
* stoping of a task
* changing of the timevalues

The format of the logfile is XML except for a missing single root.

The resulting logfile should be easily and automaticaly
transformable/manageable/exportable into anyones favoured tool for
billing, accounting of work hours etc.

Comment:
This is the first time I'm coding KDE and Qt source and the first in a few
years to code C++ again, so please be generous with possible
code-impurities of mine ;-)

I'd be happy to see the code included with karm. If this is not the right
place to post the patch to, I kindly ask to be pointed to the right place.

Thanks,
*t

-----------------------------------------------------------------------
     Tomas Pospisek
     sourcepole    -   Linux & Open Source Solutions
     http://sourcepole.com
     Elestastrasse 18,  7310 Bad Ragaz,  Switzerland
     Tel:+41 (81) 330 77 13,  Fax:+41 (81) 330 77 12
------------------------------------------------------------------------

["karm.diff" (TEXT/PLAIN)]

diff -b -B -u -N -P -r karm/loging.cpp karm.tpo/loging.cpp
--- karm/loging.cpp	Thu Jan  1 01:00:00 1970
+++ karm.tpo/loging.cpp	Fri May 25 20:59:18 2001
@@ -0,0 +1,120 @@
+#include "loging.h"
+#include "task.h"
+#include "preferences.h"
+#include <qdatetime.h>
+#include <qstring.h>
+#include <qfile.h>
+#include <qtextstream.h>
+#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
+
+Loging *Loging::_instance = 0;
+
+Loging::Loging()
+{
+	_preferences = Preferences::instance();
+}
+
+void Loging::start( Task * task)
+{
+	log(task, LOG_START);
+}
+
+void Loging::stop( Task * task)
+{
+	log(task, LOG_STOP);
+}
+
+// when time is reset...
+void Loging::newTotalTime( Task * task, long minutes)
+{
+	log(task, LOG_NEW_TOTAL_TIME, minutes);
+}
+void Loging::newSessionTime( Task * task, long minutes)
+{
+	log(task, LOG_NEW_SESSION_TIME, minutes);
+}
+
+void Loging::log( Task * task, short type, long minutes)
+{
+
+	if(_preferences->timeLoging()) {
+		QFile f(_preferences->timeLog());
+
+		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 {
+				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";
+
+			f.close();
+		} else {
+			cerr << "Couldn't write to time-log file";
+		}
+	}
+}
+
+Loging *Loging::instance()
+{
+  if (_instance == 0) {
+    _instance = new Loging();
+  }
+  return _instance;
+}
+
+QString Loging::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 Loging::escapeXML( QString string)
+{
+	QString result = QString(string);
+	result.replace( QRegExp(QS("&")),  QS("&amp;")  );
+	result.replace( QRegExp(QS("<")),  QS("&lt;")   );
+	result.replace( QRegExp(QS(">")),  QS("&gt;")   );
+	result.replace( QRegExp(QS("'")),  QS("&apos;") );
+	result.replace( QRegExp(QS("\"")), QS("&quot;") );
+	// protect also our task-separator
+	result.replace( QRegExp(QS("/")),  QS("&slash;") );
+
+	return result;
+}
+
+Loging::~Loging() {
+}
diff -b -B -u -N -P -r karm/loging.h karm.tpo/loging.h
--- karm/loging.h	Thu Jan  1 01:00:00 1970
+++ karm.tpo/loging.h	Fri May 25 19:10:27 2001
@@ -0,0 +1,32 @@
+#ifndef _LOGING_H_
+#define _LOGING_H_
+
+#include "preferences.h"
+#include <qstring.h>
+
+class Task;
+
+class Loging {
+
+private:
+  Preferences *_preferences;
+  static Loging *_instance;
+  void log( Task *task, short type, long minutes = 0);
+
+public:
+  static Loging *instance();
+  Loging();
+  ~Loging();
+  void start( Task *task);
+  void stop( Task *task);
+  void newTotalTime( Task *task, long minutes);
+  void newSessionTime( Task *task, long minutes);
+  QString Loging::constructTaskName(Task *task);
+  QString escapeXML( QString string);
+
+};
+
+#endif
+
+
+
diff -b -B -u -N -P -r karm/main.cpp karm.tpo/main.cpp
--- karm/main.cpp	Fri May 25 21:03:51 2001
+++ karm.tpo/main.cpp	Wed May 23 17:31:03 2001
@@ -14,11 +14,12 @@
 {
 	KAboutData aboutData( "karm", I18N_NOOP("KArm"),
 		KARM_VERSION, description, KAboutData::License_GPL,
-		"(c) 1997-2000, Sirtaj Singh Kang, Espen Sand, Jesper Pedersen,\nKalle Dalheimer, \
Klarälvdalens Datakonsult AB"); +		"(c) 1997-2000, Sirtaj Singh Kang, Espen Sand, \
Jesper Pedersen,\nKalle Dalheimer, Klarälvdalens Datakonsult AB, Tomas Pospisek - \
Sourcepole");  aboutData.addAuthor( "Jesper Pedersen", I18N_NOOP("Current \
Maintainer"), "blackie@kde.org" );  aboutData.addAuthor( "Sirtaj Singh Kang", \
I18N_NOOP("Original Author"), "taj@kde.org" );  aboutData.addAuthor("Espen Sand",0, \
"espen@kde.org");  aboutData.addAuthor( "Kalle Dalheimer", 0, "kalle@kde.org" );
+	aboutData.addAuthor( "Tomas Pospisek", 0, "tpo@sourcepole.ch" );
 	
 	KCmdLineArgs::init( argc, argv, &aboutData );
 	KApplication myApp;
diff -b -B -u -N -P -r karm/preferences.cpp karm.tpo/preferences.cpp
--- karm/preferences.cpp	Fri May 25 21:03:52 2001
+++ karm.tpo/preferences.cpp	Fri May 25 16:50:42 2001
@@ -27,7 +27,18 @@
   new QLabel(i18n("File to save time information to"), box3, "save label");
   _saveFileW = new QLineEdit(box3, "_saveFileW");
   
-  _doAutoSaveW = new QCheckBox(i18n("Automatically save tasks"), autoSaveMenu, \
"_doAutoSaveW"); +  _doTimeLogingW = new QCheckBox(i18n("Do time loging"), \
autoSaveMenu, +  								 "_doTimeLogingW");
+  connect(_doTimeLogingW, SIGNAL(clicked()),
+		  this, SLOT(timeLogingCheckBoxChanged()));
+  
+  QHBox *box4 = new QHBox(autoSaveMenu);
+  _timeLogingLabelW = new QLabel(i18n("File to log the times to"), box4,
+                              "save label");
+  _timeLogW = new QLineEdit(box4, "_timeLogW");
+  
+  _doAutoSaveW = new QCheckBox(i18n("Automatically save tasks"), autoSaveMenu,
+                               "_doAutoSaveW");
   connect(_doAutoSaveW, SIGNAL(clicked()), 
           this, SLOT(autoSaveCheckBoxChanged()));
   
@@ -76,6 +87,9 @@
   // set all widgets
   _saveFileW->setText(_saveFileV);
 
+  _doTimeLogingW->setChecked(_doTimeLogingV);
+  _timeLogW->setText(_timeLogV);
+
   _doIdleDetectionW->setChecked(_doIdleDetectionV);
   _idleDetectValueW->setValue(_idleDetectValueV);
 
@@ -89,6 +103,8 @@
 void Preferences::slotOk() 
 {
   _saveFileV = _saveFileW->text();
+  _timeLogV = _timeLogW->text();
+  _doTimeLogingV    = _doTimeLogingW->isChecked();
   _doIdleDetectionV = _doIdleDetectionW->isChecked();
   _idleDetectValueV = _idleDetectValueW->value();
   _doAutoSaveV    = _doAutoSaveW->isChecked();
@@ -118,9 +134,18 @@
   _autoSaveValueW->setEnabled(enabled);
 }
 
+void Preferences::timeLogingCheckBoxChanged()
+{
+  bool enabled = _doTimeLogingW->isChecked();
+  _timeLogingLabelW->setEnabled(enabled);
+  _timeLogW->setEnabled(enabled);
+}
+
 void Preferences::emitSignals() 
 {
   emit(saveFile(_saveFileV));
+  emit(timeLoging(_doTimeLogingV));
+  emit(timeLog(_timeLogV));
   emit(detectIdleness(_doIdleDetectionV));
   emit(idlenessTimeout(_idleDetectValueV));
   emit(autoSave(_doAutoSaveV));
@@ -133,6 +158,11 @@
   return _saveFileV;
 }
 
+QString Preferences::timeLog()
+{
+  return _timeLogV;
+}
+
 bool Preferences::detectIdleness()
 {
   return _doIdleDetectionV;
@@ -148,6 +178,11 @@
   return _doAutoSaveV;
 }
 
+bool Preferences::timeLoging() 
+{
+  return _doTimeLogingV;
+}
+
 int Preferences::autoSavePeriod()
 {
   return _autoSaveValueV;
@@ -169,6 +204,11 @@
   _saveFileV      = config.readEntry(QString::fromLatin1("file"), 
                                      locateLocal("appdata",
                                                  \
QString::fromLatin1("karmdata.txt"))); +  _doTimeLogingV  = \
config.readBoolEntry(QString::fromLatin1("time loging"), +  false);
+  _timeLogV   = config.readEntry(QString::fromLatin1("time log file"),
+  								 locateLocal("appdata",
+                                             QString::fromLatin1("karmlog.txt")));
   _doAutoSaveV    = config.readBoolEntry(QString::fromLatin1("auto save"), true);
   _autoSaveValueV = config.readNumEntry(QString::fromLatin1("auto save period"), 5);
 
@@ -185,6 +225,8 @@
 
   config.setGroup( QString::fromLatin1("Saving"));
   config.writeEntry( QString::fromLatin1("file"), _saveFileV);
+  config.writeEntry( QString::fromLatin1("time loging"), _doTimeLogingV);
+  config.writeEntry( QString::fromLatin1("time log file"), _timeLogV);
   config.writeEntry( QString::fromLatin1("auto save"), _doAutoSaveV);
   config.writeEntry( QString::fromLatin1("auto save period"), _autoSaveValueV);
 
diff -b -B -u -N -P -r karm/preferences.h karm.tpo/preferences.h
--- karm/preferences.h	Fri May 25 21:03:52 2001
+++ karm.tpo/preferences.h	Fri May 25 16:28:17 2001
@@ -21,6 +21,8 @@
   bool detectIdleness();
   int idlenessTimeout();
   QString saveFile();
+  bool timeLoging();
+  QString timeLog();
   bool autoSave();
   int autoSavePeriod();
 
@@ -34,6 +36,8 @@
   void detectIdleness(bool on);
   void idlenessTimeout(int minutes);
   void saveFile(QString);
+  void timeLoging(bool on);
+  void timeLog(QString);
   void autoSave(bool on);
   void autoSavePeriod(int minutes);
   void setupChanged();
@@ -43,6 +47,7 @@
   virtual void slotCancel();
   void idleDetectCheckBoxChanged();
   void autoSaveCheckBoxChanged();
+  void timeLogingCheckBoxChanged();
   
 protected:
   void emitSignals();
@@ -53,16 +58,16 @@
   bool _unsavedChanges;
 
   // Widgets in the dialog (All variables ends in W to indicate that they are \
                Widgets)
-  QCheckBox *_doIdleDetectionW, *_doAutoSaveW;
-  QLabel    *_idleDetectLabelW, *_autoSaveLabelW;
+  QCheckBox *_doIdleDetectionW, *_doAutoSaveW, *_doTimeLogingW;
+  QLabel    *_idleDetectLabelW, *_autoSaveLabelW, *_timeLogingLabelW;
   QSpinBox  *_idleDetectValueW, *_autoSaveValueW;
-  QLineEdit *_saveFileW;
+  QLineEdit *_saveFileW, *_timeLogW;
   QVBox *idleMenu;
   
   // Values for the preferences. (All variables in in V to indicate they are Values)
-  bool _doIdleDetectionV, _doAutoSaveV;
+  bool _doIdleDetectionV, _doAutoSaveV, _doTimeLogingV;
   int  _idleDetectValueV, _autoSaveValueV;
-  QString _saveFileV;
+  QString _saveFileV, _timeLogV;
   
 };
 
diff -b -B -u -N -P -r karm/task.cpp karm.tpo/task.cpp
--- karm/task.cpp	Fri May 25 21:03:53 2001
+++ karm.tpo/task.cpp	Fri May 25 20:19:22 2001
@@ -5,6 +5,7 @@
 #include <kiconloader.h>
 #include <qtimer.h>
 #include"task.h"
+#include"loging.h"
 
 
 QVector<QPixmap> *Task::icons = 0;
@@ -34,6 +35,9 @@
     }
   }
   
+  // is this the right place?
+  _loging = Loging::instance();
+
 	_name = taskName.stripWhiteSpace(); 
 	_totalTime = minutes;
   _sessionTime = sessionTime;
@@ -50,6 +54,7 @@
   if (on) {
     if (!_timer->isActive()) {
       _timer->start(1000);
+	  _loging->start(this);
       _i=7;
       updateActiveIcon();
     }
@@ -57,6 +62,7 @@
   else {
     if (_timer->isActive()) {
       _timer->stop();
+	  _loging->stop(this);
       setPixmap(1, UserIcon(QString::fromLatin1("empty-watch.xpm")));
     }
   }
@@ -71,12 +77,14 @@
 void Task::setTotalTime ( long minutes )
 {
 	_totalTime = minutes;
+	_loging->newTotalTime( this, minutes);
 	update();
 }
 
 void Task::setSessionTime ( long minutes )
 {
 	_sessionTime = minutes;
+	_loging->newSessionTime( this, minutes);
 	update();
 }
 
diff -b -B -u -N -P -r karm/task.h karm.tpo/task.h
--- karm/task.h	Fri May 25 21:03:54 2001
+++ karm.tpo/task.h	Fri May 25 20:18:54 2001
@@ -8,9 +8,11 @@
 #include <qvector.h>
 #include <qpixmap.h>
 #include "karm.h"
+#include "loging.h"
 
 class QFile;
 class QTimer;
+class Loging;
 
 /**
 	Encapsulates a task.
@@ -27,6 +29,7 @@
   QTimer *_timer;
   int _i;
   static QVector<QPixmap> *icons;
+    Loging *_loging;
 
 public:
 	/** constructor */
diff -b -B -u -N -P -r karm/Makefile.am karm.tpo/Makefile.am
--- karm/Makefile.am	Fri May 25 21:03:45 2001
+++ karm.tpo/Makefile.am	Fri May 25 21:44:18 2001
@@ -13,8 +13,8 @@
 
 karm_SOURCES =  adddlg.cpp karm.cpp main.cpp idle.cpp \
 	task.cpp top.cpp kaccelmenuwatch.cpp print.cpp docking.cpp\
-	preferences.cpp ktimewidget.cpp
-noinst_HEADERS = adddlg.h karm.h task.h toolicons.h top.h kaccelmenuwatch.h \
version.h print.h idle.h docking.h preferences.h ktimewidget.h +	preferences.cpp \
ktimewidget.cpp loging.cpp +noinst_HEADERS = adddlg.h karm.h task.h toolicons.h top.h \
kaccelmenuwatch.h version.h print.h idle.h docking.h preferences.h ktimewidget.h \
loging.h  
 KDE_ICON = karm
 


>> Visit http://master.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic