Thursday, January 24, 2013

New Return Key Behavior

Now that the edit box has its own key press event handler, the desired behavior of the Return key can be completed.  The Return key will only insert a new line if the cursor is at the end of line, except if the line is blank, otherwise it will just move the cursor to the next line.  The Control+Return can be used to always insert a new line.

To determine if the cursor is at the end of a non-blank line, the text cursor of the edit box is used.  The text cursor holds the position of the cursor and is also used to make selections and to modify  the document of the edit box.  Since the text cursor will probably by used for many of the new key sequences that will be implemented, a copy of it is obtained at the beginning of the key press event handler.  Any changes made to this copy won't show up in the edit box unless the edit box's cursor is updated (the textCursor() access function only returns a copy of the cursor).

The text cursor contains the functions atBlockEnd() and atBlockBegin() for determining if the cursor is at the end or beginning of the line.  For a normal text document, blocks are the same as lines.  So, if the cursor is not at the end of a block or at the beginning of a block, the cursor is moved to the beginning of the next block using the moveCursor() function with the NextBlock argument.  The modified cursor is put back into the edit box and the handler returns.

This created a problem for the Control+Return key code that created a new Return key event.  When this event came back to the handler, it went through the at end of block check and was treated as a Return key and only moved to the next line.  To correct this, the new event creation code was replaced with a call to the insertText() function of the text cursor with a string containing a new line character.  The handler then returns.

[commit 29159082ec]

Key Press Event Handler

Upon reading up on events, event filters and event handlers, I realized installing an event filter to handle additional key press events was not the best solution.  There are actually several levels at which events can be monitored and intercepted and event filters are the third level up.

The lowest level are the specific event handler functions for a widget, each of which handle a specific type of event.  The next level is the event handler for a widget that receives all types of events.  The third level is any installed event filter for the widget in backwards order of when they were installed.  There are several more levels above this that won't be detailed here.  The real purpose of event filters is for another class, like a parent widget, to monitor and intercept the events of several widgets.

Therefore, the event filter function was replaced with a key press event handler function.  This function will receive only key press events.  Instead of an if statement for checking for the Return or Enter keys, a switch statement was used since other keys will need to be handled.  Again, if the key is a Control+Return a new unmodified Return key press event is created and posted.  Unlike the event filter function, an event handler function just returns.  Being at the lowest level, there are no additional routines that will be called for the event.  Similar to the event filter, all unprocessed key press events are passed on to the base QTextEdit class key press event handler.

[commit 241fa39814]