summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpetasisg@gmail.com <petasisg@gmail.com@f3661a36-4baa-549a-d6c7-40e0ffef350e>2014-09-21 13:24:56 (GMT)
committerpetasisg@gmail.com <petasisg@gmail.com@f3661a36-4baa-549a-d6c7-40e0ffef350e>2014-09-21 13:24:56 (GMT)
commit4dda192dd17aa0819651eaaf5fa59b2bc5dcb678 (patch)
tree1e997e273a39014f8de34a685f1c0e47cb819d30
parentb6dbf97147dbe57d78a5f8d19d64427437ae22a8 (diff)
downloadtkdnd-4dda192dd17aa0819651eaaf5fa59b2bc5dcb678.zip
tkdnd-4dda192dd17aa0819651eaaf5fa59b2bc5dcb678.tar.gz
tkdnd-4dda192dd17aa0819651eaaf5fa59b2bc5dcb678.tar.bz2
-rw-r--r--CMakeLists.txt1
-rw-r--r--Changelog21
-rw-r--r--configure.in2
-rw-r--r--demos/basic.tcl4
-rw-r--r--demos/dndSpy.tcl14
-rw-r--r--demos/simple_target.tcl4
-rw-r--r--library/tkdnd.tcl56
-rw-r--r--library/tkdnd_generic.tcl490
-rw-r--r--library/tkdnd_macosx.tcl13
-rw-r--r--library/tkdnd_unix.tcl20
-rw-r--r--library/tkdnd_windows.tcl393
-rw-r--r--win/OleDND.h44
-rw-r--r--win/TkDND_OleDND.cpp26
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
diff --git a/Changelog b/Changelog
index 8413254..27aa1a6 100644
--- a/Changelog
+++ b/Changelog
@@ -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
*/