| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | 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] |
| | } |
| |
|