1# $Id$
2
3namespace eval bookmark {
4    hook::add postload_hook [namespace current]::init
5    hook::add open_chat_post_hook [namespace current]::on_open_chat
6    hook::add close_chat_post_hook [namespace current]::on_close_chat
7    hook::add chat_win_popup_menu_hook [namespace current]::popup_menu
8    hook::add draw_message_hook [namespace current]::add_bookmark 80
9}
10
11proc bookmark::init {} {
12    global usetabbar
13
14    if {$usetabbar} {
15	bind . <Shift-F3> [list [namespace current]::next_bookmark .]
16	catch {bind . <XF86_Switch_VT_3> [list [namespace current]::next_bookmark .]}
17	bind . <F3>       [list [namespace current]::prev_bookmark .]
18    }
19}
20
21proc bookmark::on_open_chat {chatid type} {
22    global usetabbar
23
24    if {!$usetabbar} {
25	set cw [chat::chat_win $chatid]
26	set top [winfo toplevel $cw]
27	bind $top <Shift-F3> [list [namespace current]::next_bookmark [double% $cw]]
28	catch {bind $top <XF86_Switch_VT_3> [list [namespace current]::next_bookmark [double% $cw]]}
29	bind $top <F3>       [list [namespace current]::prev_bookmark [double% $cw]]
30    }
31}
32
33proc bookmark::on_close_chat {chatid} {
34    variable bookmark
35
36    set cw [chat::chat_win $chatid]
37    catch { array unset bookmark $cw,* }
38}
39
40proc bookmark::popup_menu {m W X Y x y} {
41    set groupchat 0
42    foreach chatid [chat::opened] {
43	if {[chat::chat_win $chatid] == $W} {
44	    set groupchat [expr {[chat::is_groupchat $chatid]}]
45	    break
46	}
47    }
48    if {!$groupchat} return
49
50    $m add command -label [::msgcat::mc "Prev highlighted"] -accelerator F3 \
51        -command [list [namespace current]::prev_bookmark $W]
52    $m add command -label [::msgcat::mc "Next highlighted"] -accelerator Shift-F3 \
53        -command [list [namespace current]::next_bookmark $W]
54}
55
56
57proc bookmark::get_chatwin {} {
58    global usetabbar
59
60    if {!$usetabbar} {
61	return ""
62    }
63
64    set cw ""
65    foreach chatid [chat::opened] {
66	if {[.nb raise] == [ifacetk::nbpage [chat::winid $chatid]]} {
67	    set cw [chat::chat_win $chatid]
68	    break
69	}
70    }
71    return $cw
72}
73
74proc bookmark::add_bookmark {chatid from type body x} {
75    variable bookmark
76
77    if {$type != "groupchat"} return
78
79    set cw [chat::chat_win $chatid]
80
81    set xlib [chat::get_xlib $chatid]
82    set jid [chat::get_jid $chatid]
83    set myjid [chat::our_jid $chatid]
84    set mynick [chat::get_nick $xlib $myjid $type]
85    if {[string equal $jid $from] || [string equal $myjid $from] || \
86	    ![check_message $mynick $body]} {
87	return
88    }
89
90    if {![info exists bookmark($cw,id)]} {
91	set bookmark($cw,id) 0
92    }
93    set b [incr bookmark($cw,id)]
94    $cw mark set hbookmark$b "end - 1 char"
95    $cw mark gravity hbookmark$b left
96}
97
98proc bookmark::next_bookmark {cw} {
99    variable bookmark
100
101    if {$cw == "."} {
102	set cw [get_chatwin]
103	if {$cw == ""} return
104    }
105
106    set groupchat 0
107    foreach chatid [chat::opened] {
108	if {[chat::chat_win $chatid] == $cw} {
109	    set groupchat [expr {[chat::is_groupchat $chatid]}]
110	    break
111	}
112    }
113    if {!$groupchat} return
114
115    if {![info exists bookmark($cw,last)] || \
116	    [catch {$cw index $bookmark($cw,last)}]} {
117	set bookmark($cw,last) 0.0
118    }
119    set idx [$cw index $bookmark($cw,last)]
120    if {$bookmark($cw,last) == "end" || \
121	    (([lindex [$cw yview] 0] == 0 || [lindex [$cw yview] 1] == 1) && \
122		([$cw dlineinfo $idx] == {} || \
123		[lsearch -exact [$cw tag names $idx] sel] < 0))} {
124        set bookmark($cw,last) 0.0
125    }
126    if {$bookmark($cw,last) == "0.0"} {
127	set first_round 0
128    } else {
129	set first_round 1
130    }
131    while {($bookmark($cw,last) != {}) || $first_round} {
132	if {$bookmark($cw,last) == {}} {
133	    set bookmark($cw,last) 0.0
134	    set first_round 0
135	}
136        set bookmark($cw,last) [$cw mark next $bookmark($cw,last)]
137        if {[string match "hbookmark*" $bookmark($cw,last)]} {
138            break
139        }
140    }
141    if {$bookmark($cw,last) == {}} {
142	set bookmark($cw,last) 0.0
143    } else {
144	$cw tag remove sel 0.0 end
145	$cw tag add sel \
146	    "$bookmark($cw,last) linestart" \
147	    "$bookmark($cw,last) lineend"
148	$cw see $bookmark($cw,last)
149    }
150    return $bookmark($cw,last)
151}
152
153proc bookmark::prev_bookmark {cw} {
154    variable bookmark
155
156    if {$cw == "."} {
157	set cw [get_chatwin]
158	if {$cw == ""} return
159    }
160
161    set groupchat 0
162    foreach chatid [chat::opened] {
163	if {[chat::chat_win $chatid] == $cw} {
164	    set groupchat [expr {[chat::is_groupchat $chatid]}]
165	    break
166	}
167    }
168    if {!$groupchat} return
169
170    if {![info exists bookmark($cw,last)] || \
171	    [catch {$cw index $bookmark($cw,last)}]} {
172	set bookmark($cw,last) end
173    }
174    set idx [$cw index $bookmark($cw,last)]
175    if {$bookmark($cw,last) == "0.0" || \
176	    ([lindex [$cw yview] 1] == 1 && \
177		([$cw dlineinfo $idx] == {} || \
178		[lsearch -exact [$cw tag names $idx] sel] < 0))} {
179        set bookmark($cw,last) end
180    }
181    if {$bookmark($cw,last) == "end"} {
182	set first_round 0
183    } else {
184	set first_round 1
185    }
186    while {($bookmark($cw,last) != {}) || $first_round} {
187	if {$bookmark($cw,last) == {}} {
188	    set bookmark($cw,last) end
189	    set first_round 0
190	}
191        set bookmark($cw,last) [$cw mark previous $bookmark($cw,last)]
192        if {[string match "hbookmark*" $bookmark($cw,last)]} {
193            break
194        }
195    }
196    if {($bookmark($cw,last) == {})} {
197	set bookmark($cw,last) end
198    } else {
199	$cw tag remove sel 0.0 end
200	$cw tag add sel \
201	    "$bookmark($cw,last) linestart" \
202	    "$bookmark($cw,last) lineend"
203	$cw see $bookmark($cw,last)
204    }
205    return $bookmark($cw,last)
206}
207
208