Class: ListModel

Inherits:
Object
  • Object
show all
Includes:
Conf, DRbUndumped, ManqodCommon
Defined in:
lib/ListHolder/EditableList/DrbListModel.rb

Overview

this file is part of manqod manqod is distributed under the CDDL licence the author of manqod is Dobai-Pataky Balint([email protected])

Constant Summary

Constants included from ManqodCommon

ManqodCommon::CRITICAL, ManqodCommon::DEBUG, ManqodCommon::ERROR, ManqodCommon::INFO, ManqodCommon::NORMAL, ManqodCommon::WARNING

Constants included from Eprint

Eprint::DOMAIN, Eprint::LEVEL

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Conf

#get_conf, #load_conf, #save_conf, #set_conf

Methods included from ManqodCommon

#add_where, #admin, #admin_cache, #admin_qrow, #admin_rows, #backtrace_to_debug, #cache, #changed_ids_of_base, #client, #client_fields, #client_image_of_id, #client_qrow, #client_query, #client_rows, #eeval, #escape_string, #getBinding, #guess_base, #guess_table, #image_of_id, #lzero, #manqod_db, #measure, #myexec, #nick, #nick_id, #number_format, #qrow, #query, #reconnect_manqod_db, #rows, #run_events, #send_message, #sendmail, #set_manqod_db_uri, #set_nick

Methods included from Eprint

#ecode, #edebug, #eerror, #einfo, #enormal, #eprint, #ewarn, #gtk_set_edebug, #set_edebug, #tell_exception

Constructor Details

#initialize(list) ⇒ ListModel

Returns a new instance of ListModel.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 10

def initialize(list)
	@filter=nil
	@data=nil
	@id_index=Hash.new
	@sorter=nil
	@parentselected=nil
	@filtered_rowcount=0
	@rowcount=0
	@rows_loaded=nil
	@show_archive=false
	@list=list
	@remote_model=nil
	@key_parent=nil
	@key_parent2=nil
	@moditem=nil
	@base=nil
	@thread=nil
	@headers=Hash.new
	@headertypes=Array.new
end

Instance Attribute Details

#archive_keyObject (readonly)

Returns the value of attribute archive_key.



40
41
42
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 40

def archive_key
  @archive_key
end

#background_legendObject (readonly)

Returns the value of attribute background_legend.



42
43
44
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 42

def background_legend
  @background_legend
end

#baseObject (readonly)

Returns the value of attribute base.



36
37
38
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 36

def base
  @base
end

#column_of_backgroundObject (readonly)

Returns the value of attribute column_of_background.



36
37
38
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 36

def column_of_background
  @column_of_background
end

#column_of_child_keyObject (readonly)

Returns the value of attribute column_of_child_key.



37
38
39
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 37

def column_of_child_key
  @column_of_child_key
end

#column_of_child_key2Object (readonly)

Returns the value of attribute column_of_child_key2.



37
38
39
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 37

def column_of_child_key2
  @column_of_child_key2
end

#column_of_foregroundObject (readonly)

Returns the value of attribute column_of_foreground.



36
37
38
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 36

def column_of_foreground
  @column_of_foreground
end

#column_of_gantt_durationObject (readonly)

Returns the value of attribute column_of_gantt_duration.



39
40
41
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 39

def column_of_gantt_duration
  @column_of_gantt_duration
end

#column_of_gantt_groupObject (readonly)

Returns the value of attribute column_of_gantt_group.



39
40
41
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 39

def column_of_gantt_group
  @column_of_gantt_group
end

#column_of_gantt_group_colorObject (readonly)

Returns the value of attribute column_of_gantt_group_color.



39
40
41
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 39

def column_of_gantt_group_color
  @column_of_gantt_group_color
end

#column_of_gantt_partialObject (readonly)

Returns the value of attribute column_of_gantt_partial.



39
40
41
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 39

def column_of_gantt_partial
  @column_of_gantt_partial
end

#column_of_gantt_percentageObject (readonly)

Returns the value of attribute column_of_gantt_percentage.



39
40
41
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 39

def column_of_gantt_percentage
  @column_of_gantt_percentage
end

#column_of_gantt_startObject (readonly)

Returns the value of attribute column_of_gantt_start.



39
40
41
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 39

def column_of_gantt_start
  @column_of_gantt_start
end

#column_of_gantt_successorsObject (readonly)

Returns the value of attribute column_of_gantt_successors.



39
40
41
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 39

def column_of_gantt_successors
  @column_of_gantt_successors
end

#column_of_idObject (readonly)

Returns the value of attribute column_of_id.



36
37
38
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 36

def column_of_id
  @column_of_id
end

#column_of_parent_keyObject (readonly)

Returns the value of attribute column_of_parent_key.



37
38
39
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 37

def column_of_parent_key
  @column_of_parent_key
end

#column_of_parent_key2Object (readonly)

Returns the value of attribute column_of_parent_key2.



37
38
39
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 37

def column_of_parent_key2
  @column_of_parent_key2
end

#column_of_sensitiveObject (readonly)

Returns the value of attribute column_of_sensitive.



36
37
38
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 36

def column_of_sensitive
  @column_of_sensitive
end

#column_of_visibleObject (readonly)

Returns the value of attribute column_of_visible.



36
37
38
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 36

def column_of_visible
  @column_of_visible
end

#dataObject

Returns the value of attribute data.



30
31
32
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 30

def data
  @data
end

#filterObject

Returns the value of attribute filter.



30
31
32
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 30

def filter
  @filter
end

#filtered_rowcountObject

Returns the value of attribute filtered_rowcount.



32
33
34
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 32

def filtered_rowcount
  @filtered_rowcount
end

#foreground_legendObject (readonly)

Returns the value of attribute foreground_legend.



42
43
44
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 42

def foreground_legend
  @foreground_legend
end

#headersObject (readonly)

Returns the value of attribute headers.



41
42
43
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 41

def headers
  @headers
end

#headertypesObject (readonly)

Returns the value of attribute headertypes.



41
42
43
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 41

def headertypes
  @headertypes
end

#key_childObject (readonly)

Returns the value of attribute key_child.



38
39
40
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 38

def key_child
  @key_child
end

#key_child2Object (readonly)

Returns the value of attribute key_child2.



38
39
40
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 38

def key_child2
  @key_child2
end

#key_parentObject (readonly)

Returns the value of attribute key_parent.



38
39
40
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 38

def key_parent
  @key_parent
end

#key_parent2Object (readonly)

Returns the value of attribute key_parent2.



38
39
40
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 38

def key_parent2
  @key_parent2
end

#listObject

Returns the value of attribute list.



33
34
35
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 33

def list
  @list
end

#list_keyObject (readonly)

Returns the value of attribute list_key.



36
37
38
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 36

def list_key
  @list_key
end

#moditemObject

Returns the value of attribute moditem.



30
31
32
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 30

def moditem
  @moditem
end

#parentMObject

Returns the value of attribute parentM.



33
34
35
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 33

def parentM
  @parentM
end

#parentselectedObject

Returns the value of attribute parentselected.



34
35
36
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 34

def parentselected
  @parentselected
end

#rowcountObject (readonly)

Returns the value of attribute rowcount.



31
32
33
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 31

def rowcount
  @rowcount
end

#rows_loadedObject (readonly)

Returns the value of attribute rows_loaded.



31
32
33
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 31

def rows_loaded
  @rows_loaded
end

#show_archiveObject (readonly)

Returns the value of attribute show_archive.



40
41
42
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 40

def show_archive
  @show_archive
end

#sorterObject (readonly)

Returns the value of attribute sorter.



31
32
33
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 31

def sorter
  @sorter
end

#threadObject (readonly)

Returns the value of attribute thread.



31
32
33
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 31

def thread
  @thread
end

Instance Method Details

#add_iterObject



631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 631

def add_iter
	if table=guess_table(@querysql,'id')
		sql="insert into #{table}";
  	if @key_child
  		sql="#{sql} set #{@key_child}="
  		if @key_parent=="id"
  			sql="#{sql}'#{parentselected}'"
  		else
				if parent_header=parentM.headers[@key_parent] and parent_iter=parentM.iter_at_cursor
					sql="#{sql}'#{parent_iter[parent_header["model_col"]]}'"
				end
			end
			sql="#{sql},#{moditem['additional_on_insert']}" if moditem['additional_on_insert'].length>0
  	else
			if lastt=@querysql.index('{parentselected}')
				last=@querysql.rindex('=',lastt)-1
				temp1=@querysql[1 .. last]
				first=temp1.rindex(' ')+1
				sql="#{sql} set "+@querysql[first .. last]+"='#{parentselected}'"
				sql=sql+", "+moditem['additional_on_insert'] if moditem['additional_on_insert'].length>0
			else
				if moditem['additional_on_insert'].length>0 
					sql="#{sql} set #{moditem['additional_on_insert']}"
				else 
					sql="#{sql} () VALUES()";
				end
			end
		end
	end
	query(eeval("\"#{sql}\""))
	inserted_id=qrow("select id from #{table} order by id desc limit 1")["id"].to_i
	row_modified(inserted_id)
	inserted_id
end

#alive?Boolean

Returns:

  • (Boolean)


820
821
822
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 820

def alive?
	true
end

#change_value_of_id(iter_id, column_data, new_value) ⇒ Object



673
674
675
676
677
678
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 673

def change_value_of_id(iter_id, column_data, new_value)
	sql="update #{@base} set #{column_data}='#{new_value}' where #{@list_key}='#{iter_id}' limit 1"
	einfo("changing #{column_data.inspect} to #{new_value.inspect} updatesql: #{sql.inspect}","list")
	query(eeval("\"#{sql}\""))
	row_modified(iter_id)
end

#change_value_of_iter(iter, column_data, new_value) ⇒ Object



666
667
668
669
670
671
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 666

def change_value_of_iter(iter, column_data, new_value)
	sql="update #{@base} set #{column_data}='#{new_value}' where #{@list_key}='#{iter[column_of_id]}' limit 1"
	einfo("changing #{column_data.inspect} to #{new_value.inspect} updatesql: #{sql.inspect}","list")
	query(eeval("\"#{sql}\""))
	row_modified(iter[column_of_id])
end

#change_value_of_path(path, column_data, new_value) ⇒ Object



680
681
682
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 680

def change_value_of_path(path, column_data, new_value)
	change_value_of_iter(@sorter.get_iter(path), column_data, new_value)
end

#create_skeletonObject



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 170

def create_skeleton
	unless get_id
		edebug("can't update, no list_id set","list","error")
		return
	end
#		list.progress.pulse(list.get_id)
#		@thread=Thread.new{
	begin
		drbmodel.unsubscribe(ManqodRPC.instance.to_s) unless @remote_model.nil?
	rescue => err
		ewarn("server model is gone")
	end
	begin
		@remote_model=manqod_db.moditem(get_id)
	rescue =>err
		eerror(backtrace_to_debug(err),'list')
		if reconnect_manqod_db
			retry
		else
			tell_exception("server is gone")
		end
	end
	@moditem=cache.get("#{get_id}moditem")
	@headers=cache.get("#{get_id}headers")
	@headertypes=cache.get("#{get_id}headertypes")
	moditem_attributes=cache.get("#{get_id}attributes")
	@querysql=moditem_attributes[:querySQL]
	@base=moditem_attributes[:base]
	@list_key=moditem_attributes[:list_key]
	@key_child=moditem_attributes[:child_key]
	@key_parent=moditem_attributes[:parent_key]

	@key_child2=moditem_attributes[:child_key2]
	@key_parent2=moditem_attributes[:parent_key2]
	@tree_key=moditem_attributes[:tree_key]
	@column_of_id=moditem_attributes[:column_of_id]
	@column_of_visible=moditem_attributes[:column_of_visible]
	@column_of_sensitive=moditem_attributes[:column_of_sensitive]
	@column_of_background=moditem_attributes[:column_of_background]
	@column_of_foreground=moditem_attributes[:column_of_foreground]
	@column_of_archive=moditem_attributes[:column_of_archive]
	@column_of_tree_parent=moditem_attributes[:column_of_tree_parent]
	@column_of_tree=moditem_attributes[:column_of_tree]
	@fetch_filter_key=moditem_attributes[:fetch_filter_key]
	@fetch_filter_value=moditem_attributes[:fetch_filter_value]
	@fetch_filter_negate=moditem_attributes[:fetch_filter_negate]
	@column_of_fetch_filter=moditem_attributes[:column_of_fetch_filter]
	@archive_key=moditem_attributes[:archive_key]

	drbmodel.subscribe(ManqodRPC.instance.to_s,self)


	@parentM=list.parentM.get_model if list.parentM
	
	if @tree_key
		@data = Gtk::TreeStore.new(*headertypes)
		else
		@data = Gtk::ListStore.new(*headertypes)
	end

	hdebug="#{hdebug}\nheadertypes: #{headertypes.inspect}\nheaders:[result]order<[editable]>[rgrp_id]\n"
	
	headers.delete_if{|key,val|			
		hdebug="#{hdebug}[#{val['data']}]#{val['model_col']}#{val['editable'] == 'true' ? '[ed]' : ''}[#{val['rgrp_id']}]\n"
		val['rgrp_id'].to_i>0 && !Nick.instance.ingroup_id?(val['rgrp_id'].to_i)
	}
	edebug("#{hdebug}","list")
	@column_of_child_key=nil
	if @key_child && headers.has_key?(@key_child)
		@column_of_child_key=headers[@key_child]["model_col"]
	end
	@column_of_child_key2=nil
	if @key_child2 && headers.has_key?(@key_child2)
		@column_of_child_key2=headers[@key_child2]["model_col"]
	end
	#if child_key defined, but parent_key is not, we set parent_key=parentM.list_key
	@key_parent=parentM.list_key if @key_child && @key_parent.nil?
	#if child_key2 defined, but parent_key2 is not, we set parent_key2='id'
	@key_parent2=parentM.list_key if @key_child2 && @key_parent2.nil?

	@column_of_parent_key=nil
	if @key_parent && parentM && parentM.headers.has_key?(@key_parent)
		@column_of_parent_key=parentM.headers[@key_parent]["model_col"]
	end
	@column_of_parent_key2=nil
	if @key_parent2 && parentM && parentM.headers.has_key?(@key_parent2)
		@column_of_parent_key2=parentM.headers[@key_parent2]["model_col"]
	end
	@filter=Gtk::TreeModelFilter.new(@data)
	@filter.set_visible_column(column_of_visible)
	@sorter=Gtk::TreeModelSort.new(@filter)
	if sortcolumn=get_conf(get_id,0,"sortcolumn") and sortorder=get_conf(get_id,0,"sortorder")
		@sorter.set_sort_column_id(sortcolumn.to_i,sortorder=="asc" ? Gtk::SORT_ASCENDING : Gtk::SORT_DESCENDING)
	end

	if gantt_start=list.gtk_attribute('gantt_start')
		@column_of_gantt_start=headers[gantt_start]
	end
	
	if gantt_duration=list.gtk_attribute('gantt_duration')
		@column_of_gantt_duration=headers[gantt_duration]
	end
	if gantt_successors=list.gtk_attribute('gantt_successors')
		@column_of_gantt_successors=headers[gantt_successors]
	end
	if gantt_group=list.gtk_attribute('gantt_group')
		@column_of_gantt_group=headers[gantt_group]
	end

	if gantt_group=list.gtk_attribute('gantt_group')
		@column_of_gantt_group=headers[gantt_group]
	end
	if gantt_group_color=list.gtk_attribute('gantt_group_color')
		@column_of_gantt_group_color=headers[gantt_group_color]
	end
	if gantt_partial=list.gtk_attribute('gantt_partial')
		@column_of_gantt_partial=headers[gantt_partial]
	end
	if gantt_percentage=list.gtk_attribute('gantt_percentage')
		@column_of_gantt_percentage=headers[gantt_percentage]
	end
	
	@foreground_legend=cache.get("#{get_id}foreground")
	@background_legend=cache.get("#{get_id}background")

	list.set_info("created")
#		}
#		@thread.join
end

#data_iter_of_col_num(col_num, col_num_data) ⇒ Object

finds iter by col_num, col_num=colnum number to search for, col_num_data=the data we’re looking for



138
139
140
141
142
143
144
145
146
147
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 138

def data_iter_of_col_num(col_num,col_num_data)
	found_iter=nil
	@data.each{|model,path,iter|
		if iter[col_num]==col_num_data
			found_iter=iter
			break
		end
	}
	found_iter
end

#data_of_column(colname, lid = list.get_cursor_id) ⇒ Object



163
164
165
166
167
168
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 163

def data_of_column(colname,lid=list.get_cursor_id)
	ret=nil
	if di=iter_of_id(lid) and col=headers[colname]
		ret=di[col["model_col"]]
	end
end

#display_lock(locked_id) ⇒ Object



121
122
123
124
125
126
127
128
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 121

def display_lock(locked_id)
	einfo("display lock called for: #{locked_id}")
	if iter=@id_index[locked_id]
		iter[@column_of_sensitive]=drbmodel.data[locked_id][@column_of_sensitive]
		list.changed
		list.notify_observers(list)
	end
end

#drbmodelObject



45
46
47
48
49
50
51
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 45

def drbmodel
	begin
		@remote_model
		rescue =>err
		edebug("error: #{err}\n#{err.backtrace.joint("\n")}\n","list","error")
	end
end

#duplicate_iter(iter_to_dup) ⇒ Object



623
624
625
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 623

def duplicate_iter(iter_to_dup)
	drbmodel.duplicate_iter(iter_to_dup)
end

#filter_one_iter(iter) ⇒ Object



393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 393

def filter_one_iter(iter)
	if @key_child.nil? || (@key_child && iter[@column_of_child_key] == @current_parent_key) || (@key_child2 && iter[@column_of_child_key2] == @current_parent_key2)
		filter_count=0
		filter_hits=0
		list.columns.each{|column|
				fl=get_conf(get_id,column.header["id"],"filter").to_s.upcase
				case column.header['type']
					when 'gtk_combo', 'gtk_const_combo' then fl = (fl=="-1" or fl=="") ? "" : "=#{fl}"
				end
				#if timestamp, then we convert the comparision data to the timestamp format specified by attributes
				comp=case column.header['type']
					when 'gtk_timestamp' then Time.at(iter[column.header["model_col"]]).strftime(column.timestamp_format).upcase
					else iter[column.header["model_col"]].to_s.upcase
				end

				if fl.length>0
					filter_count=filter_count+1
					filter_hits=filter_hits+
						case column.header['type']
						when 'gtk_int','Integer','gtk_float','gtk_progress','gtk_duration' then
							case fl[0].chr
								when "<" then comp.to_f <  fl[1 .. fl.length].to_f ? 1: 0
								when ">" then comp.to_f >  fl[1 .. fl.length].to_f ? 1: 0
								when "!" then comp.to_f != fl[1 .. fl.length].to_f ? 1: 0
								when "=" then comp.to_f == fl[1 .. fl.length].to_f ? 1: 0
								else comp.to_f == fl[0 .. fl.length].to_f ? 1: 0
							end
						else
							case fl[0].chr
								when "=" then comp == fl[1 .. fl.length] ? 1: 0
								when "<" then comp <  fl[1 .. fl.length] ? 1: 0
								when ">" then comp >  fl[1 .. fl.length] ? 1: 0
								when "!" then comp != fl[1 .. fl.length] ? 1: 0
								else comp.index(fl) ? 1: 0
							end
						end
				end
			} unless list.destroyed?
			iter[column_of_visible]=filter_hits == filter_count
		#make sure parent iters are visible, only when we're tree
		unhide_tree_parent_iters(iter) if @column_of_tree && iter[@column_of_visible]
		else
				iter[@column_of_visible]=false
	end
	iter[@column_of_visible]
end

#from_csv(filename) ⇒ Object



729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 729

def from_csv(filename)
	separator=(list.gtk_attribute("csv_field_separator") ? list.gtk_attribute("csv_field_separator") : ',')
	skip_header_lines=(list.gtk_attribute("csv_skip_header_lines") ? list.gtk_attribute("csv_skip_header_lines").to_i : 1)
	row_counter=0
	ids=Array.new
	IO.foreach(filename){|line|
		row=line.chomp.split(separator)
		row_counter+=1
		if row_counter > skip_header_lines && row.size>0
			sql="insert into #{base} set"
			comma=false
			#child key auto adding
			if @key_child
				comma=true
				sql="#{sql} #{@key_child}="
				if @key_parent=="id"
					sql="#{sql}'#{parentselected}'"
				else
					if parent_header=parentM.headers[@key_parent] and parent_iter=parentM.iter_at_cursor
						sql="#{sql}'#{parent_iter[parent_header["model_col"]]}'"
					end
				end
			end
			#values
			list.columns.each{|col|
				if c=col.gtk_attribute("csv_column_number")
					sql="#{sql}#{comma ? ",": ""} #{col.header['data']}=\"#{row[c.to_i-1]}\""
					comma=true
				end
			}
			sql="#{sql};" #unless sql.nil?
			sql="#{sql} #{moditem['additional_on_insert']}" if moditem['additional_on_insert'].length>0
			query(sql)
			inserted_id=qrow("select id from #{base} order by id desc limit 1")["id"].to_i
			ids.push(inserted_id)
		end
	}
	drbmodel.rows_changed(ids,nick) if ids.size>0
	edebug("csv loaded","list")
end

#get_idObject



87
88
89
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 87

def get_id
	list.get_id
end

#iter2csv(iter) ⇒ Object



691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 691

def iter2csv(iter)
	separator=(list.gtk_attribute("csv_field_separator") ? list.gtk_attribute("csv_field_separator") : ',')
	row=""
	list.columns.each{|col|
		case col.header["type"] 
			when "gtk_const_text" then ct=col.renderer.get_display(iter[col.colnum].to_s)
			when "gtk_const_combo","gtk_combo" then ct=col.renderer.get_text_from_value(iter[col.colnum].to_s)
			else
			ct=case col.data_type.to_s
					when "Integer" then number_format(iter[col.colnum],0)
					when "Float" then number_format(iter[col.colnum],2)
					else iter[col.colnum].to_s
			end
		end
		row="#{row}#{ct.to_s}#{separator}"
	}
	row="#{row[0..row.length]}\n"
end

#iter_at_cursorObject



159
160
161
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 159

def iter_at_cursor
	iter_of_id(list.get_cursor_id) if list.get_cursor_id
end

#iter_of_id(id_of_iter) ⇒ Object



148
149
150
151
152
153
154
155
156
157
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 148

def iter_of_id(id_of_iter)
	found_iter=nil
	@sorter.each{|model,path,iter|
		if iter[@column_of_id] == id_of_iter.to_i
			found_iter=iter
			break
		end
	} if @sorter
	found_iter		
end

#load_data(notifier, ids = nil) ⇒ Object



446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 446

def load_data(notifier,ids=nil)
#		@thread=Thread.new{
	ids=[ids] if !ids.nil? and ids.class != Array
	ids.uniq! if ids.class == Array
	edebug("called for data_load for #{ids.inspect} by #{notifier}","list","info")
	begin
			we_have_server=drbmodel.alive?
		rescue => err
			if reconnect_manqod_db
				retry
			else
				tell_exception("server is gone")
			end
	end

	return unless we_have_server

	before=Time.now
	@rows_loaded=0
	@rowcount=drbmodel.rowcount
	ffv=if @fetch_filter_value then eeval(@fetch_filter_value) else nil end
	edebug("fetch-filter: key:#{@fetch_filter_key}, value:#{@fetch_filter_value}=#{ffv}","list")
	if ids.nil?
		list.set_model(nil)
		list.set_info("0")
		@data.clear
		@id_index.clear
		parent_iter=parentM.iter_at_cursor if parentM
		@current_parent_key=if @column_of_parent_key and parent_iter
			parent_iter[@column_of_parent_key]
		end
		@current_parent_key2=if @column_of_parent_key2 and parent_iter
			parent_iter[@column_of_parent_key2]
		end

		list.progress.zero(list.object_id,0,@moditem["display"])

		prep_time=Time.now.to_f-before.to_f
		before=Time.now
		ff=nil
		pkeys=Array.new
#			@thread=Thread.new{
			keys=cache.get("#{@moditem["id"]}[ids]")
			keys.each{|v| pkeys.push("#{@moditem["id"]}[#{v}]")}
			ff=cache.get(pkeys)
			@rowcount=ff ? ff.size : 0
#			}
#			@thread.join

#			ff=drbmodel.filtered_fetch2(ffv,@show_archive)
		fetch_time=Time.now.to_f-before.to_f
		list.progress.zero(list.object_id,@rowcount,@moditem["display"])

		before=Time.now
				pkeys.each{|idx|
					row=ff[idx]
					eerror("row #{idx} is nil!","list") if row.nil?
#							next if !@show_archive && !@column_of_archive.nil? && row[@column_of_archive]
					next unless (@column_of_fetch_filter.nil? || ffv.nil? || 
							(!@fetch_filter_negate && 
								row[@column_of_fetch_filter].to_s == ffv.to_s
							) || 
							(@fetch_filter_negate && row[@column_of_fetch_filter].to_s != ffv.to_s) 
						) && row && (@column_of_archive.nil? || (@show_archive || !row[@column_of_archive]))
						#we recieve a row
					iter=if @tree_key then @data.append(@id_index[row[@column_of_tree].to_i]) else @data.append end
					begin
						row.each_pair{|key,val| iter[key]=val}
					rescue =>err
#							eerror("filling row: #{err}\n#{key.inspect}=>#{val}\niter:#{iter.inspect}, row:#{row.inspect}","list")
					end
					@id_index[row[@column_of_id].to_i]=iter
					@rows_loaded+=1
					Thread.new{list.progress.step(list.object_id,@rows_loaded)}
	#				Thread.pass

				} unless ff.nil? #nil if no keys found, the list is empty

		load_time=Time.now.to_f-before.to_f
			t=Time.new
			refilter
			filtert=Time.new.to_f-t.to_f
			update_time=Time.now.to_f-before.to_f
			enormal("total: #{@filtered_rowcount}/#{@rows_loaded}/#{@rowcount} (prep:"+sprintf("%.2fs",prep_time)+",fetch:"+sprintf("%.2fs",fetch_time)+",load:"+sprintf("%.2fs",load_time)+",refilter:"+sprintf("%.2fs",filtert)+")"+sprintf("%.2fs",update_time),"time")
			einfo("data loaded #{ids or 'all rows'}","list")
	else
		ids.each{|row_id|
			begin
				row=cache.get("#{@moditem["id"]}[#{row_id}]")
#						eerror("row #{row_id} is nil!","list") if row.nil?
			#row=drbmodel.data[row_id]
				if row && (@column_of_fetch_filter.nil? || ffv.nil? || 
							(!@fetch_filter_negate && 
								row[@column_of_fetch_filter].to_s == ffv.to_s
							) || 
							(@fetch_filter_negate && row[@column_of_fetch_filter].to_s != ff_value.to_s) 
						)  && (@column_of_archive.nil? || (@show_archive || !row[@column_of_archive]))
			
				piter=@id_index[row[@column_of_tree].to_i]
				if iter=@id_index[row_id]
					#iter is found
					if iter && iter.parent!=piter
						edebug("current parent:#{iter.parent.inspect}!=new parent:#{piter.inspect} -> we remove iter, so we readd it later, thus reparenting it","list")
						parent_iter=iter.parent
						rec_save_childs(iter)
						iter=nil
						need_to_reload=true
					end
				end
				unless iter=@id_index[row_id]
					edebug("new iter, id:#{row_id.inspect}","list")
					if @tree_key then
						list.set_model(nil) if !piter.nil? and !piter.has_child?
						iter=@data.append(piter)
					else 
						iter=@data.append 
					end
				end

				begin
					row.each_pair{|key,val| iter[key]=val}
				rescue =>err
					edebug("filling one row: #{err}\n iter:#{iter}, row:#{row.inspect}, id:#{row_id}","list","error")
				end
				@id_index[row[@column_of_id].to_i]=iter
				@data.row_changed(iter.path,iter)
				reload_saved_childs if need_to_reload
				refilter(iter)
			else
				edebug("we were called to load_data of a non existing id:#{row_id}, which means it's archive and we don't show archive","list")
				if iter_to_remove=@id_index[row_id]
					data.remove(iter_to_remove)
					@id_index.delete(row_id)
				end
			end
			rescue Memcached::NotFound
				eerror("cache not found: id:[#{row_id}]")
				data.remove(iter_to_remove)
				@id_index.delete(row_id)
			
			rescue => err
				eerror("#{err}\n\t#{err.backtrace.join("\n\t")}")
				#we were called to load_data of a non existing id, which means it's deleted
			end
		}
		gstart=Time.new
		list.set_model(@sorter) if list.model.nil?
		gtime=Time.new.to_f-gstart.to_f
		Gtk.thread_protect{list.scroll_to_cursor}

		update_time=Time.now.to_f-before.to_f
#			edebug("total: #{@filtered_rowcount}/#{@rowcount} "+sprintf("%.2fs",update_time) + +sprintf("%.2fs",gtime),"time","normal")
		edebug("data loaded #{ids.inspect or 'all rows'}","list","info")
	end

#		}
end

#lock_iter(locked_id) ⇒ Object



91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 91

def lock_iter(locked_id)
	counter=0
	begin
		counter+=1
		manqod_db.lock_id_of_base(@base,locked_id)
	rescue =>err
		resubscribe
		if counter==3
			warn("server is gone",err.to_s,"list",ERROR,false,false)
		else
			retry
		end
	end
end

#locked?(locked_id) ⇒ Boolean

Returns:

  • (Boolean)


129
130
131
132
133
134
135
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 129

def locked?(locked_id)
	locked=nil
	if iter=@id_index[locked_id]
		locked=!iter[@column_of_sensitive]
	end
	locked
end

#move_down_id(uid) ⇒ Object



804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 804

def move_down_id(uid)
	ordering=@list.gtk_attribute("ordering")
	if ordering && (ocolh=headers[ordering]) && (iter=iter_of_id(uid))
		ocol=ocolh["model_col"]
		if next_iter=next_sorted_iter(iter) #only if we have next
			if nnext_iter=next_sorted_iter(next_iter)
				#middle of next and nnext
				change_value_of_iter(iter,ordering,(nnext_iter[ocol]+next_iter[ocol])/2.0)
			else
				#next +1
				change_value_of_iter(iter,ordering,next_iter[ocol]+1)
			end
		end
	end
end

#move_up_id(uid) ⇒ Object



788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 788

def move_up_id(uid)
	ordering=@list.gtk_attribute("ordering")
	if ordering && (ocolh=headers[ordering]) && (iter=iter_of_id(uid))
		ocol=ocolh["model_col"]
		if prev_iter=prev_sorted_iter(iter) #only if we have previous
			if pprev_iter=prev_sorted_iter(prev_iter)
				#middle of prev and pprev
				change_value_of_iter(iter,ordering,(prev_iter[ocol]+pprev_iter[ocol])/2.0)
			else
				#prev -1
				change_value_of_iter(iter,ordering,prev_iter[ocol]-1)
			end
		end
	end
end

#next_sorted_iter(iter) ⇒ Object



781
782
783
784
785
786
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 781

def next_sorted_iter(iter)
	pp=iter.path
	if pp.next!
		@sorter.get_iter(pp)
	end
end

#prev_sorted_iter(iter) ⇒ Object



774
775
776
777
778
779
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 774

def prev_sorted_iter(iter)
	pp=iter.path
	if pp.prev!
		@sorter.get_iter(pp)
	end
end


52
53
54
55
56
57
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 52

def print_iter(iter)
	if iter
		headers.each_value{|h| print h['data'],":",iter[h['model_col']]," "}
		print "\n"
	end
end


66
67
68
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 66

def print_iter_of_id(id_to_print)
	print_iter(iter_of_id(id_to_print))
end

#rec_save_childs(root_iter) ⇒ Object



604
605
606
607
608
609
610
611
612
613
614
615
616
617
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 604

def rec_save_childs(root_iter)
	@childs_to_readd=Array.new if @childs_to_readd.nil?
	if iter=root_iter.first_child
		loop{
			@childs_to_readd.push(iter[column_of_id])
			prev_iter=iter.clone
			finished=!iter.next!
			rec_save_childs(prev_iter)
			break if finished
		}
	end
	@id_index.delete(root_iter[@column_of_id].to_i)
	@data.remove(root_iter)
end

#refilter(one = nil) ⇒ Object



359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 359

def refilter(one=nil)
 	edebug("refiltering #{one}")
 	if one.nil?
 		list.set_model(nil)
 		list.progress.zero(list.object_id,@rows_loaded,@moditem["display"])
 		@thread=Thread.new{
			r=0
			@data.each{|model, path, iter|
				filter_one_iter(iter)
				r+=1
				list.progress.step(list.object_id,r)
			}
		}
		@thread.join
		einfo("refiltered","list")
		list.set_model(@sorter)
		list.progress.done(list.object_id)
		unless list.destroyed?
			list.scroll_to_cursor
			list.update_tip
			list.caller.list_panel.list_sum.calculate
		end
	else
		filter_one_iter(one)
	end
	
	#update filtered count
	
	@filtered_rowcount=0
	@data.each{|model, path, iter| @filtered_rowcount+=1 if iter[column_of_visible]}
	list.set_info("#{@filtered_rowcount}/#{@rows_loaded}")
	self
end

#reload_saved_childsObject



619
620
621
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 619

def reload_saved_childs
	load_data(self,@childs_to_readd) if @childs_to_readd.class == Array && @childs_to_readd.size>0
end

#remove_iters(iters_to_remove) ⇒ Object



627
628
629
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 627

def remove_iters(iters_to_remove)
	drbmodel.remove_iters(iters_to_remove,nick)
end

#resubscribeObject



58
59
60
61
62
63
64
65
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 58

def resubscribe
	begin
		@remote_model=manqod_db.moditem(get_id)
		drbmodel.subscribe(ManqodRPC.instance.to_s,self)
	rescue =>err
		retry if warn("can't reconnect to server",err.to_s,"list",ERROR,false,true)
	end
end

#row_modified(modified_id = list.get_cursor_id) ⇒ Object



684
685
686
687
688
689
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 684

def row_modified(modified_id=list.get_cursor_id)
	edebug("row modified #{modified_id.inspect}","list","info")
	drbmodel.rows_changed(modified_id,nick)
list.set_model(@sorter) if list.model.nil?
list.scroll_to_cursor
end

#set_show_archive(ns) ⇒ Object



770
771
772
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 770

def set_show_archive(ns)
	@show_archive=ns.to_s == 'true'
end

#to_csv(filename, ids = nil) ⇒ Object



710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 710

def to_csv(filename,ids=nil)
	file = File.new(filename, "wb+")
	ids=Array.new
	separator=(list.gtk_attribute("csv_field_separator") ? list.gtk_attribute("csv_field_separator") : ',')
	row=""
	list.columns.each{|col|
		row="#{row}#{col.header['header']}#{separator}"
	}
	file.write("#{row[0..row.length]}\n")

	if @list.selection.count_selected_rows > 1
		@list.selection.selected_each{|model, path, iter| file.write(iter2csv(iter))}
		else
		@filter.each{|model,path,iter| file.write(iter2csv(iter))}
	end
	file.close
	edebug("saved","list")
end

#to_sObject



70
71
72
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 70

def to_s
	"model of #{list}"
end

#unhide_tree_parent_iters(iter) ⇒ Object

recursive show parent iters



441
442
443
444
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 441

def unhide_tree_parent_iters(iter)
	iter[@column_of_visible]=true;
	unhide_tree_parent_iters(iter.parent) if iter.parent
end

#unlock_iter(unlocked_id) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 106

def unlock_iter(unlocked_id)
	counter=0
	begin
		counter+=1
		manqod_db.unlock_id_of_base(@base,unlocked_id)
	rescue =>err
		resubscribe
		if counter==3
			warn("server is gone",err.to_s,"list",ERROR,false,false)
		else
			retry
		end
	end
end

#update(notifier, ids = nil, notification_subect = nil) ⇒ Object



300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 300

def update(notifier,ids=nil,notification_subect=nil)
=begin
notifier is the notifier object
ids is the array of ids which should be reloaded/deleted
notification_subject:
	@column_of: lock/unlock the ids
	"structure": for create_skeleton
	"buttons" : reload the list buttons
	else	: load ids
=end
	before=Time.now
	case notifier.class.name
		when 'BarMenuItem'
			#we're main list, menu is notifying
			load_data(notifier)
		when 'MyEditableList'
			#we're sublist
			unless(@parentselected == notifier.get_cursor_id)
				@parentselected=notifier.get_cursor_id
				@current_parent_key=if @column_of_parent_key and parent_iter=parentM.iter_at_cursor
					parent_iter[@column_of_parent_key]
				end

				@current_parent_key2=if @column_of_parent_key2 and parent_iter
					parent_iter[@column_of_parent_key2]
				end
				if @key_child.nil? and !parentM.nil?
					tell_exception("[#{self}] add child_key attribute!","list","warning")
					load_data(notifier)
				end
				refilter
			end
		when 'String'
				case notification_subect
					when @column_of_sensitive
						einfo("lock change recieved: #{ids}","list")
						Gtk.thread_protect{display_lock(ids)}
					when "structure"
						einfo("structure change recieved","list")
						Gtk.thread_protect{@list.create_skeleton}
						Gtk.thread_protect{@list.update(self)}
					when "buttons"
						einfo("button change recieved","list")
						Gtk.thread_protect{list.caller.buttonholder.update(list,true)}
					else
						#no subject, we recieved just ids, so reload them
						einfo("load #{ids.inspect} recieved","list")
						Gtk.thread_protect{load_data(notifier,ids)}
				end
		when 'ListModel','ArchiveButton'
			#it's self
			load_data(self)
		else
			ewarn("unknown notifier #{notifier}[#{notifier.class.name}] for list update","list")
	end
	update_time=Time.now.to_f-before.to_f
	edebug("updateed in "+sprintf("%.2fs",update_time),"time","debug")
end

#wipeObject



74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/ListHolder/EditableList/DrbListModel.rb', line 74

def wipe
	begin
  	drbmodel.unsubscribe(ManqodRPC.instance.to_s) if @remote_model && @remote_model.alive?
  rescue =>err
  	eerror("unsubscribing: #{err}","main")
 	end
  	if @sorter and @sorter.sort_column_id
			edebug("saving model's sortcolumn: #{@sorter.sort_column_id}","config","info")
			set_conf(get_id,0,"sortcolumn",@sorter.sort_column_id[0])
			set_conf(get_id,0,"sortorder",if @sorter.sort_column_id[1]==Gtk::SORT_ASCENDING then "asc" else "desc";end)
		end
end