2 * Copyright (C) 2003 by Mark Bucciarelli <mark@hubcapconsutling.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the
16 * Free Software Foundation, Inc.
17 * 51 Franklin Street, Fifth Floor
18 * Boston, MA 02110-1301 USA.
22 #ifndef KTIMETRACKER_STORAGE_H
23 #define KTIMETRACKER_STORAGE_H
29 #include "reportcriteria.h"
31 #include "desktoplist.h"
33 #include <kcal/journal.h>
34 #include <kcal/calendarresources.h>
35 #include <kcal/resourcecalendar.h>
46 * Class to store/retrieve KTimeTracker data to/from persistent storage.
48 * The storage is an iCalendar file.
50 * All logic that deals with getting and saving data should go here.
52 * This program uses iCalendar to store its data. There are tasks and
53 * events. Events have a start and a end date and an associated task.
55 * @short Logic that gets and stores KTimeTracker data to disk.
56 * @author Mark Bucciarelli <mark@hubcapconsulting.com>
59 class timetrackerstorage
: public QObject
65 ~timetrackerstorage();
67 QString
setTaskParent( Task
* task
, Task
* parent
);
70 Load the list view with tasks read from iCalendar file.
72 Parses iCalendar file, builds list view items in the proper
73 hierarchy, and loads them into the list view widget.
75 If the file name passed in is the same as the last file name that was
76 loaded, this method does nothing.
78 This method considers any of the following conditions errors:
80 @li the iCalendar file does not exist
81 @li the iCalendar file is not readable
82 @li the list group currently has list items
83 @li an iCalendar todo has no related to attribute
84 @li a todo is related to another todo which does not exist
86 @param taskview The list group used in the TaskView
87 @param fileName Override preferences' filename
89 @return empty string if success, error message if error.
91 QString
load( TaskView
* taskview
, const QString
&fileName
);
94 * Return the name of the iCal file
99 * Build up the taskview.
101 * This is needed if the iCal file has been modified.
103 QString
buildTaskView(KCal::ResourceCalendar
*rc
, TaskView
*view
);
106 * Build up the taskview.
108 * This is needed if a subtask has been deleted.
110 QString
buildTaskView(TaskView
*view
);
112 /** Close calendar and clear view. Release lock if holding one. */
115 /** list of all events */
116 KCal::Event::List
rawevents();
118 /** list of all todos */
119 KCal::Todo::List
rawtodos();
121 QString
removeEvent(QString uid
);
124 * Deliver if all events of a task have an endtime
126 * If ktimetracker has been quitted with one task running, it needs to resumeRunning().
127 * This function delivers if an enddate of an event has not yet been stored.
129 * @param task The task to be examined
131 bool allEventsHaveEndTiMe(Task
* task
);
134 * Deliver if all events of the actual calendar have an endtime
136 * If ktimetracker has been quitted with one task running, it needs to resumeRunning().
137 * This function delivers if an enddate of an event has not yet been stored.
140 bool allEventsHaveEndTiMe();
142 QString
deleteAllEvents();
145 * Save all tasks and their totals to an iCalendar file.
147 * All tasks must have an associated VTODO object already created in the
148 * calendar file; that is, the task->uid() must refer to a valid VTODO in
150 * Delivers empty string if successful, else error msg.
152 * @param taskview The list group used in the TaskView
154 QString
save(TaskView
* taskview
);
157 Output a report based on contents of ReportCriteria.
159 QString
report( TaskView
*taskview
, const ReportCriteria
&rc
);
162 * Log the change in a task's time.
164 * This is also called when a timer is stopped.
165 * We create an iCalendar event to store each change. The event start
166 * date is set to the current datetime. If time is added to the task, the
167 * task end date is set to start time + delta. If the time is negative,
168 * the end date is set to the start time.
170 * In both cases (postive or negative delta), we create a custom iCalendar
171 * property that stores the delta (in seconds). This property is called
172 * X-KDE-ktimetracker-duration.
174 * Note that the ktimetracker UI allows the user to change both the session and
175 * the total task time, and this routine does not account for all posibile
176 * cases. For example, it is possible for the user to do something crazy
177 * like add 10 minutes to the session time and subtract 50 minutes from
178 * the total time. Although this change violates a basic law of physics,
181 * For now, you should pass in the change to the total task time.
183 * @param task The task the change is for.
184 * @param delta Change in task time, in seconds. Can be negative.
186 void changeTime(const Task
* task
, const long deltaSeconds
);
189 * Book time to a task.
191 * Creates an iCalendar event and adds it to the calendar. Does not write
192 * calendar to disk, just adds event to calendar in memory. However, the
193 * resource framework does try to get a lock on the file. After a
194 * successful lock, the calendar marks this incidence as modified and then
198 * @param startDateTime Date and time the booking starts.
199 * @param durationInSeconds Duration of time to book, in seconds.
201 * @return true if event was added, false if not (if, for example, the
202 * attempted file lock failed).
204 bool bookTime(const Task
* task
, const QDateTime
& startDateTime
,
205 const long durationInSeconds
);
208 * Log a change to a task name.
210 * For iCalendar storage, there is no need to log an Event for this event,
211 * since unique id's are used to link Events to Todos. No matter how many
212 * times you change a task's name, the uid stays the same.
214 * @param task The task
215 * @param oldname The old name of the task. The new name is in the task
218 void setName(const Task
* task
, const QString
& oldname
) { Q_UNUSED(task
); Q_UNUSED(oldname
); }
222 * Log the event that a timer has started for a task.
224 * For the iCalendar storage, there is no need to log anything for this
225 * event. We log an event when the timer is stopped.
227 * @param task The task the timer was started for.
229 void startTimer(const Task
* task
, const KDateTime
&when
=KDateTime::currentLocalDateTime());
232 * Start the timer for a given task ID
234 * @param taskID The task ID of the task to be started
236 void startTimer( QString taskID
);
239 * Log the event that the timer has stopped for this task.
241 * The task stores the last time a timer was started, so we log a new iCal
242 * Event with the start and end times for this task.
243 * @see timetrackerstorage::changeTime
245 * @param task The task the timer was stopped for.
246 * @param when When the timer stopped.
248 void stopTimer( const Task
* task
, const QDateTime
&when
= QDateTime::currentDateTime() );
251 * Log a new comment for this task.
253 * iCal allows multiple comment tags. So we just add a new comment to the
254 * todo for this task and write the calendar.
256 * @param task The task that gets the comment
257 * @param comment The comment
259 void addComment(const Task
* task
, const QString
& comment
);
263 * Remove this task from iCalendar file.
265 * Removes task as well as all event history for this task.
267 * @param task The task to be removed.
268 * @return true if change was saved, false otherwise
270 bool removeTask(Task
* task
);
273 * Remove this task from iCalendar file.
275 * Removes task as well as all event history for this task.
277 * @param task The task to be removed.
278 * @return true if change was saved, false otherwise
280 bool removeTask(QString taskid
);
283 * Add this task from iCalendar file.
285 * Create a new KCal::Todo object and load with task information. If
286 * parent is not zero, then set the RELATED-TO attribute for this Todo.
288 * @param task The task to be removed.
289 * @param parent The parent of this task. Must have a uid() that is in
290 * the existing calendar. If zero, this task is considered a root task.
291 * @return The unique ID for the new VTODO. Return an null QString if
292 * there was an error creating the new calendar object.
294 QString
addTask(const Task
* task
, const Task
* parent
=0);
297 * Check if the iCalendar file currently loaded has any Todos in it.
299 * @return true if iCalendar file has any todos
303 /** Return a list of all task ids for taskname */
304 QStringList
taskidsfromname(QString taskname
);
307 * Find the task with the given uid
308 * @param uid The uid that identifies the task
309 * @param view The TaskView that contains the task
310 * @return the task identified by uid, residing in the TaskView view
312 Task
* task( const QString
& uid
, TaskView
* view
);
314 /** Return a list of all task names */
315 QStringList
taskNames() const;
322 KCal::ResourceCalendar
*_calendar
;
325 void adjustFromLegacyFileFormat(Task
* task
);
326 bool parseLine(QString line
, long *time
, QString
*name
, int *level
,
327 DesktopList
* desktopList
);
328 QString
writeTaskAsTodo( Task
* task
, QStack
<KCal::Todo
*>& parents
);
329 QString
saveCalendar();
331 KCal::Event
* baseEvent(const Task
*);
332 KCal::Event
* baseEvent(const KCal::Todo
*);
333 bool remoteResource( const QString
& file
) const;
336 * Writes all tasks and their totals to a Comma-Separated Values file.
338 * The format of this file is zero or more lines of:
339 * taskName,subtaskName,..,sessionTime,time,totalSessionTime,totalTime
340 * the number of subtasks is determined at runtime.
342 QString
exportcsvFile( TaskView
*taskview
, const ReportCriteria
&rc
);
345 * Write task history to file as comma-delimited data.
347 QString
exportcsvHistory (
351 const ReportCriteria
&rc
356 * One start/stop event that has been logged.
358 * When a task is running and the user stops it, ktimetracker logs this event and
359 * saves it in the history. This class represents such an event read from
360 * storage, and abstracts it from the specific storage used.
365 /** Needed to be used in a value list. */
367 HistoryEvent( const QString
&uid
, const QString
&name
, long duration
,
368 const KDateTime
&start
, const KDateTime
&stop
,
369 const QString
&todoUid
);
370 QString
uid() {return _uid
; }
371 QString
name() {return _name
; }
373 long duration() {return _duration
; }
374 KDateTime
start() {return _start
; }
375 KDateTime
stop() { return _stop
; }
376 QString
todoUid() {return _todoUid
; }
388 #endif // KTIMETRACKER_STORAGE_H