New Home for Plugin Settings

Up until now I’ve stored custom settings for my plugins in the actual plugin folder (usually in simple text files [.txt]). However, the time has finally come to try something different.

Everytime a user upgrades the plugins they loose a number of their custom settings (ie. materials, wall presets, custom headers etc…), its only gotten worse as I’ve added more customizable features and more users are constantly upgrading. It has now gotten to the point that I am dealing with this issue for at least 1-2 hours every week in support calls and emails.

This topic has been discussed with quite some detail on at least two previous threads. After reviewing these threads I am convinced that Dan’s idea of saving plugins settings within one’s own %AppData% sub-folder is the best location for this data, as compared to all the other alternatives.

My only concern is that this method of handling data is platform independent. I know that a sub-folder called %AppData%/Medeek/medeek_wall_ext will work just fine on Windows but how about Mac? At least 25% to 30% of my user base is operating a Mac so platform independence is a serious concern for me. If it doesn’t work is there a work around?

The Mac equivalent would be ~/Library/Application Support/
This is where every program is supposed to store their preferences and where SketchUp itself stores them. I don’t have any plugins that store anything there except licenses and logs, but it would be the appropriate place to store preferences that would survive after updating SketchUp.

2 Likes

Nathan - I’ve done it this way

plugins\GKWare_CabMaker6.rb
plugins\GKWare_CabMaker6
plugins\GKWare_CabMaker6_data

This way the files can be together and the user won’t loose anything.
This works for Windows and for MacOS

1 Like

For version independent …

  if !defined?(WIN)
    WIN =( Sketchup.platform == :platform_win rescue RUBY_PLATFORM !~ /(darwin)/i )
    MAC = !WIN
  end

  def get_appdata_path
    if WIN
      appdata = ENV['AppData'].gsub(/(\\\\|\\)/,'/')
    else
      appdata = File.expand_path('~/Library/Application Support')
    end
    File.join(appdata,'Medeek')      
  end
5 Likes
File.join(app data, 'SketchUp Medeek') `

will keep them side by side…

john

1 Like

I like Gary’s idea of putting the settings in a plugin sub-folder with “data” appended to the name, this would actually be useful in that different versions of SketchUp would then maintain their own plugin settings for the Medeek suite of plugins. However, a re-install of that version of SketchUp would wipe out the settings.

However, one could also probably do something similar with Dan’s idea by creating another level of sub-folders with the SketchUp year in the name.

on a mac a reinstall [of SU] will not touch User files, which these are, as are any in the Plugins folder structure…

is that not the case on windows?

john

1 Like

The AppData folder in Windows is wiped clean on a repair install. If the option to keep files is chosen everything will remain.

1 Like

A new install of SketchUp?

So I’ll run this little check when I first load the plugin:

############
# Initialization Check for Wall Plugin Parameters

WIN_OS = ( Sketchup.platform == :platform_win rescue RUBY_PLATFORM !~ /(darwin)/i )
if WIN_OS
          	@appdata = ENV['AppData'].gsub(/(\\\\|\\)/,'/')
else
          	@appdata = File.expand_path('~/Library/Application Support')
end

su_version = Sketchup.version.to_i + 2000
    		
@appdata_medeek_wall = File.join(@appdata,"Medeek/#{su_version}/medeek_wall_ext")

unless Dir.exist?(@appdata_medeek_wall)
           # Do some stuff here
end

But why then waste memory holding the @appdata reference ?

And as this (or these) path(s) are not likely to change during a session, they’d be better to use a local constant, ie: APPDATA_MEDEEK_WALL
The constant should have the same visiblity throughout the extension submodule as the instance variable.

Also if this init code is within a method, the local references can be GC’s when the method ends, and then at the end of the loading, you can undefine the method.

1 Like

You can’t perhaps write a routine that checks for previous installs with custom information and, if found, gives you the option to retrieve / migrate that information to the new install?

1 Like

I actually came to that exact conclusion as was further testing my code just about 5 minutes ago. Maybe I’m finally starting to get this stuff… :slight_smile:

Your right the appdata path never changes so a constant is more suitable, now back to some more testing.

Julian - that is exactly what I do between major versions. This way I can pretty much upgrade users major versions without losing data. Also - since there is an upgrade charge - users can easily choose to stay with the old version if after checking out the new version.

1 Like

The idea is that when you update the plugin you don’t have to worry about losing your custom materials, headers and wall presets anymore.

I am making it so that these settings are unique for different versions of SketchUp, so for example your settings in SU 2017 for the plugin are independent (separate) from your settings in SU 2020 for the plugin. Yes, I could make a feature that copies the settings from one to the other.

Just an idea, I did not really checked in deep how it works… Aerilius storing the history in c:\Users\user_name\AppData\Roaming\SketchUp Ruby Console+\
… so it seams this one can be used even you have more SU version installed…(?)
( historyprovider.rb , api_usage_counter.rb )

Here is what I’ve ended up with:

 WIN_OS = ( Sketchup.platform == :platform_win rescue RUBY_PLATFORM !~ /(darwin)/i )
 if WIN_OS
        appdata = ENV['AppData'].gsub(/(\\\\|\\)/,'/')
 else
        appdata = File.expand_path('~/Library/Application Support')
 end

 su_version = Sketchup.version.to_i + 2000
    		
 APPDATA_MEDEEK_WALL = File.join(appdata,"Medeek/#{su_version}/medeek_wall_ext")

 unless Dir.exist?(APPDATA_MEDEEK_WALL)
         # Do stuff here
 end

A major thank-you to Dan and Gary for helping me figure out what I needed to do and where I needed to put things. As always thank-you Dan for your willingness to provide chunks of code that speed my development along and save me from a lot of pitfalls I otherwise would probably make.

3 Likes

Go just a bit further on the Mac by changing this string ‘~/Library/Application Support’ to this string ‘~/Library/Application Support/Medeek’ where Medeek is a folder (directory on Windows). this way the user settings are not an orphaned file inside Application Support.

1 Like

That is what I am doing with this line:

APPDATA_MEDEEK_WALL = File.join(appdata,"Medeek/#{su_version}/medeek_wall_ext")

Nathan - this works too

APPDATA_MEDEEK_WALL = File.join(appdata, ‘Medeek’,.su_version, ‘medeek_wall_ext’)

This way it becomes more OS independent. Also notice that single quotes are slightly faster.

1 Like