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
    1076 -        def __fixComboBoxNotShowingActiveItem(self):
    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