hal_actions.py
1 #!/usr/bin/env python 2 # vim: sts=4 sw=4 et 3 # GladeVcp actions 4 # 5 # Copyright (c) 2010 Pavel Shramov <shramov@mexmat.net> 6 # 7 # This program is free software: you can redistribute it and/or modify 8 # it under the terms of the GNU General Public License as published by 9 # the Free Software Foundation, either version 2 of the License, or 10 # (at your option) any later version. 11 # 12 # This program is distributed in the hope that it will be useful, 13 # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 # GNU General Public License for more details. 16 17 import gobject 18 import gtk 19 import os 20 import time 21 import re, string 22 23 from hal_widgets import _HalWidgetBase 24 import linuxcnc 25 from hal_glib import GStat 26 27 _ = lambda x: x 28 29 class _EMCStaticHolder: 30 def __init__(self): 31 # Delay init... 32 self.linuxcnc = None 33 self.stat = None 34 self.gstat = None 35 36 def get(self): 37 if not self.linuxcnc: 38 self.linuxcnc = linuxcnc.command() 39 if not self.gstat: 40 self.gstat = GStat() 41 return self.linuxcnc, self.gstat.stat, self.gstat 42 43 class _EMCStatic: 44 holder = _EMCStaticHolder() 45 def get(self): 46 return self.holder.get() 47 48 class _EMC_ActionBase(_HalWidgetBase): 49 _gproperties = {'name': (gobject.TYPE_STRING, 'Name', 'Action name', "", 50 gobject.PARAM_READWRITE|gobject.PARAM_CONSTRUCT) 51 } 52 53 linuxcnc_static = _EMCStatic() 54 55 def _hal_init(self): 56 self.linuxcnc, self.stat, self.gstat = self.linuxcnc_static.get() 57 self._stop_emission = False 58 # if 'NO_FORCE_HOMING' is true, MDI commands are allowed before homing. 59 inifile = os.environ.get('INI_FILE_NAME', '/dev/null') 60 ini = linuxcnc.ini(inifile) 61 self.no_f_home = int(ini.find("TRAJ", "NO_FORCE_HOMING") or 0) 62 63 def machine_on(self): 64 self.stat.poll() 65 return self.stat.task_state > linuxcnc.STATE_OFF 66 67 def is_auto_mode(self): 68 self.stat.poll() 69 print self.stat.task_mode, linuxcnc.MODE_AUTO 70 return self.stat.task_mode == linuxcnc.MODE_AUTO 71 72 def is_file_loaded(self): 73 self.stat.poll() 74 print "file name:",self.stat.file 75 if self.stat.file: 76 return True 77 else: 78 return False 79 80 def is_all_homed(self): 81 self.stat.poll() 82 homed_count = 0 83 for i,h in enumerate(self.stat.homed): 84 #Don't worry about joint to axis mapping 85 if h: homed_count +=1 86 print self.stat.joints 87 if homed_count == self.stat.joints: 88 return True 89 return False 90 91 def no_home_required(self): 92 return self.no_f_home 93 94 def safe_handler(self, f): 95 def _f(self, *a, **kw): 96 if self._stop_emission: 97 return 98 return f(self, *a, **kw) 99 return _f 100 101 def set_active_safe(self, active): 102 self._stop_emission = True 103 self.set_active(active) 104 self._stop_emission = False 105 106 def do_get_property(self, property): 107 name = property.name.replace('-', '_') 108 109 if name == 'name': 110 return self.get_name() 111 elif name == 'label': 112 return self.get_label() 113 elif name == 'tooltip': 114 return self.get_tooltip() 115 elif name == 'stock_id': 116 return self.get_stock_id() 117 else: 118 raise AttributeError("Unknown property: %s" % property.name) 119 120 def do_set_property(self, property, value): 121 name = property.name.replace('-', '_') 122 123 if name == 'name': 124 if value: 125 self.set_name(value) 126 elif name == 'label': 127 self.set_label(value) 128 elif name == 'tooltip': 129 self.set_tooltip(value) 130 elif name == 'stock_id': 131 self.set_stock_id(value) 132 else: 133 raise AttributeError("Unknown property: %s" % property.name) 134 return True 135 136 class _EMC_Action(gtk.Action, _EMC_ActionBase): 137 __gproperties__ = _EMC_ActionBase._gproperties 138 def __init__(self, name=None): 139 gtk.Action.__init__(self, None, None, None, None) 140 self._stop_emission = False 141 self.connect('activate', self.safe_handler(self.on_activate)) 142 143 def set_active_safe(self, a): return #XXX: Override set_active with nop 144 145 def on_activate(self, w): 146 return True 147 148 class _EMC_ToggleAction(gtk.ToggleAction, _EMC_ActionBase): 149 __gproperties__ = _EMC_ActionBase._gproperties 150 def __init__(self, name=None): 151 gtk.ToggleAction.__init__(self, None, None, None, None) 152 self._stop_emission = False 153 self.connect('toggled', self.safe_handler(self.on_toggled)) 154 155 # XXX: Override nop in _EMC_Action 156 set_active_safe = _EMC_ActionBase.set_active_safe 157 158 def on_toggled(self, w): 159 return True 160 161 class _EMC_RadioAction(gtk.RadioAction, _EMC_ToggleAction): 162 __gproperties__ = _EMC_ToggleAction._gproperties 163 def __init__(self, name=None): 164 gtk.RadioAction.__init__(self, None, None, None, None, 0) 165 self._stop_emission = False 166 self.connect('toggled', self.safe_handler(self.on_toggled)) 167 168 def on_toggled(self, w): 169 if not w.get_active(): 170 return 171 return self.on_activate(w) 172 173 class EMC_Stat(GStat, _EMC_ActionBase): 174 __gtype_name__ = 'EMC_Stat' 175 def __init__(self): 176 stat = self.linuxcnc_static.get()[1] 177 GStat.__init__(self, stat) 178 179 def _hal_init(self): 180 pass 181 182 def _action(klass, f, *a, **kw): 183 class _C(_EMC_Action): 184 __gtype_name__ = klass 185 def on_activate(self, w): 186 print klass 187 f(self, *a, **kw) 188 return _C 189 190 EMC_Action_ESTOP = _action('EMC_Action_ESTOP', lambda s: s.linuxcnc.state(linuxcnc.STATE_ESTOP)) 191 EMC_Action_ESTOP_RESET = _action('EMC_Action_ESTOP_RESET', lambda s: s.linuxcnc.state(linuxcnc.STATE_ESTOP_RESET)) 192 EMC_Action_ON = _action('EMC_Action_ON', lambda s: s.linuxcnc.state(linuxcnc.STATE_ON)) 193 EMC_Action_OFF = _action('EMC_Action_OFF', lambda s: s.linuxcnc.state(linuxcnc.STATE_OFF)) 194 195 class EMC_ToggleAction_ESTOP(_EMC_ToggleAction): 196 __gtype_name__ = 'EMC_ToggleAction_ESTOP' 197 def _hal_init(self): 198 _EMC_ToggleAction._hal_init(self) 199 200 self.set_active_safe(True) 201 202 self.gstat.connect('state-estop', lambda w: self.set_active_safe(True)) 203 self.gstat.connect('state-estop-reset', lambda w: self.set_active_safe(False)) 204 205 def on_toggled(self, w): 206 if self.get_active(): 207 print 'Issuing ESTOP' 208 self.linuxcnc.state(linuxcnc.STATE_ESTOP) 209 else: 210 print 'Issuing ESTOP RESET' 211 self.linuxcnc.state(linuxcnc.STATE_ESTOP_RESET) 212 213 class EMC_ToggleAction_Power(_EMC_ToggleAction): 214 __gtype_name__ = 'EMC_ToggleAction_Power' 215 def _hal_init(self): 216 _EMC_ToggleAction._hal_init(self) 217 218 self.set_active_safe(False) 219 self.set_sensitive(False) 220 221 self.gstat.connect('state-on', lambda w: self.set_active_safe(True)) 222 self.gstat.connect('state-off', lambda w: self.set_active_safe(False)) 223 self.gstat.connect('state-estop', lambda w: self.set_sensitive(False)) 224 self.gstat.connect('state-estop-reset', lambda w: self.set_sensitive(True)) 225 226 def on_toggled(self, w): 227 if self.get_active(): 228 print 'Issuing ON' 229 self.linuxcnc.state(linuxcnc.STATE_ON) 230 else: 231 print 'Issuing OFF' 232 self.linuxcnc.state(linuxcnc.STATE_OFF) 233 234 class EMC_RadioAction_ESTOP(_EMC_RadioAction): 235 __gtype_name__ = 'EMC_RadioAction_ESTOP' 236 def _hal_init(self): 237 _EMC_RadioAction._hal_init(self) 238 239 self.set_active_safe(True) 240 241 self.gstat.connect('state-estop', lambda w: self.set_active_safe(True)) 242 243 def on_activate(self, w): 244 self.linuxcnc.state(linuxcnc.STATE_ESTOP) 245 246 class EMC_RadioAction_ESTOP_RESET(_EMC_RadioAction): 247 __gtype_name__ = 'EMC_RadioAction_ESTOP_RESET' 248 def _hal_init(self): 249 _EMC_RadioAction._hal_init(self) 250 251 self.set_active_safe(False) 252 253 self.gstat.connect('state-estop-reset', lambda w: self.set_active_safe(True)) 254 255 def on_activate(self, w): 256 self.linuxcnc.state(linuxcnc.STATE_ESTOP_RESET) 257 258 class EMC_RadioAction_ON(_EMC_RadioAction): 259 __gtype_name__ = 'EMC_RadioAction_ON' 260 def _hal_init(self): 261 _EMC_RadioAction._hal_init(self) 262 263 self.set_active_safe(True) 264 265 self.gstat.connect('state-on', lambda w: self.set_active_safe(True)) 266 self.gstat.connect('state-estop', lambda w: self.set_sensitive(False)) 267 self.gstat.connect('state-estop-reset', lambda w: self.set_sensitive(True)) 268 269 def on_activate(self, w): 270 self.linuxcnc.state(linuxcnc.STATE_ON) 271 272 class EMC_RadioAction_OFF(_EMC_RadioAction): 273 __gtype_name__ = 'EMC_RadioAction_OFF' 274 def _hal_init(self): 275 _EMC_RadioAction._hal_init(self) 276 277 self.set_active_safe(False) 278 279 self.gstat.connect('state-off', lambda w: self.set_active_safe(True)) 280 self.gstat.connect('state-estop', lambda w: self.set_sensitive(False)) 281 self.gstat.connect('state-estop-reset', lambda w: self.set_sensitive(True)) 282 283 def on_activate(self, w): 284 self.linuxcnc.state(linuxcnc.STATE_OFF) 285 286 def running(s, do_poll=True): 287 if do_poll: s.poll() 288 return s.task_mode == linuxcnc.MODE_AUTO and s.interp_state != linuxcnc.INTERP_IDLE 289 290 def ensure_mode(s, c, *modes): 291 s.poll() 292 if not modes: return False 293 if s.task_mode in modes: return True 294 if running(s, do_poll=False): return False 295 c.mode(modes[0]) 296 c.wait_complete() 297 return True 298 299 class EMC_Action_Python(_EMC_Action): 300 __gtype_name__ = 'EMC_Action_Python' 301 command = gobject.property(type=str, default='', nick='Python Command') 302 is_homed = gobject.property(type=bool, default=True, nick='Must Be Homed', 303 blurb='Machine Must be homed for widgets to be sensitive to input') 304 is_on = gobject.property(type=bool, default=True, nick='Must Be On', 305 blurb='Machine Must be On for widgets to be sensitive to input') 306 is_idle = gobject.property(type=bool, default=True, nick='Must Be Idle', 307 blurb='Machine Must be Idle for widgets to be sensitive to input') 308 requires_manual = gobject.property(type=bool, default=False, nick='Preset Manual Mode', 309 blurb='Preset Manual Mode before command') 310 requires_mdi = gobject.property(type=bool, default=False, nick='Preset MDI Mode', 311 blurb='Preset MDI Mode before command') 312 requires_auto = gobject.property(type=bool, default=False, nick='Preset Auto Mode', 313 blurb='Preset Auto Mode before command') 314 315 def _hal_init(self): 316 _EMC_Action._hal_init(self) 317 self.set_sensitive(False) 318 self.gstat.connect('state-estop', lambda w: self.set_sensitive(False)) 319 if self.is_on: 320 self.gstat.connect('state-off', lambda w: self.set_sensitive(False)) 321 if self.is_homed: 322 self.gstat.connect('interp-idle', lambda w: self.set_sensitive(self.machine_on() and ( self.is_all_homed() or self.no_home_required() ) )) 323 else: 324 self.gstat.connect('interp-idle', lambda w: self.set_sensitive(self.machine_on()) ) 325 if self.is_idle: 326 self.gstat.connect('interp-run', lambda w: self.set_sensitive(False)) 327 if self.is_homed: 328 self.gstat.connect('all-homed', lambda w: self.set_sensitive(self.machine_on())) 329 330 def on_activate(self, w): 331 self._globalParameter = { 'EXT':self._panel_instance.get_handler_obj(), 332 'GSTAT':self.gstat,'CMD':self.linuxcnc,'STAT':self.stat} 333 self._localsParameter = {'dir': dir, 'self': self,'linuxcnc':linuxcnc} 334 if self.requires_manual: 335 ensure_mode(self.stat, self.linuxcnc, linuxcnc.MODE_MAN) 336 elif self.requires_mdi: 337 ensure_mode(self.stat, self.linuxcnc, linuxcnc.MODE_MDI) 338 elif self.requires_auto: 339 ensure_mode(self.stat, self.linuxcnc, linuxcnc.MODE_AUTO) 340 exec(self.command, self._globalParameter, self._localsParameter) 341 342 class EMC_Action_Run(_EMC_Action): 343 __gtype_name__ = 'EMC_Action_Run' 344 program_start_line = gobject.property(type=int, default=0, minimum=0, nick='Restart line', 345 blurb='Restart line number-Usually 0 - program start') 346 reset_line = gobject.property(type=int, default=0, minimum=0, nick='Restart line after restarting once', 347 blurb='Line number that will be set afterthe next restart. -usually 0 - program start') 348 349 def set_restart_line(self,line,resetline=0): 350 self.program_start_line = line 351 self.reset_line = resetline 352 353 def on_activate(self, w): 354 ensure_mode(self.stat, self.linuxcnc, linuxcnc.MODE_AUTO) 355 self.linuxcnc.auto(linuxcnc.AUTO_RUN, self.program_start_line) 356 self.program_start_line = self.reset_line 357 358 class EMC_Action_Step(_EMC_Action): 359 __gtype_name__ = 'EMC_Action_Step' 360 def _hal_init(self): 361 _EMC_Action._hal_init(self) 362 363 self.gstat.connect('state-off', lambda w: self.set_sensitive(False)) 364 self.gstat.connect('state-estop', lambda w: self.set_sensitive(False)) 365 self.gstat.connect('interp-idle', lambda w: self.set_sensitive(self.machine_on())) 366 367 def on_activate(self, w): 368 ensure_mode(self.stat, self.linuxcnc, linuxcnc.MODE_AUTO) 369 self.linuxcnc.auto(linuxcnc.AUTO_STEP) 370 371 class EMC_Action_Pause(_EMC_Action): 372 __gtype_name__ = 'EMC_Action_Pause' 373 def on_activate(self, w): 374 self.stat.poll() 375 if self.stat.task_mode != linuxcnc.MODE_AUTO or\ 376 self.stat.interp_state not in (linuxcnc.INTERP_READING, linuxcnc.INTERP_WAITING): 377 return 378 ensure_mode(self.stat, self.linuxcnc, linuxcnc.MODE_AUTO) 379 self.linuxcnc.auto(linuxcnc.AUTO_PAUSE) 380 381 class EMC_Action_Resume(_EMC_Action): 382 __gtype_name__ = 'EMC_Action_Resume' 383 def on_activate(self, w): 384 print "RESUME" 385 self.stat.poll() 386 if not self.stat.paused: 387 return 388 if self.stat.task_mode not in (linuxcnc.MODE_AUTO, linuxcnc.MODE_MDI): 389 return 390 ensure_mode(self.stat, self.linuxcnc, linuxcnc.MODE_AUTO, linuxcnc.MODE_MDI) 391 self.linuxcnc.auto(linuxcnc.AUTO_RESUME) 392 393 class EMC_Action_Stop(_EMC_Action): 394 __gtype_name__ = 'EMC_Action_Stop' 395 def on_activate(self, w): 396 self.linuxcnc.abort() 397 self.linuxcnc.wait_complete() 398 399 class EMC_ToggleAction_Run(_EMC_ToggleAction, EMC_Action_Run): 400 __gtype_name__ = 'EMC_ToggleAction_Run' 401 program_start_line = gobject.property(type=int, default=0, minimum=0, nick='Restart line', 402 blurb='Restart line number-Usually 0 - program start') 403 reset_line = gobject.property(type=int, default=0, minimum=0, nick='Restart line after restarting once', 404 blurb='Line number that will be set afterthe next restart. -usually 0 - program start') 405 def _hal_init(self): 406 _EMC_ToggleAction._hal_init(self) 407 408 self.set_active_safe(False) 409 self.set_sensitive(False) 410 411 self.gstat.connect('state-off', lambda w: self.set_sensitive(False)) 412 self.gstat.connect('state-estop', lambda w: self.set_sensitive(False)) 413 414 self.gstat.connect( 'interp-idle', lambda w: self.set_sensitive( self.machine_on() and ( self.is_all_homed() or self.no_home_required() ) and self.is_file_loaded() ) ) 415 self.gstat.connect('interp-idle', lambda w: self.set_active_safe(False)) 416 self.gstat.connect('interp-run', lambda w: self.set_sensitive(False)) 417 self.gstat.connect('interp-run', lambda w: self.set_active_safe(True)) 418 self.gstat.connect('all-homed', lambda w: self.set_sensitive( self.machine_on() and self.is_file_loaded() )) 419 self.gstat.connect('file-loaded', self.file_loaded_check) 420 421 def file_loaded_check(self,widget,filename): 422 self.set_sensitive( self.machine_on() and (self.is_all_homed() or self.no_home_required()) ) 423 424 def set_restart_line(self,line,resetline=0): 425 self.program_start_line = line 426 self.reset_line = resetline 427 428 def on_toggled(self, w): 429 if self.get_active(): 430 return self.on_activate(w) 431 432 class EMC_ToggleAction_Stop(_EMC_ToggleAction, EMC_Action_Stop): 433 __gtype_name__ = "EMC_ToggleAction_Stop" 434 def _hal_init(self): 435 _EMC_ToggleAction._hal_init(self) 436 437 self.set_active_safe(True) 438 self.set_sensitive(False) 439 440 self.gstat.connect('state-off', lambda w: self.set_sensitive(False)) 441 self.gstat.connect('state-estop', lambda w: self.set_sensitive(False)) 442 443 self.gstat.connect('interp-idle', lambda w: self.set_sensitive(False)) 444 self.gstat.connect('interp-idle', lambda w: self.set_active_safe(True)) 445 self.gstat.connect('interp-run', lambda w: self.set_sensitive(self.machine_on())) 446 self.gstat.connect('interp-run', lambda w: self.set_active_safe(False)) 447 448 def on_toggled(self, w): 449 if self.get_active(): 450 return self.on_activate(w) 451 452 class EMC_ToggleAction_Pause(_EMC_ToggleAction, EMC_Action_Pause): 453 __gtype_name__ = "EMC_ToggleAction_Pause" 454 def _hal_init(self): 455 _EMC_ToggleAction._hal_init(self) 456 457 self.resume = EMC_Action_Resume() 458 self.resume._hal_init() 459 460 self.set_active_safe(True) 461 self.set_sensitive(False) 462 463 self.gstat.connect('state-off', lambda w: self.set_sensitive(False)) 464 self.gstat.connect('state-estop', lambda w: self.set_sensitive(False)) 465 466 self.gstat.connect('interp-idle', lambda w: self.set_sensitive(False)) 467 self.gstat.connect('interp-idle', lambda w: self.set_active_safe(False)) 468 self.gstat.connect('interp-run', lambda w: self.set_sensitive(self.machine_on())) 469 self.gstat.connect('interp-run', lambda w: self.set_active_safe(False)) 470 self.gstat.connect('interp-paused', lambda w: self.set_active_safe(True)) 471 self.gstat.connect('interp-waiting', lambda w: self.set_active_safe(False)) 472 473 def on_toggled(self, w): 474 if self.get_active(): 475 return self.on_activate(w) 476 else: 477 return self.resume.on_activate(self.resume) 478 479 class HalTemplate(string.Template): 480 idpattern = '[_a-z][-._a-z0-9]*' 481 482 class FloatComp: 483 def __init__(self, comp): 484 self.comp = comp 485 def __getitem__(self, k): 486 v = float(self.comp[k]) 487 return "%f" % v 488 489 class EMC_Action_MDI(_EMC_Action): 490 __gtype_name__ = 'EMC_Action_MDI' 491 command = gobject.property(type=str, default='', nick='MDI Command') 492 493 def _hal_init(self): 494 _EMC_Action._hal_init(self) 495 self.set_sensitive(False) 496 self.gstat.connect('state-off', lambda w: self.set_sensitive(False)) 497 self.gstat.connect('state-estop', lambda w: self.set_sensitive(False)) 498 self.gstat.connect('interp-idle', lambda w: self.set_sensitive(self.machine_on() and ( self.is_all_homed() or self.no_home_required() ) )) 499 self.gstat.connect('interp-run', lambda w: self.set_sensitive(False)) 500 self.gstat.connect('all-homed', lambda w: self.set_sensitive(self.machine_on())) 501 502 def on_activate(self, w): 503 ensure_mode(self.stat, self.linuxcnc, linuxcnc.MODE_MDI) 504 template = HalTemplate(self.command) 505 cmd = template.substitute(FloatComp(self.hal)) 506 self.linuxcnc.mdi(cmd) 507 508 class EMC_ToggleAction_MDI(_EMC_ToggleAction, EMC_Action_MDI): 509 __gtype_name__ = 'EMC_ToggleAction_MDI' 510 __gsignals__ = { 511 'mdi-command-start': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ()), 512 'mdi-command-stop': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ()), 513 } 514 command = gobject.property(type=str, default='', nick='MDI Command') 515 516 def _hal_init(self): 517 _EMC_ToggleAction._hal_init(self) 518 EMC_Action_MDI._hal_init(self) 519 520 def on_toggled(self, w): 521 if not self.get_active(): 522 return 523 self.set_sensitive(False) 524 self.emit('mdi-command-start') 525 self.on_activate(w) 526 gobject.timeout_add(100, self.wait_complete) 527 528 def wait_complete(self): 529 if self.linuxcnc.wait_complete(0) in [-1, linuxcnc.RCS_EXEC]: 530 return True 531 self.emit('mdi-command-stop') 532 self.set_active_safe(False) 533 self.set_sensitive(self.machine_on()) 534 return False 535 536 class EMC_Action_UnHome(_EMC_Action): 537 __gtype_name__ = 'EMC_Action_Unhome' 538 axis = gobject.property(type=int, default=-1, minimum=-1, nick='Axis', 539 blurb='Axis to unhome. -1 to unhome all') 540 def _hal_init(self): 541 _EMC_Action._hal_init(self) 542 self.set_sensitive(False) 543 self.gstat.connect('state-off', lambda w: self.set_sensitive(False)) 544 self.gstat.connect('state-estop', lambda w: self.set_sensitive(False)) 545 self.gstat.connect('interp-idle', lambda w: self.set_sensitive(self.machine_on())) 546 self.gstat.connect('interp-run', lambda w: self.set_sensitive(False)) 547 548 def on_activate(self, w): 549 ensure_mode(self.stat, self.linuxcnc, linuxcnc.MODE_MANUAL) 550 self.linuxcnc.teleop_enable(False) 551 self.linuxcnc.unhome(self.axis) 552 553 def prompt_areyousure(type, message, secondary=None): 554 dialog = gtk.MessageDialog(None, 0, type, gtk.BUTTONS_YES_NO, message) 555 if secondary: 556 dialog.format_secondary_text(secondary) 557 r = dialog.run() 558 dialog.destroy() 559 return r == gtk.RESPONSE_YES 560 561 class EMC_Action_Home(_EMC_Action): 562 __gtype_name__ = 'EMC_Action_Home' 563 axis = gobject.property(type=int, default=-1, minimum=-1, nick='Axis', 564 blurb='Axis to home. -1 to home all') 565 confirm_homed = gobject.property(type=bool, default=False, nick='Confirm rehoming', 566 blurb='Ask user if axis is already homed') 567 def _hal_init(self): 568 _EMC_Action._hal_init(self) 569 self.set_sensitive(False) 570 self.gstat.connect('state-off', lambda w: self.set_sensitive(False)) 571 self.gstat.connect('state-estop', lambda w: self.set_sensitive(False)) 572 self.gstat.connect('interp-idle', lambda w: self.set_sensitive(self.machine_on())) 573 self.gstat.connect('interp-run', lambda w: self.set_sensitive(False)) 574 575 def homed(self): 576 if self.axis != -1: 577 return self.stat.homed[self.axis] 578 for i,h in enumerate(self.stat.homed): 579 if h and self.stat.axis_mask & (1<<i): 580 return True 581 582 def on_activate(self, w): 583 #if not manual_ok(): return 584 ensure_mode(self.stat, self.linuxcnc, linuxcnc.MODE_MANUAL) 585 if self.confirm_homed and self.homed(): 586 if not prompt_areyousure(gtk.MESSAGE_WARNING, 587 _("Axis is already homed, are you sure you want to re-home?")): 588 return 589 self.linuxcnc.teleop_enable(False) 590 self.linuxcnc.home(self.axis) 591 592 593 class State_Sensitive_Table(gtk.Table, _EMC_ActionBase): 594 __gtype_name__ = "State_Sensitive_Table" 595 is_homed = gobject.property(type=bool, default=True, nick='Must Be Homed', 596 blurb='Machine Must be homed for widgets to be sensitive to input') 597 is_on = gobject.property(type=bool, default=True, nick='Must Be On', 598 blurb='Machine Must be On for widgets to be sensitive to input') 599 is_idle = gobject.property(type=bool, default=True, nick='Must Be Idle', 600 blurb='Machine Must be Idle for widgets to be sensitive to input') 601 602 def _hal_init(self): 603 _EMC_ActionBase._hal_init(self) 604 self.set_sensitive(False) 605 self.gstat.connect('state-estop', lambda w: self.set_sensitive(False)) 606 if self.is_on: 607 self.gstat.connect('state-off', lambda w: self.set_sensitive(False)) 608 if self.is_homed: 609 self.gstat.connect('interp-idle', lambda w: self.set_sensitive(self.machine_on() and ( self.is_all_homed() or self.no_home_required() ) )) 610 else: 611 self.gstat.connect('interp-idle', lambda w: self.set_sensitive(self.machine_on()) ) 612 if self.is_idle: 613 self.gstat.connect('interp-run', lambda w: self.set_sensitive(False)) 614 if self.is_homed: 615 self.gstat.connect('all-homed', lambda w: self.set_sensitive(self.machine_on()))