Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 273450 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/compare/tests/ContentMergeViewerTest.java (-6 / +13 lines)
Lines 21-26 Link Here
21
public class ContentMergeViewerTest extends TestCase {
21
public class ContentMergeViewerTest extends TestCase {
22
22
23
	private MyContentMergeViewer myContentMergeViewer;
23
	private MyContentMergeViewer myContentMergeViewer;
24
	/**
25
	 * result[0]-event occurred or not; result[1]-new state that was set
26
	 */
24
	boolean[] result = new boolean[] { false, false };
27
	boolean[] result = new boolean[] { false, false };
25
28
26
	public ContentMergeViewerTest() {
29
	public ContentMergeViewerTest() {
Lines 40-50 Link Here
40
		public boolean leftDirty = false;
43
		public boolean leftDirty = false;
41
		public boolean rightDirty = false;
44
		public boolean rightDirty = false;
42
45
43
		protected boolean isLeftDirty() {
46
		public boolean isLeftDirty() {
44
			return leftDirty;
47
			return leftDirty;
45
		}
48
		}
46
49
47
		protected boolean isRightDirty() {
50
		public boolean isRightDirty() {
48
			return rightDirty;
51
			return rightDirty;
49
		}
52
		}
50
53
Lines 109-115 Link Here
109
		myContentMergeViewer.rightDirty = true;
112
		myContentMergeViewer.rightDirty = true;
110
		myContentMergeViewer.setLeftDirty(true);
113
		myContentMergeViewer.setLeftDirty(true);
111
114
112
		Assert.assertEquals(false, result[0]);
115
		Assert.assertEquals(true, result[0]);
116
		Assert.assertEquals(true, result[1]);
113
	}
117
	}
114
118
115
	public void testTFTX() {
119
	public void testTFTX() {
Lines 160-166 Link Here
160
		myContentMergeViewer.rightDirty = true;
164
		myContentMergeViewer.rightDirty = true;
161
		myContentMergeViewer.setLeftDirty(false);
165
		myContentMergeViewer.setLeftDirty(false);
162
166
163
		Assert.assertEquals(false, result[0]);
167
		Assert.assertEquals(true, result[0]);
168
		Assert.assertEquals(false, result[1]);
164
	}
169
	}
165
170
166
	// set right to true
171
	// set right to true
Lines 187-193 Link Here
187
		myContentMergeViewer.rightDirty = false;
192
		myContentMergeViewer.rightDirty = false;
188
		myContentMergeViewer.setRightDirty(true);
193
		myContentMergeViewer.setRightDirty(true);
189
194
190
		Assert.assertEquals(false, result[0]);
195
		Assert.assertEquals(true, result[0]);
196
		Assert.assertEquals(true, result[1]);
191
	}
197
	}
192
198
193
	public void testTTXT() {
199
	public void testTTXT() {
Lines 230-235 Link Here
230
		myContentMergeViewer.rightDirty = true;
236
		myContentMergeViewer.rightDirty = true;
231
		myContentMergeViewer.setRightDirty(false);
237
		myContentMergeViewer.setRightDirty(false);
232
238
233
		Assert.assertEquals(false, result[0]);
239
		Assert.assertEquals(true, result[0]);
240
		Assert.assertEquals(false, result[1]);
234
	}
241
	}
235
}
242
}
(-)compare/org/eclipse/compare/contentmergeviewer/ContentMergeViewer.java (-8 / +6 lines)
Lines 1168-1176 Link Here
1168
	protected void setLeftDirty(boolean dirty) {
1168
	protected void setLeftDirty(boolean dirty) {
1169
		if (isLeftDirty() != dirty) {
1169
		if (isLeftDirty() != dirty) {
1170
			fIsLeftDirty = dirty;
1170
			fIsLeftDirty = dirty;
1171
			// Only fire the event if the combined dirty state has changed
1171
			// Always fire the event if the dirty state has changed
1172
			if (!isRightDirty())
1172
			fireDirtyState(dirty);
1173
				fireDirtyState(dirty);
1174
		}
1173
		}
1175
	}
1174
	}
1176
	
1175
	
Lines 1186-1194 Link Here
1186
	protected void setRightDirty(boolean dirty) {
1185
	protected void setRightDirty(boolean dirty) {
1187
		if (isRightDirty() != dirty) {
1186
		if (isRightDirty() != dirty) {
1188
			fIsRightDirty = dirty;
1187
			fIsRightDirty = dirty;
1189
			// Only fire the event if the combined dirty state has changed
1188
			// Always fire the event if the dirty state has changed
1190
			if (!isLeftDirty())
1189
			fireDirtyState(dirty);
1191
				fireDirtyState(dirty);
1192
		}
1190
		}
1193
	}
1191
	}
1194
	
1192
	
Lines 1256-1262 Link Here
1256
	 * @return the dirty state of the right side of this viewer
1254
	 * @return the dirty state of the right side of this viewer
1257
	 * @since 3.3
1255
	 * @since 3.3
1258
	 */
1256
	 */
1259
	protected boolean isRightDirty() {
1257
	public boolean isRightDirty() {
1260
		return fIsRightDirty;
1258
		return fIsRightDirty;
1261
	}
1259
	}
1262
1260
Lines 1265-1271 Link Here
1265
	 * @return the dirty state of the left side of this viewer
1263
	 * @return the dirty state of the left side of this viewer
1266
	 * @since 3.3
1264
	 * @since 3.3
1267
	 */
1265
	 */
1268
	protected boolean isLeftDirty() {
1266
	public boolean isLeftDirty() {
1269
		return fIsLeftDirty;
1267
		return fIsLeftDirty;
1270
	}
1268
	}
1271
1269
(-)compare/org/eclipse/compare/CompareEditorInput.java (-30 / +88 lines)
Lines 14-19 Link Here
14
import java.util.ArrayList;
14
import java.util.ArrayList;
15
import java.util.ResourceBundle;
15
import java.util.ResourceBundle;
16
16
17
import org.eclipse.compare.contentmergeviewer.ContentMergeViewer;
17
import org.eclipse.compare.contentmergeviewer.IFlushable;
18
import org.eclipse.compare.contentmergeviewer.IFlushable;
18
import org.eclipse.compare.internal.BinaryCompareViewer;
19
import org.eclipse.compare.internal.BinaryCompareViewer;
19
import org.eclipse.compare.internal.ChangePropertyAction;
20
import org.eclipse.compare.internal.ChangePropertyAction;
Lines 191-198 Link Here
191
	private String fTitle;
192
	private String fTitle;
192
	private ListenerList fListenerList= new ListenerList();
193
	private ListenerList fListenerList= new ListenerList();
193
	private CompareNavigator fNavigator;
194
	private CompareNavigator fNavigator;
194
	private boolean fDirty= false;
195
	private ArrayList fLeftDirtyViewers = new ArrayList();
195
	private ArrayList fDirtyViewers= new ArrayList();
196
	private ArrayList fRightDirtyViewers = new ArrayList();
196
	private IPropertyChangeListener fDirtyStateListener;
197
	private IPropertyChangeListener fDirtyStateListener;
197
	
198
	
198
	boolean fStructureCompareOnSingleClick= true;
199
	boolean fStructureCompareOnSingleClick= true;
Lines 989-1006 Link Here
989
	}
990
	}
990
	
991
	
991
	/**
992
	/**
992
	 * Returns <code>true</code> if there are unsaved changes.
993
	 * Returns <code>true</code> if there are unsaved changes in either left or
993
	 * The value returned is the value of the <code>DIRTY_STATE</code> property of this input object.
994
	 * right side. The value returned is the value of the
994
	 
995
	 * <code>DIRTY_STATE</code> property of this input object.
995
	 * Returns <code>true</code> if this input has unsaved changes,
996
	 * 
996
	 * that is if <code>setDirty(true)</code> has been called.
997
	 * Returns <code>true</code> if left or right side has unsaved changes
997
	 * Subclasses don't have to override if the functionality provided by <code>setDirty</code>
998
	 * Subclasses don't have to override if the functionality provided by
998
	 * is sufficient.
999
	 * <code>setDirty</code> is sufficient.
999
	 *
1000
	 * 
1000
	 * @return <code>true</code> if there are changes that need to be saved
1001
	 * @return <code>true</code> if there are changes that need to be saved
1001
	 */
1002
	 */
1002
	public boolean isSaveNeeded() {
1003
	public boolean isSaveNeeded() {
1003
		return fDirty || fDirtyViewers.size() > 0;
1004
		return isLeftSaveNeeded() || isRightSaveNeeded();
1005
	}
1006
1007
	/**
1008
	 * Returns <code>true</code> if there are unsaved changes for left side.
1009
	 * 
1010
	 * @return <code>true</code> if there are changes that need to be saved
1011
	 */
1012
	protected boolean isLeftSaveNeeded() {
1013
		return fLeftDirtyViewers.size() > 0;
1014
	}
1015
1016
	/**
1017
	 * Returns <code>true</code> if there are unsaved changes for right side.
1018
	 * 
1019
	 * @return <code>true</code> if there are changes that need to be saved
1020
	 */
1021
	protected boolean isRightSaveNeeded() {
1022
		return fRightDirtyViewers.size() > 0;
1004
	}
1023
	}
1005
	
1024
	
1006
	/**
1025
	/**
Lines 1017-1047 Link Here
1017
	}
1036
	}
1018
		
1037
		
1019
	/**
1038
	/**
1020
	 * Sets the dirty state of this input to the given
1039
	 * Sets the dirty state of this input to the given value and sends out a
1021
	 * value and sends out a <code>PropertyChangeEvent</code> if the new value differs from the old value.
1040
	 * <code>PropertyChangeEvent</code> if the new value differs from the old
1022
	 *
1041
	 * value. Direct calling this method with parameter dirty equal to
1023
	 * @param dirty the dirty state for this compare input
1042
	 * <code>false</code> when there are unsaved changes in viewers, results in
1043
	 * inconsistent state. The dirty state of compare input should be based only
1044
	 * on the information if there are changes in viewers for left or right
1045
	 * side.
1046
	 * 
1047
	 * @param dirty
1048
	 *            the dirty state for this compare input
1024
	 */
1049
	 */
1025
	public void setDirty(boolean dirty) {
1050
	public void setDirty(boolean dirty) {
1026
		boolean oldDirty = fDirty || fDirtyViewers.size() > 0;
1051
		boolean oldDirty = isSaveNeeded();
1027
		fDirty= dirty;
1052
		boolean newDirty = dirty || isSaveNeeded();
1028
		if (!fDirty)
1053
		if (!newDirty) {
1029
			fDirtyViewers.clear();
1054
			fLeftDirtyViewers.clear();
1030
		if (oldDirty != dirty)
1055
			fRightDirtyViewers.clear();
1031
			Utilities.firePropertyChange(fListenerList, this, DIRTY_STATE, new Boolean(oldDirty), new Boolean(dirty));
1056
		}
1057
		if (oldDirty != isSaveNeeded()) {
1058
			Utilities.firePropertyChange(fListenerList, this, DIRTY_STATE, Boolean.valueOf(oldDirty), Boolean.valueOf(isSaveNeeded()));
1059
		}
1032
	}
1060
	}
1033
	
1061
	
1062
	/**
1063
	 * Method adds or removes viewers that changed left or right side of this
1064
	 * compare input. Any modification of any of the list of viewers may result
1065
	 * in dirty state change.
1066
	 * 
1067
	 * @param source
1068
	 *            the object that fired <code>PropertyChangeEvent</code>
1069
	 *            modifying the dirty state
1070
	 * @param dirty
1071
	 *            value that describes if the changes were added or removed
1072
	 */
1034
	private void setDirty(Object source, boolean dirty) {
1073
	private void setDirty(Object source, boolean dirty) {
1035
		Assert.isNotNull(source);
1074
		Assert.isNotNull(source);
1036
		boolean oldDirty= fDirty || fDirtyViewers.size() > 0;
1075
		boolean oldDirty = isSaveNeeded();
1037
		if (dirty)
1076
		ContentMergeViewer cmv = (ContentMergeViewer) source;
1038
			fDirtyViewers.add(source);
1077
		if (dirty) {
1039
		else
1078
			if (cmv.isLeftDirty()) {
1040
			fDirtyViewers.remove(source);
1079
				if (!fLeftDirtyViewers.contains(source)) {
1041
		boolean newDirty= fDirty || fDirtyViewers.size() > 0;
1080
					fLeftDirtyViewers.add(source);
1042
		if (DEBUG) System.out.println("setDirty("+source+", "+dirty+"): " + newDirty); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1081
				}
1043
		if (oldDirty != newDirty)
1082
			}
1044
			Utilities.firePropertyChange(fListenerList, this, DIRTY_STATE, new Boolean(oldDirty), new Boolean(newDirty));
1083
			if (cmv.isRightDirty()) {
1084
				if (!fRightDirtyViewers.contains(source)) {
1085
					fRightDirtyViewers.add(source);
1086
				}
1087
			}
1088
		} else {
1089
			if (!cmv.isLeftDirty()) {
1090
				fLeftDirtyViewers.remove(source);
1091
			}
1092
			if (!cmv.isRightDirty()) {
1093
				fRightDirtyViewers.remove(source);
1094
			}
1095
		}
1096
		boolean newDirty = isSaveNeeded();
1097
		if (DEBUG) {
1098
			System.out.println("setDirty(" + source + ", " + dirty + "): " + newDirty); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1099
		}
1100
		if (oldDirty != newDirty) {
1101
			Utilities.firePropertyChange(fListenerList, this, DIRTY_STATE, Boolean.valueOf(oldDirty), Boolean.valueOf(newDirty));
1102
		}
1045
	}
1103
	}
1046
	
1104
	
1047
	/* (non Javadoc)
1105
	/* (non Javadoc)
(-)src/org/eclipse/team/internal/ui/synchronize/SaveablesCompareEditorInput.java (+21 lines)
Lines 357-362 Link Here
357
		return super.isDirty();
357
		return super.isDirty();
358
	}
358
	}
359
359
360
	public boolean isSaveNeeded(Saveable arg) {
361
		// Method gives information if the Saveable given as a parameter needs
362
		// to be saved. Parameter arg can be either equal to fLeftSaveable or to
363
		// fRightSaveable. If the parameter is null or differs from both left
364
		// and right Saveable then default isSaveNeeded() is called. Default
365
		// method isSaveNeeded() is not aware which Saveable we wish to check
366
		// therefore it returns the state of the whole CompareEditorInput.
367
		// Whenever possible this method should be called instead of default
368
		// isSaveNeeded(). See bug 273450.
369
		if (arg == null) {
370
			return isSaveNeeded();
371
		}
372
		if (arg.equals(fLeftSaveable)) {
373
			return isLeftSaveNeeded();
374
		}
375
		if (arg.equals(fRightSaveable)) {
376
			return isRightSaveNeeded();
377
		}
378
		return isSaveNeeded();
379
	}
380
	
360
	/**
381
	/**
361
	 * Close the editor if it is not dirty. If it is still dirty, let the
382
	 * Close the editor if it is not dirty. If it is still dirty, let the
362
	 * content merge viewer handle the compare input change.
383
	 * content merge viewer handle the compare input change.
(-)src/org/eclipse/team/internal/ui/synchronize/LocalResourceSaveableComparison.java (+15 lines)
Lines 206-211 Link Here
206
	public boolean isDirty() {
206
	public boolean isDirty() {
207
		// We need to get the dirty state from the compare editor input
207
		// We need to get the dirty state from the compare editor input
208
		// since it is our only connection to the merge viewer
208
		// since it is our only connection to the merge viewer
209
		if (editorInput instanceof SaveablesCompareEditorInput) {
210
			return ((SaveablesCompareEditorInput) editorInput).isSaveNeeded(this);
211
		}
209
		return editorInput.isSaveNeeded();
212
		return editorInput.isSaveNeeded();
210
	}
213
	}
211
	
214
	
Lines 232-237 Link Here
232
	 * @see org.eclipse.ui.Saveable#getName()
235
	 * @see org.eclipse.ui.Saveable#getName()
233
	 */
236
	 */
234
	public String getName() {
237
	public String getName() {
238
		// When we compare two files with each other we need to know the exact
239
		// name of each of the files, not the name taken from the input. Input
240
		// gives the name based on the main element of the input. The way how
241
		// the main element is calculated is described in method
242
		// org.eclipse.team.internal.ui.mapping.AbstractCompareInput#getMainElement()
243
		// See bug 273450.
244
		if (fileElement.equals(input.getLeft())) {
245
			return input.getLeft().getName();
246
		}
247
		if (fileElement.equals(input.getRight())) {
248
			return input.getRight().getName();
249
		}
235
		return input.getName();
250
		return input.getName();
236
	}
251
	}
237
252

Return to bug 273450