2005/12/10 pjm
* I have been so derelict in keeping this log up to date. Not that I haven't been working on farVIEW, but, with the zero interest in it by anyone else, I have not bothered to say anything here. This entry will only cover what I can think of as I write this. There are many improvements and bug fixes that I simply have forgotten.
There are some new farSlang modules. In fact, the reason I am adding this note is because I just finished coding a module that helps play the Sudoku game. It has a number of features, including a pretty comprehensive, but simple, hinting algorithm. It can also save alnd load games.
I had promised myself that I wouldn't play Sudoku, but I had a few minutes a couple of weeks ago, and there was a game published in a magazine. So, I tried it. But as I played the game, I couldn't resist designing a farSlang implementation of a Sudoku Sidekick. I just finished the code for it a couple of hours ago. The module came to about 700 lines, including comments, which is the largest farSlang module I have written for the new engine to date. As a side effect, I removed some farVIEW bugs, and made some improvementsas well. I have included the source file for sudoku.far in this release. I think that I might code a few other simple games as time goes on.
Since the date of my last log entry, I have added or improved about 20 farSlang modules. The only documentation available for them, though, is in the modules themselves. Some highlights are
send.far and recv.far make up a topic mail system that you can use with other farVIEW users to share topic trees using drag-and-drop. You need to know their URLs or IP addresses to use this, and they have to agree to the relationship.
export.far and import.far comprise a simple rebuild system that converts a farBook into a text file containing a list of XML documents, one for each topic. The list can be used to build a new farBook or any part of one. The output can be emailed, of course, since it is just a text file. That's if you don't want to use the send/recv modules, for which some assembly is required.
indexer.far indexes part or all of your farBook so that farVIEW can provide full-text searching when you select the Files/Search menu item. The cool thing from an implementation point of view is that the indexing process builds another supporting farBook that contains only keys and links into the primary farBook. As part of the index and search process, there is a text file, called stop.wds, in the farVIEW directory, that lists the words that the indexer should ignore. There are a number of stop word lists on the internet, and you can make your own. Another farSlang module, words.far, can help you in this. As far as stemming is concerned, I am using an algorithm by Porter posted on the internet at http://www.tartarus.org/~martin/PorterStemmer: "This is the Porter stemming algorithm, coded up in ANSI C by the author. It may be be regarded as cononical, in that it follows the algorithm presented in Porter, 1980."
http.far implements a bare-bones HTTP server.
download.far will download a file from a specified URL
login.far is intended to provide a security frontend, but there isn't any backend as yet, so it is just good as an interesting code sample for now.
To run these modules, you first start up farVIEW, then select the farSlang/Run menu item. If you make changes to the code, be sure to also pre-select the farSlang/Debug menu item. That will make sure that the farSlang compiler recompiles the module before running it. There is a command-line way to run a farSlang module, but it still has some wrinkles, and I will upload more about that when it works properly.
While I am having fun writing farSlang modules, the reason I am including them in the farVIEW releases is to provide others a modicum of information about how to write farSlang. There is a HTML manual in the website subdirectory, and on my website, but it doesn't tell you how to interface to the farVIEW library, which is now up to about 3380 APIs at this point.
BTW: the APIs are listed in the farslang.xml document, which comes with the release.
This entry was entered using Amaya 9.2.2., which will take me some getting used to.
My wife is a case manager in the health industry, and works from home. She has an enormous amount of paperwork that she has to do, and I have been wanting to help lighten her load for months. Yesterday, I finally decided that farVIEW should be ready for her to use. The farBook that I envision will let her organize the names of the many people and organizations she must deal with, provide tools to generate and track the many documents her company requires, help her track her billable hours, and spin off directory and location information for her handheld for use in the field. A tablet would be a great platform for this application. Other functions will certainly come to mind as the project unfolds. There are products that do these things, but, by using farVIEW for the application, I get the added benefit of cleaning up bugs; and I know how to expand this tool as she needs features that other tools would not provide.
Here is the basic shape of the farBook:
Home
Activites
To
Do
People
Clients
Lawyers
Physicians
Tools
Documents
As she gets new clients, she will add new topics, one for each client, to the Clients topic. She will do the same for new Lawyers and Physicians. As activities and materials accumulate for each person, she will collect them as children of the corresponding topics. I wrote a farSlang module that is to be run by the Clients, Lawyers, and Physicians topics when the People topic is expanded. To keep them in order, she will set the title of each topic to the name of each client, last name first.
This farSlang module contains an event handler for the onAddChild event, to be run whenever a topic is added to the Clients, Lawyers, or Physicians topics. This event handler copies the form property from the parent topic to the new child topic, and it copies the contents of the parent topic to the new child topic. This sets up each new child so that its content is displayed through an appropriate form, rather than just an unstructured sheet.
Here is the code for the farSlang module:
module parent
glb System: CSystem
proc
addChild?
--
event
handlers
must
be boolean!
var
parent := System.Topic
var
child := System.DragTopic
--
Copy
the
form
name
child.SetForm(parent.GetForm)
--
Copy
the
parent
body list to the child
child.SetBody(CStrList(parent.GetBody))
--
Allow
to
add
the child to the farBook
return
false
endProc
addChild
System.Topic.SetEventContext(System.FarSlang)
System.Topic.SetEventModule('parent')
-- name of this module
-- Link the topic
onNewChild event to the onAddChild handler proc
System.Topic.SetEventProc(System.Topic, onAddChild, 'addChild')
endModule parent
Not a lot of code, but, then, it doesn't need to do much. Note that farVIEW sends the onAddChild event after it has constructed an in-memory topic object, which includes a manifest and possible content, and before it has written the topic information to the farBook. Had the event handler returned true, the topic would not be written to the farBook.
In writing and testing this bit of code, along with the form, which I had adapted from the Patient form, which is in the install, I found several bugs in farVIEW, which I fixed. Most important was that farVIEW didn't save the data that was entered into a form. That was a big one.
While I don't have much to say at this point about the Activities topic, the Tools topic is intended as a "tear-off" TOC so that she can drag-and-drop individual person topics onto specific document topics. The farSlang event handler for the onEndLMBDrag event could then copy the document file to a work site, maybe use Word/Excel objects to fill in the person-specific information, then start Word or Excel so she can finish the document. It could also add a child to the person topic for that document so that she can later access the document easily. I haven't done this yet. The function will probably be implemented using JScript as well as farSlang, since farVIEW doesn't have the ability to access MS Automation objects yet. Would be very nice though.
I've written this to give an idea of how one might develop an
application using farVIEW. I'm a bit on the sloping side of the
learning curve, myself, and the project will be ongoing. I may
have more to say in a later entry.
With this release of farVIEW. I am introducing a new national pasttime: Xtump the Xhump. Here's how it's played:
So, you may gather from the above that this release of farVIEW includes pretty much the full rendition of XPath 1.0 according to the W3C Recommendation dated 16 November 1999. Note that the CNode version has been removed from farVIEW.
Here is a list of the current XPath to-do's and limitations:
The spec-version of XPath is almost completed. The code is virtually complete, and I am testing it now. This is a part-time endeavor so it does take more time than I would like. I have added an additional API to the two described below. The Evaluate() API allows to use the XPath processor to obtain results as booleans, numbers, strings, or nodesets.
CXPath.SelectSingleNode:CNode(node: CNode,
path$)
CXPath.SelectNodes:CNodeList(node: CNode,
path$)
CXPath:Evaluate:CXPathItem(node: CNode,
path$)
The CNode versions remain in the farVIEW build for now until XPath is fully debugged.
Here is a farSlang module showing how to access the results of a CXPath:Evaluate call:
module sample
-- Load an XML document
var dom := CDocument
dom.Load('data.xml')
-- Create an XPath object and use it to evaluate
an XPath expression against the XML document
var path := CXPath
var item := path.Evaluate(dom, XPath_expression)
-- Make sure the results are valid
if not valid(item) then
CMessageBox("XPath Test - No
Item Returned", "Error = " + path.Error, FWW_ATCENTER |
FWW_OK).Run
-- Handle the nodeSet (in a CNodeList object)
returned by the evaluator
elif item.Type = XP_NODESET then
var nodes := item.NodeSet
-- Check for no nodes found
if nodes.Length = 0 then
CMessageBox("XPath Test - Nodeset Returned", "Empty",
FWW_ATCENTER | FWW_OK).Run
else -- Show the first node
found
var node :=
nodes.Item(0)
var txt$
if
valid(node) then
if
node.NodeType = ELEMENT_NODE then
txt
:=
'<'
+
node.NodeName + '> (' + string(nodes.Length, 1) + ')'
else
txt
:=
'<'
+
node.NodeValue + '> (' + string(nodes.Length, 1) + ')'
endIf
else
txt
:= 'No match for <' + exp + '>'
endIf
CMessageBox("XPath Test - Nodeset Returned", txt, FWW_ATCENTER |
FWW_OK).Run
endIf
-- Handle String returned
elif item.Type = XP_STRING then
var val := item.String
CMessageBox("XPath Test -
String Returned", val, FWW_ATCENTER | FWW_OK).Run
-- Handle Number(type is %) returned
elif item.Type = XP_NUMBER then
var val := string(item.Number)
CMessageBox("XPath Test -
Number Returned", val, FWW_ATCENTER | FWW_OK).Run
-- Handle Boolean returned
elif item.Type = XP_BOOLEAN then
var val := string(item.Bool)
CMessageBox("XPath Test - Bool
Returned", val, FWW_ATCENTER | FWW_OK).Run
endIf
endModule sample
Added a new user command, called Cross, to farVIEW in the RMB drag and drop menu that performs a bidirectional link between the drag topic and the target topic. Not only does the drag topic become a child of the target topic, but the target topic also becomes a child of the drag topic. farVIEW currently allows the user to expand crossed topics indefinitely. Will probably put a stop to that at some point. If you have nothing better to do with your time, feel free to see how long it takes for farVIEW to die in that particular way.
Not much that's new except that the farVIEW download is now a real install file instead of just a zip file. The install program is set not to wipe out your working files if you have previously installed farVIEW. However, they are written to the backup subdirectory, in case you need them.
I'm using the Inno Setup Compiler, version 3.0.6 (b) by Jordan Russel. His homepage is http://www.innosetup.com. It is easy to use and more than enough for farVIEW's installation needs.
I am working on an implementation of XPath. This is a significant undertaking, but it's fun, and I am understanding the XPath spec a whole lot better than I did when I could have used the knowledge writing XSLT scripts a couple of years ago. I have written a parser that works fine on almost all the XPath examples in Michael Kay's book, XSLT Programmer's Guide, Copyright 2000, from WROX Press. I got the traversal code for 12 of the 13 axes written last night (no namespace axis, which the farVIEW DOM doesn't yet support anyway).
Added a System.Parameter$ property. This supercedes the discussion below (2003/02/26) about how to obtain the call parameter from farSlang code.
The latest update to the download includes mostly bug fixes, but there are some issues of interest:
* Converted the preferences file (farVIEW.ini) from a conventional ini-file to an XML file. There is no DTD or schema for it. The DOM code is working well.
* Added two methods (borrowed from MSXML) to the CNode class to support a stripped-down version of XPath:
CNode.SelectSingleNode:CNode(path$, extend?)
CNode.SelectNodes:CNodeList(path$)
The extend parameter, when true, makes sure the specified path exists, even if it didn't before the call. This may prove troublesome later, but for now it is very convenient.
One of the limitations (a very big one) is that predicates are always true. The general form of what is supported is something like the following:
path ::= [ "/" ] [
"/" ] step { "/" [ "/" ] step }
step ::= [ axis ::
] nodetest [ "[" predicate "]" ]
axis ::= "ancestor"
|
"ancestor-or-self" |
"attribute" |
"child" |
"descendant" |
"descendant-or-self" |
"following" |
"following-sibling" |
"namespace" |
"parent" |
"preceding" |
"preceding-sibling" |
"self"
nodetest ::= nodename |
"@" attributename |
"*" |
"node()" |
"text()" |
"comment()"
nodename ::= attributename | elementname
predicate not supported.
This is nowhere near what the XPath spec allows. You can read tutorials at various XML sites for how XPath works, just remember that predicates are always true in farVIEW for now. It was still useful in getting values in and out of the preferences document.
* Changed the names of the colors in the Forms Color= and BackColor= attributes to not use the programmer's FWG_ prefix.
* Added farSlang event handler support to the widgets that make up the Forms subsystem.
* Added the user ability to mark text in the text window using the right mouse button and choose to associate the marked text as a keyword or keyphrase to the topic for use with the search function.
* Added the System.Menu:CMenu property. (See also, 2002/04/01 below) This property is valid when handling OnRMBUp events and references the RMB context menu. The farSlang event handler can modify the menu before it is displayed. I'll publish more on this later. (Like an example would be good, Paul.) The System.Menu property is also valid when handling the OnEndRMBDrag event and references the RMB drag-n-drop menu. Note that the content of these menus depends on whether the drop target is in a text window or a TOC window. You will find the methods to manage menus in the classes CMenu and CMenuItem enumerated (but not documented) in the farSlang.XML file. That's all that is available for documentation at this time. A forthcoming example will provide some how-to.
* Cleaned up the farSlang run capabilities of topics. You can now use the Source and Run topic manifest properties to run farSlang code. Which of the two properties you use determines when the farSlang proc is executed: when you use the Run property, the specified farSlang proc is run (after compilation, if needed) when the parent of the topic is expanded. When you use the Source property, the proc is run (again, after compilation, if needed) when the topic is opened by, for example, double-clicking the topic with the mouse.
These two moments in the visible life of a topic are important opportunities for an enterprising topic.When a farSlang proc executes as the topic is instantiated during parental expansion (the Run property), it gives the topic an opportunity to "arm" itself to handle possible incoming events for the remainder of its visual existence. This allows the topic to become an active participant in the farVIEW session. On the other hand, when a farSlang proc executes when the topic's content is accessed (the Source property), the topic can exhibit deviant behaviours in lieu of presenting its content. Note that you can suppress farSlang execution by checking the farSlang/Ignore Events menu item on the main menu bar.
BTW: none of these things happen when farSlang code loads a topic into memory.
The Run and Source properties can contain a farSlang proc invocation specification of the form:
"|" modName "|" procName "|" parameter
where
modName is the name of a farSlang
module
procName is the name of a visible
parameterless proc within the specified module
parameter allows you to pass a string
to the proc.
Be sure to use the vertical pipes before each field as needed.
The procName and parameter fields are optional, in which case only that part of the module code that is outside any proc is executed. If the procName is specified, it must reference a proc that is visible (no tilde (~)) and has no parameters. If the parameter is specified, the farSlang runtime stores the parameter value in a global, called parameter$.
When a parameter is specified, farSlang code can access the global after first declaring it, as in the following example:
module sound
glb System: CSystem
glb Parameter$
CSound.PlaySound(System.App, Parameter, "", 0, FWA_SYNC, 0, 0)
endModule
(Note that there is no error checking in this example, so it would be good if the parameter contains the name of a wav-file.)
When the farSlang proc relinquishes control back to farVIEW by exiting, the module can no longer count on the value of the Parameter global, since it may be reused when running other modules later. If you need its value for event handlers later on, copy it into a module variable as in this fragment:
glb parameter$
var myParameter := Parameter
The following would invoke the sound module shown above when the parent of a topic is expanded if in the Run property, or when the content is accessed if in the Source property::
"|sound||sound2.wav"
assuming there is a file called sound2.wav in the farBook directory. Note the empty procName field. See the sample in the Forms farBook.
With the functionality now available to farVIEW topics, we can soon start creating topics that act as waystations, community centers, postoffices, newsposts, auctioneers, mailboxes, and other message-handlers. A topic can now remain passive, or become an active participant - an agent, if you will. For example, soon, you will be able to drop a file or topic onto a mailbox topic and expect a correspondent to receive the dropped information (or a link to the information) over the internet or LAN.
Ok, it took a little over a week to get the forms cleaned up (see previous entry). And, they still aren't cleaned up since I completely rewrote them as platform-independent widgets as children of the CFormWindow class. The new forms subsystem has been (is) a major project. I could spend all my time adding more and more widgets. The popup menu and combobox widgets are the most needed at this point.
There are a number of sample form files (look for *.frm files in the main farVIEW directory.) Not all of these work, and some of them may cause farVIEW to bomb, and a couple of them appear not to do anything.. But there is a fair amount of XML in the .frm files for examples. There are a few problems and bugs remaining, but, generally, they are pretty clean. As an exercise, you can play with the patient.frm data-entry form and polish up the elements in the second tabpanel. I have already done the elements in the first tabpanel as an example.
I have added a couple of nice farSlang modules that demonstrate how to handle the onPaint event: edges.far and shades.far. Try running them through the farSlang menu (farSlang/Run/ModName: "edges"/Ok), and also look over the code using the forms farBook. The samples show how easy it is to handle events in farSlang. Also, there is the dateTime.far module to demonstrate the use of the CTimer object.
Over time, I have noticed a few little show-stopper bugs in the text editor and in the tear-off topic window facilities. I need to fix these, but they have been elusive to pin down.
There are small sample farBooks in the release: sample.vue and forms.vue. Make shortcuts that run them using a command line like
c:\farview\farview.exe sample.vue
or
c:\farview\farview.exe forms.vue
For peculiar reasons, you can't run farVIEW from a command line. I'll work on this sometime.
I have not made a release of the farVIEW program since April. I did virtually no work over the Summer, but this changelog does reflect what I am currently doing. I intend to make a release as soon as I clean up the forms. That should be within a week or two, as long as my interest holds up.
An aside: a big problem with doing a project like this off in the boonies is that there is no dialog, just a monolog with myself. I don't know how to get any attention for this project. I don't want to make it Open Source for a variety of reasons, at least for now, but I would love to have feedback. I guess the fact that it isn't OS would leave Slashdot out as a possible venue. But it is free. I haven't tried. I think I hesitate because there is "always one more thing" that needs to be done before I could possibly consider it worth presenting to others. (other than my friends, of course)
The rest of the TBD list here will be for the next release, or so.
* TBD (New section - I'll try to add a TBD to keep some focus on where I'm heading)
* Added tabbed windows. Using a tabbed window in a form, you can construct an organized presentation of lots of information. The tabbed window actually comprises five different window classes:
* Added support for the fars and cache directories. The fars folder is created by the pkunzip install while the cache folder is generated by farVIEW when it is needed. Be sure that you choose to install all subdirectories when you use WinZip to unzip the package file.
* Fixed the compiler to correct an error in allowing functions and constructors to be used as procedures and dot-operands as in
System.Body.GotoHead
(Body is a "getter" function and GotoHead is a boolean function)
CSound.PlaySound(System.App, "c01a015h.wav", "", 0, FWA_SYNC, 0, 0)
(CSound is the default constructor (i.e., no parameters))
* Found a situation when the compiler under-calculated the maximum size of the stack because of the way lbj instruction was back-patched over a pre-generated nix instruction at the end of parsing a procedure call. By the time the lbj was back-patched at the end of the parse, the running size of the stack was smaller that its maximum due to expression parameters. I decided to increase the stack size on the nix instruction even though it might later prove to create a slightly larger stack than is absolutely necessary. The following code caused the problem.
CMessageBox("title", "message",
FWW_ATCENTER | FWW_OK).Run
insts: nix
lstr
lstr
lit lit
sz1 =
0
1
2
3
4
\___opi____/ lbj
3
4
=>
4
(too
small
by one entry)
sz2 =
(1)
2
3
4
5 5 => 5 (just right)
\____4_____/
sz1 = old stack height calculation, sz2 = new stack height calculation. I used to ignore the nix (no-operation) and count the lbj (load object). Now I count the nix and not the lbj, since I can't trust the stack height by the time the lbj comes into play.
* Found that the interpreter pushes doubles and strings onto the stack without deleting them afterwards. Big memory leak. Fixed this by adding delete[] statements to the library interface routines in farslang.inc. But I still need to check out other types of calls, such as inter-module calls, and farslang class calls.
* Added remote file support with a new class: CRemoteFile, which is derived from CFile. This class handles remote files by copying them to the local cache (OpenInput, OpenAppend), then opening the cache copy for local file operations. When the file is closed, it is sent back to the host (OpenAppend, OpenOutput) as needed. Also added two methods (SendFile, ReceiveFile) to transfer between the local machine and a host machine. Added two new host commands: SF (sendFile) and RF (receiveFile), which are implemented in CServer. These commands support files that are larger than the transfer buffer size (32k).
* Added CFile::NewFile() static method to examine the file name and construct the appropriate CFile or CRemoteFile object.
* Added a CSystem object, called System, for farSlangers to access the current farVIEW environment as a global. Access System with the following global declaration:
glb System: CSystem
You can then access various farVIEW objects as properties of System.
System.App:
CApplication
-- farVIEW application object
System.Args:
CArgs
-- command-line arguments object
System.Book:
CBook
-- active farBook object
System.BookName$
-- active farBook name
System.BookPath$
--
path
to
the
active farBook
System.CachePath$
--
path
to
the
cache folder
System.Comm:
CComm
-- communication interface object
System.CommBody:
CAtom
-- received message body (server)
System.CommHeaders:
CStrList
-- received message headers (server)
System.Console:
CConsole
-- console window
System.CurrentPath$
-- ???
System.DragTopic:
CTopic
--
valid
only
after
a drag operation
System.Event:
CEvent
--
valid
only
after
a received event
System.ExecPath$
--
path
to
the
farVIEW executables folder
System.FarsPath$
--
path
to
the
farSlang library folder
System.FarSlang:
CFarSlang
-- farSlang environment object
System.ParentTopic:
CTopic
--
parent
of
the selected topic
System.Prefs:
CPreferences
-- farVIEW.ini object
System.RootTopic:
CTopic
--
root
topic
in
the Contents window
System.ServerIP$
-- farVIEW server URI (TBD)
System.ServerPort#
--
farVIEW
server
listener
port (TBD)
System.SessionID$
--
ID
of
server
session (server only)
System.TargetTopic:
CTopic
--
valid
only
after a drag operation
System.Topic:
CTopic
-- selected topic
System.UserName$
-- farVIEW user name
System.Window:
CWindow
-- active window object
-- Factory-type object builders
System.NewFile(fileName$):
CFile -- Create a CFile object for
a local or remote file.
--
The
fileName
of
a remote file begins with either
-- "http://" or "far://".
System.NewBook(bookName$):
CBook -- Create a CBook object for
a local or remote farBook.
--
The
bookName
of
a remote book begins with "far://".
System.NewWindow(parent:
CReceiver, -- Create a CWindow object based on the
type parameter.
windowType#,
rect: CRect,
attr#,
title$)
Note that all System properties are read-only for farSlangers. To use a System property object, you have to look at the documentation for it, which is pretty scarce at this point. The best I can suggest for now is to look at the files farslang.sym and farslang.xml. The XML file will eventually become the source for an online farSlang library document, since it is automatically generated, and it encompasses the entire library; but it currently lacks natural-language descriptions of the interfaces. This may make using the library very difficult for now. I will turn my attention to this problem in the near future.
* Converted all XML server far commands to the form:
<fareq op=".." user".." ... />
This will allow me to hide all command information in the body, which will eventually be encrypted and authenticated to help eliminate(?) spoofing, etc. Note: all is plaintext for now.
* Added a new window called CFormWindow to act as the primary window in a form-controlled display. It derives directly from CWindow and adds an onEvent method to deal with scripting events. See below.
* Added farSlang event handling to farVIEW forms with a new element.
<script src="modName" />
modName must specify a local file.
The following is a list of the event attributes recognized as form events:
ONBLUR
the
window
is
losing focus
ONCLICK
the mouse was clicked on the button
ONCLOSE
the window will be closed immediately
ONCOMMAND a
command key was pressed
ONDBLCLICK the mouse
was double-clicked in the window
ONFOCUS
the window is gaining focus
ONINPUT
a key was pressed
ONLOAD
the
form
has
been loaded
ONMOUSEENTER
the mouse has entered the window
ONMOUSELEAVE
the mouse has left the window
ONMOUSEMOVE the mouse has
moved in the window
ONLEFTMOUSEDOWN the left mouse
button was depressed
ONLEFTMOUSEUP the
left mouse button was released
ONRIGHTMOUSEDOWN the right mouse
button was depressed
ONRIGHTMOUSEUP the right
mouse button was released
* Added a CSystem object as a farSlang global that provides a farSlang module with a source for the current state of the system. It contains a number of properties, such as references to the application object, the preferences container, the comm object, and the current book object, among other properties.
* Implemented CEditWindow::onEditCut, onEditCopy, and onEditPaste. Also added onEditClear, onEditDelete, and onSelectAll. Still need to add onEditUndo. Also implemented RMB menu for CEditWindow. Behaviour of RMB is same as Borland IDE, which is similar to Word 97, except that the latter does not obtain a context menu while the IDE and farVIEW do. In keeping with normal Windows behaviour, RMB no longer selects text in CEditWindow, it only pops the context menu.
* Fixed text wrapping problem for some edit commands in CTextWindow.
* Fixed bugs in CTextWindow update function (CFarVIEW::UpdtBody) so that it doesn't bomb and actually does the update it's supposed to.
* Fixed active window problem in CTreeWindow that caused the label popup to appear even when the window was not active.
* Added CRadioButton and CGroupBox to the family of windows in the farWin library. CCheckBox is the base class of CRadioButton. Included an ability to link a group of checkboxes and/or radiobuttons together by identifying them by a common keyword. Added a notification to CCheckBox to indicate that the state changed to on for a "linked" CCheckBox. Also added code to CWindow to handle the notification by setting the state of all other CCheckBox children to the off state. To summarize, to link a group of sibling CCheckBox or CRadioButton widgets together, simply give them all the same link string. That will cause their parent to turn off all the other children having the same link string as the child that was turned on.
* Revamped CAcceptDialog to support CRadioButton and CGroupBox. To use the groupbox, place a "G"-entry before the radio buttons to be grouped, and an "H"-entry following them. The radio buttons will operate in the one-on-only mode whenever they are placed within a groupbox in the accept dialog. See accept.far for how the Search dialog is constructed. Added ability to hide the title of an edit window. Add a "!" in the type field to hide the title. While the title will not appear in the dialog, it is still used to obtain the value of the edit window. See sample code in accept.far for an example of a groupbox and radio buttons.
* Added tool tips to CWindow. To add a tool tip to any window, simply pass the tooltip string to the window using the SetToolTip() method. To kill the tool tip, pass an empty string as the parameter. Also added "toolTip=" attribute to forms (~XUL) window elements.
* Continued work on the farVIEW Communications Library documentation with sample farSlang code to demonstrate how to implement a simple Remote Procedure Call.
* Uploaded a new farVIEW zip incorporating these changes, except for the RPC stuff. I'm finding some bugs in the farSlang environment initialization code that still needs to be resolved, so stay tuned on that. Generally, I have not tested the farSlang sample code that I am including with this release yet. I'll get to it soon. so just look at the farSlang as coding samples for now. You can try them but no guarantees.
* Uploaded corrections to Searching along with new dialog images
* Uploaded the farVIEW executable library as a zip-file to the internet.