Conversation
Adds a control to the preferences dialog that allows a different translation (*.qm) file to be loaded for the main application - and the Qt libraries themselves - to change language. Also inserts some initial translation source and compiled files that I have been using to test GUI language change features for British-English and French-French they are not complete but do show the effects of changing language - in the interests of supporting other Mudlet developers with their own language interests there are also even less well populated Russian, German and Simplified Chinese but it is fairly painless to add others - there are some notes in the mudlet.pro project file and the dlgProfilePreferences constructor. Also inserts code into some other classes to respond to QEvent::LanguageChange: * TConsole * dlgIRC In passing found that there is no need for a separate "enable spellchecking" checkBox in the same tab of the options/preferences dialog as the GUI language change option is placed as the same effect can be achieved by the intrinsic checkbox that all groupBoxes have if it is enabled. This saves a small amount of space on that tab of the dialogue! === IMPORTANT === If using the Qt Creator IDE ensure that in the: "Options" dialog -> "C++" item -> "Qt Class Generation" tab the: "Support for changing language at runtime" option is CHECKED. This will ensure that the files produced by the forms compiler include the retranslateUi(QWidget *) method which needs to be called on Language Change to tell the generated forms (dialogues) to repaint their textual content in a (new) language. The source of that method is the (hidden) "ui_FORM_NAME.h" include file that our classes that work with the generated form code (made from the "src/ui/FORM_NAME.ui" form definition (XML) files that the Qt Designer plug-in/stand-alone utility creates) uses. For the record those header files are also the source of the "setupUi(QWidget *)" methods that can be seen near the top of the constructors for some of the Mudlet classes that use forms... ================= Also as part of a BugFix for Mudlet#1273 there is a partially complete update to show more non-GPL code licences in the "About" dialog's third tab. This and other forms/dialogues have been refactored to bring HTML code into the C++ core from the Form file ui/*.ui files to make it easier to (re)-translate such texts. Also added missing licence boiler-plate to 3rdparty/lua_yajl/lua_yajl.c to properly attribute it to its creator. Also narrowed the licence used for 3rdpaty/communi/src/3rdparty/mozilla/rdf_utils.c to GPL 2+ from the triplet which included that option in the original file as the text there says we may - so that the code has the same licence as we use for the main part of our code. Made ircmessageformatter correct for lua(not-translatable) / other use This means NOT using tr(...) for cases where the boolean isForLua is set in the various methods in this class and also not using HTML/Rich Text. It also means using something other than any raw string literals which has been enforced with the inclusion of the #define QT_NO_CAST_FROM_ASCII and QT_NO_CAST_TO_ASCII which will cause compilation to fail in any case where such literals ARE used. Typically a QString will instead be wrapped with a QLatin1String(...) wrapper should it be a true constant and destined for a method/function call that has a QLatin1String form or a QStringLiteral(...) form should it require positional argument replacements (as QString::arg(...)) in the same way that the tr(...) form does - but not as something that is subject to translation. Also fixes a few argument number errors in QString::arg(...) codes in: * (QString) IrcMessageFormatter::formatTopicMessage(IrcTopicMessage*, bool) * (QString) IrcMessageFormatter::formatInviteMessage(IrcInviteMessage*, bool) Made dlgTriggerEditor support run-time language changing It also means adding support for language changing to related classes: * dlgActionMainArea * dlgAliasMainArea * dlgKeysMainArea * dlgScriptsMainArea * dlgTimersMainArea * dlgTriggersMainArea * dlgVarsMainArea Make T2DMap better suited to translation For many texts that are subject to translation we use Rich/HTML text and in the past I have hidden the open and closing HTML paragraph tags in the none translatable part of the strings. However should the content extend to be more than one paragraph the translator would have to remember to close the first paragraph with a </p> and then open a one with <p>. By not including the outer pair of tags it is less clear to translators, IMHO what might be going on so they have been restored to the texts that translators would see. This commit also moves various entries - manly tooltips and mainly HTML, from the form definitions into the C++ source which makes it possible to de-obfuscate the HTML that later versions of the Qt Designer plugin/utility insist on making more complex even though a long standing QTBUG means that Qt Linguist is unable to display HTML markup in a way that makes it editable by translators! Also wrap some raw strings in QStringLiteral/QLatin1String wrappers to hide them from translation system and others into it. Made dlgComposer more amenable to GUI translation Added sysGuiLanguageChange & getGuiLanguageCode() for Lua subsystem This causes a sysGuiLangageChange event to be sent to all loaded profiles when the user changes the setting in the preferences. Two additional arguments are passed being the "XX" or "XX-yy" {XX is language; yy is Country} codes for the new followed by the old translation codes. Additionally a script/package can query the current setting with the getGuiLanguageCode() which returns the same type of code which could, in theory, allow package creators to tailor their scripts for more than one language - of course for API simplicity the Mudlet Lua implementation is not translated. Made TConsole more amiable to translation Convert 4 error messages that are bound for the Lua subsystem from tr(...) to QStringLiteral(...) so they are not subject to translation process. Correct/fixup some messages in TAlias One of the emended lines raised a parsing issue with lupdate {the: R"(in: ")" line, then 263 causes a "Excess closing parenthesis in C++ code (or abuse of the C++ preprocessor)" warning} I rewrote it and also arranged for it and a couple of related messages to be translatable when they may not have been before - and they are sent to the Central Debug Console and the Error display label in the top of the Editor Dialog so do constitute GUI elements IMHO. Make dlgPackageExporter class work for subDirs & translatable It was found that the form used for this dialog was not configured in a manner consistent with the Qt IDE: "Tools" -> "Options" -> "C++" -> "Qt Class Generation" -> "Embedding of the UI Class" setting of "Multiple Inheritance" that has been used for (most ?) other forms/dialog - so this commit includes switching some code over to that form. This revealed that the class member "filePath" was masking/shadowing a dialog member (a QLineEdit) of the same name. I renamed the latter to lineEdit_filePath and then found that the class member was largely redundant as the textual content of the lineEdit contains the wanted detail. I also renamed a couple of other items in the form: * (QLabel *) textLabel1 ==> textLabel_exportLocation * (QLabel *) textLabel1_2 ==> textLabel_informationText to be a bit better named. It became clear that it would be possible and might be useful to show the lineEdit contents (in readOnly mode) once it was populated. There was an issue with the creation of temporary files/directories in that they were assembled in a sub-directory: "mudlet home dir"/profiles/"profile name"/tmp/"package-name" folder that was not cleared after the creation of a module and so would not be a "temporary" one and would still be around should another instance of the same package/module be assembled. This commit changes that to have the option to properly use an OS-dependent temporary location and which is removed now after the package is created (unless a debugging line is un-commented) or which (in the linux case "/tmp") has a well-known (to the OS) as being likely to be subject to temporary file clean-up. More fundamentally it became clear that the existing code DID NOT WORK to produce modules if there were any sub-directories and in the absence of any error reporting it was not clear why. This commit changes the way that the user created files and sub-directories are scanned to pick up on sub-directories and to make the needed but missing entries in the archive for them. It also arranges for the "config.lua" file to be stored as the first "file" in the archive and the Mudlet items in the "'package-name'.xml" file to be the last (so that all the other contained files are loaded in before it is used in any way. The form/dialog has been simplified a little with a more informative text (which has been brought into the C++ code to make it easier for translators to work with {some of the fixed HTML has been hidden from them}) and it now persists for around 10 seconds after the "Export" button has been hit so that the "results label" which is now populated with a "success / fail + reason" message is at least briefly readable. In the past only a success message was shown and as the form was being hidden as part of the "close()" method called immediately after it was put up it was never seen...! Differences between the form object name and the ".ui" file that contains their definition was causing confusion in Qt Linguist as it was not clear of the context for some entries. However renaming the object meant that where they were inherited in various Mudlet class header files needed emending to match... Names changed: color_trigger_dlg ==> color_trigger profile_dialog ==> connection_profiles irc_dlg ==> irc keys_main_area ==> keybindings_main_area NotesEditor ==> notes_editor roomExits ==> room_exits MainWindow ==> main_window Some forms also referred to the old mudlet_alpha.qrc resource file instead of the correct mudlet.qrc one. As it has been a while since some forms were edited in any way, a small change in the format (removal of an unneeded space character between the last attribute in XML entity and the closing '>') has also modified some form (.ui) files edited in some other way... Also fixed a spelling mistake (overide ==> override) in my source code. I did lose a set of changes that I accidently deleted and recovered by delving in the ./.git/lost-found/other area for blobs of changed files - hopefully I managed to rescue all the bits needed... Some versions of Qt's lupdate seems to have issues parsing modern C++11(?) string literals and get confused when there are an odd number of, possibly escaped/embedded double quotations (or that is what I found) however reverting to the prior form involving back-slashes '\' seems to work. The default scripts/commands built-in to Qt Creator do not: * produce a reduced "plurals only" en_US which is all that we need for American English * mark untranslated strings - Qt Linguist does with a '#' * compress the binary files to save space I enclose a couple of shell scripts unix_lupdate.sh and unix_lrelease.sh that should be executable from within the QtCreator environment (or included in qmake/cmake project files) that should automate updating translation source files and producing binary translation output files that can be used now. They should be executed from the ./src/ sub-directory. At present the translation binary files are expected to be in the same directory as the Mudlet executable - but this is not be satisfactory for all situations and will need further revision. In the mean time for (unix) developers it is useful to include symbolic links from the "build" shadow directory to the ./src/ one so that a development executable sees the translation binaries as they are updated. Only the en_US; en_GB and fr_FR files included significant translation work at present, the first two are largely usable and the French one includes many prototype translations in order to test various features, I would like to think that it is a basis for future work but a native French speaker would probably think it is absolute "merde"... On the other hand as an British speaker the middle one does help to remove the stress I get that is centred around not seeing colour! Revised I18n "[ XXXX ] - aaa bbb ccc." cTelnet::postMessage(...) system This needed revision to allow for message tags to have different lengths in different languages. May still not be good enough to work with texts containing combining diacriticals or non-BMP plane characters... Tidied up mudlet class items, move some permanents into class For dynamic GUI language changes we will need to change the texts and tool-tips assigned to many parts of the main window but until now the QActions concerned have not explicitly been members of this class - so retrieving them later for amendment is awkward. This commit moves the following into the class (and renames them accordingly): actionConnect ==> mpActionConnect actionTriggers ==> mpActionTriggers actionAlias ==> mpActionAlias actionTimers ==> mpActionTimers actionButtons ==> mpActionButtons actionScripts ==> mpActionScripts actionKeys ==> mpActionKeys actionVars ==> mpActionVars actionIRC ==> mpActionIRC actionMapper ==> mpActionMapper actionHelp ==> mpActionHelp actionOptions ==> mpActionHelp actionNotes ==> mpActionNotes actionPackageM ==> mpActionPackageM actionModuleM ==> mpActionModuleM actionReplay ==> mpActionReplay actionMultiView ==> mpActionMultiView actionStopAllTriggers ==> mpActionStopAllTriggers actionAbout ==> mpActionAbout The following is only used in some circumstances, it is set to a null pointer when not (and I corrected a spelling mistake!): actionFullScreeniew ==> mpActionFullScreenView The following were already members of the class but it was not obvious from their previous names: actionReconnect ==> mpActionReconnect actionReplaySpeedDown ==> mpActionReplaySpeedDown actionReplaySpeedUp ==> mpActionReplaySpeedUp actionSpeedDisplay ==> mpActionSpeedDisplay actionReplayTime ==> mpActionReplayTime Also: (QToolBar *)replayToolBar ==> mpToolBarReplay (QLabel *)replaySpeedDisplay ==> mpLabelReplaySpeedDisplay (QLabel *)replayTime ==> mpLabelReplayTime (QTimer *)replayTimer ==> mpTimerReplay Many of the edited items had tooltips (though a few had status tips instead) as the items are generated by the Mudlet application rather than from a Qt Designer form they will not get modified if there is a change in the translation file(s) during an application runtime; code that sets those items up/changes them has been placed in a new private method: (void) mudlet::guiLanguageChange(void) to be called when needed. There were also many "dead" QActions (mainly with an 'm' prefix that were declared but never used in a meaningful way, they have been deleted: mactionConnect, mactionTriggers, mactionTriggers, mactionTriggers, mactionButtons, mactionButtons, mactionKeys, mactionKeys, mactionHelp, mactionOptions, mactionMultiView, mactionAbout & mactionCloseProfile. Make class member pointers in TConsole to bottom toolbar buttons so that they can be found after the end of the constructor so that their tool-tips can be revised if the GUI language changes. As we now have those pointers we can also arrange for the tool-tips to relate to the toolbar button current state. Whilst "wiring this up" I spotted that there was a useless function call from: (void) TTextEdit::slot_copySelectionToClipboard() to: (void) TTextEdit::copySelectionToClipboard() and from: (void) TTextEdit::slot_copySelectionToClipboardHTML() to: (void) TTextEdit::copySelectionToClipboardHTML() where the functions wthout the "slot_" prefix could be renamed to have it and be called directly. Also I could changed (void) TTextEdit::slot_toggleTimeStamps() to (bool) TTextEdit::toggleTimeStamps() so that it isn't a SLOT and then get it to return the state of the variable that determines whether time-stamps are showing - this is so the slot function can be in the TConsole class so that it can modify the time-stamp control button's tooltip to match the state of the control. Whilst debugging the changes herein I found that * (QToolButton *) mudlet::mpActionFullScreenView needed to be initialised in the constructors initialiser list and spotted a couple of other variables that were NOT being initialised: * (bool) mudlet::mIsLoadingLayout * (bool) mudlet::mHasSavedLayout I found an issue where, when the same "source" text is used in different places, then QtLinguist only displays ONE source which can cause issues if one source text is modified but another is not - however by adding additional developer diambigution strings each instance is separately displayed - where this has been done there will be such comments with an identical comment except for an (X of Y) indication - this may help to ensure that changes are carried through to all places in the source code when needed. One example of this is the texts to use for the Server Encoding type ComboBox on the preferences dialog when one set of translations are use on initialisation but a different set is used when the GUI Language is changed... Whilst going through the main window menu bar I noticed it badly needed a clean-up to remove cruft. I have taken the liberty of: * reorganising some items * adding the same icon where possible as is used on the main toolbar * adding a quit option to the games menu - as I find when I run the application in full screen mode I do NOT have a title-bar with a close button on it and there is nothing to click on directly to close Mudlet down without doing an un-fullscreen first. * adding the Qt provided "About Qt" action to the "Help" menu where other Qt applications often have it. * change "Settings" to "Preferences" and "Replay" to "Load Replay" so that menu items are identical to toolbar items... Do not populate or mark as translatable the doubleclick_ignore_lineedit "text" field in the profile_preferences.ui dialog so that it does not get "retranslated" should a GUI language change be invoked elsewhere in the same dialog as that will overwrite any existing contents that were set up in the dlgProfilePreferences constructor which will be the current profile settings. Enjoy Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
Storing a QString as the line style for any exit with a custom line does
not work so well when the language used to display the option has to be
changed to accommodate a different language. This commit changes the
TRoom class to store the Qt:PenStyle enum value directly instead of a
representation of the name of the style.
This did show up a slightly tricky issue when serialising the enum as at
some point in the Qt 5.x history it seems to have gotten harder to access
the underlying integer value. This is solved by a pair of QDataStream
handling "friends":
* (QDataStream) &operator<<(QDataStream&, const Qt::PenStyle&) {writing}
* (QDataStream) &operator>>(QDataStream& ds, Qt::PenStyle& value) {reading}
they have been included at the top of the TMap and TRoom classes
respectively and which are used "behind" the scenes when a Qt::PenStyle is
serialised. NOTE: the absence of the function in TRoom will throw up a
slew of compilation errors about "no match for 'operator>>' (operand types
are 'QDataStream' and 'QMap<QString, Qt::PenStyle>::mapped_type {aka
Qt::PenStyle}') in "qdatastream.h" as line 284 but it will be unclear
otherwise what on earth has gone wrong. More insidiously the absence of
a matching function in the TMap write to file process will silently
seem to work but write out a different number of bytes (several rather than
one or two) such that any data afterwards in the file produced will be
corrupted...!!!
When I tried to work out what texts to use for other languages for the
different line styles I realised I could not be certain of the Google
translations so I ran up a set of icons to use as well - they are a bit
skimpy at the moment so may need a bit of tweaking to look better.
Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
|
Hi Stephen! Thanks for doing this massive amount of effort, it is awesome to see thie PR finally come to life :) What do you think about adding the translation files into the Qt Resource file - that's how we've already been solving the runtime detection issue for files already. |
|
Let's leave #436 for later - it addresses a totally different problem and has many issues itself that'll slow down this PR from making it in. If we do this step by step, it'll be easier. |
|
On blast got an instead of: causing fails on Apveyor and it turns out I use |
vadi2
left a comment
There was a problem hiding this comment.
Not finished reviewing everything yet, just what I got done so far...
src/KeyUnit.cpp
Outdated
| mKeys[0x01020006] = QString("Zoom"); | ||
| mKeys[0x01020001] = QString("Cancel"); | ||
| // This WAS called setupKeyNames but it actually represents all that needs | ||
| // doing for this class when the language changes...! 8-) |
There was a problem hiding this comment.
Don't need to have this comment in code - we can have it in the Github review if need be. Otherwise leaving behind cruft in things will rename will lead us to comments all over the place ten years down the road saying "this used to be called this and that" and it'll be like "okay... this is adding no useful information"
There was a problem hiding this comment.
☑️ This comment removed.
| mKeys[0x0f7] = tr("division"); | ||
| mKeys[0x0ff] = tr("ydiaeresis"); | ||
|
|
||
| mKeys[0x01000000] = tr("Escape"); |
There was a problem hiding this comment.
Keyboards don't translate this stuff - it needs to stay as-is in English.
There was a problem hiding this comment.
Not necessarily - a French Key board is not going to have a "BackSpace" key and the "Shift" keys are not labelled "Shift" e.g. see Wikipedia's AZERTY Keyboard layout article...
This is about the name that is displayed to the user - it has no programmatical significance fortunately...
|
|
||
| p.save(); | ||
| p.setPen(Qt::yellow); | ||
| p.fillRect(0, 0, width(), height(), Qt::darkRed); |
There was a problem hiding this comment.
This does not look like it's related to i18n.
There was a problem hiding this comment.
sigh yeah it is a little off-topic - but as I was marking the "No map..." message I remembered being bugged by the layout and colour of the message in the past - and as there are no guarantees about the size (or shape) of the translated message it seemed sensible to use the layout system to centre it properly and allow it to be wrapped if the map was very small rather than specify a start point of half-way across the screen {neglecting the fact the message has a length}...
| } else { | ||
| customLinePen.setStyle(Qt::DashDotDotLine); | ||
| } | ||
| customLinePen.setStyle(pR->customLinesStyle.value(itk.key(), Qt::SolidLine)); |
| } | ||
| } | ||
|
|
||
| // TODO: Hide this information in release version? |
src/dlgPackageExporter.cpp
Outdated
| * This should really be called "dlgModuleExporter" - "Packages" should be | ||
| * reserved for a single node (plus sub-nodes) from one type of Mudlet item that | ||
| * is "Exported" from the "Editor" whereas "Modules" are collections of possibly | ||
| * more than one type of Mudlet item and which can include additional reasources |
There was a problem hiding this comment.
That is not correct - packages are not reserved for single-node items, they can be multi-node packages just like modules.
There was a problem hiding this comment.
How, the "Export" option in the Editor only allows one item to be selected IIRC...
There was a problem hiding this comment.
So? That is how it is isn't it, and it does have its uses to get a straight forward XML file. I guess this might be a bit of a simplistic division between the two terms but actually there is some merit in distinguishing between a simple XML "extract of one leaf/branch of one tree" in the Editor compared to a more complex "collection of multiple branches from multiple trees together with other file based resources all zipped up in an archive file"...
There was a problem hiding this comment.
I disagree but this isn't the right place to have this discussion, nor is this the i18n PR the right place to sneak remarks into the source code about completely unrelated things 😉
There was a problem hiding this comment.
☑️ Reworded to note the difference between what this class does/produces and the "Export" option in the Editor (dlgTriggerEditor class) - the latter only exports one "branch" of one "tree" (widget) of Mudlet items in an .xml file whereas this manages a whole "forest" (and external files besides) as a .mpackage (renamed .zip) archive file; but there is no mention of anything about packages vs. modules... 😉
src/dlgPackageExporter.cpp
Outdated
| } | ||
| fileEntries.remove(QStringLiteral("config.lua")); | ||
| } else { | ||
| qWarning() << "dlgPackageExporter::slot_exportPackage() - ERROR: failed to add package detail file config.lua to archive, the package/module may not work!"; |
There was a problem hiding this comment.
It'll work just fine without it, the name will just be assumed from the zip file instead.
There was a problem hiding this comment.
... but it is a warning that the config.lua file has been clobbered...
There was a problem hiding this comment.
Would:
qWarning() << "dlgPackageExporter::slot_exportPackage() - WARNING: failed to add package detail file config.lua to archive!"
be acceptable?
src/dlgProfilePreferences.cpp
Outdated
| ***************************************************************************/ | ||
|
|
||
| /* | ||
| * THIS FILE CONTAINS UTF-8 UNICODE ENCODED CHARACTER STRINGS THAT ARE (OR |
There was a problem hiding this comment.
I'm not sure what is the takeaway message I'm supposed to get here, could you explain?
There was a problem hiding this comment.
The tool-tips in the constructor MUST remain as QStringLiterals(...) and NOT be converted to tr(...) but I could word it as that now - when I started on this I was not quite sure how it would all work out... 🙂
There was a problem hiding this comment.
Okay - can we just say that, without the shouting?
| QStringList tooltipLanguageEntries; | ||
|
|
||
| // This covers the default en_US as well as en_GB: | ||
| tooltipLanguageEntries.append(QStringLiteral("Choose the language for Mudlet to use...")); |
There was a problem hiding this comment.
Should be Choose the language for Mudlet to use:
elipsis is used to indicate that there is more following in another menu in UI design.
There was a problem hiding this comment.
Well, I meant the ellipsis to mean if you select this control it carries out this action...
Grammatically I might not be entirely correct, but I suspect that a colon : is definitely not right here.
| // Handle case when no map is present: | ||
| if (pHost->mpMap && pHost->mpMap->mpRoomDB && pHost->mpMap->mpRoomDB->size() > 0 ) { | ||
| label_mapFileSaveFormatVersion->setEnabled(true); | ||
| Q_ASSERT_X((pHost->mpMap->mMaxVersion >= pHost->mpMap->mDefaultVersion |
There was a problem hiding this comment.
I think a static_assert() would work well here
There was a problem hiding this comment.
See previous comment about the same Qt Macro elsewhere
|
I've resolved the merge conflicts that occured, but the PR still has the initial outstanding issues it had in compiling! |
Repairs a stupid mistake in #ifdef-ing a couple of Windows specific chunks
of code I made before.
I didn't realise it but I am using a (locally compiled) version 1.x of
libzip but some Debian versions and the Trusty Ubuntu Travis Platform only
comes with an 0.1x version by default (that may not encode UTF-8 paths)
correctly - I am not sure of the exact details) although the source for
libzip {https://nih.at/libzip/libzip.html} has declared the functions that
we were using {zip_add(...) and zip_add_dir(...)} OBSOLETE - however that
is all that is available for those cases so I have added #ifdefs that will
use the later functions {zip_file_add(...) and zip_dir_add(...)} if they
are available. Whilst this hits two places in the previous part of the PR
there is one more instance in the code base that I have also fixed up in
this way.
As it happens both of these issues have arisen as a result of a reworking
of the package/module handling code which, prior to this PR will silently
FAIL to make packages/modules if there are any files placed in the staging
area in a sub-directory. That staging area was described as a "temporary"
one but in fact persists beyond the production of a package/module. As part
of the reworking it has been made to have the option (NOT ENABLED BY
DEFAULT) to clean up the temporary area afterwards but if a package/module
is being developed then it is likely that the other resources are likely
wanted to be kept for producing later, updated/revised, ones...
Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
... but this should be correct. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
Forgot to convert the entered value back from a QString to a UF-8 encoded const char * should the value be duff! Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
|
Could we move the translations file to a separate top-level |
Fixed a spurious open C type multi-line comment at start of: 3rdpart/communi/3rparty/mozilla/rdf_utils.c where I had chosen the GPL only licence and rewritten the header in a manner consistant with the Mozilla terms provided therein. With the addition of Q_OBJECT macro into KeyUnit and Host classes (to allow them to use Qt SIGNALs/SLOTs) it also seems to be necessary to #include <Q_OBJECT> for some build platforms even though it must be inherited from one of the other #include s... Not being totally familiar with the methodology in adding overloaded helpers for data items to QDataStream::operator<< and QDataStream::operator>> friend type helpers I did not realise I had to return the (first) argument reference for the two argument methods. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
In the source tree for development (followed by installation placement in, say, a shared, read only location such as |
With the inclusion of `Host` and `KeyUnit` classes into the list of those that use the `Q_OBJECT` macro it means that their header files need to be moved from the `mudlet_HDRS` variable to the `mudlet_MOC_HDRS` one so that they get run through the `moc`. Signed-off-by: Stephen Lyons <slysven@virginmedia.com>
|
🎉 Finally - it passed CI - ye-ha! |
|
Awesome work! |
|
|
That has some promise - though I think we'd want to enable the Note that some platforms would not want that though, Linux distributions such as Debian or Ubuntu expect those shareable, read-only files to be located elsewhere in the file-system and I expect @csmall would patch the source to strip them out of the mudlet binary, probably to A |
|
Who are we gonna share Mudlet translations with exactly? |
|
To make it easier to see which comments of mine are actually requesting changes, I've went through and made a list - hope it helps: #1334 (comment) ☑️ Updated by SlySven as he made changes to his local copy to keep track... 😀 |
Do you mean, why place them in a |
|
I think it'll be a lot easier to just embed them into a resource file. If someone asks us to split it out and gives pretty good reasoning, we can do that... but otherwise this is additional file loading complication that I'd rather not deal with. This complicates setup instructions, makes it a lot harder for Windows, adds more room for error and frustration, all for no real benefit to us. It seems like a nice idea but really the costs of it are high. |
|
Nice, thanks for addressing the feedback! I'm also keen on #1334 (comment). |
|
⏱ I'm looking at the outstanding thing about using a resource file... |
I've read and re-read this parasentence and I'm having difficulty making sense of it. Why do you suggest we exclude singular form of the messages? 🤔 |
I'd like to see it just work with the |
vadi2
left a comment
There was a problem hiding this comment.
I've had another look at this. I'd love to see this in! I love how it changes the language realtime in selection - super cool.
| mpMainToolBar->addAction(mpActionReplay); | ||
| mpMainToolBar->widgetForAction(mpActionReplay)->setObjectName(mpActionReplay->objectName()); | ||
|
|
||
| mpActionDisconnect = new QAction(this); |
There was a problem hiding this comment.
Hey we've had the discussion about scoping PRs more than once. A new disconnect button can't go in the PR that adds translations.
There was a problem hiding this comment.
I had to go through that area and clean out a load of cruft relating to unused QActions and reorganise what was left - I got the impression that as this appeared on the menu bar and is also present as a lua command that it was something that had been missed out.
I did refrain from including another one! 👼 I wanted to put a "Close" profile button
that if used returned the application to the initial pre-first profile connection state (with the menu/toolbar buttons disabled - which links into the state things would be at when the changes that #1388 handles):
There was a problem hiding this comment.
Not in this PR. Let's have it be a sub-button of Reconnect if that's going to be added, we have way too many buttons already as it is.
| #if defined( Q_OS_MAC ) | ||
| return QStringLiteral("%1/../Resources/").arg(QCoreApplication::applicationDirPath()); | ||
| #else | ||
| return QStringLiteral("%1/").arg(QCoreApplication::applicationDirPath()); |
There was a problem hiding this comment.
We need to embed this inside resource path so we don't have to deal with the complexity of find where the translation files are hiding.
There was a problem hiding this comment.
Whilst including them in the resource file is one way of doing it and one I am keen to do, I am trying to code my way around something that allows this to be made optional as a resource file method is not amiable to allowing interested parties to create their own language translations and developing them on the fly.
I am still hacking away at this but the implementation as it stands is flawed in that loading up all the translations at start-up is wasteful (keeping all the non-used ones around in memory) and not flexible (changing the source requires restarting the application). There is a better way of doing it and it includes taking into account the language settings that the user has already told the system to use - but given them the chance to change it if they insist {your tale of changing your resident country and then getting everything in the wrong language suggests something changed automatically - or that you hadn't specified your language settings...! 🙁 }
There was a problem hiding this comment.
Well:
so we don't have to deal with the complexity of find where the translation files are hiding.
Adding both methods is gonna defeat the point here as we'll have even more complicated code to do it both ways! 😄 So nevermind - let's have it be just one way, but at least let's add some search paths for the translations then so we aren't forcing people to make symlinks from whatever folder the Mudlet binary ends up at to the translations.
| const QString languageCode(mudlet::self()->getGuiLanguage()); | ||
|
|
||
| if (languageCode.isEmpty()) { | ||
| lua_pushstring(L, "none"); |
There was a problem hiding this comment.
This still needs to change - "none" is not a language people speak! Let's make this for humans, not engineers 😉
Briefly: the Qt provide external tool |
|
Alright. What about the Windows and macOS versions of the scripts? Perhaps we won't need them because the web translation service will be automatically pulling the strings anyway so translators don't have to mess around with this complicated stuff. |
|
@SlySven let's work on getting this PR finished out. What is outstanding? The disconnect button has to go as it is offtopic, "none" as a language needs to go, and need to add search paths for loading translations I think is all that is left. |
|
I have a revised (by merging in some recent changes) edition that does work for translations included as a (separate) resource file (so the inclusion can be made build environment dependent) which defaults to auto-locale selection (using the user's own or system settings) but which can be changed to a specific one on demand - this is via a comboBox on the first profile preferences ("General") tab - it is then also possible to override the location of the translation's file and specify a manual location (which can be the local source tree) in a However given the textual changes elsewhere and the other things like module code that this current includes but which I developed further/better in #1355 - I would like to get that one in and then redo this one with less in it based upon the current development branch. Basically I think in merging in things I may have broken other PRs and want to try again now I have something that operates as I would like... hopefully for Mudlet 3.7 . I have had to juggle some things on the profile preferences (added another tab for "Profile and Server preferences") and with all the other changes that have happened there it will need careful going over again to get this in: (For testing purposes I set up another user on my Box stephane who has a locale setting of "fr;en_GB") on there the current code does select things to be French - once I remember to have the translations where they should be: There is a bit of a mix up that I have to check - but the default location for this build should have been in This has to use a non-native file dialog so that the directory search will show only the |
|
OK, thank you, great progress. I've got feedback on this but as you suggest let's process #1355 first. |
|
OK, once #1355 and #1446 finally get in I can get back to bringing this Frankensteinian monster to life again. Those other two have things that interact with this one (I touched the package/module handling stuff in this one but it was only completed in the first one so that need merging in correctly and the font optional font handling stuff which has been done by moving the fonts to a second, optional, resource file has shown me how to place the translations into the resource system - for some platforms and how to access them afterwards). 🎉 All in all, I have good hopes for progressing Mudlet in 2018...! 🎆 |
|
Aaaarrggh! Yes, I wish I had KISSed it... |
|
I'll close the PR, the PR itself is too different now to be merged. It's code will still live on |
Salvaged the improvement from Mudlet#1334
Salvaged the improvement from #1334




Right this steaming pile of code represents my reworking of https://github.com/SlySven/Mudlet/tree/enhance_refactorForI18n (that was left to fester in a dark place a couple of years ago) and this should go pretty far towards the framework needed to use languages other than English (American) for the User Interface, it includes partial translation files (both source
./src/mudlet_xx_YY.tsand binary./src/mudlet_xx_YY.qm) for:At present the

.qmfiles need to appear to be in the same directory as the mudlet executable for Linux and Windows builds - I left some macOs defines in place which will not help. Currently, if no suitable files are found on start-up the control to switch on translation/change language will be disabled:During development I have found it is enough to set up some symbolic links to the

./src/mudlet_xx_YY.qmfiles from the "build" directory where the mudlet executable is built then you will get:For demonstration purposes the most obvious (and "complete"; although that complete is only in terms of the %-age of entries - the translation quality is probably 💩 !) language to try is French. Note that that control is filled with entries in the language of the particular language itself as nothing else makes sense from a UI point of view; as a help for this the tool-tip for that control is a special one in that it is NOT translated but instead contains a series of texts all saying the same thing but in a range of languages...

There are a couple of External commands that are included in the Qt Creator IDE by default that seem to be to do with:
QStrings that need to be translated from various locations in the source code {lupdate- produces/updates.tsfiles which are XML files}.tsfiles into the binary.qmfiles that are needed by the application at runtime to provide the data needed in a particular languagehowever as provided the first one reads the
TRANSLATIONSvariable in theqmakeproject file and processes all the languages to produce what are full translation files with everyQStringin - for theEnglish (American)language, as the source code is already in that language it produces a much larger file than is needed, and by running thelupdatecommand with an existingmudlet_en_US.tsfile it can be made much simpler with the additional-pluralonlyoption that only picks out the cases where the%nparameter is used to specify a (usually integer but it need not be) 3rd argument to theQObject::tr()method which enables the handling of all the different plural forms for those many languages where adding ansif there is more (or less) than one article is just plain wrong!also, the second command has a useful option - that is not used by the default configuration in Qt Creator - that will mark a case where there is not a "finished" translation in place for the particular
QStringinstance, which, when debugging a translation, or where the source code string has been modified (which invalidates the translations based on it) can be prefixed in the application to flag it as something that needs attention.Anyhow, I have included in this PR a couple of simple *nix shell scripts which can be added to the Qt Creator "External" tool list, the first one is

unix_lupdate.shand you can set it up like this:It takes one argument - the location of the current Qt library version's
bindirectory so it knows which version oflupdateto run - and it will cycle through all themudlet_xx.tsandmudlet_xx_YY.tsfiles, updating them (whether mentioned in the qmake project file or NOT) in the mudlet/srcdirectory and pick out themudlet_en_US.tsfor the special plurals only treatment.The other script
unix_lrelease.shalso takes the same path to wanted binaries argument and if run like that it will regenerate all themudlet_xx.qmandmudlet_xx_YY.qmbinaries but by default it will include a#prefix on all the unfinished translations - as doesQLinguistwhen it is previewing a form/dialogue. However you can change this with an optional second argument, I have been using~to use a different marker, to suppress any prefix supply an empty string""as a second argument.The work flow when C++ coding is:
QObject::tr(...)or other translatableQStringlupdateor myunix_lupdate.shscript - by default they will not "throw away" obsolete translations i.e. ones where the source string in thetr(...)command is changed so it will not dump already worked out translations (there is a command line option to do so, but it is an all-or-nothing action though it is possible to hand edit EVERY.tsfile if it is vital that a really wrong (accidentally obscene source text word :devil:) thing has to be purged, but that is not a thing to be undertaken lightly!QtLinguistand enter a translation for the languages you are invested in/investigating, if happy with it, mark the translation as "finished" (will have a green or yellow tick)lreleaseor myunix_lrelease.shscriptmudletand select the language (if it is not already the one that was stored as being set)We will probably have to discipline ourselves in making commits to the
.qmfiles stored in the repository - it may be useful to hash out a system where developers can keep a local "working" copy of a set of.ts/.qmfiles if they are working on GUI stuff that will hit translatedQStringsIn passing I would note that I have addressed the "other licences" issue #1273 herein.
This is a big one - please ask questions if something doesn't make sense - I regret that the main commit message is a bit of a mess as the code evolved over time and I lost some stuff and had to retrieve it from the equivalent to the git rubbish bin.
ToDo list: