KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > views > properties > PropertySheetPage


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  * Gunnar Wagenknecht - fix for bug 21756 [PropertiesView] property view sorting
11  *******************************************************************************/

12
13 package org.eclipse.ui.views.properties;
14
15 import org.eclipse.core.runtime.IAdaptable;
16 import org.eclipse.help.IContext;
17 import org.eclipse.jface.action.IMenuManager;
18 import org.eclipse.jface.action.IStatusLineManager;
19 import org.eclipse.jface.action.IToolBarManager;
20 import org.eclipse.jface.action.MenuManager;
21 import org.eclipse.jface.action.Separator;
22 import org.eclipse.jface.viewers.CellEditor;
23 import org.eclipse.jface.viewers.ISelection;
24 import org.eclipse.jface.viewers.ISelectionChangedListener;
25 import org.eclipse.jface.viewers.IStructuredSelection;
26 import org.eclipse.jface.viewers.SelectionChangedEvent;
27 import org.eclipse.swt.dnd.Clipboard;
28 import org.eclipse.swt.dnd.DND;
29 import org.eclipse.swt.dnd.DragSource;
30 import org.eclipse.swt.dnd.DragSourceAdapter;
31 import org.eclipse.swt.dnd.DragSourceEvent;
32 import org.eclipse.swt.dnd.DragSourceListener;
33 import org.eclipse.swt.dnd.TextTransfer;
34 import org.eclipse.swt.dnd.Transfer;
35 import org.eclipse.swt.events.HelpEvent;
36 import org.eclipse.swt.events.HelpListener;
37 import org.eclipse.swt.widgets.Composite;
38 import org.eclipse.swt.widgets.Control;
39 import org.eclipse.swt.widgets.Menu;
40 import org.eclipse.swt.widgets.Shell;
41 import org.eclipse.ui.IActionBars;
42 import org.eclipse.ui.IPartListener;
43 import org.eclipse.ui.ISaveablePart;
44 import org.eclipse.ui.ISharedImages;
45 import org.eclipse.ui.IWorkbenchPart;
46 import org.eclipse.ui.PlatformUI;
47 import org.eclipse.ui.help.IContextComputer;
48 import org.eclipse.ui.help.IWorkbenchHelpSystem;
49 import org.eclipse.ui.internal.views.ViewsPlugin;
50 import org.eclipse.ui.internal.views.properties.PropertiesMessages;
51 import org.eclipse.ui.part.CellEditorActionHandler;
52 import org.eclipse.ui.part.Page;
53
54 /**
55  * The standard implementation of property sheet page which presents
56  * a table of property names and values obtained from the current selection
57  * in the active workbench part.
58  * <p>
59  * This page obtains the information about what properties to display from
60  * the current selection (which it tracks).
61  * </p>
62  * <p>
63  * The model for this page is a hierarchy of <code>IPropertySheetEntry</code>.
64  * The page may be configured with a custom model by setting the root entry.
65  * <p>
66  * If no root entry is set then a default model is created which uses the
67  * <code>IPropertySource</code> interface to obtain the properties of
68  * the current selection. This requires that the selected objects provide an
69  * <code>IPropertySource</code> adapter (or implement
70  * <code>IPropertySource</code> directly). This restiction can be overcome
71  * by providing this page with an <code>IPropertySourceProvider</code>. If
72  * supplied, this provider will be used by the default model to obtain a
73  * property source for the current selection
74  * </p>
75  * <p>
76  * This class may be instantiated; it is not intended to be subclassed.
77  * </p>
78  *
79  * @see IPropertySource
80  */

81 public class PropertySheetPage extends Page implements IPropertySheetPage, IAdaptable {
82     /**
83      * Help context id
84      * (value <code>"org.eclipse.ui.property_sheet_page_help_context"</code>).
85      */

86     public static final String JavaDoc HELP_CONTEXT_PROPERTY_SHEET_PAGE = "org.eclipse.ui.property_sheet_page_help_context"; //$NON-NLS-1$
87

88     private PropertySheetViewer viewer;
89     
90     private PropertySheetSorter sorter;
91
92     private IPropertySheetEntry rootEntry;
93
94     private IPropertySourceProvider provider;
95
96     private DefaultsAction defaultsAction;
97
98     private FilterAction filterAction;
99
100     private CategoriesAction categoriesAction;
101
102     private CopyPropertyAction copyAction;
103
104     private ICellEditorActivationListener cellEditorActivationListener;
105
106     private CellEditorActionHandler cellEditorActionHandler;
107
108     private Clipboard clipboard;
109
110     private IWorkbenchPart sourcePart;
111
112     /**
113      * Part listener which cleans up this page when the source part is closed.
114      * This is hooked only when there is a source part.
115      *
116      * @since 3.2
117      */

118     private class PartListener implements IPartListener {
119         public void partActivated(IWorkbenchPart part) {
120         }
121
122         public void partBroughtToTop(IWorkbenchPart part) {
123         }
124
125         public void partClosed(IWorkbenchPart part) {
126             if (sourcePart == part) {
127                 sourcePart = null;
128                 if (viewer != null && !viewer.getControl().isDisposed()) {
129                     viewer.setInput(new Object JavaDoc[0]);
130                 }
131             }
132         }
133
134         public void partDeactivated(IWorkbenchPart part) {
135         }
136
137         public void partOpened(IWorkbenchPart part) {
138         }
139     }
140     
141     private PartListener partListener = new PartListener();
142     
143     /**
144      * Creates a new property sheet page.
145      */

146     public PropertySheetPage() {
147         super();
148     }
149
150     /* (non-Javadoc)
151      * Method declared on <code>IPage</code>.
152      */

153     public void createControl(Composite parent) {
154         // create a new viewer
155
viewer = new PropertySheetViewer(parent);
156         viewer.setSorter(sorter);
157         
158         // set the model for the viewer
159
if (rootEntry == null) {
160             // create a new root
161
PropertySheetEntry root = new PropertySheetEntry();
162             if (provider != null) {
163                 // set the property source provider
164
root.setPropertySourceProvider(provider);
165             }
166             rootEntry = root;
167         }
168         viewer.setRootEntry(rootEntry);
169         viewer.addActivationListener(getCellEditorActivationListener());
170         // add a listener to track when the entry selection changes
171
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
172             public void selectionChanged(SelectionChangedEvent event) {
173                 handleEntrySelection(event.getSelection());
174             }
175         });
176         initDragAndDrop();
177         makeActions();
178
179         // Create the popup menu for the page.
180
MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
181
menuMgr.add(copyAction);
182         menuMgr.add(new Separator());
183         menuMgr.add(defaultsAction);
184         Menu menu = menuMgr.createContextMenu(viewer.getControl());
185         viewer.getControl().setMenu(menu);
186
187         // Set help on the viewer
188
viewer.getControl().addHelpListener(new HelpListener() {
189             /*
190              * @see HelpListener#helpRequested(HelpEvent)
191              */

192             public void helpRequested(HelpEvent e) {
193                 // Get the context for the selected item
194
IStructuredSelection selection = (IStructuredSelection) viewer
195                         .getSelection();
196                 if (!selection.isEmpty()) {
197                     IPropertySheetEntry entry = (IPropertySheetEntry) selection
198                             .getFirstElement();
199                     Object JavaDoc helpContextId = entry.getHelpContextIds();
200                     if (helpContextId != null) {
201                         if (helpContextId instanceof String JavaDoc) {
202                             PlatformUI.getWorkbench()
203                                     .getHelpSystem().displayHelp(
204                                             (String JavaDoc) helpContextId);
205                             return;
206                         }
207
208                         // Since 2.0 the only valid type for helpContextIds
209
// is a String (a single id).
210
// However for backward compatibility we have to handle
211
// and array of contexts (Strings and/or IContexts)
212
// or a context computer.
213
Object JavaDoc[] contexts = null;
214                         if (helpContextId instanceof IContextComputer) {
215                             // get local contexts
216
contexts = ((IContextComputer) helpContextId)
217                                     .getLocalContexts(e);
218                         } else {
219                             contexts = (Object JavaDoc[]) helpContextId;
220                         }
221                         IWorkbenchHelpSystem help = PlatformUI.getWorkbench().getHelpSystem();
222                         // Ignore all but the first element in the array
223
if (contexts[0] instanceof IContext) {
224                             help.displayHelp((IContext) contexts[0]);
225                         } else {
226                             help.displayHelp((String JavaDoc) contexts[0]);
227                         }
228                         return;
229                     }
230                 }
231
232                 // No help for the selection so show page help
233
PlatformUI.getWorkbench().getHelpSystem().displayHelp(HELP_CONTEXT_PROPERTY_SHEET_PAGE);
234             }
235         });
236     }
237
238     /**
239      * The <code>PropertySheetPage</code> implementation of this <code>IPage</code> method
240      * disposes of this page's entries.
241      */

242     public void dispose() {
243         super.dispose();
244         if (sourcePart != null) {
245             sourcePart.getSite().getPage().removePartListener(partListener);
246         }
247         if (rootEntry != null) {
248             rootEntry.dispose();
249             rootEntry = null;
250         }
251         if (clipboard != null) {
252             clipboard.dispose();
253             clipboard = null;
254         }
255     }
256
257     /**
258      * The <code>PropertySheetPage</code> implementation of this <code>IAdaptable</code> method
259      * handles the <code>ISaveablePart</code> adapter by delegating to the source part.
260      *
261      * @since 3.2
262      */

263     public Object JavaDoc getAdapter(Class JavaDoc adapter) {
264         if (ISaveablePart.class.equals(adapter)) {
265             return getSaveablePart();
266         }
267         return null;
268     }
269     
270     /**
271      * Returns an <code>ISaveablePart</code> that delegates to the source part
272      * for the current page if it implements <code>ISaveablePart</code>, or
273      * <code>null</code> otherwise.
274      *
275      * @return an <code>ISaveablePart</code> or <code>null</code>
276      * @since 3.2
277      */

278     protected ISaveablePart getSaveablePart() {
279         if (sourcePart instanceof ISaveablePart) {
280             return (ISaveablePart) sourcePart;
281         }
282         return null;
283     }
284     
285     /**
286      * Returns the cell editor activation listener for this page
287      * @return ICellEditorActivationListener the cell editor activation listener for this page
288      */

289     private ICellEditorActivationListener getCellEditorActivationListener() {
290         if (cellEditorActivationListener == null) {
291             cellEditorActivationListener = new ICellEditorActivationListener() {
292                 public void cellEditorActivated(CellEditor cellEditor) {
293                     if (cellEditorActionHandler != null) {
294                         cellEditorActionHandler.addCellEditor(cellEditor);
295                     }
296                 }
297
298                 public void cellEditorDeactivated(CellEditor cellEditor) {
299                     if (cellEditorActionHandler != null) {
300                         cellEditorActionHandler.removeCellEditor(cellEditor);
301                     }
302                 }
303             };
304         }
305         return cellEditorActivationListener;
306     }
307
308     /* (non-Javadoc)
309      * Method declared on IPage (and Page).
310      */

311     public Control getControl() {
312         if (viewer == null) {
313             return null;
314         }
315         return viewer.getControl();
316     }
317
318     /**
319      * Handles a selection change in the entry table.
320      *
321      * @param selection the new selection
322      */

323     public void handleEntrySelection(ISelection selection) {
324         if (defaultsAction != null) {
325             if (selection.isEmpty()) {
326                 defaultsAction.setEnabled(false);
327                 return;
328             }
329             // see if item is editable
330
boolean editable = viewer.getActiveCellEditor() != null;
331             defaultsAction.setEnabled(editable);
332         }
333     }
334
335     /**
336      * Adds drag and drop support.
337      */

338     protected void initDragAndDrop() {
339         int operations = DND.DROP_COPY;
340         Transfer[] transferTypes = new Transfer[] { TextTransfer.getInstance() };
341         DragSourceListener listener = new DragSourceAdapter() {
342             public void dragSetData(DragSourceEvent event) {
343                 performDragSetData(event);
344             }
345
346             public void dragFinished(DragSourceEvent event) {
347                 //Nothing to do here
348
}
349         };
350         DragSource dragSource = new DragSource(
351                 viewer.getControl(), operations);
352         dragSource.setTransfer(transferTypes);
353         dragSource.addDragListener(listener);
354     }
355
356     /**
357      * The user is attempting to drag. Add the appropriate
358      * data to the event.
359      * @param event The event sent from the drag and drop support.
360      */

361     void performDragSetData(DragSourceEvent event) {
362         // Get the selected property
363
IStructuredSelection selection = (IStructuredSelection) viewer
364                 .getSelection();
365         if (selection.isEmpty()) {
366             return;
367         }
368         // Assume single selection
369
IPropertySheetEntry entry = (IPropertySheetEntry) selection
370                 .getFirstElement();
371
372         // Place text as the data
373
StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
374         buffer.append(entry.getDisplayName());
375         buffer.append("\t"); //$NON-NLS-1$
376
buffer.append(entry.getValueAsString());
377
378         event.data = buffer.toString();
379     }
380
381     /**
382      * Make action objects.
383      */

384     private void makeActions() {
385         ISharedImages sharedImages = PlatformUI.getWorkbench()
386                 .getSharedImages();
387
388         // Restore Default Value
389
defaultsAction = new DefaultsAction(viewer, "defaults"); //$NON-NLS-1$
390
defaultsAction.setText(PropertiesMessages.Defaults_text);
391         defaultsAction.setToolTipText(PropertiesMessages.Defaults_toolTip);
392         defaultsAction
393                 .setImageDescriptor(ViewsPlugin.getViewImageDescriptor("elcl16/defaults_ps.gif")); //$NON-NLS-1$
394
defaultsAction
395                 .setDisabledImageDescriptor(ViewsPlugin.getViewImageDescriptor("dlcl16/defaults_ps.gif")); //$NON-NLS-1$
396
defaultsAction.setEnabled(false);
397
398         // Show Advanced Properties
399
filterAction = new FilterAction(viewer, "filter"); //$NON-NLS-1$
400
filterAction.setText(PropertiesMessages.Filter_text);
401         filterAction.setToolTipText(PropertiesMessages.Filter_toolTip);
402         filterAction
403                 .setImageDescriptor(ViewsPlugin.getViewImageDescriptor("elcl16/filter_ps.gif")); //$NON-NLS-1$
404
filterAction.setChecked(false);
405
406         // Show Categories
407
categoriesAction = new CategoriesAction(viewer, "categories"); //$NON-NLS-1$
408
categoriesAction.setText(PropertiesMessages.Categories_text);
409         categoriesAction.setToolTipText(PropertiesMessages.Categories_toolTip);
410         categoriesAction
411                 .setImageDescriptor(ViewsPlugin.getViewImageDescriptor("elcl16/tree_mode.gif")); //$NON-NLS-1$
412
categoriesAction.setChecked(true);
413
414         // Copy
415
Shell shell = viewer.getControl().getShell();
416         clipboard = new Clipboard(shell.getDisplay());
417         copyAction = new CopyPropertyAction(viewer, "copy", clipboard); //$NON-NLS-1$
418
copyAction.setText(PropertiesMessages.CopyProperty_text);
419         copyAction.setImageDescriptor(sharedImages
420                 .getImageDescriptor(ISharedImages.IMG_TOOL_COPY));
421     }
422
423     /* (non-Javadoc)
424      * Method declared on IPage (and Page).
425      */

426     public void makeContributions(IMenuManager menuManager,
427             IToolBarManager toolBarManager, IStatusLineManager statusLineManager) {
428
429         // add actions to the tool bar
430
toolBarManager.add(categoriesAction);
431         toolBarManager.add(filterAction);
432         toolBarManager.add(defaultsAction);
433
434         // add actions to the menu
435
menuManager.add(categoriesAction);
436         menuManager.add(filterAction);
437
438         // set status line manager into the viewer
439
viewer.setStatusLineManager(statusLineManager);
440     }
441
442     /**
443      * Updates the model for the viewer.
444      * <p>
445      * Note that this means ensuring that the model reflects the state
446      * of the current viewer input.
447      * </p>
448      */

449     public void refresh() {
450         if (viewer == null) {
451             return;
452         }
453         // calling setInput on the viewer will cause the model to refresh
454
viewer.setInput(viewer.getInput());
455     }
456
457     /* (non-Javadoc)
458      * Method declared on ISelectionListener.
459      */

460     public void selectionChanged(IWorkbenchPart part, ISelection selection) {
461         if (viewer == null) {
462             return;
463         }
464
465         if (sourcePart != null) {
466             sourcePart.getSite().getPage().removePartListener(partListener);
467             sourcePart = null;
468         }
469         
470         // change the viewer input since the workbench selection has changed.
471
if (selection instanceof IStructuredSelection) {
472             sourcePart = part;
473             viewer.setInput(((IStructuredSelection) selection).toArray());
474         }
475
476         if (sourcePart != null) {
477             sourcePart.getSite().getPage().addPartListener(partListener);
478         }
479     }
480
481     /**
482      * The <code>PropertySheetPage</code> implementation of this <code>IPage</code> method
483      * calls <code>makeContributions</code> for backwards compatibility with
484      * previous versions of <code>IPage</code>.
485      * <p>
486      * Subclasses may reimplement.
487      * </p>
488      */

489     public void setActionBars(IActionBars actionBars) {
490         super.setActionBars(actionBars);
491         cellEditorActionHandler = new CellEditorActionHandler(actionBars);
492         cellEditorActionHandler.setCopyAction(copyAction);
493     }
494
495     /**
496      * Sets focus to a part in the page.
497      */

498     public void setFocus() {
499         viewer.getControl().setFocus();
500     }
501
502     /**
503      * Sets the given property source provider as
504      * the property source provider.
505      * <p>
506      * Calling this method is only valid if you are using
507      * this page's default root entry.
508      * </p>
509      * @param newProvider the property source provider
510      */

511     public void setPropertySourceProvider(IPropertySourceProvider newProvider) {
512         provider = newProvider;
513         if (rootEntry instanceof PropertySheetEntry) {
514             ((PropertySheetEntry) rootEntry)
515                     .setPropertySourceProvider(provider);
516             // the following will trigger an update
517
viewer.setRootEntry(rootEntry);
518         }
519     }
520
521     /**
522      * Sets the given entry as the model for the page.
523      *
524      * @param entry the root entry
525      */

526     public void setRootEntry(IPropertySheetEntry entry) {
527         rootEntry = entry;
528         if (viewer != null) {
529             // the following will trigger an update
530
viewer.setRootEntry(rootEntry);
531         }
532     }
533
534     /**
535      * Sets the sorter used for sorting categories and entries in the viewer
536      * of this page.
537      * <p>
538      * The default sorter sorts categories and entries alphabetically.
539      * </p>
540      * @param sorter the sorter to set (<code>null</code> will reset to the
541      * default sorter)
542      * @since 3.1
543      */

544     protected void setSorter(PropertySheetSorter sorter) {
545         this.sorter = sorter;
546         if (viewer != null) {
547             viewer.setSorter(sorter);
548             
549             // the following will trigger an update
550
if(null != viewer.getRootEntry()) {
551                 viewer.setRootEntry(rootEntry);
552             }
553         }
554     }
555
556 }
557
Popular Tags