rspreadsheet 0.2.0 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,54 +1,64 @@
1
- require('rspreadsheet/cell')
2
- require('forwardable')
1
+ require 'rspreadsheet/cell'
2
+ require 'rspreadsheet/xml_tied'
3
3
 
4
4
  # Currently this is only syntax sugar for cells and contains no functionality
5
5
 
6
6
  module Rspreadsheet
7
7
 
8
- class Row < RowOrNode
8
+ class Row < XMLTiedItem
9
+ include XMLTiedArray
9
10
  attr_reader :worksheet, :rowi
11
+ def xml_repeated_attribute; 'number-rows-repeated' end
12
+ def xml_items_node_name; 'table-row' end
13
+ def xml_options; {:xml_items_node_name => xml_items_node_name, :xml_repeated_attribute => xml_repeated_attribute} end
14
+ def subitem_xml_options; {:xml_items_node_name => 'table-cell', :xml_repeated_attribute => 'number-columns-repeated'} end
15
+
10
16
  def initialize(aworksheet,arowi)
11
17
  @worksheet = aworksheet
12
18
  @rowi = arowi
19
+ @itemcache = Hash.new #TODO: move to module XMLTiedArray
13
20
  end
14
- def xmlnode; @worksheet.rowxmlnode(@rowi) end
15
- def cells(coli)
16
- coli = coli.to_i
17
- if coli.to_i<=0
18
- nil
19
- else
20
- Cell.new(@worksheet,@rowi,coli)
21
+ def xmlnode; parent.find_my_subnode_respect_repeated(index, xml_options) end
22
+
23
+ # XMLTiedItem things and extensions
24
+ def parent; @worksheet end
25
+ def index; @rowi end
26
+ def set_index(value); @rowi=value end
27
+
28
+ # XMLTiedArray rozšíření
29
+ def prepare_subitem(coli); Cell.new(@worksheet,@rowi,coli) end
30
+ def cells(*params)
31
+ raise 'Invalid row reference' if invalid_reference?
32
+ case params.length
33
+ when 0 then subitems_array
34
+ when 1 then subitem(params[0])
35
+ else raise Exception.new('Wrong number of arguments.')
21
36
  end
22
37
  end
23
- def self.empty_xmlnode(repeats=1)
24
- node = LibXML::XML::Node.new('table-row',nil, Tools.get_namespace('table'))
25
- Tools.set_ns_attribute(node,'table','number-rows-repeated',repeats, 1)
26
- node
27
- end
28
- def detach_if_needed;
29
- detach if repeated?
30
- end
31
- def detach
32
- @worksheet.detach_row_in_xml(@rowi)
33
- self
34
- end
35
- def repeated
36
- (Tools.get_ns_attribute_value(self.xmlnode, 'table', 'number-rows-repeated') || 1).to_i
37
- end
38
- def repeated?; mode==:repeated || mode==:outbound end
39
- alias :is_repeated? :repeated?
38
+ # syntactis sugar to cells and its values
39
+ def [](coli); cells(coli).value end
40
+ def []=(coli,avalue); cells(coli).value=avalue end
41
+
42
+ # další
40
43
  def style_name=(value);
41
44
  detach_if_needed
42
45
  Tools.set_ns_attribute(xmlnode,'table','style-name',value)
43
46
  end
44
- def used_range
45
- @worksheet.rowrange(@rowi)
46
- end
47
47
  def nonemptycells
48
- nonemptycellsindexes.collect{ |index| cells(index) }
48
+ nonemptycellsindexes.collect{ |index| subitem(index) }
49
49
  end
50
50
  def nonemptycellsindexes
51
- @worksheet.row_nonempty_cells_col_indexes(@rowi)
51
+ myxmlnode = xmlnode
52
+ if myxmlnode.nil?
53
+ []
54
+ else
55
+ @worksheet.find_nonempty_subnode_indexes(myxmlnode, {:xml_items_node_name => 'table-cell', :xml_repeated_attribute => 'number-columns-repeated'})
56
+ end
57
+ end
58
+ alias :used_range :range
59
+ def shift_by(diff)
60
+ super
61
+ @itemcache.each_value{ |cell| cell.set_rowi(@rowi) }
52
62
  end
53
63
  end
54
64
 
@@ -68,189 +78,175 @@ end
68
78
  # --------------------------
69
79
 
70
80
 
71
- # XmlTiedArrayItemGroup is internal representation of repeated items in XmlTiedArray.
72
- class XmlTiedArrayItemGroup
73
- # extend Forwardable
74
- # delegate [:normalize ] => :@row_group
75
-
76
- def normalize; @rowgroup.normalize end
77
- def range; @rowgroup.range end
78
- def repeated?; self.range.size>1 end
79
- def xmlnode; @rowgroup.xmlnode end
81
+ # # XmlTiedArrayItemGroup is internal representation of repeated items in XmlTiedArray.
82
+ # class XmlTiedArrayItemGroup
83
+ # # extend Forwardable
84
+ # # delegate [:normalize ] => :@row_group
85
+ #
86
+ # def normalize; @rowgroup.normalize end
80
87
 
81
- def initialize(aparent_array,arange,axmlnode=nil)
82
- @rowgroup = RowGroup.new(aparent_array,arange,axmlnode)
83
- end
84
- def self.new_from_xml
85
- end
86
- def to_rowgroup
87
- @rowgroup
88
- end
89
- def range=(arange)
90
-
91
- end
92
- end
88
+ # end
93
89
 
94
90
  # array which synchronizes with xml structure and reflects. number-xxx-repeated attributes
95
91
  # also caches returned objects for indexes.
96
92
  # options must contain
97
93
  # :xml_items, :xml_repeated_attribute, :object_type
98
94
 
99
- class XmlTiedArray < Array
100
- def initialize(axmlnode, options={}) # TODO get rid of XmlTiedArray
101
- @xmlnode = axmlnode
102
- @options = options
103
-
104
- missing_options = [:xml_repeated_attribute,:xml_items_node_name,:object_type]-@options.keys
105
- raise "Some options missing (#{missing_options.inspect})" unless missing_options.empty?
106
-
107
- unless @xmlnode.nil?
108
- @xmlnode.elements.select{|node| node.name == options[:xml_items_node_name]}.each do |group_source_node|
109
- self << parse_xml_to_group(group_source_node) # it is in @xmlnode so suffices to add object to @rowgroups
110
- end
111
- end
112
- @itemcache=Hash.new()
113
- end
114
- def parse_xml_to_group(size_or_xmlnode) # parses xml to new RowGroup which can be added at the end
115
- # reading params
116
- if size_or_xmlnode.kind_of? LibXML::XML::Node
117
- size = (size_or_xmlnode[@options[:xml_repeated_attribute]] || 1).to_i
118
- node = size_or_xmlnode
119
- elsif size_or_xmlnode.to_i>0
120
- size = size_or_xmlnode.to_i
121
- node = nil
122
- else
123
- return nil
124
- end
125
- index = first_unused_index
126
- # construct result
127
- Rspreadsheet::XmlTiedArrayItemGroup.new(self,index..index+size-1,node)
128
- end
129
- def add_item_group(size_or_xmlnode)
130
- result = parse_xml_to_group(size_or_xmlnode)
131
- self << result
132
- @xmlnode << result.xmlnode
133
- result
134
- end
135
- def first_unused_index
136
- empty? ? 1 : last.range.end+1
137
- end
138
- # prolonges the RowArray to cantain rowi and returns it
139
- def detach_of_bound_item(index)
140
- fill_row_group_size = index-first_unused_index
141
- if fill_row_group_size>0
142
- add_item_group(fill_row_group_size)
143
- end
144
- add_item_group(1)
145
- get_item(index) # aby se odpoved nacacheovala
146
- end
147
- def get_item_group(index)
148
- find{ |item_group| item_group.range.cover?(index) }
149
- end
150
- def detach_item(index); get_item(index) end # TODO předělat do lazy podoby, kdy tohle nebude stejny
151
- def get_item(index)
152
- if index>= first_unused_index
153
- nil
154
- else
155
- @itemcache[index] ||= Rspreadsheet::XmlTiedArrayItem.new(self,index)
156
- end
157
- end
158
- # This detaches item index from the group and perhaps splits the RowGroup
159
- # into two pieces. This makes the row individually editable.
160
- def detach(index)
161
- group_index = get_group_index(index)
162
- item_group = self[group_index]
163
- range = item_group.range
164
- return self if range==(index..index)
165
-
166
- # prepare new components
167
- replaceby = []
168
- replaceby << RowGroup.new(self,range.begin..index-1)
169
- replaceby << (result = SingleRow.new(self,index))
170
- replaceby << RowGroup.new(self,index+1..range.end)
171
-
172
- # put original range somewhere in replaceby and shorten it
173
-
174
- if index>range.begin
175
- replaceby[0] = item_group
176
- item_group.range = range.begin..index-1
177
- else
178
- replaceby[2] = item_group
179
- item_group.range = index+1..range.end
180
- end
181
-
182
- # normalize and delete empty parts
183
- replaceby = replaceby.map(&:normalize).compact
184
-
185
- # do the replacement in xml
186
- marker = LibXML::XML::Node.new('temporarymarker')
187
- item_group.xmlnode.next = marker
188
- item_group.xmlnode.remove!
189
- replaceby.each{ |rg|
190
- marker.prev = rg.xmlnode
191
- }
192
- marker.remove!
193
-
194
- # do the replacement in array
195
- self[group_index..group_index]=replaceby
196
- result
197
- end
198
- private
199
- def get_group_index(index)
200
- self.find_index{ |rowgroup| rowgroup.range.cover?(index) }
201
- end
202
- end
95
+ # class XmlTiedArray < Array
96
+ # def initialize(axmlnode, options={}) # TODO get rid of XmlTiedArray
97
+ # @xmlnode = axmlnode
98
+ # @options = options
99
+ #
100
+ # missing_options = [:xml_repeated_attribute,:xml_items_node_name,:object_type]-@options.keys
101
+ # raise "Some options missing (#{missing_options.inspect})" unless missing_options.empty?
102
+ #
103
+ # unless @xmlnode.nil?
104
+ # @xmlnode.elements.select{|node| node.name == options[:xml_items_node_name]}.each do |group_source_node|
105
+ # self << parse_xml_to_group(group_source_node) # it is in @xmlnode so suffices to add object to @rowgroups
106
+ # end
107
+ # end
108
+ # @itemcache=Hash.new()
109
+ # end
110
+ # def parse_xml_to_group(size_or_xmlnode) # parses xml to new RowGroup which can be added at the end
111
+ # # reading params
112
+ # if size_or_xmlnode.kind_of? LibXML::XML::Node
113
+ # size = (size_or_xmlnode[@options[:xml_repeated_attribute]] || 1).to_i
114
+ # node = size_or_xmlnode
115
+ # elsif size_or_xmlnode.to_i>0
116
+ # size = size_or_xmlnode.to_i
117
+ # node = nil
118
+ # else
119
+ # return nil
120
+ # end
121
+ # index = first_unused_index
122
+ # # construct result
123
+ # Rspreadsheet::XmlTiedArrayItemGroup.new(self,index..index+size-1,node)
124
+ # end
125
+ # def add_item_group(size_or_xmlnode)
126
+ # result = parse_xml_to_group(size_or_xmlnode)
127
+ # self << result
128
+ # @xmlnode << result.xmlnode
129
+ # result
130
+ # end
131
+ # def first_unused_index
132
+ # empty? ? 1 : last.range.end+1
133
+ # end
134
+ # # prolonges the RowArray to cantain rowi and returns it
135
+ # def detach_of_bound_item(index)
136
+ # fill_row_group_size = index-first_unused_index
137
+ # if fill_row_group_size>0
138
+ # add_item_group(fill_row_group_size)
139
+ # end
140
+ # add_item_group(1)
141
+ # get_item(index) # aby se odpoved nacacheovala
142
+ # end
143
+ # def get_item_group(index)
144
+ # find{ |item_group| item_group.range.cover?(index) }
145
+ # end
146
+ # def detach_item(index); get_item(index) end # TODO předělat do lazy podoby, kdy tohle nebude stejny
147
+ # def get_item(index)
148
+ # if index>= first_unused_index
149
+ # nil
150
+ # else
151
+ # @itemcache[index] ||= Rspreadsheet::XmlTiedArrayItem.new(self,index)
152
+ # end
153
+ # end
154
+ # # This detaches item index from the group and perhaps splits the RowGroup
155
+ # # into two pieces. This makes the row individually editable.
156
+ # def detach(index)
157
+ # group_index = get_group_index(index)
158
+ # item_group = self[group_index]
159
+ # range = item_group.range
160
+ # return self if range==(index..index)
161
+ #
162
+ # # prepare new components
163
+ # replaceby = []
164
+ # replaceby << RowGroup.new(self,range.begin..index-1)
165
+ # replaceby << (result = SingleRow.new(self,index))
166
+ # replaceby << RowGroup.new(self,index+1..range.end)
167
+ #
168
+ # # put original range somewhere in replaceby and shorten it
169
+ #
170
+ # if index>range.begin
171
+ # replaceby[0] = item_group
172
+ # item_group.range = range.begin..index-1
173
+ # else
174
+ # replaceby[2] = item_group
175
+ # item_group.range = index+1..range.end
176
+ # end
177
+ #
178
+ # # normalize and delete empty parts
179
+ # replaceby = replaceby.map(&:normalize).compact
180
+ #
181
+ # # do the replacement in xml
182
+ # marker = LibXML::XML::Node.new('temporarymarker')
183
+ # item_group.xmlnode.next = marker
184
+ # item_group.xmlnode.remove!
185
+ # replaceby.each{ |rg|
186
+ # marker.prev = rg.xmlnode
187
+ # }
188
+ # marker.remove!
189
+ #
190
+ # # do the replacement in array
191
+ # self[group_index..group_index]=replaceby
192
+ # result
193
+ # end
194
+ # private
195
+ # def get_group_index(index)
196
+ # self.find_index{ |rowgroup| rowgroup.range.cover?(index) }
197
+ # end
198
+ # end
203
199
 
204
- class XmlTiedArrayItem
205
- attr_reader :index
206
- def initialize(aarray,aindex)
207
- @array = aarray
208
- @index = aindex
209
- if self.virtual?
210
- @object = nil
211
- else
212
- @object = @array.options[:object_type].new(group.xmlnode)
213
- end
214
- end
215
- def group; @array.get_item_group(index) end
216
- def repeated?; group.repeated? end
217
- def virtual?; ! self.repeated? end
218
- def array
219
- raise 'Group empty' if @group.nil?
220
- @array
221
- end
222
- end
200
+ # class XmlTiedArrayItem
201
+ # attr_reader :index
202
+ # def initialize(aarray,aindex)
203
+ # @array = aarray
204
+ # @index = aindex
205
+ # if self.virtual?
206
+ # @object = nil
207
+ # else
208
+ # @object = @array.options[:object_type].new(group.xmlnode)
209
+ # end
210
+ # end
211
+ # def group; @array.get_item_group(index) end
212
+ # def repeated?; group.repeated? end
213
+ # def virtual?; ! self.repeated? end
214
+ # def array
215
+ # raise 'Group empty' if @group.nil?
216
+ # @array
217
+ # end
218
+ # end
223
219
 
224
- class RowArray < XmlTiedArray
225
- attr_reader :row_array_cache
226
- def initialize(aworksheet,aworksheet_node)
227
- @worksheet = aworksheet
228
- @row_array_cache = Hash.new()
229
- super(aworksheet_node, :xml_items_node_name => 'table-row', :xml_repeated_attribute => 'number-rows-repeated', :object_type=>Row)
230
- end
231
- def get_row(rowi)
232
- if @row_array_cache.has_key?(rowi)
233
- return @row_array_cache[rowi]
234
- end
235
- item = self.get_item(rowi)
236
- @row_array_cache[rowi] = if item.nil?
237
- if rowi>0 then Rspreadsheet::UninitializedEmptyRow.new(self,rowi) else nil end
238
- else
239
- if item.repeated?
240
- Rspreadsheet::MemberOfRowGroup.new(item.index, item.group.to_rowgroup)
241
- else
242
- Rspreadsheet::SingleRow.new_from_rowgroup(item.group.to_rowgroup)
243
- end
244
- end
245
- end
246
- # aliases
247
- def first_unused_row_index; first_unused_index end
248
- def worksheet; @worksheet end
249
- def detach_of_bound_row_group(index)
250
- super(index)
251
- return get_row(index)
252
- end
253
- end
220
+ # class RowArray < XmlTiedArray
221
+ # attr_reader :row_array_cache
222
+ # def initialize(aworksheet,aworksheet_node)
223
+ # @worksheet = aworksheet
224
+ # @row_array_cache = Hash.new()
225
+ # super(aworksheet_node, :xml_items_node_name => 'table-row', :xml_repeated_attribute => xml_repeated_attribute, :object_type=>Row)
226
+ # end
227
+ # def get_row(rowi)
228
+ # if @row_array_cache.has_key?(rowi)
229
+ # return @row_array_cache[rowi]
230
+ # end
231
+ # item = self.get_item(rowi)
232
+ # @row_array_cache[rowi] = if item.nil?
233
+ # if rowi>0 then Rspreadsheet::UninitializedEmptyRow.new(self,rowi) else nil end
234
+ # else
235
+ # if item.repeated?
236
+ # Rspreadsheet::MemberOfRowGroup.new(item.index, item.group.to_rowgroup)
237
+ # else
238
+ # Rspreadsheet::SingleRow.new_from_rowgroup(item.group.to_rowgroup)
239
+ # end
240
+ # end
241
+ # end
242
+ # # aliases
243
+ # def first_unused_row_index; first_unused_index end
244
+ # def worksheet; @worksheet end
245
+ # def detach_of_bound_row_group(index)
246
+ # super(index)
247
+ # return get_row(index)
248
+ # end
249
+ # end
254
250
 
255
251
  # class Row
256
252
  # def initialize
@@ -272,177 +268,147 @@ end
272
268
  # end
273
269
  # end
274
270
 
275
- class RowWithXMLNode < Row
276
- attr_accessor :xmlnode
277
- def style_name=(value); Tools.set_ns_attribute(@xmlnode,'table','style-name',value) end
278
- def get_cell(coli)
279
- Cell.new(self,coli,cellnodes(coli))
280
- end
281
- def nonemptycells
282
- nonemptycellsindexes.collect{ |index| cells(index) }
283
- end
284
- def nonemptycellsindexes
285
- used_col_range.to_a.select do |coli|
286
- cellnode = cellnodes(coli)
287
- !(cellnode.content.nil? or cellnode.content.empty? or cellnode.content =='') or
288
- !cellnode.attributes.to_a.reject{ |attr| attr.name == 'number-columns-repeated'}.empty?
289
- end
290
- end
291
- def cellnodes(coli)
292
- cellnode = nil
293
- while true
294
- curr_coli=1
295
- cellnode = @xmlnode.elements.select{|n| n.name=='table-cell'}.find do |el|
296
- curr_coli += (Tools.get_ns_attribute_value(el, 'table', 'number-columns-repeated') || 1).to_i
297
- curr_coli > coli
298
- end
299
- unless cellnode.nil?
300
- return cellnode
301
- else
302
- add_cell
303
- end
304
- end
305
- end
306
- def add_cell(repeated=1)
307
- cell = Cell.new(self,first_unused_column_index)
308
- Tools.set_ns_attribute(cell.xmlnode,'table','number-columns-repeated',repeated) if repeated>1
309
- @xmlnode << cell.xmlnode
310
- cell
311
- end
312
- def first_unused_column_index
313
- 1 + @xmlnode.elements.select{|n| n.name=='table-cell'}.reduce(0) do |sum, el|
314
- sum + (Tools.get_ns_attribute_value(el, 'table', 'number-columns-repeated') || 1).to_i
315
- end
316
- end
317
- end
318
-
319
- class RowGroup < RowWithXMLNode
320
- @readonly = :yes_always
321
- attr_reader :range
322
- attr_accessor :parent_array, :xmlnode
323
- def initialize(aparent_array,arange,axmlnode=nil)
324
- super()
325
- @parent_array = aparent_array
326
- @range = arange
327
- if axmlnode.nil?
328
- axmlnode = Row.empty_row_node
329
- Tools.set_ns_attribute(axmlnode,'table','number-rows-repeated',range.size) if range.size>1
330
- end
331
- @xmlnode = axmlnode
332
- end
333
- # returns SingleRow if size of range is 1 and nil if it is 0 or less
334
- def normalize
335
- case range.size
336
- when 2..Float::INFINITY then self
337
- when 1 then SingleRow.new_from_rowgroup(self)
338
- else nil
339
- end
340
- end
341
- def repeated; range.size end
342
- def repeated?; range.size>1 end
343
- def range=(arange)
344
- @range=arange
345
- Tools.set_ns_attribute(@xmlnode,'table','number-rows-repeated',range.size, 1)
346
- end
347
- end
271
+ # class RowWithXMLNode < Row
272
+ # attr_accessor :xmlnode
273
+ # def style_name=(value); Tools.set_ns_attribute(@xmlnode,'table','style-name',value) end
274
+ # def get_cell(coli)
275
+ # Cell.new(self,coli,cellnodes(coli))
276
+ # end
277
+ # def nonemptycells
278
+ # nonemptycellsindexes.collect{ |index| cells(index) }
279
+ # end
280
+ # def nonemptycellsindexes
281
+ # used_col_range.to_a.select do |coli|
282
+ # cellnode = cellnodes(coli)
283
+ # !(cellnode.content.nil? or cellnode.content.empty? or cellnode.content =='') or
284
+ # !cellnode.attributes.to_a.reject{ |attr| attr.name == 'number-columns-repeated'}.empty?
285
+ # end
286
+ # end
287
+ # def cellnodes(coli)
288
+ # cellnode = nil
289
+ # while true
290
+ # curr_coli=1
291
+ # cellnode = @xmlnode.elements.select{|n| n.name=='table-cell'}.find do |el|
292
+ # curr_coli += (Tools.get_ns_attribute_value(el, 'table', 'number-columns-repeated') || 1).to_i
293
+ # curr_coli > coli
294
+ # end
295
+ # unless cellnode.nil?
296
+ # return cellnode
297
+ # else
298
+ # add_cell
299
+ # end
300
+ # end
301
+ # end
302
+ # def add_cell(repeated=1)
303
+ # cell = Cell.new(self,first_unused_column_index)
304
+ # Tools.set_ns_attribute(cell.xmlnode,'table','number-columns-repeated',repeated) if repeated>1
305
+ # @xmlnode << cell.xmlnode
306
+ # cell
307
+ # end
308
+ # def first_unused_column_index
309
+ # 1 + @xmlnode.elements.select{|n| n.name=='table-cell'}.reduce(0) do |sum, el|
310
+ # sum + (Tools.get_ns_attribute_value(el, 'table', 'number-columns-repeated') || 1).to_i
311
+ # end
312
+ # end
313
+ # end
348
314
 
349
- class SingleRow < RowWithXMLNode
350
- @readonly = :no
351
- attr_accessor :xmlnode
352
- # index Integer
353
- def initialize(aparent_array,aindex,axmlnode=nil)
354
- super()
355
- @parent_array = aparent_array
356
- @index = aindex
357
- if axmlnode.nil?
358
- axmlnode = Row.empty_row_node
359
- end
360
- @xmlnode = axmlnode
361
- end
362
- def self.new_from_rowgroup(rg)
363
- anode = rg.xmlnode
364
- Tools.remove_ns_attribute(anode,'table','number-rows-repeated')
365
- SingleRow.new(rg.parent_array,rg.range.begin,anode)
366
- end
367
- def normalize; self end
368
- def repeated?; false end
369
- def repeated; 1 end
370
- def range; (@index..@index) end
371
- def detach; self end
372
- def row; @index end
373
- def still_out_of_used_range?; false end
374
- end
315
+ # class RowGroup < RowWithXMLNode
316
+ # @readonly = :yes_always
317
+ # attr_reader :range
318
+ # attr_accessor :parent_array, :xmlnode
319
+ # def initialize(aparent_array,arange,axmlnode=nil)
320
+ # super()
321
+ # @parent_array = aparent_array
322
+ # @range = arange
323
+ # if axmlnode.nil?
324
+ # axmlnode = Row.empty_row_node
325
+ # Tools.set_ns_attribute(axmlnode,'table','number-rows-repeated',range.size) if range.size>1
326
+ # end
327
+ # @xmlnode = axmlnode
328
+ # end
329
+ # # returns SingleRow if size of range is 1 and nil if it is 0 or less
330
+ # def normalize
331
+ # case range.size
332
+ # when 2..Float::INFINITY then self
333
+ # when 1 then SingleRow.new_from_rowgroup(self)
334
+ # else nil
335
+ # end
336
+ # end
337
+ # def repeated; range.size end
338
+ # def repeated?; range.size>1 end
339
+ # def range=(arange)
340
+ # @range=arange
341
+ # Tools.set_ns_attribute(@xmlnode,'table','number-rows-repeated',range.size, 1)
342
+ # end
343
+ # end
375
344
 
376
- class LazyDetachableRow < Row
377
- @readonly = :yes_but_detachable
378
- def initialize(rowi)
379
- super()
380
- @index = rowi.to_i
381
- end
382
- def add_cell; detach.add_cell end
383
- def style_name=(value); detach.style_name=value end
384
- def row; @index end
385
- end
345
+ # class SingleRow < RowWithXMLNode
346
+ # @readonly = :no
347
+ # attr_accessor :xmlnode
348
+ # # index Integer
349
+ # def initialize(aparent_array,aindex,axmlnode=nil)
350
+ # super()
351
+ # @parent_array = aparent_array
352
+ # @index = aindex
353
+ # if axmlnode.nil?
354
+ # axmlnode = Row.empty_row_node
355
+ # end
356
+ # @xmlnode = axmlnode
357
+ # end
358
+ # def self.new_from_rowgroup(rg)
359
+ # anode = rg.xmlnode
360
+ # Tools.remove_ns_attribute(anode,'table','number-rows-repeated')
361
+ # SingleRow.new(rg.parent_array,rg.range.begin,anode)
362
+ # end
363
+ # def normalize; self end
364
+ # def repeated?; false end
365
+ # def repeated; 1 end
366
+ # def range; (@index..@index) end
367
+ # def detach; self end
368
+ # def row; @index end
369
+ # def still_out_of_used_range?; false end
370
+ # end
386
371
 
387
- ## there are not data in this object, they are taken from RowGroup, but this is only readonly
388
- class MemberOfRowGroup < LazyDetachableRow
389
- @readonly = :yes_but_detachable
390
- extend Forwardable
391
- delegate [:repeated?, :repeated, :xmlnode, :parent_array] => :@row_group
392
- attr_accessor :row_group # for dubugging
372
+ # class LazyDetachableRow < Row
373
+ # @readonly = :yes_but_detachable
374
+ # def initialize(rowi)
375
+ # super()
376
+ # @index = rowi.to_i
377
+ # end
378
+ # def add_cell; detach.add_cell end
379
+ # def style_name=(value); detach.style_name=value end
380
+ # def row; @index end
381
+ # end
393
382
 
394
- # @index Integer
395
- # @row_group RepeatedRow
396
- def initialize(arowi,arow_group)
397
- super(arowi)
398
- @row_group = arow_group
399
- raise 'Wrong parameter given - class is '+@row_group.class.to_a unless @row_group.is_a? RowGroup
400
- end
401
- def detach # detaches MemberOfRowGroup from its RowGroup perhaps splitting RowGroup
402
- @row_group.parent_array.detach(@index)
403
- end
404
- def get_cell(coli)
405
- c = Cell.new(self,coli,@row_group.cellnodes(coli))
406
- c.mode = :repeated
407
- c
408
- end
409
- def first_unused_column_index
410
- @row_group.first_unused_column_index
411
- end
412
- def nonemptycells
413
- @row_group.nonemptycellsindexes.collect{ |coli| cells(coli) }
414
- end
415
- end
383
+ # ## there are not data in this object, they are taken from RowGroup, but this is only readonly
384
+ # class MemberOfRowGroup < LazyDetachableRow
385
+ # @readonly = :yes_but_detachable
386
+ # extend Forwardable
387
+ # delegate [:repeated?, :repeated, :xmlnode, :parent_array] => :@row_group
388
+ # attr_accessor :row_group # for dubugging
389
+ #
390
+ # # @index Integer
391
+ # # @row_group RepeatedRow
392
+ # def initialize(arowi,arow_group)
393
+ # super(arowi)
394
+ # @row_group = arow_group
395
+ # raise 'Wrong parameter given - class is '+@row_group.class.to_a unless @row_group.is_a? RowGroup
396
+ # end
397
+ # def detach # detaches MemberOfRowGroup from its RowGroup perhaps splitting RowGroup
398
+ # @row_group.parent_array.detach(@index)
399
+ # end
400
+ # def get_cell(coli)
401
+ # c = Cell.new(self,coli,@row_group.cellnodes(coli))
402
+ # c.mode = :repeated
403
+ # c
404
+ # end
405
+ # def first_unused_column_index
406
+ # @row_group.first_unused_column_index
407
+ # end
408
+ # def nonemptycells
409
+ # @row_group.nonemptycellsindexes.collect{ |coli| cells(coli) }
410
+ # end
411
+ # end
416
412
 
417
- ## this is a row outside the used bounds. the main purpose of this object is to magically synchronize to existing data, once they are created
418
- class UninitializedEmptyRow < LazyDetachableRow
419
- @readonly = :yes_but_detachable
420
- attr_reader :parent_array # debug only
421
- def initialize(aparent_array,arowi)
422
- super(arowi)
423
- @parent_array = aparent_array
424
- end
425
- def get_cell(coli)
426
- if still_out_of_used_range?
427
- Cell.new(self,coli,nil)
428
- else
429
- @parent_array.get_row(@index).cells(coli)
430
- end
431
- end
432
- def normalize
433
- if still_out_of_used_range?
434
- self
435
- else
436
- @parent_array.get_row(@index)
437
- end
438
- end
439
- def detach; @parent_array.detach_item(@index) end
440
- def detach_cell(col)
441
- self.detach.detach_cell(col)
442
- end
443
- def still_out_of_used_range?; @index >= @parent_array.first_unused_row_index end
444
- def xmlnode; Row.empty_row_node end
445
- def first_unused_column_index; 1 end
446
- end
447
413
 
448
414
  end