Gnats 5111: Crash when writing RPL logic
Revised Title: Crash applying edit to selected top-level Rpl Function or Block Execution Constraint.
Edit 10-18-2011 (b) / Phil / CVS Note
The RplFrame class supports the following "applications":
The selection of the "top-level" object within the RplFrame is supported in all applications except SLOT_EXPRESSION. It is this sort of selection (i.e. of a "top-level" object) which occurs when clicking just below the <expr> symbol, as described in David's Oct 18 note. The image to the right shows a top-level selection within a Rpl Function. |
![]() |
When operating on the selection, the RplFrame::replaceTokenNoUndo() method gets called. This method supports operations on top-level items ONLY FOR TWO of the RplFrame applications:
Application | Top-Level Selection Implemented |
Top-Level item processing implemented in the RplFrame::replaceTokenNoUndo() method / Effect | |
BLOCK_STATEMENTS | YES | YES | |
BLOCK_EXECUTION_CONSTRAINT | YES | NO | CRASH |
FUNCTION_BODY | YES | NO | CRASH |
FUNCTION_VALUE_CONSTRAINTS | YES | YES | |
SLOT_EXPRESSION | NO | NO | (does not occur) |
Preventing the selection of the top-level object within a Slot Expression RplFrame is implemented with a special provision in the VisualToken::contains(int x, int y) method -- SEE BELOW. Note the exceptions for VisualToken::SLOT_SYMBOL in this method.
The Gnats 5111 crash can be avoided by excluding also FUNCTION_SYMBOL and BLOCK_EXEC_CONSTRAINT_SYMBOL containers.
//---------------------------------------------------------------------------- //+public // // METHOD: // VisualToken* VisualToken::contains(int x, int y) // // PURPOSE: // Returns the deepest token in this token's tree that contains the // given point. // // PARAMETERS: // (I) x,y - a cartesian point // // RETURN VALUE: // The most "junior" VisualToken containing the point x, y. NULL if no // VisualToken contains the point. // //---------------------------------------------------------------------------- VisualToken* VisualToken::contains(int x, int y) { VisualToken *selected = NULL; if (_deviceRect.contains (x, y)) { cwIterator iter; VisualToken *child = NULL; VisualToken *container = NULL; FORALL (iter, *_children) { child = _children->elem(iter); // Don't let the user select the top-level slot expression. if (((container = child->contains(x, y)) != NULL) && (!container->isA(VisualToken::SLOT_SYMBOL)) ) { if (!selected || selected->_children->size() > container->_children->size()) { selected = container; } } } // // None of my children (I may not have any) contained the point // if (!selected && !isA(VisualToken::SLOT_SYMBOL)) return this; } return selected; } |
---