| 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | # vim: ts=4:sw=4 |
|---|
| 3 | # This file is part of LOME. |
|---|
| 4 | # |
|---|
| 5 | # LOME is free software: you can redistribute it and/or modify |
|---|
| 6 | # it under the terms of the GNU General Public License as published by |
|---|
| 7 | # the Free Software Foundation, either version 3 of the License, or |
|---|
| 8 | # (at your option) any later version. |
|---|
| 9 | # |
|---|
| 10 | # LOME is distributed in the hope that it will be useful, |
|---|
| 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 13 | # GNU General Public License for more details. |
|---|
| 14 | # |
|---|
| 15 | # You should have received a copy of the GNU General Public License |
|---|
| 16 | # along with LOME. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 17 | # |
|---|
| 18 | |
|---|
| 19 | import pythoncom |
|---|
| 20 | import sys |
|---|
| 21 | __pyhook_loaded = False |
|---|
| 22 | __pyhook_msg = [] |
|---|
| 23 | try: |
|---|
| 24 | import pyHook |
|---|
| 25 | __pyhook_loaded = True |
|---|
| 26 | except: |
|---|
| 27 | import traceback |
|---|
| 28 | exceptionType, exceptionValue, exceptionTraceback = sys.exc_info() |
|---|
| 29 | msg_a = traceback.format_exception(exceptionType, exceptionValue, exceptionTraceback) |
|---|
| 30 | msg = "" |
|---|
| 31 | for m in msg_a: |
|---|
| 32 | msg += m |
|---|
| 33 | __pyhook_msg.append( msg ) |
|---|
| 34 | try: |
|---|
| 35 | import PyHook as pyHook |
|---|
| 36 | __pyhook_loaded = True |
|---|
| 37 | except: |
|---|
| 38 | import traceback |
|---|
| 39 | exceptionType, exceptionValue, exceptionTraceback = sys.exc_info() |
|---|
| 40 | msg_a = traceback.format_exception(exceptionType, exceptionValue, exceptionTraceback) |
|---|
| 41 | msg = "" |
|---|
| 42 | for m in msg_a: |
|---|
| 43 | msg += m |
|---|
| 44 | __pyhook_msg.append( msg ) |
|---|
| 45 | |
|---|
| 46 | if not __pyhook_loaded: |
|---|
| 47 | print "CANNOT LOAD PYHOOK" |
|---|
| 48 | for m in __pyhook_msg: |
|---|
| 49 | print m |
|---|
| 50 | import ctypes |
|---|
| 51 | import win32com.client |
|---|
| 52 | |
|---|
| 53 | from pgpluginclient import * |
|---|
| 54 | from szobjects import * |
|---|
| 55 | |
|---|
| 56 | #---------------------------------------------------------------- |
|---|
| 57 | # Declaration of common variables to PGInput and static def |
|---|
| 58 | pgInputInstance = None #- Instance of the plugin |
|---|
| 59 | mouseEventClientCallback = None #- Client call back used by pyHook for mouse events |
|---|
| 60 | keyPressed = [] #- Table which carries the keys pressed |
|---|
| 61 | |
|---|
| 62 | #---------------------------------------------------------------- |
|---|
| 63 | ## Call back invoked on keyboard event |
|---|
| 64 | # @param event event object |
|---|
| 65 | def onKeyBoardEvent( event): |
|---|
| 66 | # Process this event |
|---|
| 67 | key = event.ScanCode |
|---|
| 68 | if event.IsTransition(): |
|---|
| 69 | if key in keyPressed: |
|---|
| 70 | keyPressed.remove( key) |
|---|
| 71 | pgInputInstance.emit( SIGNAL("keyReleased"), keyPressed) |
|---|
| 72 | else: |
|---|
| 73 | # print '----------------------------------' |
|---|
| 74 | # print 'Ascii :', event.Ascii, chr(event.Ascii) |
|---|
| 75 | # print 'Key :', event.Key |
|---|
| 76 | # print 'KeyID :', event.KeyID |
|---|
| 77 | # print 'ScanCode :', event.ScanCode |
|---|
| 78 | # print 'Extended :', event.Extended |
|---|
| 79 | # print 'Injected :', event.Injected |
|---|
| 80 | # print 'Alt :', event.Alt |
|---|
| 81 | if not ( key in keyPressed): |
|---|
| 82 | keyPressed.append( key) |
|---|
| 83 | pgInputInstance.addKeyAssociation( key, event.Key) |
|---|
| 84 | pgInputInstance.emit( SIGNAL("keyPressed"), keyPressed) |
|---|
| 85 | |
|---|
| 86 | return True |
|---|
| 87 | #---------------------------------------------------------------- |
|---|
| 88 | ## Call back invoked on mouse event |
|---|
| 89 | # @param event event object |
|---|
| 90 | # event.MessageName -> "mouse move" --> associated with event.Position |
|---|
| 91 | # "mouse left up" / "mouse left down" |
|---|
| 92 | # "mouse middle up" / "mouse middle down" |
|---|
| 93 | # "mouse rigth up" / "mouse rigth down" |
|---|
| 94 | # "mouse wheel" |
|---|
| 95 | # "wheel" --> associated with event.Wheel |
|---|
| 96 | # event.Position -> (x,y) |
|---|
| 97 | # event.Wheel -> +1 / -1 |
|---|
| 98 | def onMouseEvent( event): |
|---|
| 99 | # Get instance of PGInput |
|---|
| 100 | self = pgInputInstance |
|---|
| 101 | |
|---|
| 102 | # We do not intercept mouseMove events |
|---|
| 103 | if ( event.MessageName == "mouse move") or ( not self): |
|---|
| 104 | return True |
|---|
| 105 | |
|---|
| 106 | # Get mouse position |
|---|
| 107 | xMouse = event.Position[0] |
|---|
| 108 | yMouse = event.Position[1] |
|---|
| 109 | |
|---|
| 110 | # Check if there are some client to notify |
|---|
| 111 | returnedValue = True |
|---|
| 112 | plugId = [] |
|---|
| 113 | for srcPludId, datas in self.requests[PGInput.MOUSE_EVENT_ID].iteritems(): |
|---|
| 114 | if ( xMouse >= datas[PGInput.X_INDEX] ) and\ |
|---|
| 115 | ( xMouse <= datas[PGInput.X_INDEX] + datas[PGInput.WIDTH_INDEX] ) and\ |
|---|
| 116 | ( yMouse >= datas[PGInput.Y_INDEX] ) and\ |
|---|
| 117 | ( yMouse <= datas[PGInput.Y_INDEX] + datas[PGInput.HEIGHT_INDEX]) : |
|---|
| 118 | plugId.append( srcPludId) |
|---|
| 119 | |
|---|
| 120 | # Do not forward the event |
|---|
| 121 | returnedValue = False |
|---|
| 122 | |
|---|
| 123 | # Send data |
|---|
| 124 | if not returnedValue: |
|---|
| 125 | # Build object and send it |
|---|
| 126 | szObject = SzMouseEvent( from_id = self.get_name() |
|---|
| 127 | , data_id = self.build_full_itemId( PGInput.MOUSE_EVENT_ID) |
|---|
| 128 | , event = event.MessageName |
|---|
| 129 | , position = event.Position |
|---|
| 130 | , wheel = event.Wheel |
|---|
| 131 | ) |
|---|
| 132 | self.send_object( plugId, PGPluginClient.OPCODE_DATA_VALUE, szObject) |
|---|
| 133 | |
|---|
| 134 | return returnedValue |
|---|
| 135 | |
|---|
| 136 | |
|---|
| 137 | |
|---|
| 138 | #================================================================ |
|---|
| 139 | ## This class subclasses the QStandardItem to provide item for tableView |
|---|
| 140 | class CmdxxxItem( QStandardItem): |
|---|
| 141 | def __init__( self, name): |
|---|
| 142 | QStandardItem.__init__( self, name) |
|---|
| 143 | |
|---|
| 144 | #================================================================ |
|---|
| 145 | ## This class is used to gather data associated to a command |
|---|
| 146 | class CmdItem(): |
|---|
| 147 | def __init__( self, cmdId): |
|---|
| 148 | self.__cmdId__ = cmdId |
|---|
| 149 | self.__name__ = cst_get_last_part_of_address( cmdId) |
|---|
| 150 | self.clearCombo() |
|---|
| 151 | |
|---|
| 152 | def getId( self): |
|---|
| 153 | return self.__cmdId__ |
|---|
| 154 | |
|---|
| 155 | def getNameItem( self): |
|---|
| 156 | name = CmdxxxItem( self.__name__) |
|---|
| 157 | name.setEditable( False) |
|---|
| 158 | return name |
|---|
| 159 | def getComboItem( self): |
|---|
| 160 | keys = CmdxxxItem( self.__comboText__) |
|---|
| 161 | keys.setEditable( False) |
|---|
| 162 | return keys |
|---|
| 163 | |
|---|
| 164 | def clearCombo( self): |
|---|
| 165 | self.__combo__ = [] |
|---|
| 166 | self.__comboLength__ = 0 |
|---|
| 167 | self.__comboText__ = "" |
|---|
| 168 | def setCombo( self, combo): |
|---|
| 169 | self.__combo__ = combo |
|---|
| 170 | self.__comboLength__ = len( combo) |
|---|
| 171 | self.__comboText__ = "" |
|---|
| 172 | for key in combo: |
|---|
| 173 | if pgInputInstance.keyAssociation.has_key( key): |
|---|
| 174 | self.__comboText__ += pgInputInstance.keyAssociation[key] + " " |
|---|
| 175 | else: |
|---|
| 176 | self.clearCombo() |
|---|
| 177 | return |
|---|
| 178 | def addKeyToCombo( self, key): |
|---|
| 179 | if pgInputInstance.keyAssociation.has_key( key) and not ( key in self.__combo__): |
|---|
| 180 | self.__combo__.append( key) |
|---|
| 181 | self.__comboLength__ += 1 |
|---|
| 182 | self.__comboText__ += pgInputInstance.keyAssociation[key] + " " |
|---|
| 183 | return True |
|---|
| 184 | return False |
|---|
| 185 | def getCombo( self): |
|---|
| 186 | return self.__combo__ |
|---|
| 187 | def hasCombo( self, combo): |
|---|
| 188 | if len(combo) == self.__comboLength__: |
|---|
| 189 | for key in combo: |
|---|
| 190 | if not ( key in self.__combo__): |
|---|
| 191 | return False |
|---|
| 192 | return True |
|---|
| 193 | return False |
|---|
| 194 | |
|---|
| 195 | |
|---|
| 196 | #================================================================ |
|---|
| 197 | ## Main class in python to manage connection with server |
|---|
| 198 | class PGInput(PGPluginClient): |
|---|
| 199 | |
|---|
| 200 | MOUSE_EVENT_ID = CST_LOPLUG_REQUEST + "MouseEventId" |
|---|
| 201 | X_INDEX = 0 |
|---|
| 202 | Y_INDEX = 1 |
|---|
| 203 | WIDTH_INDEX = 2 |
|---|
| 204 | HEIGHT_INDEX = 3 |
|---|
| 205 | |
|---|
| 206 | # Index used in TableView |
|---|
| 207 | CMD_NAME_INDEX = 0 |
|---|
| 208 | COMBO_INDEX = 1 |
|---|
| 209 | |
|---|
| 210 | # Working mode of the module |
|---|
| 211 | WORKING_MODE_NOMINAL = 0 |
|---|
| 212 | WORKING_MODE_EDITION = 1 |
|---|
| 213 | |
|---|
| 214 | infos = { "description": "Input plugin" |
|---|
| 215 | , "version" : 0.1 |
|---|
| 216 | , "icon" : "input.jpg" |
|---|
| 217 | } |
|---|
| 218 | #---------------------------------------------------------------- |
|---|
| 219 | ## Constructor |
|---|
| 220 | # @param self instance class |
|---|
| 221 | # @param config config |
|---|
| 222 | def __init__( self, config, pathname): |
|---|
| 223 | PGPluginClient.__init__( self, config, pathname) |
|---|
| 224 | |
|---|
| 225 | # Here config has been read, and config variables are set |
|---|
| 226 | |
|---|
| 227 | #================================================================ |
|---|
| 228 | # OVERRIDDEN METHODS |
|---|
| 229 | #================================================================ |
|---|
| 230 | |
|---|
| 231 | #---------------------------------------------------------------- |
|---|
| 232 | # Create all plug variables. |
|---|
| 233 | # Method invoked from __init__() method of the base class |
|---|
| 234 | # @param self instance class |
|---|
| 235 | def _create_plug_context( self): |
|---|
| 236 | self.capabilities = { "provider":[ |
|---|
| 237 | ], #- List of datas that the plugin can provide [name, id, description, type, default format] |
|---|
| 238 | "renderer":[ CST_LOPLUG_CAPA_CMD |
|---|
| 239 | ] #- List of capabilities for plugins (see constants.py for a list) |
|---|
| 240 | } |
|---|
| 241 | |
|---|
| 242 | # Init variable which are part or issued of the config. |
|---|
| 243 | global pgInputInstance |
|---|
| 244 | pgInputInstance = self #- Instance of PGInput, used by pyHook callback methodes |
|---|
| 245 | self.clientId = None #- ClientId for mouseEvent notification |
|---|
| 246 | self.requests = {} #- Discard all the requests from every plug |
|---|
| 247 | self.keyAssociation = {} #- Association KeyValue/KeyName for the used key |
|---|
| 248 | self.row = 0 #- Identify the current selected row |
|---|
| 249 | self.cmdList = [] #- list of command items |
|---|
| 250 | self.workingMode = PGInput.WORKING_MODE_NOMINAL |
|---|
| 251 | |
|---|
| 252 | # Do Hook stuff |
|---|
| 253 | self.hookManager = pyHook.HookManager() |
|---|
| 254 | self.connect( self, SIGNAL("keyPressed"), self.__onKeyPressed__ ) |
|---|
| 255 | |
|---|
| 256 | # Subscribed to keyboard events |
|---|
| 257 | self.hookManager.SubscribeKeyAll( onKeyBoardEvent) |
|---|
| 258 | self.hookManager.HookKeyboard() |
|---|
| 259 | |
|---|
| 260 | # Set mouseEvent call back. Service activation is done by the client |
|---|
| 261 | self.mouseSubscribed = False |
|---|
| 262 | self.connect( self, SIGNAL("EnableMouseHook") , self.__enableMouseHook__) |
|---|
| 263 | self.connect( self, SIGNAL("DisableMouseHook"), self.__disableMouseHook__) |
|---|
| 264 | #---------------------------------------------------------------- |
|---|
| 265 | # To load the settings |
|---|
| 266 | # Method invoked from __init__() method of the base class |
|---|
| 267 | # @param self instance class |
|---|
| 268 | def _load_config( self ): |
|---|
| 269 | # Read key association |
|---|
| 270 | self.keyAssociation = {} |
|---|
| 271 | value = self.get_config_value( "keyAssociation") |
|---|
| 272 | if value: |
|---|
| 273 | pairs = value.split("|") |
|---|
| 274 | for pair in pairs: |
|---|
| 275 | keyValue, keyName = pair.split(":") |
|---|
| 276 | self.keyAssociation[int( keyValue)] = keyName |
|---|
| 277 | |
|---|
| 278 | # Read CmdConfig |
|---|
| 279 | self.cmdList = [] |
|---|
| 280 | value = self.get_config_value( "CmdConfig") |
|---|
| 281 | if value: |
|---|
| 282 | cmdConfigs = value.split("##") |
|---|
| 283 | for cmdConfig in cmdConfigs: |
|---|
| 284 | keyId, keyCombo = cmdConfig.split(":") |
|---|
| 285 | # Create cmdItem |
|---|
| 286 | cmdItem = CmdItem( keyId) |
|---|
| 287 | # Process combo for this cmdItem |
|---|
| 288 | keyComboStr = keyCombo.split("|") |
|---|
| 289 | keyCombo = [] |
|---|
| 290 | for key in keyComboStr: |
|---|
| 291 | if key != "": |
|---|
| 292 | keyCombo.append( int( key)) |
|---|
| 293 | cmdItem.setCombo( keyCombo) |
|---|
| 294 | self.cmdList.append( cmdItem) |
|---|
| 295 | |
|---|
| 296 | #---------------------------------------------------------------- |
|---|
| 297 | # To save the settings |
|---|
| 298 | # @param self instance class |
|---|
| 299 | def _save_config( self ): |
|---|
| 300 | # Save key association |
|---|
| 301 | keyAssociation = "" |
|---|
| 302 | for keyValue, keyName in self.keyAssociation.iteritems(): |
|---|
| 303 | keyAssociation += "%s:%s|" % ( keyValue, keyName) |
|---|
| 304 | keyAssociation = keyAssociation[:-1] |
|---|
| 305 | self.set_config_value( "keyAssociation", keyAssociation) |
|---|
| 306 | |
|---|
| 307 | # Save Combo |
|---|
| 308 | keyCombo = "" |
|---|
| 309 | for cmdItem in self.cmdList: |
|---|
| 310 | cmdId = cmdItem.getId() |
|---|
| 311 | cmdKeys = cmdItem.getCombo() |
|---|
| 312 | keyCombo += "%s:" % cmdId |
|---|
| 313 | if len( cmdKeys): |
|---|
| 314 | for cmdKey in cmdKeys: |
|---|
| 315 | keyCombo += "%s|" % cmdKey |
|---|
| 316 | keyCombo = keyCombo[:-1] |
|---|
| 317 | else: |
|---|
| 318 | keyCombo += "|" |
|---|
| 319 | keyCombo += "##" |
|---|
| 320 | keyCombo = keyCombo[:-2] |
|---|
| 321 | self.set_config_value( "CmdConfig", keyCombo) |
|---|
| 322 | |
|---|
| 323 | self.workingMode = PGInput.WORKING_MODE_NOMINAL |
|---|
| 324 | #---------------------------------------------------------------- |
|---|
| 325 | # To get configuration widget. |
|---|
| 326 | # It is used to get the teamspeak executable and DLL path |
|---|
| 327 | # @param self instance class |
|---|
| 328 | # @return widget |
|---|
| 329 | def _get_config_widget( self, data): |
|---|
| 330 | self.selectedIndex = None |
|---|
| 331 | self.workingMode = PGInput.WORKING_MODE_NOMINAL |
|---|
| 332 | |
|---|
| 333 | #- List of all commands managed by the module |
|---|
| 334 | self._updateCmdList__( data) |
|---|
| 335 | |
|---|
| 336 | # Build |
|---|
| 337 | self.main = QWidget() |
|---|
| 338 | hBox = QHBoxLayout() |
|---|
| 339 | self.main.setLayout( hBox) |
|---|
| 340 | |
|---|
| 341 | self.cmdView = QTableView( self.main) |
|---|
| 342 | self.cmdView.horizontalHeader().setStretchLastSection( True) |
|---|
| 343 | self.cmdView.horizontalHeader().setResizeMode( PGInput.COMBO_INDEX, QHeaderView.Stretch) |
|---|
| 344 | self.cmdModel = QStandardItemModel( 0, 2, self.main) |
|---|
| 345 | self.cmdView.setModel( self.cmdModel) |
|---|
| 346 | |
|---|
| 347 | hBox.addWidget( self.cmdView) |
|---|
| 348 | |
|---|
| 349 | vBox = QVBoxLayout() |
|---|
| 350 | lblExplain = QLabel( self.tr( |
|---|
| 351 | """Way of working: |
|---|
| 352 | 1) Enter 'EDIT' mode |
|---|
| 353 | 2) Select the combo to change" |
|---|
| 354 | 3) Change the combo, enter key by key |
|---|
| 355 | 4) Repeat operations 2) and 3) |
|---|
| 356 | 5) Exit 'EDIT' mode |
|---|
| 357 | |
|---|
| 358 | COMBO: |
|---|
| 359 | All the keys pressed at the same time |
|---|
| 360 | This is why you can not have the same key two times |
|---|
| 361 | """) ) |
|---|
| 362 | lblExplain.setWordWrap( True ) |
|---|
| 363 | vBox.addWidget( lblExplain) |
|---|
| 364 | vBox.addStretch(0) |
|---|
| 365 | self.btnEditMode = QPushButton() |
|---|
| 366 | vBox.addWidget( self.btnEditMode) |
|---|
| 367 | vBox.addStretch(0) |
|---|
| 368 | |
|---|
| 369 | hBox.addLayout( vBox) |
|---|
| 370 | |
|---|
| 371 | self.connect( self.cmdView , SIGNAL( "clicked(const QModelIndex&)"), self.__onCmdItemSelected__ ) |
|---|
| 372 | self.connect( self.btnEditMode, SIGNAL( "clicked(bool)" ), self.__onChangeEditMode__ ) |
|---|
| 373 | |
|---|
| 374 | self.__updateUi__() |
|---|
| 375 | |
|---|
| 376 | |
|---|
| 377 | return self.main |
|---|
| 378 | #---------------------------------------------------------------- |
|---|
| 379 | # Transfert data from 'model' to 'UI' |
|---|
| 380 | # @param self instance class |
|---|
| 381 | def _init_ui( self, options=None ): |
|---|
| 382 | pass |
|---|
| 383 | |
|---|
| 384 | #---------------------------------------------------------------- |
|---|
| 385 | # Transfert data from 'UI' to 'model' |
|---|
| 386 | # @param self instance class |
|---|
| 387 | def _deinit_ui( self ): |
|---|
| 388 | pass |
|---|
| 389 | |
|---|
| 390 | #---------------------------------------------------------------- |
|---|
| 391 | # Method invoked by the PGPluginClient parent on start() |
|---|
| 392 | # When this method is invoke the config has been loaded |
|---|
| 393 | # So, here execute start specific part. |
|---|
| 394 | # @param self instance class |
|---|
| 395 | def _start( self ): # Get instance of hook manager |
|---|
| 396 | pass |
|---|
| 397 | #---------------------------------------------------------------- |
|---|
| 398 | # Method invoked by the PGPluginClient parent on restart() |
|---|
| 399 | # When this method is invoke the config has been loaded |
|---|
| 400 | # So, here execute restart specific part. |
|---|
| 401 | # @param self instance class |
|---|
| 402 | def _config_has_changed( self ): |
|---|
| 403 | pass |
|---|
| 404 | #---------------------------------------------------------------- |
|---|
| 405 | # Provider datas has been updated -> Change the UI |
|---|
| 406 | # @param self instance class |
|---|
| 407 | def _update_provider_data( self, data ): |
|---|
| 408 | self._updateCmdList__( data) |
|---|
| 409 | self.__updateUi__() |
|---|
| 410 | #---------------------------------------------------------------- |
|---|
| 411 | # A client request data |
|---|
| 412 | # So, here execute restart specific part. |
|---|
| 413 | # @param self instance class |
|---|
| 414 | # @param szDataRequest Data for this request |
|---|
| 415 | def _data_requested( self, szDataRequest): |
|---|
| 416 | # Create entry for this data if not yet done |
|---|
| 417 | dataId = szDataRequest.data_id |
|---|
| 418 | if not self.requests.has_key( dataId): |
|---|
| 419 | self.requests[dataId] = {} |
|---|
| 420 | |
|---|
| 421 | if dataId == PGInput.MOUSE_EVENT_ID: |
|---|
| 422 | # Enable hook mouse process |
|---|
| 423 | self.debug( "Enable mouse hook -----------------------------------------------------------" ) |
|---|
| 424 | self.emit( SIGNAL("EnableMouseHook")) |
|---|
| 425 | |
|---|
| 426 | srcPlugId = szDataRequest.from_id |
|---|
| 427 | if not ( srcPlugId in self.requests[dataId].keys()): |
|---|
| 428 | self.requests[dataId][srcPlugId] = [] |
|---|
| 429 | |
|---|
| 430 | if dataId == PGInput.MOUSE_EVENT_ID: |
|---|
| 431 | self.requests[dataId][srcPlugId] = [ szDataRequest.x, szDataRequest.y, szDataRequest.width, szDataRequest.height] |
|---|
| 432 | # print "Mouse event request, x[%s], y[%s], w[%s], h[%s]" % (szDataRequest.x, szDataRequest.y, szDataRequest.width, szDataRequest.height) |
|---|
| 433 | |
|---|
| 434 | |
|---|
| 435 | #---------------------------------------------------------------- |
|---|
| 436 | # To receive data discard commands |
|---|
| 437 | # @param self instance class |
|---|
| 438 | # @param srcPlugId Id of the requester plug (renderer) |
|---|
| 439 | # @param datas datas |
|---|
| 440 | def _data_discarded( self, szDataDiscard): |
|---|
| 441 | dataId = szDataDiscard.data_id |
|---|
| 442 | if self.requests.has_key( dataId): |
|---|
| 443 | srcPlugId = szDataDiscard.from_id |
|---|
| 444 | if srcPlugId in self.requests[dataId].keys(): |
|---|
| 445 | del self.requests[dataId][srcPlugId] |
|---|
| 446 | if not self.requests[dataId]: |
|---|
| 447 | del self.requests[dataId] |
|---|
| 448 | if dataId == PGInput.MOUSE_EVENT_ID: |
|---|
| 449 | # Disable hook mouse process |
|---|
| 450 | self.emit( SIGNAL("DisableMouseHook")) |
|---|
| 451 | |
|---|
| 452 | #---------------------------------------------------------------- |
|---|
| 453 | # A selection occurs on the channel list -> switch |
|---|
| 454 | # @param self instance class |
|---|
| 455 | # @param srcPlugId Id of the plug sending the data |
|---|
| 456 | # @param list_id list Id |
|---|
| 457 | # @param datas datas |
|---|
| 458 | def _selection( self, srcPlugId, list_id, datas): |
|---|
| 459 | pass |
|---|
| 460 | #---------------------------------------------------------------- |
|---|
| 461 | # To shutdown the instance |
|---|
| 462 | # To be overwritten by the daughter class if needed |
|---|
| 463 | # @param self instance class |
|---|
| 464 | def _shutDown( self): |
|---|
| 465 | pass |
|---|
| 466 | #---------------------------------------------------------------- |
|---|
| 467 | # Wait for shutdown complete |
|---|
| 468 | # @param self instance class |
|---|
| 469 | def _waitForShutDownComplete(self): |
|---|
| 470 | pass |
|---|
| 471 | |
|---|
| 472 | #================================================================ |
|---|
| 473 | # INTERFACE METHODS |
|---|
| 474 | #================================================================ |
|---|
| 475 | def addKeyAssociation( self, keyId, keyName): |
|---|
| 476 | if not self.keyAssociation.has_key( keyId): |
|---|
| 477 | self.keyAssociation[keyId] = keyName |
|---|
| 478 | |
|---|
| 479 | #================================================================ |
|---|
| 480 | # LOCAL METHODS |
|---|
| 481 | #================================================================ |
|---|
| 482 | #---------------------------------------------------------------- |
|---|
| 483 | # Invoked on receiving signal "EnableMouseHook" |
|---|
| 484 | # @param self instance class |
|---|
| 485 | def __enableMouseHook__( self): |
|---|
| 486 | # To perform mouse subscription only onece |
|---|
| 487 | if self.mouseSubscribed == False: |
|---|
| 488 | self.mouseSubscribed = True |
|---|
| 489 | self.hookManager.SubscribeMouseAll( onMouseEvent) |
|---|
| 490 | self.hookManager.HookMouse() |
|---|
| 491 | #---------------------------------------------------------------- |
|---|
| 492 | # Invoked on receiving signal "DisableMouseHook" |
|---|
| 493 | # @param self instance class |
|---|
| 494 | def __disableMouseHook__( self): |
|---|
| 495 | self.hookManager.UnhookMouse() |
|---|
| 496 | #---------------------------------------------------------------- |
|---|
| 497 | # Call back method invoked when a key is pressed |
|---|
| 498 | # @param self instance class |
|---|
| 499 | # @param keyTable table of keyCodes for all the key pressed |
|---|
| 500 | def __onKeyPressed__( self, keyTable): |
|---|
| 501 | if self.workingMode == PGInput.WORKING_MODE_EDITION: |
|---|
| 502 | if self.cmdItem: |
|---|
| 503 | for key in keyTable: |
|---|
| 504 | newKey = self.cmdItem.addKeyToCombo( key) |
|---|
| 505 | if newKey: |
|---|
| 506 | self.__updateUi__() |
|---|
| 507 | |
|---|
| 508 | else: |
|---|
| 509 | for cmdItem in self.cmdList: |
|---|
| 510 | if cmdItem.hasCombo( keyTable): |
|---|
| 511 | cmdId = cmdItem.getId() |
|---|
| 512 | opCode = PGPluginClient.OPCODE_DATA_VALUE |
|---|
| 513 | szObj = SzText( from_id = self.get_name() |
|---|
| 514 | , data_id = cmdId |
|---|
| 515 | , text = "" |
|---|
| 516 | ) |
|---|
| 517 | self.send_object([cmdId], opCode, szObj ) |
|---|
| 518 | # We stop at the first item found. |
|---|
| 519 | # But it is possible to continue if we want many commands associated to a unic combo |
|---|
| 520 | break |
|---|
| 521 | |
|---|
| 522 | #---------------------------------------------------------------- |
|---|
| 523 | # This method updates the list of cmdItem containing all the command to be processed |
|---|
| 524 | # @param self instance class |
|---|
| 525 | # @param data data related to all_providers |
|---|
| 526 | def _updateCmdList__( self, data): |
|---|
| 527 | newList = [] |
|---|
| 528 | rendered_datas = self.get_list_data_to_render_for() |
|---|
| 529 | for providerName, providerInfoList in rendered_datas.iteritems(): |
|---|
| 530 | for thisProviderInfo in providerInfoList: |
|---|
| 531 | cmdItem = None |
|---|
| 532 | for providerInfo in data["all_providers_data"]: |
|---|
| 533 | if ( thisProviderInfo.id == providerInfo.id) and providerInfo.visible: |
|---|
| 534 | cmdItem = self.__searchForCmdItem__( thisProviderInfo.id) |
|---|
| 535 | if cmdItem: |
|---|
| 536 | break |
|---|
| 537 | if not cmdItem : |
|---|
| 538 | cmdItem = CmdItem( thisProviderInfo.id) |
|---|
| 539 | |
|---|
| 540 | newList.append( cmdItem) |
|---|
| 541 | |
|---|
| 542 | self.cmdList = newList |
|---|
| 543 | #---------------------------------------------------------------- |
|---|
| 544 | # This method searchs in teh cmdList if the cmdId exits |
|---|
| 545 | # @param self instance class |
|---|
| 546 | # @param cmdId id of the command to search |
|---|
| 547 | def __searchForCmdItem__( self, cmdId): |
|---|
| 548 | for cmdItem in self.cmdList: |
|---|
| 549 | if cmdItem.getId() == cmdId: |
|---|
| 550 | return cmdItem |
|---|
| 551 | return None |
|---|
| 552 | #---------------------------------------------------------------- |
|---|
| 553 | # This method updates the UI according to the cmdList. |
|---|
| 554 | # @param self instance class |
|---|
| 555 | def __updateUi__( self): |
|---|
| 556 | self.cmdModel.clear() |
|---|
| 557 | self.cmdModel.setHorizontalHeaderLabels( [ self.tr("Command name"), self.tr("Combo")]) |
|---|
| 558 | row = 0 |
|---|
| 559 | for cmdItem in self.cmdList: |
|---|
| 560 | self.cmdModel.appendRow( [ cmdItem.getNameItem(), cmdItem.getComboItem()]) |
|---|
| 561 | self.cmdModel.setVerticalHeaderItem( row, QStandardItem()) |
|---|
| 562 | row += 1 |
|---|
| 563 | self.cmdView.resizeColumnsToContents() |
|---|
| 564 | if self.workingMode == PGInput.WORKING_MODE_NOMINAL: |
|---|
| 565 | self.btnEditMode.setText( self.tr( "Enter EDIT mode")) |
|---|
| 566 | self.cmdView.setStyleSheet( "background-color: white;" |
|---|
| 567 | "selection-background-color: pink;") |
|---|
| 568 | else: |
|---|
| 569 | self.btnEditMode.setText( self.tr( "Exit EDIT nmode")) |
|---|
| 570 | self.cmdView.setStyleSheet( "background-color: white;" |
|---|
| 571 | "selection-background-color: cyan;") |
|---|
| 572 | |
|---|
| 573 | |
|---|
| 574 | if self.selectedIndex: |
|---|
| 575 | index = self.cmdModel.index( self.selectedIndex[0], PGInput.CMD_NAME_INDEX) |
|---|
| 576 | self.cmdView.setCurrentIndex( index) |
|---|
| 577 | #---------------------------------------------------------------- |
|---|
| 578 | # Call back method invoked when 'ChangeCombo' key is pressed. |
|---|
| 579 | # @param self instance class |
|---|
| 580 | # @param clicked unused |
|---|
| 581 | def __onChangeEditMode__( self, clicked): |
|---|
| 582 | if self.workingMode == PGInput.WORKING_MODE_NOMINAL: |
|---|
| 583 | self.workingMode = PGInput.WORKING_MODE_EDITION |
|---|
| 584 | else: |
|---|
| 585 | self.workingMode = PGInput.WORKING_MODE_NOMINAL |
|---|
| 586 | |
|---|
| 587 | self.cmdItem = None |
|---|
| 588 | self.selectedIndex = None |
|---|
| 589 | self.__updateUi__() |
|---|
| 590 | #---------------------------------------------------------------- |
|---|
| 591 | # Call back method invoked when a cell is selected |
|---|
| 592 | # @param self instance class |
|---|
| 593 | # @param index provides info on the selected cell |
|---|
| 594 | def __onCmdItemSelected__( self, index): |
|---|
| 595 | self.cmdItem = self.cmdList[index.row()] |
|---|
| 596 | if self.workingMode == PGInput.WORKING_MODE_EDITION: |
|---|
| 597 | self.cmdItem.clearCombo() |
|---|
| 598 | self.selectedIndex = [index.row(), index.column()] |
|---|
| 599 | self.__updateUi__() |
|---|
| 600 | |
|---|