How to include a preference page into the preference dialog - eclipse-rcp

I know the way to add preference pages into the common preference dialog for an e3 RCP application. I have an e4 RCP application and I read that the preference dialog works different.
I found the way to open the common preference dialog, but I didn't find a way to include a customized preference page into the dialog.
public class PreferenceHandler {
#CanExecute
public boolean canExecute()
{
return true;
}
#Execute
public void execute(#Named(IServiceConstants.ACTIVE_SHELL) Shell shell, E4PreferenceRegistry prefReg,
#Optional #Named("preferencePageId") String pageId) {
PreferenceManager pm = prefReg.getPreferenceManager();
// Can display the standard dialog.
PreferenceDialog dialog = new PreferenceDialog(shell, pm);
if (pageId != null)
{
dialog.setSelectedNode(pageId);
}
dialog.create();
dialog.getTreeViewer().setComparator(new ViewerComparator());
dialog.getTreeViewer().expandAll();
dialog.open();
}
}

Most of the preference page code is part of e3 and isn't available in e4. Only the very basic JFace code is available.
So you will have to add each preference page you want directly to the PreferenceManager. Something like:
PreferenceManager pm = ... preference manager
IPreferencePage page = ... create your preference page
page.setTitle("title of the page");
IPreferenceNode node = new PreferenceNode("id of the page", page);
pm.addToRoot(node);

Related

Open DialectEditor programmatically outside of main editor area (E3/E4 hybrid)

what I want to do:
In my RCP an E3/E4 hybrid I have a project and library based on sirius tree. The User can drag an drop item from the library tree to the project tree. This works fine and was no great problem to build in. So now I want to make the UI more usable. It should looks like this layout:
what works:
After application startup I open my library presentation with the DialectUIManager.
final DialectEditor editor = (DialectEditor)
DialectUIManager.INSTANCE.openEditor(siriusSession, description, monitor);
Okay, this works. But it open it in the editor in the part market as org.eclipse.ui.editorss. This it not what I want
what does not work:
I want to show it in the "Library Part". I can move it manually with the mouse after open the editor, but how can i tell DialectUIManager to open it direct there. Or how can I programmatically it move there.
I do a lot of google research but i don't found a solution. The only thing I found was a hint Pierre-Charles David https:// www. eclipse.org/forums/index.php?t=msg&th=998476&goto=1631138&#msg_1631138
If you need is simply to show the editor outside of the main editor
area, this is possible since Eclipse 4.2 (e4 does not really treat the
main editor area as something special), so you can have your editor
"around" another editor in the middle of other views.
But at this step I stuck. I also ask it in the Sirius Forum but they say its a Eclipse E4 problem
Thanks for help, code snippets or links to correct part of manual.
I've found a solution. It's not very nice, but it works. I execute these code here after the editors have opened.
What the code does:
He is looking for the MPlaceholder which has the ID: org. eclipse. ui. editorss. There he descends until he is with the parts. These are in the Compatibly editor mode. Then he chooses the part we wants to move out of and Attach them to the MPartStack target.
public static void movePart(MApplication application,
EModelService modelService) {
MPart partToMove = null;
MUIElement muiElement =
modelService.find("org.eclipse.ui.editorss", application);
if (muiElement instanceof MPlaceholder) {
MPlaceholder placeholder = (MPlaceholder) muiElement;
MUIElement ref = placeholder.getRef();
if (ref instanceof MArea) {
MArea area = (MArea) ref;
List<MPartSashContainerElement> children = area.getChildren();
for (MPartSashContainerElement mPartSashContainerElement
: children) {
if (mPartSashContainerElement instanceof MPartStack) {
MPartStack partStack = (MPartStack) mPartSashContainerElement;
List<MStackElement> children2 = partStack.getChildren();
for (MStackElement mStackElement : children2) {
if (mStackElement instanceof MPart) {
MPart part = (MPart) mStackElement;
// Library is the Editor Name wiche I want to move
if (part.getLabel().equals("Library")) {
partToMove = part;
break;
}
}
}
}
}
}
}
if (partToMove != null) {
moveElement(modelService, application, partToMove);
}
}
private static void moveElement(EModelService modelService,
MApplication application, MPart part) {
// target PartStack
MUIElement find = modelService.find("de.bsg.onesps.rcp.
partstack.library", application);
if (find instanceof MPartStack) {
MPartStack mPartStack = (MPartStack) find;
mPartStack.getChildren().add(part);
mPartStack.setSelectedElement(part);
}
}

Eclipse RCP: Can I remove Orphaned Perspectives from the Perspective Bar?

I'm developing an RCP that has two product versions, a core app and one with some extensions. If a user opens the core app after having opened the extended app in the same workspace, eclipse detects a perspective used only in the extended app and makes a local copy of it, so it shows up in the perspective toolbar as an orphaned extension.
I created an activity to hide the extended app perspective when running the core app. That hides it from the perspective menu and the perspective shortcut menu, but it doesn't remove it from the perspective toolbar.I also tried detecting orphaned perspectives from the active page of the active workbench window (by looking for angle brackets in the label) and removing them with PlatformUI.getWorkbench().getPerspectiveRegistry().deletePerspective(perspective), but this doesn't affect the perspective toolbar either. The perspective I'm removing is not present in the core app.
Is there a way I can access the perspective toolbar programmatically so I can remove any orphaned perspectives? Or any other approach tha would work?
I thought a good solution would be creating a custom perspective switcher, but that path was blocked by an eclipse bug. There is a suggested workaround, but it did not work for me. I created a custom perspective switcher toolbar, but I could find no way to make it update when perspectives are opened or activated. My attempts are documented here.
I removed the orphan perspectives in a workspace shutdown hook, but for some reason an NPE is thrown by the E4 workbench (LazyStackRenderer line 238) when I select a perspective in the switcher that was opened but not selected when I launched the app.
I got it to work as desired by closing all open perspectives on shutdown, after storing their IDs in a preference value, and then opening them again when the app is launched in the WorkbenchWindowAdvisor. It's a bit of a hack, but it's the only way I could find to avoid the E4 workbench NPE, which also prevents setting the perspective from the toolbar until it's closed and re-opened from the Window menu.
Here's my code.
...
IWorkbench workbench = ...
static final String PERPSECTIVE_ID_1 = ...
static fnal String PERSPECTIVE_ID_2 = ...
static final String PREFERENCE_KEY = ...
workbench.addWorkbenchListener( new IWorkbenchListener() {
public boolean preShutdown( IWorkbench workbench, boolean forced ) {
IPerspectiveDescriptor[] openPerspectives = page.getOpenPerspectives();
page.closeAllPerspectives(false, false);
StringBuilder sb = new StringBuilder();
String delim = "";
for (IPerspectiveDescriptor persp : openPerspectives) {
if (!persp.getId().equals(PERSPECTIVE_ID_1) && !persp.getId().equals(PERSPECTIVE_ID_2) {
sb.append(delim + persp.getId());
delim = ";";
}
}
getPreferenceStore().setValue(PREF_KEY, sb.toString());
return true;
}
public void postShutdown( IWorkbench workbench ) {
}
});
class MyWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
static final String PRODUCT_ID_1 = ...
static final String PRODUCT_ID_2 = ...
static final String PREFERENCE_KEY = ...
...
#Override
public void postWindowOpen() {
IWorkbenchPage page = getWindowConfigurer().getWindow().getActivePage();
String savedOpenPerspectiveStr = getPreferenceStore().getString(PREFERENCE_KEY);
if (!"".equals(savedOpenPerspectiveStr)) {
List<IPerspectiveDescriptor> openPerspectives = new ArrayList<IPerspectiveDescriptor>();
String[] perspectiveIds = savedOpenPerspectiveStr.split(";");
if (perspectiveIds.length == 0) {
openPerspectives.add(PlatformUI.getWorkbench().getPerspectiveRegistry().findPerspectiveWithId(savedOpenPerspectiveStr));
} else {
for (String id : perspectiveIds) {
openPerspectives.add(PlatformUI.getWorkbench().getPerspectiveRegistry().findPerspectiveWithId(id));
}
}
//successively setting perspectives causes them to appear in the perspective switcher toolbar
for (IPerspectiveDescriptor persp : openPerspectives) {
page.setPerspective(persp);
}
}
//now we set the appropriate perspective
if (Platform.getProduct().getId().equals(PRODUCT_ID_1)) {
page.setPerspective(PlatformUI.getWorkbench().getPerspectiveRegistry().findPerspectiveWithId(PERSPECTIVE_ID_1));
} else if (Platform.getProduct().getId().equals(PRODUCT_ID_2)) {
page.setPerspective(PlatformUI.getWorkbench().getPerspectiveRegistry().findPerspectiveWithId(PERSPECTIVE_ID_2));
}
}
...
}

How to retain the state of a treeviewer in Java RCP application?

I have a simple RCP application having couple of wizards out of which one is having a tree viewer. I want to retain the state of the selected item in the tree viewer next time I open that particular view. As of now I have implemented using static variables and its working fine.I want to know how it can be done in a better way?
//Sample Code
private static RepositoryLocationItem lastRepoItemSelected;
Composite parent=new Composite(SWT.NONE)
treeViewer = new TreeViewer(parent);
treeViewer.setContentProvider(new MovingBoxContentProvider());
treeViewer.setLabelProvider(new MovingBoxLabelProvider());
treeViewer.setInput(getInitalInput());
treeViewer.addSelectionChangedListener(new ISelectionChangedListener() {
/* Setting the value of lastRepoItemSelected */
});
if(lastRepoItemSelected !=null)
{
treeViewer.setSelection(new StructuredSelection(lastRepoItemSelected),true);
}
Assuming this is a 3.x style RCP (your view extends ViewPart) you can use the saveState method to save your view state:
#Override
public void saveState(final IMemento memento)
{
// TODO set values in the 'memento'
}
You can then use the init method to restore values from the memento when the view is shown again:
#Override
public void init(final IViewSite site, final IMemento memento)
throws PartInitException
{
super.init(site, memento);
// TODO restore from 'memento'
}
Note: Mementos are persisted across restarts of your RCP so you need to store values in them which are valid in a new instance of the RCP.
Also look at the Eclipse wiki entry for more information.
For a WizardPage you can use the IDialogSettings. You must set this up in your Wizard using something like:
IDialogSettings pluginSettings = Activator.getDefault().getDialogSettings();
IDialogSettings wizardSettings = pluginSettings.getSection("id of your wizard");
if (wizardSettings == null) {
wizardSettings= new DialogSettings("id of your wizard");
pluginSettings.addSection(wizardSettings);
}
setDialogSettings(wizardSettings);
where Activator is your plugin activator class and "name of your wizard" is a id for your wizard (which can be anything as long as it is unique in your plugin).
In your wizard page you can then get the settings with:
IDialogSettings settings = getDialogSettings();
IDialogSettings has lots of methods for saving and restore various sorts of values, such as:
settings.put("key", "string value");
String value = settings.get("key");

How to pass an object from one part to another part in Eclispe e4 RCP?

I am building an application with eclipse e4 RCP. I have a navigator (similar to Navigator in eclipse IDE) and I would like to link it to an editor (similar to how a file in Navigator in eclipse IDE is linked to an editor). Currently I am using EPartService to open up my editor Part (by creating a new instance) when the user double clicks on a file in the Navigator tree. But I would like to pass it a parameter (a String or an Object) to let it know which file to open in the editor. I want to be able to open multiple editors for different nodes of the Navigator tree. I have done a lot of research on internet but could not find a solution. I think its a common problem and the e4 framework should provide an mechanism to pass such parameters from one Part to another Part. Current code is as below:
viewer.addDoubleClickListener(event -> {
final IStructuredSelection selection = (IStructuredSelection) event.getSelection();
FileNode file = null;
boolean partExists = false;
if (selection.getFirstElement() instanceof FileNode ) {
file = (FileNode ) selection.getFirstElement();
for (MPart part1 : partService.getParts()) {
if (part1.getLabel().equals(file.getName())) {
partService.showPart(part1, PartState.ACTIVATE);
partExists = true;
break;
}
}
if (!partExists) {
MPart part2 = partService
.createPart("com.parts.partdescriptor.fileeditor");
part2.setLabel(file.getName());
partService.showPart(part2, PartState.ACTIVATE);
}
}
});
Is it possible to say something like part2.setParameter("PARAM_NAME", "FILE_NAME"); ?
When you have an MPart you can call:
MPart mpart = ...
MyClass myClass = (MyClass)mpart.getObject();
to get your class for the part (the class defined in the 'Class URI' for the part in the Application.e4xmi). You can then call any methods you have defined on your part class.
You can also set data in the 'transient data' area of a part:
mpart.getTransientData().put("key", "data");
Object data = mpart.getTransientData().get("key");

gwt menu implementation

I want to implement menu in GWT as shown on this website:
http://www.openkm.com/en/
I have created the menu system and I am able to display alerts from menu using following code:
Command cmd = new Command() {
public void execute() {
Window.alert("Menu item have been selected");
}
}
I want to get rid of window.alert() and display my application pages from menu.
Create and load the appropriate page. For example if you use UiBinder then:
MyPage selectedPage = new MyPage(); // creating of your panel
RootPanel.get().clear(); // cleaning of rhe RootPanel
RootPanel.get().add(selectedPage); // adding the panel to the RootPanel
First create an array list of views
public List<UIObject> viewsList = new ArrayList<UIObject>();
Add a view to that list
viewsList.add(addMovieView);
Send the view you want to select to the helper method
public void changeView(UIObject selectedView) {
for(UIObject view : viewsList) {
if(selectedView.equals(view)) {
view.setVisible(true);
} else {
view.setVisible(false);
}
}
}
Are you trying to make the entire page GWT, or just the menu? If it's just the menu, you will need to embed a GWT element into your overall HTML, then call something like
Window.open(linkURL, "_self", "");
from the appropriate menu items, which will navigate to another page.