1 /*
2 * AiksaurusGTK - A GTK interface to the AikSaurus library
3 * Copyright (C) 2001 by Jared Davis
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18 * 02111-1307, USA.
19 */
20
21 #include "AiksaurusGTK_history.h"
22 #include "AiksaurusGTK_strlist.h"
23 #include "AiksaurusGTK_utils.h"
24
25 #include <cassert>
26
27 #ifndef NDEBUG
28 #include <iostream>
29 using namespace std;
30 #endif
31
32 //////////////////////////////////////////////////////////////////////////
33 // //
34 // Creation and Destruction //
35 // //
36 //////////////////////////////////////////////////////////////////////////
37
AiksaurusGTK_history()38 AiksaurusGTK_history::AiksaurusGTK_history()
39 {
40 d_forward_tip_ptr = d_back_tip_ptr = d_current_ptr = static_cast<char*>(NULL);
41 }
42
43
~AiksaurusGTK_history()44 AiksaurusGTK_history::~AiksaurusGTK_history()
45 {
46 if (d_current_ptr)
47 delete[] d_current_ptr;
48
49 if (d_forward_tip_ptr)
50 delete[] d_forward_tip_ptr;
51
52 if (d_back_tip_ptr)
53 delete[] d_back_tip_ptr;
54 }
55
56
57 const char*
tip_forward() const58 AiksaurusGTK_history::tip_forward() const
59 {
60 static const char* forward = "Forward";
61 static const char* forwardto = "Forward to ";
62
63 const char* nextone = d_forward.look_front();
64
65 if (!nextone)
66 {
67 return forward;
68 }
69
70 if (d_forward_tip_ptr)
71 delete[] d_forward_tip_ptr;
72
73 d_forward_tip_ptr = AiksaurusGTK_strConcat(forwardto, nextone);
74
75 return d_forward_tip_ptr;
76 }
77
78 const char*
tip_back() const79 AiksaurusGTK_history::tip_back() const
80 {
81 static const char* back = "Back";
82 static const char* backto = "Back to ";
83
84 const char* backone = d_back.look_front();
85
86 if (!backone)
87 {
88 return back;
89 }
90
91 if (d_back_tip_ptr)
92 {
93 delete[] d_back_tip_ptr;
94 d_back_tip_ptr = 0;
95 }
96
97 d_back_tip_ptr = AiksaurusGTK_strConcat(backto, backone);
98
99 return d_back_tip_ptr;
100 }
101
102
103 void
search(const char * str)104 AiksaurusGTK_history::search(const char* str)
105 {
106 // eliminate all entries which are in forward.
107 d_forward.clear();
108
109 // push current entry to top of back.
110 if (d_current_ptr != NULL)
111 {
112 d_back.push_front(d_current_ptr);
113 delete[] d_current_ptr;
114 }
115
116 // make current element mirror str.
117 d_current_ptr = AiksaurusGTK_strCopy(str);
118 }
119
120
121 void
move_back()122 AiksaurusGTK_history::move_back()
123 {
124 // make sure there is something to go back to before continuing.
125 if (!d_back.size())
126 return;
127
128 // make current element become first element of forward.
129 d_forward.push_front(d_current_ptr);
130
131 while (d_forward.size() > 200)
132 d_forward.pop_back();
133
134 // make first element of back become current.
135 delete[] d_current_ptr;
136 d_current_ptr = AiksaurusGTK_strCopy(d_back.look_front());
137
138 // pop first element of back
139 d_back.pop_front();
140 }
141
142
143 void
move_forward()144 AiksaurusGTK_history::move_forward()
145 {
146 // make sure there is something to move forward to.
147 if (!d_forward.size())
148 return;
149
150 // make current element become first element of back.
151 d_back.push_front(d_current_ptr);
152
153 while (d_back.size() > 200)
154 d_back.pop_back();
155
156 // make first element of forward become current.
157 delete[] d_current_ptr;
158 d_current_ptr = AiksaurusGTK_strCopy(d_forward.look_front());
159
160 // pop first element of forward.
161 d_forward.pop_front();
162 }
163
164
165 void
move_back_to(GList * element)166 AiksaurusGTK_history::move_back_to(GList* element)
167 {
168 int back_steps = 0;
169 for(GList* itor = const_cast<GList*>(d_back.list()); itor != NULL; itor = itor->next)
170 {
171 ++back_steps;
172
173 if (itor == element)
174 {
175 for(int i = 0;i < back_steps;++i)
176 move_back();
177
178 return;
179 }
180 }
181
182 #ifndef NDEBUG
183 cout << "AiksaurusGTK_history::move_back_to(" << element << ")\n"
184 << "Warning: element is not in back list, and it should be.\n";
185 debug();
186 #endif // NDEBUG
187 }
188
189
190 void
move_forward_to(GList * element)191 AiksaurusGTK_history::move_forward_to(GList* element)
192 {
193 int forward_steps = 0;
194 for(GList* itor = const_cast<GList*>(d_forward.list()); itor != NULL; itor = itor->next)
195 {
196 ++forward_steps;
197
198 if (itor == element)
199 {
200 for(int i = 0;i < forward_steps;++i)
201 move_forward();
202
203 return;
204 }
205 }
206
207 #ifndef NDEBUG
208 cout << "AiksaurusGTK_history::move_forward_to(" << element << ")\n"
209 << "Warning: element is not in forward list, and it should be.\n";
210 debug();
211 #endif // NDEBUG
212 }
213
214
215 unsigned int
size_back() const216 AiksaurusGTK_history::size_back() const
217 {
218 return d_back.size();
219 }
220
221
222 unsigned int
size_forward() const223 AiksaurusGTK_history::size_forward() const
224 {
225 return d_forward.size();
226 }
227
228
229 const char*
current() const230 AiksaurusGTK_history::current() const
231 {
232 return d_current_ptr;
233 }
234
235
236 const AiksaurusGTK_strlist&
list_back() const237 AiksaurusGTK_history::list_back() const
238 {
239 return d_back;
240 }
241
242
243 const AiksaurusGTK_strlist&
list_forward() const244 AiksaurusGTK_history::list_forward() const
245 {
246 return d_forward;
247 }
248
249
250
251
252
253
254
255
256
257
258 #ifndef NDEBUG
debug()259 void AiksaurusGTK_history::debug()
260 {
261 cout << "History Debug Information ======================" << endl;
262 cout << tip_back() << " " << tip_forward() << endl;
263 cout << "Current: " << current() << endl;
264
265 cout << "Back ";
266 d_back.debug();
267
268 cout << "Forward: ";
269 d_forward.debug();
270 cout << "================================================" << endl;
271 }
272 #endif
273