Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 50fe7d68490180e6ee2917e69742b24a77d27b07 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
/*******************************************************************************
 * Copyright (c) 2000, 2017 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.internal.ui.synchronize;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.action.*;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.team.internal.ui.Policy;
import org.eclipse.team.internal.ui.Utils;
import org.eclipse.team.internal.ui.synchronize.actions.DirectionFilterActionGroup;
import org.eclipse.team.ui.synchronize.*;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.part.*;

/**
 * Abstract synchronize page that can filter changes by mode (incoming, outgoing,
 * both or conflicting). It also uses forms to indicate when a model is empty and
 * provide a link to a non-empty mode.
 */
public abstract class AbstractSynchronizePage extends Page implements ISynchronizePage, IAdaptable {

	private ISynchronizePageConfiguration configuration;
	private ISynchronizePageSite site;

	// Parent composite of this view. It is remembered so that we can dispose of its children when
	// the viewer type is switched.
	private Composite composite;
	private ChangesSection changesSection;
	private Viewer changesViewer;

	private AbstractViewerAdvisor viewerAdvisor;

	/*
	 * Contribute actions for changing modes to the page.
	 */
	class ModeFilterActions extends SynchronizePageActionGroup {
		private DirectionFilterActionGroup modes;
		@Override
		public void initialize(ISynchronizePageConfiguration configuration) {
			super.initialize(configuration);
			if (isThreeWay()) {
				modes = new DirectionFilterActionGroup(configuration);
			}
		}
		@Override
		public void fillActionBars(IActionBars actionBars) {
			super.fillActionBars(actionBars);
			if (modes == null) return;
			IToolBarManager manager = actionBars.getToolBarManager();
			IContributionItem group = findGroup(manager, ISynchronizePageConfiguration.MODE_GROUP);
			if (manager != null && group != null) {
				modes.fillToolBar(group.getId(), manager);
			}
			IMenuManager viewMenu = actionBars.getMenuManager();
			group = findGroup(manager, ISynchronizePageConfiguration.MODE_GROUP);
			if (viewMenu != null && group != null) {
				IContributionItem layoutGroup = findGroup(manager, ISynchronizePageConfiguration.LAYOUT_GROUP);
				if (layoutGroup != null) {
					// Put the modes in the layout group to save space
					group = layoutGroup;
				}
				MenuManager modesItem = new MenuManager(Utils.getString("action.modes.label", Policy.getActionBundle())); //$NON-NLS-1$
				viewMenu.appendToGroup(group.getId(), modesItem);
				modes.fillMenu(modesItem);
			}
		}
		private boolean isThreeWay() {
			return ISynchronizePageConfiguration.THREE_WAY.equals(configuration.getComparisonType());
		}
	}

	/**
	 * Create a new instance of the page
	 * @param configuration a synchronize page configuration
	 */
	protected AbstractSynchronizePage(ISynchronizePageConfiguration configuration) {
		this.configuration = configuration;
		configuration.setPage(this);
		configuration.addActionContribution(new ModeFilterActions());
	}

	@Override
	public void createControl(Composite parent) {
		composite = new Composite(parent, SWT.NONE);
		//sc.setContent(composite);
		GridLayout gridLayout= new GridLayout();
		gridLayout.makeColumnsEqualWidth= false;
		gridLayout.marginWidth= 0;
		gridLayout.marginHeight = 0;
		gridLayout.verticalSpacing = 0;
		composite.setLayout(gridLayout);
		GridData data = new GridData(GridData.FILL_BOTH);
		data.grabExcessVerticalSpace = true;
		composite.setLayoutData(data);

		// Create the changes section which, in turn, creates the changes viewer and its configuration
		this.changesSection = createChangesSection(composite);
		createChangesViewer(changesSection.getContainer());
		changesSection.setViewer(changesViewer);
	}

	/**
	 * Create the changes section that will contain the changes viewer.
	 * @return the changes section that will contain the changes viewer
	 */
	protected abstract ChangesSection createChangesSection(Composite parent);

	/**
	 * Return the viewer that will display the changes associated
	 * with the page.
	 *
	 * @param parent the parent of the viewer
	 */
	private void createChangesViewer(Composite parent) {
		viewerAdvisor = createViewerAdvisor(parent);
		changesViewer = viewerAdvisor.getViewer();
		viewerAdvisor.setInitialInput();
	}

	protected abstract AbstractViewerAdvisor createViewerAdvisor(Composite parent);

	public AbstractViewerAdvisor getViewerAdvisor() {
		return viewerAdvisor;
	}

	@Override
	public void setActionBars(IActionBars actionBars) {
		// Delegate menu creation to the advisor
		viewerAdvisor.setActionBars(actionBars);
	}

	@Override
	public Control getControl() {
		return composite;
	}

	@Override
	public void setFocus() {
		changesSection.setFocus();
	}

	@Override
	public void init(ISynchronizePageSite site) {
		this.site = site;
		IDialogSettings settings = getSettings();
		if (settings != null) {
			try {
				int mode = settings.getInt(ISynchronizePageConfiguration.P_MODE);
				if (mode != 0) {
					configuration.setMode(mode);
				}
			} catch (NumberFormatException e) {
				// The mode settings does not exist.
				// Leave the mode as is (assuming the
				// participant initialized it to an
				// appropriate value
			}
		}
	}

	@Override
	public void dispose() {
		changesSection.dispose();
		composite.dispose();
		super.dispose();
	}

	@Override
	public Viewer getViewer() {
		return changesViewer;
	}

	@Override
	public boolean aboutToChangeProperty(
			ISynchronizePageConfiguration configuration, String key,
			Object newValue) {
		if (key.equals(ISynchronizePageConfiguration.P_MODE)) {
			return (internalSetMode(configuration.getMode(), ((Integer)newValue).intValue()));
		}
		return true;
	}

	private boolean internalSetMode(int oldMode, int mode) {
		if(oldMode == mode) return false;
		updateMode(mode);
		IDialogSettings settings = getSettings();
		if (settings != null) {
			settings.put(ISynchronizePageConfiguration.P_MODE, mode);
		}
		return true;
	}

	/*
	 * This method enables "Show In" support for this view
	 *
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> key) {
		if (key.equals(ISelectionProvider.class))
			return (T) changesViewer;
		if (key == IShowInSource.class) {
			return (T) (IShowInSource) () -> {
				StructuredViewer v = (StructuredViewer)changesViewer;
				if (v == null) return null;
				ISelection s = v.getSelection();
				if (s instanceof IStructuredSelection) {
					Object[] resources = Utils.getResources(((IStructuredSelection)s).toArray());
					return new ShowInContext(null, new StructuredSelection(resources));
				}
				return null;
			};
		}
		if (key == IShowInTargetList.class) {
			return (T) (IShowInTargetList) () -> new String[] { IPageLayout.ID_RES_NAV };
		}
		return null;
	}

	/**
	 * Return the page site that was assigned to this page.
	 * @return the page site that was assigned to this page
	 */
	public ISynchronizePageSite getSynchronizePageSite() {
		return site;
	}

	/**
	 * Return the synchronize page configuration that was used to create
	 * this page.
	 * @return Returns the configuration.
	 */
	public ISynchronizePageConfiguration getConfiguration() {
		return configuration;
	}

	/**
	 * Return the settings for the page from the configuration
	 * os <code>null</code> if settings can not be persisted
	 * for the page
	 * @return the persisted page settings
	 */
	protected IDialogSettings getSettings() {
		return configuration.getSite().getPageSettings();
	}

	/**
	 * Callback from the changes section that indicates that the
	 * user has chosen to reset the view contents after an error
	 * has occurred
	 */
	public abstract void reset();

	/**
	 * Change the mode to the given mode. This method is invoked
	 * when the mode in the configuration is changed by a client.
	 * @param mode the mode to be used
	 */
	protected abstract void updateMode(int mode);

	public ChangesSection getChangesSection() {
		return changesSection;
	}
}

Back to the top