diff --git a/cl-todo.lisp b/cl-todo.lisp index 948e0a9..1ce985f 100644 --- a/cl-todo.lisp +++ b/cl-todo.lisp @@ -11,30 +11,39 @@ ;;TODO change into a list of lists ;;TODO add text field at end of file (defvar *task-list* NIL) +(defvar *note-text* "") (defvar *runfile* (uiop:native-namestring "~/.todo")) (defun launch () - (setf *task-list* (load-task-file)) + (multiple-value-setq + (*task-list* *note-text*) + (load-task-file)) (make-gui) (bt:join-thread (gtk-thread))) (defun load-task-file (&optional (file-name *runfile*)) - "Load a list of (task) strings from the run file" + "Load a list of (task) strings and the note text from the run file" (with-open-file (f file-name :if-does-not-exist nil) (when (null f) (format t "~&No task file found at ~S" file-name) (return-from load-task-file)) (do* ((line (read-line f nil nil) (read-line f nil nil)) - (tasks NIL)) - ((null line) tasks) - (setf tasks (append tasks (list line)))))) - -(defun write-task-list (&optional (lst *task-list*) (filename *runfile*)) - "Write the task list to file, one entry per line." + (tasks-complete NIL) + (tasks NIL) (notes "")) + ((null line) (values tasks notes)) + (if tasks-complete + (setf notes (concatenate 'string notes line (string #\Newline))) + (if (equalp line "!=====!") + (setf tasks-complete T) + (setf tasks (append tasks (list line)))))))) + +(defun write-task-list (&optional (lst *task-list*) (notes *note-text*) (filename *runfile*)) + "Write the task list to file, one entry per line, and append the notes." (let ((f (open filename :direction :output :if-exists :supersede))) (dolist (i lst) (format f "~&~A" i)) + (format f "~&!=====!~&~A" notes) (close f))) (defun add-task! (task) diff --git a/cl-todo.lisp b/cl-todo.lisp index 948e0a9..1ce985f 100644 --- a/cl-todo.lisp +++ b/cl-todo.lisp @@ -11,30 +11,39 @@ ;;TODO change into a list of lists ;;TODO add text field at end of file (defvar *task-list* NIL) +(defvar *note-text* "") (defvar *runfile* (uiop:native-namestring "~/.todo")) (defun launch () - (setf *task-list* (load-task-file)) + (multiple-value-setq + (*task-list* *note-text*) + (load-task-file)) (make-gui) (bt:join-thread (gtk-thread))) (defun load-task-file (&optional (file-name *runfile*)) - "Load a list of (task) strings from the run file" + "Load a list of (task) strings and the note text from the run file" (with-open-file (f file-name :if-does-not-exist nil) (when (null f) (format t "~&No task file found at ~S" file-name) (return-from load-task-file)) (do* ((line (read-line f nil nil) (read-line f nil nil)) - (tasks NIL)) - ((null line) tasks) - (setf tasks (append tasks (list line)))))) - -(defun write-task-list (&optional (lst *task-list*) (filename *runfile*)) - "Write the task list to file, one entry per line." + (tasks-complete NIL) + (tasks NIL) (notes "")) + ((null line) (values tasks notes)) + (if tasks-complete + (setf notes (concatenate 'string notes line (string #\Newline))) + (if (equalp line "!=====!") + (setf tasks-complete T) + (setf tasks (append tasks (list line)))))))) + +(defun write-task-list (&optional (lst *task-list*) (notes *note-text*) (filename *runfile*)) + "Write the task list to file, one entry per line, and append the notes." (let ((f (open filename :direction :output :if-exists :supersede))) (dolist (i lst) (format f "~&~A" i)) + (format f "~&!=====!~&~A" notes) (close f))) (defun add-task! (task) diff --git a/gtk-ui.lisp b/gtk-ui.lisp index 0e229d6..4387407 100644 --- a/gtk-ui.lisp +++ b/gtk-ui.lisp @@ -23,7 +23,7 @@ :orientation :vertical :spacing 5)) (input-field (gtk-entry-new)) - (text-field (gtk-text-view-new)) + (text-pane (gtk-text-view-new)) (text-scroller (gtk-scrolled-window-new)) (tabs (gtk-notebook-new)) (scroller (make-instance 'gtk-scrolled-window @@ -46,17 +46,22 @@ (gtk-container-add scroller (create-task-widgets inner-box)) (gtk-box-pack-start outer-box scroller) (gtk-notebook-append-page tabs outer-box (gtk-label-new "Tasks")) - (gtk-container-add text-scroller text-field) + (setf (gtk-text-buffer-text (gtk-text-view-buffer text-pane)) *note-text*) + (gtk-container-add text-scroller text-pane) (gtk-notebook-append-page tabs text-scroller (gtk-label-new "Notes")) (gtk-container-add window tabs) + ;;autosave the notes panel + (g-signal-connect (gtk-text-view-buffer text-pane) "changed" + #'update-note-text) ;;ESCAPE quits the program + ;;TODO switch tabs with ALT+LEFT/RIGHT (g-signal-connect window "key-press-event" #'(lambda (window event) (when (equalp (gdk-keyval-name (gdk-event-key-keyval event)) "Escape") (gtk-widget-destroy window) (leave-gtk-main)))) ;;show the window - ;;TODO make window decoration switchable + ;;TODO make window decoration switchable with ALT+W ;;(setf (gtk-window-decorated window) decorated) (gtk-widget-show-all window)))) @@ -82,6 +87,11 @@ (gtk-box-pack-start box task-button) task-button)) +(defun update-note-text (text-buffer) + "Update the notes buffer with the contents of the text pane" + (setf *note-text* (gtk-text-buffer-text text-buffer)) + (write-task-list)) + (defun gtk-thread () "Return the thread object running the GTK main loop" (dolist (th (bt:all-threads))