1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151
|
# -*- coding: utf-8 -*-
#
# gtklick
#
# Copyright (C) 2008-2010 Dominic Sacré <dominic.sacre@gmx.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
import gtk
import gtk.keysyms
import gobject
import inspect
import weakref, new
block = False
# decorator: don't call function while gtk signals are blocked
def gui_callback(f):
def g(self, *args):
global block
# FIXME: it may be a bad idea to discard arbitrary signals
if not block:
return f(self, *args)
return g
# decorator: enclose the function in threads_enter() / threads_leave() to safely call
# gtk functions, and block gtk signals while the function is running
def osc_callback(f):
def g(self, *args):
global block
try:
gtk.gdk.threads_enter()
block = True
#print args[0], args[1]
# call function with the correct number of arguments, to allow osc callbacks to omit
# some of pyliblo's callback arguments
if inspect.getargspec(f)[1] == None:
n = len(inspect.getargspec(f)[0]) - 1
r = f(self, *args[0:n])
else:
r = f(self, *args)
return r
finally:
block = False
gtk.gdk.threads_leave()
return g
# block gtk signals while calling function f
def do_quietly(f):
global block
try:
block = True
return f()
finally:
block = False
class weakref_method:
def __init__(self, f):
self.inst = weakref.ref(f.im_self)
self.func = f.im_func
def __call__(self, *args, **kwargs):
f = new.instancemethod(self.func, self.inst(), self.inst().__class__)
return f(*args, **kwargs)
# calls function once when going idle, blocking redundant calls
class run_idle_once:
def __init__(self, call):
self.call = call
self.pending = False
def queue(self):
if not self.pending:
self.pending = True
gobject.idle_add(self.call_wrapper)
def call_wrapper(self):
self.pending = False
self.call()
return False
class TristateCheckButton(gtk.CheckButton):
def __init__(self, label):
gtk.CheckButton.__init__(self, label)
self.connect('button-release-event', self.on_button_released)
self.connect('key-press-event', self.on_key_pressed)
def get_state(self):
if self.get_inconsistent():
return 1
elif self.get_active():
return 2
else:
return 0
def set_state(self, state):
toggle = self.get_inconsistent() != (state == 1) and self.get_active() == (state != 0)
self.set_inconsistent(state == 1)
self.set_active(state != 0)
if toggle:
# emit "toggled" manually if "active" didn't change, but "inconsistent" did
self.toggled()
def on_button_released(self, b, ev):
s = ev.get_state()
if s & gtk.gdk.CONTROL_MASK:
if s & gtk.gdk.BUTTON1_MASK:
self.set_state(2)
elif s & gtk.gdk.BUTTON2_MASK:
self.set_state(1)
elif s & gtk.gdk.BUTTON3_MASK:
self.set_state(0)
else:
if s & gtk.gdk.BUTTON1_MASK:
self.set_state((self.get_state() - 1) % 3)
elif s & gtk.gdk.BUTTON2_MASK:
self.set_state(1 if self.get_state() == 2 else 2)
elif s & gtk.gdk.BUTTON3_MASK:
self.set_state(1 if self.get_state() == 0 else 0)
self.queue_draw()
return True
def on_key_pressed(self, b, ev):
if ev.keyval == gtk.keysyms.space:
self.set_state((self.get_state() - 1) % 3)
self.queue_draw()
return True
else:
return False
def treeview_remove(model, selection, i):
path = model.get_path(i)
model.remove(i)
# select next item
selection.select_path(path)
if not selection.path_is_selected(path):
row = path[0]-1
if row >= 0:
selection.select_path(row)
|