简体   繁体   中英

Eclipse RCP workbench.xmi control of saved parts

When an E4 RCP application is closed, changes are recorded/saved in workbench.xmi file.

Within a partstack, several parts may be open at the time when the application is closed.

These parts are tagged as

<children xsi:type="basic:PartStack"
                xmi:id="_The_ID"
                elementId="elemId"
                contributorURI="URI"
                containerData="3000">
  <tags>NoAutoCollapse</tags>
</children>

When the application is restarted these parts saved at workbench.xmi are created and displayed again.

How can control these parts during startup the application again in order to allow/not-allow a part to be created?

This is to be used in case that your data model (connected with your part) is saved in a file.

For example, the following sequence:

1.- RCP is closed with some parts open (ie file-to-remain.xml and file-to-be-deleted.xml )

2.- The user delete the file file-to-be-deleted.xml deleting the data.

3.- RCP is restarted, hence file-to-be-deleted.xml is created and displayed with no data.

The objective is to avoid the creation of file-to-be-deleted.xml in step 3.-

I will extend my explanations after reading greg-449 answer and also his answer in question: " e4 - removing elements from the application model "

I have a workbench.xmi saved containing one PartStack and two Parts (2 xml files) at the time when the applications was closed (file-to-remain.xml, file-to-be-deleted.xml)

Note that the element ID is a string containing the file path. Done at part creation by part.setElementID(String) method.

Also note that the parts are created by a class named AutodocuForm.class

<children xsi:type="basic:PartStack" 
          xmi:id="_iDPe2cIDEeaAXZB7N2qOIw" 
          elementId="my-plugin.partstack.0" 
          contributorURI="platform:/plugin/my-plugin" 
          containerData="3066" 
          selectedElement="_6pVbwMNsEeaiI_JEbgNbYQ">

          <children xsi:type="basic:Part"
                    xmi:id="_3ZCIocNsEeaiI_JEbgNbYQ" 
                    elementId="C:\Users\name\Desktop\file-to-remain.xml" 
                    contributorURI="platform:/plugin/my-plugin" 
                    contributionURI="bundleclass://my-plugin/my-plugin.autodocu.AutodocuForm" 
                    label="file-to-remain.xml" 
                    iconURI="platform:/plugin/my-plugin/icons/file_obj.gif" 
                    closeable="true">
         </children>

         <children xsi:type="basic:Part" 
                   xmi:id="_6pVbwMNsEeaiI_JEbgNbYQ" 
                   elementId="C:\Users\name\Desktop\file-to-be-deleted.xml" 
                   contributorURI="platform:/plugin/my-plugin" 
                   contributionURI="bundleclass://my-plugin/my-plugin.autodocu.AutodocuForm" 
                   label="file-to-be-deleted.xml" 
                   iconURI="platform:/plugin/my-plugin/icons/file_obj.gif" 
                   closeable="true">
         </children>
</children>

I have created a LifeCycle class:

public class LifeCycleManager {

    @ProcessRemovals
    void postContextCreate(IEclipseContext context, MApplication application, EModelService modelService, EPartService partService){

        List<MPart> parts = modelService.findElements(application, null, MPart.class, null);
        for(MPart elParte: parts){
            if(elParte.getContributionURI().endsWith("AutodocuForm")){
                Path partPath = Paths.get(elParte.getElementId());
                if(Files.exists(partPath, LinkOption.NOFOLLOW_LINKS)){
                    System.out.println("FILE EXISTS INTO THE FILE SYSTEM...");
                }
                else{
                    System.out.println("FILE DOES NOT EXIST INTO THE FILE SYSTEM...");
                    MElementContainer<MUIElement> parent = elParte.getParent();
                    elParte.setToBeRendered(false);
                    parent.getChildren().remove(elParte);

                }
            }
        }
    }
}

If I delete "file-to-be-deleted.xml" and restart the application, the part is not shown inside the partStack, but I obtain the following exception:

!ENTRY org.eclipse.e4.ui.workbench.swt 4 2 2016-12-20 11:09:38.601
!MESSAGE Problems occurred when invoking code from plug-in: "org.eclipse.e4.ui.workbench.swt".
!STACK 0
java.lang.NullPointerException
at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.showTab(LazyStackRenderer.java:160)
...
...

!ENTRY org.eclipse.e4.ui.workbench 4 0 2016-12-20 11:09:38.601
!MESSAGE Exception occurred while rendering: org.eclipse.e4.ui.model.application.ui.basic.impl.PartStackImpl@39478c45 
            (elementId: my-plugin.partstack.0, 
              tags: [NoAutoCollapse], 
              contributorURI: platform:/plugin/my-plugin) 
            (widget: CTabFolder {}, 
              renderer: org.eclipse.e4.ui.workbench.renderers.swt.StackRenderer@1b62d923, 
              toBeRendered: true, 
              onTop: false, 
              visible: true, 
              containerData: 3066, 
              accessibilityPhrase: null)
!STACK 0
java.lang.NullPointerException
at org.eclipse.e4.ui.workbench.renderers.swt.LazyStackRenderer.showTab(LazyStackRenderer.java:160)
...
...

It seems to me that the part is deleted from the model, but the Part Stack is not updated.

Thanks in advance

You can specify the -clearPersistedState option to make the RCP ignore the workbench.xmi and open exactly as described in the Application.e4xmi.

You can also specify -persistState false to stop the workbench.xmi being saved in the first place.

Specify these in the 'Program Arguments' section of the 'Launching' tab in the .product file editor.

There isn't any support for restoring just part of the model during startup. The workbench.xmi is just a copy of the application model as it is when you exit the RCP.

If you have a list of parts to open you could do this during the RCP startup probably in the 'application startup complete' event. This would probably be a method in your LifeCycle class (if you have one):

@Optional
@Inject
public void appStartupComplete(@UIEventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE) Event event,
                               EPartService partService)
{
  // TODO call partService.showPart for parts to be opened
}

By removing parent.getChildren().remove(elParte); the exception is solved. Furthermore it is necessary to remove the part from the model (from the part stack list) as is shown in the next snippet:

public class LifeCycleManager {

@ProcessRemovals
void postContextCreate(IEclipseContext context, MApplication application, EModelService modelService, EPartService partService){

    List<MPart> parts = modelService.findElements(application, null, MPart.class, null);
    for(MPart elParte: parts){
        if(elParte.getContributionURI().endsWith("AutodocuForm")){
            Path partPath = Paths.get(elParte.getElementId());
            if(Files.exists(partPath, LinkOption.NOFOLLOW_LINKS)){
                System.out.println("FILE EXISTS INTO THE FILE SYSTEM...");
            }
            else{
                System.out.println("FILE DOES NOT EXIST INTO THE FILE SYSTEM...");
                MElementContainer<MUIElement> parent = elParte.getParent();
                elParte.setToBeRendered(false);
                //parent.getChildren().remove(elParte);
                Iterator it = parent.getChildren().iterator();
                elParte.setToBeRendered(false);
                while(it.hasNext()){
                    MUIElement el = (MUIElement) it.next();
                    if(el.getElementId().equals(elParte.getElementId())){
                       //Remove the part from the PartStack list
                       parent.getChildren().remove(el);
                       //Remove the selected element to avoid that the 
                       //deleted file was the selected element prior to
                       //deletion, which is stored into the 
                       //workbench.xmi file
                       parent.setSelectedElement(null);
                       break;
                    }
                }
            }
        }
    }
 }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM