/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2014 Neil C Smith.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 3 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 3 for more details.
*
* You should have received a copy of the GNU General Public License version 3
* along with this work; if not, see http://www.gnu.org/licenses/
*
*
* Please visit http://neilcsmith.net if you need additional information or
* have any questions.
*/
package net.neilcsmith.praxis.live.pxr;
import net.neilcsmith.praxis.live.pxr.editors.EditorManager;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.neilcsmith.praxis.core.info.ControlInfo;
import net.neilcsmith.praxis.live.properties.EditorSupport;
import net.neilcsmith.praxis.live.properties.PraxisProperty;
import net.neilcsmith.praxis.live.pxr.editors.SubCommandEditor;
import org.openide.explorer.propertysheet.ExPropertyEditor;
import org.openide.explorer.propertysheet.PropertyEnv;
/**
*
* @author Neil C Smith (http://neilcsmith.net)
*/
class DelegatingArgumentEditor extends EditorSupport
implements ExPropertyEditor, PraxisProperty.DelegateEditor {
private final static Logger LOG = Logger.getLogger(DelegatingArgumentEditor.class.getName());
private PraxisProperty.Editor defaultEditor;
private PraxisProperty.Editor currentEditor;
private PraxisProperty.Editor[] allEditors;
private DelegateListener dl;
private BoundArgumentProperty property;
private ControlInfo info;
private PropertyEnv env;
DelegatingArgumentEditor(BoundArgumentProperty property, ControlInfo info) {
this.property = property;
this.info = info;
defaultEditor = EditorManager.getDefaultEditor(property, info); // must never be null
currentEditor = defaultEditor;
property.setValue("editor", currentEditor);
dl = new DelegateListener();
currentEditor.addPropertyChangeListener(dl);
}
@Override
public String getPraxisInitializationString() {
return currentEditor.getPraxisInitializationString();
}
public String getDisplayName() {
// if (currentEditor instanceof PraxisPropertyEditor) {
// return ((PraxisPropertyEditor) currentEditor).getDisplayName();
// } else {
return currentEditor.getClass().getSimpleName();
// }
}
@Override
public void setValue(Object value) {
if (value instanceof SubCommandArgument) {
// if (currentEditor instanceof SubCommandEditor) {
try {
LOG.finest("Delegate setting from command line");
// ((SubCommandEditor) currentEditor).setFromCommand(
// ((SubCommandArgument) value).getCommandLine());
setFromCommand(((SubCommandArgument) value).getCommandLine());
} catch (Exception ex) {
LOG.log(Level.WARNING, "Editor threw exception in command line", ex);
throw new IllegalArgumentException(ex);
}
// }
} else {
currentEditor.setValue(value);
}
}
private void setFromCommand(String command) throws Exception {
Throwable lastEx = null;
SubCommandEditor cEd;
if (currentEditor instanceof SubCommandEditor) {
cEd = (SubCommandEditor) currentEditor;
if (editorSupportsCommandLine(cEd, command)) {
try {
cEd.setFromCommand(command);
return;
} catch (Exception ex) {
lastEx = ex;
}
}
}
for (PraxisProperty.Editor ed : getAllEditors()) {
if (ed == currentEditor) {
continue;
}
if (ed instanceof SubCommandEditor) {
cEd = (SubCommandEditor) ed;
if (editorSupportsCommandLine(cEd, command)) {
try {
cEd.setFromCommand(command);
setCurrentEditor(ed);
return;
} catch (Exception ex) {
lastEx = ex;
}
}
}
}
if (lastEx == null) {
throw new IllegalArgumentException("Couldn't find editor matching command");
} else {
throw new IllegalArgumentException(lastEx);
}
}
private boolean editorSupportsCommandLine(SubCommandEditor editor, String line) {
for (String cmd : editor.getSupportedCommands()) {
if (line.startsWith(cmd + " ")) {
return true;
}
}
return false;
}
@Override
public Object getValue() {
return currentEditor.getValue();
}
@Override
public boolean isPaintable() {
return currentEditor.isPaintable();
}
@Override
public void paintValue(Graphics gfx, Rectangle box) {
currentEditor.paintValue(gfx, box);
}
@Override
public String getJavaInitializationString() {
return null;
}
@Override
public String getAsText() {
return currentEditor.getAsText();
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
currentEditor.setAsText(text);
}
@Override
public String[] getTags() {
return currentEditor.getTags();
}
@Override
public Component getCustomEditor() {
if ((allEditors != null && allEditors.length > 1)
|| EditorManager.hasAdditionalEditors(property, info)) {
return new DelegatingArgumentCustomEditor(this, env);
} else {
return currentEditor.getCustomEditor();
}
}
@Override
public boolean supportsCustomEditor() {
if (allEditors == null) {
return currentEditor.supportsCustomEditor()
|| EditorManager.hasAdditionalEditors(property, info);
} else {
return currentEditor.supportsCustomEditor()
|| allEditors.length > 1;
}
}
void setCurrentEditor(PraxisProperty.Editor editor) {
if (currentEditor != editor) {
currentEditor.removePropertyChangeListener(dl);
currentEditor.reset();
currentEditor = editor;
property.setValue("editor", editor);
currentEditor.addPropertyChangeListener(dl);
LOG.fine("Setting current editor to " + editor.getClass().getSimpleName());
}
}
void restoreDefaultEditor() {
// currentEditor.reset();
setCurrentEditor(defaultEditor);
}
@Override
public PraxisProperty.Editor getCurrentEditor() {
return currentEditor;
}
PraxisProperty.Editor[] getAllEditors() {
if (allEditors == null) {
initializeAllEditors();
}
return allEditors;
}
private void initializeAllEditors() {
if (EditorManager.hasAdditionalEditors(property, info)) {
PraxisProperty.Editor[] additional = EditorManager.getAdditionalEditors(property, info);
PraxisProperty.Editor[] all = new PraxisProperty.Editor[additional.length + 1];
all[0] = defaultEditor;
System.arraycopy(additional, 0, all, 1, additional.length);
allEditors = all;
} else {
allEditors = new PraxisProperty.Editor[]{defaultEditor};
}
}
@Override
public void attachEnv(PropertyEnv env) {
if (currentEditor instanceof ExPropertyEditor) {
((ExPropertyEditor) currentEditor).attachEnv(env);
}
this.env = env;
}
@Override
public Object getAttribute(String key) {
return currentEditor.getAttribute(key);
}
@Override
public String[] getAttributeKeys() {
return currentEditor.getAttributeKeys();
}
@Override
public void reset() {
currentEditor.reset();
}
private class DelegateListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
firePropertyChange();
}
}
}