|
|
|
/*
|
|
|
|
* This file only:
|
|
|
|
* Copyright (C) 2003 Mark Bucciarelli <mark@hubcapconsutling.com>
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
* 51 Franklin Street, Fifth Floor
|
|
|
|
* Boston, MA 02110-1301 USA.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef KARM_STORAGE_H
|
|
|
|
#define KARM_STORAGE_H
|
|
|
|
|
|
|
|
#include <tqdict.h>
|
|
|
|
#include <tqptrstack.h>
|
|
|
|
|
|
|
|
#include "journal.h"
|
|
|
|
#include "reportcriteria.h"
|
|
|
|
|
|
|
|
#include "desktoplist.h"
|
|
|
|
|
|
|
|
#include <calendarresources.h>
|
|
|
|
#include <vector>
|
|
|
|
#include "resourcecalendar.h"
|
|
|
|
#include <kdepimmacros.h>
|
|
|
|
|
|
|
|
class TQDateTime;
|
|
|
|
class Preferences;
|
|
|
|
class Task;
|
|
|
|
class TaskView;
|
|
|
|
class HistoryEvent;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Singleton to store/retrieve KArm data to/from persistent storage.
|
|
|
|
*
|
|
|
|
* The storage is an iCalendar file. Also included are methods to
|
|
|
|
* import KArm data from the two legacy file formats.
|
|
|
|
*
|
|
|
|
* All logic that deals with getting and saving data should go here. The
|
|
|
|
* storage logic has changed at least twice already in KArm's history, and
|
|
|
|
* chances are good it will change again (for example, allowing KOrganizer and
|
|
|
|
* KArm to access the same iCalendar file simultaneously).
|
|
|
|
*
|
|
|
|
* Prior to KDE 3.2, KArm just stored totals for each task--a session total
|
|
|
|
* and a task total. The session total was reset to zero each time KArm
|
|
|
|
* started up or after the user reset the session times to zero. With the
|
|
|
|
* release of KDE 3.2, KArm now stores these task totals as well as logging
|
|
|
|
* the history of each start/stop event; that is, every time you start a timer
|
|
|
|
* and then stop a timer on a task, KArm records this as an iCalendar event.
|
|
|
|
*
|
|
|
|
* @short Logic that gets and stores KArm data to disk.
|
|
|
|
* @author Mark Bucciarelli <mark@hubcapconsulting.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
class KarmStorage
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/*
|
|
|
|
* Return reference to storage singleton.
|
|
|
|
*
|
|
|
|
* The constructors are private, so this must be used to create a
|
|
|
|
* KarmStorage instance.
|
|
|
|
*/
|
|
|
|
static KarmStorage *instance();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Load the list view with tasks read from iCalendar file.
|
|
|
|
*
|
|
|
|
* Parses iCalendar file, builds list view items in the proper
|
|
|
|
* hierarchy, and loads them into the list view widget.
|
|
|
|
*
|
|
|
|
* If the file name passed in is the same as the last file name that was
|
|
|
|
* loaded, this method does nothing.
|
|
|
|
*
|
|
|
|
* This method considers any of the following conditions errors:
|
|
|
|
*
|
|
|
|
* @li the iCalendar file does not exist
|
|
|
|
* @li the iCalendar file is not readable
|
|
|
|
* @li the list group currently has list items
|
|
|
|
* @li an iCalendar todo has no related to attribute
|
|
|
|
* @li a todo is related to another todo which does not exist
|
|
|
|
*
|
|
|
|
* @param taskview The list group used in the TaskView
|
|
|
|
* @param preferences The current KArm preferences.
|
|
|
|
* @param fileName Override preferences' filename
|
|
|
|
*
|
|
|
|
* @return empty string if success, error message if error.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
TQString load(TaskView* taskview, const Preferences* preferences, TQString fileName="" );
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Return the name of the iCal file
|
|
|
|
*/
|
|
|
|
TQString icalfile();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Build up the taskview.
|
|
|
|
*
|
|
|
|
* This is needed if the iCal file has been modified
|
|
|
|
*/
|
|
|
|
TQString buildTaskView(KCal::ResourceCalendar *rc, TaskView *view);
|
|
|
|
|
|
|
|
/* Close calendar and clear view. Release lock if holding one. */
|
|
|
|
void closeStorage(TaskView* view);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Save all tasks and their totals to an iCalendar file.
|
|
|
|
*
|
|
|
|
* All tasks must have an associated VTODO object already created in the
|
|
|
|
* calendar file; that is, the task->uid() must refer to a valid VTODO in
|
|
|
|
* the calender.
|
|
|
|
* Delivers empty string if successful, else error msg.
|
|
|
|
*
|
|
|
|
* @param taskview The list group used in the TaskView
|
|
|
|
*/
|
|
|
|
TQString save(TaskView* taskview);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Read tasks and their total times from a text file (legacy storage).
|
|
|
|
*
|
|
|
|
* This reads from one of the two legacy file formats. In this version,
|
|
|
|
* the parent task times do not include the sum of all their children's
|
|
|
|
* times.
|
|
|
|
*
|
|
|
|
* The format of the file is zero or more lines of:
|
|
|
|
* 1 task id (a number)
|
|
|
|
* time in minutes
|
|
|
|
* string task name
|
|
|
|
* [string] desktops, in which to count. e.g. "1,2,5" (optional)
|
|
|
|
*/
|
|
|
|
TQString loadFromFlatFile(TaskView* taskview, const TQString& filename);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reads tasks and their total times from text file (legacy).
|
|
|
|
*
|
|
|
|
* This is the older legacy format, where the task totals included the
|
|
|
|
* children totals.
|
|
|
|
*
|
|
|
|
* @see loadFromFlatFile
|
|
|
|
*/
|
|
|
|
TQString loadFromFlatFileCumulative(TaskView* taskview,
|
|
|
|
const TQString& filename);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Output a report based on contents of ReportCriteria.
|
|
|
|
*/
|
|
|
|
TQString report( TaskView *taskview, const ReportCriteria &rc );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Log the change in a task's time.
|
|
|
|
*
|
|
|
|
* We create an iCalendar event to store each change. The event start
|
|
|
|
* date is set to the current datetime. If time is added to the task, the
|
|
|
|
* task end date is set to start time + delta. If the time is negative,
|
|
|
|
* the end date is set to the start time.
|
|
|
|
*
|
|
|
|
* In both cases (postive or negative delta), we create a custom iCalendar
|
|
|
|
* property that stores the delta (in seconds). This property is called
|
|
|
|
* X-KDE-karm-duration.
|
|
|
|
*
|
|
|
|
* Note that the KArm UI allows the user to change both the session and
|
|
|
|
* the total task time, and this routine does not account for all posibile
|
|
|
|
* cases. For example, it is possible for the user to do something crazy
|
|
|
|
* like add 10 minutes to the session time and subtract 50 minutes from
|
|
|
|
* the total time. Although this change violates a basic law of physics,
|
|
|
|
* it is allowed.
|
|
|
|
*
|
|
|
|
* For now, you should pass in the change to the total task time.
|
|
|
|
* Eventually, the UI should be changed.
|
|
|
|
*
|
|
|
|
* @param task The task the change is for.
|
|
|
|
* @param delta Change in task time, in seconds. Can be negative.
|
|
|
|
*/
|
|
|
|
void changeTime(const Task* task, const long deltaSeconds);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Book time to a task.
|
|
|
|
*
|
|
|
|
* Creates an iCalendar event and adds it to the calendar. Does not write
|
|
|
|
* calender to disk, just adds event to calendar in memory. However, the
|
|
|
|
* resource framework does try to get a lock on the file. After a
|
|
|
|
* succesful lock, the calendar marks this incidence as modified and then
|
|
|
|
* releases the lock.
|
|
|
|
*
|
|
|
|
* @param task Task
|
|
|
|
* @param startDateTime Date and time the booking starts.
|
|
|
|
* @param durationInSeconds Duration of time to book, in seconds.
|
|
|
|
*
|
|
|
|
* @return true if event was added, false if not (if, for example, the
|
|
|
|
* attempted file lock failed).
|
|
|
|
*/
|
|
|
|
bool bookTime(const Task* task, const TQDateTime& startDateTime,
|
|
|
|
long durationInSeconds);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Log a change to a task name.
|
|
|
|
*
|
|
|
|
* For iCalendar storage, there is no need to log an Event for this event,
|
|
|
|
* since unique id's are used to link Events to Todos. No matter how many
|
|
|
|
* times you change a task's name, the uid stays the same.
|
|
|
|
*
|
|
|
|
* @param task The task
|
|
|
|
* @param oldname The old name of the task. The new name is in the task
|
|
|
|
* object already.
|
|
|
|
*/
|
|
|
|
void setName(const Task* task, const TQString& oldname) { Q_UNUSED(task); Q_UNUSED(oldname); }
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Log the event that a timer has started for a task.
|
|
|
|
*
|
|
|
|
* For the iCalendar storage, there is no need to log anything for this
|
|
|
|
* event. We log an event when the timer is stopped.
|
|
|
|
*
|
|
|
|
* @param task The task the timer was started for.
|
|
|
|
*/
|
|
|
|
void startTimer(const Task* task) { Q_UNUSED(task); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Log the event that the timer has stopped for this task.
|
|
|
|
*
|
|
|
|
* The task stores the last time a timer was started, so we log a new iCal
|
|
|
|
* Event with the start and end times for this task.
|
|
|
|
* @see KarmStorage::changeTime
|
|
|
|
*
|
|
|
|
* @param task The task the timer was stopped for.
|
|
|
|
*/
|
|
|
|
void stopTimer(const Task* task, TQDateTime when=TQDateTime::currentDateTime());
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Log a new comment for this task.
|
|
|
|
*
|
|
|
|
* iCal allows multiple comment tags. So we just add a new comment to the
|
|
|
|
* todo for this task and write the calendar.
|
|
|
|
*
|
|
|
|
* @param task The task that gets the comment
|
|
|
|
* @param comment The comment
|
|
|
|
*/
|
|
|
|
void addComment(const Task* task, const TQString& comment);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove this task from iCalendar file.
|
|
|
|
*
|
|
|
|
* Removes task as well as all event history for this task.
|
|
|
|
*
|
|
|
|
* @param task The task to be removed.
|
|
|
|
* @return true if change was saved, false otherwise
|
|
|
|
*/
|
|
|
|
bool removeTask(Task* task);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add this task from iCalendar file.
|
|
|
|
*
|
|
|
|
* Create a new KCal::Todo object and load with task information. If
|
|
|
|
* parent is not zero, then set the RELATED-TO attribute for this Todo.
|
|
|
|
*
|
|
|
|
* @param task The task to be removed.
|
|
|
|
* @param parent The parent of this task. Must have a uid() that is in
|
|
|
|
* the existing calendar. If zero, this task is considered a root task.
|
|
|
|
* @return The unique ID for the new VTODO. Return an null TQString if
|
|
|
|
* there was an error creating the new calendar object.
|
|
|
|
*/
|
|
|
|
TQString addTask(const Task* task, const Task* parent);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if the iCalendar file currently loaded has any Todos in it.
|
|
|
|
*
|
|
|
|
* @return true if iCalendar file has any todos
|
|
|
|
*/
|
|
|
|
bool isEmpty();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if iCalendar file name in the preferences has changed since the
|
|
|
|
* last call to load. If there is no calendar file currently loaded,
|
|
|
|
* return false.
|
|
|
|
*
|
|
|
|
* @param preferences Set of KArm preferences.
|
|
|
|
*
|
|
|
|
* @return true if a previous file has been loaded and the iCalendar file
|
|
|
|
* specified in the preferences is different.
|
|
|
|
*/
|
|
|
|
bool isNewStorage(const Preferences* preferences) const;
|
|
|
|
|
|
|
|
/** Return a list of start/stop events for the given date range. */
|
|
|
|
TQValueList<HistoryEvent> getHistory(const TQDate& from, const TQDate& to);
|
|
|
|
|
|
|
|
private:
|
|
|
|
static KarmStorage *_instance;
|
|
|
|
KCal::ResourceCalendar *_calendar;
|
|
|
|
TQString _icalfile;
|
|
|
|
|
|
|
|
KarmStorage();
|
|
|
|
void adjustFromLegacyFileFormat(Task* task);
|
|
|
|
bool parseLine(TQString line, long *time, TQString *name, int *level,
|
|
|
|
DesktopList* desktopList);
|
|
|
|
TQString writeTaskAsTodo
|
|
|
|
(Task* task, const int level, TQPtrStack< KCal::Todo >& parents);
|
|
|
|
bool saveCalendar();
|
|
|
|
|
|
|
|
KCal::Event* baseEvent(const Task*);
|
|
|
|
bool remoteResource( const TQString& file ) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Writes all tasks and their totals to a Comma-Separated Values file.
|
|
|
|
*
|
|
|
|
* The format of this file is zero or more lines of:
|
|
|
|
* taskName,subtaskName,..,sessionTime,time,totalSessionTime,totalTime
|
|
|
|
* the number of subtasks is determined at runtime.
|
|
|
|
*/
|
|
|
|
TQString exportcsvFile( TaskView *taskview, const ReportCriteria &rc );
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Write task history to file as comma-delimited data.
|
|
|
|
*/
|
|
|
|
TQString exportcsvHistory (
|
|
|
|
TaskView* taskview,
|
|
|
|
const TQDate& from,
|
|
|
|
const TQDate& to,
|
|
|
|
const ReportCriteria &rc
|
|
|
|
);
|
|
|
|
|
|
|
|
long printTaskHistory (
|
|
|
|
const Task *task,
|
|
|
|
const TQMap<TQString,long>& taskdaytotals,
|
|
|
|
TQMap<TQString,long>& daytotals,
|
|
|
|
const TQDate& from,
|
|
|
|
const TQDate& to,
|
|
|
|
const int level,
|
|
|
|
std::vector <TQString> &matrix,
|
|
|
|
const ReportCriteria &rc
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* One start/stop event that has been logged.
|
|
|
|
*
|
|
|
|
* When a task is running and the user stops it, KArm logs this event and
|
|
|
|
* saves it in the history. This class represents such an event read from
|
|
|
|
* storage, and abstracts it from the specific storage used.
|
|
|
|
*/
|
|
|
|
class HistoryEvent
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/** Needed to be used in a value list. */
|
|
|
|
HistoryEvent() {}
|
|
|
|
HistoryEvent(TQString uid, TQString name, long duration,
|
|
|
|
TQDateTime start, TQDateTime stop, TQString todoUid);
|
|
|
|
TQString uid() {return _uid; }
|
|
|
|
TQString name() {return _name; }
|
|
|
|
/** In seconds. */
|
|
|
|
long duration() {return _duration; }
|
|
|
|
TQDateTime start() {return _start; }
|
|
|
|
TQDateTime stop() { return _stop; }
|
|
|
|
TQString todoUid() {return _todoUid; }
|
|
|
|
|
|
|
|
private:
|
|
|
|
TQString _uid;
|
|
|
|
TQString _todoUid;
|
|
|
|
TQString _name;
|
|
|
|
long _duration;
|
|
|
|
TQDateTime _start;
|
|
|
|
TQDateTime _stop;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // KARM_STORAGE_H
|