platform-ui-home/R3_1/undo-redo-proposal/undo-redo support.html

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (download) (as text) (annotate)
Tue Nov 9 19:43:11 2004 UTC (5 years ago) by nick
Branch: MAIN
Changes since 1.1: +324 -409 lines
Update from Susan
<html xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:w="urn:schemas-microsoft-com:office:word"
xmlns:st1="urn:schemas-microsoft-com:office:smarttags"
xmlns="http://www.w3.org/TR/REC-html40">

<head>
<meta http-equiv=Content-Type content="text/html; charset=windows-1252">
<meta name=ProgId content=Word.Document>
<meta name=Generator content="Microsoft Word 10">
<meta name=Originator content="Microsoft Word 10">
<link rel=File-List href="undo-redo%20support_files/filelist.xml">
<title>Undo/redo support in Eclipse</title>
<o:SmartTagType namespaceuri="urn:schemas-microsoft-com:office:smarttags"
 name="date"/>
<!--[if gte mso 9]><xml>
 <o:DocumentProperties>
  <o:Author>IBM_USER</o:Author>
  <o:LastAuthor>IBM_USER</o:LastAuthor>
  <o:Revision>2</o:Revision>
  <o:TotalTime>4237</o:TotalTime>
  <o:LastPrinted>2004-11-08T17:14:00Z</o:LastPrinted>
  <o:Created>2004-11-09T19:14:00Z</o:Created>
  <o:LastSaved>2004-11-09T19:14:00Z</o:LastSaved>
  <o:Pages>1</o:Pages>
  <o:Words>6221</o:Words>
  <o:Characters>35461</o:Characters>
  <o:Company>IBM</o:Company>
  <o:Lines>295</o:Lines>
  <o:Paragraphs>83</o:Paragraphs>
  <o:CharactersWithSpaces>41599</o:CharactersWithSpaces>
  <o:Version>10.6626</o:Version>
 </o:DocumentProperties>
</xml><![endif]--><!--[if gte mso 9]><xml>
 <w:WordDocument>
  <w:SpellingState>Clean</w:SpellingState>
  <w:Compatibility>
   <w:BreakWrappedTables/>
   <w:SnapToGridInCell/>
   <w:WrapTextWithPunct/>
   <w:UseAsianBreakRules/>
  </w:Compatibility>
  <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
 </w:WordDocument>
</xml><![endif]--><!--[if !mso]><object
 classid="clsid:38481807-CA0E-42D2-BF39-B33AF135CC4D" id=ieooui></object>
<style>
st1\:*{behavior:url(#ieooui) }
</style>
<![endif]-->
<style>
<!--
 /* Font Definitions */
 @font-face
	{font-family:Wingdings;
	panose-1:5 0 0 0 0 0 0 0 0 0;
	mso-font-charset:2;
	mso-generic-font-family:auto;
	mso-font-pitch:variable;
	mso-font-signature:0 268435456 0 0 -2147483648 0;}
 /* Style Definitions */
 p.MsoNormal, li.MsoNormal, div.MsoNormal
	{mso-style-parent:"";
	margin:0in;
	margin-bottom:.0001pt;
	mso-pagination:widow-orphan;
	font-size:12.0pt;
	font-family:"Times New Roman";
	mso-fareast-font-family:"Times New Roman";}
h1
	{mso-style-next:Normal;
	margin-top:12.0pt;
	margin-right:0in;
	margin-bottom:3.0pt;
	margin-left:0in;
	mso-pagination:widow-orphan;
	page-break-after:avoid;
	mso-outline-level:1;
	font-size:16.0pt;
	font-family:Arial;
	mso-font-kerning:16.0pt;}
h2
	{mso-style-next:Normal;
	margin-top:12.0pt;
	margin-right:0in;
	margin-bottom:3.0pt;
	margin-left:0in;
	mso-pagination:widow-orphan;
	page-break-after:avoid;
	mso-outline-level:2;
	font-size:14.0pt;
	font-family:Arial;
	font-style:italic;}
h3
	{mso-style-next:Normal;
	margin-top:12.0pt;
	margin-right:0in;
	margin-bottom:3.0pt;
	margin-left:0in;
	mso-pagination:widow-orphan;
	page-break-after:avoid;
	mso-outline-level:3;
	font-size:13.0pt;
	font-family:Arial;}
h4
	{mso-style-next:Normal;
	margin-top:12.0pt;
	margin-right:0in;
	margin-bottom:3.0pt;
	margin-left:0in;
	mso-pagination:widow-orphan;
	page-break-after:avoid;
	mso-outline-level:4;
	font-size:14.0pt;
	font-family:"Times New Roman";}
h5
	{mso-style-next:Normal;
	margin-top:12.0pt;
	margin-right:0in;
	margin-bottom:3.0pt;
	margin-left:0in;
	mso-pagination:widow-orphan;
	mso-outline-level:5;
	font-size:13.0pt;
	font-family:"Times New Roman";
	font-style:italic;}
p.MsoFootnoteText, li.MsoFootnoteText, div.MsoFootnoteText
	{mso-style-noshow:yes;
	margin:0in;
	margin-bottom:.0001pt;
	mso-pagination:widow-orphan;
	font-size:10.0pt;
	font-family:"Times New Roman";
	mso-fareast-font-family:"Times New Roman";}
span.MsoFootnoteReference
	{mso-style-noshow:yes;
	vertical-align:super;}
p.MsoBodyText2, li.MsoBodyText2, div.MsoBodyText2
	{margin-top:0in;
	margin-right:0in;
	margin-bottom:6.0pt;
	margin-left:0in;
	line-height:200%;
	mso-pagination:widow-orphan;
	font-size:12.0pt;
	font-family:"Times New Roman";
	mso-fareast-font-family:"Times New Roman";}
a:link, span.MsoHyperlink
	{color:#0000EE;
	text-decoration:underline;
	text-underline:single;}
a:visited, span.MsoHyperlinkFollowed
	{color:purple;
	text-decoration:underline;
	text-underline:single;}
span.SpellE
	{mso-style-name:"";
	mso-spl-e:yes;}
@page Section1
	{size:8.5in 11.0in;
	margin:1.0in .75in .5in 1.0in;
	mso-header-margin:.5in;
	mso-footer-margin:.5in;
	mso-paper-source:0;}
div.Section1
	{page:Section1;}
 /* List Definitions */
 @list l0
	{mso-list-id:-132;
	mso-list-type:simple;
	mso-list-template-ids:-446383164;}
@list l0:level1
	{mso-level-tab-stop:1.25in;
	mso-level-number-position:left;
	margin-left:1.25in;
	text-indent:-.25in;}
@list l1
	{mso-list-id:-131;
	mso-list-type:simple;
	mso-list-template-ids:1534092348;}
@list l1:level1
	{mso-level-tab-stop:1.0in;
	mso-level-number-position:left;
	margin-left:1.0in;
	text-indent:-.25in;}
@list l2
	{mso-list-id:-130;
	mso-list-type:simple;
	mso-list-template-ids:710070486;}
@list l2:level1
	{mso-level-tab-stop:.75in;
	mso-level-number-position:left;
	margin-left:.75in;
	text-indent:-.25in;}
@list l3
	{mso-list-id:-129;
	mso-list-type:simple;
	mso-list-template-ids:682940366;}
@list l3:level1
	{mso-level-tab-stop:.5in;
	mso-level-number-position:left;
	text-indent:-.25in;}
@list l4
	{mso-list-id:-128;
	mso-list-type:simple;
	mso-list-template-ids:949130314;}
@list l4:level1
	{mso-level-number-format:bullet;
	mso-level-text:\F0B7;
	mso-level-tab-stop:1.25in;
	mso-level-number-position:left;
	margin-left:1.25in;
	text-indent:-.25in;
	font-family:Symbol;}
@list l5
	{mso-list-id:-127;
	mso-list-type:simple;
	mso-list-template-ids:-1842289842;}
@list l5:level1
	{mso-level-number-format:bullet;
	mso-level-text:\F0B7;
	mso-level-tab-stop:1.0in;
	mso-level-number-position:left;
	margin-left:1.0in;
	text-indent:-.25in;
	font-family:Symbol;}
@list l6
	{mso-list-id:-126;
	mso-list-type:simple;
	mso-list-template-ids:819084850;}
@list l6:level1
	{mso-level-number-format:bullet;
	mso-level-text:\F0B7;
	mso-level-tab-stop:.75in;
	mso-level-number-position:left;
	margin-left:.75in;
	text-indent:-.25in;
	font-family:Symbol;}
@list l7
	{mso-list-id:-125;
	mso-list-type:simple;
	mso-list-template-ids:-676417338;}
@list l7:level1
	{mso-level-number-format:bullet;
	mso-level-text:\F0B7;
	mso-level-tab-stop:.5in;
	mso-level-number-position:left;
	text-indent:-.25in;
	font-family:Symbol;}
@list l8
	{mso-list-id:-120;
	mso-list-type:simple;
	mso-list-template-ids:1291634668;}
@list l8:level1
	{mso-level-tab-stop:.25in;
	mso-level-number-position:left;
	margin-left:.25in;
	text-indent:-.25in;}
@list l9
	{mso-list-id:-119;
	mso-list-type:simple;
	mso-list-template-ids:964484384;}
@list l9:level1
	{mso-level-number-format:bullet;
	mso-level-text:\F0B7;
	mso-level-tab-stop:.25in;
	mso-level-number-position:left;
	margin-left:.25in;
	text-indent:-.25in;
	font-family:Symbol;}
@list l10
	{mso-list-id:172575666;
	mso-list-type:hybrid;
	mso-list-template-ids:1725869360 67698703 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l10:level1
	{mso-level-tab-stop:.5in;
	mso-level-number-position:left;
	text-indent:-.25in;}
@list l10:level2
	{mso-level-number-format:bullet;
	mso-level-text:o;
	mso-level-tab-stop:1.0in;
	mso-level-number-position:left;
	text-indent:-.25in;
	font-family:"Courier New";}
@list l10:level3
	{mso-level-number-format:bullet;
	mso-level-text:\F0A7;
	mso-level-tab-stop:1.5in;
	mso-level-number-position:left;
	text-indent:-.25in;
	font-family:Wingdings;}
@list l10:level4
	{mso-level-number-format:bullet;
	mso-level-text:\F0B7;
	mso-level-tab-stop:2.0in;
	mso-level-number-position:left;
	text-indent:-.25in;
	font-family:Symbol;}
@list l11
	{mso-list-id:190000114;
	mso-list-type:hybrid;
	mso-list-template-ids:1560301118 423934604 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l11:level1
	{mso-level-start-at:0;
	mso-level-number-format:bullet;
	mso-level-text:-;
	mso-level-tab-stop:.5in;
	mso-level-number-position:left;
	text-indent:-.25in;
	font-family:Arial;
	mso-fareast-font-family:"Times New Roman";}
@list l12
	{mso-list-id:215170042;
	mso-list-type:hybrid;
	mso-list-template-ids:1511950680 67698703 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}
@list l12:level1
	{mso-level-tab-stop:.5in;
	mso-level-number-position:left;
	text-indent:-.25in;}
@list l13
	{mso-list-id:359431469;
	mso-list-type:hybrid;
	mso-list-template-ids:84734878 67698689 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l13:level1
	{mso-level-number-format:bullet;
	mso-level-text:\F0B7;
	mso-level-tab-stop:.5in;
	mso-level-number-position:left;
	text-indent:-.25in;
	font-family:Symbol;}
@list l14
	{mso-list-id:458649110;
	mso-list-type:hybrid;
	mso-list-template-ids:-38738056 423934604 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l14:level1
	{mso-level-start-at:0;
	mso-level-number-format:bullet;
	mso-level-text:-;
	mso-level-tab-stop:1.0in;
	mso-level-number-position:left;
	margin-left:1.0in;
	text-indent:-.25in;
	font-family:Arial;
	mso-fareast-font-family:"Times New Roman";}
@list l15
	{mso-list-id:547566703;
	mso-list-type:hybrid;
	mso-list-template-ids:1798573620 67698703 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}
@list l15:level1
	{mso-level-tab-stop:.5in;
	mso-level-number-position:left;
	text-indent:-.25in;}
@list l16
	{mso-list-id:752435528;
	mso-list-type:hybrid;
	mso-list-template-ids:968014730 67698703 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}
@list l16:level1
	{mso-level-tab-stop:.5in;
	mso-level-number-position:left;
	text-indent:-.25in;}
@list l17
	{mso-list-id:1072436292;
	mso-list-type:hybrid;
	mso-list-template-ids:1681550614 423934604 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l17:level1
	{mso-level-start-at:0;
	mso-level-number-format:bullet;
	mso-level-text:-;
	mso-level-tab-stop:.75in;
	mso-level-number-position:left;
	margin-left:.75in;
	text-indent:-.25in;
	font-family:Arial;
	mso-fareast-font-family:"Times New Roman";}
@list l17:level2
	{mso-level-number-format:bullet;
	mso-level-text:o;
	mso-level-tab-stop:1.25in;
	mso-level-number-position:left;
	margin-left:1.25in;
	text-indent:-.25in;
	font-family:"Courier New";}
@list l18
	{mso-list-id:1209411371;
	mso-list-type:hybrid;
	mso-list-template-ids:-1603923158 67698689 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l18:level1
	{mso-level-number-format:bullet;
	mso-level-text:\F0B7;
	mso-level-tab-stop:.75in;
	mso-level-number-position:left;
	margin-left:.75in;
	text-indent:-.25in;
	font-family:Symbol;}
@list l19
	{mso-list-id:1432318865;
	mso-list-type:hybrid;
	mso-list-template-ids:2137158298 423934604 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l19:level1
	{mso-level-start-at:0;
	mso-level-number-format:bullet;
	mso-level-text:-;
	mso-level-tab-stop:.5in;
	mso-level-number-position:left;
	text-indent:-.25in;
	font-family:Arial;
	mso-fareast-font-family:"Times New Roman";}
@list l20
	{mso-list-id:1611356098;
	mso-list-type:hybrid;
	mso-list-template-ids:-854709908 67698703 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}
@list l20:level1
	{mso-level-tab-stop:.5in;
	mso-level-number-position:left;
	text-indent:-.25in;}
@list l21
	{mso-list-id:1614744623;
	mso-list-type:hybrid;
	mso-list-template-ids:-1496942198 423934604 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l21:level1
	{mso-level-start-at:0;
	mso-level-number-format:bullet;
	mso-level-text:-;
	mso-level-tab-stop:.5in;
	mso-level-number-position:left;
	text-indent:-.25in;
	font-family:Arial;
	mso-fareast-font-family:"Times New Roman";}
@list l21:level2
	{mso-level-number-format:bullet;
	mso-level-text:o;
	mso-level-tab-stop:1.0in;
	mso-level-number-position:left;
	text-indent:-.25in;
	font-family:"Courier New";}
@list l21:level3
	{mso-level-number-format:bullet;
	mso-level-text:\F0A7;
	mso-level-tab-stop:1.5in;
	mso-level-number-position:left;
	text-indent:-.25in;
	font-family:Wingdings;}
@list l21:level4
	{mso-level-number-format:bullet;
	mso-level-text:\F0B7;
	mso-level-tab-stop:2.0in;
	mso-level-number-position:left;
	text-indent:-.25in;
	font-family:Symbol;}
@list l22
	{mso-list-id:1693457207;
	mso-list-type:hybrid;
	mso-list-template-ids:-1668623746 67698703 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l22:level1
	{mso-level-tab-stop:.5in;
	mso-level-number-position:left;
	text-indent:-.25in;}
@list l22:level2
	{mso-level-number-format:bullet;
	mso-level-text:o;
	mso-level-tab-stop:1.0in;
	mso-level-number-position:left;
	text-indent:-.25in;
	font-family:"Courier New";}
@list l22:level3
	{mso-level-number-format:bullet;
	mso-level-text:\F0A7;
	mso-level-tab-stop:1.5in;
	mso-level-number-position:left;
	text-indent:-.25in;
	font-family:Wingdings;}
@list l22:level4
	{mso-level-number-format:bullet;
	mso-level-text:\F0B7;
	mso-level-tab-stop:2.0in;
	mso-level-number-position:left;
	text-indent:-.25in;
	font-family:Symbol;}
@list l23
	{mso-list-id:1731031428;
	mso-list-type:hybrid;
	mso-list-template-ids:1886447558 67698703 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}
@list l23:level1
	{mso-level-tab-stop:39.0pt;
	mso-level-number-position:left;
	margin-left:39.0pt;
	text-indent:-.25in;}
@list l24
	{mso-list-id:1832519519;
	mso-list-type:hybrid;
	mso-list-template-ids:-658358596 423934604 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l24:level1
	{mso-level-start-at:0;
	mso-level-number-format:bullet;
	mso-level-text:-;
	mso-level-tab-stop:.5in;
	mso-level-number-position:left;
	text-indent:-.25in;
	font-family:Arial;
	mso-fareast-font-family:"Times New Roman";}
@list l25
	{mso-list-id:1853185266;
	mso-list-type:hybrid;
	mso-list-template-ids:403894856 423934604 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l25:level1
	{mso-level-start-at:0;
	mso-level-number-format:bullet;
	mso-level-text:-;
	mso-level-tab-stop:.5in;
	mso-level-number-position:left;
	text-indent:-.25in;
	font-family:Arial;
	mso-fareast-font-family:"Times New Roman";}
@list l25:level2
	{mso-level-number-format:bullet;
	mso-level-text:o;
	mso-level-tab-stop:1.0in;
	mso-level-number-position:left;
	text-indent:-.25in;
	font-family:"Courier New";}
@list l26
	{mso-list-id:1938905931;
	mso-list-type:hybrid;
	mso-list-template-ids:1084264292 423934604 67698691 67698693 67698689 67698691 67698693 67698689 67698691 67698693;}
@list l26:level1
	{mso-level-start-at:0;
	mso-level-number-format:bullet;
	mso-level-text:-;
	mso-level-tab-stop:.5in;
	mso-level-number-position:left;
	text-indent:-.25in;
	font-family:Arial;
	mso-fareast-font-family:"Times New Roman";}
ol
	{margin-bottom:0in;}
ul
	{margin-bottom:0in;}
-->
</style>
<!--[if gte mso 10]>
<style>
 /* Style Definitions */
 table.MsoNormalTable
	{mso-style-name:"Table Normal";
	mso-tstyle-rowband-size:0;
	mso-tstyle-colband-size:0;
	mso-style-noshow:yes;
	mso-style-parent:"";
	mso-padding-alt:0in 5.4pt 0in 5.4pt;
	mso-para-margin:0in;
	mso-para-margin-bottom:.0001pt;
	mso-pagination:widow-orphan;
	font-size:10.0pt;
	font-family:"Times New Roman";}
</style>
<![endif]-->
</head>

<body lang=EN-US link="#0000EE" vlink=purple style='tab-interval:.5in'>

<div class=Section1>

<h1>Generalized Undo Support in Eclipse</h1>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Last
updated:<span style='mso-spacerun:yes'>  </span></span><st1:date Month="11"
Day="9" Year="2004"><span style='font-size:10.0pt;font-family:Arial'>Nov 9,
 2004</span></st1:date><span style='font-size:10.0pt;font-family:Arial'><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Status:<span
style='mso-spacerun:yes'>  </span>Under investigation (see bug </span><a
href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=37716">37716</a>)<span
style='font-size:10.0pt;font-family:Arial'><o:p></o:p></span></p>

<h2>Problem Description<o:p></o:p></h2>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>In R3.0.1
of the Eclipse SDK, there is no generalized support for undoing user actions.<span
style='mso-spacerun:yes'>  </span>Each plug-in is left to implement its own
strategy for undo, if at all.<span style='mso-spacerun:yes'>  </span>This
approach can cause many general problems as independently developed plug-ins implement
their own undo strategies:<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>Undo
and redo actions appear in different menus.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>Undo
and redo implementations can have different semantics.<span
style='mso-spacerun:yes'>  </span>Different approaches to undo by different
plug-ins may confuse the user if they choose different semantics.<span
style='mso-spacerun:yes'>  </span>For example:<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:1.0in;text-indent:-.25in;mso-list:l21 level2 lfo1;
tab-stops:list 1.0in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:"Courier New";mso-fareast-font-family:"Courier New"'><span
style='mso-list:Ignore'>o<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>Is
undo strictly linear?<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:1.0in;text-indent:-.25in;mso-list:l21 level2 lfo1;
tab-stops:list 1.0in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:"Courier New";mso-fareast-font-family:"Courier New"'><span
style='mso-list:Ignore'>o<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>If
it is not linear, what techniques are used to undo an operation?<span
style='mso-spacerun:yes'>  </span>Implementation models for non-linear undo (rollback
and perform the history again, dynamic reversal) can affect the user outcome.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:1.0in;text-indent:-.25in;mso-list:l21 level2 lfo1;
tab-stops:list 1.0in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:"Courier New";mso-fareast-font-family:"Courier New"'><span
style='mso-list:Ignore'>o<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>What
is the scope of an undo?<span style='mso-spacerun:yes'>  </span>Is it global to
the system?<span style='mso-spacerun:yes'>  </span>Is it local to the
window?<span style='mso-spacerun:yes'>  </span>Is it model-dependent?<span
style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>Plug-ins
that want to add undo support may have to choose between different undo
strategies and implementations provided by their required plug-ins, or worse
yet, implement yet another strategy.<o:p></o:p></span></p>

<h3>Challenges with generalized undo support<o:p></o:p></h3>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>While
implementation of a centralized undo mechanism should be straightforward, it
has not been provided in previous releases due to problems in defining the
proper undo semantics across different plug-ins.<span
style='mso-spacerun:yes'>   </span>The challenge in defining consistent, predictable
undo semantics can best be understood by looking at the two different undo
models provided in the R3.0.1 release of the base Eclipse SDK.<span
style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The SDK
currently contains two undo implementations and user commands:<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l26 level1 lfo2;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>Text
undo (Edit&gt;Undo) provides a linear undo model for text-level
operations.<span style='mso-spacerun:yes'>  </span>That is, textual insert/replace/delete
operations can be undone in the reverse order in which they are applied.<span
style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span class=SpellE><span style='font-size:10.0pt;
font-family:Arial'>Refactoring</span></span><span style='font-size:10.0pt;
font-family:Arial'> undo (<span class=SpellE>Refactor</span>&gt;Undo) allows an
undo of the last <span class=SpellE>refactoring</span> operation, but only when
the workspace has not been otherwise modified since the last <span
class=SpellE>refactoring</span>.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>In
discussing the appropriate semantics for workbench undo, it is useful to
introduce terminology that is independent of any particular implementation for
undo support.<o:p></o:p></span></p>

<h3>Undo contexts </h3>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Undo
implementations must provide a history of operations performed by the user and
some knowledge of the “context” for these operations.<span
style='mso-spacerun:yes'>  </span>For example, the text editor undo operates
within the context of a single document, while <span class=SpellE>refactoring</span>
undo operates within the context of some workspace resources.<span
style='mso-spacerun:yes'>   </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The context
for an operation helps determine where the undo for that operation is
available.<span style='mso-spacerun:yes'>  </span>When the contexts for different
operations are completely separate, the semantics for undoing an operation from
either context are easily understood.<span style='mso-spacerun:yes'> 
</span>Undoing an operation from one context does not affect the operation
history from the other context. <o:p></o:p></span></p>

<h3>Undo scopes </h3>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Even when
completely separate undo contexts exist, the scope of the operation history and
resulting undo operation must be defined.<span style='mso-spacerun:yes'> 
</span>There are a few different alternatives:<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>The
UI that manipulates each separate undo context provides its own undo command.<span
style='mso-spacerun:yes'>  </span>This is done in R3.0.1 with Edit&gt;Undo and <span
class=SpellE>Refactoring</span>&gt;Undo.<span style='mso-spacerun:yes'> 
</span>This does not scale well, but makes it clear which context is to be
undone by forcing the user to explicitly choose the context for the undo.<span
style='mso-spacerun:yes'>  </span>We call this an <b style='mso-bidi-font-weight:
normal'>explicit local undo scope</b>.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>A
unified undo command exists and its meaning is interpreted according to some
current context (such as the active part or the currently edited model).<span
style='mso-spacerun:yes'>  </span>The unified command only ever operates on the
current context.<span style='mso-spacerun:yes'>  </span>This is analogous to
retargeted global actions in the Eclipse workbench.<span
style='mso-spacerun:yes'>  </span>We call this <b style='mso-bidi-font-weight:
normal'>implicit local undo scope</b>.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>A
unified undo command exists and its meaning is global for all operations
performed in the system.<span style='mso-spacerun:yes'>  </span>The history
list and default operation to be undone have no relationship to the user’s
current context.<span style='mso-spacerun:yes'>  </span>We call this <b
style='mso-bidi-font-weight:normal'>global undo scope</b>.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The
appropriate scope to be used depends on what the user is doing.<span
style='mso-spacerun:yes'>  </span>When the operations performed by a user are sequential
steps in a larger task, a global scope may be appropriate.<span
style='mso-spacerun:yes'>  </span>When a user is performing separate tasks
while working in separate views, a more localized scope is appropriate.<span
style='mso-spacerun:yes'>  </span>The decision is largely subjective and often
cannot be predicted by the system. <a style='mso-footnote-id:ftn1' href="#_ftn1"
name="_ftnref1" title=""><span class=MsoFootnoteReference><span
style='mso-special-character:footnote'><![if !supportFootnotes]><span
class=MsoFootnoteReference><span style='font-size:10.0pt;font-family:Arial;
mso-fareast-font-family:"Times New Roman";mso-ansi-language:EN-US;mso-fareast-language:
EN-US;mso-bidi-language:AR-SA'>[1]</span></span><![endif]></span></span></a><o:p></o:p></span></p>

<h3>Shared undo contexts<o:p></o:p></h3>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Unfortunately,
the SDK model for undo is more complicated.<span style='mso-spacerun:yes'> 
</span>The contexts for edit and <span class=SpellE>refactoring</span> undo are
not completely separate.<span style='mso-spacerun:yes'>  </span>The user can
trigger <span class=SpellE>refactoring</span> changes from the editor
itself.<span style='mso-spacerun:yes'>  </span>These changes can manipulate
both the document being edited and other workspace resources.<span
style='mso-spacerun:yes'>  </span>Further, these changes occur alongside
localized text editing changes, creating an operation history with multiple
contexts that are initiated from a single part.<span style='mso-spacerun:yes'> 
</span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Even when a
local undo scope is employed, there are different possibilities for
interpreting “undo” when a <span class=SpellE>refactoring</span> operation is
triggered from an editor:<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<ol style='margin-top:0in' start=1 type=1>
 <li class=MsoNormal style='mso-list:l22 level1 lfo3;tab-stops:list .5in'><span
     style='font-size:10.0pt;font-family:Arial'>Edit&gt;Undo causes reversal of
     the <span class=SpellE>refactoring</span> operation that was triggered
     inside the editor.<o:p></o:p></span></li>
 <li class=MsoNormal style='mso-list:l22 level1 lfo3;tab-stops:list .5in'><span
     style='font-size:10.0pt;font-family:Arial'>Edit&gt;Undo causes reversal of
     only the editor’s text-related changes that were caused by the <span
     class=SpellE>refactoring</span> operation.<span style='mso-spacerun:yes'> 
     </span>Thus, the text editing caused by the <span class=SpellE>refactor</span>
     is undone, but the <span class=SpellE>refactor</span> itself is not undone
     (this happens in R3.0.1).<o:p></o:p></span></li>
 <li class=MsoNormal style='mso-list:l22 level1 lfo3;tab-stops:list .5in'><span
     style='font-size:10.0pt;font-family:Arial'>Edit&gt;Undo is unaware of the <span
     class=SpellE>refactoring</span> operation since it affected a context
     larger than the editor itself.<span style='mso-spacerun:yes'>  </span>The
     text operation that occurred before the <span class=SpellE>refactor</span>
     is undone. <o:p></o:p></span></li>
</ol>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Examining
scenarios and the desired behavior shows that any one (or more) of the three
alternatives are desirable at different times, depending on what the user is
trying to achieve.<span style='mso-spacerun:yes'>  </span>Appendix A collects
various <span class=SpellE>refactoring</span> and edit scenarios to help
demonstrate the challenge.<o:p></o:p></span></p>

<h3>Linear vs. selective undo<o:p></o:p></h3>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The
appearance of a simple Edit&gt;Undo command in the UI typically implies a
linear undo.<span style='mso-spacerun:yes'>  </span>That is, the most recent operation
executed is undone.<span style='mso-spacerun:yes'>  </span>Descriptive undo
labels (such as “Undo Typing” or “Undo Rename”) help to remind the user of the
last “undoable” operation.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>As we’ve
shown in discussing scopes and contexts, a strictly linear global undo is not
the ideal behavior when working across contexts.<span
style='mso-spacerun:yes'>  </span>Once an attempt is made to choose the
“appropriate” operation to be undone in the user’s current context, it’s
possible that the chosen operation is not the most recently executed operation.<span
style='mso-spacerun:yes'>  </span>Decisions must be made about how to handle
more recently executed operations.<span style='mso-spacerun:yes'>  </span>A
strictly linear model would force more recent operations to be undone before
allowing the chosen operation to be undone.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><span
style='mso-spacerun:yes'> </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>In a
selective undo approach, users are given an opportunity to view the history
list and select the operation to be undone.<span style='mso-spacerun:yes'> 
</span>Operations that can be undone in the current state of the application
are available for undo at any time, even if there are more recent operations in
the history.<span style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The
workbench support should minimally be a hybrid of these approaches.<span
style='mso-spacerun:yes'>  </span>When the operation appropriate for one
context is not the most recently executed one, then the user (by prompt or by
preference) should have input into the decision to roll back any more recent operations
or perform the undo selectively and retain the rest of the history list.<o:p></o:p></span></p>

<h2>Proposed Undo Support<o:p></o:p></h2>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>While the
discussion and scenarios surrounding scopes and contexts have focused on the
“hard cases,” it should be realized that most users will seek out “undo” in the
simple cases.<span style='mso-spacerun:yes'>  </span>Single context, strictly
linear undo, particularly in text editing, is provided in most popular
applications.<span style='mso-spacerun:yes'>  </span>The availability of a more
selective undo for the “hard cases” should not hinder the expected behavior of
the simple cases. <o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Support for
undo should be “pay as you go,” in terms of efficiency, burden on the user, and
burden on the implementer.<span style='mso-spacerun:yes'>  </span>Validation of
operations in the history list against the current state of the application
should be on demand, rather than forcing operation objects to watch the current
state of the application and react to changes (even when the user might never
choose “undo.”)<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Undo
support should not assume the presence of a user interface.<span
style='mso-spacerun:yes'>  </span>The operations history and associated
interfaces can be defined independent of the UI.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>With these
goals in mind, the following implementation is proposed:<o:p></o:p></span></p>

<h3>Operations Framework</h3>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>A framework
for defining executable, undoable operations (<span class=SpellE>IOperation</span>)
will be provided in a core package, <span class=SpellE>org.eclipse.core.operations</span>.<span
style='mso-spacerun:yes'>  </span>As actions are run, an object describing the
operation to be performed is created, executed, and added to an operations history
(<span class=SpellE>IOperationHistory</span>).<span style='mso-spacerun:yes'> 
</span>Operations which are comprised of distinct steps are represented as
compound operations.<span style='mso-spacerun:yes'>  </span>Compound operations
must be executed as a unit, and can never be partially undone.<span
style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Operations
can be assigned one or more contexts (<span class=SpellE>IOperationContext</span>)
to which they apply.<span style='mso-spacerun:yes'>  </span>The interface for operation
contexts is left very general so that operation implementers may choose the
appropriate representation for their contexts.<span style='mso-spacerun:yes'> 
</span>In some cases, a part-oriented context may be appropriate (an editor’s
undo context is the editor part itself).<span style='mso-spacerun:yes'> 
</span>In other cases, a model object may serve as the context (the navigator’s
context is the workspace). The interface leaves this to the discretion of the
implementer and requires only that equality of contexts can be
established.<span style='mso-spacerun:yes'>  </span>User-appropriate labels and
descriptions for operation contexts are required so that any filtered operation
history views can appropriately label the contexts that are filtering the view.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Contexts
can be assigned in multiple ways:<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:39.0pt;text-indent:-.25in;mso-list:l23 level1 lfo24;
tab-stops:list 39.0pt'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>1.<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><![endif]><span
style='font-size:10.0pt;font-family:Arial'>When the triggering object knows the
context of the operation, the context can be assigned up front.<span
style='mso-spacerun:yes'>  </span>For example, text operations are triggered by
typing in the editor, and the editor can assign its context to the operation
before adding it to the history.<span style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:39.0pt;text-indent:-.25in;mso-list:l23 level1 lfo24;
tab-stops:list 39.0pt'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>2.<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><![endif]><span
style='font-size:10.0pt;font-family:Arial'>Depending on the structure of the
code, the object that creates the operation object may not know what context is
appropriate, or if other contexts should be included.<span
style='mso-spacerun:yes'>  </span>In these cases, a listener can be added to
the operations history.<span style='mso-spacerun:yes'>  </span>When an operation
is added to the history, listeners can decide if their context should be added
to the operation.<span style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:21.0pt'><span style='font-size:10.0pt;
font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Representing
the contexts for an operation as a collection (empty graph) assumes that there
is no inherent relationship between operation contexts.<span
style='mso-spacerun:yes'>  </span>This allows the most flexibility in defining
contexts.<span style='mso-spacerun:yes'>   </span>For example, an editor may perform
an operation that affects both the editor’s document and the workspace at
large.<span style='mso-spacerun:yes'>  </span>These will be considered two
independent contexts and assigned to the operation.<span
style='mso-spacerun:yes'>  </span>One could argue that the context for the
document is simply a refinement of the workspace context, and that a
hierarchical relationship between those contexts should exist.<span
style='mso-spacerun:yes'>  </span>Without more use cases, we avoid establishing
any relationship between contexts at this time<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Operation contexts
that are used when manipulating well-known models should be accessible by
API.<span style='mso-spacerun:yes'>  </span>This can be done in multiple ways:<o:p></o:p></span></p>

<ol style='margin-top:0in' start=1 type=1>
 <li class=MsoNormal style='mso-list:l20 level1 lfo25;tab-stops:list .5in'><span
     style='font-size:10.0pt;font-family:Arial'>API for obtaining a context can
     be added in the same place where the associated model can be
     obtained.<span style='mso-spacerun:yes'>  </span>For example, an editor
     can provide both the document and the context for performing operations on
     the document as API.<o:p></o:p></span></li>
 <li class=MsoNormal style='mso-list:l20 level1 lfo25;tab-stops:list .5in'><span
     style='font-size:10.0pt;font-family:Arial'>Contexts that are related
     directly to certain preexisting platform objects can be obtained using an
     adapter on that object.<span style='mso-spacerun:yes'>  </span>For
     example, the workbench could add an operation context adapter factory for
     the workspace.<span style='mso-spacerun:yes'>  </span>Clients could
     retrieve this adapter using context=<span class=SpellE>workspace.getAdapter</span>(<span
     class=SpellE>IOperationContext.class</span>);<o:p></o:p></span></li>
</ol>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The
following interfaces represent the operation, the operation history, and the operation
context.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in 189.0pt'><span style='font-size:10.0pt;
font-family:Arial'>public interface <span class=SpellE>IOperation</span> {<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in 189.0pt'><span style='font-size:10.0pt;
font-family:Arial'>void <span class=SpellE>addContext</span>(<span
class=SpellE>IOperationContext</span>);<span style='mso-tab-count:1'>           </span>//
add the context to the operation’s contexts<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in 189.0pt'><span class=SpellE><span
style='font-size:10.0pt;font-family:Arial'>boolean</span></span><span
style='font-size:10.0pt;font-family:Arial'> <span class=SpellE>hasContext</span>(<span
class=SpellE>IOperationContext</span>);<span style='mso-tab-count:1'>     </span>//answer
whether the receiver’s contexts contain the context<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in 189.0pt'><span style='font-size:10.0pt;
font-family:Arial'>List <span class=SpellE>getContexts</span>();<span
style='mso-tab-count:1'>                                    </span>// answer
the list of contexts assigned to the receiver.<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in 189.0pt'><span class=SpellE><span
style='font-size:10.0pt;font-family:Arial'>IStatus</span></span><span
style='font-size:10.0pt;font-family:Arial'> <span class=SpellE>canExecute</span>();<span
style='mso-tab-count:1'>                                </span>// answer whether
the receiver can be executed<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in 189.0pt'><span class=SpellE><span
style='font-size:10.0pt;font-family:Arial'>IStatus</span></span><span
style='font-size:10.0pt;font-family:Arial'> <span class=SpellE>canRedo</span>();<span
style='mso-tab-count:1'>                                    </span>// answer
whether the receiver can be redone<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in 189.0pt'><span class=SpellE><span
style='font-size:10.0pt;font-family:Arial'>IStatus</span></span><span
style='font-size:10.0pt;font-family:Arial'> <span class=SpellE>canUndo</span>();<span
style='mso-tab-count:1'>                                    </span>// answer
whether the receiver can be undone<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in 189.0pt'><span style='font-size:10.0pt;
font-family:Arial'>void execute(<span class=SpellE>IProgressMonitor</span>);<span
style='mso-tab-count:1'>                  </span>// execute the operation <o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in 189.0pt'><span style='font-size:10.0pt;
font-family:Arial'>void redo(<span class=SpellE>IProgressMonitor</span>);<span
style='mso-tab-count:1'>                       </span>// redo the operation<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in 189.0pt'><span style='font-size:10.0pt;
font-family:Arial'>void undo(<span class=SpellE>IProgressMonitor</span>);<span
style='mso-tab-count:1'>                      </span>// undo the operation<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in 189.0pt'><span style='font-size:10.0pt;
font-family:Arial'>void dispose();<span style='mso-tab-count:1'>                                          </span>//
the operation is no longer needed<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in 189.0pt'><span style='font-size:10.0pt;
font-family:Arial'>String <span class=SpellE>getLabel</span>();<span
style='mso-tab-count:1'>                                      </span>// provide
a label to name this operation for the user<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in 189.0pt'><span style='font-size:10.0pt;
font-family:Arial'>String <span class=SpellE>getDescription</span>();<span
style='mso-tab-count:1'>                              </span>// provide a
description of this operation for the user<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in 189.0pt'><span style='font-size:10.0pt;
font-family:Arial'>}<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><span
style='mso-tab-count:1'>            </span><o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
style='font-size:10.0pt;font-family:Arial'>public interface <span class=SpellE>IOperationHistory</span>
{<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
style='font-size:10.0pt;font-family:Arial'>void add(<span class=SpellE>IOperation</span>);<span
style='mso-tab-count:1'>                                        </span>// add
the specified operation to the history<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
style='font-size:10.0pt;font-family:Arial'>void redo(<span class=SpellE>IOperationContext</span>,
<span class=SpellE>IProgressMonitor</span>);<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
style='font-size:10.0pt;font-family:Arial'><span style='mso-tab-count:1'>            </span>//
perform the redo operation for the given context<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
style='font-size:10.0pt;font-family:Arial'>void undo(<span class=SpellE>IOperationContext</span>,
<span class=SpellE>IProgressMonitor</span>);<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
style='font-size:10.0pt;font-family:Arial'><span style='mso-tab-count:1'>            </span>//
perform the undo operation appropriate for the given context.<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
class=SpellE><span style='font-size:10.0pt;font-family:Arial'>IStatus</span></span><span
style='font-size:10.0pt;font-family:Arial'> <span class=SpellE>canRedoIn</span>(<span
class=SpellE>IOperationContext</span>);<span style='mso-tab-count:1'>              </span>//
answer whether redo is available in the given context<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
class=SpellE><span style='font-size:10.0pt;font-family:Arial'>IStatus</span></span><span
style='font-size:10.0pt;font-family:Arial'> <span class=SpellE>canUndoIn</span>(<span
class=SpellE>IOperationContext</span>);<span style='mso-tab-count:1'>              </span>//
answer whether undo is available in the given context<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
style='font-size:10.0pt;font-family:Arial'>void <span class=SpellE>addOperationHistoryListener</span>(<span
class=SpellE>IOperationHistoryListener</span>);<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
style='font-size:10.0pt;font-family:Arial'><span style='mso-tab-count:1'>            </span>//
add a listener for changes to the operation history<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
style='font-size:10.0pt;font-family:Arial'>void <span class=SpellE>removeOperationHistoryListener</span>(<span
class=SpellE>IOperationHistoryListener</span>);<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
style='font-size:10.0pt;font-family:Arial'><span style='mso-tab-count:1'>            </span>//
remove the specified history listener from the receiver.<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
class=SpellE><span style='font-size:10.0pt;font-family:Arial'>IOperation</span></span><span
style='font-size:10.0pt;font-family:Arial'> <span class=SpellE>getRedoFor</span>(<span
class=SpellE>IOperationContext</span>);<span style='mso-tab-count:1'>        </span>//
get the redo operation for the given context<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
class=SpellE><span style='font-size:10.0pt;font-family:Arial'>IOperation</span></span><span
style='font-size:10.0pt;font-family:Arial'> [] <span class=SpellE>getRedoHistoryFor</span>(<span
class=SpellE>IOperationContext</span>);<span style='mso-spacerun:yes'>  </span>//
answer the redo history list for the given context<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
class=SpellE><span style='font-size:10.0pt;font-family:Arial'>IOperation</span></span><span
style='font-size:10.0pt;font-family:Arial'> <span class=SpellE>getUndoFor</span>(<span
class=SpellE>IOperationContext</span>);<span style='mso-tab-count:1'>        </span>//
answer the undo operation for the given context<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
class=SpellE><span style='font-size:10.0pt;font-family:Arial'>IOperation</span></span><span
style='font-size:10.0pt;font-family:Arial'> [] <span class=SpellE>getUndoHistoryFor</span>(<span
class=SpellE>IOperationContext</span>);<span style='mso-spacerun:yes'>  </span>//
answer the undo history list for the given context<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
style='font-size:10.0pt;font-family:Arial'>void <span class=SpellE>disposeAll</span>(<span
class=SpellE>IOperationContext</span>);<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
style='font-size:10.0pt;font-family:Arial'><span style='mso-tab-count:1'>            </span>//
Remove all operations that have only the specified context.<span
style='mso-spacerun:yes'>  </span>Implementers must<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
style='font-size:10.0pt;font-family:Arial'><span style='mso-tab-count:1'>            </span>//
determine how to handle operations that have additional contexts.<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
style='font-size:10.0pt;font-family:Arial'>void <span class=SpellE>setLimit</span>(<span
class=SpellE>int</span>);<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
style='font-size:10.0pt;font-family:Arial'><span style='mso-tab-count:1'>            </span>//
set a limit on the operation history.<span style='mso-spacerun:yes'> 
</span>When the limit is reached, the oldest operation <o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.5in .75in 207.0pt 3.5in 297.0pt 4.75in'><span
style='font-size:10.0pt;font-family:Arial'><span style='mso-tab-count:1'>            </span>//
will be disposed to make room for new operations.<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.75in 207.0pt'><span style='font-size:10.0pt;
font-family:Arial'>}<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:.75in 207.0pt'><span style='font-size:10.0pt;
font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal style='tab-stops:207.0pt'><span style='font-size:10.0pt;
font-family:Arial'>public interface <span class=SpellE>IOperationHistoryListener</span>
{<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:207.0pt'><span style='font-size:10.0pt;
font-family:Arial'>void <span class=SpellE>operationAdded</span>(<span
class=SpellE>IOperation</span>);<span style='mso-tab-count:1'>                      </span>//
an operation has been added to the history<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:207.0pt'><span style='font-size:10.0pt;
font-family:Arial'>void <span class=SpellE>aboutToUndo</span>(<span
class=SpellE>IOperation</span>);<span style='mso-tab-count:1'>                          </span>//
the operation is about to be undone<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:207.0pt'><span style='font-size:10.0pt;
font-family:Arial'>void undone(<span class=SpellE>IOperation</span>);<span
style='mso-tab-count:1'>                                  </span>// the
operation was undone<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:207.0pt'><span style='font-size:10.0pt;
font-family:Arial'>void <span class=SpellE>aboutToRedo</span>(<span
class=SpellE>IOperation</span>);<span style='mso-tab-count:1'>                          </span>//
the operation is about to be redone<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:207.0pt'><span style='font-size:10.0pt;
font-family:Arial'>void redone(<span class=SpellE>IOperation</span>);<span
style='mso-tab-count:1'>                                   </span>// the
operation was redone<o:p></o:p></span></p>

<p class=MsoNormal style='tab-stops:207.0pt'><span style='font-size:10.0pt;
font-family:Arial'>}<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>public
interface <span class=SpellE>IOperationContext</span> {<o:p></o:p></span></p>

<p class=MsoNormal><span class=SpellE><span style='font-size:10.0pt;font-family:
Arial'>IOperationApproval</span></span><span style='font-size:10.0pt;
font-family:Arial'> <span class=SpellE>getOperationApproval</span>();<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>String <span
class=SpellE>getDescription</span>();<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>String <span
class=SpellE>getLabel</span>();<o:p></o:p></span></p>

<p class=MsoNormal><span class=SpellE><span style='font-size:10.0pt;font-family:
Arial'>boolean</span></span><span style='font-size:10.0pt;font-family:Arial'>
equals(<span class=SpellE>IOperationContext</span>);<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>}<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>public
interface <span class=SpellE>IOperationApproval</span> {<o:p></o:p></span></p>

<p class=MsoNormal><span class=SpellE><span style='font-size:10.0pt;font-family:
Arial'>boolean</span></span><span style='font-size:10.0pt;font-family:Arial'> <span
class=SpellE>proceedUndoing</span>(<span class=SpellE>IOperation</span>);<o:p></o:p></span></p>

<p class=MsoNormal><span class=SpellE><span style='font-size:10.0pt;font-family:
Arial'>boolean</span></span><span style='font-size:10.0pt;font-family:Arial'> <span
class=SpellE>proceedRedoing</span>(<span class=SpellE>IOperation</span>);<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>}<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>An
operation is responsible for validating its ability to execute and undo against
the current state of the application.<span style='mso-spacerun:yes'> 
</span>Validation may be requested even when an operation is not the most
recently executed operation (or most recently undone operation).<span
style='mso-spacerun:yes'>  </span>This is important since operations in
unrelated contexts may coexist in the same history unaware of one another’s
existence.<span style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>As
operations are executed, they are added to the operation history.<span
style='mso-spacerun:yes'>  </span>Note that the operation history does not necessarily
perform the initial execution, but rather assumes the operation is already
executed before it is added to the history.<span style='mso-spacerun:yes'> 
</span>This is necessary for text editing operations, where the operations are
happening as the user types and the recording/batching of operations for the
history occur afterwards.<span style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The operation
history is responsible for implementing the application’s undo model, and the
decisions about handling multiple contexts.<span style='mso-spacerun:yes'> 
</span>If an application chooses to implement a strictly linear, global undo,
then its implementation of <span class=SpellE>IOperationHistory</span> can
ensure that requests to perform undo or redo in a particular context will fail
if the most recent operation does not have that context.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>More
flexible undo models may be implemented with the assistance of the <span
class=SpellE>IOperationApproval</span> that is assigned to an operation context.<span
style='mso-spacerun:yes'>  </span>This interface allows other contexts to be
consulted when an operation is to be executed or undone.<span
style='mso-spacerun:yes'>  </span>The undo model defined by the operation
history determines when to consult the <span class=SpellE>IOperationApproval</span>.<span
style='mso-spacerun:yes'>  </span>Possible implementations will be discussed in
more detail in the workbench scenarios.<span style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<h3>Workbench Undo Semantics</h3>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The
workbench will adopt a hybrid undo approach that allows selective undo across
multiple contexts.<span style='mso-spacerun:yes'>  </span>The workbench will
allow undo/redo of any valid operation in the history, <i style='mso-bidi-font-style:
normal'>as long as there are no more recent operations in the history that
share a context with the operation to be executed.</i><span
style='mso-spacerun:yes'>  </span><span style='mso-spacerun:yes'> </span>If the
operation to be undone/redone has contexts that are also present in operations appearing
later in the history, then the <span class=SpellE>IOperationApproval</span> for
the contexts that have the conflicts will be consulted.<span
style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>A concrete
example will help explain this.<span style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>The
user makes local edits in editor A.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>The
user initiates a <span class=SpellE>refactoring</span> operation whose context
is “A” and “workspace.”<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>The
user makes additional local edits to editor A.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>The
user goes to the navigator and selects Undo.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>In the
proposed implementation, the navigator would request an undo for the context
“workspace.”<span style='mso-spacerun:yes'>  </span>The <span class=SpellE>refactoring</span>
operation triggered in the editor is the most recent operation that has the
workspace context, but it also contains context “A.”<span
style='mso-spacerun:yes'>  </span>Since subsequent operations in the history
also have context “A,”, the <span class=SpellE>IOperationApproval</span> for
context “A” is consulted as to whether the undo should proceed.<span
style='mso-spacerun:yes'>  </span>The <span class=SpellE>IOperationApproval</span>
<span style='mso-spacerun:yes'> </span>supplied by context “A” could do one of
the following:<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>allow
the undo to proceed, leaving the local changes to “A” in the undo history.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>quietly
undo the subsequent local changes to “A” and then allow the original undo to
proceed.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>switch
to the editor and non-quietly undo the local changes to “A” before allowing the
original undo to proceed.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>prompt
the user for the preferred action.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>provide
a user preference that drives the behavior of the scenario.<o:p></o:p></span></p>

<h4>Workbench IDE undo contexts<o:p></o:p></h4>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>To support
the existing workbench undo scenarios, there will be two kinds of contexts
defined in the workbench IDE.<span style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<ol style='margin-top:0in' start=1 type=1>
 <li class=MsoNormal style='mso-list:l10 level1 lfo26;tab-stops:list .5in'><span
     style='font-size:10.0pt;font-family:Arial'>The “workspace” context will be
     used to represent changes that affect resources in the workspace.<span
     style='mso-spacerun:yes'>  </span><span class=SpellE>Refactoring</span>
     operations will use this context.<span style='mso-spacerun:yes'> 
     </span>Additional actions that affect the workspace (such as delete and
     create resources) would use this context.<span style='mso-spacerun:yes'> 
     </span>Views that manipulate the workspace, such as the navigator and
     package explorer, will use this context when creating operations and
     querying for the current “undo operation.”<span style='mso-spacerun:yes'> 
     </span>Views or editors that may be affected by workspace operations can
     add a listener to the operation history and add their context as needed to
     operations that have been added to the history.<span
     style='mso-spacerun:yes'>  </span><span style='mso-spacerun:yes'> </span>The
     workspace context implementation is not defined at this time, but it
     should be accessible by API.<span style='mso-spacerun:yes'>  </span><o:p></o:p></span></li>
 <li class=MsoNormal style='mso-list:l10 level1 lfo26;tab-stops:list .5in'><span
     style='font-size:10.0pt;font-family:Arial'>Editors will define a context
     that represents their particular editing session.<span
     style='mso-spacerun:yes'>  </span><span style='mso-spacerun:yes'> </span>That
     is, the context will be unique per editor, but editors may in fact share
     the context implementation class.<span style='mso-spacerun:yes'> 
     </span>Workspace-affecting operations, such as <span class=SpellE>refactoring</span>
     operations, that are triggered from an editor will be considered to occur
     in the context of both the editor and the workspace.<span
     style='mso-spacerun:yes'>  </span>This allows <span class=SpellE>refactoring</span>
     operations to coexist with text editing operations in the editor’s operation
     history and also be accessible from the operation history of other views
     that support the workspace context, such as the navigator. The editor’s
     context can be added using the listener as described above.<o:p></o:p></span></li>
</ol>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Further
definition of contexts and the supported operations are required:<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>The
complete set of workspace operations (besides <span class=SpellE>refactoring</span>)
that should be undoable must be defined.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>Any
additional contexts required by the SDK (Team?<span style='mso-spacerun:yes'> 
</span>Debug?) must be defined.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>The
operation contexts for the major views in the SDK must be defined.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>The
semantics for assigning multiple contexts must be defined.<span
style='mso-spacerun:yes'>  </span>For example, do <span class=SpellE>refactoring</span>
operations that affect an open editor (but were triggered elsewhere) carry the
context of that editor? <span style='mso-spacerun:yes'> </span>Should the
editor decide this by listening for new operations that are added to the
history? <o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The
following are working assumptions about the undo operations:<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>There
is no relationship between a perspective and an operation context, since
switching perspectives will change the active part, and thus may or may not
affect the current context.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>Actions
that only change the presentation in the workbench (open a view, switch
perspectives, change the sort order) are not considered to be operations since
they are<span style='mso-spacerun:yes'>  </span>easily undone and redone
through the same window mechanics.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<h4>Workbench UI for Undo/Redo<o:p></o:p></h4>

<h5>Minimal support</h5>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The Edit&gt;Undo
and Edit&gt;Redo commands should be retargeted by most of the major views (list
of views TBD).<span style='mso-spacerun:yes'>  </span>If a view retargets
Undo/Redo, then it knows what operation contexts it supports, and it uses these
contexts to retrieve the available undo operation.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Edit&gt;Undo
is enabled based on the active part.<span style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><span
style='mso-tab-count:1'>            </span><span class=SpellE>IStatus</span>
status = <span class=SpellE>operationHistory.canUndoIn</span>(<span
class=SpellE>myContext</span>);<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><span
style='mso-tab-count:1'>            </span>// up to the active part to define
behavior for anything between OK and FATAL.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The label
for the undo action should be appended with a description of the operation.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><span
style='mso-tab-count:1'>            </span><span class=SpellE>operationToUndo</span>
= <span class=SpellE>operationHistory.getUndoFor</span>(<span class=SpellE>myContext</span>);<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><span
style='mso-tab-count:1'>            </span>label = “Undo “+ <span class=SpellE>operationToUndo.label</span>();<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Undo and
Redo on the toolbar include a drop down that shows the operation history.<span
style='mso-spacerun:yes'>  </span>This history depends on the current part’s
context.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><span
style='mso-tab-count:1'>            </span><span class=SpellE>operationHistory.getUndoHistoryFor</span>(<span
class=SpellE>myContext</span>);<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The drop
down permits range selection of operations from the top down (see MS Word and
other applications).<span style='mso-spacerun:yes'>  </span>This UI implies a
linear undo within any particular set of contexts.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The UI for
handling special cases should be determined.<span style='mso-spacerun:yes'> 
</span>Consider the following scenarios:<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>Scenario #1:</span></b><span
style='font-size:10.0pt;font-family:Arial'><span style='mso-spacerun:yes'> 
</span>Mixed contexts in an editor, undo from another view<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>The
user makes local edits in editor A.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>The
user initiates a <span class=SpellE>refactoring</span> operation whose context
is “A” and “workspace.”<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>The
user makes additional local edits to editor A.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>The
user goes to the navigator and selects Undo.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The <span
class=SpellE>IOperationApproval</span> for the editor’s context can implement
UI for handling this case if desired.<span style='mso-spacerun:yes'> 
</span>Possible options include:<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>warn
the user about the local changes in A and ask whether to undo them or leave
them<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>provide
a user preference that drives the behavior of the scenario.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The exact
solution will be prototyped and may involve both a first-time prompt and
subsequent preference (“Don’t ask me again”).<o:p></o:p></span></p>

<p class=MsoNormal><o:p>&nbsp;</o:p></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>Scenario #2</span></b><span
style='font-size:10.0pt;font-family:Arial'>:<span style='mso-spacerun:yes'> 
</span>Editor undo triggers a non-local operation<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>The
user makes local edits in editor A.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>The
user initiates a <span class=SpellE>refactoring</span> operation whose context
is “A” and “workspace.”<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>The
user makes additional local edits to editor A.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>The
user selects undo repeatedly from the editor<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Most operations
in the editor’s context affect only the editor.<span style='mso-spacerun:yes'> 
</span>The <span class=SpellE>refactoring</span> operation affects not only the
editor, but other objects in the workspace.<span style='mso-spacerun:yes'> 
</span>It might surprise the user for the <span class=SpellE>refactoring</span>
to be undone.<span style='mso-spacerun:yes'>  </span>The editor could implement
a warning dialog when it detects that the proposed undo operation has
additional contexts.<span style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>If the <span
class=SpellE>refactoring</span> had been triggered elsewhere (say, editor “B”
or the navigator), but resulted in changes to editor “A,” it is even more
important that the user be warned about the operation invoked by the undo
command.<span style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The<span
style='mso-spacerun:yes'>  </span>solution for this scenario will be prototyped
and may involve both a warning and subsequent preference.<span
style='mso-spacerun:yes'>  </span>For example, a prompt could provide the label
and description of the operation and warn that it affects other views.<span
style='mso-spacerun:yes'>  </span>The user could choose whether to proceed, and
the choice could be remembered in a preference.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>It appears
that the proposed framework allows detection of these cases and hooks for
supplying the necessary UI.<o:p></o:p></span></p>

<h5>Advanced support</h5>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>More
selective undo approaches can be supported by the framework, but the ability to
support them in the workbench depends upon the implementation of the individual
operations and their ability to be undone independently.<span
style='mso-spacerun:yes'>  </span>The priority is TBD.<span
style='mso-spacerun:yes'>  </span>Ideas include:<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Additional menu
commands show the operation history.<o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:.5in'><span style='font-size:10.0pt;
font-family:Arial'>Edit&gt;Undo… shows the undo operation history based on the
active part’s context.<o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:.5in'><span style='font-size:10.0pt;
font-family:Arial'>Edit&gt;Redo… shows the redo operation history based on the
active part’s context.<o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:.5in'><span style='font-size:10.0pt;
font-family:Arial'><span style='mso-tab-count:1'>            </span><span
class=SpellE>operationHistory.getUndoHistoryFor</span>(<span class=SpellE>myContext</span>);<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The operation
history can be shown in a view or dialog.<span style='mso-spacerun:yes'> 
</span>Operations that are valid can be selected (one at a time) and undone (or
redone) regardless of sequential order.<span style='mso-spacerun:yes'>  </span>Multiple
selections are not allowed since the validation state for an operation might
change as other operations are undone.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The operation
history view could allow changing of the filtering.<span
style='mso-spacerun:yes'>  </span>While the default filtering could depend on
the active part’s context, the user could be shown the available contexts and
choose one or more contexts (or none at all) that affect the filtering of the
list.<span style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Note that
the UI for the advanced cases can be implemented independently from the operations,
and may be useful for testing the framework.<o:p></o:p></span></p>

<h3>Compatibility Issues</h3>

<h4><span class=SpellE>JFace</span> Text</h4>

<p class=MsoNormal><span class=SpellE><span style='font-size:10.0pt;font-family:
Arial'>JFace</span></span><span style='font-size:10.0pt;font-family:Arial'> text
currently has API for retrieving an <span class=SpellE>IUndoManager</span> from
a text viewer.<span style='mso-spacerun:yes'>  </span>The undo manager is
connected to a text viewer and watches the changes that happen in the
viewer.<span style='mso-spacerun:yes'>  </span>As editing actions occurs,
commands (<span class=SpellE>TextCommand</span>) are created and then
“committed” to a command stack.<span style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span class=SpellE><span style='font-size:10.0pt;font-family:
Arial'>TextCommand</span></span><span style='font-size:10.0pt;font-family:Arial'>
could be changed to implement <span class=SpellE>IOperation</span>.<span
style='mso-spacerun:yes'>  </span>The mapping from <span class=SpellE>IOperation</span>
to <span class=SpellE>TextCommand</span> protocol is straightforward.<span
style='mso-spacerun:yes'>  </span>Currently the <span class=SpellE>TextCommand</span>
directly pushes itself onto a local command stack of a viewer when a set of pending
changes are committed.<span style='mso-spacerun:yes'>  </span>Instead, it would
need to set its context to one appropriate for the text viewer and add itself
to the workbench operation history.<span style='mso-spacerun:yes'>  </span><span
style='mso-spacerun:yes'> </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span class=SpellE><span style='font-size:10.0pt;font-family:
Arial'>IUndoManager</span></span><span style='font-size:10.0pt;font-family:
Arial'> API could be mapped as follows:<o:p></o:p></span></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>connect(<span class=SpellE>ITextViewer</span>)
<o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Creates a
context (<span class=SpellE>myContext</span>) appropriate for representing this
document’s operations<o:p></o:p></span></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>disconnect(<span class=SpellE>ITextViewer</span>)
<o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Performs
necessary disconnect behavior and clears the operation history of operations involving
the viewer.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in'><span class=SpellE><span
style='font-size:10.0pt;font-family:Arial'>operationHistory.disposeAll</span></span><span
style='font-size:10.0pt;font-family:Arial'>(<span class=SpellE>myContext</span>);<o:p></o:p></span></p>

<p class=MsoNormal><span class=SpellE><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>beginCompoundChange</span></b></span><b
style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt;font-family:
Arial'>() <o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Creates a <span
class=SpellE>CompoundOperation</span> and stores subsequent <span class=SpellE>TextCommands</span>
in this operation.<o:p></o:p></span></p>

<p class=MsoNormal><span class=SpellE><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>endCompoundChange</span></b></span><b
style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt;font-family:
Arial'><o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Adds the current
compound operation to the operation history.<o:p></o:p></span></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>reset()<o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Clears the operation
history of operations involving the viewer.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><span
style='mso-tab-count:1'>            </span><span class=SpellE>operationHistory.disposeAll</span>(<span
class=SpellE>myContext</span>);<o:p></o:p></span></p>

<p class=MsoNormal><span class=SpellE><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>setMaximumUndoLevel</span></b></span><b
style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt;font-family:
Arial'>(<span class=SpellE>int</span>) – TBD<o:p></o:p></span></b></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>undoable() <o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Maps as
follows:<o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:.5in'><span style='font-size:10.0pt;
font-family:Arial'>status = <span class=SpellE>operationHistory.canUndoIn</span>(<span
class=SpellE>myContext</span>);<o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:.5in'><span style='font-size:10.0pt;
font-family:Arial'>return <span class=SpellE>status.isOK</span>();<span
style='mso-spacerun:yes'>  </span>// may require further checking of other
cases<o:p></o:p></span></p>

<p class=MsoNormal><span class=SpellE><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>redoable</span></b></span><b
style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt;font-family:
Arial'>() <o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Maps as
follows:<o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:.5in'><span style='font-size:10.0pt;
font-family:Arial'>status = <span class=SpellE>operationHistory.canRedoIn</span>(<span
class=SpellE>myContext</span>);<o:p></o:p></span></p>

<p class=MsoNormal style='text-indent:.5in'><span style='font-size:10.0pt;
font-family:Arial'>return <span class=SpellE>status.isOK</span>();<span
style='mso-spacerun:yes'>  </span>// may require further checking of other
cases<o:p></o:p></span></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>undo()<o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Use <span
class=SpellE>operationHistory.performUndoFor</span>(<span class=SpellE>myContext</span>)
instead of managing its own stack.<o:p></o:p></span></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>redo()<o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Use <span
class=SpellE>operationHistory.performRedoFor</span>(<span class=SpellE>myContext</span>)
instead of managing its own stack.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The <span
class=SpellE>TextCommand</span> class is private, so no API mapping is
discussed here.<span style='mso-spacerun:yes'>  </span>However, its protocol is
very similar to <span class=SpellE>IOperation</span> and the
reimplementation/mapping is straightforward.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Issues:<span
style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>As
discussed throughout this document, additional operations (such as compound operations
or <span class=SpellE>refactoring</span> operations) might appear in the text
viewer’s context, and therefore in its <span class=SpellE>IUndoManager</span>.<span
style='mso-spacerun:yes'>  </span>The implementation should be checked for any
assumptions that the current operation is a <span class=SpellE>TextCommand</span>.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.5in;text-indent:-.25in;mso-list:l21 level1 lfo1;
tab-stops:list .5in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span class=SpellE><span style='font-size:10.0pt;
font-family:Arial'>IUndoManager</span></span><span style='font-size:10.0pt;
font-family:Arial'> currently keeps a local history limit.<span
style='mso-spacerun:yes'>  </span>How do we handle this?<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.75in;text-indent:-.25in;mso-list:l17 level1 lfo20;
tab-stops:list .75in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>allow
local history limits per context (seems complicated)<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.75in;text-indent:-.25in;mso-list:l17 level1 lfo20;
tab-stops:list .75in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>ignore
this part of the API in the new world<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.75in;text-indent:-.25in;mso-list:l17 level1 lfo20;
tab-stops:list .75in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>decide
how to affect the global history limit based on the local limit<o:p></o:p></span></p>

<h4><span class=SpellE>Refactoring</span> </h4>

<p class=MsoNormal><span class=SpellE><span style='font-size:10.0pt;font-family:
Arial'>Refactoring</span></span><span style='font-size:10.0pt;font-family:Arial'>
undo is currently implemented with change objects,<span
style='mso-spacerun:yes'>  </span>Change objects record workspace changes
initiated by <span class=SpellE>refactoring</span> operations.<span
style='mso-spacerun:yes'>  </span>When a <span class=SpellE>refactoring</span>
change is performed, it can optionally return another change that could be used
to undo the change just executed.<span style='mso-spacerun:yes'>  </span>The
undo change is placed in <span class=SpellE>refactoring’s</span> <span
class=SpellE>IUndoManager</span>.<span style='mso-spacerun:yes'> 
</span>Changes can be performed, but any undo or redo causes a new change to be
created vs. having each change know how to undo and redo itself. <o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>While this
approach simplifies the protocol for an operation, it has not been used in the
proposed framework for several reasons:<o:p></o:p></span></p>

<ol style='margin-top:0in' start=1 type=1>
 <li class=MsoNormal style='mso-list:l12 level1 lfo27;tab-stops:list .5in'><span
     style='font-size:10.0pt;font-family:Arial'>It is not compatible with the
     implementation used by text, EMF, or GEF. <o:p></o:p></span></li>
 <li class=MsoNormal style='mso-list:l12 level1 lfo27;tab-stops:list .5in'><span
     style='font-size:10.0pt;font-family:Arial'>It causes additional operations
     to be created before an undo is ever requested.<span
     style='mso-spacerun:yes'>  </span>This violates the goal of “pay as you
     go.”<o:p></o:p></span></li>
</ol>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Additional
protocol is provided for initializing data needed to do a live validation for
execution.<span style='mso-spacerun:yes'>  </span>Validation can be done with
this cached information or on the fly.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Protocol is
also provided to return the object modified by a change (<span class=SpellE>getModifiedElement</span>()).<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The Change
API could be mapped as follows.<span style='mso-spacerun:yes'>  </span>Note
that much of the protocol could be provided in an abstract “<span class=SpellE>RefactoringOperation</span>”
or perhaps in a more generic “<span class=SpellE>WorkspaceOperation</span>.”<span
style='mso-spacerun:yes'>  </span>However we do not promote these concepts to
the framework since different kinds of operations have different needs for
caching model objects, validation state, etc.<span style='mso-spacerun:yes'> 
</span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span class=SpellE><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>getModifiedElement</span></b></span><b
style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt;font-family:
Arial'>() <o:p></o:p></span></b></p>

<p class=MsoNormal><span class=SpellE><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>getAdapter</span></b></span><b
style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt;font-family:
Arial'>(Class)<o:p></o:p></span></b></p>

<p class=MsoNormal><span class=SpellE><span style='font-size:10.0pt;font-family:
Arial'>Refactoring</span></span><span style='font-size:10.0pt;font-family:Arial'>
changes need to know which model element is modified by the change.<span
style='mso-spacerun:yes'>  </span>They must also implement <span class=SpellE>IAdaptable</span>.<span
style='mso-spacerun:yes'>  </span>This protocol can be provided in an abstract <span
class=SpellE>RefactoringOperation</span> and interpreted by individual
subclasses as done today.<span style='mso-spacerun:yes'>  </span>This protocol
might in fact be suitable for all workspace-affecting operations.<span
style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal><span class=SpellE><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>getParent</span></b></span><b
style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt;font-family:
Arial'>()<o:p></o:p></span></b></p>

<p class=MsoNormal><span class=SpellE><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>setParent</span></b></span><b
style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt;font-family:
Arial'>(Change)<o:p></o:p></span></b></p>

<p class=MsoNormal><span class=SpellE><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>isEnabled</span></b></span><b
style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt;font-family:
Arial'>()<o:p></o:p></span></b></p>

<p class=MsoNormal><span class=SpellE><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>setEnabled</span></b></span><b
style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt;font-family:
Arial'>(<span class=SpellE>boolean</span>)<o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The
associated fields and protocol can be defined in an abstract class. <o:p></o:p></span></p>

<p class=MsoNormal><span class=SpellE><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>initializeValidationData</span></b></span><b
style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt;font-family:
Arial'>(</span></b><span class=SpellE><span style='font-size:10.0pt;font-family:
Arial'>IProgressMonitor</span></span><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>)<o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>This hook
allows changes to cache local validation data, or to hook up listeners to the
model and listen for changes that may invalidate the change.<span
style='mso-spacerun:yes'>  </span>This protocol could be provided in the
abstract <span class=SpellE>refactoring</span> class. <o:p></o:p></span></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>dispose()<o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Maps
directly.<o:p></o:p></span></p>

<p class=MsoNormal><span class=SpellE><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>getName</span></b></span><b
style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt;font-family:
Arial'>()<o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Maps to <span
class=SpellE>operation.getLabel</span><o:p></o:p></span></p>

<p class=MsoNormal><span class=SpellE><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>isValid</span></b></span><b
style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt;font-family:
Arial'>(<span class=SpellE>IProgressMonitor</span>)<o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Maps to <span
class=SpellE>canUndo</span>(), <span class=SpellE>canRedo</span>(), and <span
class=SpellE>canExecute</span>().<span style='mso-spacerun:yes'>  </span>See
discussion below.<o:p></o:p></span></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>perform(<span class=SpellE>IProgressMonitor</span>)<o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Maps to undo(<span
class=SpellE>IProgressMonitor</span>), redo(<span class=SpellE>IProgressMonitor</span>)
and <span class=SpellE>canExecute</span>(<span class=SpellE>IProgressMonitor</span>).<span
style='mso-spacerun:yes'>  </span>See discussion below.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Issues<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.75in;text-indent:-.25in;mso-list:l17 level1 lfo20;
tab-stops:list .75in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span class=SpellE><span style='font-size:10.0pt;
font-family:Arial'>Refactoring</span></span><span style='font-size:10.0pt;
font-family:Arial'> change objects do not support direct undo() or redo().<span
style='mso-spacerun:yes'>  </span>Rather, a change that supports undo() returns
a new change that “undoes” it whenever it is executed.<span
style='mso-spacerun:yes'>  </span>The code for <span class=SpellE>refactoring</span>
changes would have to be <span class=SpellE>refactored</span> in one of these
ways:<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:1.25in;text-indent:-.25in;mso-list:l17 level2 lfo20;
tab-stops:list 1.25in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:"Courier New";mso-fareast-font-family:"Courier New"'><span
style='mso-list:Ignore'>o<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>Eliminate
the creation of the undo change and move this work into an undo() method.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:1.25in;text-indent:-.25in;mso-list:l17 level2 lfo20;
tab-stops:list 1.25in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:"Courier New";mso-fareast-font-family:"Courier New"'><span
style='mso-list:Ignore'>o<span style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>Continue
to create the undo change when performing a change, but instead of returning
it, cache it in the change itself.<span style='mso-spacerun:yes'>  </span>Undo
protocol checks for the presence of this change and uses it for any undo
validation or execution requests.<o:p></o:p></span></p>

<p class=MsoNormal style='margin-left:.75in;text-indent:-.25in;mso-list:l17 level1 lfo20;
tab-stops:list .75in'><![if !supportLists]><span style='font-size:10.0pt;
font-family:Arial;mso-fareast-font-family:Arial'><span style='mso-list:Ignore'>-<span
style='font:7.0pt "Times New Roman"'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
</span></span></span><![endif]><span style='font-size:10.0pt;font-family:Arial'>Validation
of <span class=SpellE>refactoring</span> changes is assumed to be expensive, so
a progress monitor is provided in validation protocol.<span
style='mso-spacerun:yes'>  </span>This concept is not promoted to the framework
since validity is checked when building the undo menu command.<span
style='mso-spacerun:yes'>  </span>Is the progress monitor absolutely necessary
for validation vs. execution?<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><span
style='mso-spacerun:yes'> </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>It is
likely that many views and editors in the workbench IDE will be aware of this special
kind of <span class=SpellE>IOperation</span>.<span style='mso-spacerun:yes'> 
</span>An additional interface, <span class=SpellE>IWorkspaceOperation</span>,
may evolve as <span class=SpellE>refactoring</span> changes are adapted to the
new operations framework.<span style='mso-spacerun:yes'>  </span>Patterns
surrounding the workspace operation will develop, particularly involving
operation contexts.<span style='mso-spacerun:yes'>  </span>For example, views
and editors (such as text editors) that are workspace-aware could listen to the
operations history.<span style='mso-spacerun:yes'>  </span>As new workspace
operations are added to the history, the modified element can be queried by the
listener.<span style='mso-spacerun:yes'>  </span>The listener can add its
operation context to the operation if desired.<span style='mso-spacerun:yes'> 
</span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<h4>GEF</h4>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>GEF
supplies a Command framework and a <span class=SpellE>CommandStack</span> which
manages an internal undo and redo stack.<span style='mso-spacerun:yes'> 
</span>Commands are pushed onto the stack when they are executed by the stack.<span
style='mso-spacerun:yes'>  </span>Most GEF command protocol can be mapped to
the proposed operation protocol.<span style='mso-spacerun:yes'>  </span>The GEF
commands are very similar to <span class=SpellE>IOperation</span> without the
notion of contexts.<span style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Issues for
GEF arise in the differences between <span class=SpellE>GEF’s</span> command
stack and the proposed operation history.<span style='mso-spacerun:yes'> 
</span>We assume that GEF intends for GEF commands to coexist with other
workbench operations in a shared undo history.<span style='mso-spacerun:yes'> 
</span>If so, then the command stack must be replaced by the operation
history.<span style='mso-spacerun:yes'>  </span>Issues include:<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span class=SpellE><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>isDirty</span></b></span><b
style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt;font-family:
Arial'>()<o:p></o:p></span></b></p>

<p class=MsoNormal><span class=SpellE><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>markSaveLocation</span></b></span><b
style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt;font-family:
Arial'>()<o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>GEF
supports a marker (<span class=SpellE>saveLocation</span>) that becomes dirty
if any commands are added after the mark is made.<span
style='mso-spacerun:yes'>  </span>If this concept is still needed in light of
the new framework, then GEF might have to mark the location inside its own
commands or using a dummy marker command.<o:p></o:p></span></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>execute(Command)<o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The GEF
command stack executes commands on behalf of the client and adds them to the
stack, while the operation history does not do the execution on behalf of the
client.<span style='mso-spacerun:yes'>  </span>GEF clients that create GEF
commands would alter the pattern “<span class=SpellE>commandStack.execute</span>(<span
class=SpellE>someCommand</span>)” to instead use “<span class=SpellE>someCommand.execute</span>(null);
<span class=SpellE>operationHistory.add</span>(<span class=SpellE>someCommand</span>)”<span
style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal><span class=SpellE><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>addCommandStackListener</span></b></span><b
style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt;font-family:
Arial'>(<span class=SpellE>CommandStackListener</span>)<o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>GEF is
evolving its <span class=SpellE>CommandListener</span> interface in R3.1 to
include additional notification.<span style='mso-spacerun:yes'>  </span>This
must be reconciled with the proposed support in <span class=SpellE>IOperationHistoryListener</span>
and the ability to further validate commands using <span class=SpellE>IOperationApproval</span>.<span
style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<h4>EMF/WTP</h4>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The EMF
command framework is very similar to the GEF support and has similar issues to
those described above.<span style='mso-spacerun:yes'>  </span>Additional issues
arise for:<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span class=SpellE><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>getResult</span></b></span><b
style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt;font-family:
Arial'>();<o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>This method
answers the result of command execution when the command is in certain
states.<span style='mso-spacerun:yes'>  </span>Since clients can execute an
operation explicitly in the framework, EMF code could query the result after
execution and store it in an EMF abstract operation.<span
style='mso-spacerun:yes'>  </span>This protocol could then be provided in the
EMF operations.<o:p></o:p></span></p>

<p class=MsoNormal><span class=SpellE><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>getAffectedObjects</span></b></span><b
style='mso-bidi-font-weight:normal'><span style='font-size:10.0pt;font-family:
Arial'>();<o:p></o:p></span></b></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>This method
is used to highlight the appropriate objects in a view to show what the EMF command
did.<span style='mso-spacerun:yes'>  </span><span
style='mso-spacerun:yes'>  </span>It is not clear that this will be generally necessary.<span
style='mso-spacerun:yes'>  </span>This protocol could be added in an EMF
operation abstract class.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>As
discussed with <span class=SpellE>refactoring</span> changes, an abstract class
providing the mapped protocol will likely evolve, along with usage patterns for
listening for new EMF operations and assigning appropriate operation contexts. <o:p></o:p></span></p>

<b><span style='font-size:16.0pt;font-family:Arial;mso-fareast-font-family:
"Times New Roman";mso-font-kerning:16.0pt;mso-ansi-language:EN-US;mso-fareast-language:
EN-US;mso-bidi-language:AR-SA'><br clear=all style='page-break-before:always'>
</span></b>

<h1>Appendix A:<span style='mso-spacerun:yes'>  </span>Workbench Undo Scenarios<span
style='font-size:10.0pt'><o:p></o:p></span></h1>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The
following scenarios were used while discussing possible designs for a common
undo framework.<span style='mso-spacerun:yes'>  </span><span
style='mso-spacerun:yes'> </span>Most of these scenarios involve conflicting
contexts or scopes.<span style='mso-spacerun:yes'>  </span>These scenarios,
involving mixed text edits and <span class=SpellE>refactoring</span>
operations, have complicated previous efforts to define a common undo
framework.<span style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>The
scenarios assume that an integrated undo in the workbench should present a
common “Undo” command rather than the separate commands employed today, and
that the “Undo” command is descriptive enough to imply the operation that will
take place.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>For each
scenario described, we attempt to describe the desired outcome, the outcome in
R3.0.1 where applicable, and any interesting alternative outcomes. <o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Note that
some scenarios involve nearly the same user interactions, but are different in
desired outcome based on what the user was trying to accomplish while
performing the operations.<span style='mso-spacerun:yes'>  </span>Specific user
intent is described in order to clarify the scenario.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>Scenario #1:</span></b><span
style='font-size:10.0pt;font-family:Arial'><span style='mso-spacerun:yes'> 
</span>User is editing source file “A.”<span style='mso-spacerun:yes'> 
</span>While editing the document, some interrupt occurs causing the user to go
to the navigator and <span class=SpellE>refactor</span> some code unrelated to
A.<span style='mso-spacerun:yes'>  </span>When the <span class=SpellE>refactoring</span>
is complete, the user returns to the editor on “A” and notices a typo.<span
style='mso-spacerun:yes'>  </span>The user selects Edit&gt;Undo.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><span
style='mso-tab-count:1'>            </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Desired
Outcome:<span style='mso-spacerun:yes'>  </span>The last text editing operation
made before the unrelated <span class=SpellE>refactoring</span> operation is
undone.<span style='mso-spacerun:yes'>  </span>The typo is corrected.<span
style='mso-spacerun:yes'>  </span>The undo command was described as “undo
typing”<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>R3.0.1
Outcome:<span style='mso-spacerun:yes'>  </span>Desired Outcome.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Proposal
Outcome:<span style='mso-spacerun:yes'>  </span>Desired Outcome.<span
style='mso-spacerun:yes'>  </span>(Unrelated <span class=SpellE>refactoring</span>
operation did not have the editor’s context).<span style='mso-spacerun:yes'> 
</span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>Scenario #2:</span></b><span
style='font-size:10.0pt;font-family:Arial'><span style='mso-spacerun:yes'> 
</span>User is editing source file “A.”<span style='mso-spacerun:yes'> 
</span>While editing the document, some interrupt occurs causing the user to go
to the navigator and <span class=SpellE>refactor</span> some code.<span
style='mso-spacerun:yes'>  </span>The <span class=SpellE>refactoring</span>
operation updates references to the <span class=SpellE>refactored</span> code
in file “A.”<span style='mso-spacerun:yes'>  </span>When the <span
class=SpellE>refactoring</span> is complete, the user returns to the editor on
“A” and notices a typo.<span style='mso-spacerun:yes'>  </span>The user selects
Edit&gt;Undo.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><span
style='mso-tab-count:1'>            </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Desired
Outcome:<span style='mso-spacerun:yes'>  </span>This scenario depends largely
on the user’s intent.<span style='mso-spacerun:yes'>  </span>If the typo was in
a location completely unrelated to the <span class=SpellE>refactor</span>, the
user expects the last text editing operation made before the <span
class=SpellE>refactoring</span> operation to be undone, correcting the
typo.<span style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>R3.0.1
Outcome:<span style='mso-spacerun:yes'>  </span>The text edit caused by the <span
class=SpellE>refactoring</span> operation is undone, but the <span
class=SpellE>refactoring</span> itself is not undone.<span
style='mso-spacerun:yes'>  </span>The typo remains until the user invokes
subsequent “Undo.”<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Proposal
Outcome:<span style='mso-spacerun:yes'>  </span>This outcome can be implemented
in different ways.<span style='mso-spacerun:yes'>  </span>If the <span
class=SpellE>refactoring</span> operation command is assigned the context for
“A,” since A was affected, then the <span class=SpellE>refactoring</span>
operation would be undone before the typo.<span style='mso-spacerun:yes'> 
</span>However, the editor could notice that the operation has multiple contexts
and prompt the user with an operation history.<span style='mso-spacerun:yes'>  
</span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>Scenario #3:</span></b><span
style='font-size:10.0pt;font-family:Arial'><span style='mso-spacerun:yes'> 
</span>User is editing source file “A.”<span style='mso-spacerun:yes'> 
</span>While editing the document, some interrupt occurs causing the user to go
to the navigator and <span class=SpellE>refactor</span> some code.<span
style='mso-spacerun:yes'>  </span>The <span class=SpellE>refactoring</span>
operation updates references to the <span class=SpellE>refactored</span> code
in file “A.”<span style='mso-spacerun:yes'>  </span>When the <span
class=SpellE>refactoring</span> is complete, the user recalls making a typo
just before the <span class=SpellE>refactor</span>.<span
style='mso-spacerun:yes'>  </span>The user returns to the editor on “A” and
looks for the typo.<span style='mso-spacerun:yes'>  </span>It is not there, as
it has been replaced with new code due to the <span class=SpellE>refactoring</span>
operation. The user selects Edit&gt;Undo.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><span
style='mso-tab-count:1'>            </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Desired
Outcome:<span style='mso-spacerun:yes'>  </span>At this point, the user needs
information that helps explain the disappearance of the typo.<span
style='mso-spacerun:yes'>  </span>In this case, there are two helpful options:<o:p></o:p></span></p>

<ol style='margin-top:0in' start=1 type=1>
 <li class=MsoNormal style='mso-list:l16 level1 lfo5;tab-stops:list .5in'><span
     style='font-size:10.0pt;font-family:Arial'>The last performed <span
     class=SpellE>refactoring</span> operation is undone.<span
     style='mso-spacerun:yes'>  </span>This returns the user to the typo, in
     effect showing why the typo had disappeared.<span
     style='mso-spacerun:yes'>  </span>The user then selects “Redo,” having
     been satisfied that the typo was corrected by the <span class=SpellE>refactoring</span>
     operation.<span style='mso-spacerun:yes'>  </span>This operation is
     somewhat “heavyweight,” but one could argue that it’s the more expected
     outcome.<o:p></o:p></span></li>
 <li class=MsoNormal style='mso-list:l16 level1 lfo5;tab-stops:list .5in'><span
     style='font-size:10.0pt;font-family:Arial'>The text edit caused by the <span
     class=SpellE>refactoring</span> is undone, exposing the typo and, in
     effect, showing why it’s gone.<span style='mso-spacerun:yes'>  </span>The
     user then selects “Redo,” having been satisfied that the typo was already
     corrected by the <span class=SpellE>refactoring</span> operation. <span
     style='mso-spacerun:yes'> </span>This is a “lighter weight” solution but
     perhaps more confusing.<o:p></o:p></span></li>
</ol>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><span
style='mso-spacerun:yes'> </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>R3.0.1
Outcome:<span style='mso-spacerun:yes'>  </span>Desired Outcome #2.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Proposal
outcome:<span style='mso-spacerun:yes'>  </span>Desired Outcome #1.<span
style='mso-spacerun:yes'>  </span>This scenario is the same as scenario #2
except for user intent, so the UI could present similar choices as described
above.<span style='mso-spacerun:yes'>  </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>Scenario #4:</span></b><span
style='font-size:10.0pt;font-family:Arial'><span style='mso-spacerun:yes'> 
</span>User is editing source file “A” and considers renaming a method in
“A.”<span style='mso-spacerun:yes'>  </span>While typing a new name for the
method, the user realizes that a <span class=SpellE>refactoring</span>
operation will simplify the editing process.<span style='mso-spacerun:yes'> 
</span>The user chooses “<span class=SpellE>Refactor</span>&gt;Rename” to
rename the method.<span style='mso-spacerun:yes'>  </span>The <span
class=SpellE>refactor</span> causes references to be updated in other
files.<span style='mso-spacerun:yes'>  </span>The user then decides that the
rename was not appropriate.<span style='mso-spacerun:yes'>  </span>The user selects
Edit&gt;Undo.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><span
style='mso-tab-count:1'>            </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Desired
Outcome:<span style='mso-spacerun:yes'>  </span>The <span class=SpellE>refactoring</span>
operation is undone, updating all of the references. The user is returned to
the typing state before the <span class=SpellE>refactor</span>.<span
style='mso-spacerun:yes'>  </span>Selecting another Edit&gt;Undo will undo the
typing of the new name and return to the old name. <o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><span
style='mso-spacerun:yes'> </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>R3.0.1
Outcome:<span style='mso-spacerun:yes'>  </span>The text edit implied by the <span
class=SpellE>refactoring</span> operation is undone, and the user is returned
to the typing state before the <span class=SpellE>refactor</span>.<span
style='mso-spacerun:yes'>  </span>However, the <span class=SpellE>refactoring</span>
itself is not undone.<span style='mso-spacerun:yes'>  </span>This is undoable
from a separate <span class=SpellE>Refactor</span>&gt;Undo.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Proposal
outcome:<span style='mso-spacerun:yes'>  </span>Desired Outcome.<span
style='mso-spacerun:yes'>  </span>A user prompt or verification may occur as
discussed in other scenarios.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>Scenario #5:</span></b><span
style='font-size:10.0pt;font-family:Arial'><span style='mso-spacerun:yes'> 
</span>User is editing source file “A” and considers renaming a method in
“A.”<span style='mso-spacerun:yes'>  </span>The user decides that a <span
class=SpellE>refactoring</span> operation is in order.<span
style='mso-spacerun:yes'>  </span>The user chooses “<span class=SpellE>Refactor</span>&gt;Rename”
to rename the method.<span style='mso-spacerun:yes'>  </span>The <span
class=SpellE>refactor</span> causes references to be updated in other
files.<span style='mso-spacerun:yes'>  </span>The user then makes additional
edits to the <span class=SpellE>javadoc</span> for the renamed method and
realizes that the rename was not appropriate.<span style='mso-spacerun:yes'> 
</span>The user selects Edit&gt;Undo.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><span
style='mso-tab-count:1'>            </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Desired
Outcome:<span style='mso-spacerun:yes'>  </span>The most recent editing changes
to the <span class=SpellE>javadoc</span> are undone.<span
style='mso-spacerun:yes'>  </span>The user can continue selecting “Undo” until
the <span class=SpellE>refactoring</span> operation is undone, updating all of
the references. <o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>R3.0.1
Outcome:<span style='mso-spacerun:yes'>  </span>The most recent editing changes
to the <span class=SpellE>javadoc</span> are undone.<span
style='mso-spacerun:yes'>  </span>The user can continue selecting “Undo” until
the text edit implied by the <span class=SpellE>refactoring</span> operation is
undone.<span style='mso-spacerun:yes'>  </span>However, the <span class=SpellE>refactoring</span>
itself is not undone.<span style='mso-spacerun:yes'>  </span>This is undoable
from a separate <span class=SpellE>Refactor</span>&gt;Undo.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Proposal
outcome:<span style='mso-spacerun:yes'>  </span>Desired Outcome.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><b style='mso-bidi-font-weight:normal'><span
style='font-size:10.0pt;font-family:Arial'>Scenario #6:</span></b><span
style='font-size:10.0pt;font-family:Arial'><span style='mso-spacerun:yes'> 
</span>User is editing source file “A” and considers renaming a method in
“A.”<span style='mso-spacerun:yes'>  </span>The user decides that a <span
class=SpellE>refactoring</span> operation is in order.<span
style='mso-spacerun:yes'>  </span>The user chooses “<span class=SpellE>Refactor</span>&gt;Rename”
to rename the method.<span style='mso-spacerun:yes'>  </span>The <span
class=SpellE>refactor</span> causes references to be updated in other
files.<span style='mso-spacerun:yes'>  </span>The user then proceeds to edit <span
class=SpellE>javadoc</span> in another part of the file, unrelated to
change.<span style='mso-spacerun:yes'>  </span>The user realizes the <span
class=SpellE>refactor</span> was not appropriate, and not wanting to undo the
edits to the <span class=SpellE>javadoc</span>, selects the navigator view, and
selects Edit&gt;Undo, assuming that the navigator undo won’t affect local edit
changes.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><span
style='mso-tab-count:1'>            </span><o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Desired
Outcome:<span style='mso-spacerun:yes'>  </span>The <span class=SpellE>refactoring</span>
operation is undone, but the changes to the <span class=SpellE>javadoc</span>
made afterward are not undone.<span style='mso-spacerun:yes'>  </span>The local
changes to file “A” could only be undone while inside editor A.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>R3.0.1
Outcome:<span style='mso-spacerun:yes'>  </span>The <span class=SpellE>refactoring</span>
operation is undone, and the most recent changes to the file are lost.<o:p></o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'><o:p>&nbsp;</o:p></span></p>

<p class=MsoNormal><span style='font-size:10.0pt;font-family:Arial'>Proposal
outcome:<span style='mso-spacerun:yes'>  </span>This can be implemented in
different ways with <span class=SpellE>IOperationApproval</span>.<span
style='mso-spacerun:yes'>  </span>The operation history would notice that the
chosen operation has context “A” and that later changes for “A” are in the
history.<span style='mso-spacerun:yes'>  </span>The <span class=SpellE>IOperationApproval</span>
assigned to context “A” could prompt the user as to whether to undo the more
recent changes in “A.”<o:p></o:p></span></p>

<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt;
font-family:Arial'><o:p>&nbsp;</o:p></span></p>

</div>

<div style='mso-element:footnote-list'><![if !supportFootnotes]><br clear=all>

<hr align=left size=1 width="33%">

<![endif]>

<div style='mso-element:footnote' id=ftn1>

<p class=MsoNormal><a style='mso-footnote-id:ftn1' href="#_ftnref1" name="_ftn1"
title=""><span class=MsoFootnoteReference><span style='mso-special-character:
footnote'><![if !supportFootnotes]><span class=MsoFootnoteReference><span
style='font-size:12.0pt;font-family:"Times New Roman";mso-fareast-font-family:
"Times New Roman";mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA'>[1]</span></span><![endif]></span></span></a> <span
style='font-size:10.0pt;font-family:Arial'>Literature addressing multi-user
undo [<span class=SpellE>Abowd</span> &amp; Dix] addresses similar scoping
issues in a multi-user model.<span style='mso-spacerun:yes'> 
</span>Collaborating users may expect a global undo scope while users working
in separate contexts may not.<span style='mso-spacerun:yes'>  </span>Users may
be moving between collaboration and separation in a single work session, and the
system cannot detect which is the case.<span style='mso-spacerun:yes'> 
</span>Undo implementations in these systems typically keep track of the user
who initiated the operation within a global history and filter the history
appropriately.<span style='mso-spacerun:yes'>  </span>Potential conflicts are
brought to the attention of the user(s).<o:p></o:p></span></p>

<p class=MsoFootnoteText><o:p>&nbsp;</o:p></p>

</div>

</div>

</body>

</html>