Bugs and Problems with C++ TV version 2.00

This file deals with bugs and documentation problems in the first release
of Turbo Vision 2.0.  I expect that most of these problems will be fixed
in a later release so this file may not be pertinent if you have a later
release.

Some of these bugs are quite serious.  I know you're not going to want to
modify your TV.LIB file but, unless you do, you won't be able to effectively
use some of the new TV 2 features such as:

  Validators
  TMultiCheckBoxes in resources

Once you modify TV.LIB be sure an build
  cpprsrc.exe
  readrsrc.exe
and any other resource generating or reading file with the revised
tv.lib.

Here then is a list of problems I've found and some reported by others.


1. The setButtonState() function used to enable/disable individual
checkboxes, radiobuttons is undocumented.  Here's the definition from the
Pascal manual which seems to be correct for C++ also.

virtual void setButtonState(ulong aMask, Boolean enable)

Sets or clears the bits in enableMask corresponding to the bits in aMask.
If enable is True, and bits set in aMask are enabled in enableMask; if
enable is False, the bits are cleared.  If disabling individual buttons
produces a complete cluster of disabled buttons, setButtonState() makes the
cluster unselectable.


2. The documentation on TRangeValidator is either incorrect or very
misleading.  It seems to imply that setData(), getData() for a TInputLine/
TRangeValidator will transfer a long.  Actually, in the default case,
the data string is copied just like any other TInputLine transfer.  To
transfer a long, the voTransfer bit must be set in TRangeValidator::options.


3.  Color problem with disable checkboxes, radiobuttons
Symptom: When individual checkboxes, radiobuttons are disabled, they
have strange color combinations.

Fix:  Add the missing "x" in the palette definition for TCluster in
tcluster.cpp.

#define cpCluster "\x10\x11\x12\x12\1f"
                  "x" is missing----^

4. TMultiCheckBoxes problem in resource files
Symptom:  Make a dialog resource when the dialog contains a TMultiCheckBoxes
control.  When reading the resource, get a "Assert Error, ch == ']'" message.

Fix:  Name definition was omitted from dialogs.h.  In dialogs.h, add the
following in the TMultiCheckBoxes section:

    virtual const char *streamableName() const
        { return name; }
 
You can use the TCheckBoxes section immediately above as an example of how
and where to add these lines.  After making this change, you should recompile
tmulchkb.cpp and smulchkb.cpp.

5. ofValidate bug.
Symptom 1: ofValidate not set.  Data in TInputLine does not meet validation.
When tabbing to next view, get validation error message which you shouldn't
get when ofValidate is not set.

Symptom 2: ofValidate set.  Data in TInputLine *is* valid.  Cannot tab to
another view.

Fix: In tview.cpp, TView::focus(), change "if (result) ..." to:
            if (result)
                if ((owner->current == 0) ||
                     ((owner->current->options & ofValidate) == 0) ||
                     (owner->current->valid(cmReleasedFocus)))
                    select();
                else
                    return False;
This changes both the order of the conditional expression and an '&&' to an '||'

6. Double Selection Bug.
Symptom:  In a dialog (after making the above change), enter data in a
TInputLine (ofValidate not set) which does not meet validation requirements.
Tab to another view.  Hit "OK", and a validation error message occurs.  At
this point, *two* views are selected, the invalid TInputLine and the view
that was selected before "OK" was hit.  Tabbing now longer works correctly.

Fix:  tinputli.cpp, TInputLine::valid(), remove (or comment out) the

       owner->current = 0;

line.  This allows the select() on the next line to deselect the former
selected view when the new selection is made.

7. TRangeValidator bug.
Symptom:  Set up TRangeValidator with an acceptable range from a neg number
to positive number, voTransfer set.  In the dialog, enter either a blank or a
single '-' sign.  Hit "OK".  What happens at this point is unpredictable
(depends on what garbage is on the stack, I think).  Sometimes a validation
error is reported (correct) but often the dialog closes and a strange number
is transfered from the TRangeValidator.

Fix: tvalidat.cpp, TRangeValidator:: isValid(..), change the sscanf statement:

    if (sscanf(s,"%ld", &value) != EOF)  //<--change 0 to EOF



The following problems were reported by Eric F. Woodruff 72134,1150 on
the BCPPDOS forum :

TVALIDAT.CPP
------------
    There is a #define that overrides the toupper() function in this module.
The code used is incorrect and will cause any literal alpha characters in a
picture string to be converted to uppercase.  Alterations to the picture
string are not desired and a toupper() function should not modify the
picture string anyway, so it should be fixed as follows:

In TVALIDAT.CPP, line 31 is:

#define toupper(c) ( (('a' <= (c)) && ((c) <= 'z')) ? c += ('A'-'a') : (c) )

Change it to:
                                                       vvv
#define toupper(c) ( (('a' <= (c)) && ((c) <= 'z')) ? c + ('A'-'a') : (c) )
                                                       ^^^
                                 -------->>> Change the '+=' to '+' only!


    Secondly, TPXPictureValidator::picture() fails to include the comma in
its list of special characters so pictures with groups like
"M{iss,s.,r{.,s.}}" will fill in too much if auto fill is enabled.  For
example, typing "Ms" into a 4 character field with the above picture will
actually result in an auto fill of "Ms.," because it doesn't recognize the
comma as special and includes it in the fill.  The fix is as follows:

In TVALIDAT.CPP, line 574 is:

    while ((index < strlen(pic)) && !isSpecial(pic[index], "#?&!@*{}[]"))

Change it to:
                                                                     vvv
    while ((index < strlen(pic)) && !isSpecial(pic[index], "#?&!@*{}[],"))
                                                                     ^^^
                                       -------->>> Add a ',' to the string!



The following was reported by Pat Reilly [71333,2764] on the BCPPDOS
forum:


 Bug: TStringLookupValidator is not properly disposing of a TObject - its
deleting it instead of destroy()ing it, thus causing memory leaks.

 Fix: in TVALIDAT.CPP, line 797:

 void TStringLookupValidator::newStringList(TStringCollection* aStrings)
 {
  if (strings)
     /* delete strings;   Bug: change to: */
     destroy( strings );

  strings = aStrings;
 }
