Jump to content

Quick Clipboard Translation


Recommended Posts

Hi everybody :)
The script Google Translation with GUI works fine, especially when the text to translate is long and plenty of languages can be used for translation.

But today, I also needed a shorter version, where I could translate in a snap (in a click) what is found in the clipboard, for example while browsing on web pages that are not written in my native language.

So I scripted what follows, based on :
1) a minimal GUI (no title, popup, resizable, topmost)
2) a label control, draggable ($GUI_WS_EX_PARENTDRAG) with same size as the GUI client size, so the GUI can be dragged anywhere (and stay on top) while dragging the label control, great !
3) a context menu associated to the label control.
4) an ini file wich will be created after we launch the script once. It will contain the gui coords when the script was exited, the background color of the label control, the language of the translated text etc...

The 1st time we run the script, the GUI appears like this :

GoogleTranslatev13apic1.png.ce15caf78080b876202135c70d896620.png


We resize it, move it near the buttons of our Browser (for example), we change the color of the background through the context menu (not changed for now, let's keep it yellow), we choose our native language (context menu). There are other options in the context menu, i.e. an InputBox if we want to type a couple of words to translate them quickly, an option to modify the transparency of the GUI, an option to minimize the GUI and finally an option to exit the script.

GoogleTranslatev13bpic2.png.6f740a9c01b47ecb7ee815d44e8d68da.png

For example, I didn't know what "caveat" means so I selected the 3 lines (see pic below), clicked "Translate" in the context menu and the translation appears in a MsgBox whose buttons got special captions (note the "Copy Text" button) as scripted a few hours ago in this thread

GoogleTranslatev13cpic3.thumb.png.3228108ba9f24a777574aab5b4bfae9e.png

As you see, the goal isn't to translate plenty of lines (it won't fit in a MsgBox and "Google Translation with GUI" is much more appropriate to do that) but just to translate a few sentences found here and there, no matter the original language, and to translate them quickly in a user-friendly way.

If your native language is not amongst the 6 languages already hard coded (english, french, german, italian, portuguese, spanish) and you would like to add it the script, then it's doable by modifying one line in the script, which is :

Local $aLangTo[][2] = [["en","English"],["fr","French"],["de","German"],["it","Italian"],["pt","Portuguese"],["es","Spanish"]]

The script requires the file "Json.au3" scripted by @AspirinJunkie (link found at 3rd line in the script), many thanks to him :)

; Version 13b (August 1, 2024)
; requires AutoIt 3.3.16.1 (which includes Maps, as Json.au3 requires Maps for some translations)

#include "Json.au3" ; by @AspirinJunkie, download from https://github.com/Sylvan86/autoit-json-udf
#include <FileConstants.au3>
#include <GUIConstantsEx.au3>
#include <Misc.au3>
#include <MsgBoxConstants.au3>
#include <StaticConstants.au3>
#include <WinAPISysWin.au3>
#include <WindowsConstants.au3>

Opt("MustDeclareVars", 1) ;0=no, 1=require pre-declaration
Opt("GUICloseOnESC", 0) ;1=ESC closes (default), 0=ESC won't close

Global $hGUI, $bContextMenu = True
Global $g_aCaption, $g_sTitle ; 2 global variables for _TimerProc()

Example()

;==============================================
Func Example()

    ; If a user wants to add/remove a "Language To" , then modify THE following line, that's all.
    Local $aLangTo[][2] = [["en","English"],["fr","French"],["de","German"],["it","Italian"],["pt","Portuguese"],["es","Spanish"]]
    Local $iMaxLangTo = Ubound($aLangTo)

    Local $sIniFile = StringTrimRight(@ScriptFullPath, 4) & ".ini" ; ".au3" | ".a3x" | ".exe" => ".ini"
    Local $aIni = _ReadIniFile($sIniFile)
    Local $iBkColor = $aIni[6], $iTrans = $aIni[7], $sLangTo = $aIni[8] ; "en" or "fr" or ... (or "" if ini file doesn't exist)

    $hGUI = GUICreate("Clipboard Translation", $aIni[4], $aIni[5], -1, -1, BitOr($WS_POPUP, $WS_SIZEBOX), $WS_EX_TOPMOST)
    WinSetTrans($hGUI, "", $iTrans)

    Local $idLabel = GUICtrlCreateLabel("Translate", 0, 0, $aIni[4], $aIni[5], BitOr($SS_CENTERIMAGE, $SS_CENTER), $GUI_WS_EX_PARENTDRAG)
    GUICtrlSetBkColor(-1, $iBkColor)

    Local $idContextMenu = GUICtrlCreateContextMenu($idLabel)
    Local $idTranslate = GUICtrlCreateMenuItem("Translate", $idContextMenu)
    GUICtrlCreateMenuItem("", $idContextMenu) ; separator
    Local $idMenuTo = GUICtrlCreateMenu("To", $idContextMenu) ; create the languages menuradioitem IMMEDIATELY after this line, in a loop.
        Local $bIsChecked
        For $i = 0 To $iMaxLangTo - 1
            GUICtrlCreateMenuItem($aLangTo[$i][1], $idMenuTo, -1, 1) ; 1 = create a menuradioitem
            If $sLangTo = $aLangTo[$i][0] Then
                GUICtrlSetState(-1, $GUI_CHECKED)
                $bIsChecked = True
            EndIf
        Next
        If Not $bIsChecked Then
            GUICtrlSetState($idMenuTo + 1, $GUI_CHECKED)
            $sLangTo = $aLangTo[0][0]
        EndIf
    Local $idInputBox = GUICtrlCreateMenuItem("InputBox", $idContextMenu)
    GUICtrlCreateMenuItem("", $idContextMenu)
    Local $idSelectColor = GUICtrlCreateMenuItem("Back Color", $idContextMenu)
    Local $idTransparency = GUICtrlCreateMenuItem("Transparency", $idContextMenu)
    GUICtrlCreateMenuItem("", $idContextMenu)
    Local $idMinimize = GUICtrlCreateMenuItem("Minimize", $idContextMenu)
    Local $idQuit = GUICtrlCreateMenuItem("Quit", $idContextMenu)

    WinMove($hGUI, "", $aIni[0], $aIni[1], $aIni[2], $aIni[3])

    GUISetState(@SW_SHOW)
    GUIRegisterMsg($WM_CONTEXTMENU, "WM_CONTEXTMENU") ; deactivate context menu while setting transparency

    Local $nMsg
    While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
            Case $idQuit ; context menu ($GUI_EVENT_CLOSE not usable in this script because no GUI close button and GUICloseOnESC, 0)
                _WriteIniFile($sIniFile, $iBkColor, $iTrans, $sLangTo)
                ExitLoop

            Case $idInputBox ; context menu
                Local $sTextInput = InputBox("InputBox", "Enter a string to translate", "", " M", _ ; M means Mandatory
                    220, 140, Default, Default, 0, $hGui)
                If @error <> 1 Then ; 3 possible reasons for @error = 1 : click on InputBox close X button OR push Cancel button OR Esc key.
                    ClipPut(StringStripWS($sTextInput, 1 + 2)) ; 1 = strip leading white space, 2 = strip trailing white space.
                    CONTINUECASE ; translate (see Case JUST below : do not insert any other Case between them or ContinueCase will fail !)
                EndIf

            Case $idTranslate ; context menu
                GUICtrlSetState($idTranslate, $GUI_DISABLE) ; prevent accidental double click on the context menuitem (possible ?)
                GUICtrlSetData($idLabel, "Processing...")
                _Translate($sLangTo, $idLabel)
                GUICtrlSetData($idLabel, "Translate")
                GUICtrlSetState($idTranslate, $GUI_ENABLE)

            Case $idMenuTo + 1 To $idMenuTo + $iMaxLangTo ; context menu (any "Language To" menuitem)
                $sLangTo = $aLangTo[$nMsg - $idMenuTo - 1][0] ; will be saved to .ini file (ex. "en" or "fr" or etc...)

            Case $idSelectColor ; context menu
                Local $iChooseColor = _ChooseColor(2, $iBkColor, 2, $hGUI) ; both 2's mean RGB hex (output & input)
                If $iChooseColor <> -1 Then
                    $iBkColor = $iChooseColor
                    GUICtrlSetBkColor($idLabel, $iBkColor)
                EndIf

            Case $idTransparency ; context menu
                $bContextMenu = False
                $iTrans = _Transparency($iTrans)
                $bContextMenu = True

            Case $idMinimize ; context menu
                WinSetState($hGUI, "", @SW_MINIMIZE)
        EndSwitch
    WEnd

    GUIDelete($hGUI)
EndFunc   ;==>Example

;==============================================
Func WM_CONTEXTMENU($hwnd, $iMsg, $wParam, $lParam)

    If Not $bContextMenu Then Return 0
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_CONTEXTMENU

;==============================================
Func _Transparency($iTrans)

    ; Calculate coords so $hGUI2 is always created near $hGUI
    Local $aPos = WinGetPos($hGUI), $iLeft = $aPos[0], $iTop = $aPos[1], $iRight = $iLeft + $aPos[2], $iBottom = $iTop + $aPos[3]
    Local $iLeft2, $iTop2, $iWidth2 = 220, $iHeight2 = 30 ; $hGUI2 (30 is good for future slider thumb size, tested)
    $iLeft2 = ($iLeft + $iWidth2 + 10 < @DesktopWidth) ? $iLeft : $iRight - ($iWidth2 + 10)
    $iTop2 = ($iBottom + 20 + $iHeight2 + 20 < @DesktopHeight) ? $iBottom + 10 : $iTop - 10 - ($iHeight2 + 20)

    Local $hGUI2 = GUICreate("Transparency " & $iTrans, $iWidth2, $iHeight2, $iLeft2, $iTop2, _
        BitOR($WS_CAPTION, $WS_POPUP, $WS_SYSMENU, $WS_SIZEBOX), BitOr($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))

    Local $idSlider = GUICtrlCreateSlider(0, 0, $iWidth2, $iHeight2)
    GUICtrlSetLimit(-1, 255, 100) ; set max/min value (never set minimal value at 0, or $hGUI won't be clickable when transparency 0 !)
    GUICtrlSetData(-1, $iTrans)

    GUISetState(@SW_SHOW, $hGUI2)

    Local $iTrans_Old = $iTrans
    While 2
        Switch GUIGetMsg()
            Case $GUI_EVENT_CLOSE
                ExitLoop
        EndSwitch

        $iTrans = GUICtrlRead($idSlider)
        If $iTrans <> $iTrans_Old Then
            WinSetTrans($hGUI, "", $iTrans)
            WinSetTitle($hGUI2, "", "Transparency " & $iTrans)
            $iTrans_Old = $iTrans
        EndIf
    WEnd

    GUIDelete($hGUI2)

    Return $iTrans
EndFunc   ;==>_Transparency

;==============================================
Func _Translate($sLangTo, $idLabel)

    Local $sLangFrom = "auto"

    Local $iMaxInputLength = 5460 ; this value allows any encoded string to be < 65536 length, even if each character is a Unicode character
                                  ; requiring 4 bytes. In this case, each character will be coded on 12 bytes in the string "%..%..%..%.."
                                  ; 5460 * 12 = 65520 bytes (which is < 65536)

    Local $bTruncated = (StringLen(ClipGet()) > $iMaxInputLength) ? True : False
    Local $sEncoded = _URIEncode(StringLeft(ClipGet(), $iMaxInputLength))

    If StringLen($sEncoded) = 0 Then
        GUICtrlSetData ($idLabel, "Done")
        MsgBox($MB_TOPMOST, "Clipboard is empty", "Nothing to translate", 0, $hGUI)
        Return
    EndIf

    Local $sLangUsed, $sTranslated = _GoogleAPITranslate($sEncoded, $sLangFrom, $sLangTo, $sLangUsed)
    GUICtrlSetData ($idLabel, "Done")

    If $sLangUsed Then ; translation has succeeded and $sLangUsed always contains the code that Google used for its last translation
        Dim $g_aCaption[2] = ["Copy text", "Ok"] ; 2 buttons
        $g_sTitle =  "Clipboard translated From  " & _
            (($sLangFrom = "auto") ? ("auto (" & $sLangUsed & ")") : ($sLangFrom)) & _
            "  To  " & $sLangTo & _
            ($bTruncated ? "  (truncated)" : "")
        Local $iChoice = _MsgBox(BitOr($MB_OKCANCEL, $MB_DEFBUTTON2, $MB_TOPMOST), $g_sTitle, _
            $sTranslated, 0, $hGUI) ; think of $MB_YESNO too (2 buttons without Esc allowed)
        If $iChoice = 1 Then ; button "Copy text"
            ClipPut($sTranslated)
        EndIf

    Else ; translation failed as $sLangUsed is still empty
        MsgBox($MB_TOPMOST, "Error", _
            "Something went wrong during translation" & @crlf & _
            "(Internet connection ok ?)", 0, $hGUI)
    EndIf
EndFunc   ;==>_Translate

;==============================================
Func _GoogleAPITranslate(Const ByRef $sEncoded, $sFrom, $sTo, ByRef $sLangUsed)
    Local $oLocalCOMErrorHandler = ObjEvent("AutoIt.Error", "_ErrFuncLocal")

    ; format and send request
    With ObjCreate("WinHttp.WinHttpRequest.5.1") ; thanks AspirinJunkie for correct syntax of the Object methods below.
        .Open("POST", "https://translate.googleapis.com/translate_a/single", False)
        .SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
        .Send(StringFormat("client=gtx&sl=%s&tl=%s&dt=t&q=%s", $sFrom, $sTo, $sEncoded))
         Local $sResponse = .ResponseText
    EndWith
    ; ConsoleWrite(BinaryToString(StringToBinary("$sResponse: " & $sResponse, $SB_UTF8), $SB_ANSI) & @crlf)
    Local $vResponse = _JSON_Parse($sResponse)

    ; process return
    Local $sOutput = ""
    If VarGetType($vResponse) = 'Array' Then
        Local $aData = $vResponse[0]
        If VarGetType($aData) = 'Array' Then
            For $i = 0 To UBound($aData) -1
                $sOutput &= ($aData[$i])[0]
            Next
        EndIf
        $sLangUsed = $vResponse[2] ; ex. "en" , "de" , ... to display which language Google used for translation, when $sFrom = "auto"
    EndIf

    Return $sOutput
EndFunc   ;==>_GoogleAPITranslate

;==============================================
Func _URIEncode(Const ByRef $sData)

    ; code below from Prog@ndy (minor changes) : https://www.autoitscript.com/forum/topic/95850-url-encoding/?do=findComment&comment=689060
    ; maybe Chr(32) should always be encoded as "%20" and not "+" to be compatible with all browsers (?) we'll see...
    Local $aData = StringSplit(BinaryToString(StringToBinary($sData, $SB_UTF8), $SB_ANSI), "") ; "" => each character returns as an element
    Local $nChar, $sEncoded = ""
    For $i = 1 To $aData[0]
        $nChar = Asc($aData[$i])
        Switch $nChar
            Case 45, 46, 48 To 57, 65 To 90, 95, 97 To 122, 126
                $sEncoded &= $aData[$i]
            Case 32
                $sEncoded &= "+"
            Case Else
                $sEncoded &= "%" & Hex($nChar, 2)
        EndSwitch
    Next
    Return $sEncoded
EndFunc   ;==>_URIEncode

;==============================================
Func _ErrFuncLocal($oError)
    ; https://www.autoitscript.com/forum/topic/191401-com-error-handling-in-a-udf-best-practice/?do=findComment&comment=1373102

    MsgBox($MB_TOPMOST, @ScriptName & " (" & $oError.scriptline & ") : ==> Local COM error handler - COM Error intercepted !", _
        @Tab & "err.number is: " & @Tab & @Tab & "0x" & Hex($oError.number) & @crlf & _
        @Tab & "err.windescription:" & @Tab & @Tab & StringStripWS($oError.windescription, 2) & @crlf & _
        @Tab & "err.description is: " & @Tab & @Tab & StringStripWS($oError.description, 2) & @crlf & _
        @Tab & "err.source is: " & @Tab & @Tab & $oError.source & @crlf & _
        @Tab & "err.helpfile is: " & @Tab & @Tab & $oError.helpfile & @crlf & _
        @Tab & "err.helpcontext is: " & @Tab & @Tab & $oError.helpcontext & @crlf & _
        @Tab & "err.lastdllerror is: " & @Tab & @Tab & $oError.lastdllerror & @crlf & _
        @Tab & "err.scriptline is: " & @Tab & @Tab & $oError.scriptline & @crlf & _
        @Tab & "err.retcode is: " & @Tab & @Tab & "0x" & Hex($oError.retcode), 0, $hGUI)
EndFunc   ;==>_ErrFuncLocal

;===========================================
Func _MsgBox($iFlag, $g_sTitle, ByRef $sText, $iTimeOut = 0, $hWnd = 0)

    Local $hTimerProc = DllCallbackRegister('_TimerProc', 'none', 'hwnd;uint;uint_ptr;dword')
    Local $iTimerID = _WinAPI_SetTimer(0, 0, 10, DllCallbackGetPtr($hTimerProc))

    Local $iChoice = MsgBox($iFlag, $g_sTitle, $sText, $iTimeOut, $hWnd)

    _WinAPI_KillTimer(0, $iTimerID)
    DllCallbackFree($hTimerProc)
    Return $iChoice
EndFunc   ;==>_MsgBox

;===========================================
Func _TimerProc($hWnd, $iMsg, $iTimerID, $iTime)

    If WinActive($g_sTitle) Then
        _WinAPI_KillTimer(0, $iTimerID)
        If Ubound($g_aCaption) > 3 Then ReDim $g_aCaption[3]
        For $i = 0 To Ubound($g_aCaption) - 1
            ControlSetText($g_sTitle, "", "Button" & ($i + 1), $g_aCaption[$i])
        Next
    EndIf
EndFunc   ;==>_TimerProc

;==============================================
Func _ReadIniFile($sIniFile)

    If FileExists($sIniFile) Then
        Local $aIni = FileReadToArray($sIniFile)
        If @extended <> 9 Then
            MsgBox($MB_TOPMOST, "_FileReadToArray: extended = " & @extended, _
                "Ini file should have exactly 9 lines, not " & @extended & @crlf & _
                "(this message is normal if you just upgraded the script to a new version)" & @crlf & _
                "" & @crlf & _
                "Incompatible .ini file will be deleted now, please run the script again.")
            FileDelete($sIniFile)
            Exit
        EndIf

    Else ; ini file doesn't exist
        Local $aIni[9]
        $aIni[0] = @DesktopWidth / 2 - 50 ; GUI X position
        $aIni[1] = @DesktopHeight / 2 - 50 ; GUI Y position
        $aIni[2] = 106 ; GUI Width
        $aIni[3] = 106 ; GUI Height
        $aIni[4] = 100 ; GUI Width  (client)
        $aIni[5] = 100 ; GUI Height (client)
        $aIni[6] = 0xFFFF00 ; yellow (background color of label control)
        $aIni[7] = 255 ; opaque (GUI transparency)
        $aIni[8] = "" ; code of Language To (it will become for example "en" or "fr" or etc...)
    EndIf

    Return $aIni
EndFunc   ;==>_ReadIniFile

;==============================================
Func _WriteIniFile($sIniFile, $iBkColor, $iTrans, $sLangTo)

    Local $hIni = FileOpen($sIniFile, $FO_OVERWRITE)
    If $hIni = -1 Then
        MsgBox($MB_TOPMOST, "FileOpen error", $sIniFile, 0, $hGUI)
    Else
        Local $aPos = WinGetPos($hGUI)
        Local $aCli = WinGetClientSize($hGUI)
        FileWrite($hIni, _
            $aPos[0] & @crlf & _
            $aPos[1] & @crlf & _
            $aPos[2] & @crlf & _
            $aPos[3] & @crlf & _
            $aCli[0] & @crlf & _
            $aCli[1] & @crlf & _
            $iBkColor & @crlf & _
            $iTrans & @crlf & _
            $sLangTo)
            ; There are 9 lines in the ini file (no need of a last @crlf , though it is allowed but not mandatory)
        FileClose($hIni)
    EndIf
EndFunc   ;==>_WriteIniFile

 

Edited by pixelsearch
minor change : renamed a couple of variables
Link to comment
Share on other sites

New version 13c (August 2, 2024)
* Translation is done in a MsgBox whose buttons captions are personalized (look at the last pic in the 1st post, a MsgBox button got a "Copy Text" caption). So the user can now easily copy the result of the translation in the clipboard, if necessary.

* In this new version, the translation is done in an easier way, directly by a left-click inside the GUI. It wasn't obvious (at least for me) to achieve this, because the GUI is also  draggable by a left-click inside the GUI. Fingers crossed :)

Link to comment
Share on other sites

Reverted to version 13b, which translates via the context menu

A couple of users told me they prefer to translate via the context menu. As I prefer it too (a lot !) then I reverted to version 13b that I use daily for a couple of weeks . Added a couple of functionalities (see pictures of context menu in 1st post) . Script updated in 1st post.

This will be the last update for this script (except if a bug is detected)

Happy translations :)

Link to comment
Share on other sites

Posted (edited)

Thanks DanyFirex for your appreciation :)

Never say never... I wrote yesterday that there won't be any update for the script (except if a bug is found)
Though there is no bug found (for now !) I improved the code today, to get rid of plenty of lines & variables, also to make it easier for a user who wants to add / remove a language code (It just happened to me when I wanted to add the Portuguese language)

So bye-bye to this :

Local $idLangTo1 = GUICtrlCreateMenuItem("English", $idMenuTo, -1, 1) ; 1 = create a menuradioitem
Local $idLangTo2 = GUICtrlCreateMenuItem("French", $idMenuTo, -1, 1)
Local $idLangTo3 = GUICtrlCreateMenuItem("German", $idMenuTo, -1, 1)
Local $idLangTo4 = GUICtrlCreateMenuItem("Italian", $idMenuTo, -1, 1)
Local $idLangTo5 = GUICtrlCreateMenuItem("Spanish", $idMenuTo, -1, 1)

...

Case $idLangTo1 ; context menu
    $idLangTo = $idLangTo1
    $sLangTo = "en" ; english

Case $idLangTo2 ; context menu
    $idLangTo = $idLangTo2
    $sLangTo = "fr" ; french

Case $idLangTo3 ; context menu
    $idLangTo = $idLangTo3
    $sLangTo = "de" ; german

Case $idLangTo4 ; context menu
    $idLangTo = $idLangTo4
    $sLangTo = "it" ; italian

Case $idLangTo5 ; context menu
    $idLangTo = $idLangTo5
    $sLangTo = "es" ; spanish

Replaced with that :

For $i = 0 To $iMaxLangTo - 1
    GUICtrlCreateMenuItem($aLangTo[$i][1], $idMenuTo, -1, 1) ; 1 = create a menuradioitem
    ...
Next

...

Case $idMenuTo + 1 To $idMenuTo + $iMaxLangTo ; context menu (any "Language To" menuitem)
    $sLangTo = $aLangTo[$nMsg - $idMenuTo - 1][0] ; will be saved to .ini file (ex. "en" or "fr" or etc...)

To add / remove languages from the script, the only line to modify in the script is :

; If a user wants to add/remove a "Language To" , then modify THE following line, that's all.
Local $aLangTo[][2] = [["en","English"],["fr","French"],["de","German"],["it","Italian"],["pt","Portuguese"],["es","Spanish"]]

Script updated in 1st post above.

Edit : for the record, here are the codes of 133 languages. They could be useful to some users who can pick their native language from the list below and add it to the list found in the script :

["af","Afrikaans"],["sq","Albanian"],["am","Amharic"],["ar","Arabic"],["hy","Armenian"],["as","Assamese"],["ay","Aymara"],["az","Azerbaijani"],["bm","Bambara"],["eu","Basque"],["be","Belarusian"],["bn","Bengali"],["bho","Bhojpuri"],["bs","Bosnian"],["bg","Bulgarian"],["ca","Catalan"],["ceb","Cebuano"],["ny","Chichewa"],["zh-CN","Chinese (Simplified)"],["zh-TW","Chinese (Traditional)"],["co","Corsican"],["hr","Croatian"],["cs","Czech"],["da","Danish"],["dv","Dhivehi"],["doi","Dogri"],["nl","Dutch"],["en","English"],["eo","Esperanto"],["et","Estonian"],["ee","Ewe"],["tl","Filipino"],["fi","Finnish"],["fr","French"],["fy","Frisian"],["gl","Galician"],["ka","Georgian"],["de","German"],["el","Greek"],["gn","Guarani"],["gu","Gujarati"],["ht","Haitian Creole"],["ha","Hausa"],["haw","Hawaiian"],["iw","Hebrew"],["hi","Hindi"],["hmn","Hmong"],["hu","Hungarian"],["is","Icelandic"],["ig","Igbo"],["ilo","Ilocano"],["id","Indonesian"],["ga","Irish"],["it","Italian"],["ja","Japanese"],["jw","Javanese"],["kn","Kannada"],["kk","Kazakh"],["km","Khmer"],["rw","Kinyarwanda"],["gom","Konkani"],["ko","Korean"],["kri","Krio"],["ku","Kurdish (Kurmanji)"],["ckb","Kurdish (Sorani)"],["ky","Kyrgyz"],["lo","Lao"],["la","Latin"],["lv","Latvian"],["ln","Lingala"],["lt","Lithuanian"],["lg","Luganda"],["lb","Luxembourgish"],["mk","Macedonian"],["mai","Maithili"],["mg","Malagasy"],["ms","Malay"],["ml","Malayalam"],["mt","Maltese"],["mi","Maori"],["mr","Marathi"],["mni-Mtei","Meiteilon (Manipuri)"],["lus","Mizo"],["mn","Mongolian"],["my","Myanmar (Burmese)"],["ne","Nepali"],["no","Norwegian"],["or","Odia (Oriya)"],["om","Oromo"],["ps","Pashto"],["fa","Persian"],["pl","Polish"],["pt","Portuguese"],["pa","Punjabi"],["qu","Quechua"],["ro","Romanian"],["ru","Russian"],["sm","Samoan"],["sa","Sanskrit"],["gd","Scots Gaelic"],["nso","Sepedi"],["sr","Serbian"],["st","Sesotho"],["sn","Shona"],["sd","Sindhi"],["si","Sinhala"],["sk","Slovak"],["sl","Slovenian"],["so","Somali"],["es","Spanish"],["su","Sundanese"],["sw","Swahili"],["sv","Swedish"],["tg","Tajik"],["ta","Tamil"],["tt","Tatar"],["te","Telugu"],["th","Thai"],["ti","Tigrinya"],["ts","Tsonga"],["tr","Turkish"],["tk","Turkmen"],["ak","Twi"],["uk","Ukrainian"],["ur","Urdu"],["ug","Uyghur"],["uz","Uzbek"],["vi","Vietnamese"],["cy","Welsh"],["xh","Xhosa"],["yi","Yiddish"],["yo","Yoruba"],["zu","Zulu"]

 I just did a test and added temporarily the 133 languages in the script (in a snap) by modifying the appropriate line... and it worked fine. Now let's go back to 6 languages.

Happy translations :bye:

Edited by pixelsearch
a temporary test with 133 languages in the context menu
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...