Showing posts with label GUI. Show all posts
Showing posts with label GUI. Show all posts

Saturday, January 4, 2014

Main Window – Multiple Edit Boxes

The application will eventually support multiple edit boxes where the subroutines and functions can be opened at the same time in additional edit boxes.  The main routine or any of the subroutines or functions could also be opened in multiple edit boxes.  This support will be added later, but some preparation work can be done and this will be useful in the reorganization of the program and edit box classes.

Currently there is a list of actions that are built and given to the edit box instance for its context menu.  This context menu will only be assigned to the edit box that is currently active and only one edit box will be active at a given time (the one that has focus).  When the focus changes to a different edit box, the context menu needs to be removed from the edit box losing focus and added to the one gaining focus.  To make this easier, the list of actions are built and stored into a new member variable.  This list will be assigned to an edit box instance as needed.

In addition to setting the actions (context menu) of an edit box, the various signals from the edit box needs to be connected to the various actions in the context menu (for enabling and disabling the actions) and to the status bar update slot (for the cursor changed signal).  These items need to be done when an edit box instance becomes active.  For the edit box losing focus, the context menu (actions) needs to be removed and the signals disconnected.

This code was put into a new edit box set active routine that takes an edit box instance as an argument.  Preliminary code was added for first disconnecting the signals and removing the actions of the edit box losing focus.  This code was commented since there is currently only one edit box instance.

[commit 5b8741768c]

Saturday, December 7, 2013

Program (Recreator) and GUI Integration

The recreator is fully integrated with the program model such that program lines can be converted back into text.  When lines are entered into the program, the lines need to be recreated back to text and put into the edit box (the GUI), specifically into the text document of the edit box.  Like the temporary program view (being used for debugging) is the viewer of the data held by the program model, the edit box is the viewer of the data contained in the document.  The edit box also allows editing, so it is more than just a viewer.

The document of the edit box is really just the text representation of the program.  The program model holds the actual data of the program.  Ideally, the program model would be the document of the edit box and it would convert text to program code and back while editing.  However, Qt does not have an abstract text document class from which a document sub-class could be built that would hold its data in another form like program code.  The QTextDocument class is meant for text.

Alternatively, a new viewer could be designed that would allow all the text editing features (cut, copy, paste, undo, redo, etc.) like the QPlainTextEdit class that the edit box class is based on.  Designing one would be quite an effort.  Therefore, the edit box will the viewer for two data models at the same time, the text document (to allow text editing) and the program model (for holding the program code).  The program model will be the master of the data, with the text document being updated as the program changes.

This implies that the edit box either own the program model with the program code or at least have easy access to it like via a pointer.  The later approach will be used since the main window class will ultimately be the owner of the program.  Eventually there will be a list of program models, one for the main routine and several for the subroutines and functions of the program.  There will only be associated edit box instances when the main routine, subroutines or functions are open for editing.

Since the edit box will now have access to the program model, signals from the program model (for program changes) do not need to contain actual data.  For instance, when a program line has changed, its recreated text is needed to update the text document.  The signal could contain both the line number and text (already recreated).  Looking at the edit box to document interface, when the document changes, only the position, number of characters removed and inserted are contained in the signal.  The edit box must obtain the actual text changes by querying the document.  So, when the program changes, only the line number will be sent and the edit box will request the recreated text from the program model.

Sunday, October 27, 2013

GUI Program View – Code Output

The program view contents was changed from the text of the translated RPN list to the debug text output of the program code using the debug text routine of the program model.  The program model data function is used by the program view widget for getting its contents.  Unfortunately, this was not as simple as change as it sounds.

The data function is a constant function (const).  Because this function is constant, the debug text function also needed to be a constant function.  Making this function constant required several variables in the function to be constant, and the operand text function also needed to be changed to constant.  Changing the operand text function to constant required the table operand text function pointers to be constant.  Changing these functions required their program model pointer argument to also be change to constant.

[commit f089c78b59]

Saturday, June 15, 2013

Translator/GUI Integration - Release

The integration of the Translator and the GUI is now complete, which includes a debugging program view of the program internals containing the translated RPN lists of the program lines.  This will eventually show the internal program codes once the encoder is implemented.  Version 0.3.5 has been released (branch0.3 was merged to the master branch and tagged v0.3.5).

Archive files containing the source and binary files(with test files) have been  uploaded to SourceForge.  For Windows, there is also the ibcp-libs.zip file that contains all the dynamic linked libraries required to run the program if the MinGW and QtSDK packages have not been installed (extract into the ibcp directory).  Linux should already have the required libraries installed.

This concludes the 0.3 development series.  Implementation of the next step will now begin with the 0.4 development series, which will be defined in the next post.

[commit 046c47cd9a]

Friday, June 14, 2013

Modifying A Line With An Error

When a line is modified that contains an error, the highlighted error can be shifted around or changed in size.  This can make the error message no longer applicable, so the highlighted error should be removed.  Upon the cursor leaving the line, the line will be rechecked for errors.  A check for this situation was added to the document change slot of the edit box class when a single line is changed.  No action was taken for single line changes.

When a single line is modified, the errors lists is searched its line number.  If the line contains an error, but the modification occurred after the error, no further action is taken.  If the cursor and the error are at the end of the line, or the cursor is within the error, the error is removed from the error list.  If the cursor is before the error, the column of the error is moved by the net change (number of characters added less the number removed).

The update errors slot is called to update the display.  A cursor changed signal is also emitted so that the error message on the status line is removed when the error is removed.  This didn't always occur because the cursor is not always moved when the document is changed (for example, when characters are deleted).  New move error column functions were added to the error list and error item classes to support the shifting of errors.

[commit 98d7b2c0b4]

Thursday, June 13, 2013

Error Action Enabling/Disabling

Now with actions to move the cursor to the next or previous error, these actions should only be enabled when there are actually errors.  To accomplish this, an errors available signal was added to the edit box class.  The update errors slot was modified to determine when the errors available condition changes by comparing the before and after error list emptiness status.  Several problems were found and corrected while testing the new signal.

In the update errors slot, when there were no errors in the incoming errors list, a Qt error occurred because bad indexes were used in accessing the errors list.  This was due to using the start and end change indexes when they were not valid.  A check was added for when the incoming error list has no errors to prevent this.

The second problem occurred when there were no errors and the next or previous error key shortcuts were used.  This was due because the Ctrl+. (period) and Ctrl+, (comma) were not intercepted since the errors actions were disabled, causing these keys to be treated as a regular period and comma, which was inserted into the program.  Checks were added to the key press event handler to catch and ignore the period and comma keys when the Ctrl modifier was active.

Finally, during testing, an unrelated problem was found with the detection of changed lines when comparing RPN lists that contained errors.  Previously this comparison (equality operator function) compared the error column and length and reported equality if they were the same.  This caused a problem were sometimes the error was not displayed correctly in the modified line (or not at all).  The equality function was modified to report no match if either RPN list has an error.

[commit 352667221f] [commit 15084235a2]

Saturday, May 18, 2013

Move To Error Actions

It would be convenient to be able to move the cursor the next (or previous) error.  This was accomplished be adding two additional actions, one for moving the cursor to the next error and the other to move the cursor to the previous error.  Each action was given an arrow icon, which were modified to have a red hue.  Both were also assigned key shortcuts, which were Ctrl+. (period) for next and Ctrl+, (comma) for previous.  These keys were chosen because they also contain the greater than and less than keys, which are like arrows.

The actions are automatically connected to associated triggered functions in the MainWindow class, which call new functions in the EditBox class to perform the action.  These functions first find the error for the current line.  If the current line does not have an error, the find returns the index of next error or will return in index one beyond the end of the error list.  The functions then move to the next or previous error depending whether the cursor is already sitting at the error found.  If beyond the last or first error, a question box is displayed informing this and asks whether to move to the first or last error in the program.  If there is only one error, then no question box is displayed.

There is some sort of issue when running on Linux (Mint 13 KDE) using the static QMessageBox::question() function to display the question asking whether to wrap around and to the first or last error - an X Error message is output.  This may have something to do with another problem where there is suppose to be a question mark icon on this message box, but the information icon is displayed instead.  These problems do not occur on Windows and also do not occur on Linux if the application is launched with the -style Plastique option.

For now the next and previous error tool bar buttons and edit menu items are always enabled.  Next these will be disabled when there are no errors.

[commit f086ce50b8]

Sunday, May 12, 2013

Error Highlighting – Error Messages

To display error messages in the status bar area at the bottom of the application window required a few minor changes.  Two labels were added to the status bar of the main window, one for the current line number and column, and the other for the error message.  A signal was added to the edit box, which is emitted when the cursor positioned has changed.

A new function was added to the main window class for creating the status bar: adding the labels to the status bar and connecting the signal cursor changed signal from the edit box to a new update status bar slot in main window.  New member label pointers were added so that the labels are easily accessible when it's time to update their text.  New access functions were added to the edit box class to return the current line number, column and message for the line (if there is one) so the update slot can get the information for the status bar labels.

The new message access function of the edit box searches for the line number in the error list.  A new find index function was added to the error list class, which returns a -1 if the line number does not have an error.  The existing find function is called, which only returns an index regardless if the line has an error, so a check is made if the index returned is the line being search for.  If the line does not have an error, a blank message string is returned.

There were a couple of issues getting the error messages to be displayed in the status bar correctly.  Click Continue... for details of these issues and how they were resolved.

[commit c38cd02bd4]

Saturday, May 11, 2013

Error Highlighting – Program Load Fix

Displaying the error messages on the status bar at the bottom of the window has proven to be difficult.  While working on getting these changes to work, a problem was discovered when loading a program with errors - the errors were not display just like the problem when the application first starts.

The mechanism added to correct that initial start up problem did not work for this case because the cursor valid flag, which is initially reset, is set the first time the cursor is moved.  When a program is loaded, the text of the program loaded in set in the edit box's document using the setPlainText() function.  Apparently while the text is being set, the cursor is again invalid preventing the errors from being highlighted.

The cursor valid flag mechanism was utilized to correct this problem.  The setPlainText() function of the base QPlainTextEdit class was reimplemented in the edit box class, which resets the cursor valid flag and calls the base class function.  Once the text is set, a cursor changed signal gets emitted and the cursor valid flag is once again set triggering the errors to be updated.

[commit 58b0f23680]

Saturday, May 4, 2013

Errors List Corrections

While testing the error highlighting, some problems were found.  The first one exhibited itself as the last error was not correctly updated when it changed.  The problem was that a new error was being incorrectly inserted each time an error was changed.  This occurred in the set error routine in the program model because it did not return after replacing an error and it proceeded to also insert an error.

The set error routine was cleaned up where the first part now specifically handles changes (not inserts) and returns after an error is removed (the line no longer has an error), or an error is replaced (the line still has an error).  The rest of the routine handles inserting a new error and adjusting the rest of the error indexes and line numbers (for line inserts).  The remove error routine contained an else clause for exiting when called for an insert, but since this no longer occurs, the else clause was removed.

The second problem was in the edit box update errors slot.  The problem occurred when two or more lines with an error were removed and all the errors were changed as a result (due to the line numbers changing).  The problem is that the ending change index is set to the last index upon the first removed error, but after the second error is removed, the ending change index is not beyond the end of the error list.  This caused the routine to run past the end of the errors list causing a segmentation fault.  This was corrected by limiting the number of errors changed to one less than the size of the errors list.

[commit 30e7d98a1d] [commit 65893e51f9]

Friday, May 3, 2013

Error Highlighting – Initial Start Up Fix

The problem with the errors not being highlighted when the program is first loaded was not caused due to the edit box not being drawn yet as first thought.  The problem was identified to be that the text cursor was not valid initially.  When the extra selection list was set up, each enter had an invalid cursor, so nothing was highlighted.  The seemed to be no way to initialize the text cursor in the edit box constructor.

To compensate for this problem, a mechanism was implemented where the updated errors list is saved and not acted upon unless the text cursor is valid.  A new errors list member was added to the edit box class to hold the saved errors list.  The errors list needs to be saved anyway because it will be needed to access the error messages.

A new cursor valid flag was also added to the edit box class, which is initialized to false.  In the cursor moved slot, the text cursor will be valid and this event always occurs during startup.  So in this slot, if the cursor valid flag is not set, it is set to true and then the update errors slot is called to set the extra selections list.

[commit 89cfa532a8]

Thursday, May 2, 2013

Error Highlighting – Extra Selection List

To highlight the errors sent from the program model, a new extra selections list member was added to the edit box class.  The update errors slot first determines the number of errors that have been inserted or removed by taking the difference between the size of the new errors list and the size of the current extra selections list.  The number of errors that changes is determined by taking the difference between the end and start change indexes plus one, then subtracting the number of errors inserted (which may be zero).

Starting at the start change index for the number of errors that changed (which may also be zero), the extra selection is replaced with the corresponding error item from the errors list.  Continuing for the number of errors inserted, the new error items from the error list are inserted into the extra selections list.  Finally for the number of errors removed, the extra selections are removed from the list.  (There will never be both insertions and removals.)

A new support function was added for converting an error item to an extra selection.  If the length of the error is negative, this indicates an alternate column (which occurs in the case where there is a syntax error in the exponent of a floating point number, where the column is the beginning of the number).  For this case, the syntax error will be highlighted and not the number for a length of one character.

The format of the extra selection is set to red background.  The block for the line of the error item is retrieved from the document to get its position.  The cursor of the extra selection is set to the text cursor of the document and positioned to the error (position of the line plus the column of the error.  The cursor is moved to the end of the error with the keep anchor option, which highlights the error with the selected format.

Once the extra selections list has been updated for the change in the errors list, the edit box extra selections are set, which causes the errors to highlight.  However, there is a problem.  If a program contains errors when it is loaded, the errors are not initially highlighted.  I think this is because the edit box hasn't been drawn yet at the time the first errors changed signal is emitted.

[commit 24ae7f0467]

Friday, April 26, 2013

Program Model – Error List Changes

The program model is now keeping a list of errors in the program.  This list will be used to create the extra selections in the edit box to highlight the errors in the program.  A signal was added to the program model to emit the error list when it changes and a slot was added to the edit box to receive the error list.  For now, this slot just outputs the error list with indicators of the start and end errors that were changed.

The error list class was modified to capture the start and end indexes of the changes to a list when the program model receives a lines changed signal.  New start and end change indexes were added to the error list class along with access functions - one for resetting these indexes called at the start of the program model update slot, one for checking if there was a change to the error list called at the end of the update slot (to determine if the error list change signal should be emitted), and two to access each index called by the edit box to update the error highlighting.

To catch when errors in the list are modified, the insert, remove and replace functions in the error list class were overloaded.  Each calls the QList base function and then calls a new set change index private function, which checks if the index being modified is lower or higher then the current start and end change indexes.  New increment and decrement line number functions were also implemented, which call the error item functions and then the set change index function.

The new update errors slot function for the edit box class receives the error list change signal.  For now, the function just outputs the error list with indicators on the errors that changed, which was used for debugging.

[commit 666b15b531]

Thursday, April 25, 2013

Another Undo/Redo Problem

Now that the program model is keeping a list of errors in the program, the next incremental change is to report changes to this list to the edit box so that the errors can be highlighted.  While testing these changes, another problem was found with the detection of lines changes when using redo.

The problem occurs when the current line is modified (specifically from a redo) and another redo causes a change to occur in another part of the program.  The line that was modified does not get reported.  This can also occur with an undo, but only when going up and down through the undo/redo stack.  The line is not being reported because for undo and redo, the document change signal occurs before the cursor moved signal (where a modified line gets reported).

A check was added towards the beginning of the document change slot after gathering information about the change but before acting upon it.  If there is a modified line and the modified line is not at the line of the change, then the modified line is captured before processing the current change.

A complication occurs when the modified line is after the line of the change.  When reporting the modified line, the capture routine needs to report the line number contained in the modified line variable, however, when retrieving the text of this line, since the document has already been modified by the undo or redo, the number of the line is not necessarily the same if the undo or redo inserted or deleted lines.

Fortunately, the offset of where the actual program line is (after the undo or redo change) is the same as the net line count change caused by the undo or redo.  The capture modified line routine was modified to take an optional offset.  The net line count change is passed if the modified line is after the line of the change, otherwise, no offset is needed if the modified line is before the change.

[commit 0049ab8883]

Monday, April 8, 2013

Highlighting Errors – Extra Selections

The QPlainTextEdit class, the base class for the EditBox class, contains a feature called Extra Selections, which allows for temporarily marking certain regions of the document with a given format (color and/or style).  Each extra selection is specified by the QTextEdit::ExtraSelection structure that consists of a cursor (QTextCursor) and a format (QTextCharFormat).  A list (QList) of all the extra selections is given to the plain text edit widget using the setExtraSelection() function.

The selection, the characters to temporarily format, is specified by the cursor, which is initialized from the text cursor of edit widget.  The cursor is them set to the beginning position of the selection to temporarily mark and moved to the end of the selection using the keep anchor position option.

The temporary format is specified by the format member.  The format has many options including colors (foreground and background),  and font style like italicized, bold, underlined, and curvy underline.   The underlines can even be made a different color.

For translator errors, a simple red background will be used.  Later, another color, possible yellow or light blue, will be used for warnings.  There will be no warnings from the translator, but there will be warnings from the encoder.  For example, when the beginning of an IF statement or FOR loop is entered before the END IF or NEXT is entered, or vice-versa.  These are not errors as the line is valid, but these warnings will also prevent the program from being run until corrected.

Saturday, March 23, 2013

Initial Program Model Complete

There were some minor problems with the Save As action causing it to not work as desired, namely the file name was incorrectly defaulting to "." and the directory of the file saved was not being remembered.  The default file name was set to "." in the attempt to use the current directory, but the get save file name dialog saw this as the file name with no directory and used the directory the program was started in.  The string "./" should have been used.

The way it should be working is that the file name should start with the current file name giving the user the option to replace it or modify it.  If the user doesn't change the file name, the dialog will issue a warning asking if the file should be overwritten.  If the current file is untitled, then the default file name will be set to the current directory, and the dialog will contain a blank file name.  After the file is saved successfully, the current directory (that gets saved in the program settings upon exit) is set to the directory of the saved file.

Now it is time to start hooking up the parser and translator between the edit box and program model.  But first, this is a good point to make a development release.  The release related files were updated for a new release and the repository was given the tag v0.3.3.

[commit 143f449330] [commit f95a3d8d55]

Another Undo Issue

Testing has now been completed and I think most of the possible change scenarios have been tested.  There was some more problems with undo operations when at a new line that was not yet reported as inserted.  For some undo operations, a line was not being reported as changed when it should have been.  This occurred when the line of the beginning of the undo change was more than one line away from the current line that was new.

To correct this problem, a check was added if the line of the beginning of the change is more than one line away from the modified (new) line, then the number of lines modified is set to one from zero and since this is the next line, the changed line number is incremented.

Getting into this situation was rather complex, which required an insert of a new line (Control+Enter) in the middle of a line, moving to the end of this new line, deleting the end of this line to combine it with the next line, and then one undo.  This worked so far, but doing undo again is when the problem occurred.  I'm sure there could be more complex sequences that will not be detected correctly, but it's time to move on.  Any new problems that occur will be dealt with as they appear.

There is also a screen update problem that sometime occurs during an undo where a entire line is not redrawn correctly on the screen.  However, this was proven to be a bug in the QPlainTextEdit base class, not in the EditBox class because a simple program using just the QPlainTextEdit also exhibits the same bug (though the QTextEdit class does not).

[commit 2fc26b865a]

Friday, March 22, 2013

Paste Over Selection Update Screen Issue

Another unrelated issue was found while testing, this time with paste.  The problem occurs when there is a selection, and some text is pasted over the selection, replacing the selected text.  Sometimes, the screen does not update correctly where part of the selection remains.

This can be seen by first copying a single line (some characters followed by a new line) into the clipboard.  Then selecting from the middle of a line to the end of the next non-empty line.  Pasting at this point places the cursor at the beginning of the second, the first character on the second line is removed from the screen, but the rest of the line remains and appears selected.  The document is properly updated as can be seen in the program view.

This problem was corrected by reimplementing the paste function (again).  This time it was given an argument for the clipboard mode with a default of clipboard.  The current text cursor is obtained.  If the cursor has a selection, it is copied into a temporary cursor.  With this temporary cursor, the selection is cleared and the edit box text cursor is set to the temporary cursor to applied the cleared selection.  This may not be the best way to solve this issue, but several other attempts did not work and this solution did.

The selection remains in the origin cursor.  The text is then obtained from the clipboard for the clipboard mode selected and inserted using the original cursor (replacing the selection if there was one).  To also correct the middle-click paste, the insert text call with the current text cursor was replaced with a call to the reimplemented paste function with the clipboard selection mode.

[commit 0ef619bc5c]

Thursday, March 21, 2013

Handling Shift+Enter Correctly

Testing continues and no new problems have be found so far.  However, an unrelated problem was discovered with the Shift+Enter key sequence.  When there was no selection, a Shift+Enter behaved liked a regular Enter, either moving to the next line or entering a new line if the cursor was at the end of the line.  But if there was a selection, a new line character was inserted in the middle of the line.  This was evidenced because no line number was displayed including in the program view, which is the same as for a long line.

Normally, the plain text edit widget allows the insertion of a new line with Shift+Enter (like word processors).   The reimplemented edit box key press event handler partially changed this behavior, but the old behavior remained when there was a selection.

I decided to make a Shift+Enter behave as extending the selection (or starting a selection if none is present) to the beginning of the next line.  This is the same as when holding the Shift with other movement keys (arrows, Home, End, etc.).  There is no reason to allow new lines to be inserted in the middle of program lines.

This was corrected by incepting the Shift+Enter key sequence first.  The same moveCursor()  function is called with the same NextBlock move operation, but instead of using the default MoveAnchor move mode, the KeepAnchor move mode was added, which extends (or starts) a selection.

[commit 32149da677]

Tuesday, March 19, 2013

New Line Detection Correction

The next problem discovered occurred when a multiple line selection was replaced with less lines than the selection and the cursor was at the end of the line after the change.  The lines removed were not being reported as deleted, in fact nothing was reported.  This was in the same section of code as the first problem, but this time the problem was caused because the modified line is new flag was being set when it should not have been.

As described on March 6 (second paragraph), an earlier fix added a check if characters were added when the cursor is at the end of the line to set this flag.  However, for this case, both of these conditions were true, so that flag was wrongly set.

Instead of checking if characters were added (which catches some of the wrong conditions), the code was changed to check if lines were added to the document, which was accomplish by checking if the local net line count variable is greater than zero.  If lines were deleted, or no lines were deleted or added, then this flag is not set.

[commit dea0ef4951]