Allow use of uptree .todo files
[ttodo.git] / elist.cc
blobf311cd1a7e8188526f8684ee3c90d442c0a46f3a
1 // elist.cc
2 //
4 #include "elist.h"
5 #include <stdio.h>
7 //----------------------------------------------------------------------
9 /// Constructs a list displaying \p rctdl
10 CTodoList::CTodoList (void)
11 : CListbox (),
12 m_pTodos (NULL),
13 m_CopiedId (0)
17 /// Sets the list to display.
18 void CTodoList::SetList (pctodolist_t pl)
20 m_pTodos = pl;
21 if (m_pTodos)
22 SetListSize (pl->size());
25 /// Sets internal variables when the document is updated.
26 void CTodoList::OnUpdate (void)
28 CListbox::OnUpdate();
29 SetList (&Document()->List());
30 SetSelection (Document()->Selection());
33 /// Draws list item \p ii at \p pos onto \p gc.
34 void CTodoList::OnDrawItem (CGC& gc, rcpos_t pos, uint32_t ii)
36 CListbox::OnDrawItem (gc, pos, ii);
37 if (!m_pTodos)
38 return;
39 const CTodoEntry& e ((*m_pTodos)[ii]);
40 char progBuf [5];
41 gc.Char (pos, "+ "[!e.HasSublist()]);
42 snprintf (progBuf, 5, "%3u%%", e.Progress());
43 gc.Text (pos[0] + 1, pos[1], e.Progress() ? progBuf : " ");
44 static const EColor c_PriorityColors [2][CTodoEntry::priority_Last] = {
45 { lightred, yellow, green, cyan, lightblue },
46 { lightred, yellow, lightgreen, lightcyan, lightblue }
48 gc.FgColor (c_PriorityColors [ii == Selection()][e.Priority()]);
49 gc.Text (pos[0] + 6, pos[1], e.Text());
52 /// Causes the current entry to be edited.
53 inline void CTodoList::EditEntry (void)
55 SetFlag (f_OffersFocus);
58 /// Processes keystroke \p key.
59 void CTodoList::OnKey (wchar_t key)
61 CListbox::OnKey (key);
62 pdoc_t pDoc = Document();
63 bool bReadOnly = pDoc->Flag (CDocument::f_ReadOnly);
65 if (pDoc->Selection() != Selection())
66 pDoc->SetSelection (Selection());
68 // Item navigation keys are always available.
69 if (key == kv_Left || key == 'h')
70 pDoc->LeaveCurrentEntry();
71 else if (key == 'o')
72 pDoc->ToggleCompleteVisible();
73 else if (key == 'S') { // If read-only, get an error here.
74 pDoc->Save();
75 Commit();
76 } else if (key == 'q') {
77 if (pDoc->Flag (CDocument::f_Changed)) {
78 int rv = MessageBox ("There are unsaved changes. Save now?", MB_YesNoCancel);
79 if (rv == mbrv_Cancel)
80 return;
81 else if (rv != mbrv_No)
82 pDoc->Save();
84 Close();
87 // Modification operations that are valid without a selection
88 if (!bReadOnly) {
89 if (key == 'v' && m_CopiedId)
90 pDoc->PasteLinkToEntry (m_CopiedId);
91 else if (key == 'n') {
92 pDoc->SetSelection (pDoc->ListSize() - 1);
93 pDoc->AppendEntry();
94 EditEntry();
98 // Everything below this requires a selection (that is, a non-empty list)
99 if (pDoc->Selection() >= pDoc->ListSize())
100 return;
102 // Navigation is available even if read-only
103 if (key == kv_Right || key == 'l' || key == kv_Enter)
104 pDoc->EnterCurrentEntry();
106 // Modification operations on the current entry.
107 if (!bReadOnly) {
108 if (key == kv_Space) // Toggle complete flag
109 pDoc->MarkEntryComplete();
110 else if (key == kv_Delete || key == 'D')
111 pDoc->RemoveCurrentEntry();
112 else if (key == 'e')
113 EditEntry();
114 else if (key == 'c')
115 m_CopiedId = pDoc->CurrentEntry().Id();
116 else if (key >= '1' && key <= '5')
117 pDoc->SetCurrentEntryPriority (CTodoEntry::EPriority (key - '1'));
118 else if (key == kv_Insert || key == 'i') {
119 pDoc->AppendEntry();
120 EditEntry();