Saturday, March 9, 2013

Viewing Program Changes

To monitor the contents of the program, which will be updated by the program changed signal, a Program View dock widget was added to the right side of the application GUI using Designer.  A dock widget can be docked to any side of the window, through this dock widget was restricted to the left and right sides.  A dock widget can also be undocked from the main window.

A QListView widget was added to the Program View dock widget.  The editTriggers property was set to NoEditTriggers to prevent editing and the selectionMode property was set to NoSelection to prevent selection.  In other words, this list view was made read-only.

A QListView is meant to work with a data model.  Eventually a custom Program Model will be created that will hold the program.  The MainWindow class will contain a pointer to the Program Model.  To keep it simple to start, the predefined QStringListModel was used.  This model simply maintains a list of strings, which for now are set to the program line strings.

The program model is instanced in the MainWindow constructor, which must be done before the edit box is instanced, since the edit box will generate a program change signal.  This model is then assigned to the QListView widget.  Any changes to the model will be reflected in the dock widget.  The program changed slot in main window was modified to update the program model as changes are received instead of outputting the changes to the console.

[commit 60e125362e]

Entire Loaded Program Detection

The only remaining use of edit box ignore change flag mechanism was to stop detection when the document was set using the reimplemented setPlainText() function, which set this ignore flag before calling the base class function and cleared it afterward.  The document change function upon seeing this flag set returned without processing the change.

Since it was now desired to process this change and report all lines as being added, the ignore flag mechanism was removed.  Also, the remaining functionality of the reimplemented setPlainText() function was calling the base class function and then setting the line count variable.  The line count variable will now be set by the document change function, and since this function was only calling the base class function, it was also removed.

For some strange reason, there are actually two document contents change signals generated when the document text is set, one where it indicates one character removed and none added, and a second one with no characters removed and the number of characters in the file added.  My guess is that the first signal is generated from the document being cleared before being set, and the one character is an empty line where the document always contains at least one block (with a single new line).

This first change signal needed to be ignored, which can be accomplished by checking if the document is empty.  However, this is not the only case where the document could be empty (like if all the characters were deleted).  Another indicator was needed for this condition.  The document change function does a move cursor position by the number of characters added to determine where the cursor will end up.  It turns out that this function returns whether the move succeeded.  If the document is empty, this move fails, so this status is captured.  If the document is empty and the move failed, the document change function only resets the modified line and returns.

The cursor position move also fails when with the second signal because the number of characters added is one more than the cursor can be moved.  Since this move fails, the number of lines modified ends up being zero instead of being set to the number of lines in the document that were added.  To emit the correct number of lines inserted, the number of lines changed is only adjusted if the cursor move succeeded or the number of lines modified is not less than the net line count change when lines were added to the document.

[commit 23c1ace139]

Newly Inserted Lines Fix

When a new program is loaded, the entire program must be loaded into the document (as plain text) and the class that will hold the encoded program.  One method would be to set the edit box document to the plain text of the program and then set the program class.  Another method is to allow the program change signal that would be emitted when the document is set to the text of the program (which is presently disabled).

After re-enabling the signal when the document text is set, and trying to get the proper signals to be emitted, I discovered that newly inserted lines were not always being emitted correctly.  A simple example of this is when a return is entered at the end of the new line - the line was reported as changed instead of inserted.

This problem occurred because the code needed to check if the current modified line is going to be new, but was not previously new before adjusting the number of lines changed and inserted for the new line.  When the line is new, but wasn't previously new, the number of lines modified is incremented by one and the number of inserted lines is decremented by one to account for the new line that hasn't been inserted yet.

The aid in debugging, a status indicator character was added to the line number widget after the line number of the current line to indicate when the current line is modified (with an asterisk) or is new (with a plus).  This is easier than having a message on the console indicating the line number modified and new status, and then having to refer to edit box to see which line the cursor is at.

[commit 9f15211791]

Line Change Detection Complete

The detection of program line changes should now be complete.  This feature is necessary so that program lines can be incrementally compiled as they are modified.  Even though the implementation was starting to look rather complicated, it turned out to be fairly simply, which was mostly concentrated in the processing of the edit box document's contents change signal that contained sufficient information to report line changes.  From the time the new implementation was started, the size of the edit box code was reduced by about half and the previous implementation wasn't complete.

The next step is to connect the new program changed signal from the edit box to some new program class that will eventually hold the BASIC program code, though the goal of the current 0.3.x release series is to get the translator part hooked up.  However, this is a good point to make a development release.  In preparation for this, there was some minor cleanup of the code:
  1. Renamed the edit box line number widget related functions with the consistent prefix of lineNumberWidget (separate commit).
  2. Corrected a memory leak of the edit box instance by assigning the main window as its parent.
  3. Removed the setting of the ignore change flag at the end of the edit box key press event handler (this flag is now only used when a new program is set).
  4. Updated the copyright of the modified files and a few other very minor changes.
The various files (CMake, read me, and release notes) were updated for this development release and the code was given the tag v0.3.2.

[commit a2cfa5361a] [commit a13c485632]