I tend to always use system commands to open files (or folders)
# OSX vs WINDOWS
PLATFORM_IS_OSX = ((Object::RUBY_PLATFORM =~ /darwin/i) ? true : false).freeze()
PLATFORM_IS_WINDOWS = (!PLATFORM_IS_OSX).freeze()
# get folder path and do repl
folder_path = "path/to/the/folder"
folder_path = folder_path.gsub("/", "\\\\" if PLATFORM_IS_WINDOWS
# construct the command to open Explorer on Windows or Finder on OsX
command = PLATFORM_IS_WINDOWS ? "start \"\" \"#{folder_path}\"" : "open \"#{folder_path}\""
Could this fix for cross-platform inconsistencies with URLs have introduced a platform difference for local paths? I’ve used openURL quite a few times to open local documents.
The URL specs say either %20 or + may substitute for space.
Edit: After some more research, it seems that there has been confusion about this for some time. The established practice when encoding the request part (after the ?) in an HTML GET or POST request was to use +. So, using + instead of %20 is still generally allowed in that context. But for the path part of the URL it seems to be preferred to use %20 for consistency with how other illegal characters are encoded.
The change in behavior in UI.openURL jumped out on Mac because the normal path for extension files is
The “PLATFORM_IS” approach is extremely problematic to any developer who does have both platforms to test. You make the change, assemble all the code, upload it to the warehouse, thousands of users download it, then you see typo that you couldn’t test.
Opening a 30 page user manual in the default browser is much better than using HTML dialog. The help file can contain links to other websites, and the user has browser support for search within the document.
Before Trimble allowed such a change, they should have performed a global search for OpenURL in all ruby code in the warehouse (I expect that they keep the unencrypted ruby) and send a red alert email to every developer. Another indication that adult supervision is lacking.
Why?
Just create a method that does this good for once and for all and just call that method from everywhere in your code…
# somewhere in constants.rb f.e.
# OSX vs WINDOWS
PLATFORM_IS_OSX = ((Object::RUBY_PLATFORM =~ /darwin/i) ? true : false).freeze()
PLATFORM_IS_WINDOWS = (!PLATFORM_IS_OSX).freeze()
# somewhere in utils.rb f.e.
def open_external(path)
# do replace on windows
path= path.gsub("/", "\\\\") if PLATFORM_IS_WINDOWS
# construct the command to open Explorer on Windows or Finder on OsX
command = PLATFORM_IS_WINDOWS ? "start \"\" \"#{path}\"" : "open \"#{path}\""
system(command)
end #def
# somewhere in your code
open_external("C:/users/") # this should work both for folders and files
It means being aware of the big picture. “Solutions” like yours are what the API is for.
It maybe it should have a method “OpenURLfromSU” well tested by Trimble on both platforms to do thus.
It should not have to be reinvented and propagated by every developer.
if you check the API or Julia’s link. you’ll see that SU does have a platform method…
Sketchup.platform == :platform_win
# or
Sketchup.platform == :platform_osx
and as you don’t even need a url to open a html file in a browser or any in Finder on a mac, you set yourself up for a fall…
help = File.join(File.dirname(__FILE__), 'myextensions', 'help.html')
if Sketchup.platform == :platform_win
UI.openURL("file:///#{help}")
else # use one of the incredibly common, standard Ruby methods
# all these work
`open "#{help}"`
# or
%x[ open "#{help}" ]
# or
system("open #{help.inspect}")
# there are even more variants, this opens any file type in Finder...
%x[ open -R #{help.inspect}]
end
there is no need to reinvent the wheel if carry out some ‘due diligence’ before publishing…
Never noticed it. Got added in 2014 it seems. The check I use has been stuck on top of my constants.rb file for ages I believe.
Will change my starter kit to use the sketchup specific method. Thanks.
It’s totally unnecessary to replace forward unix-like slashes with double backslashes on Windows. Windows NT has always AFAIK accepted pathnames with forward slashes. I usually do the opposite, replacing backslashes with forward slashes (there are some Sketchup module methods that return double backslashed pathnames on Windows, but shouldn’t have been written this way.) …
path = path.gsub(/(\\\\|\\)/,'/') if PLATFORM_IS_WIN
I think the main exception is registry hive paths.
RUBY_PLATFORM being a constant defined in Object, is global.
The class qualification is not necessary.
=~ does not return a boolean true || false so you use a tertiary IF, but instead it’s better (more elegant) to do the opposite and use !~ method which does directly return true || false so no tertiary IF is needed (ie., it’s faster.) Ex …
The Sketchup.platform method came out for SU2014 but for backward compatibility you can use a rescue clause when the Sketchup module doesn’t respond to a ::platform() call. IE …
Freezing / Constants are not really constant. Ie …
EDIT (ADD): Trying to freeze an immediate singleton object like true or false is a frivolous endeavor.
PLATFORM_IS_OSX = !PLATFORM_IS_WIN.freeze()
Then do this …
PLATFORM_IS_OSX = "I've been changed!"
You get a warning that the constant was previously set, but it is still reassigned to point at the new object (in this case a String.) The global = reference assignment function is an interpreter function, not a Ruby method, so it can reassign references that point at frozen objects so that they point at other objects (frozen or not.)
So to truly freeze your constants, you must wrap them within a nested mixin module, freeze that module, and then mixin (via include) this module wherever you need to access these constants.
module Author
module SomePlugin
module Constants
PLATFORM_IS_WIN =(
Sketchup.platform == :platform_win rescue RUBY_PLATFORM !~ /darwin/i
)
PLATFORM_IS_OSX = !PLATFORM_IS_WIN
end
Constants.freeze
include Constants
# Plugin module code here can access Constants.constants
end
end
Or perhaps the constants are in a separate file oustide the current plugin module. Ex …
# plugin_main.rb
require 'constants.rb'
module Author
module SomePlugin
include Author::Constants
# Plugin module code here can access Author::Constants.constants
end
end
What type of docs? Do you have an example of how you have launced documents? (and what type of documents?)
The Windows version never auto-encoded the given URL, and we’d never heard any questions and complains about that. Given that an Windows is 90% of our userbase we felt confident at the time wasn’t a big problem. We do understand though that changes are frustrating and try to keep things working whenever possible. In this case the encoding Mac performed had problems of it’s own in that it would encode important characters such as #.
That’s not particularly constructive Barry. Keep it civil - no need to get personal.
I’m using it to open external SketchUp files in my reference manger and I’ve worked on extensions using it for opening PDF manuals. I used it just the other day to open .layout files generated by the SketchUp Ruby Layout API. Not sure if I’ve used it more but those are the things I can remember on the top of my head.