diff --git a/spi.viewmodel/apichanges.xml b/spi.viewmodel/apichanges.xml
--- a/spi.viewmodel/apichanges.xml
+++ b/spi.viewmodel/apichanges.xml
@@ -399,6 +399,39 @@
+
+
+ Separate the value and HTML value and allow custom property editors.
+
+
+
+
+
+ So far the HTML value is automatically retrieved from the value provided
+ by the TableModel
when the value is a String
+ and contains HTML code. This is not flexible enough and therefore
+ we separate the value and HTML value by introduction of TableHTMLModel
+ and TableHTMLModelFilter
.
+ In addition to that, this API change also brings a prossibility
+ to provide custom property editor, separately for every value.
+ Two interfaces are introduced for this purpose: TablePropertyEditorsModel
+ and TablePropertyEditorsModelFilter
.
+ This also implies, that Models.CompoundModel
now implements
+ TableHTMLModel
and TablePropertyEditorsModel
.
+ In order to be able to fire changes in HTML value and also in r/w state,
+ an additional constructor of ModelEvent.TableValueChanged
+ is added, which takes the change mask. Three change masks are defined:
+ VALUE_MASK
, HTML_VALUE_MASK
and IS_READ_ONLY_MASK
.
+ To get the change mask, ModelEvent.TableValueChanged.getChange()
+ method is added.
+
+
+
+
+
+
+
+
diff --git a/spi.viewmodel/manifest.mf b/spi.viewmodel/manifest.mf
--- a/spi.viewmodel/manifest.mf
+++ b/spi.viewmodel/manifest.mf
@@ -1,5 +1,5 @@
Manifest-Version: 1.0
OpenIDE-Module: org.netbeans.spi.viewmodel/2
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/viewmodel/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.41
+OpenIDE-Module-Specification-Version: 1.42
diff --git a/spi.viewmodel/src/org/netbeans/modules/viewmodel/TreeModelNode.java b/spi.viewmodel/src/org/netbeans/modules/viewmodel/TreeModelNode.java
--- a/spi.viewmodel/src/org/netbeans/modules/viewmodel/TreeModelNode.java
+++ b/spi.viewmodel/src/org/netbeans/modules/viewmodel/TreeModelNode.java
@@ -951,11 +951,17 @@
firePropertyChange(null, null, null);
}
- void refreshColumn(String column) {
+ void refreshColumn(String column, int changeMask) {
synchronized (properties) {
- properties.remove(column);
- properties.remove(column + "#html");
- properties.remove(column + "#canWrite");
+ if ((ModelEvent.TableValueChanged.VALUE_MASK & changeMask) != 0) {
+ properties.remove(column);
+ }
+ if ((ModelEvent.TableValueChanged.HTML_VALUE_MASK & changeMask) != 0) {
+ properties.remove(column + "#html");
+ }
+ if ((ModelEvent.TableValueChanged.IS_READ_ONLY_MASK & changeMask) != 0) {
+ properties.remove(column + "#canWrite");
+ }
}
firePropertyChange(column, null, null);
}
@@ -1869,14 +1875,19 @@
public void run() {
Object value = "";
String htmlValue = null;
- String nonHtmlValue = null;
+ Object nonHtmlValue = null;
try {
//System.err.println("getValueAt("+object+", "+id+") of node "+TreeModelNode.this);
value = model.getValueAt (object, id);
+ nonHtmlValue = value;
+ boolean hasHTML = model.hasHTMLValueAt(object, id);
+ if (hasHTML) {
+ htmlValue = model.getHTMLValueAt(object, id);
+ }
//System.err.println(" Value of ("+object+") executed in "+Thread.currentThread()+" is "+value);
//System.out.println(" evaluateLazily("+TreeModelNode.this.getDisplayName()+", "+id+"): have value = "+value);
//System.out.println(" object = "+object+" class = "+((object != null) ? object.getClass().toString() : "null"));
- if (value instanceof String) {
+ if (!hasHTML && (value instanceof String)) { // For backward compatibility
htmlValue = htmlValue ((String) value);
nonHtmlValue = removeHTML ((String) value);
}
@@ -1893,12 +1904,8 @@
//evaluatedNotify.run();
boolean fire;
synchronized (properties) {
- if (value instanceof String) {
- properties.put (id, nonHtmlValue);
- properties.put (id + "#html", htmlValue);
- } else {
- properties.put (id, value);
- }
+ properties.put (id, nonHtmlValue);
+ properties.put (id + "#html", htmlValue);
synchronized (evaluated) {
fire = evaluated[0] == -1;
evaluated[0] = 1;
@@ -1992,13 +1999,18 @@
private Object getTheValue() {
Object value = "";
String htmlValue = null;
- String nonHtmlValue = null;
+ Object nonHtmlValue = null;
try {
value = model.getValueAt (object, id);
+ nonHtmlValue = value;
+ boolean hasHTML = model.hasHTMLValueAt(object, id);
+ if (hasHTML) {
+ htmlValue = model.getHTMLValueAt(object, id);
+ }
//System.err.println(" Value of ("+object+") executed in "+Thread.currentThread()+" is "+value);
//System.out.println(" evaluateLazily("+TreeModelNode.this.getDisplayName()+", "+id+"): have value = "+value);
//System.out.println(" object = "+object+" class = "+((object != null) ? object.getClass().toString() : "null"));
- if (value instanceof String) {
+ if (!hasHTML && (value instanceof String)) { // For backward compatibility
htmlValue = htmlValue ((String) value);
nonHtmlValue = removeHTML ((String) value);
}
@@ -2008,12 +2020,8 @@
}
} finally {
synchronized (properties) {
- if (value instanceof String) {
- properties.put (id, nonHtmlValue);
- properties.put (id + "#html", htmlValue);
- } else {
- properties.put (id, value);
- }
+ properties.put (id, nonHtmlValue);
+ properties.put (id + "#html", htmlValue);
}
}
return value;
@@ -2124,13 +2132,19 @@
Object v = value;
model.setValueAt (object, id, v);
v = model.getValueAt(object, id); // Store the new value
+ String htmlValue = null;
+ Object nonHtmlValue = v;
+ boolean hasHTML = model.hasHTMLValueAt(object, id);
+ if (hasHTML) {
+ htmlValue = model.getHTMLValueAt(object, id);
+ }
+ if (!hasHTML && (v instanceof String)) { // For backward compatibility
+ htmlValue = htmlValue ((String) v);
+ nonHtmlValue = removeHTML ((String) v);
+ }
synchronized (properties) {
- if (v instanceof String) {
- properties.put (id, removeHTML ((String) v));
- properties.put (id + "#html", htmlValue ((String) v));
- } else {
- properties.put (id, v);
- }
+ properties.put (id, nonHtmlValue);
+ properties.put (id + "#html", htmlValue);
}
firePropertyChange (propertyId, null, null);
} catch (UnknownTypeException e) {
@@ -2140,11 +2154,19 @@
@Override
public PropertyEditor getPropertyEditor () {
- PropertyEditor pe = columnModel.getPropertyEditor ();
+ PropertyEditor pe = null;
+ try {
+ pe = model.getPropertyEditor(object, id);
+ } catch (UnknownTypeException ex) {
+ Logger.getLogger(TreeModelNode.class.getName()).log(Level.CONFIG, "Column id:" + columnModel.getID ()+"\nModel: "+model, ex);
+ }
if (pe == null) {
+ pe = columnModel.getPropertyEditor ();
+ }
+ if (pe != null) {
+ return pe;
+ } else {
return super.getPropertyEditor();
- } else {
- return pe;
}
}
diff --git a/spi.viewmodel/src/org/netbeans/modules/viewmodel/TreeModelRoot.java b/spi.viewmodel/src/org/netbeans/modules/viewmodel/TreeModelRoot.java
--- a/spi.viewmodel/src/org/netbeans/modules/viewmodel/TreeModelRoot.java
+++ b/spi.viewmodel/src/org/netbeans/modules/viewmodel/TreeModelRoot.java
@@ -334,10 +334,11 @@
if (node != null) {
TreeModelNode[] tmNodes = findNode(node);
//System.err.println(" nodes = "+Arrays.toString(tmNodes));
+ int change = tvEvent.getChange();
for (TreeModelNode tmNode : tmNodes) {
String column = tvEvent.getColumnID();
if (column != null) {
- tmNode.refreshColumn(column);
+ tmNode.refreshColumn(column, change);
} else {
tmNode.refresh(model);
}
diff --git a/spi.viewmodel/src/org/netbeans/spi/viewmodel/ModelEvent.java b/spi.viewmodel/src/org/netbeans/spi/viewmodel/ModelEvent.java
--- a/spi.viewmodel/src/org/netbeans/spi/viewmodel/ModelEvent.java
+++ b/spi.viewmodel/src/org/netbeans/spi/viewmodel/ModelEvent.java
@@ -87,8 +87,25 @@
*/
public static class TableValueChanged extends ModelEvent {
+ /**
+ * The mask for value change.
+ * @since 1.42
+ */
+ public static final int VALUE_MASK = 1;
+ /**
+ * The mask for HTML value change.
+ * @since 1.42
+ */
+ public static final int HTML_VALUE_MASK = 2;
+ /**
+ * The mask for change of the read only state.
+ * @since 1.42
+ */
+ public static final int IS_READ_ONLY_MASK = 4;
+
private Object node;
private String columnID;
+ private int change;
/**
* Creates a new instance of TableValueChanged event.
@@ -104,9 +121,28 @@
Object node,
String columnID
) {
+ this(source, node, columnID, 0xffffffff);
+ }
+
+ /**
+ * Creates a new instance of TableValueChanged event.
+ *
+ * @param source a source if event.
+ * @param node a changed node instance
+ * @param columnID a changed column name
+ * @param change one of the *_MASK constants or their aggregation.
+ * @since 1.42
+ */
+ public TableValueChanged (
+ Object source,
+ Object node,
+ String columnID,
+ int change
+ ) {
super (source);
this.node = node;
this.columnID = columnID;
+ this.change = change;
}
/**
@@ -130,6 +166,16 @@
public String getColumnID () {
return columnID;
}
+
+ /**
+ * Get the change mask.
+ *
+ * @return the change mask, one of the *_MASK constants or their aggregation.
+ * @since 1.42
+ */
+ public int getChange() {
+ return change;
+ }
}
/**
diff --git a/spi.viewmodel/src/org/netbeans/spi/viewmodel/Models.java b/spi.viewmodel/src/org/netbeans/spi/viewmodel/Models.java
--- a/spi.viewmodel/src/org/netbeans/spi/viewmodel/Models.java
+++ b/spi.viewmodel/src/org/netbeans/spi/viewmodel/Models.java
@@ -48,6 +48,7 @@
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.event.ActionEvent;
+import java.beans.PropertyEditor;
import java.io.IOException;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
@@ -266,7 +267,7 @@
// ; or the models directly
boolean hasLists = false;
int modelsSize = models.size();
- if (11 <= modelsSize && modelsSize <= 15) {
+ if (11 <= modelsSize && modelsSize <= 18) {
Iterator it = models.iterator ();
boolean failure = false;
while (it.hasNext ()) {
@@ -306,6 +307,18 @@
ml.tableRendererModels = (List) models.get(13);
if (modelsSize > 14) {
ml.tableRendererModelFilters = (List) models.get(14);
+ //if (modelsSize > 15) {
+ // ml.tableHtmlModels = (List) models.get(15);
+ if (modelsSize > 15) {
+ ml.tableHtmlModelFilters = (List) models.get(15);
+ if (modelsSize > 16) {
+ ml.tablePropertyEditorsModels = (List) models.get(16);
+ if (modelsSize > 17) {
+ ml.tablePropertyEditorsModelFilters = (List) models.get(17);
+ }
+ }
+ }
+ //}
}
}
}
@@ -400,7 +413,7 @@
new DefaultAsynchronousModel(),//new DelegatingAsynchronousModel (ml.asynchModels),
ml.asynchModelFilters
),
- null,
+ null, null,
propertiesHelpID
);
} else {
@@ -424,7 +437,8 @@
ml.columnModels,
createCompoundTableModel (
new DelegatingTableModel (ml.tableModels),
- ml.tableModelFilters
+ ml.tableModelFilters,
+ ml.tableHtmlModelFilters
),
createCompoundAsynchronousModel (
new DefaultAsynchronousModel(),//new DelegatingAsynchronousModel (ml.asynchModels),
@@ -434,6 +448,14 @@
new DelegatingTableRendererModel(ml.tableRendererModels),
ml.tableRendererModelFilters
),
+ /*createCompoundTableHTMLModel (
+ new DelegatingTableHTMLModel(ml.tableHtmlModels),
+ ml.tableHtmlModelFilters
+ ),*/
+ createCompoundTablePropertyEditorModel (
+ new DelegatingTablePropertyEditorsModel(ml.tablePropertyEditorsModels),
+ ml.tablePropertyEditorsModelFilters
+ ),
propertiesHelpID
);
}
@@ -557,11 +579,12 @@
*
* @returns compound table model
*/
- private static TableModel createCompoundTableModel (
- TableModel originalTableModel,
- List tableModelFilters
+ private static TableHTMLModel createCompoundTableModel (
+ TableHTMLModel originalTableModel,
+ List tableModelFilters,
+ List tableHtmlModelFilters
) {
- TableModel tm = originalTableModel;
+ TableHTMLModel tm = originalTableModel;
int i, k = tableModelFilters.size ();
for (i = 0; i < k; i++) {
tm = new CompoundTableModel (
@@ -569,6 +592,13 @@
(TableModelFilter) tableModelFilters.get (i)
);
}
+ k = tableHtmlModelFilters.size ();
+ for (i = 0; i < k; i++) {
+ tm = new CompoundTableModel (
+ tm,
+ (TableHTMLModelFilter) tableHtmlModelFilters.get (i)
+ );
+ }
return tm;
}
@@ -595,6 +625,21 @@
}
return tm;
}
+
+ private static TablePropertyEditorsModel createCompoundTablePropertyEditorModel (
+ TablePropertyEditorsModel originalTableModel,
+ List tableModelFilters
+ ) {
+ TablePropertyEditorsModel tm = originalTableModel;
+ int i, k = tableModelFilters.size ();
+ for (i = 0; i < k; i++) {
+ tm = new CompoundTablePropertyEditorsModel (
+ tm,
+ (TablePropertyEditorsModelFilter) tableModelFilters.get (i)
+ );
+ }
+ return tm;
+ }
/**
* Creates {@link org.netbeans.spi.viewmodel.NodeActionsProvider} for given NodeActionsProvider and
@@ -1031,7 +1076,8 @@
} else if (event instanceof ModelEvent.TableValueChanged) {
newEvent = new ModelEvent.TableValueChanged(newSource,
((ModelEvent.TableValueChanged) event).getNode(),
- ((ModelEvent.TableValueChanged) event).getColumnID());
+ ((ModelEvent.TableValueChanged) event).getColumnID(),
+ ((ModelEvent.TableValueChanged) event).getChange());
} else if (event instanceof ModelEvent.TreeChanged) {
newEvent = new ModelEvent.TreeChanged(newSource);
} else {
@@ -1357,11 +1403,12 @@
*
* @author Jan Jancura
*/
- private final static class CompoundTableModel implements TableModel, ModelListener {
-
-
- private TableModel model;
+ private final static class CompoundTableModel implements TableHTMLModel, ModelListener {
+
+
+ private TableHTMLModel model;
private TableModelFilter filter;
+ private TableHTMLModelFilter htmlFilter;
private final Collection modelListeners = new HashSet();
@@ -1370,11 +1417,16 @@
* Creates {@link org.netbeans.spi.viewmodel.TableModel} for given TableModel and
* {@link org.netbeans.spi.viewmodel.TableModelFilter}.
*/
- CompoundTableModel (TableModel model, TableModelFilter filter) {
+ CompoundTableModel (TableHTMLModel model, TableModelFilter filter) {
this.model = model;
this.filter = filter;
}
+ CompoundTableModel (TableHTMLModel model, TableHTMLModelFilter htmlFilter) {
+ this.model = model;
+ this.htmlFilter = htmlFilter;
+ }
+
/**
* Returns value to be displayed in column columnID
* and row node
. Column ID is defined in by
@@ -1391,7 +1443,29 @@
@Override
public Object getValueAt (Object node, String columnID) throws
UnknownTypeException {
- return filter.getValueAt (model, node, columnID);
+ if (filter != null) {
+ return filter.getValueAt (model, node, columnID);
+ } else {
+ return model.getValueAt(node, columnID);
+ }
+ }
+
+ @Override
+ public boolean hasHTMLValueAt(Object node, String columnID) throws UnknownTypeException {
+ if (htmlFilter != null) {
+ return htmlFilter.hasHTMLValueAt(model, node, columnID);
+ } else {
+ return model.hasHTMLValueAt(node, columnID);
+ }
+ }
+
+ @Override
+ public String getHTMLValueAt(Object node, String columnID) throws UnknownTypeException {
+ if (htmlFilter != null) {
+ return htmlFilter.getHTMLValueAt(model, node, columnID);
+ } else {
+ return model.getHTMLValueAt(node, columnID);
+ }
}
/**
@@ -1410,7 +1484,11 @@
@Override
public boolean isReadOnly (Object node, String columnID) throws
UnknownTypeException {
- return filter.isReadOnly (model, node, columnID);
+ if (filter != null) {
+ return filter.isReadOnly (model, node, columnID);
+ } else {
+ return model.isReadOnly(node, columnID);
+ }
}
/**
@@ -1428,7 +1506,11 @@
@Override
public void setValueAt (Object node, String columnID, Object value)
throws UnknownTypeException {
- filter.setValueAt (model, node, columnID, value);
+ if (filter != null) {
+ filter.setValueAt (model, node, columnID, value);
+ } else {
+ model.setValueAt(node, columnID, value);
+ }
}
/**
@@ -1440,7 +1522,9 @@
public void addModelListener (ModelListener l) {
synchronized (modelListeners) {
if (modelListeners.isEmpty()) {
- filter.addModelListener (this);
+ if (filter != null) {
+ filter.addModelListener (this);
+ }
model.addModelListener (this);
}
modelListeners.add(l);
@@ -1457,7 +1541,9 @@
synchronized (modelListeners) {
modelListeners.remove(l);
if (modelListeners.isEmpty()) {
- filter.removeModelListener (this);
+ if (filter != null) {
+ filter.removeModelListener (this);
+ }
model.removeModelListener (this);
}
}
@@ -1490,15 +1576,16 @@
}
public String toString (String n) {
+ Model theFilter = (filter != null) ? filter : htmlFilter;
if (model instanceof CompoundTableModel) {
- return n + filter + "\n" +
+ return n + theFilter + "\n" +
((CompoundTableModel) model).toString (n + " ");
}
if (model instanceof DelegatingTableModel) {
- return n + filter + "\n" +
+ return n + theFilter + "\n" +
((DelegatingTableModel) model).toString (n + " ");
}
- return n + filter + "\n" +
+ return n + theFilter + "\n" +
n + " " + model;
}
}
@@ -1899,6 +1986,40 @@
}
}
+ private final static class CompoundTablePropertyEditorsModel implements TablePropertyEditorsModel {
+
+ private TablePropertyEditorsModel model;
+ private TablePropertyEditorsModelFilter filter;
+
+ CompoundTablePropertyEditorsModel(TablePropertyEditorsModel model, TablePropertyEditorsModelFilter filter) {
+ this.model = model;
+ this.filter = filter;
+ }
+
+ @Override
+ public PropertyEditor getPropertyEditor(Object node, String columnID) throws UnknownTypeException {
+ return filter.getPropertyEditor(model, node, columnID);
+ }
+
+ @Override
+ public String toString () {
+ return super.toString () + "\n" + toString (" ");
+ }
+
+ public String toString (String n) {
+ if (model instanceof CompoundTablePropertyEditorsModel) {
+ return n + filter + "\n" +
+ ((CompoundTablePropertyEditorsModel) model).toString (n + " ");
+ }
+ if (model instanceof DelegatingTablePropertyEditorsModel) {
+ return n + filter + "\n" +
+ ((DelegatingTablePropertyEditorsModel) model).toString (n + " ");
+ }
+ return n + filter + "\n" +
+ n + " " + model;
+ }
+ }
+
/**
* Creates {@link org.netbeans.spi.viewmodel.NodeActionsProvider}
* for given NodeActionsProvider and
@@ -2078,7 +2199,7 @@
*
* @author Jan Jancura
*/
- private final static class DelegatingTableModel implements TableModel {
+ private final static class DelegatingTableModel implements TableModel, TableHTMLModel {
private TableModel[] models;
private HashMap classNameToModel = new HashMap();
@@ -2286,6 +2407,94 @@
sb.append (models [i]);
return new String (sb);
}
+
+ // HTML extension:
+
+ private boolean defaultHasHTMLValueAt() {
+ return false;
+ }
+
+ @Override
+ public boolean hasHTMLValueAt(Object node, String columnID) throws UnknownTypeException {
+ UnknownTypeException uex = null;
+ TableModel model = classNameToModel.get (
+ node.getClass ().getName ()
+ );
+ if (model != null) {
+ if (model instanceof TableHTMLModel) {
+ try {
+ return ((TableHTMLModel) model).hasHTMLValueAt(node, columnID);
+ } catch (UnknownTypeException e) {
+ uex = e;
+ }
+ } else {
+ return defaultHasHTMLValueAt();
+ }
+ }
+ int i, k = models.length;
+ boolean isHTML = false;
+ for (i = 0; i < k; i++) {
+ if (models[i] instanceof TableHTMLModel) {
+ try {
+ boolean has = ((TableHTMLModel) models [i]).hasHTMLValueAt(node, columnID);
+ classNameToModel.put (node.getClass ().getName (), models [i]);
+ return has;
+ } catch (UnknownTypeException e) {
+ uex = e;
+ }
+ isHTML = true;
+ }
+ }
+ if (!isHTML) {
+ return defaultHasHTMLValueAt();
+ }
+ if (uex != null) {
+ throw uex;
+ } else {
+ throw new UnknownTypeException (node);
+ }
+ }
+
+ @Override
+ public String getHTMLValueAt(Object node, String columnID) throws UnknownTypeException {
+ UnknownTypeException uex = null;
+ TableModel model = classNameToModel.get (
+ node.getClass ().getName ()
+ );
+ if (model != null) {
+ if (model instanceof TableHTMLModel) {
+ try {
+ return ((TableHTMLModel) model).getHTMLValueAt(node, columnID);
+ } catch (UnknownTypeException e) {
+ uex = e;
+ }
+ } else {
+ return null;
+ }
+ }
+ int i, k = models.length;
+ boolean isHTML = false;
+ for (i = 0; i < k; i++) {
+ if (models[i] instanceof TableHTMLModel) {
+ try {
+ String htmlValue = ((TableHTMLModel) models [i]).getHTMLValueAt(node, columnID);
+ classNameToModel.put (node.getClass ().getName (), models [i]);
+ return htmlValue;
+ } catch (UnknownTypeException e) {
+ uex = e;
+ }
+ isHTML = true;
+ }
+ }
+ if (!isHTML) {
+ return null;
+ }
+ if (uex != null) {
+ throw uex;
+ } else {
+ throw new UnknownTypeException (node);
+ }
+ }
}
/**
@@ -2484,6 +2693,79 @@
}
}
+
+ private final static class DelegatingTablePropertyEditorsModel implements TablePropertyEditorsModel {
+
+ private TablePropertyEditorsModel[] models;
+ private HashMap classNameToModel = new HashMap();
+
+ DelegatingTablePropertyEditorsModel(List models) {
+ this(convert(models));
+ }
+
+ private static TablePropertyEditorsModel[] convert(List l) {
+ TablePropertyEditorsModel[] models = new TablePropertyEditorsModel[l.size()];
+ return l.toArray(models);
+ }
+
+ DelegatingTablePropertyEditorsModel(TablePropertyEditorsModel[] models) {
+ this.models = models;
+ }
+
+ @Override
+ public PropertyEditor getPropertyEditor(Object node, String columnID) throws UnknownTypeException {
+ UnknownTypeException utex = null;
+ TablePropertyEditorsModel model = classNameToModel.get(
+ node.getClass().getName()
+ );
+ if (model != null) {
+ try {
+ return model.getPropertyEditor(node, columnID);
+ } catch (UnknownTypeException e) {
+ utex = e;
+ }
+ }
+ int i, k = models.length;
+ for (i = 0; i < k; i++) {
+ try {
+ PropertyEditor pe = models [i].getPropertyEditor(node, columnID);
+ classNameToModel.put (node.getClass ().getName (), models [i]);
+ return pe;
+ } catch (UnknownTypeException e) {
+ utex = e;
+ }
+ }
+ if (k == 0) {
+ return null;
+ }
+ if (utex != null) {
+ throw utex;
+ } else {
+ throw new UnknownTypeException (node);
+ }
+ }
+
+ @Override
+ public String toString () {
+ return super.toString () + "\n" + toString (" ");
+ }
+
+ public String toString (String n) {
+ int i, k = models.length - 1;
+ if (k == -1) {
+ return "";
+ }
+ StringBuffer sb = new StringBuffer ();
+ for (i = 0; i < k; i++) {
+ sb.append (n);
+ sb.append (models [i]);
+ sb.append ('\n');
+ }
+ sb.append (n);
+ sb.append (models [i]);
+ return new String (sb);
+ }
+ }
/**
* Creates one {@link org.netbeans.spi.viewmodel.TableModel}
@@ -3955,9 +4237,10 @@
CheckNodeModel,
DnDNodeModel,
NodeActionsProvider,
- TableModel,
+ TableHTMLModel,
TreeExpansionModel,
- TableRendererModel {
+ TableRendererModel,
+ TablePropertyEditorsModel {
private ReorderableTreeModel treeModel;
private ExtendedNodeModel nodeModel;
@@ -3965,8 +4248,9 @@
private DnDNodeModel dndNodeModel;
private NodeActionsProvider nodeActionsProvider;
private ColumnModel[] columnModels;
- private TableModel tableModel;
+ private TableHTMLModel tableModel;
private TableRendererModel tableRendererModel;
+ private TablePropertyEditorsModel tablePropertyEditorsModel;
private TreeExpansionModel treeExpansionModel;
private AsynchronousModel asynchModel;
@@ -3997,9 +4281,10 @@
ExtendedNodeModel nodeModel,
NodeActionsProvider nodeActionsProvider,
List columnModels,
- TableModel tableModel,
+ TableHTMLModel tableModel,
AsynchronousModel asynchModel,
TableRendererModel tableRendererModel,
+ TablePropertyEditorsModel tablePropertyEditorsModel,
String propertiesHelpID
) {
if (treeModel == null || nodeModel == null || tableModel == null ||
@@ -4024,6 +4309,7 @@
}
this.tableModel = tableModel;
this.tableRendererModel = tableRendererModel;
+ this.tablePropertyEditorsModel = tablePropertyEditorsModel;
this.nodeActionsProvider = nodeActionsProvider;
this.columnModels = columnModels.toArray (
new ColumnModel [columnModels.size ()]
@@ -4582,6 +4868,31 @@
return null;
}
}
+
+ // TableHTMLModel
+
+ @Override
+ public boolean hasHTMLValueAt(Object node, String columnID) throws UnknownTypeException {
+ return tableModel.hasHTMLValueAt(node, columnID);
+ }
+
+ @Override
+ public String getHTMLValueAt(Object node, String columnID) throws UnknownTypeException {
+ return tableModel.getHTMLValueAt(node, columnID);
+ }
+
+ // TablePropertyEditorsModel
+
+ @Override
+ public PropertyEditor getPropertyEditor(Object node, String columnID) throws UnknownTypeException {
+ if (tablePropertyEditorsModel != null) {
+ return tablePropertyEditorsModel.getPropertyEditor(node, columnID);
+ } else {
+ return null;
+ }
+ }
+
+
}
@@ -4602,6 +4913,10 @@
public List asynchModelFilters = Collections.emptyList();
public List tableRendererModels = Collections.emptyList();
public List tableRendererModelFilters = Collections.emptyList();
+ public List tableHtmlModels = Collections.emptyList();
+ public List tableHtmlModelFilters = Collections.emptyList();
+ public List tablePropertyEditorsModels = Collections.emptyList();
+ public List tablePropertyEditorsModelFilters = Collections.emptyList();
public void addOtherModels(List extends Model> otherModels) {
Iterator it = otherModels.iterator ();
@@ -4668,6 +4983,30 @@
tableRendererModelFilters.add(0, (TableRendererModelFilter) model);
}
}
+ if (model instanceof TableHTMLModel && !tableHtmlModels.contains((TableHTMLModel) model)) {
+ tableHtmlModels = new ArrayList(tableHtmlModels);
+ tableHtmlModels.add((TableHTMLModel) model);
+ }
+ if (model instanceof TableHTMLModelFilter && !tableHtmlModelFilters.contains((TableHTMLModelFilter) model)) {
+ tableHtmlModelFilters = new ArrayList(tableHtmlModelFilters);
+ if (first) {
+ tableHtmlModelFilters.add((TableHTMLModelFilter) model);
+ } else {
+ tableHtmlModelFilters.add(0, (TableHTMLModelFilter) model);
+ }
+ }
+ if (model instanceof TablePropertyEditorsModel && !tablePropertyEditorsModels.contains((TablePropertyEditorsModel) model)) {
+ tablePropertyEditorsModels = new ArrayList(tablePropertyEditorsModels);
+ tablePropertyEditorsModels.add((TablePropertyEditorsModel) model);
+ }
+ if (model instanceof TablePropertyEditorsModelFilter && !tablePropertyEditorsModelFilters.contains((TablePropertyEditorsModelFilter) model)) {
+ tablePropertyEditorsModelFilters = new ArrayList(tablePropertyEditorsModelFilters);
+ if (first) {
+ tablePropertyEditorsModelFilters.add((TablePropertyEditorsModelFilter) model);
+ } else {
+ tablePropertyEditorsModelFilters.add(0, (TablePropertyEditorsModelFilter) model);
+ }
+ }
if (model instanceof NodeActionsProvider && !nodeActionsProviders.contains((NodeActionsProvider) model)) {
nodeActionsProviders = new ArrayList(nodeActionsProviders);
nodeActionsProviders.add((NodeActionsProvider) model);
diff --git a/spi.viewmodel/src/org/netbeans/spi/viewmodel/TableHTMLModel.java b/spi.viewmodel/src/org/netbeans/spi/viewmodel/TableHTMLModel.java
new file mode 100644
--- /dev/null
+++ b/spi.viewmodel/src/org/netbeans/spi/viewmodel/TableHTMLModel.java
@@ -0,0 +1,90 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2013 Sun Microsystems, Inc.
+ */
+package org.netbeans.spi.viewmodel;
+
+/**
+ * Use this to separate value and the HTML value.
+ * When displaying a property value, then if the value is a String and if it contains
+ * a HTML code, it's automatically rendered as HTML. The HTML code is then
+ * stripped out to get the raw value.
+ * If this is not desired or if it's necessary to provide a value and HTML code
+ * that differs from each other, implement this model.
+ *
+ * @author Martin Entlicher
+ * @since 1.42
+ * @see TableHTMLModelFilter
+ */
+public interface TableHTMLModel extends TableModel {
+
+ /**
+ * Test if the model has a HTML value.
+ * For backward compatibility, if it returns false
,
+ * HTML value is is taken from the String value, if it contains some.
+ * If this is not desired, return true here and null from
+ * {@link #getHTMLValueAt(java.lang.Object, java.lang.String)}.
+ * @param node an object returned from {@link TreeModel#getChildren(java.lang.Object, int, int) }
+ * for this row
+ * @param columnID an id of column defined by {@link ColumnModel#getID()}
+ * @return true
if there is some HTML value to be returned
+ * from {@link #getHTMLValueAt(java.lang.Object, java.lang.String)},
+ * false
otherwise.
+ * When false
is returned,
+ * {@link #getHTMLValueAt(java.lang.Object, java.lang.String)} is not called.
+ * @throws UnknownTypeException if there is nothing to be provided for the given
+ * parameter type
+ */
+ boolean hasHTMLValueAt(Object node, String columnID) throws UnknownTypeException;
+
+ /**
+ * Get the HTML value.
+ *
+ * @param node an object returned from {@link TreeModel#getChildren(java.lang.Object, int, int) }
+ * for this row
+ * @param columnID an id of column defined by {@link ColumnModel#getID()}
+ * @return The HTML value, or null
when no HTML value is provided.
+ * @throws UnknownTypeException if there is nothing to be provided for the given
+ * parameter type
+ * @see #hasHTMLValueAt(java.lang.Object, java.lang.String)
+ */
+ String getHTMLValueAt(Object node, String columnID) throws UnknownTypeException;
+
+}
diff --git a/spi.viewmodel/src/org/netbeans/spi/viewmodel/TableHTMLModelFilter.java b/spi.viewmodel/src/org/netbeans/spi/viewmodel/TableHTMLModelFilter.java
new file mode 100644
--- /dev/null
+++ b/spi.viewmodel/src/org/netbeans/spi/viewmodel/TableHTMLModelFilter.java
@@ -0,0 +1,102 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2013 Sun Microsystems, Inc.
+ */
+package org.netbeans.spi.viewmodel;
+
+/**
+ * Use this to separate value and the HTML value.
+ * Implement this filter to override the behavior of any registered {@link TableHTMLModel}s.
+ *
+ * @author Martin Entlicher
+ * @since 1.42
+ * @see TableHTMLModel
+ */
+public interface TableHTMLModelFilter extends Model {
+
+ /**
+ * Test if the model has a HTML value.
+ * For backward compatibility, if it returns false
,
+ * HTML value is is taken from the String value, if it contains some.
+ * If this is not desired, return true here and null from
+ * {@link #getHTMLValueAt(org.netbeans.spi.viewmodel.TableHTMLModel, java.lang.Object, java.lang.String)}.
+ * @param original The original {@link TableHTMLModel}
+ * @param node an object returned from {@link TreeModel#getChildren(java.lang.Object, int, int) }
+ * for this row
+ * @param columnID an id of column defined by {@link ColumnModel#getID()}
+ * @return true
if there is some HTML value to be returned
+ * from {@link #getHTMLValueAt(org.netbeans.spi.viewmodel.TableHTMLModel, java.lang.Object, java.lang.String)},
+ * false
otherwise.
+ * When false
is returned,
+ * {@link #getHTMLValueAt(org.netbeans.spi.viewmodel.TableHTMLModel, java.lang.Object, java.lang.String)}
+ * is not called.
+ * @throws UnknownTypeException if there is nothing to be provided for the given
+ * parameter type
+ */
+ boolean hasHTMLValueAt(TableHTMLModel original, Object node, String columnID) throws UnknownTypeException;
+
+ /**
+ * Get the HTML value.
+ *
+ * @param original The original {@link TableHTMLModel}
+ * @param node an object returned from {@link TreeModel#getChildren(java.lang.Object, int, int) }
+ * for this row
+ * @param columnID an id of column defined by {@link ColumnModel#getID()}
+ * @return The HTML value, or null
when no HTML value is provided.
+ * @throws UnknownTypeException if there is nothing to be provided for the given
+ * parameter type
+ * @see #hasHTMLValueAt(org.netbeans.spi.viewmodel.TableHTMLModel, java.lang.Object, java.lang.String)
+ */
+ String getHTMLValueAt(TableHTMLModel original, Object node, String columnID) throws UnknownTypeException;
+
+ /**
+ * Registers given listener.
+ *
+ * @param l the listener to add
+ */
+ public abstract void addModelListener (ModelListener l);
+
+ /**
+ * Unregisters given listener.
+ *
+ * @param l the listener to remove
+ */
+ public abstract void removeModelListener (ModelListener l);
+}
diff --git a/spi.viewmodel/src/org/netbeans/spi/viewmodel/TablePropertyEditorsModel.java b/spi.viewmodel/src/org/netbeans/spi/viewmodel/TablePropertyEditorsModel.java
new file mode 100644
--- /dev/null
+++ b/spi.viewmodel/src/org/netbeans/spi/viewmodel/TablePropertyEditorsModel.java
@@ -0,0 +1,67 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2013 Sun Microsystems, Inc.
+ */
+package org.netbeans.spi.viewmodel;
+
+import java.beans.PropertyEditor;
+
+/**
+ * Use this to provide different property editors for different table cells.
+ *
+ * @author Martin Entlicher
+ * @since 1.42
+ * @see TablePropertyEditorsModelFilter
+ */
+public interface TablePropertyEditorsModel extends Model {
+
+ /**
+ * Get the property editor for the given table cell.
+ *
+ * @param node an object returned from {@link TreeModel#getChildren(java.lang.Object, int, int) }
+ * for this row
+ * @param columnID an id of column defined by {@link ColumnModel#getID()}
+ * @return The property editor or null
to use the column default one.
+ * @throws UnknownTypeException if there is nothing to be provided for the given
+ * parameter type
+ */
+ PropertyEditor getPropertyEditor(Object node, String columnID) throws UnknownTypeException;
+
+}
diff --git a/spi.viewmodel/src/org/netbeans/spi/viewmodel/TablePropertyEditorsModelFilter.java b/spi.viewmodel/src/org/netbeans/spi/viewmodel/TablePropertyEditorsModelFilter.java
new file mode 100644
--- /dev/null
+++ b/spi.viewmodel/src/org/netbeans/spi/viewmodel/TablePropertyEditorsModelFilter.java
@@ -0,0 +1,70 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License. When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ *
+ * Contributor(s):
+ *
+ * Portions Copyrighted 2013 Sun Microsystems, Inc.
+ */
+package org.netbeans.spi.viewmodel;
+
+import java.beans.PropertyEditor;
+
+/**
+ * Use this to provide different property editors for different table cells.
+ * Implement this filter to override the behavior of any registered {@link TablePropertyEditorsModel}s.
+ *
+ * @author Martin Entlicher
+ * @since 1.42
+ * @see TablePropertyEditorsModel
+ */
+public interface TablePropertyEditorsModelFilter extends Model {
+
+ /**
+ * Get the property editor for the given table cell.
+ *
+ * @param original The original {@link TablePropertyEditorsModel}
+ * @param node an object returned from {@link TreeModel#getChildren(java.lang.Object, int, int) }
+ * for this row
+ * @param columnID an id of column defined by {@link ColumnModel#getID()}
+ * @return The property editor or null
to use the column default one.
+ * @throws UnknownTypeException if there is nothing to be provided for the given
+ * parameter type
+ */
+ PropertyEditor getPropertyEditor(TablePropertyEditorsModel original,
+ Object node, String columnID) throws UnknownTypeException;
+
+}