Fall back on index for sort if the due date is the same, not just if both due dates...
[tdl.git] / done.c
1 /*;
2    $Header: /cvs/src/tdl/done.c,v 1.10.2.1 2004/01/07 00:09:05 richard Exp $
3   
4    tdl - A console program for managing to-do lists
5    Copyright (C) 2001-2004  Richard P. Curnow
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20    */
21
22 #include "tdl.h"
23
24 int has_open_child(struct node *y)/*{{{*/
25 {
26   struct node *c;
27   int result = 0;
28   for (c = y->kids.next; c != (struct node *) &y->kids; c = c->chain.next) {
29     if (c->done == 0) {
30       result = 1;
31       break;
32     }
33   }
34
35   return result;
36 }
37 /*}}}*/
38 static void mark_done_from_bottom_up(struct links *x, time_t done_time)/*{{{*/
39 {
40   struct node *y; 
41
42   for (y = x->next; y != (struct node *) x; y = y->chain.next) {
43
44     if (has_kids(y)) {
45       mark_done_from_bottom_up(&y->kids, done_time);
46     }
47     
48     if (y->flag) {
49       if (has_open_child(y)) {
50         fprintf(stderr, "Cannot mark %s done, it has open sub-tasks\n", y->scratch);
51       } else {
52         y->done = done_time;
53       }
54     }
55   }
56 }
57 /*}}}*/
58 static int internal_done(time_t when, char **x)/*{{{*/
59 {
60   struct node *n;
61   int do_descendents;
62
63   clear_flags(&top);
64
65   while (*x) {
66     do_descendents = include_descendents(*x); /* May modify *x */
67     n = lookup_node(*x, 0, NULL);
68     if (!n) return -1;
69     n->flag = 1;
70     if (do_descendents) {
71       mark_all_descendents(n);
72     }
73     n->scratch = *x; /* Safe to alias, *x has long lifetime */
74     x++;
75   }
76    
77   mark_done_from_bottom_up(&top, when);
78
79   return 0;
80 }
81 /*}}}*/
82 int process_done(char **x)/*{{{*/
83 {
84   time_t done_time = time(NULL);
85
86   if (*x && (x[0][0] == '@')) {
87     int error;
88     done_time = parse_date(x[0]+1, done_time, 0, &error);
89     if (error < 0) return error;
90     x++;
91   }
92
93   internal_done(done_time, x);
94   return 0;
95 }
96 /*}}}*/
97 int process_ignore(char **x)/*{{{*/
98 {
99   /* (struct node).done == 0 means not done yet.  So use 1 to mean ancient
100    * history (never shows up in reports, sure to be purged at next purge) */
101   internal_done(IGNORED_TIME, x);
102   return 0;
103 }
104 /*}}}*/
105 static void undo_descendents(struct node *y)/*{{{*/
106 {
107   struct node *c;
108   for (c = y->kids.next; c != (struct node *) &y->kids; c = c->chain.next) {
109     c->done = 0;
110     if (has_kids(c)) {
111       undo_descendents(c);
112     }
113   }
114 }
115 /*}}}*/
116 static void undo_ancestors(struct node *y)/*{{{*/
117 {
118   struct node *parent;
119   parent = y->parent;
120   while (parent) {
121     parent->done = 0;
122     parent = parent->parent;
123   }
124 }
125 /*}}}*/
126 int process_undo(char **x)/*{{{*/
127 {
128   struct node *n;
129   int do_descendents;
130
131   while (*x) {
132     do_descendents = include_descendents(*x); /* May modify *x */
133     n = lookup_node(*x, 0, NULL);
134     if (!n) return -1;
135     n->done = 0;
136     undo_ancestors(n);
137     if (do_descendents) {
138       undo_descendents(n);
139     }
140     x++;
141   }
142
143   return 0;
144
145 }
146 /*}}}*/
147
This page took 0.082598 seconds and 4 git commands to generate.