updated on Sun Jan 22 16:00:49 UTC 2012
[aur-mirror.git] / pylendar / pylendar.py
blob6531e6f3223c8de9cebeb943bc4d3673ac33275b
1 #!/usr/bin/env python2
2 # -*- coding: utf-8 -*-
4 # pylendar -- simple GTK calendar, with basic calendar features, that
5 # uses another application, like GNU Emacs org-mode, for
6 # agenda and project management.
7 # Copyright (C) 2009, 2010 Adrian C. <anrxc_sysphere_org>
9 # This program is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 2 of the License, or
12 # (at your option) any later version.
14 # Documentation
15 # - http://www.pygtk.org/docs/pygtk/
17 import gtk
18 import gobject
19 from sys import argv
20 from os import path, getenv
21 from subprocess import call
22 from calendar import month_name
23 # From 2.4 CALENDAR_WEEK_START_MONDAY is ignored and locales are used,
24 # which is broken, but if you still want it in your own language call:
25 import locale
26 locale.setlocale(locale.LC_ALL, "en_US.utf-8")
29 # Pylendar settings
31 # Name, Type, X, Y, Padding, Border, Timeout, Buttons
32 appprop = ["Pylendar", gtk.WINDOW_POPUP, 1088, 14, 0, 5, 15000, True]
34 # Icon theme, icon size, icon category, icon name
35 appicon = ["Tango", "16x16", "apps", "office-calendar.png"]
37 # Agenda and project management application, and options
38 appagen = ["emacsclient", " --eval '(org-agenda-list)'"]
40 # Buttons and tooltips
41 apptips = {
42 1 : ["Agenda", "Open org-mode agenda in Emacs"],
43 2 : ["Close", "Close the calendar"],
44 3 : ["Praznici za", "Holidays in"]
47 # Local non-working holidays
48 nonworking = {
49 1 : [["Nova Godina", 1],
50 ["Sveta tri kralja", 6]],
51 2 : [],
52 3 : [],
53 4 : [["Veliki petak", 2],
54 ["Uskrs", 4],
55 ["Uskrsni ponedjeljak", 5]],
56 5 : [["Praznik rada", 1]],
57 6 : [["Tijelovo", 3],
58 ["Dan antifašističke borbe", 22],
59 ["Dan državnosti", 25]],
60 7 : [],
61 8 : [["Dan domovinske zahvalnosti", 5],
62 ["Dan domovinske zahvalnosti", 6],
63 ["Velika Gospa", 15]],
64 9 : [],
65 10 : [["Dan neovisnosti", 8]],
66 11 : [["Svi sveti", 1]],
67 12 : [["Božić", 25],
68 ["Sveti Stjepan", 26]]
72 class PyLendar:
73 DEF_POS_X, DEF_POS_Y, DEF_PAD = appprop[2], appprop[3], appprop[4]
75 def calendar_select_icon(self):
76 icopath = '/'.join(appicon)
77 xdgdata = getenv("XDG_DATA_DIRS").split(":")
78 xdgdata.append(getenv("XDG_DATA_HOME"))
79 xdgdata.append(getenv("HOME") + "/")
81 for i in xdgdata:
82 icopref = i.endswith("/") and ".icons/" or "/icons/"
83 if path.isfile(i + icopref + icopath):
84 pylendar_icon = gtk.gdk.pixbuf_new_from_file(i + icopref + icopath)
85 break
86 else: # Default to stock
87 pylendar_icon = self.window.render_icon(gtk.STOCK_EDIT, gtk.ICON_SIZE_DIALOG)
88 return pylendar_icon
90 def calendar_show_agenda(self):
91 call(appagen[0] + appagen[1], shell=True)
93 def calendar_month_changed(self, widget):
94 year, month, day = self.window.get_date()
96 self.window.clear_marks()
98 tooltip = "%s %s:" % (apptips[3][0], month_name[month+1])
99 for key, holiday in list(nonworking.items()):
100 if key == month+1 and holiday:
101 for i in holiday:
102 self.window.mark_day(i[1])
103 # Even out all dates for aligned table-like display
104 if len(str(i[1])) < 2:
105 tableday = "0%.0f" % i[1]
106 else:
107 tableday = i[1]
108 tooltip = "%s\n | %s.%s | %s" % (tooltip, str(tableday), str(key), i[0])
109 self.window.set_tooltip_text(tooltip)
112 def __init__(self, monthspec=None):
113 self.window = None
114 # Create a new window
115 window = gtk.Window(appprop[1])
116 # - floating when TOPLEVEL
117 window.set_resizable(False)
118 # - window properties
119 window.set_title(appprop[0])
120 window.set_border_width(appprop[5])
122 # Connect the destroy event to a handler
123 window.connect("destroy", lambda x: gtk.main_quit())
124 # Auto exit after timeout
125 timer = gobject.timeout_add(appprop[6], lambda: gtk.main_quit())
127 # The top part of the window: calendar box
128 vbox = gtk.VBox(False, self.DEF_PAD)
129 hbox = gtk.HBox(False, self.DEF_PAD)
130 hbbox = gtk.HButtonBox()
131 window.add(vbox)
132 vbox.pack_start(hbox, True, True, self.DEF_PAD)
133 hbox.pack_start(hbbox, False, False, self.DEF_PAD)
134 hbbox.set_layout(gtk.BUTTONBOX_SPREAD)
135 hbbox.set_spacing(0)
137 # Calendar widget
138 frame = gtk.Frame()
139 hbbox.pack_start(frame, False, True, self.DEF_PAD)
140 calendar = gtk.Calendar()
141 self.window = calendar
143 # Calendar options
144 # GTK_CALENDAR_SHOW_HEADING = 1 << 0,
145 # GTK_CALENDAR_SHOW_DAY_NAMES = 1 << 1,
146 # GTK_CALENDAR_NO_MONTH_CHANGE = 1 << 2,
147 # GTK_CALENDAR_SHOW_WEEK_NUMBERS = 1 << 3,
148 # GTK_CALENDAR_WEEK_START_MONDAY = 1 << 4,
149 # GTK_CALENDAR_SHOW_DETAILS = 1 << 5
150 # As default, show heading, show days and allow date changes
151 #self.window.set_display_options(3 + (1<<5))
153 # Show a specific month if requested on startup
154 if monthspec in range(1, 13):
155 # Clear day selection if not viewing current month
156 if monthspec != self.window.get_date()[1]+1:
157 self.window.select_day(0)
158 self.window.select_month(monthspec-1, self.window.get_date()[0])
160 # Fake a month change on startup, to get marks right away
161 self.calendar_month_changed(calendar)
163 # Put the finished widget in the frame
164 frame.add(calendar)
166 # Signals Handlers
167 calendar.connect("month_changed", self.calendar_month_changed)
169 # Setup buttons
170 if appprop[7]:
171 # The bottom part of the window: button box
172 bbox = gtk.HButtonBox ()
173 vbox.pack_start(bbox, False, False, 0)
174 bbox.set_layout(gtk.BUTTONBOX_SPREAD)
176 # Button widget: Agenda
177 # - modify default label for STOCK_EDIT
178 gtk.stock_add([(gtk.STOCK_EDIT, apptips[1][0], 0, 0, "")])
179 button = gtk.Button(stock=gtk.STOCK_EDIT)
180 button.connect("clicked", lambda w: self.calendar_show_agenda())
181 bbox.add(button)
182 button.set_tooltip_text(apptips[1][1])
184 # Button widget: Close
185 # - modify default label for STOCK_CANCEL
186 gtk.stock_add([(gtk.STOCK_CANCEL, apptips[2][0], 0, 0, "")])
187 button = gtk.Button(stock=gtk.STOCK_CANCEL)
188 button.connect("clicked", lambda w: gtk.main_quit())
189 bbox.add(button)
190 # - this is the default button
191 button.set_flags(gtk.CAN_DEFAULT)
192 button.grab_default()
193 button.set_tooltip_text(apptips[2][1])
195 # Set application icon
196 gtk.window_set_default_icon(self.calendar_select_icon())
198 # Position the window
199 window.move(self.DEF_POS_X, self.DEF_POS_Y)
201 # Draw the calendar
202 window.show_all()
205 def main():
206 gtk.main()
207 return 0
210 if __name__ == "__main__":
211 if len(argv) < 2:
212 PyLendar()
213 else:
214 try:
215 PyLendar(int(argv[1]))
216 except ValueError:
217 raise SystemExit("Usage: %s [month (1-12)]" % path.split(argv[0])[1])
218 main()