001: /*
002: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
003: */
004: package org.terracotta.dso.editors;
005:
006: import org.apache.commons.lang.StringUtils;
007: import org.eclipse.core.resources.IProject;
008: import org.eclipse.swt.SWT;
009: import org.eclipse.swt.events.SelectionAdapter;
010: import org.eclipse.swt.events.SelectionEvent;
011: import org.eclipse.swt.layout.GridData;
012: import org.eclipse.swt.layout.GridLayout;
013: import org.eclipse.swt.widgets.Button;
014: import org.eclipse.swt.widgets.Composite;
015: import org.eclipse.swt.widgets.Event;
016: import org.eclipse.swt.widgets.Label;
017: import org.eclipse.swt.widgets.Listener;
018: import org.eclipse.swt.widgets.Table;
019: import org.eclipse.swt.widgets.TableColumn;
020: import org.eclipse.swt.widgets.TableItem;
021: import org.terracotta.dso.editors.chooser.ExpressionChooser;
022: import org.terracotta.dso.editors.chooser.FieldBehavior;
023: import org.terracotta.dso.editors.chooser.NavigatorBehavior;
024: import org.terracotta.ui.util.SWTUtil;
025:
026: import com.tc.util.event.UpdateEvent;
027: import com.tc.util.event.UpdateEventListener;
028: import com.terracottatech.config.DsoApplication;
029: import com.terracottatech.config.Root;
030: import com.terracottatech.config.Roots;
031:
032: public class RootsPanel extends ConfigurationEditorPanel {
033: private IProject m_project;
034: private DsoApplication m_dsoApp;
035: private Roots m_roots;
036:
037: private Layout m_layout;
038:
039: private AddRootHandler m_addRootHandler;
040: private RemoveRootHandler m_removeRootHandler;
041: private TableSelectionListener m_tableSelectionListener;
042: private TableDataListener m_tableDataListener;
043:
044: private static final int FIELD_COLUMN = 0;
045: private static final int NAME_COLUMN = 1;
046:
047: public RootsPanel(Composite parent, int style) {
048: super (parent, style);
049: m_layout = new Layout(this );
050: m_addRootHandler = new AddRootHandler();
051: m_removeRootHandler = new RemoveRootHandler();
052: m_tableSelectionListener = new TableSelectionListener();
053: m_tableDataListener = new TableDataListener();
054: }
055:
056: public boolean hasAnySet() {
057: return m_roots != null && m_roots.sizeOfRootArray() > 0;
058: }
059:
060: private Roots ensureRoots() {
061: if (m_roots == null) {
062: ensureXmlObject();
063: }
064: return m_roots;
065: }
066:
067: public void ensureXmlObject() {
068: super .ensureXmlObject();
069:
070: if (m_roots == null) {
071: removeListeners();
072: m_roots = m_dsoApp.addNewRoots();
073: updateChildren();
074: addListeners();
075: }
076: }
077:
078: private void syncModel() {
079: if (!hasAnySet() && m_dsoApp.getRoots() != null) {
080: m_dsoApp.unsetRoots();
081: m_roots = null;
082: fireXmlObjectStructureChanged(m_dsoApp);
083: }
084: fireRootsChanged();
085: testDisableRemoveButton();
086: }
087:
088: private void testDisableRemoveButton() {
089: m_layout.m_removeButton.setEnabled(m_layout.m_table
090: .getSelectionCount() > 0);
091: }
092:
093: private void addListeners() {
094: m_layout.m_addButton.addSelectionListener(m_addRootHandler);
095: m_layout.m_removeButton
096: .addSelectionListener(m_removeRootHandler);
097: m_layout.m_table.addSelectionListener(m_tableSelectionListener);
098: m_layout.m_table.addListener(SWT.SetData, m_tableDataListener);
099: }
100:
101: private void removeListeners() {
102: m_layout.m_addButton.removeSelectionListener(m_addRootHandler);
103: m_layout.m_removeButton
104: .removeSelectionListener(m_removeRootHandler);
105: m_layout.m_table
106: .removeSelectionListener(m_tableSelectionListener);
107: m_layout.m_table.removeListener(SWT.SetData,
108: m_tableDataListener);
109: }
110:
111: public void updateChildren() {
112: initTableItems();
113: testDisableRemoveButton();
114: }
115:
116: public void updateModel() {
117: removeListeners();
118: updateChildren();
119: addListeners();
120: }
121:
122: public void setup(IProject project, DsoApplication dsoApp) {
123: setEnabled(true);
124: removeListeners();
125:
126: m_project = project;
127: m_dsoApp = dsoApp;
128: m_roots = m_dsoApp != null ? m_dsoApp.getRoots() : null;
129:
130: updateChildren();
131: addListeners();
132: }
133:
134: public void tearDown() {
135: removeListeners();
136: clearTableItems();
137:
138: m_project = null;
139: m_dsoApp = null;
140: m_roots = null;
141:
142: setEnabled(false);
143: }
144:
145: private void clearTableItems() {
146: m_layout.m_table.removeAll();
147: }
148:
149: private void initTableItems() {
150: clearTableItems();
151: if (m_roots == null)
152: return;
153: Root[] roots = m_roots.getRootArray();
154: for (int i = 0; i < roots.length; i++) {
155: createTableItem(roots[i]);
156: }
157: if (roots.length > 0) {
158: m_layout.m_table.setSelection(0);
159: }
160: }
161:
162: private void initTableItem(TableItem item, Root root) {
163: String fieldNameOrExpression;
164: if (root.isSetFieldName()) {
165: fieldNameOrExpression = root.getFieldName();
166: } else {
167: fieldNameOrExpression = root.getFieldExpression();
168: }
169: item.setText(new String[] { fieldNameOrExpression,
170: root.getRootName() });
171: }
172:
173: private void updateTableItem(int index) {
174: TableItem item = m_layout.m_table.getItem(index);
175: initTableItem(item, (Root) item.getData());
176: }
177:
178: private void createTableItem(Root root) {
179: TableItem item = new TableItem(m_layout.m_table, SWT.NONE);
180: initTableItem(item, root);
181: item.setData(root);
182: }
183:
184: private void internalAddRoot(String fieldNameOrExpression) {
185: Root root = ensureRoots().addNewRoot();
186:
187: fieldNameOrExpression = fieldNameOrExpression.trim();
188: String sansWhitespace = StringUtils
189: .deleteWhitespace(fieldNameOrExpression);
190: if (fieldNameOrExpression.length() != sansWhitespace.length()) {
191: root.setFieldExpression(fieldNameOrExpression);
192: root.unsetFieldName();
193: } else {
194: root.setFieldName(fieldNameOrExpression);
195: root.unsetFieldName();
196: }
197: createTableItem(root);
198:
199: int row = m_layout.m_table.getItemCount() - 1;
200: m_layout.m_table.setSelection(row);
201: }
202:
203: private static class Layout {
204: private static final String ROOTS = "Roots";
205: private static final String FIELD = "Field/Expression";
206: private static final String NAME = "Name";
207: private static final String ADD = "Add...";
208: private static final String REMOVE = "Remove";
209:
210: private Table m_table;
211: private Button m_addButton;
212: private Button m_removeButton;
213:
214: public void reset() {
215: m_removeButton.setEnabled(false);
216: m_table.removeAll();
217: }
218:
219: private Layout(Composite parent) {
220: Composite comp = new Composite(parent, SWT.NONE);
221: GridLayout gridLayout = new GridLayout(2, false);
222: gridLayout.marginWidth = gridLayout.marginHeight = 10;
223: comp.setLayout(gridLayout);
224:
225: Composite sidePanel = new Composite(comp, SWT.NONE);
226: gridLayout = new GridLayout();
227: gridLayout.marginWidth = gridLayout.marginHeight = 0;
228: sidePanel.setLayout(gridLayout);
229: sidePanel.setLayoutData(new GridData(GridData.FILL_BOTH));
230:
231: Label label = new Label(sidePanel, SWT.NONE);
232: label.setText(ROOTS);
233: label.setLayoutData(new GridData(
234: GridData.VERTICAL_ALIGN_BEGINNING));
235:
236: m_table = new Table(sidePanel, SWT.BORDER | SWT.MULTI
237: | SWT.FULL_SELECTION | SWT.V_SCROLL);
238: m_table.setHeaderVisible(true);
239: m_table.setLinesVisible(true);
240: SWTUtil.makeTableColumnsResizeWeightedWidth(sidePanel,
241: m_table, new int[] { 2, 1 });
242: SWTUtil.makeTableColumnsEditable(m_table,
243: new int[] { 0, 1 });
244: GridData gridData = new GridData(GridData.FILL_BOTH);
245: gridData.heightHint = SWTUtil.tableRowsToPixels(m_table, 3);
246: m_table.setLayoutData(gridData);
247:
248: TableColumn fieldCol = new TableColumn(m_table, SWT.NONE);
249: fieldCol.setResizable(true);
250: fieldCol.setText(FIELD);
251: fieldCol.pack();
252:
253: TableColumn nameCol = new TableColumn(m_table, SWT.NONE);
254: nameCol.setResizable(true);
255: nameCol.setText(NAME);
256: nameCol.pack();
257:
258: Composite buttonPanel = new Composite(comp, SWT.NONE);
259: gridLayout = new GridLayout();
260: gridLayout.marginWidth = gridLayout.marginHeight = 0;
261: buttonPanel.setLayout(gridLayout);
262: buttonPanel.setLayoutData(new GridData(
263: GridData.VERTICAL_ALIGN_BEGINNING));
264:
265: new Label(buttonPanel, SWT.NONE); // filler
266:
267: m_addButton = new Button(buttonPanel, SWT.PUSH);
268: m_addButton.setText(ADD);
269: m_addButton.setLayoutData(new GridData(
270: GridData.VERTICAL_ALIGN_END));
271: SWTUtil.applyDefaultButtonSize(m_addButton);
272:
273: m_removeButton = new Button(buttonPanel, SWT.PUSH);
274: m_removeButton.setText(REMOVE);
275: m_removeButton.setEnabled(false);
276: m_removeButton.setLayoutData(new GridData(
277: GridData.VERTICAL_ALIGN_BEGINNING));
278: SWTUtil.applyDefaultButtonSize(m_removeButton);
279: }
280: }
281:
282: class AddRootHandler extends SelectionAdapter {
283: public void widgetSelected(SelectionEvent e) {
284: m_layout.m_table.forceFocus();
285: NavigatorBehavior behavior = new FieldBehavior();
286: ExpressionChooser chooser = new ExpressionChooser(
287: getShell(), behavior.getTitle(),
288: FieldBehavior.ADD_MSG, m_project, behavior);
289: chooser.addValueListener(new UpdateEventListener() {
290: public void handleUpdate(UpdateEvent updateEvent) {
291: String[] items = (String[]) updateEvent.data;
292: for (int i = 0; i < items.length; i++) {
293: internalAddRoot(items[i]);
294: }
295: fireRootsChanged();
296: }
297: });
298: chooser.open();
299: }
300: }
301:
302: class RemoveRootHandler extends SelectionAdapter {
303: public void widgetSelected(SelectionEvent e) {
304: m_layout.m_table.forceFocus();
305: int[] selection = m_layout.m_table.getSelectionIndices();
306: for (int i = selection.length - 1; i >= 0; i--) {
307: ensureRoots().removeRoot(selection[i]);
308: }
309: m_layout.m_table.remove(selection);
310: syncModel();
311: }
312: }
313:
314: class TableSelectionListener extends SelectionAdapter {
315: public void widgetSelected(SelectionEvent e) {
316: m_layout.m_removeButton.setEnabled(true);
317: }
318: }
319:
320: class TableDataListener implements Listener {
321: public void handleEvent(Event e) {
322: TableItem item = (TableItem) e.item;
323: String text = item.getText(e.index);
324: Root root = (Root) item.getData();
325:
326: if (e.index == FIELD_COLUMN) {
327: if (text.length() == 0) {
328: int index = m_layout.m_table.indexOf(item);
329: ensureRoots().removeRoot(index);
330: m_layout.m_table.remove(index);
331: syncModel();
332: return;
333: } else {
334: root.setFieldName(text);
335: }
336: } else if (e.index == NAME_COLUMN) {
337: root.setRootName(text);
338: }
339: fireRootChanged(m_layout.m_table.indexOf(item));
340: }
341: }
342:
343: public void rootChanged(IProject project, int index) {
344: if (project.equals(getProject())) {
345: updateTableItem(index);
346: }
347: }
348: }
|