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