POW - cursor position in inactive view should not change.


Subject: POW - cursor position in inactive view should not change.
From: Martin Sevior (msevior@mccubbin.ph.unimelb.edu.au)
Date: Sat Jan 13 2001 - 19:14:27 CST


Hi everyone,
            Here is the first of the new series of Projects of the Week.
This POW is to fix the fact that the cursor in an inactive view gets set
to the cursor position in the active view. In doing this POW you will
learn how the Abi Model- View-Controller scheme works and to fix a
significant failure of it.

To see the bug, Open a multi-page document. Open another window on the
document. Move to a different page in the document. Type something there.
Delete the typing then undo the delete. Focus in the first Window and
start typing. You see the cursor has moved to location where you undid the
deleted text and not where you left it.

In abi the PieceTable is the Model, the fl_*Layout classes are the view
and the controller is split between fv_View.cpp and pd_Document.cpp. Abi
allows multiple views of the same document and each view not only gets its
own fl_*layout.cpp classes but also its own fv_View.

fv_View maintains an insertion point m_iInsPoint which is just a UT_uint32
offset to the current PieceTable location. When an editting change occurs
in the currently active frame, this information is transmitted to the
piecetable which changes it's content. Then pd_Document signals to all
active views that they must update themselves to reflect the changed
piecetable state.

In the end these changes are made in the fl_BlockLayout::doclistener_*
methods of fl_BlockLayout. Now often these changes require that the
insertion point is changed in the view. In particular the method

doclistener_deleteSpan has the following code:

        FV_View* pView = m_pLayout->getView();
        if (pView)
        {
                 pView->_resetSelection();
                 pView->_setPoint(pcrs->getPosition());
        }

Which will set the insertion points in ALL views to the currently active
view.

Your job is think of a way that insertion point is only changed in the
currently active frame, while keeping the insertion point inactive frames
sane.

For example, suppose the insertion point in the inactive frame is at the
end of the document but in the active frame you delete all text from the
middle to the end of the document. If you don't the change inactive
insertion point you'll get a segfault when type in the inactive frame.

Here are some hints I've thought of.

1. You can tell if the current BlockLayout is the active view by looking
to see if the the getView() method (as shown above) returns the same
pointer as getApp()->getFrame()->getCurrentView().

2. Work out an algorithm to update the insertion point based on
location of the insertion point of the view in the layout compared
to the insertion point in the active view.

The easy case is if the insertion point of the active view is larger the
view in the layout. In this case we don't change the insertion point at
all.

Good Luck!

Martin



This archive was generated by hypermail 2b25 : Sat Jan 13 2001 - 19:14:34 CST