qdml 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +4 -0
- data/README +29 -0
- data/Rakefile +131 -0
- data/bin/QDMLParser +41 -0
- data/lib/Parser.rb +49 -0
- data/lib/QParser.rb +578 -0
- data/test/qdml_test.rb +7 -0
- data/test/test_helper.rb +3 -0
- metadata +72 -0
data/ChangeLog
ADDED
data/README
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
|
2
|
+
= qdml
|
3
|
+
|
4
|
+
|
5
|
+
== Description
|
6
|
+
|
7
|
+
|
8
|
+
== Installation
|
9
|
+
|
10
|
+
=== Archive Installation
|
11
|
+
|
12
|
+
rake install
|
13
|
+
|
14
|
+
=== Gem Installation
|
15
|
+
|
16
|
+
gem install qdml
|
17
|
+
|
18
|
+
|
19
|
+
== Features/Problems
|
20
|
+
|
21
|
+
|
22
|
+
== Synopsis
|
23
|
+
|
24
|
+
|
25
|
+
== Copyright
|
26
|
+
|
27
|
+
Author:: kana <kana@>
|
28
|
+
Copyright:: Copyright (c) 2008 kana
|
29
|
+
License::
|
data/Rakefile
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/packagetask'
|
6
|
+
require 'rake/gempackagetask'
|
7
|
+
require 'rake/rdoctask'
|
8
|
+
require 'rake/contrib/rubyforgepublisher'
|
9
|
+
require 'rake/contrib/sshpublisher'
|
10
|
+
require 'fileutils'
|
11
|
+
include FileUtils
|
12
|
+
|
13
|
+
NAME = "qdml"
|
14
|
+
AUTHOR = "kana"
|
15
|
+
EMAIL = "white.kna@gmail.com"
|
16
|
+
DESCRIPTION = ""
|
17
|
+
RUBYFORGE_PROJECT = "qdml"
|
18
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
19
|
+
BIN_FILES = %w(QDMLParser)
|
20
|
+
VERS = "0.0.1"
|
21
|
+
|
22
|
+
REV = File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
|
23
|
+
CLEAN.include ['**/.*.sw?', '*.gem', '.config']
|
24
|
+
RDOC_OPTS = [
|
25
|
+
'--title', "#{NAME} documentation",
|
26
|
+
"--charset", "utf-8",
|
27
|
+
"--opname", "index.html",
|
28
|
+
"--line-numbers",
|
29
|
+
"--main", "README",
|
30
|
+
"--inline-source",
|
31
|
+
]
|
32
|
+
|
33
|
+
task :default => [:test]
|
34
|
+
task :package => [:clean]
|
35
|
+
|
36
|
+
Rake::TestTask.new("test") do |t|
|
37
|
+
t.libs << "test"
|
38
|
+
t.pattern = "test/**/*_test.rb"
|
39
|
+
t.verbose = true
|
40
|
+
end
|
41
|
+
|
42
|
+
spec = Gem::Specification.new do |s|
|
43
|
+
s.name = NAME
|
44
|
+
s.version = VERS
|
45
|
+
s.platform = Gem::Platform::RUBY
|
46
|
+
s.has_rdoc = true
|
47
|
+
s.extra_rdoc_files = ["README", "ChangeLog"]
|
48
|
+
s.rdoc_options += RDOC_OPTS + ['--exclude', '^(examples|extras)/']
|
49
|
+
s.summary = DESCRIPTION
|
50
|
+
s.description = DESCRIPTION
|
51
|
+
s.author = AUTHOR
|
52
|
+
s.email = EMAIL
|
53
|
+
s.homepage = HOMEPATH
|
54
|
+
s.executables = BIN_FILES
|
55
|
+
s.rubyforge_project = RUBYFORGE_PROJECT
|
56
|
+
s.bindir = "bin"
|
57
|
+
s.require_path = "lib"
|
58
|
+
s.autorequire = ""
|
59
|
+
s.test_files = Dir["test/test_*.rb"]
|
60
|
+
|
61
|
+
#s.add_dependency('activesupport', '>=1.3.1')
|
62
|
+
#s.required_ruby_version = '>= 1.8.2'
|
63
|
+
|
64
|
+
s.files = %w(README ChangeLog Rakefile) +
|
65
|
+
Dir.glob("{bin,doc,test,lib,templates,generator,extras,website,script}/**/*") +
|
66
|
+
Dir.glob("ext/**/*.{h,c,rb}") +
|
67
|
+
Dir.glob("examples/**/*.rb") +
|
68
|
+
Dir.glob("tools/*.rb")
|
69
|
+
|
70
|
+
s.extensions = FileList["ext/**/extconf.rb"].to_a
|
71
|
+
end
|
72
|
+
|
73
|
+
Rake::GemPackageTask.new(spec) do |p|
|
74
|
+
p.need_tar = true
|
75
|
+
p.gem_spec = spec
|
76
|
+
end
|
77
|
+
|
78
|
+
task :install do
|
79
|
+
name = "#{NAME}-#{VERS}.gem"
|
80
|
+
sh %{rake package}
|
81
|
+
sh %{sudo gem install pkg/#{name}}
|
82
|
+
end
|
83
|
+
|
84
|
+
task :uninstall => [:clean] do
|
85
|
+
sh %{sudo gem uninstall #{NAME}}
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
Rake::RDocTask.new do |rdoc|
|
90
|
+
rdoc.rdoc_dir = 'html'
|
91
|
+
rdoc.options += RDOC_OPTS
|
92
|
+
rdoc.template = "resh"
|
93
|
+
#rdoc.template = "#{ENV['template']}.rb" if ENV['template']
|
94
|
+
if ENV['DOC_FILES']
|
95
|
+
rdoc.rdoc_files.include(ENV['DOC_FILES'].split(/,\s*/))
|
96
|
+
else
|
97
|
+
rdoc.rdoc_files.include('README', 'ChangeLog')
|
98
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
99
|
+
rdoc.rdoc_files.include('ext/**/*.c')
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
desc "Publish to RubyForge"
|
104
|
+
task :rubyforge => [:rdoc, :package] do
|
105
|
+
require 'rubyforge'
|
106
|
+
Rake::RubyForgePublisher.new(RUBYFORGE_PROJECT, 'kana').upload
|
107
|
+
end
|
108
|
+
|
109
|
+
desc 'Package and upload the release to rubyforge.'
|
110
|
+
task :release => [:clean, :package] do |t|
|
111
|
+
v = ENV["VERSION"] or abort "Must supply VERSION=x.y.z"
|
112
|
+
abort "Versions don't match #{v} vs #{VERS}" unless v == VERS
|
113
|
+
pkg = "pkg/#{NAME}-#{VERS}"
|
114
|
+
|
115
|
+
rf = RubyForge.new
|
116
|
+
puts "Logging in"
|
117
|
+
rf.login
|
118
|
+
|
119
|
+
c = rf.userconfig
|
120
|
+
# c["release_notes"] = description if description
|
121
|
+
# c["release_changes"] = changes if changes
|
122
|
+
c["preformatted"] = true
|
123
|
+
|
124
|
+
files = [
|
125
|
+
"#{pkg}.tgz",
|
126
|
+
"#{pkg}.gem"
|
127
|
+
].compact
|
128
|
+
|
129
|
+
puts "Releasing #{NAME} v. #{VERS}"
|
130
|
+
rf.add_release RUBYFORGE_PROJECT, NAME, VERS, *files
|
131
|
+
end
|
data/bin/QDMLParser
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
QDMLDIR = File.join(File.dirname(__FILE__),'..')
|
3
|
+
$LOAD_PATH << File.join(QDMLDIR,'lib')
|
4
|
+
|
5
|
+
require 'QParser'
|
6
|
+
require 'Parser'
|
7
|
+
require 'Qt'
|
8
|
+
|
9
|
+
require 'optparse'
|
10
|
+
|
11
|
+
opt = OptionParser.new
|
12
|
+
|
13
|
+
conf = {
|
14
|
+
:format => 'XML'
|
15
|
+
}
|
16
|
+
|
17
|
+
opt.on('-f','--format FORMAT'){|v|
|
18
|
+
conf[:format] = v
|
19
|
+
}
|
20
|
+
|
21
|
+
opt.on('-d', '--debug'){
|
22
|
+
QProc.debug_level = QProc::QDMLDebug::High
|
23
|
+
}
|
24
|
+
|
25
|
+
opt.on('--Debug-all'){
|
26
|
+
QProc.debug_level = QProc::QDMLDebug::ALL
|
27
|
+
}
|
28
|
+
|
29
|
+
opt.parse!(ARGV)
|
30
|
+
|
31
|
+
if ARGV.size != 1
|
32
|
+
puts opt.to_s
|
33
|
+
exit 1
|
34
|
+
end
|
35
|
+
|
36
|
+
fname = ARGV[0]
|
37
|
+
|
38
|
+
$app = Qt::Application.new(ARGV)
|
39
|
+
doc = QProc.parse(fname,conf[:format])
|
40
|
+
QProc.new(doc).show
|
41
|
+
$app.exec
|
data/lib/Parser.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
module Parser
|
2
|
+
class Element
|
3
|
+
attr_reader :namespace, :name, :attr ,:elements
|
4
|
+
|
5
|
+
def each(&block)
|
6
|
+
@elements.each(&block)
|
7
|
+
end
|
8
|
+
def each_element(&block)
|
9
|
+
each{|c| block.call(c) unless c.is_a?(String) }
|
10
|
+
end
|
11
|
+
def each_text(&block)
|
12
|
+
each{|c| block.call(c) if c.is_a?(String) }
|
13
|
+
end
|
14
|
+
def initialize(ns, n)
|
15
|
+
@namespace = ns.to_s
|
16
|
+
@name = n.to_s
|
17
|
+
@attr = Hash.new
|
18
|
+
@elements = Array.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
"<#{@namespace}:#{@name} #{@attr.map{|k,v| "#{k}=\"#{v}\"" }.join(" ")}>\n" +
|
23
|
+
"#{@elements.join("\n")}\n" +
|
24
|
+
"</#{@namespace}:#{@name}>"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class << self
|
29
|
+
def xml(string)
|
30
|
+
require 'rexml/document'
|
31
|
+
xml = REXML::Document.new string
|
32
|
+
|
33
|
+
y = Proc.new{|x|
|
34
|
+
e = Element.new(x.namespace, x.name)
|
35
|
+
x.attributes.each{|k,v| e.attr[k.to_sym] = v.to_s unless k =~ /^xmlns/}
|
36
|
+
x.each{|c|
|
37
|
+
if c.is_a? REXML::Text
|
38
|
+
e.elements.push c.to_s
|
39
|
+
else
|
40
|
+
e.elements.push y.call(c)
|
41
|
+
end
|
42
|
+
}
|
43
|
+
e
|
44
|
+
}
|
45
|
+
|
46
|
+
y.call(xml.root)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/QParser.rb
ADDED
@@ -0,0 +1,578 @@
|
|
1
|
+
#FIXME MAC OS X
|
2
|
+
#GC.disable
|
3
|
+
|
4
|
+
class QProc
|
5
|
+
begin
|
6
|
+
require 'Qt'
|
7
|
+
rescue LoadError
|
8
|
+
print "Load Error : [Qt] : Qt module not loaaded\n"
|
9
|
+
exit
|
10
|
+
end
|
11
|
+
|
12
|
+
#module Saving Class Name
|
13
|
+
module ClassId; end;
|
14
|
+
|
15
|
+
#original Exception
|
16
|
+
class QDMLException < Exception; end
|
17
|
+
|
18
|
+
#debug level
|
19
|
+
module QDMLDebug
|
20
|
+
Off,Minimal,ALL = 0,1,2
|
21
|
+
end
|
22
|
+
@@debug_level = QDMLDebug::Off
|
23
|
+
|
24
|
+
#default setting
|
25
|
+
@@default_layout = Qt::VBoxLayout
|
26
|
+
@@default_inheritance = Qt::Widget
|
27
|
+
@@filename_suffix = ".xml"
|
28
|
+
|
29
|
+
#class method
|
30
|
+
class << self
|
31
|
+
def debug_level=(level)
|
32
|
+
@@debug_level = level
|
33
|
+
end
|
34
|
+
def debug_level
|
35
|
+
@@debug_level
|
36
|
+
end
|
37
|
+
|
38
|
+
def default_layout=(layout)
|
39
|
+
unless Qt.const_defined? layout
|
40
|
+
error "non Qt Class Layout : #{layout}","default_layout"
|
41
|
+
return
|
42
|
+
end
|
43
|
+
@@default_layout = Qt.const_get(layout)
|
44
|
+
end
|
45
|
+
|
46
|
+
def default_layout
|
47
|
+
@@default_layout
|
48
|
+
end
|
49
|
+
|
50
|
+
def default_inheritance=(inheritance)
|
51
|
+
unless Qt.const_defined? inheritance
|
52
|
+
error "non Qt Class : #{inheritance}","default_inheritance"
|
53
|
+
return
|
54
|
+
end
|
55
|
+
@@default_inheritance = Qt.const_get(inheritance)
|
56
|
+
end
|
57
|
+
|
58
|
+
def default_inheritance
|
59
|
+
@@default_inheritance
|
60
|
+
end
|
61
|
+
|
62
|
+
def filename_suffix=(suffix)
|
63
|
+
@@filename_suffix = suffix
|
64
|
+
end
|
65
|
+
|
66
|
+
def filename_suffix
|
67
|
+
@@filename_suffix
|
68
|
+
end
|
69
|
+
|
70
|
+
def parse(fname,format = nil)
|
71
|
+
unless format
|
72
|
+
format = "XML"
|
73
|
+
end
|
74
|
+
self.__send__(:"#{format}",fname)
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
def XML(fname)
|
79
|
+
if File.exists? fname
|
80
|
+
Parser::xml File.read(fname)
|
81
|
+
else
|
82
|
+
Parser::xml fname
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def initialize(tree)
|
88
|
+
@tree = tree
|
89
|
+
@widget = nil
|
90
|
+
|
91
|
+
#Layoutの状態を保存するスタック
|
92
|
+
@layout = Array.new
|
93
|
+
|
94
|
+
#connect array
|
95
|
+
@carray = CArray.new
|
96
|
+
end
|
97
|
+
attr_reader :tree,:widget
|
98
|
+
|
99
|
+
def parse; run; end
|
100
|
+
def parseTree; parseRoot; end
|
101
|
+
|
102
|
+
def show
|
103
|
+
run
|
104
|
+
if @widget.methods.include? "show"
|
105
|
+
@widget.show
|
106
|
+
else
|
107
|
+
error "show method doesn't defined","show"
|
108
|
+
raise QDMLException, "show method doesn't defined"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
private
|
113
|
+
class SlotProc < Qt::Widget
|
114
|
+
def initialize(block)
|
115
|
+
super nil
|
116
|
+
@block = block
|
117
|
+
end
|
118
|
+
|
119
|
+
slots :call
|
120
|
+
def call; @block.call; end
|
121
|
+
end
|
122
|
+
|
123
|
+
class Connect
|
124
|
+
def initialize(widget,signal,value)
|
125
|
+
@wid = widget
|
126
|
+
@sig = signal
|
127
|
+
@value = value
|
128
|
+
|
129
|
+
self.class.module_eval{ include ::QProc::Messages }
|
130
|
+
end
|
131
|
+
def debug_level; QProc.debug_level; end
|
132
|
+
|
133
|
+
def connect(widget)
|
134
|
+
if @value[0] == "{"[0] then
|
135
|
+
unless @value[-1] == "}"[0] then
|
136
|
+
error "syntax ereror: ignore connect #{k}=\"#{@value}\"","connect"
|
137
|
+
return
|
138
|
+
end
|
139
|
+
|
140
|
+
pr = SlotProc.new( lambda{ widget.instance_eval( @value[1..-2] ) } )
|
141
|
+
target = pr
|
142
|
+
slot = :call
|
143
|
+
else
|
144
|
+
if @value.index '.'
|
145
|
+
t,s = @value.split('.')
|
146
|
+
target = widget.instance_variable_get(t.to_sym)
|
147
|
+
|
148
|
+
debug "target name = #{t} target = #{target}","connect" if debug_level >= QDMLDebug::Minimal
|
149
|
+
slot = s.to_sym
|
150
|
+
else
|
151
|
+
target = widget
|
152
|
+
slot = @value.to_sym
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
debug "target is #{target} , widget is #{widget}","connect" if debug_level >= QDMLDebug::Minimal
|
157
|
+
widget.connect(@wid,SIGNAL(@sig),target,SLOT(slot))
|
158
|
+
end
|
159
|
+
def to_s
|
160
|
+
"connect #{@wid} #{@sig} #{@value}"
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
class CArray
|
165
|
+
def initialize
|
166
|
+
@array = Array.new
|
167
|
+
self.class.module_eval{ include ::QProc::Messages }
|
168
|
+
end
|
169
|
+
def debug_level; QProc.debug_level; end
|
170
|
+
def <<(op); @array.push op; end
|
171
|
+
|
172
|
+
def connect(widget)
|
173
|
+
@array.each{|c| c.connect widget; debug c.to_s,"connect" if debug_level >= QDMLDebug::Minimal }
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def parseRoot
|
178
|
+
setRootLayout(@widget,@tree.attr[:layout])
|
179
|
+
@tree.attr.delete :layout
|
180
|
+
|
181
|
+
attrprocess(@widget,@tree.attr)
|
182
|
+
|
183
|
+
@tree.each_element{|e|
|
184
|
+
#Igonore "Script tag"'s children element
|
185
|
+
if e.name == "script" || e.name == "Script"
|
186
|
+
if e.attr.has_key? :source
|
187
|
+
path = e.attr[:source]
|
188
|
+
info "load source file: #{path}"
|
189
|
+
@widget.class.module_eval File.read(path)
|
190
|
+
else
|
191
|
+
script = ""
|
192
|
+
e.each_text{|t| script += t }
|
193
|
+
|
194
|
+
debug "#{script}","parseRoot" if @@debug_level >= QDMLDebug::ALL
|
195
|
+
|
196
|
+
@widget.class.module_eval(script)
|
197
|
+
|
198
|
+
debug "script tag added","parseRoot" if @@debug_level >= QDMLDebug::Minimal
|
199
|
+
end
|
200
|
+
else
|
201
|
+
nextChild e
|
202
|
+
end
|
203
|
+
}
|
204
|
+
end
|
205
|
+
|
206
|
+
def setRootSource
|
207
|
+
if @tree.attr.has_key? :source
|
208
|
+
if File.exist? @tree.attr[:source]
|
209
|
+
require @tree.attr[:source]
|
210
|
+
else
|
211
|
+
warning "file not found #{@tree.attr[:source]}","parseRoot"
|
212
|
+
end
|
213
|
+
@tree.attr.delete :source
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
def run
|
218
|
+
setRootSource
|
219
|
+
if @tree.elements.size == 0
|
220
|
+
attrs = @tree.attr
|
221
|
+
setRootSource
|
222
|
+
@widget = classnew(@tree.name,attrs)
|
223
|
+
attrprocess(@widget,attrs)
|
224
|
+
else
|
225
|
+
if @tree.name == "Application"
|
226
|
+
if @tree.attr.has_key? :inheritance
|
227
|
+
klassname = @tree.attr[:inheritance].to_s
|
228
|
+
unless Qt.constants.include? klassname
|
229
|
+
error "inheritance specify non supported class #{klassname}","parse"
|
230
|
+
raise QDMLException, "inheritance specify non supported class #{klassname}"
|
231
|
+
end
|
232
|
+
|
233
|
+
@tree.attr.delete :inheritance
|
234
|
+
inheritance = Qt.const_get klassname
|
235
|
+
else
|
236
|
+
inheritance = @@default_inheritance
|
237
|
+
end
|
238
|
+
elsif Qt.constants.include? @tree.name
|
239
|
+
inheritance = Qt.const_get @tree.name
|
240
|
+
elsif Object.constants.include? @tree.name
|
241
|
+
inheritance = Object.const_get(:"#{@tree.name}")
|
242
|
+
|
243
|
+
unless inheritance.ancestors.include? Qt::Base
|
244
|
+
error "inheritance specify non supported class #{@tree.name}: non inheritance Qt::Base", "parse"
|
245
|
+
raise QDMLException,"inheritance specify non supported class #{@tree.name}"
|
246
|
+
end
|
247
|
+
else
|
248
|
+
error "root element specify non supported #{@tree.name}","parse"
|
249
|
+
raise QDMLException, "root element specify non supported #{@tree.name}"
|
250
|
+
end
|
251
|
+
|
252
|
+
info "inheritance is #{inheritance}"
|
253
|
+
|
254
|
+
this = self
|
255
|
+
klass = Class.new(inheritance){
|
256
|
+
define_method(:initialize){
|
257
|
+
super(nil)
|
258
|
+
@self = this
|
259
|
+
@_self = self
|
260
|
+
}
|
261
|
+
|
262
|
+
define_method(:_parse){
|
263
|
+
@self.parseTree
|
264
|
+
}
|
265
|
+
}
|
266
|
+
|
267
|
+
id = klass.object_id.to_s(16).gsub('-','_')
|
268
|
+
|
269
|
+
unless ClassId.const_defined? :"I#{id}"
|
270
|
+
ClassId.const_set(:"I#{id}",klass)
|
271
|
+
else
|
272
|
+
error "same constants defined I#{id}","parse"
|
273
|
+
raise QDMLException, "same constants defined I#{id}"
|
274
|
+
end
|
275
|
+
|
276
|
+
@widget = klass.new
|
277
|
+
@widget._parse
|
278
|
+
|
279
|
+
if @widget.class.method_defined? :_init
|
280
|
+
@widget._init
|
281
|
+
debug "init call #{@widget}","parse" if @@debug_level >= QDMLDebug::Minimal
|
282
|
+
end
|
283
|
+
|
284
|
+
evalconnect
|
285
|
+
end
|
286
|
+
|
287
|
+
@widget
|
288
|
+
end
|
289
|
+
|
290
|
+
def errorattr(attrs)
|
291
|
+
attrs.each{|k,v| warning "non processed attributes #{k} = #{v}", "errorattr" }
|
292
|
+
end
|
293
|
+
|
294
|
+
def attrprocess(widget,attrs)
|
295
|
+
connect(widget,attrs)
|
296
|
+
executeattr(widget,attrs)
|
297
|
+
errorattr(attrs)
|
298
|
+
end
|
299
|
+
|
300
|
+
def parseElement(widget,element)
|
301
|
+
registInstance(widget,element.attr)
|
302
|
+
attrprocess(widget,element.attr)
|
303
|
+
|
304
|
+
#WidgetがLayoutだった場合
|
305
|
+
if widget.methods.include? "addLayout"
|
306
|
+
debug "addLayout #{widget}","parseElement" if @@debug_level >= QDMLDebug::Minimal
|
307
|
+
|
308
|
+
unless @layout.empty?
|
309
|
+
layout = @layout.pop
|
310
|
+
layout.addLayout widget
|
311
|
+
@layout.push layout
|
312
|
+
end
|
313
|
+
|
314
|
+
#現在のLayoutを退避
|
315
|
+
@layout.push widget
|
316
|
+
|
317
|
+
#next child
|
318
|
+
element.each_element{|e| nextChild e }
|
319
|
+
|
320
|
+
#Layoutを元に戻す
|
321
|
+
widget = @layout.pop
|
322
|
+
else
|
323
|
+
layout = @layout.pop
|
324
|
+
|
325
|
+
#Widgetを現在のレイアウトに追加
|
326
|
+
debug "addWidget #{widget}","parseElement" if @@debug_level >= QDMLDebug::Minimal
|
327
|
+
|
328
|
+
if @layout.size != 0
|
329
|
+
layout.addWidget(widget)
|
330
|
+
else
|
331
|
+
@widget.layout.addWidget(widget)
|
332
|
+
end
|
333
|
+
|
334
|
+
@layout.push layout
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
def nextChild(element)
|
339
|
+
if !element.namespace.empty?
|
340
|
+
if File.exist? element.namespace
|
341
|
+
debug "other file read start : #{element.namespace}","nextChild" if @@debug_level >= QDMLDebug::Minimal
|
342
|
+
|
343
|
+
path = File.join(element.namespace,element.name) + @@filename_suffix
|
344
|
+
|
345
|
+
unless File.exist? path
|
346
|
+
error "File not found: ignore #{path}","nextChild"
|
347
|
+
return
|
348
|
+
end
|
349
|
+
|
350
|
+
xml = Parser::xml File.read(path)
|
351
|
+
widget = QProc.new(xml).parse
|
352
|
+
registInstance(widget,element.attr)
|
353
|
+
|
354
|
+
attrprocess(widget,element.attr)
|
355
|
+
|
356
|
+
layout = @layout.pop
|
357
|
+
|
358
|
+
if widget.methods.include? "addLayout"
|
359
|
+
layout.addLayout widget
|
360
|
+
else
|
361
|
+
layout.addWidget widget
|
362
|
+
end
|
363
|
+
|
364
|
+
@layout.push layout
|
365
|
+
|
366
|
+
debug "other file read end","nextChild" if @@debug_level >= QDMLDebug::Minimal
|
367
|
+
else
|
368
|
+
error "Directory not found: ignore #{element.namespace}","nextChild"
|
369
|
+
end
|
370
|
+
elsif Qt.const_defined?(element.name) || Object.const_defined?(element.name) || @widget.class.const_defined?(element.name)
|
371
|
+
widget = classnew(element.name,element.attr)
|
372
|
+
parseElement(widget,element)
|
373
|
+
else
|
374
|
+
error "No Class: ignore #{element.name}","nextChild"
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
def connect(widget,attrs)
|
379
|
+
attrs.each{|k,v|
|
380
|
+
key = k.to_s
|
381
|
+
if key =~ /^s:/
|
382
|
+
signal = key[2..-1].to_sym
|
383
|
+
debug "connect added", "connect" if @@debug_level >= QDMLDebug::ALL
|
384
|
+
@carray << Connect.new(widget,signal,v)
|
385
|
+
attrs.delete k
|
386
|
+
end
|
387
|
+
}
|
388
|
+
end
|
389
|
+
def evalconnect; @carray.connect @widget; end
|
390
|
+
|
391
|
+
def classnew(name,attrs)
|
392
|
+
debug "name: #{name}","classnew" if @@debug_level >= QDMLDebug::Minimal
|
393
|
+
|
394
|
+
if Qt.const_defined? name
|
395
|
+
klass = Qt.const_get(name)
|
396
|
+
elsif Object.const_defined? name
|
397
|
+
klass = Object.const_get(name)
|
398
|
+
elsif @widget.class.const_defined? name
|
399
|
+
klass = @widget.class.const_get(name)
|
400
|
+
else
|
401
|
+
error "no class #{name} : class not found","classnew"
|
402
|
+
raise QDMLException,"class not found #{name}"
|
403
|
+
end
|
404
|
+
|
405
|
+
unless klass.ancestors.include? Qt::Base
|
406
|
+
error "not Qt class #{name}","class new"
|
407
|
+
raise QDMLException,"not Qt class #{name}"
|
408
|
+
end
|
409
|
+
|
410
|
+
if attrs.has_key? :constractor
|
411
|
+
constractor = attrs[:constractor]
|
412
|
+
attrs.delete :constractor
|
413
|
+
|
414
|
+
if constractor[0] != "{"[0]
|
415
|
+
warning "constractor specify \"{ruby script}\"","classnew"
|
416
|
+
widget = klass.new
|
417
|
+
else
|
418
|
+
widget = klass.__send__(:new , eval(constractor[1..-2]))
|
419
|
+
end
|
420
|
+
else
|
421
|
+
widget = klass.new
|
422
|
+
end
|
423
|
+
widget
|
424
|
+
end
|
425
|
+
|
426
|
+
def setRootLayout(widget,layoutname)
|
427
|
+
if widget.methods.include? "addLayout"
|
428
|
+
info "target widget is layout"
|
429
|
+
info "skip set root layout"
|
430
|
+
@layout.push widget
|
431
|
+
return
|
432
|
+
end
|
433
|
+
|
434
|
+
unless layoutname
|
435
|
+
layout = @@default_layout.new
|
436
|
+
@layout.push layout
|
437
|
+
widget.layout = layout
|
438
|
+
return
|
439
|
+
end
|
440
|
+
|
441
|
+
layout = nil
|
442
|
+
if Qt.const_defined? layoutname
|
443
|
+
info "layout specify #{layoutname} by user"
|
444
|
+
layout = Qt.const_get(layoutname).new
|
445
|
+
elsif @widget.class.const_defined? layoutname
|
446
|
+
info "layout specify #{layoutname} by user"
|
447
|
+
layout = @widget.class.const_get(layoutname).new
|
448
|
+
elsif Object.const_defined? layoutname
|
449
|
+
info "layout specify #{layoutname} by user"
|
450
|
+
layout = Object.const_defined? layoutname
|
451
|
+
else
|
452
|
+
layout = @@default_layout.new
|
453
|
+
end
|
454
|
+
@layout.push layout
|
455
|
+
widget.layout = layout
|
456
|
+
end
|
457
|
+
|
458
|
+
def registInstance(widget,attrs)
|
459
|
+
if attrs.has_key? :id
|
460
|
+
@widget.instance_variable_set("@#{attrs[:id]}",widget)
|
461
|
+
@widget.class.module_eval("attr_reader :#{attrs[:id]}")
|
462
|
+
|
463
|
+
debug "regist instance variable #{attrs[:id]} = #{widget}","parseElement" if @@debug_level >= QDMLDebug::Minimal
|
464
|
+
|
465
|
+
attrs.delete :id
|
466
|
+
end
|
467
|
+
end
|
468
|
+
|
469
|
+
def executeattr(widget,attrs)
|
470
|
+
if attrs != nil then
|
471
|
+
attrs.each{ |a,e|
|
472
|
+
|
473
|
+
#layout attributes
|
474
|
+
if a.to_s =~ /^l:.*$/
|
475
|
+
unless widget.layout #widget.layout == nil
|
476
|
+
warning "layout is nil","executeattr"
|
477
|
+
next
|
478
|
+
end
|
479
|
+
executeattr(widget.layout, { :"#{(a.to_s)[2,(a.to_s).size]}" => e } )
|
480
|
+
attrs.delete a
|
481
|
+
next
|
482
|
+
end
|
483
|
+
|
484
|
+
#use accessor
|
485
|
+
if widget.class.instance_methods.include? a.to_s+"="
|
486
|
+
if e =~ /^\{(.*)\}$/
|
487
|
+
arg = "[" + $~[1] + "]"
|
488
|
+
widget.__send__(a.to_s+"=",*(eval(arg)))
|
489
|
+
debug "accessor called #{a}=(#{arg})","executeattr" if @@debug_level >= QDMLDebug::Minimal
|
490
|
+
else
|
491
|
+
widget.__send__(a.to_s+"=",e)
|
492
|
+
debug "accessor called #{a}=(#{e})","executeattr" if @@debug_level >= QDMLDebug::Minimal
|
493
|
+
end
|
494
|
+
attrs.delete a
|
495
|
+
next
|
496
|
+
end
|
497
|
+
|
498
|
+
#method execute
|
499
|
+
if widget.class.instance_methods.include? a.to_s
|
500
|
+
if e =~ /^\{(.*)\}$/
|
501
|
+
arg = "[" + $~[1] + "]"
|
502
|
+
widget.__send__(a.to_s,*(eval(arg)))
|
503
|
+
debug "method called #{a}(#{arg})","executeattr" if @@debug_level >= QDMLDebug::Minimal
|
504
|
+
end
|
505
|
+
attrs.delete a
|
506
|
+
next
|
507
|
+
end
|
508
|
+
}
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
module Messages
|
513
|
+
begin
|
514
|
+
require 'rubygems'
|
515
|
+
require 'term/ansicolor'
|
516
|
+
def error msg,method = nil
|
517
|
+
if method
|
518
|
+
print Term::ANSIColor::red, "[error][#{method}]:" + msg , Term::ANSIColor::reset , "\n"
|
519
|
+
else
|
520
|
+
print Term::ANSIColor::red, "[error] " + msg , Term::ANSIColor::reset , "\n"
|
521
|
+
end
|
522
|
+
end
|
523
|
+
def warning msg,method = nil
|
524
|
+
if method
|
525
|
+
print Term::ANSIColor::yellow, "[warning][#{method}]:" + msg , Term::ANSIColor::reset , "\n"
|
526
|
+
else
|
527
|
+
print Term::ANSIColor::yellow, "[warning] " + msg , Term::ANSIColor::reset , "\n"
|
528
|
+
end
|
529
|
+
end
|
530
|
+
def info msg,method = nil
|
531
|
+
if method
|
532
|
+
print "[info][#{method}]: " + msg + "\n"
|
533
|
+
else
|
534
|
+
print "[info] " + msg + "\n"
|
535
|
+
end
|
536
|
+
end
|
537
|
+
def debug msg,method = nil
|
538
|
+
if method
|
539
|
+
print Term::ANSIColor::blue, "[debug][#{method}]:" + msg , Term::ANSIColor::reset , "\n"
|
540
|
+
else
|
541
|
+
print Term::ANSIColor::blue, "[debug] " + msg , Term::ANSIColor::reset , "\n"
|
542
|
+
end
|
543
|
+
end
|
544
|
+
rescue LoadError
|
545
|
+
print "Load Error : [term-ansicolor] : error messages not coloring\n"
|
546
|
+
|
547
|
+
def error msg,method = nil
|
548
|
+
if method
|
549
|
+
print "[error][#{method}]:" + msg , "\n"
|
550
|
+
else
|
551
|
+
print "[error] " + msg , "\n"
|
552
|
+
end
|
553
|
+
end
|
554
|
+
def warning msg,method = nil
|
555
|
+
if method
|
556
|
+
print "[warning][#{method}]:" + msg , "\n"
|
557
|
+
else
|
558
|
+
print "[warning] " + msg , "\n"
|
559
|
+
end
|
560
|
+
end
|
561
|
+
def info msg,method = nil
|
562
|
+
if method
|
563
|
+
print "[info][#{method}]: " + msg + "\n"
|
564
|
+
else
|
565
|
+
print "[info] " + msg + "\n"
|
566
|
+
end
|
567
|
+
end
|
568
|
+
def debug msg,method = nil
|
569
|
+
if method
|
570
|
+
print "[debug][#{method}]:" + msg , "\n"
|
571
|
+
else
|
572
|
+
print "[debug] " + msg , "\n"
|
573
|
+
end
|
574
|
+
end
|
575
|
+
end
|
576
|
+
end
|
577
|
+
include Messages
|
578
|
+
end
|
data/test/qdml_test.rb
ADDED
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: qdml
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- kana
|
8
|
+
autorequire: ""
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-12-13 00:00:00 +09:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: ""
|
17
|
+
email: white.kna@gmail.com
|
18
|
+
executables:
|
19
|
+
- QDMLParser
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- README
|
24
|
+
- ChangeLog
|
25
|
+
files:
|
26
|
+
- README
|
27
|
+
- ChangeLog
|
28
|
+
- Rakefile
|
29
|
+
- bin/QDMLParser
|
30
|
+
- test/qdml_test.rb
|
31
|
+
- test/test_helper.rb
|
32
|
+
- lib/Parser.rb
|
33
|
+
- lib/QParser.rb
|
34
|
+
has_rdoc: true
|
35
|
+
homepage: http://qdml.rubyforge.org
|
36
|
+
post_install_message:
|
37
|
+
rdoc_options:
|
38
|
+
- --title
|
39
|
+
- qdml documentation
|
40
|
+
- --charset
|
41
|
+
- utf-8
|
42
|
+
- --opname
|
43
|
+
- index.html
|
44
|
+
- --line-numbers
|
45
|
+
- --main
|
46
|
+
- README
|
47
|
+
- --inline-source
|
48
|
+
- --exclude
|
49
|
+
- ^(examples|extras)/
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: "0"
|
57
|
+
version:
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: "0"
|
63
|
+
version:
|
64
|
+
requirements: []
|
65
|
+
|
66
|
+
rubyforge_project: qdml
|
67
|
+
rubygems_version: 1.3.0
|
68
|
+
signing_key:
|
69
|
+
specification_version: 2
|
70
|
+
summary: ""
|
71
|
+
test_files:
|
72
|
+
- test/test_helper.rb
|