/*
* Beryl - A web platform based on XML, XSLT and Java
* This file is part of the Beryl XML GUI
*
* Copyright (C) 2004 Wenzel Jakob <wazlaf@tigris.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This program 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-3107 USA
*/
package org.beryl.gui.builder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;
import org.beryl.gui.Controller;
import org.beryl.gui.GUIEvent;
import org.beryl.gui.GUIException;
import org.beryl.gui.MessageDialog;
import org.beryl.gui.Widget;
import org.beryl.gui.WidgetFactory;
import org.beryl.gui.model.MapChangeEvent;
import org.beryl.gui.model.MapDataModel;
import org.beryl.gui.model.ModelChangeEvent;
import org.beryl.gui.model.ModelChangeListener;
import org.beryl.gui.validators.FloatValidator;
import org.beryl.gui.validators.IntegerValidator;
import org.beryl.gui.validators.ValidationException;
import org.beryl.gui.validators.Validator;
import org.beryl.gui.widgets.Button;
import org.beryl.gui.widgets.Dialog;
import org.beryl.gui.widgets.Group;
import org.beryl.gui.widgets.LabeledWidget;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
public class AnchorEditor extends Controller implements ModelChangeListener {
private WidgetUserObject userObject = null;
private Widget parent = null;
private Dialog dialog = null;
private Group group = null;
private MapDataModel dataModel = null;
private Element anchorNode = null;
private ArrayList activeComponents = null;
private HashMap customComponents = null;
private Button okButton = null;
private MapDataModel editorModel = null;
public AnchorEditor(Widget parent, MapDataModel editorModel) throws GUIException {
this(parent, ((PropertyTableRow)editorModel.getValue("row")).getPropertyNode(), null);
this.editorModel = editorModel;
}
public AnchorEditor(Widget parent, Element anchorNode, WidgetUserObject userObject) throws GUIException {
this.anchorNode = anchorNode;
this.userObject = userObject;
this.parent = parent;
dataModel = new MapDataModel();
dialog = constructDialog("AnchorEditor", dataModel);
group = (Group) dialog.getWidget("Group");
okButton = (Button) dialog.getWidget("OKButton");
customComponents = new HashMap();
activeComponents = new ArrayList();
loadCustomComponent("hig", "HIG_Row", new IntegerValidator());
loadCustomComponent("hig", "HIG_Column", new IntegerValidator());
loadCustomComponent("hig", "HIG_Width", new IntegerValidator());
loadCustomComponent("hig", "HIG_Height", new IntegerValidator());
loadCustomComponent("hig", "HIG_Alignment", null);
loadCustomComponent("border", "Border_Alignment", null);
loadCustomComponent("box", "Box_AlignX", new FloatValidator());
loadCustomComponent("box", "Box_AlignY", new FloatValidator());
doLoad();
dataModel.addModelChangeListener(this);
}
public void show() {
try {
dialog.initDialog(parent);
dialog.show();
} catch (GUIException e) {
new MessageDialog(e);
}
}
private void loadCustomComponent(String layoutName, String name, Validator validator) throws GUIException {
Widget widget = WidgetFactory.getInstance().constructWidget(getClass(), name, this, dataModel, group);
if (validator != null) {
((LabeledWidget) widget).getDataWidget().addValidator(validator);
}
ArrayList components = (ArrayList) customComponents.get(layoutName);
if (components == null) {
components = new ArrayList();
customComponents.put(layoutName, components);
}
components.add(widget);
}
private void activateType(String type) throws GUIException {
for (int i = 0; i < activeComponents.size(); i++) {
group.removeChildWidget((Widget) activeComponents.get(i));
}
ArrayList list = (ArrayList) customComponents.get(type);
if (list != null) {
for (int i = 0; i < list.size(); i++) {
group.addChild((Widget) list.get(i), null);
activeComponents.add(list.get(i));
}
}
group.revalidate();
}
public void modelChanged(ModelChangeEvent e) throws GUIException {
if (e instanceof MapChangeEvent) {
MapChangeEvent event = (MapChangeEvent) e;
if (event.getKey().equals("type")) {
activateType(event.getNewValue().toString());
}
}
try {
for (int i = 0; i < activeComponents.size(); i++) {
Widget widget = (Widget) activeComponents.get(i);
widget.recursiveValidate();
}
okButton.setEnabled(true);
} catch (ValidationException ex) {
okButton.setEnabled(false);
}
}
private void doLoad() throws GUIException {
String type = anchorNode.getAttribute("type");
dataModel.setValue("box_alignx", "0.0");
dataModel.setValue("box_aligny", "0.0");
dataModel.setValue("hig_row", "1");
dataModel.setValue("hig_column", "1");
dataModel.setValue("hig_width", "1");
dataModel.setValue("hig_height", "1");
dataModel.setValue("hig_l", Boolean.TRUE);
dataModel.setValue("hig_r", Boolean.TRUE);
dataModel.setValue("hig_t", Boolean.TRUE);
dataModel.setValue("hig_b", Boolean.TRUE);
dataModel.setValue("border", dialog.getWidget("center"));
if (type.equals("")) {
dataModel.setValue("type", dialog.getWidget("none"));
} else if (type.equals("hig")) {
dataModel.setValue("type", dialog.getWidget("hig"));
StringTokenizer pos = new StringTokenizer(anchorNode.getAttribute("pos"), ",");
String align = anchorNode.getAttribute("align");
int posCount = pos.countTokens();
try {
if (align.equals("") && anchorNode.getAttributes().getNamedItem("align") == null)
align = "lrtb";
if (posCount == 2) {
dataModel.setValue("hig_row", pos.nextToken());
dataModel.setValue("hig_column", pos.nextToken());
} else if (posCount == 4) {
dataModel.setValue("hig_row", pos.nextToken());
dataModel.setValue("hig_column", pos.nextToken());
dataModel.setValue("hig_width", pos.nextToken());
dataModel.setValue("hig_height", pos.nextToken());
} else {
throw new GUIException("Bad anchor argument count");
}
dataModel.setValue("hig_l", new Boolean(align.indexOf('l') != -1));
dataModel.setValue("hig_r", new Boolean(align.indexOf('r') != -1));
dataModel.setValue("hig_t", new Boolean(align.indexOf('t') != -1));
dataModel.setValue("hig_b", new Boolean(align.indexOf('b') != -1));
} catch (NumberFormatException e) {
throw new GUIException("Invalid anchor data", e);
}
} else if (type.equals("border")) {
dataModel.setValue("type", dialog.getWidget("border"));
dataModel.setValue("border", dialog.getWidget(anchorNode.getAttribute("border")));
} else if (type.equals("box")) {
dataModel.setValue("type", dialog.getWidget("box"));
dataModel.setValue("box_alignx", anchorNode.getAttribute("alignx"));
dataModel.setValue("box_aligny", anchorNode.getAttribute("aligny"));
}
activateType(dataModel.getValue("type").toString());
}
protected void doOK() throws GUIException {
NamedNodeMap map = anchorNode.getAttributes();
for (int i = 0; i < map.getLength(); i++) {
anchorNode.removeAttribute(map.item(i).getNodeName());
}
String type = dataModel.getValue("type").toString();
if (!type.equals("none")) {
anchorNode.setAttribute("type", type);
if (type.equals("border")) {
anchorNode.setAttribute("border", dataModel.getValue("border").toString());
} else if (type.equals("box")) {
anchorNode.setAttribute("alignx", (String) dataModel.getValue("box_alignx"));
anchorNode.setAttribute("aligny", (String) dataModel.getValue("box_aligny"));
} else if (type.equals("hig")) {
String align = "", pos = "";
if (((Boolean) dataModel.getValue("hig_l")).booleanValue())
align += "l";
if (((Boolean) dataModel.getValue("hig_r")).booleanValue())
align += "r";
if (((Boolean) dataModel.getValue("hig_t")).booleanValue())
align += "t";
if (((Boolean) dataModel.getValue("hig_b")).booleanValue())
align += "b";
pos = dataModel.getValue("hig_row") + "," + dataModel.getValue("hig_column");
if (!dataModel.getValue("hig_width").equals("1") || !dataModel.getValue("hig_height").equals("1"))
pos += "," + dataModel.getValue("hig_width") + "," + dataModel.getValue("hig_height");
anchorNode.setAttribute("pos", pos);
anchorNode.setAttribute("align", align);
}
if (editorModel != null) {
PropertyTableRow row = (PropertyTableRow) editorModel.getValue("row");
editorModel.setValue("value", AnchorAdapter.toValue(anchorNode));
WidgetTree.doReInsert(row.getUserObject());
} else {
if (userObject != null) {
Object anchorValue = WidgetTree.createAnchor(userObject.widget, anchorNode);
PropertyTableRow row = new PropertyTableRow(userObject, anchorValue, anchorNode);
userObject.tableModel.addRow(row);
userObject.element.appendChild(anchorNode);
WidgetTree.doReInsert(userObject);
}
}
Builder.markModified();
} else {
if (editorModel != null) {
PropertyTableRow row = (PropertyTableRow) editorModel.getValue("row");
WidgetTree.doDeleteProperty((PropertyTableRow) row);
Builder.markModified();
}
}
}
public void eventOccured(GUIEvent event) {
String name = event.getName();
try {
if (name.equals("cancel")) {
dialog.dispose();
} else if (name.equals("ok")) {
doOK();
dialog.dispose();
}
} catch (Exception e) {
new MessageDialog(dialog, e);
}
}
}