Wednesday, January 23, 2013

Keyboard Event Filter

One of the tasks for the edit box is to intercept keys before they are processed by the QTextEdit base class so that additional programming related keyboard commands can be implemented.  This is accomplished by installing a custom event filter function to the widget.  An installed event filter is called before the doing the regular event processing.  An event filter can be a member of any class and be installed to any widget.  Because I don't see a reason not to, the EditBox class was given an event filter and it is installed to itself in the constructor:
installEventFilter(this);
The argument of this function call is the class containing the event filter, which in this case is the instance itself.  The event filter contains an argument of the object receiving the event and the event itself.  In this case, since the event filter was only installed for this instance of the edit box, the object will be the instance itself and there is no need to check it.

The first key to modify is the Return key.  For a text editor, the Return key simply inserts a new line.  It is desired that a Return key enter the current line into the program (parse, translate, etc.) no matter where on the line the cursor is at.  In other words, not to break the line into two lines at the cursor.  However, if the cursor is at the end of the line, it will open a new line (insert a blank line) on the next line.  To allow a line to be broken into two, the Control+Return key will be used.  The Control+Return is ignored by the QTextEdit class.  So the first behavior implemented in the new event filter was to treat a Control+Return key as a Return key.

The event filter receives all event types, so the event type is first checked for key press event.  The event pointer is then cast to a QKeyEvent so that the specifics of the key press event can be checked starting with if it contains the Return key.  Since the Enter key on the numeric keypad is received as a different code, both the Return and Enter values are checked for.  Finally the keyboard modifiers (Control, Shift, Alt, etc.) of the key press event is checked for a control modifier. 

The Control+Return key needs to be changed to a regular Return to allow the new line insertion to take place, but the key event can't be modified and passed on.  Instead, a new key press event is created for a unmodified Return key and this new event is posted by calling the QApplication::postEvent() static function with the edit box instance pointer (this) for the new event.  A true is returned to indicate that the Control+Return key event has been processed.  If the event was not a key press Control+Return event, the event is passed through to the regular event filter by calling QTextEdit::eventFilter().

[commit cb32f9ab0e]