]> git.saurik.com Git - wxWidgets.git/blame - utils/ogl/src/constrnt.cpp
accidentally removed IMPLEMENT_DYNAMIC_CLASS added back
[wxWidgets.git] / utils / ogl / src / constrnt.cpp
CommitLineData
0fc1a713
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: constrnt.cpp
3// Purpose: OGL Constraint classes
4// Author: Julian Smart
5// Modified by:
6// Created: 12/07/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "constrnt.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include <wx/wxprec.h>
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include <wx/wx.h>
25#endif
26
0fc1a713 27#include <wx/wxexpr.h>
0fc1a713
JS
28
29#include "basic.h"
30#include "constrnt.h"
31#include "canvas.h"
32
6f5f3ca0 33wxList *wxOGLConstraintTypes = NULL;
0fc1a713
JS
34
35/*
36 * Constraint type
37 *
38 */
39
6f5f3ca0 40IMPLEMENT_DYNAMIC_CLASS(wxOGLConstraintType, wxObject)
0fc1a713 41
6f5f3ca0 42wxOGLConstraintType::wxOGLConstraintType(int theType, const wxString& theName, const wxString& thePhrase)
0fc1a713
JS
43{
44 m_type = theType;
45 m_name = theName;
46 m_phrase = thePhrase;
47}
48
6f5f3ca0 49wxOGLConstraintType::~wxOGLConstraintType()
0fc1a713
JS
50{
51}
52
53void OGLInitializeConstraintTypes()
54{
6f5f3ca0 55 if (!wxOGLConstraintTypes)
5de76427 56 return;
0fc1a713 57
6f5f3ca0 58 wxOGLConstraintTypes = new wxList(wxKEY_INTEGER);
0fc1a713 59
6f5f3ca0
JS
60 wxOGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_VERTICALLY,
61 new wxOGLConstraintType(gyCONSTRAINT_CENTRED_VERTICALLY, "Centre vertically", "centred vertically w.r.t."));
0fc1a713 62
6f5f3ca0
JS
63 wxOGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_HORIZONTALLY,
64 new wxOGLConstraintType(gyCONSTRAINT_CENTRED_HORIZONTALLY, "Centre horizontally", "centred horizontally w.r.t."));
0fc1a713 65
6f5f3ca0
JS
66 wxOGLConstraintTypes->Append(gyCONSTRAINT_CENTRED_BOTH,
67 new wxOGLConstraintType(gyCONSTRAINT_CENTRED_BOTH, "Centre", "centred w.r.t."));
0fc1a713 68
6f5f3ca0
JS
69 wxOGLConstraintTypes->Append(gyCONSTRAINT_LEFT_OF,
70 new wxOGLConstraintType(gyCONSTRAINT_LEFT_OF, "Left of", "left of"));
0fc1a713 71
6f5f3ca0
JS
72 wxOGLConstraintTypes->Append(gyCONSTRAINT_RIGHT_OF,
73 new wxOGLConstraintType(gyCONSTRAINT_RIGHT_OF, "Right of", "right of"));
0fc1a713 74
6f5f3ca0
JS
75 wxOGLConstraintTypes->Append(gyCONSTRAINT_ABOVE,
76 new wxOGLConstraintType(gyCONSTRAINT_ABOVE, "Above", "above"));
0fc1a713 77
6f5f3ca0
JS
78 wxOGLConstraintTypes->Append(gyCONSTRAINT_BELOW,
79 new wxOGLConstraintType(gyCONSTRAINT_BELOW, "Below", "below"));
0fc1a713 80
5de76427 81 // Alignment
6f5f3ca0
JS
82 wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_TOP,
83 new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_TOP, "Top-aligned", "aligned to the top of"));
0fc1a713 84
6f5f3ca0
JS
85 wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_BOTTOM,
86 new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_BOTTOM, "Bottom-aligned", "aligned to the bottom of"));
0fc1a713 87
6f5f3ca0
JS
88 wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_LEFT,
89 new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_LEFT, "Left-aligned", "aligned to the left of"));
0fc1a713 90
6f5f3ca0
JS
91 wxOGLConstraintTypes->Append(gyCONSTRAINT_ALIGNED_RIGHT,
92 new wxOGLConstraintType(gyCONSTRAINT_ALIGNED_RIGHT, "Right-aligned", "aligned to the right of"));
0fc1a713 93
5de76427 94 // Mid-alignment
6f5f3ca0
JS
95 wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_TOP,
96 new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_TOP, "Top-midaligned", "centred on the top of"));
0fc1a713 97
6f5f3ca0
JS
98 wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_BOTTOM,
99 new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_BOTTOM, "Bottom-midaligned", "centred on the bottom of"));
5de76427 100
6f5f3ca0
JS
101 wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_LEFT,
102 new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_LEFT, "Left-midaligned", "centred on the left of"));
5de76427 103
6f5f3ca0
JS
104 wxOGLConstraintTypes->Append(gyCONSTRAINT_MIDALIGNED_RIGHT,
105 new wxOGLConstraintType(gyCONSTRAINT_MIDALIGNED_RIGHT, "Right-midaligned", "centred on the right of"));
5de76427
JS
106}
107
108void OGLCleanUpConstraintTypes()
109{
6f5f3ca0 110 if (!wxOGLConstraintTypes)
5de76427
JS
111 return;
112
6f5f3ca0 113 wxNode* node = wxOGLConstraintTypes->First();
5de76427
JS
114 while (node)
115 {
6f5f3ca0 116 wxOGLConstraintType* ct = (wxOGLConstraintType*) node->Data();
5de76427
JS
117 delete ct;
118 node = node->Next();
119 }
6f5f3ca0
JS
120 delete wxOGLConstraintTypes;
121 wxOGLConstraintTypes = NULL;
0fc1a713
JS
122}
123
124/*
125 * Constraint Stuff
126 *
127 */
128
6f5f3ca0 129IMPLEMENT_DYNAMIC_CLASS(wxOGLConstraint, wxObject)
0fc1a713 130
6f5f3ca0 131wxOGLConstraint::wxOGLConstraint(int type, wxShape *constraining, wxList& constrained)
0fc1a713
JS
132{
133 m_xSpacing = 0.0;
134 m_ySpacing = 0.0;
135
136 m_constraintType = type;
137 m_constrainingObject = constraining;
138
139 m_constraintId = 0;
140 m_constraintName = "noname";
141
142 wxNode *node = constrained.First();
143 while (node)
144 {
145 m_constrainedObjects.Append(node->Data());
146 node = node->Next();
147 }
148}
149
6f5f3ca0 150wxOGLConstraint::~wxOGLConstraint()
0fc1a713
JS
151{
152}
153
6f5f3ca0 154bool wxOGLConstraint::Equals(double a, double b)
0fc1a713 155{
42cfaf8c 156 double marg = 0.5;
0fc1a713
JS
157
158 bool eq = ((b <= a + marg) && (b >= a - marg));
159 return eq;
160}
161
162// Return TRUE if anything changed
6f5f3ca0 163bool wxOGLConstraint::Evaluate()
0fc1a713 164{
42cfaf8c 165 double maxWidth, maxHeight, minWidth, minHeight, x, y;
0fc1a713
JS
166 m_constrainingObject->GetBoundingBoxMax(&maxWidth, &maxHeight);
167 m_constrainingObject->GetBoundingBoxMin(&minWidth, &minHeight);
168 x = m_constrainingObject->GetX();
169 y = m_constrainingObject->GetY();
170
171 wxClientDC dc(m_constrainingObject->GetCanvas());
172 m_constrainingObject->GetCanvas()->PrepareDC(dc);
173
174 switch (m_constraintType)
175 {
176 case gyCONSTRAINT_CENTRED_VERTICALLY:
177 {
178 int n = m_constrainedObjects.Number();
42cfaf8c 179 double totalObjectHeight = 0.0;
0fc1a713
JS
180 wxNode *node = m_constrainedObjects.First();
181 while (node)
182 {
183 wxShape *constrainedObject = (wxShape *)node->Data();
184
42cfaf8c 185 double width2, height2;
0fc1a713
JS
186 constrainedObject->GetBoundingBoxMax(&width2, &height2);
187 totalObjectHeight += height2;
188 node = node->Next();
189 }
42cfaf8c
JS
190 double startY;
191 double spacingY;
0fc1a713
JS
192 // Check if within the constraining object...
193 if ((totalObjectHeight + (n + 1)*m_ySpacing) <= minHeight)
194 {
42cfaf8c
JS
195 spacingY = (double)((minHeight - totalObjectHeight)/(n + 1));
196 startY = (double)(y - (minHeight/2.0));
0fc1a713
JS
197 }
198 // Otherwise, use default spacing
199 else
200 {
201 spacingY = m_ySpacing;
42cfaf8c 202 startY = (double)(y - ((totalObjectHeight + (n+1)*spacingY)/2.0));
0fc1a713
JS
203 }
204
205 // Now position the objects
206 bool changed = FALSE;
207 node = m_constrainedObjects.First();
208 while (node)
209 {
210 wxShape *constrainedObject = (wxShape *)node->Data();
42cfaf8c 211 double width2, height2;
0fc1a713 212 constrainedObject->GetBoundingBoxMax(&width2, &height2);
42cfaf8c 213 startY += (double)(spacingY + (height2/2.0));
0fc1a713
JS
214 if (!Equals(startY, constrainedObject->GetY()))
215 {
216 constrainedObject->Move(dc, constrainedObject->GetX(), startY, FALSE);
217 changed = TRUE;
218 }
42cfaf8c 219 startY += (double)(height2/2.0);
0fc1a713
JS
220 node = node->Next();
221 }
222 return changed;
223 }
224 case gyCONSTRAINT_CENTRED_HORIZONTALLY:
225 {
226 int n = m_constrainedObjects.Number();
42cfaf8c 227 double totalObjectWidth = 0.0;
0fc1a713
JS
228 wxNode *node = m_constrainedObjects.First();
229 while (node)
230 {
231 wxShape *constrainedObject = (wxShape *)node->Data();
232
42cfaf8c 233 double width2, height2;
0fc1a713
JS
234 constrainedObject->GetBoundingBoxMax(&width2, &height2);
235 totalObjectWidth += width2;
236 node = node->Next();
237 }
42cfaf8c
JS
238 double startX;
239 double spacingX;
0fc1a713
JS
240 // Check if within the constraining object...
241 if ((totalObjectWidth + (n + 1)*m_xSpacing) <= minWidth)
242 {
42cfaf8c
JS
243 spacingX = (double)((minWidth - totalObjectWidth)/(n + 1));
244 startX = (double)(x - (minWidth/2.0));
0fc1a713
JS
245 }
246 // Otherwise, use default spacing
247 else
248 {
249 spacingX = m_xSpacing;
42cfaf8c 250 startX = (double)(x - ((totalObjectWidth + (n+1)*spacingX)/2.0));
0fc1a713
JS
251 }
252
253 // Now position the objects
254 bool changed = FALSE;
255 node = m_constrainedObjects.First();
256 while (node)
257 {
258 wxShape *constrainedObject = (wxShape *)node->Data();
42cfaf8c 259 double width2, height2;
0fc1a713 260 constrainedObject->GetBoundingBoxMax(&width2, &height2);
42cfaf8c 261 startX += (double)(spacingX + (width2/2.0));
0fc1a713
JS
262 if (!Equals(startX, constrainedObject->GetX()))
263 {
264 constrainedObject->Move(dc, startX, constrainedObject->GetY(), FALSE);
265 changed = TRUE;
266 }
42cfaf8c 267 startX += (double)(width2/2.0);
0fc1a713
JS
268 node = node->Next();
269 }
270 return changed;
271 }
272 case gyCONSTRAINT_CENTRED_BOTH:
273 {
274 int n = m_constrainedObjects.Number();
42cfaf8c
JS
275 double totalObjectWidth = 0.0;
276 double totalObjectHeight = 0.0;
0fc1a713
JS
277 wxNode *node = m_constrainedObjects.First();
278 while (node)
279 {
280 wxShape *constrainedObject = (wxShape *)node->Data();
281
42cfaf8c 282 double width2, height2;
0fc1a713
JS
283 constrainedObject->GetBoundingBoxMax(&width2, &height2);
284 totalObjectWidth += width2;
285 totalObjectHeight += height2;
286 node = node->Next();
287 }
42cfaf8c
JS
288 double startX;
289 double spacingX;
290 double startY;
291 double spacingY;
0fc1a713
JS
292
293 // Check if within the constraining object...
294 if ((totalObjectWidth + (n + 1)*m_xSpacing) <= minWidth)
295 {
42cfaf8c
JS
296 spacingX = (double)((minWidth - totalObjectWidth)/(n + 1));
297 startX = (double)(x - (minWidth/2.0));
0fc1a713
JS
298 }
299 // Otherwise, use default spacing
300 else
301 {
302 spacingX = m_xSpacing;
42cfaf8c 303 startX = (double)(x - ((totalObjectWidth + (n+1)*spacingX)/2.0));
0fc1a713
JS
304 }
305
306 // Check if within the constraining object...
307 if ((totalObjectHeight + (n + 1)*m_ySpacing) <= minHeight)
308 {
42cfaf8c
JS
309 spacingY = (double)((minHeight - totalObjectHeight)/(n + 1));
310 startY = (double)(y - (minHeight/2.0));
0fc1a713
JS
311 }
312 // Otherwise, use default spacing
313 else
314 {
315 spacingY = m_ySpacing;
42cfaf8c 316 startY = (double)(y - ((totalObjectHeight + (n+1)*spacingY)/2.0));
0fc1a713
JS
317 }
318
319 // Now position the objects
320 bool changed = FALSE;
321 node = m_constrainedObjects.First();
322 while (node)
323 {
324 wxShape *constrainedObject = (wxShape *)node->Data();
42cfaf8c 325 double width2, height2;
0fc1a713 326 constrainedObject->GetBoundingBoxMax(&width2, &height2);
42cfaf8c
JS
327 startX += (double)(spacingX + (width2/2.0));
328 startY += (double)(spacingY + (height2/2.0));
0fc1a713
JS
329
330 if ((!Equals(startX, constrainedObject->GetX())) || (!Equals(startY, constrainedObject->GetY())))
331 {
332 constrainedObject->Move(dc, startX, startY, FALSE);
333 changed = TRUE;
334 }
335
42cfaf8c
JS
336 startX += (double)(width2/2.0);
337 startY += (double)(height2/2.0);
0fc1a713
JS
338
339 node = node->Next();
340 }
341 return changed;
342 }
343 case gyCONSTRAINT_LEFT_OF:
344 {
345 bool changed = FALSE;
346
347 wxNode *node = m_constrainedObjects.First();
348 while (node)
349 {
350 wxShape *constrainedObject = (wxShape *)node->Data();
351
42cfaf8c 352 double width2, height2;
0fc1a713
JS
353 constrainedObject->GetBoundingBoxMax(&width2, &height2);
354
42cfaf8c 355 double x3 = (double)(x - (minWidth/2.0) - (width2/2.0) - m_xSpacing);
0fc1a713
JS
356 if (!Equals(x3, constrainedObject->GetX()))
357 {
358 changed = TRUE;
359 constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
360 }
361
362 node = node->Next();
363 }
364 return changed;
365 }
366 case gyCONSTRAINT_RIGHT_OF:
367 {
368 bool changed = FALSE;
369
370 wxNode *node = m_constrainedObjects.First();
371 while (node)
372 {
373 wxShape *constrainedObject = (wxShape *)node->Data();
374
42cfaf8c 375 double width2, height2;
0fc1a713
JS
376 constrainedObject->GetBoundingBoxMax(&width2, &height2);
377
42cfaf8c 378 double x3 = (double)(x + (minWidth/2.0) + (width2/2.0) + m_xSpacing);
0fc1a713
JS
379 if (!Equals(x3, constrainedObject->GetX()))
380 {
381 changed = TRUE;
382 constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
383 }
384
385 node = node->Next();
386 }
387 return changed;
388
389 return FALSE;
390 }
391 case gyCONSTRAINT_ABOVE:
392 {
393 bool changed = FALSE;
394
395 wxNode *node = m_constrainedObjects.First();
396 while (node)
397 {
398 wxShape *constrainedObject = (wxShape *)node->Data();
399
42cfaf8c 400 double width2, height2;
0fc1a713
JS
401 constrainedObject->GetBoundingBoxMax(&width2, &height2);
402
42cfaf8c 403 double y3 = (double)(y - (minHeight/2.0) - (height2/2.0) - m_ySpacing);
0fc1a713
JS
404 if (!Equals(y3, constrainedObject->GetY()))
405 {
406 changed = TRUE;
407 constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
408 }
409
410 node = node->Next();
411 }
412 return changed;
413 }
414 case gyCONSTRAINT_BELOW:
415 {
416 bool changed = FALSE;
417
418 wxNode *node = m_constrainedObjects.First();
419 while (node)
420 {
421 wxShape *constrainedObject = (wxShape *)node->Data();
422
42cfaf8c 423 double width2, height2;
0fc1a713
JS
424 constrainedObject->GetBoundingBoxMax(&width2, &height2);
425
42cfaf8c 426 double y3 = (double)(y + (minHeight/2.0) + (height2/2.0) + m_ySpacing);
0fc1a713
JS
427 if (!Equals(y3, constrainedObject->GetY()))
428 {
429 changed = TRUE;
430 constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
431 }
432
433 node = node->Next();
434 }
435 return changed;
436 }
437 case gyCONSTRAINT_ALIGNED_LEFT:
438 {
439 bool changed = FALSE;
440
441 wxNode *node = m_constrainedObjects.First();
442 while (node)
443 {
444 wxShape *constrainedObject = (wxShape *)node->Data();
445
42cfaf8c 446 double width2, height2;
0fc1a713
JS
447 constrainedObject->GetBoundingBoxMax(&width2, &height2);
448
42cfaf8c 449 double x3 = (double)(x - (minWidth/2.0) + (width2/2.0) + m_xSpacing);
0fc1a713
JS
450 if (!Equals(x3, constrainedObject->GetX()))
451 {
452 changed = TRUE;
453 constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
454 }
455
456 node = node->Next();
457 }
458 return changed;
459 }
460 case gyCONSTRAINT_ALIGNED_RIGHT:
461 {
462 bool changed = FALSE;
463
464 wxNode *node = m_constrainedObjects.First();
465 while (node)
466 {
467 wxShape *constrainedObject = (wxShape *)node->Data();
468
42cfaf8c 469 double width2, height2;
0fc1a713
JS
470 constrainedObject->GetBoundingBoxMax(&width2, &height2);
471
42cfaf8c 472 double x3 = (double)(x + (minWidth/2.0) - (width2/2.0) - m_xSpacing);
0fc1a713
JS
473 if (!Equals(x3, constrainedObject->GetX()))
474 {
475 changed = TRUE;
476 constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
477 }
478
479 node = node->Next();
480 }
481 return changed;
482
483 return FALSE;
484 }
485 case gyCONSTRAINT_ALIGNED_TOP:
486 {
487 bool changed = FALSE;
488
489 wxNode *node = m_constrainedObjects.First();
490 while (node)
491 {
492 wxShape *constrainedObject = (wxShape *)node->Data();
493
42cfaf8c 494 double width2, height2;
0fc1a713
JS
495 constrainedObject->GetBoundingBoxMax(&width2, &height2);
496
42cfaf8c 497 double y3 = (double)(y - (minHeight/2.0) + (height2/2.0) + m_ySpacing);
0fc1a713
JS
498 if (!Equals(y3, constrainedObject->GetY()))
499 {
500 changed = TRUE;
501 constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
502 }
503
504 node = node->Next();
505 }
506 return changed;
507 }
508 case gyCONSTRAINT_ALIGNED_BOTTOM:
509 {
510 bool changed = FALSE;
511
512 wxNode *node = m_constrainedObjects.First();
513 while (node)
514 {
515 wxShape *constrainedObject = (wxShape *)node->Data();
516
42cfaf8c 517 double width2, height2;
0fc1a713
JS
518 constrainedObject->GetBoundingBoxMax(&width2, &height2);
519
42cfaf8c 520 double y3 = (double)(y + (minHeight/2.0) - (height2/2.0) - m_ySpacing);
0fc1a713
JS
521 if (!Equals(y3, constrainedObject->GetY()))
522 {
523 changed = TRUE;
524 constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
525 }
526
527 node = node->Next();
528 }
529 return changed;
530 }
531 case gyCONSTRAINT_MIDALIGNED_LEFT:
532 {
533 bool changed = FALSE;
534
535 wxNode *node = m_constrainedObjects.First();
536 while (node)
537 {
538 wxShape *constrainedObject = (wxShape *)node->Data();
539
42cfaf8c 540 double x3 = (double)(x - (minWidth/2.0));
0fc1a713
JS
541 if (!Equals(x3, constrainedObject->GetX()))
542 {
543 changed = TRUE;
544 constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
545 }
546
547 node = node->Next();
548 }
549 return changed;
550 }
551 case gyCONSTRAINT_MIDALIGNED_RIGHT:
552 {
553 bool changed = FALSE;
554
555 wxNode *node = m_constrainedObjects.First();
556 while (node)
557 {
558 wxShape *constrainedObject = (wxShape *)node->Data();
559
42cfaf8c 560 double x3 = (double)(x + (minWidth/2.0));
0fc1a713
JS
561 if (!Equals(x3, constrainedObject->GetX()))
562 {
563 changed = TRUE;
564 constrainedObject->Move(dc, x3, constrainedObject->GetY(), FALSE);
565 }
566
567 node = node->Next();
568 }
569 return changed;
570
571 return FALSE;
572 }
573 case gyCONSTRAINT_MIDALIGNED_TOP:
574 {
575 bool changed = FALSE;
576
577 wxNode *node = m_constrainedObjects.First();
578 while (node)
579 {
580 wxShape *constrainedObject = (wxShape *)node->Data();
581
42cfaf8c 582 double y3 = (double)(y - (minHeight/2.0));
0fc1a713
JS
583 if (!Equals(y3, constrainedObject->GetY()))
584 {
585 changed = TRUE;
586 constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
587 }
588
589 node = node->Next();
590 }
591 return changed;
592 }
593 case gyCONSTRAINT_MIDALIGNED_BOTTOM:
594 {
595 bool changed = FALSE;
596
597 wxNode *node = m_constrainedObjects.First();
598 while (node)
599 {
600 wxShape *constrainedObject = (wxShape *)node->Data();
601
42cfaf8c 602 double y3 = (double)(y + (minHeight/2.0));
0fc1a713
JS
603 if (!Equals(y3, constrainedObject->GetY()))
604 {
605 changed = TRUE;
606 constrainedObject->Move(dc, constrainedObject->GetX(), y3, FALSE);
607 }
608
609 node = node->Next();
610 }
611 return changed;
612 }
613
614 default:
615 return FALSE;
616 }
617 return FALSE;
618}
619