![]() HTML PLAIN reference V1.1 4. The graphical user interface ![]() |
![]() ![]() ![]() ![]() ![]() Next: 5. Example and test Up: HTML PLAIN reference V1.1 Previous: 3. Parsing the documents Subsections
|
|
This editor basically reads a file with Perl assignments in the form
All assignments with the structure mentioned above are shown as ``Setting/Value'' in a list with two columns. Because the name of the setting is read only and the number of the settings is fixed, the front end is quite simple. It allows the right hand columns to be changed, but not the left hand ones. Due to the fact that no entries can be deleted or inserted, it is also easy to add the comments again when saving the documents, and fit in any other lines that did not contribute to the settings.
This was the first one of the series of configuration tools I wrote. The design
is very basic; the only tricky component are the two linked list boxes. Even
though it is extensively covered in [Wel97, pp. 513 ff.], the implementation
given there is not completely bug free, and lacks any keyboard support. It tried
my best to improve it, but there are still a few occasions where the two list
boxes do not cooperate as expected - and it seems to be impossible to fix that.
This screen shot (as any other screen shot) has been taken under WindowMaker. It shows the configuration editor. The settings are shown to the left, their values to the right. As soon as a user selects on a setting (or its value) either with the mouse or with the keyboard, it appears in the upper part of the window. The first entry is read only, so the cursor will appear just at the second part where the setting can be changed. The comments in the script file are used as status messages in the program, in order to provide the user some guidance for selecting the correct setting.
The user confirms the changes with [Return] or by pressing the ``Ok'' button. The change can be canceled by pressing [Esc] or selecting a different entry. The ``Reload'' button (later renamed to ``Revert'') reverts the changes back to the state of the last saved file.
Implementing the spreadsheet-look-alike required using the Tk canvas, which allows the free placement of a wide range of widgets. Implementing the scrolling is surprisingly simple, and the example given in [Wel97, pp. 411 ff.] could almost directly be used in the actual program. However, there were again some subtleties and problems that were not covered by the book.
First, it seems to be impossible to make the text entries in the canvas object scale if the window size is changed. The canvas grows or shrinks with the surrounding parent window, but the size of the entry widgets is always the same. The book did not provide any hints on whether this can be implemented or not. The only solution that worked was to choose a generous size for the entry widgets and then disabling horizontal resizing, which is of course not a very nice solution.
Second, keyboard traversal and focus behavior were again not covered by the example, but because using a canvas yields a much cleaner implementation than by trying to make two list boxes cooperate, it was not hard to implement that.
The user can again select the entry that he wants to change with the mouse or the keyboard. Alternatively, he can press [Insert] or [Delete] in order to create an empty entry or delete an existing one, respectively. An ``Undo'' operation has been added in order to provide recovery from accidental deletions. The program also checks whether a changed or new entry collides with existing ones (since no two variable names may be the same).
Unfortunately, tracking the position of comments that go over an entire line is quite difficult when entries are added or deleted. Therefore, the method that loads the file stores these comments in a separate list and inserts them all at the beginning of the file when it is saved. This mangles the order in which the comments were inserted. It is recommended not to use comments that go over an entire line or multiple lines, and indeed this option is not allowed in the editor, which only allows the insertion of comments at the end of a definition. This should be all right in most cases, as comments that go over an entire line are commonly only used at the beginning of a file (e. g. for copyright notes).
In order to save some typing when the user wants a WWW color (one out of 216 colors whose R, G, B values are multiples of 0x33) or a filename (e. g. if he wants to refer to a non-HTML document), two dialogs ``Insert Color'' and ``Insert Filename'' have been provided. They can both be invoked with the right button, in which case a pop-up menu appears. (On Mac computers with one button, a modifier key has to be pressed together with the mouse button for getting the same function.) The filename selection is not worth further description, because it just uses the given Tk dialog
tk_getOpenFile. The color picker has been rewritten from scratch, though.
There are two color pickers that ship with the standard Tk libraries. One is the
tk_chooseColor dialog, which belongs to the Tk library and is available through a simple library call. That colorpicker is quite small, fast and simple, but it does not help the user in choosing a color that is compatible to the standard 216 color palette. Another disadvantage is that only the colors that are derived from the current RGB value by changing one number of the (R, G, B) triple are shown. It is therefore not always easy for a user to imagine which slider he has to move in order to end up with the color he likes, especially not if he is not familiar with the RGB model.
Therefore I tried to improve the other given color picker which is commonly found under
/usr/lib/tk8.0/demos/tcolor or a similar name. That color picker supports the RGB, CMYK and HSV models and also shows a large number of predefined color names. This may sound very appealing (especially for professional artists). However, there are some serious drawbacks:
Therefore I decided to write a new color picker from scratch, which does not have any of these disadvantages. The user can conveniently select one of the 216 colors directly with the mouse, or enter a numerical value (in which case the color that matches the entered one best is chosen from the graphical representation). The rectangle to the lower left always shows the exact chosen color. The only disadvantage with this color picker is the fact that drawing all 216 colors in the first place takes a while under Tk, but the delay is acceptable (roughly one second, probably less with fast CPUs).
The template editor has almost exactly the same functionality as the variable editor; therefore, the two programs share most of their code in a module called
common.tcl. The major difference between both programs is the fact that tag redefinitions can span several lines; therefore the parsing of the file structure and the user interface become a bit more complicated.
One of the more outstanding features of the template editor is syntax coloring. This could be relatively easily achieved in tcl/tk, because the text entry widget supports ``tags'' which allow to change the style of a certain part of the text very easily, and also ``marks'' which enable the programmer to keep track of certain parts of the text, independently of absolute locations.
Of course the algorithm for the easy recognition of the portions of the text that need to be highlighted still needs to be written. I use the following approach: Every keystroke is ignored, except for the few special keystrokes which either delete a character or add one of the syntactically important ones, being
"<", ">", "&", ";" and the double quote itself. For other texts than HTML, this could of course be extended. For HTML entities between "&" and ";", the action to be taken is quite simple: if there is a closing ";" within the current line, color everything that forms the HTML entity, otherwise use a warning color indicating a syntax error. The same goes for HTML tags, even though they can span multiple lines. However, for clarity and simplicity, this is not allowed in the template editor.It soon turned out that just having some special code for each one of the delimiters of a symbol may be fast, but would soon lead to rather messy code. This is mainly because the deletion of such a character can yield to many possible states. E. g. the deletion of a
"&" sign can be in one of the following situations (the underlined "&" gets deleted):
Therefore, the whole line has to be parsed when a character changes. This can be speeded up by only doing that when one of the delimiters of a syntactic entity is added or deleted. For HTML, these symbols are
"<", ">", "&", ";", "!" (for comments) and the double quote. If such a symbol is typed, the whole line is parsed and colored.Deletion of a character is still a special case, because two lines may be joined. However, this was not much of a problem. For similar reasons, [Return] has also to be treated specially, because it separates two lines.
In the implementation, the default handler is carried out after the supplied custom handler. This means that if the user types a character, the custom handler is carried out before that character is actually inserted into the buffer! This is of course not acceptable for an editor with syntax coloring, since the true text is always known one keystroke too late. Fortunately, the order in which events are processed can be changed by the
bindtags command. This allows to override the ordering in which the handlers are carried out.However, if the default handler is carried out, we run into a problem when a character is deleted. Because the character is removed from the buffer before our handler is invoked, we can no longer find out which character was actually deleted. Therefore the only solution is to have our handler executed first and then execute the default handler. If our handler is called, we have to insert the typed key ourselves, in order to have an updated buffer. Of course we have to suppress the default handler in that case, since this would result in having every character inserted twice. The current implementation overrides the default handler for all special characters (the delimiter symbols, backspace, delete and return) and does not allow the default handler to run in these cases. For all normal characters, the default handler does the job of inserting the character.
The procedure for coloring a line of text is not too complicated. A regular expression search shows us the first occurrence of a delimiting character, in which case we look for the character that ends the entity. In the case of an HTML tag, whenever we see a
"<", we look for the closing ">" and color all the text between the two angular brackets (and the brackets itself) with the appropriate color. This can be easily achieved by using Tk ``tags'' for changing the appearance of text (see Section 4.5.1). We have to take care to delete all existing tags in a line first, before re-tagging that line.Because different syntactical entities may occur within each other (e. g. a quoted string within an HTML tag), the procedure is recursive. Usually it is not allowed to have a different kind of entity within another one (e. g. a quoted string within an HTML entity), in which case we indicate this syntax error with a special color.
Due to the simple pattern matching used, the syntax coloring is not perfect and cannot detect all mistakes. E. g. if someone types
Other than the replacement of the simple entry widget by a more sophisticated text widget with syntax coloring, there are few differences between the template and the variable editor. The possibility to insert colors or filenames directly into the text has been omitted, because this should be done in the variable editor. The idea is that the user defines a variable for each color used, in order to be able to change that color more easily later on. This variable can then be used in several places in the template.
Of course the file format is slightly different, which leads to a different parsing method for loading the files. Namely the line spanning tags and C comments were tricky to handle. Because Tcl's regular expressions are not quite as powerful as Perl's, only C comments which go from the beginning to the end of a line are allowed. Since C comments are only used by people who edit the file directly in ASCII mode, this should not be a problem. The template editor also inserts all long comments at the beginning of a file when saving it, thus having the same minor restriction as the variable editor.
In order to allow easier testing by as many people as possible, a small demo program is provided that launches all the other programs so the user does not have to remember which
.tcl files to use.
I first tried to find some testers via freshmeat |http://freshmeat.net/| (a page that announces many newly released software, mainly Open Source software for Linux), and there were indeed many people who downloaded it during the time when it was visible on the front page (about 40 people per hour during about five hours), which is quite surprising, because I did not release the back end yet, so the program did not actually do anything useful at that stage :-)
However, I did not get any feedback either. Probably no one cared that much about a simple Tcl/Tk user interface in order to help me to improve it. Therefore the next release would include the back end and all required documentation. And indeed, I got a little feedback, which proved quite useful - mainly for improving the documentation.
Next: 5. Example and test
Up: HTML PLAIN reference V1.1
Previous: 3. Parsing the documents