1 /******************************************************************************* 2 * Copyright (c) 2006, 2017 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 *******************************************************************************/ 14 package org.eclipse.team.internal.ui.mapping; 15 16 import java.util.ArrayList; 17 import java.util.Arrays; 18 import java.util.HashSet; 19 import java.util.List; 20 import java.util.Set; 21 22 import org.eclipse.core.resources.mapping.IModelProviderDescriptor; 23 import org.eclipse.core.resources.mapping.ModelProvider; 24 import org.eclipse.core.resources.mapping.ResourceTraversal; 25 import org.eclipse.core.runtime.Adapters; 26 import org.eclipse.core.runtime.CoreException; 27 import org.eclipse.core.runtime.IPath; 28 import org.eclipse.core.runtime.IProgressMonitor; 29 import org.eclipse.core.runtime.IStatus; 30 import org.eclipse.core.runtime.MultiStatus; 31 import org.eclipse.core.runtime.jobs.IJobChangeEvent; 32 import org.eclipse.core.runtime.jobs.Job; 33 import org.eclipse.core.runtime.jobs.JobChangeAdapter; 34 import org.eclipse.jface.dialogs.ErrorDialog; 35 import org.eclipse.jface.preference.PreferenceStore; 36 import org.eclipse.jface.util.IPropertyChangeListener; 37 import org.eclipse.jface.util.PropertyChangeEvent; 38 import org.eclipse.jface.viewers.TreeViewer; 39 import org.eclipse.jface.viewers.Viewer; 40 import org.eclipse.osgi.util.NLS; 41 import org.eclipse.swt.SWT; 42 import org.eclipse.swt.events.SelectionEvent; 43 import org.eclipse.swt.events.SelectionListener; 44 import org.eclipse.swt.layout.GridData; 45 import org.eclipse.swt.layout.GridLayout; 46 import org.eclipse.swt.widgets.Button; 47 import org.eclipse.swt.widgets.Composite; 48 import org.eclipse.swt.widgets.Label; 49 import org.eclipse.team.core.diff.FastDiffFilter; 50 import org.eclipse.team.core.diff.IDiffChangeEvent; 51 import org.eclipse.team.core.diff.IDiffChangeListener; 52 import org.eclipse.team.core.diff.IDiffTree; 53 import org.eclipse.team.core.diff.IThreeWayDiff; 54 import org.eclipse.team.core.mapping.ISynchronizationContext; 55 import org.eclipse.team.core.mapping.ISynchronizationScope; 56 import org.eclipse.team.internal.core.subscribers.SubscriberDiffTreeEventHandler; 57 import org.eclipse.team.internal.ui.TeamUIMessages; 58 import org.eclipse.team.internal.ui.TeamUIPlugin; 59 import org.eclipse.team.internal.ui.Utils; 60 import org.eclipse.team.internal.ui.synchronize.AbstractSynchronizePage; 61 import org.eclipse.team.internal.ui.synchronize.ForwardingChangesSection; 62 import org.eclipse.team.internal.ui.synchronize.StartupPreferencePage; 63 import org.eclipse.team.internal.ui.synchronize.SynchronizePageConfiguration; 64 import org.eclipse.team.internal.ui.synchronize.SynchronizeView; 65 import org.eclipse.team.ui.ISharedImages; 66 import org.eclipse.team.ui.TeamUI; 67 import org.eclipse.team.ui.mapping.ISynchronizationCompareAdapter; 68 import org.eclipse.team.ui.mapping.ITeamContentProviderDescriptor; 69 import org.eclipse.team.ui.mapping.ITeamContentProviderManager; 70 import org.eclipse.team.ui.synchronize.ISynchronizePageConfiguration; 71 import org.eclipse.team.ui.synchronize.ModelOperation; 72 import org.eclipse.team.ui.synchronize.ModelSynchronizeParticipant; 73 import org.eclipse.ui.forms.events.HyperlinkAdapter; 74 import org.eclipse.ui.forms.events.HyperlinkEvent; 75 import org.eclipse.ui.forms.widgets.Hyperlink; 76 77 public class DiffTreeChangesSection extends ForwardingChangesSection implements IDiffChangeListener, IPropertyChangeListener, IEmptyTreeListener { 78 79 private ISynchronizationContext context; 80 private IStatus[] errors; 81 private boolean showingError; 82 private JobChangeAdapter jobChangeListener; 83 84 public interface ITraversalFactory { getTraversals(ISynchronizationScope scope)85 ResourceTraversal[] getTraversals(ISynchronizationScope scope); 86 } 87 DiffTreeChangesSection(Composite parent, AbstractSynchronizePage page, ISynchronizePageConfiguration configuration)88 public DiffTreeChangesSection(Composite parent, AbstractSynchronizePage page, ISynchronizePageConfiguration configuration) { 89 super(parent, page, configuration); 90 context = (ISynchronizationContext)configuration.getProperty(ITeamContentProviderManager.P_SYNCHRONIZATION_CONTEXT); 91 context.getDiffTree().addDiffChangeListener(this); 92 getConfiguration().addPropertyChangeListener(this); 93 jobChangeListener = new JobChangeAdapter() { 94 @Override 95 public void running(IJobChangeEvent event) { 96 if (isJobOfInterest(event.getJob())) { 97 if (context.getDiffTree().isEmpty()) 98 calculateDescription(); 99 } 100 } 101 private boolean isJobOfInterest(Job job) { 102 if (job.belongsTo(getConfiguration().getParticipant())) 103 return true; 104 SubscriberDiffTreeEventHandler handler = getHandler(); 105 if (handler != null && handler.getEventHandlerJob() == job) 106 return true; 107 return false; 108 } 109 @Override 110 public void done(IJobChangeEvent event) { 111 if (isJobOfInterest(event.getJob())) { 112 if (context.getDiffTree().isEmpty()) 113 calculateDescription(); 114 } 115 } 116 }; 117 Job.getJobManager().addJobChangeListener(jobChangeListener); 118 } 119 120 @Override dispose()121 public void dispose() { 122 context.getDiffTree().removeDiffChangeListener(this); 123 getConfiguration().removePropertyChangeListener(this); 124 Job.getJobManager().removeJobChangeListener(jobChangeListener); 125 super.dispose(); 126 } 127 128 @Override getChangesCount()129 protected int getChangesCount() { 130 return context.getDiffTree().size(); 131 } 132 133 @Override getChangesInMode(int candidateMode)134 protected long getChangesInMode(int candidateMode) { 135 long numChanges; 136 long numConflicts = context.getDiffTree().countFor(IThreeWayDiff.CONFLICTING, IThreeWayDiff.DIRECTION_MASK); 137 switch (candidateMode) { 138 case ISynchronizePageConfiguration.CONFLICTING_MODE: 139 numChanges = numConflicts; 140 break; 141 case ISynchronizePageConfiguration.OUTGOING_MODE: 142 numChanges = numConflicts + context.getDiffTree().countFor(IThreeWayDiff.OUTGOING, IThreeWayDiff.DIRECTION_MASK); 143 break; 144 case ISynchronizePageConfiguration.INCOMING_MODE: 145 numChanges = numConflicts + context.getDiffTree().countFor(IThreeWayDiff.INCOMING, IThreeWayDiff.DIRECTION_MASK); 146 break; 147 case ISynchronizePageConfiguration.BOTH_MODE: 148 numChanges = numConflicts + context.getDiffTree().countFor(IThreeWayDiff.INCOMING, IThreeWayDiff.DIRECTION_MASK) 149 + context.getDiffTree().countFor(IThreeWayDiff.OUTGOING, IThreeWayDiff.DIRECTION_MASK); 150 break; 151 default: 152 numChanges = 0; 153 break; 154 } 155 return numChanges; 156 } 157 hasChangesInMode(String id, ISynchronizationCompareAdapter adapter, int candidateMode)158 protected boolean hasChangesInMode(String id, ISynchronizationCompareAdapter adapter, int candidateMode) { 159 switch (candidateMode) { 160 case ISynchronizePageConfiguration.CONFLICTING_MODE: 161 return hasChangesFor(id, adapter, context, new int[] { IThreeWayDiff.CONFLICTING }, IThreeWayDiff.DIRECTION_MASK); 162 case ISynchronizePageConfiguration.OUTGOING_MODE: 163 return hasChangesFor(id, adapter, context, new int[] { IThreeWayDiff.CONFLICTING, IThreeWayDiff.OUTGOING }, IThreeWayDiff.DIRECTION_MASK); 164 case ISynchronizePageConfiguration.INCOMING_MODE: 165 return hasChangesFor(id, adapter, context, new int[] { IThreeWayDiff.CONFLICTING, IThreeWayDiff.INCOMING }, IThreeWayDiff.DIRECTION_MASK); 166 case ISynchronizePageConfiguration.BOTH_MODE: 167 return hasChangesFor(id, adapter, context, new int[] { IThreeWayDiff.CONFLICTING, IThreeWayDiff.INCOMING, IThreeWayDiff.OUTGOING }, IThreeWayDiff.DIRECTION_MASK); 168 } 169 return false; 170 } 171 hasChangesFor(String id, ISynchronizationCompareAdapter adapter, ISynchronizationContext context, int[] states, int mask)172 private boolean hasChangesFor(String id, ISynchronizationCompareAdapter adapter, ISynchronizationContext context, int[] states, int mask) { 173 ITraversalFactory factory = Adapters.adapt(adapter, ITraversalFactory.class); 174 ResourceTraversal[] traversals; 175 if (factory == null) { 176 traversals = context.getScope().getTraversals(id); 177 } else { 178 traversals = factory.getTraversals(context.getScope()); 179 } 180 return (context.getDiffTree().hasMatchingDiffs(traversals, FastDiffFilter.getStateFilter(states, mask))); 181 } 182 183 @Override getVisibleChangesCount()184 protected long getVisibleChangesCount() { 185 ISynchronizePageConfiguration configuration = getConfiguration(); 186 if (configuration.getComparisonType() == ISynchronizePageConfiguration.TWO_WAY) { 187 return context.getDiffTree().size(); 188 } 189 int currentMode = configuration.getMode(); 190 String id = (String)configuration.getProperty(ModelSynchronizeParticipant.P_VISIBLE_MODEL_PROVIDER); 191 if (id != null && !id.equals(ModelSynchronizeParticipant.ALL_MODEL_PROVIDERS_VISIBLE)) { 192 try { 193 IModelProviderDescriptor desc = ModelProvider.getModelProviderDescriptor(id); 194 ISynchronizationCompareAdapter adapter = Utils.getCompareAdapter(desc.getModelProvider()); 195 if (adapter != null) { 196 return hasChangesInMode(desc.getId(), adapter, getConfiguration().getMode()) ? -1 : 0; 197 } 198 } catch (CoreException e) { 199 TeamUIPlugin.log(e); 200 } 201 // Use the view state to indicate whether there are visible changes 202 return isViewerEmpty() ? 0 : -1; 203 } 204 return getChangesInMode(currentMode); 205 } 206 207 @Override getCandidateMode()208 protected int getCandidateMode() { 209 SynchronizePageConfiguration configuration = (SynchronizePageConfiguration)getConfiguration(); 210 long outgoingChanges = context.getDiffTree().countFor(IThreeWayDiff.OUTGOING, IThreeWayDiff.DIRECTION_MASK); 211 if (outgoingChanges > 0) { 212 if (configuration.isModeSupported(ISynchronizePageConfiguration.OUTGOING_MODE)) { 213 return ISynchronizePageConfiguration.OUTGOING_MODE; 214 } 215 if (configuration.isModeSupported(ISynchronizePageConfiguration.BOTH_MODE)) { 216 return ISynchronizePageConfiguration.BOTH_MODE; 217 } 218 } 219 long incomingChanges = context.getDiffTree().countFor(IThreeWayDiff.INCOMING, IThreeWayDiff.DIRECTION_MASK); 220 if (incomingChanges > 0) { 221 if (configuration.isModeSupported(ISynchronizePageConfiguration.INCOMING_MODE)) { 222 return ISynchronizePageConfiguration.INCOMING_MODE; 223 } 224 if (configuration.isModeSupported(ISynchronizePageConfiguration.BOTH_MODE)) { 225 return ISynchronizePageConfiguration.BOTH_MODE; 226 } 227 } 228 return configuration.getMode(); 229 } 230 231 @Override diffsChanged(IDiffChangeEvent event, IProgressMonitor monitor)232 public void diffsChanged(IDiffChangeEvent event, IProgressMonitor monitor) { 233 IStatus[] errors = event.getErrors(); 234 if (errors.length > 0) { 235 this.errors = errors; 236 } 237 calculateDescription(); 238 } 239 240 @Override propertyChanged(IDiffTree tree, int property, IPath[] paths)241 public void propertyChanged(IDiffTree tree, int property, IPath[] paths) { 242 // Do nothing 243 } 244 245 @Override propertyChange(PropertyChangeEvent event)246 public void propertyChange(PropertyChangeEvent event) { 247 if (event.getProperty().equals(ISynchronizePageConfiguration.P_MODE) 248 || event.getProperty().equals(ModelSynchronizeParticipant.P_VISIBLE_MODEL_PROVIDER)) { 249 calculateDescription(); 250 } 251 } 252 253 @Override getEmptyChangesComposite(Composite parent)254 protected Composite getEmptyChangesComposite(Composite parent) { 255 if (context.getDiffTree().isEmpty()) { 256 SubscriberDiffTreeEventHandler handler = getHandler(); 257 if (handler != null && handler.getState() == SubscriberDiffTreeEventHandler.STATE_STARTED) { 258 // The context has not been initialized yet 259 return getInitializationPane(parent); 260 } 261 if (isRefreshRunning() || (handler != null && handler.getEventHandlerJob().getState() != Job.NONE)) { 262 return getInitializingMessagePane(parent); 263 } 264 } else { 265 ISynchronizePageConfiguration configuration = getConfiguration(); 266 String id = (String)configuration.getProperty(ModelSynchronizeParticipant.P_VISIBLE_MODEL_PROVIDER); 267 if (id == null) 268 id = ModelSynchronizeParticipant.P_VISIBLE_MODEL_PROVIDER; 269 if (id.equals(ModelSynchronizeParticipant.ALL_MODEL_PROVIDERS_VISIBLE)) { 270 if (getChangesInMode(getConfiguration().getMode()) > 0 && isAtLeastOneProviderDisabled()) { 271 // There are changes in this mode but they are not visible so enable 272 // all providers 273 return createEnableParticipantModelProvidersPane(parent); 274 } 275 } else { 276 // A particular model is active so we need to look for a model that has changes in this 277 // same mode before offering to change modes. 278 ModelProvider[] providers =findModelsWithChangesInMode(getConfiguration().getMode()); 279 ModelProvider currentProvider = null; 280 for (ModelProvider provider : providers) { 281 if (isEnabled(provider)) { 282 if (provider.getDescriptor().getId().equals(id)) { 283 currentProvider = provider; 284 } else { 285 return getPointerToModel(parent, provider, id); 286 } 287 } 288 } 289 if (currentProvider != null || providers.length > 0) { 290 // The current provider has changes but the view is empty 291 // or there is a disabled provider with changes 292 // This is an error so offer to enable and show all models 293 return createEnableParticipantModelProvidersPane(parent); 294 } 295 } 296 } 297 return super.getEmptyChangesComposite(parent); 298 } 299 isAtLeastOneProviderDisabled()300 private boolean isAtLeastOneProviderDisabled() { 301 ModelProvider[] providers =findModelsWithChangesInMode(getConfiguration().getMode()); 302 for (ModelProvider provider : providers) { 303 if (!isEnabled(provider)) { 304 return true; 305 } 306 } 307 return false; 308 } 309 findModelsWithChangesInMode(int mode)310 private ModelProvider[] findModelsWithChangesInMode(int mode) { 311 ModelProvider[] providers =context.getScope().getModelProviders(); 312 providers = ModelOperation.sortByExtension(providers); 313 List<ModelProvider> result = new ArrayList<>(); 314 for (ModelProvider provider : providers) { 315 ISynchronizationCompareAdapter adapter = Utils.getCompareAdapter(provider); 316 if (adapter != null) { 317 boolean hasChanges = hasChangesInMode(provider.getId(), adapter, getConfiguration().getMode()); 318 if (hasChanges) { 319 result.add(provider); 320 } 321 } 322 } 323 return result.toArray(new ModelProvider[result.size()]); 324 } 325 isEnabled(ModelProvider provider)326 private boolean isEnabled(ModelProvider provider) { 327 ITeamContentProviderDescriptor desc = TeamUI.getTeamContentProviderManager().getDescriptor(provider.getId()); 328 return (desc != null && desc.isEnabled()); 329 } 330 createEnableParticipantModelProvidersPane(Composite parent)331 private Composite createEnableParticipantModelProvidersPane(Composite parent) { 332 Composite composite = new Composite(parent, SWT.NONE); 333 composite.setBackground(getListBackgroundColor()); 334 GridLayout layout = new GridLayout(); 335 layout.numColumns = 2; 336 composite.setLayout(layout); 337 GridData data = new GridData(GridData.FILL_BOTH); 338 data.grabExcessVerticalSpace = true; 339 composite.setLayoutData(data); 340 341 String message; 342 int changesCount = getChangesCount(); 343 if (changesCount == 1) { 344 message = TeamUIMessages.DiffTreeChangesSection_8; 345 } else { 346 message = NLS.bind(TeamUIMessages.DiffTreeChangesSection_9, Integer.valueOf(changesCount)); 347 } 348 final ITeamContentProviderDescriptor[] descriptors = getEnabledContentDescriptors(); 349 if (descriptors.length == 0) 350 message = NLS.bind(TeamUIMessages.DiffTreeChangesSection_10, message); 351 else 352 message = NLS.bind(TeamUIMessages.DiffTreeChangesSection_11, message); 353 354 createDescriptionLabel(composite, message); 355 356 Label warning = new Label(composite, SWT.NONE); 357 warning.setImage(TeamUIPlugin.getPlugin().getImage(ISharedImages.IMG_WARNING_OVR)); 358 359 Hyperlink link = getForms().createHyperlink(composite, TeamUIMessages.DiffTreeChangesSection_12, SWT.WRAP); 360 link.addHyperlinkListener(new HyperlinkAdapter() { 361 @Override 362 public void linkActivated(HyperlinkEvent e) { 363 ModelSynchronizeParticipant participant = (ModelSynchronizeParticipant)getConfiguration().getParticipant(); 364 ModelProvider[] providers = participant.getEnabledModelProviders(); 365 Set<ITeamContentProviderDescriptor> toEnable = new HashSet<>(); 366 toEnable.addAll(Arrays.asList(descriptors)); 367 for (ModelProvider provider : providers) { 368 ITeamContentProviderDescriptor desc = TeamUI.getTeamContentProviderManager().getDescriptor(provider.getId()); 369 if (desc != null && !desc.isEnabled()) { 370 toEnable.add(desc); 371 } 372 } 373 TeamUI.getTeamContentProviderManager() 374 .setEnabledDescriptors(toEnable.toArray(new ITeamContentProviderDescriptor[toEnable.size()])); 375 getConfiguration().setProperty(ModelSynchronizeParticipant.P_VISIBLE_MODEL_PROVIDER, ModelSynchronizeParticipant.ALL_MODEL_PROVIDERS_VISIBLE ); 376 377 } 378 }); 379 getForms().getHyperlinkGroup().add(link); 380 381 return composite; 382 } 383 getEnabledContentDescriptors()384 private ITeamContentProviderDescriptor[] getEnabledContentDescriptors() { 385 ModelSynchronizeParticipant participant = (ModelSynchronizeParticipant)getConfiguration().getParticipant(); 386 ModelProvider[] providers = participant.getEnabledModelProviders(); 387 Set<ITeamContentProviderDescriptor> result = new HashSet<>(); 388 for (ModelProvider provider : providers) { 389 ITeamContentProviderDescriptor desc = TeamUI.getTeamContentProviderManager().getDescriptor(provider.getId()); 390 if (desc != null && desc.isEnabled()) 391 result.add(desc); 392 } 393 return result.toArray(new ITeamContentProviderDescriptor[result.size()]); 394 } 395 getInitializationPane(Composite parent)396 private Composite getInitializationPane(Composite parent) { 397 Composite composite = new Composite(parent, SWT.NONE); 398 composite.setBackground(getListBackgroundColor()); 399 GridLayout layout = new GridLayout(); 400 layout.numColumns = 2; 401 composite.setLayout(layout); 402 GridData data = new GridData(GridData.FILL_BOTH); 403 data.grabExcessVerticalSpace = true; 404 composite.setLayoutData(data); 405 406 createDescriptionLabel(composite, NLS.bind(TeamUIMessages.DiffTreeChangesSection_3, new String[] { Utils.shortenText(SynchronizeView.MAX_NAME_LENGTH, getConfiguration().getParticipant().getName()) })); 407 408 final boolean[] remember = new boolean[] { false }; 409 final PreferenceStore store = (PreferenceStore) getConfiguration() 410 .getProperty(StartupPreferencePage.STARTUP_PREFERENCES); 411 Hyperlink link = getForms().createHyperlink(composite, TeamUIMessages.DiffTreeChangesSection_4, SWT.WRAP); 412 link.addHyperlinkListener(new HyperlinkAdapter() { 413 @Override 414 public void linkActivated(HyperlinkEvent e) { 415 if (remember[0] && store != null) { 416 store.putValue(StartupPreferencePage.PROP_STARTUP_ACTION, StartupPreferencePage.STARTUP_ACTION_POPULATE); 417 } 418 getHandler().initializeIfNeeded(); 419 } 420 }); 421 getForms().getHyperlinkGroup().add(link); 422 423 link = getForms().createHyperlink(composite, TeamUIMessages.DiffTreeChangesSection_5, SWT.WRAP); 424 link.addHyperlinkListener(new HyperlinkAdapter() { 425 @Override 426 public void linkActivated(HyperlinkEvent e) { 427 if (remember[0] && store != null) { 428 store.putValue(StartupPreferencePage.PROP_STARTUP_ACTION, StartupPreferencePage.STARTUP_ACTION_SYNCHRONIZE); 429 } 430 getConfiguration().getParticipant().run(getConfiguration().getSite().getPart()); 431 } 432 }); 433 getForms().getHyperlinkGroup().add(link); 434 435 if (store != null) { 436 final Button rememberButton = getForms().createButton(composite, TeamUIMessages.DiffTreeChangesSection_14, SWT.CHECK); 437 rememberButton.setToolTipText(TeamUIMessages.DiffTreeChangesSection_14); 438 data = new GridData(GridData.FILL_HORIZONTAL); 439 data.horizontalSpan = 2; 440 data.horizontalIndent=5; 441 data.verticalIndent=5; 442 data.widthHint = 100; 443 rememberButton.setLayoutData(data); 444 rememberButton.addSelectionListener(new SelectionListener() { 445 @Override 446 public void widgetSelected(SelectionEvent e) { 447 remember[0] = rememberButton.getSelection(); 448 } 449 @Override 450 public void widgetDefaultSelected(SelectionEvent e) { 451 // Do nothing 452 } 453 }); 454 } 455 456 return composite; 457 } 458 getInitializingMessagePane(Composite parent)459 private Composite getInitializingMessagePane(Composite parent) { 460 Composite composite = new Composite(parent, SWT.NONE); 461 composite.setBackground(getListBackgroundColor()); 462 GridLayout layout = new GridLayout(); 463 layout.numColumns = 2; 464 composite.setLayout(layout); 465 GridData data = new GridData(GridData.FILL_BOTH); 466 data.grabExcessVerticalSpace = true; 467 composite.setLayoutData(data); 468 if (isRefreshRunning()) { 469 createDescriptionLabel(composite,NLS.bind(TeamUIMessages.DiffTreeChangesSection_6, new String[] { Utils.shortenText(SynchronizeView.MAX_NAME_LENGTH, getConfiguration().getParticipant().getName()) })); 470 } else { 471 createDescriptionLabel(composite,NLS.bind(TeamUIMessages.DiffTreeChangesSection_7, new String[] { Utils.shortenText(SynchronizeView.MAX_NAME_LENGTH, getConfiguration().getParticipant().getName()) })); 472 } 473 return composite; 474 } 475 isRefreshRunning()476 private boolean isRefreshRunning() { 477 return Job.getJobManager().find(getConfiguration().getParticipant()).length > 0; 478 } 479 getHandler()480 private SubscriberDiffTreeEventHandler getHandler() { 481 return Adapters.adapt(context, SubscriberDiffTreeEventHandler.class); 482 } 483 getPointerToModel(Composite parent, final ModelProvider provider, String oldId)484 private Composite getPointerToModel(Composite parent, final ModelProvider provider, String oldId) { 485 Composite composite = new Composite(parent, SWT.NONE); 486 composite.setBackground(getListBackgroundColor()); 487 GridLayout layout = new GridLayout(); 488 layout.numColumns = 2; 489 composite.setLayout(layout); 490 GridData data = new GridData(GridData.FILL_BOTH); 491 data.grabExcessVerticalSpace = true; 492 composite.setLayoutData(data); 493 494 IModelProviderDescriptor oldDesc = ModelProvider.getModelProviderDescriptor(oldId); 495 String message; 496 String modeToString = Utils.modeToString(getConfiguration().getMode()); 497 message = NLS.bind(TeamUIMessages.DiffTreeChangesSection_0, new String[] { 498 provider.getDescriptor().getLabel(), 499 modeToString }); 500 message = NLS.bind(TeamUIMessages.DiffTreeChangesSection_1, new String[] { modeToString, oldDesc.getLabel(), message }); 501 502 createDescriptionLabel(composite, message); 503 504 Label warning = new Label(composite, SWT.NONE); 505 warning.setImage(TeamUIPlugin.getPlugin().getImage(ISharedImages.IMG_WARNING_OVR)); 506 507 Hyperlink link = getForms().createHyperlink(composite, NLS.bind(TeamUIMessages.DiffTreeChangesSection_2, new String[] { provider.getDescriptor().getLabel() }), SWT.WRAP); 508 link.addHyperlinkListener(new HyperlinkAdapter() { 509 @Override 510 public void linkActivated(HyperlinkEvent e) { 511 getConfiguration().setProperty(ModelSynchronizeParticipant.P_VISIBLE_MODEL_PROVIDER, provider.getDescriptor().getId() ); 512 } 513 }); 514 getForms().getHyperlinkGroup().add(link); 515 516 new Label(composite, SWT.NONE); 517 Hyperlink link2 = getForms().createHyperlink(composite, TeamUIMessages.DiffTreeChangesSection_13, SWT.WRAP); 518 link2.addHyperlinkListener(new HyperlinkAdapter() { 519 @Override 520 public void linkActivated(HyperlinkEvent e) { 521 getConfiguration().setProperty(ModelSynchronizeParticipant.P_VISIBLE_MODEL_PROVIDER, ModelSynchronizeParticipant.ALL_MODEL_PROVIDERS_VISIBLE ); 522 } 523 }); 524 getForms().getHyperlinkGroup().add(link2); 525 526 return composite; 527 } 528 529 @Override treeEmpty(TreeViewer viewer)530 public void treeEmpty(TreeViewer viewer) { 531 handleEmptyViewer(); 532 } 533 handleEmptyViewer()534 private void handleEmptyViewer() { 535 // Override stand behavior to do our best to show something 536 TeamUIPlugin.getStandardDisplay().asyncExec(() -> { 537 if (!getContainer().isDisposed()) 538 updatePage(getEmptyChangesComposite(getContainer())); 539 }); 540 } 541 542 @Override calculateDescription()543 protected void calculateDescription() { 544 if (errors != null && errors.length > 0) { 545 if (!showingError) { 546 TeamUIPlugin.getStandardDisplay().asyncExec(() -> { 547 updatePage(getErrorComposite(getContainer())); 548 showingError = true; 549 }); 550 } 551 return; 552 } 553 showingError = false; 554 if (isViewerEmpty()) { 555 handleEmptyViewer(); 556 } else { 557 super.calculateDescription(); 558 } 559 } 560 isViewerEmpty()561 private boolean isViewerEmpty() { 562 Viewer v = getPage().getViewer(); 563 if (v instanceof CommonViewerAdvisor.NavigableCommonViewer) { 564 CommonViewerAdvisor.NavigableCommonViewer cv = (CommonViewerAdvisor.NavigableCommonViewer) v; 565 return cv.isEmpty(); 566 } 567 return false; 568 } 569 570 @Override notEmpty(TreeViewer viewer)571 public void notEmpty(TreeViewer viewer) { 572 calculateDescription(); 573 } 574 getErrorComposite(Composite parent)575 private Composite getErrorComposite(Composite parent) { 576 Composite composite = new Composite(parent, SWT.NONE); 577 composite.setBackground(getListBackgroundColor()); 578 GridLayout layout = new GridLayout(); 579 layout.numColumns = 2; 580 composite.setLayout(layout); 581 GridData data = new GridData(GridData.FILL_BOTH); 582 data.grabExcessVerticalSpace = true; 583 composite.setLayoutData(data); 584 585 createDescriptionLabel(composite, NLS.bind(TeamUIMessages.ChangesSection_10, new String[] { Utils.shortenText(SynchronizeView.MAX_NAME_LENGTH, getConfiguration().getParticipant().getName()) })); 586 587 Hyperlink link = getForms().createHyperlink(composite, TeamUIMessages.ChangesSection_8, SWT.WRAP); 588 link.addHyperlinkListener(new HyperlinkAdapter() { 589 @Override 590 public void linkActivated(HyperlinkEvent e) { 591 showErrors(); 592 } 593 }); 594 getForms().getHyperlinkGroup().add(link); 595 596 link = getForms().createHyperlink(composite, TeamUIMessages.ChangesSection_9, SWT.WRAP); 597 link.addHyperlinkListener(new HyperlinkAdapter() { 598 @Override 599 public void linkActivated(HyperlinkEvent e) { 600 errors = null; 601 calculateDescription(); 602 SubscriberDiffTreeEventHandler handler = getHandler(); 603 if (handler != null) 604 handler.initializeIfNeeded(); 605 else 606 getConfiguration().getParticipant().run(getConfiguration().getSite().getPart()); 607 } 608 }); 609 getForms().getHyperlinkGroup().add(link); 610 611 return composite; 612 } 613 showErrors()614 /* private */ void showErrors() { 615 if (errors != null) { 616 IStatus[] status = errors; 617 String title = TeamUIMessages.ChangesSection_11; 618 if (status.length == 1) { 619 ErrorDialog.openError(getShell(), title, status[0].getMessage(), status[0]); 620 } else { 621 MultiStatus multi = new MultiStatus(TeamUIPlugin.ID, 0, status, TeamUIMessages.ChangesSection_12, null); 622 ErrorDialog.openError(getShell(), title, null, multi); 623 } 624 } 625 } 626 } 627