]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/richtext/textpanel/SimpleCommandLog.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / richtext / textpanel / SimpleCommandLog.java
1 /*\r
2  * (C) Copyright IBM Corp. 1998-2004.  All Rights Reserved.\r
3  *\r
4  * The program is provided "as is" without any warranty express or\r
5  * implied, including the warranty of non-infringement and the implied\r
6  * warranties of merchantibility and fitness for a particular purpose.\r
7  * IBM will not be liable for any damages suffered by you as a result\r
8  * of using the Program. In no event will IBM be liable for any\r
9  * special, indirect or consequential damages or lost profits even if\r
10  * IBM has been advised of the possibility of their occurrence. IBM\r
11  * will not be liable for any third party claims against you.\r
12  */\r
13 package com.ibm.richtext.textpanel;\r
14 \r
15 final class SimpleCommandLog {\r
16     static final String COPYRIGHT =\r
17                 "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";\r
18     private Command fLastCommand = null;\r
19     private Command fCurrentCommand = null;\r
20     private PanelEventBroadcaster fListener;\r
21 \r
22     private boolean fBaseIsModified;\r
23 \r
24     private int fLogSize = 14;\r
25 \r
26     public SimpleCommandLog(PanelEventBroadcaster listener) {\r
27         fListener = listener;\r
28         fBaseIsModified = false;\r
29     }\r
30 \r
31     /** adds the specfied command to the top of the command stack\r
32     * (any undone commands on the stack are removed)\r
33     * This function assumes the command has already been executed (i.e., its execute() method\r
34     * has been called, or an equivalent action has been taken) */\r
35     void add(Command newCommand) {\r
36         // if there are commands on the stack that have been undone, they are\r
37         // dropped on the floor here\r
38         newCommand.setPreviousCommand(fCurrentCommand);\r
39         \r
40         final Command oldLastCommand = fLastCommand;\r
41         fLastCommand = null;\r
42         \r
43         fCurrentCommand = newCommand;\r
44         limitCommands(fLogSize);\r
45         \r
46         if (oldLastCommand != null) {\r
47             fListener.textStateChanged(TextPanelEvent.UNDO_STATE_CHANGED);\r
48         }\r
49     }\r
50 \r
51     /**\r
52      * If the command list is longer than logSize, truncate it.\r
53      * This method traverses the list each time, and is not a model\r
54      * of efficiency.  It's a temporary way to plug this memory leak\r
55      * until I can implement a bounded command log.\r
56      */\r
57     private void limitCommands(int logSize) {\r
58 \r
59         if (logSize == 0) {\r
60             fCurrentCommand = null;\r
61         }\r
62         else {\r
63             Command currentCommand = fCurrentCommand;\r
64             int remaining = logSize-1;\r
65             while (currentCommand != null && remaining > 0) {\r
66                 currentCommand = currentCommand.previousCommand();\r
67                 remaining -= 1;\r
68             }\r
69             if (currentCommand != null) {\r
70                 currentCommand.setPreviousCommand(null);\r
71             }\r
72         }\r
73     }\r
74 \r
75     /** adds the specfied command to the top of the command stack and executes it */\r
76     void addAndDo(Command newCommand) {\r
77         add(newCommand);\r
78         newCommand.execute();\r
79 \r
80         fListener.textStateChanged(TextPanelEvent.UNDO_STATE_CHANGED);\r
81     }\r
82 \r
83     /** undoes the command on the top of the command stack, if there is one */\r
84     void undo() {\r
85         if (fCurrentCommand != null) {\r
86             Command current = fCurrentCommand;\r
87             current.undo();\r
88 \r
89             fCurrentCommand = current.previousCommand();\r
90 \r
91             current.setPreviousCommand(fLastCommand);\r
92             fLastCommand = current;\r
93 \r
94             fListener.textStateChanged(TextPanelEvent.UNDO_STATE_CHANGED);\r
95         }\r
96     }\r
97 \r
98     /** redoes the last undone command on the command stack, if there are any */\r
99     void redo() {\r
100         if (fLastCommand != null) {\r
101             Command last = fLastCommand;\r
102             last.redo();\r
103 \r
104             fLastCommand = last.previousCommand();\r
105 \r
106             last.setPreviousCommand(fCurrentCommand);\r
107             fCurrentCommand = last;\r
108 \r
109             fListener.textStateChanged(TextPanelEvent.UNDO_STATE_CHANGED);\r
110         }\r
111     }\r
112 \r
113     public boolean canUndo() {\r
114         return fCurrentCommand != null;\r
115     }\r
116 \r
117     public boolean canRedo() {\r
118         return fLastCommand != null;\r
119     }\r
120 \r
121     public boolean isModified() {\r
122 \r
123         if (fCurrentCommand == null) {\r
124             return fBaseIsModified;\r
125         }\r
126         else {\r
127             return fCurrentCommand.isModified();\r
128         }\r
129     }\r
130 \r
131     public void setModified(boolean modified) {\r
132 \r
133         if (fCurrentCommand == null) {\r
134             fBaseIsModified = modified;\r
135         }\r
136         else {\r
137             fCurrentCommand.setModified(modified);\r
138         }\r
139     }\r
140 \r
141     public void clearLog() {\r
142 \r
143         if (fCurrentCommand != null) {\r
144             fBaseIsModified = fCurrentCommand.isModified();\r
145         }\r
146         // variable not used boolean changed = fCurrentCommand != null || fLastCommand != null;\r
147         fCurrentCommand = null;\r
148         fLastCommand = null;\r
149         \r
150         fListener.textStateChanged(TextPanelEvent.UNDO_STATE_CHANGED);\r
151     }\r
152 \r
153     public void setLogSize(int size) {\r
154 \r
155         if (size < 0) {\r
156             throw new IllegalArgumentException("log size cannot be negative");\r
157         }\r
158         \r
159         if (size < fLogSize) {\r
160             limitCommands(size);\r
161         }\r
162         \r
163         fLogSize = size;\r
164         \r
165         if (fLastCommand != null || size == 0) {\r
166             fLastCommand = null;\r
167             fListener.textStateChanged(TextPanelEvent.UNDO_STATE_CHANGED);\r
168         }\r
169     }\r
170 \r
171     public int getLogSize() {\r
172 \r
173         return fLogSize;\r
174     }\r
175 }\r