create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / gui / main / RocketActions.java
1 package net.sf.openrocket.gui.main;
2
3
4 import java.awt.event.ActionEvent;
5 import java.awt.event.KeyEvent;
6 import java.util.ArrayList;
7
8 import javax.swing.AbstractAction;
9 import javax.swing.Action;
10 import javax.swing.JCheckBox;
11 import javax.swing.JOptionPane;
12 import javax.swing.JPanel;
13 import javax.swing.KeyStroke;
14
15 import net.miginfocom.swing.MigLayout;
16 import net.sf.openrocket.document.OpenRocketDocument;
17 import net.sf.openrocket.document.Simulation;
18 import net.sf.openrocket.gui.components.StyledLabel;
19 import net.sf.openrocket.gui.configdialog.ComponentConfigDialog;
20 import net.sf.openrocket.gui.util.Icons;
21 import net.sf.openrocket.l10n.Translator;
22 import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
23 import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
24 import net.sf.openrocket.rocketcomponent.Rocket;
25 import net.sf.openrocket.rocketcomponent.RocketComponent;
26 import net.sf.openrocket.rocketcomponent.Stage;
27 import net.sf.openrocket.startup.Application;
28 import net.sf.openrocket.startup.Preferences;
29 import net.sf.openrocket.util.Pair;
30
31
32
33 /**
34  * A class that holds Actions for common rocket and simulation operations such as
35  * cut/copy/paste/delete etc.
36  * 
37  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
38  */
39 public class RocketActions {
40
41         public static final KeyStroke CUT_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_X,
42                         ActionEvent.CTRL_MASK);
43         public static final KeyStroke COPY_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_C,
44                         ActionEvent.CTRL_MASK);
45         public static final KeyStroke PASTE_KEY_STROKE = KeyStroke.getKeyStroke(KeyEvent.VK_V,
46                         ActionEvent.CTRL_MASK);
47         
48         private final OpenRocketDocument document;
49         private final Rocket rocket;
50         private final BasicFrame parentFrame;
51         private final DocumentSelectionModel selectionModel;
52
53
54         private final RocketAction deleteComponentAction;
55         private final RocketAction deleteSimulationAction;
56         private final RocketAction deleteAction;
57         private final RocketAction cutAction;
58         private final RocketAction copyAction;
59         private final RocketAction pasteAction;
60         private final RocketAction editAction;
61         private final RocketAction newStageAction;
62         private final RocketAction moveUpAction;
63         private final RocketAction moveDownAction;
64         private static final Translator trans = Application.getTranslator();
65
66
67         public RocketActions(OpenRocketDocument document, DocumentSelectionModel selectionModel,
68                         BasicFrame parentFrame) {
69                 this.document = document;
70                 this.rocket = document.getRocket();
71                 this.selectionModel = selectionModel;
72                 this.parentFrame = parentFrame;
73
74                 // Add action also to updateActions()
75                 this.deleteAction = new DeleteAction();
76                 this.deleteComponentAction = new DeleteComponentAction();
77                 this.deleteSimulationAction = new DeleteSimulationAction();
78                 this.cutAction = new CutAction();
79                 this.copyAction = new CopyAction();
80                 this.pasteAction = new PasteAction();
81                 this.editAction = new EditAction();
82                 this.newStageAction = new NewStageAction();
83                 this.moveUpAction = new MoveUpAction();
84                 this.moveDownAction = new MoveDownAction();
85
86                 OpenRocketClipboard.addClipboardListener(this.pasteAction);
87                 updateActions();
88
89                 // Update all actions when tree selection or rocket changes
90
91                 selectionModel.addDocumentSelectionListener(new DocumentSelectionListener() {
92                         @Override
93                         public void valueChanged(int changeType) {
94                                 updateActions();
95                         }
96                 });
97                 document.getRocket().addComponentChangeListener(new ComponentChangeListener() {
98                         @Override
99                         public void componentChanged(ComponentChangeEvent e) {
100                                 updateActions();
101                         }
102                 });
103         }
104
105         /**
106          * Update the state of all of the actions.
107          */
108         private void updateActions() {
109                 deleteAction.clipboardChanged();
110                 cutAction.clipboardChanged();
111                 copyAction.clipboardChanged();
112                 pasteAction.clipboardChanged();
113                 editAction.clipboardChanged();
114                 newStageAction.clipboardChanged();
115                 moveUpAction.clipboardChanged();
116                 moveDownAction.clipboardChanged();
117         }
118         
119         
120         
121
122         public Action getDeleteComponentAction() {
123                 return deleteAction;
124         }
125
126         public Action getDeleteSimulationAction() {
127                 return deleteAction;
128         }
129
130         public Action getDeleteAction() {
131                 return deleteAction;
132         }
133
134         public Action getCutAction() {
135                 return cutAction;
136         }
137         
138         public Action getCopyAction() {
139                 return copyAction;
140         }
141         
142         public Action getPasteAction() {
143                 return pasteAction;
144         }
145         
146         public Action getEditAction() {
147                 return editAction;
148         }
149         
150         public Action getNewStageAction() {
151                 return newStageAction;
152         }
153         
154         public Action getMoveUpAction() {
155                 return moveUpAction;
156         }
157         
158         public Action getMoveDownAction() {
159                 return moveDownAction;
160         }
161
162         
163         
164         ////////  Helper methods for the actions
165
166         private boolean isDeletable(RocketComponent c) {
167                 // Sanity check
168                 if (c == null || c.getParent() == null)
169                         return false;
170
171                 // Cannot remove Rocket
172                 if (c instanceof Rocket)
173                         return false;
174
175                 // Cannot remove last stage
176                 if ((c instanceof Stage) && (c.getParent().getChildCount() == 1)) {
177                         return false;
178                 }
179
180                 return true;
181         }
182
183         private void delete(RocketComponent c) {
184                 if (!isDeletable(c)) {
185                         throw new IllegalArgumentException("Report bug!  Component " + c + 
186                                         " not deletable.");
187                 }
188
189                 RocketComponent parent = c.getParent();
190                 parent.removeChild(c);
191         }
192
193         private boolean isCopyable(RocketComponent c) {
194                 if (c==null)
195                         return false;
196                 if (c instanceof Rocket)
197                         return false;
198                 return true;
199         }
200
201         
202         private boolean isSimulationSelected() {
203                 Simulation[] selection = selectionModel.getSelectedSimulations();
204                 return (selection != null  &&  selection.length > 0);
205         }
206         
207         
208         
209         private boolean verifyDeleteSimulation() {
210                 boolean verify = Application.getPreferences().getBoolean(Preferences.CONFIRM_DELETE_SIMULATION, true);
211                 if (verify) {
212                         JPanel panel = new JPanel(new MigLayout());
213                         //// Do not ask me again
214                         JCheckBox dontAsk = new JCheckBox(trans.get("RocketActions.checkbox.Donotaskmeagain"));
215                         panel.add(dontAsk,"wrap");
216                         //// You can change the default operation in the preferences. 
217                         panel.add(new StyledLabel(trans.get("RocketActions.lbl.Youcanchangedefop"),-2));
218
219                         int ret = JOptionPane.showConfirmDialog(
220                                         parentFrame,
221                                         new Object[] {
222                                         //// Delete the selected simulations?           
223                                         trans.get("RocketActions.showConfirmDialog.lbl1"),
224                                         //// <html><i>This operation cannot be undone.</i>
225                                         trans.get("RocketActions.showConfirmDialog.lbl2"),
226                                         "",
227                                         panel },
228                                         //// Delete simulations
229                                         trans.get("RocketActions.showConfirmDialog.title"),
230                                         JOptionPane.OK_CANCEL_OPTION,
231                                         JOptionPane.WARNING_MESSAGE);
232                         if (ret != JOptionPane.OK_OPTION)
233                                 return false;
234
235                         if (dontAsk.isSelected()) {
236                                 Application.getPreferences().putBoolean(Preferences.CONFIRM_DELETE_SIMULATION, false);
237                         }
238                 }
239
240                 return true;
241         }
242
243
244         /**
245          * Return the component and position to which the current clipboard
246          * should be pasted.  Returns null if the clipboard is empty or if the
247          * clipboard cannot be pasted to the current selection.
248          * 
249          * @param   clipboard   the component on the clipboard.
250          * @return  a Pair with both components defined, or null.
251          */
252         private Pair<RocketComponent, Integer> getPastePosition(RocketComponent clipboard) {
253                 RocketComponent selected = selectionModel.getSelectedComponent();
254                 if (selected == null)
255                         return null;
256
257                 if (clipboard == null)
258                         return null;
259
260                 if (selected.isCompatible(clipboard))
261                         return new Pair<RocketComponent, Integer>(selected, selected.getChildCount());
262
263                 RocketComponent parent = selected.getParent();
264                 if (parent != null && parent.isCompatible(clipboard)) {
265                         int index = parent.getChildPosition(selected) + 1;
266                         return new Pair<RocketComponent, Integer>(parent, index);
267                 }
268
269                 return null;
270         }
271         
272         
273         
274         
275
276         ///////  Action classes
277
278         private abstract class RocketAction extends AbstractAction implements ClipboardListener {
279                 public abstract void clipboardChanged();
280         }
281
282
283         /**
284          * Action that deletes the selected component.
285          */
286         private class DeleteComponentAction extends RocketAction {
287                 public DeleteComponentAction() {
288                         //// Delete
289                         this.putValue(NAME, trans.get("RocketActions.DelCompAct.Delete"));
290                         //// Delete the selected component.
291                         this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.DelCompAct.ttip.Delete"));
292                         this.putValue(MNEMONIC_KEY, KeyEvent.VK_D);
293 //                      this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
294                         this.putValue(SMALL_ICON, Icons.EDIT_DELETE);
295                         clipboardChanged();
296                 }
297
298                 @Override
299                 public void actionPerformed(ActionEvent e) {
300                         RocketComponent c = selectionModel.getSelectedComponent();
301
302                         if (isDeletable(c)) {
303                                 ComponentConfigDialog.hideDialog();
304
305                                 document.addUndoPosition("Delete " + c.getComponentName());
306                                 delete(c);
307                         }
308                 }
309
310                 @Override
311                 public void clipboardChanged() {
312                         this.setEnabled(isDeletable(selectionModel.getSelectedComponent()));
313                 }
314         }
315
316
317         
318         /**
319          * Action that deletes the selected component.
320          */
321         private class DeleteSimulationAction extends RocketAction {
322                 public DeleteSimulationAction() {
323                         //// Delete
324                         this.putValue(NAME, trans.get("RocketActions.DelSimuAct.Delete"));
325                         //// Delete the selected simulation.
326                         this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.DelSimuAct.ttip.Delete"));
327                         this.putValue(MNEMONIC_KEY, KeyEvent.VK_D);
328 //                      this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
329                         this.putValue(SMALL_ICON, Icons.EDIT_DELETE);
330                         clipboardChanged();
331                 }
332
333                 @Override
334                 public void actionPerformed(ActionEvent e) {
335                         Simulation[] sims = selectionModel.getSelectedSimulations();
336                         if (sims.length > 0) {
337                                 if (verifyDeleteSimulation()) {
338                                         for (Simulation s: sims) {
339                                                 document.removeSimulation(s);
340                                         }
341                                 }
342                         }
343                 }
344
345                 @Override
346                 public void clipboardChanged() {
347                         this.setEnabled(isSimulationSelected());
348                 }
349         }
350
351
352         
353         /**
354          * Action that deletes the selected component.
355          */
356         private class DeleteAction extends RocketAction {
357                 public DeleteAction() {
358                         //// Delete
359                         this.putValue(NAME, trans.get("RocketActions.DelAct.Delete"));
360                         //// Delete the selected component or simulation.
361                         this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.DelAct.ttip.Delete"));
362                         this.putValue(MNEMONIC_KEY, KeyEvent.VK_D);
363                         this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
364                         this.putValue(SMALL_ICON, Icons.EDIT_DELETE);
365                         clipboardChanged();
366                 }
367
368                 @Override
369                 public void actionPerformed(ActionEvent e) {
370                         if (isSimulationSelected()) {
371                                 deleteSimulationAction.actionPerformed(e);
372                                 parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
373                         } else {
374                                 deleteComponentAction.actionPerformed(e);
375                                 parentFrame.selectTab(BasicFrame.COMPONENT_TAB);
376                         }
377                 }
378
379                 @Override
380                 public void clipboardChanged() {
381                         this.setEnabled(isDeletable(selectionModel.getSelectedComponent()) ||
382                                         isSimulationSelected());
383                 }
384         }
385
386
387         
388         /**
389          * Action the cuts the selected component (copies to clipboard and deletes).
390          */
391         private class CutAction extends RocketAction {
392                 public CutAction() {
393                         //// Cut
394                         this.putValue(NAME, trans.get("RocketActions.CutAction.Cut"));
395                         this.putValue(MNEMONIC_KEY, KeyEvent.VK_T);
396                         this.putValue(ACCELERATOR_KEY, CUT_KEY_STROKE);
397                         //// Cut this component or simulation to the clipboard and remove from this design
398                         this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.CutAction.ttip.Cut"));
399                         this.putValue(SMALL_ICON, Icons.EDIT_CUT);
400                         clipboardChanged();
401                 }
402
403                 @Override
404                 public void actionPerformed(ActionEvent e) {
405                         RocketComponent c = selectionModel.getSelectedComponent();
406                         Simulation[] sims = selectionModel.getSelectedSimulations();
407
408                         if (isDeletable(c) && isCopyable(c)) {
409                                 ComponentConfigDialog.hideDialog();
410                                 
411                                 document.addUndoPosition("Cut " + c.getComponentName());
412                                 OpenRocketClipboard.setClipboard(c.copy());
413                                 delete(c);
414                                 parentFrame.selectTab(BasicFrame.COMPONENT_TAB);
415                         } else if (isSimulationSelected()) {
416
417                                 Simulation[] simsCopy = new Simulation[sims.length];
418                                 for (int i=0; i < sims.length; i++) {
419                                         simsCopy[i] = sims[i].copy();
420                                 }
421                                 OpenRocketClipboard.setClipboard(simsCopy);
422
423                                 for (Simulation s: sims) {
424                                         document.removeSimulation(s);
425                                 }
426                                 parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
427                         }
428                 }
429
430                 @Override
431                 public void clipboardChanged() {
432                         RocketComponent c = selectionModel.getSelectedComponent();
433                         this.setEnabled((isDeletable(c) && isCopyable(c)) || isSimulationSelected());
434                 }
435         }
436
437
438
439         /**
440          * Action that copies the selected component to the clipboard.
441          */
442         private class CopyAction extends RocketAction {
443                 public CopyAction() {
444                         //// Copy
445                         this.putValue(NAME, trans.get("RocketActions.CopyAct.Copy"));
446                         this.putValue(MNEMONIC_KEY, KeyEvent.VK_C);
447                         this.putValue(ACCELERATOR_KEY, COPY_KEY_STROKE);
448                         //// Copy this component (and subcomponents) to the clipboard.
449                         this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.CopyAct.Copy"));
450                         this.putValue(SMALL_ICON, Icons.EDIT_COPY);
451                         clipboardChanged();
452                 }
453
454                 @Override
455                 public void actionPerformed(ActionEvent e) {
456                         RocketComponent c = selectionModel.getSelectedComponent();
457                         Simulation[] sims = selectionModel.getSelectedSimulations();
458
459                         if (isCopyable(c)) {
460                                 OpenRocketClipboard.setClipboard(c.copy());
461                                 parentFrame.selectTab(BasicFrame.COMPONENT_TAB);
462                         } else if (sims.length >= 0) {
463
464                                 Simulation[] simsCopy = new Simulation[sims.length];
465                                 for (int i=0; i < sims.length; i++) {
466                                         simsCopy[i] = sims[i].copy();
467                                 }
468                                 OpenRocketClipboard.setClipboard(simsCopy);
469                                 parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
470                         }
471                 }
472
473                 @Override
474                 public void clipboardChanged() {
475                         this.setEnabled(isCopyable(selectionModel.getSelectedComponent()) ||
476                                         isSimulationSelected());
477                 }
478                 
479         }
480
481
482
483         /**
484          * Action that pastes the current clipboard to the selected position.
485          * It first tries to paste the component to the end of the selected component
486          * as a child, and after that as a sibling after the selected component. 
487          */
488         private class PasteAction extends RocketAction {
489                 public PasteAction() {
490                         //// Paste
491                         this.putValue(NAME, trans.get("RocketActions.PasteAct.Paste"));
492                         this.putValue(MNEMONIC_KEY, KeyEvent.VK_P);
493                         this.putValue(ACCELERATOR_KEY, PASTE_KEY_STROKE);
494                         //// Paste the component or simulation on the clipboard to the design.
495                         this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.PasteAct.ttip.Paste"));
496                         this.putValue(SMALL_ICON, Icons.EDIT_PASTE);
497                         clipboardChanged();
498                 }
499
500                 @Override
501                 public void actionPerformed(ActionEvent e) {
502                         RocketComponent clipboard = OpenRocketClipboard.getClipboardComponent();
503                         Simulation[] sims = OpenRocketClipboard.getClipboardSimulations();
504                         
505                         Pair<RocketComponent, Integer> position = getPastePosition(clipboard);
506                         if (position != null) {
507                                 ComponentConfigDialog.hideDialog();
508                                 
509                                 RocketComponent pasted = clipboard.copy();
510                                 document.addUndoPosition("Paste " + pasted.getComponentName());
511                                 position.getU().addChild(pasted, position.getV());
512                                 selectionModel.setSelectedComponent(pasted);
513                                 
514                                 parentFrame.selectTab(BasicFrame.COMPONENT_TAB);
515                                 
516                         } else if (sims != null) {
517                                 
518                                 ArrayList<Simulation> copySims = new ArrayList<Simulation>();
519
520                                 for (Simulation s: sims) {
521                                         Simulation copy = s.duplicateSimulation(rocket);
522                                         String name = copy.getName();
523                                         if (name.matches(OpenRocketDocument.SIMULATION_NAME_PREFIX + "[0-9]+ *")) {
524                                                 copy.setName(document.getNextSimulationName());
525                                         }
526                                         document.addSimulation(copy);
527                                         copySims.add(copy);
528                                 }
529                                 selectionModel.setSelectedSimulations(copySims.toArray(new Simulation[0]));
530                                 
531                                 parentFrame.selectTab(BasicFrame.SIMULATION_TAB);
532                         }
533                 }
534
535                 @Override
536                 public void clipboardChanged() {
537                         this.setEnabled(
538                                         (getPastePosition(OpenRocketClipboard.getClipboardComponent()) != null) ||
539                                         (OpenRocketClipboard.getClipboardSimulations() != null));
540                 }
541         }
542         
543         
544         
545         
546
547         
548         /**
549          * Action to edit the currently selected component.
550          */
551         private class EditAction extends RocketAction {
552                 public EditAction() {
553                         //// Edit
554                         this.putValue(NAME, trans.get("RocketActions.EditAct.Edit"));
555                         //// Edit the selected component.
556                         this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.EditAct.ttip.Edit"));
557                         clipboardChanged();
558                 }
559
560                 @Override
561                 public void actionPerformed(ActionEvent e) {
562                         RocketComponent c = selectionModel.getSelectedComponent();
563                         if (c == null)
564                                 return;
565                         
566                         ComponentConfigDialog.showDialog(parentFrame, document, c);
567                 }
568
569                 @Override
570                 public void clipboardChanged() {
571                         this.setEnabled(selectionModel.getSelectedComponent() != null);
572                 }
573         }
574
575
576         
577         
578         
579         
580         
581         /**
582          * Action to add a new stage to the rocket.
583          */
584         private class NewStageAction extends RocketAction {
585                 public NewStageAction() {
586                         //// New stage
587                         this.putValue(NAME, trans.get("RocketActions.NewStageAct.Newstage"));
588                         //// Add a new stage to the rocket design.
589                         this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.NewStageAct.Newstage"));
590                         clipboardChanged();
591                 }
592
593                 @Override
594                 public void actionPerformed(ActionEvent e) {
595                         
596                         ComponentConfigDialog.hideDialog();
597
598                         RocketComponent stage = new Stage();
599                         //// Booster stage
600                         stage.setName(trans.get("RocketActions.ActBoosterstage"));
601                         //// Add stage
602                         document.addUndoPosition("Add stage");
603                         rocket.addChild(stage);
604                         rocket.getDefaultConfiguration().setAllStages();
605                         selectionModel.setSelectedComponent(stage);
606                         ComponentConfigDialog.showDialog(parentFrame, document, stage);
607                         
608                 }
609
610                 @Override
611                 public void clipboardChanged() {
612                         this.setEnabled(true);
613                 }
614         }
615
616
617
618         
619         /**
620          * Action to move the selected component upwards in the parent's child list.
621          */
622         private class MoveUpAction extends RocketAction {
623                 public MoveUpAction() {
624                         //// Move up
625                         this.putValue(NAME, trans.get("RocketActions.MoveUpAct.Moveup"));
626                         //// Move this component upwards.
627                         this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.MoveUpAct.ttip.Moveup"));
628                         clipboardChanged();
629                 }
630
631                 @Override
632                 public void actionPerformed(ActionEvent e) {
633                         RocketComponent selected = selectionModel.getSelectedComponent();
634                         if (!canMove(selected))
635                                 return;
636                         
637                         ComponentConfigDialog.hideDialog();
638
639                         RocketComponent parent = selected.getParent();
640                         document.addUndoPosition("Move "+selected.getComponentName());
641                         parent.moveChild(selected, parent.getChildPosition(selected)-1);
642                         selectionModel.setSelectedComponent(selected);
643                 }
644
645                 @Override
646                 public void clipboardChanged() {
647                         this.setEnabled(canMove(selectionModel.getSelectedComponent()));
648                 }
649                 
650                 private boolean canMove(RocketComponent c) {
651                         if (c == null || c.getParent() == null)
652                                 return false;
653                         RocketComponent parent = c.getParent();
654                         if (parent.getChildPosition(c) > 0)
655                                 return true;
656                         return false;
657                 }
658         }
659
660
661
662         /**
663          * Action to move the selected component down in the parent's child list.
664          */
665         private class MoveDownAction extends RocketAction {
666                 public MoveDownAction() {
667                         //// Move down
668                         this.putValue(NAME, trans.get("RocketActions.MoveDownAct.Movedown"));
669                         //// Move this component downwards.
670                         this.putValue(SHORT_DESCRIPTION, trans.get("RocketActions.MoveDownAct.ttip.Movedown"));
671                         clipboardChanged();
672                 }
673
674                 @Override
675                 public void actionPerformed(ActionEvent e) {
676                         RocketComponent selected = selectionModel.getSelectedComponent();
677                         if (!canMove(selected))
678                                 return;
679                         
680                         ComponentConfigDialog.hideDialog();
681
682                         RocketComponent parent = selected.getParent();
683                         document.addUndoPosition("Move "+selected.getComponentName());
684                         parent.moveChild(selected, parent.getChildPosition(selected)+1);
685                         selectionModel.setSelectedComponent(selected);
686                 }
687
688                 @Override
689                 public void clipboardChanged() {
690                         this.setEnabled(canMove(selectionModel.getSelectedComponent()));
691                 }
692                 
693                 private boolean canMove(RocketComponent c) {
694                         if (c == null || c.getParent() == null)
695                                 return false;
696                         RocketComponent parent = c.getParent();
697                         if (parent.getChildPosition(c) < parent.getChildCount()-1)
698                                 return true;
699                         return false;
700                 }
701         }
702
703
704
705 }