diff options
| author | petasisg@gmail.com <petasisg@gmail.com@f3661a36-4baa-549a-d6c7-40e0ffef350e> | 2014-09-21 13:24:56 (GMT) |
|---|---|---|
| committer | petasisg@gmail.com <petasisg@gmail.com@f3661a36-4baa-549a-d6c7-40e0ffef350e> | 2014-09-21 13:24:56 (GMT) |
| commit | 4dda192dd17aa0819651eaaf5fa59b2bc5dcb678 (patch) | |
| tree | 1e997e273a39014f8de34a685f1c0e47cb819d30 | |
| parent | b6dbf97147dbe57d78a5f8d19d64427437ae22a8 (diff) | |
| download | tkdnd-4dda192dd17aa0819651eaaf5fa59b2bc5dcb678.zip tkdnd-4dda192dd17aa0819651eaaf5fa59b2bc5dcb678.tar.gz tkdnd-4dda192dd17aa0819651eaaf5fa59b2bc5dcb678.tar.bz2 | |
| -rw-r--r-- | CMakeLists.txt | 1 | ||||
| -rw-r--r-- | Changelog | 21 | ||||
| -rw-r--r-- | configure.in | 2 | ||||
| -rw-r--r-- | demos/basic.tcl | 4 | ||||
| -rw-r--r-- | demos/dndSpy.tcl | 14 | ||||
| -rw-r--r-- | demos/simple_target.tcl | 4 | ||||
| -rw-r--r-- | library/tkdnd.tcl | 56 | ||||
| -rw-r--r-- | library/tkdnd_generic.tcl | 490 | ||||
| -rw-r--r-- | library/tkdnd_macosx.tcl | 13 | ||||
| -rw-r--r-- | library/tkdnd_unix.tcl | 20 | ||||
| -rw-r--r-- | library/tkdnd_windows.tcl | 393 | ||||
| -rw-r--r-- | win/OleDND.h | 44 | ||||
| -rw-r--r-- | win/TkDND_OleDND.cpp | 26 |
13 files changed, 688 insertions, 400 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 96064d1..018e77c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -204,6 +204,7 @@ INSTALL ( TARGETS ${PKG_TARGET_LIB_NAME} ARCHIVE DESTINATION ${PKG_TARGET_LIB_NAME} ) INSTALL ( FILES library/pkgIndex.tcl library/tkdnd.tcl + library/tkdnd_generic.tcl library/tkdnd_compat.tcl library/tkdnd_macosx.tcl library/tkdnd_unix.tcl @@ -1,3 +1,24 @@ + +2014-09-21 Petasis George <petasis@iit.demokritos.gr> + * CMakeLists.txt: + * configure.in: Updated installed files. + + * demos/basic.tcl: + * demos/dndSpy.tcl: + * demos/simple_target.tcl: Bug fixes. + + * library/tkdnd.tcl: + * library/tkdnd_macosx.tcl: + * library/tkdnd_unix.tcl: Various bug fixes. + + * win/OleDND.h: + * win/TkDND_OleDND.cpp: + * library/tkdnd_windows.tcl: Changed implementation to re-use the + generic implementation. + + * library/tkdnd_generic.tcl: Added a new "generic" implementation, with + the aim to be re-used by all supported platforms. + 2014-08-19 Petasis George <petasis@iit.demokritos.gr> * unix/TkDND_XDND.c: * win/OleDND.h: Corrected behaviour when mouse drags over overlapping diff --git a/configure.in b/configure.in index dff9c3d..de9d242 100644 --- a/configure.in +++ b/configure.in @@ -77,7 +77,7 @@ TEA_ADD_INCLUDES([]) TEA_ADD_LIBS([]) TEA_ADD_CFLAGS([]) TEA_ADD_STUB_SOURCES([]) -TEA_ADD_TCL_SOURCES([library/tkdnd_compat.tcl library/tkdnd.tcl library/tkdnd_unix.tcl library/tkdnd_windows.tcl library/tkdnd_macosx.tcl]) +TEA_ADD_TCL_SOURCES([library/tkdnd_compat.tcl library/tkdnd.tcl library/tkdnd_generic.tcl library/tkdnd_unix.tcl library/tkdnd_windows.tcl library/tkdnd_macosx.tcl]) #-------------------------------------------------------------------- # __CHANGE__ diff --git a/demos/basic.tcl b/demos/basic.tcl index ce1c2c9..b3f1e2d 100644 --- a/demos/basic.tcl +++ b/demos/basic.tcl @@ -58,7 +58,7 @@ tkdnd::drop_target register .drop_target * set cmd {handle_event %e %W %X %Y %ST %TT %a %A %CST %CTT %t %T %CPT %b %D}
set itemList {Event Widget X Y Source_Types Target_Types Source_Actions Action
Common_Source_Types Common_Target_Types Types
- Drop_Type Cross_Platform_Drop_Type
+ Drop_Type Cross_Platform_Drop_Type
Pressed_Keys Data}
# Add the various events...
bind .drop_target <<DropEnter>> $cmd
@@ -73,7 +73,7 @@ bind .drop_target <<Drop>> $cmd bind .drop_target <<Drop:DND_Files>> $cmd
# Add a special drop command for DND_Color...
-bind .drop_target <<Drop:DND_Color>> $cmd
+bind .drop_target <<Drop:DND_Color>> $cmd
# Create some widgets for showing event info.
foreach item $itemList {
diff --git a/demos/dndSpy.tcl b/demos/dndSpy.tcl index be0c9e2..f7becfc 100644 --- a/demos/dndSpy.tcl +++ b/demos/dndSpy.tcl @@ -74,12 +74,12 @@ proc FillData {text Data type code} { FileGroupDescriptor* { foreach item $Data { $text insert end " * \"$item\"\n" - if {[file exists $item]} { - $text insert end " -> File exists. Deleting...\n" - file delete -force $item - } else { - $text insert end " -> File missing...\n" - } + if {[file exists $item]} { + $text insert end " -> File exists. Deleting...\n" + file delete -force $item + } else { + $text insert end " -> File missing...\n" + } } } DND_Files { @@ -102,7 +102,7 @@ set abg #8fbc8f set type * dnd bindtarget .typeList $type <DragEnter> ".typeList configure -bg $abg FillTypeListbox .typeList %t %T %c %C %a %A %m -return \[lindex %A 0\]" +return \[lindex %a 0\]" dnd bindtarget .typeList $type <Drag> \ [dnd bindtarget .typeList $type <DragEnter>] dnd bindtarget .typeList $type <Drop> \ diff --git a/demos/simple_target.tcl b/demos/simple_target.tcl index 341cac2..57c82dd 100644 --- a/demos/simple_target.tcl +++ b/demos/simple_target.tcl @@ -1,7 +1,9 @@ package require tkdnd
catch {console show}
-pack [ttk::button .drop_target -text " Drop Target (I can accept anything!) "] \
+pack [ttk::button .drop_target \
+ -text " Drop Target (I can accept anything!)\
+ \n but only on the left half!"] \
-fill x -padx 20 -pady 20
tkdnd::drop_target register .drop_target *
diff --git a/library/tkdnd.tcl b/library/tkdnd.tcl index d15f622..51ed777 100644 --- a/library/tkdnd.tcl +++ b/library/tkdnd.tcl @@ -1,6 +1,6 @@ # # tkdnd.tcl -- -# +# # This file implements some utility procedures that are used by the TkDND # package. # @@ -21,13 +21,13 @@ # and need not follow the licensing terms described here, provided that # the new terms are clearly indicated on the first page of each file where # they apply. -# +# # IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY # FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES # ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY # DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. -# +# # THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE @@ -38,7 +38,7 @@ package require Tk -namespace eval tkdnd { +namespace eval ::tkdnd { variable _topw ".drag" variable _tabops variable _state @@ -56,7 +56,7 @@ namespace eval tkdnd { bind TkDND_Drag2 <B2-Motion> {tkdnd::_begin_drag motion 2 %W %s %X %Y} bind TkDND_Drag3 <ButtonPress-3> {tkdnd::_begin_drag press 3 %W %s %X %Y} bind TkDND_Drag3 <B3-Motion> {tkdnd::_begin_drag motion 3 %W %s %X %Y} - + # ---------------------------------------------------------------------------- # Command tkdnd::initialise: Initialise the TkDND package. # ---------------------------------------------------------------------------- @@ -97,7 +97,7 @@ namespace eval tkdnd { ## OS X returns "unix," but that's not useful because it has its own ## windowing system, aqua ## Under windows we have to also combine HOMEDRIVE & HOMEPATH... - if {![info exists UserHomeDir] && + if {![info exists UserHomeDir] && [string equal $_windowingsystem windows] && [info exists env(HOMEDRIVE)] && [info exists env(HOMEPATH)]} { if {[file isdirectory $env(HOMEDRIVE)$env(HOMEPATH)]} { @@ -109,7 +109,7 @@ namespace eval tkdnd { set UserHomeDir [pwd] } set UserHomeDir [file normalize $UserHomeDir] - + ## Try to locate a temporary directory... foreach var {TKDND_TEMP_DIR TEMP TMP} { if {[info exists env($var)]} { @@ -135,7 +135,8 @@ namespace eval tkdnd { 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 @@ -147,7 +148,6 @@ namespace eval tkdnd { set _platform_namespace olednd } aqua { - source $dir/tkdnd_unix.tcl source $dir/tkdnd_macosx.tcl set _platform_namespace macdnd } @@ -168,13 +168,13 @@ namespace eval tkdnd { variable _drop_file_temp_dir set _drop_file_temp_dir $dir } - -};# namespace tkdnd + +};# namespace ::tkdnd # ---------------------------------------------------------------------------- # Command tkdnd::drag_source # ---------------------------------------------------------------------------- -proc tkdnd::drag_source { mode path { types {} } { event 1 } } { +proc ::tkdnd::drag_source { mode path { types {} } { event 1 } } { set tags [bindtags $path] set idx [lsearch $tags "TkDND_Drag*"] switch -- $mode { @@ -202,7 +202,7 @@ proc tkdnd::drag_source { mode path { types {} } { event 1 } } { # ---------------------------------------------------------------------------- # Command tkdnd::drop_target # ---------------------------------------------------------------------------- -proc tkdnd::drop_target { mode path { types {} } } { +proc ::tkdnd::drop_target { mode path { types {} } } { variable _windowingsystem set types [platform_specific_types $types] switch -- $mode { @@ -255,7 +255,7 @@ proc tkdnd::drop_target { mode path { types {} } } { # ---------------------------------------------------------------------------- # Command tkdnd::_begin_drag # ---------------------------------------------------------------------------- -proc tkdnd::_begin_drag { event button source state X Y } { +proc ::tkdnd::_begin_drag { event button source state X Y } { variable _x0 variable _y0 variable _state @@ -285,7 +285,7 @@ proc tkdnd::_begin_drag { event button source state X Y } { # ---------------------------------------------------------------------------- # Command tkdnd::_init_drag # ---------------------------------------------------------------------------- -proc tkdnd::_init_drag { button source state rootX rootY } { +proc ::tkdnd::_init_drag { button source state rootX rootY } { # Call the <<DragInitCmd>> binding. set cmd [bind $source <<DragInitCmd>>] if {[string length $cmd]} { @@ -308,7 +308,7 @@ proc tkdnd::_init_drag { button source state rootX rootY } { foreach {t d} $_data { foreach t [platform_specific_types $t] { lappend types $t; lappend data $d - } + } } unset _data t d } else { @@ -341,8 +341,8 @@ proc tkdnd::_init_drag { button source state rootX rootY } { # ---------------------------------------------------------------------------- # Command tkdnd::_end_drag # ---------------------------------------------------------------------------- -proc tkdnd::_end_drag { button source target action type data result - state rootX rootY } { +proc ::tkdnd::_end_drag { button source target action type data result + state rootX rootY } { set rootX 0 set rootY 0 # Call the <<DragEndCmd>> binding. @@ -380,39 +380,39 @@ proc tkdnd::_end_drag { button source target action type data result # ---------------------------------------------------------------------------- # Command tkdnd::platform_specific_types # ---------------------------------------------------------------------------- -proc tkdnd::platform_specific_types { types } { +proc ::tkdnd::platform_specific_types { types } { variable _platform_namespace - ${_platform_namespace}::_platform_specific_types $types + ${_platform_namespace}::platform_specific_types $types }; # tkdnd::platform_specific_types # ---------------------------------------------------------------------------- # Command tkdnd::platform_independent_types # ---------------------------------------------------------------------------- -proc tkdnd::platform_independent_types { types } { +proc ::tkdnd::platform_independent_types { types } { variable _platform_namespace - ${_platform_namespace}::_platform_independent_types $types + ${_platform_namespace}::platform_independent_types $types }; # tkdnd::platform_independent_types # ---------------------------------------------------------------------------- # Command tkdnd::platform_specific_type # ---------------------------------------------------------------------------- -proc tkdnd::platform_specific_type { type } { +proc ::tkdnd::platform_specific_type { type } { variable _platform_namespace - ${_platform_namespace}::_platform_specific_type $type + ${_platform_namespace}::platform_specific_type $type }; # tkdnd::platform_specific_type # ---------------------------------------------------------------------------- # Command tkdnd::platform_independent_type # ---------------------------------------------------------------------------- -proc tkdnd::platform_independent_type { type } { +proc ::tkdnd::platform_independent_type { type } { variable _platform_namespace - ${_platform_namespace}::_platform_independent_type $type + ${_platform_namespace}::platform_independent_type $type }; # tkdnd::platform_independent_type # ---------------------------------------------------------------------------- # Command tkdnd::bytes_to_string # ---------------------------------------------------------------------------- -proc tkdnd::bytes_to_string { bytes } { +proc ::tkdnd::bytes_to_string { bytes } { set string {} foreach byte $bytes { append string [binary format c $byte] @@ -423,7 +423,7 @@ proc tkdnd::bytes_to_string { bytes } { # ---------------------------------------------------------------------------- # Command tkdnd::urn_unquote # ---------------------------------------------------------------------------- -proc tkdnd::urn_unquote {url} { +proc ::tkdnd::urn_unquote {url} { set result "" set start 0 while {[regexp -start $start -indices {%[0-9a-fA-F]{2}} $url match]} { diff --git a/library/tkdnd_generic.tcl b/library/tkdnd_generic.tcl new file mode 100644 index 0000000..af62a25 --- /dev/null +++ b/library/tkdnd_generic.tcl @@ -0,0 +1,490 @@ +# +# tkdnd_generic.tcl -- +# +# This file implements some utility procedures that are used by the TkDND +# package. +# +# This software is copyrighted by: +# George Petasis, National Centre for Scientific Research "Demokritos", +# Aghia Paraskevi, Athens, Greece. +# e-mail: petasis@iit.demokritos.gr +# +# The following terms apply to all files associated +# with the software unless explicitly disclaimed in individual files. +# +# The authors hereby grant permission to use, copy, modify, distribute, +# and license this software and its documentation for any purpose, provided +# that existing copyright notices are retained in all copies and that this +# notice is included verbatim in any distributions. No written agreement, +# license, or royalty fee is required for any of the authorized uses. +# Modifications to this software may be copyrighted by their authors +# and need not follow the licensing terms described here, provided that +# the new terms are clearly indicated on the first page of each file where +# they apply. +# +# IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY +# FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES +# ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY +# DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, +# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE +# IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE +# NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR +# MODIFICATIONS. +# + +namespace eval generic { + variable _types {} + variable _typelist {} + variable _codelist {} + variable _actionlist {} + variable _pressedkeys {} + variable _action {} + variable _common_drag_source_types {} + variable _common_drop_target_types {} + variable _drag_source {} + variable _drop_target {} + + variable _dragging 0 + + variable _last_mouse_root_x 0 + variable _last_mouse_root_y 0 + + variable _tkdnd2platform + variable _platform2tkdnd + + proc debug {msg} { + puts $msg + };# debug + + proc initialise { } { + };# initialise + + proc initialise_platform_to_tkdnd_types { types } { + variable _platform2tkdnd + variable _tkdnd2platform + set _platform2tkdnd [dict create {*}$types] + set _tkdnd2platform [dict create] + foreach type [dict keys $_platform2tkdnd] { + dict lappend _tkdnd2platform [dict get $_platform2tkdnd $type] $type + } + };# initialise_platform_to_tkdnd_types + + proc initialise_tkdnd_to_platform_types { types } { + variable _tkdnd2platform + set _tkdnd2platform [dict create {*}$types] + };# initialise_tkdnd_to_platform_types + +};# namespace generic + +# ---------------------------------------------------------------------------- +# Command generic::HandleEnter +# ---------------------------------------------------------------------------- +proc generic::HandleEnter { drop_target drag_source typelist codelist + actionlist pressedkeys } { + variable _typelist; set _typelist $typelist + variable _pressedkeys; set _pressedkeys $pressedkeys + variable _action; set _action refuse_drop + variable _common_drag_source_types; set _common_drag_source_types {} + variable _common_drop_target_types; set _common_drop_target_types {} + variable _actionlist + variable _drag_source; set _drag_source $drag_source + variable _drop_target; set _drop_target {} + variable _actionlist; set _actionlist $actionlist + variable _codelist set _codelist $codelist + + variable _last_mouse_root_x; set _last_mouse_root_x 0 + variable _last_mouse_root_y; set _last_mouse_root_y 0 + # debug "\n===============================================================" + # debug "generic::HandleEnter: drop_target=$drop_target,\ + # drag_source=$drag_source,\ + # typelist=$typelist" + # debug "generic::HandleEnter: ACTION: default" + return default +};# generic::HandleEnter + +# ---------------------------------------------------------------------------- +# Command generic::HandlePosition +# ---------------------------------------------------------------------------- +proc generic::HandlePosition { drop_target drag_source pressedkeys + rootX rootY } { + variable _types + variable _typelist + variable _codelist + variable _actionlist + variable _pressedkeys + variable _action + variable _common_drag_source_types + variable _common_drop_target_types + variable _drag_source + variable _drop_target + + variable _last_mouse_root_x; set _last_mouse_root_x $rootX + variable _last_mouse_root_y; set _last_mouse_root_y $rootY + + # debug "generic::HandlePosition: drop_target=$drop_target,\ + # _drop_target=$_drop_target, rootX=$rootX, rootY=$rootY" + + if {![info exists _drag_source] && ![string length $_drag_source]} { + # debug "generic::HandlePosition: no or empty _drag_source:\ + # return refuse_drop" + return refuse_drop + } + + if {$drag_source ne "" && $drag_source ne $_drag_source} { + debug "generic position event from unexpected source: $_drag_source\ + != $drag_source" + return refuse_drop + } + + set _pressedkeys $pressedkeys + + ## Does the new drop target support any of our new types? + set _types [bind $drop_target <<DropTargetTypes>>] + # debug ">> Accepted types: $drop_target $_types" + if {[llength $_types]} { + ## Examine the drop target types, to find at least one match with the drag + ## source types... + set supported_types [supported_types $_typelist] + foreach type $_types { + foreach matched [lsearch -glob -all -inline $supported_types $type] { + ## Drop target supports this type. + lappend common_drag_source_types $matched + lappend common_drop_target_types $type + } + } + } + + # debug "\t($_drop_target) -> ($drop_target)" + if {$drop_target != $_drop_target} { + if {[string length $_drop_target]} { + ## Call the <<DropLeave>> event. + # debug "\t<<DropLeave>> on $_drop_target" + set cmd [bind $_drop_target <<DropLeave>>] + if {[string length $cmd]} { + set cmd [string map [list %W $_drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A \{$_action\} %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D \{\} %e <<DropLeave>> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + uplevel \#0 $cmd + } + } + set _drop_target {} + + if {[info exists common_drag_source_types]} { + set _action [lindex $_actionlist 0] + set _common_drag_source_types $common_drag_source_types + set _common_drop_target_types $common_drop_target_types + set _drop_target $drop_target + ## Drop target supports at least one type. Send a <<DropEnter>>. + # puts "<<DropEnter>> -> $drop_target" + set cmd [bind $drop_target <<DropEnter>>] + if {[string length $cmd]} { + focus $drop_target + set cmd [string map [list %W $drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D \{\} %e <<DropEnter>> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + } + } + set _drop_target $drop_target + } + + set _drop_target {} + if {[info exists common_drag_source_types]} { + set _common_drag_source_types $common_drag_source_types + set _common_drop_target_types $common_drop_target_types + set _drop_target $drop_target + ## Drop target supports at least one type. Send a <<DropPosition>>. + set cmd [bind $drop_target <<DropPosition>>] + if {[string length $cmd]} { + set cmd [string map [list %W $drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D \{\} %e <<DropPosition>> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + } + } + # Return values: copy, move, link, ask, private, refuse_drop, default + # debug "generic::HandlePosition: ACTION: $_action" + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + return $_action +};# generic::HandlePosition + +# ---------------------------------------------------------------------------- +# Command generic::HandleLeave +# ---------------------------------------------------------------------------- +proc generic::HandleLeave { } { + variable _types + variable _typelist + variable _codelist + variable _actionlist + variable _pressedkeys + variable _action + variable _common_drag_source_types + variable _common_drop_target_types + variable _drag_source + variable _drop_target + variable _last_mouse_root_x + variable _last_mouse_root_y + if {![info exists _drop_target]} {set _drop_target {}} + # debug "generic::HandleLeave: _drop_target=$_drop_target" + if {[info exists _drop_target] && [string length $_drop_target]} { + set cmd [bind $_drop_target <<DropLeave>>] + if {[string length $cmd]} { + set cmd [string map [list %W $_drop_target \ + %X $_last_mouse_root_x %Y $_last_mouse_root_y \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A \{$_action\} %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D \{\} %e <<DropLeave>> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + } + } + foreach var {_types _typelist _actionlist _pressedkeys _action + _common_drag_source_types _common_drop_target_types + _drag_source _drop_target} { + set $var {} + } +};# generic::HandleLeave + +# ---------------------------------------------------------------------------- +# Command generic::HandleDrop +# ---------------------------------------------------------------------------- +proc generic::HandleDrop {drop_target drag_source pressedkeys rootX rootY time } { + variable _types + variable _typelist + variable _codelist + variable _actionlist + variable _pressedkeys + variable _action + variable _common_drag_source_types + variable _common_drop_target_types + variable _drag_source + variable _drop_target + variable _last_mouse_root_x + variable _last_mouse_root_y + variable _last_mouse_root_x; set _last_mouse_root_x $rootX + variable _last_mouse_root_y; set _last_mouse_root_y $rootY + + set _pressedkeys $pressedkeys + + # puts "generic::HandleDrop: $time" + + if {![info exists _drag_source] && ![string length $_drag_source]} { + return refuse_drop + } + if {![info exists _drop_target] && ![string length $_drop_target]} { + return refuse_drop + } + if {![llength $_common_drag_source_types]} {return refuse_drop} + ## Get the dropped data. + set data [GetDroppedData $time] + ## Try to select the most specific <<Drop>> event. + foreach type [concat $_common_drag_source_types $_common_drop_target_types] { + set type [platform_independent_type $type] + set cmd [bind $_drop_target <<Drop:$type>>] + if {[string length $cmd]} { + set cmd [string map [list %W $_drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D [list $data] %e <<Drop:$type>> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + # Return values: copy, move, link, ask, private, refuse_drop + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + return $_action + } + } + set cmd [bind $_drop_target <<Drop>>] + if {[string length $cmd]} { + set cmd [string map [list %W $_drop_target %X $rootX %Y $rootY \ + %CST \{$_common_drag_source_types\} \ + %CTT \{$_common_drop_target_types\} \ + %CPT \{[lindex [platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ + %ST \{$_typelist\} %TT \{$_types\} \ + %A $_action %a \{$_actionlist\} \ + %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ + %D [list $data] %e <<Drop>> \ + %L \{$_typelist\} %% % \ + %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ + %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ + ] $cmd] + set _action [uplevel \#0 $cmd] + } + # Return values: copy, move, link, ask, private, refuse_drop + switch -exact -- $_action { + copy - move - link - ask - private - refuse_drop - default {} + default {set _action copy} + } + return $_action +};# generic::HandleDrop + +# ---------------------------------------------------------------------------- +# Command generic::GetDroppedData +# ---------------------------------------------------------------------------- +proc generic::GetDroppedData { time } { + variable _dropped_data + return $_dropped_data +};# generic::GetDroppedData + +# ---------------------------------------------------------------------------- +# Command generic::SetDroppedData +# ---------------------------------------------------------------------------- +proc generic::SetDroppedData { data } { + variable _dropped_data + set _dropped_data $data +};# generic::SetDroppedData + +# ---------------------------------------------------------------------------- +# Command generic::GetDragSource +# ---------------------------------------------------------------------------- +proc generic::GetDragSource { } { + variable _drag_source + return $_drag_source +};# generic::GetDragSource + +# ---------------------------------------------------------------------------- +# Command generic::GetDropTarget +# ---------------------------------------------------------------------------- +proc generic::GetDropTarget { } { + variable _drop_target + if {[string length $_drop_target]} { + return [winfo id $_drop_target] + } + return 0 +};# generic::GetDropTarget + +# ---------------------------------------------------------------------------- +# Command generic::GetDragSourceCommonTypes +# ---------------------------------------------------------------------------- +proc generic::GetDragSourceCommonTypes { } { + variable _common_drag_source_types + return $_common_drag_source_types +};# generic::GetDragSourceCommonTypes + +# ---------------------------------------------------------------------------- +# Command generic::GetDropTargetCommonTypes +# ---------------------------------------------------------------------------- +proc generic::GetDropTargetCommonTypes { } { + variable _common_drag_source_types + return $_common_drag_source_types +};# generic::GetDropTargetCommonTypes + +# ---------------------------------------------------------------------------- +# Command generic::platform_specific_types +# ---------------------------------------------------------------------------- +proc generic::platform_specific_types { types } { + set new_types {} + foreach type $types { + set new_types [concat $new_types [platform_specific_type $type]] + } + return $new_types +}; # generic::platform_specific_types + +# ---------------------------------------------------------------------------- +# Command generic::platform_specific_type +# ---------------------------------------------------------------------------- +proc generic::platform_specific_type { type } { + variable _tkdnd2platform + if {[dict exists $_tkdnd2platform $type]} { + return [dict get $_tkdnd2platform $type] + } + list $type +}; # generic::platform_specific_type + +# ---------------------------------------------------------------------------- +# Command tkdnd::platform_independent_types +# ---------------------------------------------------------------------------- +proc ::tkdnd::platform_independent_types { types } { + set new_types {} + foreach type $types { + set new_types [concat $new_types [platform_independent_type $type]] + } + return $new_types +}; # tkdnd::platform_independent_types + +# ---------------------------------------------------------------------------- +# Command generic::platform_independent_type +# ---------------------------------------------------------------------------- +proc generic::platform_independent_type { type } { + variable _platform2tkdnd + if {[dict exists $_platform2tkdnd $type]} { + return [dict get $_platform2tkdnd $type] + } + return $type +}; # generic::platform_independent_type + +# ---------------------------------------------------------------------------- +# Command generic::supported_types +# ---------------------------------------------------------------------------- +proc generic::supported_types { types } { + set new_types {} + foreach type $types { + if {[supported_type $type]} {lappend new_types $type} + } + return $new_types +}; # generic::supported_types + +# ---------------------------------------------------------------------------- +# Command generic::supported_type +# ---------------------------------------------------------------------------- +proc generic::supported_type { type } { + variable _platform2tkdnd + if {[dict exists $_platform2tkdnd $type]} { + return 1 + } + return 0 +}; # generic::supported_type diff --git a/library/tkdnd_macosx.tcl b/library/tkdnd_macosx.tcl index d92d43f..a571c33 100644 --- a/library/tkdnd_macosx.tcl +++ b/library/tkdnd_macosx.tcl @@ -54,7 +54,7 @@ if {[tk windowingsystem] eq "aqua" && "AppKit" ni [winfo server .]} { namespace eval macdnd { variable _dropped_data - proc initialise {} { + proc initialise { } { variable _tkdnd2platform variable _platform2tkdnd @@ -68,6 +68,7 @@ namespace eval macdnd { lappend _tkdnd2platform($_platform2tkdnd($type)) $type } };# initialise + };# namespace macdnd # ---------------------------------------------------------------------------- @@ -87,7 +88,7 @@ proc macdnd::_HandlePosition { drop_target rootX rootY } { # ---------------------------------------------------------------------------- # Command macdnd::_HandleLeave # ---------------------------------------------------------------------------- -proc macdnd::_HandleLeave { args } { +proc macdnd::_HandleLeave { args } { ::tkdnd::xdnd::_HandleXdndLeave };# macdnd::_HandleLeave @@ -114,28 +115,28 @@ proc xdnd::_GetDroppedData { time } { # ---------------------------------------------------------------------------- # Command macdnd::_GetDragSource # ---------------------------------------------------------------------------- -proc macdnd::_GetDragSource { } { +proc macdnd::_GetDragSource { } { ::tkdnd::xdnd::_GetDragSource };# macdnd::_GetDragSource # ---------------------------------------------------------------------------- # Command macdnd::_GetDropTarget # ---------------------------------------------------------------------------- -proc macdnd::_GetDropTarget { } { +proc macdnd::_GetDropTarget { } { ::tkdnd::xdnd::_GetDropTarget };# macdnd::_GetDropTarget # ---------------------------------------------------------------------------- # Command macdnd::_GetDragSourceCommonTypes # ---------------------------------------------------------------------------- -proc macdnd::_GetDragSourceCommonTypes { } { +proc macdnd::_GetDragSourceCommonTypes { } { ::tkdnd::xdnd::_GetDragSourceCommonTypes };# macdnd::_GetDragSourceCommonTypes # ---------------------------------------------------------------------------- # Command macdnd::_GetDropTargetCommonTypes # ---------------------------------------------------------------------------- -proc macdnd::_GetDropTargetCommonTypes { } { +proc macdnd::_GetDropTargetCommonTypes { } { ::tkdnd::xdnd::_GetDropTargetCommonTypes };# macdnd::_GetDropTargetCommonTypes diff --git a/library/tkdnd_unix.tcl b/library/tkdnd_unix.tcl index 34d219e..2379fc8 100644 --- a/library/tkdnd_unix.tcl +++ b/library/tkdnd_unix.tcl @@ -64,17 +64,21 @@ namespace eval xdnd { # ---------------------------------------------------------------------------- # Command xdnd::_HandleXdndEnter # ---------------------------------------------------------------------------- -proc xdnd::_HandleXdndEnter { path drag_source typelist } { +proc xdnd::_HandleXdndEnter { path drag_source typelist + { actionlist { copy move link ask private } } + { pressedkeys 1 } + { codelist {} } + } { variable _typelist; set _typelist $typelist - variable _pressedkeys; set _pressedkeys 1 + variable _pressedkeys; set _pressedkeys $pressedkeys variable _action; set _action refuse_drop variable _common_drag_source_types; set _common_drag_source_types {} variable _common_drop_target_types; set _common_drop_target_types {} variable _actionlist variable _drag_source; set _drag_source $drag_source variable _drop_target; set _drop_target {} - variable _actionlist; set _actionlist \ - {copy move link ask private} + variable _actionlist; set _actionlist $actionlist + variable _codelist set _codelist $codelist variable _last_mouse_root_x; set _last_mouse_root_x 0 variable _last_mouse_root_y; set _last_mouse_root_y 0 @@ -140,7 +144,6 @@ proc xdnd::_HandleXdndPosition { drop_target rootX rootY {drag_source {}} } { # debug "\t<<DropLeave>> on $_drop_target" set cmd [bind $_drop_target <<DropLeave>>] if {[string length $cmd]} { - set _codelist $_typelist set cmd [string map [list %W $_drop_target %X $rootX %Y $rootY \ %CST \{$_common_drag_source_types\} \ %CTT \{$_common_drop_target_types\} \ @@ -168,7 +171,6 @@ proc xdnd::_HandleXdndPosition { drop_target rootX rootY {drag_source {}} } { set cmd [bind $drop_target <<DropEnter>>] if {[string length $cmd]} { focus $drop_target - set _codelist $_typelist set cmd [string map [list %W $drop_target %X $rootX %Y $rootY \ %CST \{$_common_drag_source_types\} \ %CTT \{$_common_drop_target_types\} \ @@ -199,7 +201,6 @@ proc xdnd::_HandleXdndPosition { drop_target rootX rootY {drag_source {}} } { ## Drop target supports at least one type. Send a <<DropPosition>>. set cmd [bind $drop_target <<DropPosition>>] if {[string length $cmd]} { - set _codelist $_typelist set cmd [string map [list %W $drop_target %X $rootX %Y $rootY \ %CST \{$_common_drag_source_types\} \ %CTT \{$_common_drop_target_types\} \ @@ -227,7 +228,7 @@ proc xdnd::_HandleXdndPosition { drop_target rootX rootY {drag_source {}} } { # ---------------------------------------------------------------------------- # Command xdnd::_HandleXdndLeave # ---------------------------------------------------------------------------- -proc xdnd::_HandleXdndLeave { } { +proc xdnd::_HandleXdndLeave { } { variable _types variable _typelist variable _actionlist @@ -244,7 +245,6 @@ proc xdnd::_HandleXdndLeave { } { if {[info exists _drop_target] && [string length $_drop_target]} { set cmd [bind $_drop_target <<DropLeave>>] if {[string length $cmd]} { - set _codelist $_typelist set cmd [string map [list %W $_drop_target \ %X $_last_mouse_root_x %Y $_last_mouse_root_y \ %CST \{$_common_drag_source_types\} \ @@ -302,7 +302,6 @@ proc xdnd::_HandleXdndDrop { time } { set type [_platform_independent_type $type] set cmd [bind $_drop_target <<Drop:$type>>] if {[string length $cmd]} { - set _codelist $_typelist set cmd [string map [list %W $_drop_target %X $rootX %Y $rootY \ %CST \{$_common_drag_source_types\} \ %CTT \{$_common_drop_target_types\} \ @@ -326,7 +325,6 @@ proc xdnd::_HandleXdndDrop { time } { } set cmd [bind $_drop_target <<Drop>>] if {[string length $cmd]} { - set _codelist $_typelist set cmd [string map [list %W $_drop_target %X $rootX %Y $rootY \ %CST \{$_common_drag_source_types\} \ %CTT \{$_common_drop_target_types\} \ diff --git a/library/tkdnd_windows.tcl b/library/tkdnd_windows.tcl index 312d08e..6475179 100644 --- a/library/tkdnd_windows.tcl +++ b/library/tkdnd_windows.tcl @@ -37,370 +37,119 @@ # namespace eval olednd { - variable _types {} - variable _typelist {} - variable _codelist {} - variable _actionlist {} - variable _pressedkeys {} - variable _action {} - variable _common_drag_source_types {} - variable _common_drop_target_types {} - variable _unhandled_types {} - - variable _last_mouse_root_x 0 - variable _last_mouse_root_y 0 proc initialise { } { + ## Mapping from platform types to TkDND types... + ::tkdnd::generic::initialise_platform_to_tkdnd_types [list \ + CF_UNICODETEXT DND_Text \ + CF_TEXT DND_Text \ + CF_HDROP DND_Files \ + FileGroupDescriptor DND_Files \ + FileGroupDescriptorW DND_Files \ + CF_HTML DND_HTML \ + {HTML Format} DND_HTML \ + CF_RTF DND_RTF \ + CF_RTFTEXT DND_RTF \ + {Rich Text Format} DND_RTF \ + ] + + ## Mapping from TkDND types to platform types... + ::tkdnd::generic::initialise_tkdnd_to_platform_types [list \ + DND_Text {CF_UNICODETEXT CF_TEXT} \ + DND_Files {CF_HDROP} \ + DND_HTML {CF_HTML {HTML Format}} \ + DND_RTF {CF_RTF CF_RTFTEXT {Rich Text Format}} \ + ] };# initialise + };# namespace olednd # ---------------------------------------------------------------------------- -# Command olednd::_HandleDragEnter +# Command olednd::HandleDragEnter # ---------------------------------------------------------------------------- -proc olednd::_HandleDragEnter { drop_target typelist actionlist pressedkeys - rootX rootY codelist } { - variable _typelist; set _typelist $typelist - variable _codelist; set _codelist $codelist - variable _actionlist; set _actionlist $actionlist - variable _pressedkeys; set _pressedkeys $pressedkeys - variable _action; set _action refuse_drop - variable _common_drag_source_types; set _common_drag_source_types {} - variable _common_drop_target_types; set _common_drop_target_types {} - - variable _last_mouse_root_x; set _last_mouse_root_x $rootX - variable _last_mouse_root_y; set _last_mouse_root_y $rootY - - # puts "olednd::_HandleDragEnter: drop_target=$drop_target,\ - # typelist=$typelist, actionlist=$actionlist,\ - # pressedkeys=$pressedkeys, rootX=$rootX, rootY=$rootY" +proc olednd::HandleDragEnter { drop_target typelist actionlist pressedkeys + rootX rootY codelist } { focus $drop_target - - ## Does the new drop target support any of our new types? - variable _types; set _types [bind $drop_target <<DropTargetTypes>>] - if {[llength $_types]} { - ## Examine the drop target types, to find at least one match with the drag - ## source types... - set supported_types [_supported_types $_typelist] - foreach type $_types { - foreach matched [lsearch -glob -all -inline $supported_types $type] { - ## Drop target supports this type. - lappend common_drag_source_types $matched - lappend common_drop_target_types $type - } - } - } - - if {[info exists common_drag_source_types]} { - set _common_drag_source_types $common_drag_source_types - set _common_drop_target_types $common_drop_target_types - ## Drop target supports at least one type. Send a <<DropEnter>>. - set cmd [bind $drop_target <<DropEnter>>] - if {[string length $cmd]} { - set cmd [string map [list %W $drop_target %X $rootX %Y $rootY \ - %CST \{$_common_drag_source_types\} \ - %CTT \{$_common_drop_target_types\} \ - %CPT \{[lindex [_platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ - %ST \{$_typelist\} %TT \{$_types\} \ - %A $_action %a \{$_actionlist\} \ - %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ - %D \{\} %e <<DropEnter>> \ - %L \{$_typelist\} %% % \ - %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ - %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ - ] $cmd] - set _action [uplevel \#0 $cmd] - } - } + ::tkdnd::generic::HandleEnter $drop_target 0 $typelist \ + $codelist $actionlist $pressedkeys + set action [::tkdnd::generic::HandlePosition $drop_target {} \ + $pressedkeys $rootX $rootY] if {$::tkdnd::_auto_update} {update} - # Return values: copy, move, link, ask, private, refuse_drop, default - switch -exact -- $_action { - copy - move - link - ask - private - refuse_drop - default {} - default {set _action copy} - } - return $_action -};# olednd::_HandleDragEnter + return $action +};# olednd::HandleDragEnter # ---------------------------------------------------------------------------- -# Command olednd::_HandleDragOver +# Command olednd::HandleDragOver # ---------------------------------------------------------------------------- -proc olednd::_HandleDragOver { drop_target pressedkeys rootX rootY } { - variable _types - variable _typelist - variable _codelist - variable _actionlist - variable _pressedkeys - variable _action - variable _common_drag_source_types - variable _common_drop_target_types - - variable _last_mouse_root_x; set _last_mouse_root_x $rootX - variable _last_mouse_root_y; set _last_mouse_root_y $rootY - - # puts "olednd::_HandleDragOver: drop_target=$drop_target,\ - # pressedkeys=$pressedkeys, rootX=$rootX, rootY=$rootY" - - if {![llength $_common_drag_source_types]} {return refuse_drop} - set _pressedkeys $pressedkeys - set cmd [bind $drop_target <<DropPosition>>] - if {[string length $cmd]} { - set cmd [string map [list %W $drop_target %X $rootX %Y $rootY \ - %CST \{$_common_drag_source_types\} \ - %CTT \{$_common_drop_target_types\} \ - %CPT \{[lindex [_platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ - %ST \{$_typelist\} %TT \{$_types\} \ - %A $_action %a \{$_actionlist\} \ - %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ - %D \{\} %e <<DropPosition>> \ - %L \{$_typelist\} %% % \ - %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ - %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ - ] $cmd] - set _action [uplevel \#0 $cmd] - } +proc olednd::HandleDragOver { drop_target pressedkeys rootX rootY } { + set action [::tkdnd::generic::HandlePosition $drop_target {} \ + $pressedkeys $rootX $rootY] if {$::tkdnd::_auto_update} {update} - # Return values: copy, move, link, ask, private, refuse_drop, default - switch -exact -- $_action { - copy - move - link - ask - private - refuse_drop - default {} - default {set _action copy} - } - return $_action -};# olednd::_HandleDragOver + return $action +};# olednd::HandleDragOver # ---------------------------------------------------------------------------- -# Command olednd::_HandleDragLeave +# Command olednd::HandleDragLeave # ---------------------------------------------------------------------------- -proc olednd::_HandleDragLeave { drop_target } { - variable _types - variable _typelist - variable _codelist - variable _actionlist - variable _pressedkeys - variable _action - variable _common_drag_source_types - variable _common_drop_target_types - variable _last_mouse_root_x - variable _last_mouse_root_y - - if {![llength $_common_drag_source_types]} {return} - - set cmd [bind $drop_target <<DropLeave>>] - if {[string length $cmd]} { - set cmd [string map [list %W $drop_target \ - %X $_last_mouse_root_x %Y $_last_mouse_root_y \ - %CST \{$_common_drag_source_types\} \ - %CTT \{$_common_drop_target_types\} \ - %CPT \{[lindex [_platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ - %ST \{$_typelist\} %TT \{$_types\} \ - %A \{$_action\} %a \{$_actionlist\} \ - %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ - %D \{\} %e <<DropLeave>> \ - %L \{$_typelist\} %% % \ - %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ - %u \{$_codelist\} %C \{[lindex $_codelist 0]\} \ - ] $cmd] - uplevel \#0 $cmd - } +proc olednd::HandleDragLeave { drop_target } { + ::tkdnd::generic::HandleLeave if {$::tkdnd::_auto_update} {update} - foreach var {_types _typelist _actionlist _pressedkeys _action - _common_drag_source_types _common_drop_target_types} { - set $var {} - } -};# olednd::_HandleDragLeave +};# olednd::HandleDragLeave # ---------------------------------------------------------------------------- -# Command olednd::_HandleXdndDrop +# Command olednd::HandleXdndDrop # ---------------------------------------------------------------------------- -proc olednd::_HandleDrop { drop_target pressedkeys rootX rootY _type data } { - variable _types - variable _typelist - variable _codelist - variable _actionlist - variable _pressedkeys - variable _action - variable _common_drag_source_types - variable _common_drop_target_types - set data [_normalise_data $_type $data] - # puts "olednd::_HandleDrop: drop_target=$drop_target,\ - # pressedkeys=$pressedkeys, rootX=$rootX, rootY=$rootY,\ - # data=\"$data\"" - - if {![llength $_common_drag_source_types]} {return refuse_drop} - set _pressedkeys $pressedkeys - ## Try to select the most specific <<Drop>> event. - foreach type [concat $_common_drag_source_types $_common_drop_target_types] { - set type [lindex [_platform_independent_type $type] 0] - set cmd [bind $drop_target <<Drop:$type>>] - if {[string length $cmd]} { - set cmd [string map [list %W $drop_target %X $rootX %Y $rootY \ - %CST \{$_common_drag_source_types\} \ - %CTT \{$_common_drop_target_types\} \ - %CPT \{[lindex [_platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ - %ST \{$_typelist\} %TT \{$_types\} \ - %A $_action %a \{$_actionlist\} \ - %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ - %D [list $data] %e <<Drop:$type>> \ - %L \{$_typelist\} %% % \ - %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ - %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ - ] $cmd] - set _action [uplevel \#0 $cmd] - # Return values: copy, move, link, ask, private, refuse_drop - switch -exact -- $_action { - copy - move - link - ask - private - refuse_drop - default {} - default {set _action copy} - } - if {$::tkdnd::_auto_update} {update} - return $_action - } - } - set cmd [bind $drop_target <<Drop>>] - if {[string length $cmd]} { - set cmd [string map [list %W $drop_target %X $rootX %Y $rootY \ - %CST \{$_common_drag_source_types\} \ - %CTT \{$_common_drop_target_types\} \ - %CPT \{[lindex [_platform_independent_type [lindex $_common_drag_source_types 0]] 0]\} \ - %ST \{$_typelist\} %TT \{$_types\} \ - %A $_action %a \{$_actionlist\} \ - %b \{$_pressedkeys\} %m \{$_pressedkeys\} \ - %D [list $data] %e <<Drop>> \ - %L \{$_typelist\} %% % \ - %t \{$_typelist\} %T \{[lindex $_common_drag_source_types 0]\} \ - %c \{$_codelist\} %C \{[lindex $_codelist 0]\} \ - ] $cmd] - set _action [uplevel \#0 $cmd] - } +proc olednd::HandleDrop { drop_target pressedkeys rootX rootY type data } { + ::tkdnd::generic::SetDroppedData [normalise_data $type $data] + set action [::tkdnd::generic::HandleDrop $drop_target {} \ + $pressedkeys $rootX $rootY 0] if {$::tkdnd::_auto_update} {update} - # Return values: copy, move, link, ask, private, refuse_drop - switch -exact -- $_action { - copy - move - link - ask - private - refuse_drop - default {} - default {set _action copy} - } - return $_action -};# olednd::_HandleXdndDrop + return $action +};# olednd::HandleXdndDrop # ---------------------------------------------------------------------------- # Command olednd::_GetDropTypes # ---------------------------------------------------------------------------- -proc olednd::_GetDropTypes { drop_target } { - variable _common_drag_source_types - return $_common_drag_source_types -};# olednd::_GetDropTypes +proc olednd::GetDropTypes { drop_target } { + ::tkdnd::generic::GetDragSourceCommonTypes +};# olednd::GetDropTypes # ---------------------------------------------------------------------------- -# Command olednd::_GetDroppedData +# Command olednd::platform_specific_types # ---------------------------------------------------------------------------- -proc olednd::_GetDroppedData { } { - variable _drop_target - return [selection get -displayof $_drop_target \ - -selection XdndSelection -type STRING] -};# olednd::_GetDroppedData +proc olednd::platform_specific_types { types } { + ::tkdnd::generic::platform_specific_types $types +}; # olednd::platform_specific_types # ---------------------------------------------------------------------------- -# Command olednd::_GetDragSource +# Command olednd::platform_specific_type # ---------------------------------------------------------------------------- -proc olednd::_GetDragSource { } { - variable _drag_source - return $_drag_source -};# olednd::_GetDragSource +proc olednd::platform_specific_type { type } { + ::tkdnd::generic::platform_specific_type $type +}; # olednd::platform_specific_type # ---------------------------------------------------------------------------- -# Command olednd::_GetDropTarget +# Command tkdnd::platform_independent_types # ---------------------------------------------------------------------------- -proc olednd::_GetDropTarget { } { - variable _drop_target - return [winfo id $_drop_target] -};# olednd::_GetDropTarget +proc ::tkdnd::platform_independent_types { types } { + ::tkdnd::generic::platform_independent_types $types +}; # tkdnd::platform_independent_types # ---------------------------------------------------------------------------- -# Command olednd::_supported_types +# Command olednd::platform_independent_type # ---------------------------------------------------------------------------- -proc olednd::_supported_types { types } { - set new_types {} - foreach type $types { - if {[_supported_type $type]} {lappend new_types $type} - } - return $new_types -}; # olednd::_supported_types - -# ---------------------------------------------------------------------------- -# Command olednd::_platform_specific_types -# ---------------------------------------------------------------------------- -proc olednd::_platform_specific_types { types } { - set new_types {} - foreach type $types { - set new_types [concat $new_types [_platform_specific_type $type]] - } - return $new_types -}; # olednd::_platform_specific_types +proc olednd::platform_independent_type { type } { + ::tkdnd::generic::platform_independent_type $type +}; # olednd::platform_independent_type # ---------------------------------------------------------------------------- -# Command olednd::_platform_independent_types +# Command olednd::normalise_data # ---------------------------------------------------------------------------- -proc olednd::_platform_independent_types { types } { - set new_types {} - foreach type $types { - set new_types [concat $new_types [_platform_independent_type $type]] - } - return $new_types -}; # olednd::_platform_independent_types - -# ---------------------------------------------------------------------------- -# Command olednd::_normalise_data -# ---------------------------------------------------------------------------- -proc olednd::_normalise_data { type data } { - switch [lindex [_platform_independent_type $type] 0] { +proc olednd::normalise_data { type data } { + switch [lindex [::tkdnd::generic::platform_independent_type $type] 0] { DND_Text {return $data} DND_Files {return $data} DND_HTML {return [encoding convertfrom utf-8 $data]} default {return $data} } -}; # olednd::_normalise_data - -# ---------------------------------------------------------------------------- -# Command olednd::_platform_specific_type -# ---------------------------------------------------------------------------- -proc olednd::_platform_specific_type { type } { - switch $type { - DND_Text {return [list CF_UNICODETEXT CF_TEXT]} - DND_Files {return [list CF_HDROP]} - DND_HTML {return [list "HTML Format"]} - DND_RTF {return [list "Rich Text Format"]} - default { - # variable _unhandled_types - # if {[lsearch -exact $_unhandled_types $type] == -1} { - # lappend _unhandled_types $type - # } - return [list $type]} - } -}; # olednd::_platform_specific_type - -# ---------------------------------------------------------------------------- -# Command olednd::_platform_independent_type -# ---------------------------------------------------------------------------- -proc olednd::_platform_independent_type { type } { - switch $type { - CF_UNICODETEXT - CF_TEXT {return [list DND_Text]} - CF_HDROP {return [list DND_Files]} - CF_HTML - "HTML Format" {return [list DND_HTML]} - CF_RTF - CF_RTFTEXT - "Rich Text Format" {return [list DND_RTF]} - default {return [list $type]} - } -}; # olednd::_platform_independent_type - -# ---------------------------------------------------------------------------- -# Command olednd::_supported_type -# ---------------------------------------------------------------------------- -proc olednd::_supported_type { type } { - # return 1; - switch $type { - CF_UNICODETEXT - CF_TEXT - - FileGroupDescriptor - FileGroupDescriptorW - - CF_HTML - CF_RTF - CF_RTFTEXT - - "HTML Format" - "Rich Text Format" - - CF_HDROP {return 1} - } - # Is the type in our known, but unhandled types? - variable _unhandled_types - if {[lsearch -exact $_unhandled_types $type] != -1} {return 1} - return 0 -}; # olednd::_supported_type +}; # olednd::normalise_data diff --git a/win/OleDND.h b/win/OleDND.h index e20382f..4c968c8 100644 --- a/win/OleDND.h +++ b/win/OleDND.h @@ -471,7 +471,9 @@ class TkDND_DropTarget: public IDropTarget { TCHAR szTempStr[MAX_PATH+2]; Tcl_Obj *typelist, *actionlist, *codelist; +#ifdef DND_USE_ACTIVE bool drop_active; +#endif const TCHAR * FormatName(UINT cfFormat) { for (int i = 0; ClipboardFormatBook[i].name != 0; i++) { @@ -484,11 +486,17 @@ class TkDND_DropTarget: public IDropTarget { public: TkDND_DropTarget(Tcl_Interp *_interp, Tk_Window _tkwin) : - interp(_interp), tkwin(_tkwin), m_lRefCount(1), drop_active(false), + interp(_interp), tkwin(_tkwin), m_lRefCount(1), +#ifdef DND_USE_ACTIVE + drop_active(false), +#endif typelist(NULL), actionlist(NULL), codelist(NULL) { }; /* TkDND_DropTarget */ ~TkDND_DropTarget(void) { + if (typelist != NULL) Tcl_DecrRefCount(typelist); + if (actionlist != NULL) Tcl_DecrRefCount(actionlist); + if (codelist != NULL) Tcl_DecrRefCount(codelist); }; /* ~TkDND_DropTarget */ /* IUnknown interface members */ @@ -553,11 +561,13 @@ class TkDND_DropTarget: public IDropTarget { ActionCopy, ActionMove, ActionLink, ActionAsk, ActionPrivate, refuse_drop, ActionDefault }; +#ifdef DND_USE_ACTIVE if (drop_active) { return DROPEFFECT_COPY; } +#endif - objv[0] = Tcl_NewStringObj("tkdnd::olednd::_HandleDragEnter", -1); + objv[0] = Tcl_NewStringObj("::tkdnd::olednd::HandleDragEnter", -1); objv[1] = Tcl_NewStringObj(Tk_PathName(tkwin), -1); objv[2] = typelist; objv[3] = actionlist; @@ -583,7 +593,9 @@ class TkDND_DropTarget: public IDropTarget { case ActionDefault: effect = DROPEFFECT_COPY; break; case refuse_drop: effect = DROPEFFECT_NONE; /* Refuse drop. */ } +#ifdef DND_USE_ACTIVE drop_active = true; +#endif return effect; }; /* SendDragEnter */ @@ -600,10 +612,12 @@ class TkDND_DropTarget: public IDropTarget { ActionCopy, ActionMove, ActionLink, ActionAsk, ActionPrivate, refuse_drop, ActionDefault }; +#ifdef DND_USE_ACTIVE if (!drop_active) { return effect; } - objv[0] = Tcl_NewStringObj("tkdnd::olednd::_HandleDragOver", -1); +#endif + objv[0] = Tcl_NewStringObj("::tkdnd::olednd::HandleDragOver", -1); objv[1] = Tcl_NewStringObj(Tk_PathName(tkwin), -1); objv[2] = GetPressedKeys(grfKeyState); objv[3] = Tcl_NewLongObj(pt.x); @@ -642,11 +656,13 @@ class TkDND_DropTarget: public IDropTarget { ActionCopy, ActionMove, ActionLink, ActionAsk, ActionPrivate, refuse_drop, ActionDefault }; +#ifdef DND_USE_ACTIVE if (!drop_active) { return effect; } drop_active = false; - objv[0] = Tcl_NewStringObj("tkdnd::olednd::_HandleDrop", -1); +#endif + objv[0] = Tcl_NewStringObj("::tkdnd::olednd::HandleDrop", -1); objv[1] = Tcl_NewStringObj(Tk_PathName(tkwin), -1); objv[2] = GetPressedKeys(grfKeyState); objv[3] = Tcl_NewLongObj(pt.x); @@ -654,13 +670,14 @@ class TkDND_DropTarget: public IDropTarget { objv[5] = type; objv[6] = data; TkDND_Status_Eval(7); + index = (enum dropactions) refuse_drop; if (status == TCL_OK) { /* Get the returned action... */ result = Tcl_GetObjResult(interp); Tcl_IncrRefCount(result); status = Tcl_GetIndexFromObj(interp, result, (const char **)DropActions, "dropactions", 0, &index); Tcl_DecrRefCount(result); - if (status != TCL_OK) index = (enum dropactions) ActionDefault; + if (status != TCL_OK) index = (enum dropactions) refuse_drop; } switch ((enum dropactions) index) { case ActionCopy: effect = DROPEFFECT_COPY; break; @@ -677,12 +694,16 @@ class TkDND_DropTarget: public IDropTarget { void SendDragLeave(void) { Tcl_Obj *objv[2]; int i; +#ifdef DND_USE_ACTIVE if (drop_active) { - objv[0] = Tcl_NewStringObj("tkdnd::olednd::_HandleDragLeave", -1); +#endif + objv[0] = Tcl_NewStringObj("::tkdnd::olednd::HandleDragLeave", -1); objv[1] = Tcl_NewStringObj(Tk_PathName(tkwin), -1); TkDND_Eval(2); +#ifdef DND_USE_ACTIVE } drop_active = false; +#endif }; /* SendDragLeave */ /* @@ -716,7 +737,9 @@ class TkDND_DropTarget: public IDropTarget { typelist = Tcl_NewListObj(0, NULL); Tcl_IncrRefCount(typelist); actionlist = Tcl_NewListObj(0, NULL); Tcl_IncrRefCount(actionlist); codelist = Tcl_NewListObj(0, NULL); Tcl_IncrRefCount(codelist); +#ifdef DND_USE_ACTIVE drop_active = false; +#endif /* * Get the types supported by the drag source. @@ -795,10 +818,12 @@ class TkDND_DropTarget: public IDropTarget { TYPE_FILEGROUPDESCRIPTORW, TYPE_FILEGROUPDESCRIPTOR }; *pdwEffect = DROPEFFECT_NONE; +#ifdef DND_USE_ACTIVE if (!drop_active) return S_OK; drop_active = false; +#endif // Get the drop format list. - objv[0] = Tcl_NewStringObj("tkdnd::olednd::_GetDropTypes", -1); + objv[0] = Tcl_NewStringObj("::tkdnd::olednd::GetDropTypes", -1); objv[1] = Tcl_NewStringObj(Tk_PathName(tkwin), -1); TkDND_Status_Eval(2); if (status != TCL_OK) return S_OK; result = Tcl_GetObjResult(interp); Tcl_IncrRefCount(result); @@ -817,7 +842,7 @@ class TkDND_DropTarget: public IDropTarget { case TYPE_CF_RTF: case TYPE_CF_RTFTEXT: case TYPE_CF_RICHTEXTFORMAT: - data = GetData_Bytearray(pDataObject, type); + data = GetData_Bytearray(pDataObject, typeObj[type_index]); break; case TYPE_CF_TEXT: data = GetData_CF_TEXT(pDataObject); break; @@ -858,8 +883,9 @@ class TkDND_DropTarget: public IDropTarget { // We are ready to pass the info to the Tcl level, and get the desired // action. + Tcl_IncrRefCount(data); *pdwEffect = SendDrop(pt, grfKeyState, type, data); - Tcl_DecrRefCount(type); + Tcl_DecrRefCount(type); Tcl_IncrRefCount(data); return S_OK; }; /* Drop */ diff --git a/win/TkDND_OleDND.cpp b/win/TkDND_OleDND.cpp index 7da6a57..2188bc1 100644 --- a/win/TkDND_OleDND.cpp +++ b/win/TkDND_OleDND.cpp @@ -1,6 +1,6 @@ /*
* TkDND_OleDND.h -- Tk OleDND Drag'n'Drop Protocol Implementation
- *
+ *
* This file implements the unix portion of the drag&drop mechanism
* for the Tk toolkit. The protocol in use under windows is the
* OleDND protocol.
@@ -23,13 +23,13 @@ * and need not follow the licensing terms described here, provided that
* the new terms are clearly indicated on the first page of each file where
* they apply.
- *
+ *
* IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
* FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
* DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
- *
+ *
* THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE
@@ -48,7 +48,7 @@ int TkDND_RegisterDragDropObjCmd(ClientData clientData, Tcl_Interp *interp, TkDND_DropTarget *pDropTarget;
Tk_Window tkwin;
HRESULT hret;
-
+
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "path");
return TCL_ERROR;
@@ -94,7 +94,7 @@ int TkDND_RevokeDragDropObjCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
Tk_Window tkwin;
HRESULT hret;
-
+
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "path");
return TCL_ERROR;
@@ -114,7 +114,7 @@ int TkDND_RevokeDragDropObjCmd(ClientData clientData, Tcl_Interp *interp, "\" has never been registered as a drop target", (char *) NULL);
return TCL_ERROR;
}
-
+
return TCL_OK;
}; /* TkDND_RevokeDragDropObjCmd */
@@ -284,7 +284,7 @@ int TkDND_DoDragDropObjCmd(ClientData clientData, Tcl_Interp *interp, size = 0;
for (j = 0; j < file_nu; ++j) {
Tcl_DStringInit(&ds);
- native_name = Tcl_TranslateFileName(NULL,
+ native_name = Tcl_TranslateFileName(NULL,
Tcl_GetString(File[j]), &ds);
if (native_name == NULL) {
Tcl_DStringFree(&ds);
@@ -300,7 +300,7 @@ int TkDND_DoDragDropObjCmd(ClientData clientData, Tcl_Interp *interp, buffer_size = sizeof(wchar_t) * (size+1);
m_pfmtetc[i].cfFormat = CF_HDROP;
- m_pstgmed[i].hGlobal = GlobalAlloc(GHND,
+ m_pstgmed[i].hGlobal = GlobalAlloc(GHND,
(DWORD) (sizeof(DROPFILES) + buffer_size));
if (m_pstgmed[i].hGlobal) {
TCHAR *CurPosition;
@@ -309,7 +309,7 @@ int TkDND_DoDragDropObjCmd(ClientData clientData, Tcl_Interp *interp, pDropFiles->pFiles = sizeof(DROPFILES);
// File contains wide characters?
pDropFiles->fWide = TRUE;
- CurPosition = (TCHAR *) (LPBYTE(pDropFiles) + sizeof(DROPFILES));
+ CurPosition = (TCHAR *) (LPBYTE(pDropFiles) + sizeof(DROPFILES));
Tcl_ListObjGetElements(NULL, native_files_obj, &file_nu, &File);
for (j = 0; j < file_nu; j++) {
TCHAR *pszFileName = (TCHAR *)
@@ -343,13 +343,13 @@ int TkDND_DoDragDropObjCmd(ClientData clientData, Tcl_Interp *interp, break;
}
}; /* for (i = 0; i < type_nu; i++) */
-
+
pDataObject = new TkDND_DataObject(m_pfmtetc, m_pstgmed, type_nu);
if (pDataObject == NULL) {
Tcl_SetResult(interp, "unable to create OLE Data object", TCL_STATIC);
return TCL_ERROR;
}
-
+
pDropSource = new TkDND_DropSource(button);
if (pDropSource == NULL) {
pDataObject->Release();
@@ -405,7 +405,7 @@ int DLLEXPORT Tkdnd_Init(Tcl_Interp *interp) { HRESULT hret;
if (
-#ifdef USE_TCL_STUBS
+#ifdef USE_TCL_STUBS
Tcl_InitStubs(interp, "8.3", 0)
#else
Tcl_PkgRequire(interp, "Tcl", "8.3", 0)
@@ -436,7 +436,7 @@ int DLLEXPORT Tkdnd_Init(Tcl_Interp *interp) { * Initialise OLE.
*/
hret = OleInitialize(NULL);
-
+
/*
* If OleInitialize returns S_FALSE, OLE has already been initialized
*/
|
