Calendar uses month+1
[gregoa/zavai.git] / src / app_calendar.vala
1 /*
2  * app_calendar - zavai calendar applet
3  *
4  * Copyright (C) 2009  Enrico Zini <enrico@enricozini.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 namespace zavai {
22 namespace ui {
23 namespace calendar {
24
25 public class Calendar : Applet
26 {
27         protected Gtk.Calendar calendar;
28         protected Gtk.ScrolledWindow scroll;
29         protected Gtk.TextBuffer text_buffer;
30         protected Gtk.TextView text;
31         protected int cur_year;
32         protected int cur_month;
33         protected int cur_day;
34         protected bool text_dirty;
35         protected Regex re_dayfile;
36
37         public Calendar()
38         {
39                 _label = "Calendar";
40                 calendar = new Gtk.Calendar();
41                 calendar.day_selected += on_day_selected;
42                 calendar.month_changed += on_month_changed;
43                 pack_start(calendar, false, false, 0);
44
45                 text_buffer = new Gtk.TextBuffer(null);
46                 text_buffer.changed += on_textbuffer_changed;
47                 text = new Gtk.TextView.with_buffer(text_buffer);
48                 text.wrap_mode = Gtk.WrapMode.WORD;
49                 text.cursor_visible = true;
50                 text.editable = true;
51                 scroll = new Gtk.ScrolledWindow (null, null);
52                 scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
53                 scroll.add(text);
54                 pack_start(scroll, true, true, 0);
55
56                 re_dayfile = new Regex("[0-9][0-9]\\.txt");
57
58                 text_dirty = false;
59         }
60         
61         private void on_textbuffer_changed()
62         {
63                 text_dirty = true;
64         }
65
66         private string month_path(int year, int month)
67         {
68                 return "%s/cal/%04d/%02d".printf(zavai.config.homedir, year, month);
69         }
70
71         private string day_path(int year, int month, int day)
72         {
73                 return "%s/%02d.txt".printf(month_path(year, month), day);
74         }
75
76         private void flush()
77         {
78                 if (text_dirty)
79                         save(cur_year, cur_month, cur_day);
80         }
81
82         private void on_month_changed()
83         {
84                 flush();
85                 calendar.clear_marks();
86                 string mpath = month_path(calendar.year, calendar.month + 1);
87                 Dir dir;
88                 try {
89                         dir = Dir.open(mpath);
90                 } catch (FileError e) {
91                         zavai.log.error(e.message);
92                         return;
93                 }
94                 while (true)
95                 {
96                         var d = dir.read_name();
97                         if (d == null) break;
98                         if (re_dayfile.match(d))
99                         {
100                                 calendar.mark_day((int)d.to_ulong(null, 10));
101                         }
102                 }
103         }
104
105         private void on_day_selected()
106         {
107                 flush();
108                 load(calendar.year, calendar.month + 1, calendar.day);
109                 // Scroll to beginning
110                 Gtk.TextIter iter;
111                 text_buffer.get_iter_at_offset(out iter, 0);
112                 Gtk.TextMark mark = text_buffer.create_mark(null, iter, true);
113                 text.scroll_mark_onscreen(mark);
114         }
115
116         private void load(int year, int month, int day)
117         {
118                 string path = day_path(year, month, day);
119                 if (!FileUtils.test (path, FileTest.IS_REGULAR))
120                         text_buffer.text = "";
121                 else
122                 {
123                         try {
124                                 string text;
125                                 FileUtils.get_contents(path, out text);
126                                 text_buffer.text = text;
127                         } catch (FileError e) {
128                                 zavai.log.error(e.message);
129                                 text_buffer.text = "";
130                         }
131                 }
132                 text_dirty = false;
133                 cur_year = year; cur_month = month; cur_day = day;
134         }
135
136         private void save(int year, int month, int day)
137         {
138                 string mpath = month_path(year, month);
139                 if (DirUtils.create_with_parents(mpath, 0777) < 0)
140                 {
141                         zavai.log.error("Cannot create directory " + mpath);
142                         return;
143                 }
144                 string path = day_path(year, month, day);
145                 try {
146                         FileUtils.set_contents(path, text_buffer.text);
147                 } catch (FileError e) {
148                         zavai.log.error(e.message);
149                 }
150                 text_dirty = false;
151
152                 if (calendar.year == year && calendar.month + 1 == month)
153                 {
154                         calendar.mark_day(day);
155                 }
156         }
157
158         public override void start()
159         {
160                 // Go to current date
161                 var now = Time.local(time_t());
162                 calendar.year = now.year + 1900;
163                 calendar.month = now.month;
164                 calendar.day = now.day;
165         }
166         public override void stop()
167         {
168                 flush();
169         }
170 }
171
172 Calendar calendar;
173
174 public void init()
175 {
176         calendar = new Calendar();
177         zavai.registry.register_applet("ui.calendar", calendar);
178         zavai.registry.getmenu("menu.misc").add_applet("ui.calendar");
179 }
180
181 }
182 }
183 }