home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Freelog 65
/
Freelog065.iso
/
BAS
/
Bureautique
/
Gnumeric
/
gnumeric-1.3.92-rc1.exe
/
libglade-convert
< prev
next >
Wrap
Text File
|
2004-09-27
|
46KB
|
1,202 lines
#!/usr/bin/python
# -*- mode: python -*-
# yes, this requires python 2.x and an XML parser module (eg. PyExpat)
import re
import sys
import string
import getopt
import xml.dom.minidom
translatable_properties = [
'label', 'title', 'text', 'format', 'copyright', 'comments',
'preview_text', 'tooltip'
]
# --- Code to represent a widget in memory, and dump it to stdout ---
upgrade = 1
verbose = 0
class WidgetDef:
def __init__(self, parent=None):
self.wclass = None
self.name = None
self.property_names = [ ]
self.properties = { }
self.signals = []
self.accels = []
self.children = []
self.parent = parent
def __getitem__(self, name):
if name == 'name':
return self.name
if name == 'class':
return self.wclass
if name == 'parent':
return self.parent
return self.properties[name]
def __setitem__(self, name, value):
if name == 'name':
self.name = value
return
if name == 'class':
self.wclass = value
return
if self.properties.has_key(name):
self.property_names.remove(name)
del self.properties[name]
if value == 'True': value = 'yes'
if value == 'False': value = 'no'
self.property_names.append(name)
self.properties[name] = value
def __delitem__(self, name):
if self.properties.has_key(name):
self.property_names.remove(name)
del self.properties[name]
else:
raise KeyError, "unknown property `%s'" % name
def has_prop(self, name):
return self.properties.has_key(name)
def rename_prop(self, old_name, new_name):
if self.has_prop(old_name):
self[new_name] = self[old_name]
del self[old_name]
def remove_prop(self, name):
if self.properties.has_key(name):
self.property_names.remove(name)
del self.properties[name]
def mark_obsolete (self):
self.properties ['obsolete'] = 'yes'
def add_signal(self, name, handler, object=None, after=0):
self.signals.append((name, handler, object, after))
def add_accel(self, key, modifiers, signal):
self.accels.append((key, modifiers, signal))
class ChildDef:
def __init__(self, widget, internal_child=None):
self.internal_child = internal_child
self.property_names = []
self.properties = {}
self.widget = widget
def __getitem__(self, name):
return self.properties[name]
def __setitem__(self, name, value):
if self.properties.has_key(name):
self.property_names.remove(name)
del self.properties[name]
if value == 'True': value = 'yes'
if value == 'False': value = 'no'
self.property_names.append(name)
self.properties[name] = value
def __delitem__(self, name):
if self.properties.has_key(name):
self.property_names.remove(name)
del self.properties[name]
else:
raise KeyError, "unknown property `%s'" % name
def has_prop(self, name):
return self.properties.has_key(name)
def rename_prop(self, old_name, new_name):
if self.has_prop(old_name):
self[new_name] = self[old_name]
del self[old_name]
def remove_prop(self, name):
if self.properties.has_key(name):
self.property_names.remove(name)
del self.properties[name]
def dump(self, indent):
if self.widget.has_prop('obsolete'):
return
if self.internal_child:
print '%s<child internal-child="%s">' % \
(indent, self.internal_child)
else:
print '%s<child>' % indent
if self.widget.wclass == 'Placeholder':
print '%s <placeholder />' % indent
else:
self.widget.dump(indent + ' ')
if self.properties:
print '%s <packing>' % indent
for name in self.property_names:
attrs = ''
if name in translatable_properties:
attrs += ' translatable="yes"'
if name[:3] == 'cxx':
attrs += ' agent="glademm"'
print '%s <property name="%s"%s>%s</property>' % \
(indent, name, attrs, self.properties[name])
print '%s </packing>' % indent
print '%s</child>' % indent
def add_child(self, widget, internal_child=None):
child = self.ChildDef(widget, internal_child)
self.children.append(child)
return child
def dump(self, indent):
print '%s<widget class="%s" id="%s">' %(indent, self.wclass, self.name)
want_newline = 0
for name in self.property_names:
attrs = ''
translatable = name in translatable_properties
if name == 'label' and \
self.has_prop('use_stock') and self['use_stock'] == 'yes':
translatable = 0
if translatable:
attrs += ' translatable="yes"'
if name[:3] == 'cxx':
attrs += ' agent="glademm"'
print '%s <property name="%s"%s>%s</property>' % \
(indent, name, attrs, self.properties[name])
want_newline = 1
if want_newline and (self.signals or self.accels or self.children):
print
want_newline = 0
for name, handler, object, after in self.signals:
print '%s <signal name="%s" handler="%s"' % (indent, name,
handler),
if object: print 'object="%s"' % object,
if after: print 'after="yes"',
print '/>'
want_newline = 1
if want_newline and (self.accels or self.children): print
want_newline = 0
for key, modifiers, signal in self.accels:
print '%s <accelerator key="%s" modifiers="%s" signal="%s" />' % \
(indent, key, modifiers, signal)
want_newline = 1
if want_newline and self.children: print
want_newline = 0
for child in self.children:
if want_newline: print
child.dump(indent + ' ')
want_newline = 1
print '%s</widget>' % indent
# --- Code to parse the glade1 XML files into WidgetDef instances ---
def totext(nodelist):
return string.join(map(lambda node: node.toxml(), nodelist), '')
def handle_signal(widget, signalnode):
name = None
handler = None
object = None
after = 0
for node in signalnode.childNodes:
if node.nodeType != node.ELEMENT_NODE:
continue
if node.nodeName == 'name':
name = totext(node.childNodes)
elif node.nodeName == 'handler':
handler = totext(node.childNodes)
elif node.nodeName == 'object':
object = totext(node.childNodes)
elif node.nodeName == 'after':
after = (totext(node.childNodes) == 'True')
widget.add_signal(name, handler, object, after)
def handle_accel(widget, accelnode):
key = None
modifiers = None
signal = None
for node in accelnode.childNodes:
if node.nodeType != node.ELEMENT_NODE:
continue
if node.nodeName == 'key':
key = totext(node.childNodes)
if key[:4] == 'GDK_': key = key[4:]
elif node.nodeName == 'modifiers':
modifiers = totext(node.childNodes)
elif node.nodeName == 'signal':
signal = totext(node.childNodes)
widget.add_accel(key, modifiers, signal)
def get_child_props(childdef, widgetnode):
for node in widgetnode.childNodes:
if node.nodeType != node.ELEMENT_NODE:
continue
if node.nodeName == 'child':
child = node
break
else:
return []
for node in child.childNodes:
if node.nodeType != node.ELEMENT_NODE:
continue
childdef[node.nodeName] = totext(node.childNodes)
def handle_widget(widgetnode, parent=None):
widget = WidgetDef(parent)
properties = []
signals = []
accels = []
children = []
for node in widgetnode.childNodes:
if node.nodeType != node.ELEMENT_NODE:
continue
if node.nodeName == 'widget':
child_widget = handle_widget(node, widget)
childdef = widget.add_child(child_widget)
get_child_props(childdef, node)
elif node.nodeName in ('signal', 'Signal'):
handle_signal(widget, node)
elif node.nodeName in ('accelerator', 'Accelerator'):
handle_accel(widget, node)
elif node.nodeName == 'child':
pass # handled by the parent widget
else:
widget[node.nodeName] = totext(node.childNodes)
return widget
# --- Code to do widget type specific cleanups ---
name_counter = 0
def make_name():
global name_counter
name_counter = name_counter + 1
return 'convertwidget' + str(name_counter)
# properties to change on all widgets
global_obsolete_props = [
'child_min_width',
'child_min_height',
'child_ipad_x',
'child_ipad_y'
]
global_renamed_props = [
('width', 'width-request'),
('height', 'height-request'),
]
# properties to change on specific widgets
obsolete_props = {
'GtkWindow': [ 'auto_shrink' ],
'GnomePropertyBox': [ 'auto_shrink' ],
'GtkMenuItem': [ 'right_justify' ],
'GtkGammaCurve': [ 'curve_type', 'min_x', 'max_x', 'min_y', 'max_y' ],
'GtkHPaned': [ 'handle_size', 'gutter_size' ],
'GtkVPaned': [ 'handle_size', 'gutter_size' ],
'GtkHScale': [ 'policy' ],
'GtkVScale': [ 'policy' ],
'GtkHScrollbar': [ 'policy' ],
'GtkVScrollbar': [ 'policy' ],
'GtkHRuler': [ 'metric' ],
'GtkVRuler': [ 'metric' ],
'GnomeFileEntry' : [ 'max_saved' ],
'GnomeEntry' : [ 'max_saved' ],
'GtkMenuBar' : [ 'shadow_type' ],
'GtkToolbar' : [ 'space_size', 'space_style', 'relief', 'tooltips' ],
'GtkImage' : [ 'image_width', 'image_height', 'image_visual', 'image_type'],
'GtkColorSelection' : [ 'policy' ],
'GtkColorSelectionDialog' : [ 'policy' ],
'GnomeIconEntry': [ 'max_saved' ],
}
renamed_props = {
'GtkWindow': [ ('position', 'window-position') ],
'GtkEntry': [ ('text_max_length', 'max-length'),
('text_visible', 'visibility') ],
'GtkFrame': [ ('shadow_type', 'shadow') ],
'GtkHandleBox': [ ('shadow_type', 'shadow') ],
'GtkNotebook': [ ('popup_enable', 'enable-popup') ],
'GtkRange': [ ('policy', 'update-policy') ],
'GtkTable': [ ('rows', 'n-rows'), ('columns', 'n-columns') ],
'GtkSpinButton' : [ ('snap', 'snap_to_ticks') ],
'GtkCombo' : [ ('use_arrows', 'enable_arrow_keys'),
('use_arrows_always', 'enable_arrows_always'),
('ok_if_empty', 'allow_empty') ],
'GnomeFileEntry' : [ ('directory', 'directory_entry'),
('title', 'browse_dialog_title'),
],
'GnomeIconEntry' : [ ('title', 'browse_dialog_title') ],
'GnomePixmapEntry' : [ ('title', 'browse_dialog_title') ],
'GtkLabel' : [ ('default_focus_target', 'mnemonic_widget'), ('focus_target', 'mnemonic_widget')],
'GtkCList' : [ ('columns', 'n_columns') ],
'GtkCTree' : [ ('columns', 'n_columns') ],
'GtkToolbar': [ ('type', 'toolbar-style') ],
'GtkOptionMenu' : [ ('initial_choice', 'history') ],
'GtkLayout' : [ ('area_width', 'width'), ('area_height', 'height') ],
'GtkFileSelection' : [ ('show_file_op_buttons', 'show-fileops') ],
'GnomeDruidPageStandard' : [ ('title_color', 'title_foreground'),
('background_color', 'background'),
('logo_background_color', 'logo_background'),
('logo_image', 'logo'),
],
'GnomeFontPicker': [ ('use_font_size', 'label-font-size'),
('use_font', 'use-font-in-label'),
],
}
# child properties to change on specific widgets
global_renamed_child_props = [
('pack', 'pack_type'),
('child_ipad_x', 'child_internal_pad_x'),
('child_ipad_y', 'child_internal_pad_y')
]
obsolete_child_props = {
}
renamed_child_props = {
'GtkTable' : [ ('xpad', 'x_padding'), ('ypad', 'y_padding') ],
}
def collect_adjustment(widgetdef, prop_prefix, new_name):
value, lower, upper, step, page, page_size = (0, 0, 100, 1, 10, 10)
adj_set = 0
if widgetdef.has_prop(prop_prefix + 'value'):
value = widgetdef[prop_prefix + 'value']
del widgetdef[prop_prefix + 'value']
adj_set = 1
if widgetdef.has_prop(prop_prefix + 'lower'):
lower = widgetdef[prop_prefix + 'lower']
del widgetdef[prop_prefix + 'lower']
adj_set = 1
if widgetdef.has_prop(prop_prefix + 'upper'):
upper = widgetdef[prop_prefix + 'upper']
del widgetdef[prop_prefix + 'upper']
adj_set = 1
if widgetdef.has_prop(prop_prefix + 'step'):
step = widgetdef[prop_prefix + 'step']
del widgetdef[prop_prefix + 'step']
adj_set = 1
if widgetdef.has_prop(prop_prefix + 'page'):
page = widgetdef[prop_prefix + 'page']
del widgetdef[prop_prefix + 'page']
adj_set = 1
if widgetdef.has_prop(prop_prefix + 'page_size'):
page_size = widgetdef[prop_prefix + 'page_size']
del widgetdef[prop_prefix + 'page_size']
adj_set = 1
if adj_set:
widgetdef[new_name] = '%s %s %s %s %s %s' % (value, lower, upper,
step, page, page_size)
parent_table = {
'GtkContainer' : 'GtkWidget',
'GtkBin' : 'GtkContainer',
'GtkDialog' : 'GtkWindow',
'GnomePropertyBox' : 'GnomeDialog',
'GnomeAbout' : 'GtkDialog',
'GnomeApp' : 'GtkWindow',
'GnomeScores' : 'GnomeDialog',
'GnomeDialog' : 'GtkWindow',
'GnomeMessageBox' : 'GnomeDialog',
'GnomeDruid' : 'GtkContainer',
'GnomeEntry' : 'GtkCombo',
'GtkCheckMenuItem' : 'GtkMenuItem',
'GtkRadioMenuItem' : 'GtkMenuItem',
'GtkImageMenuItem' : 'GtkMenuItem',
'GtkFileSelection' : 'GtkDialog',
'GtkFontSelectionDialog' : 'GtkDialog',
'GnomeColorPicker' : 'GtkButton',
'GtkToggleButton' : 'GtkButton',
'GtkCheckButton' : 'GtkToggleButton',
'GtkRadioButton' : 'GtkToggleButton',
'GtkColorSelectionDialog': 'GtkDialog',
'GtkFontSelectionDialog': 'GtkDialog',
}
global_group_map = { }
def find_parent(type):
if parent_table.has_key(type):
return parent_table[type]
return ''
# fix up attribute naming, and possibly adding missing children.
def fixup_widget(widget):
type = widget['class']
while (type and not fixup_as_type (widget, type)):
type = find_parent (type)
for childdef in widget.children:
fixup_widget(childdef.widget)
def new_label(class_type, text, accel_object):
label = WidgetDef()
label['class'] = class_type
label['name'] = make_name()
label['label'] = text;
if '_' in text:
label['use-underline'] = 'yes'
if not class_type == 'GtkMenuItem':
label['xalign'] = '0.0'
if class_type == 'GtkAccelLabel':
label['accel-widget'] = accel_object
label['use-underline'] = 'yes'
return label
stock_pixmaps = {
'REVERT': 'gtk-revert-to-saved',
'SCORES': 'gnome-stock-scores',
'SEARCH': 'gtk-find',
'SEARCHRPL': 'gtk-find-and-replace',
'BACK': 'gtk-go-back',
'FORWARD': 'gtk-go-forward',
'FIRST': 'gtk-goto-first',
'LAST': 'gtk-goto-last',
'TIMER': 'gnome-stock-timer',
'TIMER_STOP': 'gnome-stock-timer-stop',
'MAIL': 'gnome-stock-mail',
'MAIL_RCV': 'gnome-stock-mail-rcv',
'MAIL_SND': 'gnome-stock-mail-send',
'MAIL_RPL': 'gnome-stock-mail-rply',
'MAIL_FWD': 'gnome-stock-mail-fwd',
'MAIL_NEW': 'gnome-stock-mail-new',
'TRASH': 'gnome-stock-trash',
'TRASH_FULL': 'gnome-stock-trash-full',
'SPELLCHECK': 'gtk-spell-check',
'MIC': 'gnome-stock-mic',
'LINE_IN': 'gnome-stock-line-in',
'VOLUME': 'gnome-stock-volume',
'MIDI': 'gnome-stock-midi',
'BOOK_RED': 'gnome-stock-book-red',
'BOOK_GREEN': 'gnome-stock-book-green',
'BOOK_BLUE': 'gnome-stock-book-blue',
'BOOK_YELLOW': 'gnome-stock-book-yellow',
'BOOK_OPEN': 'gnome-stock-book-open',
'ABOUT': 'gnome-stock-about',
'MULTIPLE': 'gnome-stock-multiple-file',
'NOT': 'gnome-stock-not',
'UP': 'gtk-go-up',
'DOWN': 'gtk-go-down',
'TOP': 'gtk-goto-top',
'BOTTOM': 'gtk-goto-bottom',
'ATTACH': 'gnome-stock-attach',
'FONT': 'gtk-select-font',
'EXEC': 'gtk-execute',
'ALIGN_LEFT': 'gtk-justify-left',
'ALIGN_RIGHT': 'gtk-justify-right',
'ALIGN_CENTER': 'gtk-justify-center',
'ALIGN_JUSTIFY': 'gtk-justify-fill',
'TEXT_BOLD': 'gtk-bold',
'TEXT_ITALIC': 'gtk-italic',
'TEXT_UNDERLINE': 'gtk-underline',
'TEXT_STRIKEOUT': 'gtk-strikethrough',
'TEXT_INDENT': 'gnome-stock-text-indent',
'TEXT_UNINDENT': 'gnome-stock-text-unindent',
'EXIT': 'gtk-quit',
'COLORSELECTOR': 'gtk-select-color',
'TABLE_BORDERS': 'gnome-stock-table-borders',
'TABLE_FILL': 'gnome-stock-table-fill',
'TEXT_BULLETED_LIST': 'gnome-stock-text-bulleted-list',
'TEXT_NUMBERED_LIST': 'gnome-stock-text-numbered-list',
'NEXT': 'gtk-go-forward',
'PREV': 'gtk-go-back'
}
def stock_icon_translate(old_name):
if re.match ('GNOME_STOCK_MENU_.*', old_name):
name = re.sub('GNOME_STOCK_MENU_', '', old_name, 1)
try:
return stock_pixmaps[name]
except KeyError:
name = re.sub('_', '-', name)
return 'gtk-' + name.lower ()
else:
return old_name
def stock_button_translate(old_name):
if re.match ('GNOME_STOCK_BUTTON_.*', old_name):
name = re.sub('GNOME_STOCK_BUTTON_', '', old_name)
try:
return stock_pixmaps[name]
except KeyError:
name = re.sub('_', '-', name)
return 'gtk-' + name.lower ()
else:
return old_name
def stock_pixmap_translate(old_name):
if re.match ('GNOME_STOCK_PIXMAP_.*', old_name):
name = re.sub('GNOME_STOCK_PIXMAP_', '', old_name)
try:
return stock_pixmaps[name]
except KeyError:
name = re.sub('_', '-', name)
return 'gtk-' + name.lower ()
stock_menu_items = {
'GNOMEUIINFO_MENU_NEW_ITEM': (1, 'gtk-new'),
'GNOMEUIINFO_MENU_NEW_SUBTREE': (1, 'gtk-new'),
'GNOMEUIINFO_MENU_OPEN_ITEM': (1, 'gtk-open'),
'GNOMEUIINFO_MENU_SAVE_ITEM': (1, 'gtk-save'),
'GNOMEUIINFO_MENU_SAVE_AS_ITEM': (1, 'gtk-save-as'),
'GNOMEUIINFO_MENU_REVERT_ITEM': (1, 'gtk-revert-to-saved'),
'GNOMEUIINFO_MENU_PRINT_ITEM': (1, 'gtk-print'),
'GNOMEUIINFO_MENU_PRINT_SETUP_ITEM': (0, 'Print S_etup...'),
'GNOMEUIINFO_MENU_CLOSE_ITEM': (1, 'gtk-close'),
'GNOMEUIINFO_MENU_EXIT_ITEM': (1, 'gtk-quit'),
'GNOMEUIINFO_MENU_CUT_ITEM': (1, 'gtk-cut'),
'GNOMEUIINFO_MENU_COPY_ITEM': (1, 'gtk-copy'),
'GNOMEUIINFO_MENU_PASTE_ITEM': (1, 'gtk-paste'),
'GNOMEUIINFO_MENU_SELECT_ALL_ITEM': (0, '_Select All'),
'GNOMEUIINFO_MENU_CLEAR_ITEM': (1, 'gtk-clear'),
'GNOMEUIINFO_MENU_UNDO_ITEM': (1, 'gtk-undo'),
'GNOMEUIINFO_MENU_REDO_ITEM': (1, 'gtk-redo'),
'GNOMEUIINFO_MENU_FIND_ITEM': (1, 'gtk-find'),
'GNOMEUIINFO_MENU_FIND_AGAIN_ITEM': (0, 'Find _Again'),
'GNOMEUIINFO_MENU_REPLACE_ITEM': (1, 'gtk-find-and-replace'),
'GNOMEUIINFO_MENU_PROPERTIES_ITEM': (1, 'gtk-properties'),
'GNOMEUIINFO_MENU_PREFERENCES_ITEM': (1, 'gtk-preferences'),
'GNOMEUIINFO_MENU_NEW_WINDOW_ITEM': (0, 'Create New _Window'),
'GNOMEUIINFO_MENU_CLOSE_WINDOW_ITEM': (0, '_Close This Window'),
'GNOMEUIINFO_MENU_ABOUT_ITEM': (1, 'gnome-stock-about'),
'GNOMEUIINFO_MENU_NEW_GAME_ITEM': (0, '_New game'),
'GNOMEUIINFO_MENU_PAUSE_GAME_ITEM': (0, '_Pause game'),
'GNOMEUIINFO_MENU_RESTART_GAME_ITEM': (0, '_Restart game'),
'GNOMEUIINFO_MENU_UNDO_MOVE_ITEM': (0, '_Undo move'),
'GNOMEUIINFO_MENU_REDO_MOVE_ITEM': (0, '_Redo move'),
'GNOMEUIINFO_MENU_HINT_ITEM': (0, '_Hint'),
'GNOMEUIINFO_MENU_SCORES_ITEM': (0, '_Scores...'),
'GNOMEUIINFO_MENU_END_GAME_ITEM': (0, '_End game'),
'GNOMEUIINFO_MENU_FILE_TREE': (0, '_File'),
'GNOMEUIINFO_MENU_EDIT_TREE': (0, '_Edit'),
'GNOMEUIINFO_MENU_VIEW_TREE': (0, '_View'),
'GNOMEUIINFO_MENU_SETTINGS_TREE': (0, '_Settings'),
'GNOMEUIINFO_MENU_FILES_TREE': (0, 'Fi_les'),
'GNOMEUIINFO_MENU_WINDOWS_TREE': (0, '_Windows'),
'GNOMEUIINFO_MENU_HELP_TREE': (0, '_Help'),
'GNOMEUIINFO_MENU_GAME_TREE': (0, '_Game'),
}
def stock_menu_translate(old_name):
if stock_menu_items.has_key(old_name):
return stock_menu_items[old_name]
else:
return (0, old_name)
def translate_color (color):
c = string.split (color, ',')
return '#%.2x%.2x%.2x' % (int (c[0]), int (c[1]), int (c[2]))
def fixup_as_type(widget, type):
if verbose:
print >> sys.stderr, 'Fixing', widget['name'], 'up as', type
# table based property removals/renames
for name in global_obsolete_props:
widget.remove_prop(name)
for old, new in global_renamed_props:
widget.rename_prop(old, new)
if obsolete_props.has_key(type):
for name in obsolete_props[type]:
widget.remove_prop(name)
if renamed_props.has_key(type):
for old, new in renamed_props[type]:
widget.rename_prop(old, new)
for old, new in global_renamed_child_props:
for childdef in widget.children:
childdef.rename_prop(old, new)
if obsolete_child_props.has_key(type):
for name in obsolete_child_props[type]:
for childdef in widget.children:
childdef.remove_prop(name)
if renamed_child_props.has_key(type):
for old, new in renamed_child_props[type]:
for childdef in widget.children:
childdef.rename_prop(old, new)
# add the visible property if missing:
if not widget.has_prop('visible'):
widget['visible'] = 'yes'
# fix up child packing properties for tables
if type == 'GtkTable':
for childdef in widget.children:
options = []
if childdef.has_prop('xexpand'):
if childdef['xexpand'] == 'yes':
options.append('expand')
del childdef['xexpand']
if childdef.has_prop('xshrink'):
if childdef['xshrink'] == 'yes':
options.append('shrink')
del childdef['xshrink']
if childdef.has_prop('xfill'):
if childdef['xfill'] == 'yes':
options.append('fill')
del childdef['xfill']
if options:
childdef['x_options'] = string.join(options,'|')
else: # Gtk+ has some wierd defaults here clobber them
childdef['x_options'] = ''
options = []
if childdef.has_prop('yexpand'):
if childdef['yexpand'] == 'yes':
options.append('expand')
del childdef['yexpand']
if childdef.has_prop('yshrink'):
if childdef['yshrink'] == 'yes':
options.append('shrink')
del childdef['yshrink']
if childdef.has_prop('yfill'):
if childdef['yfill'] == 'yes':
options.append('fill')
del childdef['yfill']
if options:
childdef['y_options'] = string.join(options,'|')
else: # Gtk+ has some wierd defaults here clobber them
childdef['y_options'] = ''
# fixup GtkNotebook child tab widgets.
if type == 'GtkNotebook':
for childdef in widget.children:
if childdef.widget.has_prop ('child_name'):
if childdef.widget['child_name'] == 'Notebook:tab':
del childdef.widget['child_name']
childdef['type'] = 'tab'
else:
print >> sys.stderr , 'Unknown child_name', \
childdef.widget['child_name']
if type == 'GtkFileSelection':
for childdef in widget.children:
if childdef.widget.has_prop ('child_name'):
if re.match ('FileSel:.*', childdef.widget['child_name']):
name = re.sub ('FileSel:', '', childdef.widget['child_name'])
del childdef.widget['child_name']
childdef.internal_child = name
if type == 'GtkColorSelectionDialog':
for childdef in widget.children:
if childdef.widget.has_prop ('child_name'):
if re.match ('ColorSel:.*', childdef.widget['child_name']):
name = re.sub ('ColorSel:', '', childdef.widget['child_name'])
del childdef.widget['child_name']
childdef.internal_child = name
if type == 'GtkFontSelectionDialog':
for childdef in widget.children:
if childdef.widget.has_prop ('child_name'):
if re.match ('FontSel:.*', childdef.widget['child_name']):
name = re.sub ('FontSel:', '', childdef.widget['child_name'])
del childdef.widget['child_name']
childdef.internal_child = name
# fix up adjustment properties
if type in ('GtkHScale', 'GtkHScrollbar',
'GtkVScale', 'GtkVScrollbar',
'GtkSpinButton'):
collect_adjustment(widget, 'h', 'adjustment') # compat
collect_adjustment(widget, 'v', 'adjustment') # compat
collect_adjustment(widget, '', 'adjustment')
if type in ('GtkViewport', 'GtkLayout', 'GtkScrolledWindow'):
collect_adjustment(widget, 'h', 'hadjustment')
collect_adjustment(widget, 'v', 'vadjustment')
if widget.has_prop('width'):
width = widget['width']
del widget['width']
widget['width'] = width
if widget.has_prop('height'):
height = widget['height']
del widget['height']
widget['height'] = height
if type in ('GtkProgressBar', ):
collect_adjustment(widget, '', 'adjustment')
# add label children to menu items.
if type == 'GtkMenuItem':
if widget.has_prop('stock_item'):
use_stock, stock = stock_menu_translate(widget['stock_item'])
widget['label'] = stock
widget['use_stock'] = use_stock and 'yes' or 'no'
widget['use_underline'] = 'yes'
del widget['stock_item']
if type == 'GtkImageMenuItem':
if widget.has_prop('stock_icon'):
icon = WidgetDef()
icon['class'] = 'GtkImage'
icon['name'] = make_name ()
icon['stock'] = stock_icon_translate (widget['stock_icon'])
widget.add_child (icon, 'image')
del widget['stock_icon']
if type == 'GtkButton':
if widget.has_prop('stock_button'):
widget['label'] = stock_button_translate (widget['stock_button'])
widget['use_stock'] = 'yes'
widget['use_underline'] = 'yes'
del widget['stock_button']
# GnomeDialog sucks, and this is tricky to get right so just
# ignore the pixmap for now
if widget.has_prop('stock_pixmap'):
del widget['stock_pixmap']
if type == 'GtkDialog':
if widget.children:
childdef = widget.children[0]
if childdef.widget.has_prop ('child_name'):
childdef.internal_child = 'vbox'
del childdef.widget['child_name']
try:
childdef = filter(lambda x: x.widget.has_prop('child_name'),
childdef.widget.children)[0]
except IndexError:
return 0
childdef.widget['class'] = 'GtkHButtonBox'
childdef.internal_child = 'action_area'
del childdef.widget['child_name']
if type == 'GnomeDialog':
if widget.children:
childdef = widget.children[0]
if childdef.widget.has_prop ('child_name'):
childdef.internal_child = 'vbox'
del childdef.widget['child_name']
try:
childdef = filter(lambda x: x.widget.has_prop('child_name'),
childdef.widget.children)[0]
except IndexError:
return 0
childdef.widget['class'] = 'GtkHButtonBox'
childdef.internal_child = 'action_area'
del childdef.widget['child_name']
if type == 'GtkOptionMenu':
menu = WidgetDef()
menu['class'] = 'GtkMenu'
menu['name'] = make_name ()
widget.add_child (menu, 'menu')
if widget.has_prop('items'):
# FIXME: this needs continuing, we need a GtkMenu
# item, and a hacked up special case to do the
# set_menu on the optionmenu with it, then we need
# to pack these ( working ) MenuItems into it
if not widget['items'] == '':
items = widget['items'].split ('\n')
for item in items:
if not item == '':
menu.add_child ( \
new_label ('GtkMenuItem', \
item, widget['name']))
del widget['items']
if type == 'GtkScrolledWindow':
if widget.has_prop ('hupdate_policy'):
scroll = WidgetDef ()
scroll['class'] = 'GtkHScrollbar'
scroll['name'] = make_name ()
scroll['update_policy'] = widget['hupdate_policy']
widget.add_child(scroll, 'hscrollbar')
del widget['hupdate_policy']
if widget.has_prop ('vupdate_policy'):
scroll = WidgetDef ()
scroll['class'] = 'GtkVScrollbar'
scroll['name'] = make_name ()
scroll['update_policy'] = widget['vupdate_policy']
widget.add_child(scroll, 'vscrollbar')
del widget['vupdate_policy']
if type == 'GtkCombo':
childdef = widget.children[0]
childdef.internal_child = 'entry'
del childdef.widget['child_name']
if widget.has_prop('items'):
items = widget['items'].split('\n')
del widget['items']
list = WidgetDef()
list['class'] = 'GtkList'
list['name'] = make_name()
widget.add_child(list, 'list')
for item in items:
listitem = WidgetDef()
listitem['class'] = 'GtkListItem'
listitem['name'] = make_name()
list.add_child(listitem)
listitem.add_child (new_label ('GtkLabel', item, ''))
if type in ('GtkCList', 'GtkCTree'):
for childdef in widget.children:
del childdef.widget['child_name']
if type in ('GtkLabel', 'GtkButton', 'GtkMenuItem'):
if widget.has_prop('label'):
if re.match('.*_.*', widget['label']):
widget['use_underline'] = 'yes'
if type == 'GnomeFileEntry':
childdef = widget.children[0]
childdef.internal_child = 'entry'
del childdef.widget['child_name']
if type == 'GnomePropertyBox':
childdef = widget.children[0]
childdef.internal_child = 'notebook'
del childdef.widget['child_name']
fixup_as_type (widget, 'GtkWindow')
return 1
# Fixup radio groups, the 'group' property has to
# have the glade id of the root group widget.
if type == 'GtkRadioButton' or type == 'GtkRadioMenuItem':
if widget.has_prop ('group'):
if global_group_map.has_key (widget['group']):
widget['group'] = global_group_map[widget['group']]
else:
global_group_map[widget['group']] = widget['name']
del widget['group']
if type == 'GtkToolbar':
for childdef in widget.children:
if childdef.widget.has_prop('child_name'):
if childdef.widget['child_name'] == 'Toolbar:button':
if childdef.widget['class'] == 'GtkButton':
childdef.widget['class'] = 'button'
elif childdef.widget['class'] == 'GtkToggleButton':
childdef.widget['class'] = 'toggle'
elif childdef.widget['class'] == 'GtkRadioButton':
childdef.widget['class'] = 'radio'
if childdef.widget.has_prop('group'):
if global_group_map.has_key (childdef.widget['group']):
childdef.widget['group'] = global_group_map[childdef.widget['group']]
else:
global_group_map[childdef.widget['group']] = childdef.widget['name']
del childdef.widget['group']
del childdef.widget['child_name']
if childdef.widget.has_prop('stock_pixmap'):
name = stock_pixmap_translate (childdef.widget['stock_pixmap'])
childdef.widget['stock_pixmap'] = name
if type == 'GtkCalendar':
options = []
if widget.has_prop('show_heading'):
if widget['show_heading'] == 'yes':
options.append('GTK_CALENDAR_SHOW_HEADING')
del widget['show_heading']
if widget.has_prop('show_day_names'):
if widget['show_day_names'] == 'yes':
options.append('GTK_CALENDAR_SHOW_DAY_NAMES')
del widget['show_day_names']
if widget.has_prop('no_month_change'):
if widget['no_month_change'] == 'yes':
options.append('GTK_CALENDAR_NO_MONTH_CHANGE')
del widget['no_month_change']
if widget.has_prop('show_week_numbers'):
if widget['show_week_numbers'] == 'yes':
options.append('GTK_CALENDAR_SHOW_WEEK_NUMBERS')
del widget['show_week_numbers']
if widget.has_prop('week_start_monday'):
if widget['week_start_monday'] == 'yes':
options.append('GTK_CALENDAR_WEEK_START_MONDAY')
del widget['week_start_monday']
if options:
widget['display_options'] = string.join(options, '|')
else:
widget['display_options'] = ''
if type == 'GnomeApp':
for childdef in widget.children:
if childdef.widget.has_prop('child_name'):
if childdef.widget['child_name'] == 'GnomeApp:dock':
del childdef.widget['child_name']
childdef.internal_child = 'dock'
elif childdef.widget['child_name'] == 'GnomeApp:appbar':
del childdef.widget['child_name']
childdef.internal_child = 'appbar'
if type == 'BonoboDock':
for childdef in widget.children:
if childdef.widget.has_prop('child_name'):
if childdef.widget['child_name'] == 'GnomeDock:contents':
del childdef.widget['child_name']
if childdef.widget['class'] == 'BonoboDockItem':
behavior = []
if childdef.widget.has_prop('placement'):
name = childdef.widget['placement']
if re.match ('GNOME_.*', name):
name = re.sub('GNOME_', 'BONOBO_', name, 1)
childdef['placement'] = name
del childdef.widget['placement']
if childdef.widget.has_prop('band'):
childdef['band'] = childdef.widget['band']
del childdef.widget['band']
if childdef.widget.has_prop ('position'):
childdef['position'] = childdef.widget['position']
del childdef.widget['position']
if childdef.widget.has_prop ('offset'):
childdef['offset'] = childdef.widget['offset']
del childdef.widget['offset']
if childdef.widget.has_prop ('locked'):
if childdef.widget['locked'] == 'yes':
behavior.append ('BONOBO_DOCK_ITEM_BEH_LOCKED')
del childdef.widget['locked']
if childdef.widget.has_prop ('exclusive'):
if childdef.widget['exclusive'] == 'yes':
behavior.append ('BONOBO_DOCK_ITEM_BEH_EXCLUSIVE')
del childdef.widget['exclusive']
if childdef.widget.has_prop ('never_floating'):
if childdef.widget['never_floating'] == 'yes':
behavior.append ('BONOBO_DOCK_ITEM_BEH_NEVER_FLOATING')
del childdef.widget['never_floating']
if childdef.widget.has_prop ('never_vertical'):
if childdef.widget['never_vertical'] == 'yes':
behavior.append ('BONOBO_DOCK_ITEM_BEH_NEVER_VERTICAL')
del childdef.widget['never_vertical']
if childdef.widget.has_prop ('never_horizontal'):
if childdef.widget['never_horizontal'] == 'yes':
behavior.append ('BONOBO_DOCK_ITEM_BEH_NEVER_HORIZONTAL')
del childdef.widget['never_horizontal']
if behavior:
childdef['behavior'] = string.join(behavior, '|')
else:
childdef['behavior'] = 'BONOBO_DOCK_ITEM_BEH_NORMAL'
if type == 'GnomeDateEdit':
flags = []
if widget.has_prop('show_time'):
if widget['show_time'] == 'yes':
flags.append ('GNOME_DATE_EDIT_SHOW_TIME')
del widget['show_time']
if widget.has_prop('use_24_format'):
if widget['use_24_format'] == 'yes':
flags.append ('GNOME_DATE_EDIT_24_HR')
del widget['use_24_format']
if widget.has_prop('week_start_monday'):
if widget['week_start_monday'] == 'yes':
flags.append ('GNOME_DATE_EDIT_WEEK_STARTS_ON_MONDAY')
del widget['week_start_monday']
if flags:
widget['dateedit_flags'] = string.join(flags, '|')
else:
widget['dateedit_flags'] = '0'
if type == 'GnomeMessageBox':
try:
name = widget['message_box_type']
except KeyError:
name = 'GNOME_MESSAGE_BOX_GENERIC'
name = re.sub ('GNOME_MESSAGE_BOX_', '', name)
widget['message_box_type'] = name.lower ()
if type == 'GnomeDruidPageEdge':
for color in ( 'title_color', 'text_color', 'background_color', 'logo_background_color', 'textbox_color' ):
if widget.has_prop (color):
widget[color] = translate_color (widget[color])
if type == 'GnomeDruidPageStandard':
for color in ( 'title_foreground', 'background', 'logo_background' ):
if widget.has_prop (color):
widget[color] = translate_color (widget[color])
if widget.children:
if widget.children[0].widget.has_prop ('child_name'):
widget.children[0].internal_child = 'vbox'
del widget.children[0].widget['child_name']
return 0
# upgrade widgets to their gtk/gnome 2.0 equivalents
def upgrade_widget(widget):
do_children = 1
# some widgets are totally removed, so upgrade anyway
if widget['class'] == 'GnomeDockItem':
widget['class'] = 'BonoboDockItem'
elif widget['class'] == 'GnomeDock':
widget['class'] = 'BonoboDock'
elif widget['class'] == 'GnomeAnimator':
widget['class'] = 'GtkImage'
if widget.has_prop ('loop_type'):
del widget['loop_type']
if widget.has_prop ('playback_direction'):
del widget['playback_direction']
if widget.has_prop ('playback_speed'):
del widget['playback_speed']
elif widget['class'] == 'GnomeDruidPageStart':
widget['class'] = 'GnomeDruidPageEdge'
widget['position'] = 'GNOME_EDGE_START'
elif widget['class'] == 'GnomeDruidPageFinish':
widget['class'] = 'GnomeDruidPageEdge'
widget['position'] = 'GNOME_EDGE_FINISH'
elif widget['class'] == 'GtkPixmapMenuItem':
widget['class'] = 'GtkImageMenuItem'
if not upgrade:
if do_children:
for childdef in widget.children:
upgrade_widget(childdef.widget)
return
# use GtkImage for image display now.
if widget['class'] == 'GtkPixmap':
widget['class'] = 'GtkImage'
widget.rename_prop('filename', 'pixbuf')
widget.remove_prop('build_insensitive')
elif widget['class'] == 'GnomeFontSelector':
widget['class'] = 'GtkFontSelectionDialog'
elif widget['class'] == 'GnomePixmap':
widget['class'] = 'GtkImage'
widget.rename_prop('filename', 'pixbuf')
elif widget['class'] == 'GtkText':
widget['class'] = 'GtkTextView'
widget['wrap_mode'] = 'GTK_WRAP_WORD'
parent = widget['parent']
if parent['class'] == 'GtkScrolledWindow':
parent['shadow_type'] = 'GTK_SHADOW_IN'
elif widget['class'] in ('GtkCList', 'GtkCTree', 'GtkList', 'GtkTree'):
widget['class'] = 'GtkTreeView'
parent = widget['parent']
if parent['class'] == 'GtkScrolledWindow':
parent['shadow_type'] = widget['shadow_type']
widget.remove_prop('shadow_type')
widget.rename_prop('show_titles', 'headers-visible')
widget.remove_prop('columns')
widget.remove_prop('column_widths')
widget.remove_prop('selection_mode')
widget.remove_prop('view_mode')
widget.remove_prop('view_line')
elif widget['class'] == 'GnomeDialog':
widget['class'] = 'GtkDialog'
if widget.has_prop ('auto_close'):
del widget['auto_close']
if widget.has_prop ('hide_on_close'):
del widget['hide_on_close']
if do_children:
for childdef in widget.children:
upgrade_widget(childdef.widget)
# warn about removed widgets, and build a list of libraries used
bad_widgets = {
'GtkText': 'broken',
'GtkList': 'broken',
'GtkTree': 'broken',
'GtkTreeItem': 'broken',
'GtkCList': 'deprecated',
'GtkCTree': 'deprecated',
'GtkPixmap': 'deprecated',
'GnomePixmap': 'deprecated',
# 'GnomeFontPicker': 'removed',
'GtkPixmapMenuItem': 'removed',
'GtkPacker': 'removed',
'GnomeDialog': 'deprecated',
'GnomeNumberEntry': 'removed',
'GtkDial': 'removed',
'GtkClock': 'removed',
'GnomeCalculator': 'removed',
'GnomeLess': 'removed',
'GnomeSpell': 'removed',
}
def check_widget(widget, requirelist=[]):
try:
error = bad_widgets[widget['class']]
print >> sys.stderr , 'widget %s of class %s is %s.' % \
(widget['name'], widget['class'], error)
if error == 'removed':
widget.mark_obsolete ()
except KeyError:
pass
if widget['class'] == 'GnomeCanvas':
if 'canvas' not in requirelist:
requirelist.append('canvas')
elif widget['class'][:5] == 'Gnome' and 'gnome' not in requirelist:
requirelist.append('gnome')
elif widget['class'][:6] == 'Bonobo' and 'bonobo' not in requirelist:
requirelist.append('bonobo')
for childdef in widget.children:
check_widget(childdef.widget, requirelist)
# --- parse the file for widget definitions, fixup problems and dump.
def handle_file(filename):
document = xml.dom.minidom.parse(filename)
widgets = []
for node in document.documentElement.childNodes:
if node.nodeType == node.ELEMENT_NODE and \
node.nodeName == 'widget':
widgets.append(handle_widget(node))
requireslist = []
for widgetdef in widgets:
upgrade_widget(widgetdef)
fixup_widget(widgetdef)
check_widget(widgetdef, requireslist)
print '<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->'
print '<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd" >'
print
print '<glade-interface>'
for requirement in requireslist:
print ' <requires lib="%s" />' % requirement
if requireslist:
print
indent = ' '
for widgetdef in widgets:
widgetdef.dump(indent)
print '</glade-interface>'
document.unlink() # only needed for python interpreters without cyclic gc
usage = 'usage: libglade-convert [--no-upgrade] [--verbose] oldfile.glade'
def main():
global upgrade, verbose
opts, args = getopt.getopt(sys.argv[1:], '',
['no-upgrade', 'verbose', 'help'])
for opt, arg in opts:
if opt == '--no-upgrade':
upgrade = 0
elif opt == '--verbose':
verbose = 1
elif opt == '--help':
print usage
sys.exit(0)
if len(args) != 1:
print >> sys.stderr, usage
sys.exit(1)
handle_file(args[0])
if __name__ == '__main__':
main()