Glade3 and changing strings within the GUI - user-interface
I need GUI in which I have a number of strings regularly changing for instance in a multilanguage environment. So how can I enter these strings as variables instead as constants and still use the Gtkbuilder routine and be able to change the strings runtime. If that is impossible how can I tranlate the .glade file to an ADA file that doe the same.
Edit: I don't think the answer you gave me are real answers to my question, because I want the GUI changing languages without rebuilding the program, i.e. only one version of the program and not a version per language. Second point is that however I have not found then yet, but it can be possible that in other cases, it can be nice to have variables I can change during running the program instead of constants.
GtkAda https://www.AdaCore.com/gtkada should have a sufficiently complete coverage of the Gtk featureset for internationalization of strings https://developer.gnome.org/gtkmm-tutorial/stable/chapter-internationalization.html.en via POT & PO files as explained well https://www.drupal.org/community/contributor-guide/reference-information/localize-drupal-org/working-with-offline/po-and by the Drupal community for any UI that ultimately borrows from GNU gettext's leadership http://www.gnu.org/software/gettext/manual/html_node/PO-Files.html on this POT & PO file approach to internationalization of strings.
GtkAda has support
https://docs.AdaCore.com/live/wave/gtkada/html/gtkada_ug/glade.html
for Glade 3.
Then gate3
https://SourceForge.net/projects/lorenz/files should produce a GtkAda
code sketch in Ada source code.
Here are the steps for re-creating a minimal example on Debian. I can't tell how portable this example actually is to other OS'es, but at least it's some starting point. Working with locales is not straight forward IMHO. Most of the mechanics in internationalization in GtkAda revolves around the package gtkada-intl.ads.
First of all I enabled the locales of interest by running
$ sudo dpkg-reconfigure locales
I wanted test translations for Dutch and French so I selected fr_FR.UTF-8 and nl_NL.UTF-8 in addition to those already selected (like, in my case, en_US.UTF-8). I also kept en_US.UTF-8 as the default locale. This was my locale configuration after the reconfiguration:
$ locale -a
C
C.UTF-8
en_US.utf8
fr_FR.utf8
nl_NL.utf8
POSIX
I then created a simple Glade UI file with a window (with title "English") containing one label (with text "Hello world!"). I made sure that all the texts were marked "translatable". This is a property attribute that can be enabled via the "Edit Text" dialog box. This dialog box can be accessed by clicking the button on the right side of the text area where you enter, for example, the label text.
example.glade (note in particular the translatable="yes" attributes)
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<object class="GtkWindow" id="Window">
<property name="can_focus">False</property>
<property name="title" translatable="yes">English</property>
<property name="window_position">center</property>
<property name="default_width">300</property>
<property name="default_height">60</property>
<child>
<object class="GtkLabel" id="Label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Hello world!</property>
</object>
</child>
</object>
</interface>
I now created two translation files (.po files) as shown below: one for Dutch and one for French. Note how the msgid matches the window title text and label text.
translations_nl.po
msgid "English"
msgstr "Nederlands"
msgid "Hello world!"
msgstr "Hallo wereld!"
translations_fr.po
msgid "English"
msgstr "Français"
msgid "Hello world!"
msgstr "Bonjour le monde!"
These files must be converted to machine readable files using the msgfmt tool that ships with GtkAda (see GtkAda's bin directory), i.e.
$ msgfmt translations_nl.po -o messages.mo
I finally created a project and the required Ada sources using GNAT Studio CE 2020 (sources are at the end of this answer). I made sure all files were organized as follows:
example/
+- example.glade
+- default.gpr
+- obj/
| +- <various build files>
+- src/
| +- main.adb
| +- translation_demo.ads
| +- translation_demo.adb
| +- po/
| +- translations_nl.po
| +- translations_fr.po
+- locales/
+- nl_NL/
| +- LC_MESSAGES/
| +- messages.mo (generated using msgfmt)
+- fr_FR/
+- LC_MESSAGES/
+- messages.mo (generated using msgfmt)
If all goes well, then after building and running the executable, the proper translations will appear in the UI depending on the setting of the LANGUAGE environment variable.
Note that in this example I set the LANGUAGE environment variable from within the program using the Ada.Environment_Variables.Set procedure (see main.adb). This is only to show how to control the language from within your program at application startup (e.g. in case you want to control the language via a configuration file read at startup; an approach that might be needed on OS'es other than Linux). On Debian (and Linux in general), the LANGUAGE environment variable is typically set by the OS on behalf of the user (check output of the env command).
As an alternative, you might also try the example without setting the environment variable in main.adb and check the result if you start the program via
LANGUAGE=nl_NL ./obj/main
or
LANGUAGE=fr_FR ./obj/main.adb
In conclusion, note that the process of getting this to work is a precise process: Debian must know the locales nl_NL.UTF-8 and fr_FR.UTF-8, the .mo files must be available in the correct directories and the LANGUAGE environment variable must be set. Furthermore, because I use relative paths in the example code, the application must be started from project root directory, i.e.
$ ./obj/main
If something is wrong, then the translation will just not happen and no error and or warning will be provided.
main.adb
with Ada.Environment_Variables;
with Translation_Demo;
procedure Main is
NL : constant string := "nl_NL:nl";
FR : constant String := "fr_FR:fr";
begin
-- Set environment varianble.
Ada.Environment_Variables.Set ("LANGUAGE", NL);
Translation_Demo.Run;
end Main;
translation_demo.ads
package Translation_Demo is
procedure Run;
end Translation_Demo;
translation_demo.adb
with Ada.Text_IO;
with Gtk.Main;
with Gtk.Widget;
with Gtk.Builder;
with Gtk.Window;
with Gtk.Button;
with Gtkada.Intl;
with Glib; use Glib;
with Glib.Error; use Glib.Error;
package body Translation_Demo is
-- Name of the .mo file without extention.
Text_Domain : constant String := "messages";
-- (Relative) location of the <lang>/LC_MESSAGES/<domain>.mo files.
Text_Domain_Dir : constant String := "./locale";
-- (Relative) location of the Glade file.
Glade_File : constant String := "./example.glade";
Builder : Gtk.Builder.Gtk_Builder;
Window : Gtk.Window.Gtk_Window;
procedure Destroy_Event_Callback
(Widget : access Gtk.Widget.Gtk_Widget_Record'Class);
---------
-- Run --
---------
procedure Run is
use Gtk.Builder;
use Gtk.Window;
Success : GUint;
Error : aliased GError;
begin
-- Initialize GtkAda.
Gtk.Main.Init;
-- Setup the translation domain and directory where to find the .mo files.
Gtkada.Intl.Setlocale;
Gtkada.Intl.Text_Domain (Text_Domain);
Gtkada.Intl.Bind_Text_Domain (Text_Domain, Text_Domain_Dir);
-- Construct a Gtk_Builder instance and load our UI description.
Gtk_New (Builder);
-- Set the translation domain for the Glade file.
Builder.Set_Translation_Domain (Text_Domain);
-- Read the Glade file.
Success := Builder.Add_From_File (Glade_File, Error'Access);
if Success = 0 then
Ada.Text_IO.Put_Line ("failed to read Glade file");
Error_Free (Error);
Gtk.Main.Main_Quit;
end if;
-- Window
Window := Gtk_Window (Builder.Get_Object ("Window"));
Window.On_Destroy (Destroy_Event_Callback'Access);
Window.Show_All;
-- Start the main event loop
Gtk.Main.Main;
end Run;
----------------------------
-- Destroy_Event_Callback --
----------------------------
procedure Destroy_Event_Callback
(Widget : access Gtk.Widget.Gtk_Widget_Record'Class)
is
begin
Gtk.Main.Main_Quit;
end Destroy_Event_Callback;
end Translation_Demo;
default.gpr
with "gtkada";
project Default is
for Source_Dirs use ("src");
for Object_Dir use "obj";
for Main use ("main.adb");
end Default;
Related
How to add Walk/1 to jq 1.5 installed by Chocolatey NuGet on Windows 10
I have been automating some data processing within a batch environment using jq. I recently ran into a use case where I need to recursively apply fromjson to strings inside of my json data. Unfortunately jq 1.5 does not have the walk/1 function natively so I need to add it. I am having trouble finding the correct location to add the code. I need to add this code: def walk(f): . as $in | if type == "object" then reduce keys_unsorted[] as $key ( {}; . + { ($key): ($in[$key] | walk(f)) } ) | f elif type == "array" then map( walk(f) ) | f else f end; To my initialization file, but I cannot find it. Does anyone know where the initialization fold is when jq is installed with chocolatey?
The standard installation does not include a .jq file or .jq directory. There are some good reasons not to use ~/.jq as a file, but setting those aside for the time being, if you want to use ~/.jq as a startup file, just create it. You might need to check (or alter) the HOME environment variable. That is, jq's idea of where to look depends on HOME. You might find you need to set or reset the environment variable HOME. The main reason for not using ~/.jq as a startup file is that if ~/.jq is a directory, jq's module system will take note of that. So you may simply want to use the module system, though this has the disadvantage that you'll need to include an include MODULE; or import MODULE as _; directive in your scripts. You should consider upgrading to jq 1.6. If this is not possible with choco, you can snarf the relevant jq.exe from Appveyor -- see https://github.com/stedolan/jq/wiki/Installation#windows-using-appveyor There is in my opinion room for improvement here -- you might like to repurpose your issue at https://github.com/stedolan/jq/issues/1955 with that in mind.
nesting environment-variables on Windows
I have a very simply (maybee very stupid) question regarding the Windows 7 (Path)-Variables. Until Windows 10 the Gui looks very ugly und uncomfortable (short Textboxes for large Inputs) I Use custom variables to short down my view. For example: envi -->C:\Program Files (x86)\MiKTeX 2.9\miktex\bin;C:\Program Files (x86)\Skype\Phone\;C:\Program Files\TortoiseSVN\bin; So I can use it in path like this: path -->"[...];%envi%;" Now I tried to do the same with the default settet part end extract the following: sys --> %SystemRoot%\system32;%SystemRoot%;%SystemRoot%\System32\Wbem;%SystemRoot%\System32\WindowsPowerShell\v1.0\; But THAT does not work: path --> ;%sys%; %envi%; [...] even if I type "echon %sys%" it seems ok. But if I type "echo %path% it will resolve every variable instead of %sys%. Now my question: Is that impossible coursed by nested variables (%sys% contains %SystemRoot%?) Or may there be another problem? Greatings Oekel
How to print japanese text in PDF along with English characters using rghost?
I want to generate a PDF with English characters along with some Japanese characters also; using Rghost but unable to text. There is a ruby config file in Ruby 1.9.3, external encoding was ascii-8 bit, which i changed it to UTF-8 still no difference. The Japanese character is “アナンド” but while printing in PDF, its coming as “ã¢ãã³ã”. What can be the probable solutions ? Ruby version : 1.9.3 Rghost : 0.9.5 OS : Windows 7
Rghost does not ship with Japanese font by default. If you have installed an external font, you can double check if it's installed properly by code below to generate catalog information RGhost::Config.environment_fonts.render :pdf, :filename => 'mycatalog.pdf' If you have not installed any external fonts, then you can do so by searching for .ttf fonts (External fonts such as TTF,PFA,PFB are supported font format). Here's one such link After downloading the file follow the steps below: Step 1: Create a directory and copy the fonts to the created directory mkdir /temp/fontfolder Step 2: Create a file with filename Fontmap Edit the file to include the following lines /Japanesefont1 (aquafont.ttf); /Japanesefont2 (arialuni.ttf); /Japanesefont3 (Cyberbit.ttf); So that the file directory structure should look like |-- temp | |-- fontfolder | | |-- Japanesefont1 | | |-- Japanesefont2 | | |-- Japanesefont3 Step 4: Load the fonts RGhost::Config::GS[:extensions] << '/temp/fontfolder'
abbyy finereader.exe looking for cmd commands to use in other programms
I just bought abbyy finereader 11 copr to rund it from another programm, but i cant find any commends to be used for finereader.exe. so without any commands it simply openens and scans but i need to tell it where to save the document and how to name and the to close the app again, also it would be cool to have it as a background task.
While doing my OCR research project, found one. Works with FR12, didn't tested with earlier versions. FineCmd.exe PRESS2.TIFF /lang Mixed /out C:\temp\result.txt /quit general command line: <open_keys/scanning> [<recognition_keys>] [<export_keys>] <open_keys/scanning> ::= ImageFiles | /scan [SourceName] | /file [filename1 filename2], where ImageFiles - list of files for recognition SourceName - images source (scanner); if not specified, current is used filename.. - list of files for recognition <recognition_keys> ::= [/lang Language] [/optionsFile OptionsFileName], where Language - name of language in English (russian, greek, Mixed) OptionsFileName - path to options file <export_key> ::= /out ExportFile | /send Target, where ExportFile - name of file with extension to save file to (txt, rtf, doc, docx, xml, htm(l), xls, xlsx, ppt, pptx, pdf, dbf, csv, lit); Target - name of target app where to open (MSWord, MSExcel, WordPro, WordPerfect, StarWriter, Mail, Clipboard, WebBrowser, Acrobat, PowerPoint) This command opens FR ui, processes the file and then closes it (if you pass argument /quit). FineCmd.exe located in FR directory where you installed it
Hello I saw this msg very late but i m using ABBYY command line for 10years . I prefer ABBYY 8 because makes same good job faster and does not open any GUI . It comes with FineOCR.exe: "C:\...\ABBYY FineReader 8\FineOCR.exe" %1 /lang greek english /send MsWord It does OCR and opens MsWord . FineOCR.txt is a simple help file. Regarding ABBYY 11,12 (all versions) there is a FineCmd.exe . Using something like: "c:\...\FineReader\FineCMD.exe" %1 /lang greek english /send MsWord does what FineOCR did before (but no .txt help file)
Unfortunately, Such a professional OCR software doesn't support command line utilities. For batch processing, it offers HOT FOLDER utility inside it (from GUI). http://informationworker.ru/finereader10.en/hotfolder_and_scheduling/installandrun.htm If you want to make OCR batch processing from your program, they sell another software, called 'ABBYY Recoginition Server'. There also offer a comprehensive API for programmers : http://www.abbyy.com/ocr_sdk_windows/technical_specifications/developer_environment/ If your plan is to batch process them and write the contents to a Database, you can also do a programmatical trick to overcome such limitation, as I did recently in one of my projects (It is a bit offline-way but it is simple and works) : While parsing the files and putting them to your Database table from your program, move (or copy) them all into a folder while changing their filename to include an ID from your Database table. Then use 'hot folder' utility to OCR all files, by having the same filename with TXT extention (It is set from 'hot folder' settings). Then in your program parse the folder's text files, get their content as string, and parse the table IDS from filename, the rest is updating your table with that information.)
An year later, ABBYY does support command line usage: http://www.ocr4linux.com/en:documentation
Version 14 does not save the output file using: FineCmd.exe PRESS2.TIFF /lang Mixed /out C:\temp\result.txt /quit or FineCmd.exe PRESS2.TIFF /lang Mixed /out C:\temp\result.txt Versions 11 & 12 work well using the above commands (does save the output) but does display the GUI which can be closed using /quit. Versions 9 & 10 don't come with FineCmd.exe or FineOCR.exe. Version 8 can OCR and send the output to an application of choice but cannot save using /out. In my experience it does open the GUI.
Ctags - tag for project and library files (multiple dir with absolute path)
The below dir hierarchy is from ctags faq I could create a tag file, with absolute file path as cd ~/project ctags --file-scope=no -R `pwd` how can I create one tag file which searches my project, and the std library functions. For example, say my project is /sysint/client , and the library is at /misccomp. How can I create a tag file which searches both these dir and sub dir. (I do not want to search all under / ). DO you thinking splitting into 2 tag file is better? `-----misccomp | `... `-----sysint `-----client | `-----hdrs | `-----lib | `-----src | `-----test `-----common | `-----hdrs | `-----lib | `-----src | `-----test `-----server `-----hdrs `-----lib `-----src `-----test
I think that splitting into 2 tag file is better. Why: I think, you need to update your tags sometimes. There is faster to update smaller tag file than bigger one. So, when you edit your project, only project's tags are updated, when you edit lib - only lig's tags are updated. Instead of update all the tags every time; While I was writing plugin Indexer I found out that several tag files works not slower that single tag file. I also would recommend you to use this plugin Indexer, it will do all the work automatically. It provides painless automatic tags generation and keeps tags up-to-date. Tags file is generated in background, so you don't have to wait. Check it if you want. UPD: For detailed information, see the article: Vim: convenient code navigation for your projects, which explains the usage of Indexer + Vimprj thoroughly. Among other things, tags for libraries are explained, which is exactly what you want.