KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > ide > dialogs > PathVariablesGroup


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.internal.ide.dialogs;
12
13 import java.util.HashSet JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.Map JavaDoc;
16 import java.util.Set JavaDoc;
17 import java.util.SortedMap JavaDoc;
18 import java.util.TreeMap JavaDoc;
19
20 import org.eclipse.core.filesystem.IFileInfo;
21 import org.eclipse.core.resources.IPathVariableManager;
22 import org.eclipse.core.resources.IResource;
23 import org.eclipse.core.resources.ResourcesPlugin;
24 import org.eclipse.core.runtime.CoreException;
25 import org.eclipse.core.runtime.IPath;
26 import org.eclipse.core.runtime.Path;
27 import org.eclipse.jface.dialogs.Dialog;
28 import org.eclipse.jface.dialogs.ErrorDialog;
29 import org.eclipse.jface.dialogs.IDialogConstants;
30 import org.eclipse.jface.resource.ImageDescriptor;
31 import org.eclipse.jface.window.Window;
32 import org.eclipse.swt.SWT;
33 import org.eclipse.swt.events.SelectionAdapter;
34 import org.eclipse.swt.events.SelectionEvent;
35 import org.eclipse.swt.graphics.Font;
36 import org.eclipse.swt.graphics.FontMetrics;
37 import org.eclipse.swt.graphics.GC;
38 import org.eclipse.swt.graphics.Image;
39 import org.eclipse.swt.layout.GridData;
40 import org.eclipse.swt.layout.GridLayout;
41 import org.eclipse.swt.widgets.Button;
42 import org.eclipse.swt.widgets.Composite;
43 import org.eclipse.swt.widgets.Control;
44 import org.eclipse.swt.widgets.Event;
45 import org.eclipse.swt.widgets.Label;
46 import org.eclipse.swt.widgets.Listener;
47 import org.eclipse.swt.widgets.Shell;
48 import org.eclipse.swt.widgets.Table;
49 import org.eclipse.swt.widgets.TableItem;
50 import org.eclipse.ui.ISharedImages;
51 import org.eclipse.ui.PlatformUI;
52 import org.eclipse.ui.internal.ide.IDEWorkbenchMessages;
53 import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
54 import org.eclipse.ui.plugin.AbstractUIPlugin;
55
56 /**
57  * A widget group that displays path variables.
58  * Includes buttons to edit, remove existing variables and create new ones.
59  *
60  * @since 2.1
61  */

62 public class PathVariablesGroup {
63     /**
64      * Simple data structure that holds a path variable name/value pair.
65      */

66     public static class PathVariableElement {
67         /**
68          * The name of the element.
69          */

70         public String JavaDoc name;
71
72         /**
73          * The path of the element.
74          */

75         public IPath path;
76     }
77
78     // sizing constants
79
private static final int SIZING_SELECTION_PANE_WIDTH = 400;
80
81     // parent shell
82
private Shell shell;
83
84     private Label variableLabel;
85
86     private Table variableTable;
87
88     private Button addButton;
89
90     private Button editButton;
91
92     private Button removeButton;
93
94     // used to compute layout sizes
95
private FontMetrics fontMetrics;
96
97     // create a multi select table
98
private boolean multiSelect;
99
100     // IResource.FILE and/or IResource.FOLDER
101
private int variableType;
102
103     // External listener called when the table selection changes
104
private Listener selectionListener;
105
106     // temporary collection for keeping currently defined variables
107
private SortedMap JavaDoc tempPathVariables;
108
109     // set of removed variables' names
110
private Set JavaDoc removedVariableNames;
111
112     // reference to the workspace's path variable manager
113
private IPathVariableManager pathVariableManager;
114
115     // file image
116
private final Image FILE_IMG = PlatformUI.getWorkbench().getSharedImages()
117             .getImage(ISharedImages.IMG_OBJ_FILE);
118
119     // folder image
120
private final Image FOLDER_IMG = PlatformUI.getWorkbench()
121             .getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
122
123     // unknown (non-existent) image. created locally, dispose locally
124
private Image imageUnkown;
125
126     /**
127      * Creates a new PathVariablesGroup.
128      *
129      * @param multiSelect create a multi select tree
130      * @param variableType the type of variables that are displayed in
131      * the widget group. <code>IResource.FILE</code> and/or <code>IResource.FOLDER</code>
132      * logically ORed together.
133      */

134     public PathVariablesGroup(boolean multiSelect, int variableType) {
135         this.multiSelect = multiSelect;
136         this.variableType = variableType;
137         pathVariableManager = ResourcesPlugin.getWorkspace()
138                 .getPathVariableManager();
139         removedVariableNames = new HashSet JavaDoc();
140         tempPathVariables = new TreeMap JavaDoc();
141         // initialize internal model
142
initTemporaryState();
143     }
144
145     /**
146      * Creates a new PathVariablesGroup.
147      *
148      * @param multiSelect create a multi select tree
149      * @param variableType the type of variables that are displayed in
150      * the widget group. <code>IResource.FILE</code> and/or <code>IResource.FOLDER</code>
151      * logically ORed together.
152      * @param selectionListener listener notified when the selection changes
153      * in the variables list.
154      */

155     public PathVariablesGroup(boolean multiSelect, int variableType,
156             Listener selectionListener) {
157         this(multiSelect, variableType);
158         this.selectionListener = selectionListener;
159     }
160
161     /**
162      * Opens a dialog for creating a new variable.
163      */

164     private void addNewVariable() {
165         // constructs a dialog for editing the new variable's current name and value
166
PathVariableDialog dialog = new PathVariableDialog(shell,
167                 PathVariableDialog.NEW_VARIABLE, variableType,
168                 pathVariableManager, tempPathVariables.keySet());
169
170         // opens the dialog - just returns if the user cancels it
171
if (dialog.open() == Window.CANCEL) {
172             return;
173         }
174
175         // otherwise, adds the new variable (or updates an existing one) in the
176
// temporary collection of currently defined variables
177
String JavaDoc newVariableName = dialog.getVariableName();
178         IPath newVariableValue = new Path(dialog.getVariableValue());
179         tempPathVariables.put(newVariableName, newVariableValue);
180
181         // the UI must be updated
182
updateWidgetState(newVariableName);
183     }
184
185     /**
186      * Creates the widget group.
187      * Callers must call <code>dispose</code> when the group is no
188      * longer needed.
189      *
190      * @param parent the widget parent
191      * @return container of the widgets
192      */

193     public Control createContents(Composite parent) {
194         Font font = parent.getFont();
195
196         if (imageUnkown == null) {
197             ImageDescriptor descriptor = AbstractUIPlugin
198                     .imageDescriptorFromPlugin(
199                             IDEWorkbenchPlugin.IDE_WORKBENCH,
200                             "$nl$/icons/full/obj16/warning.gif"); //$NON-NLS-1$
201
imageUnkown = descriptor.createImage();
202         }
203         initializeDialogUnits(parent);
204         shell = parent.getShell();
205
206         // define container & its layout
207
Composite pageComponent = new Composite(parent, SWT.NULL);
208         GridLayout layout = new GridLayout();
209         layout.numColumns = 2;
210         layout.marginWidth = 0;
211         layout.marginHeight = 0;
212         pageComponent.setLayout(layout);
213         GridData data = new GridData(GridData.FILL_BOTH);
214         data.widthHint = SIZING_SELECTION_PANE_WIDTH;
215         pageComponent.setLayoutData(data);
216         pageComponent.setFont(font);
217
218         // layout the table & its buttons
219
variableLabel = new Label(pageComponent, SWT.LEFT);
220         variableLabel.setText(IDEWorkbenchMessages.PathVariablesBlock_variablesLabel);
221         data = new GridData();
222         data.horizontalAlignment = GridData.FILL;
223         data.horizontalSpan = 2;
224         variableLabel.setLayoutData(data);
225         variableLabel.setFont(font);
226
227         int tableStyle = SWT.BORDER | SWT.FULL_SELECTION;
228         if (multiSelect) {
229             tableStyle |= SWT.MULTI;
230         }
231         variableTable = new Table(pageComponent, tableStyle);
232         variableTable.addSelectionListener(new SelectionAdapter() {
233             public void widgetSelected(SelectionEvent e) {
234                 updateEnabledState();
235                 if (selectionListener != null) {
236                     selectionListener.handleEvent(new Event());
237                 }
238             }
239         });
240         data = new GridData(GridData.FILL_BOTH);
241         data.heightHint = variableTable.getItemHeight() * 7;
242         variableTable.setLayoutData(data);
243         variableTable.setFont(font);
244
245         createButtonGroup(pageComponent);
246         // populate table with current internal state and set buttons' initial state
247
updateWidgetState(null);
248
249         return pageComponent;
250     }
251
252     /**
253      * Disposes the group's resources.
254      */

255     public void dispose() {
256         if (imageUnkown != null) {
257             imageUnkown.dispose();
258             imageUnkown = null;
259         }
260     }
261
262     /**
263      * Opens a dialog for editing an existing variable.
264      *
265      * @see PathVariableDialog
266      */

267     private void editSelectedVariable() {
268         // retrieves the name and value for the currently selected variable
269
TableItem item = variableTable.getItem(variableTable
270                 .getSelectionIndex());
271         String JavaDoc variableName = (String JavaDoc) item.getData();
272         IPath variableValue = (IPath) tempPathVariables.get(variableName);
273
274         // constructs a dialog for editing the variable's current name and value
275
PathVariableDialog dialog = new PathVariableDialog(shell,
276                 PathVariableDialog.EXISTING_VARIABLE, variableType,
277                 pathVariableManager, tempPathVariables.keySet());
278         dialog.setVariableName(variableName);
279         dialog.setVariableValue(variableValue.toOSString());
280
281         // opens the dialog - just returns if the user cancels it
282
if (dialog.open() == Window.CANCEL) {
283             return;
284         }
285
286         // the name can be changed, so we remove the current variable definition...
287
removedVariableNames.add(variableName);
288         tempPathVariables.remove(variableName);
289
290         String JavaDoc newVariableName = dialog.getVariableName();
291         IPath newVariableValue = new Path(dialog.getVariableValue());
292
293         // and add it again (maybe with a different name)
294
tempPathVariables.put(newVariableName, newVariableValue);
295
296         // now we must refresh the UI state
297
updateWidgetState(newVariableName);
298
299     }
300
301     /**
302      * Returns the enabled state of the group's widgets.
303      * Returns <code>true</code> if called prior to calling
304      * <code>createContents</code>.
305      *
306      * @return boolean the enabled state of the group's widgets.
307      * <code>true</code> if called prior to calling <code>createContents</code>.
308      */

309     public boolean getEnabled() {
310         if (variableTable != null && !variableTable.isDisposed()) {
311             return variableTable.getEnabled();
312         }
313         return true;
314     }
315
316     /**
317      * Returns the selected variables.
318      *
319      * @return the selected variables. Returns an empty array if
320      * the widget group has not been created yet by calling
321      * <code>createContents</code>
322      */

323     public PathVariableElement[] getSelection() {
324         if (variableTable == null) {
325             return new PathVariableElement[0];
326         }
327         TableItem[] items = variableTable.getSelection();
328         PathVariableElement[] selection = new PathVariableElement[items.length];
329
330         for (int i = 0; i < items.length; i++) {
331             String JavaDoc name = (String JavaDoc) items[i].getData();
332             selection[i] = new PathVariableElement();
333             selection[i].name = name;
334             selection[i].path = (IPath) tempPathVariables.get(name);
335         }
336         return selection;
337     }
338
339     /**
340      * Creates the add/edit/remove buttons
341      *
342      * @param parent the widget parent
343      */

344     private void createButtonGroup(Composite parent) {
345         Font font = parent.getFont();
346         Composite groupComponent = new Composite(parent, SWT.NULL);
347         GridLayout groupLayout = new GridLayout();
348         groupLayout.marginWidth = 0;
349         groupLayout.marginHeight = 0;
350         groupComponent.setLayout(groupLayout);
351         GridData data = new GridData();
352         data.verticalAlignment = GridData.FILL;
353         data.horizontalAlignment = GridData.FILL;
354         groupComponent.setLayoutData(data);
355         groupComponent.setFont(font);
356
357         addButton = new Button(groupComponent, SWT.PUSH);
358         addButton.setText(IDEWorkbenchMessages.PathVariablesBlock_addVariableButton);
359         addButton.addSelectionListener(new SelectionAdapter() {
360             public void widgetSelected(SelectionEvent e) {
361                 addNewVariable();
362             }
363         });
364         addButton.setFont(font);
365         setButtonLayoutData(addButton);
366
367         editButton = new Button(groupComponent, SWT.PUSH);
368         editButton.setText(IDEWorkbenchMessages.PathVariablesBlock_editVariableButton);
369         editButton.addSelectionListener(new SelectionAdapter() {
370             public void widgetSelected(SelectionEvent e) {
371                 editSelectedVariable();
372             }
373         });
374         editButton.setFont(font);
375         setButtonLayoutData(editButton);
376
377         removeButton = new Button(groupComponent, SWT.PUSH);
378         removeButton.setText(IDEWorkbenchMessages.PathVariablesBlock_removeVariableButton);
379         removeButton.addSelectionListener(new SelectionAdapter() {
380             public void widgetSelected(SelectionEvent e) {
381                 removeSelectedVariables();
382             }
383         });
384         removeButton.setFont(font);
385         setButtonLayoutData(removeButton);
386     }
387
388     /**
389      * Initializes the computation of horizontal and vertical dialog units
390      * based on the size of current font.
391      * <p>
392      * This method must be called before <code>setButtonLayoutData</code>
393      * is called.
394      * </p>
395      *
396      * @param control a control from which to obtain the current font
397      */

398     protected void initializeDialogUnits(Control control) {
399         // Compute and store a font metric
400
GC gc = new GC(control);
401         gc.setFont(control.getFont());
402         fontMetrics = gc.getFontMetrics();
403         gc.dispose();
404     }
405
406     /**
407      * (Re-)Initialize collections used to mantain temporary variable state.
408      */

409     private void initTemporaryState() {
410         String JavaDoc[] varNames = pathVariableManager.getPathVariableNames();
411
412         tempPathVariables.clear();
413         for (int i = 0; i < varNames.length; i++) {
414             IPath value = pathVariableManager.getValue(varNames[i]);
415
416             // the value may not exist any more
417
if (value != null) {
418                 boolean isFile = value.toFile().isFile();
419                 if ((isFile && (variableType & IResource.FILE) != 0)
420                         || (isFile == false && (variableType & IResource.FOLDER) != 0)) {
421
422                     tempPathVariables.put(varNames[i], value);
423                 }
424             }
425         }
426         removedVariableNames.clear();
427     }
428
429     /**
430      * Updates button enabled state, depending on the number of currently selected
431      * variables in the table.
432      */

433     private void updateEnabledState() {
434         int itemsSelectedCount = variableTable.getSelectionCount();
435         editButton.setEnabled(itemsSelectedCount == 1);
436         removeButton.setEnabled(itemsSelectedCount > 0);
437     }
438
439     /**
440      * Rebuilds table widget state with the current list of variables (reflecting
441      * any changes, additions and removals), and selects the item corresponding to
442      * the given variable name. If the variable name is <code>null</code>, the
443      * first item (if any) will be selected.
444      *
445      * @param selectedVarName the name for the variable to be selected (may be
446      * <code>null</code>)
447      * @see IPathVariableManager#getPathVariableNames()
448      * @see IPathVariableManager#getValue(String)
449      */

450     private void updateVariableTable(String JavaDoc selectedVarName) {
451         variableTable.removeAll();
452         int selectedVarIndex = 0;
453         for (Iterator JavaDoc varNames = tempPathVariables.keySet().iterator(); varNames
454                 .hasNext();) {
455             TableItem item = new TableItem(variableTable, SWT.NONE);
456             String JavaDoc varName = (String JavaDoc) varNames.next();
457             IPath value = (IPath) tempPathVariables.get(varName);
458             IFileInfo file = IDEResourceInfoUtils.getFileInfo(value);
459
460             item.setText(varName + " - " + value.toOSString()); //$NON-NLS-1$
461
// the corresponding variable name is stored in each table widget item
462
item.setData(varName);
463             item.setImage(file.exists() ? (file.isDirectory() ? FOLDER_IMG
464                     : FILE_IMG ) : imageUnkown);
465             if (varName.equals(selectedVarName)) {
466                 selectedVarIndex = variableTable.getItemCount() - 1;
467             }
468         }
469         if (variableTable.getItemCount() > selectedVarIndex) {
470             variableTable.setSelection(selectedVarIndex);
471             if (selectionListener != null) {
472                 selectionListener.handleEvent(new Event());
473             }
474         } else if (variableTable.getItemCount() == 0
475                 && selectionListener != null) {
476             selectionListener.handleEvent(new Event());
477         }
478     }
479
480     /**
481      * Commits the temporary state to the path variable manager in response to user
482      * confirmation.
483      * @return boolean <code>true</code> if there were no problems.
484      * @see IPathVariableManager#setValue(String, IPath)
485      */

486     public boolean performOk() {
487         try {
488             // first process removed variables
489
for (Iterator JavaDoc removed = removedVariableNames.iterator(); removed
490                     .hasNext();) {
491                 String JavaDoc removedVariableName = (String JavaDoc) removed.next();
492                 // only removes variables that have not been added again
493
if (!tempPathVariables.containsKey(removedVariableName)) {
494                     pathVariableManager.setValue(removedVariableName, null);
495                 }
496             }
497
498             // then process the current collection of variables, adding/updating them
499
for (Iterator JavaDoc current = tempPathVariables.entrySet().iterator(); current
500                     .hasNext();) {
501                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) current.next();
502                 String JavaDoc variableName = (String JavaDoc) entry.getKey();
503                 IPath variableValue = (IPath) entry.getValue();
504                 pathVariableManager.setValue(variableName, variableValue);
505             }
506             // re-initialize temporary state
507
initTemporaryState();
508
509             // performOk accepted
510
return true;
511         } catch (CoreException ce) {
512             ErrorDialog.openError(shell, null, null, ce.getStatus());
513         }
514         return false;
515     }
516
517     /**
518      * Removes the currently selected variables.
519      */

520     private void removeSelectedVariables() {
521         // remove each selected element
522
int[] selectedIndices = variableTable.getSelectionIndices();
523         for (int i = 0; i < selectedIndices.length; i++) {
524             TableItem selectedItem = variableTable.getItem(selectedIndices[i]);
525             String JavaDoc varName = (String JavaDoc) selectedItem.getData();
526             removedVariableNames.add(varName);
527             tempPathVariables.remove(varName);
528         }
529         updateWidgetState(null);
530     }
531
532     /**
533      * Sets the <code>GridData</code> on the specified button to
534      * be one that is spaced for the current dialog page units. The
535      * method <code>initializeDialogUnits</code> must be called once
536      * before calling this method for the first time.
537      *
538      * @param button the button to set the <code>GridData</code>
539      * @return the <code>GridData</code> set on the specified button
540      */

541     private GridData setButtonLayoutData(Button button) {
542         GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
543         int widthHint = Dialog.convertHorizontalDLUsToPixels(fontMetrics,
544                 IDialogConstants.BUTTON_WIDTH);
545         data.widthHint = Math.max(widthHint, button.computeSize(SWT.DEFAULT,
546                 SWT.DEFAULT, true).x);
547         button.setLayoutData(data);
548         return data;
549     }
550
551     /**
552      * Sets the enabled state of the group's widgets.
553      * Does nothing if called prior to calling <code>createContents</code>.
554      *
555      * @param enabled the new enabled state of the group's widgets
556      */

557     public void setEnabled(boolean enabled) {
558         if (variableTable != null && !variableTable.isDisposed()) {
559             variableLabel.setEnabled(enabled);
560             variableTable.setEnabled(enabled);
561             addButton.setEnabled(enabled);
562             if (enabled) {
563                 updateEnabledState();
564             } else {
565                 editButton.setEnabled(enabled);
566                 removeButton.setEnabled(enabled);
567             }
568         }
569     }
570
571     /**
572      * Updates the widget's current state: refreshes the table with the current
573      * defined variables, selects the item corresponding to the given variable
574      * (selects the first item if <code>null</code> is provided) and updates
575      * the enabled state for the Add/Remove/Edit buttons.
576      *
577      * @param selectedVarName the name of the variable to be selected (may be null)
578      */

579     private void updateWidgetState(String JavaDoc selectedVarName) {
580         updateVariableTable(selectedVarName);
581         updateEnabledState();
582     }
583 }
584
Popular Tags