comparison dwtx/jface/text/DefaultUndoManager.d @ 140:26688fec6d23

Following dsss compile errors
author Frank Benoit <benoit@tionex.de>
date Sun, 24 Aug 2008 03:23:46 +0200
parents b6bad70d540a
children eb21d3dfc767
comparison
equal deleted inserted replaced
139:93a6ec48fd28 140:26688fec6d23
299 /* 299 /*
300 * @see dwtx.core.commands.operations.IUndoableOperation#canUndo() 300 * @see dwtx.core.commands.operations.IUndoableOperation#canUndo()
301 * @since 3.1 301 * @since 3.1
302 */ 302 */
303 public bool canUndo() { 303 public bool canUndo() {
304 304
305 if (isConnected() && isValid()) { 305 if (isConnected() && isValid()) {
306 IDocument doc= fTextViewer.getDocument(); 306 IDocument doc= fTextViewer.getDocument();
307 if ( cast(IDocumentExtension4)doc ) { 307 if ( cast(IDocumentExtension4)doc ) {
308 long docStamp= (cast(IDocumentExtension4)doc).getModificationStamp(); 308 long docStamp= (cast(IDocumentExtension4)doc).getModificationStamp();
309 309
310 // Normal case: an undo is valid if its redo will restore document 310 // Normal case: an undo is valid if its redo will restore document
311 // to its current modification stamp 311 // to its current modification stamp
312 bool canUndo= docStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP || 312 bool canUndo= docStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP ||
313 docStamp is getRedoModificationStamp(); 313 docStamp is getRedoModificationStamp();
314 314
315 /* Special case to check if the answer is false. 315 /* Special case to check if the answer is false.
316 * If the last document change was empty, then the document's 316 * If the last document change was empty, then the document's
317 * modification stamp was incremented but nothing was committed. 317 * modification stamp was incremented but nothing was committed.
318 * The operation being queried has an older stamp. In this case only, 318 * The operation being queried has an older stamp. In this case only,
319 * the comparison is different. A sequence of document changes that 319 * the comparison is different. A sequence of document changes that
320 * include an empty change is handled correctly when a valid commit 320 * include an empty change is handled correctly when a valid commit
321 * follows the empty change, but when #canUndo() is queried just after 321 * follows the empty change, but when #canUndo() is queried just after
322 * an empty change, we must special case the check. The check is very 322 * an empty change, we must special case the check. The check is very
323 * specific to prevent false positives. 323 * specific to prevent false positives.
324 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=98245 324 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=98245
325 */ 325 */
326 if (!canUndo && 326 if (!canUndo &&
327 this is fHistory.getUndoOperation(fUndoContext) && // this is the latest operation 327 this is fHistory.getUndoOperation(fUndoContext) && // this is the latest operation
328 this !is fCurrent && // there is a more current operation not on the stack 328 this !is fCurrent && // there is a more current operation not on the stack
329 !fCurrent.isValid() && // the current operation is not a valid document modification 329 !fCurrent.isValid() && // the current operation is not a valid document modification
330 fCurrent.fUndoModificationStamp !is // the invalid current operation has a document stamp 330 fCurrent.fUndoModificationStamp !is // the invalid current operation has a document stamp
331 IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) { 331 IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) {
332 canUndo= fCurrent.fRedoModificationStamp is docStamp; 332 canUndo= fCurrent.fRedoModificationStamp is docStamp;
333 } 333 }
334 /* 334 /*
335 * When the composite is the current command, it may hold the timestamp 335 * When the composite is the current command, it may hold the timestamp
336 * of a no-op change. We check this here rather than in an override of 336 * of a no-op change. We check this here rather than in an override of
337 * canUndo() in CompoundTextCommand simply to keep all the special case checks 337 * canUndo() in CompoundTextCommand simply to keep all the special case checks
338 * in one place. 338 * in one place.
339 */ 339 */
340 if (!canUndo && 340 if (!canUndo &&
341 this is fHistory.getUndoOperation(fUndoContext) && // this is the latest operation 341 this is fHistory.getUndoOperation(fUndoContext) && // this is the latest operation
342 this instanceof CompoundTextCommand && 342 null !is cast(CompoundTextCommand)this &&
343 this is fCurrent && // this is the current operation 343 this is fCurrent && // this is the current operation
344 this.fStart is -1 && // the current operation text is not valid 344 this.fStart is -1 && // the current operation text is not valid
345 fCurrent.fRedoModificationStamp !is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) { // but it has a redo stamp 345 fCurrent.fRedoModificationStamp !is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) { // but it has a redo stamp
346 canUndo= fCurrent.fRedoModificationStamp is docStamp; 346 canUndo= fCurrent.fRedoModificationStamp is docStamp;
347 } 347 }
360 public bool canRedo() { 360 public bool canRedo() {
361 if (isConnected() && isValid()) { 361 if (isConnected() && isValid()) {
362 IDocument doc= fTextViewer.getDocument(); 362 IDocument doc= fTextViewer.getDocument();
363 if ( cast(IDocumentExtension4)doc ) { 363 if ( cast(IDocumentExtension4)doc ) {
364 long docStamp= (cast(IDocumentExtension4)doc).getModificationStamp(); 364 long docStamp= (cast(IDocumentExtension4)doc).getModificationStamp();
365 return docStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP || 365 return docStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP ||
366 docStamp is getUndoModificationStamp(); 366 docStamp is getUndoModificationStamp();
367 } 367 }
368 // if there is no timestamp to check, simply return true per the 3.0.1 behavior 368 // if there is no timestamp to check, simply return true per the 3.0.1 behavior
369 return true; 369 return true;
370 } 370 }
408 resetProcessChangeSate(); 408 resetProcessChangeSate();
409 return Status.OK_STATUS; 409 return Status.OK_STATUS;
410 } 410 }
411 return IOperationHistory.OPERATION_INVALID_STATUS; 411 return IOperationHistory.OPERATION_INVALID_STATUS;
412 } 412 }
413 413
414 /** 414 /**
415 * Re-applies the change described by this command. 415 * Re-applies the change described by this command.
416 * 416 *
417 * @since 2.0 417 * @since 2.0
418 */ 418 */
495 if (fStart > -1) { 495 if (fStart > -1) {
496 fText= fTextBuffer.toString(); 496 fText= fTextBuffer.toString();
497 fPreservedText= fPreservedTextBuffer.toString(); 497 fPreservedText= fPreservedTextBuffer.toString();
498 } 498 }
499 } 499 }
500 500
501 /** 501 /**
502 * Attempt a commit of this command and answer true if a new 502 * Attempt a commit of this command and answer true if a new
503 * fCurrent was created as a result of the commit. 503 * fCurrent was created as a result of the commit.
504 * 504 *
505 * @return true if the command was committed and created a 505 * @return true if the command was committed and created a
506 * new fCurrent, false if not. 506 * new fCurrent, false if not.
507 * @since 3.1 507 * @since 3.1
508 */ 508 */
509 protected bool attemptCommit() { 509 protected bool attemptCommit() {
553 text.append("preservedText: '"); //$NON-NLS-1$ 553 text.append("preservedText: '"); //$NON-NLS-1$
554 text.append(fPreservedText); 554 text.append(fPreservedText);
555 text.append('\''); 555 text.append('\'');
556 return text.toString(); 556 return text.toString();
557 } 557 }
558 558
559 /** 559 /**
560 * Return the undo modification stamp 560 * Return the undo modification stamp
561 * 561 *
562 * @return the undo modification stamp for this command 562 * @return the undo modification stamp for this command
563 * @since 3.1 563 * @since 3.1
564 */ 564 */
565 protected long getUndoModificationStamp() { 565 protected long getUndoModificationStamp() {
566 return fUndoModificationStamp; 566 return fUndoModificationStamp;
567 } 567 }
568 568
569 /** 569 /**
570 * Return the redo modification stamp 570 * Return the redo modification stamp
571 * 571 *
572 * @return the redo modification stamp for this command 572 * @return the redo modification stamp for this command
573 * @since 3.1 573 * @since 3.1
574 */ 574 */
575 protected long getRedoModificationStamp() { 575 protected long getRedoModificationStamp() {
576 return fRedoModificationStamp; 576 return fRedoModificationStamp;
608 /* 608 /*
609 * @see dwtx.jface.text.DefaultUndoManager.TextCommand#undo() 609 * @see dwtx.jface.text.DefaultUndoManager.TextCommand#undo()
610 */ 610 */
611 public IStatus undo(IProgressMonitor monitor, IAdaptable uiInfo) { 611 public IStatus undo(IProgressMonitor monitor, IAdaptable uiInfo) {
612 resetProcessChangeSate(); 612 resetProcessChangeSate();
613 613
614 int size= fCommands.size(); 614 int size= fCommands.size();
615 if (size > 0) { 615 if (size > 0) {
616 616
617 TextCommand c; 617 TextCommand c;
618 618
705 protected bool isValid() { 705 protected bool isValid() {
706 if (isConnected()) 706 if (isConnected())
707 return (fStart > -1 || fCommands.size() > 0); 707 return (fStart > -1 || fCommands.size() > 0);
708 return false; 708 return false;
709 } 709 }
710 710
711 /** 711 /**
712 * Returns the undo modification stamp. 712 * Returns the undo modification stamp.
713 * 713 *
714 * @return the undo modification stamp 714 * @return the undo modification stamp
715 * @since 3.1 715 * @since 3.1
716 */ 716 */
717 protected long getUndoModificationStamp() { 717 protected long getUndoModificationStamp() {
718 if (fStart > -1) 718 if (fStart > -1)
720 else if (fCommands.size() > 0) 720 else if (fCommands.size() > 0)
721 return (cast(TextCommand)fCommands.get(0)).getUndoModificationStamp(); 721 return (cast(TextCommand)fCommands.get(0)).getUndoModificationStamp();
722 722
723 return fUndoModificationStamp; 723 return fUndoModificationStamp;
724 } 724 }
725 725
726 /** 726 /**
727 * Returns the redo modification stamp. 727 * Returns the redo modification stamp.
728 * 728 *
729 * @return the redo modification stamp 729 * @return the redo modification stamp
730 * @since 3.1 730 * @since 3.1
731 */ 731 */
732 protected long getRedoModificationStamp() { 732 protected long getRedoModificationStamp() {
733 if (fStart > -1) 733 if (fStart > -1)
884 if (event.getOperation().hasContext(fUndoContext)) { 884 if (event.getOperation().hasContext(fUndoContext)) {
885 fTextViewer.getTextWidget().getDisplay().syncExec(new class() Runnable { 885 fTextViewer.getTextWidget().getDisplay().syncExec(new class() Runnable {
886 public void run() { 886 public void run() {
887 // if we are undoing/redoing a command we generated, then ignore 887 // if we are undoing/redoing a command we generated, then ignore
888 // the document changes associated with this undo or redo. 888 // the document changes associated with this undo or redo.
889 if (event.getOperation() instanceof TextCommand) { 889 if (cast(TextCommand)event.getOperation() ) {
890 if ( cast(TextViewer)fTextViewer ) 890 if ( cast(TextViewer)fTextViewer )
891 (cast(TextViewer)fTextViewer).ignoreAutoEditStrategies(true); 891 (cast(TextViewer)fTextViewer).ignoreAutoEditStrategies(true);
892 listenToTextChanges(false); 892 listenToTextChanges(false);
893 893
894 // in the undo case only, make sure compounds are closed 894 // in the undo case only, make sure compounds are closed
895 if (type is OperationHistoryEvent.ABOUT_TO_UNDO) { 895 if (type is OperationHistoryEvent.ABOUT_TO_UNDO) {
896 if (fFoldingIntoCompoundChange) { 896 if (fFoldingIntoCompoundChange) {
897 endCompoundChange(); 897 endCompoundChange();
898 } 898 }
899 } 899 }
900 } else { 900 } else {
901 // the undo or redo has our context, but it is not one of 901 // the undo or redo has our context, but it is not one of
902 // our commands. We will listen to the changes, but will 902 // our commands. We will listen to the changes, but will
903 // reset the state that tracks the undo/redo history. 903 // reset the state that tracks the undo/redo history.
904 commit(); 904 commit();
905 fLastAddedCommand= null; 905 fLastAddedCommand= null;
906 } 906 }
907 } 907 }
908 }); 908 });
1068 * 1068 *
1069 * @param command the command to be added 1069 * @param command the command to be added
1070 * @since 3.1 1070 * @since 3.1
1071 */ 1071 */
1072 private void addToCommandStack(TextCommand command){ 1072 private void addToCommandStack(TextCommand command){
1073 if (!fFoldingIntoCompoundChange || command instanceof CompoundTextCommand) { 1073 if (!fFoldingIntoCompoundChange || cast(CompoundTextCommand)command ) {
1074 fHistory.add(command); 1074 fHistory.add(command);
1075 fLastAddedCommand= command; 1075 fLastAddedCommand= command;
1076 } 1076 }
1077 } 1077 }
1078 1078
1127 if (fCurrent.isValid()) 1127 if (fCurrent.isValid())
1128 addToCommandStack(fCurrent); 1128 addToCommandStack(fCurrent);
1129 } 1129 }
1130 fCurrent.commit(); 1130 fCurrent.commit();
1131 } 1131 }
1132 1132
1133 /** 1133 /**
1134 * Reset processChange state. 1134 * Reset processChange state.
1135 * 1135 *
1136 * @since 3.2 1136 * @since 3.2
1137 */ 1137 */
1138 private void resetProcessChangeSate() { 1138 private void resetProcessChangeSate() {
1139 fInserting= false; 1139 fInserting= false;
1140 fOverwriting= false; 1140 fOverwriting= false;
1177 if (replacedText is null) 1177 if (replacedText is null)
1178 replacedText= ""; //$NON-NLS-1$ 1178 replacedText= ""; //$NON-NLS-1$
1179 1179
1180 int length= insertedText.length(); 1180 int length= insertedText.length();
1181 int diff= modelEnd - modelStart; 1181 int diff= modelEnd - modelStart;
1182 1182
1183 if (fCurrent.fUndoModificationStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) 1183 if (fCurrent.fUndoModificationStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP)
1184 fCurrent.fUndoModificationStamp= beforeChangeModificationStamp; 1184 fCurrent.fUndoModificationStamp= beforeChangeModificationStamp;
1185 1185
1186 // normalize 1186 // normalize
1187 if (diff < 0) { 1187 if (diff < 0) {
1196 // by typing or whitespace 1196 // by typing or whitespace
1197 if (!fInserting || (modelStart !is fCurrent.fStart + fTextBuffer.length())) { 1197 if (!fInserting || (modelStart !is fCurrent.fStart + fTextBuffer.length())) {
1198 fCurrent.fRedoModificationStamp= beforeChangeModificationStamp; 1198 fCurrent.fRedoModificationStamp= beforeChangeModificationStamp;
1199 if (fCurrent.attemptCommit()) 1199 if (fCurrent.attemptCommit())
1200 fCurrent.fUndoModificationStamp= beforeChangeModificationStamp; 1200 fCurrent.fUndoModificationStamp= beforeChangeModificationStamp;
1201 1201
1202 fInserting= true; 1202 fInserting= true;
1203 } 1203 }
1204 if (fCurrent.fStart < 0) 1204 if (fCurrent.fStart < 0)
1205 fCurrent.fStart= fCurrent.fEnd= modelStart; 1205 fCurrent.fStart= fCurrent.fEnd= modelStart;
1206 if (length > 0) 1206 if (length > 0)
1300 } 1300 }
1301 } 1301 }
1302 // because of typing or pasting whereby selection is not empty 1302 // because of typing or pasting whereby selection is not empty
1303 fCurrent.fRedoModificationStamp= beforeChangeModificationStamp; 1303 fCurrent.fRedoModificationStamp= beforeChangeModificationStamp;
1304 if (fCurrent.attemptCommit()) 1304 if (fCurrent.attemptCommit())
1305 fCurrent.fUndoModificationStamp= beforeChangeModificationStamp; 1305 fCurrent.fUndoModificationStamp= beforeChangeModificationStamp;
1306 1306
1307 fCurrent.fStart= modelStart; 1307 fCurrent.fStart= modelStart;
1308 fCurrent.fEnd= modelEnd; 1308 fCurrent.fEnd= modelEnd;
1309 fTextBuffer.append(insertedText); 1309 fTextBuffer.append(insertedText);
1310 fPreservedTextBuffer.append(replacedText); 1310 fPreservedTextBuffer.append(replacedText);