Search code examples
eclipse-rcpperspectivee4

How do I reset perspective for Eclipse e4 RCP application?


After building a perspective in application.e4xmi file, I am unable to reset perspective by calling IWorkbenchPage.resetPerspective().


Solution

  • I thought this may save others some time, as well as document it for myself.

    The trick to being able to reset an e4 perspective is as follows (assumes a basic application.e4xmi with PerspectiveStack element):

    1. In your application.e4xmi file, locate your PerspectiveStack under your Application/TrimmedWindow node. Record/set its ID.
    2. In Eclipse 4 Model Editor, drag your Perspective(s) from underneath your PerspectiveStack to Application/Snippets. (This will cause your perspective IDs to register with IPerspectiveRegistry, and provide a pristine state).
    3. Create new CopyPerspectiveSnippetProcessor. This will copy the perspectives in your snippets to your PerspectiveStack on startup. This makes it so you don't have to maintain two copies of each perspective element in your e4xmi file.

      package com.example.application.processors;
      
      import org.eclipse.e4.core.di.annotations.Execute;
      import org.eclipse.e4.ui.model.application.MApplication;
      import org.eclipse.e4.ui.model.application.ui.MUIElement;
      import org.eclipse.e4.ui.model.application.ui.advanced.MPerspective;
      import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack;
      import org.eclipse.e4.ui.workbench.modeling.EModelService;
      
      /**
       * Copies all snippet perspectives to perspective stack called "MainPerspectiveStack" In order to register/reset perspective and not have to sync two copies in
       * e4xmi.
       * 
       */
      public class CopyPerspectiveSnippetProcessor {
          private static final String MAIN_PERSPECTIVE_STACK_ID = "MainPerspectiveStack";
      
          @Execute
          public void execute(EModelService modelService, MApplication application) {
              MPerspectiveStack perspectiveStack = (MPerspectiveStack) modelService.find(MAIN_PERSPECTIVE_STACK_ID, application);
      
              // Only do this when no other children, or the restored workspace state will be overwritten.
              if (!perspectiveStack.getChildren().isEmpty())
                  return;
      
              // clone each snippet that is a perspective and add the cloned perspective into the main PerspectiveStack
              boolean isFirst = true;
              for (MUIElement snippet : application.getSnippets()) {
                  if (snippet instanceof MPerspective) {
                      MPerspective perspectiveClone = (MPerspective) modelService.cloneSnippet(application, snippet.getElementId(), null);
                      perspectiveStack.getChildren().add(perspectiveClone);
                      if (isFirst) {
                          perspectiveStack.setSelectedElement(perspectiveClone);
                          isFirst = false;
                      }
                  }
              }
          }
      }
      
    4. Register your CopyPerspectiveSnippetProcess into your plugin.xml file.

      <extension id="MainAppModel" point="org.eclipse.e4.workbench.model">
          <processor beforefragment="false" class="com.example.application.processors.CopyPerspectiveSnippetProcessor"/>
      </extension>
      
    5. Reset the perspective as normal. You will also want to set the perspective stack and the current perspective to visible, as these can sometimes be set to invisible. A sample handler might look like:

      import org.eclipse.e4.core.di.annotations.Execute;
      import org.eclipse.e4.ui.model.application.MApplication;
      import org.eclipse.e4.ui.model.application.ui.advanced.MPerspectiveStack;
      import org.eclipse.e4.ui.workbench.modeling.EModelService;
      import org.eclipse.ui.PlatformUI;
      
      public class ResetPerspectiveHandler {
          private static final String MAIN_PERSPECTIVE_STACK_ID = "MainPerspectiveStack";
      
          @Execute
          public void execute(EModelService modelService, MApplication application) {
               MPerspectiveStack perspectiveStack = (MPerspectiveStack) modelService.find(MAIN_PERSPECTIVE_STACK_ID, application);
               PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().resetPerspective();
               perspectiveStack.getSelectedElement().setVisible(true);
               perspectiveStack.setVisible(true);
          }
      }