Eclipse Search

Loading

Jul 31, 2008

Eclipse Search - now with a Firefox plugin

Sometime ago I wrote about the Eclipse Search, a Google Custom Search that I created for searching Eclipse related resources. It searches around 250 sites and presents the results with different labels like Blogs, Docs, Source etc. Today I thought of creating a Firefox Search plugin. Unlike my estimations, the task was completed in an hour or so. Gave a revamp to the search page and moved it to a new location also. Try some queries like EMF in both Google and this Eclipse Search and see the difference yourself.



BTW, in case you are interested in installing the Firefox Plugin, go to this page, and the search engine will be automatically detected:

Update: Its now detected in this page itself! If you are using Firefox 2.x + or IE 7.0 +, look at the search bar of your browser

 Just add the engine and start searching.



To uninstall the plugin, click the "Manage Search Engines" and select Eclipse Search and Delete it.



On a related note, I've implemented this as an OpenSearch plugin, which means it should work exactly the same way in IE 7 also. I didn't have access to Windows box, I hope it works fine there as well.

Jul 19, 2008

How to create a new File Wizard?

Problem is simple. Implement a INewWizard for creating some file type in your application.



For this problem, I have seen people start creating the WizardPage on their own. But luckily there is a reusable WizardPage which is specifically meant for this - WizardNewFileCreationPage. In this tip, lets see how to use the class. Lets assume that we need to create a new properties file with the extension .config



First we need to create a sub class of WizardNewFileCreationPage.



public class NewConfigFileWizardPage extends WizardNewFileCreationPage {

    public NewConfigFileWizardPage(IStructuredSelection selection) {
        super("NewConfigFileWizardPage", selection);
        setTitle("Config File");
        setDescription("Creates a new Config File");
        setFileExtension("config");
    }

    @Override
    protected InputStream getInitialContents() {
        try {
            return Activator.getDefault().getBundle().getEntry("/resources/newFileContents.config").openStream();
        } catch (IOException e) {
            return null; // ignore and create empty comments
        }
    }
}




The constructor sets the initial selection, wizard page title & description and the extension of the file to be created. Not just extension, you can even set the initial name for the file also using the setFileName() method.



If you want to create some default contents for this file, override the getInitialContents(). I've taken the initial contents from a file, but you can have your own logic there.



WizardPage is done, lets see the code for Wizard:



public class NewConfigFileWizard extends Wizard implements INewWizard {

    private IStructuredSelection selection;
    private NewConfigFileWizardPage newFileWizardPage;
    private IWorkbench workbench;
 


    public NewConfigFileWizard() {

        setWindowTitle("New Config File");

    } 






    @Override
    public void addPages() {

        newFileWizardPage = new NewConfigFileWizardPage(selection);
        addPage(newFileWizardPage);
    }
   
    @Override
    public boolean performFinish() {
       
        IFile file = newFileWizardPage.createNewFile();
        if (file != null)
            return true;
        else
            return false;
    }

    public void init(IWorkbench workbench, IStructuredSelection selection) {
        this.workbench = workbench;
        this.selection = selection;
    }
}







Nothing fancy in this. Just call the wizardPage's createNewFile() method when Finish button is pressed. Thats it. Now what are the advantages that we get by reusing WizardNewFileCreationPage rather than the one hand crafted by you?



  • Live error notification if a file already exists in the selected folder for the name you typed

  • It understand the selection in the Package Explorer/Navigator and selects it for you


  • If the parent folder structure you have entered is not present, it will automatically create it for you

  • Allows you to link to a different file (in this case your getInitialContents() will not be called)


  • Undo/Redo support - You can undo/redo the file creation





Now next time you want to create a new file, don't reinvent the wheel. Just use the WizardNewFileCreationPage.



The above code works just fine. Only thing is that the file is not opened in an editor. So the user will have no clue of whether its properly created or not. So in the performFinish() method, open the newly created file in an editor using one of the IDE.openEditor() methods

Jul 17, 2008

Selection Dialogs in Eclipse

If you are an Eclipse Plug-in developer, you must have used the MessageDialog. There are many other Dialogs provided by Eclipse Platform are reusable and part of the API. I'll try to explain the various selection dialogs that I know of. In case I've missed any, add a comment and do let me know. Will add it to the list
ContainerSelectionDialog:
     You can use this dialog when you want to select a container (Project/Folder) for your new resource.
 
Example:
ContainerSelectionDialog dialog = new ContainerSelectionDialog(window.getShell(), null, true, "Select a parent:");

dialog.setTitle("Container Selection");

dialog.open();
You can even restrict the resource to be within a project/folder by passing the respective object as the second parameter for the constructor.
 ResourceSelectionDialog:
The ContainerSelectionDialog allowed you to select only one resource that too it should be a container. If you want to select multiple resources including files, this is the dialog you should be using.
 
Example:
ResourceSelectionDialog dialog = new ResourceSelectionDialog(window.getShell(), ResourcesPlugin.getWorkspace().getRoot(), "Select Resource:");

dialog.setTitle("Resource Selection");

dialog.open();
ResourceListSelectionDialog:
The above dialog is good when you want to present the entire set of resources under a parent and allow the user to select multiple resources. But if you have a set of resources and want the user to select only one from that, then probably this dialog is the one you should be using.
Example:
ResourceListSelectionDialog dialog = new ResourceListSelectionDialog(window.getShell(), resourcesArray);
dialog.setTitle("Resource Selection");
dialog.open();


ElementListSelectionDialog:
Alright. So far we have been looking at selecting something from the workspace. But what if I have some elements on my own and I want to select from that? The first dialog you would be using is ElementListSelectionDialog. The user can select an element from the set. You have to pass the elements as an array and supply a  label provider to render the element. The user can filter using wildcards as well:
 
Example:
ElementListSelectionDialog dialog = new ElementListSelectionDialog(window.getShell(), new LabelProvider());

dialog.setTitle("String Selection");

dialog.setMessage("Select a String (* = any string, ? = any char):");

dialog.setElements(new Object[] { "one", "two", "three" });

dialog.open();


 
ListSelectionDialog:
That holds good for selecting a single element. What if you want to select multiple elements from the given set? ListSelectionDialog is the answer to it. It is basically a single column TableViewer with SWT.CHECK style applied. You have to supply your own ContentProvider and LabelProvider for the TableViewer. It also has Select All & Deselect All buttons. (In the example I've used workspace and the associated label & content providers, but this dialog is not tied to IResource in anyway
Example:
ListSelectionDialog dlg = new ListSelectionDialog(window.getShell(), ResourcesPlugin.getWorkspace().getRoot(), new BaseWorkbenchContentProvider(), new WorkbenchLabelProvider(), "Select the Project:");
dlg.setTitle("Project Selection");
dlg.open();
CheckedTreeSelectionDialog:
If you have your items in a tree structure and want to select few elements from them, then CheckedTreeSelectionDialog is your choice. You have to bring your own content & label provider and the input. Again, due to sheer laziness, I'm using the workspace as the input and associated content & label providers, but remember that this dialog can work well with your own data as well.
Example:
CheckedTreeSelectionDialog dialog = new CheckedTreeSelectionDialog(window.getShell(), new WorkbenchLabelProvider(), new BaseWorkbenchContentProvider());

dialog.setTitle("Tree Selection");

dialog.setMessage("Select the elements from the tree:");

dialog.setInput(ResourcesPlugin.getWorkspace().getRoot());

dialog.open();
ElementTreeSelectionDialog:
This is the same as the above except that it will allow you to select a single element in the whole tree rather than multiple elements. Again, not tied to workspace & resources.
Example:
ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(window.getShell(), new WorkbenchLabelProvider(), new BaseWorkbenchContentProvider());
dialog.setTitle("Tree Selection");
dialog.setMessage("Select the elements from the tree:");
dialog.setInput(ResourcesPlugin.getWorkspace().getRoot());
dialog.open();
FilteredItemsSelectionDialog:
Have you used the Open Type (Ctrl + Shift + T) or Open Resource (Ctrl+Shift+R) dialog? Its similar to the ElementListSelectionDialog, but it has more features. It can select multiple items, display a detail pane about the item that is currently selected, it can even remember your previous selections; store them in history and present them before the other choices. 
FilteredItemsSelectionDialog is the key. Its an abstract class and you have to extend it and create a concrete implementation to use it. I'll resever the details of extending it for a separate tip, till then you can go thru the JavaDoc.



[Update]: This has been added to the Eclipse User Interface Guidelines.

Jul 12, 2008

[Off Topic] Making magic with Eclipse

Yeah, we all know that with Eclipse, we can code, run jUnit, play sudoku, chat with your friend all that. But how about connecting to another computer and get the display inside your Eclipse?



I happened to come across this bug and saw the attached screencast. I'm really impressed with the work that is being done. I wish this makes into Eclipse.

Jul 1, 2008

How to add Zoom support to a GEF editor?

Adding Zoom support to GEF editors is a trivial task, yet many people struggle to do that. Probably lack of all the documentation in a single place? Let me fill up that void with this tip. Let me take the Shapes example and add Zoom support, step by step.



GEF gives you first class support for Zooming. It gives you ZoomManager class which handles the the functionality in a GEF Editor. The first step is to make our Editor to understand the ZoomManager. To make that happen in the ShapesEditor.getAdapter() method add these lines:



if (type == ZoomManager.class)

     return getGraphicalViewer().getProperty(ZoomManager.class.toString());



Ok. Now that our Editor understands the Zooming, how to control it? How about adding a Combo box in the Editor's toolbar with the percentages? Don't worry. You don't have to implement it from the scratch. GEF already has the ZoomComboContributionItem and all you need to is instantiate it and add it to the tool bar. Add this line to ShapesEditorActionBarContributor.contributeToToolBar() method



toolBarManager.add(new ZoomComboContributionItem(getPage()));



Just these two steps and you can see the Zoom working in your editor. 










 




Alright. Now that we have the basics working, lets move on to the extras.



Adding predefined Zoom Levels:



The Zoom levels are currently integers. Either you can choose from the Combo or type in a custom % value there. But if you want to see the entire image, you may want to zoom to "Fit Page", "Fit Width" etc. Again, this is as simple as adding the following line in the ShapesEditor.configureGraphicalViewer() method:



List zoomContributions = Arrays.asList(new String[] { 

     ZoomManager.FIT_ALL, 

     ZoomManager.FIT_HEIGHT, 

     ZoomManager.FIT_WIDTH });

rootEditPart.getZoomManager().setZoomLevelContributions(zoomContributions);


Adding keyboard shortcuts for Zooming:



Keyboard shortcuts are great way to save time. You don't have to lift your hand out of the keyboard, pick up the mouse, click something, when you can so the same thing in a split second by pressing a key sequence. How about Ctrl+ or Ctrl - for Zooming in our GEF Editor?



GEF provides you two predefined actions (ZoomInAction & ZoomOutAction)  for this. You can use these actions to have keyboard shortcut support. Right after the zoomContributions you have added in the ShapesEditor.configureGraphicalViewer() method, add these lines:



IAction zoomIn = new ZoomInAction(rootEditPart.getZoomManager());

IAction zoomOut = new ZoomOutAction(rootEditPart.getZoomManager());

getActionRegistry().registerAction(zoomIn);

getActionRegistry().registerAction(zoomOut);

getSite().getKeyBindingService().registerAction(zoomIn);

getSite().getKeyBindingService().registerAction(zoomOut);



Adding menu options for Zoom:



It would be nice to have menu options for this Zoom functions. That would give hint about the keyboard shortcuts as well. GEF provides two retargetable actions ( ZoomInRetargetAction & ZoomOutRetargetAction) to assist you.



Adding these actions is a two step process. First add you need to create these actions. Add the below two lines in the ShapesEditorActionBarContributor.buildActions() method for that:



addRetargetAction(new ZoomInRetargetAction());

addRetargetAction(new ZoomOutRetargetAction());


Now, override contributeToMenu() method in ShapesEditorActionBarContributor and add this as contents:



public void contributeToMenu(IMenuManager menubar) {
    super.contributeToMenu(menubar);
    MenuManager viewMenu = new MenuManager("&View");
    viewMenu.add(getAction(GEFActionConstants.ZOOM_IN));
    viewMenu.add(getAction(GEFActionConstants.ZOOM_OUT));
    menubar.insertAfter(IWorkbenchActionConstants.M_EDIT, viewMenu);
}







Adding MouseWheel support: 



Zooming through keyboard shortcuts is fine, but what about mouse wheel support? There are numerous users who want to Zoom In/Out using the Ctrl+Mouse Wheel. Once again, GEF comes to resue with its MouseWheelZoomHandler class. All you need to do is set the property on the viewer. In the ShapesEditor.configureGraphicalViewer() method add this:



viewer.setProperty(MouseWheelHandler.KeyGenerator.getKey(SWT.MOD1), MouseWheelZoomHandler.SINGLETON);



In case you want Alt+Mouse Wheel to handle the Zoom functionality, in the above line change SWT.MOD1 to SWT.MOD3. (or SWT.MOD2 if you want Shift + Mouse Wheel)



As I said in the beginning, adding the complete support for Zooming in a GEF editor is pretty simple. GEF already has all the required implementations and all you have to do is to add them in proper places. Use these in your GEF editor and make your users happy :-)