Package autoglade :: Module autoglade
[hide private]
[frames] | no frames]

Source Code for Module autoglade.autoglade

   1  #! /usr/bin/env python 
   2  # -*- coding: utf-8 -*- 
   3  """ 
   4  $Id: autoglade.py 35 2008-08-14 13:52:40Z dtmilano $ 
   5  """ 
   6   
   7  __license__ = """ 
   8   
   9  Copyright (C) 2007 Diego Torres Milano <diego@codtech.com> 
  10   
  11   
  12  This program is free software; you can redistribute it and/or modify 
  13  it under the terms of the GNU General Public License as published by 
  14  the Free Software Foundation; either version 2 of the License, or 
  15  (at your option) any later version. 
  16   
  17  This program is distributed in the hope that it will be useful, 
  18  but WITHOUT ANY WARRANTY; without even the implied warranty of 
  19  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  20  GNU General Public License for more details. 
  21   
  22  You should have received a copy of the GNU General Public License 
  23  along with this program; if not, write to the Free Software 
  24  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
  25  USA 
  26  """ 
  27   
  28  __version__ = '0.4' 
  29  __rev__ = '$Rev: 35 $' 
  30   
  31  """ 
  32  AutoGlade 
  33   
  34  @var AUTO_INVOKE_RE: Default regular expression to map Glade widget names 
  35  @type AUTO_INVOKE_RE: str 
  36   
  37  @var AUTO_INVOKE_WIDGET: Default position of the widget name group in L{AUTO_INVOKE_RE} 
  38  @type AUTO_INVOKE_WIDGET: int 
  39   
  40  @var AUTO_INVOKE_METHOD: Default position of the group indicating the method name to invoke 
  41  @type AUTO_INVOKE_METHOD: int 
  42   
  43  @var AGO_POSTPONED: Constant to indicate that some initialization is 
  44          deferred because the value is not yet available. 
  45          Used in L{AUtoGladeObject}. 
  46  @type AGO_POSTPONED: int 
  47  """ 
  48   
  49   
  50  AUTO_DELIMITER = ':' 
  51   
  52  AUTO_INVOKE_RE = '(.*)' + AUTO_DELIMITER + 'auto' + AUTO_DELIMITER + \ 
  53          '([^' + AUTO_DELIMITER + ']*)(' + AUTO_DELIMITER +'(.+))?' 
  54   
  55  AUTO_INVOKE_WIDGET = 1  # the position containing widget name 
  56  # FIXME: 
  57  # this was AUTO_INVOKE_OBJECT, and perhaps it's a better name, because it's 
  58  # possible that objects being passed insted of methods. 
  59  # Verify its usage. 
  60  AUTO_INVOKE_METHOD = 2  # the position of the group inside the re containing method name 
  61  AUTO_INVOKE_HASARGS = 3         # the position of the group inside the re containing method args 
  62  AUTO_INVOKE_ARGS = 4    # the position of the group inside the re containing the arg 
  63   
  64  AUTO_TREEVIEW_SET_CELL_RE = 'setTreeview(.+)Cell(\d+)' 
  65   
  66  AGO_POSTPONED = -2              # AutoGladeObject POSTPONED 
  67   
  68  AGO_DIALOG_PREFERENCES = 'dialogPreferences' 
  69  AGO_BUTTON_PREFERENCES = 'buttonPreferences' 
  70  AGO_MENU_ITEM_PREFERENCES = 'menuItemPreferences' 
  71  AGO_TOOL_BUTTON_PREFERENCES = 'toolButtonPreferences' 
  72   
  73  AGO_BUTTON_NEW = 'buttonNew' 
  74  AGO_MENU_ITEM_NEW = 'menuItemNew' 
  75  AGO_TOOL_BUTTON_NEW = 'toolButtonNew' 
  76   
  77  AGO_BUTTON_OPEN = 'buttonOpen' 
  78  AGO_MENU_ITEM_OPEN = 'menuItemOpen' 
  79  AGO_TOOL_BUTTON_OPEN = 'toolButtonOpen' 
  80   
  81  AGO_BUTTON_SAVE = 'buttonSave' 
  82  AGO_MENU_ITEM_SAVE = 'menuItemSave' 
  83  AGO_TOOL_BUTTON_SAVE = 'toolButtonSave' 
  84   
  85  AGO_MENU_ITEM_SAVE_AS = 'menuItemSaveas' # should be SaveAs, but... 
  86   
  87  AGO_MENU_ITEM_COPY = 'menuItemCopy' 
  88   
  89  AGO_MENU_ITEM_CUT = 'menuItemCut' 
  90   
  91  AGO_MENU_ITEM_PASTE = 'menuItemPaste' 
  92   
  93  AGO_MENU_ITEM_DELETE = 'menuItemDelete' 
  94   
  95  AGO_BUTTON_QUIT = 'buttonQuit' 
  96  AGO_MENU_ITEM_QUIT = 'menuItemQuit' 
  97  AGO_TOOL_BUTTON_QUIT = 'toolButtonQuit' 
  98   
  99  AGO_DIALOG_ABOUT = 'dialogAbout' 
 100  AGO_BUTTON_ABOUT = 'buttonAbout' 
 101  AGO_MENU_ITEM_ABOUT = 'menuItemAbout' 
 102  AGO_TOOL_BUTTON_ABOUT = 'toolButtonAbout' 
 103   
 104  AGOS = [ 
 105          AGO_DIALOG_PREFERENCES, 
 106          AGO_BUTTON_PREFERENCES, 
 107          AGO_MENU_ITEM_PREFERENCES, 
 108          AGO_TOOL_BUTTON_PREFERENCES, 
 109          AGO_BUTTON_NEW, 
 110          AGO_MENU_ITEM_NEW, 
 111          AGO_TOOL_BUTTON_NEW, 
 112          AGO_BUTTON_OPEN, 
 113          AGO_MENU_ITEM_OPEN, 
 114          AGO_TOOL_BUTTON_OPEN, 
 115          AGO_BUTTON_SAVE, 
 116          AGO_MENU_ITEM_SAVE, 
 117          AGO_TOOL_BUTTON_SAVE, 
 118          AGO_MENU_ITEM_SAVE_AS, 
 119          AGO_MENU_ITEM_COPY, 
 120          AGO_MENU_ITEM_CUT, 
 121          AGO_MENU_ITEM_PASTE, 
 122          AGO_MENU_ITEM_DELETE, 
 123          AGO_BUTTON_QUIT, 
 124          AGO_MENU_ITEM_QUIT, 
 125          AGO_TOOL_BUTTON_QUIT, 
 126          AGO_DIALOG_ABOUT, 
 127          AGO_BUTTON_ABOUT, 
 128          AGO_MENU_ITEM_ABOUT, 
 129          AGO_TOOL_BUTTON_ABOUT, 
 130  ] 
 131   
 132  ASI_STOCK = 0 
 133  ASI_GTKCLASS = 1 
 134   
 135  import sys 
 136  import os 
 137  import re 
 138  import gobject 
 139  import gtk.glade 
 140  try: 
 141          import gconf 
 142  except: 
 143          pass 
 144  import warnings 
 145  import traceback 
 146  from optparse import OptionParser 
 147  from xml.dom import minidom 
 148   
 149  prog = os.path.basename(sys.argv[0]) 
 150  version = __version__ 
 151  revision = __rev__ 
 152  DEBUG = [ '__autoConnect', 'autoCopy', 'autoOpen', 'open', 'autoNew', 
 153          'autoSaveas', 'save'] 
 154  WARNING = [ '__autoConnect' ] 
 155   
 156  colors = {"default":"", 
 157          "blue":   "\x1b[01;34m", 
 158          "cyan":   "\x1b[01;36m", 
 159          "green":  "\x1b[01;32m", 
 160          "red":  "\x1b[01;05;37;41m", 
 161          "magenta":      "\x1b[01;35m", 
 162          "sgr0":  "\x1b[m\x1b(B" 
 163          } 
 164   
 165  CYAN = colors['cyan'] 
 166  RED = colors['red'] 
 167  BLUE = colors['blue'] 
 168  GREEN = colors['green'] 
 169  MAGENTA = colors['magenta'] 
 170  SGR0 = colors['sgr0'] 
 171   
172 -def FN():
173 """ 174 Get the function name from the previous (calling) frame 175 """ 176 177 return sys._getframe(1).f_code.co_name
178
179 -def warning(str, *cond):
180 if WARNING: 181 if cond: 182 for c in cond: 183 if c in WARNING: 184 break 185 return 186 187 warnings.warn(str, RuntimeWarning)
188
189 -def debug(str, *cond):
190 DEBUGDEBUG = False 191 if DEBUG: 192 if cond: 193 found = False 194 for c in cond: 195 if DEBUGDEBUG: 196 print >>sys.stderr, "debug: testing %s in %s" % (c, DEBUG) 197 if c in DEBUG: 198 if DEBUGDEBUG: 199 print >>sys.stderr, "debug: true" 200 found = True 201 break 202 for d in DEBUG: 203 if re.compile(d).match(c): 204 found = True 205 break 206 if not found: 207 return 208 209 print >>sys.stderr, str
210 211 212 EMPTY_GLADE = """<?xml version="1.0" encoding="UTF-8" standalone="no"?> 213 <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> 214 <!--Generated with glade3 3.2.0 on Tue Sep 25 21:27:17 2007 by diego@bruce--> 215 <glade-interface> 216 </glade-interface> 217 """ 218 219 INPUT_CLASS = ['GtkRadioButton', 'GtkCheckButton', 220 'GtkToggleButton', 'GtkEntry', 'GtkHScale', 'GtkVScale', 221 'GtkSpinButton', 'GtkComboBox', 'GtkFileChooserButton', 222 'GtkFontButton', 'GtkColorButton', 'GtkCalendar'] 223
224 -class AutoGladeAttributeError(AttributeError):
225 """ 226 AutoGladeAttributeError is an identificable AttributeError 227 """ 228
229 - def __init__(self, key):
230 """ 231 Constructor 232 233 @param key: key not found 234 @type key: str 235 """ 236 237 AttributeError.__init__(self, key)
238
239 -class AutoGladeRuntimeError(RuntimeError):
240 """ 241 AutoGladeRuntimeError 242 """ 243
244 - def __init__(self, msg):
245 RuntimeError.__init__(self, msg)
246 247
248 -class AutoGladeItemNotFoundException(Exception):
249 """ 250 AutoGladeItemNotFoundException 251 """ 252
253 - def __init__(self, msg):
254 Exception.__init__(self, msg)
255 256
257 -class AutoGladeObject:
258 """ 259 AutoGladeObject is an utility class that relates together the Glade 260 widget, its name and the XML element in a particular autoglade instance. 261 """ 262 263 DEBUG = True 264 __autoglade = None 265 __name = None 266 __widget = None 267 __element = None 268
269 - def __init__(self, autoglade, name=None, widget=None, element=None):
270 """ 271 Constructor 272 273 @param autoglade: Autoglade objet to which object is related to 274 @type autoglade: AutoGlade.AutoGlade 275 276 @param name: Name of the AutoGladeObject 277 @type name: str 278 279 @param widget: Widget of the AutoGladeObject. This accepts the 280 special value L{autoglade.AGO_POSTPONED} to defer the 281 initialization of the widget until some conditions are met. 282 @type widget: L{gtk.Widget} 283 284 @param element: Element of the AutoGladeObject 285 @type element: str 286 287 @raise AutoGladeRuntimeError: If the AutoGladeObject cannot be 288 initialized because some values are missing this L{Exception} 289 is raised. 290 """ 291 292 cond = FN() 293 debug("%s: AutoGladeObject(autoglade=%s, name=%s, " \ 294 "element=%s, widget=%s)" % \ 295 (cond, autoglade, name, element, widget), cond) 296 297 self.__autoglade = None 298 self.__name = None 299 self.__widget = None 300 self.__element = None 301 302 self.__autoglade = autoglade 303 if name: 304 self.__name = name 305 if widget: 306 self.__widget = widget 307 if element: 308 self.__element = element 309 310 if not self.__element: 311 if not self.__name: 312 if self.__widget: 313 self.__name = self.__widget.get_name() 314 if not self.__name: 315 raise AutoGladeRuntimeError("Cannot get widget name for widget=%s" % self.__widget) 316 else: 317 raise AutoGladeRuntimeError("Cannot determine element unless name or widget are specified.") 318 self.__element = self.__getElementByName(self.__name) 319 320 if not self.__widget: 321 if not self.__name: 322 self.__name = self.__element.getAttribute('id') 323 else: 324 self.__widget = self.__autoglade.__getattr__(self.__name) 325 326 if not (self.__name and self.__widget and self.__element): 327 raise AutoGladeRuntimeError("One attribute is missing (name=%s, element=%s, widget=%s)" % 328 (self.__name, self.__element, self.__widget))
329
330 - def getName(self):
331 return self.__name
332
333 - def getWidget(self):
334 debug("AutoGladeObject::getWidget()\n" + 335 "\t__widget = %s\n" % self.__widget + 336 "\t__name = %s" % self.__name, 337 FN()) 338 339 if self.__widget != AGO_POSTPONED: 340 return self.__widget 341 else: 342 self.__widget = self.__autoglade.__getattr__(self.__name) 343 return self.__widget
344
345 - def getElement(self):
346 return self.__element
347
348 - def __getElementByName(self, name):
349 """ 350 Get the DOM element by name. 351 352 @param name: Element name to find 353 @type name: str 354 355 @raise AutoGladeRuntimeError: If there's no element matching name 356 """ 357 358 cond = FN() 359 360 for element in self.__autoglade.getGladeInterface().getElementsByTagName('widget'): 361 debug("__getElementByName::Looking for %s found %s" % (name, 362 element.getAttribute('id')), cond) 363 if element.getAttribute('id') == name: 364 return element 365 366 debug("\tNOT FOUND !", cond); 367 raise AutoGladeRuntimeError("Couldn't find element for name=%s" % name)
368
369 - def connectIfNotConnected(self, signal, handler, *args):
370 """ 371 Connect the specified signal with handler if there's no another handler defined. 372 373 @param signal: Signal name 374 @type signal: str 375 376 @param handler: Signal handler 377 @type handler: Callable 378 379 @param args: Extra arguments 380 @type args: List 381 """ 382 383 cond = FN() 384 385 debug("%s(signal=%s, handler=%s)" % (cond, signal, handler), cond) 386 debug("\telement = %s" % self.__element, cond) 387 debug("\tsignal = %s" % self.__element.getElementsByTagName('signal'), cond) 388 debug("\tname = %s" % self.getName(), cond) 389 390 # check for signals handlers defined in glade XML file 391 for child in self.__element.childNodes: 392 if child.localName == 'signal' and child.attributes['name'] == signal : 393 return 394 395 debug("\tconnecting signal " + signal + " to auto handler", cond) 396 debug("\twidget %s" % self.getWidget(), cond) 397 debug("\thandler %s" % handler, cond) 398 399 if args: 400 self.getWidget().connect(signal, handler, args[0]) 401 else: 402 self.getWidget().connect(signal, handler)
403
404 -class AutoTreeviewSetCell:
405 """ 406 AutoTreeviewSetCell helper class. 407 408 This is a helper class to set cells in L{gtk.Treeview}. 409 Usually, to set cell properties the call used is as: 410 411 C{cell.set_property('pixbuf', treeModel.get_value(iter, B{0}))} 412 413 But to avoid the problem of having to hardcode the cell index, 0 in this 414 case, this helper class is used. 415 This is used in conjuntion with L{AutoGlade.__getitem__} which returns 416 and instance of L{AutoTreeviewSetCell} if C{key} matches the 417 C{AUTO_TREEVIEW_SET_CELL_RE}. 418 It's used, most frequently in initialization funtions 419 (see L{AutoGlade.autoInit}) like this 420 421 C{tvcolumn.set_cell_data_func(cellPixbuf, self.setTreeviewPixbufCell0)} 422 423 or 424 425 C{tvcolumn.set_cell_data_func(cellText, self.setTreeviewTextCell1)} 426 """ 427 428 DEBUG = False 429
430 - def __init__(self, cellType, cellIndex):
431 """ 432 Constructor 433 434 @param cellType: the cell type (i.e.: text, pixbuf, activatable) 435 @type cellType: str 436 437 @param cellIndex: the cell (column) index inside the Treeview 438 @type cellIndex: int 439 """ 440 441 debug("AutoTreeviewSetCell::__init__(cellType=%s, cellIndex=%s)" % ( 442 cellType, cellIndex)) 443 444 if cellType == 'toggle': 445 cellType = 'active' 446 self.__cellType = cellType 447 self.__cellIndex = int(cellIndex)
448
449 - def __call__(self, column, cell, treeModel, iter, *data):
450 debug("AutoTreeviewSetCell::__call__(column=%s, cell=%s, treeModel=%s, iter=%s)%s" % (column, cell, treeModel, iter)) 451 cell.set_property(self.__cellType, treeModel.get_value(iter, 452 self.__cellIndex)) 453 return
454
455 -class AutoGlade:
456 """ 457 AutoGlade main class. 458 459 This is the main AutoGlade class. 460 461 Conventions 462 =========== 463 These are the conventions used to relate Glade files. 464 465 @cvar DEBUG: Set debugging output 466 @type DEBUG: bool 467 468 @ivar __reAutoInvoke: The regular expression to parse the Glade widget name 469 @type __reAutoInvoke: str 470 471 472 @ivar __menuItemAbout: Stock menu item about 473 @type __menuItemAbout: L{gtk.Widget} 474 475 @ivar __menuItemQuit: Stock menu item quit 476 @type __menuItemQuit: L{gtk.Widget} 477 478 @ivar __menuItemPreferences: Stock menu item preferences 479 @type __menuItemPreferences: L{gtk.Widget} 480 """ 481 482 ## 483 ## * The glade definition file should have the same name as the parent class 484 ## or should be specified by glade=filename parameter 485 ## * Signal handler names must start with 'on_' @see{__getitem__} 486 ## * For on_automenuitem_activate to work, in the Glade interface designer 487 ## the signal handler for this menu item should be on_menuitem_activate and 488 ## user data must be the name of the widget to call (.i.e: dialog) 489 490 DEBUG = False 491 __reAutoInvoke = re.compile(AUTO_INVOKE_RE) 492 __reSetTreeviewCell = re.compile(AUTO_TREEVIEW_SET_CELL_RE) 493 494 __topLevelWidgetNames = [] 495 __mainTopLevelWidget = None # AutoGladeObject 496 __autoGladeObjects = {} # AutoGladeObjetcs 497 for ago in AGOS: 498 __autoGladeObjects[ago] = None 499 __topLevelWidgets = {} 500 __signalHandlers = {} 501 __autoDumpMap = {} 502 __gconf = None 503 __dump = {} 504 __autoArgs = '' 505 __autoProperties = {} 506 __autoStockItems = {} 507 508 __autoStockItems[AGO_BUTTON_PREFERENCES] = ['gtk-preferences', gtk.Button] 509 __autoStockItems[AGO_MENU_ITEM_PREFERENCES] = ['gtk-preferences', gtk.MenuItem] 510 __autoStockItems[AGO_TOOL_BUTTON_PREFERENCES] = ['gtk-preferences', gtk.ToolButton] 511 512 __autoStockItems[AGO_BUTTON_NEW] = ['gtk-new', gtk.Button] 513 __autoStockItems[AGO_MENU_ITEM_NEW] = ['gtk-new', gtk.MenuItem] 514 __autoStockItems[AGO_TOOL_BUTTON_NEW] = ['gtk-new', gtk.ToolButton] 515 516 __autoStockItems[AGO_BUTTON_OPEN] = ['gtk-open', gtk.Button] 517 __autoStockItems[AGO_MENU_ITEM_OPEN] = ['gtk-open', gtk.MenuItem] 518 __autoStockItems[AGO_TOOL_BUTTON_OPEN] = ['gtk-open', gtk.ToolButton] 519 520 __autoStockItems[AGO_BUTTON_SAVE] = ['gtk-save', gtk.Button] 521 __autoStockItems[AGO_MENU_ITEM_SAVE] = ['gtk-save', gtk.MenuItem] 522 __autoStockItems[AGO_TOOL_BUTTON_SAVE] = ['gtk-save', gtk.ToolButton] 523 524 __autoStockItems[AGO_MENU_ITEM_SAVE_AS] = ['gtk-save-as', gtk.MenuItem] 525 526 __autoStockItems[AGO_MENU_ITEM_COPY] = ['gtk-copy', gtk.MenuItem] 527 528 __autoStockItems[AGO_MENU_ITEM_CUT] = ['gtk-cut', gtk.MenuItem] 529 530 __autoStockItems[AGO_MENU_ITEM_PASTE] = ['gtk-paste', gtk.MenuItem] 531 532 __autoStockItems[AGO_MENU_ITEM_DELETE] = ['gtk-delete', gtk.MenuItem] 533 534 __autoStockItems[AGO_BUTTON_QUIT] = ['gtk-quit', gtk.Button] 535 __autoStockItems[AGO_MENU_ITEM_QUIT] = ['gtk-quit', gtk.MenuItem] 536 __autoStockItems[AGO_TOOL_BUTTON_QUIT] = ['gtk-quit', gtk.ToolButton] 537 538 __autoStockItems[AGO_BUTTON_ABOUT] = ['gtk-about', gtk.Button] 539 __autoStockItems[AGO_MENU_ITEM_ABOUT] = ['gtk-about', gtk.MenuItem] 540 __autoStockItems[AGO_TOOL_BUTTON_ABOUT] = ['gtk-about', gtk.ToolButton] 541 542 cellText = gtk.CellRendererText() 543 cellPixbuf = gtk.CellRendererPixbuf() 544 cellToggle = gtk.CellRendererToggle() 545 546 # FIXME 547 # WARNING 548 # autorun default value changed from False to True
549 - def __init__(self, glade=None, root=None, autorun=True, autoinit=None, 550 autoinitSplit=':', autodump='text'):
551 """ 552 Constructor 553 554 Constructs the AutoGlade object based on the arguments passed. 555 556 @param glade: The glade filename, defaults to the name of the class. 557 Default C{None} 558 @type glade: str 559 560 @param root: The root widget name. Default C{None}. 561 @type root: str 562 563 @param autorun: Will autoglade auto run the GUI ? 564 @type autorun: boolean 565 566 @param autoinit: Autoinit initialization string 567 @type autoinit: str 568 569 @param autodump: Autodump type output format (i.e.: text, shell) 570 @type autodump: str 571 """ 572 573 debug("AutoGlade::__init__(glade=%s, root=%s, autorun=%s, autoinit=%s, autodump=%s)" % (glade, root, autorun, autoinit, autodump)) 574 575 cn = self.__class__.__name__ 576 if not glade : 577 if cn != 'AutoGlade': 578 glade = cn + '.glade' 579 #else: 580 # raise RuntimeError('Parameter glade is not set and no class name to obtain galde file.') 581 582 debug('Should open %s' % glade) 583 debug('\tworking directory: %s' % os.getcwdu()) 584 585 self.__glade = glade 586 # FIXME 587 # perhaps the program name should come from somewhere 588 # an extra argument for programs 589 # the name of the main widget for autorun 590 self.__programName = cn 591 self.__autoDump = autodump 592 self.__autoDumpMap = { 593 "text": self.autoDumpText, 594 "shell": self.autoDumpShell, 595 } 596 597 if self.__glade: 598 self.__dom = minidom.parse(self.__glade) 599 else: 600 self.__dom = minidom.parseString(EMPTY_GLADE) 601 self.__gladeInterface = self.__dom.documentElement 602 603 try: 604 self.__gconf = gconf.client_get_default() 605 except NameError: 606 self.__gconf = None 607 608 self.abbreviations() 609 610 if autorun: 611 try: 612 import gnome 613 614 properties = {gnome.PARAM_APP_DATADIR : '/usr/share'} 615 # FIXME 616 # perhaps, gnome.program_init should be invoked with the 617 # main top level widget (__mainTopLevelWidget) name as its 618 # first arg 619 # FIXME 620 # version is constant 621 gnome.program_init(self.__programName, 'version', 622 properties=properties) 623 except: 624 pass 625 626 if root: 627 self.__topLevelWidgetNames = [root] 628 else: 629 self.__getTopLevelWidgetNames() 630 631 self.__getTopLevelWidgets() 632 self.__mapAutoInvokeWidgetNames() 633 self.__getSignalHandlers() 634 self.__getStockItems() 635 self.__fixComboBoxNotShowingActiveItem() 636 637 self.__autoConnect() 638 639 self.__autoinitSplit = autoinitSplit 640 641 exitval = 0 642 # FIXME 643 # the try except block here is to support methods that don't return 644 # an integer value 645 try: 646 exitval = self.autoInit(autoinit) 647 except Exception, ex: 648 print >>sys.stderr, "Exception: ", ex 649 print >>sys.stderr, sys.exc_info()[0] 650 print >>sys.stderr, sys.exc_info()[1] 651 print >>sys.stderr, sys.exc_info()[2] 652 print >>sys.stderr, ''.join(traceback.format_exception( 653 *sys.exc_info())[-2:]).strip().replace('\n',': ') 654 except: 655 print >>sys.stderr, "Unexpected error in autoInit:", \ 656 sys.exc_info()[0] 657 pass 658 659 if autorun: 660 debug("autorun") 661 # now exitval holds the return value of self.autoInit, which 662 # was called before. See comments in autoInit 663 #exitval = 0 664 665 # FIXME 666 # TEST ONLY 667 # this function, should be added in some way in autoinit 668 # the name of the progress bar should be specified somewhere 669 # maybe stting a class attribute in autoinit 670 #self.__timerId = gobject.timeout_add(1000, self.autoProgressBar) 671 672 resp = self.autoRun() 673 debug("autorun resp=%s" % resp) 674 if resp: 675 debug("autorun exitval=%s" % exitval) 676 if resp == gtk.RESPONSE_OK: 677 self.autoDumpValues() 678 else: 679 exitval = -resp 680 debug("autorun exit=%s" % exitval) 681 sys.exit(exitval)
682 683 # Provides self['name'].method()
684 - def __getitem__(self, key):
685 """ 686 __getitem__ 687 688 Provides B{self['name'].method()} access. 689 If the C{key} starts with C{on_} then the corresponding method is 690 executed instead of returning the attribute value. 691 692 @param key: The key to search 693 @type key: str 694 695 696 @return: if key starts with 'on_' returns the value of the execution 697 of B{self.key}, if key matches 698 C{AUTO_TREEVIEW_SET_CELL_RE} (or whatever 699 C{self.__reSetTreeviewCell} has compiled in) then returns an 700 instance of L{AutoTreeviewSetCell} or 701 returns the corresponding widget if exists, otherwise raise an 702 L{AutoGladeAttributeError}. 703 704 @raise AutoGladeAttributeError: If the key is not found 705 """ 706 707 cond = FN() 708 debug('__getitem__(%s, %s)' % (self.__class__.__name__, key.__str__()), cond) 709 710 if key: 711 if key[0:3] == 'on_': 712 try: 713 exec 'return self.' + key 714 except SyntaxError: 715 raise AutoGladeAttributeError("method " + key + 716 " not defined") 717 else: 718 debug("\tchecking if key=%s matches reSetTreeviewCell RE" % key, cond) 719 mo = self.__reSetTreeviewCell.match(key) 720 if mo: 721 return AutoTreeviewSetCell(mo.group(1).lower(), mo.group(2)) 722 723 w = None 724 for g in self.__topLevelWidgets.itervalues(): 725 w = g.get_widget(key) 726 if w: 727 """ 728 This was taken from Mitch Chapman's article in LJ 729 Cache the widget to speed up future lookups. If multiple 730 widgets in a hierarchy have the same name, the lookup 731 behavior is non-deterministic just as for libglade. 732 """ 733 setattr(self, key, w) 734 debug("__getitem__: FOUND", cond) 735 return w 736 737 raise AutoGladeAttributeError(key)
738 739 # Provides self.name.method()
740 - def __getattr__(self, name):
741 """ 742 __getattr__ 743 744 Provides B{self.name.method()} access 745 746 @param name: Item name 747 @type name: L{str} 748 749 @return: Returns L{__getitem__}C{(name)} 750 """ 751 752 return self.__getitem__(name)
753
754 - def __call__(args):
755 warning("__call__(%s)")
756 757 # Misc method
758 - def __getTopLevelWidgetNames(self):
759 """ 760 Get the top level widget names. 761 762 Glade XML files have not been parsed yet. 763 """ 764 765 debug("__getTopLevelWidgetNames start") 766 767 first = True 768 for element in self.__gladeInterface.getElementsByTagName('widget'): 769 debug("\twidget:%s" % element.getAttribute('id')) 770 if element.parentNode == self.__gladeInterface: 771 name = element.getAttribute('id') 772 self.__topLevelWidgetNames.append(name) 773 debug("\tappending " + name) 774 if first: 775 debug("\t\tfirst") 776 self.__mainTopLevelWidget = AutoGladeObject(self, name=name, widget=AGO_POSTPONED) 777 first = False 778 debug("\ttop level name: %s" % element.getAttribute('id')) 779 780 debug("__getTopLevelWidgetNames finish")
781
782 - def __getSignalHandlers(self):
783 for element in self.__gladeInterface.getElementsByTagName('signal'): 784 self.__signalHandlers[element.getAttribute('handler')]=1 785 debug("signal handler: %s" % element.getAttribute('handler'))
786
787 - def __getSignalHandlerFromAGOKey(self, agokey):
788 """ 789 Get signal handler from Auto Glade Object key 790 791 This method obtains the signal handler from the Auto Galde Object 792 key in camel case, assuming the handler method named is formed by 793 the last component of the camel case key, capitalized and with the 794 prefix 'auto' prepended. 795 796 Examples:: 797 agokey = menuItemOpen} 798 method = autoOpen} 799 800 agokey = toolButtonSaveas # note the lowercase in as} 801 method = autoSaveas 802 803 @param agokey: The Auto Glade Object key 804 @type agokey: str 805 806 @return: The signal handler method instance or None if there's no 807 match 808 """ 809 810 handler = None 811 m = re.compile('(.*)([A-Z][a-z0-9]*)').match(agokey) 812 if m: 813 if m.group(1) == 'dialog': 814 method = 'autoDialog' 815 else: 816 method = 'auto' + m.group(2) 817 handler = getattr(self, method) 818 819 return handler
820
821 - def __autoConnectAGO(self, agokey, handler='auto', signal='auto'):
822 try: 823 ago = self.__autoGladeObjects[agokey] 824 #print ">>>>>>> ago[%s]=%s" % (agokey, ago) 825 if not ago: 826 # None because this specific AGO key was not found in the 827 # Glade definition file (.i.e: there's no preferences button) 828 return 829 except Exception, ex: 830 # FIXME 831 print >>sys.stderr, "\n" 832 print >>sys.stderr, "*" * 70 833 print >>sys.stderr, "Unhundled exception in %s" % FN() 834 print >>sys.stderr, "Exception: ", ex 835 print >>sys.stderr, sys.exc_info()[0] 836 print >>sys.stderr, sys.exc_info()[1] 837 print >>sys.stderr, sys.exc_info()[2] 838 print >>sys.stderr, ''.join(traceback.format_exception( 839 *sys.exc_info())[-2:]).strip().replace('\n',': ') 840 print >>sys.stderr, "*" * 70 841 print >>sys.stderr, "\n" 842 return 843 except: 844 print >>sys.stderr, "\n" 845 print >>sys.stderr, "*" * 70 846 print >>sys.stderr, "Unexpected error in %s: %s" % (FN(), 847 sys.exc_info()[0]) 848 print >>sys.stderr, "*" * 70 849 print >>sys.stderr, "\n" 850 return 851 852 if handler == 'auto': 853 handler = self.__getSignalHandlerFromAGOKey(agokey) 854 855 if signal == 'auto': 856 widget = ago.getWidget() 857 if isinstance(widget, gtk.Button) or isinstance(widget, gtk.ToolButton): 858 signal = 'clicked' 859 elif isinstance(widget, gtk.MenuItem): 860 signal = 'activate' 861 elif isinstance(widget, gtk.Dialog): 862 signal = 'response' 863 else: 864 print >>sys.stderr, ">>>>>> NOT IMPLEMENTED: %s" % widget 865 signal = None 866 867 if signal: 868 ago.connectIfNotConnected(signal, handler)
869
870 - def __autoConnect(self):
871 cond = FN() 872 debug("__autoConnect start", cond) 873 874 for tlwn,tlw in self.__topLevelWidgets.iteritems(): 875 debug("\tautoConnecting top level: " + tlwn, cond) 876 tlw.signal_autoconnect(self) 877 878 # connect quit to destory of main widget 879 # there's a special case where there's no top level widget when the 880 # interface is empty 881 if self.__mainTopLevelWidget: 882 debug("\tautoConnecting 'destroy' if not connected", cond) 883 self.__mainTopLevelWidget.connectIfNotConnected('destroy', 884 self.autoQuit) 885 886 for agokey in AGOS: 887 self.__autoConnectAGO(agokey) 888 889 debug("__autoConnect finish")
890 891
892 - def __getTopLevelWidgets(self):
893 """ 894 Get the top level widgets parsing the glade XML file. 895 The widget trees (one for every top level widget) are also created 896 in this operation. 897 """ 898 899 debug("__getTopLevelWidgets start") 900 901 for tl in self.__topLevelWidgetNames: 902 debug('toplevel=%s' % tl) 903 w = gtk.glade.XML(self.__glade, tl) 904 self.__topLevelWidgets[tl] = w 905 debug("\tw=%s tlw=%s" % (w, self.__topLevelWidgets)) 906 907 debug("__getTopLevelWidgets finish")
908
909 - def __mapAutoInvokeWidgetNames(self):
910 """ 911 Map the autoInvoke names (widget:auto:method) to its plain form 912 (widget). 913 Invoke 'auto:init' method if present. 914 Connect 'auto:sensitize' signals. 915 Connect signal for menu items (and tool buttons ?) if not connected 916 """ 917 918 debug("__mapAutoInvokeWidgetNames() start") 919 920 # in normal situations initMethod is initialized below in this 921 # method, so this copes with some missing cases 922 initMethod = None 923 924 #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 925 # FIXME 926 # this should involve root (top level widgets) 927 #!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 928 for element in self.__gladeInterface.getElementsByTagName('widget'): 929 debug("\twidget:%s" % (element.getAttribute('id'))) 930 name = element.getAttribute('id') 931 widgetClass = element.getAttribute('class') 932 m = self.__reAutoInvoke.match(name) 933 if m: 934 # this is the case of one widget named as the autoInvoke 935 # convention widget:auto:method 936 # because of this name it cannot be invoked as self.name 937 # so a workaround should be used 938 # another alternative would be to use a '_' instead of ':' 939 940 # get the widget 941 widget = self.__getitem__(name) 942 943 # n is the 'real' widget name, the first part of the mapped 944 # name widget:auto:method 945 n = m.group(AUTO_INVOKE_WIDGET) 946 setattr(self, n, self.__getitem__(name)) 947 method = m.group(AUTO_INVOKE_METHOD) 948 args = m.group(AUTO_INVOKE_ARGS) 949 debug("\tmethod:%s" % method) 950 # special methods handling 951 if method == 'init': 952 val = None 953 if args == 'env': 954 # widgetname:auto:init:env will initialize the widget 955 # value from environment variable 'widgetname' 956 # if 'widgetname' does not exist with an empty value. 957 try: 958 val = os.environ[n] 959 except KeyError: 960 debug("**** looking for '%s' in environ, but not found ****" % n) 961 # FIXME 962 # there's a special case handled in the if widgetClass 963 # section below, because for example for radio buttons 964 # we have to strip the last number to find the variable 965 # name 966 val = None 967 968 # FIXME 969 # this is the same as in 'gconf' 970 if widgetClass in ['GtkFileChooser', 971 'GtkFileChooserButton']: 972 initMethod = self[name].set_filename 973 elif widgetClass in ['GtkHScale', 'GtkVScale']: 974 initMethod = self[name].set_value 975 # thanks to python for this dynamic typing 976 val = float(val and val or 0) 977 elif widgetClass in ['GtkLabel']: 978 # FIXME 979 # overwrites previous markup, which could not be 980 # the intention 981 initMethod = self[name].set_markup 982 elif widgetClass in ['GtkRadioButton']: 983 initMethod = self[name].set_active 984 # this is also close to line 1650 985 debug("**** name=%s n=%s val=%s ****" % (name, n, val)) 986 nnn = re.match('(.+\D)\d+$', n).group(1) 987 try: 988 debug("**** &&& name=%s val=%s nnn=%s label=%s ****" % (name, val, nnn, self[name].get_label())) 989 debug("**** env[%s]=%s ****" % (nnn, os.environ[nnn])) 990 val = (self[name].get_label() == os.environ[nnn]) 991 except KeyError: 992 # not in environment, use first radio as default 993 # we don't know if there's more than one 994 val = 1 995 996 debug("**** name=%s val=%s nnn=%s label=%s ****" % (name, val, nnn, self[name].get_label())) 997 else: 998 debug("**** No initMethod defined to initialize from environment for this widget class: %s (%s) ****" % (widgetClass, type(self[name]))) 999 1000 elif args == 'gconf': 1001 baseKey = '/apps/%s/autoglade/init/%s' % (self.__topLevelWidgetNames[0], n) 1002 if self.DEBUG: 1003 print >>sys.stderr, '@' * 50 1004 print >>sys.stderr, '@' + ' should initialize the widget %s using method %s with args %s' % (n, method, args) 1005 print >>sys.stderr, '@' + ' gconf baseKey: %s' % baseKey 1006 1007 key = baseKey + '/' 1008 # FIXME 1009 # this is the same as in 'env' 1010 if widgetClass in ['GtkFileChooser', 1011 'GtkFileChooserButton']: 1012 key += 'filename' 1013 initMethod = self[name].set_filename 1014 val = self.__gconf.get_string(key) 1015 1016 #if val and initMethod: 1017 # perhaps I want to set val=False or val=None 1018 if initMethod: 1019 if self.DEBUG: 1020 print >>sys.stderr, "**** initMethod=%s val=%s ****" % (initMethod, val) 1021 initMethod(val) 1022 elif method in ['show', 'sensitize' ]: 1023 if self.DEBUG: 1024 print >>sys.stderr, MAGENTA + "show/sensitize: widget%s %s method=%s args=%s" % (widget, widgetClass, method, args) + SGR0 1025 if args: 1026 h = getattr(self, 'on_auto' + method) 1027 if isinstance(widget, gtk.ToggleButton) or isinstance(widget, gtk.CheckMenuItem): 1028 for targetWidget in args.split(AUTO_DELIMITER): 1029 if self.DEBUG: 1030 print >>sys.stderr, 'Connecting' 1031 widget.connect('toggled', h, 1032 self.__getitem__(targetWidget)) 1033 elif method == 'dump': 1034 self.__dump[n] = args 1035 else: 1036 ############################################################ 1037 # FIXME 1038 # This is not working as intended becasue 1039 # connectIfNotConnected 1040 # in next statement is called BEFORE __autoConnect is called 1041 # so no signals are connected yet 1042 # It must be tested what happens if the call to this method 1043 # is positioned after __autoConnect 1044 ############################################################ 1045 # FIXME 1046 # Connect the signal for menu items. 1047 # Don't know what to do with other classes yet 1048 ############################################################ 1049 if widgetClass in ['GtkMenuItem', 'GtkImageMenuItem', 1050 'GtkCheckMenuItem']: 1051 AutoGladeObject(self, name=name, widget=widget).connectIfNotConnected('activate', self.on_automenuitem_activate, args) 1052 # FIXME 1053 # Analyze the case for GtkTookButton, should it connect 1054 # on_automenuitem_activate or on_autobutton_clicked ? 1055 elif widgetClass == 'GtkToolButton': 1056 AutoGladeObject(self, name=name, widget=widget).connectIfNotConnected('clicked', self.on_automenuitem_activate, args) 1057 # FIXME 1058 # When is more convenient to use gtk classes like here 1059 # gtk.Button or string class names 'GtkButton' ? 1060 # Using gtk classes we have inheritance. 1061 elif isinstance(widget, gtk.Button): 1062 if self.DEBUG: 1063 print >>sys.stderr, "Button %s" % name 1064 print >>sys.stderr, "args %s" % args 1065 print >>sys.stderr, "type %s" % args.__class__.__name__ 1066 # FIXME 1067 # perhaps this should be applied to every other case 1068 if isinstance(args, str) or isinstance(args, unicode): 1069 if self.DEBUG: 1070 print >>sys.stderr, "Splitting args=%s" % args 1071 args = tuple(args.split(AUTO_DELIMITER)) 1072 if self.DEBUG: 1073 print >>sys.stderr, "args=%s" % args 1074 AutoGladeObject(self, name=name, widget=widget).connectIfNotConnected('clicked', self.on_autobutton_clicked, args)
1075
1077 """ 1078 Fix a problem found with Combo Box widgets. 1079 1080 Is this a libglade bug ? 1081 """ 1082 1083 warning("FIXING COMBOBOX PROBLEM") 1084 for element in self.__gladeInterface.getElementsByTagName('widget'): 1085 if element.getAttribute('class') == 'GtkComboBox': 1086 name = element.getAttribute('id') 1087 a = -1 1088 for property in element.getElementsByTagName('property'): 1089 if property.getAttribute('name') == 'active': 1090 for node in property.childNodes: 1091 if node.nodeType == node.TEXT_NODE: 1092 a = int(node.data) 1093 # get the widget 1094 widget = self.__getitem__(name) 1095 if widget.get_active() == -1: 1096 if a != -1: 1097 widget.set_active(a)
1098
1099 - def __getAboutDialog(self):
1100 """ 1101 Get the about dialog from the internal list of top level widgets 1102 and set the L{AutoGladeObject} accordingly. 1103 """ 1104 1105 for n,g in self.__topLevelWidgets.iteritems(): 1106 w = self.__getattr__(n) 1107 if isinstance(w, gtk.AboutDialog): 1108 """ 1109 In the special case of gtk.AboutDialog, get_name() doesn't 1110 return the widget name but the application name set by gnome 1111 application. 1112 What the developers were thinking ? 1113 So, to compensate from this unusual an not orthogonal behavior 1114 next AutoGladeObject creation includes the name too. 1115 """ 1116 self.__autoGladeObjects[AGO_DIALOG_ABOUT] = \ 1117 AutoGladeObject(self, widget=w, name=n) 1118 return 1119 1120 warning("About dialog not found")
1121
1122 - def __getPreferencesDialog(self):
1123 """ 1124 Get the preferences dialog from the internal list of top level 1125 widgets and set the L{AutoGladeObject} accordingly. 1126 1127 To find it, widget name is matched against 'preferences' ignoring 1128 case. 1129 """ 1130 1131 for n,g in self.__topLevelWidgets.iteritems(): 1132 w = self.__getattr__(n) 1133 if isinstance(w, gtk.Dialog) and \ 1134 re.search('preferences', n, re.IGNORECASE): 1135 debug("Setting preferences dialog to '%s': %s" % (n, w)) 1136 self.__autoGladeObjects[AGO_DIALOG_PREFERENCES] = \ 1137 AutoGladeObject(self, widget=w, name=n) 1138 return 1139 1140 warning("Preferences dialog not found")
1141
1142 - def __getStockItem(self, agokey, stock, gtkClass=gtk.Widget):
1143 try: 1144 self.__autoGladeObjects[agokey] = self.__findStockItem(stock, gtkClass) 1145 except AutoGladeItemNotFoundException: 1146 warning("Stock item not found: ago=%s stock=%s gtkClass=%s" % ( 1147 agokey, stock, gtkClass)) 1148 self.__autoGladeObjects[agokey] = None
1149
1150 - def __getStockItems(self):
1151 """ 1152 Get stock items. 1153 """ 1154 1155 # special cases 1156 self.__getAboutDialog() 1157 self.__getPreferencesDialog() 1158 1159 # generic cases 1160 for asi in self.__autoStockItems: 1161 self.__getStockItem(asi, self.__autoStockItems[asi][ASI_STOCK], 1162 self.__autoStockItems[asi][ASI_GTKCLASS])
1163
1164 - def __findStockItem(self, stock, gtkClass=gtk.Widget):
1165 """ 1166 Find a stock item in the elements tree. 1167 1168 WARNING: Right now only find the first widget if more than one 1169 satisfies the conditions 1170 1171 @param stock: The stock item to find 1172 @type stock: str 1173 """ 1174 1175 cond = FN() 1176 debug("%s(%s, %s) start" % (cond, stock, gtkClass), cond) 1177 1178 # a bit too much: all the properties in the glade file ! 1179 for element in self.__gladeInterface.getElementsByTagName('property'): 1180 if element.getAttribute('name') == 'stock_id' and \ 1181 element.childNodes[0].nodeValue == stock: 1182 debug("%s: value=%s" % (cond, element.childNodes[0].nodeValue), 1183 cond) 1184 parent = element.parentNode 1185 name = parent.getAttribute('id') 1186 widget = self.__getattr__(name) 1187 debug("%s: testing if %s (%s) is an instance of %s" % (cond, 1188 name, widget, gtkClass), cond) 1189 if isinstance(widget, gtkClass): 1190 debug("%s: FOUND", cond) 1191 return AutoGladeObject(self, name=name, element=element, 1192 widget=widget) 1193 elif element.getAttribute('name') == 'label': 1194 for node in element.childNodes: 1195 if node.nodeType == node.TEXT_NODE: 1196 if node.data == stock: 1197 parent = element.parentNode 1198 debug("%s: parent = %s" % (cond, parent), cond) 1199 if parent.tagName != 'widget': 1200 raise RuntimeError('Parent is not widget') 1201 name = parent.getAttribute('id') 1202 element = parent 1203 widget = self.__getattr__(name) 1204 if isinstance(widget, gtkClass): 1205 debug("%s: FOUND %s" % (cond, name), cond) 1206 return AutoGladeObject(self, name=name, 1207 element=element, widget=widget) 1208 raise AutoGladeItemNotFoundException("Stock item %s not found" % stock)
1209 1210 # Getters and setters
1211 - def getGladeInterface(self):
1212 return self.__gladeInterface
1213
1214 - def getDom(self):
1215 return self.__dom
1216
1217 - def getTopLevelWidgets(self):
1218 return self.__topLevelWidgets
1219
1220 - def getSignalHandlers(self):
1221 return self.__signalHandlers.keys()
1222
1223 - def getWidgetNames(self, widgetClassFilter=None, 1224 widgetCanonicalNames=False):
1225 """ 1226 List the widget names possible filtered. 1227 1228 This method was an idea suggested by Charles Edward Pax and 1229 Christopher Pax from Gladex project (http://www.openphysics.org/~gladex/) 1230 """ 1231 1232 wn = [] 1233 wcf = None 1234 1235 if widgetClassFilter: 1236 if isinstance(widgetClassFilter, str): 1237 if widgetClassFilter == 'input': 1238 wcf = INPUT_CLASS 1239 else: 1240 wcf = [ widgetClassFilter ] 1241 elif isinstance(widgetClassFilter, list): 1242 wcf = widgetClassFilter 1243 else: 1244 raise TypeError('Invalid widget class filter') 1245 1246 for element in self.__gladeInterface.getElementsByTagName('widget'): 1247 if wcf: 1248 widgetClass = element.getAttribute('class') 1249 if not widgetClass in wcf: 1250 continue 1251 name = element.getAttribute('id') 1252 if widgetCanonicalNames: 1253 m = self.__reAutoInvoke.match(name) 1254 if m: 1255 name = m.group(AUTO_INVOKE_WIDGET) 1256 wn.append(name) 1257 return wn
1258 1259 # Methods
1260 - def autoInit(self, autoinit=None):
1261 """ 1262 Default autoInit method, can be overriden by children. 1263 1264 @param autoinit: The string containing autoinit commands 1265 @type autoinit: L{str} 1266 """ 1267 1268 retval = 0 1269 1270 if autoinit: 1271 if self.DEBUG: 1272 print >>sys.stderr, '$$$$ executing: self.' + autoinit 1273 # FIXME 1274 # here ':' is used as a separator between autoinit statements 1275 # but trere would be a possibility that something is intended 1276 # with a widget that conains ':' in its name 1277 if self.__autoinitSplit != 'NONE': 1278 for init in autoinit.split(self.__autoinitSplit): 1279 # FIXME 1280 # this is a little tricky. To obtain the return value of 1281 # multiple autoinits sequences we are substracting the values 1282 # because return values are mostly negatives from gtk.RESPONSE 1283 # values. This is mainly to obtain the response from an 1284 # autoinit question dialog, for example. 1285 # FIXME 1286 # If autoinit calls a method that has a different return type 1287 # it its used in this operation and raises an exception 1288 exec 'retval -= self.' + init 1289 else: 1290 exec 'retval -= self.' + autoinit 1291 1292 return retval
1293 1294 # Default handlers
1295 - def on_cancelbutton_clicked(self, widget):
1296 """ 1297 Default handler for B{Cancel} buttons C{clicked} signal. 1298 1299 @param widget: The widget receiving the signal 1300 @type widget: L{gtk.Widget} 1301 """ 1302 1303 if self.DEBUG: 1304 print >>sys.stderr, BLUE + "on_cancelbutton_clicked" + SGR0 1305 gtk.main_quit()
1306
1307 - def on_autosensitize(self, widget, targetWidget):
1308 """ 1309 Toggle the 'sensitive' property on a target widget 1310 """ 1311 1312 # Please !!!! 1313 # Tell me why there's no get_sensitive !!!! 1314 #s = targetWidget.get_sensitive() 1315 s = targetWidget.get_property('sensitive') 1316 targetWidget.set_sensitive(not s)
1317
1318 - def on_autoshow(self, widget, targetWidget):
1319 """ 1320 Toggle the 'visible' property on a target widget 1321 """ 1322 1323 cond = FN() 1324 debug("%s(%s, %s)" % (cond, widget, targetWidget), cond) 1325 1326 if targetWidget.get_property('visible'): 1327 targetWidget.hide() 1328 else: 1329 targetWidget.show() 1330 1331 # FIXME 1332 # This is perhaps not true, but it's a good assumption, 1333 # if widgets were showed or hidden it's a good opportunity to 1334 # resize 1335 # Actually it seems to be false, when resized the window returns 1336 # to its original size, not its current size if it was resized 1337 self.__mainTopLevelWidget.getWidget().resize(1,1)
1338
1339 - def on_automenuitem_activate(self, widget, *args):
1340 """ 1341 Default handler for menu items C{activate} signal 1342 1343 This is a handler method intended to be a simple menu item handler. 1344 The idea is to simplify handling menu items usually connected to 1345 dialog boxes. 1346 activate signal on the menu item object must point to this function 1347 and user data parameter of this signal must point to the object to 1348 call. 1349 In the case of a dialog, user data parameter is the dialog object 1350 which this method will run. 1351 1352 This can also be used (and it's used by autoInvoke) in 1353 L{gtk.ToolButton} objects. 1354 1355 @param widget: The widget receiving the signal 1356 @type widget: L{gtk.Widget} 1357 """ 1358 1359 cond = FN() 1360 debug("%s(%s, %s)" % (cond, widget, args), cond) 1361 1362 if isinstance(widget, gtk.MenuItem): 1363 self.autoInvoke(widget) 1364 elif isinstance(widget, gtk.ToolButton): 1365 self.autoInvoke(widget) 1366 elif isinstance(widget, gtk.Dialog): 1367 widget.run() 1368 else: 1369 warning("Not implemented yet: %s" % widget)
1370
1371 - def on_autobutton_clicked(self, widget, *args):
1372 """ 1373 on_autobutton_clicked 1374 1375 @param widget: The widget receiving the signal 1376 @type widget: L{gtk.Widget} 1377 """ 1378 1379 cond = FN() 1380 debug("%s(%s, %s)" % (cond, widget, args), cond) 1381 1382 if isinstance(widget, gtk.Button): 1383 if args: 1384 self.autoInvoke(widget, args[0]) 1385 else: 1386 self.autoInvoke(widget) 1387 elif isinstance(widget, gtk.ToolButton): 1388 self.autoInvoke(widget) 1389 elif isinstance(widget, gtk.Dialog): 1390 widget.run() 1391 else: 1392 warning("%s: Not implemented yet: %s" % (cond, widget))
1393
1394 - def on_autotoolbutton_clicked(self, widget):
1395 """ 1396 on_autotoolbutton_clicked 1397 1398 @param widget: The widget receiving the signal 1399 @type widget: L{gtk.Widget} 1400 """ 1401 1402 return self.on_autobutton_clicked(widget)
1403
1404 - def autoInvoke(self, widget, *args):
1405 """ 1406 Auto invoke the method codified in widget name 1407 1408 Auto invoke the method codified and described in the Glade widget name. 1409 The pattern string is described by the regular expression in X{self.__reAutoInvoke} 1410 which typically is '(.*):auto:(.*)' or everything before ':auto:' is the 1411 standard widget name, and everything after is the method name or widget (in 1412 the case of L{gtk.Dialog}) to be invoked. 1413 1414 The methods C{name}Pre, C{name} and C{name}Post are invoked in order (if exist) 1415 and if and only if the predecesor returns C{True}. 1416 1417 @param widget: The widget receiving the signal 1418 @type widget: L{gtk.Widget} 1419 """ 1420 1421 cond = FN() 1422 debug("%s start" % cond, cond) 1423 1424 name = widget.get_name() 1425 m = self.__reAutoInvoke.match(name) 1426 if m: 1427 f = m.group(AUTO_INVOKE_METHOD) 1428 debug("%s: should invoke method '%s' with args %s" % (cond, f, 1429 args), cond) 1430 1431 # Pre 1432 pre = True 1433 try: 1434 pre = getattr(self, f + 'Pre')(args) 1435 except AutoGladeAttributeError, ex: 1436 if self.DEBUG: 1437 print >>sys.stderr, 50*'@' 1438 print >>sys.stderr, 'Not raising exception because should correspond to a' \ 1439 'not yet implemented method self.' + f + 'Pre.' 1440 print >>sys.stderr, f + "Pre() undefined. ex=%s pre=%s" % (ex, pre) 1441 print >>sys.stderr, ex.__str__() 1442 print >>sys.stderr, 50*'@' 1443 # FIXME !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 1444 #except FuckingAttributeError, ex: 1445 # # FIXME 1446 # # For some reason self. is removed from the method name when 1447 # # the exception is raised 1448 # if 'self.' + ex.__str__() == method: 1449 # if self.DEBUG: 1450 # print >>sys.stderr, 50*'@' 1451 # print >>sys.stderr, 'Not raising exception because should correspond to a' \ 1452 # 'not yet implemented method self.' + method 1453 # print >>sys.stderr, f + "Pre() undefined. ex=%s pre=%s" % (ex, pre) 1454 # print >>sys.stderr, ex.__str__() 1455 # print >>sys.stderr, 50*'@' 1456 # else: 1457 # if self.DEBUG: 1458 # print >>sys.stderr, 50*'@' 1459 # print >>sys.stderr, 'Raisin exception' 1460 # print >>sys.stderr, 50*'@' 1461 # raise ex 1462 except NameError, ex: 1463 if self.DEBUG: 1464 print >>sys.stderr, 50*'@' 1465 print >>sys.stderr, 'Not raising exception because should correspond to a' \ 1466 'not yet implemented method self.' + method 1467 print >>sys.stderr, f + "Pre() undefined. ex=%s pre=%s" % (ex, pre) 1468 print >>sys.stderr, ex.__str__() 1469 print >>sys.stderr, 50*'@' 1470 except Exception, ex: 1471 raise ex 1472 1473 post = False 1474 # Method 1475 if pre: 1476 try: 1477 # try to find 'f' as an attribute 1478 obj = getattr(self, f) 1479 debug("%s: obj=%s class=%s" % (cond, obj, 1480 obj.__class__.__name__), cond) 1481 1482 if callable(obj): 1483 post = obj(args) 1484 elif isinstance(obj, gtk.Dialog): 1485 # FIXME: 1486 # I'm not sure that post should be assigned here and that 1487 # it receives the correct value after assignement 1488 resp = obj.run() 1489 debug("%s: resp=%s" % (cond, resp), cond) 1490 # FIXME: 1491 # Not sure about this hide 1492 obj.hide() 1493 #except: 1494 #try: 1495 # # if 'f' was not an attribute, then call it 1496 # # FIXME: 1497 # # perhpas self. should not be imposed 1498 # #post = eval('self.' + f + '(%s)' % args) 1499 # #method = self.__getattr__(f) 1500 # method = getattr(self, f) 1501 # post = method(args) 1502 #except AutoGladeAttributeError, ex: 1503 # raise RuntimeError("Method '%s' not implemented yet or attribute not found exception inside this method: %s" % (f, ex)) 1504 except AutoGladeAttributeError, ex: 1505 raise RuntimeError("Method '%s' not implemented yet or 'attribute not found exception' inside this method: %s" % (f, ex)) 1506 except Exception, ex: 1507 raise ex 1508 1509 # Post 1510 if post: 1511 try: 1512 getattr(self, f + 'Post')(args) 1513 except: 1514 pass 1515 else: 1516 """ 1517 Sometimes C{aboutdialog} is not added as C{user data} parameter to 1518 the C{on_automenuitem_activate} handler, so here is a fallback. 1519 Is this a libglade or gtk.Glade bug ? 1520 """ 1521 debug("%s: autoInvoke: NO MATCH" % cond, cond) 1522 if len(args) >= 1 and isinstance(args[0], gtk.Dialog): 1523 # FIXME 1524 # realy goes here ? 1525 debug("%s: fallback running dialog %s (%s)"% (cond, name, 1526 args[0])) 1527 return args[0].run()
1528
1529 - def on_autodialog_response(self, widget, response, *args):
1530 """ 1531 Default handler for L{gtk.Dialog} C{response} signal 1532 1533 This is a handler method intended to be a simple dialog handler. 1534 response signal of widget must be connected to this method and the 1535 user data parameter must be left untouched (as of Glade 3.0 and 1536 libglade 2). 1537 1538 Note: 1539 Perhaps this method should set a Singleton object value to the response 1540 received 1541 1542 gtk response values 1543 =================== 1544 These are the response values:: 1545 1546 gtk.RESPONSE_NONE=-1 1547 gtk.RESPONSE_REJECT=-2 1548 gtk.RESPONSE_ACCEPT=-3 1549 gtk.RESPONSE_DELETE_EVENT=-4 1550 gtk.RESPONSE_OK=-5 1551 gtk.RESPONSE_CANCEL=-6 1552 gtk.RESPONSE_CLOSE=-7 1553 gtk.RESPONSE_YES=-8 1554 gtk.RESPONSE_NO=-9 1555 gtk.RESPONSE_APPLY=-10 1556 gtk.RESPONSE_HELP=-11 1557 1558 @param widget: The widget receiving the signal 1559 @type widget: L{gtk.Widget} 1560 1561 @param response: The dialog response (i.e.: button pressed) 1562 @type response: int 1563 """ 1564 1565 cond = FN() 1566 debug("%s(%s, %s, %s)" % (cond, widget, response, args), cond) 1567 1568 if response in [gtk.RESPONSE_CLOSE, gtk.RESPONSE_OK, 1569 gtk.RESPONSE_CANCEL, 1570 gtk.RESPONSE_ACCEPT, gtk.RESPONSE_REJECT, 1571 gtk.RESPONSE_DELETE_EVENT, gtk.RESPONSE_NONE]: 1572 debug('\thiding widget=%s' % widget) 1573 widget.hide()
1574
1575 - def on_autobuttonexpandall_clicked(self, widget):
1576 cond = FN() 1577 debug('%s' % cond, cond) 1578 widget.expand_all()
1579
1580 - def on_autobuttoncollapseall_clicked(self, widget):
1581 cond = FN() 1582 debug('%s' % cond, cond) 1583 widget.collapse_all()
1584
1585 - def autoRun(self):
1586 """ 1587 auto run the graphical user interface 1588 1589 Runs the graphical user interface automatically. 1590 There ase some special cases contempled. 1591 1592 1. If there's no L{__mainTopLevelWidget} then it does nothing 1593 1594 2. If the L{__mainTopLevelWidget} is a L{gtk.Dialog} then the 1595 dialog box is run. Loops forever until one of the values of a 1596 valid response is received, then return this value 1597 1598 3. if the L{__mainTopLevelWidget} is not a L{gtk.Dialog} then the 1599 main GTK loop is entered 1600 """ 1601 1602 if self.__mainTopLevelWidget: 1603 if self.DEBUG: 1604 print >>sys.stderr, "main widget: %s" % \ 1605 self.__mainTopLevelWidget.getName() 1606 mw = self.__mainTopLevelWidget.getWidget() 1607 mw.show() 1608 1609 if isinstance(mw, gtk.Dialog): 1610 if self.DEBUG: 1611 print >>sys.stderr, "It's a dialog instance, running it until one of the valid responses is received..." 1612 while True: 1613 # we could have been done this if gtk.Dialog implements 1614 # __call__(self): 1615 # self.run() 1616 #resp = mw() 1617 resp = mw.run() 1618 if self.DEBUG: 1619 print >>sys.stderr, "\tresp=", resp 1620 if resp in [gtk.RESPONSE_CLOSE, gtk.RESPONSE_OK, 1621 gtk.RESPONSE_CANCEL, 1622 gtk.RESPONSE_DELETE_EVENT, gtk.RESPONSE_NONE]: 1623 return resp 1624 elif resp == gtk.RESPONSE_HELP: 1625 self.autoHelp() 1626 else: 1627 gtk.main()
1628
1629 - def autoErrorDialog(self, ex):
1630 m = gtk.MessageDialog(type=gtk.MESSAGE_ERROR, 1631 buttons=gtk.BUTTONS_OK, message_format=None) 1632 m.set_title("Error") 1633 m.set_markup(ex.__str__()) 1634 m.run() 1635 m.hide()
1636
1637 - def autoWarningDialog(self, msg, message_format=None):
1638 w = gtk.MessageDialog(type=gtk.MESSAGE_WARNING, 1639 buttons=gtk.BUTTONS_OK, message_format=message_format) 1640 w.set_title("Warning") 1641 w.set_markup(msg) 1642 w.run() 1643 w.hide()
1644
1645 - def autoQuestionDialog(self, msg, buttons=gtk.BUTTONS_YES_NO):
1646 if self.DEBUG: 1647 print >>sys.stderr, "autoQuestionDialog(%s)" % msg 1648 q = gtk.MessageDialog(type=gtk.MESSAGE_QUESTION, 1649 buttons=buttons, message_format=None) 1650 q.set_title("Question") 1651 q.set_markup(msg) 1652 resp = q.run() 1653 if self.DEBUG: 1654 print >>sys.stderr, "\tresp=%s" % resp 1655 q.hide() 1656 return resp
1657
1658 - def autoInfoDialog(self, msg="No message", message_format=None):
1659 i = gtk.MessageDialog(type=gtk.MESSAGE_INFO, 1660 buttons=gtk.BUTTONS_OK, message_format=message_format) 1661 i.set_title("Info") 1662 # msg must be flattened 1663 if isinstance(msg, tuple): 1664 msg = msg[0] 1665 i.set_markup(msg) 1666 resp = i.run() 1667 if self.DEBUG: 1668 print >>sys.stderr, "**** autoInfoDialog: resp=%s" % resp 1669 i.hide() 1670 return resp
1671
1672 - def autoAddTimeout(self, msecs=1000, method=None, *args):
1673 if isinstance(method, str): 1674 method = getattr(self, method) 1675 self.__timerId = gobject.timeout_add(msecs, method, args)
1676
1677 - def autoProgressBar(self, args):
1678 if self.DEBUG: 1679 print >>sys.stderr, ">>>> autoProgressBar (BEGIN) args='%s'" % args 1680 # flatten args 1681 if not args: 1682 return False 1683 1684 name = args[0] 1685 1686 if len(args) > 1: 1687 okButton = args[1] 1688 else: 1689 okButton = None 1690 1691 if len(args) > 2: 1692 cancelButton = args[2] 1693 else: 1694 cancelButton = None 1695 1696 line = sys.stdin.readline() 1697 if not line: 1698 return False 1699 if self.DEBUG: 1700 print >>sys.stderr, "\tline='%s'" % line 1701 n = 0 1702 try: 1703 n = int(line) 1704 except: 1705 pass 1706 v = n/100.0 1707 if self.DEBUG: 1708 print >>sys.stderr, "\tupdating n=%s %s" % (n, v) 1709 self[name].set_fraction(v) 1710 self[name].set_text("%s %%" % n) 1711 if v >= 1.0: 1712 if okButton: 1713 if self.DEBUG: 1714 print >>sys.stderr, "\tsetting sensitive on %s" % (okButton) 1715 self[okButton].set_sensitive(True) 1716 if cancelButton: 1717 if self.DEBUG: 1718 print >>sys.stderr, "\tsetting sensitive on %s" % (cancelButton) 1719 self[cancelButton].set_sensitive(False) 1720 if self.DEBUG: 1721 print >>sys.stderr, ">>>> autoProgressBar (END)" 1722 return True
1723
1724 - def isInputClass(self, widgetClass):
1725 return widgetClass in INPUT_CLASS
1726
1727 - def autoDumpText(self, var, val):
1728 print "%s:%s" % (var, val)
1729
1730 - def autoDumpShell(self, var, val):
1731 if var != 'autoargs': 1732 if self.__autoArgs: 1733 self.__autoArgs += ' ' 1734 self.__autoArgs += '$' + var 1735 1736 # FIXME 1737 # special charcters in var should be mapped 1738 # single quotes in val should be mapped or escaped 1739 print "%s='%s'" % (var, val)
1740
1741 - def autoDumpValues(self):
1742 if self.DEBUG: 1743 print >>sys.stderr, "autoDumpValues" 1744 1745 # FIXME 1746 # this may not be needed 1747 self.__autoArgs = '' 1748 1749 for element in self.__gladeInterface.getElementsByTagName('widget'): 1750 widgetClass = element.getAttribute('class') 1751 if self.isInputClass(widgetClass): 1752 name = element.getAttribute('id') 1753 m = self.__reAutoInvoke.match(name) 1754 if m: 1755 # this is the case of one widget named as the autoInvoke 1756 # convention widget:auto:method 1757 # because of this name it cannot be invoked as self.name 1758 # so a workaround should be used 1759 # another alternative would be to use a '_' instead of ':' 1760 1761 # n is the 'real' widget name, the first part of the mapped 1762 # name widget:auto:method 1763 n = m.group(AUTO_INVOKE_WIDGET) 1764 else: 1765 n = name 1766 if self.DEBUG: 1767 print >>sys.stderr, '%s\tshould dump %s (%s)%s' % (RED, n, name, SGR0) 1768 if widgetClass == 'GtkRadioButton': 1769 # it seems that there's no group leader, or even there's no 1770 # such concept in glade, and we don't have a way to obtain 1771 # the group leader to obtain its name and use it to 1772 # print the values (label values) 1773 # to solve this a convention is used, all of the 1774 # radiobuttons must be named name<n> and the number is 1775 # stripped when printed 1776 for rb in self[name].get_group(): 1777 if self.DEBUG: 1778 print >>sys.stderr, "group contains rb: %s %s" % ( 1779 rb.get_name(), rb.get_active()) 1780 n = rb.get_name() 1781 if n == name and rb.get_active(): 1782 if self.DEBUG: 1783 print >>sys.stderr, "rb %s is active" % n 1784 # remove the last number from widget name (group) 1785 m = self.__reAutoInvoke.match(n) 1786 if m: 1787 n = m.group(AUTO_INVOKE_WIDGET) 1788 nnn = re.match('(.+\D)\d+$', n).group(1) 1789 print >>sys.stderr, "***** n=%s" % n 1790 print >>sys.stderr, "***** nnn=%s" % nnn 1791 print >>sys.stderr, "***** name=%s" % name 1792 v = None 1793 try: 1794 v = self.__dump[n] 1795 except: 1796 v = rb.get_label().replace('_','') 1797 self.__autoDumpMap[self.__autoDump](nnn, v) 1798 # rb.get_label().replace('_','')) 1799 elif widgetClass in ['GtkCheckButton', 'GtkToggleButton']: 1800 v = self[name].get_active() 1801 d = None 1802 try: 1803 d = self.__dump[n] 1804 except: 1805 pass 1806 1807 if v: 1808 if d: 1809 v = d 1810 else: 1811 if d: 1812 v = '' 1813 1814 self.__autoDumpMap[self.__autoDump](n, v) 1815 elif widgetClass == 'GtkEntry': 1816 w = self[name] 1817 if isinstance(self[name], gtk.ComboBoxEntry): 1818 w = w.child 1819 self.__autoDumpMap[self.__autoDump](n, w.get_text()) 1820 elif widgetClass == 'GtkComboBox': 1821 self.__autoDumpMap[self.__autoDump](n, self[name].get_active_text()) 1822 elif widgetClass in ['GtkHScale','GtkVscale','GtkSpinButton']: 1823 fmt = "%d" 1824 if self[name].get_digits() > 0: 1825 fmt = "%f" 1826 self.__autoDumpMap[self.__autoDump](n, fmt % self[name].get_value()) 1827 elif widgetClass == 'GtkFileChooserButton': 1828 self.__autoDumpMap[self.__autoDump](n, self[name].get_filename()) 1829 elif widgetClass == 'GtkColorButton': 1830 color = self[name].get_color() 1831 self.__autoDumpMap[self.__autoDump](n, 1832 "#%04x%04x%04x" % (color.red, color.green, color.blue)) 1833 elif widgetClass == 'GtkFontButton': 1834 self.__autoDumpMap[self.__autoDump](n, self[name].get_font_name()) 1835 elif widgetClass == 'GtkCalendar': 1836 self.__autoDumpMap[self.__autoDump](n, self[name].get_date()) 1837 else: 1838 print >>sys.stderr, "Not implemented: %s" % widgetClass 1839 1840 self.__autoDumpMap[self.__autoDump]('autoargs', self.__autoArgs)
1841
1842 - def autoDialog(self, widget, *args):
1843 cond = FN() 1844 debug("%s: widget=%s args=%s" % (cond, widget, args), cond) 1845 self.on_autodialog_response(widget, *args)
1846
1847 - def autoHelp(self):
1848 if self.DEBUG: 1849 print >>sys.stderr, "==================================" 1850 print >>sys.stderr, "HELP" 1851 print >>sys.stderr, "==================================" 1852 try: 1853 import gnome 1854 gnome.help_display(self.__programName) 1855 except: 1856 pass
1857
1858 - def autoQuit(self, widget, *args):
1859 gtk.main_quit()
1860
1861 - def autoAbout(self, widget, *args):
1862 cond = FN() 1863 debug("%s: widget=%s args=%s" % (cond, widget, args), cond) 1864 ago = self.__autoGladeObjects[AGO_DIALOG_ABOUT] 1865 if ago: 1866 dialog = ago.getWidget() 1867 if dialog: 1868 dialog.run()
1869
1870 - def autoNew(self, widget, *args):
1871 cond = FN() 1872 debug("%s: widget=%s args=%s" % (cond, widget, args), cond) 1873 autoNewMethod = None 1874 1875 name = widget.get_name() 1876 m = self.__reAutoInvoke.match(name) 1877 if m: 1878 methodOrWidgetName = m.group(AUTO_INVOKE_METHOD) 1879 methodOrWidget = getattr(self, methodOrWidgetName) 1880 if isinstance(methodOrWidget, gtk.TextView): 1881 tv = methodOrWidget 1882 widget = tv 1883 if tv.get_buffer().get_modified(): 1884 debug("autoNew: buffer was modified, should save !", cond) 1885 # FIXME 1886 # this is copied from autoOpen (refactor!) 1887 try: 1888 filename = self.__autoProperties[methodOrWidgetName]['filename'] 1889 message_format = "Do you want to save changes to %s ?" % \ 1890 filename 1891 except: 1892 filename = None 1893 message_format = "Do you want to save changes ?" 1894 1895 dialog = gtk.MessageDialog(parent=None, 1896 type=gtk.MESSAGE_QUESTION, 1897 buttons=gtk.BUTTONS_YES_NO, 1898 message_format=message_format) 1899 resp = dialog.run() 1900 debug("%s: resp=%s" % (cond, resp), cond) 1901 dialog.hide() 1902 if resp == gtk.RESPONSE_ACCEPT: 1903 self.autoSave(tv, args) 1904 1905 debug("%s: new(%s)" % (cond, widget), cond) 1906 self.new(widget) 1907 debug("%s: deleting property filename for %s" % (cond, methodOrWidgetName), cond) 1908 try: 1909 del self.__autoProperties[methodOrWidgetName]['filename'] 1910 except Exception, ex: 1911 # if it wasn't the property not found because it was never set 1912 if ex.message != methodOrWidgetName: 1913 raise Exception(ex)
1914
1915 - def autoOpen(self, widget, *args):
1916 cond = FN() 1917 autoOpenMethod = None 1918 1919 name = widget.get_name() 1920 debug("%s: name: %s" % (cond, name), cond) 1921 m = self.__reAutoInvoke.match(name) 1922 if m: 1923 methodOrWidgetName = m.group(AUTO_INVOKE_METHOD) 1924 methodOrWidget = getattr(self, methodOrWidgetName) 1925 debug("%s: method or widget: %s" % (cond, methodOrWidget), cond) 1926 if isinstance(methodOrWidget, gtk.TextView): 1927 widget = methodOrWidget 1928 if widget.get_buffer().get_modified(): 1929 debug("%s: buffer was modified, should save !" % cond, cond) 1930 # The Buttons Type constants specify the pre-defined sets of buttons for the dialog. If none of these choices are appropriate, simply use gtk.BUTTONS_NONE then call the add_buttons() method. 1931 try: 1932 filename = self.__autoProperties[methodOrWidgetName]['filename'] 1933 message_format = "Do you want to save changes to %s ?" % \ 1934 filename 1935 except: 1936 filename = None 1937 message_format = "Do you want to save changes ?" 1938 1939 dialog = gtk.MessageDialog(parent=None, 1940 type=gtk.MESSAGE_QUESTION, 1941 buttons=gtk.BUTTONS_YES_NO, 1942 message_format=message_format) 1943 resp = dialog.run() 1944 debug("%s: resp=%s" % (cond, resp), cond) 1945 dialog.hide() 1946 if resp == gtk.RESPONSE_ACCEPT: 1947 self.autoSave(widget, args) 1948 1949 fcd = gtk.FileChooserDialog(parent=None, 1950 buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, 1951 gtk.STOCK_OPEN, gtk.RESPONSE_ACCEPT)) 1952 # FIXME 1953 # why multiple selection when then is discarded in self.open() bellow ? 1954 #fcd.set_select_multiple(True) 1955 fcd.set_select_multiple(False) 1956 resp = fcd.run() 1957 fcd.hide() 1958 if resp == gtk.RESPONSE_ACCEPT: 1959 self.open(fcd.get_filenames()[0], widget)
1960
1961 - def autoSaveas(self, widget, *args):
1962 cond = FN() 1963 autoOpenMethod = None 1964 1965 name = widget.get_name() 1966 debug("%s: name: %s" % (cond, name), cond) 1967 m = self.__reAutoInvoke.match(name) 1968 if m: 1969 methodOrWidgetName = m.group(AUTO_INVOKE_METHOD) 1970 1971 fcd = gtk.FileChooserDialog(parent=None, 1972 action=gtk.FILE_CHOOSER_ACTION_SAVE, 1973 buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, 1974 gtk.STOCK_SAVE, gtk.RESPONSE_ACCEPT)) 1975 fcd.set_select_multiple(False) 1976 try: 1977 fcd.set_filename(self.__autoProperties[methodOrWidgetName]['filename']) 1978 except: 1979 pass 1980 resp = fcd.run() 1981 fcd.hide() 1982 if resp == gtk.RESPONSE_ACCEPT: 1983 if m: 1984 methodOrWidget = getattr(self, methodOrWidgetName) 1985 debug("autoOpen: method or widget: %s" % methodOrWidget, cond) 1986 if isinstance(methodOrWidget, gtk.TextView): 1987 widget = methodOrWidget 1988 name = methodOrWidgetName 1989 1990 filename = fcd.get_filenames()[0] 1991 self.save(filename, widget) 1992 self.__autoProperties.setdefault(methodOrWidgetName, {}).update( 1993 {'filename':filename})
1994
1995 - def autoSave(self, widget, *args):
1996 cond = FN() 1997 autoOpenMethod = None 1998 1999 name = widget.get_name() 2000 m = self.__reAutoInvoke.match(name) 2001 if m: 2002 methodOrWidgetName = m.group(AUTO_INVOKE_METHOD) 2003 try: 2004 filename = self.__autoProperties[methodOrWidgetName]['filename'] 2005 except: 2006 return self.autoSaveas(widget, args) 2007 methodOrWidget = getattr(self, methodOrWidgetName) 2008 debug("%s: method or widget: %s" % (cond, methodOrWidget), cond) 2009 if isinstance(methodOrWidget, gtk.TextView): 2010 widget = methodOrWidget 2011 2012 self.save(filename, widget)
2013
2014 - def autoCopy(self, widget, *args):
2015 cond = FN() 2016 name = widget.get_name() 2017 debug("autoCopy: name: %s" % name, cond) 2018 m = self.__reAutoInvoke.match(name) 2019 if m: 2020 methodOrWidgetName = m.group(AUTO_INVOKE_METHOD) 2021 methodOrWidget = getattr(self, methodOrWidgetName) 2022 debug("autoCopy: method: %s" % methodOrWidget, cond) 2023 if isinstance(methodOrWidget, gtk.TextView): 2024 tv = methodOrWidget 2025 tv.get_buffer().copy_clipboard(gtk.Clipboard())
2026
2027 - def autoCut(self, widget, *args):
2028 cond = FN() 2029 name = widget.get_name() 2030 debug("autoCut: name: %s" % name, cond) 2031 m = self.__reAutoInvoke.match(name) 2032 if m: 2033 methodOrWidgetName = m.group(AUTO_INVOKE_METHOD) 2034 methodOrWidget = getattr(self, methodOrWidgetName) 2035 debug("autoCut: method: %s" % methodOrWidget, cond) 2036 if isinstance(methodOrWidget, gtk.TextView): 2037 tv = methodOrWidget 2038 tv.get_buffer().cut_clipboard(gtk.Clipboard(), tv.get_editable())
2039
2040 - def autoPaste(self, widget, *args):
2041 cond = FN() 2042 name = widget.get_name() 2043 debug("autoCopy: name: %s" % name, cond) 2044 m = self.__reAutoInvoke.match(name) 2045 if m: 2046 methodOrWidgetName = m.group(AUTO_INVOKE_METHOD) 2047 methodOrWidget = getattr(self, methodOrWidgetName) 2048 debug("autoCopy: method: %s" % methodOrWidget, cond) 2049 if isinstance(methodOrWidget, gtk.TextView): 2050 tv = methodOrWidget 2051 tv.get_buffer().paste_clipboard(gtk.Clipboard(), None, 2052 tv.get_editable())
2053
2054 - def autoDelete(self, widget, *args):
2055 cond = FN() 2056 name = widget.get_name() 2057 debug("autoCopy: name: %s" % name, cond) 2058 m = self.__reAutoInvoke.match(name) 2059 if m: 2060 methodOrWidgetName = m.group(AUTO_INVOKE_METHOD) 2061 methodOrWidget = getattr(self, methodOrWidgetName) 2062 debug("autoCopy: method: %s" % methodOrWidget, cond) 2063 if isinstance(methodOrWidget, gtk.TextView): 2064 tv = methodOrWidget 2065 tv.get_buffer().delete_selection(True, tv.get_editable())
2066 2067
2068 - def autoPreferences(self, widget, *args):
2069 if self.DEBUG: 2070 print >>sys.stderr, "autoPreferences: name: %s" % self.__menuItemPreferences.getName() 2071 print >>sys.stderr, "autoPreferences: ***** SEMI IMPLEMENTED *****" 2072 # do something with preferences values 2073 # FIXME 2074 # this code is copied form autoRun 2075 # needs to be refactored 2076 #resp = self.__preferencesDialog.getWidget().run() 2077 ago = self.__autoGladeObjects[AGO_DIALOG_PREFERENCES] 2078 if ago: 2079 dialog = ago.getWidget() 2080 resp = dialog.run() 2081 if self.DEBUG: 2082 print >>sys.stderr, "\tresp=", resp 2083 if resp in [gtk.RESPONSE_CLOSE, gtk.RESPONSE_OK, 2084 gtk.RESPONSE_CANCEL, 2085 gtk.RESPONSE_DELETE_EVENT, gtk.RESPONSE_NONE]: 2086 dialog.hide() 2087 return resp 2088 elif resp == gtk.RESPONSE_HELP: 2089 self.autoHelp()
2090 2091
2092 - def printval(self, *args):
2093 str = "No value" 2094 exitval = -1 2095 2096 if self.DEBUG: 2097 print "1) printval: args=%s len=%d" % (args, len(args)) 2098 2099 # msg must be flattened 2100 if isinstance(args, tuple): 2101 args = args[0] 2102 if isinstance(args, tuple): 2103 args = args[0] 2104 2105 if args and len(args) > 0: 2106 str = args[0] 2107 if args and len(args) > 1: 2108 exitval = int(args[1]) 2109 2110 # print the str 2111 print str 2112 if exitval >= 0: 2113 sys.exit(exitval)
2114
2115 - def new(self, widget):
2116 if widget: 2117 if isinstance(widget, gtk.TextView): 2118 tv = widget 2119 tv.get_buffer().set_text("") 2120 tv.get_buffer().set_modified(False)
2121
2122 - def open(self, filename, widget):
2123 cond = FN() 2124 debug("%s: open filename=%s" % (cond, filename), cond) 2125 if widget: 2126 name = widget.get_name() 2127 debug("%s: and set %s" % (cond, name), cond) 2128 if isinstance(widget, gtk.TextView): 2129 tv = widget 2130 f = open(filename) 2131 tv.get_buffer().set_text(f.read()) 2132 f.close() 2133 tv.get_buffer().set_modified(False) 2134 self.__autoProperties.setdefault(name, {}).update( 2135 {'filename':filename})
2136
2137 - def save(self, filename, widget):
2138 cond = FN() 2139 debug("%s: save filename=%s" % (cond, filename), cond) 2140 if widget: 2141 debug("%s: from %s" % (cond, widget.get_name()), cond) 2142 if isinstance(widget, gtk.TextView): 2143 tv = widget 2144 f = open(filename, "w") 2145 buf = tv.get_buffer() 2146 (start, end) = buf.get_bounds() 2147 f.write(buf.get_text(start, end)) 2148 f.close() 2149 tv.get_buffer().set_modified(False)
2150
2151 - def abbreviations(self):
2152 self.aed = self.autoErrorDialog 2153 self.aid = self.autoInfoDialog 2154 self.aqd = self.autoQuestionDialog 2155 self.awd = self.autoWarningDialog 2156 self.apb = self.autoProgressBar 2157 self.aat = self.autoAddTimeout
2158 2159 # Utility methods 2160 # not AutoGlade class members
2161 -def treeview_toogle_expansion(treeview, path):
2162 if treeview.row_expanded(path): 2163 treeview.collapse_row(path) 2164 else: 2165 treeview.expand_row(path, open_all=False)
2166 2167 2168 usage = "usage: autoglade [options] [file.glade]" 2169 2170 if __name__ == "__main__": 2171 autorun = True 2172 2173 parser = OptionParser(usage=usage, 2174 version = "%s version %s (%s)" % (prog, version, revision)) 2175 parser.add_option("-?", action="help", 2176 help="show this help message and exit") 2177 parser.add_option("-V", "--long-version", action="store_true", 2178 dest="longversion", help="Get the long version message") 2179 parser.add_option("-i", "--autoinit", type="string", 2180 dest="autoinit", 2181 help="Pass an autoinit sequence") 2182 parser.add_option("", "--autoinit-split", type="string", 2183 dest="autoinitSplit", default=':', 2184 help="Split autoinit sequence at specified delimiter (NONE to avoid splitting") 2185 parser.add_option("-d", "--autodump", type="string", 2186 dest="autodump", default='shell', 2187 help="Use the specified syntax type for autodump (shell, text)") 2188 parser.add_option("", "--get-widget-names", action="store_true", 2189 dest="getWidgetNames", default=False, 2190 help="Get the list of widget names in the glade file") 2191 parser.add_option("", "--widget-class-filter", type="string", 2192 dest="widgetClassFilter", default=None, 2193 help="Specifies a widget class filter for some operations") 2194 parser.add_option("", "--widget-canonical-names", action="store_true", 2195 dest="widgetCanonicalNames", default=False, 2196 help="Widget's canonical names instead of autoglade full names") 2197 parser.add_option("-r", "--root", type="string", 2198 dest="root", default=None, 2199 help="Name of the root widget") 2200 parser.add_option("-x", "--debug", type="string", 2201 dest="debug", help="Print debug messages", default=DEBUG) 2202 2203 (options, args) = parser.parse_args() 2204 2205 DEBUG = options.debug 2206 2207 if options.longversion: 2208 print "autoglade version %s (%s)" % (version, revision) 2209 print __license__ 2210 sys.exit(0) 2211 2212 l = len(args) 2213 if l == 1: 2214 glade = args[0] 2215 elif l == 0: 2216 glade = None 2217 if options.getWidgetNames: 2218 print >>sys.stderr, "ERROR: to obtain the list of widget names a glade file must be specified" 2219 sys.exit(1) 2220 if not options.autoinit: 2221 print >>sys.stderr, "WARNING: autoinit is empty and no glade file specified." 2222 else: 2223 print >>sys.stderr, usage 2224 sys.exit(1) 2225 2226 if DEBUG: 2227 print >>sys.stderr, "root=%s" % options.root 2228 print >>sys.stderr, "autoinit=%s" % options.autoinit 2229 print >>sys.stderr, "autonitsplit=%s" % options.autoinitSplit 2230 print >>sys.stderr, "autodump=%s" % options.autodump 2231 2232 if options.getWidgetNames: 2233 autorun = False 2234 2235 ag = AutoGlade(glade, autorun=autorun, root=options.root, 2236 autoinit=options.autoinit, autoinitSplit=options.autoinitSplit, 2237 autodump=options.autodump) 2238 2239 if not autorun: 2240 if options.getWidgetNames: 2241 for wn in ag.getWidgetNames(options.widgetClassFilter, 2242 options.widgetCanonicalNames): 2243 print wn 2244