Skip to content

Commit

Permalink
Implementation of Renes suggestion for an improved ToolControl for
Browse files Browse the repository at this point in the history
monitoring the Jobs progress
  • Loading branch information
vogella committed Aug 4, 2015
1 parent 282dd96 commit d5f2484
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 204 deletions.
2 changes: 1 addition & 1 deletion com.example.e4.rcp.todo/Application.e4xmi
Expand Up @@ -113,7 +113,7 @@
<children xsi:type="menu:ToolControl" xmi:id="_mQav4BO4EeS5RO-5PCVTqQ" elementId="com.example.e4.rcp.todo.toolcontrol.1" contributionURI="bundleclass://com.example.e4.rcp.todo/com.example.e4.rcp.todo.toolcontrols.SwitchLanguageToolControl"/>
</trimBars>
<trimBars xmi:id="_O6v78NXpEeODCZCgwFhKTQ" elementId="com.example.e4.rcp.todo.trimbar.0" side="Bottom">
<children xsi:type="menu:ToolControl" xmi:id="_QA6SwNXpEeODCZCgwFhKTQ" elementId="statusbar" visible="false" contributionURI="bundleclass://com.example.e4.rcp.todo/com.example.e4.rcp.todo.toolcontrols.ProgressMonitorControl"/>
<children xsi:type="menu:ToolControl" xmi:id="_QA6SwNXpEeODCZCgwFhKTQ" elementId="statusbar" contributionURI="bundleclass://com.example.e4.rcp.todo/com.example.e4.rcp.todo.toolcontrols.ProgressMonitorControl"/>
</trimBars>
</children>
<handlers xmi:id="_V35JgMZrEeGbkqRLZ7osPQ" elementId="com.example.e4.rcp.todo.handlers.saveall" contributionURI="bundleclass://com.example.e4.rcp.todo/com.example.e4.rcp.todo.handlers.SaveAllHandler" command="_vTZDkMZXEeGbkqRLZ7osPQ"/>
Expand Down
@@ -1,90 +1,112 @@
package com.example.e4.rcp.todo.addons;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.inject.Inject;

import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.di.UIEventTopic;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.basic.MWindow;
import org.eclipse.e4.ui.workbench.IWorkbench;
import org.eclipse.e4.ui.workbench.UIEvents;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.EPartService;
import org.eclipse.e4.ui.workbench.modeling.ElementMatcher;
import org.eclipse.e4.ui.workbench.modeling.IWindowCloseHandler;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.widgets.Shell;
import org.osgi.service.event.Event;

// @PostConstruct will not work as workbench gets instantiated after the processing of the add-ons
// @PostConstruct does not work as the workbench gets
// instantiated after the processing of the add-ons
// hence this approach uses method injection

public class WindowCloseListenerAddon {

@Inject
@Optional
MApplication application;

@Inject
@Optional
EPartService partService;

@Inject
@Optional
IWorkbench workbench;


@Inject
@Optional
private void subscribeApplicationCompleted(@UIEventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE) Event event) {
if (application!=null && partService != null &&workbench !=null ){
registerCloseHandler(partService, workbench, application);
}
private void subscribeApplicationCompleted(
@UIEventTopic(UIEvents.UILifeCycle.APP_STARTUP_COMPLETE) final MApplication application,
final IWorkbench workbench) {
// only if a close of the main window is requested
MWindow mainWindow = findMainWindow(application);

mainWindow.getContext().set(IWindowCloseHandler.class, new IWindowCloseHandler() {
@Override
public boolean close(MWindow window) {
Collection<EPartService> allPartServices = getAllPartServices(application);

if (containsDirtyParts(allPartServices)) {
Shell shell = (Shell) window.getWidget();
MessageDialog msgDialog = new MessageDialog(shell, "Close Application", null,
"Do you want to save the changes before you close the entire application?",
MessageDialog.QUESTION_WITH_CANCEL, new String[] { IDialogConstants.YES_LABEL,
IDialogConstants.NO_LABEL, IDialogConstants.CANCEL_LABEL },
0);
switch (msgDialog.open()) {
case 0: // YES: save all and close
saveAll(allPartServices);
return workbench.close();

case 1: // NO: save nothing and close
return workbench.close();

case 2: // CANCEL: prevent close
default:
return false;
}
} else {
Shell shell = (Shell) window.getWidget();
if (MessageDialog.openConfirm(shell, "Close Application",
"Do you really want to close the entire application?")) {
return workbench.close();
}
}

return false;
}
});
}
@Inject
@Optional
private void subscribeTopicChildrenChanged(@UIEventTopic(UIEvents.ElementContainer.TOPIC_CHILDREN) Event event) {
Object changedObj = event.getProperty(UIEvents.EventTags.ELEMENT);
System.out.println(changedObj);

if (!(changedObj instanceof MApplication)) {
return;
}

MApplication application = (MApplication) changedObj;
if (application!=null && partService != null && workbench !=null ){
registerCloseHandler(partService, workbench, application);
}

// only interested in changes to application




private static MWindow findMainWindow(MApplication application) {
// instead of using the index you could also use a tag on the MWindow to
// mark the main window
return application.getChildren().get(0);
}

private void registerCloseHandler(final EPartService partService, final IWorkbench workbench,
MApplication application) {
// each window gets its own close handler
for (MWindow window : application.getChildren()) {

final Shell shell = (Shell) window.getWidget();

IWindowCloseHandler closeHandler = new IWindowCloseHandler() {

@Override
public boolean close(MWindow window) {
if (partService.getDirtyParts().size() > 0) {
boolean close = MessageDialog.openConfirm(shell, "Unsaved data", "Really close?");
if (close) {
workbench.close();
}
return close;
}
return true;
private static Collection<EPartService> getAllPartServices(MApplication application) {
List<EPartService> partServices = new ArrayList<EPartService>();

EModelService modelService = application.getContext().get(EModelService.class);
List<MWindow> elements = modelService.findElements(application, MWindow.class, EModelService.IN_ACTIVE_PERSPECTIVE,
new ElementMatcher(null, MWindow.class, (List<String>) null));
for (MWindow w : elements) {
if (w.isVisible() && w.isToBeRendered()) {
EPartService partService = w.getContext().get(EPartService.class);
if (partService != null) {
partServices.add(partService);
}
};
window.getContext().set(IWindowCloseHandler.class, closeHandler);
}
}

return partServices;
}

private static boolean containsDirtyParts(Collection<EPartService> partServices) {
for (EPartService partService : partServices) {
if (!partService.getDirtyParts().isEmpty())
return true;
}

return false;
}

private static void saveAll(Collection<EPartService> partServices) {
for (EPartService partService : partServices) {
partService.saveAll(false); // false: save without prompt
}
}
}
}
Expand Up @@ -12,17 +12,14 @@
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobManager;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.ProgressProvider;
import org.eclipse.e4.core.di.annotations.Optional;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.core.services.nls.Translation;
import org.eclipse.e4.ui.di.Focus;
import org.eclipse.e4.ui.di.UIEventTopic;
import org.eclipse.e4.ui.di.UISynchronize;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.ui.menu.MToolControl;
import org.eclipse.e4.ui.services.EMenuService;
import org.eclipse.e4.ui.workbench.modeling.EModelService;
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
Expand All @@ -49,7 +46,6 @@
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.Text;
import org.osgi.service.event.Event;

import com.example.e4.rcp.todo.events.MyEventConstants;
import com.example.e4.rcp.todo.i18n.Messages;
Expand Down Expand Up @@ -94,36 +90,7 @@ public void createControls(Composite parent, EMenuService menuService, @Translat
btnNewButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {

final MToolControl toolControl = (MToolControl) modelService.find("statusbar", application);
toolControl.setVisible(true);

Job job = new Job("loading") {
@Override
protected IStatus run(IProgressMonitor monitor) {
toolControl.setVisible(false);
final List<Todo> list = todoService.getTodos();
System.out.println(list);
broker.post(MyEventConstants.TOPIC_TODOS_CHANGED,
new Event(MyEventConstants.TOPIC_TODOS_CHANGED, new HashMap<String, String>()));
return Status.OK_STATUS;
}
};
if (toolControl != null) {
IJobManager jobManager = job.getJobManager();
Object widget = toolControl.getObject();
final IProgressMonitor p = (IProgressMonitor) widget;
ProgressProvider provider = new ProgressProvider() {

@Override
public IProgressMonitor createMonitor(Job job) {
return p;
}
};
jobManager.setProgressProvider(provider);

}
job.schedule();
broker.post(MyEventConstants.TOPIC_TODOS_CHANGED, new HashMap<String, String>());
}
});

Expand Down Expand Up @@ -226,10 +193,25 @@ public void selectionChanged(SelectionChangedEvent event) {
@Optional
private void subscribeTopicTodoAllTopics(
@UIEventTopic(MyEventConstants.TOPIC_TODO_ALLTOPICS) Map<String, String> event) {
if (viewer != null) {
writableList.clear();
writableList.addAll(todoService.getTodos());
}
Job job = new Job("loading") {
@Override
protected IStatus run(IProgressMonitor monitor) {
final List<Todo> list = todoService.getTodos();
sync.asyncExec(new Runnable() {
@Override
public void run() {
if (viewer != null) {
writableList.clear();
writableList.addAll(list);
}
}
});
return Status.OK_STATUS;
}
};
job.schedule();


}

@Focus
Expand Down

0 comments on commit d5f2484

Please sign in to comment.