Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace eval vimage {
- global auto_path
- global configdir
- variable Config
- variable System
- variable toolbar_button
- variable useTkImageTools
- set System(script_dir) [file dirname [info script]]
- set auto_path [linsert $auto_path 0 [file join $System(script_dir) lib]]
- package require http
- package require msgcat
- package require viewer
- package require BWidget
- package require Img
- ::msgcat::mcload [file join $System(script_dir) msgs]
- set System(extensions) {gif|pixmap}
- append System(extensions) {|bmp|ico|jpeg|jpg|pcx|}
- append System(extensions) {png|ppm|postscript|sgi|sun|}
- append System(extensions) {tga|tiff|xbm|xpm}
- # Hidden Group
- custom::defvar toolbar_button(index) {-1} \
- [::msgcat::mc "Last button index"] \
- -type string -group Hidden
- custom::defvar toolbar_button(state) {1} \
- [::msgcat::mc "Button (and plugin) state"] \
- -type string -group Hidden
- set Config(ignore_history_urls) 1
- set Config(validate_urls) 0
- set Config(auto_show_viewer) 1
- set Config(show_progressbar) 1
- set Config(max_size) 100
- set Config(add_toolbar_button) 1
- set Config(show_tooltip) 1
- set Config(image_width) 200
- set Config(show_label) 1
- set Config(auto_getting) 0
- set Config(viewer,position) center
- set Config(viewer,alpha) -1
- set Config(viewer,topmost) 0
- set Config(viewer,size) default
- set Config(viewer,scroller_gain) sticky_mouse
- set Config(viewer,startup_history_state) 1
- image create photo vimage/toolbar -file [file join $System(script_dir) pixmaps toolbar.png]
- image create photo vimage/normal -file [file join $System(script_dir) pixmaps normal.gif]
- image create photo vimage/image -file [file join $System(script_dir) pixmaps image.gif]
- image create photo vimage/process -file [file join $System(script_dir) pixmaps process.gif]
- image create photo vimage/error -file [file join $System(script_dir) pixmaps error.gif]
- image create photo vimage/large -file [file join $System(script_dir) pixmaps large.gif]
- image create photo vimage/no_image_available -file [file join $System(script_dir) pixmaps no_image_available.gif]
- }
- proc vimage::add_toolbar_button {} {
- variable toolbar_button
- catch {.mainframe gettoolbar 0} toolbar
- set bbox $toolbar.bbox
- if {[winfo exist $toolbar.bbox] && ![ButtonBox::exist $toolbar.bbox $toolbar_button(index)]} {
- set toolbar_button(index) [ifacetk::add_toolbar_button \
- vimage/toolbar \
- [list [namespace origin see_image_in_viewer] {}] \
- [::msgcat::mc "Show vimage history"]]
- }
- }
- proc vimage::delete_toolbar_button {} {
- variable toolbar_button
- catch {.mainframe gettoolbar 0} toolbar
- set bbox $toolbar.bbox
- if {[winfo exist $toolbar.bbox] && [ButtonBox::exist $toolbar.bbox $toolbar_button(index)]} {
- ButtonBox::delete $toolbar.bbox $toolbar_button(index)
- set toolbar_button(index) -1
- }
- }
- proc vimage::add_or_delete_toolbar_button {args} {
- variable Config
- switch -- $Config(add_toolbar_button) {
- 1 add_toolbar_button
- 0 delete_toolbar_button
- }
- }
- proc vimage::add_to_located {nurl lurl} {
- variable ImagesData
- lappend ImagesData(located,$lurl) $nurl
- set ImagesData(located,$lurl) \
- [lsort -unique $ImagesData(located,$lurl)]
- }
- proc vimage::draw_message {chatid from type body extras} {
- variable Config
- if {$Config(ignore_history_urls) &&
- [::xmpp::delay::exists $extras]} \
- {return}
- foreach iUrl [get_image_urls $body] {
- update_icon_on_chatwin $iUrl $chatid image
- if { ! [image_getted $iUrl] && $Config(auto_getting)} {
- schedule [namespace origin getting] $iUrl $chatid
- } else {
- show_process $iUrl $chatid
- }
- }
- }
- proc vimage::comp_getting {iUrl chatid} {
- variable Config
- set old_msize $Config(max_size)
- set Config(max_size) 1000000
- getting $iUrl $chatid -reload
- set Config(max_size) $old_msize
- }
- proc vimage::getting {iUrl chatid {type -get}} {
- if {[string equal $type "-reload"]} \
- {set_state_getting $iUrl reload}
- update_icon_on_chatwin $iUrl $chatid process
- if { ! [image_getted $iUrl]} {
- get_image_from_url $iUrl $chatid
- }
- show_process $iUrl $chatid
- clean_process_update $iUrl $chatid
- }
- proc vimage::show_process {iUrl chatid} {
- switch -exact -- [image_state $iUrl] {
- -1 {
- update_icon_on_chatwin $iUrl $chatid image
- }
- 0 {
- update_icon_on_chatwin $iUrl $chatid normal
- show_process_normal $iUrl $chatid
- }
- 1 {
- update_icon_on_chatwin $iUrl $chatid large
- }
- 2 {
- update_icon_on_chatwin $iUrl $chatid error
- }
- }
- }
- proc vimage::show_process_normal {iUrl chatid} {
- variable Config
- add_image_in_viewer \
- [image_id $iUrl] [::chat::get_jid $chatid] $iUrl
- if {$Config(auto_show_viewer) && ![image_showed $iUrl]} {
- after idle [list [namespace origin see_image_in_viewer] $iUrl]
- }
- if {$Config(show_tooltip)} {
- addResized $iUrl
- }
- }
- proc vimage::get_image_from_url {iUrl chatid} {
- variable Config
- if {$Config(validate_urls)} {
- set iUrl [location $iUrl]
- }
- if {[catch {set token [http::geturl $iUrl -binary 1 -blocksize 1024 \
- -command [list [namespace origin image_get_end] $iUrl $chatid] \
- -progress [list [namespace origin image_get_process] $iUrl $chatid]]
- }]} {return [set_state_getting $iUrl error]}
- http::wait $token
- }
- proc vimage::location {iUrl} {
- if {[catch {set token [http::geturl $iUrl -validate 1]} err]} \
- {return $iUrl}
- foreach {type value} [http::meta $token] {
- if {[string equal $type "Location"]} \
- {set iUrl $value}
- }
- return $iUrl
- }
- proc vimage::image_get_end {iUrl chatid token} {
- if {[catch {image create photo vimage/$iUrl -data [http::data $token]}]} {
- set_state_getting $iUrl error
- } else {set_state_getting $iUrl normal vimage/$iUrl}
- http::cleanup $token
- }
- proc vimage::image_get_process {iUrl chatid token total current} {
- variable Config
- setImageSize $iUrl $total
- set max_size [expr {$Config(max_size)*1024}]
- if {$current > $max_size || $total > $max_size} {
- http::reset $token
- set_state_getting $iUrl large
- }
- update_url_getting_on_chatwin $iUrl $chatid $total $current
- return
- }
- proc vimage::setImageSize {iUrl total} {
- variable ImagesData
- set ImagesData(total,$iUrl) $total
- }
- proc vimage::getImageSize {iUrl} {
- variable ImagesData
- if {[info exist ImagesData(total,$iUrl)]} {
- return $ImagesData(total,$iUrl)
- }
- return 0
- }
- proc vimage::clean_process_update {iUrl chatid} {
- catch {destroy .mainframe.status.prgf.prb}
- catch {destroy .mainframe.status.prgf.lab}
- }
- proc vimage::update_url_getting_on_chatwin {iUrl chatid total current} {
- variable Config
- set current [expr {round($current / 1024)}]
- set total [expr {round($total / 1024)}]
- set [namespace current]::progress-$iUrl $current
- progressbar [namespace current]::progress-$iUrl $total $current [::chat::get_jid $chatid]
- return
- }
- proc vimage::update_icon_on_chatwin {iUrl chatid type} {
- variable Config
- set chatwin [::chat::chat_win $chatid]
- foreach {sind eind} [$chatwin tag range [list uri $iUrl]] {
- set tag icon/$iUrl
- if {[lsearch [$chatwin tag names $eind] $tag] < 0} {
- $chatwin image create $eind -image vimage/$type -padx 2
- $chatwin tag add $tag $eind
- }
- $chatwin image configure $eind -image vimage/$type
- }
- bind_set $chatid $tag $iUrl $type
- update idletasks
- }
- proc vimage::bind_set {chatid tag iUrl type} {
- variable Config
- set chatwin [::chat::chat_win $chatid]
- if {$Config(show_tooltip)} {
- $chatwin tag bind $tag <Any-Enter> [list [namespace origin showTooltip] %W $tag $iUrl]
- $chatwin tag bind $tag <Any-Motion> [list [namespace origin motionTooltip] %W]
- $chatwin tag bind $tag <Any-Leave> [list destroy %W.tooltip]
- $chatwin tag bind $tag <Any-KeyPress> [list destroy %W.tooltip]
- $chatwin tag bind $tag <Any-Button> [list destroy %W.tooltip]
- }
- # Change a cursor
- $chatwin tag bind $tag <Any-Enter> +[list [namespace origin on_icon] Any-Enter $iUrl $chatid]
- $chatwin tag bind $tag <Any-Leave> +[list [namespace origin on_icon] Any-Leave $iUrl $chatid]
- # View image
- $chatwin tag bind $tag <Button-1><ButtonRelease-1> [list [namespace origin on_icon] 1 $iUrl $chatid $type]
- }
- proc vimage::on_icon {button iUrl chatid {type ""}} {
- set chatwin [::chat::chat_win $chatid]
- switch -exact -- $button {
- 1 {
- switch -exact -- $type {
- normal {
- see_image_in_viewer $iUrl
- }
- large {
- comp_getting $iUrl $chatid
- }
- image -
- error {
- getting $iUrl $chatid -reload
- }
- }
- }
- 2 {
- getting $iUrl $chatid -reload
- }
- Any-Enter {
- $chatwin configure -cursor [option get $chatwin urlcursor Text]
- }
- Any-Leave {
- $chatwin configure -cursor [get_conf $chatwin -cursor]
- }
- }
- }
- proc vimage::menu_draw {iUrl chatid} {
- set m .menu_vimage
- if {[winfo exist $m]} {
- destroy $m
- }
- menu $m -tearoff 0
- $m add command \
- -label [::msgcat::mc "View"] \
- -command [list [namespace origin see_image_in_viewer] $iUrl]
- $m add command \
- -label [::msgcat::mc "Reload"] \
- -command [list [namespace origin getting] $iUrl $chatid -reload]
- $m add command \
- -label [::msgcat::mc "View without size limit"] \
- -command [list [namespace origin comp_getting] $iUrl $chatid]
- tk_popup $m [winfo pointerx .] [winfo pointery .]
- }
- proc vimage::progressbar { varname max current jid } {
- variable Config
- set win .mainframe.status.prgf
- if {[winfo exist $win] && [winfo exist $win.prb]} {
- if {$max > 0} {
- if {$Config(show_progressbar)} {
- $win.prb configure -maximum $max -variable $varname
- }
- if {$Config(show_label)} {
- $win.lab configure -text "$jid ($current/$max)"
- }
- }
- return
- }
- if {$Config(show_label)} {
- label $win.lab -text $jid -background [$win cget -background]
- }
- if {$Config(show_progressbar)} {
- ProgressBar $win.prb -type nonincremental_infinite \
- -variable $varname -relief groove
- }
- if {$max > 0} {
- if {$Config(show_progressbar)} {
- $win.prb configure -maximum $max -type normal
- }
- if {$Config(show_label)} {
- $win.lab configure -text "$jid ($current/$max)"
- }
- }
- if {$Config(show_progressbar) && $Config(show_label)} {
- pack $win.lab $win.prb -padx 2 -side left
- } elseif {$Config(show_progressbar)} {
- pack $win.prb -padx 2 -side left
- } else {
- pack $win.lab -padx 2 -side left
- }
- }
- proc vimage::see_image_in_viewer {iUrl} {
- variable System
- add_to_showed $iUrl
- if {[info exist System(viewer)] &&
- [winfo exist $System(viewer)]} {
- $System(viewer) see $iUrl text
- $System(viewer) show
- }
- }
- proc vimage::add_image_in_viewer {image_id jid iUrl} {
- variable System
- variable Config
- if { ! [info exist System(viewer)] || ! [winfo exist $System(viewer)]} {
- set System(viewer) .viewer_screen
- ::viewer::viewer .viewer_screen -position $Config(viewer,position) \
- -alpha $Config(viewer,alpha) -topmost $Config(viewer,topmost) \
- -size $Config(viewer,size) -scroller_gain $Config(viewer,scroller_gain) \
- -startup_history_state $Config(viewer,startup_history_state)
- }
- $System(viewer) add $jid $iUrl $image_id
- }
- proc vimage::set_state_getting {iUrl type {image_id ""}} {
- variable ImagesData
- switch -exact -- $type {
- error {
- set ImagesData(getted,$iUrl) 0
- set ImagesData(state,$iUrl) 2
- set ImagesData(image,$iUrl) {}
- set ImagesData(image_resized,$iUrl) {}
- }
- normal {
- set ImagesData(getted,$iUrl) 1
- set ImagesData(state,$iUrl) 0
- set ImagesData(image,$iUrl) $image_id
- set ImagesData(image_resized,$iUrl) {}
- }
- large {
- set ImagesData(getted,$iUrl) 0
- set ImagesData(state,$iUrl) 1
- set ImagesData(image,$iUrl) {}
- set ImagesData(image_resized,$iUrl) {}
- }
- init {
- set ImagesData(getted,$iUrl) 0
- set ImagesData(state,$iUrl) -1
- set ImagesData(image,$iUrl) {}
- set ImagesData(image_resized,$iUrl) {}
- }
- reload {
- array unset ImagesData *,$iUrl
- }
- }
- }
- proc vimage::image_getted {iUrl} {
- variable ImagesData
- expr {[info exist ImagesData(getted,$iUrl)] &&
- $ImagesData(getted,$iUrl)}
- }
- proc vimage::image_state {iUrl} {
- variable ImagesData
- expr {[info exist ImagesData(state,$iUrl)] ? \
- $ImagesData(state,$iUrl) : -1}
- }
- proc vimage::image_id {iUrl} {
- variable ImagesData
- expr {[info exist ImagesData(image,$iUrl)] ? \
- $ImagesData(image,$iUrl) : ""}
- }
- proc vimage::addResized {iUrl {image_id ""}} {
- variable ImagesData
- variable Config
- if { ! $::useTkImageTools} {
- return
- }
- if {[string length $image_id] == 0} {
- set image_id [image_id $iUrl]
- }
- set iw [image width $image_id]
- set ih [image height $image_id]
- set mw $Config(image_width)
- set mh [expr {round( $ih / ( $iw / $mw + 1))}]
- if {$iw <= $mw || $ih <= $mh} {
- return [set ImagesData(image_resized,$iUrl) $image_id]
- }
- set dest [image create photo]
- tkImageTools::resize $image_id $dest $mw $mh
- set ImagesData(image_resized,$iUrl) $dest
- return
- }
- proc vimage::getResized {iUrl} {
- variable ImagesData
- if {[info exist ImagesData(image_resized,$iUrl)] &&
- [string length $ImagesData(image_resized,$iUrl)] > 0} {
- return $ImagesData(image_resized,$iUrl)
- }
- return vimage/no_image_available
- }
- proc vimage::get_image_urls {str} {
- variable System
- set regUrls {(https?://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,4}(?:\/\S*)?(?:[a-zA-Z0-9_])+\.(?:@INSERT@))}
- regsub -all @INSERT@ $regUrls $System(extensions) regularString
- lsort -unique [regexp -inline -nocase -all -- "$regularString" $str]
- }
- proc vimage::get_all_urls {str} {
- set regUrls {(https?://[a-z0-9\-]+\.[a-z0-9\-\.]+(?:/|(?:/[a-zA-Z0-9!#\$%&'\*\+,\-\.:;=\?@\[\]_~]+)*))}
- lsort -unique [regexp -inline -nocase -all -- $regUrls $str]
- }
- proc vimage::image_showed {iUrl} {
- variable ImagesData
- if {[info exist ImagesData(showed,$iUrl)]} {
- return $ImagesData(showed,$iUrl)
- }
- return 0
- }
- proc vimage::add_to_showed {iUrl} {
- variable ImagesData
- set ImagesData(showed,$iUrl) 1
- }
- proc vimage::schedule {args} {
- after idle [list after 0 $args]
- }
- proc vimage::init_menu {m chatwin X Y x y} {
- set tags [$chatwin tag names "@$x,$y"]
- set idx [lsearch $tags href_*]
- set idx1 [lsearch $tags uri*]
- if { $idx < 0 } {
- return
- }
- if { $idx1 >= 0 } {
- set url [lindex [lindex $tags $idx1] 1]
- } else {
- lassign [$w tag prevrange url "@$x,$y"] a b
- set url [$w get $a $b]
- }
- if {[llength [get_image_urls $url]] == 0} {
- return
- }
- set iUrl [lindex [get_image_urls $url] 0]
- set winid [chatwin_to_winid $chatwin]
- set chatid [::chat::winid_to_chatid $winid]
- create_menu $iUrl $m $chatid
- }
- proc vimage::create_menu {iUrl m chatid} {
- set text [::msgcat::mc "View"]
- if { ! [image_getted $iUrl]} {
- set text [::msgcat::mc "Get"]
- }
- $m add command \
- -label $text \
- -command [list [namespace origin getting] $iUrl $chatid]
- set state normal
- if { ! [image_getted $iUrl]} {
- set state disabled
- }
- $m add command \
- -label [::msgcat::mc "Reload"] \
- -command [list [namespace origin comp_getting] $iUrl $chatid -reload] \
- -state $state
- $m add separator
- }
- proc vimage::chatwin_to_winid {w} {
- set last $w
- if {[winfo parent $w] == "."} {return $last}
- return [chatwin_to_winid [winfo parent $w]]
- }
- ###########
- # HACK: create new procedures in ButtonBox for
- # adding and deleting toolbar button
- #
- proc ::ButtonBox::exist {path index} {
- variable $path
- upvar 0 $path data
- return [expr {[lsearch -exact $data(buttons) $index] > 0}]
- }
- proc ::ButtonBox::delete {path idx} {
- variable $path
- upvar 0 $path data
- set i [lsearch -exact $data(buttons) $idx]
- set data(buttons) [lreplace $data(buttons) $i $i]
- destroy $path.b$idx
- }
- proc vimage::showTooltip {widget tag iUrl} {
- if {[string match $widget* [winfo containing \
- [winfo pointerx .] [winfo pointery .]]] == 0 } {
- return
- }
- if {[winfo exist $widget.tooltip]} {
- destroy $widget.tooltip
- }
- set img_id [getResized $iUrl]
- set scrh [winfo screenheight $widget]
- set scrw [winfo screenwidth $widget]
- set tooltip [toplevel $widget.tooltip]
- wm geometry $tooltip +$scrh+$scrw
- catch {wm overrideredirect $tooltip 1}
- if {[lsearch -exact [wm attributes $tooltip] "-topmost"] >= 0} {
- wm attributes $tooltip -topmost 1
- }
- pack [label $tooltip.label -image $img_id -justify left]
- update idletasks
- set width [winfo reqwidth $tooltip.label]
- set height [winfo reqheight $tooltip.label]
- set x [winfo pointerx .]
- set y [winfo pointery .]
- set pbm [expr {$y > ([winfo screenheight .] / 2.0)}]
- set positionX [expr {$x + 10}]
- set positionY [expr {$y+ round($height / 2.0) * ($pbm * -2 + 1) - round($height / 2.0)}]
- if {$positionX > [expr {round([winfo screenwidth .] / 2)}]} {
- set positionX [expr {$positionX - $width - 20}]
- }
- wm geometry $tooltip +[join "$positionX + $positionY" {}]
- raise $tooltip
- bind $widget.tooltip <Any-Enter> {destroy %W}
- bind $widget.tooltip <Any-Leave> {destroy %W}
- }
- proc vimage::motionTooltip {widget} {
- if { ! [winfo exist $widget.tooltip]} {
- return
- }
- if {[string match $widget* [winfo containing \
- [winfo pointerx .] [winfo pointery .]]] == 0 } {
- return
- }
- set width [winfo reqwidth $widget.tooltip.label]
- set height [winfo reqheight $widget.tooltip.label]
- set x [winfo pointerx .]
- set y [winfo pointery .]
- set pbm [expr {$y > ([winfo screenheight .] / 2.0)}]
- set positionX [expr {$x + 10}]
- set positionY [expr {$y+ round($height / 2.0) * ($pbm * -2 + 1) - round($height / 2.0)}]
- if {$positionX > [expr {round([winfo screenwidth .] / 2)}]} {
- set positionX [expr {$positionX - $width - 20}]
- }
- wm geometry $widget.tooltip +[join "$positionX + $positionY" {}]
- }
- namespace eval vimage {
- if {[catch {package require TkImageTools} result]} {
- set ::useTkImageTools 0
- hook::add finload_hook {
- tk_messageBox -icon warning -title [::msgcat::mc "Load package: error"] \
- -message [::msgcat::mc "Can't find TkImageTools package.\
- \nBalloon suspended.\n\n$result"] \
- -detail [::msgcat::mc "See doc/TkImageTools for detals."]
- }
- } else {set ::useTkImageTools 1}
- hook::add draw_message_post_hook [namespace origin draw_message] 80
- hook::add chat_win_popup_menu_hook [namespace origin init_menu] 1
- hook::add finload_hook [namespace origin add_toolbar_button]
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement