from __future__ import with_statement
+import os
+import errno
import sys
-import traceback
+import time
+import itertools
import functools
import contextlib
-import warnings
+import logging
import threading
import Queue
import gtk
+_moduleLogger = logging.getLogger("gtk_toolbox")
+
+
+def get_screen_orientation():
+ width, height = gtk.gdk.get_default_root_window().get_size()
+ if width < height:
+ return gtk.ORIENTATION_VERTICAL
+ else:
+ return gtk.ORIENTATION_HORIZONTAL
+
+
+def orientation_change_connect(handler, *args):
+ """
+ @param handler(orientation, *args) -> None(?)
+ """
+ initialScreenOrientation = get_screen_orientation()
+ orientationAndArgs = list(itertools.chain((initialScreenOrientation, ), args))
+
+ def _on_screen_size_changed(screen):
+ newScreenOrientation = get_screen_orientation()
+ if newScreenOrientation != orientationAndArgs[0]:
+ orientationAndArgs[0] = newScreenOrientation
+ handler(*orientationAndArgs)
+
+ rootScreen = gtk.gdk.get_default_root_window()
+ return gtk.connect(rootScreen, "size-changed", _on_screen_size_changed)
+
+
+@contextlib.contextmanager
+def flock(path, timeout=-1):
+ WAIT_FOREVER = -1
+ DELAY = 0.1
+ timeSpent = 0
+
+ acquired = False
+
+ while timeSpent <= timeout or timeout == WAIT_FOREVER:
+ try:
+ fd = os.open(path, os.O_CREAT | os.O_EXCL | os.O_RDWR)
+ acquired = True
+ break
+ except OSError, e:
+ if e.errno != errno.EEXIST:
+ raise
+ time.sleep(DELAY)
+ timeSpent += DELAY
+
+ assert acquired, "Failed to grab file-lock %s within timeout %d" % (path, timeout)
+
+ try:
+ yield fd
+ finally:
+ os.unlink(path)
+
+
@contextlib.contextmanager
def gtk_lock():
gtk.gdk.threads_enter()
@autostart
+def printer_sink(format = "%s"):
+ """
+ >>> pr = printer_sink("%r")
+ >>> pr.send("Hello")
+ 'Hello'
+ >>> pr.send("5")
+ '5'
+ >>> pr.send(5)
+ 5
+ >>> p = printer_sink()
+ >>> p.send("Hello")
+ Hello
+ >>> p.send("World")
+ World
+ >>> # p.throw(RuntimeError, "Goodbye")
+ >>> # p.send("Meh")
+ >>> # p.close()
+ """
+ while True:
+ item = yield
+ print format % (item, )
+
+
+@autostart
def null_sink():
"""
Good for uses like with cochain to pick up any slack
"""
>>> p = printer_sink()
>>> cm = comap(lambda x: x+1, p)
- >>> cm.send(0)
+ >>> cm.send((0, ))
1
- >>> cm.send(1.0)
+ >>> cm.send((1.0, ))
2.0
- >>> cm.send(-2)
+ >>> cm.send((-2, ))
-1
- >>> # cm.throw(RuntimeError, "Goodbye")
- >>> # cm.send(0)
- >>> # cm.send(1.0)
- >>> # cm.close()
"""
while True:
try:
item = yield
mappedItem = function(*item)
target.send(mappedItem)
- except StandardError, e:
- target.throw(e.__class__, e.message)
+ except Exception, e:
+ _moduleLogger.exception("Forwarding exception!")
+ target.throw(e.__class__, str(e))
+
+
+def _flush_queue(queue):
+ while not queue.empty():
+ yield queue.get()
@autostart
try:
item = yield
queue.put((None, item))
- except StandardError, e:
- queue.put((e.__class__, e.message))
+ except Exception, e:
+ queue.put((e.__class__, str(e)))
except GeneratorExit:
queue.put((GeneratorExit, None))
raise
def nonqueue_source(queue, target):
- """
- >>> q = Queue.Queue()
- >>> for i in [
- ... (None, 'Hello'),
- ... (None, 'World'),
- ... (GeneratorExit, None),
- ... ]:
- ... q.put(i)
- >>> qs = queue_source(q, printer_sink())
- Hello
- """
isDone = False
while not isDone:
item = queue.get()
return queue_sink(messages)
+def log_exception(logger):
+
+ def log_exception_decorator(func):
+
+ @functools.wraps(func)
+ def wrapper(*args, **kwds):
+ try:
+ return func(*args, **kwds)
+ except Exception:
+ logger.exception(func.__name__)
+
+ return wrapper
+
+ return log_exception_decorator
+
+
class LoginWindow(object):
def __init__(self, widgetTree):
self._serviceCombo.add_attribute(cell, 'text', 1)
self._serviceCombo.set_active(0)
- callbackMapping = {
- "on_loginbutton_clicked": self._on_loginbutton_clicked,
- "on_loginclose_clicked": self._on_loginclose_clicked,
- }
- widgetTree.signal_autoconnect(callbackMapping)
+ widgetTree.get_widget("loginbutton").connect("clicked", self._on_loginbutton_clicked)
+ widgetTree.get_widget("logins_close_button").connect("clicked", self._on_loginclose_clicked)
- def request_credentials(self, parentWindow = None):
+ def request_credentials(self,
+ parentWindow = None,
+ defaultCredentials = ("", "")
+ ):
"""
@note UI Thread
"""
self._serviceCombo.hide()
self._serviceList.clear()
+ self._usernameEntry.set_text(defaultCredentials[0])
+ self._passwordEntry.set_text(defaultCredentials[1])
+
try:
self._dialog.set_transient_for(parentWindow)
self._dialog.set_default_response(gtk.RESPONSE_OK)
self.push_message(message)
def push_message(self, message):
- if 0 < len(self.__messages):
- self.__messages.append(message)
- else:
+ self.__messages.append(message)
+ if 1 == len(self.__messages):
self.__show_message(message)
- def push_exception_with_lock(self, exception = None):
+ def push_exception_with_lock(self):
with gtk_lock():
- self.push_exception(exception)
+ self.push_exception()
- def push_exception(self, exception = None):
- if exception is None:
- userMessage = str(sys.exc_value)
- warningMessage = str(traceback.format_exc())
- else:
- userMessage = str(exception)
- warningMessage = str(exception)
+ def push_exception(self):
+ userMessage = str(sys.exc_info()[1])
self.push_message(userMessage)
- warnings.warn(warningMessage, stacklevel=2)
+ _moduleLogger.exception(userMessage)
def pop_message(self):
- if 0 < len(self.__messages):
- self.__show_message(self.__messages[0])
- del self.__messages[0]
- else:
+ del self.__messages[0]
+ if 0 == len(self.__messages):
self.__hide_message()
+ else:
+ self.__errorDescription.set_text(self.__messages[0])
def _on_close(self, *args):
self.pop_message()
self.__show_message(message)
def push_exception(self, exception = None):
- if exception is None:
- warningMessage = traceback.format_exc()
- else:
- warningMessage = exception
- warnings.warn(warningMessage, stacklevel=3)
+ userMessage = str(sys.exc_value)
+ _moduleLogger.exception(userMessage)
def pop_message(self):
if 0 < len(self.__messages):
del self.__messages[0]
def __show_message(self, message):
- warnings.warn(message, stacklevel=2)
+ _moduleLogger.debug(message)
class MessageBox(gtk.MessageDialog):
try:
self._calendar.select_month(self._displayDate.month, self._displayDate.year)
self._calendar.select_day(self._displayDate.day)
- except StandardError, e:
- warnings.warn(e.message)
+ except Exception, e:
+ _moduleLogger.exception(e)
class QuickAddView(object):
self._taskNameEntry.set_text("")
self._signalSink.stage.send(("add", name))
- except StandardError, e:
+ except Exception, e:
self._errorDisplay.push_exception()
def _on_add_edit(self, *args):
self._taskNameEntry.set_text("")
self._signalSink.stage.send(("add-edit", name))
- except StandardError, e:
+ except Exception, e:
self._errorDisplay.push_exception()
def _on_add_pressed(self, widget):
try:
self._addToEditTimerId = gobject.timeout_add(1000, self._on_add_edit)
- except StandardError, e:
+ except Exception, e:
self._errorDisplay.push_exception()
def _on_add_released(self, widget):
if self._addToEditTimerId is not None:
gobject.source_remove(self._addToEditTimerId)
self._addToEditTimerId = None
- except StandardError, e:
+ except Exception, e:
self._errorDisplay.push_exception()
def _on_paste(self, *args):
if addedText:
entry += addedText
self._taskNameEntry.set_text(entry)
- except StandardError, e:
+ except Exception, e:
self._errorDisplay.push_exception()
def _on_clear(self, *args):
try:
self._taskNameEntry.set_text("")
- except StandardError, e:
+ except Exception, e:
self._errorDisplay.push_exception()
def _on_button_press(self, *args):
# Hack to handle weird notebook behavior
self._isPointerInside = True
+ self._isTap = True
if self._tapTimeoutId is not None:
gobject.source_remove(self._tapTimeoutId)