diff options
Diffstat (limited to 'bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeModelUpdateHandler.java')
-rw-r--r-- | bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeModelUpdateHandler.java | 734 |
1 files changed, 367 insertions, 367 deletions
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeModelUpdateHandler.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeModelUpdateHandler.java index 14aacad9c..e027dffc3 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeModelUpdateHandler.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeModelUpdateHandler.java @@ -59,9 +59,9 @@ import com.ibm.icu.text.SimpleDateFormat; * handler's thread. */ public class SynchronizeModelUpdateHandler extends BackgroundEventHandler implements IResourceChangeListener, ISyncInfoSetChangeListener { - private static final IWorkspaceRoot ROOT = ResourcesPlugin.getWorkspace().getRoot(); + private static final IWorkspaceRoot ROOT = ResourcesPlugin.getWorkspace().getRoot(); - // Event that indicates that the markers for a set of elements has changed + // Event that indicates that the markers for a set of elements has changed private static final int MARKERS_CHANGED = 1; private static final int BUSY_STATE_CHANGED = 2; private static final int RESET = 3; @@ -81,14 +81,14 @@ public class SynchronizeModelUpdateHandler extends BackgroundEventHandler implem * Custom event for posting marker changes */ class MarkerChangeEvent extends Event { - private final ISynchronizeModelElement[] elements; - public MarkerChangeEvent(ISynchronizeModelElement[] elements) { - super(MARKERS_CHANGED); - this.elements = elements; - } - public ISynchronizeModelElement[] getElements() { - return elements; - } + private final ISynchronizeModelElement[] elements; + public MarkerChangeEvent(ISynchronizeModelElement[] elements) { + super(MARKERS_CHANGED); + this.elements = elements; + } + public ISynchronizeModelElement[] getElements() { + return elements; + } } /** @@ -96,65 +96,65 @@ public class SynchronizeModelUpdateHandler extends BackgroundEventHandler implem */ class BusyStateChangeEvent extends Event { - private final ISynchronizeModelElement element; - private final boolean isBusy; - public BusyStateChangeEvent(ISynchronizeModelElement element, boolean isBusy) { - super(BUSY_STATE_CHANGED); - this.element = element; - this.isBusy = isBusy; - } - public ISynchronizeModelElement getElement() { - return element; - } - public boolean isBusy() { - return isBusy; - } + private final ISynchronizeModelElement element; + private final boolean isBusy; + public BusyStateChangeEvent(ISynchronizeModelElement element, boolean isBusy) { + super(BUSY_STATE_CHANGED); + this.element = element; + this.isBusy = isBusy; + } + public ISynchronizeModelElement getElement() { + return element; + } + public boolean isBusy() { + return isBusy; + } } /** * Custom event for posting sync info set changes */ class SyncInfoSetChangeEvent extends Event { - private final ISyncInfoSetChangeEvent event; - public SyncInfoSetChangeEvent(ISyncInfoSetChangeEvent event) { - super(SYNC_INFO_SET_CHANGED); - this.event = event; - } - public ISyncInfoSetChangeEvent getEvent() { - return event; - } + private final ISyncInfoSetChangeEvent event; + public SyncInfoSetChangeEvent(ISyncInfoSetChangeEvent event) { + super(SYNC_INFO_SET_CHANGED); + this.event = event; + } + public ISyncInfoSetChangeEvent getEvent() { + return event; + } } private IPropertyChangeListener listener = event -> { if (event.getProperty() == ISynchronizeModelElement.BUSY_PROPERTY) { Object source = event.getSource(); if (source instanceof ISynchronizeModelElement) - updateBusyState((ISynchronizeModelElement)source, ((Boolean)event.getNewValue()).booleanValue()); + updateBusyState((ISynchronizeModelElement)source, ((Boolean)event.getNewValue()).booleanValue()); } }; - private boolean performingBackgroundUpdate; + private boolean performingBackgroundUpdate; - /* - * Map used to keep track of additions so they can be added in batch at the end of the update - */ - private Map<ISynchronizeModelElement, Set<ISynchronizeModelElement>> additionsMap; + /* + * Map used to keep track of additions so they can be added in batch at the end of the update + */ + private Map<ISynchronizeModelElement, Set<ISynchronizeModelElement>> additionsMap; /** - * Create the marker update handler. - */ - public SynchronizeModelUpdateHandler(AbstractSynchronizeModelProvider provider) { - super(TeamUIMessages.SynchronizeModelProvider_0, TeamUIMessages.SynchronizeModelUpdateHandler_0); // - this.provider = provider; - ResourcesPlugin.getWorkspace().addResourceChangeListener(this); - provider.getSyncInfoSet().addSyncSetChangedListener(this); - } - - /** - * Return the marker types that are of interest to this handler. - * @return the marker types that are of interest to this handler - */ - protected String[] getMarkerTypes() { + * Create the marker update handler. + */ + public SynchronizeModelUpdateHandler(AbstractSynchronizeModelProvider provider) { + super(TeamUIMessages.SynchronizeModelProvider_0, TeamUIMessages.SynchronizeModelUpdateHandler_0); // + this.provider = provider; + ResourcesPlugin.getWorkspace().addResourceChangeListener(this); + provider.getSyncInfoSet().addSyncSetChangedListener(this); + } + + /** + * Return the marker types that are of interest to this handler. + * @return the marker types that are of interest to this handler + */ + protected String[] getMarkerTypes() { return new String[] {IMarker.PROBLEM}; } @@ -181,38 +181,38 @@ public class SynchronizeModelUpdateHandler extends BackgroundEventHandler implem IMarkerDelta delta = markerDeltas[i]; IResource resource = delta.getResource(); if (!handledResources.contains(resource)) { - handledResources.add(resource); - ISynchronizeModelElement[] elements = provider.getClosestExistingParents(delta.getResource()); + handledResources.add(resource); + ISynchronizeModelElement[] elements = provider.getClosestExistingParents(delta.getResource()); if(elements != null && elements.length > 0) { - for (int j = 0; j < elements.length; j++) { - ISynchronizeModelElement element = elements[j]; - changes.add(element); - } + for (int j = 0; j < elements.length; j++) { + ISynchronizeModelElement element = elements[j]; + changes.add(element); + } } } } } if (!changes.isEmpty()) { - updateMarkersFor(changes.toArray(new ISynchronizeModelElement[changes.size()])); + updateMarkersFor(changes.toArray(new ISynchronizeModelElement[changes.size()])); } } - private void updateMarkersFor(ISynchronizeModelElement[] elements) { - queueEvent(new MarkerChangeEvent(elements), false /* not on front of queue */); - } + private void updateMarkersFor(ISynchronizeModelElement[] elements) { + queueEvent(new MarkerChangeEvent(elements), false /* not on front of queue */); + } - protected void updateBusyState(ISynchronizeModelElement element, boolean isBusy) { - queueEvent(new BusyStateChangeEvent(element, isBusy), false /* not on front of queue */); - } + protected void updateBusyState(ISynchronizeModelElement element, boolean isBusy) { + queueEvent(new BusyStateChangeEvent(element, isBusy), false /* not on front of queue */); + } - @Override + @Override protected void processEvent(Event event, IProgressMonitor monitor) throws CoreException { - switch (event.getType()) { + switch (event.getType()) { case BackgroundEventHandler.RUNNABLE_EVENT : executeRunnable(event, monitor); break; - case MARKERS_CHANGED: + case MARKERS_CHANGED: // Changes contains all elements that need their labels updated long start = System.currentTimeMillis(); ISynchronizeModelElement[] elements = getChangedElements(event); @@ -227,46 +227,46 @@ public class SynchronizeModelUpdateHandler extends BackgroundEventHandler implem String took = TIME_FORMAT.format(new Date(time)); System.out.println(took + " for " + elements.length + " files"); //$NON-NLS-1$//$NON-NLS-2$ } - break; - case BUSY_STATE_CHANGED: - BusyStateChangeEvent e = (BusyStateChangeEvent)event; - queueForLabelUpdate(e.getElement()); - if (e.isBusy()) { - // indicate that we want an early dispatch to show busy elements - dispatchEarly = true; - } - break; - case RESET: - // Perform the reset immediately - pendingLabelUpdates.clear(); - provider.reset(); - break; - case SYNC_INFO_SET_CHANGED: - // Handle the sync change immediately - handleChanges(((SyncInfoSetChangeEvent)event).getEvent(), monitor); - default: - break; - } - } - - private ISynchronizeModelElement[] getChangedElements(Event event) { - if (event.getType() == MARKERS_CHANGED) { - return ((MarkerChangeEvent)event).getElements(); - } - return new ISynchronizeModelElement[0]; - } - - @Override + break; + case BUSY_STATE_CHANGED: + BusyStateChangeEvent e = (BusyStateChangeEvent)event; + queueForLabelUpdate(e.getElement()); + if (e.isBusy()) { + // indicate that we want an early dispatch to show busy elements + dispatchEarly = true; + } + break; + case RESET: + // Perform the reset immediately + pendingLabelUpdates.clear(); + provider.reset(); + break; + case SYNC_INFO_SET_CHANGED: + // Handle the sync change immediately + handleChanges(((SyncInfoSetChangeEvent)event).getEvent(), monitor); + default: + break; + } + } + + private ISynchronizeModelElement[] getChangedElements(Event event) { + if (event.getType() == MARKERS_CHANGED) { + return ((MarkerChangeEvent)event).getElements(); + } + return new ISynchronizeModelElement[0]; + } + + @Override protected boolean doDispatchEvents(IProgressMonitor monitor) throws TeamException { // Fire label changed - dispatchEarly = false; - if (pendingLabelUpdates.isEmpty()) { - return false; - } else { + dispatchEarly = false; + if (pendingLabelUpdates.isEmpty()) { + return false; + } else { Utils.asyncExec((Runnable) () -> firePendingLabelUpdates(), getViewer()); return true; - } - } + } + } /** * Forces the viewer to update the labels for queued elemens @@ -287,7 +287,7 @@ public class SynchronizeModelUpdateHandler extends BackgroundEventHandler implem * Forces the viewer to update the labels for the given elements */ private void updateLabels(Object[] elements) { - StructuredViewer tree = getViewer(); + StructuredViewer tree = getViewer(); if (Utils.canUpdateViewer(tree)) { tree.update(elements, null); } @@ -390,287 +390,287 @@ public class SynchronizeModelUpdateHandler extends BackgroundEventHandler implem /* * Queue an event that will reset the provider */ - private void reset() { - queueEvent(new ResourceEvent(ROOT, RESET, IResource.DEPTH_INFINITE), false); - } + private void reset() { + queueEvent(new ResourceEvent(ROOT, RESET, IResource.DEPTH_INFINITE), false); + } - public void dispose() { - shutdown(); - ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); - provider.getSyncInfoSet().removeSyncSetChangedListener(this); - } + public void dispose() { + shutdown(); + ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); + provider.getSyncInfoSet().removeSyncSetChangedListener(this); + } - @Override + @Override protected long getShortDispatchDelay() { - if (dispatchEarly) { - dispatchEarly = false; - return EARLY_DISPATCH_INCREMENT; - } - return super.getShortDispatchDelay(); - } - - /** - * This method is invoked whenever a node is added to the viewer - * by the provider or a sub-provider. The handler adds an update - * listener to the node and notifies the root provider that - * a node was added. - * @param element the added element - * @param provider the provider that added the element - */ - public void nodeAdded(ISynchronizeModelElement element, AbstractSynchronizeModelProvider provider) { - element.addPropertyChangeListener(listener); - this.provider.nodeAdded(element, provider); - if (Policy.DEBUG_SYNC_MODELS) { - System.out.println("Node added: " + getDebugDisplayLabel(element) + " -> " + getDebugDisplayLabel((ISynchronizeModelElement)element.getParent()) + " : " + getDebugDisplayLabel(provider)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - } - - /** - * This method is invoked whenever a node is removed the viewer - * by the provider or a sub-provider. The handler removes any - * listener and notifies the root provider that - * a node was removed. The node removed may have children for which - * a nodeRemoved callback was not invoked (see modelObjectCleared). - * @param element the removed element - * @param provider the provider that added the element - */ - public void nodeRemoved(ISynchronizeModelElement element, AbstractSynchronizeModelProvider provider) { - element.removePropertyChangeListener(listener); - this.provider.nodeRemoved(element, provider); - if (Policy.DEBUG_SYNC_MODELS) { - System.out.println("Node removed: " + getDebugDisplayLabel(element) + " -> " + getDebugDisplayLabel((ISynchronizeModelElement)element.getParent()) + " : " + getDebugDisplayLabel(provider)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ - } - } - - /** - * This method is invoked whenever a model object (i.e. node) - * is cleared from the model. This is similar to node removal but - * is deep. - * @param node the node that was cleared - */ - public void modelObjectCleared(ISynchronizeModelElement node) { - node.removePropertyChangeListener(listener); - this.provider.modelObjectCleared(node); - if (Policy.DEBUG_SYNC_MODELS) { - System.out.println("Node cleared: " + getDebugDisplayLabel(node)); //$NON-NLS-1$ - } - } - - private String getDebugDisplayLabel(ISynchronizeModelElement node) { - if (node == null) { - return "ROOT"; //$NON-NLS-1$ - } - if (node.getResource() != null) { - return node.getResource().getFullPath().toString(); - } - return node.getName(); - } - - private String getDebugDisplayLabel(AbstractSynchronizeModelProvider provider2) { - return provider2.toString(); - } - - @Override + if (dispatchEarly) { + dispatchEarly = false; + return EARLY_DISPATCH_INCREMENT; + } + return super.getShortDispatchDelay(); + } + + /** + * This method is invoked whenever a node is added to the viewer + * by the provider or a sub-provider. The handler adds an update + * listener to the node and notifies the root provider that + * a node was added. + * @param element the added element + * @param provider the provider that added the element + */ + public void nodeAdded(ISynchronizeModelElement element, AbstractSynchronizeModelProvider provider) { + element.addPropertyChangeListener(listener); + this.provider.nodeAdded(element, provider); + if (Policy.DEBUG_SYNC_MODELS) { + System.out.println("Node added: " + getDebugDisplayLabel(element) + " -> " + getDebugDisplayLabel((ISynchronizeModelElement)element.getParent()) + " : " + getDebugDisplayLabel(provider)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + } + + /** + * This method is invoked whenever a node is removed the viewer + * by the provider or a sub-provider. The handler removes any + * listener and notifies the root provider that + * a node was removed. The node removed may have children for which + * a nodeRemoved callback was not invoked (see modelObjectCleared). + * @param element the removed element + * @param provider the provider that added the element + */ + public void nodeRemoved(ISynchronizeModelElement element, AbstractSynchronizeModelProvider provider) { + element.removePropertyChangeListener(listener); + this.provider.nodeRemoved(element, provider); + if (Policy.DEBUG_SYNC_MODELS) { + System.out.println("Node removed: " + getDebugDisplayLabel(element) + " -> " + getDebugDisplayLabel((ISynchronizeModelElement)element.getParent()) + " : " + getDebugDisplayLabel(provider)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + } + + /** + * This method is invoked whenever a model object (i.e. node) + * is cleared from the model. This is similar to node removal but + * is deep. + * @param node the node that was cleared + */ + public void modelObjectCleared(ISynchronizeModelElement node) { + node.removePropertyChangeListener(listener); + this.provider.modelObjectCleared(node); + if (Policy.DEBUG_SYNC_MODELS) { + System.out.println("Node cleared: " + getDebugDisplayLabel(node)); //$NON-NLS-1$ + } + } + + private String getDebugDisplayLabel(ISynchronizeModelElement node) { + if (node == null) { + return "ROOT"; //$NON-NLS-1$ + } + if (node.getResource() != null) { + return node.getResource().getFullPath().toString(); + } + return node.getName(); + } + + private String getDebugDisplayLabel(AbstractSynchronizeModelProvider provider2) { + return provider2.toString(); + } + + @Override public void syncInfoSetReset(SyncInfoSet set, IProgressMonitor monitor) { if(provider.isDisposed()) { set.removeSyncSetChangedListener(this); } else { - reset(); + reset(); } - } + } - @Override + @Override public void syncInfoChanged(final ISyncInfoSetChangeEvent event, IProgressMonitor monitor) { if (! (event instanceof ISyncInfoTreeChangeEvent)) { reset(); } else { queueEvent(new SyncInfoSetChangeEvent(event), false); } - } + } - /* - * Handle the sync info set change event in the UI thread. - */ - private void handleChanges(final ISyncInfoSetChangeEvent event, final IProgressMonitor monitor) { - runViewUpdate(() -> { + /* + * Handle the sync info set change event in the UI thread. + */ + private void handleChanges(final ISyncInfoSetChangeEvent event, final IProgressMonitor monitor) { + runViewUpdate(() -> { provider.handleChanges((ISyncInfoTreeChangeEvent)event, monitor); firePendingLabelUpdates(); }, true /* preserve expansion */); - } + } - @Override + @Override public void syncInfoSetErrors(SyncInfoSet set, ITeamStatus[] errors, IProgressMonitor monitor) { // When errors occur we currently don't process them. It may be possible to decorate // elements in the model with errors, but currently we prefer to let ignore and except // another listener to display them. - } - - public ISynchronizeModelProvider getProvider() { - return provider; - } - - public void connect(IProgressMonitor monitor) { - getProvider().getSyncInfoSet().connect(this, monitor); - } - - public void runViewUpdate(final Runnable runnable, final boolean preserveExpansion) { - if (Utils.canUpdateViewer(getViewer()) || isPerformingBackgroundUpdate()) { - internalRunViewUpdate(runnable, preserveExpansion); - } else { - if (Thread.currentThread() != getEventHandlerJob().getThread()) { - // Run view update should only be called from the UI thread or - // the update handler thread. - // We will log the problem for now and make it an assert later - TeamUIPlugin.log(IStatus.WARNING, "View update invoked from invalid thread", new TeamException("View update invoked from invalid thread")); //$NON-NLS-1$ //$NON-NLS-2$ - } - final Control ctrl = getViewer().getControl(); - if (ctrl != null && !ctrl.isDisposed()) { - ctrl.getDisplay().syncExec(() -> { + } + + public ISynchronizeModelProvider getProvider() { + return provider; + } + + public void connect(IProgressMonitor monitor) { + getProvider().getSyncInfoSet().connect(this, monitor); + } + + public void runViewUpdate(final Runnable runnable, final boolean preserveExpansion) { + if (Utils.canUpdateViewer(getViewer()) || isPerformingBackgroundUpdate()) { + internalRunViewUpdate(runnable, preserveExpansion); + } else { + if (Thread.currentThread() != getEventHandlerJob().getThread()) { + // Run view update should only be called from the UI thread or + // the update handler thread. + // We will log the problem for now and make it an assert later + TeamUIPlugin.log(IStatus.WARNING, "View update invoked from invalid thread", new TeamException("View update invoked from invalid thread")); //$NON-NLS-1$ //$NON-NLS-2$ + } + final Control ctrl = getViewer().getControl(); + if (ctrl != null && !ctrl.isDisposed()) { + ctrl.getDisplay().syncExec(() -> { if (!ctrl.isDisposed()) { BusyIndicator.showWhile(ctrl.getDisplay(), () -> internalRunViewUpdate(runnable, preserveExpansion)); } }); - } - } - } - - /* - * Return whether the event handler is performing a background view update. - * In other words, a client has invoked <code>performUpdate</code>. - */ - public boolean isPerformingBackgroundUpdate() { - return Thread.currentThread() == getEventHandlerJob().getThread() && performingBackgroundUpdate; - } - - /* - * Method that can be called from the UI thread to update the view model. - */ - private void internalRunViewUpdate(final Runnable runnable, boolean preserveExpansion) { - StructuredViewer viewer = getViewer(); - IResource[] expanded = null; - IResource[] selected = null; + } + } + } + + /* + * Return whether the event handler is performing a background view update. + * In other words, a client has invoked <code>performUpdate</code>. + */ + public boolean isPerformingBackgroundUpdate() { + return Thread.currentThread() == getEventHandlerJob().getThread() && performingBackgroundUpdate; + } + + /* + * Method that can be called from the UI thread to update the view model. + */ + private void internalRunViewUpdate(final Runnable runnable, boolean preserveExpansion) { + StructuredViewer viewer = getViewer(); + IResource[] expanded = null; + IResource[] selected = null; try { - if (Utils.canUpdateViewer(viewer)) { - viewer.getControl().setRedraw(false); - if (preserveExpansion) { - expanded = provider.getExpandedResources(); - selected = provider.getSelectedResources(); - } - if (viewer instanceof AbstractTreeViewer && additionsMap == null) - additionsMap = new HashMap<>(); - } + if (Utils.canUpdateViewer(viewer)) { + viewer.getControl().setRedraw(false); + if (preserveExpansion) { + expanded = provider.getExpandedResources(); + selected = provider.getSelectedResources(); + } + if (viewer instanceof AbstractTreeViewer && additionsMap == null) + additionsMap = new HashMap<>(); + } runnable.run(); } finally { - if (Utils.canUpdateViewer(viewer)) { - try { - if (additionsMap != null && !additionsMap.isEmpty() && Utils.canUpdateViewer(viewer)) { - for (Iterator iter = additionsMap.keySet().iterator(); iter.hasNext();) { - ISynchronizeModelElement parent = (ISynchronizeModelElement) iter.next(); - if (Policy.DEBUG_SYNC_MODELS) { - System.out.println("Adding child view items of " + parent.getName()); //$NON-NLS-1$ - } - Set<ISynchronizeModelElement> toAdd = additionsMap.get(parent); - ((AbstractTreeViewer)viewer).add(parent, toAdd.toArray(new Object[toAdd.size()])); - } - additionsMap = null; - } - if (expanded != null) { - provider.expandResources(expanded); - } - if (selected != null) { - provider.selectResources(selected); - } - } finally { - viewer.getControl().setRedraw(true); - } - } + if (Utils.canUpdateViewer(viewer)) { + try { + if (additionsMap != null && !additionsMap.isEmpty() && Utils.canUpdateViewer(viewer)) { + for (Iterator iter = additionsMap.keySet().iterator(); iter.hasNext();) { + ISynchronizeModelElement parent = (ISynchronizeModelElement) iter.next(); + if (Policy.DEBUG_SYNC_MODELS) { + System.out.println("Adding child view items of " + parent.getName()); //$NON-NLS-1$ + } + Set<ISynchronizeModelElement> toAdd = additionsMap.get(parent); + ((AbstractTreeViewer)viewer).add(parent, toAdd.toArray(new Object[toAdd.size()])); + } + additionsMap = null; + } + if (expanded != null) { + provider.expandResources(expanded); + } + if (selected != null) { + provider.selectResources(selected); + } + } finally { + viewer.getControl().setRedraw(true); + } + } } ISynchronizeModelElement root = provider.getModelRoot(); if(root instanceof SynchronizeModelElement) ((SynchronizeModelElement)root).fireChanges(); - } - - /** - * Execute a runnable which performs an update of the model being displayed - * by the handler's provider. The runnable should be executed in a thread-safe manner - * which esults in the view being updated. - * @param runnable the runnable which updates the model. - * @param preserveExpansion whether the expansion of the view should be preserver - * @param updateInUIThread if <code>true</code>, the model will be updated in the - * UI thread. Otherwise, the model will be updated in the handler thread and the view - * updated in the UI thread at the end. - */ - public void performUpdate(final IWorkspaceRunnable runnable, boolean preserveExpansion, boolean updateInUIThread) { - if (updateInUIThread) { - queueEvent(new BackgroundEventHandler.RunnableEvent(getUIUpdateRunnable(runnable, preserveExpansion), true), true); - } else { - queueEvent(new BackgroundEventHandler.RunnableEvent(getBackgroundUpdateRunnable(runnable, preserveExpansion), true), true); - } - } - - /** - * Wrap the runnable in an outer runnable that preserves expansion. - */ - private IWorkspaceRunnable getUIUpdateRunnable(final IWorkspaceRunnable runnable, final boolean preserveExpansion) { - return monitor -> { - final CoreException[] exception = new CoreException[] { null }; - runViewUpdate(() -> { - try { - runnable.run(monitor); - } catch (CoreException e) { - exception[0] = e; - } + } + + /** + * Execute a runnable which performs an update of the model being displayed + * by the handler's provider. The runnable should be executed in a thread-safe manner + * which esults in the view being updated. + * @param runnable the runnable which updates the model. + * @param preserveExpansion whether the expansion of the view should be preserver + * @param updateInUIThread if <code>true</code>, the model will be updated in the + * UI thread. Otherwise, the model will be updated in the handler thread and the view + * updated in the UI thread at the end. + */ + public void performUpdate(final IWorkspaceRunnable runnable, boolean preserveExpansion, boolean updateInUIThread) { + if (updateInUIThread) { + queueEvent(new BackgroundEventHandler.RunnableEvent(getUIUpdateRunnable(runnable, preserveExpansion), true), true); + } else { + queueEvent(new BackgroundEventHandler.RunnableEvent(getBackgroundUpdateRunnable(runnable, preserveExpansion), true), true); + } + } + + /** + * Wrap the runnable in an outer runnable that preserves expansion. + */ + private IWorkspaceRunnable getUIUpdateRunnable(final IWorkspaceRunnable runnable, final boolean preserveExpansion) { + return monitor -> { + final CoreException[] exception = new CoreException[] { null }; + runViewUpdate(() -> { + try { + runnable.run(monitor); + } catch (CoreException e) { + exception[0] = e; + } }, true /* preserve expansion */); - if (exception[0] != null) - throw exception[0]; + if (exception[0] != null) + throw exception[0]; }; - } - - /* - * Wrap the runnable in an outer runnable that preserves expansion if requested - * and refreshes the view when the update is completed. - */ - private IWorkspaceRunnable getBackgroundUpdateRunnable(final IWorkspaceRunnable runnable, final boolean preserveExpansion) { - return new IWorkspaceRunnable() { - IResource[] expanded; - IResource[] selected; - @Override + } + + /* + * Wrap the runnable in an outer runnable that preserves expansion if requested + * and refreshes the view when the update is completed. + */ + private IWorkspaceRunnable getBackgroundUpdateRunnable(final IWorkspaceRunnable runnable, final boolean preserveExpansion) { + return new IWorkspaceRunnable() { + IResource[] expanded; + IResource[] selected; + @Override public void run(IProgressMonitor monitor) throws CoreException { - if (preserveExpansion) - recordExpandedResources(); - try { - performingBackgroundUpdate = true; - runnable.run(monitor); - } finally { - performingBackgroundUpdate = false; - } - updateView(); - - } - private void recordExpandedResources() { - final StructuredViewer viewer = getViewer(); - if (viewer != null && !viewer.getControl().isDisposed() && viewer instanceof AbstractTreeViewer) { - viewer.getControl().getDisplay().syncExec(() -> { + if (preserveExpansion) + recordExpandedResources(); + try { + performingBackgroundUpdate = true; + runnable.run(monitor); + } finally { + performingBackgroundUpdate = false; + } + updateView(); + + } + private void recordExpandedResources() { + final StructuredViewer viewer = getViewer(); + if (viewer != null && !viewer.getControl().isDisposed() && viewer instanceof AbstractTreeViewer) { + viewer.getControl().getDisplay().syncExec(() -> { if (viewer != null && !viewer.getControl().isDisposed()) { - expanded = provider.getExpandedResources(); - selected = provider.getSelectedResources(); + expanded = provider.getExpandedResources(); + selected = provider.getSelectedResources(); } }); - } - } - private void updateView() { - // Refresh the view and then set the expansion - runViewUpdate(() -> { - provider.getViewer().refresh(); - if (expanded != null) - provider.expandResources(expanded); - if (selected != null) - provider.selectResources(selected); + } + } + private void updateView() { + // Refresh the view and then set the expansion + runViewUpdate(() -> { + provider.getViewer().refresh(); + if (expanded != null) + provider.expandResources(expanded); + if (selected != null) + provider.selectResources(selected); }, false /* do not preserve expansion (since it is done above) */); - } - }; - } + } + }; + } /* * Execute the RunnableEvent @@ -689,29 +689,29 @@ public class SynchronizeModelUpdateHandler extends BackgroundEventHandler implem } } - /** - * Add the element to the viewer. - * @param parent the parent of the element which is already added to the viewer - * @param element the element to be added to the viewer - */ - protected void doAdd(ISynchronizeModelElement parent, ISynchronizeModelElement element) { - if (additionsMap == null) { - if (Policy.DEBUG_SYNC_MODELS) { - System.out.println("Added view item " + element.getName()); //$NON-NLS-1$ - } - AbstractTreeViewer viewer = (AbstractTreeViewer)getViewer(); - viewer.add(parent, element); - } else { - // Accumulate the additions - if (Policy.DEBUG_SYNC_MODELS) { - System.out.println("Queueing view item for addition " + element.getName()); //$NON-NLS-1$ - } - Set<ISynchronizeModelElement> toAdd = additionsMap.get(parent); - if (toAdd == null) { - toAdd = new HashSet<>(); - additionsMap.put(parent, toAdd); - } - toAdd.add(element); - } - } + /** + * Add the element to the viewer. + * @param parent the parent of the element which is already added to the viewer + * @param element the element to be added to the viewer + */ + protected void doAdd(ISynchronizeModelElement parent, ISynchronizeModelElement element) { + if (additionsMap == null) { + if (Policy.DEBUG_SYNC_MODELS) { + System.out.println("Added view item " + element.getName()); //$NON-NLS-1$ + } + AbstractTreeViewer viewer = (AbstractTreeViewer)getViewer(); + viewer.add(parent, element); + } else { + // Accumulate the additions + if (Policy.DEBUG_SYNC_MODELS) { + System.out.println("Queueing view item for addition " + element.getName()); //$NON-NLS-1$ + } + Set<ISynchronizeModelElement> toAdd = additionsMap.get(parent); + if (toAdd == null) { + toAdd = new HashSet<>(); + additionsMap.put(parent, toAdd); + } + toAdd.add(element); + } + } } |