diff options
author | Jean Michel-Lemieux | 2004-03-09 20:51:17 +0000 |
---|---|---|
committer | Jean Michel-Lemieux | 2004-03-09 20:51:17 +0000 |
commit | 70d8db4a04629905c0aefa376adfc27566b12c73 (patch) | |
tree | 99abba1031918f6e868a7a1ad3e7faed7abce295 /bundles/org.eclipse.team.ui/src/org/eclipse/team/internal | |
parent | b1c14fbe58367c34bf6eef789f77edca3623f574 (diff) | |
download | eclipse.platform.team-70d8db4a04629905c0aefa376adfc27566b12c73.tar.gz eclipse.platform.team-70d8db4a04629905c0aefa376adfc27566b12c73.tar.xz eclipse.platform.team-70d8db4a04629905c0aefa376adfc27566b12c73.zip |
Added several things:
- a global action to refresh
- a compare dialog framework that will allow you to show compare input in a dialog and support saving
Diffstat (limited to 'bundles/org.eclipse.team.ui/src/org/eclipse/team/internal')
37 files changed, 2099 insertions, 437 deletions
diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/IPreferenceIds.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/IPreferenceIds.java index 38c613284..3bd284dc8 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/IPreferenceIds.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/IPreferenceIds.java @@ -28,5 +28,11 @@ public interface IPreferenceIds { public static final String SYNCVIEW_VIEW_BKG_PROMPT_WHEN_NO_CHANGES = PREFIX + "syncview__bkg_promptwhennochanges"; //$NON-NLS-1$ public static final String SYNCVIEW_VIEW_BKG_PROMPT_WITH_CHANGES = PREFIX + "syncview_bkg_promptwithchanges"; //$NON-NLS-1$ - public static final String SYNCVIEW_VIEW_SMART_MODE_SWITCH = PREFIX + "syncview_smartmode"; //$NON-NLS-1$ -} + public static final String SYNCHRONIZING_DEFAULT_PARTICIPANT = PREFIX + "sychronizing_default_participant"; //$NON-NLS-1$ + public static final String SYNCHRONIZING_COMPLETE_SHOW_DIALOG = PREFIX + "sychronizing_dontshow_complete_dialog"; //$NON-NLS-1$ + + public static final String SYNCHRONIZING_COMPLETE_PERSPECTIVE = PREFIX + "sychronizing_default_perspective_to_show"; //$NON-NLS-1$ + public static final String SYNCHRONIZING_COMPLETE_PERSPECTIVE_PROMPT = PREFIX + "sychronizing_default_perspective_to_show_prompt"; //$NON-NLS-1$ + public static final String SYNCHRONIZING_COMPLETE_PERSPECTIVE_ALWAYS = PREFIX + "sychronizing_default_perspective_to_show_always"; //$NON-NLS-1$ + public static final String SYNCHRONIZING_COMPLETE_PERSPECTIVE_NEVER = PREFIX + "sychronizing_default_perspective_to_show_never"; //$NON-NLS-1$ +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/OverlayIcon.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/OverlayIcon.java index 801bd250e..df86de033 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/OverlayIcon.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/OverlayIcon.java @@ -14,9 +14,7 @@ import java.util.Arrays; import org.eclipse.jface.resource.CompositeImageDescriptor; import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.*; /** * An OverlayIcon consists of a main icon and several adornments. diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/Policy.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/Policy.java index 36611f963..700e99613 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/Policy.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/Policy.java @@ -15,11 +15,7 @@ import java.text.MessageFormat; import java.util.MissingResourceException; import java.util.ResourceBundle; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.OperationCanceledException; -import org.eclipse.core.runtime.SubProgressMonitor; +import org.eclipse.core.runtime.*; import org.eclipse.team.internal.core.InfiniteSubProgressMonitor; import org.eclipse.team.internal.core.NullSubProgressMonitor; diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/TeamUIPlugin.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/TeamUIPlugin.java index 5de10c18f..533724f5e 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/TeamUIPlugin.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/TeamUIPlugin.java @@ -28,6 +28,7 @@ import org.eclipse.swt.graphics.Image; import org.eclipse.swt.widgets.Display; import org.eclipse.team.internal.ui.synchronize.SynchronizeManager; import org.eclipse.team.internal.ui.synchronize.TeamSynchronizingPerspective; +import org.eclipse.team.internal.ui.synchronize.actions.GlobalRefreshAction; import org.eclipse.team.ui.ISharedImages; import org.eclipse.team.ui.TeamUI; import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; @@ -145,7 +146,9 @@ public class TeamUIPlugin extends AbstractUIPlugin { store.setDefault(IPreferenceIds.SYNCVIEW_VIEW_PROMPT_WITH_CHANGES, true); store.setDefault(IPreferenceIds.SYNCVIEW_VIEW_BKG_PROMPT_WHEN_NO_CHANGES, false); store.setDefault(IPreferenceIds.SYNCVIEW_VIEW_BKG_PROMPT_WITH_CHANGES, true); - store.setDefault(IPreferenceIds.SYNCVIEW_VIEW_SMART_MODE_SWITCH, false); + store.setDefault(IPreferenceIds.SYNCHRONIZING_DEFAULT_PARTICIPANT, GlobalRefreshAction.NO_DEFAULT_PARTICPANT); + store.setDefault(IPreferenceIds.SYNCHRONIZING_COMPLETE_SHOW_DIALOG, true); + store.setDefault(IPreferenceIds.SYNCHRONIZING_COMPLETE_PERSPECTIVE, IPreferenceIds.SYNCHRONIZING_COMPLETE_PERSPECTIVE_PROMPT); //$NON-NLS-1$ } /** @@ -288,9 +291,9 @@ public class TeamUIPlugin extends AbstractUIPlugin { createImageDescriptor(plugin, ISharedImages.IMG_CONFLICT_OVR, baseURL); createImageDescriptor(plugin, ISharedImages.IMG_CHECKEDIN_OVR, baseURL); createImageDescriptor(plugin, ISharedImages.IMG_CHECKEDOUT_OVR, baseURL); - - + createImageDescriptor(plugin, ISharedImages.IMG_SYNC_VIEW, baseURL); + createImageDescriptor(plugin, ISharedImages.IMG_COMPARE_VIEW, baseURL); // Collapse all createImageDescriptor(plugin, ISharedImages.IMG_COLLAPSE_ALL, baseURL); diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/Utils.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/Utils.java index 3a2a29329..a02f4537b 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/Utils.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/Utils.java @@ -10,46 +10,30 @@ *******************************************************************************/ package org.eclipse.team.internal.ui; +import java.io.*; import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.HashSet; +import java.util.*; import java.util.List; -import java.util.ResourceBundle; -import java.util.Set; import org.eclipse.compare.CompareConfiguration; import org.eclipse.compare.structuremergeviewer.IDiffContainer; import org.eclipse.compare.structuremergeviewer.IDiffElement; import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IAdaptable; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; -import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.action.IAction; -import org.eclipse.jface.dialogs.ErrorDialog; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.jface.dialogs.ProgressMonitorDialog; +import org.eclipse.jface.dialogs.*; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.custom.BusyIndicator; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.*; import org.eclipse.team.core.TeamException; import org.eclipse.team.core.synchronize.SyncInfo; import org.eclipse.team.core.variants.IResourceVariant; import org.eclipse.team.ui.TeamImages; import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; import org.eclipse.team.ui.synchronize.viewers.SynchronizeModelElement; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchPartSite; -import org.eclipse.ui.IWorkbenchSite; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.IWorkingSet; +import org.eclipse.ui.*; import org.eclipse.ui.progress.IWorkbenchSiteProgressService; public class Utils { @@ -470,4 +454,35 @@ public class Utils { } job.schedule(); } + + public static byte[] readBytes(InputStream in) { + ByteArrayOutputStream bos= new ByteArrayOutputStream(); + try { + while (true) { + int c= in.read(); + if (c == -1) + break; + bos.write(c); + } + + } catch (IOException ex) { + return null; + + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException x) { + // silently ignored + } + } + try { + bos.close(); + } catch (IOException x) { + // silently ignored + } + } + + return bos.toByteArray(); + } }
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/JobRunnableContext.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/JobRunnableContext.java index 3eebe1a5b..806a46a8a 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/JobRunnableContext.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/actions/JobRunnableContext.java @@ -13,21 +13,14 @@ package org.eclipse.team.internal.ui.actions; import java.lang.reflect.InvocationTargetException; import org.eclipse.core.resources.WorkspaceJob; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; -import org.eclipse.core.runtime.jobs.IJobChangeListener; -import org.eclipse.core.runtime.jobs.ISchedulingRule; -import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.jobs.*; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; import org.eclipse.team.core.TeamException; import org.eclipse.team.internal.ui.Utils; -import org.eclipse.ui.IWorkbenchSite; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.*; /** * This runnable context executes it's operation in the context of a background job. diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/DialogArea.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/DialogArea.java index 035f8a3cb..1275112a2 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/DialogArea.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/DialogArea.java @@ -10,26 +10,18 @@ *******************************************************************************/ package org.eclipse.team.internal.ui.dialogs; -import java.util.ArrayList; -import java.util.Iterator; +import java.util.*; import java.util.List; +import org.eclipse.jface.dialogs.*; import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.FontMetrics; -import org.eclipse.swt.graphics.GC; +import org.eclipse.swt.graphics.*; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.*; /** * This class provides facilities to allow common widget groupings to be shared diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/PreferencePageContainerDialog.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/PreferencePageContainerDialog.java index acaf2b035..3bc3b6a5d 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/PreferencePageContainerDialog.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/dialogs/PreferencePageContainerDialog.java @@ -16,35 +16,18 @@ import java.util.List; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.preference.IPersistentPreferenceStore; -import org.eclipse.jface.preference.IPreferencePageContainer; -import org.eclipse.jface.preference.IPreferenceStore; -import org.eclipse.jface.preference.PreferenceDialog; -import org.eclipse.jface.preference.PreferencePage; -import org.eclipse.jface.resource.ImageDescriptor; -import org.eclipse.jface.resource.ImageRegistry; -import org.eclipse.jface.resource.JFaceColors; -import org.eclipse.jface.resource.JFaceResources; +import org.eclipse.jface.preference.*; +import org.eclipse.jface.resource.*; import org.eclipse.jface.util.IPropertyChangeListener; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; -import org.eclipse.swt.graphics.Color; -import org.eclipse.swt.graphics.Font; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.graphics.*; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Layout; -import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.*; import org.eclipse.team.internal.ui.TeamUIPlugin; import org.eclipse.team.internal.ui.Utils; diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/RefreshUserNotificationPolicy.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/RefreshUserNotificationPolicy.java index 52191239a..1c7fa1542 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/RefreshUserNotificationPolicy.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/jobs/RefreshUserNotificationPolicy.java @@ -1,37 +1,35 @@ package org.eclipse.team.internal.ui.jobs; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Status; +import java.util.*; + +import org.eclipse.compare.CompareUI; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.runtime.*; import org.eclipse.swt.widgets.Shell; import org.eclipse.team.core.synchronize.SyncInfo; -import org.eclipse.team.internal.ui.IPreferenceIds; -import org.eclipse.team.internal.ui.Policy; -import org.eclipse.team.internal.ui.TeamUIPlugin; -import org.eclipse.team.internal.ui.synchronize.IRefreshEvent; -import org.eclipse.team.internal.ui.synchronize.IRefreshSubscriberListener; +import org.eclipse.team.internal.ui.*; import org.eclipse.team.internal.ui.synchronize.RefreshCompleteDialog; import org.eclipse.team.ui.TeamUI; -import org.eclipse.team.ui.synchronize.ISynchronizeManager; -import org.eclipse.team.ui.synchronize.ISynchronizeParticipant; -import org.eclipse.team.ui.synchronize.ISynchronizeView; -import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; +import org.eclipse.team.ui.synchronize.subscriber.*; +import org.eclipse.team.ui.synchronize.viewers.SyncInfoCompareInput; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.progress.UIJob; +/** + * This class manages the notification and setup that occurs after a refresh is completed. + * + * + */ public class RefreshUserNotificationPolicy implements IRefreshSubscriberListener { private SubscriberParticipant participant; - private boolean addIfNeeded; - public RefreshUserNotificationPolicy(SubscriberParticipant participant, boolean addIfNeeded) { + public RefreshUserNotificationPolicy(SubscriberParticipant participant) { this.participant = participant; - this.addIfNeeded = addIfNeeded; } /* * (non-Javadoc) - * * @see org.eclipse.team.internal.ui.jobs.IRefreshSubscriberListener#refreshStarted(org.eclipse.team.internal.ui.jobs.IRefreshEvent) */ public void refreshStarted(IRefreshEvent event) { @@ -39,61 +37,49 @@ public class RefreshUserNotificationPolicy implements IRefreshSubscriberListener /* * (non-Javadoc) - * * @see org.eclipse.team.internal.ui.jobs.IRefreshSubscriberListener#refreshDone(org.eclipse.team.internal.ui.jobs.IRefreshEvent) */ - public void refreshDone(IRefreshEvent event) { - if(event.getSubscriber() != participant.getSubscriberSyncInfoCollector().getSubscriber()) return; + public void refreshDone(final IRefreshEvent event) { + // Ensure that this event was generated for this participant + if (event.getSubscriber() != participant.getSubscriberSyncInfoCollector().getSubscriber()) + return; - int type = event.getRefreshType(); - - boolean promptWithChanges = TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_PROMPT_WITH_CHANGES); - boolean promptWhenNoChanges = TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_PROMPT_WHEN_NO_CHANGES); - boolean promptWithChangesBkg = TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_BKG_PROMPT_WITH_CHANGES); - boolean promptWhenNoChangesBkg = TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_BKG_PROMPT_WHEN_NO_CHANGES); - - boolean shouldPrompt = false; - SyncInfo[] infos = event.getChanges(); - - if (type == IRefreshEvent.USER_REFRESH) { - if (promptWhenNoChanges && infos.length == 0) { - shouldPrompt = true; - } else if (promptWithChanges && infos.length > 0) { - shouldPrompt = true; - } - } else { - if (promptWhenNoChangesBkg && infos.length == 0) { - shouldPrompt = true; - } else if (promptWithChangesBkg && infos.length > 0) { - shouldPrompt = true; - } - } - - // If there are interesting changes, ensure the sync view is showing them - // Also, add the participant to the sync view only if changes have been found. - if (infos.length > 0) { - participant.setMode(SubscriberParticipant.INCOMING_MODE); - final ISynchronizeManager manager = TeamUI.getSynchronizeManager(); - if (addIfNeeded) { - manager.addSynchronizeParticipants(new ISynchronizeParticipant[]{participant}); - TeamUIPlugin.getStandardDisplay().asyncExec(new Runnable() { - public void run() { - ISynchronizeView view = manager.showSynchronizeViewInActivePage(null); - if (view != null) { - view.display(participant); + // Decide on what action to take after the refresh is completed + TeamUIPlugin.getStandardDisplay().asyncExec(new Runnable() { + public void run() { + boolean prompt = TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCHRONIZING_COMPLETE_SHOW_DIALOG); + + SyncInfo[] infos = event.getChanges(); + List selectedResources = new ArrayList(); + selectedResources.addAll(Arrays.asList(event.getResources())); + for (int i = 0; i < infos.length; i++) { + selectedResources.add(infos[i].getLocal()); + } + IResource[] resources = (IResource[]) selectedResources.toArray(new IResource[selectedResources.size()]); + + // If it's a file, simply show the compare editor + if (resources.length == 1 && resources[0].getType() == IResource.FILE) { + IResource file = resources[0]; + SyncInfo info = participant.getSubscriberSyncInfoCollector().getSubscriberSyncInfoSet().getSyncInfo(file); + if(info != null) { + CompareUI.openCompareEditor(new SyncInfoCompareInput(participant.getName(), info)); + prompt = false; } } - }); - } - } - - // Prompt user if preferences are set for this type of refresh. - if (shouldPrompt) { - notifyIfNeededModal(event); - } + + // ensure the synchronize views are shown + TeamUI.getSynchronizeManager().showSynchronizeViewInActivePage(); + + + // Prompt user if preferences are set for this type of refresh. + if (prompt) { + notifyIfNeededModal(event); + } + } + }); RefreshSubscriberJob.removeRefreshListener(this); } - + private void notifyIfNeededModal(final IRefreshEvent event) { TeamUIPlugin.getStandardDisplay().asyncExec(new Runnable() { public void run() { @@ -115,4 +101,6 @@ public class RefreshUserNotificationPolicy implements IRefreshSubscriberListener } }, message); } + + }
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/messages.properties b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/messages.properties index 9b93efdf6..d70efa8ab 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/messages.properties +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/messages.properties @@ -342,17 +342,12 @@ Utils.24=Incoming/Outgoing Utils.25=Conflicting Utils.26=unknown mode RefreshCompleteDialog.4=Team Resfresh Complete - {0} -RefreshCompleteDialog.5={0} new changes found -RefreshCompleteDialog.6=No new changes found -RefreshCompleteDialog.7=refreshing the following {0} resource(s): -RefreshCompleteDialog.13=SyncViewerPreferencePage.16 -RefreshCompleteDialog.14=SyncViewerPreferencePage.17 -RefreshCompleteDialog.15=SyncViewerPreferencePage.31 -RefreshCompleteDialog.16=SyncViewerPreferencePage.32 -RefreshCompleteDialog.17=Preview Changes >> -RefreshCompleteDialog.18=<< Preview Changes -RefreshUserNotificationPolicy.0=Refresh of ''{0}'' Complete. -ConfigureRefreshScheduleDialog.0=Configure Refresh Schedule - {0} +RefreshCompleteDialog.5=Synchronize has completed and you have changes to synchronize. {0} currently has {1} outgoing, {2} incoming, and {3} conflicting changes. +RefreshCompleteDialog.6=No changes to synchronize. +RefreshCompleteDialog.17=Details >> +RefreshCompleteDialog.18=<< Details +RefreshUserNotificationPolicy.0=Synchronize of ''{0}'' Complete. +ConfigureRefreshScheduleDialog.0=Configure Synchronize Schedule - {0} ConfigureRefreshScheduleDialog.1=You can allow ''{0}'' to periodically refresh it's synchronization state in the background. ConfigureRefreshScheduleDialog.1a=The last refresh occured at: {0} ConfigureRefreshScheduleDialog.2=Don't schedule the refresh operation to run periodically. @@ -377,3 +372,22 @@ ChangesSection.9=Reset View ChangesSection.10=Errors have occurred calculating the synchronization state for {0} ChangesSection.11=Errors Populating View ChangesSection.12=Multiple errors occurred while attempting to populate the view. + +OpenComparedDialog.diffViewTitleMany=Changes +OpenComparedDialog.diffViewTitleOne=Changes +OpenComparedDialog.noChangeTitle=Operation Complete +OpenComparedDialog.noChangesMessage=No Changes Found. +GlobalRefreshAction.4=Synchronize... +GlobalRefreshAction.5=Synchronize {0}... +SubscriberRefreshWizard.0=Synchronize +ParticipantCompareDialog.1=Remember this result by placing it in the Synchronize View. +ParticipantCompareDialog.2=Confirm Save +ParticipantCompareDialog.3=Do you want to save changes? +RefreshCompleteDialog.21=Show only the latest new incoming changes +RefreshCompleteDialog.22=Don't show this dialog again. +SynchronizeManager.27=Confirm Perspective Switch +SynchronizeManager.28=Never +SynchronizeManager.29=Always +SynchronizeManager.30=Synchronization is associated with the {0} perspective. Do you want to switch to that perspective now? +RefreshCompleteDialog.9=Changes +RefreshSubscriberJob.2=Synchronizing {0} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/preferences/IgnorePreferencePage.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/preferences/IgnorePreferencePage.java index 924527d9b..4374a8fa0 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/preferences/IgnorePreferencePage.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/preferences/IgnorePreferencePage.java @@ -11,28 +11,17 @@ package org.eclipse.team.internal.ui.preferences; +import org.eclipse.jface.dialogs.*; import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.dialogs.InputDialog; -import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.preference.PreferencePage; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Event; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Listener; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableItem; +import org.eclipse.swt.widgets.*; import org.eclipse.team.core.IIgnoreInfo; import org.eclipse.team.core.Team; -import org.eclipse.team.internal.ui.IHelpContextIds; -import org.eclipse.team.internal.ui.Policy; -import org.eclipse.team.internal.ui.TeamUIPlugin; +import org.eclipse.team.internal.ui.*; import org.eclipse.team.ui.TeamUI; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/preferences/SyncViewerPreferencePage.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/preferences/SyncViewerPreferencePage.java index a423da7c9..2a5f1c12b 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/preferences/SyncViewerPreferencePage.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/preferences/SyncViewerPreferencePage.java @@ -31,10 +31,9 @@ public class SyncViewerPreferencePage extends FieldEditorPreferencePage implemen private BooleanFieldEditor compressFolders = null; private BooleanFieldEditor showSyncInLabels = null; - private BooleanFieldEditor promptWithChanges = null; - private BooleanFieldEditor promptWhenNoChanges = null; - private BooleanFieldEditor promptWithChangesBkg = null; - private BooleanFieldEditor promptWhenNoChangesBkg = null; + private BooleanFieldEditor promptAtEndOfSynchronize = null; + private BooleanFieldEditor useDefaultPerspective = null; + private RadioGroupFieldEditor synchronizePerspectiveSwitch = null; private static class PerspectiveDescriptorComparator implements Comparator { /* @@ -69,25 +68,25 @@ public class SyncViewerPreferencePage extends FieldEditorPreferencePage implemen * @see org.eclipse.jface.preference.FieldEditorPreferencePage#createFieldEditors() */ public void createFieldEditors() { - Group displayGroup = createGroup(getFieldEditorParent(), Policy.bind("SyncViewerPreferencePage.8")); //$NON-NLS-1$ - - compressFolders = new BooleanFieldEditor(SYNCVIEW_COMPRESS_FOLDERS, Policy.bind("SyncViewerPreferencePage.9"), SWT.NONE, displayGroup); //$NON-NLS-1$ + compressFolders = new BooleanFieldEditor(SYNCVIEW_COMPRESS_FOLDERS, Policy.bind("SyncViewerPreferencePage.9"), SWT.NONE, getFieldEditorParent()); //$NON-NLS-1$ addField(compressFolders); - showSyncInLabels = new BooleanFieldEditor(SYNCVIEW_VIEW_SYNCINFO_IN_LABEL, Policy.bind("SyncViewerPreferencePage.19"), SWT.NONE, displayGroup); //$NON-NLS-1$ + showSyncInLabels = new BooleanFieldEditor(SYNCVIEW_VIEW_SYNCINFO_IN_LABEL, Policy.bind("SyncViewerPreferencePage.19"), SWT.NONE, getFieldEditorParent()); //$NON-NLS-1$ addField(showSyncInLabels); - Group promptGroup = createGroup(getFieldEditorParent(), Policy.bind("SyncViewerPreferencePage.30")); //$NON-NLS-1$ + new Label(getFieldEditorParent(), SWT.NONE); + + promptAtEndOfSynchronize = new BooleanFieldEditor(SYNCHRONIZING_COMPLETE_SHOW_DIALOG, "Prompt at the end of a synchronize operation.", SWT.NONE, getFieldEditorParent()); //$NON-NLS-1$ + addField(promptAtEndOfSynchronize); - promptWhenNoChanges = new BooleanFieldEditor(SYNCVIEW_VIEW_PROMPT_WHEN_NO_CHANGES, Policy.bind("SyncViewerPreferencePage.16"), SWT.NONE, promptGroup); //$NON-NLS-1$ - addField(promptWhenNoChanges); - promptWithChanges = new BooleanFieldEditor(SYNCVIEW_VIEW_PROMPT_WITH_CHANGES, Policy.bind("SyncViewerPreferencePage.17"), SWT.NONE, promptGroup); //$NON-NLS-1$ - addField(promptWithChanges); + synchronizePerspectiveSwitch= new RadioGroupFieldEditor(SYNCHRONIZING_COMPLETE_PERSPECTIVE, "Switch to the associated perspective when a synchronize operation completes", 3, + new String[][] { + {"Always", SYNCHRONIZING_COMPLETE_PERSPECTIVE_ALWAYS}, + {"Never", SYNCHRONIZING_COMPLETE_PERSPECTIVE_NEVER}, + {"Prompt", SYNCHRONIZING_COMPLETE_PERSPECTIVE_PROMPT} + }, + getFieldEditorParent(), true); + addField(synchronizePerspectiveSwitch); - promptWhenNoChangesBkg = new BooleanFieldEditor(SYNCVIEW_VIEW_BKG_PROMPT_WHEN_NO_CHANGES, Policy.bind("SyncViewerPreferencePage.31"), SWT.NONE, promptGroup); //$NON-NLS-1$ - addField(promptWhenNoChangesBkg); - promptWithChangesBkg = new BooleanFieldEditor(SYNCVIEW_VIEW_BKG_PROMPT_WITH_CHANGES, Policy.bind("SyncViewerPreferencePage.32"), SWT.NONE, promptGroup); //$NON-NLS-1$ - addField(promptWithChangesBkg); - Group perspectiveGroup = createGroup(getFieldEditorParent(), Policy.bind("SyncViewerPreferencePage.15")); //$NON-NLS-1$ createLabel(perspectiveGroup, Policy.bind("SynchronizationViewPreference.defaultPerspectiveDescription"), 1); //$NON-NLS-1$ diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/preferences/TeamPreferencePage.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/preferences/TeamPreferencePage.java index dbf86809a..c65178491 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/preferences/TeamPreferencePage.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/preferences/TeamPreferencePage.java @@ -16,12 +16,8 @@ import org.eclipse.jface.preference.PreferencePage; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.team.internal.ui.IHelpContextIds; -import org.eclipse.team.internal.ui.Policy; -import org.eclipse.team.internal.ui.TeamUIPlugin; +import org.eclipse.swt.widgets.*; +import org.eclipse.team.internal.ui.*; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.eclipse.ui.help.WorkbenchHelp; diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/registry/SynchronizeParticipantDescriptor.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/registry/SynchronizeParticipantDescriptor.java index f1675c65d..995140b84 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/registry/SynchronizeParticipantDescriptor.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/registry/SynchronizeParticipantDescriptor.java @@ -23,12 +23,14 @@ public class SynchronizeParticipantDescriptor implements ISynchronizeParticipant public static final String ATT_ICON = "icon"; //$NON-NLS-1$ public static final String ATT_CLASS = "class"; //$NON-NLS-1$ private static final String ATT_TYPE = "type"; //$NON-NLS-1$ - private static final String TYPE_STATIC = "static"; //$NON-NLS-1$ + private static final String ATT_TYPE_STATIC = "static"; //$NON-NLS-1$ + private static final String ATT_SUPPORTS_REFRESH = "supportsRefresh"; //$NON-NLS-1$ private String label; private String className; private String type; private String id; + private boolean supportsRefresh; private ImageDescriptor imageDescriptor; private String description; @@ -82,13 +84,17 @@ public class SynchronizeParticipantDescriptor implements ISynchronizeParticipant return imageDescriptor; } - public String getLabel() { + public String getName() { return label; } public boolean isStatic() { if(type == null) return true; - return type.equals(TYPE_STATIC); + return type.equals(ATT_TYPE_STATIC); + } + + public boolean doesSupportRefresh() { + return supportsRefresh; } /** @@ -99,6 +105,12 @@ public class SynchronizeParticipantDescriptor implements ISynchronizeParticipant label = configElement.getAttribute(ATT_NAME); className = configElement.getAttribute(ATT_CLASS); type = configElement.getAttribute(ATT_TYPE); + String supportsRefreshString = configElement.getAttribute(ATT_SUPPORTS_REFRESH); + if(supportsRefreshString == null) { + supportsRefresh = true; + } else { + supportsRefresh = Boolean.valueOf(supportsRefreshString).booleanValue(); + } // Sanity check. if ((label == null) || (className == null) || (identifier == null)) { diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangesSection.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangesSection.java index 6ae1b6723..a0b90fea1 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangesSection.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ChangesSection.java @@ -263,7 +263,7 @@ public class ChangesSection extends Composite { Label warning = new Label(composite, SWT.NONE); warning.setImage(TeamUIPlugin.getPlugin().getImage(ISharedImages.IMG_WARNING)); - Hyperlink link = forms.createHyperlink(composite, Policy.bind("ChangesSection.workingSetRemove"), SWT.WRAP); + Hyperlink link = forms.createHyperlink(composite, Policy.bind("ChangesSection.workingSetRemove"), SWT.WRAP); //$NON-NLS-1$ link.addHyperlinkListener(new HyperlinkAdapter() { public void linkActivated(HyperlinkEvent e) { participant.setWorkingSet(null); diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/CompressedFoldersModelProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/CompressedFoldersModelProvider.java new file mode 100644 index 000000000..786d85898 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/CompressedFoldersModelProvider.java @@ -0,0 +1,282 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ui.synchronize; + +import java.util.*; + +import org.eclipse.compare.structuremergeviewer.IDiffContainer; +import org.eclipse.compare.structuremergeviewer.IDiffElement; +import org.eclipse.core.resources.*; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.internal.ui.TeamUIPlugin; +import org.eclipse.team.ui.ISharedImages; +import org.eclipse.team.ui.synchronize.viewers.*; + +public class CompressedFoldersModelProvider extends HierarchicalModelProvider { + + protected class UnchangedCompressedDiffNode extends UnchangedResourceModelElement { + public UnchangedCompressedDiffNode(IDiffContainer parent, IResource resource) { + super(parent, resource); + } + + /* (non-Javadoc) + * @see org.eclipse.compare.structuremergeviewer.DiffNode#getName() + */ + public String getName() { + IResource resource = getResource(); + return resource.getProjectRelativePath().toString(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SyncInfoModelElement#getImageDescriptor(java.lang.Object) + */ + public ImageDescriptor getImageDescriptor(Object object) { + return TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_COMPRESSED_FOLDER); + } + } + + /** + * A compressed folder appears under a project and contains out-of-sync resources + */ + public class CompressedFolderDiffNode extends SyncInfoModelElement { + + public CompressedFolderDiffNode(IDiffContainer parent, SyncInfo info) { + super(parent, info); + } + + /* (non-Javadoc) + * @see org.eclipse.compare.structuremergeviewer.DiffNode#getName() + */ + public String getName() { + IResource resource = getResource(); + return resource.getProjectRelativePath().toString(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SyncInfoModelElement#getImageDescriptor(java.lang.Object) + */ + public ImageDescriptor getImageDescriptor(Object object) { + return TeamUIPlugin.getImageDescriptor(ISharedImages.IMG_COMPRESSED_FOLDER); + } + } + + public CompressedFoldersModelProvider(SyncInfoTree set) { + super(set); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.SyncInfoDiffNodeRoot#getSorter() + */ + public ViewerSorter getViewerSorter() { + return new SynchronizeModelElementSorter() { + protected int compareNames(IResource resource1, IResource resource2) { + if (resource1.getType() == IResource.FOLDER && resource2.getType() == IResource.FOLDER) { + return collator.compare(resource1.getProjectRelativePath().toString(), resource2.getProjectRelativePath().toString()); + } + return super.compareNames(resource1, resource2); + } + }; + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.viewers.HierarchicalModelProvider#createModelObjects(org.eclipse.compare.structuremergeviewer.DiffNode) + */ + protected IDiffElement[] createModelObjects(SynchronizeModelElement container) { + IResource resource = null; + if (container == getModelRoot()) { + resource = ResourcesPlugin.getWorkspace().getRoot(); + } else { + resource = container.getResource(); + } + if(resource != null) { + if (resource.getType() == IResource.PROJECT) { + return getProjectChildren(container, (IProject)resource); + } + if (resource.getType() == IResource.FOLDER) { + return getFolderChildren(container, resource); + } + } + return super.createModelObjects(container); + } + + private IDiffElement[] getFolderChildren(SynchronizeModelElement parent, IResource resource) { + // Folders will only contain out-of-sync children + IResource[] children = getSyncInfoTree().members(resource); + List result = new ArrayList(); + for (int i = 0; i < children.length; i++) { + IResource child = children[i]; + if (child.getType() == IResource.FILE) { + result.add(createModelObject(parent, child)); + } + } + return (IDiffElement[])result.toArray(new IDiffElement[result.size()]); + } + + private IDiffElement[] getProjectChildren(SynchronizeModelElement parent, IProject project) { + // The out-of-sync elements could possibly include the project so the code + // below is written to ignore the project + SyncInfo[] outOfSync = getSyncInfoTree().getSyncInfos(project, IResource.DEPTH_INFINITE); + Set result = new HashSet(); + Set resourcesToShow = new HashSet(); + for (int i = 0; i < outOfSync.length; i++) { + SyncInfo info = outOfSync[i]; + IResource local = info.getLocal(); + if (local.getProjectRelativePath().segmentCount() == 1 && local.getType() == IResource.FILE) { + resourcesToShow.add(local); + } else { + if (local.getType() == IResource.FILE) { + resourcesToShow.add(local.getParent()); + } else if (local.getType() == IResource.FOLDER){ + resourcesToShow.add(local); + } + } + } + for (Iterator iter = resourcesToShow.iterator(); iter.hasNext();) { + IResource resource = (IResource) iter.next(); + result.add(createModelObject(parent, resource)); + } + + return (IDiffElement[])result.toArray(new IDiffElement[result.size()]); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.views.HierarchicalModelProvider#createChildNode(org.eclipse.compare.structuremergeviewer.DiffNode, org.eclipse.core.resources.IResource) + */ + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.viewers.HierarchicalModelProvider#createModelObject(org.eclipse.compare.structuremergeviewer.DiffNode, org.eclipse.core.resources.IResource) + */ + protected SynchronizeModelElement createModelObject(SynchronizeModelElement parent, IResource resource) { + if (resource.getType() == IResource.FOLDER) { + SyncInfo info = getSyncInfoTree().getSyncInfo(resource); + SynchronizeModelElement newNode; + if(info != null) { + newNode = new CompressedFolderDiffNode(parent, info); + } else { + newNode = new UnchangedCompressedDiffNode(parent, resource); + } + addToViewer(newNode); + return newNode; + } + return super.createModelObject(parent, resource); + } + + /** + * Update the viewer for the sync set additions in the provided event. + * This method is invoked by <code>handleChanges(ISyncInfoSetChangeEvent)</code>. + * Subclasses may override. + * @param event + */ + protected void handleResourceAdditions(ISyncInfoTreeChangeEvent event) { + SyncInfo[] infos = event.getAddedResources(); + for (int i = 0; i < infos.length; i++) { + SyncInfo info = infos[i]; + addResource(info); + } + } + + private void addResource(SyncInfo info) { + IResource local = info.getLocal(); + SynchronizeModelElement existingNode = getModelObject(local); + if (existingNode == null) { + if (local.getType() == IResource.FILE) { + SynchronizeModelElement parentNode = getModelObject(local.getParent()); + if (parentNode == null) { + SynchronizeModelElement projectNode = getModelObject(local.getProject()); + if (projectNode == null) { + projectNode = createModelObject(getModelRoot(), local.getProject()); + } + if (local.getParent().getType() == IResource.PROJECT) { + parentNode = projectNode; + } else { + parentNode = createModelObject(projectNode, local.getParent()); + } + } + createModelObject(parentNode, local); + } else { + SynchronizeModelElement projectNode = getModelObject(local.getProject()); + if (projectNode == null) { + projectNode = createModelObject(getModelRoot(), local.getProject()); + } + createModelObject(projectNode, local); + } + } else { + // Either The folder node was added as the parent of a newly added out-of-sync file + // or the file was somehow already there so just refresh + handleChange(existingNode, info); + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.internal.ui.sync.views.SyncSetContentProvider#handleResourceRemovals(org.eclipse.team.internal.ui.sync.views.SyncSetChangedEvent) + */ + protected void handleResourceRemovals(ISyncInfoTreeChangeEvent event) { + IResource[] roots = event.getRemovedSubtreeRoots(); + + // First, deal with any projects that have been removed + List removedProjects = new ArrayList(); + for (int i = 0; i < roots.length; i++) { + IResource resource = roots[i]; + if (resource.getType() == IResource.PROJECT) { + removeFromViewer(resource); + removedProjects.add(resource); + } + } + + IResource[] resources = event.getRemovedResources(); + for (int i = 0; i < resources.length; i++) { + IResource resource = resources[i]; + if (!removedProjects.contains(resource.getProject())) { + if (resource.getType() == IResource.FILE) { + if (isCompressedParentEmpty(resource)) { + // The parent compressed folder is also empty so remove it + removeFromViewer(resource.getParent()); + } else { + removeFromViewer(resource); + } + } else { + // A folder has been removed (i.e. is in-sync) + // but may still contain children + removeFromViewer(resource); + if (hasFileMembers((IContainer)resource)) { + createModelObject(getModelObject(resource.getProject()), resource); + buildModelObjects(getModelObject(resource)); + } + } + } + } + } + + private boolean isCompressedParentEmpty(IResource resource) { + IContainer parent = resource.getParent(); + if (parent == null + || parent.getType() == IResource.ROOT + || parent.getType() == IResource.PROJECT) { + return false; + } + return !hasFileMembers(parent); + } + + private boolean hasFileMembers(IContainer parent) { + // Check if the sync set has any file children of the parent + IResource[] members = getSyncInfoTree().members(parent); + for (int i = 0; i < members.length; i++) { + IResource member = members[i]; + if (member.getType() == IResource.FILE) { + return true; + } + } + // The parent does not contain any files + return false; + } +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ConfigureRefreshScheduleDialog.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ConfigureRefreshScheduleDialog.java index c4c62f649..63f241520 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ConfigureRefreshScheduleDialog.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/ConfigureRefreshScheduleDialog.java @@ -2,16 +2,13 @@ package org.eclipse.team.internal.ui.synchronize; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.events.*; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.*; +import org.eclipse.team.internal.ui.Policy; import org.eclipse.team.internal.ui.dialogs.DetailsDialog; import org.eclipse.team.ui.synchronize.subscriber.SubscriberRefreshSchedule; -import org.eclipse.team.internal.ui.Policy; public class ConfigureRefreshScheduleDialog extends DetailsDialog { diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/HierarchicalModelProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/HierarchicalModelProvider.java new file mode 100644 index 000000000..7ecfb3a56 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/HierarchicalModelProvider.java @@ -0,0 +1,231 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ui.synchronize; + +import org.eclipse.compare.structuremergeviewer.IDiffElement; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.jface.viewers.AbstractTreeViewer; +import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.ui.synchronize.viewers.*; + +/** + * An input that can be used with both {@link } and + * {@link }. The + * job of this input is to create the logical model of the contents of the + * sync set for displaying to the user. The created logical model must diff + * nodes. + * <p> + * 1. First, prepareInput is called to initialize the model with the given sync + * set. Building the model occurs in the ui thread. + * 2. The input must react to changes in the sync set and adjust its diff node + * model then update the viewer. In effect mediating between the sync set + * changes and the model shown to the user. This happens in the ui thread. + * </p> + * NOT ON DEMAND - model is created then maintained! + * @since 3.0 + */ +public class HierarchicalModelProvider extends SynchronizeModelProvider { + + /** + * Create an input based on the provide sync set. The input is not initialized + * until <code>prepareInput</code> is called. + * + * @param set the sync set used as the basis for the model created by this input. + */ + public HierarchicalModelProvider(SyncInfoTree set) { + super(set); + } + + public ViewerSorter getViewerSorter() { + return new SynchronizeModelElementSorter(); + } + + protected SyncInfoTree getSyncInfoTree() { + return (SyncInfoTree)getSyncInfoSet(); + } + + /** + * Invoked by the <code>buildModelObject</code> method to create + * the childen of the given node. This method can be overriden + * by subclasses but subclasses should inv + * @param container + * @return + */ + protected IDiffElement[] createModelObjects(SynchronizeModelElement container) { + IResource resource = null; + if (container == getModelRoot()) { + resource = ResourcesPlugin.getWorkspace().getRoot(); + } else { + resource = container.getResource(); + } + if(resource != null) { + SyncInfoTree infoTree = getSyncInfoTree(); + IResource[] children = infoTree.members(resource); + SynchronizeModelElement[] nodes = new SynchronizeModelElement[children.length]; + for (int i = 0; i < children.length; i++) { + nodes[i] = createModelObject(container, children[i]); + } + return nodes; + } + return new IDiffElement[0]; + } + + protected SynchronizeModelElement createModelObject(SynchronizeModelElement parent, IResource resource) { + SyncInfo info = getSyncInfoTree().getSyncInfo(resource); + SynchronizeModelElement newNode; + if(info != null) { + newNode = new SyncInfoModelElement(parent, info); + } else { + newNode = new UnchangedResourceModelElement(parent, resource); + } + addToViewer(newNode); + return newNode; + } + + /** + * Invokes <code>getModelObject(Object)</code> on an array of resources. + * @param resources + * the resources + * @return the model objects for the resources + */ + protected Object[] getModelObjects(IResource[] resources) { + Object[] result = new Object[resources.length]; + for (int i = 0; i < resources.length; i++) { + result[i] = getModelObject(resources[i]); + } + return result; + } + + /** + * Handle the change for the existing diff node. The diff node + * should be changed to have the given sync info + * @param diffNode the diff node to be changed + * @param info the new sync info for the diff node + */ + protected void handleChange(SynchronizeModelElement diffNode, SyncInfo info) { + IResource local = info.getLocal(); + // TODO: Get any additional sync bits + if(diffNode instanceof SyncInfoModelElement) { + boolean wasConflict = isConflicting(diffNode); + // The update preserves any of the additional sync info bits + ((SyncInfoModelElement)diffNode).update(info); + boolean isConflict = isConflicting(diffNode); + updateLabel(diffNode); + if (wasConflict && !isConflict) { + setParentConflict(diffNode, false); + } else if (!wasConflict && isConflict) { + setParentConflict(diffNode, true); + } + } else { + removeFromViewer(local); + addResources(new IResource[] {local}); + } + // TODO: set any additional sync info bits + } + + protected void addResources(IResource[] added) { + for (int i = 0; i < added.length; i++) { + IResource resource = added[i]; + SynchronizeModelElement node = getModelObject(resource); + if (node != null) { + // Somehow the node exists. Remove it and read it to ensure + // what is shown matches the contents of the sync set + removeFromViewer(resource); + } + // Build the sub-tree rooted at this node + SynchronizeModelElement parent = getModelObject(resource.getParent()); + if (parent != null) { + node = createModelObject(parent, resource); + buildModelObjects(node); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.viewers.SynchronizeModelProvider#buildModelObjects(org.eclipse.team.ui.synchronize.viewers.SynchronizeModelElement) + */ + protected IDiffElement[] buildModelObjects(SynchronizeModelElement node) { + IDiffElement[] children = createModelObjects(node); + for (int i = 0; i < children.length; i++) { + IDiffElement element = children[i]; + if (element instanceof SynchronizeModelElement) { + buildModelObjects((SynchronizeModelElement) element); + } + } + return children; + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.viewers.SynchronizeModelProvider#doAdd(org.eclipse.team.ui.synchronize.viewers.SynchronizeModelElement, org.eclipse.team.ui.synchronize.viewers.SynchronizeModelElement) + */ + protected void doAdd(SynchronizeModelElement parent, SynchronizeModelElement element) { + AbstractTreeViewer viewer = (AbstractTreeViewer)getViewer(); + viewer.add(parent, element); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.viewers.SynchronizeModelProvider#doRemove(org.eclipse.team.ui.synchronize.viewers.SynchronizeModelElement) + */ + protected void doRemove(SynchronizeModelElement element) { + AbstractTreeViewer viewer = (AbstractTreeViewer)getViewer(); + viewer.remove(element); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.viewers.SynchronizeModelProvider#handleResourceAdditions(org.eclipse.team.core.synchronize.ISyncInfoTreeChangeEvent) + */ + protected void handleResourceAdditions(ISyncInfoTreeChangeEvent event) { + IResource[] added = event.getAddedSubtreeRoots(); + addResources(added); + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.viewers.SynchronizeModelProvider#handleResourceChanges(org.eclipse.team.core.synchronize.ISyncInfoTreeChangeEvent) + */ + protected void handleResourceChanges(ISyncInfoTreeChangeEvent event) { + // Refresh the viewer for each changed resource + SyncInfo[] infos = event.getChangedResources(); + for (int i = 0; i < infos.length; i++) { + SyncInfo info = infos[i]; + IResource local = info.getLocal(); + SynchronizeModelElement diffNode = getModelObject(local); + if (diffNode != null) { + handleChange(diffNode, info); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.viewers.SynchronizeModelProvider#handleResourceRemovals(org.eclipse.team.core.synchronize.ISyncInfoTreeChangeEvent) + */ + protected void handleResourceRemovals(ISyncInfoTreeChangeEvent event) { + // Remove the removed subtrees + IResource[] removedRoots = event.getRemovedSubtreeRoots(); + for (int i = 0; i < removedRoots.length; i++) { + removeFromViewer(removedRoots[i]); + } + // We have to look for folders that may no longer be in the set + // (i.e. are in-sync) but still have descendants in the set + IResource[] removedResources = event.getRemovedResources(); + for (int i = 0; i < removedResources.length; i++) { + IResource resource = removedResources[i]; + if (resource.getType() != IResource.FILE) { + SynchronizeModelElement node = getModelObject(resource); + if (node != null) { + removeFromViewer(resource); + addResources(new IResource[] {resource}); + } + } + } + } +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/IRefreshEvent.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/IRefreshEvent.java deleted file mode 100644 index 1fd7579a0..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/IRefreshEvent.java +++ /dev/null @@ -1,36 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.ui.synchronize; - -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.team.core.subscribers.Subscriber; -import org.eclipse.team.core.synchronize.SyncInfo; - -public interface IRefreshEvent { - public static final int SCHEDULED_REFRESH = 1; - - public static final int USER_REFRESH = 2; - - public int getRefreshType(); - - public Subscriber getSubscriber(); - - public SyncInfo[] getChanges(); - - public long getStartTime(); - - public long getStopTime(); - - public IStatus getStatus(); - - public IResource[] getResources(); -}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/IRefreshSubscriberListener.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/IRefreshSubscriberListener.java deleted file mode 100644 index 12bb707a5..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/IRefreshSubscriberListener.java +++ /dev/null @@ -1,6 +0,0 @@ -package org.eclipse.team.internal.ui.synchronize; - -public interface IRefreshSubscriberListener { - public void refreshStarted(IRefreshEvent event); - public void refreshDone(IRefreshEvent event); -}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/LocalResourceTypedElement.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/LocalResourceTypedElement.java index 237a00fea..4ea6fa6f0 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/LocalResourceTypedElement.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/LocalResourceTypedElement.java @@ -10,20 +10,12 @@ *******************************************************************************/ package org.eclipse.team.internal.ui.synchronize; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; -import org.eclipse.compare.IEditableContent; -import org.eclipse.compare.IStreamContentAccessor; -import org.eclipse.compare.ITypedElement; -import org.eclipse.compare.ResourceNode; +import org.eclipse.compare.*; import org.eclipse.compare.internal.BufferedResourceNode; import org.eclipse.compare.structuremergeviewer.IStructureComparator; -import org.eclipse.core.resources.IFile; -import org.eclipse.core.resources.IFolder; -import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.*; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -78,6 +70,7 @@ public class LocalResourceTypedElement extends ResourceNode { file.create(is, false, pm); fDirty= false; } finally { + fireContentChanged(); if (is != null) try { is.close(); @@ -124,6 +117,7 @@ public class LocalResourceTypedElement extends ResourceNode { } catch (CoreException ex) { } } + fireContentChanged(); return child; } diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RefreshCompleteDialog.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RefreshCompleteDialog.java index 800693903..5d96ae5de 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RefreshCompleteDialog.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RefreshCompleteDialog.java @@ -11,15 +11,16 @@ package org.eclipse.team.internal.ui.synchronize; import java.lang.reflect.InvocationTargetException; + import org.eclipse.compare.CompareConfiguration; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogSettings; -import org.eclipse.jface.viewers.ArrayContentProvider; -import org.eclipse.jface.viewers.TableViewer; import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.*; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; @@ -28,22 +29,24 @@ import org.eclipse.team.core.subscribers.FilteredSyncInfoCollector; import org.eclipse.team.core.synchronize.*; import org.eclipse.team.internal.ui.*; import org.eclipse.team.internal.ui.dialogs.DetailsDialog; +import org.eclipse.team.ui.synchronize.subscriber.IRefreshEvent; import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; -import org.eclipse.team.ui.synchronize.viewers.TreeViewerAdvisor; import org.eclipse.team.ui.synchronize.viewers.SynchronizeCompareInput; -import org.eclipse.ui.model.WorkbenchLabelProvider; +import org.eclipse.team.ui.synchronize.viewers.TreeViewerAdvisor; public class RefreshCompleteDialog extends DetailsDialog { + // For remembering the dialog sizings private static final String HEIGHT_KEY = "width-key"; //$NON-NLS-1$ - private final static int RESOURCE_LIST_SIZE = 10; private static final String WIDTH_KEY = "height-key"; //$NON-NLS-1$ + + private SyncInfoFilter filter; private FilteredSyncInfoCollector collector; private SynchronizeCompareInput compareEditorInput; private IRefreshEvent event; private SubscriberParticipant participant; - private Button promptWhenNoChanges; - private Button promptWithChanges; + private Button dontShowAgainButton; + private IDialogSettings settings; private SyncInfoTree syncInfoSet = new SyncInfoTree(); @@ -56,8 +59,7 @@ public class RefreshCompleteDialog extends DetailsDialog { setImageKey(DLG_IMG_INFO); // Set-up a sync info set that contains the resources that where found // when the refresh occured. - SyncInfoFilter filter = new SyncInfoFilter() { - + filter = new SyncInfoFilter() { public boolean select(SyncInfo info, IProgressMonitor monitor) { IResource[] resources = getResources(); for (int i = 0; i < resources.length; i++) { @@ -123,11 +125,10 @@ public class RefreshCompleteDialog extends DetailsDialog { protected Composite createDropDownDialogArea(Composite parent) { try { CompareConfiguration compareConfig = new CompareConfiguration(); - TreeViewerAdvisor viewerAdvisor = new TreeViewerAdvisor(participant.getId(), null, syncInfoSet); + TreeViewerAdvisor viewerAdvisor = new TreeViewerAdvisor(syncInfoSet); compareEditorInput = new SynchronizeCompareInput(compareConfig, viewerAdvisor) { - public String getTitle() { - return "Resources found during last refresh"; + return Policy.bind("RefreshCompleteDialog.9"); //$NON-NLS-1$ } }; // Preparing the input should be fast since we haven't started the collector @@ -151,6 +152,22 @@ public class RefreshCompleteDialog extends DetailsDialog { Control c = compareEditorInput.createContents(result); data = new GridData(GridData.FILL_BOTH); c.setLayoutData(data); + + Button onlyNewChangesButton = new Button(result, SWT.CHECK); + onlyNewChangesButton.setText(Policy.bind("RefreshCompleteDialog.21")); //$NON-NLS-1$ + onlyNewChangesButton.setSelection(true); + onlyNewChangesButton.addSelectionListener(new SelectionListener() { + public void widgetSelected(SelectionEvent e) { + if(((Button)e.getSource()).getSelection()) { + collector.setFilter(filter, new NullProgressMonitor()); + } else { + collector.setFilter(new FastSyncInfoFilter(), new NullProgressMonitor()); + } + } + public void widgetDefaultSelected(SelectionEvent e) { + } + }); + return result; } @@ -161,60 +178,35 @@ public class RefreshCompleteDialog extends DetailsDialog { StringBuffer text = new StringBuffer(); SyncInfo[] changes = event.getChanges(); IResource[] resources = event.getResources(); - if (changes.length != 0) { - text.append(Policy.bind("RefreshCompleteDialog.5", Integer.toString(changes.length))); //$NON-NLS-1$ + SyncInfoSet set = getSubscriberSyncInfoSet(); + if (! set.isEmpty()) { + String outgoing = Long.toString(set.countFor(SyncInfo.OUTGOING, SyncInfo.DIRECTION_MASK)); + String incoming = Long.toString(set.countFor(SyncInfo.INCOMING, SyncInfo.DIRECTION_MASK)); + String conflicting = Long.toString(set.countFor(SyncInfo.CONFLICTING, SyncInfo.DIRECTION_MASK)); + text.append(Policy.bind("RefreshCompleteDialog.5", new Object[] {participant.getName(), outgoing, incoming, conflicting})); //$NON-NLS-1$ + createLabel(parent, text.toString(), 2); } else { text.append(Policy.bind("RefreshCompleteDialog.6")); //$NON-NLS-1$ + createLabel(parent, text.toString(), 2); } - text.append(Policy.bind("RefreshCompleteDialog.7", Integer.toString(resources.length))); //$NON-NLS-1$ //$NON-NLS-2$ - createLabel(parent, text.toString(), 2); - Table table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); - GridData data = new GridData(GridData.FILL_BOTH | GridData.GRAB_HORIZONTAL); - data.horizontalSpan = 2; - data.widthHint = 200; - data.heightHint = 125; - table.setLayoutData(data); - TableViewer resourceList = new TableViewer(table); - resourceList.setContentProvider(new ArrayContentProvider()); - resourceList.setLabelProvider(new WorkbenchLabelProvider()); - resourceList.setInput(resources); - createLabel(parent, "", 2); //$NON-NLS-1$ - promptWhenNoChanges = new Button(parent, SWT.CHECK); - data = new GridData(GridData.VERTICAL_ALIGN_BEGINNING); - data.horizontalSpan = 2; - promptWhenNoChanges.setLayoutData(data); - promptWithChanges = new Button(parent, SWT.CHECK); - data = new GridData(GridData.VERTICAL_ALIGN_BEGINNING); - data.horizontalSpan = 2; - promptWithChanges.setLayoutData(data); - if (event.getRefreshType() == IRefreshEvent.USER_REFRESH) { - promptWhenNoChanges.setText(Policy.bind(Policy.bind("RefreshCompleteDialog.13"))); //$NON-NLS-1$ - promptWhenNoChanges.setSelection(TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_PROMPT_WHEN_NO_CHANGES)); - promptWithChanges.setText(Policy.bind(Policy.bind("RefreshCompleteDialog.14"))); //$NON-NLS-1$ - promptWithChanges.setSelection(TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_PROMPT_WITH_CHANGES)); - } else { - promptWhenNoChanges.setText(Policy.bind(Policy.bind("RefreshCompleteDialog.15"))); //$NON-NLS-1$ - promptWhenNoChanges.setSelection(TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_BKG_PROMPT_WHEN_NO_CHANGES)); - promptWithChanges.setText(Policy.bind(Policy.bind("RefreshCompleteDialog.16"))); //$NON-NLS-1$ - promptWithChanges.setSelection(TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCVIEW_VIEW_BKG_PROMPT_WITH_CHANGES)); - } + + dontShowAgainButton = new Button(parent, SWT.CHECK); + dontShowAgainButton.setText(Policy.bind("RefreshCompleteDialog.22")); //$NON-NLS-1$ + + initializeSettings(); Dialog.applyDialogFont(parent); } - /* (non-Javadoc) - * @see org.eclipse.team.internal.ui.dialogs.DetailsDialog#getDetailsButtonLabelHide() - */ - protected String getDetailsButtonLabelHide() { - return Policy.bind("RefreshCompleteDialog.18"); + private void initializeSettings() { + if(dontShowAgainButton != null) { + dontShowAgainButton.setSelection(! TeamUIPlugin.getPlugin().getPreferenceStore().getBoolean(IPreferenceIds.SYNCHRONIZING_COMPLETE_SHOW_DIALOG)); + } } - /* (non-Javadoc) - * @see org.eclipse.team.internal.ui.dialogs.DetailsDialog#getDetailsButtonLabelShow() - */ - protected String getDetailsButtonLabelShow() { - return Policy.bind("RefreshCompleteDialog.17"); + protected SyncInfoSet getSubscriberSyncInfoSet() { + return participant.getSubscriberSyncInfoCollector().getSubscriberSyncInfoSet(); } - + /* (non-Javadoc) * @see org.eclipse.jface.window.Window#getInitialSize() */ @@ -241,7 +233,7 @@ public class RefreshCompleteDialog extends DetailsDialog { * @see org.eclipse.team.internal.ui.dialogs.DetailsDialog#includeDetailsButton() */ protected boolean includeDetailsButton() { - return event.getChanges().length != 0; + return ! getSubscriberSyncInfoSet().isEmpty(); } /* (non-Javadoc) @@ -255,14 +247,10 @@ public class RefreshCompleteDialog extends DetailsDialog { * @see org.eclipse.jface.dialogs.Dialog#okPressed() */ protected void okPressed() { - if (event.getRefreshType() == IRefreshEvent.USER_REFRESH) { - TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCVIEW_VIEW_PROMPT_WHEN_NO_CHANGES, promptWhenNoChanges.getSelection()); - TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCVIEW_VIEW_PROMPT_WITH_CHANGES, promptWithChanges.getSelection()); - } else { - TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCVIEW_VIEW_BKG_PROMPT_WHEN_NO_CHANGES, promptWhenNoChanges.getSelection()); - TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCVIEW_VIEW_BKG_PROMPT_WITH_CHANGES, promptWithChanges.getSelection()); + if(dontShowAgainButton != null) { + TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCHRONIZING_COMPLETE_SHOW_DIALOG, ! dontShowAgainButton.getSelection()); } - TeamUIPlugin.getPlugin().savePluginPreferences(); + TeamUIPlugin.getPlugin().savePluginPreferences(); super.okPressed(); } @@ -277,6 +265,7 @@ public class RefreshCompleteDialog extends DetailsDialog { label.setText(text); GridData data = new GridData(); data.horizontalSpan = columns; + data.widthHint = 375; label.setLayoutData(data); return label; } diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RemoteResourceTypedElement.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RemoteResourceTypedElement.java index 912f874d5..3210ffbaf 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RemoteResourceTypedElement.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/RemoteResourceTypedElement.java @@ -18,6 +18,7 @@ import org.eclipse.core.runtime.*; import org.eclipse.swt.graphics.Image; import org.eclipse.team.core.TeamException; import org.eclipse.team.core.variants.IResourceVariant; +import org.eclipse.team.internal.core.Assert; /** * RemoteResourceTypedElement @@ -31,6 +32,7 @@ public class RemoteResourceTypedElement extends BufferedContent implements IType * Creates a new content buffer for the given team node. */ public RemoteResourceTypedElement(IResourceVariant remote) { + Assert.isNotNull(remote); this.remote = remote; } @@ -112,4 +114,15 @@ public class RemoteResourceTypedElement extends BufferedContent implements IType public void cacheContents(IProgressMonitor monitor) throws TeamException { bufferedContents = remote.getStorage(monitor); } + + /** + * Update the remote handle in this typed element. + * @param variant the new remote handle + */ + public void update(IResourceVariant variant) { + Assert.isNotNull(variant); + discardBuffer(); + remote = variant; + fireContentChanged(); + } }
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeManager.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeManager.java index 5e6f95f1b..8e5e1e062 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeManager.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeManager.java @@ -10,51 +10,21 @@ *******************************************************************************/ package org.eclipse.team.internal.ui.synchronize; -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.Reader; -import java.io.Writer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.io.*; +import java.util.*; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IConfigurationElement; -import org.eclipse.core.runtime.IPath; -import org.eclipse.core.runtime.ISafeRunnable; -import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.Platform; -import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.*; +import org.eclipse.jface.dialogs.IDialogConstants; +import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.util.ListenerList; +import org.eclipse.swt.widgets.Display; import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.ui.IPreferenceIds; -import org.eclipse.team.internal.ui.Policy; -import org.eclipse.team.internal.ui.TeamUIPlugin; -import org.eclipse.team.internal.ui.Utils; +import org.eclipse.team.internal.ui.*; import org.eclipse.team.internal.ui.registry.SynchronizeParticipantDescriptor; import org.eclipse.team.internal.ui.registry.SynchronizeParticipantRegistry; import org.eclipse.team.ui.ITeamUIConstants; -import org.eclipse.team.ui.synchronize.ISynchronizeManager; -import org.eclipse.team.ui.synchronize.ISynchronizeParticipant; -import org.eclipse.team.ui.synchronize.ISynchronizeParticipantDescriptor; -import org.eclipse.team.ui.synchronize.ISynchronizeParticipantListener; -import org.eclipse.team.ui.synchronize.ISynchronizeView; -import org.eclipse.ui.IMemento; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.WorkbenchException; -import org.eclipse.ui.XMLMemento; +import org.eclipse.team.ui.synchronize.*; +import org.eclipse.ui.*; /** * Manages the registered synchronize participants. It handles notification of @@ -160,7 +130,7 @@ public class SynchronizeManager implements ISynchronizeManager { participant.init(savedState); } catch (PartInitException e2) { participant = null; - throw new TeamException(Policy.bind("SynchronizeManager.11"), e2); + throw new TeamException(Policy.bind("SynchronizeManager.11"), e2); //$NON-NLS-1$ } catch (CoreException e) { participant = null; throw TeamException.asTeamException(e); @@ -329,16 +299,16 @@ public class SynchronizeManager implements ISynchronizeManager { return (ISynchronizeParticipant[]) participants.toArray(new ISynchronizeParticipant[participants.size()]); } - /** - * Called to display the synchronize view in the given page. If the given - * page is <code>null</code> the synchronize view is shown in the default - * active workbench window. + /* (non-Javadoc) + * @see org.eclipse.team.ui.synchronize.ISynchronizeManager#showSynchronizeViewInActivePage() */ - public ISynchronizeView showSynchronizeViewInActivePage(IWorkbenchPage activePage) { + public ISynchronizeView showSynchronizeViewInActivePage() { IWorkbench workbench = TeamUIPlugin.getPlugin().getWorkbench(); IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); - if (!TeamUIPlugin.getPlugin().getPreferenceStore().getString(IPreferenceIds.SYNCVIEW_DEFAULT_PERSPECTIVE).equals(IPreferenceIds.SYNCVIEW_DEFAULT_PERSPECTIVE_NONE)) { + boolean switchPerspectives = promptForPerspectiveSwitch(); + IWorkbenchPage activePage = null; + if(switchPerspectives) { try { String pId = TeamUIPlugin.getPlugin().getPreferenceStore().getString(IPreferenceIds.SYNCVIEW_DEFAULT_PERSPECTIVE); activePage = workbench.showPerspective(pId, window); @@ -358,6 +328,64 @@ public class SynchronizeManager implements ISynchronizeManager { return null; } } + + /** + * Decides what action to take when switching perspectives and showing the synchronize view. Basically there are a + * set of user preferences that control how perspective switching. + */ + private boolean promptForPerspectiveSwitch() { + // Decide if a prompt is even required + String option = TeamUIPlugin.getPlugin().getPreferenceStore().getString(IPreferenceIds.SYNCHRONIZING_COMPLETE_PERSPECTIVE); + if(option.equals(IPreferenceIds.SYNCHRONIZING_COMPLETE_PERSPECTIVE_ALWAYS)) { + return true; + } else if(option.equals(IPreferenceIds.SYNCHRONIZING_COMPLETE_PERSPECTIVE_NEVER)) { + return false; + } + + // Otherwise determine if a prompt is required + IPerspectiveRegistry registry= PlatformUI.getWorkbench().getPerspectiveRegistry(); + String defaultSyncPerspective = TeamUIPlugin.getPlugin().getPreferenceStore().getString(IPreferenceIds.SYNCVIEW_DEFAULT_PERSPECTIVE); + String currentPerspective = null; + IPerspectiveDescriptor perspectiveDescriptor = registry.findPerspectiveWithId(defaultSyncPerspective); + IWorkbenchPage page = TeamUIPlugin.getActivePage(); + if(page != null) { + IPerspectiveDescriptor p = page.getPerspective(); + if(currentPerspective != null && currentPerspective.equals(defaultSyncPerspective)) { + perspectiveDescriptor = null; + } + } + + if(perspectiveDescriptor != null) { + String perspectiveName = perspectiveDescriptor.getLabel(); + + MessageDialog m = new MessageDialog(Display.getDefault().getActiveShell(), + Policy.bind("SynchronizeManager.27"), //$NON-NLS-1$ + null, // accept the default window icon + Policy.bind("SynchronizeManager.30", perspectiveDescriptor.getLabel()), //$NON-NLS-1$ + MessageDialog.QUESTION, + new String[] {IDialogConstants.YES_LABEL, IDialogConstants.NO_LABEL, Policy.bind("SynchronizeManager.28"), Policy.bind("SynchronizeManager.29")}, //$NON-NLS-1$ //$NON-NLS-2$ + 0); // yes is the default + + int result = m.open(); + switch (result) { + // yes + case 0 : + return true; + // no + case 1 : + return false; + // never + case 2 : + TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCHRONIZING_COMPLETE_PERSPECTIVE, IPreferenceIds.SYNCHRONIZING_COMPLETE_PERSPECTIVE_NEVER); + return false; + // always + case 3 : + TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCHRONIZING_COMPLETE_PERSPECTIVE, IPreferenceIds.SYNCHRONIZING_COMPLETE_PERSPECTIVE_ALWAYS); + return true; + } + } + return false; + } /** * Creates the participant registry and restore any saved participants. diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeModelProvider.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeModelProvider.java new file mode 100644 index 000000000..576117caf --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeModelProvider.java @@ -0,0 +1,448 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ui.synchronize; + +import java.util.*; + +import org.eclipse.compare.structuremergeviewer.IDiffContainer; +import org.eclipse.compare.structuremergeviewer.IDiffElement; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.*; +import org.eclipse.jface.util.IPropertyChangeListener; +import org.eclipse.jface.util.PropertyChangeEvent; +import org.eclipse.jface.viewers.*; +import org.eclipse.swt.custom.BusyIndicator; +import org.eclipse.swt.widgets.Control; +import org.eclipse.team.core.ITeamStatus; +import org.eclipse.team.core.synchronize.*; +import org.eclipse.team.internal.core.Assert; +import org.eclipse.team.internal.ui.Policy; +import org.eclipse.team.internal.ui.TeamUIPlugin; +import org.eclipse.team.ui.synchronize.viewers.*; +import org.eclipse.ui.progress.UIJob; + +/** + * This class is reponsible for creating and maintaining a presentation model of + * {@link SynchronizeModelElement} elements that can be shown in a viewer. The model + * is based on the synchronization information contained in the provided {@link SyncInfoSet}. + * <p> + * label updates (property propagation to parent nodes) + * sync change listener (changes, additions, removals, reset) + * batching busy updates + * </p> + * + * @see HierarchicalModelProvider + * @see CompressedFoldersModelProvider + * @since 3.0 + */ +public abstract class SynchronizeModelProvider implements ISyncInfoSetChangeListener, ISynchronizeModelProvider { + + // Flasg to indicate if tree control should be updated while + // building the model. + private boolean refreshViewer; + + protected Map resourceMap = Collections.synchronizedMap(new HashMap()); + + protected SynchronizeModelElement root; + + // The viewer this input is being displayed in + private StructuredViewer viewer; + + private Set pendingLabelUpdates = new HashSet(); + + private LabelUpdateJob labelUpdater = new LabelUpdateJob(); + + private IPropertyChangeListener listener = new IPropertyChangeListener() { + public void propertyChange(final PropertyChangeEvent event) { + if (event.getProperty() == SynchronizeModelElement.BUSY_PROPERTY) { + labelUpdater.add(event.getSource(), ((Boolean)event.getNewValue()).booleanValue()); + } + } + }; + + class LabelUpdateJob extends UIJob { + public static final int BATCH_WAIT_INCREMENT = 100; + Set nodes = new HashSet(); + public LabelUpdateJob() { + super(Policy.bind("HierarchicalModelProvider.0")); //$NON-NLS-1$ + setSystem(true); + } + public IStatus runInUIThread(IProgressMonitor monitor) { + Object[] updates; + synchronized(nodes) { + updates = nodes.toArray(new Object[nodes.size()]); + nodes.clear(); + } + if (canUpdateViewer()) { + StructuredViewer tree = getViewer(); + tree.update(updates, null); + } + schedule(BATCH_WAIT_INCREMENT); + return Status.OK_STATUS; + } + public void add(Object node, boolean isBusy) { + synchronized(nodes) { + nodes.add(node); + } + if (isBusy) { + schedule(BATCH_WAIT_INCREMENT); + } else { + // Wait when unbusying to give the events a chance to propogate through + // the collector + schedule(BATCH_WAIT_INCREMENT * 10); + } + } + public boolean shouldRun() { + return !nodes.isEmpty(); + } + } + + private SyncInfoSet set; + + /** + * Create an input based on the provide sync set. The input is not + * initialized until <code>prepareInput</code> is called. + * @param set + * the sync set used as the basis for the model created by this + * input. + */ + public SynchronizeModelProvider(SyncInfoSet set) { + this(new UnchangedResourceModelElement(null, ResourcesPlugin.getWorkspace().getRoot()) { + /* + * Override to ensure that the diff viewer will appear in CompareEditorInputs + */ + public boolean hasChildren() { + return true; + } + }, set); + } + + public SynchronizeModelProvider(SynchronizeModelElement parent, SyncInfoSet set) { + Assert.isNotNull(set); + Assert.isNotNull(parent); + this.root = parent; + this.set = set; + } + + public SyncInfoSet getSyncInfoSet() { + return set; + } + + /** + * Return the <code>AbstractTreeViewer</code> asociated with this content + * provider or <code>null</code> if the viewer is not of the proper type. + * @return + */ + public StructuredViewer getViewer() { + return viewer; + } + + public void setViewer(StructuredViewer viewer) { + Assert.isTrue(viewer instanceof AbstractTreeViewer); + this.viewer = (AbstractTreeViewer) viewer; + } + + /** + * Builds the viewer model based on the contents of the sync set. + */ + public SynchronizeModelElement prepareInput(IProgressMonitor monitor) { + // Connect to the sync set which will register us as a listener and give us a reset event + // in a background thread + getSyncInfoSet().connect(this, monitor); + return getModelRoot(); + } + + /** + * The provider can try and return a mapping for the provided object. Providers often use mappings + * to store the source of a logical element they have created. For example, when displaying resource + * based logical elements, a provider will cache the resource -> element mapping for quick retrieval + * of the element when resource based changes are made. + * + * @param object the object to query for a mapping + * @return an object created by this provider that would be shown in a viewer, or <code>null</code> + * if the provided object is not mapped by this provider. + */ + public Object getMapping(Object object) { + return resourceMap.get(object); + } + + /** + * Dispose of the builder + */ + public void dispose() { + resourceMap.clear(); + getSyncInfoSet().removeSyncSetChangedListener(this); + } + + /** + * Returns the input created by this controller or <code>null</code> if + * {@link #prepareInput(IProgressMonitor)} hasn't been called on this object yet. + * @return + */ + public SynchronizeModelElement getModelRoot() { + return root; + } + + public abstract ViewerSorter getViewerSorter(); + + /** + * Return the model object (i.e. an instance of <code>SyncInfoModelElement</code> + * or one of its subclasses) for the given IResource. + * @param resource + * the resource + * @return the <code>SyncInfoModelElement</code> for the given resource + */ + protected SynchronizeModelElement getModelObject(IResource resource) { + return (SynchronizeModelElement) resourceMap.get(resource); + } + + public void syncInfoChanged(final ISyncInfoSetChangeEvent event, IProgressMonitor monitor) { + if (! (event instanceof ISyncInfoTreeChangeEvent)) { + reset(); + } else { + final Control ctrl = getViewer().getControl(); + if (ctrl != null && !ctrl.isDisposed()) { + ctrl.getDisplay().syncExec(new Runnable() { + public void run() { + if (!ctrl.isDisposed()) { + BusyIndicator.showWhile(ctrl.getDisplay(), new Runnable() { + public void run() { + handleChanges((ISyncInfoTreeChangeEvent)event); + getModelRoot().fireChanges(); + } + }); + } + } + }); + } + } + } + + /** + * For each node create children based on the contents of + * @param node + * @return + */ + protected abstract IDiffElement[] buildModelObjects(SynchronizeModelElement node); + + protected abstract void doAdd(SynchronizeModelElement parent, SynchronizeModelElement element); + + protected abstract void doRemove(SynchronizeModelElement element); + + protected void associateDiffNode(SynchronizeModelElement node) { + IResource resource = node.getResource(); + if(resource != null) { + resourceMap.put(resource, node); + } + } + + protected void unassociateDiffNode(IResource resource) { + resourceMap.remove(resource); + } + + /** + * Handle the changes made to the viewer's <code>SyncInfoSet</code>. + * This method delegates the changes to the three methods <code>handleResourceChanges(ISyncInfoSetChangeEvent)</code>, + * <code>handleResourceRemovals(ISyncInfoSetChangeEvent)</code> and + * <code>handleResourceAdditions(ISyncInfoSetChangeEvent)</code>. + * @param event + * the event containing the changed resourcses. + */ + protected void handleChanges(ISyncInfoTreeChangeEvent event) { + StructuredViewer viewer = getViewer(); + try { + viewer.getControl().setRedraw(false); + handleResourceChanges(event); + handleResourceRemovals(event); + handleResourceAdditions(event); + firePendingLabelUpdates(); + } finally { + viewer.getControl().setRedraw(true); + } + } + + /** + * Update the viewer for the sync set additions in the provided event. This + * method is invoked by <code>handleChanges(ISyncInfoSetChangeEvent)</code>. + * Subclasses may override. + * @param event + */ + protected abstract void handleResourceAdditions(ISyncInfoTreeChangeEvent event); + + /** + * Update the viewer for the sync set changes in the provided event. This + * method is invoked by <code>handleChanges(ISyncInfoSetChangeEvent)</code>. + * Subclasses may override. + * @param event + */ + protected abstract void handleResourceChanges(ISyncInfoTreeChangeEvent event); + + protected boolean isConflicting(SynchronizeModelElement diffNode) { + return (diffNode.getKind() & SyncInfo.DIRECTION_MASK) == SyncInfo.CONFLICTING; + } + + /** + * Update the viewer for the sync set removals in the provided event. This + * method is invoked by <code>handleChanges(ISyncInfoSetChangeEvent)</code>. + * Subclasses may override. + * @param event + */ + protected abstract void handleResourceRemovals(ISyncInfoTreeChangeEvent event); + + protected void reset() { + try { + refreshViewer = false; + + // Clear existing model, but keep the root node + resourceMap.clear(); + clearModelObjects(getModelRoot()); + // remove all from tree viewer + IDiffElement[] elements = getModelRoot().getChildren(); + for (int i = 0; i < elements.length; i++) { + doRemove((SynchronizeModelElement)elements[i]); + } + + // Rebuild the model + associateDiffNode(getModelRoot()); + buildModelObjects(getModelRoot()); + + // Notify listeners that model has changed + getModelRoot().fireChanges(); + } finally { + refreshViewer = true; + } + TeamUIPlugin.getStandardDisplay().asyncExec(new Runnable() { + public void run() { + StructuredViewer viewer = getViewer(); + if (viewer != null && !viewer.getControl().isDisposed()) { + viewer.refresh(); + } + } + }); + } + + /** + * Remove any traces of the resource and any of it's descendants in the + * hiearchy defined by the content provider from the content provider and + * the viewer it is associated with. + * @param resource + */ + protected void removeFromViewer(IResource resource) { + SynchronizeModelElement node = getModelObject(resource); + if (node == null) return; + if (isConflicting(node)) { + setParentConflict(node, false); + } + clearModelObjects(node); + if (canUpdateViewer()) { + doRemove(node); + } + } + + /** + * Clear the model objects from the diff tree, cleaning up any cached state + * (such as resource to model object map). This method recurses deeply on + * the tree to allow the cleanup of any cached state for the children as + * well. + * @param node + * the root node + */ + protected void clearModelObjects(SynchronizeModelElement node) { + IDiffElement[] children = node.getChildren(); + for (int i = 0; i < children.length; i++) { + IDiffElement element = children[i]; + if (element instanceof SynchronizeModelElement) { + clearModelObjects((SynchronizeModelElement) element); + } + } + IResource resource = node.getResource(); + if (resource != null) { + unassociateDiffNode(resource); + } + IDiffContainer parent = node.getParent(); + if (parent != null) { + parent.removeToRoot(node); + } + } + + protected void addToViewer(SynchronizeModelElement node) { + associateDiffNode(node); + node.addPropertyChangeListener(listener); + if (isConflicting(node)) { + setParentConflict(node, true); + } + if (canUpdateViewer()) { + doAdd((SynchronizeModelElement)node.getParent(), node); + } + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener#syncInfoSetReset(org.eclipse.team.core.synchronize.SyncInfoSet, org.eclipse.core.runtime.IProgressMonitor) + */ + public void syncInfoSetReset(SyncInfoSet set, IProgressMonitor monitor) { + reset(); + } + + /* (non-Javadoc) + * @see org.eclipse.team.core.synchronize.ISyncInfoSetChangeListener#syncInfoSetErrors(org.eclipse.team.core.synchronize.SyncInfoSet, org.eclipse.team.core.ITeamStatus[], org.eclipse.core.runtime.IProgressMonitor) + */ + 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. + } + + /** + * Update the label of the given diff node. Diff nodes + * are accumulated and updated in a single call. + * @param diffNode the diff node to be updated + */ + protected void updateLabel(SynchronizeModelElement diffNode) { + pendingLabelUpdates.add(diffNode); + } + + /** + * @param tree + * @return + */ + private boolean canUpdateViewer() { + return refreshViewer && getViewer() != null; + } + + /** + * Forces the viewer to update the labels for parents whose children have + * changed during this round of sync set changes. + */ + protected void firePendingLabelUpdates() { + try { + if (canUpdateViewer()) { + StructuredViewer tree = getViewer(); + tree.update(pendingLabelUpdates.toArray(new Object[pendingLabelUpdates.size()]), null); + } + } finally { + pendingLabelUpdates.clear(); + } + } + + protected void setParentConflict(SynchronizeModelElement diffNode, boolean value) { + diffNode.setPropertyToRoot(SynchronizeModelElement.PROPAGATED_CONFLICT_PROPERTY, value); + updateParentLabels(diffNode); + } + + private void updateParentLabels(SynchronizeModelElement diffNode) { + updateLabel(diffNode); + while (diffNode.getParent() != null) { + diffNode = (SynchronizeModelElement)diffNode.getParent(); + updateLabel(diffNode); + } + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeView.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeView.java index 8875ed041..e794f0106 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeView.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/SynchronizeView.java @@ -23,16 +23,9 @@ import org.eclipse.team.internal.ui.Policy; import org.eclipse.team.internal.ui.TeamUIPlugin; import org.eclipse.team.internal.ui.synchronize.actions.SynchronizePageDropDownAction; import org.eclipse.team.ui.TeamUI; -import org.eclipse.team.ui.synchronize.ISynchronizeManager; -import org.eclipse.team.ui.synchronize.ISynchronizeParticipant; -import org.eclipse.team.ui.synchronize.ISynchronizeParticipantListener; -import org.eclipse.team.ui.synchronize.ISynchronizeView; +import org.eclipse.team.ui.synchronize.*; import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.part.IPage; -import org.eclipse.ui.part.IPageBookViewPage; -import org.eclipse.ui.part.MessagePage; -import org.eclipse.ui.part.PageBook; -import org.eclipse.ui.part.PageBookView; +import org.eclipse.ui.part.*; /** * Implements a Synchronize View that contains multiple synchronize participants. diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/TeamSynchronizingPerspective.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/TeamSynchronizingPerspective.java index b28617e0d..3387a7b4c 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/TeamSynchronizingPerspective.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/TeamSynchronizingPerspective.java @@ -10,9 +10,7 @@ *******************************************************************************/ package org.eclipse.team.internal.ui.synchronize; -import org.eclipse.ui.IFolderLayout; -import org.eclipse.ui.IPageLayout; -import org.eclipse.ui.IPerspectiveFactory; +import org.eclipse.ui.*; public class TeamSynchronizingPerspective implements IPerspectiveFactory { diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/GlobalRefreshAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/GlobalRefreshAction.java new file mode 100644 index 000000000..ce43c6c6d --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/GlobalRefreshAction.java @@ -0,0 +1,186 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ui.synchronize.actions; + +import org.eclipse.jface.action.*; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.wizard.IWizard; +import org.eclipse.jface.wizard.WizardDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.*; +import org.eclipse.team.internal.ui.*; +import org.eclipse.team.internal.ui.wizards.GlobalSynchronizeWizard; +import org.eclipse.team.ui.TeamUI; +import org.eclipse.team.ui.synchronize.ISynchronizeParticipant; +import org.eclipse.ui.IWorkbenchWindow; +import org.eclipse.ui.IWorkbenchWindowPulldownDelegate; + +/** + * A global refresh action that allows the user to select the participant to refresh + * or the default action is to refresh the last selected participant. Participants are + * only listed if they support + * <p> + * This action is normally associated with the Team action set and is enabled by default + * in the Team Synchronizing perspective. + * </p> + * @since 3.0 + */ +public class GlobalRefreshAction extends Action implements IMenuCreator, IWorkbenchWindowPulldownDelegate { + + public final static String NO_DEFAULT_PARTICPANT = "none"; //$NON-NLS-1$ + private Menu fMenu; + private Action synchronizeAction; + private IWorkbenchWindow window; + + static class SynchronizeWizardDialog extends WizardDialog { + SynchronizeWizardDialog(Shell parent, IWizard wizard) { + super(parent, wizard); + setShellStyle(getShellStyle()); + setMinimumPageSize(500, 300); + } + } + + class RefreshParticipantAction extends Action { + private ISynchronizeParticipant participant; + + public void run() { + TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCHRONIZING_DEFAULT_PARTICIPANT, participant.getId()); + IWizard wizard = participant.createSynchronizeWizard(); + SynchronizeWizardDialog dialog = new SynchronizeWizardDialog(window.getShell(), wizard); + dialog.open(); + GlobalRefreshAction.this.updateTooltipMessage(); + } + + public RefreshParticipantAction(int prefix, ISynchronizeParticipant participant) { + super("&" + prefix + " " + participant.getName()); //$NON-NLS-1$ //$NON-NLS-2$ + this.participant = participant; + setImageDescriptor(participant.getImageDescriptor()); + } + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.texteditor.IUpdate#update() + */ + public void update() { + ISynchronizeParticipant[] pages = TeamUI.getSynchronizeManager().getSynchronizeParticipants(); + setEnabled(pages.length >= 1); + } + + public GlobalRefreshAction() { + Utils.initAction(this, "action.refreshSubscriber."); //$NON-NLS-1$ + synchronizeAction = new Action(Policy.bind("GlobalRefreshAction.4")) { //$NON-NLS-1$ + public void run() { + IWizard wizard = new GlobalSynchronizeWizard(); + SynchronizeWizardDialog dialog = new SynchronizeWizardDialog(window.getShell(), wizard); + dialog.open(); + } + }; + setMenuCreator(this); + setToolTipText("this is a test"); + //updateTooltipMessage(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.action.IMenuCreator#dispose() + */ + public void dispose() { + if (fMenu != null) { + fMenu.dispose(); + } + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets.Menu) + */ + public Menu getMenu(Menu parent) { + return null; + } + + /* + * (non-Javadoc) + * @see org.eclipse.jface.action.IMenuCreator#getMenu(org.eclipse.swt.widgets.Control) + */ + public Menu getMenu(Control parent) { + if (fMenu != null) { + fMenu.dispose(); + } + fMenu = new Menu(parent); + ISynchronizeParticipant[] participants = TeamUI.getSynchronizeManager().getSynchronizeParticipants(); + for (int i = 0; i < participants.length; i++) { + ISynchronizeParticipant description = participants[i]; + if (description.doesSupportSynchronize()) { + Action action = new RefreshParticipantAction(i + 1, description); + addActionToMenu(fMenu, action); + } + } + addMenuSeparator(); + addActionToMenu(fMenu, synchronizeAction); + return fMenu; + } + + protected void addActionToMenu(Menu parent, Action action) { + ActionContributionItem item = new ActionContributionItem(action); + item.fill(parent, -1); + } + + protected void addMenuSeparator() { + new MenuItem(fMenu, SWT.SEPARATOR); + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow) + */ + public void init(IWorkbenchWindow window) { + this.window = window; + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) + */ + public void run(IAction action) { + String id = TeamUIPlugin.getPlugin().getPreferenceStore().getString(IPreferenceIds.SYNCHRONIZING_DEFAULT_PARTICIPANT); + IWizard wizard = new GlobalSynchronizeWizard(); + if(! id.equals(NO_DEFAULT_PARTICPANT)) { + ISynchronizeParticipant[] participants = TeamUI.getSynchronizeManager().find(id); + if(participants.length > 0) { + wizard = participants[0].createSynchronizeWizard(); + } + } + SynchronizeWizardDialog dialog = new SynchronizeWizardDialog(window.getShell(), wizard); + dialog.open(); + updateTooltipMessage(); + } + + /* + * (non-Javadoc) + * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, + * org.eclipse.jface.viewers.ISelection) + */ + public void selectionChanged(IAction action, ISelection selection) { + } + + protected void updateTooltipMessage() { + String id = TeamUIPlugin.getPlugin().getPreferenceStore().getString(IPreferenceIds.SYNCHRONIZING_DEFAULT_PARTICIPANT); + if(! id.equals(NO_DEFAULT_PARTICPANT)) { + ISynchronizeParticipant[] participants = TeamUI.getSynchronizeManager().find(id); + if(participants.length > 0) { + setToolTipText(Policy.bind("GlobalRefreshAction.5", participants[0].getName())); //$NON-NLS-1$ + } + } else { + setToolTipText(Policy.bind("GlobalRefreshAction.4")); //$NON-NLS-1$ + } + } +}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenInCompareAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenInCompareAction.java index bb4784fc7..0a99a1f94 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenInCompareAction.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenInCompareAction.java @@ -10,7 +10,6 @@ *******************************************************************************/ package org.eclipse.team.internal.ui.synchronize.actions; -import org.eclipse.compare.CompareConfiguration; import org.eclipse.compare.CompareUI; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; @@ -95,9 +94,7 @@ public class OpenInCompareAction extends Action { */ private static SyncInfoCompareInput getCompareInput(ISynchronizeParticipant participant, SyncInfo info) { if (info != null && info.getLocal() instanceof IFile) { - CompareConfiguration cc = new CompareConfiguration(); - //cc.setProperty(CompareConfiguration.USE_OUTLINE_VIEW, Boolean.TRUE); - return new SyncInfoCompareInput(cc, participant.getName(), info); + return new SyncInfoCompareInput(participant.getName(), info); } return null; } diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenWithActionGroup.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenWithActionGroup.java index 71a6d58fc..1d1fd9cfa 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenWithActionGroup.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/OpenWithActionGroup.java @@ -16,8 +16,9 @@ import org.eclipse.jface.action.IMenuManager; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.team.internal.ui.Utils; -import org.eclipse.team.ui.synchronize.*; -import org.eclipse.team.ui.synchronize.subscriber.*; +import org.eclipse.team.ui.synchronize.ISynchronizeParticipant; +import org.eclipse.team.ui.synchronize.ISynchronizeView; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipantPage; import org.eclipse.ui.actions.ActionGroup; import org.eclipse.ui.actions.OpenWithMenu; import org.eclipse.ui.views.navigator.ResourceNavigatorMessages; diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/ShowSynchronizeParticipantAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/ShowSynchronizeParticipantAction.java index e0d21abd6..2714a2500 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/ShowSynchronizeParticipantAction.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/ShowSynchronizeParticipantAction.java @@ -11,8 +11,8 @@ package org.eclipse.team.internal.ui.synchronize.actions; import org.eclipse.jface.action.Action; -import org.eclipse.team.ui.synchronize.ISynchronizeView; import org.eclipse.team.ui.synchronize.ISynchronizeParticipant; +import org.eclipse.team.ui.synchronize.ISynchronizeView; public class ShowSynchronizeParticipantAction extends Action { diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/TeamParticipantRefreshAction.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/TeamParticipantRefreshAction.java deleted file mode 100644 index 1dbb8fce9..000000000 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/synchronize/actions/TeamParticipantRefreshAction.java +++ /dev/null @@ -1,33 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2003 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.team.internal.ui.synchronize.actions; - -import org.eclipse.core.resources.IResource; -import org.eclipse.jface.viewers.ISelectionProvider; -import org.eclipse.team.internal.ui.jobs.RefreshUserNotificationPolicy; -import org.eclipse.team.ui.synchronize.subscriber.RefreshAction; -import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; -import org.eclipse.ui.IWorkbenchSite; - -/** - * A specialized RefreshAction that extracts the required components from a - * particpant. - */ -public class TeamParticipantRefreshAction extends RefreshAction { - - public TeamParticipantRefreshAction(ISelectionProvider provider, SubscriberParticipant participant, boolean addIfNeeded, boolean refreshAll) { - super(provider, participant.getName(), participant.getSubscriberSyncInfoCollector(), new RefreshUserNotificationPolicy(participant, addIfNeeded), refreshAll); - } - - public static void run(IWorkbenchSite site, IResource[] resources, SubscriberParticipant participant, boolean addIfNeeded) { - run(site, participant.getName(), resources, participant.getSubscriberSyncInfoCollector(), new RefreshUserNotificationPolicy(participant, addIfNeeded)); - } -}
\ No newline at end of file diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/GlobalRefreshParticipantSelectionPage.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/GlobalRefreshParticipantSelectionPage.java new file mode 100644 index 000000000..ac82939c1 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/GlobalRefreshParticipantSelectionPage.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ui.wizards; + +import java.util.*; + +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.resource.ImageDescriptor; +import org.eclipse.jface.viewers.*; +import org.eclipse.jface.wizard.*; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.team.ui.TeamUI; +import org.eclipse.team.ui.synchronize.*; +import org.eclipse.ui.model.BaseWorkbenchContentProvider; +import org.eclipse.ui.views.navigator.ResourceSorter; + +/** + * Page that allows the user to select a set of resources that are managed + * by a synchronize participant. + * + * Remembers last participant + * + * @since 3.0 + */ +public class GlobalRefreshParticipantSelectionPage extends WizardPage implements IDoubleClickListener, ISelectionChangedListener { + + private TableViewer fViewer; + private ISynchronizeParticipantDescriptor selectedParticipantDescriptor; + private IWizard wizard; + private ISynchronizeParticipant participant; + private List createdImages; + + class MyContentProvider extends BaseWorkbenchContentProvider { + public Object[] getChildren(Object element) { + if(element instanceof ISynchronizeManager) { + List participants = new ArrayList(); + ISynchronizeManager manager = (ISynchronizeManager)element; + ISynchronizeParticipant[] desciptors = manager.getSynchronizeParticipants(); + for (int i = 0; i < desciptors.length; i++) { + ISynchronizeParticipant descriptor = desciptors[i]; + if(descriptor.doesSupportSynchronize()) { + participants.add(descriptor); + } + } + return (ISynchronizeParticipant[]) participants.toArray(new ISynchronizeParticipant[participants.size()]); + } + return super.getChildren(element); + } + } + + class MyLabelProvider extends LabelProvider { + public String getText(Object element) { + if(element instanceof ISynchronizeParticipant) { + ISynchronizeParticipant descriptor = (ISynchronizeParticipant)element; + return descriptor.getName(); + } + return null; + } + + public Image getImage(Object element) { + if(element instanceof ISynchronizeParticipant) { + ISynchronizeParticipant descriptor = (ISynchronizeParticipant)element; + ImageDescriptor d = descriptor.getImageDescriptor(); + if(createdImages == null) { + createdImages = new ArrayList(3); + } + Image image = d.createImage(); + createdImages.add(image); + return image; + } + return null; + } + } + + public GlobalRefreshParticipantSelectionPage() { + super("Synchronize"); + setDescription("Select the participant to synchronize"); + setTitle("Select a Synchronize Participant"); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#dispose() + */ + public void dispose() { + if (createdImages != null) { + for (Iterator it = createdImages.iterator(); it.hasNext();) { + Image image = (Image) it.next(); + image.dispose(); + } + } + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent2) { + Composite top = new Composite(parent2, SWT.NULL); + top.setLayout(new GridLayout()); + setControl(top); + + Label l = new Label(top, SWT.NULL); + l.setText("Available synchronize participants:"); + fViewer = new TableViewer(top, SWT.BORDER); + GridData data = new GridData(GridData.FILL_BOTH); + fViewer.getControl().setLayoutData(data); + fViewer.setContentProvider(new MyContentProvider()); + fViewer.addDoubleClickListener(this); + fViewer.setLabelProvider(new MyLabelProvider()); + fViewer.setSorter(new ResourceSorter(ResourceSorter.NAME)); + fViewer.setInput(TeamUI.getSynchronizeManager()); + fViewer.addSelectionChangedListener(this); + fViewer.getTable().setFocus(); + Dialog.applyDialogFont(parent2); + } + + public void doubleClick(DoubleClickEvent event) { + selectionChanged( + new SelectionChangedEvent( + event.getViewer(), + event.getViewer().getSelection())); + getContainer().showPage(getNextPage()); + } + + public void selectionChanged(SelectionChangedEvent event) { + // Initialize the wizard so we can tell whether to enable the + // Next button + ISelection selection = event.getSelection(); + if (selection == null || !(selection instanceof IStructuredSelection)) { + wizard = null; + setPageComplete(false); + return; + } + IStructuredSelection ss = (IStructuredSelection) selection; + if (ss.size() != 1) { + wizard = null; + setPageComplete(false); + return; + } + participant = (ISynchronizeParticipant)ss.getFirstElement(); + wizard = participant.createSynchronizeWizard(); + wizard.addPages(); + // Ask the container to update button enablement + setPageComplete(true); + } + + public IWizard getSelectedWizard() { + return this.wizard; + } + + public ISynchronizeParticipant getSelectedParticipant() { + return this.participant; + } + + /** + * The <code>WizardSelectionPage</code> implementation of + * this <code>IWizardPage</code> method returns the first page + * of the currently selected wizard if there is one. + * + * @see WizardPage#getNextPage + */ + public IWizardPage getNextPage() { + if (wizard == null) return null; + return wizard.getStartingPage(); + } + + public void setVisible(boolean visible) { + super.setVisible(visible); + if (visible) { + fViewer.getTable().setFocus(); + } + } +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/GlobalRefreshResourceSelectionPage.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/GlobalRefreshResourceSelectionPage.java new file mode 100644 index 000000000..e269f03b3 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/GlobalRefreshResourceSelectionPage.java @@ -0,0 +1,240 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ui.wizards; + +import java.util.Arrays; +import java.util.List; + +import org.eclipse.core.resources.IContainer; +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.jface.viewers.*; +import org.eclipse.jface.wizard.WizardPage; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Image; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.*; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; +import org.eclipse.ui.*; +import org.eclipse.ui.dialogs.IWorkingSetSelectionDialog; +import org.eclipse.ui.ide.IDE; +import org.eclipse.ui.internal.dialogs.ContainerCheckedTreeViewer; +import org.eclipse.ui.model.BaseWorkbenchContentProvider; +import org.eclipse.ui.model.WorkbenchLabelProvider; +import org.eclipse.ui.views.navigator.ResourceSorter; + +/** + * Page that allows the user to select a set of resources that are managed + * by a synchronize participant. + * + * Remembers last selection + * Remembers last working set + * + * @since 3.0 + */ +public class GlobalRefreshResourceSelectionPage extends WizardPage { + + private SubscriberParticipant participant; + private Button selectOutgoingChanges; + private ContainerCheckedTreeViewer fViewer; + + class MyContentProvider extends BaseWorkbenchContentProvider { + public Object[] getChildren(Object element) { + if(element instanceof SubscriberParticipant) { + return ((SubscriberParticipant)element).getResources(); + } + return super.getChildren(element); + } + } + + class MyLabelProvider extends LabelProvider { + private LabelProvider workbenchProvider = new WorkbenchLabelProvider(); + public String getText(Object element) { + if(element instanceof IContainer) { + IContainer c = (IContainer)element; + List participantRoots = Arrays.asList(participant.getResources()); + if(participantRoots.contains(c)) { + return c.getFullPath().toString(); + } + } + return workbenchProvider.getText(element); + } + public Image getImage(Object element) { + return workbenchProvider.getImage(element); + } + } + + class MyContainerCheckedTree extends ContainerCheckedTreeViewer { + + public MyContainerCheckedTree(Composite parent, int style) { + super(parent, style); + } + + protected void doCheckStateChanged(Object element) { + Widget item = findItem(element); + if (item instanceof TreeItem) { + TreeItem treeItem = (TreeItem) item; + treeItem.setGrayed(false); + //updateChildrenItems(treeItem); + doUpdateParentItems(treeItem.getParentItem()); + } + } + + /** + * Updates the check / gray state of all parent items + */ + private void doUpdateParentItems(TreeItem item) { + if (item != null) { + Item[] children = getChildren(item); + boolean containsChecked = false; + boolean containsUnchecked = false; + for (int i = 0; i < children.length; i++) { + TreeItem curr = (TreeItem) children[i]; + containsChecked |= curr.getChecked(); + containsUnchecked |= (!curr.getChecked() || curr.getGrayed()); + } + item.setChecked(containsChecked); + item.setGrayed(containsChecked && containsUnchecked); + doUpdateParentItems(item.getParentItem()); + } + } + + /* (non-Javadoc) + * @see org.eclipse.ui.internal.dialogs.ContainerCheckedTreeViewer#setExpanded(org.eclipse.swt.widgets.Item, boolean) + */ + protected void setExpanded(Item item, boolean expand) { + ((TreeItem) item).setExpanded(expand); + } + } + + public GlobalRefreshResourceSelectionPage(SubscriberParticipant participant) { + super("Synchronize"); + setDescription("Select the resource to synchronize"); + setTitle("Synchronize"); + setParticipant(participant); + } + + public void setParticipant(SubscriberParticipant participant) { + this.participant = participant; + } + + /* (non-Javadoc) + * @see org.eclipse.jface.dialogs.IDialogPage#createControl(org.eclipse.swt.widgets.Composite) + */ + public void createControl(Composite parent2) { + Composite top = new Composite(parent2, SWT.NULL); + top.setLayout(new GridLayout()); + top.setLayoutData(new GridData(GridData.FILL_BOTH)); + setControl(top); + + if (participant.getSubscriber().roots().length == 0) { + Label l = new Label(top, SWT.NULL); + l.setText("There are no resources associated with '" + participant.getName() + "''."); + } else { + Label l = new Label(top, SWT.NULL); + l.setText("Available resources to Synchronize:"); + fViewer = new ContainerCheckedTreeViewer(top, SWT.BORDER) { + + }; + GridData data = new GridData(GridData.FILL_BOTH); + fViewer.getControl().setLayoutData(data); + fViewer.setContentProvider(new MyContentProvider()); + fViewer.setLabelProvider(new MyLabelProvider()); + fViewer.addCheckStateListener(new ICheckStateListener() { + public void checkStateChanged(CheckStateChangedEvent event) { + updateOKStatus(); + } + }); + fViewer.setSorter(new ResourceSorter(ResourceSorter.NAME)); + fViewer.setInput(participant); + + Composite buttonComposote = new Composite(top, SWT.NULL); + GridLayout layout = new GridLayout(); + layout.marginHeight = 0; + layout.marginWidth = 0; + layout.numColumns = 3; + layout.makeColumnsEqualWidth = true; + buttonComposote.setLayout(layout); + data = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING); + buttonComposote.setLayoutData(data); + + Button selectAll = new Button(buttonComposote, SWT.NULL); + selectAll.setText("&Select All"); + selectAll.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + fViewer.setCheckedElements(participant.getResources()); + updateOKStatus(); + } + }); + data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); + selectAll.setLayoutData(data); + Dialog.applyDialogFont(selectAll); + + Button deSelectAll = new Button(buttonComposote, SWT.NULL); + deSelectAll.setText("&Deselect All"); + deSelectAll.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + fViewer.setCheckedElements(new Object[0]); + updateOKStatus(); + } + }); + data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); + deSelectAll.setLayoutData(data); + Dialog.applyDialogFont(deSelectAll); + + Button selectWorkingSetButton = new Button(buttonComposote, SWT.NULL); + selectWorkingSetButton.setText("&Working Set..."); + selectWorkingSetButton.addSelectionListener(new SelectionAdapter() { + public void widgetSelected(SelectionEvent e) { + IWorkingSetManager manager = PlatformUI.getWorkbench().getWorkingSetManager(); + IWorkingSetSelectionDialog dialog = manager.createWorkingSetSelectionDialog(getShell(), false); + dialog.open(); + IWorkingSet[] workingSet = dialog.getSelection(); + if(workingSet != null) { + for (int i = 0; i < workingSet.length; i++) { + IWorkingSet set = workingSet[i]; + List resources = IDE.computeSelectedResources(new StructuredSelection(set.getElements())); + if(! resources.isEmpty()) { + fViewer.setCheckedElements((IResource[])resources.toArray(new IResource[resources.size()])); + } + } + updateOKStatus(); + } + } + }); + data = new GridData(GridData.HORIZONTAL_ALIGN_FILL); + selectWorkingSetButton.setLayoutData(data); + Dialog.applyDialogFont(selectWorkingSetButton); + } + updateOKStatus(); + Dialog.applyDialogFont(top); + } + + protected void updateOKStatus() { + if(fViewer != null) { + setPageComplete(fViewer.getCheckedElements().length > 0); + } else { + setPageComplete(true); + } + } + + public IResource[] getSelectedResources() { + if(fViewer != null) { + List resources = IDE.computeSelectedResources(new StructuredSelection(fViewer.getCheckedElements())); + return (IResource[]) resources.toArray(new IResource[resources.size()]); + } else { + return null; + } + } +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/GlobalSynchronizeWizard.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/GlobalSynchronizeWizard.java new file mode 100644 index 000000000..5844001d9 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/GlobalSynchronizeWizard.java @@ -0,0 +1,137 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ui.wizards; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.jface.wizard.*; +import org.eclipse.team.internal.ui.IPreferenceIds; +import org.eclipse.team.internal.ui.TeamUIPlugin; +import org.eclipse.team.ui.*; +import org.eclipse.team.ui.synchronize.ISynchronizeManager; +import org.eclipse.team.ui.synchronize.ISynchronizeParticipant; +import org.eclipse.ui.IWorkbench; + +/** + * The wizard for synchronizing a synchronize participant. + * + * @since 3.0 + */ +public class GlobalSynchronizeWizard extends Wizard { + + protected IWorkbench workbench; + protected IWizard wizard; + protected GlobalRefreshParticipantSelectionPage mainPage; + protected ISynchronizeParticipant participant; + private String pluginId = TeamUIPlugin.PLUGIN_ID; + + public GlobalSynchronizeWizard() { + setNeedsProgressMonitor(true); + setWindowTitle("Synchronize"); //$NON-NLS-1$ + setDefaultPageImageDescriptor(TeamImages.getImageDescriptor(ISharedImages.IMG_WIZBAN_SHARE)); + setForcePreviousAndNextButtons(true); + } + + /* + * @see Wizard#addPages + */ + public void addPages() { + ISynchronizeParticipant[] participants = getParticipants(); + if (participants.length == 1) { + // If there is only one wizard, skip the first page. + // Only skip the first page if the one wizard has at least one + // page. + participant = participants[0]; + IWizard wizard = participants[0].createSynchronizeWizard(); + wizard.addPages(); + if (wizard.getPageCount() > 0) { + wizard.setContainer(getContainer()); + IWizardPage[] pages = wizard.getPages(); + for (int i = 0; i < pages.length; i++) { + addPage(pages[i]); + } + return; + } + } + mainPage = new GlobalRefreshParticipantSelectionPage(); + addPage(mainPage); + } + + public IWizardPage getNextPage(IWizardPage page) { + if (wizard != null) { + return wizard.getNextPage(page); + } + return super.getNextPage(page); + } + + public boolean canFinish() { + // If we are on the first page, never allow finish unless the selected + // wizard has no pages. + if (getContainer().getCurrentPage() == mainPage) { + if (mainPage.getSelectedWizard() != null && mainPage.getNextPage() == null) { + return true; + } + return false; + } + if (wizard != null) { + return wizard.canFinish(); + } + return super.canFinish(); + } + + /* + * @see Wizard#performFinish + */ + public boolean performFinish() { + // There is only one wizard with at least one page + if (wizard != null) { + TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCHRONIZING_DEFAULT_PARTICIPANT, getSelectedParticipant().getId()); + return wizard.performFinish(); + } + // If we are on the first page and the selected wizard has no pages then allow it to finish. + if (getContainer().getCurrentPage() == mainPage) { + IWizard noPageWizard = mainPage.getSelectedWizard(); + if (noPageWizard != null) { + if (noPageWizard.canFinish()) { + TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCHRONIZING_DEFAULT_PARTICIPANT, getSelectedParticipant().getId()); + return noPageWizard.performFinish(); + } + } + } + // If the wizard has pages and there are several + // wizards registered then the registered wizard + // will call it's own performFinish(). + TeamUIPlugin.getPlugin().getPreferenceStore().setValue(IPreferenceIds.SYNCHRONIZING_DEFAULT_PARTICIPANT, getSelectedParticipant().getId()); + return true; + } + + protected ISynchronizeParticipant[] getParticipants() { + List participants = new ArrayList(); + ISynchronizeManager manager = (ISynchronizeManager) TeamUI.getSynchronizeManager(); + ISynchronizeParticipant[] desciptors = manager.getSynchronizeParticipants(); + for (int i = 0; i < desciptors.length; i++) { + ISynchronizeParticipant descriptor = desciptors[i]; + if (descriptor.doesSupportSynchronize()) { + participants.add(descriptor); + } + } + return (ISynchronizeParticipant[]) participants.toArray(new ISynchronizeParticipant[participants.size()]); + } + + protected ISynchronizeParticipant getSelectedParticipant() { + if(participant == null && mainPage != null) { + return mainPage.getSelectedParticipant(); + } else { + return participant; + } + } +} diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ProjectSetImportWizard.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ProjectSetImportWizard.java index f29f19f97..34e57b626 100644 --- a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ProjectSetImportWizard.java +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/ProjectSetImportWizard.java @@ -10,19 +10,11 @@ *******************************************************************************/ package org.eclipse.team.internal.ui.wizards; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; +import java.io.*; import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; +import javax.xml.parsers.*; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.IProgressMonitor; @@ -30,17 +22,10 @@ import org.eclipse.jface.dialogs.ErrorDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.wizard.Wizard; -import org.eclipse.team.core.IProjectSetSerializer; -import org.eclipse.team.core.Team; -import org.eclipse.team.core.TeamException; -import org.eclipse.team.internal.ui.Policy; -import org.eclipse.team.internal.ui.ProjectSetContentHandler; -import org.eclipse.team.internal.ui.TeamUIPlugin; +import org.eclipse.team.core.*; +import org.eclipse.team.internal.ui.*; import org.eclipse.team.ui.ISharedImages; -import org.eclipse.ui.IImportWizard; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkingSet; -import org.eclipse.ui.IWorkingSetManager; +import org.eclipse.ui.*; import org.eclipse.ui.actions.WorkspaceModifyOperation; import org.xml.sax.InputSource; import org.xml.sax.SAXException; diff --git a/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/SubscriberRefreshWizard.java b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/SubscriberRefreshWizard.java new file mode 100644 index 000000000..fdc4fafa7 --- /dev/null +++ b/bundles/org.eclipse.team.ui/src/org/eclipse/team/internal/ui/wizards/SubscriberRefreshWizard.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.team.internal.ui.wizards; + +import org.eclipse.core.resources.IResource; +import org.eclipse.jface.wizard.Wizard; +import org.eclipse.team.internal.ui.Policy; +import org.eclipse.team.ui.ISharedImages; +import org.eclipse.team.ui.TeamImages; +import org.eclipse.team.ui.synchronize.subscriber.SubscriberParticipant; + +public class SubscriberRefreshWizard extends Wizard { + + private SubscriberParticipant participant; + private GlobalRefreshResourceSelectionPage selectionPage; + + public SubscriberRefreshWizard(SubscriberParticipant participant) { + this.participant = participant; + setWindowTitle(Policy.bind("SubscriberRefreshWizard.0") + participant.getName()); //$NON-NLS-1$ + setDefaultPageImageDescriptor(TeamImages.getImageDescriptor(ISharedImages.IMG_WIZBAN_SHARE)); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.wizard.Wizard#addPages() + */ + public void addPages() { + selectionPage = new GlobalRefreshResourceSelectionPage(participant); + addPage(selectionPage); + } + + /* (non-Javadoc) + * @see org.eclipse.jface.wizard.IWizard#performFinish() + */ + public boolean performFinish() { + IResource[] resources = selectionPage.getSelectedResources(); + if(resources != null) { + participant.refresh(resources); + } + return true; + } +} |