3

I'm testing an non-e4 RCP application using SWTBot and I need to change the size of my view. (Move the sash-bar)

I unsuccessfully tried

  • Resize my view using SWTBot (no such api)
  • Resize my view using Eclipse 3 API (no supported)
  • Resize my view using underlying e4 model (resizing not working)

e4 model seams to be promising, but I'm missing something, so it doesn't work.

I can

  • Get MPart of my view: view = ePartService.findPart(ID)
  • Get MTrimmedWindow: window = (view as EObject).eContainer as MTrimmedWindow

I can't

  • locale correct MPartSashContainer
  • move sash-bar with setContainerData()

I would like to know

  • How can I move from MPart to its direct parent (e.g. MPartStack)
  • Why common EObject methods like eContainer() are not present on M... objects?
tkotisis
  • 3,442
  • 25
  • 30
Boris Brodski
  • 8,425
  • 4
  • 40
  • 55
  • `MPart` (and all other `MUIElement` objects) has a `getParent()` method which give you the immediate parent. – greg-449 Nov 09 '17 at 13:42
  • Unfortunately it returns null for my "view" MPart :( – Boris Brodski Nov 09 '17 at 13:53
  • Then it hasn't been added to a container yet. This **always** returns a parent for parts that are being shown. – greg-449 Nov 09 '17 at 14:33
  • @greg-449 I do `page.showView(ID,...)`, then wait for 5 seconds, then `ePartService.findPart(ID).getParent()` is still `null`. Any ideas? – Boris Brodski Nov 09 '17 at 15:01
  • I don't know what happens with part ids in 3.x compatibility mode. I am not sure that the id used by `IWorkbenchPage.showPage` is the same id as the application model MPart id. – greg-449 Nov 09 '17 at 15:05

1 Answers1

1

Ok, I found a solution myself.

The thing is, that the view is not a part of the e4 UI-Tree. view.eContainer is directly the MWindow. To be placed at the right spot the view is connected to the MPlaceholder, that is a part of the e4 UI-Tree and has getParent() != null.

In order to resize a view the steps are:

  • Show view
  • Find MPlaceholder of the view
  • Find MPartStack and `MPartSashContainer´ object
  • Set containerData
  • Redraw widget (yes, auto-update seam not to work in this case)

Example:

EModelService modelService = PlatformUI.getWorkbench().getService(EModelService.class);
EPartService  partService  = PlatformUI.getWorkbench().getService(EPartService.class);

// Show view
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
page.showView(MyView.ID, null, IWorkbenchPage.VIEW_ACTIVATE);

MPart view = partService.findPart(MyView.ID);
// view.getParent() => null, because 'view' is not a part of the e4 UI-model!
// It is connected to the Model using MPlaceholder

// Let's find the placeholder
MWindow window = (MWindow)(((EObject)eView).eContainer);
MPlaceholder placeholder = modelService.findPlaceholderFor(window, view);

MUIElement element = placeholder;
MPartStack partStack = null;
while (element != null) {
    // This may not suite your configuration of views/stacks/sashes
    if (element instanceof MPartStack && ((Object)element.parent) instanceof MPartSashContainer) {
            partStack = (MPartStack)element;
            break;
        }
        element = element.parent;
    }
}
if (partStack == null) { /* handle error */ }

// Now let's change the width weights
for (MUIElement element : partStack.getParent().getChildren()) {
    if (element == partStack) {
        element.setContainerData("50"); // Width for my view
    } else {
        element.setContainerData("25"); // Widths for other views & editors
    }
}

// Surprisingly I had to redraw tho UI manually
// There is for sure a better way to do it. Here is my (quick & very dirty):
partStack.toBeRendered = false
partStack.toBeRendered = true
Boris Brodski
  • 8,425
  • 4
  • 40
  • 55