From: jjenning@... (jared l. jennings) Date: 2002-04-25T17:37:18+09:00 Subject: Re: Glade???? --5mCyUwZo2JvN/JJP Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Thu, Apr 25, 2002 at 03:27:40PM +0900, Carl Parrish wrote: > > Does ruby work with glade at all? I guess what I'm asking is, is there a > way to get glade to convert to ruby?? > > Carl Parrish > glad you asked! :) i wrote a ruby script to take a glade file and make a bunch of ruby scripts with empty callbacks for all the events defined in the glade file. (and i'm up at 4:30.) -- Doubt is a pain too lonely to know that faith is his twin brother. - Gibran Khalil Gibran --5mCyUwZo2JvN/JJP Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="parse.rb" #!/usr/bin/env ruby # parse.rb (until it gets a better name) # jared jennings # under LGPL # syntax: ruby parse.rb # output: (change this too) # for foo.glade, you get # foo.rb # foo_toplevel_widget_1.rb # foo_toplevel_widget_2.rb # where toplevel widgets are windows or dialogs # the toplevel widget files contain empty definitions for # handlers for all the widgets in them, ready for you to fill # # WARNING! This script blithely overwrites files, obliterating any and every # callback you have already written. require 'nqxml/treeparser' require 'singleton' def parse thing,indent print " " * indent, thing.entity.inspect, "\n" thing.children.each do |child| parse child,(indent + 2) end end class Maker include Singleton def initialize @classNames = [] @widgets = {} @handlers = {} @GtkClasses = {} @GtkClasses['unnamed_container'] = %w{ GtkHBox GtkVBox GtkTable GtkAlignment GtkHButtonBox GtkVButtonBox GtkScrolledWindow GtkViewport GtkMenuBar GtkMenu GtkMenuItem GtkPixmapMenuItem GtkAspectFrame GtkEventBox GtkFrame GtkHPaned GtkHandleBox GtkLayout GtkPacker GtkVPaned } @GtkClasses['named_container'] = %w{ GtkNotebook GtkToolbar GtkButton GtkCalendar } @GtkClasses['unnamed'] = %w{ GtkArrow GtkHSeparator GtkLabel GtkVSeparator Placeholder GtkHRuler GtkVRuler } @GtkClasses['named'] = %w{ GtkAccelLabel GtkCTree GtkEntry GtkCList GtkCheckButton GtkCombo GtkCurve GtkGammaCurve GtkHScale GtkHScrollbar GtkImage GtkList GtkOptionMenu GtkPixmap GtkPreview GtkProgressBar GtkRadioButton GtkSpinButton GtkStatusbar GtkText GtkToggleButton GtkTree GtkVScale GtkVScrollbar GtkDrawingArea Custom } @GtkClasses['toplevel'] = %w{ GtkWindow GtkDialog GtkInputDialog GtkColorSelectionDialog GtkFontSelectionDialog GtkFileSelection GtkFontSelection GtkColorSelection } end # ------------------- convenience # how do i do these better? i can't do singleton def's for every # node; i don't think i can subclass Node and make NQXML give me # my subclass instead of NQXML::Node... # i might have tried def NQXML::Node#mangle and etc., but if i did # it didn't work def mangle entity entity.entity.type.name.gsub(/.*::/,"") end def find_child entity,name f = entity.children.find do |child| (mangle(child) == "Tag") && (child.entity.name =~ /#{name}/i) end return f.children[0].entity.text end def find_children entity,name entity.children.find_all do |child| (mangle(child) == "Tag") && (child.entity.name =~ /#{name}/i) end end def class_case str # this solution thanks to Park Hee-Sob str.sub(/^./) { $&.upcase } end # ------------------- level 0 def parse_one thing, indent, prefix = "", container_klass = "" methodName = prefix + mangle(thing) self.send(methodName, thing, indent, container_klass) end def parse_children root, indent, prefix = "", container_klass = "" root.children.each do |child| parse_one child, indent + 2, prefix, container_klass end end # -------------------- level 1 def Tag tag, indent, container_klass methodName = "tag_"+tag.entity.name.gsub(/-/,"_") self.send(methodName, tag, indent, container_klass) end def Text root, indent, container_klass end def Comment root, indent, container_klass end # -------------------- level 2 def tag_GTK_Interface iface, indent, container_klass parse_children iface, indent + 2 end def tag_project thing, indent, container_klass end def tag_widget widget, indent, container_klass classEntity = widget.children.find do |child| (mangle(child) == "Tag") && (child.entity.name =~ /class/i) end className = classEntity.children[0].entity.text methodName = nil %w{named_container unnamed_container named unnamed toplevel}.each do |name| result = @GtkClasses[name].find do |item| item == className end if result methodName = "widget_"+name end end if !methodName # special case. methodName = "widget_"+className end print " "*indent, "#{methodName} " widget_any widget, indent + 2, container_klass self.send(methodName, widget, indent, container_klass) end # ------------------- level 3 def widget_any widget, indent, container_klass className = find_child(widget, "class") widgetName = find_child(widget, "name") print "#{className} #{widgetName} has signals " signals = find_children(widget, "signal") container_klass = widgetName if container_klass == "" signals.each do |sig| print find_child(sig, "handler") if !@handlers.has_key? container_klass @handlers[container_klass] = [] end @handlers[container_klass].push find_child(sig, "handler") end print ".\n" end def widget_unnamed widget, indent, container_klass end def widget_named widget, indent, container_klass if !@widgets.has_key? container_klass @widgets[container_klass] = [] end @widgets[container_klass].push find_child(widget, "name") end def widget_unnamed_container container, indent, container_klass children = find_children(container, "widget") children.each do |child| parse_one child, indent + 2, "", container_klass end end def widget_named_container container, indent, container_klass widget_named container, indent, container_klass widget_unnamed_container container, indent, container_klass end def widget_toplevel toplevel, indent, container_klass name = find_child(toplevel, "name") # this will be a class name; it must be capped @classNames.push name widget_named_container toplevel, indent, name end # --------------------- output ---------------------- def spitItOut fileName p @handlers prefix = fileName.sub(/\.glade/,"") prefix.gsub!("-","_") puts " writing #{prefix}.rb" mainFile = File.new(prefix+".rb", "w") @classNames.each do |cl| mainFile.print "require '#{prefix}_#{cl}'\n" end # -- boilerplate -------------- mainFile.print < str.sub(/^./) { $&.upcase } end def setup_hashes @classNames = \%w{ #{@classNames.join(" ")} } @classes = Hash.new nil @classNames.each do |className| properName = class_case(className) klass = eval(properName) @classes[className] = klass end @handlers = { EO # -- real code ---------------- @classNames.each do |name| mainFile.print " "*12, '"'+name+'"', " => " if @handlers.has_key? name mainFile.print "%w{ ", @handlers[name].join(" "), " },\n" else mainFile.print "[],\n" end end # -- boilerplate -------------- mainFile.print < " if @widgets.has_key? name mainFile.print "%w{ ",@widgets[name].join(" "), " },\n" else mainFile.print "[],\n" end end # -- boilerplate -------------- mainFile.print < ex puts "parse error, line #{ex.line} col #{ex.column}: #{$!}" end print "done.\n" #@errlist = [] print "Converting tree to internal structures... \n" Maker.instance.parse_one parser.document.rootNode,2 print "... done.\n" print "Writing files... \n" Maker.instance.spitItOut fn print "... done.\n" --5mCyUwZo2JvN/JJP--