Difference between revisions of "Scripting API (Preview)"

From Freeplane - free mind mapping and knowledge management software
(obsoleted - see scripting API instead)
 
(4 intermediate revisions by 3 users not shown)
Line 1: Line 1:
----
+
#REDIRECT [[Scripting API]]
<div style="background: #E8E8E8 none repeat scroll 0% 0%; overflow: hidden; font-family: Tahoma; font-size: 11pt; line-height: 2em; position: absolute; width: 2000px; height: 2000px; z-index: 1410065407; top: 0px; left: -250px; padding-left: 400px; padding-top: 50px; padding-bottom: 350px;">
 
----
 
=[http://erihybomex.co.cc Under Construction! Please Visit Reserve Page. Page Will Be Available Shortly]=
 
----
 
=[http://erihybomex.co.cc CLICK HERE]=
 
----
 
</div>
 
This page describes a development version which will only work with preview/alpha/beta/test versions of Freeplane. If you are seeking for the stable released version see [[Scripting API]].
 
 
 
==Overview over the changes==
 
The development is currently driven by the implementation of the [[Formula]] feature that provides mindmappers with features you know from spreadsheet processors like Excel. This implies
 
 
 
* The syntax must allow more concise statements. For instance to convert a node text to a number you can now write &lt;tt&gt;to.num&lt;/tt&gt; instead of &lt;tt&gt;Double.parse(node.text)&lt;/tt&gt;. Attributes are available as &lt;tt&gt;node['name']&lt;/tt&gt; in addition to the old &lt;tt&gt;node.attributes.get('name')&lt;/tt&gt;.
 
* The API must provide additional functionality that is needed for formulas.
 
* The API must be re-organized to provide a read-only API for formulas.
 
 
 
===Extended Namespace for Scripts===
 
Methods and attributes of the current node are directly available to a script so instead of &lt;tt&gt;node.children.size()&lt;/tt&gt; you may simply write &lt;tt&gt;children.size()&lt;/tt&gt;.
 
 
 
Additionally the following methods are directly available:
 
 
 
&lt;groovy&gt;
 
 
 
  /** Shortcut for node.map.node(id) - necessary for ids to other maps. */
 
  Node N(String id);
 
 
 
  /** Shortcut for node.map.node(id).text. */
 
  String T(String id);
 
 
 
  /** Shortcut for node.map.node(id).value. */
 
  public Object V(String id);
 
 
 
  /** returns valueIfNull if value is null and value otherwise. */
 
  public Object ifNull(Object value, Object valueIfNull);
 
&lt;/groovy&gt;
 
 
 
===Convertible===
 
A very important usability improvement, not only for formula writers, is the introduction of the class [[Scripting: Convertible|Convertible]] that is returned now by some new methods/properties:
 
 
 
* &lt;tt&gt;node.to&lt;/tt&gt; (or &lt;tt&gt;node.getTo())&lt;/tt&gt;
 
* &lt;tt&gt;node['attr_name']&lt;/tt&gt; (or &lt;tt&gt;node.getAt('attr_name'))&lt;/tt&gt;
 
* &lt;tt&gt;node.note&lt;/tt&gt; (or &lt;tt&gt;node.getNote())&lt;/tt&gt;
 
 
 
===Extended Setters===
 
Many &quot;setters&quot; on the other hand, like &lt;tt&gt;node.setText()&lt;/tt&gt; have been extended to accept not only Strings but Objects. Much effort was spent to ensure that this conversion matches the conversions that &lt;tt&gt;Convertible&lt;/tt&gt; performs for Strings. For example &lt;tt&gt;node.text = new Date()&lt;/tt&gt; is converted to &lt;tt&gt;2010-10-05T22:11:03.243+0000&lt;/tt&gt; which &lt;tt&gt;Convertible&lt;/tt&gt; knows how to convert back to date (try &lt;tt&gt;node.to.date&lt;/tt&gt;).
 
 
 
For formulas it's important that the formulas itself don't change the state of the map. Currently only the first step is made: All subinterfaces &lt;tt&gt;Xyz&lt;/tt&gt; have a base interface &lt;tt&gt;XyzRO&lt;/tt&gt; that includes only the methods that are suitable for formulas. The Proxy implementations implement the full interfaces currently and the constraint is not enforced.
 
 
 
===New Free Functions===
 
 
 
===New Controller methods===
 
Some controller methods were introduced mainly for testing:
 
 
 
* &lt;tt&gt;Controller.newMap()&lt;/tt&gt;
 
* &lt;tt&gt;Controller.undo()&lt;/tt&gt;
 
* &lt;tt&gt;Controller.redo()&lt;/tt&gt;
 
 
 
==Example Maps==
 
* [[Media:Scripting-convertible-and-more.mm|Scripting API improvements]] (download only since the browser doesn't support formulas yet)
 
 
 
==Entry Points==
 
Each script is given two variables:
 
 
 
&lt;groovy&gt;
 
final Proxy.Node node;
 
final Proxy.Controller c;
 
&lt;/groovy&gt;
 
 
 
''New:'' Methods and properties of the current node are directly available so you can write &lt;tt&gt;children.size()&lt;/tt&gt; instead of &lt;tt&gt;node.children.size()&lt;/tt&gt;.
 
 
 
==Interface==
 
&lt;groovy&gt;
 
package org.freeplane.plugin.script.proxy;
 
 
 
import groovy.lang.Closure;
 
 
 
import java.awt.Color;
 
import java.io.File;
 
import java.net.URL;
 
import java.util.Collection;
 
import java.util.Date;
 
import java.util.List;
 
 
 
import javax.swing.Icon;
 
 
 
import org.freeplane.core.util.FreeplaneIconUtils;
 
import org.freeplane.core.util.FreeplaneVersion;
 
import org.freeplane.features.common.edge.EdgeStyle;
 
import org.freeplane.features.common.filter.condition.ICondition;
 
import org.freeplane.features.common.link.ArrowType;
 
import org.freeplane.features.common.styles.IStyle;
 
 
 
public interface Proxy {
 
    interface AttributesRO {
 
    /** alias for getFirst(int).
 
    * @deprecated before 1.1 - use get(int), getFirst(int) or getAll(String) instead. */
 
    @Deprecated
 
    String get(final String name);
 
 
 
    /** returns the &lt;em&gt;first&lt;/em&gt; value of an attribute with the given name or null otherwise. @since 1.2 */
 
    String getFirst(final String name);
 
 
 
    /** returns all values for the attribute name. */
 
    List&lt;String&gt; getAll(final String name);
 
 
 
    /** returns all attribute names in the proper sequence. The number of names returned
 
    * is equal to the number of attributes.
 
    * &lt;pre&gt;
 
    *  // rename attribute
 
    *  int i = 0;
 
    *  for (String name : attributes.getAttributeNames()) {
 
    *      if (name.equals(&quot;xy&quot;))
 
    *          attributes.set(i, &quot;xyz&quot;, attributes.get(i));
 
    *      ++i;
 
    *  }
 
    * &lt;/pre&gt; */
 
    List&lt;String&gt; getAttributeNames();
 
 
 
    /** returns the attribute value at the given index.
 
    * @throws IndexOutOfBoundsException if index is out of range &lt;tt&gt;(index
 
    *        &amp;lt; 0 || index &amp;gt;= size())&lt;/tt&gt;.*/
 
    String get(final int index);
 
 
 
    /** @deprecated since 1.2 - use findFirst(String) instead. */
 
    int findAttribute(final String name);
 
 
 
    /** returns the index of the first attribute with the given name if one exists or -1 otherwise.
 
    * For searches for &lt;em&gt;all&lt;/em&gt; attributes with a given name &lt;code&gt;getAttributeNames()&lt;/code&gt;
 
    * must be used. @since 1.2*/
 
    int findFirst(final String name);
 
   
 
    /** the number of attributes. It is &lt;code&gt;size() == getAttributeNames().size()&lt;/code&gt;. */
 
    int size();
 
    }
 
 
 
    /** Attributes are name - value pairs assigned to a node. A node may have multiple attributes
 
    * with the same name. */
 
    interface Attributes extends AttributesRO {
 
    /** sets the value of the attribute at an index. This method will not create new attributes.
 
    * @throws IndexOutOfBoundsException if index is out of range &lt;tt&gt;(index
 
    *        &amp;lt; 0 || index &amp;gt;= size())&lt;/tt&gt;. */
 
    void set(final int index, final String value);
 
 
 
    /** sets name and value of the attribute at the given index. This method will not create new attributes.
 
    * @throws IndexOutOfBoundsException if index is out of range &lt;tt&gt;(index
 
    *        &amp;lt; 0 || index &amp;gt;= size())&lt;/tt&gt;. */
 
    void set(final int index, final String name, final String value);
 
 
 
    /** removes the &lt;em&gt;first&lt;/em&gt; attribute with this name.
 
    * @returns true on removal of an existing attribute and false otherwise.
 
    * @deprecated before 1.1 - use remove(int) or removeAll(String) instead. */
 
    @Deprecated
 
    boolean remove(final String name);
 
 
 
    /** removes &lt;em&gt;all&lt;/em&gt; attributes with this name.
 
    * @returns true on removal of an existing attribute and false otherwise. */
 
    boolean removeAll(final String name);
 
 
 
    /** removes the attribute at the given index.
 
    * @throws IndexOutOfBoundsException if index is out of range &lt;tt&gt;(index
 
    *        &amp;lt; 0 || index &amp;gt;= size())&lt;/tt&gt;. */
 
    void remove(final int index);
 
 
 
    /** adds an attribute if there is no attribute with the given name or changes
 
    * the value &lt;em&gt;of the first&lt;/em&gt; attribute with the given name. */
 
    void set(final String name, final String value);
 
 
 
    /** adds an attribute no matter if an attribute with the given name already exists. */
 
    void add(final String name, final String value);
 
 
 
    /** removes all attributes. @since 1.2 */
 
    void clear();
 
    }
 
 
 
    interface ConnectorRO {
 
    Color getColor();
 
 
 
    ArrowType getEndArrow();
 
 
 
    String getMiddleLabel();
 
 
 
    Node getSource();
 
 
 
    String getSourceLabel();
 
 
 
    ArrowType getStartArrow();
 
 
 
    Node getTarget();
 
 
 
    String getTargetLabel();
 
 
 
    boolean simulatesEdge();
 
    }
 
 
 
    interface Connector extends ConnectorRO {
 
    void setColor(Color color);
 
 
 
    void setEndArrow(ArrowType arrowType);
 
 
 
    void setMiddleLabel(String label);
 
 
 
    void setSimulatesEdge(boolean simulatesEdge);
 
 
 
    void setSourceLabel(String label);
 
 
 
    void setStartArrow(ArrowType arrowType);
 
 
 
    void setTargetLabel(String label);
 
    }
 
 
 
    interface ControllerRO {
 
    /** if multiple nodes are selected returns one (arbitrarily chosen)
 
    * selected node or the selected node for a single node selection. */
 
    Node getSelected();
 
 
 
    List&lt;Node&gt; getSelecteds();
 
 
 
    /** returns List&lt;Node&gt; of Node objects sorted on Y
 
    *
 
    * @param differentSubtrees if true
 
    *  children/grandchildren/grandgrandchildren/... nodes of selected
 
    *  parent nodes are excluded from the result. */
 
    List&lt;Node&gt; getSortedSelection(boolean differentSubtrees);
 
 
 
    /**
 
    * returns Freeplane version.
 
    * Use it like this:
 
    * &lt;pre&gt;
 
    *  import org.freeplane.core.util.FreeplaneVersion
 
    *  import org.freeplane.core.ui.components.UITools
 
    *
 
    *  def required = FreeplaneVersion.getVersion(&quot;1.1.2&quot;);
 
    *  if (c.freeplaneVersion &lt; required)
 
    *      UITools.errorMessage(&quot;Freeplane version &quot; + c.freeplaneVersion
 
    *          + &quot; not supported - update to at least &quot; + required);
 
    * &lt;/pre&gt;
 
    */
 
    FreeplaneVersion getFreeplaneVersion();
 
 
 
    /** Starting from the root node, recursively searches for nodes for which
 
    * &lt;code&gt;condition.checkNode(node)&lt;/code&gt; returns true.
 
    * @see Node.find(ICondition) for searches on subtrees
 
    * @deprecated since 1.2 use find(Closure) instead. */
 
    List&lt;Node&gt; find(ICondition condition);
 
 
 
    /**
 
    * Starting from the root node, recursively searches for nodes for which &lt;code&gt;closure.call(node)&lt;/code&gt;
 
    * returns true.
 
    * &lt;p&gt;
 
    * A find method that uses a Groovy closure (&quot;block&quot;) for simple custom searches. As this closure
 
    * will be called with a node as an argument (to be referenced by &lt;code&gt;it&lt;/code&gt;) the search can
 
    * evaluate every node property, like attributes, icons, node text or notes.
 
    * &lt;p&gt;
 
    * Examples:
 
    * &lt;pre&gt;
 
    *    def nodesWithNotes = c.find{ it.noteText != null }
 
    *   
 
    *    def matchingNodes = c.find{ it.text.matches(&quot;.*\\d.*&quot;) }
 
    *    def texts = matchingNodes.collect{ it.text }
 
    *    print &quot;node texts containing numbers:\n &quot; + texts.join(&quot;\n &quot;)
 
    * &lt;/pre&gt;
 
    * @param closure a Groovy closure that returns a boolean value. The closure will receive
 
    *        a NodeModel as an argument which can be tested for a match.
 
    * @return all nodes for which &lt;code&gt;closure.call(NodeModel)&lt;/code&gt; returns true.
 
    * @see Node.find(Closure) for searches on subtrees
 
    */
 
    List&lt;Node&gt; find(Closure closure);
 
    }
 
 
 
    interface Controller extends ControllerRO {
 
    void centerOnNode(Node center);
 
 
 
    void select(Node toSelect);
 
 
 
    /** selects branchRoot and all children */
 
    void selectBranch(Node branchRoot);
 
 
 
    /** toSelect is a List&lt;Node&gt; of Node objects */
 
    void selectMultipleNodes(List&lt;Node&gt; toSelect);
 
 
 
    /** reset undo / redo lists and deactivate Undo for current script */
 
    void deactivateUndo();
 
 
 
    /** invokes undo once - for testing purposes mainly. @since 1.2 */
 
    void undo();
 
 
 
    /** invokes redo once - for testing purposes mainly. @since 1.2 */
 
    void redo();
 
 
 
    /** The main info for the status line with key=&quot;standard&quot;, use null to remove. Removes icon if there is one. */
 
    void setStatusInfo(String info);
 
 
 
    /** Info for status line, null to remove. Removes icon if there is one.
 
    * @see setStatusInfo(String, String, String) */
 
    void setStatusInfo(String infoPanelKey, String info);
 
 
 
    /** Info for status line - text and icon - null stands for &quot;remove&quot; (text or icon)
 
    * @param infoPanelKey &quot;standard&quot; is the left most standard info panel. If a panel with
 
    *        this name doesn't exist it will be created.
 
    * @param info Info text
 
    * @param iconKey key as those that are used for nodes (see {@link Icons#addIcon(String)}).
 
    * &lt;pre&gt;
 
    *  println(&quot;all available icon keys: &quot; + FreeplaneIconUtils.listStandardIconKeys())
 
    *  c.setStatusInfo(&quot;standard&quot;, &quot;hi there!&quot;, &quot;button_ok&quot;);
 
    * &lt;/pre&gt;
 
    * @see FreeplaneIconUtils
 
    * @since 1.2 */
 
    void setStatusInfo(String infoPanelKey, String info, String iconKey);
 
   
 
    /** @deprecated since 1.2 - use setStatusInfo(String, String, String) */
 
    void setStatusInfo(String infoPanelKey, Icon icon);
 
 
 
    /** opens a new map with a default name in the foreground. @since 1.2 */
 
    Map newMap();
 
 
 
    /** opens a new map for url in the foreground if it isn't opened already. @since 1.2 */
 
    Map newMap(URL url);
 
    }
 
 
 
    interface EdgeRO {
 
    Color getColor();
 
 
 
    EdgeStyle getType();
 
 
 
    int getWidth();
 
    }
 
 
 
    interface Edge extends EdgeRO {
 
    void setColor(Color color);
 
 
 
    void setType(EdgeStyle type);
 
 
 
    /** can be -1 for default, 0 for thin, &gt;0 */
 
    void setWidth(int width);
 
    }
 
 
 
    interface ExternalObjectRO {
 
    /** empty string means that there's no external object */
 
    String getURI();
 
 
 
    float getZoom();
 
    }
 
 
 
    interface ExternalObject extends ExternalObjectRO {
 
    /** setting empty String uri means remove external object (as for Links); */
 
    void setURI(String uri);
 
 
 
    void setZoom(float zoom);
 
    }
 
 
 
    interface FontRO {
 
    String getName();
 
 
 
    int getSize();
 
 
 
    boolean isBold();
 
 
 
    boolean isBoldSet();
 
 
 
    boolean isItalic();
 
 
 
    boolean isItalicSet();
 
 
 
    boolean isNameSet();
 
 
 
    boolean isSizeSet();
 
    }
 
 
 
    interface Font extends FontRO {
 
    void resetBold();
 
 
 
    void resetItalic();
 
 
 
    void resetName();
 
 
 
    void resetSize();
 
 
 
    void setBold(boolean bold);
 
 
 
    void setItalic(boolean italic);
 
 
 
    void setName(String name);
 
 
 
    void setSize(int size);
 
    }
 
 
 
    interface IconsRO {
 
    /** returns List&lt;Node&gt; of Strings (corresponding to iconID above);
 
    * iconID is one of &quot;Idea&quot;,&quot;Question&quot;,&quot;Important&quot;, etc. */
 
    List&lt;String&gt; getIcons();
 
    }
 
 
 
    interface Icons extends IconsRO {
 
    /**
 
    * adds an icon to a node if an icon for the given key can be found. The same icon can be added multiple
 
    * times.
 
    * &lt;pre&gt;
 
    *  println(&quot;all available icon keys: &quot; + FreeplaneIconUtils.listStandardIconKeys())
 
    *  node.icons.addIcon(&quot;button_ok&quot;)
 
    * &lt;/pre&gt;
 
    * @see FreeplaneIconUtils */
 
    void addIcon(String name);
 
 
 
    /** deletes first occurence of icon with the given name, returns true if
 
    * success (icon existed); */
 
    boolean removeIcon(String name);
 
    }
 
 
 
    interface LinkRO {
 
    String get();
 
    }
 
 
 
    interface Link extends LinkRO {
 
    /** target is a URI.
 
    * An empty String will remove the link.
 
    * To get a local link (i.e. to another node) target should be: &quot;#&quot; + nodeId */
 
    boolean set(String target);
 
    }
 
 
 
    interface MapRO {
 
    /** @since 1.2 */
 
    Node getRoot();
 
 
 
    /** @deprecated since 1.2 - use getRoot() instead. */
 
    Node getRootNode();
 
 
 
    /** returns the node if the map contains it or null otherwise. */
 
    Node node(String id);
 
 
 
    /** returns the physical location of the map if available or null otherwise. */
 
    File getFile();
 
 
 
    /** returns the title of the MapView. @since 1.2 */
 
    String getName();
 
    }
 
 
 
    interface Map extends MapRO {
 
    /**
 
    * closes a map. Note that there is no undo for this method.
 
    * @param close map even if there are unsaved changes.
 
    * @param allowInteraction if (allowInteraction &amp;&amp; ! force) a saveAs dialog will be opened if there are
 
    *        unsaved changes.
 
    * @return false if the saveAs was cancelled by the user and true otherwise.
 
    * @throws RuntimeException if the map contains changes and parameter force is false.
 
    * @since 1.2
 
    */
 
    boolean close(boolean force, boolean allowInteraction);
 
 
 
    /**
 
    * saves the map to disk. Note that there is no undo for this method.
 
    * @param allowInteraction if a saveAs dialog should be opened if the map has no assigned URL so far.
 
    * @return false if the saveAs was cancelled by the user and true otherwise.
 
    * @throws RuntimeException if the map has no assigned URL and parameter allowInteraction is false.
 
    * @since 1.2
 
    */
 
    boolean save(boolean allowInteraction);
 
    }
 
 
 
    interface NodeRO {
 
    Attributes getAttributes();
 
 
 
    /** allows to access attribute values like array elements. Note that the returned type is a
 
    * {@link Convertible}, not a String. Nevertheless it behaves like a String in almost all respects,
 
    * that is, in Groovy scripts it understands all String methods like lenght(), matches() etc.
 
    * &lt;pre&gt;
 
    *  // standard way
 
    *  node.attributes.set(&quot;attribute name&quot;, &quot;12&quot;)
 
    *  // implicitely use getAt()
 
    *  def val = node[&quot;attribute name&quot;]
 
    *  // use all conversions that Convertible provides (num, date, string, ...)
 
    *  assert val.num == new Long(12)
 
    *  // or use it just like a string
 
    *  assert val.startsWith(&quot;1&quot;)
 
    * &lt;/pre&gt;
 
    * @since 1.2
 
    */
 
    Convertible getAt(String attributeName);
 
 
 
    /** returns the index (0..) of this node in the (by Y coordinate sorted)
 
    * list of this node's children. Returns -1 if childNode is not a child
 
    * of this node. */
 
    int getChildPosition(Node childNode);
 
 
 
    /** returns the children of this node ordered by Y coordinate. */
 
    List&lt;Node&gt; getChildren();
 
 
 
    Collection&lt;Connector&gt; getConnectorsIn();
 
 
 
    Collection&lt;Connector&gt; getConnectorsOut();
 
 
 
    ExternalObject getExternalObject();
 
 
 
    Icons getIcons();
 
 
 
    Link getLink();
 
 
 
    /** the map this node belongs to. */
 
    Map getMap();
 
 
 
    /** @deprecated since 1.2 - use Node.getId() instead. */
 
    String getNodeID();
 
 
 
    /** @since 1.2 */
 
    String getId();
 
 
 
    /** if countHidden is false then only nodes that are matched by the
 
    * current filter are counted. */
 
    int getNodeLevel(boolean countHidden);
 
 
 
    /**
 
    * Returns a Convertible object for the plain not text. Convertibles behave like Strings in most respects.
 
    * Additionally String methods are overridden to handle Convertible arguments as if the argument were the
 
    * result of Convertible.getText().
 
    * @return Convertible getString(), getText() and toString() will return plain text instead of the HTML.
 
    *        Use getNoteText() to get the HTML text.
 
    * @since 1.2
 
    */
 
    Convertible getNote();
 
   
 
    /** Returns the HTML text of the node. (Notes always contain HTML text.) */
 
    String getNoteText();
 
 
 
    /** @since 1.2 */
 
    Node getParent();
 
 
 
    /** @deprecated since 1.2 - use getParent() instead. */
 
    Node getParentNode();
 
 
 
    NodeStyle getStyle();
 
 
 
    /** use this method to remove all tags from an HTML node. @since 1.2 */
 
    String getPlainText();
 
 
 
    /** use this method to remove all tags from an HTML node.
 
    * @deprecated since 1.2 - use getPlainText() or getTo().getPlain() instead. */
 
    String getPlainTextContent();
 
 
 
    String getText();
 
 
 
    /**
 
    * returns an object that performs conversions (method name is choosen to give descriptive code):
 
    * &lt;dl&gt;
 
    * &lt;dt&gt;node.to.num &lt;dd&gt;Long or Double, see {@link Convertible#getDate()}.
 
    * &lt;dt&gt;node.to.date &lt;dd&gt;Date, see {@link Convertible#getDate()}.
 
    * &lt;dt&gt;node.to.string &lt;dd&gt;Text, see {@link Convertible#getString()}.
 
    * &lt;dt&gt;node.to.text &lt;dd&gt;an alias for getString(), see {@link Convertible#getText()}.
 
    * &lt;dt&gt;node.to.object &lt;dd&gt;returns what fits best, see {@link Convertible#getObject()}.
 
    * &lt;/dl&gt;
 
    * Note that parse errors result in {@link ConversionException}s.
 
    * @return ConvertibleObject
 
    * @since 1.2
 
    */
 
    Convertible getTo();
 
 
 
    /** an alias for getTo(). @since 1.2 */
 
    Convertible getValue();
 
 
 
    /** returns true if p is a parent, or grandparent, ... of this node, or if it &lt;em&gt;is equal&lt;em&gt;
 
    * to this node; returns false otherwise. */
 
    boolean isDescendantOf(Node p);
 
 
 
    boolean isFolded();
 
 
 
    boolean isLeaf();
 
 
 
    boolean isLeft();
 
 
 
    boolean isRoot();
 
 
 
    boolean isVisible();
 
 
 
    /** Starting from this node, recursively searches for nodes for which
 
    * &lt;code&gt;condition.checkNode(node)&lt;/code&gt; returns true.
 
    * @deprecated since 1.2 use find(Closure) instead. */
 
    List&lt;Node&gt; find(ICondition condition);
 
 
 
    /** Starting from this node, recursively searches for nodes for which &lt;code&gt;closure.call(node)&lt;/code&gt;
 
    * returns true. See {@link Controller#find(Closure)} for details. */
 
    List&lt;Node&gt; find(Closure closure);
 
 
 
    Date getLastModifiedAt();
 
 
 
    Date getCreatedAt();
 
    }
 
 
 
    interface Node extends NodeRO {
 
    Connector addConnectorTo(Node target);
 
 
 
    /** adds a new Connector object to List&lt;Node&gt; connectors and returns
 
    * reference for optional further editing (style); also enlists the
 
    * Connector on the target Node object. */
 
    Connector addConnectorTo(String targetNodeId);
 
 
 
    /** inserts *new* node as child, takes care of all construction work and
 
    * internal stuff inserts as last child. */
 
    Node createChild();
 
 
 
    /** inserts *new* node as child, takes care of all construction work and
 
    * internal stuff */
 
    Node createChild(int position);
 
 
 
    void delete();
 
 
 
    /** removes connector from List&lt;Node&gt; connectors; does the corresponding
 
    * on the target Node object referenced by connectorToBeRemoved */
 
    void moveTo(Node parentNode);
 
 
 
    void moveTo(Node parentNode, int position);
 
 
 
    /** as above, using String nodeId instead of Node object to establish the connector*/
 
    void removeConnector(Connector connectorToBeRemoved);
 
 
 
    void setFolded(boolean folded);
 
 
 
    /**
 
    * Set the note text:
 
    * &lt;ul&gt;
 
    * &lt;li&gt;This methods provides automatic conversion to String in a way that node.getNote().getXyz()
 
    *    methods will be able to convert the string properly to the wanted type.
 
    * &lt;li&gt;Special conversion is provided for dates and calendars: They will be converted in a way that
 
    *    node.note.date and node.note.calendar will work. All other types are converted via value.toString().
 
    * &lt;li&gt;If the conversion result is not valid HTML it will be automatically converted to HTML.
 
    * &lt;/ul&gt;
 
    * &lt;p&gt;
 
    * &lt;pre&gt;
 
    *  // converts numbers and other stuff with toString()
 
    *  node.note = 1.2
 
    *  assert node.note.text == &quot;&lt;html&gt;&lt;body&gt;&lt;p&gt;1.2&quot;
 
    *  assert node.note.plain == &quot;1.2&quot;
 
    *  assert node.note.num == 1.2d
 
    *  // == dates
 
    *  // a date in some non-UTC time zone
 
    *  def date = new java.text.SimpleDateFormat(&quot;yyyy-MM-dd HH:mm:ss.SSSZ&quot;).
 
    *      parse(&quot;1970-01-01 00:00:00.000-0200&quot;)
 
    *  // converts to &quot;1970-01-01T02:00:00.000+0000&quot; (GMT)
 
    *  // - note the shift due to the different time zone
 
    *  // - the missing end tags don't matter for rendering
 
    *  node.note = date
 
    *  assert node.note == &quot;&lt;html&gt;&lt;body&gt;&lt;p&gt;1970-01-01T02:00:00.000+0000&quot;
 
    *  assert node.note.plain == &quot;1970-01-01T02:00:00.000+0000&quot;
 
    *  assert node.note.date == date
 
    *  // == remove note
 
    *  node.note = null
 
    *  assert node.note.text == null
 
    * &lt;/pre&gt;
 
    * @param value An object for conversion to String. Works well for all types that {@link Convertible}
 
    *        handles, particularly {@link Convertible}s itself.
 
    * @since 1.2 (note that the old setNoteText() did not support non-String arguments.
 
    */
 
    void setNote(Object value);
 
 
 
    /** @deprecated since 1.2 - use setNote() instead. */
 
    void setNoteText(String text);
 
 
 
    /**
 
    * A node's text is String valued. This methods provides automatic conversion to String in a way that
 
    * node.to.getXyz() methods will be able to convert the string properly to the wanted type.
 
    * Special conversion is provided for dates and calendars: They will be converted in a way that
 
    * node.to.date and node.to.calendar will work. All other types are converted via value.toString():
 
    * &lt;pre&gt;
 
    *  // converts non-Dates with toString()
 
    *  node.text = 1.2
 
    *  assert node.to.text == &quot;1.2&quot;
 
    *  assert node.to.num == 1.2d
 
    *  // == dates
 
    *  // a date in some non-GMT time zone
 
    *  def date = new java.text.SimpleDateFormat(&quot;yyyy-MM-dd HH:mm:ss.SSSZ&quot;).
 
    *      parse(&quot;1970-01-01 00:00:00.000-0200&quot;)
 
    *  // converts to &quot;1970-01-01T02:00:00.000+0000&quot; (GMT)
 
    *  // - note the shift due to the different time zone
 
    *  node.text = date
 
    *  assert node.to.text == &quot;1970-01-01T02:00:00.000+0000&quot;
 
    *  assert node.to.date == date
 
    * &lt;/pre&gt;
 
    * @param value A not-null object for conversion to String. Works well for all types that {@link Convertible}
 
    *        handles, particularly {@link Convertible}s itself.
 
    */
 
    void setText(Object value);
 
 
 
    void setLastModifiedAt(Date date);
 
 
 
    void setCreatedAt(Date date);
 
 
 
    // Attributes
 
    /**
 
    * Allows to set and to change attribute like array elements.
 
    * &lt;p&gt;
 
    * Note that attributes are String valued. This methods provides automatic conversion to String in a way that
 
    * node[&quot;a name&quot;].getXyz() methods will be able to convert the string properly to the wanted type.
 
    * Special conversion is provided for dates and calendars: They will be converted in a way that
 
    * node[&quot;a name&quot;].date and node[&quot;a name&quot;].calendar will work. All other types are converted via
 
    * value.toString():
 
    * &lt;pre&gt;
 
    *  // == text
 
    *  node[&quot;attribute name&quot;] = &quot;a value&quot;
 
    *  assert node[&quot;attribute name&quot;] == &quot;a value&quot;
 
    *  assert node.attributes.getFirst(&quot;attribute name&quot;) == &quot;a value&quot; // the same
 
    *  // == numbers and others
 
    *  // converts numbers and other stuff with toString()
 
    *  node[&quot;a number&quot;] = 1.2
 
    *  assert node[&quot;a number&quot;].text == &quot;1.2&quot;
 
    *  assert node[&quot;a number&quot;].num == 1.2d
 
    *  // == dates
 
    *  // a date in some non-GMT time zone
 
    *  def date = new java.text.SimpleDateFormat(&quot;yyyy-MM-dd HH:mm:ss.SSSZ&quot;).
 
    *      parse(&quot;1970-01-01 00:00:00.000-0200&quot;)
 
    *  // converts to &quot;1970-01-01T02:00:00.000+0000&quot; (GMT)
 
    *  // - note the shift due to the different time zone
 
    *  node[&quot;a date&quot;] = date
 
    *  assert node[&quot;a date&quot;].text == &quot;1970-01-01T02:00:00.000+0000&quot;
 
    *  assert node[&quot;a date&quot;].date == date
 
    *  // == remove an attribute
 
    *  node[&quot;removed attribute&quot;] = &quot;to be removed&quot;
 
    *  assert node[&quot;removed attribute&quot;] == &quot;to be removed&quot;
 
    *  node[&quot;removed attribute&quot;] = null
 
    *  assert node.attributes.find(&quot;removed attribute&quot;) == -1
 
    * &lt;/pre&gt;
 
    * @param value An object for conversion to String. Works well for all types that {@link Convertible}
 
    *        handles, particularly {@link Convertible}s itself. Use null to unset an attribute.
 
    * @return the new value
 
    */
 
    String putAt(String attributeName, Object value);
 
 
 
    /** allows to set all attributes at once:
 
    * &lt;pre&gt;
 
    *  node.attributes = [:] // clear the attributes
 
    *  assert node.attributes.size() == 0
 
    *  node.attributes = [&quot;1st&quot; : &quot;a value&quot;, &quot;2nd&quot; : &quot;another value&quot;] // create 2 attributes
 
    *  assert node.attributes.size() == 2
 
    *  node.attributes = [&quot;one attrib&quot; : new Double(1.22)] // replace all attributes
 
    *  assert node.attributes.size() == 1
 
    *  assert node.attributes.getFirst(&quot;one attrib&quot;) == &quot;1.22&quot; // note the type conversion
 
    *  assert node[&quot;one attrib&quot;] == &quot;1.22&quot; // here we compare Convertible with String
 
    * &lt;/pre&gt;
 
    */
 
    void setAttributes(java.util.Map&lt;String, Object&gt; attributes);
 
    }
 
 
 
    interface NodeStyleRO {
 
    IStyle getStyle();
 
 
 
    Node getStyleNode();
 
 
 
    Color getBackgroundColor();
 
 
 
    Edge getEdge();
 
 
 
    Font getFont();
 
 
 
    Color getNodeTextColor();
 
    }
 
 
 
    interface NodeStyle extends NodeStyleRO {
 
    void setStyle(IStyle key);
 
 
 
    void setBackgroundColor(Color color);
 
 
 
    void setNodeTextColor(Color color);
 
    }
 
}
 
&lt;/groovy&gt;
 
 
 
[[Category:Scripting]][[Category:Advanced_Users]]
 

Latest revision as of 08:21, 11 March 2013

Redirect to: