[Omnis-Newsletter] Omnis Technical Newsletter

omnis-news-admin@omnis.net omnis-news-admin@omnis.net
Wed, 12 Jun 2002 16:45:19 +0100


 June 12th, 2002

========================================

UNSUBSCRIBE OPTIONS: You have been sent this email because you have directly
signed up for, or expressed an interest in receiving a technical newsletter
when you downloaded an evaluation of Omnis Studio, or registered Omnis
Studio via a magazine promotion. If, however you feel you have received this
email in error you can unsubscribe as well as change your subscription
options at www.omnis.net/newsletter.

N.B.  If you subscribed by checking a box on one of our forms, you will not
have received a password. You will need to submit your email address at
www.omnis.net/newsletter and select the 'email me my password' option on the
next page in order to receive this.

========================================

WELCOME!

Welcome and thank you for subscribing to the Omnis Technical Newsletter.
Published fortnightly, it is intended for Omnis developers of all levels and
experience, for those people evaluating Omnis Studio, or for developers
moving from a similar tool. We think you'll find the content both
interesting and useful for your Omnis development needs and hopefully it
will help you become more productive in Omnis application design.

This time round our OO guru Geir Fjaerli takes a break. In the main tutorial
part of this newsletter, David Swain delves into the properties of Masked
Entry Fields and shows how you can closely control how the user enters data
and thus provide greater integrity to your data.

You may find it easier to work through the exercises and examples in this
newsletter by printing it out before you begin.

CONTENTS:
-About the Author
-OzOmnis: Register before June 15th and save money!
-Hidden Masked Entry Field Properties, by David Swain
-oXML: Omnis to the Power X
-Let's get Technical...
-Copyright and Unsubscribe details


========================================

About the Author

David Swain is the founder and president of Polymath Business Systems, for
many years a leading provider of Omnis training. His expertise in Omnis
programming and his ability to make complex concepts understandable are
recognized throughout the worldwide Omnis community. His current schedule of
Omnis Studio training classes can be found on his web site at
http://www.polymath-bus-sys.com.


========================================

OzOmnis: Register before June 15th and save money!

Register for OzOmnis before June 15th and it will cost an all-inclusive
A$750. OzOmnis 2002 is the Australian version of the highly acclaimed
EurOmnis and AmerOmnis Omnis Developers' Conference organized for and by the
Omnis Developer Community. OzOmnis 2002 has been designed to give
Australian, New Zealand and South East Asian developers a chance to meet
face to face, to exchange experiences, to develop new ideas, and to get to
know the latest developments in the Omnis world.

The conference program includes such highlights as web client sessions from
Dr Caroline Wilkins, an introduction to XML by former RD consultant Jeff
Spicer, and Studio 101 sessions by respected Omnis trainer and author David
Swain.

The conference takes place August 10-13, 2002, at the Newport Mirage in the
northern beach area of Sydney Australia... So register at www.OzOmnis.com
now or before June 15th and save money!


========================================

Hidden Masked Entry Field Properties

In the movie "Spiderman", the publisher of the "Daily Bugle", J. Jonah
Jameson, suggested that people who wear masks must have something to hide.
Could this also be true of "Entry" fields?

There are two distinct aspects to an Entry Field and its properties: how
values are displayed and how values are accepted during data entry. Most
properties of Entry Fields are either "data entry" properties or "display"
properties.

This is also true of Masked Entry Fields - including the kinds of "masks" we
can apply. We have the "formatstring" property that defines a "display" mask
and the "inputmask" property that defines a "data entry" mask. Often only
one or the other is needed.


But there are a number of "Entry" Field properties apparently missing from a
"Masked Entry" Field - at least, according to the Property Manager. This
article explores six of them. These are very useful properties that I would
prefer to not be without. Some are "display" properties that have no direct
equivalent in the options of the "formatstring" property while others are
"data entry" properties that have no direct equivalent in the options
available for the "inputmask" property. Fortunately for people who think
like I do, these properties are still there! We just have to "look behind
the mask"...

Background

Consider what we use Masked Entry Fields for:

1) We may simply want to impose specific formatting on the values displayed
for a variable. (If the field is disabled so it can only display a value but
not accept data entry, this is the only item that applies.)
2) We may want to restrict data entry for a field to a specific format.
3) We may want to do both of these things with the same field (in which case
our "input" and "display" masks should "match" in some way).

For example, suppose we need a field that displays and accepts data entry
for a numeric variable whose values can become large. We may wish to impose
formatting that displays a thousands separator to make these numbers easier
to read. Since this is not an option of a standard "Entry" field, we must
use a "Masked Entry" field to get this functionality. So far, so good.

But what if we need to capture negative numbers with this field during data
entry? Suddenly we find that the field "doesn't seem to work right" anymore.
Sure, we can DISPLAY a negative value in the field if the associated
variable contains one. We can even assign separate display characteristics,
such as a different color or additional characters, for negative values
using the "section" options of the "formatstring" property, but the field
will beep at us if we attempt to ENTER a "minus" character. There are no
options (at least none that I know of) of the "inputmask" property that
affect our ability to capture negative numbers.

$negallowed

The property that is "missing" in this case is the "negallowed" property.
This is the property that allows us (or can be set to NOT allow us) to be
able to enter negative numbers. Normally a field whose "dataname" property
contains the name of a numeric variable only allows numerals to be entered.
(Non-integer variable names in the "dataname" property also allow a "decimal
point" character and the "floating point" subtype allows an upper- or
lower-case "e" that precedes an optional "power of ten" exponent factor.)
The "negallowed" property, when set to "kTrue", also allows the "minus sign"
character to be entered.

The "negallowed" property is a "data entry" property that has no equivalent
in the options of the "inputmask" property on which Masked Entry Fields
rely. In fact, we would not often use an "input" mask for a numeric field
because this mask requires character-by-character compliance and the range
of the numeric variable associated with our field may be broad enough that
we could not predetermine the number of digits to include in our "input"
mask. So we REALLY need that "negallowed" property!

The problem here is that while the "negallowed" property actually does exist
for a Masked Entry Field, it defaults to "kFalse" and we have no access to
the property through the Property Manager to change this. (Actually, each of
the properties discussed in this article probably defaults to an "empty"
value, since Omnis Studio apparently doesn't expect us to use them. This
"empty" value is interpreted as "kFalse" by Omnis Studio for those
properties where "empty" is not a valid option.) Since this property is
necessary for many numeric variables, we need to find a way to adjust its
value to "kTrue" for those cases.

All we have to do is change the property value through Notation. We can
either change the property value at the Class level or at the Instance
level. Here are some suggested techniques:

Changing the value of the "negallowed" property at the Class level will make
the most immediate sense to most Omnis Studio developers since it is done at
design time, becomes the value used by all instances of the design object
and then is forgotten. The process is very simple to do. If the name of the
field is "numberEntry", we first create a method line like this somewhere in
the Window class using the Method Editor:

Calculate $cclass.$objs.numberEntry.$negallowed as kTrue

Notice that we did not include parentheses after "$cclass" since we are
going to execute this code from the class itself, so we don't need to
"resolve" the reference as we would if we were to execute this method line
from within an instance of the class. (The parentheses won't hurt in this
case - they just aren't necessary.)

To execute this method line, we just double-click it in the Method Editor
and then click one of the "Step" buttons ("Step In" or "Step Over") or use
the keyboard equivalent. This executes the method line in Design Space -
that is, as a Code method within the Class. (Be sure to "Clear method stack"
from the "Stack" menu after executing the line so that Omnis Studio doesn't
remain in "method execution" mode!)

The property value has now been updated at the Class level. We can test this
by executing another method line in the same manner:

OK message  {[$cclass.$objs. numberEntry.$negallowed]}

If the property is still turned off, we will see a value of "0", but if we
were successful in changing it, we will see a value of "1". We could now
either comment out or completely remove this line of code as it has done its
job.

It doesn't matter where we put the line of code for execution within our
window class if we run it in this manner. It just has to be somewhere within
the Class in order for "$cclass" to have the proper meaning. We could also
have put this line of code inside an "On evClick" block of some clickable
object (like a pushbutton field), opened a test instance of our Window class
and clicked the object instance to execute the method. It's just a little
extra work to do it that way (and we have to remember the parentheses so
that "$cclass()" resolves correctly).

Whichever way we do this, our Masked Entry Field will now allow negative
values to be entered during data entry. The one difficulty with this, of
course, is that we can't tell by looking at the Property Manager how the
value of this property has been set. We will always have to query the
property through Notation to determine this as explained above. Perhaps we
can find some way of making this setting available for our inspection during
design time.

If we choose to forget about whether the "negallowed" property value is set
in the Class and focus on making sure it is correct for our purposes in the
Instance, we can have a way of effectively inspecting the "assigned" value
at design time. To do this, we will set the property value of the field as
it constructs in our window instance by putting the code that sets the
property value in the "$construct" method of the field (you will probably
have to create one) and letting it execute at runtime. This also shortens
the command line to:

Calculate $cfield.$negallowed as kTrue

In this case, we need the code to remain intact since it must be executed as
the window constructs. We can then look at this setting in the Method Editor
any time we want in Design Mode to see how we have chosen to set the
property. Granted, it's not as convenient as seeing the property and its
value in the Property Manager, but it helps our Masked Entry Field be less
"secretive".

This also gives us the option of setting the property value conditionally,
depending on other current settings within the application or some aspect of
the data being examined. Our "$construct" method for the field would then
become:

If "some condition"
    Calculate $cfield.$negallowed as kTrue
End if

Other "Hidden" Properties

We work with the other properties mentioned in this article in the same way
as the "negallowed" property. The rest of the article is mainly a discussion
on how these properties can be beneficial.

$zeroempty

Often it is important for the "cleanliness" of an application to have
certain numeric fields display as empty unless they contain non-zero values.
"Normal" Entry Fields have a property named "zeroempty" that does exactly
that. The property appears to not belong to Masked Entry Fields, but it
does - it simply doesn't appear in the Property Manager and it defaults to
"kFalse".

"zeroempty" is a "display" property that has no exact equivalent in the
options of the "formatstring" property. Sure, we can use the "#" character
that displays "Digit or nothing" as opposed to the "0" character that
displays "Digit or zero" for each character position in our "formatstring"
property to partially emulate the "zeroempty" look. This formatting
character is intended to suppress leading zeros before the decimal and
trailing zeros after it. It works great for fields representing integer
variables! But if we must display a decimal number in the field, that pesky
decimal point appears even when the number is exactly zero and all the
digits are suppressed!

When the "zeroempty" property value is set to "kTrue", even the decimal
point is suppressed for zero values. That is the behavior we want, so the
"zeroempty" property is still necessary - and fortunately still available
through Notation!

$uppercase

Occasionally we may desire to convert alphabetic keystrokes to their upper
case equivalents in certain fields. There are many reasons for doing this,
but they generally boil down to the general reason of "interface
consistency". Entry Fields have a property named "uppercase" that does this.

"uppercase" is a "data entry" property, so we must look to the "inputmask"
property to see if there is an equivalent. And sure enough, there is!
...Well, sort of... We actually can have control over this on a
character-by-character basis, but we need to know exactly how many
characters will be entered. This will work just fine for fields representing
"Character" variables that have a fixed format. In fact, it's WONDERFUL for
that purpose! But what about situations where we want to impose a specific
"display" mask, but not a "data entry" mask - or where a variable number of
characters may be entered.

My specific example is date entry. I often use a Masked Entry Field to
represent date variables so that I can impose a specific display format on
the field contents. But at the same time, I want to allow for the wide
variety of valid date "inputs" that Omnis Studio allows - with one
exception: I prefer that alphabetic keystrokes be forced to upper case for
consistency with the "month abbreviation" display format. Certainly Omnis
Studio will interpret "jun 10" the same as "JUN 10" (or the other way around
for non-US date part ordering), but sometimes users need that extra
consistency that the "uppercase" property can provide.

The good news is that we can modify the "uppercase" property of a Masked
Entry Field through Notation, so we have this extra data entry option at our
disposal!

$horzscroll

Perhaps the most frustrating thing a user can encounter is a data entry
field that can't quite hold all the characters we just KNOW it should. This
most often occurs in cross-platform applications where the interface wasn't
thoroughly tested on the "other" platform from the one on which it was
built. The purpose of the "horzscroll" property of a "basic" Entry Field is
to allow text to be entered beyond the "physical" boundary of the field.
This allows the length limitation of the associated variable to impose the
data entry restriction rather than the width of the entry box.

There is no visible sign that this ability exists (no scroll bar appears)
and the property is definitely of the "data entry" variety (we can't scroll
the contents when the field is disabled), but "horzscroll" is certainly
useful when trying to save space on a window while still allowing for that
rare "maximum length" text value.

Perhaps Masked Entry Fields hide this from us because they expect us to size
them "just right" for the number of characters in our "inputmask" value. But
even if we do, most fonts we use today aren't monospaced and many uppercase
alpha characters are wider than the characters used as placeholders in those
masks.

And maybe we won't be using an input mask at all. I'll go back to the date
variable example above. (Apologies in advance for the use of US date
formatting.) We may force the display of a date to be "06/10/02" to save
space while still allowing the user to enter "JUN 10 2002" if this makes
them more comfortable. (Or perhaps our "#FD" value does this when the focus
enters the field...) If the field contents can't scroll, we have a serious
problem!

Fortunately, we can use Notation to set "horzscroll" to "kTrue" even though
it doesn't appear in the Property Manager. Problem solved!

$calculated And $text

As I recall from years ago, one very important use of the "formatstring"
property in Omnis 7 was for formatting the display of derived values in
"calculated display" fields. These are fields with no "dataname" value that
are used simply to generate a value for display on a window (or report),
such as the total of a column of a list or a "line item extension" on an
invoice line. Sure, we could surround our expression that derives such a
value with a "jst()" function and impose special formatting with the
functions second parameter, but sometimes a "formatstring" is simpler to
manage (for example, offering separate formats for negative and non-negative
numeric values in the "sections" of a "formatstring" value).

The problem: Masked Entry Fields in Omnis Studio have no "calculated"
property in the Property Manager. Again, there IS such a property, but we
must change its default value of "kFalse" to "kTrue" using Notation when we
need to display a derived value with a "display" mask. (Guess it's really
only a problem when you don't know the solution...)

Not only do we have to set "calculated" to "kTrue", we also have to set
"enabled" to "kFalse", "dataname" to "empty" (unless we intend some variable
to receive the result of this calculation), and we have to supply a suitable
expression in the "text" property (also apparently missing) as we would for
a "normal" Entry Field intended for use as a "calculated display" field.
This is one of those cases in Omnis Studio where only a specific combination
of property values will achieve a workable result.

"calculated" and "text" are neither "display" nor "input" properties. As a
team they generate a value to be displayed in a field that cannot accept
user input - a very special exception to the usual purpose of properties.
(They may also depend in part on the "local" property for redraws as the
variables referenced in "text" change in value, but that's a topic for
another time...) It is GREAT that we can still apply this combination to
Masked Entry Fields using Notation, taking advantage of both value
generation and display formatting at once!

$text With $calculated=kFalse

The "text" property of an Entry Field has another special use when
"calculated" equals "kFalse", "enabled" equals "kTrue" and the name of a
variable is contained in "dataname". It acts as a simple check calculation
during data entry. Granted it is not as flexible as a typical "On evAfter"
event handling method block, but it has its advantages. There isn't enough
time to branch into that topic here, but there is an entire article entitled
"Operational Properties" in the next issue of my technical journal
OmniScience, scheduled for release before the end of June 2002, that
explains this and a number of related issues.

$formatstring And $inputmask Of Entry Fields

In case you were wondering, there are no "hidden" properties regarding masks
for "normal" Entry Fields in the current versions of Omnis Studio. Masked
Entry Fields do have a valid rationale for separate existence from Entry
Fields: There is significantly more overhead in managing their "display" and
"input" masks than for "straight" data entry fields. While it makes sense
that the properties mentioned in this article are included with Masked Entry
Fields, it would NOT make sense (at least not to me) for there to be
"hidden" mask properties in "normal" Entry Fields.

Consider the difference between Label and Text background window objects.
Labels have fewer options than Text objects, but also require fewer system
resources, so a good case can be made for their existence. This does not
mean there won't be Omnis Studio developers with strong opinions that only
one or the other "should" be used (based upon the way they personally prefer
to work), but it is good (in my opinion) that we are given the option to
choose between "streamlined" and "feature-rich" components.

Custom Masked Entry Fields In The Component Store

After repeatedly performing special modifications of Masked Entry Fields for
certain purposes, you may wish to "plant the seed" of special property
combinations within a custom "Design objects" class in your Component
Library. This will allow you to simply pull a specialized Masked Entry Field
directly from the Component Store with all but the "dataname" property
required for a specific purpose. We have discussed this before (see
"Modifying the Component Store" in the October 17, 2001 issue of Omnis Tech
News), but I strongly suggest that you consider this as you delve further
into Omnis Studio.

And while you're at it, another good idea might be to add a "$construct"
method to the default Masked Entry Field object in the "_Field Components"
class in the Component Store and place a line of code for all six of these
properties, defaulting them to the "empty" state like this:

Calculate $cfield.$negallowed as kFalse
Calculate $cfield.$zeroempty as kFalse
Calculate $cfield.$uppercase as kFalse
Calculate $cfield.$horzscroll as kFalse
Calculate $cfield.$calculated as kFalse
Calculate $cfield.$text as ''

This will eliminate the need to remember how all this is accomplished (or
the need to refer back to this article) as well as the need to build the
code lines again for special Masked Entry Field requirements that are not
met by a component you have placed in a custom Class of the Component
Library. It's always good to plan ahead...

Final Words

I don't believe that the existence of these "hidden" properties of Masked
Entry Fields is a "bug" to be fixed. I hope I have made reasonable arguments
for their existence and have given realistic examples of some possible uses
for them. They lend more flexibility to Masked Entry Fields than the
"visible" property set offers alone.

All of the above was tested thoroughly on Omnis Studio 3.1 on both Mac OSX
and Mac OS9 while this article was being written. A few tests were also
performed on Omnis Studio 3.2 beta on Mac OSX to be certain this information
would not be made obsolete by modifications included in the new version.
While the Windows, Linux and Solaris versions were not directly tested,
students in my "Omnis Studio: Beyond the Basics" classes have confirmed this
behavior works as described above on a variety of Windows versions. (Guess
I'll have to come up with some new course content now that this topic is
public knowledge!) There is no reason to assume that the Linux or Solaris
versions of Omnis Studio should behave differently.

But I would like to hear if you find otherwise. Please email me at
mailto:dataguru@polymath-bus-sys.com if this does not work for you as
described. Let me know the details of your setup (operating system and
version, version of Omnis Studio, etc.) as well as the results you see.


========================================

oXML: Omnis to the Power X...

Raining Data is delighted to announce the recent release of the oXML plug-in
for Omnis Studio, opening up many new and exciting opportunities for your
future application development. oXML allows you to manipulate and create XML
documents in Omnis Studio and is available for all Windows, Unix, and Mac OS
platforms. The oXML plug-in is an Omnis Studio external component that
allows you to parse and manipulate XML documents using a standard set of
methods provided by the DOM API, plus some additional methods that speed up
the process of building a document.

Read more about the oXML component and other news in the Omnis News:
http://www.omnis.net/news


========================================

Let's get Technical...

Subscribers to the Omnis Technical Newsletter will know that Geir Fjaerli
has been writing about object orientation and its implementation in Omnis
Studio. This subject was also covered by Richard Mortimer, Senior Consultant
and Trainer in the UK office, at the May 'Technical Thursday', a free
technical seminar held every first Thursday of the month in the UK Sales
office at Chalfont St Peter. We have added Richard's excellent presentation
to the Omnis web site, which is available here:
http://www.omnis.net/develop/resources/notes

Meanwhile, the June and July 'Technical Thursday' sessions will feature our
multi-value products and the next Omnis-based seminar will be the September
session on the subject of the new Studio V3 multi-threaded DAMs.

To attend any of the 'Technical Thursday' seminars, please contact the UK
sales office, Telephone: +44 (0)1753 882872, or email: uk_sales@omnis.net


========================================

I hope you've found this issue of the Omnis Tech Newsletter both interesting
and informative. Please send me your comments and feedback, and include
suggestions for future articles if you like. We would like to hear from
you...

Regards,
--Andrew Smith.
Omnis Technical Newsletter Editor
Email: editor@omnis.net

========================================

No part of this newsletter may be reproduced, transmitted, stored in a
retrieval system or translated into any language in any form by any means
without the written permission of Raining Data.
(c) Copyright Raining Data, Inc., and its licensors 2002. All rights
reserved.
Omnis(r) is a registered trademark and Omnis 7(tm), and Omnis Studio are
trademarks of Raining Data UK Ltd. Other products mentioned are trademarks
or registered trademarks of their corporations.

========================================

To unsubscribe from this newsletter or change your subscription options,
please go to:
www.omnis.net/newsletter