diff -Naur Tkabber-orig/chats.tcl Tkabber/chats.tcl --- Tkabber-orig/chats.tcl 2006-07-22 14:33:53.000000000 +0400 +++ Tkabber/chats.tcl 2006-07-22 21:21:37.850266400 +0400 @@ -691,6 +691,16 @@ return $chats(inputwin,$chatid) } +proc chat::search_panel {chatwin {spanel ""}} { + variable chats + + if {![cequal $spanel ""]} { + set chats(spanel,$chatwin) $spanel + } + + return $chats(spanel,$chatwin) +} + proc chat::is_groupchat {chatid} { variable chats if {[info exists chats(type,$chatid)]} { diff -Naur Tkabber-orig/disco-search.tcl Tkabber/disco-search.tcl --- Tkabber-orig/disco-search.tcl 1970-01-01 03:00:00.000000000 +0300 +++ Tkabber/disco-search.tcl 2006-07-22 21:28:01.600266400 +0400 @@ -0,0 +1,275 @@ +# Searching in the descovery window. +# $Id: disco-search.tcl 13 2006-07-21 00:06:48Z kostix $ + +proc disco::browser::search_open_panel {bw {nocheck 0}} { + variable browser + + set f $browser(search,$bw,panel) + + if {$nocheck && [winfo ismapped $f]} return + + search_reset $bw + + pack $f -side bottom -fill x + focus $f +} + + + +proc disco::browser::search_close_panel {bw {nocheck 0}} { + variable browser + + set f $browser(search,$bw,panel) + + if {$nocheck && ![winfo ismapped $f]} return + + pack forget $browser(search,$bw,panel) +} + + + +proc disco::browser::search_toggle_panel {bw} { + variable browser + + set f $browser(search,$bw,panel) + + if {[winfo ismapped $f]} { + search_close_panel $bw 1 + } else { + search_open_panel $bw 1 + } +} + + + +proc disco::browser::search_setup_panel {bw} { + variable browser + + # Main frame -- the search panel itself: + set panel [frame $bw.search] + set browser(search,$bw,panel) $panel + + # Top frame: pattern entry and buttons: + + set tf [frame $panel.top] + + button $tf.close -text [::msgcat::mc Close] -command \ + [list [namespace current]::search_close_panel $bw] + button $tf.sup -text [::msgcat::mc {Search up}] \ + -command [list [namespace current]::search_next $bw up] + button $tf.sdown -text [::msgcat::mc {Search down}] \ + -command [list [namespace current]::search_next $bw down] + button $tf.reset -text [::msgcat::mc Reset] \ + -command [list [namespace current]::search_reset $bw] + pack $tf.close $tf.reset $tf.sdown $tf.sup -side right + + entry $tf.pattern \ + -textvar [namespace current]::browser(search,$bw,pattern) + pack $tf.pattern -side left -fill x -expand true + + pack $tf -fill x + + # Middle frame: search mode toggles + status label: + + set mf [frame $panel.middle] + + set browser(search,$bw,mode) jid/node + + label $mf.stext -text [::msgcat::mc {Search by:}] -padx 0 + radiobutton $mf.jid -text [::msgcat::mc JID/node] \ + -value jid/node \ + -variable [namespace current]::browser(search,$bw,mode) + radiobutton $mf.title -text [::msgcat::mc name] \ + -value name \ + -variable [namespace current]::browser(search,$bw,mode) + pack $mf.stext $mf.jid $mf.title -side left + + label $mf.status -anchor e \ + -textvar [namespace current]::browser(search,$bw,status) + pack $mf.status -side right -fill x + + pack $mf -fill x + + # Bottom frame: matching modes + case insensetiveness: + + set bf [frame $panel.bottom] + + label $bf.lmatch -text [::msgcat::mc {Match using:}] -padx 0 + + set browser(search,$bw,match) glob + + radiobutton $bf.glob -text [::msgcat::mc glob-style] \ + -value glob \ + -variable [namespace current]::browser(search,$bw,match) + radiobutton $bf.regexp -text [::msgcat::mc regexp] \ + -value regexp \ + -variable [namespace current]::browser(search,$bw,match) + radiobutton $bf.exact -text [::msgcat::mc exact] \ + -value exact \ + -variable [namespace current]::browser(search,$bw,match) + + set browser(search,$bw,nocase) 1 + + checkbutton $bf.nocase -text [::msgcat::mc {Case insensitive}] \ + -anchor e \ + -variable [namespace current]::browser(search,$bw,nocase) + + pack $bf.lmatch $bf.glob $bf.regexp $bf.exact -side left + pack $bf.nocase -side right + + pack $bf -fill x +} + + + +proc disco::browser::search_next {bw direction} { + variable browser + + if {[cequal $browser(search,$bw,pattern) ""]} { + search_set_status $bw [::msgcat::mc {No pattern to search}] + return + } + + search_set_status $bw "" + + set tw $browser(tree,$bw) + + # Get the root-of-the-search node: + set tnode [search_get_root $bw] + if {[cequal $tnode ""]} { # no root, no selection + search_set_status $bw [::msgcat::mc {Select a populated item}] + return + } + + lassign [$tw itemcget $tnode -data] type + if {![cequal $type item]} { # cannot search on non-items + search_set_status $bw [::msgcat::mc {Select a populated item}] + return + } + + # Save root node, if needed: + if {![info exists browser(search,$bw,root)]} { + set browser(search,$bw,root) $tnode + } + + # Get list of children nodes + set children [$tw nodes $tnode] + set len [llength $children] + + # Setup iterate-by-children loop based on the search direction + if {[cequal $direction down]} { + if {[info exists browser(search,$bw,lastix)]} { + set ix $browser(search,$bw,lastix) + incr ix ;# next to last + } else { # just on the 1st element + set ix 0 + } + set cond {$ix < $len} + set post {incr ix} + } else { # up + if {[info exists browser(search,$bw,lastix)]} { + set ix $browser(search,$bw,lastix) + incr ix -1 ;# prev to last + } else { # just on the last element + set ix [expr $len - 1] + } + set cond {$ix >= 0} + set post {incr ix -1} + } + + # Now $ix is the index of the children to start searching from + + for {} $cond $post { + set child [lindex $children $ix] + + set data [lassign [$tw itemcget $child -data] type] + + if {![cequal $type item]} continue + + lassign $data jid node + + if {[cequal $browser(search,$bw,mode) name]} { + set what [[namespace parent]::get_jid_name $jid $node] + } else { + set what $jid + } + + if {[search_match $bw $what]} { + set browser(search,$bw,lastix) $ix + search_hilite $tw $child + return + } + } + + search_set_status $bw [::msgcat::mc {Nothing was found}] +} + + + +proc disco::browser::search_match {bw what} { + variable browser + + set pat $browser(search,$bw,pattern) + + if {$browser(search,$bw,nocase)} { + set args [list -nocase $pat $what] + } else { + set args [list $pat $what] + } + + switch -- $browser(search,$bw,match) { + exact { + return [eval string equal $args] + } + glob { + return [eval string match $args] + } + regexp { + return [eval regexp $args] + } + } + + return 0 +} + + + +proc disco::browser::search_hilite {tw tnode} { + $tw see $tnode + $tw selection set $tnode +} + + + +proc disco::browser::search_set_status {bw status} { + variable browser + set browser(search,$bw,status) $status +} + + + +proc disco::browser::search_reset {bw} { + variable browser + + set tnode [search_get_root $bw] + if {$tnode != ""} { + search_hilite $browser(tree,$bw) $tnode + } + + search_set_status $bw "" + + unset -nocomplain browser(search,$bw,root) + unset -nocomplain browser(search,$bw,lastix) +} + + + +proc disco::browser::search_get_root {bw} { + variable browser + + if {[info exists browser(search,$bw,root)]} { + return $browser(search,$bw,root) + } else { + return [lindex [$browser(tree,$bw) selection get] 0] + } +} diff -Naur Tkabber-orig/disco.tcl Tkabber/disco.tcl --- Tkabber-orig/disco.tcl 2006-03-17 07:29:42.000000000 +0300 +++ Tkabber/disco.tcl 2006-07-22 20:03:58.053391400 +0400 @@ -1,4 +1,4 @@ -# $Id: disco.tcl,v 1.42 2006/03/17 04:29:42 aleksey Exp $ +# $Id: disco.tcl 12 2006-07-20 17:31:59Z kostix $ set ::NS(disco_items) "http://jabber.org/protocol/disco#items" set ::NS(disco_info) "http://jabber.org/protocol/disco#info" @@ -440,6 +440,8 @@ set config(identitycolor) [option get $w identitycolor JDisco] set config(optioncolor) [option get $w optioncolor JDisco] + bind $w [list [namespace current]::destroy_state $w] + frame $w.navigate button $w.navigate.back -text <- \ -command [list [namespace current]::history_move $w 1] @@ -502,6 +504,10 @@ set browser(hist,$w) {} set browser(histpos,$w) 0 + search_setup_panel $w + bind $w <> \ + [list [namespace current]::search_toggle_panel $w] + go $w } @@ -1245,6 +1251,23 @@ } } + + +# Destroy all (global) state assotiated with the given browser window. +# Intended to be bound to a event handler for browser windows. +proc disco::browser::destroy_state {bw} { + variable browser + + array unset browser(*,$bw) + array unset browser(*,$bw,*) + + foreach ix [lsearch -all $browser(opened) $bw] { + set browser(opened) [lreplace $browser(opened) $ix $ix] + } +} + + + hook::add postload_hook \ [list browser::register_ns_handler $::NS(disco_info) disco::browser::open_win \ -desc [list * [::msgcat::mc "Discover service"]]] diff -Naur Tkabber-orig/ifacetk/iface.tcl Tkabber/ifacetk/iface.tcl --- Tkabber-orig/ifacetk/iface.tcl 2006-07-22 14:33:53.000000000 +0400 +++ Tkabber/ifacetk/iface.tcl 2006-07-22 21:33:09.990891400 +0400 @@ -2,6 +2,7 @@ namespace eval ifacetk { variable options + variable toplevel_events custom::defgroup IFace \ [::msgcat::mc "Options for main interface."] \ @@ -1369,3 +1370,33 @@ -message $message -type user -buttons ok -default 0 -cancel 0 } +# Synthesize the given event in the frame that is packed in the +# frame (ouch!) of the active tab (for tabbed interface). +# NOTE that if the target frame hasn't any handler for the event, +# it is (usually) passed back to the toplevel, so we guard against +# multiple runs for the same event. +proc ifacetk::dispatch_event_to_active_tab {event} { + variable toplevel_events + + if {[info exists toplevel_events($event)]} return + + set page [.nb raise] + if {$page == {}} return + set frame [lindex [pack slaves [.nb getframe $page]] 0] + + set toplevel_events($event) 1 + event generate $frame $event + unset toplevel_events($event) +} + +event add <> + +proc ifacetk::install_toplevel_events {} { + if {!$::usetabbar} return + + foreach event {<>} { + bind . $event [list ifacetk::dispatch_event_to_active_tab $event] + } +} + +hook::add finload_hook ifacetk::install_toplevel_events diff -Naur Tkabber-orig/plugins/chat/search.tcl Tkabber/plugins/chat/search.tcl --- Tkabber-orig/plugins/chat/search.tcl 2005-08-29 00:46:15.000000000 +0400 +++ Tkabber/plugins/chat/search.tcl 2006-07-22 21:18:19.631516400 +0400 @@ -1,6 +1,8 @@ # $Id: search.tcl,v 1.4 2005/08/28 20:46:15 aleksey Exp $ -proc open_search_panel {sf chatw} { +proc open_search_panel {chatw} { + set sf [chat::search_panel $chatw] + set sentry $sf.search pack $sf -side bottom -anchor w -fill x -before [winfo parent $chatw].csw @@ -29,6 +31,8 @@ set sf [frame [winfo parent $chatw].search] + chat::search_panel $chatw $sf + #set slabel [label $sf.slabel -text [::msgcat::mc "Search:"]] #pack $slabel -side left @@ -52,9 +56,8 @@ bind $sentry \ [double% [list [namespace current]::close_search_panel $sf $chatid]] - event add <> - bind $cw.input <> \ - [double% [list [namespace current]::open_search_panel $sf $chatw]] + bind $cw <> \ + [double% [list [namespace current]::open_search_panel $chatw]] } hook::add open_chat_post_hook [namespace current]::setup_search_panel diff -Naur Tkabber-orig/tkabber.tcl Tkabber/tkabber.tcl --- Tkabber-orig/tkabber.tcl 2006-06-09 00:21:44.000000000 +0400 +++ Tkabber/tkabber.tcl 2006-07-22 21:27:00.365891400 +0400 @@ -237,6 +237,7 @@ load_source login.tcl load_source browser.tcl load_source disco.tcl +load_source disco-search.tcl load_source userinfo.tcl load_source datagathering.tcl load_source negotiate.tcl