qtext 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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