| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| package require Tk |
|
|
| namespace eval ::tkdnd { |
| variable _topw ".drag" |
| variable _tabops |
| variable _state |
| variable _x0 |
| variable _y0 |
| variable _platform_namespace |
| variable _drop_file_temp_dir |
| variable _auto_update 1 |
| variable _dx 3 |
| variable _dy 3 |
|
|
| variable _windowingsystem |
|
|
| bind TkDND_Drag1 <ButtonPress-1> {tkdnd::_begin_drag press 1 %W %s %X %Y %x %y} |
| bind TkDND_Drag1 <B1-Motion> {tkdnd::_begin_drag motion 1 %W %s %X %Y %x %y} |
| bind TkDND_Drag2 <ButtonPress-2> {tkdnd::_begin_drag press 2 %W %s %X %Y %x %y} |
| bind TkDND_Drag2 <B2-Motion> {tkdnd::_begin_drag motion 2 %W %s %X %Y %x %y} |
| bind TkDND_Drag3 <ButtonPress-3> {tkdnd::_begin_drag press 3 %W %s %X %Y %x %y} |
| bind TkDND_Drag3 <B3-Motion> {tkdnd::_begin_drag motion 3 %W %s %X %Y %x %y} |
|
|
| |
| |
| |
| proc initialise { dir PKG_LIB_FILE PACKAGE_NAME} { |
| variable _platform_namespace |
| variable _drop_file_temp_dir |
| variable _windowingsystem |
| global env |
|
|
| switch [tk windowingsystem] { |
| x11 { |
| set _windowingsystem x11 |
| } |
| win32 - |
| windows { |
| set _windowingsystem windows |
| } |
| aqua { |
| set _windowingsystem aqua |
| } |
| default { |
| error "unknown Tk windowing system" |
| } |
| } |
|
|
| |
| |
| foreach var {HOME HOMEPATH USERPROFILE ALLUSERSPROFILE APPDATA} { |
| if {[info exists env($var)]} { |
| if {[file isdirectory $env($var)]} { |
| set UserHomeDir $env($var) |
| break |
| } |
| } |
| } |
|
|
| |
| |
| |
| |
| if {![info exists UserHomeDir] && |
| [string equal $_windowingsystem windows] && |
| [info exists env(HOMEDRIVE)] && [info exists env(HOMEPATH)]} { |
| if {[file isdirectory $env(HOMEDRIVE)$env(HOMEPATH)]} { |
| set UserHomeDir $env(HOMEDRIVE)$env(HOMEPATH) |
| } |
| } |
| |
| if {![info exists UserHomeDir]} { |
| set UserHomeDir [pwd] |
| } |
| set UserHomeDir [file normalize $UserHomeDir] |
|
|
| |
| foreach var {TKDND_TEMP_DIR TEMP TMP} { |
| if {[info exists env($var)]} { |
| if {[file isdirectory $env($var)] && [file writable $env($var)]} { |
| set _drop_file_temp_dir $env($var) |
| break |
| } |
| } |
| } |
| if {![info exists _drop_file_temp_dir]} { |
| foreach _dir [list "$UserHomeDir/Local Settings/Temp" \ |
| "$UserHomeDir/AppData/Local/Temp" \ |
| /tmp \ |
| C:/WINDOWS/Temp C:/Temp C:/tmp \ |
| D:/WINDOWS/Temp D:/Temp D:/tmp] { |
| if {[file isdirectory $_dir] && [file writable $_dir]} { |
| set _drop_file_temp_dir $_dir |
| break |
| } |
| } |
| } |
| if {![info exists _drop_file_temp_dir]} { |
| set _drop_file_temp_dir $UserHomeDir |
| } |
| set _drop_file_temp_dir [file native $_drop_file_temp_dir] |
|
|
| source $dir/tkdnd_generic.tcl |
| switch $_windowingsystem { |
| x11 { |
| source $dir/tkdnd_unix.tcl |
| set _platform_namespace xdnd |
| } |
| win32 - |
| windows { |
| source $dir/tkdnd_windows.tcl |
| set _platform_namespace olednd |
| } |
| aqua { |
| source $dir/tkdnd_macosx.tcl |
| set _platform_namespace macdnd |
| } |
| default { |
| error "unknown Tk windowing system" |
| } |
| } |
| load $dir/$PKG_LIB_FILE $PACKAGE_NAME |
| source $dir/tkdnd_compat.tcl |
| ${_platform_namespace}::initialise |
| } |
|
|
| proc GetDropFileTempDirectory { } { |
| variable _drop_file_temp_dir |
| return $_drop_file_temp_dir |
| } |
| proc SetDropFileTempDirectory { dir } { |
| variable _drop_file_temp_dir |
| set _drop_file_temp_dir $dir |
| } |
|
|
| } |
|
|
| |
| |
| |
| proc ::tkdnd::drag_source { mode path { types {} } { event 1 } |
| { tagprefix TkDND_Drag } } { |
| set tags [bindtags $path] |
| set idx [lsearch $tags ${tagprefix}$event] |
| switch -- $mode { |
| register { |
| if { $idx != -1 } { |
| |
| |
| } else { |
| bindtags $path [linsert $tags 1 ${tagprefix}$event] |
| } |
| _drag_source_update_types $path $types |
| } |
| unregister { |
| if { $idx != -1 } { |
| bindtags $path [lreplace $tags $idx $idx] |
| } |
| } |
| } |
| } |
|
|
| proc ::tkdnd::_drag_source_update_types { path types } { |
| set types [platform_specific_types $types] |
| set old_types [bind $path <<DragSourceTypes>>] |
| foreach type $types { |
| if {[lsearch $old_types $type] < 0} {lappend old_types $type} |
| } |
| bind $path <<DragSourceTypes>> $old_types |
| } |
|
|
| |
| |
| |
| proc ::tkdnd::drop_target { mode path { types {} } } { |
| variable _windowingsystem |
| set types [platform_specific_types $types] |
| switch -- $mode { |
| register { |
| switch $_windowingsystem { |
| x11 { |
| _register_types $path [winfo toplevel $path] $types |
| } |
| win32 - |
| windows { |
| _RegisterDragDrop $path |
| bind <Destroy> $path {+ tkdnd::_RevokeDragDrop %W} |
| } |
| aqua { |
| macdnd::registerdragwidget [winfo toplevel $path] $types |
| } |
| default { |
| error "unknown Tk windowing system" |
| } |
| } |
| set old_types [bind $path <<DropTargetTypes>>] |
| set new_types {} |
| foreach type $types { |
| if {[lsearch -exact $old_types $type] < 0} {lappend new_types $type} |
| } |
| if {[llength $new_types]} { |
| bind $path <<DropTargetTypes>> [concat $old_types $new_types] |
| } |
| } |
| unregister { |
| switch $_windowingsystem { |
| x11 { |
| } |
| win32 - |
| windows { |
| _RevokeDragDrop $path |
| } |
| aqua { |
| error todo |
| } |
| default { |
| error "unknown Tk windowing system" |
| } |
| } |
| bind $path <<DropTargetTypes>> {} |
| } |
| } |
| } |
|
|
| |
| |
| |
| proc ::tkdnd::_begin_drag { event button source state X Y x y } { |
| variable _x0 |
| variable _y0 |
| variable _state |
|
|
| switch -- $event { |
| press { |
| set _x0 $X |
| set _y0 $Y |
| set _state "press" |
| } |
| motion { |
| if { ![info exists _state] } { |
| |
| |
| return |
| } |
| if { [string equal $_state "press"] } { |
| variable _dx |
| variable _dy |
| if { abs($_x0-$X) > ${_dx} || abs($_y0-$Y) > ${_dy} } { |
| set _state "done" |
| _init_drag $button $source $state $X $Y $x $y |
| } |
| } |
| } |
| } |
| } |
|
|
| |
| |
| |
| proc ::tkdnd::_init_drag { button source state rootX rootY X Y } { |
| |
| set cmd [bind $source <<DragInitCmd>>] |
| |
| if {[string length $cmd]} { |
| set cmd [string map [list %W $source %X $rootX %Y $rootY %x $X %y $Y \ |
| %S $state %e <<DragInitCmd>> %A \{\} %% % \ |
| %t [bind $source <<DragSourceTypes>>]] $cmd] |
| set code [catch {uplevel \#0 $cmd} info options] |
| |
| switch -exact -- $code { |
| 0 {} |
| 3 - 4 { |
| |
| return |
| } |
| default { |
| return -options $options $info |
| } |
| } |
|
|
| set len [llength $info] |
| if {$len == 3} { |
| foreach { actions types _data } $info { break } |
| set types [platform_specific_types $types] |
| set data [list] |
| foreach type $types { |
| lappend data $_data |
| } |
| unset _data |
| } elseif {$len == 2} { |
| foreach { actions _data } $info { break } |
| set data [list]; set types [list] |
| foreach {t d} $_data { |
| foreach t [platform_specific_types $t] { |
| lappend types $t; lappend data $d |
| } |
| } |
| unset _data t d |
| } else { |
| if {$len == 1 && [string equal [lindex $actions 0] "refuse_drop"]} { |
| return |
| } |
| error "not enough items in the result of the <<DragInitCmd>>\ |
| event binding. Either 2 or 3 items are expected. The command |
| executed was: \"$cmd\"\nResult was: \"$info\"" |
| } |
| set action refuse_drop |
| variable _windowingsystem |
| |
| |
| |
| |
| |
| switch $_windowingsystem { |
| x11 { |
| set action [xdnd::_dodragdrop $source $actions $types $data $button] |
| } |
| win32 - |
| windows { |
| set action [_DoDragDrop $source $actions $types $data $button] |
| } |
| aqua { |
| set action [macdnd::dodragdrop $source $actions $types $data $button] |
| } |
| default { |
| error "unknown Tk windowing system" |
| } |
| } |
| |
| |
| _end_drag $button $source {} $action {} $data {} $state $rootX $rootY $X $Y |
| } |
| } |
|
|
| |
| |
| |
| proc ::tkdnd::_end_drag { button source target action type data result |
| state rootX rootY X Y } { |
| set rootX 0 |
| set rootY 0 |
| |
| set cmd [bind $source <<DragEndCmd>>] |
| if {[string length $cmd]} { |
| set cmd [string map [list %W $source %X $rootX %Y $rootY %x $X %y $Y %% % \ |
| %S $state %e <<DragEndCmd>> %A \{$action\}] $cmd] |
| set info [uplevel \#0 $cmd] |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
| } |
|
|
| |
| |
| |
| proc ::tkdnd::platform_specific_types { types } { |
| variable _platform_namespace |
| ${_platform_namespace}::platform_specific_types $types |
| } |
|
|
| |
| |
| |
| proc ::tkdnd::platform_independent_types { types } { |
| variable _platform_namespace |
| ${_platform_namespace}::platform_independent_types $types |
| } |
|
|
| |
| |
| |
| proc ::tkdnd::platform_specific_type { type } { |
| variable _platform_namespace |
| ${_platform_namespace}::platform_specific_type $type |
| } |
|
|
| |
| |
| |
| proc ::tkdnd::platform_independent_type { type } { |
| variable _platform_namespace |
| ${_platform_namespace}::platform_independent_type $type |
| } |
|
|
| |
| |
| |
| proc ::tkdnd::bytes_to_string { bytes } { |
| set string {} |
| foreach byte $bytes { |
| append string [binary format c $byte] |
| } |
| return $string |
| } |
|
|
| |
| |
| |
| proc ::tkdnd::urn_unquote {url} { |
| set result "" |
| set start 0 |
| while {[regexp -start $start -indices {%[0-9a-fA-F]{2}} $url match]} { |
| foreach {first last} $match break |
| append result [string range $url $start [expr {$first - 1}]] |
| append result [format %c 0x[string range $url [incr first] $last]] |
| set start [incr last] |
| } |
| append result [string range $url $start end] |
| return [encoding convertfrom utf-8 $result] |
| } |
|
|