Using Qt 4.7.4 on Mac.
My *.TS files are generated and are UTF-8 using a perl script I wrote. Long story with legacy dependency. We have 13 languages we have to support including some exotic ones. Generating *.QM files out of them seems to work well. You can load the *.QM file into Qt Linguist and everything looks healthy.
Due to legacy reasons, my system langauge is “Enums”. That is, I do something like this:
QString label = tr("APP_STRINGS_MYLABEL_TEXT"); // this translates to 13 langauges...
so, an excerpt from the english .TS file for instance reads:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.0" language="en">
<defaultcodec>UTF-8</defaultcodec>
<context>
<name>MyApp</name>
<message>
<source>APP_STRINGS_MYLABEL_TEXT/source>
<translation>My Label Text In English</translation>
</message>
..
..
..
</context>
My project file has the following:
CODECFORTR = UTF-8
My main method has test code that looks like this:
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8"));
QTranslator translator;
bool empty = translator.isEmpty(); // Returns TRUE
bool loaded = translator.load("myApp_en","/Users/user/Dev/myApp/translation");
empty = translator.isEmpty(); // returns FALSE
// install the translator.
MyApp->installTranslator(&translator);
// Here comes my problem...
QString test = MyApp->trUtf8("APP_STRINGS_MYLABEL_TEXT"); // returns "APP_STRINGS_MYLABEL_TEXT"
QString test2 = MyApp->tr("APP_STRINGS_MYLABEL_TEXT"); // returns "APP_STRINGS_MYLABEL_TEXT"
As you can see, all my strings are being translated back to their original values. No real translation takes place. If you have any idea why thins might be happening, i’d appreciate the assistance. I am at a loss right now.
The culprit was the context. Since I am using generated strings from a 3rd party source, the context was always wrong. As soon as I started using the "MyApp" context explicitly in the translate API it started working.
thanks to all those who responded.
Related
I would like to translate my installer wizard (Qt Installer Framework based) in English or French (OS language depends).
I added those lines in the "installscript.qs" file :
Component.prototype.retranslateUi = function()
{
component.languageChanged();
}
and I added those in "config.xml" file :
<Installer>
...
<Translations>
<Translation>fr.qm</Translation>
</Translations>
</Installer>
But everything is ok (all long texts are translated) (in French) but the buttons like "Next", "Cancel", "Quit" are not translated (see the screenshot) :
ps: I don't want to use C++ code. (only Script or Xml)
You need to load the Qt translation file in addition to your own .qm file(s). The file is located in the translation sub-folder of your Qt installation folder (e.g. ./usr/share/qt5/translations/). For some languages it seems sufficient to load qt_xx (where XX should be replaced with your locale), but for German I had to load "qtbase_XX" to translate the Next and Cancel buttons. In example for the fr locale they are named qt_fr.qm and qtbase_fr.qm.
EDIT:
Because of the comment of John Smith I checked the Installer framework source and the framework is not capable loading more than one translation file:
See installer-framework/src/libs/installer/component.cpp
/*!
Loads the translations matching the name filters \a qms inside \a directory. Only translations
with a base name matching the current locale's name are loaded. For more information, see
\l{Translating Pages}.
*/
void Component::loadTranslations(const QDir &directory, const QStringList &qms)
So my original answer above (which would lead to a translated QWizard::CancelButton) is not working.
I got the Quit button of the Installer Frameworks translation example translated to German by correcting the de.ts file provided within the framworks source in installer-framework/src/sdk/translations
The original translation coming with the feramework is missing an &:
So, changing:
<context>
<name>QInstaller::IntroductionPage</name>
...
<message>
<source>Quit</source>
<translation>Beenden</translation>
</message>
to
<context>
<name>QInstaller::IntroductionPage</name>
...
<message>
<source>&Quit</source>
<translation>Beenden</translation>
</message>
and recompiling the Framework leads to a translated Quit button (Beenden) within the framework.
I did not tried, but studying /installer-framework/src/libs/installer/packagemanagergui.cpp should enable you to translate the Next button, too.
Adding a context may help:
function Component()
{
qsTranslate("QInstaller::IntroductionPage", "&Quit");
}
It woked after Next and Back, but could not find where to write the qsTranslate().
I'm making an application part of which is reading from an XML which stores some preferences. However, whenever I build the project, all the sources get copied but the preferences file does not! I have added the following to the .pro file -
RESOURCES += rsc.qrc
And my rsc.qrc contains
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>data/preferences.xml</file>
<file>data/gamedata.xml</file>
</qresource>
</RCC>
Now whenever I try to open preferences.xml
QFile preferences(":/data/preferences.xml");
if(!preferences.exists()){
preferences.open(QFile::WriteOnly);
preferences.write("abc");
qDebug() << "Written";
}
else {
qDebug() << "File exists";
}
Absolutely nothing gets printed and even the rest of the application stops working.
You don't use the resource part correctly in your example.
It will most likely not work because you try to write to a resource that is embedded into your executable after you have build your application. Reading is fine, but writing can't work by definition.
If you want a editable setting files, you have to distribute them along with your executable, or use a different method for reading/writing your settings like QSettings.
However using QSettings also means, that you will need to configure all your default settings in your loading function in case the values do not exist if you use the default configuration. Meaning you use registry on windows.
You have the option to force the use of a INI file format in the constructor of QSettings, this can make sense if you want to provide a default settings INI file instead of your xml files.
In case you want to store more complex data a xml file might be needed anyway, so if you want to stick with that you will need a way to copy your setting files to your build path. This can be done within your pro file with QMAKE_POST_LINK.
Example:
COPY_CMD = "$$PWD\\data\\preferences.xml $$OUT_PWD\\release\\data\\preferences.xml"
COPY_CMD = $${QMAKE_COPY} $$replace( COPY_CMD, "/", "\\" ) $$escape_expand( \\n\\t )
QMAKE_POST_LINK += $$COPY_CMD
Im running into an issue with getting TAO_idl not generating typesupportc header. the dds_TAOv2_all.sln builds just fine and all the examples generate their respectful typesupport files including the typesupportc.h file that is necessary for the typesupport_var in my IDL file.
module X {
#pragma DCPS_DATA_TYPE "X::packet"
#pragma DCPS_DATA_KEY "X::packet from"
typedef sequence<octet> binary;
struct packet {
string from;
long packet_id;
long count;
long timer;
binary mydata;
};
};
the Xtypesupportc.h was genereated before, but ever since I had to reload DDS(DDS is compiled configured etc) when I run tao_idl and openDDS_idl with the x.idl file the xtypesupportc and xtypesupports don't get created and thus I can't register the type. any obvious thing that I am doing wrong? thank you.
We're using a quintagroup.transmogrifier content import profile to load content for our automated tests (very useful). Setting the default page doesn't seem to work.
The docs suggest quintagroup.transmogrifier supports setting default pages but not whether it does for generic set-up import steps. I eventually figured out you need to add a properties.xml file into the folder of the folderish item with the following:
<?xml version="1.0" encoding="utf-8"?>
<properties>
<property name="default_page" type="string">
index
</property>
</properties>
where index is replaced by the id of the default page and also in your import.cfg you need
[transmogrifier]
pipeline =
reader
…
propertiesimporter
[reader]
…
.properties.xml = propertymanager
[propertiesimporter]
blueprint = quintagroup.transmogrifier.propertiesimporter
However this doesn't work. We're running Plone 4.1rc3 + Dexterity 1.0 and presumably it's not compatible with Dexterity. I've tracked down the bit of code in quintagroup.transmogrifier.propertymanager.PropertiesImporterSection where it is falling down:
path = item[pathkey]
obj = self.context.unrestrictedTraverse(path, None)
Here path is a unicode string and unrestrictedTraverse returns None. If you use a byte string then it returns the correct object. Is this an incompatibility with Dexterity or am I doing something wrong?
This is a bug you'll need to report with the authors of the quintagroup.transmogrifier package. Paths must always be ASCII bytestrings, not Unicode objects. All sections in collective.transmogrifier (the underlying engine that quintagroup.transmogrifier uses) encode paths to ASCII.
Here is a code snippet from collective.transmogrifier.sections.constructor for example:
type_, path = item[typekey], item[pathkey]
fti = self.ttool.getTypeInfo(type_)
if fti is None: # not an existing type
yield item; continue
path = path.encode('ASCII')
elems = path.strip('/').rsplit('/', 1)
container, id = (len(elems) == 1 and ('', elems[0]) or elems)
context = self.context.unrestrictedTraverse(container, None)
Report it to the dedicated issue tracker on Plone.org so the authors can fix it for you.
I am currently developing an ASP.NET web application and do most of my development on the road, i.e. offline. I plan to use Google/Microsoft/an-other CDN for JQuery and a couple of other script resources.
My question is, is there a straightforward way to develop with a link to a local file within the solution, but to point to the CDN upon deployment/release build?
Thank you in advance!
You could write a helper function:
public static string JQuerySource()
{
var config = WebConfigurationManager.OpenWebConfiguration("~");
var compilation = config.GetSection("system.web/compilation") as CompilationSection;
if (compilation == null || compilation.Debug)
{
// Running in Debug mode
return "/scripts/jquery.js";
}
// Running in Release mode
return "http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js";
}
That you would use like this:
<script type="text/javascript" src="<%=JQuerySource() %>"></script>
You could just change the link before you deploy...?
Update:
A simple Replace All will suffice if you have a link everywhere.
I know these might be really dumb and simple solutions, but it seems to me that your problem is too simple to require an abstraction or extra code writing.
However, if you must, this is one way of doing it:
Create an XML file that holds values:
MyAppSettings.xml
<?xml version="1.0" encoding="utf-8" ?>
<MyAppSettings>
<JqueryLink
value="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"
store1="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"
store2="../jquery.min.js"
>
</JqueryLink>
</MyAppSettings>
And get the value from the XML file:
public static string GetJqueryUrl()
{
XElement file = XElement.Load(HttpContext.Current.Server.MapPath("~/App_Data/MyAppSettings.xml"));
string jquerylink = file.Element("JqueryLink").Attribute("value");
return jquerylink;
}
You could make a helper function for the previous code and use it all over your code.
Whenever you want to switch between deploy and offline links, just change the "value" parameter in the xml file.
You can keep the attributes "store1" and "store2" in there just so I wouldn't have to remember what they are when I do switch them.