how do you do simple Open, Close, read file, write files that are standard ASCII files (.txt) via the API. Example of ruby reading/ writing into a text file in the Plugins directory
thx in advance
how do you do simple Open, Close, read file, write files that are standard ASCII files (.txt) via the API. Example of ruby reading/ writing into a text file in the Plugins directory
thx in advance
(I moved this from Meta
to Developers > Ruby API
)
The SketchUp API doesn’t provide methods to read or write files - this is one by Ruby itself. So you need to supplement The Sketch API docs with the Ruby language docs: Class: File (Ruby 2.0.0)
To read and write ASCII files can be as simple as this:
# Read a file.
content = File.read(filename)
# Write a file.
File.write(filename, content)
However, for this part of your question:
I would recommend against writing to files in the Plugins folder. A couple of reasons:
Further more - don’t assume your extension is always installed in the Plugins folder. Some users install them to custom locations - for instance to share among versions etc.
I recommend that if you need to read a file from your extension’s support folder then you use relative paths. Use __dir__
to get the folder for the current RB file. (Or if you need to support Ruby 1.8 - File.dirname(__FILE__)
.
If you really need to find the actual Plugins folder then you use Sketchup.find_support_folder('Plugins')
. But due to the things I mentioned earlier here you really should not need this.
@sannerwind: What might not be apparent to newbies to Ruby, is that the File
class is a subclass, of the IO
class, and therefor inherits all the methods of it’s superclass(es.)
http://ruby-doc.org/core-2.0.0/IO.html
This is why you will not see read()
and write()
listed under the File
class methods. So you need to refer to both classes.
“Basic Input and Output”, from the ol’ “Pick Axe” Ruby book:
http://ruby-doc.com/docs/ProgrammingRuby/html/tut_io.html
Above gentlemen, thank you. Twas hard to believe SU did not add a few basic I/O or FILE classes/ methods, ruby IO references in their docs Hard to imagine a competent/ worthy system w/o some best and common I/O. Betcha they’re indexed/ hash access and virtual i/o extensions, methods which are in the bowels of their stickyness modules, which they should offer we peons. Re access to /plugins, usually, its not wise, but, depends on whatcha want to do, and why. there is in SU, importer/ classes and io methods.tantalizing to think there’s a centraliztion somewhere for console I/O, Puts, print… I want to see more SU users, so to have a better on-ramp makes good sense, and requires some pre-chewed I/O, file . thx again…
Hi guys, sorry for buggin here. Ive got this piece of code which i got from some one.
It check all open panels in SU and writes those to a txt file. The problem is it somehow doesnt write the list to the txt file
end
my_Toolbars.each do |tb|
# p SKETCHUP_CONSOLE = my_Toolbars.each
File.open(my_toolbar_list, ‘w’) { |f| f.write(tb) }
# File.write(my_toolbar_list, ‘w’) { |f| f.write(tb) }
end
i did got the list by printing it to the ruby console (# p SKETCHUP_CONSOLE = my_Toolbars.each)
Im working on mac and do see that the file is changed at a certain time but not is added.
hi, I finally saw you messages and PM’d you at SCF…
john
Well i got it fixed by changing a variable in the code… i replaced |tb| with my_toolsbars. I then wrights the correct code to the textfile need to get the tool panels back
end
my_Toolbars.each do |tb|
File.open(my_toolbar_list, ‘w’) { |f| f.write(my_Toolbars) }
end
The IO.write
and Kernel.puts
methods expect a String
object as an argument.
When this is not true, many Ruby methods will attempt to coerce the argument into a String
, by calling to_s()
or inspect()
upon the argument. If this is not successful, then Ruby will raise a TypeError
exception.
ruby_tbs = []
require "objectspace" unless defined?(ObjectSpace)
ObjectSpace.each_object(UI::Toolbar) {|obj| ruby_tbs << obj.name }
native_tbs = UI.toolbar_names
all_tb_names = ruby_tbs + native_tbs
all_tb_names.sort!
home_dir = ENV["HOME"] || ENV["USERPROFILE"]
my_toolbar_list = UI.savepanel("Save toolbar list",home_dir,"my_toolbar_list.txt")
if my_toolbar_list # false if user cancelled dialog
File.open(my_toolbar_list, 'w') {|file|
all_tb_names.each {|name| file.puts(name) }
}
end
it was old v8 one of mine that I had quickly pulled out of something else…
it’s a helper for the fact you need to turn them on individually from the ‘hidden’ menu on a mac…
I fixed it a bit now and added verbose commenting…
# main module namespace
module JcB
# plugins namespace
module MacTB
# we have the main menu in 'Help'
main_tb_menu = UI.menu('Help').add_submenu('My Toolbar Organiser') unless file_loaded?(__FILE__)
# then we have 4 sub menu items that we add after the required command
# we find our list and turn those on using a multiline block
my_tbs_on = UI::Command.new('MY TBs ON') do
# we have choices of retriving the file depending on SU and Ruby versions
# first is for older version
## my_toolbar_txt = File.join(File.dirname(__FILE__), 'my_toolbar.txt')
# but this should work for v16
my_toolbar_txt = File.join(__dir__, 'my_toolbars.txt')
# we can check the path while testing
puts " my_toolbar_txt #{my_toolbar_txt}"
# then we need SU to understand our list as an array
# there are many ways depending on how it's written
# as we write an array format we can just read it using eval
my_toolbar_list = eval(IO.read(my_toolbar_txt))
# SU has two ways of storing toolbars
# UI.toolbar_names.collect{ |native_toolbar| p native_toolbar}
# ObjectSpace.each_object(UI::Toolbar){ |ruby_toolbar| p ruby_toolbar.name}
# we can select and show these separately
# for ruby we get the name and compare it
my_toolbar_list.each do |ruby_toolbar_name|
ObjectSpace.each_object(UI::Toolbar) do |named_toolbar|
named_toolbar.show if named_toolbar.name === ruby_toolbar_name
end # do |named_toolbar|
end # do |ruby_toolbar_name|
# for native it's much easier
my_toolbar_list.select { |native_toolbar| UI.set_toolbar_visible(native_toolbar, true) }
end # my_tbs_on
# then we can add info for the menu, etc...
my_tbs_on.status_bar_text = 'turn them all on'
my_tbs_on.menu_text = 'MY TBs ON'
main_tb_menu.add_item(my_tbs_on)
# end of first item
# we also need two ways of turning the two types off and it's really ANY toolbar...
any_tbs_off = UI::Command.new('MY TBs OFF') do
ObjectSpace.each_object(UI::Toolbar) { |ruby_toolbar| (ruby_toolbar.hide) }
UI.toolbar_names.map { |native_toolbar| UI.set_toolbar_visible(native_toolbar, false) }
end
# then we can add info for the menu, etc...
any_tbs_off.status_bar_text = 'turn them all off'
any_tbs_off.menu_text = 'MY TBs OFF'
main_tb_menu.add_item(any_tbs_off)
# end of second item
# and turn them all on so we can position and record them
all_tbs_on = UI::Command.new('Show All TBs') do
ObjectSpace.each_object(UI::Toolbar) { |ruby_toolbar| (ruby_toolbar.show) }
UI.toolbar_names.map { |native_toolbar| UI.set_toolbar_visible(native_toolbar, true) }
end
# then we can add info for the menu, etc...
all_tbs_on.status_bar_text = 'turn them all on and start from scratch'
all_tbs_on.menu_text = 'Show All TBs'
main_tb_menu.add_item(all_tbs_on)
# end of All item
# after we tun off any we don't want in our set, we record it to the txt file...
record_my_choice = UI::Command.new('Record My TBs') do
# we open the file inside the block so it only ever load when we use the tool...
my_toolbar_list = File.join(__dir__, 'my_toolbars.txt')
my_toolbar = []
# need both types so we push them into an array using [] << inside a block
ObjectSpace.each_object(UI::Toolbar) do |ruby_toolbar|
my_toolbar << ruby_toolbar.name if ruby_toolbar.respond_to?(:name) && ruby_toolbar.visible? && ruby_toolbar != nil?
end
UI.toolbar_names.map do |native_toolbar|
my_toolbar << native_toolbar if UI.toolbar_visible?(native_toolbar) && native_toolbar != nil?
end
File.open(my_toolbar_list, 'w') { |f| f.write(my_toolbar.each{|tb| tb}) }
end
# then we can add info for the menu, etc...
record_my_choice.status_bar_text = 'put in place'
record_my_choice.menu_text = 'Record My TBs'
main_tb_menu.add_item(record_my_choice)
# end of item
end # MacTB
end # JcB
as you see it’s a little more complex than getting all the toolbars…
The idea is you turn them all on, position those you use, record the ones left on, and can toggle those off/on when rendering or writing code, etc…
john