From cb5385b932956072fc14fd6531c45f12c9cc4925 Mon Sep 17 00:00:00 2001 From: Daniel Liu Date: Sun, 7 Feb 2021 23:57:48 -0500 Subject: [PATCH] moving items between lists --- .gitignore | 1 - README.md | 13 ++- headers/menu.h | 5 +- menu.c | 52 ++++++----- old.c | 227 ------------------------------------------------- parser.c | 1 + taskasaur.c | 54 +++++++++++- 7 files changed, 98 insertions(+), 255 deletions(-) delete mode 100644 .gitignore delete mode 100644 old.c diff --git a/.gitignore b/.gitignore deleted file mode 100644 index ba2906d..0000000 --- a/.gitignore +++ /dev/null @@ -1 +0,0 @@ -main diff --git a/README.md b/README.md index 9f4deb7..36e7a34 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,15 @@ A very simple kanban style todolist with vim keybindings. -Boards are stored in markdown files. +This project is practically a clone of [taskell](https://github.com/smallhadroncollider/taskell), but written in c, since the haskell dependencies that were pulled in were a bit too heavy for my liking. + +Taskasaur is also meant to be extended with patches, allowing the main project to remain slim. Simply edit the config.h file to your liking and recompile. + +## Installation + +To build from source, simply clone the repo and run +``` +make && sudo make clean install +``` + +A gentoo ebuild with savedconfig use may or may not be coming in the future. diff --git a/headers/menu.h b/headers/menu.h index 89b46b0..617f416 100644 --- a/headers/menu.h +++ b/headers/menu.h @@ -29,12 +29,15 @@ extern MenuItem* create_menuitem(char* contents); extern Menu* create_menu(char* menu_name, MenuItem** item_list); extern int set_menu_win(Menu* menu, WINDOW* win); -extern MenuItem* get_menu_items(Menu* menu); +extern MenuItem* get_menu_item(Menu* menu, int index); extern int set_menu_focus(Menu* menu, bool focus); extern int get_selected_item(Menu* menu); extern int set_selected_item(Menu* menu, int selected_item); extern int get_menu_length(Menu* menu); +extern int insert_item(Menu* menu, MenuItem* menuitem, int index); +extern int delete_item(Menu* menu, int index); + extern int menu_driver(Menu* menu, MenuAction action); extern int render_menu(Menu* menu); diff --git a/menu.c b/menu.c index 1013a69..6768de2 100644 --- a/menu.c +++ b/menu.c @@ -34,12 +34,14 @@ typedef struct Menu { } Menu; int swap_item(Menu* menu, int src_index, int dest_index); -int delete_item(Menu* menu, int index); -int insert_item(Menu* menu, int index); /* insert mode */ int menu_insert_mode(Menu* menu, int insert_index); +/* prob temp for now */ +MenuItem* create_blank_menuitem(void); + + MenuItem* create_menuitem(char* contents) { @@ -51,6 +53,12 @@ create_menuitem(char* contents) return new_menuitem; } +MenuItem* +create_blank_menuitem(void) +{ + return create_menuitem(strdup("")); +} + Menu* create_menu(char* menu_name, MenuItem** item_list) { @@ -91,9 +99,11 @@ set_menu_win(Menu* menu, WINDOW* win) } MenuItem* -get_menu_items(Menu* menu) +get_menu_item(Menu* menu, int index) { - return NULL; + if (index < 0 || index >= menu->menu_length) return NULL; + + return menu->menu_items[index]; } int @@ -141,10 +151,9 @@ delete_item(Menu* menu, int index) { if (index < 0 || index > menu->menu_length-1) return -1; - int temp_size = (menu->menu_length-index-1)*sizeof(MenuItem*); - - /* might break if last item? */ - memmove(menu->menu_items[index], menu->menu_items[index+1], temp_size); + for (int i = index; i <= menu->menu_length-1; i++) { + menu->menu_items[i] = menu->menu_items[i+1]; + } menu->menu_items = realloc(menu->menu_items, menu->menu_length*sizeof(MenuItem*)); menu->menu_items[menu->menu_length-1] = 0; // preserve null at end @@ -156,22 +165,15 @@ delete_item(Menu* menu, int index) menu->selected_item = menu->menu_length-1; } + wclear(menu->sub_win); + return 0; } int -insert_item(Menu* menu, int index) +insert_item(Menu* menu, MenuItem* menuitem, int index) { // note, this func does not validate index - char* new_content; - MenuItem* new_menuitem; - - // remember null char - /* new_content = malloc((MAX_CONTENTS_LENGTH+1)*sizeof(char)); */ - new_content = strdup(""); - - new_menuitem = create_menuitem(new_content); - /* resize array and insert */ menu->menu_items = realloc(menu->menu_items, (menu->menu_length+2)*sizeof(MenuItem*)); @@ -179,7 +181,7 @@ insert_item(Menu* menu, int index) menu->menu_items[i] = menu->menu_items[i-1]; } - menu->menu_items[index] = new_menuitem; + menu->menu_items[index] = menuitem; menu->menu_items[menu->menu_length+1] = 0; // remember null at end menu->menu_length += 1; @@ -215,6 +217,11 @@ menu_insert_mode(Menu* menu, int insert_index) new_contents = strdup(temp); menu->menu_items[insert_index]->contents = new_contents; + /* delete if empty - maybe move this to a cleanup stage */ + if (strlen(new_contents) == 0) { + delete_item(menu, insert_index); + } + return 0; } @@ -253,21 +260,20 @@ menu_driver(Menu* menu, MenuAction action) case MENU_DELETE: delete_item(menu, menu->selected_item); - wclear(menu->sub_win); break; case MENU_APPEND: - insert_item(menu, menu->menu_length); + insert_item(menu, create_blank_menuitem(), menu->menu_length); menu_insert_mode(menu, menu->selected_item); break; case MENU_INSERT_ABOVE: - insert_item(menu, menu->selected_item); + insert_item(menu, create_blank_menuitem(), menu->selected_item); menu_insert_mode(menu, menu->selected_item); break; case MENU_INSERT_BELOW: - insert_item(menu, menu->selected_item+1); + insert_item(menu, create_blank_menuitem(), menu->selected_item+1); menu_insert_mode(menu, menu->selected_item); // inserted item is cur now break; diff --git a/old.c b/old.c deleted file mode 100644 index 28c25a8..0000000 --- a/old.c +++ /dev/null @@ -1,227 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#define SELECTED_COLOR 1 -#define NON_SELECTED_COLOR 2 - -struct todo_item { - char* name; - char* description; - char** items; -}; - -void winch_handler(int sig); - -char** read_todo(FILE* file, int* length); - -WINDOW* create_win(int height, int width, int y, int x); -MENU* create_todo_menu(WINDOW* win, char** todo_list, int todo_length); - -void on_select(char *item); - -void free_todo(char** todo_list, int todo_length); - -#include "config.h" - -int -main(int argc, char** argv) -{ - int flag; - FILE* board_file; - char** todos; - int todo_length; - - int height, width; - int ch; - - WINDOW* todo_win; - MENU* todo_menu; - - signal(SIGWINCH, winch_handler); - - // read command line args - flag = getopt(argc, argv, "o:n:"); - switch (flag) { - case 'o': - - // read from task file (might need to check for read and write permissions) - board_file = fopen(optarg, "r"); - if (!board_file) { - printf("%s does not exist\n", optarg); - return 1; - } - - todos = read_todo(board_file, &todo_length); - fclose(board_file); - - break; - - case 'n': - - // make sure file does not exist - // however, it maybe be possible that an different error has occured (besides the file not existing) - if (access(optarg, F_OK) == 0) { - printf("%s already exists\n", optarg); - return 1; - } - // create a file here - board_file = fopen(optarg, "w"); - // write init stuff here - fclose(board_file); - printf("Successfully created %s\n", optarg); - - todos = malloc(0); - todo_length = 0; - - break; - - case -1: - case '?': - printf("Help string\n"); - return 2; - } - - // start ncurses - initscr(); - cbreak(); - noecho(); - curs_set(0); - keypad(stdscr, TRUE); - start_color(); - - /* colors */ - init_pair(SELECTED_COLOR, selected_color, COLOR_BLACK); - init_pair(NON_SELECTED_COLOR, non_selected_color, COLOR_BLACK); - - getmaxyx(stdscr, height, width); - - todo_win = create_win(20, 40, 5, 5); - todo_menu = create_todo_menu(todo_win, todos, todo_length); - post_menu(todo_menu); - refresh(); - wrefresh(todo_win); - - while ((ch = getch()) != BINDING_QUIT) { - - switch (ch) { - case BINDING_SCROLL_UP: - menu_driver(todo_menu, REQ_UP_ITEM); - break; - case BINDING_SCROLL_DOWN: - menu_driver(todo_menu, REQ_DOWN_ITEM); - break; - case BINDING_JUMP_TOP: - menu_driver(todo_menu, REQ_FIRST_ITEM); - break; - case BINDING_JUMP_BOTTOM: - menu_driver(todo_menu, REQ_LAST_ITEM); - break; - case BINDING_SELECT: - break; - } - wrefresh(todo_win); - - } - - endwin(); - - /* Free mem */ - unpost_menu(todo_menu); - free_todo(todos, todo_length); - - return 0; -} - -void -winch_handler(int sig) -{ - endwin(); - refresh(); -} - -char** -read_todo(FILE* file, int* length) -{ // apparently getline isn't rly that portable, so consider other options - char** out_arr; - int out_len; - char* lineptr; - size_t len; - ssize_t nread; - - out_arr = NULL; - out_len = 0; - lineptr = NULL; - len = 0; - - while ((nread = getline(&lineptr, &len, file)) != -1) { - out_len++; - out_arr = realloc(out_arr, (sizeof(char*))*out_len); // bad to keep resizing? - - lineptr[strcspn(lineptr, "\n")] = 0; // remove newline - out_arr[out_len-1] = lineptr; - - lineptr = NULL; - } - - *length = out_len; - return out_arr; -} - -WINDOW* -create_win(int height, int width, int y, int x) -{ - WINDOW* new_win = newwin(height, width, y, x); - wrefresh(new_win); - return new_win; -} - -MENU* -create_todo_menu(WINDOW* win, char** todo_list, int todo_length) -{ - MENU* todo_menu; - ITEM** item_list; - ITEM* cur_item; - int wheight, wwidth; - - item_list = malloc((todo_length+1)*sizeof(ITEM*)); - for (int i = 0; i < todo_length; i++) { - item_list[i] = new_item(todo_list[i], ""); - set_item_userptr(item_list[i], on_select); - } - item_list[todo_length] = NULL; // last item needs to be a null pointer for some reason? - - todo_menu = new_menu(item_list); - - getmaxyx(win, wheight, wwidth); - set_menu_win(todo_menu, win); - set_menu_sub(todo_menu, derwin(win, wheight-2, wwidth-2, 1, 2)); - set_menu_mark(todo_menu, ""); - set_menu_spacing(todo_menu, 1, 2, 1); - set_menu_fore(todo_menu, COLOR_PAIR(SELECTED_COLOR)); - set_menu_back(todo_menu, COLOR_PAIR(NON_SELECTED_COLOR)); - - box(win, 0, 0); //temp - - return todo_menu; -} - -void -on_select(char *item) -{ - printf("lol"); -} - -void -free_todo(char** todo_list, int todo_length) -{ - // probably check if list is too short or too long - for (int i = 0; i < todo_length; i++) { - free(todo_list[i]); - } - free(todo_list); -} diff --git a/parser.c b/parser.c index 9b129d4..326d3c7 100644 --- a/parser.c +++ b/parser.c @@ -165,6 +165,7 @@ exit_todolist(State* state) sb->todolist_list[sb->todolist_count-1] = state->cur_todolist; state->cur_todolist = NULL; + #undef sb } void diff --git a/taskasaur.c b/taskasaur.c index 8eb2f89..dc90110 100644 --- a/taskasaur.c +++ b/taskasaur.c @@ -71,9 +71,60 @@ main(int argc, char** argv) menu_driver(active_menu, MENU_MOVE_DOWN); break; case BINDING_MOVE_ITEM_LEFT: + if (boardmenu->selected-1 < 0) break; + { + Menu* from_menu; + Menu* to_menu; + + from_menu = boardmenu->menu_list[boardmenu->selected], + to_menu = boardmenu->menu_list[boardmenu->selected-1], + + insert_item( + to_menu, + get_menu_item( + from_menu, + get_selected_item(from_menu) + ), + min( + get_selected_item(from_menu), + get_menu_length(to_menu) + ) + ); + delete_item( + from_menu, + get_selected_item(from_menu) + ); + set_selected_menu(boardmenu, boardmenu->selected-1); + } break; case BINDING_MOVE_ITEM_RIGHT: + if (boardmenu->selected >= boardmenu->menu_count-1) break; + // this is legit cpy paste please fix this + { + Menu* from_menu; + Menu* to_menu; + + from_menu = boardmenu->menu_list[boardmenu->selected], + to_menu = boardmenu->menu_list[boardmenu->selected+1], + + insert_item( + to_menu, + get_menu_item( + from_menu, + get_selected_item(from_menu) + ), + min( + get_selected_item(from_menu), + get_menu_length(to_menu) + ) + ); + delete_item( + from_menu, + get_selected_item(from_menu) + ); + set_selected_menu(boardmenu, boardmenu->selected+1); + } break; case BINDING_DELETE_ITEM: @@ -133,8 +184,7 @@ set_selected_menu(BoardMenu* boardmenu, int index) /* also try to jump to a similar position if possible */ /* rn theres a bug if old menu is empty */ - new_pos = (get_selected_item(old_menu) > get_menu_length(new_menu)-1) ? - get_menu_length(new_menu)-1 : get_selected_item(old_menu); + new_pos = min(get_selected_item(old_menu), get_menu_length(new_menu)-1); set_selected_item(new_menu, new_pos); boardmenu->selected = index; -- 2.20.1