First try at re-enabling loading and saving task settings

- Pull gtk builder config out of pycam-project.ui and into task_settings.ui
- StatusManager.py:
  - add UI_FILE and register ui with Settinsg
  - state item registration
  - start work on load_task_settings() method
  - fix compile errors
  - remove unused (I hope) functions
- Project.py:
  - Unbundle task_settings and EnableODE configs
  - Uncomment and implement load_task_settings() method
- Settings.py:
  - Fix set() method to call gtk function
  - Experimental {set,get}closure() methods to help with gtk callbacks
- pycam script:
  - call load_task_settings with any --config command line arg
- menubar.xml:
  - uncomment task settings menu items (not implemented at all)
StatusManager.py:  handle empty '' task_settings filenames properly
Updated 'core methods' registration for plugins

Plugins may register 'core methods' available to other plugins as
e.g. self.core.my_core_method().  Previously, the functions were
accessed using the Settings class get and set methods.  This resulted
in code that was difficult to read, e.g.
self.core.get("my_core_method")().

The old functionality is maintained but deprecated.

Gui/Settings.py: new addmethod() and delmethod() functions can create and
remove new class methods to the Settings class at runtime.

Plugins/__init__.py: The PluginBase class includes a new CORE_METHODS
attribute where names of plugin methods to be added to the Settings
class are listed.  The register/unregister_core_methods() functions
should be called from setup() and teardown(), respectively, to add or
remove these core methods.  This is a bit less verbose than before,
where there were no convenience functions and each function was added
individually.

The rest of the changes touch a great many source files where the new
way of calling plugin methods was updated, but there are no changes to
flow or logic, and should be safe if Gui/Settings.py and
Plugins/__init__.py are correct.
WIP:  save task settings

- Log messages about reading/writing config files
- Stub function for save_task_settings & plumbing (need to revisit this)
- Bug fix for loading prefs file
Change PluginBase._state_items from list to dict

The PluginBase object stored state_items as a list of (path, getter,
setter) tuples.  The StatusManager plugin collected these into one
place by passing a 'result' list to each plugin, which would append
its own respective list of tuples, a rather unusual way of returning
data back to a calling function.  The plugins used 'if ... in ...' and
'list.remove()' on the lists, also unusual.

This commit changes state items to a dict keyed on path, with the
value a (getter, setter) tuple.  Locating and clearing state items by
path is more intuitive with a dict.  In addition, the resulting dict
can be serialized directly by e.g. PyYAML to create a human-readable,
structured configuration file or other configuration persistence.
Add 'plugin_manager' attribute to PluginBase.core

Small code readability fix
Put state items into categories

Both tool settings and gui settings were bunched together in the
_state_items dict.  In preparation for saving them separately,
_state_items adds an extra top level to the dict, 'section', that may
be either 'gui-settings' or 'task-settings'.  When persistence is
implemented, gui-settings and task-settings should be stored in different
persistence stores.

PluginBase.register_state_item now has 'section' as an additional
initial parameter.

PluginBase.unregister_state_item also has the initial 'section'
parameter, and removes the unneeded get_func and set_func params.
task setting persistence:  fix save tasks

Save task functionality restored.

Save format is yaml.  Old XML formatting removed.

Menus moved into plugin.

  FIXME These really need to be abstracted out into the PluginBase
  class.  The whole "Settings menu items" block can be moved out,
  and those tuples placed into a class attribute.

  FIXME Ideally the share/ui/*.ui should be renamed to *_builder.xml,
  and menus and other uimanager stuff should be called *_ui.xml.

Fixes to dump_state needed to deal with the objects in ListPluginBase
so that a generic python data structure can be passed to the
serializer.
StatusManager:  save last task settings filename, not uri

change the last_task_settings_uri attribute name to
last_task_settings_file and store the filename, not
pycam.Utils.URIHandler(filename) into it
Fix task data serialization

More fixes to dump_state needed to deal with serializing lower-level
objects in the TaskEntity data (and then we turned off saving task
data anyway).

ObjectWithAttributes objects now have a 'serializable()' method that
returns a vanilla data structure of itself for consumption by
picklers.

Models and Tasks persistence is turned off.  Models doesn't seem to be
useful data anyway.

Tasks depend on Models, and also on bounds, processes and tools.
Saving task data might still be useful somehow and is ready to be
turned back on once it's decided what to do with Models.

Add to 5e93463ba03c5554773c5eaa08774a588d798608
Remove 'import exceptions' from Settings.py

Add this to c1e1945a; AttributeError is a built-in Exception
Fix default task settings load on startup

default_task_settings_file param is saved to the GTK file button
object correctly, but as written, the getter function fails to
retrieve it from the object.  Reverted to the default getter
function.
Change _log to self.log in Plugins in a few spots

self.log is defined by PluginBase; this is a small clean-up
Remove experimental crap from 50f67c12
Settings persistence:  remove _state_item & get settings from self.core

The redundant _state_item infrastructure has been removed.

Instead, non-ListPluginBase plugins that have settings to be saved
should mark them in either the 'PERSIST_GENERAL_PREFERENCES' or
'PERSIST_TASK_SETTINGS' attribute.  These should be in a dict to
structure the data (dict of dicts to structure it deeply), and values
should be lists of self.core keys to persist.

StatusManager has a new method get_global_persist_data.  This takes
one argument: the name of the PERSIST_* attribute noted above.  It
goes through each plugin in turn, calling its get_persist_data method
with the same argument, and merging the results.  This data is
guaranteed to be only built-in Python structures and data types to
make it easier for a variety of picklers to deal with.

For now, colors are marked for persistence here, but this should be
changed soon.

Next steps:
     - plug this into saving
     - fix up restoring and plug this in there
Add a command-line debugging console

A menu entry in the 'View' menu (for lack of a better place) starts a
python interactive shell on the console.  This is very handy for newby
developers trying to find their way around (I know this personally!).

FIXME:

It will break the GtkConsole until a proper solution for stdin/stdout
handling is devised.  The GtkConsole hijacks those, which breaks the
console shell.

FIXME:

The menu item needs a weight to appear at the bottom of the list.
Right now it appears randomly at top or bottom.

FIXME:

Alternatively, add some extra buttons to the existing graphical
console to add debugging objects (self.core) and start the shell on
the terminal.
Save/retrieve general configuration with new StatusManager functions

~/.pycam/preferences.conf is successfully read and written.

FIXME:  still some old code to rip out.

FIXME: need some generalization.  This should happen when we start
persisting task settings.
New Utils.Persistence model; move config load/save to StatusManager

New pycam.Utils.Persistence module takes care of file load/save
operations and of serializing data

StatusManager plugin registers core functions
'load/save_general_preferences', connecting Persistence operations
with plugin settings

Rationale:

load/save_preferences were in the busy Project.py, ProjectGui class.
Some helper functions were spread into the Settings module.

Moving generic save/restore functions to a separate Persistence class
prepares the way for using the same functions for persisting task
settings.  It also groups the functions back into one place together
again.

The specific functions to save/restore gui prefs have two lines of
meat each, one calling the function to get/set prefs from modules, one
calling the persist function to un/serialize and restore from/save to
file.  These are made generally available by registering them as
self.core methods.

FIXME:  deal with setting defaults

FIXME:  default_task_settings_file ends up with empty string when no
file is selected; this should be None.

FIXME:  check for left over cruft
Persistence:  add comment at top of preferences.conf
Persistence module:  generalize persistence functions

Pull load/save and serialization functions out of preferences routines
for later use by task setting persistence