Tips_todo   >   Misc   >   String Tables

String Tables

String tables can be used to support multiple languages. String tables are a good discipline to follow, even if you are supporting only 1 language.

Books on GUI recommend that developers use some sort of a common "phrase dictionary" for all the labels, titles, prompts, and messages throughout the application. By using a centralized "phrase dictionary" you are better assured that the same terminology is used for the same things throughout your application. This is especially critical for applications being developed by multiple programmers. The user becomes confused when in one window you refer to the a certain menu as the "Application Menu" and in another window you refer to it as "Main Menu".

String tables could also be used for operating system sensitive terminlogy.
e.g. Mac vs. Win vs. Unix. Ctrl-Click vs. Right-Click

At the time of writing this section in StudioTips, finding the information on String Tables took some effort. Eventually I found a Tech Note on the Omnis web site at: www.omnis.net/develop/resources/notes/technotes.html

You can also download 2 String Table demo libraries from Omnis. "strtest.lbs" and "Table.lbs"

This section of StudioTips goes through the information provided in the Tech Note giving demos and examples of how to implement String Tables. Each String Table function is listed and explained.

Thanks to Jock Philip for helping me get started with String Tables. Thanks goes to Omnis for allowing me to use bits and pieces of their Tech Notes for this section.

$colcnt

Do StringTable.$colcnt([TableName])
Returns the column count for TableName.

$getcolumnname

Do StringTable.$getcolumnname(TableName)

Gets the column name for the current column.

Note that TableName is not required if only one String Table is loaded.

$getcolumnnumber

Do StringTable.$getcolumnnumber(TableName)

Gets the column number for the current column.

Note that TableName is not required if only one String Table is loaded.

$gettext

Do StringTable.$gettext('[TableName.]ID') Returns Text

[StringTable.$gettext('TableName.ID')] ;; If using square brackets

Gets the text in the current column of the specified String Table for the row matching ID.

$loadcolumn

Do StringTable.$loadcolumn(ColumnName,TableName,Path)

Creates a String Table using a single column of an existing String Table.

$loadlistfromtable

Do StringTable.$loadlistfromtable(TableName) Returns List

Loads a String Table already in memory to an Omnis list.

$loadstringtable

Do StringTable.$loadstringtable(TableName,Path)

Loads an existing String Table into memory from an existing String Table file.

Note: If the String Table has already been loaded, you must first "$unloadstringtable". Trying to load the same String Table will result in an error.

$loadtablefromlist

Do StringTable.$loadtablefromlist(TableName,Path,List)

Creates a String Table from an Omnis List. It should be noted that the table is created in memory at this point. To save the table, use $savestringtable.

Although this command requires a path, it doesn't actually create the file until you issue the $savestringtable.

Note: If the String Table has already been loaded, you must first "$unloadstringtable". Trying to load the same String Table will result in an error.

$redraw

Do StringTable.$redraw(WindowInstanceRef.$hwnd)

Redraws the String Table labels on an entire window.

NOTE: Not including the ".$hwnd" will cause Studio to crash. (I know from experience!)

$redrawAll

Redraw all windows after selecting a new String Table.

This is NOT a String Table function. This is a method you can create/use for redrawing all the String Table labels in all the open windows.

$removestringtable

Do StringTable.$removestringtable(Path)

Deletes a String Table stored on disk.

DANGER! This function really does delete the String Table file!

$rowcnt

Do StringTable.$rowcnt([TableName])

Returns the row count for TableName.

$savestringtable

Do StringTable.$savestringtable(TableName)

Saves a String Table which has been previously created.

Note: A path name is not required when saving. Pathnames are only specified when creating String Tables.

If you had a new String Table in a list, the process of creating the new String Table file on disk
would be as follows:

$setcolumn

Do StringTable.$setcolumn([StringTableName.]ColumnName)

Sets the current column to "ColumnName". This may be either a name or a number.

Note: "ColumnName" is case sensitive. If multiple String Tables are being used then the format needs to be "TableName.ColumnName"

e.g. StringTable.$setcolumn("Table1.French") or StringTable.$setcolumn("Table1.3")

$unloadall

Do StringTable.$unloadall()

Unloads all String Tables from memory.

This function is optional, as all String Tables are automatically unloaded when Omnis quits.

$unloadstringtable

Do StringTable.$unloadstringtable(TableName)

Unloads a String Table from memory.

This function is optional, as all String Tables are automatically unloaded when Omnis quits.

Headed List Column Headings

The headed list $columnnames property doesn't seem to evaluate [] square bracket $gettext notation. One workaround is to build the $columnnames string in the $construct method of the headed list.

Click "Run Demo" to see how this can be done.

String Table Column Names

If you are using String Tables for supporting various languages, you may want to use the same language abbreviations used by the web browsers. Why bother figuring out codes for the various languages, when there is already a standard being used.

To find out the code, open the "Preferences" in your web brower and click on the "Languages" preferences setting. Click on the "Add..." button, and you will be prompted with a list of languages and their abbreviations.

English/United States [en-US]
English/United Kingdom [en-GB]
German/Germany [de-DE]
Italian [it]
Dutch [nl] etc.

So for my string tables I'm using "en-US" as the 2nd column name.

Note: Don't include brackets () in your string table column names ... the brackets will mess up your notation.

Many thanks to Pierre Huber for pointing out the web browser language codes.

String Table Editor

The String Table Editor is a window interface which Omnis has created to assist developers in creating, editting, and saving String Tables.

To open the String Table Editor look under the Tools menu > Add-Ons > String Table Editor... Look through the File and Tools menus. Hold your mouse of the toolbar buttons to review all the String Table Editor functions that Omnis has provided for you to use.

When you "Save" the String Table, Omnis sorts the table on the ID column just prior to saving it. This is done to speed lookups when the String Table is being used.

If you aren't happy with the String Table Editor you can "roll your own". You might find it easier to create your string table in Excel and then import it. For editing an existing String Table, you have the option of exporting it, editing it in Excel and then importing it.

NOTE: The +Plus version of StudioTips includes a String Table editor. Click "String Tables Editor" on the tab strip at the bottom of the StudioTips Browser window to access it.

String Table Labels

Omnis provides a handy "String Table Label" external component which works well with String Tables. You will find the String Table Label in the Component Store under "Background Components".

The String Table Label has a property $rowid under the "Custom" tab where you enter TableName.ID

The only "gotcha" with "String Table Labels" is that they don't support $fieldstyles. (see General tab > Fonts>#STYLES) This short coming makes the String Table Label unusable for me.

An enhancement request has been put through to Tech Support to add $fieldstyle to String Table Labels.

One alternative is to use "text" background objects and enclose the $gettext() function in [square brackets].
Example: [StringTable.$gettext('TableName.ID')]

Using String Tables

So, how do you go about using String Tables in your own application? Well, as usual there are many ways. Some developers choose to create and store the String Tables as lists which are stored in the data file, rather than using actual String Table files stored on disk. In that case you would use $loadtablefromlist() instead of $loadstringtable().

My own preference at this stage is to use the Omnis String Table files stored on disk.

To keep your String Tables manageable, it is recommended that you have a String Tables for various categories. e.g. Labels,Buttons,Menus,Prompts,ErrorMessages.

Store all the String Tables files in a separate sub-folder below the main library of your application. For StudioTips I created a "string_tables" folder located inside the "studiotips_stuff" folder.

Create your String Table using the Tools menu > Add-Ons > String Table Editor... Save it. Then load the String Table(s) in the Startup_Task.$construct and test your labels.

Even if you are currently only developing your application in one language, the use of String Tables can be a good discipline for keeping your terminology consistent throughout your application.

CREATING STRING TABLES MATCHING YOUR SQL TABLES

As I was adding labels to the entry fields on a window the idea occurred to me to create a string table for each server table and to use the server table column name in the string table ID column. Every colum in my database would be mapped to a unique string table row.

I have embarked on a mission to create a String Table for every SQL table that has data which is displayed on a window or report. The String Table file name and Òshort nameÓ is the SQL table name. The ID column of the String Table is the SQL table column names, and the different language columns contain the exact label wording as I want it displayed in window labels for that column name.

For example, a SQL table column name of "ChequeNumber" in the en-US (English-US) column will say "Check Number" and in the en-GB (English-British) column will say "Cheque Number".

Now when I "LoadStringTables" at the time of opening the library, I can simply loop through all the SQL tables and generically load all the corresponding String Tables for each SQL table.

In my window text labels I use the following square bracket notation:
[StringTable.$gettext('SQLTable.ColumnName')].

No further thinking or coding is required! When the window opens the labels will display the correct label text for the language column that was set when the library was opened. If I or my client want to change the label for the SQL table column "LastName" from "Last Name" to "Surname" ... no problem. Change it in the String Table and EVERY place "LastName" is displayed will be changed from "Last Name" to "Surname".

To speed up creation of String Tables which match existing schema classes, I've created a String Table Editor which allows you to select a schema class and then using a context menu call a method which builds a String Table list with the ID and 1st language column already filled in. You can then edit and "Save As..." the String Table.

NOTE: The full version of StudioTips includes a String Table editor with the "Create String Table from Schema
Class" feature. Click "String Tables Editor" on the tab strip at the bottom of the StudioTips Browser window to access it.