qtext 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,10 @@
1
+ == 0.6.0
2
+ * add Qt::Widget.signal class method which adds some signal emitting and
3
+ handling methods.
4
+ * remove Qt::Widget.construct and construct_exec because they're already part
5
+ of Qt::Widget.new
6
+ * Documentation
7
+ * Some testing
8
+
9
+ == 0.5.0
10
+ * Add ActionBuilder to create menus and other sets of Qt::Action objects
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 FIXME full name
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,24 @@
1
+ History.txt
2
+ License.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ config/hoe.rb
7
+ config/requirements.rb
8
+ env.sh
9
+ lib/qtext.rb
10
+ lib/qtext/action_builder.rb
11
+ lib/qtext/extensions.rb
12
+ lib/qtext/flags.rb
13
+ lib/qtext/object_table_model.rb
14
+ lib/qtext/version.rb
15
+ script/console
16
+ script/destroy
17
+ script/generate
18
+ script/txt2html
19
+ tasks/deployment.rake
20
+ tasks/environment.rake
21
+ tasks/website.rake
22
+ test/test_helper.rb
23
+ test/test_object_table.rb
24
+ test/test_widget.rb
data/README.txt CHANGED
@@ -1,32 +1,39 @@
1
1
  = qtext
2
2
 
3
- * FIX (url)
3
+ http://rubyforge.org/projects/qtext
4
4
 
5
5
  == DESCRIPTION:
6
6
 
7
- Some extensions to qt4-qtruby to make it more rubyish
7
+ Some extensions to qt4-qtruby to make it more rubyish.
8
8
 
9
- == FEATURES/PROBLEMS:
10
-
11
- * FIX (list of features or problems)
9
+ == FEATURES
10
+ - ActionBuilder module to simplify creating Action objects for inclusion into menus.
11
+ - ObjectTableModel so that you can easily display a collection of objects in a table
12
+ - signal and construct_signal for Qt::Widget to reduce the need for c++ signatures
13
+ - to_variant method for Object. Specific overrides for some objects.
14
+ - invalid method for Qt::ModelIndex to cache creation of an empty index
15
+ - invalid method for Qt::Variant to cache creation of an empty variant
16
+ - KeyEvent instances will respond to things like delete? (the delete key) for most keys
17
+ - value method for some widgets (RadioButton, CheckBox), returning the value of the widget
12
18
 
13
19
  == SYNOPSIS:
14
20
 
15
- FIX (code sample of usage)
21
+ require 'qtext'
16
22
 
17
23
  == REQUIREMENTS:
18
24
 
19
- * FIX (list of requirements)
20
-
25
+ - qtruby4
26
+ - Shoulda if you want to run tests
27
+ - ActiveSupport. Only needed in Header for humanize.
21
28
  == INSTALL:
22
29
 
23
- * FIX (sudo gem install, anything else)
30
+ sudo gem install qtext
24
31
 
25
32
  == LICENSE:
26
33
 
27
34
  (The MIT License)
28
35
 
29
- Copyright (c) 2008 FIX
36
+ Copyright (c) 2008 John Anderson
30
37
 
31
38
  Permission is hereby granted, free of charge, to any person obtaining
32
39
  a copy of this software and associated documentation files (the
@@ -0,0 +1,4 @@
1
+ require 'config/requirements'
2
+ require 'config/hoe' # setup Hoe + all gem configuration
3
+
4
+ Dir['tasks/**/*.rake'].each { |rake| load rake }
@@ -0,0 +1,73 @@
1
+ require 'qtext/version'
2
+
3
+ AUTHOR = 'FIXME full name' # can also be an array of Authors
4
+ EMAIL = "panic@semiosix.com"
5
+ DESCRIPTION = "description of gem"
6
+ GEM_NAME = 'qtext' # what ppl will type to install your gem
7
+ RUBYFORGE_PROJECT = 'qtext' # The unix name for your project
8
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
9
+ DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
10
+ EXTRA_DEPENDENCIES = [
11
+ # ['activesupport', '>= 1.3.1']
12
+ ] # An array of rubygem dependencies [name, version]
13
+
14
+ @config_file = "~/.rubyforge/user-config.yml"
15
+ @config = nil
16
+ RUBYFORGE_USERNAME = "unknown"
17
+ def rubyforge_username
18
+ unless @config
19
+ begin
20
+ @config = YAML.load(File.read(File.expand_path(@config_file)))
21
+ rescue
22
+ puts <<-EOS
23
+ ERROR: No rubyforge config file found: #{@config_file}
24
+ Run 'rubyforge setup' to prepare your env for access to Rubyforge
25
+ - See http://newgem.rubyforge.org/rubyforge.html for more details
26
+ EOS
27
+ exit
28
+ end
29
+ end
30
+ RUBYFORGE_USERNAME.replace @config["username"]
31
+ end
32
+
33
+
34
+ REV = nil
35
+ # UNCOMMENT IF REQUIRED:
36
+ # REV = YAML.load(`svn info`)['Revision']
37
+ VERS = Qtext::VERSION::STRING + (REV ? ".#{REV}" : "")
38
+ RDOC_OPTS = ['--quiet', '--title', 'qtext documentation',
39
+ "--opname", "index.html",
40
+ "--line-numbers",
41
+ "--main", "README",
42
+ "--inline-source"]
43
+
44
+ class Hoe
45
+ def extra_deps
46
+ @extra_deps.reject! { |x| Array(x).first == 'hoe' }
47
+ @extra_deps
48
+ end
49
+ end
50
+
51
+ # Generate all the Rake tasks
52
+ # Run 'rake -T' to see list of generated tasks (from gem root directory)
53
+ $hoe = Hoe.new(GEM_NAME, VERS) do |p|
54
+ p.developer(AUTHOR, EMAIL)
55
+ p.description = DESCRIPTION
56
+ p.summary = DESCRIPTION
57
+ p.url = HOMEPATH
58
+ p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
59
+ p.test_globs = ["test/**/test_*.rb"]
60
+ p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
61
+
62
+ # == Optional
63
+ p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
64
+ #p.extra_deps = EXTRA_DEPENDENCIES
65
+
66
+ #p.spec_extras = {} # A hash of extra values to set in the gemspec.
67
+ end
68
+
69
+ CHANGES = $hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
70
+ PATH = (RUBYFORGE_PROJECT == GEM_NAME) ? RUBYFORGE_PROJECT : "#{RUBYFORGE_PROJECT}/#{GEM_NAME}"
71
+ $hoe.remote_rdoc_dir = File.join(PATH.gsub(/^#{RUBYFORGE_PROJECT}\/?/,''), '')
72
+ $hoe.rsync_args = '-av --delete --ignore-errors'
73
+ $hoe.spec.post_install_message = File.open(File.dirname(__FILE__) + "/../PostInstall.txt").read rescue ""
@@ -0,0 +1,15 @@
1
+ require 'fileutils'
2
+ include FileUtils
3
+
4
+ require 'rubygems'
5
+ %w[rake hoe newgem rubigen].each do |req_gem|
6
+ begin
7
+ require req_gem
8
+ rescue LoadError
9
+ puts "This Rakefile requires the '#{req_gem}' RubyGem."
10
+ puts "Installation: gem install #{req_gem} -y"
11
+ exit
12
+ end
13
+ end
14
+
15
+ $:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
data/env.sh ADDED
@@ -0,0 +1 @@
1
+ export RUBYLIB=$RUBYLIB:`pwd`/lib
@@ -1,66 +1,95 @@
1
1
  require 'Qt4'
2
2
  require 'qtext/extensions.rb'
3
3
 
4
+ # The declaration of module Find in the require breaks
5
+ # the constant in Qt::KeySequence. It's a bug in the Qt bindings.
6
+ begin
7
+ $old_qt_key_sequence_find_value = Qt::KeySequence::Find
8
+ require 'find'
9
+ if Qt::KeySequence::Find == Find
10
+ module Qt
11
+ class KeySequence
12
+ Find = $old_qt_key_sequence_find_value
13
+ end
14
+ end
15
+ end
16
+
17
+ end
18
+
4
19
  =begin rdoc
5
- This module can be used to make the construction of collections of actions
6
- more rubyish. Menus are generally made up of a collection of actions.
20
+ This module can be used in an object that has
21
+ an add_action method (usually a subclass of Qt::Widget) to make the construction of
22
+ collections of actions more rubyish.
23
+ Menus are generally made up of a collection of actions.
7
24
 
8
- Once included, it's intended to be called as follows, where self is a descendant of Qt::Widget:
9
- build_actions do
10
- list( :edit ) do
11
- #~ new_action :action_cut, 'Cu&t', :shortcut => Qt::KeySequence::Cut
12
- action :action_copy, '&Copy', :shortcut => Qt::KeySequence::Copy, :method => :copy_current_selection
13
- action :action_paste, '&Paste', :shortcut => Qt::KeySequence::Paste, :method => :paste
14
- separator
15
- action :action_ditto, '&Ditto', :shortcut => 'Ctrl+\'', :method => :ditto, :tool_tip => 'Copy same field from previous record'
16
- action :action_ditto_right, 'Ditto R&ight', :shortcut => 'Ctrl+]', :method => :ditto_right, :tool_tip => 'Copy field one to right from previous record'
17
- action :action_ditto_left, '&Ditto L&eft', :shortcut => 'Ctrl+[', :method => :ditto_left, :tool_tip => 'Copy field one to left from previous record'
18
- action :action_insert_date, 'Insert Date', :shortcut => 'Ctrl+;', :method => :insert_current_date
19
- action :action_open_editor, '&Open Editor', :shortcut => 'F4', :method => :open_editor
20
- separator
21
- action :action_row, 'New Ro&w', :shortcut => 'Ctrl+N', :method => :row
22
- action :action_refresh, '&Refresh', :shortcut => 'Ctrl+R', :method => :refresh
23
- action :action_delete_rows, 'Delete Rows', :shortcut => 'Ctrl+Delete', :method => :delete_rows
24
-
25
- if $options[:debug]
26
- action :action_dump, 'D&ump', :shortcut => 'Ctrl+Shift+D' do
27
- puts model.collection[current_index.row].inspect
25
+ Once included, it's intended to be called as follows:
26
+ def some_setup_method_or_other
27
+ build_actions do
28
+ list :edit do
29
+ #~ new_action :action_cut, 'Cu&t', :shortcut => Qt::KeySequence::Cut
30
+ action :action_copy, '&Copy', :shortcut => Qt::KeySequence::Copy, :method => :copy_current_selection
31
+ action :action_paste, '&Paste', :shortcut => Qt::KeySequence::Paste, :method => :paste
32
+ separator
33
+ action :action_ditto, '&Ditto', :shortcut => 'Ctrl+\'', :method => :ditto, :tool_tip => 'Copy same field from previous record'
34
+ action :action_ditto_right, 'Ditto R&ight', :shortcut => 'Ctrl+]', :method => :ditto_right, :tool_tip => 'Copy field one to right from previous record'
35
+ action :action_ditto_left, '&Ditto L&eft', :shortcut => 'Ctrl+[', :method => :ditto_left, :tool_tip => 'Copy field one to left from previous record'
36
+ action :action_insert_date, 'Insert Date', :shortcut => 'Ctrl+;', :method => :insert_current_date
37
+ action :action_open_editor, '&Open Editor', :shortcut => 'F4', :method => :open_editor
38
+ separator
39
+ action :action_row, 'New Ro&w', :shortcut => 'Ctrl+N', :method => :row
40
+ action :action_refresh, '&Refresh', :shortcut => 'Ctrl+R', :method => :refresh
41
+ action :action_delete_rows, 'Delete Rows', :shortcut => 'Ctrl+Delete', :method => :delete_rows
42
+
43
+ if $options[:debug]
44
+ action :action_dump, 'D&ump', :shortcut => 'Ctrl+Shift+D' do
45
+ puts model.collection[current_index.row].inspect
46
+ end
28
47
  end
29
48
  end
49
+
50
+ separator
30
51
  end
31
-
32
- separator
33
52
  end
34
-
35
- You can also do something like this:
36
-
53
+ Or you can pass a parameter to the block if you need access to surrounding variables:
37
54
  build_actions do |ab|
38
- ab.list( :edit ) do
55
+ ab.list :edit do
39
56
  #~ new_action :action_cut, 'Cu&t', :shortcut => Qt::KeySequence::Cut
40
57
  ab.action :action_copy, '&Copy', :shortcut => Qt::KeySequence::Copy, :method => :copy_current_selection
41
58
  end
42
59
  end
43
-
44
60
  If the including class defines a method called action_triggered( &block ),
45
61
  it can be used to wrap the code triggered by actions. That way, the
46
62
  including class
47
- can catch exceptions and things like that. If this method is not
48
- defined, it will be defined as an empty wrapper.
63
+ can catch exceptions and things like that.
64
+ def action_triggered( &block )
65
+ catch :something_happened do
66
+ yield
67
+ end
68
+ end
69
+ If this method is not defined, it will be created in the including class as an empty wrapper.
49
70
  =end
50
71
  module ActionBuilder
51
- def build_actions( &block )
52
- yield( self )
53
- end
54
-
55
- def collect_actions
56
- @collect_actions ||= []
72
+ # raise a RuntimeError if the including class/module does not define add_action
73
+ def self.included( including_module )
74
+ shortlist = including_module.instance_methods.grep /action/i
75
+ # add_action is actually an method_missing lookup for addAction, so
76
+ # search for both.
77
+ unless shortlist.any? {|x| %w{add_action addAction}.include?( x )}
78
+ raise NotImplementedError( "#{including_module.class.name} must have an add_action method" )
79
+ end
57
80
  end
58
81
 
59
- def collect_actions=( arr )
60
- @collect_actions = arr
82
+ # Outer block for the build process.
83
+ def build_actions( &block )
84
+ raise 'a block must be present' if block.nil?
85
+ if block.arity == -1
86
+ instance_eval &block
87
+ else
88
+ yield self
89
+ end
61
90
  end
62
91
 
63
- # create a new separator
92
+ # Create a new separator and add a new separator.
64
93
  def separator
65
94
  Qt::Action.construct( parent ) do |action|
66
95
  action.separator = true
@@ -69,27 +98,29 @@ module ActionBuilder
69
98
  end
70
99
  end
71
100
 
72
- # create and return a list of actions. The actions are grouped together, but not
73
- # as strongly as with Qt::ActionGroup
74
- # a method called "#{group_name}_actions" will be added to self, which will return the
75
- # set of Qt::Action instances created in the block
101
+ # Create and return a list of actions. The actions are grouped together, but not
102
+ # as strongly as with Qt::ActionGroup.
103
+ # A method called "#{group_name}_actions" will be added to self, which will return the
104
+ # set of Qt::Action instances created in the block.
76
105
  def list( group_name, &block )
77
106
  unless respond_to?( "#{group_name.to_s}_actions" )
78
107
  self.class.send( :define_method, "#{group_name.to_s}_actions" ) do
79
108
  eval "@#{group_name.to_s}_actions"
80
109
  end
81
110
  end
82
- self.collect_actions = []
111
+ self.collect_actions.clear
83
112
  yield( self )
84
113
  # copy actions to the right instance variable
85
114
  eval "@#{group_name.to_s}_actions = collect_actions"
86
115
  end
87
116
 
88
- # Create an action and add_action
89
- # block takes predence over options[:method], which is a method
117
+ # Create a new Qt::Action and
118
+ # 1. pass it to Qt::Widget::add_action
119
+ # 1. add it to the collect_actions collection.
120
+ # The block takes predence over options[:method], which is a method
90
121
  # on self to be called.
91
- # option keys can be any method in Qt::Action, ie :tool_tip, :shortcut, :status_tip etc
92
- # a value for :shortcut is automatically passed to Qt::KeySequence.new
122
+ # Option keys can be any method in Qt::Action, ie :tool_tip, :shortcut, :status_tip etc.
123
+ # A value for :shortcut is automatically passed to Qt::KeySequence.new.
93
124
  def action( name_or_action, text = nil, options = {}, &block )
94
125
  if name_or_action.class == Qt::Action
95
126
  add_action( name_or_action )
@@ -114,15 +145,27 @@ module ActionBuilder
114
145
  # add action for Qt
115
146
  add_action action
116
147
 
117
- # add actions for list. Yes, it's a side-effect. Is there a better way?
148
+ # add actions for list. Yes, it's a side-effect.
149
+ # TODO is there a better way to do this?
118
150
  collect_actions << action
119
151
 
120
152
  action_method_or_block( action, options, &block )
121
153
  end
122
154
  end
123
155
  end
156
+
157
+ protected
158
+
159
+ # the set of actions created so far in a particular list.
160
+ def collect_actions
161
+ @collect_actions ||= []
162
+ end
163
+
164
+ def collect_actions=( arr )
165
+ @collect_actions = arr
166
+ end
124
167
 
125
- # if parent doesn't define this, add it so that
168
+ # If parent doesn't define this, add it so that
126
169
  # our action_method_or_block will work.
127
170
  unless instance_methods.include?( :action_triggered )
128
171
  def action_triggered( &someblock )
@@ -17,28 +17,6 @@ class Object
17
17
  end
18
18
  end
19
19
 
20
- class Class
21
- # TODO Qt bindings will accept a block for new, which
22
- # makes this somewhat irrelevant. Unless it's really
23
- # necessary to pass args in
24
- def construct_exec( *args, &block )
25
- raise "block is nil" if block.nil?
26
- inst = self.new( *args )
27
- # using the Rails implementation, included in Qt
28
- block.bind( inst )[*args]
29
- # return the newly configured instance
30
- inst
31
- end
32
-
33
- # see self.construct
34
- def construct( *args, &block )
35
- raise "block is nil" if block.nil?
36
- inst = self.new( *args )
37
- yield( inst )
38
- inst
39
- end
40
- end
41
-
42
20
  class NilClass
43
21
  def to_variant
44
22
  Qt::Variant.invalid
@@ -103,6 +81,7 @@ module Qt
103
81
  class ItemSelection
104
82
  include Enumerable
105
83
 
84
+ # Iterate through SelectionRange instances in this selection
106
85
  def each( &block )
107
86
  index = 0
108
87
  max = self.count
@@ -122,9 +101,6 @@ module Qt
122
101
  end
123
102
  end
124
103
 
125
- # This provides a bunch of methods to get easy access to the entity
126
- # and it's values directly from the index without having to keep
127
- # asking the model and jumping through other unncessary hoops
128
104
  class ModelIndex
129
105
  # Because using Qt::ModelIndex.new the whole time is wasteful
130
106
  def self.invalid
@@ -133,7 +109,8 @@ module Qt
133
109
 
134
110
  alias_method :old_inspect, :inspect
135
111
  def inspect
136
- if valid?
112
+ # need the self here otherwise Qt bindings get confused.
113
+ if self.valid?
137
114
  #<Qt::ModelIndex:0xb6004e8c>
138
115
  # fetch address from superclass inspect
139
116
  super =~ /ModelIndex:(.*)>/
@@ -157,7 +134,8 @@ module Qt
157
134
 
158
135
  end
159
136
 
160
- # make keystrokes easier to work with
137
+ # Make keystrokes events easier to work with. For <tt>Qt::Key_Whatever</tt>
138
+ # events, KeyEvent instances will now respond to <tt>whatever?</tt>
161
139
  class KeyEvent
162
140
  # override otherwise the new method_missing fails
163
141
  # to call the old_method_missing
@@ -184,8 +162,7 @@ module Qt
184
162
 
185
163
  alias_method :old_method_missing, :method_missing
186
164
 
187
- # shortcut for the Qt::Key_Whatever constants
188
- # just say event.whatever?
165
+ # Provide a shortcut for the Qt::Key_Whatever constants. Just say event.whatever?
189
166
  def method_missing( sym, *args )
190
167
  begin
191
168
  if sym.to_s[-1] == "?"[0]
@@ -218,10 +195,10 @@ module Qt
218
195
  end
219
196
 
220
197
  class TableView
221
- # otherwise model object gets garbage-collected
222
- def model=( m )
223
- @model = m
224
- super( m )
198
+ # store the model in a data member, otherwise it gets garbage-collected.
199
+ def model=( model )
200
+ @model = model
201
+ super( model )
225
202
  end
226
203
  end
227
204
 
@@ -266,9 +243,11 @@ module Qt
266
243
 
267
244
  class Widget
268
245
  # add a signal with the given signature, and create
269
- # a method called method_name which will return the signal
246
+ # a method called method_name which will emit the signal,
247
+ # a method called method_name_signal which will return the signal
270
248
  # ready to be used in a connect. If method_name is not provided
271
- # the method will be named as the name part of signature
249
+ # the method will be named as the name part of signature.
250
+ # Also create a handler on_method_name {|*args| }
272
251
  def self.construct_signal( signature, method_name = nil )
273
252
  # add the signal
274
253
  q_signal( signature )
@@ -286,7 +265,62 @@ module Qt
286
265
  SIGNAL( signature )
287
266
  end
288
267
 
289
- # TODO create the connection method
268
+ # create the connection method
269
+ line, st = __LINE__, <<-EOF
270
+ def on_#{base_method_name}( &block )
271
+ connect( #{method_name} ) do |*args|
272
+ yield( *args )
273
+ end
274
+ end
275
+ EOF
276
+ class_eval st, __FILE__, line + 1
277
+ end
278
+
279
+ # specify a signal symbol, and add the other methods, namely
280
+ # - <tt>symbol</tt> which emits the signal
281
+ # - <tt>symbol_signal</tt> which is the method added by q_signal, ie the actual Qt emitter
282
+ # - <tt>on_symbol {|*args| }</tt> which is the handler
283
+ def self.signal( symbol )
284
+ # add the signal emitter
285
+ signature = "#{symbol.to_s}_signal( QVariant & )"
286
+ q_signal( signature )
287
+
288
+ # add an emitter
289
+ line_number, st = __LINE__, <<-EOF
290
+ def #{symbol.to_s}( *args )
291
+ #~ puts "ingoing args: \#\{args.inspect\}"
292
+ # convert args to variant(s)
293
+ variant =
294
+ case args.size
295
+ when 0; Qt::Variant.new
296
+ when 1; args[0].to_variant
297
+ else; Qt::Variant.new( args )
298
+ end
299
+ #~ puts "ingoing variant: \#\{variant.inspect\}"
300
+ emit #{symbol.to_s}_signal( variant )
301
+ end
302
+ EOF
303
+ class_eval st, __FILE__, line_number + 1
304
+
305
+ # create the connection method
306
+ line_number, st = __LINE__, <<-EOF
307
+ def on_#{symbol.to_s}( &block )
308
+ Kernel.raise "on_#{symbol.to_s} must have a block" if block.nil?
309
+ connect( SIGNAL( '#{signature}' ) ) do |variant|
310
+ #~ puts "outcoming variant: \#\{variant.inspect\}"
311
+ # convert variants to Ruby objects
312
+ args =
313
+ case variant.typeName
314
+ when nil; nil
315
+ when 'QVariantList'; variant.value.map{|x| x.value}
316
+ else variant.value
317
+ end
318
+ #~ puts "outcoming args: \#\{args.inspect\}"
319
+ yield( *args )
320
+ end
321
+ end
322
+ EOF
323
+ class_eval st, __FILE__, line_number + 1
290
324
  end
291
325
  end
292
326
 
@@ -1,9 +1,17 @@
1
1
  require 'active_support'
2
2
  require 'qtext/flags.rb'
3
3
 
4
+ =begin rdoc
5
+ A header for ObjectTableModel.
6
+ =end
4
7
  class Header
5
8
  attr_reader :attribute, :title, :alignment
6
-
9
+
10
+ # args is a hash that can contain the following:
11
+ # - :attribute (required) is the name of the attribute on objects in the table's collection,
12
+ # the values for which will be displayed in this column.
13
+ # - :title is the column header. Defaults to attribute.humanize
14
+ # - :alignment is one of the Qt::Align constants. Defaults to Qt::AlignLeft | Qt::AlignVCenter.
7
15
  def initialize( args = {} )
8
16
  raise "there must be an attribute" unless args.has_key?( :attribute )
9
17
  @attribute = args[:attribute]
@@ -13,23 +21,46 @@ class Header
13
21
  end
14
22
 
15
23
  =begin rdoc
16
- A Qt TableModel that is given a collection of objects, and a collection
17
- of headers, which are methods to call on the objects to populate columns
24
+ A specialisation of Qt::TableModel that is given a collection of objects, and a collection
25
+ of headers, which are methods to call on the objects to populate columns.
26
+
27
+ Given
28
+ Thing = Struct.new( :name, :value, :location, :price, :other, :ignored )
29
+ and
30
+ @data = method_to_create_lots_of_things
31
+ The following will display the four named attributes in 4 columns
32
+ ObjectTableModel.new :data => @data, :headers => [ :name, :value, :location, :price ]
33
+ and this will right-align the price column:
34
+ ObjectTableModel.new :data => @data, :headers => [ :name, :value, :location, Header.new( :attribute => :price, :alignment => Qt::AlignRight ) ]
18
35
  =end
19
36
  class ObjectTableModel < Qt::AbstractTableModel
20
37
  include QtFlags
21
38
  attr_reader :collection, :headers
22
39
 
23
- # data => array of objects
24
- # headers => array of methods to call on objects
40
+ # Rubyish method for rowCount
41
+ def row_count( parent_index = Qt::ModelIndex.invalid )
42
+ rowCount( parent_index )
43
+ end
44
+
45
+ # Rubyish method for columnCount
46
+ def column_count( parent_index = Qt::ModelIndex.invalid )
47
+ columnCount( parent_index )
48
+ end
49
+
50
+ # args can contain the following:
51
+ # - :parent => the Qt::Object that is the parent of this class.
52
+ # - :headers => array of either symbols representing the attribute on the
53
+ # elements of the data collection, or Header instances.
54
+ # - :data => array of objects, with attributes corresponding to the headers
55
+ # - :collection is an alias for :data
25
56
  def initialize( args = {} )
26
- super()
57
+ super( args[:parent] )
27
58
  @collection = args[:data] || args[:collection] || []
28
59
  set_headers( args[:headers] )
29
60
  end
30
61
 
31
62
  # implementation of Qt:AbstractItemModel method
32
- def rowCount( parent_model_index )
63
+ def rowCount( parent_model_index = Qt::ModelIndex.invalid )
33
64
  if parent_model_index.valid?
34
65
  0
35
66
  else
@@ -45,16 +76,6 @@ class ObjectTableModel < Qt::AbstractTableModel
45
76
  end
46
77
  end
47
78
 
48
- def attribute_for_index( column )
49
- headers[column]
50
- end
51
-
52
- def field_value_at( index )
53
- obj = collection[index.row]
54
- att = attribute_for_index( index.column ).attribute
55
- obj.send( att ) unless obj.nil? or att.nil?
56
- end
57
-
58
79
  # implementation of Qt:AbstractItemModel method
59
80
  def headerData( section, orientation, role )
60
81
  value =
@@ -152,7 +173,7 @@ class ObjectTableModel < Qt::AbstractTableModel
152
173
  end
153
174
 
154
175
  # implementation of Qt:AbstractItemModel method
155
- # TODO make this editable
176
+ #-- TODO make this editable
156
177
  def flags( index )
157
178
  return 0 unless index.valid?
158
179
  super
@@ -162,6 +183,7 @@ class ObjectTableModel < Qt::AbstractTableModel
162
183
  collection[index]
163
184
  end
164
185
 
186
+ # Set the value at the index, and make sure the view is updated.
165
187
  def []=( index, value )
166
188
  if index >= collection.size
167
189
  beginInsertRows( Qt::ModelIndex.invalid, collection.size, collection.size + ( index - collection.size ) )
@@ -173,6 +195,7 @@ class ObjectTableModel < Qt::AbstractTableModel
173
195
  end
174
196
  end
175
197
 
198
+ # Insert a new object into the collection, and make sure the view is updated.
176
199
  def <<( obj )
177
200
  beginInsertRows( Qt::ModelIndex.invalid, collection.size, collection.size )
178
201
  collection << obj
@@ -198,7 +221,7 @@ class ObjectTableModel < Qt::AbstractTableModel
198
221
  reset
199
222
  end
200
223
 
201
- # a collection of CheckableFields
224
+ # a collection of Header instances
202
225
  def headers=( arr )
203
226
  set_headers( arr )
204
227
  reset
@@ -215,4 +238,15 @@ protected
215
238
  end
216
239
  end
217
240
  end
241
+
242
+ def attribute_for_index( column )
243
+ headers[column]
244
+ end
245
+
246
+ def field_value_at( index )
247
+ obj = collection[index.row]
248
+ att = attribute_for_index( index.column ).attribute
249
+ obj.send( att ) unless obj.nil? or att.nil?
250
+ end
251
+
218
252
  end
@@ -1,7 +1,7 @@
1
1
  module Qtext #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 5
4
+ MINOR = 6
5
5
  TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # File: script/console
3
+ irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
+
5
+ libs = " -r irb/completion"
6
+ # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
+ # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
+ libs << " -r #{File.dirname(__FILE__) + '/../lib/qtext.rb'}"
9
+ puts "Loading qtext gem"
10
+ exec "#{irb} #{libs} --simple-prompt"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/destroy'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Destroy.new.run(ARGV)
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
+
4
+ begin
5
+ require 'rubigen'
6
+ rescue LoadError
7
+ require 'rubygems'
8
+ require 'rubigen'
9
+ end
10
+ require 'rubigen/scripts/generate'
11
+
12
+ ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
+ RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
+ RubiGen::Scripts::Generate.new.run(ARGV)
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ GEM_NAME = 'qtext' # what ppl will type to install your gem
4
+ RUBYFORGE_PROJECT = 'qtext'
5
+
6
+ require 'rubygems'
7
+ begin
8
+ require 'newgem'
9
+ require 'rubyforge'
10
+ rescue LoadError
11
+ puts "\n\nGenerating the website requires the newgem RubyGem"
12
+ puts "Install: gem install newgem\n\n"
13
+ exit(1)
14
+ end
15
+ require 'redcloth'
16
+ require 'syntax/convertors/html'
17
+ require 'erb'
18
+ require File.dirname(__FILE__) + "/../lib/#{GEM_NAME}/version.rb"
19
+
20
+ version = Qtext::VERSION::STRING
21
+ download = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
22
+
23
+ def rubyforge_project_id
24
+ RubyForge.new.autoconfig["group_ids"][RUBYFORGE_PROJECT]
25
+ end
26
+
27
+ class Fixnum
28
+ def ordinal
29
+ # teens
30
+ return 'th' if (10..19).include?(self % 100)
31
+ # others
32
+ case self % 10
33
+ when 1: return 'st'
34
+ when 2: return 'nd'
35
+ when 3: return 'rd'
36
+ else return 'th'
37
+ end
38
+ end
39
+ end
40
+
41
+ class Time
42
+ def pretty
43
+ return "#{mday}#{mday.ordinal} #{strftime('%B')} #{year}"
44
+ end
45
+ end
46
+
47
+ def convert_syntax(syntax, source)
48
+ return Syntax::Convertors::HTML.for_syntax(syntax).convert(source).gsub(%r!^<pre>|</pre>$!,'')
49
+ end
50
+
51
+ if ARGV.length >= 1
52
+ src, template = ARGV
53
+ template ||= File.join(File.dirname(__FILE__), '/../website/template.html.erb')
54
+ else
55
+ puts("Usage: #{File.split($0).last} source.txt [template.html.erb] > output.html")
56
+ exit!
57
+ end
58
+
59
+ template = ERB.new(File.open(template).read)
60
+
61
+ title = nil
62
+ body = nil
63
+ File.open(src) do |fsrc|
64
+ title_text = fsrc.readline
65
+ body_text_template = fsrc.read
66
+ body_text = ERB.new(body_text_template).result(binding)
67
+ syntax_items = []
68
+ body_text.gsub!(%r!<(pre|code)[^>]*?syntax=['"]([^'"]+)[^>]*>(.*?)</\1>!m){
69
+ ident = syntax_items.length
70
+ element, syntax, source = $1, $2, $3
71
+ syntax_items << "<#{element} class='syntax'>#{convert_syntax(syntax, source)}</#{element}>"
72
+ "syntax-temp-#{ident}"
73
+ }
74
+ title = RedCloth.new(title_text).to_html.gsub(%r!<.*?>!,'').strip
75
+ body = RedCloth.new(body_text).to_html
76
+ body.gsub!(%r!(?:<pre><code>)?syntax-temp-(\d+)(?:</code></pre>)?!){ syntax_items[$1.to_i] }
77
+ end
78
+ stat = File.stat(src)
79
+ created = stat.ctime
80
+ modified = stat.mtime
81
+
82
+ $stdout << template.result(binding)
@@ -0,0 +1,34 @@
1
+ desc 'Release the website and new gem version'
2
+ task :deploy => [:check_version, :website, :release] do
3
+ puts "Remember to create SVN tag:"
4
+ puts "svn copy svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/trunk " +
5
+ "svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/tags/REL-#{VERS} "
6
+ puts "Suggested comment:"
7
+ puts "Tagging release #{CHANGES}"
8
+ end
9
+
10
+ desc 'Runs tasks website_generate and install_gem as a local deployment of the gem'
11
+ task :local_deploy => [:website_generate, :install_gem]
12
+
13
+ task :check_version do
14
+ unless ENV['VERSION']
15
+ puts 'Must pass a VERSION=x.y.z release version'
16
+ exit
17
+ end
18
+ unless ENV['VERSION'] == VERS
19
+ puts "Please update your version.rb to match the release version, currently #{VERS}"
20
+ exit
21
+ end
22
+ end
23
+
24
+ desc 'Install the package as a gem, without generating documentation(ri/rdoc)'
25
+ task :install_gem_no_doc => [:clean, :package] do
26
+ sh "#{'sudo ' unless Hoe::WINDOZE }gem install pkg/*.gem --no-rdoc --no-ri"
27
+ end
28
+
29
+ namespace :manifest do
30
+ desc 'Recreate Manifest.txt to include ALL files'
31
+ task :refresh do
32
+ `rake check_manifest | patch -p0 > Manifest.txt`
33
+ end
34
+ end
@@ -0,0 +1,7 @@
1
+ task :ruby_env do
2
+ RUBY_APP = if RUBY_PLATFORM =~ /java/
3
+ "jruby"
4
+ else
5
+ "ruby"
6
+ end unless defined? RUBY_APP
7
+ end
@@ -0,0 +1,17 @@
1
+ desc 'Generate website files'
2
+ task :website_generate => :ruby_env do
3
+ (Dir['website/**/*.txt'] - Dir['website/version*.txt']).each do |txt|
4
+ sh %{ #{RUBY_APP} script/txt2html #{txt} > #{txt.gsub(/txt$/,'html')} }
5
+ end
6
+ end
7
+
8
+ desc 'Upload website files to rubyforge'
9
+ task :website_upload do
10
+ host = "#{rubyforge_username}@rubyforge.org"
11
+ remote_dir = "/var/www/gforge-projects/#{PATH}/"
12
+ local_dir = 'website'
13
+ sh %{rsync -aCv #{local_dir}/ #{host}:#{remote_dir}}
14
+ end
15
+
16
+ desc 'Generate and upload website files'
17
+ task :website => [:website_generate, :website_upload, :publish_docs]
@@ -1,2 +1,48 @@
1
1
  require 'test/unit'
2
2
  require File.dirname(__FILE__) + '/../lib/qtext'
3
+ require 'shoulda'
4
+
5
+ # Allow running of setup and teardown things before
6
+ # an entire suite, instead of just one per test
7
+ class SuiteWrapper < Test::Unit::TestSuite
8
+ attr_accessor :tests
9
+
10
+ def initialize( name, test_case )
11
+ super( name )
12
+ @test_case = test_case
13
+ end
14
+
15
+ def startup
16
+ end
17
+
18
+ def shutdown
19
+ end
20
+
21
+ def run( *args )
22
+ startup
23
+ @test_case.startup if @test_case.respond_to? :startup
24
+ retval = super
25
+ @test_case.shutdown if @test_case.respond_to? :shutdown
26
+ shutdown
27
+ retval
28
+ end
29
+ end
30
+
31
+ module Test
32
+ module Unit
33
+ class TestCase
34
+ unless respond_to? :old_suite
35
+ class << self
36
+ alias_method :old_suite, :suite
37
+ end
38
+
39
+ def self.suite
40
+ os = old_suite
41
+ sw = SuiteWrapper.new( os.name, self )
42
+ sw.tests = os.tests
43
+ sw
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -3,25 +3,72 @@ require 'qtext/object_table_model.rb'
3
3
  require 'Qt4'
4
4
 
5
5
  class TestObjectTableModel < Test::Unit::TestCase
6
- Thing = Struct.new( :name, :value, :location, :price )
6
+ Thing = Struct.new( :name, :value, :location, :price, :ignored )
7
+
8
+ def self.startup
9
+ $app ||= Qt::Application.new( [] )
10
+ end
11
+
7
12
  def setup
8
13
  @data = [
9
- Thing.new( "Screwdriver", 'high', 'toolbox', 10.96 ),
10
- Thing.new( "Thermometer", '15 degrees', 'bathroom', 0.01 ),
14
+ Thing.new( "Screwdriver", 'high', 'toolbox', 10.96, 'not' ),
15
+ Thing.new( "Thermometer", '15 degrees', 'bathroom', 0.01, 'here' ),
11
16
  Thing.new( "Bed", 'large', 'bedroom' ),
12
- Thing.new( "Approximation", 'useful', 'maths', 'none' )
17
+ Thing.new( "Approximation", 'useful', 'maths', 'none', 'all' )
13
18
  ]
19
+ @model = ObjectTableModel.new( :data => @data, :headers => [ :name, :value, :location, Header.new( :attribute => :price, :alignment => Qt::AlignRight ) ] )
20
+ @main_window = Qt::MainWindow.new
21
+ @view = Qt::TableView.new( @main_window ) { |tv| tv.model = @model }
22
+ @main_window.central_widget = @view
23
+ end
24
+
25
+ should 'have a 4 x 4 size' do
26
+ assert_equal 4, @model.rowCount
27
+ assert_equal 4, @model.row_count
28
+ assert_equal 4, @model.columnCount
29
+ assert_equal 4, @model.column_count
30
+ end
31
+
32
+ should 'have 0x0 size for children models at a given index' do
33
+ index = @model.create_index(1,1)
34
+ assert_equal 0, @model.row_count( index )
35
+ assert_equal 0, @model.column_count( index )
36
+ end
37
+
38
+ should 'return correct data' do
39
+ @data.each_with_index do |item,i|
40
+ Thing.members.each_with_index do |member,j|
41
+ next if j >= 4
42
+ model_index = @model.create_index(i,j)
43
+ assert_equal item[member], @model.data( model_index ).value
44
+ end
45
+ end
46
+ end
47
+
48
+ should 'return nil for invalid index' do
49
+ assert_equal Qt::Variant.invalid, @model.data( Qt::ModelIndex.invalid )
50
+ end
51
+
52
+ should 'have price aligned right' do
53
+ assert_equal Qt::AlignLeft.to_i, @model.data( @model.create_index(0,0), Qt::TextAlignmentRole ).to_i & Qt::AlignLeft.to_i
54
+ assert_equal Qt::AlignLeft.to_i, @model.data( @model.create_index(0,1), Qt::TextAlignmentRole ).to_i & Qt::AlignLeft.to_i
55
+ assert_equal Qt::AlignRight.to_i, @model.data( @model.create_index(0,3), Qt::TextAlignmentRole ).to_i & Qt::AlignRight.to_i
56
+ end
57
+
58
+ should_eventually 'display the window' do
59
+ #~ should 'display the window' do
60
+ @main_window.window_title = 'Test ObjectTableModel'
61
+ @main_window.move( 150, 0 )
62
+ @main_window.show
63
+ $app.exec
64
+ end
65
+
66
+ should 'have a nil parent' do
67
+ assert_nil @model.parent
14
68
  end
15
69
 
16
- def test_model
17
- model = ObjectTableModel.new( :data => @data, :headers => [ :name, :value, :location, :price ] )
18
- app = Qt::Application.new( [] )
19
- main_window = Qt::MainWindow.new
20
- main_window.central_widget = Qt::TableView.construct( main_window ) { |tv| tv.model = model }
21
-
22
- main_window.window_title = 'Test ObjectTableModel'
23
- main_window.move( 150, 0 )
24
- main_window.show
25
- app.exec
70
+ should 'have parent == @model' do
71
+ model = ObjectTableModel.new( :parent => @model, :data => @data, :headers => [ :name, :value, :location, Header.new( :attribute => :price, :alignment => Qt::AlignRight ) ] )
72
+ assert_equal @model, model.parent
26
73
  end
27
74
  end
@@ -0,0 +1,106 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ $app = Qt::Application.new []
4
+
5
+ class Thok < Qt::Widget
6
+ signal :whatever
7
+ end
8
+
9
+ class TestWidget < Test::Unit::TestCase
10
+
11
+ def setup
12
+ @thok = Thok.new
13
+ end
14
+
15
+ should 'have a whatever_signal method' do
16
+ assert_equal 1, @thok.methods.grep( /^whatever_signal$/ ).size
17
+ assert_raise ArgumentError do
18
+ @thok.whatever_signal( 'hello' )
19
+ end
20
+
21
+ assert_nothing_raised do
22
+ @thok.whatever_signal( 'hello'.to_variant )
23
+ end
24
+ end
25
+
26
+ should 'have a whatever emitter' do
27
+ assert_equal 1, @thok.methods.grep( /^whatever$/ ).size
28
+ assert_nothing_raised { @thok.whatever }
29
+ assert_nothing_raised { @thok.whatever 1 }
30
+ assert_nothing_raised { @thok.whatever 1,2,3 }
31
+ assert_nothing_raised { @thok.whatever [4,5,6] }
32
+ end
33
+
34
+ should 'have an on_whatever handler' do
35
+ assert_equal 1, @thok.methods.grep( /^on_whatever$/ ).size
36
+ end
37
+
38
+ context 'on_whatever handler' do
39
+ should 'handle nil args' do
40
+ @thok.on_whatever do |arg|
41
+ assert_nil arg
42
+ end
43
+ @thok.whatever
44
+ @thok.whatever( nil )
45
+ end
46
+
47
+ should 'handle single args' do
48
+ @thok.on_whatever do |arg|
49
+ assert_not_nil arg
50
+ assert_not_equal Array, arg.class
51
+ end
52
+ @thok.whatever 1
53
+ @thok.whatever 'hello'
54
+ end
55
+
56
+ should_eventually 'handle objects' do
57
+ NVP = Struct.new :name, :value
58
+ nvp = NVP.new
59
+ nvp.name = 'how'
60
+ nvp.value = 'that'
61
+ @thok.on_whatever do |arg|
62
+ assert_not_nil arg
63
+ assert_equal NVP, arg.class
64
+ end
65
+ @thok.whatever nvp
66
+ end
67
+
68
+ should 'handle arg lists' do
69
+ @thok.on_whatever do |arg1,arg2|
70
+ assert_not_nil arg1
71
+ assert_not_nil arg2
72
+ assert_not_equal Array, arg1.class
73
+ assert_not_equal Array, arg2.class
74
+ end
75
+ @thok.whatever 1,2
76
+ @thok.whatever 'hello','there'
77
+ end
78
+
79
+ should 'handle a single array' do
80
+ @thok.on_whatever do |ary|
81
+ assert_not_nil ary
82
+ assert_equal Array, ary.class
83
+ assert_equal 3, ary.size
84
+ assert_equal [4,5,6], ary
85
+ end
86
+ @thok.whatever [4,5,6]
87
+ end
88
+
89
+ should_eventually 'handle multiple arrays' do
90
+ @thok.on_whatever do |ary1,ary2|
91
+ assert_not_nil ary1
92
+ assert_not_nil ary2
93
+ assert_equal Array, ary1.class
94
+ assert_equal Array, ary2.class
95
+ assert_equal 3, ary1.size
96
+ assert_equal 3, ary2.size
97
+ # fails here because ary1 is an array of variants
98
+ puts "ary1: #{ary1.inspect}"
99
+ assert_equal [4,5,6], ary1
100
+ assert_equal [7,8,9], ary2
101
+ end
102
+ @thok.whatever( [4,5,6], [7,8,9] )
103
+ end
104
+ end
105
+
106
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qtext
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - FIXME full name
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-08-21 00:00:00 +02:00
12
+ date: 2008-10-09 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -30,25 +30,38 @@ executables: []
30
30
  extensions: []
31
31
 
32
32
  extra_rdoc_files:
33
+ - History.txt
34
+ - License.txt
35
+ - Manifest.txt
33
36
  - README.txt
34
37
  files:
38
+ - History.txt
39
+ - License.txt
40
+ - Manifest.txt
35
41
  - README.txt
42
+ - Rakefile
43
+ - config/hoe.rb
44
+ - config/requirements.rb
45
+ - env.sh
36
46
  - lib/qtext.rb
37
47
  - lib/qtext/action_builder.rb
38
- - lib/qtext/version.rb
39
- - lib/qtext/flags.rb
40
48
  - lib/qtext/extensions.rb
49
+ - lib/qtext/flags.rb
41
50
  - lib/qtext/object_table_model.rb
51
+ - lib/qtext/version.rb
52
+ - script/console
53
+ - script/destroy
54
+ - script/generate
55
+ - script/txt2html
56
+ - tasks/deployment.rake
57
+ - tasks/environment.rake
58
+ - tasks/website.rake
59
+ - test/test_helper.rb
60
+ - test/test_object_table.rb
61
+ - test/test_widget.rb
42
62
  has_rdoc: true
43
63
  homepage: http://qtext.rubyforge.org
44
- post_install_message: |+
45
-
46
- For more information on qtext, see http://qtext.rubyforge.org
47
-
48
- NOTE: Change this information in PostInstall.txt
49
- You can also delete it if you don't want it.
50
-
51
-
64
+ post_install_message: ""
52
65
  rdoc_options:
53
66
  - --main
54
67
  - README.txt
@@ -75,5 +88,5 @@ specification_version: 2
75
88
  summary: description of gem
76
89
  test_files:
77
90
  - test/test_object_table.rb
78
- - test/test_qtext.rb
91
+ - test/test_widget.rb
79
92
  - test/test_helper.rb
@@ -1,11 +0,0 @@
1
- require File.dirname(__FILE__) + '/test_helper.rb'
2
-
3
- class TestQtext < Test::Unit::TestCase
4
-
5
- def setup
6
- end
7
-
8
- def test_truth
9
- assert true
10
- end
11
- end