Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable Translations #89

Closed
wants to merge 3 commits into from
Closed

Conversation

achow101
Copy link

@achow101 achow101 commented Sep 9, 2016

I got most (nearly all I think) of the GUI strings that will need to be translated wrapped in the tr() function. I'm sure I missed a few, but I may have accidentally wrapped a few things that shouldn't be translated, so be sure to check for that during review.

I've also added the resource files for translations, but no code yet to handle actual translations. These resource files are from Transifex (except English) but I don't think the translations have been reviewed, so they may not be accurate. However, these translations won't be in use until languages can be selected.

Also, any new strings added that will appear in the GUI will need to be wrapped in the tr() function. pylupdate4 will then need to be run to generate the English resource file and that file uploaded to Transifex.

@goatpig
Copy link
Owner

goatpig commented Sep 9, 2016

How does this work exactly? Do we have to implement a language selector in app?

@goatpig goatpig closed this Sep 9, 2016
@goatpig goatpig reopened this Sep 9, 2016
@achow101
Copy link
Author

achow101 commented Sep 9, 2016

At some point, yes we will need to implement a language selector. I'd put it in the settings. There will also need to be a change in the build process to add lupdate so that the language stuff will work. I'm looking into how doing all of this translation stuff should be done.

Also, getting the language selector isn't really urgent yet since no languages are close to being fully translated yet (after I tripled the number of strings to be translated).

@goatpig
Copy link
Owner

goatpig commented Sep 9, 2016

You could replace all entries with a lorem ipsum just for the sake of testing though. I'm more concerned about breaking some far fetched 6 layer deep dialog than the actual quality of completion of tsl.

@achow101
Copy link
Author

achow101 commented Sep 9, 2016

well first we need to implement a language selector. RIght now, this breaks nothing. The only thing I am really concerned about are a few strings that had weird format stuff that I changed (not sure if I changed them correctly) and that I may have accidentally added something that wasn't a GUI string to be translated (e.g. an identifier for something in the wallet).

@goatpig
Copy link
Owner

goatpig commented Sep 9, 2016

At any rate the first step is reviewing and testing these. Last time one of the ATI devs tried to tr() everything in the Armory code base, it blew up in epic proportion and 99% of it was rolled back.

@achow101
Copy link
Author

achow101 commented Sep 9, 2016

Right... There are actually a few strings that probably should have been left alone due to the weird formatting thing that was happening with them. I'll see if I can find them (qtdialogs is just massive) and revert them.

@goatpig
Copy link
Owner

goatpig commented Sep 9, 2016

Regardless this is a good time to do this change, right at the end of the early testing phase.

armorymodels.py Outdated
@@ -1114,7 +1114,7 @@ def data(self, index, role=Qt.DisplayRole):
return QVariant( cppAddr.getTxioCount())
if col==COL.ChainIdx:
if self.wlt.addrMap[addr160].chainIndex==-2:
return QVariant('Imported')
return QVariant(tr('Imported'))
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a label that is displayed or something for the wallet internally?

@achow101
Copy link
Author

achow101 commented Sep 9, 2016

The string at https://github.com/achow101/BitcoinArmory/blob/355db40ad408008a407587de92838afe1529b493/qtdialogs.py#L4210 is questionable as to whether I formatted it correctly.

@droark
Copy link

droark commented Sep 9, 2016

utACK

No changes jumped out at me. Looks good. I feel like there was a reason Alan stopped using tr(), though. I can't remember why. I know there was an attempt at adding translations but it was pulled eventually. Anyone remember?

In any event, other than having to remember to wrap any new text in tr(), I'm fine with this commit. I'll test on OSX once it's finally running again.

@josephbisch
Copy link

utACK

Nothing jumped out at me either. However, I just scrolled through a lot of it, but not all.

The questionable string (L4210 of qtdialogs.py) looks good to me, but I think the %s format specifiers will literally show up in the string to be translated, if I understand how this works. So the translators will need to know to leave the %s characters as is when they translate the string. The only other issue I see is that the use of %s to format the string leaves less flexibility for the translators. For example, what if theoretically there is a language that makes words plural in some way other than appending a character on the end of the word. But that is probably overthinking this and I don't know how you would handle that with PyQt.

@achow101
Copy link
Author

achow101 commented Sep 9, 2016

I've replaced the tr()s with self.tr()s. I also squashed the commits.

@achow101 achow101 force-pushed the translations-setup branch 3 times, most recently from cd7b139 to f6cc697 Compare September 10, 2016 00:06
@achow101
Copy link
Author

It turns out tr() does work with the % formatting that Armory mostly uses for strings. I am now slowly going through the strings again and replacing them with QString's .arg() function.

@achow101 achow101 force-pushed the translations-setup branch 3 times, most recently from ffe8f1f to a37a506 Compare September 10, 2016 04:01
@achow101
Copy link
Author

Ok, I think I fixed everything and it's ready for review, and merging. I did some testing.

You can use achow101@c5b56e0 for testing. Just change the name of the .qm file to whatever other language you want to try translating. You will have to run lrelease lang/*.ts first.

@achow101 achow101 changed the title Translations setup Enable Translations Sep 10, 2016
@achow101
Copy link
Author

achow101 commented Sep 10, 2016

I've finished everything that needs to be done for translations. You can now change the language in the settings.

All that's left is to wait for all of the translations to be completed. And testing and review of all of the changes.

Now if someone could make a test translation with a bunch of lorem ipsums....

@achow101 achow101 force-pushed the translations-setup branch 5 times, most recently from 75f6ab2 to 8c813d9 Compare September 16, 2016 20:51
ArmoryQt.py Outdated
qt4reactor.install()

# Setup translations
langSetting = SettingsFile(CLI_OPTIONS.settingsPath).get('Language')
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be in ArmoryUtils, where it can also be detected a cli arg if needs be.

ArmoryQt.py Outdated
No passphrase was selected for the encrypted backup.
No backup was created"""), QMessageBox.Ok)
newPassphrase = SecureBinaryData(str(dlgCrypt.edtPasswd1.text()))
newPassphrase = SecureBinaryData(unicode(dlgCrypt.edtPasswd1.text()))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a wild search and replace. This is not actual text, it is casting a QString to a python string for the SWIG constructor. These casts are necessary for SWIG to work.

ArmoryQt.py Outdated
currComment = str(view.model().index(row, LEDGERCOLS.Comment).data().toString())
wltID = str(view.model().index(row, LEDGERCOLS.WltID ).data().toString())
txHash = str(view.model().index(row, LEDGERCOLS.TxHash ).data().toString())
currComment = unicode(view.model().index(row, LEDGERCOLS.Comment).data().toString())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a dangerous cast. Legacy Armory wallets cannot support multi byte characters. This cast would allow to convert actual unicode characters to multi byte values that would then be written to the wallet, breaking the container.

ArmoryQt.py Outdated
txHash = str(view.model().index(row, LEDGERCOLS.TxHash ).data().toString())
currComment = unicode(view.model().index(row, LEDGERCOLS.Comment).data().toString())
wltID = unicode(view.model().index(row, LEDGERCOLS.WltID ).data().toString())
txHash = unicode(view.model().index(row, LEDGERCOLS.TxHash ).data().toString())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would break comparison functions. Hashes in wallets are strings, and comments are keyed by strings. It would fail to find the entry later if it is keyed as a unicode object.

ArmoryQt.py Outdated
currComment = str(view.model().index(row, ADDRESSCOLS.Comment).data().toString())
addrStr = str(view.model().index(row, ADDRESSCOLS.Address).data().toString())
currComment = unicode(view.model().index(row, ADDRESSCOLS.Comment).data().toString())
addrStr = unicode(view.model().index(row, ADDRESSCOLS.Address).data().toString())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above with comment and hashes. These need to be str, not unicode

qtdialogs.py Outdated
@@ -12410,10 +12395,10 @@ def verifyUserInput(self):
if self.chkEncrypt.isChecked():
dlgPasswd = DlgChangePassphrase(self, self.main)
if dlgPasswd.exec_():
passwd = SecureBinaryData(str(dlgPasswd.edtPasswd1.text()))
passwd = SecureBinaryData(unicode(dlgPasswd.edtPasswd1.text()))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SWIG cast

qtdialogs.py Outdated
@@ -13200,9 +13184,9 @@ def processFrags(self):
if self.chkEncrypt.isChecked():
dlgPasswd = DlgChangePassphrase(self, self.main)
if dlgPasswd.exec_():
passwd = SecureBinaryData(str(dlgPasswd.edtPasswd1.text()))
passwd = SecureBinaryData(unicode(dlgPasswd.edtPasswd1.text()))
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SWIG cast

qtdialogs.py Outdated
The ID field indicates that this is a SecurePrint™
Backup Type. You have either entered the ID incorrectly or
have chosen an incorrect Backup Type."""), QMessageBox.Ok)
return
for i in rng:
hasError = False
try:
rawEntry = str(self.edtList[i].text())
rawEntry = unicode(self.edtList[i].text())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

readSixteenBytesEasy input, should be str


def getDescription(self):
return str(self.editDescription.toPlainText())
return unicode(self.editDescription.toPlainText())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These return values are probably saved in the lockbox container, should be str to be on the safe side.

if self.passphraseCallback:
self.passphraseCallback()
return result

def getPassphrase(self):
return str(self.editPasswd1.text())
return unicode(self.editPasswd1.text())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passphrase will probably get SWIG casted right away, this should be str.

@achow101 achow101 force-pushed the translations-setup branch 3 times, most recently from d83429d to 64e9fa2 Compare February 13, 2017 19:31
@achow101
Copy link
Author

I have addressed your comments (the unicode stuff in particular) and squashed and rebased.

@achow101
Copy link
Author

Now I remember why those were put in unicode. Many languages don't have ASCII and some of the things that were put into unicode were because that part of the code would be reading things being displayed for some reason, but those were in other languages that didn't use ASCII and thus caused crashes.

ArmoryQt.py Outdated
@@ -3242,7 +3262,7 @@ def showLedgerTx(self):
row = self.ledgerView.selectedIndexes()[0].row()
txHash = str(self.ledgerView.model().index(row, LEDGERCOLS.TxHash).data().toString())
wltID = str(self.ledgerView.model().index(row, LEDGERCOLS.WltID).data().toString())
txtime = unicode(self.ledgerView.model().index(row, LEDGERCOLS.DateStr).data().toString())
txtime = unstricode(self.ledgerView.model().index(row, LEDGERCOLS.DateStr).data().toString())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo

armorymodels.py Outdated
@@ -251,50 +251,50 @@ def data(self, index, role=Qt.DisplayRole):
isCB = rowData[COL.isCoinbase]
isConfirmed = (nConf>119 if isCB else nConf>5)
if isConfirmed:
return QVariant('Transaction confirmed!\n(%d confirmations)'%nConf)
return QVariant(self.tr('Transaction confirmed!\n(%d confirmations)')%nConf)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a proper way to feed in % args? You were using self.tr().arg() elsewhere.

@@ -977,11 +975,11 @@ def createLockboxDashboardTab(self):
# simulfunding widgets
self.stkDashboard = QStackedWidget()

simultxt = 'Simul'
simultxt = self.tr('SimulFund')
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want translators to figure out translations for this? This is an ATI trademark too afaik, better off leaving it as is.

Copy link
Author

@achow101 achow101 Feb 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It came up in a transifex issue where the translator was saying that some of the strings say "check the Simul box" (or something like that) but Simul was not in the strings to be translated. If SimulFund is trademarked, it shouldn't be translated. Should I leave that untranslated for translate Simul

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be left as SimulFund then, without a tr encapsulation. Sadly I believe translating a trademark without the owner's approval is a form of trademark law violation.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Done.

ui/TxFrames.py Outdated
@@ -1317,12 +1314,12 @@ def __init__(self, parent=None, main=None, initLabel=''):
self.sentToSelfWarn = False
self.fileLoaded = None

lblDescr = QRichLabel(\
lblDescr = QRichLabel(tr(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing self.

ui/TxFrames.py Outdated
self.infoLbls[-1].append(QRichLabel(''))

# ##
self.infoLbls.append([])
self.infoLbls[-1].append(self.main.createToolTipWidget(\
self.infoLbls[-1].append(self.main.createToolTipWidget(tr(
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing self.

ui/TxFrames.py Outdated
QMessageBox.warning(self, 'No Internet!', \
'Armory lost its connection to Bitcoin-Core, and cannot '
QMessageBox.warning(self, self.tr('No Internet!'), \
self.tr('Armory lost its connection to , and cannot '
Copy link
Owner

@goatpig goatpig Feb 14, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bitcoin-Core removed as a whole in the few following sentences. No rephrasing though.

@goatpig
Copy link
Owner

goatpig commented Feb 14, 2017

Updated the code review

@achow101
Copy link
Author

Updated with fixes.

Wrapped all strings that need to be translated with self.tr for Qt translation. Replaces the % formatters with %1, %2 to use with QString arg() function instead.

Fixes several typos that were found during translations

Added the language files downloaded from Transifex. The English file is the source generated with pylupdate4
Added a language selector and CLI arg to change the language for the translations stuff
@achow101 achow101 force-pushed the translations-setup branch 4 times, most recently from d7c5c81 to ab2b5a0 Compare February 14, 2017 20:43
nextAddr = wlt.peekNextUnusedAddr()

addrStr = self.getAddrStr(wlt, nextAddr)
self.lblSelectWlt.setText('Will create new address: %s...' % \
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this removed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably a bad rebase/squash. I have added it back in.

qtdialogs.py Outdated
f.write(self.tr('Export Date: %1\n').arg(unixTimeToFormatStr(RightNow())))
f.write(self.tr('Total Funds: %1\n').argcoin2str(totalFunds, maxZeros=0).strip())
f.write(self.tr('Spendable Funds: %1\n').argcoin2str(spendFunds, maxZeros=0).strip())
f.write(self.tr('Unconfirmed Funds: %1\n').argcoin2str(unconfFunds, maxZeros=0).strip())
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These 3 lines missing one set of parenthesis around coin2str()

ArmoryQt.py Outdated
'now?', QMessageBox.Yes | QMessageBox.No)
reply = QMessageBox.information(self, self.tr('No Wallets!'), self.tr('''
You just clicked on a "bitcoin:" link to send money, but you
urrently have no wallets! Would you like to create a wallet
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo

Fixes for plural forms.

Typo fixes.

The dashboard labels requires stripping strings, but str() does not support some characters used in other languages, so they need to be moved to unicode()
@achow101
Copy link
Author

This has been merged as commits 03cef63...f3353eb

@achow101 achow101 closed this Feb 15, 2017
This was referenced Feb 15, 2017
@achow101 achow101 deleted the translations-setup branch March 3, 2017 20:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants