1 # vim: ft=tcl foldmarker=<<<,>>>
3 option add Browse_treeview_flat.width
130 widgetDefault
4 option add Browse_treeview_flat.height
200 widgetDefault
6 class tlc
::Browse_treeview_flat {
7 inherit tlc
::Mywidget tlc
::Browsegeneric tlc
::Baselog
12 itk_option define
-actionspos actionsPos ActionsPos
\
13 {11,10 -fill x
} need_relayout
14 itk_option define
-actions_orient actionsOrient ActionsOrient h
15 itk_option define
-action_buttonwidth actionButtonWidth ActionButtonWidth
9
16 itk_option define
-column_widths columnWidths ColumnWidths
{}
17 itk_option define
-yscrollmode yScrollMode YScrollMode static
18 itk_option define
-xscrollmode xScrollMode XScrollMode dynamic
21 # inherited, overridden interface
27 method select_items
{itemlist
}
28 method get_selected_items
{}
29 method action_add
{args
}
30 method action_attach_signal
{label signal
{sense normal
}}
31 method action_add_supported
{}
32 method action_tips
{args
}
33 method filter_add
{label varinfo
{matchcode
1}}
34 method filter_add_standard
{label varinfo matchcode
}
35 method filter_data
{args
}
36 method filter_item
{item
}
37 method filter_add_cb
{cb
}
39 # specific to this implementation
40 variable hide_id_col
0
42 variable col_justifies
""
43 variable col_paddings
""
44 variable col_widths
""
45 variable hidden_cols
{}
46 variable item_bindings
{}
47 # for the inbuilt functions: choose case insenstivity or not
48 # for the inbuilt functions: toggle display of case-sensitive checkbutton
49 variable trim_filter
0
50 variable filter_mode
1
51 variable tree_style
"" {style_tree
}
53 method sortcolumn
{colname
}
54 method hideshowcol
{colname hidden
}
55 method filter
{searchstring
{matchcode
""} {filternames
{}}}
57 method get_criteria_form
{}
58 method reload_from_criteria_form
{}
60 method getsite
{sitename
}
61 method gen_popup
{{pop_commands
""}}
62 method style_tree
{{stylename
""}}
64 method column_configure
{colname args
}
65 method component_actions
{}
76 variable shadowdata
{}
77 variable treeheaders
{}
78 variable hidden_nodes
""
81 variable itemform_header
""
82 variable last_headers
{}
83 variable current_edit
{}
84 variable filterform
{}
85 variable filterform_schema
{}
88 variable filter_after_id
""
90 variable or_filter_ok_ids
""
91 variable filtered_nodes
92 variable filter_cbs
{}
93 variable cached_col_widths
94 variable selection_present
95 variable delayed_select_afterid
""
97 method onclick
{nodeid numclicks
}
98 method selection_changed
{}
99 method render_filters
{}
100 method form_filter
{{form_data
{}}}
101 method partial_match
{filterarray rowarray type
102 {applicable_cols
{}} {filternames
{}}}
103 method cache_col_widths
{}
104 method restore_col_widths
{}
105 method process_delayed_select
{cb data row row_id
}
110 configbody tlc
::Browse_treeview_flat::yscrollmode { #<<<1
111 $w.treeframe.hs configure
-mode $itk_option(-yscrollmode)
115 configbody tlc
::Browse_treeview_flat::xscrollmode { #<<<1
116 $w.treeframe.hs configure
-mode $itk_option(-xscrollmode)
120 configbody tlc
::Browse_treeview_flat::actions_orient { #<<<1
121 if {[winfo exists
$w.actionsframe.actions
]} {
122 $w.actionsframe.actions configure
-orient $itk_option(-actions_orient)
127 configbody tlc
::Browse_treeview_flat::action_buttonwidth { #<<<1
128 #puts "Browse_treeview_flat: Reconfiguring action_buttonwidth: ($itk_option(-action_buttonwidth))"
129 if {[winfo exists
$w.actionsframe.actions
]} {
130 $w.actionsframe.actions configure
\
131 -buttonwidth $itk_option(-action_buttonwidth)
136 configbody tlc
::Browse_treeview_flat::column_widths { #<<<1
137 foreach {colname width
} $itk_option(-column_widths) {
138 catch {$tv column configure
$colname -width $width}
144 body tlc
::Browse_treeview_flat::constructor {args
} { #<<<1
145 tlc
::Signal #auto selection_present -name "$this selection_present"
147 set datatree
[blt
::tree create
]
148 # (a) create the treeview <<<
150 set f
[frame $w.treeframe
]
152 # puts "constructing:
153 # blt::treeview $f.list -width 130 -height 200 \\
154 # -xscrollcommand [list $f.hs set] \\
155 # -yscrollcommand [list $f.vs set] \\
157 # -exportselection 1 \\
158 # -selectcommand [code $this selection_changed] \\
164 itk_component add listview
{
165 blt
::treeview $f.
list$::fooseq
167 keep
-takefocus -selectmode -width -height
168 #rename -background -textbackground textBackground TextBackground
170 set tv
$itk_component(listview
)
172 -xscrollcommand [list $f.hs
set] \
173 -yscrollcommand [list $f.vs
set] \
176 -selectcommand [code
$this selection_changed
] \
180 $tv style checkbox check
\
181 -onvalue 1 -offvalue 0 \
184 $tv column configure treeView
-hide 1
185 tlc
::myscrollbar_win32 $f.hs
-orient h
-command [list $tv xview
] -mode static
186 tlc
::myscrollbar_win32 $f.vs
-orient v
-command [list $tv yview
] -mode static
193 blt
::table configure
$f r2 c2
-resize none
196 # Setup mousewheel x and y scrolling <<<
197 bind $tv <Button-4
> {if {!$tk_strictMotif} {%W yview scroll
-2 units
}}
198 bind $tv <Button-5
> {if {!$tk_strictMotif} {%W yview scroll
2 units
}}
199 bind $tv <Control-Button-4
> {if {!$tk_strictMotif} {%W xview scroll
-2 units
}}
200 bind $tv <Control-Button-5
> {if {!$tk_strictMotif} {%W xview scroll
2 units
}}
201 bind $tv <Key-F5
> [code
$this refresh
]
202 bind $w <Key-F5
> [code
$this refresh
]
203 # Setup mousewheel x and y scrolling >>>
204 # (a) create the treeview >>>
206 eval itk_initialize
$args
208 # (b) create the criteria form (server-side searching) <<<
209 set f
[frame $w.criteriaframe
]
210 if {$show_criteria} {
211 label $f.criterialabel
-text $criteria_label
213 set cf
[tlc
::Form $f.criteriaform
-schema [$datasource get_criteria
]]
214 $f.criteriaform set_data
[$datasource get_criteria_values
]
216 tlc
::Tools $f.criteria_tools
217 $f.criteria_tools add
"Refresh" \
218 [code
$this reload_from_criteria_form
] right
219 $f.criteria_tools attach_signal
"Refresh" \
220 [$f.criteriaform signal_ref form_dirty
]
222 if {$criteria_label != ""} {
224 $f.criterialabel
1,1 -fill x
\
228 $f.criteriaform
2,1 -fill x
-anchor n
\
229 $f.criteria_tools
3,1 -fill x
230 blt
::table configure
$f r1 r3
-resize none
232 # (b) create the criteria form (server-side searching) >>>
234 # (c) create the toolbar (if necessary) <<<
235 set tb
[tlc
::Tools $w.actionsframe
]
236 # (c) create the toolbar (if necessary) >>>
238 # (d) the filter (client-side searching) <<<
239 set filterframe
[frame $w.filterframe
]
240 # (d) the filter (client-side searching) >>>
242 # (e) layout with table <<<
244 # (e) end layout with table >>>
246 # get an item dialogue
247 set itemform
[tlc
::Formdialog $w.itemform
-mode schema
]
251 body tlc
::Browse_treeview_flat::destructor {} { #<<<1
252 #destroy $w.treeframe.list ;# DIE DIE DIE
253 after cancel
$delayed_select_afterid; set delayed_select_afterid
""
254 if {[winfo exists
$w.itemform
]} {
260 body tlc
::Browse_treeview_flat::refresh {} { #<<<1
263 #after idle [code $this onclick "" 1] ;# Fake click to blank any existing selection
265 set id_colname
[lindex [$datasource get_id_column
] 1]
266 array set old_sel_ids
{}
267 foreach row
[get_selected_items
] {
270 if {[info exists tmp
($id_colname)]} {
271 set row_id
$tmp($id_colname)
272 set old_sel_ids
($row_id) 1
277 # get data to load <<<
278 set cv
[$datasource get_criteria_values
]
279 set list_data
[$datasource get_labelled_list
$cv headers
]
280 set last_headers
$headers
281 # get data to load >>>
285 # if the data's headers have changed, update the treeview columns <<<
286 if {$headers != $treeheaders} {
287 set tmp
[lrange [$tv column names
] 1 end
]
289 # the first "name" returned should be treeview,
290 # but is something not quite
291 # that; still we don't want to remove it
292 # (unless we are seeking segfaults)
293 # note that the placement of this column is only because
294 # i have chosen to insert
295 # after it -- it's not a hard rule that the first col
296 # is the treeview >>>
297 # remove old headers <<<
299 $tv column delete
$col
301 # remove old headers >>>
302 # get format options for headers <<<
303 # (which may have, conceivably, changed, if the field list has changed)
304 foreach col
$headers {
309 array set jus
$col_justifies
310 array set pad
$col_paddings
311 array set wid
$col_widths
312 #array set colwidths $itk_option(-column_widths)
313 array set wid
$itk_option(-column_widths)
314 # get format options for headers >>>
315 # Get id column and name <<<
316 set id_col
[$datasource get_id_column
]
317 set id_col_name
[lindex $id_col 1]
318 #puts "Browse_treeview_flat::refresh: id_col: ($id_col) id_col_name: ($id_col_name)"
319 # Get id column and name >>>
321 foreach col
$headers {
323 -justify $jus($col) \
326 -hide [expr {[lsearch $hidden_cols $col] != -1}] \
327 -command [code
$this sortcolumn
$col]]
329 if {[lsearch $checkvars $col] >= 0} {
330 lappend colargs
-style check
334 set curr_id
[eval [list $tv column insert end
$col] $colargs]
336 error "Error inserting column ($col): $msg\n\tAll: ([$tv column names])\n$::errorInfo"
339 #if {[info exists colwidths($col)]} {
340 # $tv column configure $col -width $colwidths($col)
344 # if the data's headers have changed, update the treeview columns >>>
346 # Handle the id column (hide, etc) <<<
347 set id_colname
[lindex [$datasource get_id_column
] 1]
348 if {$hide_id_col && $id_colname != ""} {
349 $tv column configure
$id_colname -hide [expr {$hide_id_col}]
351 # Handle the id column (hide, etc) >>>
353 # load up the data <<<
356 foreach row
$list_data {
357 set tmpid
[$datatree insert root
-data $row]
358 lappend shadowdata
$row
359 $tv bind $tmpid <Button-1
> [code
$this onclick
$tmpid 1]
360 $tv bind $tmpid <Double-Button-1
> [code
$this onclick
$tmpid 2]
361 $tv bind $tmpid <Key-F5
> [code
$this refresh
]
362 foreach {binding action
} $item_bindings {
363 $tv bind $tmpid $binding $action
365 set m
[expr {($m + 1) % 2}]
367 # load up the data >>>
369 # Re-apply the filter
374 # Attempt to restore selection <<<
376 set id_colname
[lindex [$datasource get_id_column
] 1]
378 foreach {parent itemid nodename data tags
} [$datatree dump root
] {
381 if {[info exists tmp
($id_colname)]} {
382 set row_id
$tmp($id_colname)
383 if {[info exists old_sel_ids
($row_id)]} {
385 $tv selection set $itemid
389 log warning
"row is missing id_colname ($id_colname):"
395 after idle
[code
$this onclick
"" 1]
397 # Attempt to restore selection >>>
402 body tlc
::Browse_treeview_flat::clear {} { #<<<1
403 $datatree delete root
407 body tlc
::Browse_treeview_flat::sortcolumn {colname
} { #<<<1
408 # sort the treeview on a certain column
409 # unscrupulously ripped from the blt treeview demo
410 set old
[$tv sort cget
-column]
412 if {"$old" == "$colname"} {
413 set decreasing
[$tv sort cget
-decreasing]
414 set decreasing
[expr !$decreasing]
416 $tv sort configure
-decreasing $decreasing -column $colname -mode integer
417 if {![$tv cget
-flat]} {
418 $tv configure
-flat yes
421 style_tree
$tree_style
424 blt
::busy release
$tv
428 body tlc
::Browse_treeview_flat::hideshowcol {colname hidden
} { #<<<1
430 set hidden_cols
[lsort -unique [concat $hidden_cols [list $colname]]]
432 set idx
[lsearch $hidden_cols $colname]
434 set hidden_cols
[lreplace $hidden_cols $idx $idx]
437 catch {$tv configure
$colname -hide $hidden}
440 body tlc
::Browse_treeview_flat::add_item {} { #<<<1
441 # populate with defaults
442 array set res
[$datasource get_defaults
]
443 if {![$itemform ask res
[$datasource get_item_schema
]]} return
444 array set res
[$datasource add_item
[array get res
]]
447 foreach header
[$datasource get_headers
] {
448 if {[info exists res
($header)]} {
449 lappend row
$res($header)
454 set row_id
[lindex $row [lindex $id_col 0]]
455 invoke_handlers onadd_array
[array get res
]
456 invoke_handlers onadd
$row
457 invoke_handlers onadd_id
$row_id
460 body tlc
::Browse_treeview_flat::update_item {} { #<<<1
461 set oldrows
[get_selected_items
]
462 # check that the oldrow only contains one row: updating multiple rows is not supported
463 if {[llength $oldrows] > 1} {
464 log debug
"multiple row updates are not supported"
466 set oldrow
[lindex $oldrows 0]
467 array set res
$oldrow
468 if {![$itemform ask res
[$datasource get_item_schema
]]} return
470 array set res
[$datasource update_item
$oldrow [array get res
]]
474 foreach header
[$datasource get_headers
] {
475 lappend row
$res($header)
477 set row_id
[lindex $row [lindex $id_col 0]]
479 invoke_handlers onupdate_array
[array get res
]
480 invoke_handlers onupdate
$row
481 invoke_handlers onupdate_id
$row_id
485 body tlc
::Browse_treeview_flat::remove_item {} { #<<<1
486 # set up a mini-description of the item
487 set sel_items
[get_selected_items
]
488 if {[llength $sel_items]>1} {
490 set msg
"Are you sure you would like to remove these items?"
493 set msg
"Are you sure you would like to remove this item?"
495 if {[.confirm ask
$msg "Ok" "Cancel"] == "Ok"} {
496 set h
[$datasource get_headers
]
497 foreach item
$sel_items {
498 $datasource remove_item
$item
500 foreach header
[$datasource get_headers
] {
501 if {[info exists res
($header)]} {
502 lappend row
$res($header)
507 set row_id
[lindex $row [lindex $id_col 0]]
508 invoke_handlers ondelete_array
$item
509 invoke_handlers ondelete
$row
510 invoke_handlers ondelete_id
$row_id
516 body tlc
::Browse_treeview_flat::select_items {itemlist
} { #<<<1
519 body tlc
::Browse_treeview_flat::getsite {sitename
} { #<<<1
520 # returns a site referenced by a keyword -- to be used by a parent that wishes to inject something into one of the sites
521 switch -- [string tolower
$sitename] {
522 "criteria" {return $w.criteriaframe
}
523 "actions" {return $w.actionframe
}
524 "filter" {return $w.filterframe
}
526 "list" {return $w.treeframe
}
528 log
error "Unable to return reference to site $sitename -- site should be one of: criteria,actions,filter,tree|list"
534 body tlc
::Browse_treeview_flat::filter {searchstring
{matchcode
{}} {filternames
{} }} { #<<<1
535 # comments about the function <<<
536 # for each node in the current treeview, we see if it matches up with
537 # the search string, and if so, it gets to stay.
538 # If not, it gets dumped in the removed_nodes variable (which is just
540 # This variable is also checked for matches, which are added back
541 # into the tree if found
543 # set up the filter array
544 if {$filterform != ""} {
545 array set filter
[$filterform get_data
]
547 log
error "filterform does not exist: ($filterform)"
550 switch -- $filter_mode {
554 foreach node
[$datatree children root
] {
555 set rawrow
[$datatree get
$node]
556 if {[llength $rawrow] > 0} {
557 array set row
$rawrow
558 if {![expr $matchcode]} {
559 $datatree delete
$node
566 error "Bad filter_mode $filter_mode: only \"and\" is supported"
571 body tlc
::Browse_treeview_flat::get_criteria_form {} { #<<<1
575 body tlc
::Browse_treeview_flat::reload_from_criteria_form {} { #<<<1
576 $datasource set_criteria_values
[$cf get_data
]
578 $w.criteriaframe.criteriaform mark_dirty
0
581 body tlc
::Browse_treeview_flat::get_selected_items {} { #<<<1
582 set sel_ids
[$tv curselection
]
584 foreach id
$sel_ids {
585 lappend ret
[$datatree get
$id]
591 body tlc
::Browse_treeview_flat::onclick {nodeid numclicks
} { #<<<1
593 set data
[$datatree get
$nodeid]
600 foreach h
$last_headers {
601 if {![info exists tmp
($h)]} {
608 set row_id
[$datasource extract_id
$row]
611 switch -- $numclicks {
612 1 {set cb
"onselect"}
613 2 {set cb
"doubleclick"}
614 default {error "mad number of clicks sent through: ($numclicks)"}
617 #puts "onclick: nodeid: ($nodeid) data: ($data) selection present: ([$tv selection present])"
618 $item_selected set_state
[expr {$nodeid != ""}]
620 if {$delayed_select_afterid != ""} {
621 set pending
[lindex [after info $delayed_select_afterid] 0]
622 if {$pending != ""} {
626 set delayed_select_afterid
[after idle
\
627 [code
$this process_delayed_select
$cb $data $row $row_id]]
631 body tlc
::Browse_treeview_flat::action_add {args
} { #<<<1
632 set label [lindex $args 0]
633 if {![winfo exists
$w.actionsframe.actions
]} {
634 set f
$w.actionsframe
635 #puts "\n\nBrowse_treeview_flat::action_add:\n\torient: ($itk_option(-actions_orient))\n\tbuttonwidth: ($itk_option(-action_buttonwidth))\n\n"
636 set tb
[tlc
::Tools $f.actions
\
637 -buttonwidth $itk_option(-action_buttonwidth) \
638 -orient $itk_option(-actions_orient)]
639 blt
::table $f $f.actions
1,1 -fill both
642 switch -- [string tolower
[lindex $args 1]] {
646 if {[$datasource can_do insert
]} {
647 set title
[lindex $args 0]
648 set ltitle
[expr {[string length
$title]?
"$title":"Add New"}]
649 $tb add
$ltitle [code
$this add_item
]
650 lappend actions
"$ltitle" "[code $this add_item]"
652 error "Datasource can't do insert; refusing to create add\
659 if {[$datasource can_do delete
]} {
660 set title
[lindex $args 0]
661 set ltitle
[expr {[string length
$title] ?
"$title" : "Delete"}]
662 $tb add
$ltitle [code
$this remove_item
]
663 $tb attach_signal
$ltitle [selected_ref
]
664 lappend actions
"$ltitle" "[code $this remove_item]"
666 error "Datasource can't do delete; refusing to create delete\
673 if {[$datasource can_do
update]} {
674 set title
[lindex $args 0]
675 set ltitle
[expr {[string length
$title] ?
"$title" : "Update"}]
676 $tb add
$ltitle [code
$this update_item
]
677 $tb attach_signal
$ltitle [selected_ref
]
678 lappend actions
"$ltitle" "[code $this update_item]"
680 error "Datasource can't do update; refusing to create update\
685 set title
[lindex $args 0]
686 set ltitle
[expr {[string length
$title] ?
"$title" : "Refresh"}]
687 $tb add
$ltitle [code
$this refresh
]
688 lappend actions
"$ltitle" "[code $this refresh]"
691 eval [list $tb add
] $args
692 lappend actions
"[lindex $args 0]" "[lindex $args 1]"
697 body tlc
::Browse_treeview_flat::action_add_supported {} { #<<<
698 foreach action
"insert update delete" {
699 if {[$datasource can_do
$action]} {
700 action_add
"" $action
703 action_add
"" "refresh"
706 body tlc
::Browse_treeview_flat::action_attach_signal {label signal
{sense normal
}} { #<<<1
707 #puts "Browse_treeview_flat::action_attach_signal ($label) ($signal) ($sense)"
708 $tb attach_signal
$label $signal $sense
712 body tlc
::Browse_treeview_flat::action_tips {args
} { #<<<1
713 eval [list $tb set_tips
] $args
717 body tlc
::Browse_treeview_flat::selection_changed {} { #<<<1
718 $selection_present set_state
[$tv selection present
]
721 body tlc
::Browse_treeview_flat::gen_popup {{pop_commands
""}} { #<<<1
723 if {$pop_follows_actions} {
724 foreach {action cmd
} $actions {
725 lappend menu_schema
"$action" "command [list $cmd]"
728 #puts "generating popup with schema: ($menu_schema $pop_commands)"
729 Mymenu
$w.pop
-schema "$menu_schema $pop_commands"
730 bind $tv <Button-3
> [list tk_popup $w.pop
%X
%Y
]
733 body tlc
::Browse_treeview_flat::filter_add {label varinfo
{matchcode
1}} { #<<<1
734 set varname
[lindex $varinfo 0]
735 lappend filterform_schema
$label $varinfo
736 set filtercode
($varname) $matchcode
737 set last_filter
($varname) ""
738 set filter_after_id
[after idle
[code
$this render_filters
]]
742 body tlc
::Browse_treeview_flat::filter_add_standard {label varinfo matchcode
} { #<<<1
743 # implement some fairly standard search capabilities
744 set orig_matchcode
$matchcode
747 switch -- [lindex $matchcode 0] {
751 set matchcode
{[eval partial_match
[list [array get filter
]] \
752 [list [array get row
]] "left" \
754 [list $filternames]]}
760 set matchcode
{[partial_match
[list [array get filter
]] \
761 [list [array get row
]] "right" \
763 [list $filternames]]}
769 set matchcode
{[partial_match
[list [array get filter
]] \
770 [list [array get row
]] "exact" \
772 [list $filternames]]}
779 set matchcode
{[eval partial_match
[list [array get filter
]] \
780 [list [array get row
]] "partial" \
782 [list $filternames]]}
785 default { ;# default is to leave the match code alone
790 set repidx
[lsearch $matchcode "%%foo%%"]
791 set matchcode
[lreplace $matchcode $repidx $repidx [lrange $orig_matchcode 1 end
]]
794 return [filter_add
$label $varinfo $matchcode]
798 body tlc
::Browse_treeview_flat::render_filters {} { #<<<1
799 after cancel
$filter_after_id
800 set filter_after_id
""
801 if {$filter_label != ""} {
802 label $filterframe.filterheader
-text $filter_label
803 blt
::table $filterframe \
804 $filterframe.filterheader
1,1 -columnspan 2
806 if {[winfo exists
$filterframe.filterform
]} {
807 $filterframe.filterform configure
-schema $filterform_schema
809 set filterform
[tlc
::Form $filterframe.filterform
-schema $filterform_schema]
812 blt
::table $filterframe \
813 $filterframe.filterform
2,1 -columnspan 2
814 blt
::table configure
$filterframe r1 r2
-resize none
816 if {$filter_allow_sense_change} {
817 label $filterframe.insensitivelabel
-text "Filter is case insensitive:"
818 checkbutton $filterframe.insensitive
-variable $filter_insensitive
819 blt
::table $filterframe \
820 $filterframe.insensitivelabel
3,1 -anchor ne
\
821 $filterframe.insensitive
3,2 -anchor nw
822 blt
::table configure
$filterframe r3
-resize none
825 if {$filter_allow_mode_change && [llength [array names filtercode
]] > 1} {
826 label $filterframe.modelabel
-text "Require all conditions be met."
827 checkbutton $filterframe.mode
\
828 -command [code
$this form_filter
] \
829 -variable [scope filter_mode
]
830 blt
::table $filterframe \
831 $filterframe.modelabel
4,1 -anchor ne
\
832 $filterframe.mode
4,2 -anchor nw
833 blt
::table configure
$filterframe r4
-resize none
835 $filterform register_handler onchange
[code
$this form_filter
]
838 body tlc
::Browse_treeview_flat::form_filter {{form_data
{}}} { #<<<1
839 if {[llength $form_data] == 0 && $filterform != ""} {
840 set form_data
[$filterform get_data
]
842 set form_data
$form_data
844 # initial filtering method notes: <<<
845 # we have two possible filter methods: and and or (keeping it simple)
846 # for the case of an or, we start with a blank datatree and add in
847 # the elements from the shadowtree that make the grade.
848 # for the case of an and, we start with a filled datatree and remove
849 # items that violate the filtering rules
851 set required_filters
{}
852 array set lfilters
$form_data
853 foreach {filter value
} [array get lfilters
] {
855 lappend required_filters
$filter
859 switch -- $filter_mode {
863 $datatree delete root
864 foreach dataarray
$shadowdata {
865 set tmpid
[$datatree insert root
\
867 $tv bind $tmpid <Button-1
> [code
$this onclick
$tmpid 1]
868 $tv bind $tmpid <Double-Button-1
> \
869 [code
$this onclick
$tmpid 2]
870 $tv bind $tmpid <Key-F5
> [code
$this refresh
]
871 foreach {binding action
} $item_bindings {
872 $tv bind $tmpid $binding $action
875 log debug
"populated"
878 foreach filter
$required_filters {
879 filter
$lfilters($filter) $filtercode($filter) $filter
881 foreach cb
$filter_cbs {
882 foreach node
[$datatree children root
] {
883 set rawrow
[$datatree get
$node]
884 if {[llength $rawrow] > 0} {
885 if {![$cb $rawrow]} {
886 $datatree delete
$node
897 body tlc
::Browse_treeview_flat::partial_match {filterarray rowarray type
898 {applicable_cols
{}} {filternames
{}}} {
899 array set afilter
$filterarray
900 array set arow
$rowarray
901 if {[llength $applicable_cols] == 0} {
902 foreach idx
[array names afilter
] {
903 lappend applicable_cols
$idx
906 if {[llength $filternames] == 0} {set filternames
[array names afilter
]}
909 "partial" {set pre
"*"; set post
"*"}
910 "left" {set pre
""; set post
"*"}
911 "right" {set pre
"*"; set post
""}
913 default {set pre
""; set post
""}
916 if {$trim_filter} {set val
[string trim
$val]}
917 # ok, bear with me: i'm trying to keep the miniumum of checks on the
918 # inner loop, so there are a lot of variations on a theme here
919 if {$filter_insensitive} {
920 foreach idx
$filternames {
921 if {[lsearch $applicable_cols $idx] > -1} {
922 if {[info exists arow
($idx)]} {
923 if {$afilter($idx) != ""} {
924 if {[eval string match
-nocase \
925 {${pre
}$afilter($idx)${post
}} \
926 {$arow($idx)} ] == 1} {
934 foreach {idx val
} $filternames {
935 if {[lsearch $applicable_cols $idx] > -1} {
936 if {[info exists arow
($idx)]} {
937 if {$afilter($idx) != ""} {
938 if {[eval string match
\
939 {${pre
}$afilter($idx)${post
}} \
940 {$arow($idx)} ] == 1} {
949 switch -- $filter_mode {
951 1 {return [expr {[llength $applicable_cols] == $hits ?
1 : 0}]}
953 0 {return [expr {$hits > 0 ?
1 : 0}]}
957 body tlc
::Browse_treeview_flat::cache_col_widths {} { #<<<1
958 foreach col
[$tv column names
] {
959 set cached_col_widths
($col) [$tv column cget
$col -width]
963 body tlc
::Browse_treeview_flat::restore_col_widths {} { #<<<1
964 foreach col
[$tv column names
] {
965 if {[info exists cached_col_widths
($col)]} {
966 $tv column configure
$col -width $cached_col_widths($col)
971 body tlc
::Browse_treeview_flat::style_tree {{stylename
""}} { #<<<1
972 switch -- $stylename {
980 foreach col
[$tv column names
] {
981 $tv column configure
$col \
982 -titlerelief raised
\
983 -titlebackground "#e5e5e5" \
984 -activetitlebackground "#e5e5e5" \
985 -titleforeground "#000000" \
987 -background "#f5f5f5" \
988 -titleborderwidth 1 \
994 # tries to make the listview fit in with the chrome of the system
995 set chrome
[$tlc::theme setting background
]
996 set textbackground
[$tlc::theme setting textbackground
]
997 set fg
[$tlc::theme setting foreground
]
1000 -selectbackground [$tlc::theme setting selectbackground
] \
1003 -background $textbackground
1004 foreach col
[$tv column names
] {
1005 $tv column configure
$col \
1006 -titlerelief raised
\
1007 -background $textbackground \
1008 -titlebackground $chrome \
1009 -activetitlebackground $chrome \
1010 -titleforeground $fg \
1012 -activetitlebackground $chrome
1019 body tlc
::Browse_treeview_flat::get_tv_ref {} { #<<<1
1024 body tlc
::Browse_treeview_flat::column_configure {colname args
} { #<<<1
1025 if {[refresh_pending
]} {
1028 return [eval [list $tv column configure
$colname] $args]
1032 body tlc
::Browse_treeview_flat::relayout {} { #<<<1
1033 eval [list blt
::table $w $w.treeframe
] $listpos
1034 eval [list blt
::table $w $w.filterframe
] $filterpos
1035 set coords
[split [lindex $filterpos 0] ","]
1037 eval [list blt
::table $w $w.criteriaframe
] $criteriapos
1038 set coords
[split [lindex $criteriapos 0] ","]
1040 eval [list blt
::table $w $w.actionsframe
] $itk_option(-actionspos)
1041 set coords
[split [lindex $itk_option(-actionspos) 0], ","]
1043 # Restrict row and col growth to those containing the list <<<
1044 array set targets
{}
1045 foreach child
[blt
::table search
$w -pattern *] {
1046 set table_info
[blt
::table info $w $child]
1047 foreach {row col
} [split [lindex $table_info 0] ,] break
1048 set targets
(r
$row) 1
1049 set targets
(c
$col) 1
1051 eval [list blt
::table configure
$w] [array names targets
] -resize none
1052 foreach {row col
} [split [lindex [blt
::table info $w $w.treeframe
] 0] ,] break
1053 blt
::table configure
$w r
$row c
$col -resize both
1054 # Restrict row and col growth to those containing the list >>>
1058 body tlc
::Browse_treeview_flat::component_actions {} { #<<<1
1059 if {[winfo exists
$w.actionsframe.actions
]} {
1060 return $w.actionsframe.actions
1062 error "No actions configured"
1067 body tlc
::Browse_treeview_flat::filter_data {args
} { #<<<1
1068 if {$filter_after_id != ""} {render_filters
}
1069 switch -- [llength $args] {
1071 if {$filterform != ""} {
1072 return [$filterform get_data
]
1074 log
error "filterform does not exist: ($filterform)"
1080 if {$filterform != ""} {
1081 return [$filterform set_data
[lindex $args 0]]
1083 log
error "filterform does not exist: ($filterform)"
1089 error "Incorrect number of arguments: ($args) must be ?newdata?"
1095 body tlc
::Browse_treeview_flat::filter_item {item
} { #<<<1
1096 return [$filterform path
$item]
1100 body tlc
::Browse_treeview_flat::filter_add_cb {cb
} { #<<<1
1101 lappend filter_cbs
$cb
1107 body tlc
::Browse_treeview_flat::process_delayed_select {cb data row row_id
} { #<<<1
1108 after cancel
$delayed_select_afterid; set delayed_select_afterid
""
1110 invoke_handlers
${cb
}_array
$data
1111 invoke_handlers
$cb $row
1112 invoke_handlers
${cb
}_id
$row_id