Introduction
AnyText requires StringTheory.
AnyText requires GUTS
(A Free Accessory).
AnyText allows a user to change the text in your program at runtime. All
visible text, including Window Captions, Prompts, Buttons and so on can be
translated. This allows you to create multi-language versions of your
application, where users can be responsible for translating the text as
required.
It also allows users to change terminology inside a program, even if they
are using the same language. This helps to make the program more familiar
to users. For example, in some countries you would use a ZIP CODE in an
address, whereas in others this is known as a POSTAL CODE. Even specific
words, like color / colour can have different spellings in different
countries. AnyText allows this to be tweaked to best fit the user who is
using it.
In different languages it may be necessary to change the "Display
Pictures" for fields as well. For example any numeric containing a
currency, date and time fields, and so on. AnyText allows users to change
these locally on a window, or globally across the whole application.
Note: If you are upgrading from a version prior to 2.10, to version 2.10
or later, then please read the section on
Upgrading
to version 2.10 or later
ClarionLive
An excellent way to get an overview of AnyText is to
watch
ClarionLive
webinar number 235. In this webinar, Bruce covers the goals and
features of AnyText as well as walks you though implementing AnyText in
your application.
Installation
Run the supplied installation file:
Upgrading to version 2.10 or later
If you have upgraded from a build of AnyText before
2.10 to version 2.10 or later, then the following small changes will need
to be made to your existing application.
- ABC Templates Only - If your app
is based on the Clarion (Legacy) templates then proceed with step 2.
In your dictionary, go to the AnyTextVariables
section and set the THREAD attribute ON for the
AnyText:LocalTableName field. Repeat this with the AnyText:GlobalTableName
field.
- Do NOT change AnyText:Language - leave
this as unthreaded.
- The code in the AnyTextSetLanguage
procedure has been split, with the code setting the
AnyText:GlobalTableName and
AnyText:LocalTableName variables moved into a procedure
called AnyTextSetFileNames.
Update your app by importing the
\clarion\accessories\libsrc\win\AnyTextUpdate1ABC.Txa file or
\clarion\accessories\libsrc\win\AnyTextUpdate1Clarion.Txa
file.
In a multi-DLL situation you only need to do this in the Data DLL.
When prompted during the import select "Replace All".
NOTE : If you have edited the lines for setting the file name
variables in AnyTextSetLanguage then you
will need to make these same edits to the code in AnyTextSetFileNames.
- A new procedure has been added called
StartAnyTextTranslateGlobal. This is included in the update
files from step 3. This procedure allows the
AnyTextTranslateGlobal procedure to be called, on it's own
thread, from a menu item or toolbar button.
- The Prototype of the AnyTextTranslateGlobal procedure
has changed from (anytext pAnyText) to (<anytext pAnyText>). You need to make
this change to the procedure by hand.
- ABC templates Only - If your app
is based on the Clarion (Legacy) templates then proceed with step 7.
The embed code in AnyTextTranslateGlobal changes from
pAnyText.PutGlobal(Queue:Browse.ATG:Original
,Queue:Browse.ATG:Translation)
ThisGuts.PostEvent(Guts:EventRefresh,family:anytext)
to
if not omitted(pAnyText)
pAnyText.PutGlobal(Queue:Browse.ATG:Original
,Queue:Browse.ATG:Translation)
ThisGuts.PostEvent(Guts:EventRefresh,family:anytext)
else
AnyTextFreeCache()
end
It is best to make this change by hand in the procedure.
- Clarion (Legacy) Templates Only
The embed code in AnyTextTranslateGlobal changes from
pAnyText.PutGlobal(Queue:Browse.BRW3::ATG:Original
,Queue:Browse.BRW3::ATG:Translation)
ThisGuts.PostEvent(Guts:EventRefresh,family:anytext)
to
if not omitted(pAnyText)
pAnyText.PutGlobal(Queue:Browse.BRW3::ATG:Original
,Queue:Browse.BRW3::ATG:Translation)
ThisGuts.PostEvent(Guts:EventRefresh,family:anytext)
else
AnyTextFreeCache()
end
It is best to make this change by hand in the procedure.
JumpStart
- Import the AnyText File Structures into your dictionary. These are
supplied in the file AnyText.TXD (located in the clarion\accessory\libsrc\win
directory). This creates 2 new tables, and one new set of global
Variables to the dictionary; AnyTextVariables,
AnyTextGlobal and AnyTextLocal.
- Add the GUTS Global Extension to the application, if it has not
already been added.
- Add the StringTheory Global Extension to the application if it has
not already been added.
- Add the AnyText Global Extension to the application. If you are
creating a simple single EXE app then proceed to step 5. If you are
using Anytext in Multi-App suite then proceed to step 6.
- 5a. On the AnyText Global Extension, on the General tab, click the
button Import AnyText Procedures.
Importing the procedures should import 5 procedures into the
application; AnyTextTranslate,
AnyTextTranslateGlobal, AnyTextSetLanguage,
AnyTextSetFileNames and
StartAnyTextTranslateGlobal. If any of these are missing then
you may have missed step 1 above.
5b. On the Options Tab set the HotKey (The default
is CtrlF10 which may display as 633)
5c. On the Options Tab set the Global File by
selecting the appropriate file from your dictionary.
5d. On the Options Tab set the Local File by
selecting the appropriate file from your dictionary.
5e. In Clarion 9 (not Clarion 8 and not Clarion 9.1 etc), after
importing, you will need to open the procedure properties for each of
the imported procedures. This works-around an IDE bug introduced in
Clarion 9 and fixed in 9.1.
Proceed to step 7.
- In the DATA DLL:
6a. On the AnyText Global Extension, on the General tab, click the
button Import AnyText Procedures.
6b. On the Options Tab set the HotKey (The default
is CtrlF10 which may display as 633)
6c. On the Options Tab set the Global File by
selecting the appropriate file from your dictionary.
6d. On the Options Tab set the Local File by
selecting the appropriate file from your dictionary.
6e. On the Multi-DLL Tab tick on the option: This is part of
a Multi-DLL program
6f. On the Multi-DLL Tab tick on the option: Export Class
from this DLL
In all other DLL's and the EXE's:
6g. On the AnyText Global Extension, on the General tab, click the
button Import EXTERNAL AnyText Procedures.
6h. On the Options Tab set the HotKey (The default
is CtrlF10 which may display as 633)
6i. On the Multi-DLL Tab tick on the option: This is part of
a Multi-DLL program
- Read the Section on Table names,
go to AnyTextSetLanguage procedure,
and set the code appropriately there.
- Read the section on Translating Hand-Code.
Over time you will need to tweak any existing hand-code you may have
which contains static text.
ABCErrorClass
ABC generates a number of errors internally. These
ultimately flow through the MESSAGE procedure to display a message to the
user.
there are two possible approaches to translating these messages.
Override the MESSAGE procedure
Clarion allows you to override the MESSAGE procedure
in your application, using the
System{prop:MessageHook}
approach. You can code your own MESSAGE procedure (as a window in your
application) and translate the messages there before they appear.
If you use CapeSoft's
MessageBox
accessory then this approach is done for you. However since some of the
messages contain variables (like file or key names) it may still be
desirable to use the approach below as this allows you to translate the
message before the variable parts are replaced.
Translate the root message in ABERROR class
NOTE: As of writing this older versions of Clarion
have a small bug (PTSS 42474) in the ErrorClass which prevents this
approach from working. [this bug was corrected in Clarion 11 build
11.0.13227]. Fortunately, if you have an older Clarion version, fixing
the bug yourself is trivial and has no side effects. See note
[1]
below for details.
An option on the AnyText Global Extension, Options Tab,
Translate
ErrorClass turns this support on or off.
If this option is on, and a message has been displayed to the user, then
the message can be translated on the Global Translation window.
The original ErrorClass messages can be found in the ABERROR.TRN file.
You can change this file if you wish, but if you make changes then you
will need to make a local copy of that file or it will be overwritten
with the next Clarion update. This file is used at Compile time though,
it cannot be used as a source of runtime translations.
Note [1]: Fixing
ABERROR.INC
- Open \Clarion\Libsrc\Win\ABERROR.INC
in an editor (the Clarion IDE is fine.)
- Search for line circa 195, which looks like this;
SubsString PROCEDURE,STRING,PROTECTED
- Add the attribute ,VIRTUAL to that line so it reads
SubsString PROCEDURE,STRING,PROTECTED,VIRTUAL
Relationship
with other 3rdParty products
We've been building Clarion Accessory products for 20
years. During that time we've released almost 40 products. Not
surprisingly we avoid duplicating code wherever possible, so inevitably we
end up making use of things we've already done. Where possible we try and
avoid dependencies, but in some cases it makes sense to make use of
existing code.
- GUTS
(Free) - Required. Guts is a free accessory that manages a Global
UnThreaded object Store.
-
StringTheory - Required. StringTheory is a general purpose
string manipulation class.
- Edit-In-Place - Required (but not available yet). An interim
template is provided (see below).
- AnyFont
- Optional. AnyFont allows your program to change the font, and
crucially the charset, at runtime. This may be necessary if changing
text into a language with a different character set (for example
Greek).
- MessageBox
- (Version 2.22 or later). Optional - Makes it easier to translate
all the MESSAGE calls in your application without having to re-code
each one. It also makes it possible to translate MESSAGE calls which
are not in your code, but in template or class code written by others.
The EditInPlace TPL file is a temporary measure until the EditInPlace
Install is built. EditInPlace is a template which we have used internally
for many years, offering EIP functionality on Browses and List-Boxes.
Because the AnyText windows make use of EditInPlace you need this
template.
In the medium term this template will be replaced by a refactored
Edit-In-Place template and class. Owners of AnyText purchased before the
release of Edit-In-Place will automatically get a free copy of
Edit-In-Place when it is available.
Tables
AnyText makes use of two new tables in your
dictionary. The one is called AnyTextLocal and
the other is AnyTextGlobal. Not surprisingly
these store the translations applicable to a single Local window, and the
translations applicable to the whole application respectively.
You can change the file structures if necessary to match the File Driver
the rest of your system is using.
A pair of translation files contains a single language translation. In
other words if your program supports multiple languages then you will have
a disk file, or SQL table for each of these, for each supported language.
By keeping files separate like this it is much easier to maintain multiple
languages.
A procedure called AnyTextSetFileNames is added to your application (to
the Data DLL in a multi-DLL situation) which sets the name for each table.
The exact code will depend a bit on the File Driver you are using, and
also on your personal preferences. When adding AnyText to an application
you will almost certainly want to change this code. See the next section
in this doc for more information on that.
The tables start out empty, and records are created in them as you visit
the various screens in your application.
AnyTextSetLanguage Procedure
The AnyTextSetLanguage procedure is a procedure added
to your application, which can be called from anywhere to change the
language the app is currently using. It takes a single parameter (
pOptions)
which you can use to identify the language to use.
The code in this procedure can be edited. It performs three basic tasks.
- Set the AnyText:Language variable. This
can then be used elsewhere in your application to show the user which
language is active.
- Set the AnyText:GlobalTableName and AnyText:LocalTableName variables. This will be
dependent on the File Driver you have chosen. See below for some
examples.
- Call ThisGuts.PostEvent to alert all the existing objects of the
language change. For example;
ThisGuts.PostEvent(At:NewLanguage,family:anytext,0,0,random(1,5000))
The last parameter is an efficient method for clearing the
AnyText cache.
Setting File Names
Here are some examples for setting the File Names in
the AnyTextSetLanguage procedure. You have
a fair amount of flexibility when creating these names, so you can use
any code you prefer here, as long as the result is that the AnyText:GlobalTableName
and AnyText:LocalTableName variables are
set to something legal. These are just some examples of what you might
have.
BTRIEVE / CLARION
AnyText:GlobalTableName =
'Lang-G-'&clip(pOptions)&'.Dat'
AnyText:LocalTableName = 'Lang-L-'&clip(pOptions)&'.Dat'
TOPSPEED
AnyText:GlobalTableName =
'Lang-'&clip(pOptions)&'.Tps\!Global'
AnyText:LocalTableName = 'Lang-'&clip(pOptions)&'.Tps\!Local'
SQL
AnyText:GlobalTableName =
'dbo.Global'&clip(pOptions)
AnyText:LocalTableName = 'dbo.Local'&clip(pOptions)
Calling the Procedure
The procedure can be called from anywhere in your
program. You can pass anything you like in as the parameter - presumably
though it will be something that identifies the correct language file to
use.
Translating Reports
The short version: Holding down the Shift key when the
report procedure starts triggers the translation window.
Shift Key
If you hold down the Shift key while starting the
report procedure (in other words Shift-Click the button or menu item
etc) then the report will go to the translation window before generating
the report. Note that depending on the setup the report may not actually
translate on this run (although it likely will.)
ABC
In ABC applications, report procedures contain
fully-functional window structures and objects. This means that the
"Pause the Process" control template can be added to report procedures.
This template is useful because it allows to "Start Paused" - which in
turn means you can put report options directly on the window.
In this situation the Ctrl-F10 (or whatever) keycode works as normal and
allows you to translate the report as well as the window.
In ABC the Shift-Key approach works on all windows, not just reports. In
other words shift-clicking a Browse or Form or whatever also works.
Translating Text in Hand Code
In many cases you will already have hand-code in your
application which contains static text in one or other language. In order
to make all the text in your application translatable, you need to pass
this through the translation engine. To do this you wrap existing static
text in a call to ThisAnyText.Translate. For
example the following;
If Message('Do you want to close this window?', |
'Question',|
Icon:Question,button:Yes+Button:No,Button:No) = Button:Yes
Post(Event:Closewindow)
End
becomes
If Message(ThisAnyText.Translate('Do you want to
close this window?'),|
ThisAnyText.Translate('Question'),|
Icon:Question,button:Yes+Button:No,Button:No) = Button:Yes
Post(Event:Closewindow)
End
Note that this call should only be made after the object has initialized.
So make sure that the call is done after the call to
ThisAnyText.Init in the procedure.
Translating a Window in Hand Code
Occasionally you have a Source procedure, or some
other procedure, which has a hand-coded window declaration. Since the
template is unaware of this window it does not add the necessary AnyText
support to it. Fortunately you can add support manually by following these
instructions;
In these instructions the window name is assumed to be MyWindow. Tweak the
instructions to match your window name.
- Create an AnyText object for this window. If the procedure has
multiple windows then create a separate object for each window. For
example;
MyAnyText AnyText
- Immediately after the window is opened initialize the MyAnyText
object.
MyAnyText.Init(AnyTextCache,ThisGuts,AnyTextLocal,AnyTextGlobal,'ProcedureNameMyWindow')
The last parameter in this call should be unique for the
application. So if this is a source procedure then the procedure name
will suffice. If it's a Window procedure, with another hand-coded
window, then you should add the window name to make the string unique.
- Then immediately apply the initial translation
MyAnyText.SetWindow(MyWindow)
MyAnyText.TranslateWindow()
- Inside the ACCEPT loop for this window add
If MyAnyText.TakeEvent() then cycle.
If Event() = Event:AlertKey and Keycode() = CtrlF10 then
AnyTextTranslate(ThisAnyText).
Translating Text in a NetTalk Web Server Application
NetTalk is a different accessory from CapeSoft, used
for building web applications in Clarion. NetTalk is not included in
AnyText. If you are using NetTalk to build web applications then this
section explains how to use AnyText to translate the text in that
application.
- Add AnyText as normal to the application.
- Add the languages you will support on the AnyText Global Extension,
Web tab.
- Add the AnyTextTranslateWebHandler extension
template to the WebHandler procedure.
At this point the basic code for supporting multiple languages is now in
the application.
Changing Languages
A user can change from one language to another by
passing the _language_ parameter as part of the URL. For example;
http://www.whatever.com?_language_=spanish
Only languages which have been added in step 2 above are valid values
for this parameter.
You can offer a user a menu item, or button, or image (or anything else
which can take a URL) to allow them to change languages. All you need to
do is add the _language_=something parameter to the URL.
You can also set the
_language_ session
value directly when the user logs in, to automatically switch to their
selected language. For example;
p_web.SetSessionValue('_language_','spanish')
When changing a language only the subsequent requests from the browser
will be translated into that language. Existing parts of the page that
are not refreshed will not be translated. For this reason it is
recommended that the link to change the language returns the user to the
starting URL in the application.
Translating Text
As is normal in AnyText the translations themselves
are stored in different SQL or TPS tables. In order to actually do the
translations in these files you can do one of the following;
a) add a Button to the WebServer procedure, which calls the StartAnyTextTranslateGlobal
procedure on a new thread. The language currently set in AnyText:Language will be used, so change this
variable to the correct language before the call.
OR
b) create a separate program that browses the tables, and make
translations directly in there
OR
c) add a NetWebBrowse on the Global table, with Edit-In-Place editing
for translations.
Limitations
Only global translations are applied. At this stage
local translations are not supported. Local translations may be
supported in a future release.
How To Turn AnyText OFF
There will likely be some text in your program which
your customer should not be able to translate. The ABOUT
procedure containing the product name, copyright message and so
on is a good candidate for this.
To turn off the translations for a window, you go to that procedure, to
the Extensions list and locate the CapeSoft AnyText extension. On that
extension tick on the prompt Disable This Template.
It is also possible to suppress AnyText across the whole application by
using a command line switch
/notranslations
This can be included when calling the program, or it can be set
programmatically using the command
SETCOMMAND(' /notranslations')
It can be removed by using the command
SETCOMMAND(' /notranslations=')
If you wish to suppress the translation of the caption bar on a specific
window then you can set the DontTranslateCaption
property for that window. For example
ThisAnyText.DontTranslateCaption = true
If you wish to disable translations for a specific window (at runtime)
then you can set the TranslationDisabled property
for that window. For example;
ThisAnyText.TranslationDisabled = true
Windows Charset for Non-Unicode Programs
ENTRY and TEXT controls use a Windows Setting to
determine which Charset they are using. So even though your program may be
set to use say CHARSET:GREEK, and even though some controls (like LIST and
BUTTON) controls use this "as is" - some controls (like ENTRY and TEXT)
make use of the Windows setting to determine what Charset to use.
This setting is usually determined by the flavor of Windows you have
installed. So for example if you have Polish Windows installed then this
setting is automatically CHARSET:EASTEUROPE and everything "just works".
This can be an issue though if you wish to do the translations on a
version of Windows which is not in the same locale as the language you are
translating to. In order to translate into Thai, on your English version
of Windows, you will need to change a setting in Windows to make this
possible.
Of course your end user will need this locale set as well, but since they
are in say Thailand, they are likely running in this locale already, so
should not need to do anything to their machine to run your program.
- Control Panel
- Search for Region. (The search may contain multiple results - click
on Region)
- You should see the Region Settings Window - something like this;
- Select the Administrative Tab
- Click on the Change System Locale button
- Select the country you are translating to from the list of
countries.
This means of course that your ENTRY fields (that use extended character
sets) can really only be for one region at a time. Since translations are
done at runtime this means may be translating from one region to another
region. For the purposes of doing the translation you want to set the
above setting to the TO region, not the FROM region.
Limitations
- AnyText Requires StringTheory
and GUTS.
GUTS is free, but StringTheory is not.
- MDI Child Windows do not translate any Menu or Toolbar controls.
Thus in an MDI situation where MDI children have their own menu or
toolbar, those controls will not be translated.
- Procedure name, Original Text and Translated text are limited by the
field size in the two dictionary tables. You can adjust these field
sizes up to 255 chars for each. Since both the procedure name and
original/translation text appear in the keys In the AnyTextLocal
table, and because some file drivers limit the overall key length, the
shipping default length has been set to 50 for the procedure name and
200 for the text. This can be adjusted (depending on what your
preferred file driver allows) up to a maximum of 255 chars in each
field.
- The size of the control on the window (for most controls) does not
grow based on the text. Certainly the space assigned to controls does
not change. So some work may be required at the screen design level to
accommodate longer-than-designed-for text.
- The TextCache object will store (by default) 5000 items before doing
an automatic clean of the cache. This can be set in embed code to a
higher (or lower) value if preferred;
AnyTextCache.RecordsLimit = whatever
AnyTextCache is a global object shared by all the windows, so this
only has to be set once.
- Maximum columns per listbox (where the headers will be translated)
is 255. This is set as an equate in AnyText.Inc.
If a larger number is desirable please contact us.
- Different languages may contain different characters. In order to
get different characters you may need to change the font in your
application to a different Character Set. AnyText does not change the
font or character set, so if you are using languages with alternate
character sets you will need some other tool to change the Charset. We
recommend AnyFont
for this task.
Examples
There are a number of examples that ship with AnyText;
- ABC
An example of using AnyText in a single ABC Template based EXE program
- Legacy
An example of using AnyText in a single Clarion Template based EXE
program
- MultiDLLABC
An example of using AnyText in an ABC program, comprising of a Data
DLL, an EXE and other DLL's.
- MultiDLLLegacy
An example of using AnyText in a Clarion Template program, comprising
of a Data DLL, an EXE and other DLL's.
- ABCWithMessageBox
Similar to the ABC example, but using MessageBox (version 2.22 or
later) to translate any MESSAGE calls.
Support
Your questions, comments and suggestions are welcome.
Check our web page (
www.capesoft.com)
for new versions. You can also contact us in one of the following ways:
CapeSoft Support |
Support Page |
Find support page with various options here |
Email |
|
Telephone |
+27 87 828 0123 |
Distribution
No additional files are required for shipping.
FAQs
Compile Errors
You have not downloaded and installed GUTs.
You must also add the GUTs global extension to the application.
Template Reference
The Global AnyText Extension
General Tab
Disable All AnyText Features
This disables the AnyText template, and no AnyText template code will
be generated into the application. This is useful for debugging.
Options Tab
HotKey
The key that the user will press to invoke translations. The default
is CtrlF10 (which may display as 633).
Translate Window
The name of the TranslateWindow procedure. Defaults to
AnyTextTranslate
AnyTextSetLanguage Procedure
The name of the procedure that sets the FileName variables. Default is
AnyTextSetLanguage. This procedure is called on program startup. You
can call it yourself whenever is appropriate for the language file to
change (for example if a user, with a specific language set logs in).
AnyTextSetFileNames Procedure
Default is AnyTextSetFileNames. This is the name of the procedure
which sets the file name variables for the Local Translation File and
global Translation File.
Global Table
The name of the table in the dictionary which will hold the
global-level translations. Usually AnyTextGlobal.
Local Table
The name of the table in the dictionary which will hold the
local-level translations. Usually AnyTextLocal.
Disable IF
An expression, which if true, turns off translations. This can be
useful for debugging at runtime. Defaults to
command('/notranslations')
which means that if you run your program with the command-line switch
/notranslations then translations are
disabled. Also you can set this switch in your code using the Clarion
SETCOMMAND call.
Date Pictures can be translated on browses and forms. This is done via
the _DatePicture_ item in the translation file. This can be translated
globally or locally.
If this item is not set in the translation file, then the Default Date
Picture is used.
If the Default Date Picture is not set (ie this option in the template
is blank) and the item is not set in the translation file, then the
date picture is left as-is.
If this is on the code is added to the ErrorClass object which
translates messages before they are sent to the MESSAGE procedure.
This option is on by default, but if you wish to suppress this
behavior then you can turn it off here. Note that you may need to fix
a bug in the ABERROR.INC file in order for this feature to work. For
more information see
ABC Error Class.
In a Multi-DLL system, with many apps, this option is available in the
EXE app only. The whole system follows the setting as set in the Exe
app.
Web (NetTalk) Tab
Cache the following Languages
List the languages here that the web server will support. These are
fixed values, so do not use quotes.
Multi-DLL Tab
This is part of a Multi-DLL program
Tick this on if this app is part of a Multi-DLL suite of apps. This
should be on for all DLL and all EXE apps in the suite.
Export Class from this DLL
Tick this on if this is the Data DLL app in your Multi-DLL suite.
Leave it off for all other DLL's and EXE's.
Classes Tab
TextCache Object
AnyText caches common translations in memory to speed up performance.
The cache is a global, unthreaded object. This setting is the name of
that object. The default is AnyTextCache.
TextCache Class
This is the name of the AnyTextCache class. The default is TextCache.
The Local AnyText Extension
General Tab
Disable this template
If this is on then the AnyText object is not generated into the
window, and hence translation is disabled for this window.
Classes Tab
Object Name
The name of the AnyText object. Defaults to ThisAnyText.
Class Name
The name of the AnyText class. Defaults to AnyText.
Class Reference
AnyText Object Architecture
AnyText uses
GUTS.
GUTS is a global, unthreaded queue of references (in this case AnyText
references) which allows all AnyText objects to be notified when a
translation is changed, or a different language is selected.
The AnyText template creates an instance of the
TextCache
class in your application. This instance is Global and Unthreaded. A
pointer to this global glass is passed into each local AnyText object
via the INIT method.
Each Window and Report procedure gets an instance of the
AnyText
class called (by default) ThisAnyText.
AnyText Class Method Reference
Methods
Construct
Construct()
Description
Automatically called when the object comes into scope.
Sets the RecordsLimit property to the default cache size.
Parameters
None
Return Value
None.
See Also
Destruct
Methods
Destruct
Destruct()
Description
Automatically called when the object goes out of scope.
Parameters
None
Return Value
None.
See Also
Construct
Methods
AddControl
AddControl(Long
pControl, Long pTarget, Long pSuppressed=False)
Description
Adds a control to the
ControlQueue
property.
Parameters
Parameter |
Description |
pControl |
The Field Equate number of the control to add. |
pTarget |
The target structure of the owner of the control. One of
At:TargetWindow or at:TargetReport. Will be stored as
At:TargetMenu if the control is a Menu or MenuItem control. |
pSuppressed |
Set to true if this control may not be translated by the end
user. Good for product names, Brand names, and so on. |
Return Value
None.
See Also
AddOtherText
Methods
AddGlobal
AddGlobal(String
pOriginal, String pTranslation)
Description
Adds a record into the
GlobalFile table.
Parameters
Parameter |
Description |
pOriginal |
The original text. |
pTranslation |
The translated form of the text. |
Return Value
Long. The Clarion standard error code returned by the
ADD. 0 indicates success. If an Error does occur then the
ErrorTrap method will be called.
See Also
GetGlobal,
PutGlobal
Methods
AddOtherText
AddOtherText(String
pStr)
Description
Adds other text to the ControlQueue property. This text is not a Window
or Report, but is used by the procedure. Adding it using this method
means it shows up on the Local Translation window.
Parameters
Parameter |
Description |
pStr |
The text used by the procedure |
Return Value
None.
See Also
AddControl
Methods
CleanForSort
CleanForSort(string
pStr)
Description
In order to sort text without regard for the & sign, an additional
column in the table is used. This method removes all & characters
from the string, and is used when priming that sort field.
Parameters
Parameter |
Description |
pStr |
The text, possibly including the & character. |
Return Value
String: The clean version of the string.
See Also
Methods
CloseFiles
CloseFiles()
Description
Closes the GlobalTable and LocalTable
tables. Files are opened as required in the Translate method.
They are only closed if the thread ends, or the Language changes.
Parameters
None
Return Value
None.
See Also
Translate
Methods
ErrorTrap
ErrorTrap(String
pStr)
Description
This method is called when an error occurs in the class. By default the
text is passed to the debug output (Debugview.Exe)
Parameters
Parameter |
Description |
pStr |
A text description of the error. |
Return Value
None.
See Also
Trace
Methods
GetDatePic
GetDatePic(String
pStr)
Description
Returns the date picture for this language - this is stored in the
translation file as the translation for _DatePicture_
Parameters
None
Return Value
String. A Clarion date picture. If the value is not set in the
translation file, then @D6 is used as the default.
See Also
Methods
GetGlobal
GetGlobal(String
pOriginal)
Description
Gets a record from the
GlobalFile.
Parameters
Parameter |
Description |
pOriginal |
The original text of the record to fetch. |
Return Value
Long. The Clarion standard error code returned by the
GET. 0 indicates success.
See Also
AddGlobal,
GetLocal
Methods
GetLocal
GetLocal(String
pOriginal)
Description
Gets a record from the
LocalFile.
Parameters
Parameter |
Description |
pOriginal |
The original text of the record to fetch. |
Return Value
Long. The Clarion standard error code returned by the
GET. 0 indicates success.
See Also
PutLocal
Methods
Init
Init(TextCache
pTextCache,<Guts pGuts>, File pLocal, File pGlobal, string
pProcedure)
Description
Gets a record from the
LocalFile.
Parameters
Parameter |
Description |
pTextCache |
A pointer to the global TextCache object. This cache is
(safely) shared across multiple threads. |
pGuts [optional] |
A pointer to the global GUTS object. Used to alert other
windows in the application when the translation table is
updated, or when the user selects a different language. |
pLocal |
The table containing the Local translations. |
pGlobal |
The table containing the Global translations. |
pProcedure |
The name of this procedure (used to identify local
translations) |
Return Value
None
See Also
LinkObjectToFiles, SetWindow, SetReport
Methods
LinkObjectToFiles
LinkObjectToFiles()
Description
Gets a record from the LocalFile.
Parameters
None
Return Value
None
See Also
Init
Methods
PutGlobal
PutGlobal(String
pOriginal, String pTranslation)
Description
Updates a record in the Global table. If the record does not exist then
the
AddGlobal method is automatically used
to add the record. Thus a call to
PutGlobal could
be described as an "update or add record" call. The text in the cache is
also updated.
Parameters
Parameter |
Description |
pOriginal |
The original text of the record to update. |
pTranslation |
The translated text for the record |
Return Value
Long. The Clarion standard error code returned by the
ADD or
PUT. 0 indicates success.
If an Error does occur then the
ErrorTrap method
will be called.
See Also
GetGlobal,
AddGlobal,
Methods
PutLocal
PutLocal(String
pOriginal, String pTranslation)
Description
Updates a record in the Local table. If the record does not exist
thenthe record is automatically added to the table. Thus a call to
PutLocal could be described as an "update or
add record" call. The text in the cache is also updated. If the
pTranslation parameter is an empty string then the record is deleted
from the table.
Parameters
Parameter |
Description |
pOriginal |
The original text of the record to update. |
pTranslation |
The translated text for the record |
Return Value
Long. The Clarion standard error code returned by the
ADD or
PUT. 0 indicates success.
If an Error does occur then the
ErrorTrap method
will be called.
See Also
GetLocal
Methods
RefreshFile
RefreshFile()
Description
This method is not typically used, and is included for files created
with AnyText version 1 (which was not publically available.) It is used
to populate the TranslationSort, and OriginalSort fields in the GlobalFile.
Parameters
None
Return Value
None
Methods
SetReport
SetReport(Report
pReport)
Description
Sets the
Report property to the passed
parameter. This method must be called before the TranslateReport method
can be called.
Parameters
Parameter |
Description |
pReport |
A pointer to a Report structure. |
Return Value
None
See Also
SetWindow, TranslateReport
Methods
SetWindow
SetWindow(Window
pWindow)
Description
Sets the
Window property to the passed
parameter. This method should be called before the
TranslateWindow
method can be called.
Parameters
Parameter |
Description |
pWindow |
A pointer to a Window structure. |
Return Value
None
See Also
SetReport, TranslateWindow
Methods
Trace
Trace(String pStr)
Description
Passes the parameter to Debugview.Exe. Used for debugging.
Parameters
Parameter |
Description |
pStr |
The string to pass to Debugview. |
Return Value
None
Methods
Translate
Translate(String
pOriginal, Long pOptions=At:TargetOther)
Description
Returns a translation, if one exists, for the Original string. The
LocalCache and Global cache are checked first, followed by the LocalFile
and then the GlobalFile.
Parameters
Parameter |
Description |
pOriginal |
The text to translate |
pOptions [optional] |
One or more of the following options added together.
AT:Nocache: The cache is not checked
.
AT:GlobalOnly: The LocalFile is not
checked for a translation.
AT:LocalOnly: The Globalfile is not
checked for a translation.
AT:TargetOther: The text is not from
a window or report.
0 : None of the above. |
Return Value
String. The translation string for the original text. If no translation
is found then the original text is returned.
See Also
TranslateWindow, TranslateReport, TranslateControl
AnyText Class Property Reference
Property |
Type |
Description |
General Properties |
Caption |
String |
The caption of the window, as originally set by the window
designer. |
ChangeFiles |
Long |
Set to true if the files should be closed and opened the next
time files are accessed on the procedure thread. This is caused by
the |
ControlQueue |
&ControlQueueType |
A queue of type ControlQueueType, which contains all the
controls on the window and report. |
DatePic |
String |
The preferred date picture to use in this procedure. |
DontTranslateCaption |
Long |
If set to true then the Window caption is not translated. This
is useful on windows (like say the About window) that contain the
product name in the Caption. |
FilesOnThread |
Long |
Contains the thread the code was running on when the File
properties were last set using the LinkObjectToFiles method. |
Inited |
Long |
Set to true once the INIT method has been called for the object. |
Guts |
&Guts |
A pointer to the global, unthreaded, GUTS object used by this
object. |
GutsId |
Long |
The ID returned by the GUTS object after registering this object
with GUTS. |
Proc |
String |
The name of the procedure which instantiated this object. |
Report |
&Report |
A pointer to the report structure in the procedure, if it
exists. |
TextCache |
&TextCache |
A pointer to a global, unthreaded instance of the TextCache
class. |
Thread |
Long |
The Thread of the procedure which instantiated this object. |
TranslationDisabled |
Long |
If set to true then translation is disabled for this window.
This property is set automatically to true if the command line
switch /notranslations is set. You
can thus set translations off globally in the program using
SETCOMMAND(' /notranslations') |
Window |
&Window |
A pointer to the window structure in the procedure, if it
exists. |
Properties related to the Local Translation
Table
These properties are set by the LinkObjectToFiles method.
With the exception of the first property, they refer to the tables
on the currently executing thread. If the currently executing
thread changes then LinkObjectToFiles is called. |
_LocalFile0 |
&File |
A pointer to the Local Table, as returned by INSTANCE(0). |
LocalFile |
&File |
A pointer to the Local Table on the currently executing thread. |
lProcOrigKey |
&Key |
A pointer to a key, containing the Procedure name and Original
Text. |
lnProcedure |
String |
The name of the procedure field - defaults to localProcedure |
lnOriginal |
String |
The name of the original field - defaults to original |
lnTranslation |
String |
The name of the translation field - defaults to translation |
lfProcedure |
ANY |
The LocalProcedure field in the table record. |
lfOriginal |
ANY |
The Original field in the table record. |
lfTranslation |
ANY |
The Translation field in the table record. |
lProcedure |
Long |
The field number of the procedure field in the record. |
lOriginal |
Long |
The field number of the original field in the record. |
lTranslation |
Long |
The field number of the translation field in the record. |
Properties related to the Global Translation
Table
These properties are set by the LinkObjectToFiles method.
With the exception of the first property, they refer to the tables
on the currently executing thread. If the currently executing
thread changes then LinkObjectToFiles is called. |
_GlobalFile0 |
&File |
A pointer to the Global Table, as returned by INSTANCE(0). |
GlobalFile |
&File |
A pointer to the Global Table on the currently executing thread. |
gOrigKey |
&Key |
A pointer to a key containing the original
text. |
gnOriginal |
String |
The name of the original field - defaults to original |
gnOriginalSort |
String |
The name of the originalsort field - defaults to originalsort |
gnTranslation |
String |
The name of the translation field - defaults to translation |
gnTranslationSort |
String |
The name of the translationsort field - defaults to
translationsort |
gfOriginal |
ANY |
The Original field in the table record. |
gfOriginalSort |
ANY |
The OriginalSort field in the table record. |
gfTranslation |
ANY |
The Translation field in the table record. |
gfTranslationSort |
ANY |
The TranslationSort field in the table record. |
gOriginal |
Long |
The field number of the original field in the record. |
gOriginalSort |
Long |
The field number of the originalsort field in the record. |
gTranslation |
Long |
The field number of the translation field in the record. |
gTranslationSort |
Long |
The field number of the translationsort field in the record. |
TextCache Class Method Reference
Methods
Construct
Construct()
Description
Automatically called when the object comes into scope.
Sets the RecordsLimit property to the default cache size.
Parameters
None
Return Value
None.
See Also
Destruct
Methods
Destruct
Destruct()
Description
Automatically called when the object goes out of scope.
Parameters
None
Return Value
None
See Also
Construct
Methods
Delete
Delete(String
pProc,String pOriginal)
Description
Deletes a record, if it exists, from the cache.
Parameters
Parameter |
Description |
pProc |
The name of the procedure |
pOriginal |
The original text |
Return Value
Long. Returns
cache:ok
Example
ThisAnyText.TextCache.Delete(ThisAnyText.Proc,'Insert')
See Also
Put,
Get,
Free
Methods
Free
Free(Long
pCacheNumber=0)
Description
Deletes all the records in the cache.
Parameters
Parameter |
Description |
pCacheNumber |
If multiple calls to Free are made, with the same cacheNumber,
then only the first call actually clears the queue. Subsequent
calls with the same number (other than 0) are ignored. |
Return Value
None
See Also
Get,
Put,
Delete
Methods
Get
Get(String
pProc,String pOriginal,*String pTranslation)
Description
Gets a record, if it exists, from the cache.
Parameters
Parameter |
Description |
pProc |
The name of the procedure |
pOriginal |
The original text |
pTranslation |
The translation of the text. |
Return Value
Long. Returns
cache:NotFound if no record
was found,
cache:ok if a record was found.
If a record was found the value in
pTranslation is
updated, otherwise
pTranslation is
unaltered.
Example
ThisAnyText.TextCache.Get(ThisAnyText.Proc,'Insert',InsertText)
See Also
Put,
Delete,
Free
Methods
Put
Put(String
pProc,String pOriginal,String pTranslation)
Description
Adds a record to the cache. If it already exists then it is updated.
Parameters
Parameter |
Description |
pProc |
The name of the procedure |
pOriginal |
The original text |
pTranslation |
The translation of the text. |
Return Value
Long. Returns
cache:ok
Example
ThisAnyText.TextCache.Get(ThisAnyText.Proc,'Insert',InsertText)
See Also
Get,
Delete,
Free
Methods
Release
Release(Long pId)
Description
Used when access to the queue is required. Must be paired with one, and
only one, call to Wait.
Parameters
Parameter |
Description |
pId |
Used to identify where the method is called from. Useful for
debugging when unbalanced Wait/Release calls occur. |
Return Value
None
See Also
Wait
Methods
Trace
Trace(String pStr)
Description
Used for debugging. Sends a string to
DebugView.
Parameters
Parameter |
Description |
pStr |
The contents of the string are sent to DebugView. |
Return Value
None
Methods
Wait
Wait(Long pId)
Description
Used when access to the queue is required. Must be paired with one, and
only one, call to Release.
Parameters
Parameter |
Description |
pId |
Used to identify where the method is called from. Useful for
debugging when unbalanced Wait/Release calls occur. |
Return Value
None
See Also
Release
TextCache Class Property Reference
Property |
Type |
Description |
TextQueue |
&TextQueueType |
A queue which contains the procedure name, original text, and
translated text in memory. Since the object is global, unthreaded,
the queue is also global, unthreaded. |
RecordsLimit |
Long |
The number of records allowed to be in the queue. When the cache
exceeds this limit the cache is cleared, and starts caching again.
The default cache limit is 5000 records. |
cs |
ICriticalSection |
A Critical Section to prevent contention on the TextQueue. |
CacheNumber |
Long |
A number which is assigned to the current queue instance. Used
as an optimization so that if multiple threads issue a Clear Cache
instruction at the same time, then the first call clears the
threads, but the other calls (with the same number) are ignored. |
License & Copyright
This template is copyright 2023 by CapeSoft Software.
None of the included files may be distributed. Your programs which use
AnyText can be distributed without any royalties.
This product is provided as-is. Use it entirely at your own risk. Use of
this product implies your acceptance of this, along with the recognition
of the copyright stated above. In no way will CapeSoft Software, their
employees or affiliates be liable in any way for any damages or losses you
may incur as a direct or indirect result of using this product.
Version History
Note: If you are
upgrading from a version prior to 2.10, to version 2.10 or later, then
please read the section on
Upgrading
to version 2.10 or later
2.40 - 6 July 2023
- Fix: ClarionLegacy TXA for importing functions wasn't right.
2.39 - 21 April 2023
2.38 - 17 April 2023
2.37 - 16 February 2022
2.36 - 12 October 2021
- _DatePicture_ value now applies to browse columns as well as form
fields.
2.35 - 24 May 2021
2.34 - 15 April 2021
- Fix: Pictures on STRING controls were not working correctly.
- Add: Legacy Reports. If you hold the SHIFT key when opening the
report procedure, then the Translate window will immediately appear.
2.33 - 27 August 2020
- Fix: Template used fixed file names in GlobalErrors.SubString. Now
uses tables as specified by options.
2.32 - 16 July 2020
- Fix: Removed "left" from text being translated, so text with
leading spaces can be translated.
- Fix: In legacy apps, code for webhandler could be injected into
wrong translate method
2.31 - 14 September 2018
- Add: Clarion 11 to install.
2.30 - 16 January 2018
- Change: Buttons on the not-topmost window are not translated until
the window is the topmost window. This works-around a possible
instability in the RTL.
- Fix: Do not handle a GUTS event if a GUTS event is currently being
handled.
2.29 - 2 August 2017
- Add: Template Extension Support for Source procedures.
2.27 - 17 May 2017
2.26 - 17 May 2017
- Fix: Template error -Suppress controls only worked if No window
Title was on. (Thanks to Rick Martin.)
2.25 - 20 Feb 2017
2.24 - 21 July 2016
- Fix: Legacy apps did not call SetFileNames on the start of every
thread.
2.23 - 30 June 2016
- Add: Support for translating "Pictures" as well as text. For
example currency pics, date and time formats, and so on.
- Add : New property TranslationDisabled
- Add: ListPicture, Picture to ControlQueueType.
- Fix: Cache:language objects exported from data DLL.
2.22 - 8 May 2015
- Fix: Template changes for 2.21 were not included in the build.
2.21 - 7 May 2015
- Add: Support for Group Header text in a list control.
- Change: Internal change to reduce the memory consumed for each
window.
- Fix: EditInPlace template does not Cycle Alert events which are on
a non-alerted column. Makes Locator on Global translation window
work.
2.20 - 13 April 2015
- TXA's for external procedures was missing AnyTextSetFileNames
procedure
- If "Set File Names Procedure" global extension setting was equal
to the "Set Language Procedure" setting then a GPF would occur.
2.19 - 9 March 2015
- Corrected Utility Template
2.18 - 25 February 2015
2.17 - 5 February 2015
- Add: Global Extension Setting to set name of AnyTextSetFileNames
procedure.
- Add: SetFileNames and TakeEvent methods.
- Change: at:NewLanguage event changed from Event:User+1 to
Event:User+191
- Fix: Filename changes did not occur on threads that were already
open
2.16 - 26 November 2014
- Add: Ability to suppress controls on the local extension.
- Add: Ability to suppress translation of the window caption.
- Fix: If the window caption was being set by the Form template (in
the Ask method) then that happened after the call to Translate.
- Internal: AddControl got a new
parameter.
2.15 - 22 October 2014
- Added support for CPCS Legacy Reports.
2.14 - 11 July 2014
- Update: Current Date and Time on (other) reports was not
translating correctly.
2.13 - 2 May 2014
- Update: Current Date and Time on reports was not translating
correctly.
2.12 - 17 April 2014
- Update: TXA's updated to be better compatible with Clarion 8 (they
preferred Clarion 9).
2.11 - 18 February 2014
- Update: Examples updated to Clarion 8
- Fix: New TXA's did not import into Clarion 8.
- Fix: TranslateReport did not get called for all reports.
- Added Report to Legacy Example
- Updated Upgrading doc for Legacy.
2.10 - 7 February 2014
2.07 - 23 January 2014
2.06 - 13 January 2014
- Updated template to Cape 4.06 level. Should make some Legacy
generation problems go away.
2.05 - 6 January 2014
- Updated template to Cape 4.05 level. Should make some Legacy
generation problems go away.
2.04 - 17 December 2013
- Add: New Method GetDatePic
2.03 - 5 December 2013
- Added support for Radio options which set a STRING field, and
where the Value simply defaults to the contents of the Option
string. The value for the radio button is now explicitly set to the
"pre-translated" value, not the translated value.
2.02 - 12 November 2013
- Buttons on toolbar were not being translated.
- Excess TRACE statements removed from class
- Expanded technical sections in documentation - property reference
done, method reference still todo.
2.01 - 12 November 2013
- Update to Examples and TXA's.
- Better support for Legacy and MessageBox.
- Recommended use with MessageBox 2.22 or later.
2.00 - 8 November 2013