|
Lines 25-40
Link Here
|
| 25 |
import org.eclipse.compare.internal.CompareHandlerService; |
25 |
import org.eclipse.compare.internal.CompareHandlerService; |
| 26 |
import org.eclipse.compare.internal.CompareMessages; |
26 |
import org.eclipse.compare.internal.CompareMessages; |
| 27 |
import org.eclipse.compare.internal.ICompareUIConstants; |
27 |
import org.eclipse.compare.internal.ICompareUIConstants; |
|
|
28 |
import org.eclipse.compare.internal.IFlushable2; |
| 29 |
import org.eclipse.compare.internal.ISavingStateProvider; |
| 28 |
import org.eclipse.compare.internal.MergeViewerContentProvider; |
30 |
import org.eclipse.compare.internal.MergeViewerContentProvider; |
| 29 |
import org.eclipse.compare.internal.Utilities; |
31 |
import org.eclipse.compare.internal.Utilities; |
| 30 |
import org.eclipse.compare.internal.ViewerSwitchingCancelled; |
32 |
import org.eclipse.compare.internal.ViewerSwitchingCancelled; |
| 31 |
import org.eclipse.compare.structuremergeviewer.Differencer; |
33 |
import org.eclipse.compare.structuremergeviewer.Differencer; |
| 32 |
import org.eclipse.compare.structuremergeviewer.ICompareInput; |
34 |
import org.eclipse.compare.structuremergeviewer.ICompareInput; |
| 33 |
import org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener; |
35 |
import org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener; |
| 34 |
import org.eclipse.core.commands.ExecutionEvent; |
|
|
| 35 |
import org.eclipse.core.commands.ExecutionException; |
| 36 |
import org.eclipse.core.commands.IExecutionListener; |
| 37 |
import org.eclipse.core.commands.NotHandledException; |
| 38 |
import org.eclipse.core.runtime.Assert; |
36 |
import org.eclipse.core.runtime.Assert; |
| 39 |
import org.eclipse.core.runtime.CoreException; |
37 |
import org.eclipse.core.runtime.CoreException; |
| 40 |
import org.eclipse.core.runtime.IProgressMonitor; |
38 |
import org.eclipse.core.runtime.IProgressMonitor; |
|
Lines 71-79
Link Here
|
| 71 |
import org.eclipse.swt.widgets.Layout; |
69 |
import org.eclipse.swt.widgets.Layout; |
| 72 |
import org.eclipse.swt.widgets.Sash; |
70 |
import org.eclipse.swt.widgets.Sash; |
| 73 |
import org.eclipse.swt.widgets.Shell; |
71 |
import org.eclipse.swt.widgets.Shell; |
| 74 |
import org.eclipse.ui.IWorkbenchCommandConstants; |
72 |
import org.eclipse.ui.ISaveablesSource; |
| 75 |
import org.eclipse.ui.PlatformUI; |
73 |
import org.eclipse.ui.IWorkbenchPart; |
| 76 |
import org.eclipse.ui.commands.ICommandService; |
74 |
import org.eclipse.ui.Saveable; |
| 77 |
|
75 |
|
| 78 |
/** |
76 |
/** |
| 79 |
* An abstract compare and merge viewer with two side-by-side content areas |
77 |
* An abstract compare and merge viewer with two side-by-side content areas |
|
Lines 102-108
Link Here
|
| 102 |
* @see TextMergeViewer |
100 |
* @see TextMergeViewer |
| 103 |
*/ |
101 |
*/ |
| 104 |
public abstract class ContentMergeViewer extends ContentViewer |
102 |
public abstract class ContentMergeViewer extends ContentViewer |
| 105 |
implements IPropertyChangeNotifier, IFlushable { |
103 |
implements IPropertyChangeNotifier, IFlushable, IFlushable2 { |
| 106 |
|
104 |
|
| 107 |
/* package */ static final int HORIZONTAL= 1; |
105 |
/* package */ static final int HORIZONTAL= 1; |
| 108 |
/* package */ static final int VERTICAL= 2; |
106 |
/* package */ static final int VERTICAL= 2; |
|
Lines 295-304
Link Here
|
| 295 |
private boolean fIsLeftDirty; |
293 |
private boolean fIsLeftDirty; |
| 296 |
private boolean fIsRightDirty; |
294 |
private boolean fIsRightDirty; |
| 297 |
|
295 |
|
| 298 |
private boolean fIsSaving; |
|
|
| 299 |
private ICommandService fCommandService; |
| 300 |
private IExecutionListener fExecutionListener; |
| 301 |
|
| 302 |
private CompareHandlerService fHandlerService; |
296 |
private CompareHandlerService fHandlerService; |
| 303 |
|
297 |
|
| 304 |
// SWT widgets |
298 |
// SWT widgets |
|
Lines 371-413
Link Here
|
| 371 |
|
365 |
|
| 372 |
fIsLeftDirty = false; |
366 |
fIsLeftDirty = false; |
| 373 |
fIsRightDirty = false; |
367 |
fIsRightDirty = false; |
| 374 |
|
|
|
| 375 |
fIsSaving = false; |
| 376 |
fCommandService = (ICommandService)PlatformUI.getWorkbench().getAdapter(ICommandService.class); |
| 377 |
if (fCommandService != null) { |
| 378 |
fCommandService.addExecutionListener(getExecutionListener()); |
| 379 |
} |
| 380 |
} |
368 |
} |
| 381 |
|
369 |
|
| 382 |
private IExecutionListener getExecutionListener() { |
|
|
| 383 |
if (fExecutionListener == null) { |
| 384 |
fExecutionListener = new IExecutionListener() { |
| 385 |
public void preExecute(String commandId, ExecutionEvent event) { |
| 386 |
if (IWorkbenchCommandConstants.FILE_SAVE.equals(commandId) |
| 387 |
|| IWorkbenchCommandConstants.FILE_SAVE_ALL.equals(commandId)) |
| 388 |
fIsSaving = true; |
| 389 |
} |
| 390 |
|
| 391 |
public void postExecuteSuccess(String commandId, Object returnValue) { |
| 392 |
if (IWorkbenchCommandConstants.FILE_SAVE.equals(commandId) |
| 393 |
|| IWorkbenchCommandConstants.FILE_SAVE_ALL.equals(commandId)) |
| 394 |
fIsSaving= false; |
| 395 |
} |
| 396 |
|
| 397 |
public void postExecuteFailure(String commandId, ExecutionException exception) { |
| 398 |
if (IWorkbenchCommandConstants.FILE_SAVE.equals(commandId) |
| 399 |
|| IWorkbenchCommandConstants.FILE_SAVE_ALL.equals(commandId)) |
| 400 |
fIsSaving= false; |
| 401 |
} |
| 402 |
|
| 403 |
public void notHandled(String commandId, NotHandledException exception) { |
| 404 |
// not needed |
| 405 |
} |
| 406 |
}; |
| 407 |
} |
| 408 |
return fExecutionListener; |
| 409 |
} |
| 410 |
|
| 411 |
//---- hooks --------------------- |
370 |
//---- hooks --------------------- |
| 412 |
|
371 |
|
| 413 |
/** |
372 |
/** |
|
Lines 1037-1048
Link Here
|
| 1037 |
fHVSashCursor= null; |
996 |
fHVSashCursor= null; |
| 1038 |
} |
997 |
} |
| 1039 |
|
998 |
|
| 1040 |
if (fCommandService != null) { |
|
|
| 1041 |
fCommandService.removeExecutionListener(fExecutionListener); |
| 1042 |
fCommandService = null; |
| 1043 |
fExecutionListener = null; |
| 1044 |
} |
| 1045 |
|
| 1046 |
super.handleDispose(event); |
999 |
super.handleDispose(event); |
| 1047 |
} |
1000 |
} |
| 1048 |
|
1001 |
|
|
Lines 1168-1176
Link Here
|
| 1168 |
protected void setLeftDirty(boolean dirty) { |
1121 |
protected void setLeftDirty(boolean dirty) { |
| 1169 |
if (isLeftDirty() != dirty) { |
1122 |
if (isLeftDirty() != dirty) { |
| 1170 |
fIsLeftDirty = dirty; |
1123 |
fIsLeftDirty = dirty; |
| 1171 |
// Only fire the event if the combined dirty state has changed |
1124 |
// Always fire the event if the dirty state has changed |
| 1172 |
if (!isRightDirty()) |
1125 |
fireDirtyState(dirty); |
| 1173 |
fireDirtyState(dirty); |
|
|
| 1174 |
} |
1126 |
} |
| 1175 |
} |
1127 |
} |
| 1176 |
|
1128 |
|
|
Lines 1186-1194
Link Here
|
| 1186 |
protected void setRightDirty(boolean dirty) { |
1138 |
protected void setRightDirty(boolean dirty) { |
| 1187 |
if (isRightDirty() != dirty) { |
1139 |
if (isRightDirty() != dirty) { |
| 1188 |
fIsRightDirty = dirty; |
1140 |
fIsRightDirty = dirty; |
| 1189 |
// Only fire the event if the combined dirty state has changed |
1141 |
// Always fire the event if the dirty state has changed |
| 1190 |
if (!isLeftDirty()) |
1142 |
fireDirtyState(dirty); |
| 1191 |
fireDirtyState(dirty); |
|
|
| 1192 |
} |
1143 |
} |
| 1193 |
} |
1144 |
} |
| 1194 |
|
1145 |
|
|
Lines 1215-1221
Link Here
|
| 1215 |
public final void flush(IProgressMonitor monitor) { |
1166 |
public final void flush(IProgressMonitor monitor) { |
| 1216 |
flushContent(getInput(), monitor); |
1167 |
flushContent(getInput(), monitor); |
| 1217 |
} |
1168 |
} |
| 1218 |
|
1169 |
|
| 1219 |
/** |
1170 |
/** |
| 1220 |
* Flush the modified content back to input elements via the content provider. |
1171 |
* Flush the modified content back to input elements via the content provider. |
| 1221 |
* The provided input may be the current input of the viewer or it may be |
1172 |
* The provided input may be the current input of the viewer or it may be |
|
Lines 1227-1262
Link Here
|
| 1227 |
* @since 3.3 |
1178 |
* @since 3.3 |
| 1228 |
*/ |
1179 |
*/ |
| 1229 |
protected void flushContent(Object input, IProgressMonitor monitor) { |
1180 |
protected void flushContent(Object input, IProgressMonitor monitor) { |
| 1230 |
|
1181 |
flushLeftSide(input, monitor); |
| 1231 |
// write back modified contents |
1182 |
flushRightSide(input, monitor); |
| 1232 |
IMergeViewerContentProvider content= (IMergeViewerContentProvider) getContentProvider(); |
1183 |
} |
| 1233 |
|
1184 |
|
| 1234 |
boolean leftEmpty= content.getLeftContent(input) == null; |
1185 |
|
| 1235 |
boolean rightEmpty= content.getRightContent(input) == null; |
1186 |
protected void flushLeftSide(Object input, IProgressMonitor monitor) { |
|
|
1187 |
IMergeViewerContentProvider content = (IMergeViewerContentProvider) getContentProvider(); |
| 1188 |
|
| 1189 |
boolean rightEmpty = content.getRightContent(input) == null; |
| 1236 |
|
1190 |
|
| 1237 |
if (getCompareConfiguration().isLeftEditable() && isLeftDirty()) { |
1191 |
if (getCompareConfiguration().isLeftEditable() && isLeftDirty()) { |
| 1238 |
byte[] bytes= getContents(true); |
1192 |
byte[] bytes = getContents(true); |
| 1239 |
if (rightEmpty && bytes != null && bytes.length == 0) |
1193 |
if (rightEmpty && bytes != null && bytes.length == 0) |
| 1240 |
bytes= null; |
1194 |
bytes = null; |
| 1241 |
setLeftDirty(false); |
1195 |
setLeftDirty(false); |
| 1242 |
content.saveLeftContent(input, bytes); |
1196 |
content.saveLeftContent(input, bytes); |
| 1243 |
} |
1197 |
} |
| 1244 |
|
1198 |
} |
|
|
1199 |
|
| 1200 |
protected void flushRightSide(Object input, IProgressMonitor monitor) { |
| 1201 |
IMergeViewerContentProvider content = (IMergeViewerContentProvider) getContentProvider(); |
| 1202 |
|
| 1203 |
boolean leftEmpty = content.getLeftContent(input) == null; |
| 1204 |
|
| 1245 |
if (getCompareConfiguration().isRightEditable() && isRightDirty()) { |
1205 |
if (getCompareConfiguration().isRightEditable() && isRightDirty()) { |
| 1246 |
byte[] bytes= getContents(false); |
1206 |
byte[] bytes = getContents(false); |
| 1247 |
if (leftEmpty && bytes != null && bytes.length == 0) |
1207 |
if (leftEmpty && bytes != null && bytes.length == 0) |
| 1248 |
bytes= null; |
1208 |
bytes = null; |
| 1249 |
setRightDirty(false); |
1209 |
setRightDirty(false); |
| 1250 |
content.saveRightContent(input, bytes); |
1210 |
content.saveRightContent(input, bytes); |
| 1251 |
} |
1211 |
} |
| 1252 |
} |
1212 |
} |
| 1253 |
|
1213 |
|
|
|
1214 |
public void flushLeft(IProgressMonitor monitor) { |
| 1215 |
flushLeftSide(getInput(), monitor); |
| 1216 |
} |
| 1217 |
|
| 1218 |
public void flushRight(IProgressMonitor monitor) { |
| 1219 |
flushRightSide(getInput(), monitor); |
| 1220 |
} |
| 1221 |
|
| 1254 |
/** |
1222 |
/** |
| 1255 |
* Return the dirty state of the right side of this viewer. |
1223 |
* Return the dirty state of the right side of this viewer. |
| 1256 |
* @return the dirty state of the right side of this viewer |
1224 |
* @return the dirty state of the right side of this viewer |
| 1257 |
* @since 3.3 |
1225 |
* @since 3.3 |
| 1258 |
*/ |
1226 |
*/ |
| 1259 |
protected boolean isRightDirty() { |
1227 |
public boolean isRightDirty() { |
| 1260 |
return fIsRightDirty; |
1228 |
return fIsRightDirty; |
| 1261 |
} |
1229 |
} |
| 1262 |
|
1230 |
|
|
Lines 1265-1271
Link Here
|
| 1265 |
* @return the dirty state of the left side of this viewer |
1233 |
* @return the dirty state of the left side of this viewer |
| 1266 |
* @since 3.3 |
1234 |
* @since 3.3 |
| 1267 |
*/ |
1235 |
*/ |
| 1268 |
protected boolean isLeftDirty() { |
1236 |
public boolean isLeftDirty() { |
| 1269 |
return fIsLeftDirty; |
1237 |
return fIsLeftDirty; |
| 1270 |
} |
1238 |
} |
| 1271 |
|
1239 |
|
|
Lines 1279-1285
Link Here
|
| 1279 |
protected void handleCompareInputChange() { |
1247 |
protected void handleCompareInputChange() { |
| 1280 |
// before setting the new input we have to save the old |
1248 |
// before setting the new input we have to save the old |
| 1281 |
Object input = getInput(); |
1249 |
Object input = getInput(); |
| 1282 |
if (!fIsSaving && (isLeftDirty() || isRightDirty())) { |
1250 |
if (!isSaving() && (isLeftDirty() || isRightDirty())) { |
| 1283 |
|
1251 |
|
| 1284 |
if (Utilities.RUNNING_TESTS) { |
1252 |
if (Utilities.RUNNING_TESTS) { |
| 1285 |
if (Utilities.TESTING_FLUSH_ON_COMPARE_INPUT_CHANGE) { |
1253 |
if (Utilities.TESTING_FLUSH_ON_COMPARE_INPUT_CHANGE) { |
|
Lines 1310-1320
Link Here
|
| 1310 |
break; |
1278 |
break; |
| 1311 |
} |
1279 |
} |
| 1312 |
} |
1280 |
} |
|
|
1281 |
refresh(); |
| 1313 |
} |
1282 |
} |
| 1314 |
refresh(); |
|
|
| 1315 |
} |
1283 |
} |
| 1316 |
|
1284 |
|
| 1317 |
CompareHandlerService getCompareHandlerService() { |
1285 |
CompareHandlerService getCompareHandlerService() { |
| 1318 |
return fHandlerService; |
1286 |
return fHandlerService; |
| 1319 |
} |
1287 |
} |
|
|
1288 |
|
| 1289 |
/** |
| 1290 |
* @return true if any of the Saveables is being saved |
| 1291 |
*/ |
| 1292 |
private boolean isSaving() { |
| 1293 |
ICompareContainer container = fCompareConfiguration.getContainer(); |
| 1294 |
ISaveablesSource source = null; |
| 1295 |
if (container instanceof ISaveablesSource) { |
| 1296 |
source = (ISaveablesSource) container; |
| 1297 |
} else { |
| 1298 |
IWorkbenchPart part = container.getWorkbenchPart(); |
| 1299 |
if (part instanceof ISaveablesSource) { |
| 1300 |
source = (ISaveablesSource) part; |
| 1301 |
} |
| 1302 |
} |
| 1303 |
if (source != null) { |
| 1304 |
Saveable[] saveables = source.getSaveables(); |
| 1305 |
for (int i = 0; i < saveables.length; i++) { |
| 1306 |
if (saveables[i] instanceof ISavingStateProvider) { |
| 1307 |
ISavingStateProvider saveable = (ISavingStateProvider) saveables[i]; |
| 1308 |
if (saveable.isSaving()) |
| 1309 |
return true; |
| 1310 |
} |
| 1311 |
} |
| 1312 |
} |
| 1313 |
return false; |
| 1314 |
} |
| 1315 |
|
| 1320 |
} |
1316 |
} |