import waba.ui.*;
import waba.sys.*;
import waba.fx.*;
import waba.util.*;
import superwaba.ext.xplat.ui.MultiEdit;
import superwaba.ext.xplat.xml.*;
public class EditFmNode extends Container {
private Tree tree;
private TreeModel model;
private Node node;
private ScaledIcons icons;
private FmParser fmp;
private FreeMindNode fmNode;
private Button btnQuit;
private Button btnExtended;
private Button btnOk;
private Edit standardEdit;
private MultiEdit editDescription;
private ListBox listAtts; /* A drop-down list of attributes. */
private ComboBox cbxAttrs;
private int bigEditBoxHeight = Settings.screenHeight / 3;
private boolean extendedEdit = false;
private boolean newNode = false;
private Vector buttonList = new Vector(); /* Buttons for the icons. */
private boolean[] iconSelected;
/* Tells us if the icon button is active or not. */
/**
* Edit a node of a tree. If no node is specified, add a new one as a child
* of the currently selected node in the tree.
* @param fmp Parser, needed for icon images and types.
* @param model Model containing this tree's node.
* @param node node to edit or null for new node.
*/
public EditFmNode(ScaledIcons icons, TreeModel model) {
super();
tree = model.getTree();
this.model = model;
this.icons = icons;
}
public void onStart() {
btnQuit = new Button("Quit");
add(btnQuit, LEFT, BOTTOM);
btnExtended = new Button("Extended");
add(btnExtended, AFTER + 2, BOTTOM);
btnOk = new Button(" OK ");
add(btnOk, AFTER + 2, BOTTOM);
/* Reserve space for a combobox */
cbxAttrs = new ComboBox(new ListBox(new String[] { "A", "B", "C" }));
add(cbxAttrs);
cbxAttrs.setRect(LEFT, TOP, FILL, PREFERRED);
/* Create a standard text box. */
add(standardEdit = new Edit(), CENTER, AFTER + 1);
standardEdit.setRect(LEFT, SAME, FILL, PREFERRED);
/* Put up a selection of icons below where the large edit field goes. */
int icony = standardEdit.getRect().y + bigEditBoxHeight;
int iconx = 0;
Button b;
iconSelected = new boolean[icons.allIcons.size()];
for (int i = 0; i < icons.allIcons.size(); i++) {
Image bImg = (Image) (icons.allIcons.items[i]);
b = new Button(bImg);
add(b);
b.setRect(iconx, icony, icons.iconSize + 8, icons.iconSize + 8);
/* Mark icons we've got as selected. Assume they're not. */
b.setBorder(BORDER_NONE);
b.setGap(0);
iconSelected[i] = false;
/* Allow plenty for border and spacing. */
iconx += icons.iconSize + 8;
buttonList.add(b);
}
}
/** Populate the container edit fields etc. with the contents of this node.
*
* @param n Node to take editable data from.
*/
public void populateContainer(Node n) {
if (n == null) {
newNode = true;
this.node = prepareNewNode();
} else {
newNode = false;
this.node = tree.getSelectedNode();
}
/* Stop if we couldn't make a node. */
if (this.node == null) {
waba.sys.Vm.debug("Unable to make or open edit node.");
getParentWindow().swap(null);
} else {
fmNode = (FreeMindNode) this.node.getUserObject();
}
/* Trap dud nodes. */
if (node == null) {
add(new Label("Nothing to edit."), CENTER, CENTER);
return;
}
/* List the attributes */
AttributeList.Iterator a = fmNode.atts.new Iterator();
int textItem = 0;
int i = 0;
String selectedText = "";
listAtts = new ListBox();
while (a.next()) {
listAtts.add(a.getAttributeAsString());
if (a.getAttributeName().equals("TEXT")) {
textItem = i;
selectedText = a.getAttributeValue();
}
i++;
}
/* House list in a combobox */
if (cbxAttrs!=null) remove(cbxAttrs);
cbxAttrs = new ComboBox(listAtts);
add(cbxAttrs);
cbxAttrs.setRect(LEFT, TOP, FILL, PREFERRED);
cbxAttrs.select(textItem);
/* Fill the standard text box. */
standardEdit.setText(selectedText);
/* If the extended edit is selected, remove any old extened edit box and
* create a new one. */
if (extendedEdit == true) {
if (editDescription != null) {
remove(editDescription);
editDescription = null;
}
setExtendedEdit();
}
extendedEdit = false;
/* Loop round for all button icons, and set their borders if this entry uses them. */
for (i = 0; i < buttonList.size(); i++) {
/* Pick the button. */
Button b = (Button) buttonList.items[i];
Image bImg = b.getImage();
/* Assume no border needed. */
b.setBorder(BORDER_NONE);
iconSelected[i] = false;
/* If this is an icon we know about, add a visible border. */
for (int j = 0; j < node.userIcons.size(); j++) {
if (((NodeIcon) (node.userIcons.items[j])).getImage()
== bImg) {
b.setBorder(BORDER_SIMPLE);
iconSelected[i] = true;
break;
}
}
}
/* Position the cursor at the end of any text. */
standardEdit.setCursorPos(
standardEdit.getLength(),
standardEdit.getLength());
getParentWindow().repaintNow();
}
/**
* Standard event handler.
*/
public void onEvent(Event event) {
int n; /* Number of button found. */
switch (event.type) {
case ControlEvent.PRESSED :
if (event.target == btnQuit) {
/* Byebye */
getParentWindow().swap(null);
} else if (event.target == btnOk) {
/* If we have been editing a new node, add it in. */
if (newNode) {
Node oldNode = tree.getSelectedNode();
tree.collapse(oldNode);
/* Tack the new child onto the end of the node's list. */
model.insertNode(oldNode, node, -1);
tree.expand(oldNode);
tree.select(node);
}
/* Tack selected icons onto node. */
node.deleteIcons();
for (int i = 0; i < iconSelected.length; i++) {
if (iconSelected[i]) {
/* Add this icon into the tree's node with a BUILTIN attribute. */
AttributeList a = new AttributeList();
a.addAttribute(
"BUILTIN",
(String) (icons.iconNames.items[i]),
(byte) '"');
node.addIcon(
new FmIcon((Image) icons.allIcons.items[i], a));
}
}
/* Set the required attribute. Find out what one we've picked. */
String key[] =
splitTo(((String) listAtts.getSelectedItem()), "=");
/* Trash the old object */
fmNode.atts.remove(key[0]);
/* Add in the new value. */
String s;
if (extendedEdit) {
s = editDescription.getText();
} else {
s = standardEdit.getText();
}
fmNode.atts.addAttribute(key[0], s, (byte) ('\"'));
/* Byebye */
getParentWindow().swap(null);
} else if (event.target == btnExtended) {
/* User is trying to switch to extended edit mode. */
if (extendedEdit) {
/* We're already in extended edit mode. Go back to one-line mode. */
extendedEdit = false;
standardEdit.setText(editDescription.getText());
/* When we remove a Mulit-edit box, the area is not correctly redrawn.
* so we blank it manually. */
remove(editDescription);
editDescription = null;
standardEdit.requestFocus();
standardEdit.setCursorPos(
standardEdit.getLength(),
standardEdit.getLength());
getParentWindow().repaintNow();
} else {
/* We're not in extended edit mode. Go there. */
setExtendedEdit();
}
} else if (event.target == cbxAttrs) {
/* Get the data for the selected attribute and pop it in the edit control. */
String key[] =
splitTo(((String) listAtts.getSelectedItem()), "=");
if (extendedEdit) {
editDescription.setText(
fmNode.atts.getAttributeValue(key[0]));
editDescription.repaintNow();
} else {
standardEdit.setText(
fmNode.atts.getAttributeValue(key[0]));
}
} else if ((n = buttonList.find(event.target)) >= 0) {
/* Toggle the selected state for the icon. */
Button b = ((Button) (buttonList.items[n]));
if (iconSelected[n]) {
b.setBorder(BORDER_NONE);
iconSelected[n] = false;
} else {
b.setBorder(BORDER_RAISED);
iconSelected[n] = true;
}
}
break;
case ControlEvent.FOCUS_IN :
if ((event.target == this) && (standardEdit != null)) {
standardEdit.requestFocus();
}
break;
}
}
/**
* Create a new node with TEXT attribute.
* @param tf
* @return
*/
private Node prepareNewNode() {
/* Create a new child node with a TEXT attribute. Collapse the node first
* to get around an unexplored redraw bug. */
AttributeList newAtts = new AttributeList();
newAtts.addAttribute("TEXT", "", (byte) 0);
Node newNode =
new Node(new FreeMindNode(null, newAtts, FmParser.nodeTag));
/* Text nodes may have children. */
newNode.setAllowsChildren(true);
return newNode;
}
private String[] splitTo(String source, String splitter) {
int x = source.indexOf(splitter);
if (x < 0) {
/* String not there. return nothings. */
return null;
} else {
String[] s = new String[2];
s[0] = source.substring(0, x);
s[1] = source.substring(x + splitter.length());
return s;
}
}
/* Take a standard edit field and switch it into extended edit. */
private void setExtendedEdit() {
extendedEdit = true;
String s = standardEdit.getText();
Rect r = standardEdit.getRect();
add(editDescription = new MultiEdit(2, 1), CENTER, r.y);
editDescription.setText(s);
editDescription.setRect(LEFT, SAME, FILL, bigEditBoxHeight);
editDescription.requestFocus();
}
}