Package autoglade ::
Module autoglade
|
|
1
2
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
56
57
58
59
60 AUTO_INVOKE_METHOD = 2
61 AUTO_INVOKE_HASARGS = 3
62 AUTO_INVOKE_ARGS = 4
63
64 AUTO_TREEVIEW_SET_CELL_RE = 'setTreeview(.+)Cell(\d+)'
65
66 AGO_POSTPONED = -2
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'
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
173 """
174 Get the function name from the previous (calling) frame
175 """
176
177 return sys._getframe(1).f_code.co_name
178
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
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
225 """
226 AutoGladeAttributeError is an identificable AttributeError
227 """
228
230 """
231 Constructor
232
233 @param key: key not found
234 @type key: str
235 """
236
237 AttributeError.__init__(self, key)
238
240 """
241 AutoGladeRuntimeError
242 """
243
246
247
249 """
250 AutoGladeItemNotFoundException
251 """
252
255
256
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
332
344
347
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
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
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
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
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
484
485
486
487
488
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
496 __autoGladeObjects = {}
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
547
548
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
580
581
582 debug('Should open %s' % glade)
583 debug('\tworking directory: %s' % os.getcwdu())
584
585 self.__glade = glade
586
587
588
589
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
616
617
618
619
620
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
643
644
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
662
663
664
665
666
667
668
669
670
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
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
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
756
757
781
783 for element in self.__gladeInterface.getElementsByTagName('signal'):
784 self.__signalHandlers[element.getAttribute('handler')]=1
785 debug("signal handler: %s" % element.getAttribute('handler'))
786
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
822 try:
823 ago = self.__autoGladeObjects[agokey]
824
825 if not ago:
826
827
828 return
829 except Exception, ex:
830
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
890
891
908
1075
1077 """
1078 Fix a problem found with Combo Box widgets.
1079
1080 Is this a libglade bug ?
1081 """
1082
1083 warning("FIXING COMBOBOX PROBLEM")
1084 for element in self.__gladeInterface.getElementsByTagName('widget'):
1085 if element.getAttribute('class') == 'GtkComboBox':
1086 name = element.getAttribute('id')
1087 a = -1
1088 for property in element.getElementsByTagName('property'):
1089 if property.getAttribute('name') == 'active':
1090 for node in property.childNodes:
1091 if node.nodeType == node.TEXT_NODE:
1092 a = int(node.data)
1093
1094 widget = self.__getitem__(name)
1095 if widget.get_active() == -1:
1096 if a != -1:
1097 widget.set_active(a)
1098
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
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
1149
1163
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
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
1212 return self.__gladeInterface
1213
1216
1219
1222
1258
1259
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
1274
1275
1276
1277 if self.__autoinitSplit != 'NONE':
1278 for init in autoinit.split(self.__autoinitSplit):
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288 exec 'retval -= self.' + init
1289 else:
1290 exec 'retval -= self.' + autoinit
1291
1292 return retval
1293
1294
1306
1308 """
1309 Toggle the 'sensitive' property on a target widget
1310 """
1311
1312
1313
1314
1315 s = targetWidget.get_property('sensitive')
1316 targetWidget.set_sensitive(not s)
1317
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
1332
1333
1334
1335
1336
1337 self.__mainTopLevelWidget.getWidget().resize(1,1)
1338
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
1393
1403
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
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
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
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
1475 if pre:
1476 try:
1477
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
1486
1487
1488 resp = obj.run()
1489 debug("%s: resp=%s" % (cond, resp), cond)
1490
1491
1492 obj.hide()
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
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
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
1524
1525 debug("%s: fallback running dialog %s (%s)"% (cond, name,
1526 args[0]))
1527 return args[0].run()
1528
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
1579
1584
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
1614
1615
1616
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
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
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
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
1659 i = gtk.MessageDialog(type=gtk.MESSAGE_INFO,
1660 buttons=gtk.BUTTONS_OK, message_format=message_format)
1661 i.set_title("Info")
1662
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
1673 if isinstance(method, str):
1674 method = getattr(self, method)
1675 self.__timerId = gobject.timeout_add(msecs, method, args)
1676
1678 if self.DEBUG:
1679 print >>sys.stderr, ">>>> autoProgressBar (BEGIN) args='%s'" % args
1680
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
1726
1727 - def autoDumpText(self, var, val):
1728 print "%s:%s" % (var, val)
1729
1731 if var != 'autoargs':
1732 if self.__autoArgs:
1733 self.__autoArgs += ' '
1734 self.__autoArgs += '$' + var
1735
1736
1737
1738
1739 print "%s='%s'" % (var, val)
1740
1742 if self.DEBUG:
1743 print >>sys.stderr, "autoDumpValues"
1744
1745
1746
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
1756
1757
1758
1759
1760
1761
1762
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
1770
1771
1772
1773
1774
1775
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
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
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
1846
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
1860
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
1886
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
1912 if ex.message != methodOrWidgetName:
1913 raise Exception(ex)
1914
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
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
1953
1954
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
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
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
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
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
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
2069 if self.DEBUG:
2070 print >>sys.stderr, "autoPreferences: name: %s" % self.__menuItemPreferences.getName()
2071 print >>sys.stderr, "autoPreferences: ***** SEMI IMPLEMENTED *****"
2072
2073
2074
2075
2076
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
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
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
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
2158
2159
2160
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