Created with JBuilder
package multivalent.std;

import multivalent.*;
import multivalent.gui.VCheckbox;

	Augment selection for clipboard with author, title.
	Elaborately commented to serve as a simple example of translating Multivalent protocols into methods.
public class ClipProvenance extends Behavior {
  protected boolean active_ = false;

	When the Clipboard menu announces it is being built by sending a semantic event with
	message "createWidget/Clipboard" and the node of the menu root in the out field,
	add an entry.  The entry uses createUI method defined in Behavior
	with the right parameters to create a "checkbox" widget with title "Provenance",
	which when invoked will execute the script which sends a semantic event named "toggleProvenance",
	added to the menu in category "AuxSelect", and which is not disabled (diabled flag = false).
  public boolean semanticEventBefore(SemanticEvent se, String msg) {
	// call superclass.  In before protocols, this call is usually done before the subclass.
	// If the superclass is short-circuiting (returns true), respect that.
	// (In this case, we could have omitted this since we're inheriting directly from Behavior, and Behavior doesn't have any default behavior, but that's dangerous.)
	if (super.semanticEventBefore(se, msg)) return true;

	else if ("createWidget/Clipboard"==msg) {
		INode menu = (INode)se.getOut();
		VCheckbox cb = (VCheckbox)createUI("checkbox", "Provenance", "event toggleProvenance", menu, "AuxSelect", false);

	// returning true would short-circuit other behaviors, which is seldom the right thing
	return false;

	Catch the "toggleProvenance" event sent in semanticEventBefore,
	assuming it hasn't been short-circuited by some other behavior.
	This just toggles the internal active flag, to determine whether
	to take action in the next clipboard procotol.  Note that any behavior
	can communicate with ClipProvenance at this high level by sending
	the message it understands, namely "toggleProvenance"; other behaviors
	don't have to work through its GUI or have hardcoded to some particular
	method signature--they just send in the event the right String
	as socially agreed upon (or proclaimed, that is, documented, by ClipProvenance).
  public boolean semanticEventAfter(SemanticEvent se, String msg) {
	if ("toggleProvenance"==msg) active_=!active_;

	// in after phases, we invoke the superclass afterwards,
	// and unless we want to short-circuit, the overall short-circuit is the superclass's short-circuit
	return super.semanticEventAfter(se, msg);

	This behavior has its effect (if it's active) during the clipboard protocol,
	but that protocol is based on a tree walk, so if it is to know of the tree
	walk, it has to hook into the tree.  It registers interest during buildAfter,
	as we know the tree will have been built by this point, and registers
	interest on the root of the document, which is passed as a parameter,
	in order to pick up clipboard extractions everywhere in the tree.
	It's common for a behavior to register interest at the root as opposed to
	smaller subtrees.
  public void buildAfter(Document doc) {

	The clipboard protocol builds up the text in a StringBuffer.
	Since this is the after phase, we know that the tree walk has taken place,
	and therefore the StringBuffer holds the text one expects from
	copying the selection into the clipboard.  If the behavior is active (as
	set by its GUI, slip the URL in at the head of the StringBuffer.
  public boolean clipboardAfter(StringBuffer sb, Node node) {
//System.out.println("ClipProvenance clipboardAfter "+node);
	if (active_) {
		Browser br = getBrowser();
		// simple action: insert URL at head
		// if excerpt is long, insert a blank line too.
		sb.insert(0, "From "+br.getCurDocument().getURL()+(sb.length()<80*4? "\n": "\n\n"));

		// If we had more metadata, such as author and title, that would be great.
		// If some convention were established, another behavior could check and further augment the clipboard.
		// Maybe the metadata is kept in a database and can be fetched with an ISBN attached to the document,
		// or perhaps one or more particular new document formats carry this metadata,
		// in which case site- or genre-specific behavior could take advantage of it.
		//Node root = getBrowser().getCurDocument();
		//sb.insert(0, "From \""+root.getAttr("title")+"\" by "+root.getAttr("author")+" in "+root.getAttr("source")+":\n\n");
	return false;
Created with JBuilder