package name.abuchen.portfolio.ui.util; import java.util.Objects; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Shell; import name.abuchen.portfolio.model.Client; import name.abuchen.portfolio.model.ConfigurationSet; import name.abuchen.portfolio.model.ConfigurationSet.Configuration; import name.abuchen.portfolio.ui.Messages; /** * Stores a set of named configurations whereby one is the active configuration * at any given time. Each configuration has a name given by the user. */ public class ConfigurationStore { public interface ConfigurationStoreOwner { void beforeConfigurationPicked(); void onConfigurationPicked(String data); } private static final class InputValidator implements IInputValidator { @Override public String isValid(String newText) { return newText == null || newText.trim().isEmpty() ? Messages.ConfigurationErrorMissingValue : null; } } private static final String KEY_ACTIVE = "$picked"; //$NON-NLS-1$ private final String identifier; private final Client client; private final IPreferenceStore preferences; private final ConfigurationStoreOwner listener; private final ConfigurationSet configSet; private Configuration active; private Menu contextMenu; public ConfigurationStore(String identifier, Client client, IPreferenceStore preferences, ConfigurationStoreOwner listener) { this.identifier = identifier; this.client = client; this.preferences = preferences; this.listener = listener; this.configSet = client.getSettings().getConfigurationSet(identifier); // make one active (and there always must be one active) this.active = configSet.lookup(preferences.getString(identifier + KEY_ACTIVE)) .orElseGet(() -> configSet.getConfigurations().findFirst().orElseGet(() -> { Configuration defaultConfig = new Configuration(Messages.ConfigurationStandard, null); configSet.add(defaultConfig); return defaultConfig; })); preferences.setValue(identifier + KEY_ACTIVE, active.getUUID()); } /** * Shows menu to manage views, e.g. create, copy, rename, and delete a view. * * @param shell */ public void showMenu(Shell shell) { if (contextMenu == null) { MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$ menuMgr.setRemoveAllWhenShown(true); menuMgr.addMenuListener(this::saveMenuAboutToShow); contextMenu = menuMgr.createContextMenu(shell); } contextMenu.setVisible(true); } /** * Disposes the configuration store. */ public void dispose() { if (contextMenu != null && !contextMenu.isDisposed()) contextMenu.dispose(); } private void saveMenuAboutToShow(IMenuManager manager) // NOSONAR { configSet.getConfigurations().forEach(config -> { Action action = new SimpleAction(config.getName(), a -> activate(config)); action.setChecked(active == config); manager.add(action); }); manager.add(new Separator()); manager.add(new SimpleAction(Messages.ConfigurationNew, a -> createNew(null))); manager.add(new SimpleAction(Messages.ConfigurationDuplicate, a -> createNew(active))); manager.add(new SimpleAction(Messages.ConfigurationRename, a -> rename(active))); manager.add(new SimpleAction(Messages.ConfigurationDelete, a -> delete(active))); } private void createNew(Configuration template) { InputDialog dlg = new InputDialog(Display.getCurrent().getActiveShell(), Messages.ConfigurationNew, Messages.ChartSeriesPickerDialogMsg, template != null ? template.getName() : null, new InputValidator()); if (dlg.open() != InputDialog.OK) return; String name = dlg.getValue(); listener.beforeConfigurationPicked(); active = new Configuration(name, template != null ? template.getData() : null); configSet.add(active); client.markDirty(); preferences.setValue(identifier + KEY_ACTIVE, active.getUUID()); listener.onConfigurationPicked(active.getData()); } private void rename(Configuration config) { InputDialog dlg = new InputDialog(Display.getCurrent().getActiveShell(), Messages.ConfigurationRename, Messages.ChartSeriesPickerDialogMsg, config.getName(), new InputValidator()); if (dlg.open() != InputDialog.OK) return; config.setName(dlg.getValue()); client.markDirty(); } private void delete(Configuration config) { configSet.remove(config); listener.beforeConfigurationPicked(); active = configSet.getConfigurations().findAny().orElseGet(() -> { Configuration defaultConfig = new Configuration(Messages.ConfigurationStandard, null); configSet.add(defaultConfig); return defaultConfig; }); preferences.setValue(identifier + KEY_ACTIVE, active.getUUID()); listener.onConfigurationPicked(active.getData()); } private void activate(Configuration config) { listener.beforeConfigurationPicked(); active = config; preferences.setValue(identifier + KEY_ACTIVE, active.getUUID()); listener.onConfigurationPicked(config.getData()); } public void updateActive(String data) { if (!Objects.equals(data, active.getData())) { active.setData(data); client.markDirty(); } } public String getActive() { return active.getData(); } public String getActiveName() { return active.getName(); } public void insertMigratedConfiguration(String data) { active = new Configuration(Messages.ConfigurationStandard, data); configSet.add(active); preferences.setValue(identifier + KEY_ACTIVE, active.getUUID()); client.markDirty(); } }