~marmuta/onboard/onboard-ignore-bad-translations

« back to all changes in this revision

Viewing changes to Onboard/Keyboard.py

  • Committer: Bazaar Package Importer
  • Author(s): Francesco Fumanti
  • Date: 2010-08-20 17:11:12 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20100820171112-dofabf23w2x6hgsz
Tags: 0.94.0-0ubuntu1
  * Feature freeze exception request to update to new release (LP: #621374)
  * Make onboard follow keyboard layout changes (LP: 526791, LP: 65626)
  * Save onboard geometry on quit instead on configure-events (LP: #596248)
  * Improve handling of missing dependency for the clicks (LP: #524148):
      - Use soname instead of linker for libXi in X11.py
      - Add dependency on libxi6 to break package build if necessary
      - Get current version of soname for libx11 from environment
      - Respect DISPLAY environment variable in KeyboardGTK.py
      - Add debian/README.source with info about libxi6 and libx11
  * Do not crash if icon of IconPalette is missing (LP: #538109)
  * Fix Menu key, Delete key and Insert key
  * Qualify the import of our X11 module
  * Make strings in our X11 module translatable
  * Some cleanup by remove trailing spaces
  * debian/control:
      - Update email address of original maintainer
      - Set minimal required version for python-virtkey to 0.60.0
      - Add libxi6 to Build-Depends
      - Add libxi6 and libx11-6 to Depends
  * debian/copyright:
      - Add hosting site
      - Add section with upstream authors
      - Update license information to GPL 3
  * debian/watch:
      - Add watch file
  * debian/README.source
      - Add README.source file

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
### Logging ###
 
2
import logging
 
3
_logger = logging.getLogger("Keyboard")
 
4
###############
 
5
 
1
6
import gobject
2
7
import gtk
3
8
import string
4
 
import virtkey
5
9
 
6
10
from Onboard.KeyGtk import *
7
11
from Onboard import KeyCommon
20
24
    "Cairo based keyboard widget"
21
25
 
22
26
    # When set to a pane, the pane overlays the basePane.
23
 
    activePane = None 
 
27
    activePane = None
24
28
    active = None #Currently active key
25
29
    scanningActive = None # Key currently being scanned.
26
 
    altLocked = False 
 
30
    altLocked = False
27
31
    scanning_x = None
28
32
    scanning_y = None
29
33
 
30
34
### Properties ###
31
 
    
 
35
 
32
36
    _mods = {1:0,2:0, 4:0,8:0, 16:0,32:0,64:0,128:0}
33
37
    def _get_mod(self, key):
34
38
        return self._mods[key]
40
44
 
41
45
##################
42
46
 
43
 
    def __init__(self):
44
 
        self.vk = virtkey.virtkey()
45
 
 
46
 
 
47
 
        #List of keys which have been latched.  
 
47
    def __init__(self, vk):
 
48
        self.vk = vk
 
49
 
 
50
        #List of keys which have been latched.
48
51
        #ie. pressed until next non sticky button is pressed.
49
 
        self.stuck = [] 
 
52
        self.stuck = []
50
53
        self.tabKeys = []
51
54
        self.panes = [] # All panes except the basePane
52
55
        self.tabKeys.append(BaseTabKey(self, config.SIDEBARWIDTH))
53
56
        self.queue_draw()
54
 
        
55
 
       
 
57
 
56
58
    def set_basePane(self, basePane):
57
59
        self.basePane = basePane #Pane which is always visible
58
60
 
59
61
    def add_pane(self, pane):
60
62
        self.panes.append(pane)
61
63
        self.tabKeys.append(TabKey(self, config.SIDEBARWIDTH, pane))
62
 
 
 
64
 
63
65
    def utf8_to_unicode(self,utf8Char):
64
66
        return ord(utf8Char.decode('utf-8'))
65
 
    
 
67
 
66
68
    def scan_tick(self): #at intervals scans across keys in the row and then down columns.
67
69
        if self.scanningActive:
68
70
            self.scanningActive.beingScanned = False
69
 
        
 
71
 
70
72
        if self.activePane:
71
73
            pane = self.activePane
72
74
        else:
73
75
            pane = self.basePane
74
 
        
 
76
 
75
77
        if not self.scanning_y == None:
76
78
            self.scanning_y = (self.scanning_y + 1) % len(pane.columns[self.scanning_x])
77
79
        else:
78
80
            self.scanning_x = (self.scanning_x + 1) % len(pane.columns)
79
 
        
 
81
 
80
82
        if self.scanning_y == None:
81
83
            y = 0
82
84
        else:
83
85
            y = self.scanning_y
84
 
        
 
86
 
85
87
        self.scanningActive = pane.columns[self.scanning_x][y]
86
 
        
 
88
 
87
89
        self.scanningActive.beingScanned = True
88
90
        self.queue_draw()
89
 
        
 
91
 
90
92
        return True
91
 
        
 
93
 
92
94
    def is_key_pressed(self,key, widget, event):
93
95
        if(key.pointWithinKey(widget, event.x, event.y)):
94
96
            self.press_key(key)
95
 
    
 
97
 
96
98
    def _on_mods_changed(self):
97
99
        raise NotImplementedException()
98
100
 
99
101
    def press_key(self, key):
 
102
        if not self.vk:
 
103
            return
 
104
 
100
105
        if not key.on:
101
106
            if self.mods[8]:
102
107
                self.altLocked = True
103
 
                self.vk.lock_mod(8) 
 
108
                self.vk.lock_mod(8)
104
109
 
105
110
            if key.sticky == True:
106
111
                    self.stuck.append(key)
107
 
                    
 
112
 
108
113
            else:
109
114
                self.active = key #Since only one non-sticky key can be pressed at once.
110
 
            
 
115
 
111
116
            key.on = True
112
 
            
 
117
 
113
118
            self.locked = []
114
119
            if key.action_type == KeyCommon.CHAR_ACTION:
115
120
                self.vk.press_unicode(self.utf8_to_unicode(key.action))
116
 
            
 
121
 
117
122
            elif key.action_type == KeyCommon.KEYSYM_ACTION:
118
123
                self.vk.press_keysym(key.action)
119
124
            elif key.action_type == KeyCommon.KEYPRESS_NAME_ACTION:
120
125
                self.vk.press_keysym(get_keysym_from_name(key.action))
121
126
            elif key.action_type == KeyCommon.MODIFIER_ACTION:
122
127
                mod = key.action
123
 
                
 
128
 
124
129
                if not mod == 8: #Hack since alt puts metacity into move mode and prevents clicks reaching widget.
125
130
                    self.vk.lock_mod(mod)
126
131
                self.mods[mod] += 1
127
132
            elif key.action_type == KeyCommon.MACRO_ACTION:
128
133
                try:
129
134
                    mString = unicode(config.snippets[string.atoi(key.action)])
130
 
# If mstring exists do the below, otherwise the code in finally should always 
 
135
# If mstring exists do the below, otherwise the code in finally should always
131
136
# be done.
132
137
                    if mString:
133
138
                        for c in mString:
134
139
                            self.vk.press_unicode(ord(c))
135
140
                            self.vk.release_unicode(ord(c))
136
141
                        return
137
 
                            
 
142
 
138
143
                except IndexError:
139
144
                    pass
140
 
                
 
145
 
141
146
                if not config.xid_mode:  # block dialog in xembed mode
142
 
                
143
 
                    dialog = gtk.Dialog("No snippet", self.parent, 0, 
144
 
                            ("_Save snippet", gtk.RESPONSE_OK, 
 
147
 
 
148
                    dialog = gtk.Dialog("No snippet", self.parent, 0,
 
149
                            ("_Save snippet", gtk.RESPONSE_OK,
145
150
                             "_Cancel", gtk.RESPONSE_CANCEL))
146
151
                    dialog.vbox.add(gtk.Label(
147
152
                        "No snippet for this button,\nType new snippet"))
148
 
                    
149
 
                    macroEntry = gtk.Entry()                
150
 
                
 
153
 
 
154
                    macroEntry = gtk.Entry()
 
155
 
151
156
                    dialog.connect("response", self.cb_dialog_response,string.atoi(key.action), macroEntry)
152
 
                    
 
157
 
153
158
                    macroEntry.connect("activate", self.cb_macroEntry_activate,string.atoi(key.action), dialog)
154
159
                    dialog.vbox.pack_end(macroEntry)
155
160
 
157
162
 
158
163
            elif key.action_type == KeyCommon.KEYCODE_ACTION:
159
164
                self.vk.press_keycode(key.action);
160
 
                
 
165
 
161
166
            elif key.action_type == KeyCommon.SCRIPT_ACTION:
162
167
                if not config.xid_mode:  # block settings dialog in xembed mode
163
168
                    if key.action:
167
172
                    if k.pane == self.activePane:
168
173
                        k.on = False
169
174
                        k.stuckOn = False
170
 
                
 
175
 
171
176
                self.activePane = key.pane
172
177
        else:
173
178
            if key in self.stuck:
178
183
                self.release_key(key)
179
184
 
180
185
        self.queue_draw()
181
 
            
182
 
        
 
186
 
 
187
 
183
188
    def cb_dialog_response(self, widget, response, macroNo,macroEntry):
184
189
        self.set_new_macro(macroNo, response, macroEntry, widget)
185
190
 
186
191
    def cb_macroEntry_activate(self,widget,macroNo,dialog):
187
192
        self.set_new_macro(macroNo, gtk.RESPONSE_OK, widget, dialog)
188
 
    
 
193
 
189
194
    def set_new_macro(self,macroNo,response,macroEntry,dialog):
190
 
        if response == gtk.RESPONSE_OK: 
 
195
        if response == gtk.RESPONSE_OK:
191
196
            config.set_snippet(macroNo, macroEntry.get_text())
192
197
 
193
198
        dialog.destroy()
194
 
    
 
199
 
195
200
    def release_key(self,key):
 
201
        if not self.vk:
 
202
            return
 
203
 
196
204
        if key.action_type == KeyCommon.CHAR_ACTION:
197
205
            self.vk.release_unicode(self.utf8_to_unicode(key.action))
198
206
        elif key.action_type == KeyCommon.KEYSYM_ACTION:
201
209
            self.vk.release_keysym(get_keysym_from_name(key.action))
202
210
        elif key.action_type == KeyCommon.MODIFIER_ACTION:
203
211
            mod = key.action
204
 
            
205
 
            if not mod == 8:        
 
212
 
 
213
            if not mod == 8:
206
214
                self.vk.unlock_mod(mod)
207
 
            
 
215
 
208
216
            self.mods[mod] -= 1
209
 
            
 
217
 
210
218
        elif key.action_type == KeyCommon.KEYCODE_ACTION:
211
219
            self.vk.release_keycode(key.action);
212
 
            
 
220
 
213
221
        elif key.action_type == KeyCommon.MACRO_ACTION:
214
222
            pass
215
223
        elif key.action_type == KeyCommon.SCRIPT_ACTION:
218
226
            elif key.name == "secondaryClick":
219
227
                self.map_pointer_button(3) # map secondary button to primary
220
228
 
221
 
                
 
229
 
222
230
        else:
223
231
            self.activePane = None
224
 
        
225
 
        
 
232
 
 
233
 
226
234
        if self.altLocked:
227
235
            self.altLocked = False
228
236
            self.vk.unlock_mod(8)
229
 
        
230
 
        gobject.idle_add(self.release_key_idle,key) #Makes sure we draw key pressed before unpressing it. 
 
237
 
 
238
        gobject.idle_add(self.release_key_idle,key) #Makes sure we draw key pressed before unpressing it.
231
239
 
232
240
    def release_key_idle(self,key):
233
241
        key.on = False
239
247
            for group in pane.key_groups.values():
240
248
                for key in group:
241
249
                    if key.on: self.release_key(key)
 
250
 
 
251
        # Somehow keyboard objects don't get released
 
252
        # when switching layouts, there are still
 
253
        # excess references/memory leaks somewhere.
 
254
        # Therefore virtkey references have to be released
 
255
        # explicitely or Xlib runs out of client connections
 
256
        # after a couple dozen layout switches.
 
257
        self.vk = None
 
258