Skip to content

Commit 549a2e7

Browse files
committed
Example: Add insertion of files from a file manager
This illustrates how several clipboard formats from other apps can be read and used.
1 parent ea3c203 commit 549a2e7

File tree

1 file changed

+79
-4
lines changed

1 file changed

+79
-4
lines changed

examples/iconlist.rb

Lines changed: 79 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require 'fox16'
2+
require 'uri'
23

34
include Fox
45

@@ -47,14 +48,23 @@ def initialize(app)
4748
iconlist.appendHeader("User", nil, 50)
4849
iconlist.appendHeader("Group", nil, 50)
4950

50-
big_folder = loadIcon("bigfolder.png")
51-
mini_folder = loadIcon("minifolder.png")
51+
@big_folder = loadIcon("bigfolder.png")
52+
@mini_folder = loadIcon("minifolder.png")
5253

53-
iconlist.appendItem("Really BIG and wide item to test\tDocument\t10000\tJune 13, 1999\tUser\tSoftware", big_folder, mini_folder)
54+
iconlist.appendItem("Really BIG and wide item to test\tDocument\t10000\tJune 13, 1999\tUser\tSoftware", @big_folder, @mini_folder)
5455
1.upto(400) do |i|
55-
iconlist.appendItem("Filename_#{i}\tDocument\t10000\tJune 13, 1999\tUser\tSoftware", big_folder, mini_folder)
56+
iconlist.appendItem("Filename_#{i}\tDocument\t10000\tJune 13, 1999\tUser\tSoftware", @big_folder, @mini_folder)
5657
end
5758
iconlist.currentItem = iconlist.numItems - 1
59+
@iconlist = iconlist
60+
61+
FXMenuPane.new(self) do |menuPane|
62+
paste_icon = loadIcon("paste.png")
63+
FXMenuCommand.new(menuPane, "&Insert from clipboard\tCtrl-V", paste_icon) do |mc|
64+
mc.connect(SEL_COMMAND) { insert_from_clipboard }
65+
end
66+
FXMenuTitle.new(menubar, "&Edit", nil, menuPane)
67+
end
5868

5969
# Arrange menu
6070
FXMenuPane.new(self) do |menuPane|
@@ -67,13 +77,78 @@ def initialize(app)
6777
end
6878
# Let's see a tooltip
6979
FXToolTip.new(getApp())
80+
81+
# Register the drag types for copy files from the clipboard
82+
@dragtype_urilist = app.registerDragType("text/uri-list")
83+
@dragtype_filename = app.registerDragType("FileNameW")
84+
@dragtype_filegroup = app.registerDragType("FileGroupDescriptorW")
85+
7086
end
7187

7288
# Overrides base class version
7389
def create
7490
super
7591
show(PLACEMENT_SCREEN)
7692
end
93+
94+
def get_clipboard_files
95+
# Show the avaliable clipboard formats:
96+
puts "Avaliable clipboard formats:"
97+
type_ids = inquireDNDTypes(FROM_CLIPBOARD)
98+
pp type_ids.map{|id| [id, app.getDragTypeName(id), getDNDData(FROM_CLIPBOARD, id)] }
99+
100+
# Process copied files with standard uri list (on Linux)
101+
paths = getDNDData(FROM_CLIPBOARD, @dragtype_urilist)
102+
if paths
103+
files = paths.each_line.map do |file|
104+
# file.chomp.sub(%r{^file://}, "")
105+
URI.decode_uri_component(URI(file.chomp).path)
106+
end
107+
return files
108+
end
109+
110+
# Process copied data from Windows Explorer
111+
# This works for files only, but not for directories.
112+
path = getDNDData(FROM_CLIPBOARD, @dragtype_filename)
113+
filesdata = getDNDData(FROM_CLIPBOARD, @dragtype_filegroup)
114+
if path && filesdata
115+
path = path.encode("UTF-8", "UTF-16LE").rstrip("\0")
116+
path = File.dirname(path)
117+
cnt, rest = filesdata.unpack("Ia*")
118+
files = cnt.times.map do
119+
# Unpack the FILEGROUPDESCRIPTORW struct
120+
# DWORD dwFlags;
121+
# CLSID clsid;
122+
# SIZEL sizel;
123+
# POINTL pointl;
124+
# DWORD dwFileAttributes;
125+
# FILETIME ftCreationTime;
126+
# FILETIME ftLastAccessTime;
127+
# FILETIME ftLastWriteTime;
128+
# DWORD nFileSizeHigh;
129+
# DWORD nFileSizeLow;
130+
# CHAR cFileName[MAX_PATH];
131+
dwFlags, clsid, sizel, pointl, dwFileAttributes,
132+
ftCreationTime, ftLastAccessTime, ftLastAccessTime,
133+
nFileSizeHigh, nFileSizeLow, cFileName, rest =
134+
rest.unpack("La16a8a8La8a8a8LLa520a*")
135+
fname = cFileName.encode("UTF-8", "UTF-16LE").rstrip("\0")
136+
File.join(path, fname)
137+
end
138+
return files
139+
end
140+
end
141+
142+
def insert_from_clipboard
143+
files = get_clipboard_files
144+
145+
files&.each do |file|
146+
ftype = File.ftype(file)
147+
fsize = File.size(file)
148+
mtime = File.mtime(file)
149+
@iconlist.prependItem([file, ftype, fsize, mtime].join("\t"), @big_folder, @mini_folder)
150+
end
151+
end
77152
end
78153

79154
if __FILE__ == $0

0 commit comments

Comments
 (0)