upload tizen1.0 source
[sdk/ide/product.git] / org.eclipse.cdt.ui / src / org / eclipse / cdt / internal / ui / preferences / PathEntryVariablesGroup.java
1 /*******************************************************************************
2  * Copyright (c) 2002, 2008 QNX Software Systems 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  * QNX Software Systems - Initial API and implementation
10  *     IBM Corporation - initial API and implementation
11  *******************************************************************************/
12
13 package org.eclipse.cdt.internal.ui.preferences;
14
15 import java.io.File;
16 import java.util.HashSet;
17 import java.util.Set;
18 import java.util.SortedMap;
19 import java.util.TreeMap;
20 import java.util.Map.Entry;
21
22 import org.eclipse.core.resources.IPathVariableManager;
23 import org.eclipse.core.resources.IResource;
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
53 import org.eclipse.cdt.core.CCorePlugin;
54 import org.eclipse.cdt.core.resources.IPathEntryVariableManager;
55
56 import org.eclipse.cdt.internal.ui.CPluginImages;
57
58 /**
59  * @deprecated in CDT 8.0. This class appears to be never used.
60  */
61 @Deprecated
62 public class PathEntryVariablesGroup {
63         
64         /**
65          * Simple data structure that holds a path variable name/value pair.
66          */
67         public static class PathEntryVariableElement {
68                 public String name;
69                 
70                 public IPath path;
71         }
72         
73         // sizing constants
74         private static final int SIZING_SELECTION_PANE_WIDTH = 400;
75         
76         // parent shell
77         private Shell shell;
78         
79         private Label variableLabel;
80         
81         private Table variableTable;
82         
83         private Button addButton;
84         
85         private Button editButton;
86         
87         private Button removeButton;
88         
89         // used to compute layout sizes
90         private FontMetrics fontMetrics;
91         
92         // create a multi select table
93         private boolean multiSelect;
94         
95         // IResource.FILE and/or IResource.FOLDER
96         private int variableType;
97         
98         // External listener called when the table selection changes
99         protected Listener selectionListener;
100         
101         // temporary collection for keeping currently defined variables
102         private SortedMap<String, IPath> tempPathVariables;
103         
104         // set of removed variables' names
105         private Set<String> removedVariableNames;
106         
107         // reference to the workspace's path variable manager
108         private IPathEntryVariableManager pathEntryVariableManager;
109         
110         // file image
111         private final Image FILE_IMG = PlatformUI.getWorkbench().getSharedImages()
112         .getImage(ISharedImages.IMG_OBJ_FILE);
113         
114         // folder image
115         private final Image FOLDER_IMG = PlatformUI.getWorkbench()
116         .getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
117         
118         // unknown (non-existent) image. created locally, dispose locally
119         private Image imageUnkown;
120         
121         /**
122          * Creates a new PathVariablesGroup.
123          *
124          * @param multiSelect create a multi select tree
125          * @param variableType the type of variables that are displayed in 
126          *      the widget group. <code>IResource.FILE</code> and/or <code>IResource.FOLDER</code>
127          *      logically ORed together.
128          */
129         public PathEntryVariablesGroup(boolean multiSelect, int variableType) {
130                 this.multiSelect = multiSelect;
131                 this.variableType = variableType;
132                 pathEntryVariableManager = CCorePlugin.getDefault().getPathEntryVariableManager();
133                 removedVariableNames = new HashSet<String>();
134                 tempPathVariables = new TreeMap<String, IPath>();
135                 // initialize internal model
136                 initTemporaryState();
137         }
138         
139         /**
140          * Creates a new PathVariablesGroup.
141          *
142          * @param multiSelect create a multi select tree
143          * @param variableType the type of variables that are displayed in 
144          *      the widget group. <code>IResource.FILE</code> and/or <code>IResource.FOLDER</code>
145          *      logically ORed together.
146          * @param selectionListener listener notified when the selection changes
147          *      in the variables list.
148          */
149         public PathEntryVariablesGroup(boolean multiSelect, int variableType,
150                         Listener selectionListener) {
151                 this(multiSelect, variableType);
152                 this.selectionListener = selectionListener;
153         }
154         
155         /**
156          * Opens a dialog for creating a new variable.
157          */
158         protected void addNewVariable() {
159                 // constructs a dialog for editing the new variable's current name and value
160                 PathEntryVariableDialog dialog = new PathEntryVariableDialog(shell,
161                                 PathEntryVariableDialog.NEW_VARIABLE, variableType, tempPathVariables.keySet());
162                 
163                 // opens the dialog - just returns if the user cancels it
164                 if (dialog.open() == Window.CANCEL)
165                         return;
166                 
167                 // otherwise, adds the new variable (or updates an existing one) in the
168                 // temporary collection of currently defined variables
169                 String newVariableName = dialog.getVariableName();
170                 IPath newVariableValue = new Path(dialog.getVariableValue());
171                 tempPathVariables.put(newVariableName, newVariableValue);
172                 
173                 // the UI must be updated
174                 updateWidgetState(newVariableName);
175         }
176         
177         /**
178          * Creates the widget group.
179          * Callers must call <code>dispose</code> when the group is no 
180          * longer needed.
181          * 
182          * @param parent the widget parent
183          * @return container of the widgets 
184          */
185         public Control createContents(Composite parent) {
186                 Font font = parent.getFont();
187                 
188                 if (imageUnkown == null) {
189                         ImageDescriptor descriptor = CPluginImages.DESC_OVR_WARNING;
190                         imageUnkown = descriptor.createImage();
191                 }
192                 initializeDialogUnits(parent);
193                 shell = parent.getShell();
194                 
195                 // define container & its layout
196                 Composite pageComponent = new Composite(parent, SWT.NULL);
197                 GridLayout layout = new GridLayout();
198                 layout.numColumns = 2;
199                 layout.marginWidth = 0;
200                 layout.marginHeight = 0;
201                 pageComponent.setLayout(layout);
202                 GridData data = new GridData(GridData.FILL_BOTH);
203                 data.widthHint = SIZING_SELECTION_PANE_WIDTH;
204                 pageComponent.setLayoutData(data);
205                 pageComponent.setFont(font);
206                 
207                 // layout the table & its buttons
208                 variableLabel = new Label(pageComponent, SWT.LEFT);
209                 variableLabel.setText(PreferencesMessages.PathEntryVariablesBlock_variablesLabel); 
210                 data = new GridData();
211                 data.horizontalAlignment = GridData.FILL;
212                 data.horizontalSpan = 2;
213                 variableLabel.setLayoutData(data);
214                 variableLabel.setFont(font);
215                 
216                 int tableStyle = SWT.BORDER | SWT.FULL_SELECTION;
217                 if (multiSelect) {
218                         tableStyle |= SWT.MULTI;
219                 }
220                 variableTable = new Table(pageComponent, tableStyle);
221                 variableTable.addSelectionListener(new SelectionAdapter() {
222                         @Override
223                         public void widgetSelected(SelectionEvent e) {
224                                 updateEnabledState();
225                                 if (selectionListener != null)
226                                         selectionListener.handleEvent(new Event());
227                         }
228                 });
229                 data = new GridData(GridData.FILL_BOTH);
230                 data.heightHint = variableTable.getItemHeight() * 7;
231                 variableTable.setLayoutData(data);
232                 variableTable.setFont(font);
233                 
234                 createButtonGroup(pageComponent);
235                 // populate table with current internal state and set buttons' initial state
236                 updateWidgetState(null);
237                 
238                 return pageComponent;
239         }
240         
241         /**
242          * Disposes the group's resources. 
243          */
244         public void dispose() {
245                 if (imageUnkown != null) {
246                         imageUnkown.dispose();
247                         imageUnkown = null;
248                 }
249         }
250         
251         /**
252          * Opens a dialog for editing an existing variable.
253          *
254          * @see PathEntryVariableDialog
255          */
256         protected void editSelectedVariable() {
257                 // retrieves the name and value for the currently selected variable
258                 TableItem item = variableTable.getItem(variableTable
259                                 .getSelectionIndex());
260                 String variableName = (String) item.getData();
261                 IPath variableValue = tempPathVariables.get(variableName);
262                 
263                 // constructs a dialog for editing the variable's current name and value
264                 PathEntryVariableDialog dialog = new PathEntryVariableDialog(shell,
265                                 PathEntryVariableDialog.EXISTING_VARIABLE, variableType, tempPathVariables.keySet());
266                 dialog.setVariableName(variableName);
267                 dialog.setVariableValue(variableValue.toOSString());
268                 
269                 // opens the dialog - just returns if the user cancels it
270                 if (dialog.open() == Window.CANCEL)
271                         return;
272                 
273                 // the name can be changed, so we remove the current variable definition...
274                 removedVariableNames.add(variableName);
275                 tempPathVariables.remove(variableName);
276                 
277                 String newVariableName = dialog.getVariableName();
278                 IPath newVariableValue = new Path(dialog.getVariableValue());
279                 
280                 // and add it again (maybe with a different name)
281                 tempPathVariables.put(newVariableName, newVariableValue);
282                 
283                 // now we must refresh the UI state
284                 updateWidgetState(newVariableName);
285                 
286         }
287         
288         /**
289          * Returns the enabled state of the group's widgets.
290          * Returns <code>true</code> if called prior to calling 
291          * <code>createContents</code>.
292          * 
293          * @return boolean the enabled state of the group's widgets.
294          *       <code>true</code> if called prior to calling <code>createContents</code>.
295          */
296         public boolean getEnabled() {
297                 if (variableTable != null && !variableTable.isDisposed()) {
298                         return variableTable.getEnabled();
299                 }
300                 return true;
301         }
302         
303         /**
304          * Returns the selected variables.
305          *  
306          * @return the selected variables. Returns an empty array if 
307          *      the widget group has not been created yet by calling 
308          *      <code>createContents</code>
309          */
310         public PathEntryVariableElement[] getSelection() {
311                 if (variableTable == null) {
312                         return new PathEntryVariableElement[0];
313                 }
314                 TableItem[] items = variableTable.getSelection();
315                 PathEntryVariableElement[] selection = new PathEntryVariableElement[items.length];
316                 
317                 for (int i = 0; i < items.length; i++) {
318                         String name = (String) items[i].getData();
319                         selection[i] = new PathEntryVariableElement();
320                         selection[i].name = name;
321                         selection[i].path = tempPathVariables.get(name);
322                 }
323                 return selection;
324         }
325         
326         /**
327          * Creates the add/edit/remove buttons
328          * 
329          * @param parent the widget parent
330          */
331         private void createButtonGroup(Composite parent) {
332                 Font font = parent.getFont();
333                 Composite groupComponent = new Composite(parent, SWT.NULL);
334                 GridLayout groupLayout = new GridLayout();
335                 groupLayout.marginWidth = 0;
336                 groupLayout.marginHeight = 0;
337                 groupComponent.setLayout(groupLayout);
338                 GridData data = new GridData();
339                 data.verticalAlignment = GridData.FILL;
340                 data.horizontalAlignment = GridData.FILL;
341                 groupComponent.setLayoutData(data);
342                 groupComponent.setFont(font);
343                 
344                 addButton = new Button(groupComponent, SWT.PUSH);
345                 addButton.setText(PreferencesMessages.PathEntryVariablesBlock_addVariableButton); 
346                 addButton.addSelectionListener(new SelectionAdapter() {
347                         @Override
348                         public void widgetSelected(SelectionEvent e) {
349                                 addNewVariable();
350                         }
351                 });
352                 addButton.setFont(font);
353                 setButtonLayoutData(addButton);
354                 
355                 editButton = new Button(groupComponent, SWT.PUSH);
356                 editButton.setText(PreferencesMessages.PathEntryVariablesBlock_editVariableButton); 
357                 editButton.addSelectionListener(new SelectionAdapter() {
358                         @Override
359                         public void widgetSelected(SelectionEvent e) {
360                                 editSelectedVariable();
361                         }
362                 });
363                 editButton.setFont(font);
364                 setButtonLayoutData(editButton);
365                 
366                 removeButton = new Button(groupComponent, SWT.PUSH);
367                 removeButton.setText(PreferencesMessages.PathEntryVariablesBlock_removeVariableButton); 
368                 removeButton.addSelectionListener(new SelectionAdapter() {
369                         @Override
370                         public void widgetSelected(SelectionEvent e) {
371                                 removeSelectedVariables();
372                         }
373                 });
374                 removeButton.setFont(font);
375                 setButtonLayoutData(removeButton);
376         }
377         
378         /**
379          * Initializes the computation of horizontal and vertical dialog units
380          * based on the size of current font.
381          * <p>
382          * This method must be called before <code>setButtonLayoutData</code> 
383          * is called.
384          * </p>
385          *
386          * @param control a control from which to obtain the current font
387          */
388         protected void initializeDialogUnits(Control control) {
389                 // Compute and store a font metric
390                 GC gc = new GC(control);
391                 gc.setFont(control.getFont());
392                 fontMetrics = gc.getFontMetrics();
393                 gc.dispose();
394         }
395         
396         /**
397          * (Re-)Initialize collections used to mantain temporary variable state.
398          */
399         private void initTemporaryState() {
400                 String[] varNames = pathEntryVariableManager.getVariableNames();
401                 
402                 tempPathVariables.clear();
403                 for (String varName : varNames) {
404                         IPath value = pathEntryVariableManager.getValue(varName);
405                         
406                         // the value may not exist any more
407                         if (value != null) {
408                                 boolean isFile = value.toFile().isFile();
409                                 if ((isFile && (variableType & IResource.FILE) != 0)
410                                                 || (isFile == false && (variableType & IResource.FOLDER) != 0)) {
411                                         
412                                         tempPathVariables.put(varName, value);
413                                 }
414                         }
415                 }
416                 removedVariableNames.clear();
417         }
418         
419         /**
420          * Updates button enabled state, depending on the number of currently selected
421          * variables in the table.
422          */
423         protected void updateEnabledState() {
424                 int itemsSelectedCount = variableTable.getSelectionCount();
425                 editButton.setEnabled(itemsSelectedCount == 1);
426                 removeButton.setEnabled(itemsSelectedCount > 0);
427         }
428         
429         /**
430          * Rebuilds table widget state with the current list of variables (reflecting
431          * any changes, additions and removals), and selects the item corresponding to
432          * the given variable name. If the variable name is <code>null</code>, the
433          * first item (if any) will be selected.
434          * 
435          * @param selectedVarName the name for the variable to be selected (may be
436          * <code>null</code>)
437          * @see IPathVariableManager#getPathVariableNames()
438          * @see IPathVariableManager#getValue(String)
439          */
440         private void updateVariableTable(String selectedVarName) {
441                 variableTable.removeAll();
442                 int selectedVarIndex = 0;
443                 for (String varName : tempPathVariables.keySet()) {
444                         TableItem item = new TableItem(variableTable, SWT.NONE);
445                         IPath value = tempPathVariables.get(varName);
446                         File file = value.toFile();
447                         
448                         item.setText(varName + " - " + value.toOSString()); //$NON-NLS-1$ 
449                         // the corresponding variable name is stored in each table widget item
450                         item.setData(varName);
451                         item.setImage(file.exists() ? (file.isFile() ? FILE_IMG
452                                         : FOLDER_IMG) : imageUnkown);
453                         if (varName.equals(selectedVarName))
454                                 selectedVarIndex = variableTable.getItemCount() - 1;
455                 }
456                 if (variableTable.getItemCount() > selectedVarIndex) {
457                         variableTable.setSelection(selectedVarIndex);
458                         if (selectionListener != null)
459                                 selectionListener.handleEvent(new Event());
460                 } else if (variableTable.getItemCount() == 0
461                                 && selectionListener != null)
462                         selectionListener.handleEvent(new Event());
463         }
464         
465         /**
466          * Commits the temporary state to the path variable manager in response to user
467          * confirmation.
468          *
469          * @see IPathEntryVariableManager#setValue(String, IPath)
470          */
471         public boolean performOk() {
472                 try {
473                         // first process removed variables  
474                         for (String removedVariableName : removedVariableNames) {
475                                 // only removes variables that have not been added again
476                                 if (!tempPathVariables.containsKey(removedVariableName))
477                                         pathEntryVariableManager.setValue(removedVariableName, null);
478                         }
479                         
480                         // then process the current collection of variables, adding/updating them
481                         for (Entry<String, IPath> entry : tempPathVariables.entrySet()) {
482                                 String variableName = entry.getKey();
483                                 IPath variableValue = entry.getValue();
484                                 pathEntryVariableManager.setValue(variableName, variableValue);
485                         }
486                         // re-initialize temporary state
487                         initTemporaryState();
488                         
489                         // performOk accepted
490                         return true;
491                 } catch (CoreException ce) {
492                         ErrorDialog.openError(shell, null, null, ce.getStatus());
493                 }
494                 return false;
495         }
496         
497         /**
498          * Removes the currently selected variables.
499          */
500         protected void removeSelectedVariables() {
501                 // remove each selected element
502                 int[] selectedIndices = variableTable.getSelectionIndices();
503                 for (int selectedIndice : selectedIndices) {
504                         TableItem selectedItem = variableTable.getItem(selectedIndice);
505                         String varName = (String) selectedItem.getData();
506                         removedVariableNames.add(varName);
507                         tempPathVariables.remove(varName);
508                 }
509                 updateWidgetState(null);
510         }
511         
512         /**
513          * Sets the <code>GridData</code> on the specified button to
514          * be one that is spaced for the current dialog page units. The
515          * method <code>initializeDialogUnits</code> must be called once
516          * before calling this method for the first time.
517          *
518          * @param button the button to set the <code>GridData</code>
519          * @return the <code>GridData</code> set on the specified button
520          */
521         private GridData setButtonLayoutData(Button button) {
522                 GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
523                 int widthHint = Dialog.convertHorizontalDLUsToPixels(fontMetrics,
524                                 IDialogConstants.BUTTON_WIDTH);
525                 data.widthHint = Math.max(widthHint, button.computeSize(SWT.DEFAULT,
526                                 SWT.DEFAULT, true).x);
527                 button.setLayoutData(data);
528                 return data;
529         }
530         
531         /**
532          * Sets the enabled state of the group's widgets.
533          * Does nothing if called prior to calling <code>createContents</code>.
534          * 
535          * @param enabled the new enabled state of the group's widgets
536          */
537         public void setEnabled(boolean enabled) {
538                 if (variableTable != null && !variableTable.isDisposed()) {
539                         variableLabel.setEnabled(enabled);
540                         variableTable.setEnabled(enabled);
541                         addButton.setEnabled(enabled);
542                         if (enabled)
543                                 updateEnabledState();
544                         else {
545                                 editButton.setEnabled(enabled);
546                                 removeButton.setEnabled(enabled);
547                         }
548                 }
549         }
550         
551         /**
552          * Updates the widget's current state: refreshes the table with the current 
553          * defined variables, selects the item corresponding to the given variable 
554          * (selects the first item if <code>null</code> is provided) and updates 
555          * the enabled state for the Add/Remove/Edit buttons.
556          * 
557          * @param selectedVarName the name of the variable to be selected (may be null)
558          */
559         private void updateWidgetState(String selectedVarName) {
560                 updateVariableTable(selectedVarName);
561                 updateEnabledState();
562         }
563         
564 }