Deleting a sub-section of the INI file or Registry

I commonly use the read_default and write_default methods to store global settings for my plugins.

A typical write call might be:

Sketchup.write_default "MEDEEK_WALL_PLUGIN", "WIN_CASINGLOC", @Win_casingloc_new

I’m wondering if there might be a method or some way to easily delete the entire sub-section (ie. MEDEEK_WALL_PLUGIN) or to remove all of the key/value pairs from the sub-section in a single command?

Searching through the API and nothing jumps out at me but I may just be missing it.

There is no SketchUp API for this. Maybe you could use system API, but it would be different on Mac and Windows.

What is the use case for this?

1 Like

I would like to setup a way so that the user can completely flush all of their global settings for my plugins, that way they can start with a clean slate. Essentially a “reset” switch.

Occasionally I have users who upgrade from very old versions of the plugins and this sort of thing would be useful and save me numerous emails and phone calls.

You could save your default values somewhere, e.g. in a text file, and have a feature for rewriting SketchUp’s “defaults” (why is this feature called “defaults”??) with the default values.

1 Like

You need to make a list of all of your keys as an array thus…

keys = ["key0",
"key1",
"key2" ### etc
]
keys.each{|key|
  Sketchup.write_default("MEDEEK_WALL_PLUGIN", key, nil)
}

You could have a txt file containing the desired key names - which you’d ship in your main subfolder, one key per line, e.g. split by ‘newline’ \n

keys=[]
IO.readlines("{DESIRED_FOLDER_PATH}/wall_keys.txt").each{|k| keys << k.chomp! }
### note how the chomp deletes end \n character

keys is now an array of keys, which you can process as the first example…
There are many ways of reading strings from a file and restructuring the output

1 Like

(1) The first problem is platform.

  • The MacOS platform does not have a registry, nor .ini files.
    SketchUp used plist files on the Mac platform. They are similar to JSON or Ruby’s PStore library.
    [I personally do not know if plist files are PStore compatible,. not ever having a Mac.]

  • The Windows platform used registry entries from v7 onward. (I never used any older version, so I cannot say if the old .ini format was ever used. I don’t think your extensions are old enough to worry about running in a SketchUp version that might use .ini.)

(2) The second issue is version and how it pertains to data location and format.

SketchUp switched to mostly JSON files in the initial 2018 release.

Release Notes say …

Preferences Location

The majority of preferences are now stored in two json files. There are still some OS controlled preferences that remain in the registry (Win) or plist (Mac). The json files are saved in the following locations:

On Win:
PrivatePreferences.json is saved to
C:\Users\[user name]\AppData\Local\SketchUp\SketchUp 2018\SketchUp
SharedPreferences.json is saved to
C:\Users\[user name]\AppData\Roaming\SketchUp\SketchUp 2018\SketchUp

On Mac:
Both PrivatePreferences.json and SharedPreferences.json are saved to
/Users/[user name]/Library/Application Support/SketchUp 2018/SketchUp

The OS controlled values are mainly for application window size and position; inspector window and tray panel positions, sizes and states; and the recent file list.

All the extension settings written by Sketchup.write_default and the UI::WebDialog and UI::HtmlDialog classes are saved in the JSON preferences files (since 2018 release.)

A major problem with making changes to these files outside of the API is that SketchUp will overwrite your changes when it closes.

So, prior to version 2018, you’d need to do platform variable workarounds.

Test show that TIG’s idea of setting all the values nil, on Windows clears the values in the section, but does not actually removed the keys, nor the section. (There never has been any “remove_default” or “delete_default_section” methods in the API.)

We’ve discussed this in the past in several of the forums, BTW.
The workaround for Mac has been talked about by John and Steve elsewhere.

On Windows there are two main workarounds:

(a) Using the WIN32OLE class and the Windows Scripting Host’s Shell Object registry access methods.

(b) Using Ruby’s Win32::Registry class from the Standard Library. (Note, you have to require "win32/registry" before use.)

I just tested on SketchUp 2016, writing a section and test attribute to the registry. Then outside of SketchUp (manually using regedit) deleted the entire section (attributes and all). Then closed SketchUp, and it did not rewrite the section.
A second test showed that a manual change outside SketchUp to an attribute value was not over written by SketchUp when it closed down.
These results apply only to custom sections, attributes and values.
Most other attributes and values created by SketchUp get overwritten by SketchUp when it closes.

1 Like

Based on the comments thus far it would seem that sticking to methods within the API make the most sense (ie. platform independence and the ability to the retain the changes when SU shuts down).

My only concern is with setting the values to “nil”, would that cause any sort of instability. I know setting certain arrays to nil or empty within attributes libraries has caused problems in SU but maybe that is entirely different than this.

For now I will try to run with TIG’s idea and see if I can make it work.

It would be really nice to have an API call to remove key/value pairs, remove_default.

So I end up with something like this:

def reset_global_settings

	params1 = ['LANGUAGE',
	'UI_GRAPHIC',
	'CHECK_UPDATES',
	'PREVIEW3D_OPTION',
	'CALLOUT_OPTION',
	'LAYOUTIN3D_OPTION',
	'LINE_OPTION',
	'SHEATHOUTLINE_OPTION',
	'CLADOUTLINE_OPTION',
	'GYPSUMOUTLINE_OPTION',
	'COLCALLOUT_OPTION',
	'SSWCALLOUT_OPTION',
	'BEAMCALLOUT_OPTION',
	'POSTCALLOUT_OPTION',
	'HEADERCALLOUT_OPTION',
	'WALLCALLOUT_OPTION',
	'FRAMECALLOUT_OPTION',
	'WALL_PREFIX',
	'BEAM_PREFIX',
	'POST_PREFIX',
	'AGN_OPTION',
	'WALL2DIN3D_OPTION',
	'CDIM',
	'CDIM_END',
	'CDIM_SIZE',
	'CDIM_COLOR',
	'INPUT_COLOR',
	'WALL_DIM_OPTION',
	'WALL_DIM_OFFSET']
	
	params1.each{|key|
		Sketchup.write_default('MEDEEK_WALL_PLUGIN', key, nil)
	}

	params2 = ['LAYERS_OPTION',
	'LAYER_WALL_FRAME',
	'LAYER_WALL_SHEATH',
	'LAYER_WALL_CLAD',
	'LAYER_WALL_TRIM',
	'LAYER_WALL_CASING',
	'LAYER_WALL_GYPSUM',
	'LAYER_WALL_INSUL',
	'LAYER_WALL_HW',
	'LAYER_WALL_DOOR',
	'LAYER_WALL_WINDOW',
	'LAYER_WALL_DIM',
	'LAYER_WALL_SHUTTER',
	'LAYER_WALL_CMU',
	'LAYER_WALL_DIM2',
	'LAYER_WALL_DIM3',
	'LAYER_WALL_DIM4',
	'LAYER_WALL_2D',
	'LAYER_WALL_CODE',
	'LAYER_WALL_ENG',
	'LAYER_ADV_OPTION',
	'LAYER_WALL_HEADER',
	'LAYER_WALL_PLATE',
	'LAYER_WALL_BEAM',
	'LAYER_WALL_COLUMN',
	'LAYER_WALL_KING',
	'LAYER_WALL_TRIMMER']
	
	params2.each{|key|
		Sketchup.write_default('MEDEEK_WALL_PLUGIN', key, nil)
	}

	params3 = ['MATERIALS_OPTION',
	'MFG_LOGO',
	'LUMBER_MAT',
	'LUMBERPT_MAT',
	'LABEL_MAT',
	'WALL2D_MAT',
	'OPEN2D_MAT']
	
	params3.each{|key|
		Sketchup.write_default('MEDEEK_WALL_PLUGIN', key, nil)
	}
end

Actually, I tried hard to get you and Nathaniel to instead use a Ruby hash for your extension options and write out to a JSON file that you control. It’s dead simple. And you also get in the JSON habit and can more easily pass data into HtmlDialogs.

I’ll try once more …

A path to a save location is needed …

COMPANY ||= 'MEDEEK ENGINEERING'
APPDATA ||= ENV['APPDATA'].dup.force_encoding('UTF-8').gsub(/\\\\|\\/,'/')
EXTDATA ||= File.join(APPDATA, COMPANY, 'MEDEEK_WALL_PLUGIN')
EXTJSON ||= 'medeek_wall_options.json'

Saving the hash to disk:

  # @options is a hash with symbol keys
  File.write(
    File.join(EXTDATA, EXTJSON),
    JSON.pretty_generate(@options),
    mode:'w:UTF-8:UTF-8'
  )

Getting the options hash from disk:

  json_text = File.read(
    File.join(EXTDATA, EXTJSON), mode:'r:UTF-8:UTF-8'
  )
  @options = JSON.parse(json_text, symbolize_names: true)

ADD: Clearing the json file of ALL key / value pairs …

  File.write(
    File.join(EXTDATA, EXTJSON),
    {}.to_json, # empty literal hash
    mode:'w:UTF-8:UTF-8'
  )

My example uses symbol keys because they are easier and they stand out in my editor being a different color. But, you can use string keys if you like.

1 Like