Commit 0673b707 authored by nobody's avatar nobody
Browse files

This commit was manufactured by cvs2svn to accommodate

a server-side copy/move.

svn path=/trunk/kdepim/; revision=112130
parent 4f92279c
BUGS
----
Lots.
please report bugs to taj@kde.org or at http://buglist.kde.org.
0.2
Now supports floating toolbar
Documentation converted to linuxdoc
KArm is a time tracker for busy people who need
to keep track of the amount of time they spend
on various tasks.
############ Autoconf-generated variables ###################
AM_CPPFLAGS = -DQT_NO_CAST_ASCII
INCLUDES = $(all_includes)
LDFLAGS = $(all_libraries) $(KDE_RPATH)
LDADD = -lkdeprint $(LIBXSS)
bin_PROGRAMS = karm
SUBDIRS = support pics
METASOURCES = AUTO
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
KDE_ICON = karm
appsdir = $(kde_appsdir)/Utilities
rcdir = $(kde_datadir)/karm
rc_DATA = karmui.rc
install-data-local:
$(mkinstalldirs) $(appsdir)
$(INSTALL_DATA) $(srcdir)/support/karm.desktop $(appsdir)
uninstall-local:
rm -f $(kde_appsdir)/karm.kdesktop
messages: rc.cpp
$(XGETTEXT) *.cpp -o $(podir)/karm.pot
srcdoc:
kdoc -a -p -H -d $(HOME)/web/src/karm karm *.h -lkdecore -lkdeui -lqt
KArm 0.6
--------
- It is now possible to type in the time like 3:20, or 3:20 + 1:10
- The two QListBoxes with time and description has been replaced with one
QListView. This makes the interface nicer, and simplifies a lot internally.
KArm 0.3
--------
Fixes edit task bugs
Complies to new FSSTND
KArm 0.2
--------
In my day, I may have to work on several different projects and keep track
separately of how much time I spent working on each project. If you are
like me, then KArm is for you.
KArm is a time tracker. You can enter a list of "tasks", start KArm's clock,
and it will count the number of minutes you spend on the highlighted task.
KArm was inspired by Harald Tveit Alvestrand's very useful utility called
titrax, the only failing of which is that it is based on the Xt toolkit. One
day KArm will do all that titrax does, but not today.
The word "karm", in my mother tongue Punjabi, means "work".
There is a screenshot at
http://www.ph.unimelb.edu.au/~ssk/kde/karm/karm.gif
and is installed with the included (sparse) documentation.
/*
* karm
* This file only: Copyright (C) 1999 Espen Sand, espensa@online.no
* Modifications (see CVS log) Copyright (C) 2000 Klarlvdalens
* Datakonsult AB <kalle@dalheimer.de>, Jesper Pedersen <blackie@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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
*/
#include <qlabel.h>
#include <qlineedit.h>
#include <qlayout.h>
#include <qregexp.h>
#include <qhbox.h>
#include <kapp.h>
#include <klocale.h>
#include <qcombobox.h>
#include <kdebug.h>
#include <qradiobutton.h>
#include <qbuttongroup.h>
#include <qpixmap.h>
#include <kiconloader.h>
#include <qwhatsthis.h>
#include "adddlg.h"
#include "karm.h"
#include "ktimewidget.h"
AddTaskDialog::AddTaskDialog(QString caption, bool editDlg)
:KDialogBase(0, "AddTaskDialog", true, caption, Ok|Cancel, Ok, true )
{
QWidget *page = new QWidget( this );
setMainWidget(page);
QVBoxLayout *lay1 = new QVBoxLayout(page);
QHBoxLayout *lay2 = new QHBoxLayout();
lay1->addLayout(lay2);
// The name of the widget
QLabel *label = new QLabel( i18n("Task name"), page, "name" );
lay2->addWidget( label );
lay2->addSpacing(5);
_name = new QLineEdit( page, "lineedit" );
_name->setMinimumWidth(fontMetrics().maxWidth()*15);
lay2->addWidget( _name );
// The "Edit Absolut" radio button
lay1->addSpacing(10);lay1->addStretch(1);
_absoluteRB = new QRadioButton( i18n( "Edit Absolute" ), page, "_absoluteRB" );
lay1->addWidget( _absoluteRB );
connect( _absoluteRB, SIGNAL( clicked() ), this, SLOT(slotAbsolutePressed()) );
// Absolute times
QHBoxLayout *lay5 = new QHBoxLayout();
lay1->addLayout(lay5);
lay5->addSpacing(20);
QGridLayout *lay3 = new QGridLayout( 2, 2, -1, "lay3" );
lay5->addLayout(lay3);
// Total Time
_totalLA = new QLabel( i18n("Total:"), page, "time" );
lay3->addWidget( _totalLA, 0, 0 );
_totalTW = new KTimeWidget( page, "_totalTW" );
lay3->addWidget( _totalTW, 0, 1 );
// Session
_sessionLA = new QLabel( i18n("Session time:"), page, "session time" );
lay3->addWidget( _sessionLA, 1, 0 );
_sessionTW = new KTimeWidget( page, "_sessionTW" );
lay3->addWidget( _sessionTW, 1, 1 );
// The "Edit relative" radio button
lay1->addSpacing(10);lay1->addStretch(1);
_relativeRB = new QRadioButton( i18n( "Edit Relative (Apply to both session and total)" ), page, "_relativeRB" );
lay1->addWidget( _relativeRB );
connect( _relativeRB, SIGNAL( clicked() ), this, SLOT(slotRelativePressed()) );
// The relative times
QHBoxLayout *lay4 = new QHBoxLayout();
lay1->addLayout( lay4 );
lay4->addSpacing(20);
_operator = new QComboBox(page);
_operator->insertItem( QString::fromLatin1( "+" ) );
_operator->insertItem( QString::fromLatin1( "-" ) );
lay4->addWidget( _operator );
lay4->addSpacing(5);
_diffTW = new KTimeWidget( page, "_sessionAddTW" );
lay4->addWidget( _diffTW );
KIconLoader loader;
QPixmap whatsThisIM = loader.loadIcon(QString::fromLatin1("contexthelp"), KIcon::Toolbar);
QPushButton* whatsThisBU = new QPushButton(page, "whatsThisLA");
whatsThisBU->setFocusPolicy(NoFocus);
connect(whatsThisBU, SIGNAL(clicked()), this, SLOT(enterWhatsThis()));
whatsThisBU->setPixmap( whatsThisIM );
lay4->addWidget(whatsThisBU);
lay1->addStretch(1);
if ( editDlg ) {
// This is an edit dialog.
_operator->setFocus();
}
else {
// This is an initial dialog
_name->setFocus();
}
origTotal = 0;
origSession = 0;
slotRelativePressed();
// Whats this help.
QWhatsThis::add(_name, i18n("Enter the name of the task here. This name is for your eyes only."));
QWhatsThis::add(_absoluteRB, i18n("If you select this radio button, you specify that you want "
"to enter the time as absolute values. For example: "
"total for this task is 20 hours and 15 minutes.\n\n"
"The time is specified for the session time and for the total time "
"separately."));
QWhatsThis::add(_relativeRB, i18n("If you select this radio button, you specify that you want "
"to add or subtract time for the task. For example: I've worked 2 hours "
"and 20 minutes more on this task (without having the timer "
"running.)\n\n"
"This time will be added or subtracted for both the "
"session time and the total time."));
QWhatsThis::add(_totalTW, i18n("This is the overall time this task has been running."));
QWhatsThis::add(_sessionTW, i18n("This is the time the task has been running this session."));
QWhatsThis::add(_diffTW, i18n("Specify how much time to add or subtract to the overall and "
"session time"));
}
void AddTaskDialog::enterWhatsThis()
{
QWhatsThis::enterWhatsThisMode ();
}
void AddTaskDialog::slotAbsolutePressed()
{
_relativeRB->setChecked( false );
_absoluteRB->setChecked( true );
_operator->setEnabled( false );
_diffTW->setEnabled( false );
_totalLA->setEnabled( true );
_sessionLA->setEnabled( true );
_totalTW->setEnabled( true );
_sessionTW->setEnabled( true );
}
void AddTaskDialog::slotRelativePressed()
{
_relativeRB->setChecked( true );
_absoluteRB->setChecked( false );
_operator->setEnabled( true );
_diffTW->setEnabled( true );
_totalLA->setEnabled( false );
_sessionLA->setEnabled( false );
_totalTW->setEnabled( false );
_sessionTW->setEnabled( false );
}
void AddTaskDialog::setTask( const QString &name, long total, long session )
{
_name->setText( name );
_totalTW->setTime( total / 60, total % 60 );
_sessionTW->setTime( session / 60, session % 60 );
origTotal = total;
origSession = session;
}
QString AddTaskDialog::taskName( void ) const
{
return( _name->text() );
}
void AddTaskDialog::status( long *total, long *totalDiff, long *session, long *sessionDiff ) const
{
if ( _absoluteRB->isChecked() ) {
*total = _totalTW->time();
*session = _sessionTW->time();
}
else {
int diff = _diffTW->time();
if ( _operator->currentItem() == 1) {
diff = -diff;
}
*total = origTotal + diff;
*session = origSession + diff;
}
*totalDiff = *total - origTotal;
*sessionDiff = *session - origSession;
}
#include "adddlg.moc"
/*
* karm
* This file only: Copyright (C) 1999 Espen Sand, espensa@online.no
*
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#ifndef KarmAddDlg_included
#define KarmAddDlg_included
#include <stdlib.h>
#include <kdialogbase.h>
#include <qvalidator.h>
#include "adddlg.h"
class QLineEdit;
class KTimeWidget;
class QRadioButton;
class AddTaskDialog : public KDialogBase
{
Q_OBJECT
public:
AddTaskDialog(QString caption, bool editDlg);
void setTask(const QString &name, long time, long sessionTime );
QString taskName( void ) const;
void status( long *total, long *totalDiff, long *session, long *sessionDiff ) const;
private slots:
void slotAbsolutePressed();
void slotRelativePressed();
void enterWhatsThis();
private:
QLineEdit* _name;
KTimeWidget* _totalTW;
KTimeWidget* _sessionTW;
KTimeWidget* _diffTW;
QComboBox* _operator;
long origTotal;
long origSession;
QRadioButton *_absoluteRB;
QRadioButton *_relativeRB;
QLabel* _totalLA;
QLabel* _sessionLA;
};
#endif // KarmAddDlg_included
ac_ldflags_safe="$LDFLAGS"
ac_libs_safe="$LIBS"
LIBS="-lXext -lX11 $X_LDFLAGS"
LIBXSS=""
AC_CHECK_LIB(Xss, XScreenSaverAllocInfo, [LIBXSS="-lXext -lXss"])
if test "x$LIBXSS" != "x"; then
AC_DEFINE(HAVE_LIBXSS,1,[Define if you have libXss installed])
fi
LIBS="$ac_libs_safe"
LDFLAGS="$ac_ldflags_safe"
AC_SUBST(LIBXSS)
#include "top.h"
#include <qtooltip.h>
#include <kapp.h>
#include "docking.h"
#include <klocale.h>
#include <kiconloader.h>
#include <kglobal.h>
#include <kpopupmenu.h>
DockWidget::DockWidget( KarmWindow* parent, const char *name)
: KDockWindow( parent, name )
{
setPixmap( SmallIcon(QString::fromLatin1("karm")));
}
DockWidget::~DockWidget() {
}
#include "docking.moc"
#ifndef _DOCKING_H_
#define _DOCKING_H_
#include <kdockwindow.h>
class KarmWindow;
class DockWidget : public KDockWindow {
Q_OBJECT
public:
DockWidget( KarmWindow* parent, const char *name=0);
~DockWidget();
};
#endif
#include "idle.h"
#include <qmessagebox.h>
#include <klocale.h>
#include <qtimer.h>
#include <qdatetime.h>
IdleTimer::IdleTimer(int maxIdle)
{
_maxIdle = maxIdle;
#ifdef HAVE_LIBXSS
int event_base, error_base;
if(XScreenSaverQueryExtension(qt_xdisplay(), &event_base, &error_base)) {
_idleDetectionPossible = true;
}
else {
_idleDetectionPossible = false;
}
_timer = new QTimer(this);
connect(_timer, SIGNAL(timeout()), this, SLOT(check()));
#else
_idleDetectionPossible = false;
#endif // HAVE_LIBXSS
}
bool IdleTimer::isIdleDetectionPossible()
{
return _idleDetectionPossible;
}
void IdleTimer::check()
{
#ifdef HAVE_LIBXSS
if (_idleDetectionPossible) {
_mit_info = XScreenSaverAllocInfo ();
XScreenSaverQueryInfo(qt_xdisplay(), qt_xrootwin(), _mit_info);
int idleMinutes = (_mit_info->idle/1000)/secsPerMinutes;;
if (idleMinutes >= _maxIdle) {
informOverrun(idleMinutes);
}
}
#endif // HAVE_LIBXSS
}
void IdleTimer::setMaxIdle(int maxIdle)
{
_maxIdle = maxIdle;
}
#ifdef HAVE_LIBXSS
void IdleTimer::informOverrun(int idleMinutes)
{
if (!_overAllIdleDetect) {
return; // In the preferences the user has indicated that he do not
// want idle detection.
}
_timer->stop();
QDateTime start = QDateTime::currentDateTime();
QDateTime idleStart = start.addSecs(-60 * _maxIdle);
QString backThen;
backThen.sprintf("%d:%02d", idleStart.time().hour(), idleStart.time().minute());
int id = QMessageBox::warning(0,i18n("Idle detection"),
i18n("Desktop has been idle since %1."
" What should we do?").arg(backThen),
i18n("Revert and Stop"), i18n("Revert and Continue"),
i18n("Continue Timing"),0,2);
QDateTime end = QDateTime::currentDateTime();
int diff = start.secsTo(end)/secsPerMinutes;
if (id == 0) {
// Revert And Stop
emit(extractTime(idleMinutes+diff));
emit(stopTimer());
}
else if (id == 1) {
// Revert and Continue
emit(extractTime(idleMinutes+diff));
_timer->start(testInterval);
}
else {
// Continue
_timer->start(testInterval);
}
}
#endif // HAVE_LIBXSS
void IdleTimer::startIdleDetection()
{
#ifdef HAVE_LIBXSS
if (!_timer->isActive())
_timer->start(testInterval);
#endif //HAVE_LIBXSS
}
void IdleTimer::stopIdleDetection()
{
#ifdef HAVE_LIBXSS
if (_timer->isActive())
_timer->stop();
#endif // HAVE_LIBXSS
}
void IdleTimer::toggleOverAllIdleDetection(bool on)
{
_overAllIdleDetect = on;
}
#include "idle.moc"
#ifndef __IDLETIMER
#define __IDLETIMER
#include <qobject.h>
#include "config.h"
#ifdef HAVE_LIBXSS
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/extensions/scrnsaver.h>
#endif // HAVE_LIBXSS
class QTimer;
// Seconds per minutes - usefull for speeding debugging up!
const int secsPerMinutes = 60;
// Minutes between each idle overrun test.
const int testInterval= secsPerMinutes * 1000;
class IdleTimer :public QObject
{
Q_OBJECT
public:
/**
Initializes and idle test timer
@param maxIdle minutes before the idle timer will go off.
**/
IdleTimer(int maxIdle);
/**
Returns true if it is possible to do idle detection.
Idle detection relys on a feature in the X server, which might not
allways be present.
**/
bool isIdleDetectionPossible();
signals:
/**
Tells the listener to extract time from current timing.
The time to extract is due to the idle time since the dialog wass
shown, and until the user answers the dialog.
@param minutes Minutes to extract.
**/
void extractTime(int minutes);