KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > activities > ws > ActivityEnabler


1 /*******************************************************************************
2  * Copyright (c) 2003, 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.activities.ws;
12
13 import java.util.ArrayList JavaDoc;
14 import java.util.Arrays JavaDoc;
15 import java.util.Collection JavaDoc;
16 import java.util.HashSet JavaDoc;
17 import java.util.Iterator JavaDoc;
18 import java.util.List JavaDoc;
19 import java.util.Properties JavaDoc;
20 import java.util.Set JavaDoc;
21
22 import org.eclipse.jface.dialogs.Dialog;
23 import org.eclipse.jface.dialogs.IDialogConstants;
24 import org.eclipse.jface.resource.JFaceResources;
25 import org.eclipse.jface.viewers.AbstractTreeViewer;
26 import org.eclipse.jface.viewers.CheckStateChangedEvent;
27 import org.eclipse.jface.viewers.CheckboxTreeViewer;
28 import org.eclipse.jface.viewers.ICheckStateListener;
29 import org.eclipse.jface.viewers.ISelectionChangedListener;
30 import org.eclipse.jface.viewers.IStructuredSelection;
31 import org.eclipse.jface.viewers.SelectionChangedEvent;
32 import org.eclipse.jface.viewers.StructuredSelection;
33 import org.eclipse.jface.viewers.ViewerComparator;
34 import org.eclipse.swt.SWT;
35 import org.eclipse.swt.events.SelectionAdapter;
36 import org.eclipse.swt.events.SelectionEvent;
37 import org.eclipse.swt.graphics.FontMetrics;
38 import org.eclipse.swt.graphics.GC;
39 import org.eclipse.swt.graphics.Point;
40 import org.eclipse.swt.layout.GridData;
41 import org.eclipse.swt.layout.GridLayout;
42 import org.eclipse.swt.widgets.Button;
43 import org.eclipse.swt.widgets.Composite;
44 import org.eclipse.swt.widgets.Control;
45 import org.eclipse.swt.widgets.Label;
46 import org.eclipse.swt.widgets.Text;
47 import org.eclipse.ui.activities.ActivitiesPreferencePage;
48 import org.eclipse.ui.activities.IActivity;
49 import org.eclipse.ui.activities.ICategory;
50 import org.eclipse.ui.activities.ICategoryActivityBinding;
51 import org.eclipse.ui.activities.IMutableActivityManager;
52 import org.eclipse.ui.activities.NotDefinedException;
53
54 /**
55  * A simple control provider that will allow the user to toggle on/off the
56  * activities bound to categories.
57  *
58  * @since 3.0
59  */

60 public class ActivityEnabler {
61
62     private static final int ALL = 2;
63
64     private static final int NONE = 0;
65
66     private static final int SOME = 1;
67
68     private ISelectionChangedListener selectionListener = new ISelectionChangedListener() {
69
70         /*
71          * (non-Javadoc)
72          *
73          * @see org.eclipse.jface.viewers.ISelectionChangedListener#selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent)
74          */

75         public void selectionChanged(SelectionChangedEvent event) {
76             Object JavaDoc element = ((IStructuredSelection) event.getSelection())
77                     .getFirstElement();
78             try {
79                 if (element instanceof ICategory) {
80                     descriptionText.setText(((ICategory) element)
81                             .getDescription());
82                 } else if (element instanceof IActivity) {
83                     descriptionText.setText(((IActivity) element)
84                             .getDescription());
85                 }
86             } catch (NotDefinedException e) {
87                 descriptionText.setText(""); //$NON-NLS-1$
88
}
89         }
90     };
91
92     /**
93      * Listener that manages the grey/check state of categories.
94      */

95     private ICheckStateListener checkListener = new ICheckStateListener() {
96
97         /*
98          * (non-Javadoc)
99          *
100          * @see org.eclipse.jface.viewers.ICheckStateListener#checkStateChanged(org.eclipse.jface.viewers.CheckStateChangedEvent)
101          */

102         public void checkStateChanged(CheckStateChangedEvent event) {
103             Set JavaDoc checked = new HashSet JavaDoc(Arrays.asList(dualViewer
104                     .getCheckedElements()));
105             Object JavaDoc element = event.getElement();
106             if (element instanceof ICategory) {
107                 // clicking on a category should enable/disable all activities
108
// within it
109
dualViewer.setSubtreeChecked(element, event.getChecked());
110                 // the state of the category is always absolute after clicking
111
// on it. Never gray.
112
dualViewer.setGrayed(element, false);
113                 Object JavaDoc categoryActivities[] = provider.getChildren(element);
114                 // Update the category's activities for multiplicity in other
115
// categories
116
for (int index = 0; index < categoryActivities.length; index++) {
117                     handleDuplicateActivities(event.getChecked(),
118                             categoryActivities[index]);
119                 }
120
121             } else {
122                 // Activity checked
123
handleActivityCheck(checked, element);
124                 handleDuplicateActivities(event.getChecked(), element);
125             }
126         }
127
128         /**
129          * Handle duplicate activities.
130          *
131          * @param checkedState
132          * Checked state of the element.
133          * @param element
134          * The checked element.
135          */

136         private void handleDuplicateActivities(boolean checkedState,
137                 Object JavaDoc element) {
138             // Retrieve duplicate activities from the other categories
139
Object JavaDoc[] duplicateActivities = provider
140                     .getDuplicateCategoryActivities((CategorizedActivity) element);
141             CategorizedActivity activity = null;
142             for (int index = 0; index < duplicateActivities.length; index++) {
143                 activity = (CategorizedActivity) duplicateActivities[index];
144                 // Update the duplicate activity with the same state as the
145
// original
146
dualViewer.setChecked(activity, checkedState);
147                 // handle the activity check to potentially update its
148
// category's enablement
149
handleActivityCheck(new HashSet JavaDoc(Arrays.asList(dualViewer
150                         .getCheckedElements())), activity);
151             }
152         }
153
154         /**
155          * Handle the checking of an activity and update its category's checked
156          * state.
157          *
158          * @param checked
159          * The set of checked elements in the viewer.
160          * @param element
161          * The checked element.
162          */

163         private void handleActivityCheck(Set JavaDoc checked, Object JavaDoc element) {
164             // clicking on an activity can potentially change the check/gray
165
// state of its category.
166
CategorizedActivity proxy = (CategorizedActivity) element;
167             Object JavaDoc[] children = provider.getChildren(proxy.getCategory());
168             int state = NONE;
169             int count = 0;
170             for (int i = 0; i < children.length; i++) {
171                 if (checked.contains(children[i])) {
172                     count++;
173                 }
174             }
175
176             if (count == children.length) {
177                 state = ALL;
178             } else if (count != 0) {
179                 state = SOME;
180             }
181
182             if (state == NONE) {
183                 checked.remove(proxy.getCategory());
184             } else {
185                 checked.add(proxy.getCategory());
186             }
187
188             dualViewer.setGrayed(proxy.getCategory(), state == SOME);
189             dualViewer.setCheckedElements(checked.toArray());
190             // Check child required activities and uncheck parent required activities
191
// if needed
192
handleRequiredActivities(checked, element);
193         }
194
195         /**
196          * Handle the activity's required activities (parent and child).
197          *
198          * @param checked
199          * The set of checked elements in the viewer.
200          * @param element
201          * The checked element.
202          *
203          */

204         private void handleRequiredActivities(Set JavaDoc checked, Object JavaDoc element) {
205             Object JavaDoc[] requiredActivities = null;
206             // An element has been checked - we want to check its child required
207
// activities
208
if (checked.contains(element)) {
209                 requiredActivities = provider
210                         .getChildRequiredActivities(((CategorizedActivity) element)
211                                 .getId());
212                 for (int index = 0; index < requiredActivities.length; index++) {
213                     // We want to check the element if it is unchecked
214
if (!checked.contains(requiredActivities[index])) {
215                         dualViewer.setChecked(requiredActivities[index], true);
216                         handleActivityCheck(new HashSet JavaDoc(Arrays
217                                 .asList(dualViewer.getCheckedElements())),
218                                 requiredActivities[index]);
219                     }
220                 }
221             }
222             // An element has been unchecked - we want to uncheck its parent
223
// required activities
224
else {
225                 requiredActivities = provider
226                         .getParentRequiredActivities(((CategorizedActivity) element)
227                                 .getId());
228                 for (int index = 0; index < requiredActivities.length; index++) {
229                     // We want to uncheck the element if it is checked
230
if (checked.contains(requiredActivities[index])) {
231                         dualViewer.setChecked(requiredActivities[index], false);
232                         handleActivityCheck(new HashSet JavaDoc(Arrays
233                                 .asList(dualViewer.getCheckedElements())),
234                                 requiredActivities[index]);
235                     }
236                 }
237             }
238         }
239
240     };
241
242     protected CheckboxTreeViewer dualViewer;
243
244     /**
245      * The Set of activities that belong to at least one category.
246      */

247     private Set JavaDoc managedActivities = new HashSet JavaDoc(7);
248
249     /**
250      * The content provider.
251      */

252     protected ActivityCategoryContentProvider provider = new ActivityCategoryContentProvider();
253
254     /**
255      * The descriptive text.
256      */

257     protected Text descriptionText;
258
259     private Properties JavaDoc strings;
260
261     private IMutableActivityManager activitySupport;
262
263     /**
264      * Create a new instance.
265      *
266      * @param activitySupport
267      * the <code>IMutableActivityMananger</code> to use.
268      * @param strings
269      * map of strings to use. See the constants on
270      * {@link org.eclipse.ui.activities.ActivitiesPreferencePage} for
271      * details.
272      */

273     public ActivityEnabler(IMutableActivityManager activitySupport, Properties JavaDoc strings) {
274         this.activitySupport = activitySupport;
275         this.strings = strings;
276     }
277
278     /**
279      * Create the controls.
280      *
281      * @param parent
282      * the parent in which to create the controls.
283      * @return the composite in which the controls exist.
284      */

285     public Control createControl(Composite parent) {
286         GC gc = new GC(parent);
287         gc.setFont(JFaceResources.getDialogFont());
288         FontMetrics fontMetrics = gc.getFontMetrics();
289         gc.dispose();
290         
291         Composite composite = new Composite(parent, SWT.NONE);
292         composite.setLayout(createGridLayoutWithoutMargins(1, fontMetrics));
293
294         new Label(composite, SWT.NONE).setText(strings.getProperty(ActivitiesPreferencePage.ACTIVITY_NAME, ActivityMessages.ActivityEnabler_activities) + ':');
295
296         dualViewer = new CheckboxTreeViewer(composite);
297         dualViewer.setComparator(new ViewerComparator());
298         dualViewer.setLabelProvider(new ActivityCategoryLabelProvider());
299         dualViewer.setContentProvider(provider);
300         dualViewer.setInput(activitySupport);
301         GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
302         dualViewer.getControl().setLayoutData(data);
303
304         Composite buttonComposite = new Composite(composite, SWT.NONE);
305         buttonComposite.setLayout(createGridLayoutWithoutMargins(2, fontMetrics));
306
307         Button selectAllButton = new Button(buttonComposite, SWT.PUSH);
308         selectAllButton.setText(ActivityMessages.ActivityEnabler_selectAll);
309         selectAllButton.addSelectionListener(new SelectionAdapter() {
310             /*
311              * (non-Javadoc)
312              *
313              * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
314              */

315             public void widgetSelected(SelectionEvent e) {
316                 toggleTreeEnablement(true);
317             }
318         });
319         setButtonLayoutData(selectAllButton, fontMetrics);
320
321         Button deselectAllButton = new Button(buttonComposite, SWT.PUSH);
322         deselectAllButton.setText(ActivityMessages.ActivityEnabler_deselectAll);
323         deselectAllButton.addSelectionListener(new SelectionAdapter() {
324             /*
325              * (non-Javadoc)
326              *
327              * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
328              */

329             public void widgetSelected(SelectionEvent e) {
330                 toggleTreeEnablement(false);
331             }
332         });
333         setButtonLayoutData(deselectAllButton, fontMetrics);
334
335         new Label(composite, SWT.NONE).setText(ActivityMessages.ActivityEnabler_description);
336
337         descriptionText = new Text(composite, SWT.READ_ONLY | SWT.WRAP | SWT.BORDER
338                 | SWT.V_SCROLL);
339         data = new GridData(SWT.FILL, SWT.FILL, true, false);
340         data.heightHint = Dialog.convertHeightInCharsToPixels(fontMetrics, 5);
341         descriptionText.setLayoutData(data);
342         setInitialStates();
343
344         dualViewer.addCheckStateListener(checkListener);
345         dualViewer.addSelectionChangedListener(selectionListener);
346
347         dualViewer.setSelection(new StructuredSelection());
348
349         Dialog.applyDialogFont(composite);
350         
351         return composite;
352     }
353
354     private GridLayout createGridLayoutWithoutMargins(int nColumns, FontMetrics fontMetrics) {
355         GridLayout layout = new GridLayout(nColumns, false);
356         layout.marginHeight = 0;
357         layout.marginWidth = 0;
358         layout.horizontalSpacing = Dialog.convertHorizontalDLUsToPixels(fontMetrics, IDialogConstants.HORIZONTAL_SPACING);
359         layout.verticalSpacing = Dialog.convertVerticalDLUsToPixels(fontMetrics, IDialogConstants.VERTICAL_SPACING);
360         return layout;
361     }
362
363     private GridData setButtonLayoutData(Button button, FontMetrics fontMetrics) {
364         GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
365         int widthHint = Dialog.convertHorizontalDLUsToPixels(fontMetrics, IDialogConstants.BUTTON_WIDTH);
366         Point minSize = button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
367         data.widthHint = Math.max(widthHint, minSize.x);
368         button.setLayoutData(data);
369         return data;
370     }
371     
372     /**
373      * @param categoryId
374      * the id to fetch.
375      * @return return all ids for activities that are in the given in the
376      * category.
377      */

378     private Collection JavaDoc getCategoryActivityIds(String JavaDoc categoryId) {
379         ICategory category = activitySupport.getCategory(
380                 categoryId);
381         Set JavaDoc activityBindings = category.getCategoryActivityBindings();
382         List JavaDoc categoryActivities = new ArrayList JavaDoc(activityBindings.size());
383         for (Iterator JavaDoc i = activityBindings.iterator(); i.hasNext();) {
384             ICategoryActivityBinding binding = (ICategoryActivityBinding) i
385                     .next();
386             String JavaDoc activityId = binding.getActivityId();
387             categoryActivities.add(activityId);
388         }
389         return categoryActivities;
390     }
391
392     /**
393      * Set the enabled category/activity check/grey states based on initial
394      * activity enablement.
395      */

396     private void setInitialStates() {
397         Set JavaDoc enabledActivities = activitySupport
398                 .getEnabledActivityIds();
399         setEnabledStates(enabledActivities);
400     }
401
402     private void setEnabledStates(Set JavaDoc enabledActivities) {
403         Set JavaDoc categories = activitySupport
404                 .getDefinedCategoryIds();
405         List JavaDoc checked = new ArrayList JavaDoc(10), grayed = new ArrayList JavaDoc(10);
406         for (Iterator JavaDoc i = categories.iterator(); i.hasNext();) {
407             String JavaDoc categoryId = (String JavaDoc) i.next();
408             ICategory category = activitySupport
409                     .getCategory(categoryId);
410
411             int state = NONE;
412             Collection JavaDoc activities = getCategoryActivityIds(categoryId);
413             int foundCount = 0;
414             for (Iterator JavaDoc j = activities.iterator(); j.hasNext();) {
415                 String JavaDoc activityId = (String JavaDoc) j.next();
416                 managedActivities.add(activityId);
417                 if (enabledActivities.contains(activityId)) {
418                     IActivity activity = activitySupport
419                             .getActivity(activityId);
420                     checked.add(new CategorizedActivity(category, activity));
421                     //add activity proxy
422
foundCount++;
423                 }
424             }
425
426             if (foundCount == activities.size()) {
427                 state = ALL;
428             } else if (foundCount > 0) {
429                 state = SOME;
430             }
431
432             if (state == NONE) {
433                 continue;
434             }
435             checked.add(category);
436
437             if (state == SOME) {
438                 grayed.add(category);
439             }
440         }
441
442         dualViewer.setCheckedElements(checked.toArray());
443         dualViewer.setGrayedElements(grayed.toArray());
444     }
445
446     /**
447      * Update activity enablement based on the check states of activities in the
448      * tree.
449      */

450     public void updateActivityStates() {
451         Set JavaDoc enabledActivities = new HashSet JavaDoc(activitySupport
452                 .getEnabledActivityIds());
453
454         // remove all but the unmanaged activities (if any).
455
enabledActivities.removeAll(managedActivities);
456
457         Object JavaDoc[] checked = dualViewer.getCheckedElements();
458         for (int i = 0; i < checked.length; i++) {
459             Object JavaDoc element = checked[i];
460             if (element instanceof ICategory || dualViewer.getGrayed(element)) {
461                 continue;
462             }
463             enabledActivities.add(((IActivity) element).getId());
464         }
465
466         activitySupport.setEnabledActivityIds(enabledActivities);
467     }
468
469     /**
470      * Restore the default activity states.
471      */

472     public void restoreDefaults() {
473         Set JavaDoc defaultEnabled = new HashSet JavaDoc();
474         Set JavaDoc activityIds = activitySupport.getDefinedActivityIds();
475         for (Iterator JavaDoc i = activityIds.iterator(); i.hasNext();) {
476             String JavaDoc activityId = (String JavaDoc) i.next();
477             IActivity activity = activitySupport.getActivity(activityId);
478             try {
479                 if (activity.isDefaultEnabled()) {
480                     defaultEnabled.add(activityId);
481                 }
482             } catch (NotDefinedException e) {
483                 // this can't happen - we're iterating over defined activities.
484
}
485         }
486         
487         setEnabledStates(defaultEnabled);
488     }
489
490     /**
491      * Toggles the enablement state of all activities.
492      *
493      * @param enabled
494      * whether the tree should be enabled
495      */

496     protected void toggleTreeEnablement(boolean enabled) {
497         Object JavaDoc[] elements = provider.getElements(activitySupport);
498         
499         //reset grey state to null
500
dualViewer.setGrayedElements(new Object JavaDoc[0]);
501         
502         //enable all categories
503
for (int i = 0; i < elements.length; i++) {
504             dualViewer
505                     .expandToLevel(elements[i], AbstractTreeViewer.ALL_LEVELS);
506             dualViewer.setSubtreeChecked(elements[i], enabled);
507         }
508     }
509 }
510
Popular Tags