1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 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 299 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 358 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
|
# debug.tcl --
#
# This file implements Debug plugin for the Tkabber XMPP client.
# It allows one to log Tkabber debug messages into a file or a
# log window.
#
# Author: Marshall T. Rose
# Modifications: Badlop
# Modifications: Sergei Golovan
package require msgcat
catch {package require Tclx}
namespace eval debug {
::msgcat::mcload [file join [file dirname [info script]] msgs]
if {![::plugins::is_registered debug]} {
::plugins::register debug \
-namespace [namespace current] \
-source [info script] \
-description [::msgcat::mc "Whether the Debug live\
plugin is loaded."] \
-loadcommand [namespace code load] \
-unloadcommand [namespace code unload]
return
}
custom::defgroup Plugins [::msgcat::mc "Plugins options."] \
-group Tkabber
custom::defgroup Debug [::msgcat::mc "Debug live plugin options."] \
-group Plugins
custom::defvar options(log_to_file) 0 \
[::msgcat::mc "Log debug messages to file %s." \
[file join $::configdir tkabber.log]] \
-group Debug \
-type boolean
custom::defvar options(log_to_window) 0 \
[::msgcat::mc "Log debug messages to a separate tab/window."] \
-group Debug \
-type boolean
variable modules {attline
avatar
browser
browseurl
caps
chat
conference
custom
disco
emoticons
filetransfer
filters
georoster
gpg
headlines
hook
http
iface
iq
jidlink
logger
login
message
mucignore
negotiate
nick
otr
pconnect::https
pconnect::socks4
pconnect::socks5
pep
plugins
popupmenu
presence
privacy
pubsub
register
richtext
roster
search
si
ssj
sw
tclchat
tkabber
userinfo
utils
warning
xmpp
xmpp::transport::bosh
xmpp::transport::poll
zerobot}
foreach module $modules {
custom::defvar debug($module) 0 \
[::msgcat::mc "Log debug messages for module %s to a tab/window." \
$module] \
-group Debug -type boolean
}
}
proc debug::load {} {
if {[llength [info procs ::debugmsg:debug]] == 0} {
rename ::debugmsg ::debugmsg:debug
proc ::debugmsg {module msg} \
"[namespace current]::debugmsg \$module \$msg"
}
foreach ns {otr
pconnect::https
pconnect::socks4
pconnect::socks5
xmpp
xmpp::transport::bosh
xmpp::transport::poll} {
if {[llength [info procs ::${ns}::Debug]] > 0 && \
[llength [info procs ::${ns}::Debug:debug]] == 0} {
rename ::${ns}::Debug ::${ns}::Debug:debug
proc ::${ns}::Debug {xlib level str} \
"[namespace current]::debugmsg $ns \"\$xlib \$str\""
}
}
foreach ns {gpg} {
if {[llength [info procs ::${ns}::Debug]] > 0 && \
[llength [info procs ::${ns}::Debug:debug]] == 0} {
rename ::${ns}::Debug ::${ns}::Debug:debug
proc ::${ns}::Debug {level str} \
"[namespace current]::debugmsg $ns \"\$str\""
}
}
if {[llength [info procs ::otr::smp::Debug]] > 0 && \
[llength [info procs ::otr::smp::Debug:debug]] == 0} {
rename ::otr::smp::Debug ::otr::smp::Debug:debug
proc ::otr::smp::Debug {level str} \
"[namespace current]::debugmsg otr \$str"
}
hook::add finload_hook [namespace current]::setup_menu
if {![catch {.mainframe getmenu debug}]} {
setup_menu
}
}
proc debug::unload {} {
variable debug_fd
if {![catch {.mainframe getmenu debug}]} {
destroy_menu
}
if {[info exists debug_fd]} {
close $debug_fd
unset debug_fd
}
if {[winfo exists .debug]} {
destroy_win .debug
}
hook::remove finload_hook [namespace current]::setup_menu
foreach ns {gpg
otr
pconnect::https
pconnect::socks4
pconnect::socks5
xmpp
xmpp::transport::bosh
xmpp::transport::poll} {
if {[llength [info procs ::${ns}::Debug:debug]] > 0} {
rename ::${ns}::Debug ""
rename ::${ns}::Debug:debug ::${ns}::Debug
}
}
if {[llength [info procs ::otr::smp::Debug:debug]] > 0} {
rename ::otr::smp::Debug ""
rename ::otr::smp::Debug:debug ::otr::smp::Debug
}
if {[llength [info procs ::debugmsg:debug]] > 0} {
rename ::debugmsg ""
rename ::debugmsg:debug ::debugmsg
}
namespace delete [namespace current]::search
}
proc debug::destroy_menu {} {
set m [.mainframe getmenu debug]
if {![catch {$m index [::msgcat::mc "Debug"]} idx] && \
![string equal $idx none]} {
set mm [$m entrycget $idx -menu]
$m delete $idx
destroy $mm
}
if {![catch {$m index [::msgcat::mc "Profile on"]} idx] && \
![string equal $idx none]} {
$m delete $idx
}
if {![catch {$m index [::msgcat::mc "Profile report"]} idx] && \
![string equal $idx none]} {
$m delete $idx
}
}
proc debug::setup_menu {} {
variable options
variable modules
variable debug
set m [.mainframe getmenu debug]
if {![catch {$m index [::msgcat::mc "Debug"]} idx] && \
![string equal $idx none]} {
return
}
set buttons [menu $m.devel -tearoff $ifacetk::options(show_tearoffs)]
$buttons add checkbutton -label [::msgcat::mc "Log to file"] \
-variable [namespace current]::options(log_to_file)
$buttons add checkbutton -label [::msgcat::mc "Log to window"] \
-variable [namespace current]::options(log_to_window)
$buttons add separator
set n 0
foreach module $modules {
if {$n == 0} {
set submodules [list $module]
} else {
lappend submodules $module
}
incr n
if {$n == 8 || $module == [lindex $modules end]} {
set n 0
set me [menu $buttons.[string map {:: #} [lindex $submodules 0]] \
-tearoff $::ifacetk::options(show_tearoffs)]
$buttons add cascade \
-label [lindex $submodules 0]-[lindex $submodules end] \
-menu $me
foreach mod $submodules {
$me add checkbutton -label $mod \
-variable [namespace current]::debug($mod)
}
}
}
$m add cascade -label [::msgcat::mc "Debug"] -menu $buttons
if {[llength [info commands profile]] > 0} {
$m add command -label [::msgcat::mc "Profile on"] \
-command {
profile -commands -eval on
}
$m add command -label [::msgcat::mc "Profile report"] \
-command {
profile off profil
profrep profil real profresults
}
}
}
proc debug::debugmsg {module msg} {
variable options
variable debug
variable debug_fd
if {$options(log_to_file)} {
if {![info exists debug_fd]} {
catch { file rename -force -- $::configdir/tkabber.log \
$::configdir/tkabber0.log }
set debug_fd [open $::configdir/tkabber.log w]
fconfigure $debug_fd -buffering line
}
puts $debug_fd [format "%s %-12.12s %s %s" \
[clock format [clock seconds] -format "%m/%d %T"] \
$module [lindex [info level -2] 0] $msg]
}
if {!$options(log_to_window) || ![info exists debug($module)] || \
!$debug($module)} {
return
}
set dw .debug
if {![winfo exists $dw]} {
if {[catch {
add_win $dw \
-title [::msgcat::mc Debug] \
-tabtitle [::msgcat::mc Debug] \
-class Chat \
-raisecmd [list [namespace current]::focus_body $dw]
}]} {
# Main window isn't created yet
return
}
[ScrolledWindow $dw.sw] setwidget \
[Text $dw.body -yscrollcommand [list $dw.scroll set] \
-state disabled -takefocus 1]
bind [Wrapped $dw.body] <1> [list [namespace current]::focus_body \
[double% $dw]]
pack $dw.sw -side bottom -fill both -expand yes
$dw.body tag configure module \
-foreground [option get $dw theyforeground Chat]
$dw.body tag configure proc \
-foreground [option get $dw meforeground Chat]
$dw.body tag configure error \
-foreground [option get $dw errforeground Chat]
search::setup_panel $dw
}
$dw.body configure -state normal
set scroll [expr {[lindex [$dw.body yview] 1] == 1}]
$dw.body insert end \
[format "%s: %-12.12s" \
[clock format [clock seconds] -format "%m/%d %T"] \
$module] module " "
set tag normal
$dw.body insert end [lindex [info level -2] 0] proc " "
$dw.body insert end [string trimright $msg] $tag
$dw.body insert end "\n\n"
if {$scroll} {
$dw.body see end
}
$dw.body configure -state disabled
}
proc debug::focus_body {w} {
focus [Wrapped $w.body]
}
namespace eval debug::search {}
proc debug::search::open_panel {w sf} {
pack $sf -side bottom -anchor w -fill x -before $w.sw
update idletasks
$w.body see end
}
proc debug::search::close_panel {w sf} {
$w.body tag remove search_highlight 0.0 end
pack forget $sf
[namespace parent]::focus_body $w
}
proc debug::search::setup_panel {w} {
set body $w.body
$body mark set sel_start end
$body mark set sel_end 0.0
set sf [plugins::search::spanel [winfo parent $body].search \
-searchcommand [list ::plugins::search::do_text_search $body] \
-closecommand [list [namespace current]::close_panel $w]]
bind [Wrapped $body] <<OpenSearchPanel>> \
[double% [list [namespace current]::open_panel $w $sf]]
}
# vim:ts=8:sw=4:sts=4:et
|