2 * widgets/calendar - zavai calendar widget
4 * Copyright (C) 2009 Enrico Zini <enrico@enricozini.org>
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.
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.
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
24 private string month_path(int year, int month)
26 return "%s/cal/%04d/%02d".printf(zavai.config.homedir, year, month);
29 private string day_path(int year, int month, int day)
31 return "%s/%02d.txt".printf(month_path(year, month), day);
35 public class FileNotes : Gtk.ScrolledWindow
37 protected Gtk.TextBuffer text_buffer;
38 protected Gtk.TextView text;
39 protected bool text_dirty;
40 protected string fname;
46 text_buffer = new Gtk.TextBuffer(null);
47 text_buffer.changed += on_textbuffer_changed;
48 text = new Gtk.TextView.with_buffer(text_buffer);
49 text.wrap_mode = Gtk.WrapMode.WORD;
50 text.cursor_visible = true;
53 set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
57 private void on_textbuffer_changed()
62 public void load(string new_fname)
67 if (!FileUtils.test (fname, FileTest.IS_REGULAR))
68 text_buffer.text = "";
73 FileUtils.get_contents(fname, out text);
74 text_buffer.text = text;
75 } catch (FileError e) {
76 zavai.log.error(e.message);
77 text_buffer.text = "";
81 // Scroll to beginning
83 text_buffer.get_iter_at_offset(out iter, 0);
84 Gtk.TextMark mark = text_buffer.create_mark(null, iter, true);
85 text.scroll_mark_onscreen(mark);
92 if (fname == null) return;
93 if (text_dirty == false) return;
95 string mpath = Path.get_dirname(fname);
96 if (DirUtils.create_with_parents(mpath, 0777) < 0)
98 zavai.log.error("Cannot create directory " + mpath);
102 if (text_buffer.text == "")
104 if (FileUtils.test(fname, FileTest.EXISTS))
105 FileUtils.unlink(fname);
107 FileUtils.set_contents(fname, text_buffer.text);
109 } catch (FileError e) {
110 zavai.log.error(e.message);
116 public class Next30 : Gtk.ScrolledWindow
118 protected Gtk.ListStore model;
119 protected Gtk.TreeView list;
120 public signal void selected(int year, int month, int day);
124 set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
125 model = new Gtk.ListStore(5, typeof(string), typeof(string), typeof(int), typeof(int), typeof(int));
126 list = new Gtk.TreeView.with_model(model);
127 list.insert_column_with_attributes (-1, "Day", new Gtk.CellRendererText(), "text", 0);
128 list.insert_column_with_attributes (-1, "Notes", new Gtk.CellRendererText(), "text", 1);
131 list.cursor_changed += on_row_selected;
134 //private void on_row_selected(Gtk.TreeView tv, Gtk.TreePath path, Gtk.TreeViewColumn column)
135 private void on_row_selected(Gtk.TreeView tv)
138 list.get_cursor(out path, null);
142 if (!model.get_iter(out iter, path)) return;
143 Value year, month, day;
144 model.get_value(iter, 2, out year);
145 model.get_value(iter, 3, out month);
146 model.get_value(iter, 4, out day);
147 selected((int)year, (int)month, (int)day);
150 protected void add_day(Date date, string notes)
152 var buffer = new char[64];
153 date.strftime(buffer, "%d %a");
155 model.append (out iter);
156 model.set(iter, 0, (string)buffer);
157 model.set(iter, 1, notes);
158 model.set(iter, 2, date.get_year());
159 model.set(iter, 3, date.get_month());
160 model.set(iter, 4, date.get_day());
163 public void update(Date start)
167 for (uint i = 0; i < 30; ++i)
169 string path = day_path(date.get_year(), date.get_month(), date.get_day());
171 if (!FileUtils.test (path, FileTest.IS_REGULAR))
176 FileUtils.get_contents(path, out text);
177 } catch (FileError e) {
181 if (i == 0 || text != "")
190 public class Calendar : Gtk.VBox
192 protected Gtk.Calendar calendar;
193 protected Gtk.Notebook notebook;
194 protected Gtk.Notebook day_notebook;
195 protected FileNotes month_notes;
196 protected FileNotes day_notes;
197 protected FileNotes general_notes;
198 protected Next30 next_30;
199 protected int cur_year;
200 protected int cur_month;
201 protected int cur_day;
202 protected Regex re_dayfile;
206 calendar = new Gtk.Calendar();
207 calendar.day_selected += on_day_selected;
208 calendar.month_changed += on_month_changed;
209 pack_start(calendar, false, false, 0);
211 notebook = new Gtk.Notebook();
213 day_notebook = new Gtk.Notebook();
214 next_30 = new Next30();
215 next_30.selected += on_next30_selected;
216 day_notebook.append_page(next_30, new Gtk.Label("Next 30"));
217 day_notes = new FileNotes();
218 day_notebook.append_page(day_notes, new Gtk.Label("Day"));
219 notebook.append_page(day_notebook, new Gtk.Label("Day"));
220 day_notebook.show_tabs = false;
222 month_notes = new FileNotes();
223 notebook.append_page(month_notes, new Gtk.Label("Month"));
224 general_notes = new FileNotes();
225 general_notes.load(zavai.config.homedir + "/cal/notes.txt");
226 notebook.append_page(general_notes, new Gtk.Label("General"));
228 pack_start(notebook, true, true, 0);
230 re_dayfile = new Regex("[0-9][0-9]\\.txt");
236 private void on_next30_selected(int year, int month, int day)
238 // Select this day in the calendar
239 calendar.year = year;
240 calendar.month = month-1;
243 // View the day notes
244 day_notebook.set_current_page(1);
246 // TODO: when clicking on calendar, show next30 again
249 private void on_month_changed()
252 calendar.clear_marks();
253 string mpath = month_path(calendar.year, calendar.month + 1);
254 month_notes.load(mpath + "/00.txt");
257 dir = Dir.open(mpath);
258 } catch (FileError e) {
259 zavai.log.error(e.message);
264 var d = dir.read_name();
265 if (d == null) break;
266 if (re_dayfile.match(d))
268 calendar.mark_day((int)d.to_ulong(null, 10));
273 private void on_day_selected()
275 cur_year = calendar.year;
276 cur_month = calendar.month + 1;
277 cur_day = calendar.day;
279 string path = day_path(cur_year, cur_month, cur_day);
280 day_notes.load(path);
282 string mpath = month_path(cur_year, cur_month);
283 month_notes.load(mpath + "/00.txt");
286 date.set_dmy((DateDay)cur_day, cur_month, (DateYear)cur_year);
287 next_30.update(date);
288 day_notebook.set_current_page(0);
295 general_notes.save();
298 public void show_today()
300 // Go to current date
301 var now = Time.local(time_t());
302 calendar.year = now.year + 1900;
303 calendar.month = now.month;
304 calendar.day = now.day;