/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set et sw=2 ts=2: */ /*************************************************************************** * task.cc * * Fri Feb 24 08:16:30 CET 2012 * Copyright 2012 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of Munia. * * Munia 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. * * Munia 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 Munia; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "taskmanager.h" #include // Global TaskManager object. TaskManager task_manager; #define ROOT_ID 0 #define FINISHED_ID 1 #define BACKLOG_ID 2 #define LOSTFOUND_ID 3 #define PROJECTS_ID 4 #define FIRST_TASK_ID 10 static bool isProtected(taskid_t id) { return id < FIRST_TASK_ID; } TaskManager::TaskManager() { idCount = FIRST_TASK_ID; } TaskManager::~TaskManager() { } void TaskManager::init(std::string filename) { printf("Reading tasks from file: %s\n", filename.c_str()); file = filename; FILE *fp = fopen(file.c_str(), "r"); if(fp) { std::string xml; while(!feof(fp)) { char buf[64]; size_t sz = fread(buf, 1, sizeof(buf), fp); xml.append(buf, sz); } tree.fromXML(xml); fclose(fp); } else { // Create new basis config task_t t; t.title = "root"; t.id = ROOT_ID; tree.insertAsChild(0, ROOT_ID, t); t.title = "Finished"; t.id = FINISHED_ID; tree.insertAsChild(ROOT_ID, FINISHED_ID, t); t.title = "Backlog"; t.id = BACKLOG_ID; tree.insertAsChild(ROOT_ID, BACKLOG_ID, t); t.title = "Lost+Found"; t.id = LOSTFOUND_ID; tree.insertAsChild(ROOT_ID, LOSTFOUND_ID, t); t.title = "Projects"; t.id = PROJECTS_ID; tree.insertAsChild(ROOT_ID, PROJECTS_ID, t); } tree.toStdOut(); } task_t TaskManager::task(taskid_t t) { return tree.data(t); } taskid_t TaskManager::createId() { return tree.createId(); } TaskIdListPair TaskManager::moveTask(taskid_t id, taskid_t to) throw (std::exception) { if(isProtected(id)) return TaskIdListPair(); task_t t = tree.data(id); t.parentid = to; TaskIdList tilremove = tree.remove(id); TaskIdList tilcreate = tree.insertAsChild(to, id, t); TaskIdListPair tilpair; tilpair.first = tilremove; tilpair.second = tilcreate; flushTasks(); return tilpair; } TaskIdList TaskManager::removeTask(taskid_t id) throw (std::exception) { if(isProtected(id)) return TaskIdList(); TaskIdList affectedTasks; if(tree.bfs(id).size() > 1) throw std::exception(); try { affectedTasks = tree.remove(id); } catch(std::exception& e) { throw e; } flushTasks(); return affectedTasks; } TaskIdList TaskManager::updateTask(taskid_t id, task_t t) throw (std::exception) { if(isProtected(id)) return TaskIdList(); TaskIdList affectedTasks; try { affectedTasks = tree.updateData(id, t); } catch (std::exception& e) { throw e; } flushTasks(); return affectedTasks; } TaskIdList TaskManager::createTask(taskid_t parentid, taskid_t *pid) throw (std::exception) { TaskIdList affectedTasks; task_t t; taskid_t id = *pid;//createId(); t.title = ""; t.id = id; if(pid) *pid = id; try { affectedTasks = tree.insertAsChild(parentid, id, t); } catch (std::exception& e) { throw e; } flushTasks(); return affectedTasks; } TaskIdList TaskManager::subTasks(taskid_t t) throw (std::exception) { TaskIdList affectedTasks; try { affectedTasks = tree.bfs(t); } catch (std::exception& e) { throw e; } return affectedTasks; } /* TaskIdList TaskManager::ancestorList(taskid_t id) throw (std::exception) { TaskIdList ancestors; try { ancestors = tree.ancestorList(id); goto finish; } catch (std::exception& e) { throw e; } finish: return ancestors; } */ void TaskManager::flushTasks() { FILE *fp = fopen(file.c_str(), "w"); if(!fp) return; std::string xml = tree.toXML(); fwrite(xml.c_str(), xml.size(), 1, fp); fclose(fp); } #if 0 TaskList tasklist; task_t create_task(std::string title, std::string desc) { task_t t; t.parent_id = current_id_count(); t.title = title; t.desc = desc; t.id = id_count; id_count++; return t; } TaskList load_tasklist_from_file(std::string file) { TaskList list; // create MuniaDb class which handles tasks, db-flush and db-init. return list; } bool save_tasklist_to_file(TaskList list, std::string file) { FILE* fp; if(! (fp = fopen(file.c_str(), "w"))) { return false; } if(!fprintf(fp, "\n")) { fclose(fp); return false; } TaskList::iterator it; for(it = tasklist.begin(); it != tasklist.end(); it++) { task_t t = *it; int r = 1; // printf("Flushing task %d\n", t.id); r |= fprintf(fp, " \n", t.id, t.parent_id); r |= fprintf(fp, " %s\n", xml_encode(t.title).c_str()); r |= fprintf(fp, " %s\n", xml_encode(t.desc).c_str()); r |= fprintf(fp, " )\n"); if(!r) { fclose(fp); return false; } } if(!fprintf(fp, "\n")) { fclose(fp); return false; } fclose(fp); return true; } static void delete_task(task_t t, TaskList& graveyard); static void delete_children(task_t t, TaskList& graveyard) { TaskList::iterator it; for(it = tasklist.begin(); it != tasklist.end(); it++) { if(it->parent_id == t.id) { delete_task(*it, graveyard); } } } static void delete_task(task_t t, TaskList& graveyard) { TaskList::iterator it; for(it = tasklist.begin(); it != tasklist.end(); it++) { if(it->id == t.id) { break; } } if(it != tasklist.end()) { graveyard.push_back(*it); delete_children(*it, graveyard); } } void delete_task(int id, TaskList& graveyard) { task_t t; t.id = id; delete_task(t, graveyard); for(TaskList::iterator it = graveyard.begin(); it != graveyard.end(); it++) { for(TaskList::iterator it_tl = tasklist.begin(); it_tl != tasklist.end(); it_tl++) { if(it_tl->id == it->id) { tasklist.erase(it_tl); break; } } } } #endif