3 from __future__ import with_statement
15 @contextlib.contextmanager
17 gtk.gdk.threads_enter()
21 gtk.gdk.threads_leave()
24 def find_parent_window(widget):
26 parent = widget.get_parent()
27 if isinstance(parent, gtk.Window):
34 Decorator that makes a generator-function into a function that will continue execution on next call
38 @functools.wraps(func)
39 def decorated_func(*args, **kwds):
41 a.append(func(*args, **kwds))
52 def asynchronous_gtk_message(original_func):
54 @note Idea came from http://www.aclevername.com/articles/python-webgui/
58 args, kwargs = allArgs
60 original_func(*args, **kwargs)
63 @functools.wraps(original_func)
64 def delayed_func(*args, **kwargs):
65 gobject.idle_add(execute, (args, kwargs))
70 def synchronous_gtk_message(original_func):
72 @note Idea came from http://www.aclevername.com/articles/python-webgui/
75 @functools.wraps(original_func)
76 def immediate_func(*args, **kwargs):
78 return original_func(*args, **kwargs)
83 class ErrorDisplay(object):
85 def __init__(self, widgetTree):
86 super(ErrorDisplay, self).__init__()
87 self.__errorBox = widgetTree.get_widget("errorEventBox")
88 self.__errorDescription = widgetTree.get_widget("errorDescription")
89 self.__errorClose = widgetTree.get_widget("errorClose")
90 self.__parentBox = self.__errorBox.get_parent()
92 self.__errorBox.connect("button_release_event", self._on_close)
95 self.__parentBox.remove(self.__errorBox)
97 def push_message_with_lock(self, message):
99 self.push_message(message)
101 def push_message(self, message):
102 if 0 < len(self.__messages):
103 self.__messages.append(message)
105 self.__show_message(message)
107 def push_exception_with_lock(self, exception = None):
109 self.push_exception(exception)
111 def push_exception(self, exception = None):
112 if exception is None:
113 userMessage = str(sys.exc_value)
114 warningMessage = str(traceback.format_exc())
116 userMessage = str(exception)
117 warningMessage = str(exception)
118 self.push_message(userMessage)
119 warnings.warn(warningMessage, stacklevel=3)
121 def pop_message(self):
122 if 0 < len(self.__messages):
123 self.__show_message(self.__messages[0])
124 del self.__messages[0]
126 self.__hide_message()
128 def _on_close(self, *args):
131 def __show_message(self, message):
132 self.__errorDescription.set_text(message)
133 self.__parentBox.pack_start(self.__errorBox, False, False)
134 self.__parentBox.reorder_child(self.__errorBox, 1)
136 def __hide_message(self):
137 self.__errorDescription.set_text("")
138 self.__parentBox.remove(self.__errorBox)
141 class DummyErrorDisplay(object):
144 super(DummyErrorDisplay, self).__init__()
148 def push_message_with_lock(self, message):
149 self.push_message(message)
151 def push_message(self, message):
152 if 0 < len(self.__messages):
153 self.__messages.append(message)
155 self.__show_message(message)
157 def push_exception(self, exception = None):
158 if exception is None:
159 warningMessage = traceback.format_exc()
161 warningMessage = exception
162 warnings.warn(warningMessage, stacklevel=3)
164 def pop_message(self):
165 if 0 < len(self.__messages):
166 self.__show_message(self.__messages[0])
167 del self.__messages[0]
169 def __show_message(self, message):
170 warnings.warn(message, stacklevel=2)
173 class MessageBox(gtk.MessageDialog):
175 def __init__(self, message):
177 gtk.MessageDialog.__init__(
180 gtk.DIALOG_MODAL|gtk.DIALOG_DESTROY_WITH_PARENT,
185 self.set_default_response(gtk.RESPONSE_OK)
186 self.connect('response', self._handle_clicked)
188 def _handle_clicked(self, *args):
192 class MessageBox2(gtk.MessageDialog):
194 def __init__(self, message):
196 gtk.MessageDialog.__init__(
199 gtk.DIALOG_DESTROY_WITH_PARENT,
204 self.set_default_response(gtk.RESPONSE_OK)
205 self.connect('response', self._handle_clicked)
207 def _handle_clicked(self, *args):
211 class PopupCalendar(object):
213 def __init__(self, parent, displayDate, title = ""):
214 self._displayDate = displayDate
216 self._calendar = gtk.Calendar()
217 self._calendar.select_month(self._displayDate.month, self._displayDate.year)
218 self._calendar.select_day(self._displayDate.day)
219 self._calendar.set_display_options(
220 gtk.CALENDAR_SHOW_HEADING |
221 gtk.CALENDAR_SHOW_DAY_NAMES |
222 gtk.CALENDAR_NO_MONTH_CHANGE |
225 self._calendar.connect("day-selected", self._on_day_selected)
227 self._popupWindow = gtk.Window()
228 self._popupWindow.set_title(title)
229 self._popupWindow.add(self._calendar)
230 self._popupWindow.set_transient_for(parent)
231 self._popupWindow.set_modal(True)
232 self._popupWindow.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DIALOG)
233 self._popupWindow.set_skip_pager_hint(True)
234 self._popupWindow.set_skip_taskbar_hint(True)
237 self._popupWindow.show_all()
239 def _on_day_selected(self, *args):
241 self._calendar.select_month(self._displayDate.month, self._displayDate.year)
242 self._calendar.select_day(self._displayDate.day)
243 except StandardError, e:
244 warnings.warn(e.message)
247 if __name__ == "__main__":
250 cal = PopupCalendar(None, datetime.datetime.now())
251 cal._popupWindow.connect("destroy", lambda w: gtk.main_quit())