kopia lustrzana https://github.com/inkstitch/inkstitch
185 wiersze
6.3 KiB
Python
185 wiersze
6.3 KiB
Python
import json
|
|
import os
|
|
import re
|
|
|
|
import wx
|
|
|
|
from ..i18n import _
|
|
from ..utils import cache
|
|
from .dialogs import info_dialog
|
|
|
|
|
|
class PresetsPanel(wx.Panel):
|
|
"""A wx.Panel for loading, saving, and applying presets.
|
|
|
|
A preset is a named collection of settings. From the perspective of this
|
|
class, a preset is an opaque JSON-serializable object.
|
|
|
|
The PresetsPanel will handle interaction with the user and inform the
|
|
instantiator of events such as a preset being loaded. Presets starting
|
|
and ending with "__" will not be shown to the user. This allows for the
|
|
instantiator to manage hidden presets such as "__LAST__".
|
|
"""
|
|
|
|
HIDDEN_PRESET_RE = re.compile('^__.*__$')
|
|
|
|
def __init__(self, parent, *args, **kwargs):
|
|
"""Construct a PresetsPanel.
|
|
|
|
The parent is the parent window for this wx.Panel. The parent is
|
|
expected to implement the following methods:
|
|
|
|
def get_preset_data(self)
|
|
returns a JSON object representing the current state as a preset
|
|
|
|
def apply_preset_data(self, preset_data):
|
|
apply the preset data to the GUI, updating GUI elements as necessary
|
|
|
|
def get_preset_suite_name(self):
|
|
Return a string used in the presets filename, e.g. "lettering" -> "lettering_presets.json".
|
|
If not defined, "presets.json" will be used.
|
|
"""
|
|
|
|
kwargs.setdefault('style', wx.BORDER_NONE)
|
|
wx.Panel.__init__(self, parent, wx.ID_ANY, *args, **kwargs)
|
|
self.parent = parent
|
|
|
|
self.presets_box = wx.StaticBox(self, wx.ID_ANY, label=_("Presets"))
|
|
|
|
self.preset_chooser = wx.ComboBox(self, wx.ID_ANY)
|
|
self.update_preset_list()
|
|
self.preset_chooser.SetSelection(-1)
|
|
|
|
self.load_preset_button = wx.Button(self, wx.ID_ANY, _("Load"))
|
|
self.load_preset_button.Bind(wx.EVT_BUTTON, self.load_selected_preset)
|
|
|
|
self.add_preset_button = wx.Button(self, wx.ID_ANY, _("Add"))
|
|
self.add_preset_button.Bind(wx.EVT_BUTTON, self.add_preset)
|
|
|
|
self.overwrite_preset_button = wx.Button(self, wx.ID_ANY, _("Overwrite"))
|
|
self.overwrite_preset_button.Bind(wx.EVT_BUTTON, self.overwrite_preset)
|
|
|
|
self.delete_preset_button = wx.Button(self, wx.ID_ANY, _("Delete"))
|
|
self.delete_preset_button.Bind(wx.EVT_BUTTON, self.delete_preset)
|
|
|
|
presets_sizer = wx.StaticBoxSizer(self.presets_box, wx.HORIZONTAL)
|
|
self.preset_chooser.SetMinSize((200, -1))
|
|
presets_sizer.Add(self.preset_chooser, 1, wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.BOTTOM | wx.EXPAND, 10)
|
|
presets_sizer.Add(self.load_preset_button, 0, wx.ALIGN_CENTER_VERTICAL | wx.BOTTOM | wx.LEFT, 10)
|
|
presets_sizer.Add(self.add_preset_button, 0, wx.ALIGN_CENTER_VERTICAL | wx.BOTTOM | wx.LEFT, 10)
|
|
presets_sizer.Add(self.overwrite_preset_button, 0, wx.ALIGN_CENTER_VERTICAL | wx.BOTTOM | wx.LEFT, 10)
|
|
presets_sizer.Add(self.delete_preset_button, 0, wx.ALIGN_CENTER_VERTICAL | wx.BOTTOM | wx.LEFT | wx.RIGHT, 10)
|
|
|
|
self.SetSizerAndFit(presets_sizer)
|
|
self.Layout()
|
|
|
|
@property
|
|
@cache
|
|
def suite_name(self):
|
|
try:
|
|
return self.parent.get_preset_suite_name() + "_presets"
|
|
except AttributeError:
|
|
return "presets"
|
|
|
|
@cache
|
|
def presets_path(self):
|
|
try:
|
|
import appdirs
|
|
config_path = appdirs.user_config_dir('inkstitch')
|
|
except ImportError:
|
|
config_path = os.path.expanduser('~/.inkstitch')
|
|
|
|
if not os.path.exists(config_path):
|
|
os.makedirs(config_path)
|
|
return os.path.join(config_path, '%s.json' % self.suite_name)
|
|
|
|
def _load_presets(self):
|
|
try:
|
|
with open(self.presets_path(), 'r') as presets:
|
|
presets = json.load(presets)
|
|
return presets
|
|
except IOError:
|
|
return {}
|
|
|
|
def _save_presets(self, presets):
|
|
with open(self.presets_path(), 'w') as presets_file:
|
|
json.dump(presets, presets_file)
|
|
|
|
def update_preset_list(self):
|
|
preset_names = self._load_presets().keys()
|
|
preset_names = [preset for preset in preset_names if not self.is_hidden(preset)]
|
|
self.preset_chooser.SetItems(sorted(preset_names))
|
|
|
|
def is_hidden(self, preset_name):
|
|
return self.HIDDEN_PRESET_RE.match(preset_name)
|
|
|
|
def get_preset_name(self):
|
|
preset_name = self.preset_chooser.GetValue().strip()
|
|
if preset_name:
|
|
return preset_name
|
|
else:
|
|
info_dialog(self, _("Please enter or select a preset name first."), caption=_('Preset'))
|
|
return
|
|
|
|
def check_and_load_preset(self, preset_name):
|
|
preset = self._load_presets().get(preset_name)
|
|
if not preset:
|
|
info_dialog(self, _('Preset "%s" not found.') % preset_name, caption=_('Preset'))
|
|
|
|
return preset
|
|
|
|
def store_preset(self, preset_name, data):
|
|
presets = self._load_presets()
|
|
presets[preset_name] = data
|
|
self._save_presets(presets)
|
|
self.update_preset_list()
|
|
|
|
def add_preset(self, event, overwrite=False):
|
|
preset_name = self.get_preset_name()
|
|
if not preset_name:
|
|
return
|
|
|
|
if not overwrite and preset_name in self._load_presets():
|
|
info_dialog(self, _('Preset "%s" already exists. Please use another name or press "Overwrite"') % preset_name, caption=_('Preset'))
|
|
|
|
self.store_preset(preset_name, self.parent.get_preset_data())
|
|
|
|
event.Skip()
|
|
|
|
def overwrite_preset(self, event):
|
|
self.add_preset(event, overwrite=True)
|
|
|
|
def load_preset(self, preset_name):
|
|
preset = self.check_and_load_preset(preset_name)
|
|
if not preset:
|
|
return
|
|
|
|
self.parent.apply_preset_data(preset)
|
|
|
|
def load_selected_preset(self, event):
|
|
preset_name = self.get_preset_name()
|
|
if not preset_name:
|
|
return
|
|
|
|
self.load_preset(preset_name)
|
|
|
|
event.Skip()
|
|
|
|
def delete_preset(self, event):
|
|
preset_name = self.get_preset_name()
|
|
if not preset_name:
|
|
return
|
|
|
|
preset = self.check_and_load_preset(preset_name)
|
|
if not preset:
|
|
return
|
|
|
|
presets = self._load_presets()
|
|
presets.pop(preset_name, None)
|
|
self._save_presets(presets)
|
|
|
|
self.update_preset_list()
|
|
self.preset_chooser.SetValue("")
|
|
|
|
event.Skip()
|