This adds a new class called AutoInc, which is a self-incrementing
integer that supports use as a context manager. AutoInc is used to keep
track of row numbers automatically for easy addition to config panes,
and the context manager adds a visual clue to where entries are on the
same row but different columns
tkinter ends up calling something where utf8 characters won't work
because of the windows encoding, e.g. cp1252.
We can't set encoding just for the dialogs, as it's not thread safe. So
we'll just set it at startup instead. Utilising:
locale.setlocale(locale.LC_ALL, '')
to get things set up initially, so we can properly retrieve the language
to go with the encoding on the subsequent setlocale() call.
If we use the last configured value then the width of the Scale bar
changes as per the user's last setting, even though they might not have
yet restarted for all the rest of the UI to resize.
So if at startup tk-scaling is 1.33 then a user configured 200(%) will
set it to 2.66 for this run.
* Low end of scale bar set to 10, not 0, because now 0 makes absolutely
no sense.
* In theory the width of the scale bar, in pixels, is now also correctly
scaled.
Using a Tk.DoubleVar() with a locale where a comma is used as the
decimals separator leads to internal tk code recording values with the
comma but then other tk code not accepting that back, so it always
thinks the value is zero and the scale slider can't be moved.
Ref: https://stackoverflow.com/questions/45289237/tkinter-scale-slider-with-float-values-doesnt-work-with-locale-of-language-that
* Change to storing as a REG_DWORD under 'ui_scale' not 'ui_scaling'.
* Change all the code, except the call to *set* the tk scaling to use an
integer, with 100 = 100%, i.e. equivalent to the old 1.0.
* Update strings slightly, so translations will need updating too.
NB: The theme.default_ui_scale value for plugin authors to query is
still the float that tk returns.
* If no ui_scaling yet set, set it to 'default'.
* 'default' added to dropdown choices.
Note that you still need an application restart for this to take effect.
* EDMCLogging.Logger.get_streamhandler() method to get the
logger_channel so prefs.py can call setLevel() on it.
* The top-level Logger level is always DEBUG.
* The RotatingFileHandler level is always DEBUG.
* The StreamHandler level is as configured by the user.
* EDMCLogging now creates a singleton of EDMCLogging.Logger and its
associated Logger.
* plug.py tweaked to only import EDMCLogging where it's needed for
getting/creating plugin loggers, else `import logging`.