From 06b9f25893f80d63fc74978c8a1621a33286de65 Mon Sep 17 00:00:00 2001 From: Patrick Lipka Date: Fri, 17 Dec 2021 12:05:13 +0100 Subject: [PATCH] cleanup done, more verbose comments added --- src/project.cpp | 29 +++++++++++++++++++++++------ src/string_utils.cpp | 4 ++++ src/task.cpp | 1 + src/track.cpp | 5 +++++ src/tt.cpp | 5 +++++ src/tt.h | 2 ++ src/ui.cpp | 22 ++++++++++++++++------ src/util.cpp | 6 +++++- 8 files changed, 61 insertions(+), 13 deletions(-) diff --git a/src/project.cpp b/src/project.cpp index 3f42c58..f6f2281 100644 --- a/src/project.cpp +++ b/src/project.cpp @@ -11,23 +11,27 @@ Project::Project(std::string name){ Project::active_task = NULL; } +// adds task to project void Project::add_task(Task task){ tasks.push_back(task); set_active_task(num_tasks); num_tasks++; } +// removes task from project by task id (position in tasks vector) void Project::remove_task(int id){ tasks.erase(tasks.begin()+id); set_active_task(std::max(id-1,0)); num_tasks--; } +// sets active task pointer and id by task id (position in tasks vector) void Project::set_active_task(int id){ active_task_id = id; active_task = &tasks[id]; } +// returns pointer to task with name task_name if present in tasks vector Task* Project::find_task_by_name(std::string task_name){ for (int i=0; i #include "string_utils.h" +// replaces white spaces by underscores, used for readline completion std::string space_to_underscore(std::string str){ for(size_t i = 0; i < str.length(); i++){ if(str[i] == ' ') str[i] = '_'; @@ -8,6 +9,7 @@ std::string space_to_underscore(std::string str){ return str; } +// replaces underscores by white space, used to translate readline completion to real names std::string underscore_to_space(std::string str){ for(size_t i = 0; i < str.length(); i++){ if(str[i] == '_') str[i] = ' '; @@ -15,6 +17,7 @@ std::string underscore_to_space(std::string str){ return str; } +// remove trailing and leading white spaces from string std::string trim(const std::string& str){ const char* WhiteSpace = " "; std::size_t start = str.find_first_not_of(WhiteSpace); @@ -22,6 +25,7 @@ std::string trim(const std::string& str){ return start == end ? std::string() : str.substr(start, end - start + 1); } +// check whether string is a number bool is_num(const std::string &str){ for (const char &c : str){ if (std::isdigit(c) == 0) return false; diff --git a/src/task.cpp b/src/task.cpp index a92a32d..076d4f5 100644 --- a/src/task.cpp +++ b/src/task.cpp @@ -7,6 +7,7 @@ Task::Task(std::string name){ Task::work_time = 0; } +// add working time, also used to remove working time with negative input values void Task::add_time(int seconds){ work_time = std::max(work_time+seconds,0); } diff --git a/src/track.cpp b/src/track.cpp index aaab810..b7a1029 100644 --- a/src/track.cpp +++ b/src/track.cpp @@ -6,7 +6,10 @@ int sigint; int tracking; +// signal handler to execute when receiving SIGINT (CTRL-C) void handler(int signum){ + // while tracking: end tracking and continue execution + // else: exit program if (tracking){ sigint = 1; std::cout << std::endl; @@ -15,10 +18,12 @@ void handler(int signum){ } } +// track time for active task in project void track(Project *proj){ int worktime = 0; int work_h, work_m, work_s; time_t start; + // clear terminal system("clear"); time(&start); tracking = 1; diff --git a/src/tt.cpp b/src/tt.cpp index fbf41a1..68868ca 100644 --- a/src/tt.cpp +++ b/src/tt.cpp @@ -13,16 +13,20 @@ #include "tt.h" #include "util.h" +// glovbal variables: std::string user_name, tracking_dir, config_file; int main(){ // connect SIGINT signal (CTRL-C) to signal handler from track.h to use it to stop tracking of projects signal(SIGINT, handler); tracking = 0; + + // PREFIX set by preprocessor, see Makefile std::string prefix=STRING(PREFIX); config_file = prefix+"/etc/tt.conf"; parse_config_file(config_file, &user_name, &tracking_dir); + // initialize project list for current month ProjectList proj_list(get_date()); // if available: load project list for current month, else: start with list from last month @@ -41,6 +45,7 @@ int main(){ proj_list.load(last_proj_file,true); } + // add command names and names of project list to the autocomplete names init_autocomplete(&proj_list); // use GNU readline for auto completion and history when parsing command input diff --git a/src/tt.h b/src/tt.h index a1e92d2..0ab361c 100644 --- a/src/tt.h +++ b/src/tt.h @@ -2,6 +2,8 @@ #define TT_H #include + +// global variables: extern std::string user_name; extern std::string tracking_dir; extern std::string config_file; diff --git a/src/ui.cpp b/src/ui.cpp index a9fbbea..4b431ca 100644 --- a/src/ui.cpp +++ b/src/ui.cpp @@ -15,8 +15,7 @@ #include "tt.h" #include "util.h" -// Uses GNU readline library for autocompletion and command history - +// names of available commands std::string command_names[num_commands]={ "np", "nt", @@ -32,12 +31,15 @@ std::string command_names[num_commands]={ "save" }; -std::vector autocomplete_names; +std::vector autocomplete_names; // global variable + +// completion function for readline char **tt_name_completion(const char* text, int start, int end){ rl_attempted_completion_over = 1; return rl_completion_matches(text, tt_name_generator); } +// search for input in auto complete names to attempt completion and give options char *tt_name_generator(const char *text, int state){ static std::vector::const_iterator it; if (state == 0) it=begin(autocomplete_names); @@ -51,6 +53,7 @@ char *tt_name_generator(const char *text, int state){ return NULL; } +// add command and project/task names to auto complete list void init_autocomplete(ProjectList *proj_list){ // add command names to auto complete list for (int i=0; i= 0){ + // do not let the user remove projects by accident std::cout << "Do you really want to remove project " << underscore_to_space(proj_name) << "? [y|n]" << std::endl; std::string input; while(1){ @@ -302,6 +306,7 @@ void command_rm(std::string input, ProjectList *proj_list){ int task_id = proj_list->active_project->find_task_id_by_name(trim(underscore_to_space(task_name))); if (task_id >=0){ del = false; + // do not let the user remove tasks by accident std::cout << "Do you really want to remove task " << underscore_to_space(proj->name) << "/" << underscore_to_space(task_name) << "? [y|n]" << std::endl; std::string input; while(1){ @@ -383,6 +388,7 @@ void command_st(std::string input, ProjectList *proj_list){ int proj_id = proj_list->find_project_id_by_name(trim(underscore_to_space(proj_name))); Project *proj = proj_list->find_project_by_name(trim(underscore_to_space(proj_name))); if (place_of_slash == std::string::npos){ + // task in same project proj = proj_list->active_project; proj_id = proj_list->find_project_id_by_name(trim(underscore_to_space(proj_list->active_project->name))); } @@ -540,6 +546,7 @@ void command_rt(std::string input, int wtime, ProjectList *proj_list){ } } +// print monthly report void command_report(std::string date_str, ProjectList* proj_list){ date_str = trim(date_str); size_t place_of_minus = date_str.find("-"); @@ -561,6 +568,7 @@ void command_report(std::string date_str, ProjectList* proj_list){ float wtime_task = proj->tasks[j].work_time / 3600.0; if(wtime_task >= 0.01) std::cout << "--- " << proj->tasks[j].name << ": " << std::fixed << std::setprecision(2) << wtime_task << std::endl; } + // format: *.xx hours std::cout << "Total: " << std::fixed << std::setprecision(2) << wtime_proj << std::endl << std::endl; } } @@ -580,6 +588,7 @@ void command_report(std::string date_str, ProjectList* proj_list){ float wtime_task = proj->tasks[j].work_time / 3600.0; if(wtime_task >= 0.01) std::cout << "--- " << proj->tasks[j].name << ": " << std::fixed << std::setprecision(2) << wtime_task << std::endl; } + // format: *.xx hours std::cout << "Total: " << std::fixed << std::setprecision(2) << wtime_proj << std::endl << std::endl; } } @@ -589,7 +598,8 @@ void command_report(std::string date_str, ProjectList* proj_list){ } } -// save project list to file - POSIX only +// save project list to file, uses system("mkdir") to create diretory +// might be replaced by C++ filesystem API int the future void command_save(ProjectList *proj_list){ std::string date_str = get_date(); std::string file_name = tracking_dir+"/"+date_str; diff --git a/src/util.cpp b/src/util.cpp index 166a6d0..d23180d 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -2,6 +2,7 @@ #include #include "util.h" +// returns string in format "yyyy-mm" std::string get_date(){ time_t t = time(NULL); tm *date = localtime(&t); @@ -17,12 +18,14 @@ std::string get_date(){ return date_str; } +// returns date string for previous month std::string get_last_date(){ time_t t = time(NULL); tm *date = localtime(&t); int month = date->tm_mon; int year = date->tm_year+1900; - + + // in case of January: if(month == 0){ month = 12; year--; @@ -38,6 +41,7 @@ std::string get_last_date(){ return date_str; } +// basic parsing of configureation file to get user name and tracking directory void parse_config_file(std::string file_name, std::string *user_name, std::string *tracking_dir){ std::ifstream f(file_name); if (!f){