1// BEGIN LICENSE BLOCK 2// Version: CMPL 1.1 3// 4// The contents of this file are subject to the Cisco-style Mozilla Public 5// License Version 1.1 (the "License"); you may not use this file except 6// in compliance with the License. You may obtain a copy of the License 7// at www.eclipse-clp.org/license. 8// 9// Software distributed under the License is distributed on an "AS IS" 10// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 11// the License for the specific language governing rights and limitations 12// under the License. 13// 14// The Original Code is The ECLiPSe Constraint Logic Programming System. 15// The Initial Developer of the Original Code is Cisco Systems, Inc. 16// Portions created by the Initial Developer are 17// Copyright (C) 2006 Cisco Systems, Inc. All Rights Reserved. 18// 19// Contributor(s): 20// 21// END LICENSE BLOCK 22 23package com.parctechnologies.eclipse.visualisation.viewers; 24 25import com.parctechnologies.eclipse.*; 26import com.parctechnologies.eclipse.visualisation.*; 27 28import java.awt.Rectangle; 29import java.awt.Shape; 30import java.awt.geom.*; 31import java.awt.Color; 32import java.awt.Component; 33import java.util.*; 34import java.awt.event.ActionEvent; 35import javax.swing.*; 36import javax.swing.table.*; 37import att.grappa.*; 38 39 40/** 41 * Contains default implementations of the ViewletType interface 42 */ 43public abstract class AbstractViewletType implements ViewletType, ViewletFactory { 44 private SymRef symRef; 45 46 protected final static String ELEMENT_EXECUTE_STRING = "viewable_element_execute"; 47 protected final static String CHANGEABLE_ELEMENT_EXECUTE_STRING = "viewable_changeable_execute"; 48 protected String changeableSolver; 49 50 public AbstractViewletType(String changeable) { 51 changeableSolver = changeable; 52 } 53 54 55 /* ViewletFactory methods */ 56 public boolean canBuildFrom(ElementType elementType) 57 { 58 return(true); 59 } 60 61 abstract public ViewletData build(); 62 63 abstract public String getDescription() ; 64 65 public void setSymRef(SymRef symRef) 66 { 67 this.symRef = symRef; 68 } 69 public SymRef getSymRef() 70 { 71 return(symRef); 72 } 73 74 /* ViewletType methods */ 75 abstract public TableCellRenderer getTableCellRenderer(); 76 77 abstract Class getCustomRendererClass(); 78 79 abstract public void customizeElement(ViewletDataStore store, 80 java.util.List index, 81 Element element); 82 83 84 /** 85 * Can be used to wrap a goal in either a "viewable_element_execute" 86 * or "viewable_changeable_execute" goal, which will replace 87 * occurences of the term "element(Index)" with the associated 88 * viewable element or changeable value. 89 **/ 90 protected CompoundTerm composeElementGoal(Object elementReference, 91 CompoundTerm viewableName, 92 CompoundTerm viewletGoal) 93 { 94 if (changeableSolver==null) { 95 return(new CompoundTermImpl(":", new Atom("vc_support"), 96 new CompoundTermImpl(ELEMENT_EXECUTE_STRING, 97 viewableName, new CompoundTermImpl("element",elementReference), viewletGoal))); 98 } else { 99 return(new CompoundTermImpl(":", new Atom("vc_support"), 100 new CompoundTermImpl(CHANGEABLE_ELEMENT_EXECUTE_STRING, 101 viewableName, new CompoundTermImpl("element",elementReference), viewletGoal,new Atom(changeableSolver)))); 102 } 103 } 104 105 /** 106 * Can be used to remove the wrapping applied by composeElementGoal 107 **/ 108 protected CompoundTerm decomposeElementGoal(CompoundTerm viewletGoal) 109 { 110 return ((CompoundTermImpl)viewletGoal).argCT(2).argCT(3); 111 } 112 113 114 public BatchGoal collectPreBuildGoal(Viewer viewer, 115 ViewletDataStore store, 116 ViewletRange range) { 117 return null; 118 } 119 120 public void startBuild(Viewer viewer, 121 ViewletDataStore store, 122 ViewletRange range, 123 List results) { 124 } 125 126 public void stopBuild() 127 {} 128 129 public BatchGoal collectPreUpdateGoal(Viewer viewer, 130 ViewletDataStore store, 131 ViewletRange range, 132 UpdateEvent updateEvent) 133 { 134 return null; 135 } 136 public void startUpdate(Viewer viewer, 137 ViewletDataStore store, 138 ViewletRange range, 139 List results, 140 UpdateEvent updateEvent) { 141 } 142 143 public void stopUpdate(Viewer viewer, 144 ViewletDataStore store, 145 ViewletRange range) { 146 } 147 148 149 150 151 152 /** 153 * Return a collection of actions which can be applied to viewlets 154 * in this table 155 */ 156 public Collection getActions(ViewletDataStore store, 157 ViewletRange range) { 158 Collection ll = new LinkedList(); 159 if ((range != null) & (!range.isEmpty())) { 160 ll.add((new ToggleHoldAction()).createCompoundAction(store, range)); 161 } 162 return ll; 163 } 164 165 protected class ToggleHoldAction extends ViewletAction 166 { 167 ToggleHoldAction() 168 { 169 super("Hold on updates"); 170 putValue(Action.NAME, "Hold on updates"); 171 putValue(Action.LONG_DESCRIPTION, 172 "Change whether control is held by the visualisation client during element updates"); 173 putValue(Action.SHORT_DESCRIPTION, 174 "Change whether control is held on updates"); 175 putValue(Action.SMALL_ICON, new HoldIcon(20, 20)); 176 177 } 178 179 public void actionPerformed(ActionEvent e) 180 { 181 // do nothing 182 } 183 184 /** 185 * If all viewlets in the collection have hold set to true, then the 186 * compound version sets it to false. If any of them have it set to false 187 * then the compound version sets all to true. 188 */ 189 public ViewletAction createCompoundAction(ViewletDataStore store, 190 ViewletRange range) 191 { 192 boolean allHold = true; 193 ViewletData currentViewlet; 194 Iterator viewletsIterator = store.getViewletDataIterator(range); 195 while(viewletsIterator.hasNext()) 196 { 197 currentViewlet = (ViewletData) viewletsIterator.next(); 198 if(!currentViewlet.getHoldsOnUpdates()) 199 { 200 allHold = false; 201 break; 202 } 203 } 204 return(new CompoundToggleHoldAction(!allHold, store, range)); 205 } 206 } 207 208 private void toggleHold(ViewletDataStore store, 209 ViewletRange range, 210 boolean newValue) { 211 ViewletData currentViewlet; 212 Iterator viewletsIterator = range.iterator(); 213 while(viewletsIterator.hasNext()) { 214 List index = (List)viewletsIterator.next(); 215 currentViewlet = (ViewletData)(store.getViewletDataAt(index)); 216 currentViewlet.setHoldsOnUpdates(newValue); 217 store.setViewletDataAt(index, currentViewlet); 218 } 219 // trigger the jtable to update as a whole bunch of 220 // viewlets have just changed 221 store.fireViewletRangeUpdated( range ); 222 } 223 224 private class CompoundToggleHoldAction extends ToggleHoldAction 225 { 226 private boolean newValue; 227 private ViewletRange range; 228 private ViewletDataStore store; 229 CompoundToggleHoldAction(boolean newValue, 230 ViewletDataStore store, 231 ViewletRange range) 232 { 233 super(); 234 this.newValue = newValue; 235 this.range = range; 236 this.store = store; 237 } 238 239 public void actionPerformed(ActionEvent e) 240 { 241 new ToggleHoldCommand(AbstractViewletType.this,store,range,newValue).issue(); 242 } 243 } 244 245 public static class ToggleHoldCommand extends ViewletTypeRangeCommand { 246 boolean newValue; 247 248 public ToggleHoldCommand(ViewletType type, 249 ViewletDataStore store, 250 ViewletRange range, 251 boolean newValue) { 252 super(type, store, range); 253 this.newValue = newValue; 254 } 255 256 public void postRecordIssue() { 257 if (DebuggingSupport.logMessages) { 258 DebuggingSupport. 259 logMessage(this, 260 "ToggleHoldCommand postRecordIssue invoked with type=" + 261 getViewletType() + 262 " store=" + getViewletDataStore() + 263 " range=" + getViewletRange() + 264 " newValue=" + newValue); 265 } 266 ((AbstractViewletType)getViewletType()). 267 toggleHold(getViewletDataStore(), getViewletRange(), newValue); 268 } 269 } 270} 271 272