Is there a way to control clipboard from Sketchup ?
The idea is to exchange samll informations (strings mostly) from sketchup to other external software using copy and past.
For example, is there a way to call in ruby to export :
my_string.to_clipboard
OR to import :
my_string = From_clipboard()
You could use a HtmlDialog and both let the user manually copy the text from a field pr press a button to add it to the clipboard. This may also be better UX than silently writing to the clipboard in the background somehow.
@eneroth3 : You mean by using javascript ? I’m not good in this langage. But if you have any example, I can check this.
@sWilliams : It’s really interresting, I tried this library but it depends on ffi gem. What is the best process to “install” a gem in Sketchup’s Ruby ?
Drawback with that is that it’s not a great solution for an extension that’s distributed to other users. The Gem.install call blocks SU while installing with no feedback for noticeable time. And if other extensions tried the same they might rely on different versions which might not be compatible. I’d instead make use of what ships with the StdLib.
Looking closer at the Win32 API this might not be as easy as I originally thought…
If SetClipboardData succeeds, the system owns the object identified by the hMem parameter. The application may not write to or free the data once ownership has been transferred to the system, but it can lock and read from the data until the CloseClipboard function is called. (The memory must be unlocked before the Clipboard is closed.) If the hMem parameter identifies a memory object, the object must have been allocated using the function with the GMEM_MOVEABLE flag.
I’m not sure how to create a memory buffer using Fiddle (or FFI) for which I can then hand over ownership. Might have to do a Ruby C Extension…
First off, heed TT’s comment’s on ffi above. At some point you’ll want to recode this solution using fiddle; but that can come later. For a simple test of concept we can load the Clipboard gem into Sketchup and patch together a little application.
In the Sketchup Ruby Console enter
Gem.install 'ffi'
Gem.install 'clipboard', '= 1.0.6' # this older version will encode the strings correctly
For a test program, how about this:
require 'clipboard'
module Test
x = 'ABCDEFG'
Clipboard.copy(x)
y = Clipboard.paste
puts "The string was #{y}"
nil
end
Uninstalling these gems from Sketchup takes a slightly different route. Download the su_gem.rb from this forum post and paste the Ruby code in to the Ruby Console. https://forums.sketchup.com/t/rubygems-anyone-interested-in-using/61154/6
Then to display the info about the installed Gems enter:
SUGem.query “-d”
To uninstall the ffi and clipboard gems enter:
SUGem.uninstall “clipboard”
SUGem.uninstall “ffi”
SketchUp isn’t set up to install gems that need to be locally compiled. If you match the Ruby version in SketchUp you may be able to compile outside and then copy into the gems folder inside sketchup.
might need some escaping though for special characters.
Just remember… if it is something common, but there is no ruby api method for it, there probably is a system command for it.
@DanRathbun as a sidenote. In this case, I honestly do not like having to rely on Sketchup to tell me what platform I’m on… This is such a generic thing that it might also be added to a codebase that has nothing to do with SketchUp.
Reading from system commands is more difficult. In normal ipc (Inter-process communication - Wikipedia) that should not be to difficult, but there is something going wrong in SketchUp while trying to read from system commands.
There are ways to copy something to a temporary text file and then reading in that textfile.
On Mac it’s pbpaste I think. But it’s more complicated on Windows. I don’t think there is a universal distributed utility (out of the box from Microsoft) to read the clipboard.
This cross-platform Ruby API statement will mimic the user pressing CTRL+V …
def read_clipboard()
if Sketchup.platform == :platform_win
require "tempfile"
tempfile = Tempfile.new()
tempfile.close()
cmd = "powershell -command \"Get-Clipboard\" > \"#{tempfile.path}\""
system(cmd)
result = File.read(tempfile.path)
tempfile.unlink
return result
else
# can a maccy provide this?
end
end #def
But the problem when using system commands or backtick execute strings is they “flash open” a command window on embedded Ruby.
How about …
module ClipText
extend self
CLIPDIR ||= File.join(ENV['HOME'],'.clipboard')
Dir.mkdir(CLIPDIR) if !File.exist?(CLIPDIR)
def clear
copy ''
end
if Sketchup.platform == :platform_win
def copy(text)
`echo #{text} | clip.exe`
Dir.chdir(CLIPDIR) do
`echo #{text} > "clip.txt"`
end
end
def paste()
Dir.chdir(CLIPDIR) do
`powershell -command "Get-Clipboard" > "clip.txt"`
txt = File.read('clip.txt').chomp.rstrip
# Check if ClipBoard was cleared:
txt == 'ECHO is on.' ? '' : txt
end
end
else # Mac
def copy(text)
`echo "#{text}" | pbcopy`
Dir.chdir(CLIPDIR) do
`echo "#{text}" > "clip.txt"`
end
end
def paste()
`pbpaste`.chomp
end
end
end # module