As I enter into Sketchup, I would like to provide a prompt that allows me to immediately open the last Sketchup file opened. Is the list of recent files available to ruby?
For older versions of Sketchup the Recent File List is in the registry. Look at:
HKEY_CURRENT_USER\Software\SketchUp\SketchUp 20xx\Recent File List. I don’t have a machine with Sketchup 2018 in front of me at the moment to check the latest.
Access from Ruby is by Win32::Registry::HKEY_CURRENT_USER
see: Class: Win32::Registry (Ruby 2.0.0)
or here: Class: Win32::Registry (Ruby 2.0.0)
when you click “file” to open a file, at the bottom of the roll out there should be a list of recent files. but this is in SU 2018, not sure how it is in SU8?
… also if you pin the SketchUp shortcut to the Windows taskbar or the start page, a recent files list will appear on the shortcut’s right-click popup menu.
To do a prompt at startup, try …
require "win32ole"
# Microsoft Docs > Windows Scripting Host > SendKeys method:
# https://docs.microsoft.com/en-us/previous-versions/windows/internet-explorer/ie-developer/windows-scripting/8c6yea83(v=vs.84)
SJN ||= Module.new
module SJN::LastModelOpener
# NOTE: This module is also used as an Sketchup::AppObserver object.
extend self
@@loaded = false unless defined?(@@loaded)
@@first = true unless defined?(@@first)
WshShell = WIN32OLE.new("WScript.Shell")
def expectsStartupModelNotifications # AppObserver callback
return true
end
def onNewModel(model) # AppObserver callback
if @@first
@@first = false
Sketchup.remove_observer(self) # detach AppObserver
# Do not automatically open last model if another
# skp file was double-clicked to start SketchUp:
if Sketchup.active_model.title.empty?
# PROMPT ...
choice = UI.messagebox("Open model from last session?",MB_YESNO)
open_recent_skp("1") if choice == IDYES
end
end
end
def open_recent_skp(num)
# % means ALT key. ALT+F will be File menu on English systems.
# The last saved model opened will always be prefixed by "1".
# This will be the current open model if it was saved, or the
# model file from previous session if not. IF the current skp
# has been saved or SketchUp was opened by double-clicking a
# a file, then the last session model will be prefixed by "2".
WshShell.SendKeys("%F#{num}")
end
unless @@loaded # Do this code ONCE ...
UI.add_context_menu_handler do |popup|
if Sketchup.active_model.title.empty? # ie "Untitled"
popup.add_item("Open Model from Last Session") { open_recent_skp("1") }
else
popup.add_item("Open Previous Model") { open_recent_skp("2") }
end
end
# Attach this module itself as the AppObserver object:
Sketchup.add_observer(self)
@@loaded = true
end
end # outer namespace modules
Thank you for being so responsive, and helpfully instructive.
And Dan, thanks for the example you sent. That was quite generous, and I will give it try and see how it works. It took me a while to get through the Namespaces concept, but I have finally conquered the concept and am implementing throughout my code. My first attempts were not successful because of urgency of the projects, and of course, as a result my code was quite unwieldingly long and difficult to debug. But these last few weeks, I have returned to the project and have studied and experimented with the information you have previously shared with others about Namespaces. I get it now, and I have been able to successfully create the modules I need for the application I am developing.
While awaiting feedback for my question, I was able to experiment with a few ideas, in which the result allowed me to generate a different method in order to achieve my objective and provided with a few more details about the files themselves. If anyone is interested I’d by happy to share the concept and the results.
Thanks again.
Scott.
If you don’t want to rely on OS specific hacks or directly read the Windows Registry you could also keep your own list of recent files, and use an observer to save values to that list. This allows the script to work on other platforms, on localized builds where access keys may differ and on future SketchUp versions where the data may be saved elsewhere.
Here’s a code example of how to get prompted for opening the last saved model on SketchUp launch
module YourName
module OpenLastModel
PLUGIN_ID = "your_name_open_last_model"
class MyAppObserver < Sketchup::AppObserver
@@launching = true
def expectsStartupModelNotifications
true
end
def onOpenModel(model)
@@launching = false
return if model.title.empty? # Empty new model.
# SketchUp's write_default fails if String contain backslashes.
Sketchup.write_default(PLUGIN_ID, "last_model", model.path.tr("\\", "/"))
end
def onNewModel(model)
return unless @@launching
@@launching = false
path = Sketchup.read_default(PLUGIN_ID, "last_model")
return unless path
text = "Do you want to open last saved file?"
return unless UI.messagebox(text, MB_YESNO) == IDYES
Sketchup.open_file(path)
end
end
unless @loaded
@loaded = true
Sketchup.add_observer(MyAppObserver.new)
end
end
end
In an actual plugin I’d get PLUGIN_ID from the basename of the loader file. You can also update onNewModel to include the path in the text box, as a mean to identify the last file before loading.
Btw, I would strongly advise against misusing the context menu for entries not related to the current selection.