View Javadoc

1   /*
2    * $Id: AbstractOpenWizardAction.java,v 1.2 2005/05/31 21:59:23 jlerner Exp $
3    * Created on May 6, 2004
4    *
5    * Copyright (c) 1999-2004, BBN Technologies, LLC.
6    * All rights reserved.
7    * http://www.daml.org/legal/opensource/bbn_license.html
8    */
9   
10  package com.bbn.swede.ui.wizards.action;
11  
12  import java.util.Iterator;
13  
14  import org.eclipse.swt.widgets.Shell;
15  
16  import org.eclipse.jface.action.Action;
17  import org.eclipse.jface.action.IAction;
18  import org.eclipse.jface.dialogs.MessageDialog;
19  import org.eclipse.jface.viewers.ISelection;
20  import org.eclipse.jface.viewers.IStructuredSelection;
21  import org.eclipse.jface.wizard.Wizard;
22  import org.eclipse.jface.wizard.WizardDialog;
23  
24  import org.eclipse.core.resources.IWorkspace;
25  import org.eclipse.core.resources.ResourcesPlugin;
26  import org.eclipse.core.runtime.CoreException;
27  
28  import org.eclipse.ui.IWorkbench;
29  import org.eclipse.ui.IWorkbenchWindow;
30  import org.eclipse.ui.IWorkbenchWindowActionDelegate;
31  import org.eclipse.ui.IWorkbenchWizard;
32  import org.eclipse.ui.PlatformUI;
33  import org.eclipse.ui.actions.NewProjectAction;
34  
35  import com.bbn.swede.ui.util.PixelConverter;
36  
37  /***
38   * Common base class for SWeDE's "New ..." actions.
39   * @author tself
40   */
41  public abstract class AbstractOpenWizardAction
42     extends Action
43     implements IWorkbenchWindowActionDelegate
44  {
45  
46     private Class[] _activatedOnTypes;
47     private boolean _bAcceptEmptySelection;
48     private boolean _bNoChecking;
49     private boolean _bAllowEmptyWorkspace;
50  
51     /***
52      * Creates a AbstractOpenWizardAction.
53      * @param label The label of the action
54      * @param acceptEmptySelection Specifies if the action allows an empty selection
55      */
56     public AbstractOpenWizardAction(String label, boolean acceptEmptySelection)
57     {
58        this(label, null, acceptEmptySelection);
59     }
60  
61     /***
62      * Creates a AbstractOpenWizardAction.
63      * @param label The label of the action
64      * @param activatedOnTypes The action is only enabled when all objects in the selection
65      *                         are of the given types. <code>null</code> will allow all types.
66      * @param acceptEmptySelection Specifies if the action allows an empty selection
67      */
68     public AbstractOpenWizardAction(
69        String label,
70        Class[] activatedOnTypes,
71        boolean acceptEmptySelection)
72     {
73        this(label, activatedOnTypes, acceptEmptySelection, false);
74     }
75     /***
76      * Creates an open wizard action.
77      * @param label The display name of the action
78      * @param activatedOnTypes An array of types the action can be run against
79      * @param acceptEmptySelection <code>true</code> if the action can be run
80      *                             with an empty selection, else <code>false</code>.
81      * @param allowEmptyWorkspace <code>true</code> if the action can be run in
82      *                            an empty workspace, else <code>false</code>.
83      */
84     public AbstractOpenWizardAction(
85        String label,
86        Class[] activatedOnTypes,
87        boolean acceptEmptySelection,
88        boolean allowEmptyWorkspace)
89     {
90        super(label);
91        this._activatedOnTypes = activatedOnTypes;
92        this._bAcceptEmptySelection = acceptEmptySelection;
93        _bNoChecking = false;
94        this._bAllowEmptyWorkspace = allowEmptyWorkspace;
95     }
96  
97     /***
98      * Creates a AbstractOpenWizardAction with no restrictions on types, and does allow
99      * an empty selection.
100     */
101    protected AbstractOpenWizardAction()
102    {
103       _activatedOnTypes = null;
104       _bAcceptEmptySelection = true;
105       _bNoChecking = true;
106    }
107 
108    /***
109     * Retrieves the active workbench.
110     * @return The workbench
111     */
112    protected IWorkbench getWorkbench()
113    {
114       return PlatformUI.getWorkbench();
115    }
116    
117    /***
118     * Retrieves the active workbench shell.
119     * @return The workbench shell.
120     */
121    protected Shell getActiveWorkbenchShell()
122    {
123       return getWorkbench().getActiveWorkbenchWindow().getShell();
124    }
125 
126    /***
127     * Indicates whether or not an object is an instance of an accepted class.
128     * @param obj The object to check
129     * @return <code>true</code> if <code>obj</code>'s type matches an entry in
130     *         the acceptable types array specified at construction, otherwise
131     *         <code>false</code>.
132     */
133    private boolean isOfAcceptedType(Object obj)
134    {
135       if (_activatedOnTypes != null)
136       {
137          for (int i = 0; i < _activatedOnTypes.length; i++)
138          {
139             if (_activatedOnTypes[i].isInstance(obj))
140             {
141                return true;
142             }
143          }
144          return false;
145       }
146       return true;
147    }
148 
149    private boolean isEnabled(IStructuredSelection selection)
150    {
151       Iterator iter = selection.iterator();
152       while (iter.hasNext())
153       {
154          Object obj = iter.next();
155          if (!isOfAcceptedType(obj) || !shouldAcceptElement(obj))
156          {
157             return false;
158          }
159       }
160       return true;
161    }
162 
163    /***
164     * Indicates whether or not an element should be accepted.
165     * Can be overridden to add more checks.
166     * @param obj The object to check.  Guarunteed to be an instance of an
167     *            accepted type.
168     * @return <code>true</code> if the action can be run against 
169     *         <code>obj</code>, <code>false</code> if not.
170     */
171    protected boolean shouldAcceptElement(Object obj)
172    {
173       return true;
174    }
175 
176    /***
177     * Creates a wizard for the action.
178     * @return The wizard
179     * @throws CoreException if wizard creation fails
180     */
181    protected abstract Wizard createWizard() throws CoreException;
182 
183    /***
184     * Retrieves the current selection from the workbench.
185     * @return The current selection
186     */
187    protected IStructuredSelection getCurrentSelection()
188    {
189       IWorkbenchWindow window = getWorkbench().getActiveWorkbenchWindow();
190       if (window != null)
191       {
192          ISelection selection = window.getSelectionService().getSelection();
193          if (selection instanceof IStructuredSelection)
194          {
195             return (IStructuredSelection) selection;
196          }
197 
198       }
199       return null;
200    }
201 
202    /***
203     * Performs the action.
204     */
205    public void run()
206    {
207       if (!_bNoChecking && !canActionBeAdded())
208       {
209          return;
210       }
211       if (!checkWorkspaceNotEmpty())
212       {
213          return;
214       }
215       Shell shell = getActiveWorkbenchShell();
216       try
217       {
218          Wizard wizard = createWizard();
219          if (wizard == null) // no wizard provided for this action
220          {
221             return;
222          }
223          if (wizard instanceof IWorkbenchWizard)
224          {
225             ((IWorkbenchWizard) wizard).init(
226                getWorkbench(),
227                getCurrentSelection());
228          }
229 
230          WizardDialog dialog = new WizardDialog(shell, wizard);
231          PixelConverter converter =
232             new PixelConverter(getActiveWorkbenchShell());
233 
234          dialog.setMinimumPageSize(
235             converter.convertWidthInCharsToPixels(70),
236             converter.convertHeightInCharsToPixels(20));
237          dialog.create();
238          dialog.open();
239       }
240       catch (CoreException e)
241       {
242          String title = "Error Creating Wizard";
243          String message = "Unable to create appropriate wizard dialog.";
244          MessageDialog.openError(shell, title, message);
245       }
246    }
247 
248    /***
249     * Tests if the action can be run on the current selection.
250     * @return <code>true</code> if the action can be run on the current 
251     *         selection, <code>false</code> if not.
252     */
253    public boolean canActionBeAdded()
254    {
255       IStructuredSelection selection = getCurrentSelection();
256       if (selection == null || selection.isEmpty())
257       {
258          return _bAcceptEmptySelection;
259       }
260       return isEnabled(selection);
261    }
262 
263    /*
264     *  (non-Javadoc)
265     * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
266     */
267    public void run(IAction action)
268    {
269       run();
270    }
271 
272    /*
273     *  (non-Javadoc)
274     * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose()
275     */
276    public void dispose()
277    {
278    }
279 
280    /*
281     *  (non-Javadoc)
282     * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow)
283     */
284    public void init(IWorkbenchWindow window)
285    {
286    }
287 
288    /*
289     *  (non-Javadoc)
290     * @see org.eclipse.ui.IActionDelegate#selectionChanged(
291     *    org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection)
292     */
293    public void selectionChanged(IAction action, ISelection selection)
294    {
295       // selection taken from selectionprovider
296    }
297 
298    /***
299     * Indicates whether the workspace is non-empty.
300     * @return <code>true</code> if the workspace is non-empty or if empty
301     *         workspaces are allowed, otherwise <code>false</code>.
302     */
303    protected boolean checkWorkspaceNotEmpty()
304    {
305       if (_bAllowEmptyWorkspace)
306       {
307          return true;
308       }
309       IWorkspace workspace = ResourcesPlugin.getWorkspace();
310       if (workspace.getRoot().getProjects().length == 0)
311       {
312          Shell shell = getActiveWorkbenchShell();
313          String title = "Wizard Creation Error";
314          String message =
315             "This wizard requires an active project. Select 'Yes' to create one, 'No' to abort.";
316          if (MessageDialog.openQuestion(shell, title, message))
317          {
318             IWorkbenchWindow window = getWorkbench().getActiveWorkbenchWindow();
319             (new NewProjectAction(window)).run();
320             return workspace.getRoot().getProjects().length != 0;
321          }
322          return false;
323       }
324       return true;
325    }
326 }