aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordam <dam@gudinoff>2022-10-10 23:47:40 +0000
committerdam <dam@gudinoff>2022-10-10 23:47:40 +0000
commitdd524b83197d85e04948634a1741a1bebe2907ef (patch)
tree70bece03397edb8f789a4dba0caafb7888120bb8
parentf6f597f3074c27fc3b34987d00bce831dbdbd124 (diff)
downloadtask-time-tracker-dd524b83197d85e04948634a1741a1bebe2907ef.tar.zst
task-time-tracker-dd524b83197d85e04948634a1741a1bebe2907ef.zip
Implemented move-to action. Improved TUI and action-keys.
-rw-r--r--main.c94
-rw-r--r--readme.md12
2 files changed, 80 insertions, 26 deletions
diff --git a/main.c b/main.c
index b39d6d0..3c0d7d7 100644
--- a/main.c
+++ b/main.c
@@ -305,7 +305,7 @@ bool delete_task(database_st *db, task_st *task) {
db->count--;
// Adjust selected task.
- if (db->selected_task >= db->count) {
+ if (db->selected_task >= db->count) { // TODO Can we compare ptrdiff_t with size_t?
db->selected_task--;
}
@@ -333,8 +333,57 @@ bool delete_task(database_st *db, task_st *task) {
return true;
}
+// Deletes the task provided in the pointer. If possible, shrinks the database capacity.
+// Returns success.
+bool move_task(database_st *db, task_st *task, size_t target) {
+ assert(db != NULL);
+ assert(task != NULL);
+ assert(task >= db->tasks && task < &db->tasks[db->count]);
+ assert(target >= 0 && target < db->count);
+
+
+
+ // Move tasks after the index position to their new positions.
+ ptrdiff_t index = task - db->tasks;
+ task_st *target_task = &db->tasks[target];
+ ptrdiff_t target_index = target_task - db->tasks;
+
+ if (target_task == task) {
+ return true;
+ }
+
+ task_st temp_task;
+ memcpy(&temp_task, task, SIZEOF_TASK_ST);
+
+ // TODO Simplify code
+ if (target_index > index) {
+ memmove(task, task + 1, (target_index - index) * SIZEOF_TASK_ST);
+ }
+ else {
+ memmove(target_task + 1, target_task, (index - target_index) * SIZEOF_TASK_ST);
+ }
+
+ memcpy(target_task, &temp_task, SIZEOF_TASK_ST);
+
+ if (db->active_task == index) {
+ db->active_task = target_index;
+ }
+ else if (db->active_task > index && db->active_task <= target_index) {
+ db->active_task--;
+ }
+ else if (db->active_task >= target_index && db->active_task < index) {
+ db->active_task++;
+ }
+
+ db->selected_task = target_index;
+
+ return true; // TODO
+}
+
// Resets database to the initial state and deallocates all memory taken by tasks.
void reset_database(database_st *db) {
+ assert(db != NULL);
+
free(db->tasks);
memset(db, 0, SIZEOF_DATABASE_ST);
db->active_task = -1;
@@ -344,7 +393,6 @@ void reset_database(database_st *db) {
// Stores data from database into binary file.
// Returns success.
bool store_database(const database_st *db, const char *path) {
-
assert(db != NULL);
assert(path != NULL);
@@ -366,7 +414,6 @@ bool store_database(const database_st *db, const char *path) {
// Loads data from binary file into database.
// Returns success.
bool load_database(database_st *db, const char *path) {
-
assert(db != NULL);
assert(path != NULL);
@@ -405,7 +452,6 @@ bool load_database(database_st *db, const char *path) {
// Exports data into CSV file.
// Returns success.
bool export_to_csv(const database_st *db, const char *path) {
-
assert(db != NULL);
assert(path != NULL);
@@ -1064,7 +1110,8 @@ int main(int argc, char *argv[]) {
break;
}
- case KEY_F(1): {
+ case 'n':
+ case 'N':{
// Create new task.
task_st *new_task;
if (create_task(db, &new_task) == false) {
@@ -1139,16 +1186,19 @@ int main(int argc, char *argv[]) {
break;
}
- attron(COLOR_PAIR(selected_task_theme) | A_BOLD | A_UNDERLINE);
-
- sprintf(string_buffer, "%*s", size_x - 2, "");
- mvaddstr(selected_task_row, 1, string_buffer);
- mvaddstr(selected_task_row, 1, " Move to: ");
+ attron(COLOR_PAIR(selected_task_theme) | A_BOLD);
+ move(selected_task_row, 1);
+ addch(ACS_CKBOARD);
+ addstr(" Move to: ");
+ int input_pos_x = getcurx(stdscr);
+ sprintf(string_buffer, "%*s", size_x - input_pos_x - 1, "");
+ attron(A_UNDERLINE);
+ addstr(string_buffer);
// Get line number.
echo();
curs_set(1);
- getnstr(string_buffer, MAX_TASK_NAME); // TODO use better value than MAX_TASK_NAME
+ mvgetnstr(selected_task_row, input_pos_x, string_buffer, MAX_TASK_NAME); // TODO use better value than MAX_TASK_NAME
noecho();
curs_set(0);
@@ -1162,12 +1212,12 @@ int main(int argc, char *argv[]) {
}
// TODO Implement move-task-to logic.
- db->selected_task = input < 0 ? 0 :
+ size_t target = input < 0 ? 0 :
input >= db->count ? db->count - 1 :
input;
+ move_task(db, selected_task, target);
break;
- break;
}
case 'g':
@@ -1176,16 +1226,19 @@ int main(int argc, char *argv[]) {
break;
}
- attron(COLOR_PAIR(selected_task_theme) | A_BOLD | A_UNDERLINE);
-
- sprintf(string_buffer, "%*s", size_x - 2, "");
- mvaddstr(selected_task_row, 1, string_buffer);
- mvaddstr(selected_task_row, 1, " Go to: ");
+ attron(COLOR_PAIR(selected_task_theme) | A_BOLD);
+ move(selected_task_row, 1);
+ addch(ACS_CKBOARD);
+ addstr(" Go to: ");
+ int input_pos_x = getcurx(stdscr);
+ sprintf(string_buffer, "%*s", size_x - input_pos_x - 1, "");
+ attron(A_UNDERLINE);
+ addstr(string_buffer);
// Get line number.
echo();
curs_set(1);
- getnstr(string_buffer, MAX_TASK_NAME); // TODO use better value than MAX_TASK_NAME
+ mvgetnstr(selected_task_row, input_pos_x, string_buffer, MAX_TASK_NAME); // TODO use better value than MAX_TASK_NAME
noecho();
curs_set(0);
@@ -1205,7 +1258,8 @@ int main(int argc, char *argv[]) {
break;
}
- case KEY_F(4): {
+ case 'd':
+ case 'D':{
if (selected_task == NULL) {
break;
}
diff --git a/readme.md b/readme.md
index 477a243..f045c66 100644
--- a/readme.md
+++ b/readme.md
@@ -46,16 +46,16 @@ Task Time Tracker
- [x] Check totals update speedup using https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
- For 1M entries, generic C code runs in 12.0ms while special approaches using builtins or SIMD takes around 9.5ms. Not worth the effort.
- [x] Allow to jump to specific task by index number using key `g` and `G`;
-- [ ] Move task to (using task_t tmp_task + memcpy) using key `m` and `M`;
+- [x] Move task to (using task_t tmp_task + memcpy) using key `m` and `M`;
+- [x] Rethink keys;
+ - [x] Create task using keys: `n` and `N`;
+ - [x] Delete task using key: delete;
+ - [x] Change task name using keys: `F2`;
+ - [x] Duplicate task using keys: `d` and `D`;
- [ ] Add/remove time using keys: `F3`;
- [ ] Add/remove time for any day of week;
- [ ] Implement logs as described above.
- [ ] Go over all `TODO` items;
-- [ ] Rethink keys;
- - [ ] Create task using keys: `c` and `C`;
- - [ ] Delete task using keys: `d` and `D`;
- - [ ] Change task name using keys: `F2`;
- - [ ] Clone task using keys: `r` and `R`;
- [ ] Cleanup `draw_tui`:
- Selected and active tasks should be drawn after everything else.
- Try printing each row;