Jump to content
Sign in to follow this  
AZJIO

Translates GUI into the native language

Recommended Posts

AZJIO

1. Open the script, it gives the window a list of all known texts.
2 . Translate the text into QTranslate and return the translated text in the same window.
3 . Click the "Translated" and the clipboard get script.

There are 2 modes . The first replaces the text . The second mode adds an array of the top of the script.

#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <ButtonConstants.au3>
#include <Array.au3>
#include <FileOperations.au3>
#include <UserGUI.au3>

$LngTitle = 'Translated'

; En
$LngOpn = 'Open'
$LngLPc = 'pieces'
$LngStr = 'Strings'
$LngSet = 'Setting'
$LngTrc = 'Translated'
$LngNoLimit = 'no limit'
$LngSB1 = 'Done. It Is Sent in clipboard. @extended = '
$LngMB1 = 'Message'
$LngMB2 = 'The number of rows is not the same'
$LngMB3 = ', continue?'
$LngUsAr = 'Use an array of'
$LngMiLe = 'The minimum length of the string'
$LngIgn = 'Ignore the row in which the only characters:'

; Ru
If @OSLang = 0419 Then
    $LngOpn = 'Открыть'
    $LngLPc = 'шт'
    $LngStr = 'Строки'
    $LngSet = 'Настройки'
    $LngTrc = 'Перевести'
    $LngNoLimit = 'Нет лимита'
    $LngSB1 = 'Готово. Отправлено в буфер обмена. Количество замен:'
    $LngMB1 = 'Сообщение'
    $LngMB2 = 'Число строк не совпадает'
    $LngMB3 = ', продолжить?'
    $LngUsAr = 'Использовать массив'
    $LngMiLe = 'Минимальная длина строки'
    $LngIgn = 'Игнорировать строку, в которой только символы:'
EndIf

Local $sCurrentPath, $sTextAU3, $iCountStr, $aTrslText
Local $TrArr = 0, $TrEmpty = 1, $iLengthLine = 1, $sIgnore = '\<>!@#$ ' & @Tab & '%^&*()-+=_{}[]:;|/?.,'

$hGui = GUICreate($LngTitle, 450, 460, -1, -1, $WS_OVERLAPPEDWINDOW, $WS_EX_ACCEPTFILES)

$iBtnOpen = GUICtrlCreateButton('-', 5, 4, 21, 21, $BS_ICON)
GUICtrlSetImage(-1, @SystemDir & '\shell32.dll', 4, 0)
GUICtrlSetResizing(-1, 2 + 32 + 256 + 512)
GUICtrlSetTip(-1, $LngOpn)

$iEdit = GUICtrlCreateEdit('', 5, 30, 450 - 10, 460 - 50)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
; GUICtrlSetBkColor(-1, 0xf0f0f0) ; 0xE0DFE3
GUICtrlSetResizing(-1, 6 + 32 + 64)

$iTranslated = GUICtrlCreateButton('T', 30, 4, 21, 21, $BS_ICON)
GUICtrlSetImage(-1, @SystemDir & '\shell32.dll', 25, 0)
GUICtrlSetResizing(-1, 2 + 32 + 256 + 512)
GUICtrlSetTip(-1, $LngTrc)

$iSetting = GUICtrlCreateButton('S', 55, 4, 21, 21, $BS_ICON)
GUICtrlSetImage(-1, @SystemDir & '\shell32.dll', -91, 0)
GUICtrlSetResizing(-1, 2 + 32 + 256 + 512)
GUICtrlSetTip(-1, $LngSet)

$iStatusBar = GUICtrlCreateLabel('StatusBar', 5, 460 - 17, 450 - 10, 17)
GUICtrlSetResizing(-1, 1 + 64 + 512)

$iDummy = GUICtrlCreateDummy()
Local $aAccelKeys[1][2] = [["^a", $iDummy]]

; если раскладка не совпадает с англ. яз. то временно переключаем в неё, чтобы зарегистрировать горячие клавиши
$tmp = 0
$KeyLayout = RegRead("HKCU\Keyboard Layout\Preload", 1)
If Not @error And $KeyLayout <> 00000409 Then
    _WinAPI_LoadKeyboardLayout(0x0409)
    $tmp = 1
EndIf

GUISetAccelerators($aAccelKeys)
If $tmp = 1 Then _WinAPI_LoadKeyboardLayout(Dec($KeyLayout)) ; восстанавливаем раскладку по умолчанию

GUISetState()
While 1
    Switch GUIGetMsg()
        Case $iSetting
            _Setting()
        Case $iDummy
            GUICtrlSendMsg($iEdit, $EM_SETSEL, 0, -1)
        Case $iBtnOpen
            $tmp = FileOpenDialog('', @ScriptDir & "\", "AutoIt Script (*.au3)", 1, '', $hGui)
            If @error Then ContinueLoop
            _Open($tmp)
        Case -13
            _Open(@GUI_DragFile)
        Case $iTranslated
            If Not $sCurrentPath Or Not $iCountStr Then ContinueLoop
            $iEdit0 = GUICtrlRead($iEdit) ; Новый текст
            $aTrslTextNew = StringSplit($iEdit0, @CRLF, 3)
            
; _ArrayDisplay($aTrslTextNew, 'Array')
            $iCountStrNew = UBound($aTrslTextNew)
            If $iCountStrNew <> $iCountStr And MsgBox(4, $LngMB1, $LngMB2 & ' (' & $iCountStrNew & '<>' & $iCountStr & ')' & $LngMB3) = 7 Then ContinueLoop
            $iCount = $iCountStr
            $iCountCur = 0
            $n = 0
            If $iCountStrNew < $iCountStr Then $iCount = $iCountStrNew
            $sTmpTextAU3 = $sTextAU3
            If $TrArr Then
                $sArrayVarText = '' ; Формирования кода массива
                $sArrayVarTextNew = 'If @OSLang = 0419 Then' & @CRLF ; Формирования кода массива переведённого
                For $i = 0 To $iCount - 1
                    If Not ($aTrslText[$i] == $aTrslTextNew[$i]) Then
                        $n +=1
                        $sArrayVarText &= '$Lng[' & $n & '] = ' & $aTrslText[$i] & @CRLF ; Формирования кода элементов массива
                        $sArrayVarTextNew &= @TAB & '$Lng[' & $n & '] = ' & $aTrslTextNew[$i] & @CRLF ; Формирования кода элементов массива
                        $sTmpTextAU3 = StringReplace($sTmpTextAU3, $aTrslText[$i], '$Lng[' & $n & ']', 0, 1)
                        $iCountCur += @extended
                    EndIf
                Next
                $sTmpTextAU3 = 'Global $Lng[' & $n + 1 & ']' & @CRLF & $sArrayVarText & @CRLF & $sArrayVarTextNew & 'EndIf' & @CRLF & @CRLF & $sTmpTextAU3
            Else
                For $i = 0 To $iCount - 1
                    If $aTrslText[$i] <> $aTrslTextNew[$i] Then
                        $sTmpTextAU3 = StringReplace($sTmpTextAU3, $aTrslText[$i], $aTrslTextNew[$i], 0, 1)
                        $iCountCur += @extended
                    EndIf
                Next
            EndIf
            ClipPut($sTmpTextAU3)
            $sTmpTextAU3 = ''
            GUICtrlSetData($iStatusBar, $LngSB1 & ' ' & $iCountCur)
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func _Setting()
    Local $EditBut, $hGui1, $aRect, $msg, $StrBut
    $aRect = _GetChildCoor($hGui, 410, 240)
    GUISetState(@SW_DISABLE, $hGui)

    $hGui1 = GUICreate($LngSet, $aRect[0], $aRect[1], $aRect[2], $aRect[3], BitOR($WS_CAPTION, $WS_SYSMENU, $WS_POPUP), -1, $hGui)

    $iChRpc = GUICtrlCreateCheckbox($LngUsAr, 5, 5, 130, 17)
    If $TrArr Then GUICtrlSetState(-1, $GUI_CHECKED)

    GUICtrlCreateLabel($LngMiLe, 5, 28, 170, 17)
    $iLLine = GUICtrlCreateCombo('', 175, 25, 70, 23)
    $sLimit = $LngNoLimit &  '|0|1|2|5|20|50|200|500'
    If $iLengthLine = -1 Then
        GUICtrlSetData($iLLine, $sLimit, $LngNoLimit)
    Else
        If Not StringInStr( '|' & $sLimit & '|',  '|' & $iLengthLine & '|') Then $sLimit &=  '|' & $iLengthLine
        GUICtrlSetData($iLLine, $sLimit, $iLengthLine)
    EndIf

    GUICtrlCreateLabel($LngIgn, 5, 53, 170, 17)
    $iIgnore = GUICtrlCreateInput($sIgnore, 175, 50, 170, 22)
    
    $OK = GUICtrlCreateButton("OK", (410 - 60) / 2, 240 - 35, 60, 30)

    GUISetState(@SW_SHOW, $hGui1)
    While 1
        Switch GUIGetMsg()
            Case $OK
                If GUICtrlRead($iChRpc) = 1 Then
                    $TrArr = 1
                Else
                    $TrArr = 0
                EndIf
                $iLLine0 = GUICtrlRead($iLLine)
                If $iLLine0 = $LngNoLimit Then
                    $iLengthLine = -1
                Else
                    If StringIsDigit($iLLine0) And $iLLine0>=0 Then $iLengthLine = $iLLine0
                EndIf
                $tmp = GUICtrlRead($iIgnore)
                If $sIgnore <> $tmp Then $sIgnore = _Unique($tmp)
                ContinueCase
            Case $GUI_EVENT_CLOSE
                GUISetState(@SW_ENABLE, $hGui)
                GUIDelete($hGui1)
                ExitLoop
        EndSwitch
    WEnd
EndFunc   ;==>_Setting

Func _Unique($string)
    $a = StringSplit($string, '', 2)
    $string = _ArrayToString(_ArrayUnique($a), '', 1)
    Return $string
EndFunc

Func _Open($sFilePath)
    If StringRegExp($sFilePath, '\v') Then $sFilePath = StringRegExpReplace($sFilePath, '\v.*', '')
    $sTmp = _FO_IsDir($sFilePath)
    If @error Or $sTmp Or StringRight($sFilePath, 4) <> '.au3' Then Return ; Вылет если это не скрипт

    $sTextAU3 = FileRead($sFilePath)
    $Tmp = $sTextAU3
    $sRes = ''
    _stripComments($Tmp) ; Удаление комментариев
    ; MsgBox(0, 'Сообщение', '(?m)"[^"]' & $sLmt & '?"|''[^'']' & $sLmt & '?''')
    ; $aTrslText = StringRegExp($sTextAU3, '(?m)"[^"]' & $sLmt & '?"|''[^'']' & $sLmt & '?''', 3) ; Извлечение текстов
    $aTrslText = StringRegExp($Tmp, '(?m)"[^"]*?"|''[^'']*?''', 3) ; Извлечение текстов
    If @error Then
        Return _Clear()
    Else
        If $iLengthLine > -1 Then
            $tmp = $iLengthLine + 2
            For $i = 0 To UBound($aTrslText) - 1
                If StringLen($aTrslText[$i]) < $tmp Then $aTrslText[$i] = ''
            Next
        EndIf
        If $sIgnore Then
            $tmp = $sIgnore
            $tmp = StringRegExpReplace($sIgnore, '[][\\^-]', '\\$0')
            For $i = 0 To UBound($aTrslText) - 1
                If StringRegExpReplace($aTrslText[$i], '[''"' & $tmp & ']+', '') = '' Then $aTrslText[$i] = ''
            Next
        EndIf
        $sCurrentPath = $sFilePath
        $sRes = _StringUnique($aTrslText) ; Удаление дубликатов
        $iCountStr = @extended
        If @error Then Return _Clear()
        ; $iCountStr = UBound($aTrslText)
        ; For $i In $aTrslText
        ; For $i = 0 To UBound($aTrslText) - 1
            ; If $aTrslText[$i] Then $sRes &= $aTrslText[$i] & @CRLF
            ; $sRes &= $i & @CRLF
        ; Next
        ; $sRes = StringTrimRight($sRes, 2)
        GUICtrlSetData($iEdit, $sRes)
        WinSetTitle($hGui, '', $LngTitle & ' (' & StringRegExpReplace($sCurrentPath, '^.*\\(.*)$', '\1') & ')')
    EndIf
    GUICtrlSetData($iStatusBar, $LngStr & ' - ' & $iCountStr & ' ' & $LngLPc)
    GUICtrlSetState($iEdit, $GUI_FOCUS)
EndFunc   ;==>_Open

Func _Clear()
    $sCurrentPath = ''
    $sTextAU3 = ''
    $iCountStr = 0
    $aTrslText = 0
    GUICtrlSetData($iEdit, '')
    WinSetTitle($hGui, '', $LngTitle)
    GUICtrlSetData($iStatusBar, 'error')
EndFunc

Func _StringUnique(ByRef $aArray)
    Local $i, $k
    Local $oSD = ObjCreate("Scripting.Dictionary")
    $oSD.CompareMode = 0

    $k = 0
    $sText = ''
    For $i In $aArray
        If Not $oSD.Exists($i) And $i Then
            $oSD.Add($i, '')
            $sText &= $i & @CRLF
            $k += 1
        EndIf
    Next
    If Not $k Then
        $aArray = 0
        Return SetError(2, 0, '')
    EndIf
    ; $aArray = $oSD.Keys()
    $sText = StringTrimRight($sText, 2)
    $aArray = StringSplit($sText, @CRLF, 3) ; Нативно извлекаем, без последствий
    ; Return $oDict.Keys()
    Return SetError(0, $k, $sText)
EndFunc   ;==>_StringUnique

Func _ArrayRemoveDuplicates2(Const ByRef $aArray)
    If Not IsArray($aArray) Then Return SetError(1, 0, 0)
    Local $oDict = ObjCreate("Scripting.Dictionary")
    $oDict.CompareMode = 0 ; учитывать регистр букв, бинарное сравнение
    For $i In $aArray
        If Not $i=='' Then ContinueLoop ; Удаление пусты строк
        $oDict.Item($i) ; shown by wraithdu
    Next
    Return $oDict.Keys()
EndFunc   ;==>_ArrayRemoveDuplicates

; заимствовано из "Organize Includes"
Func _stripComments(ByRef $string)
    $string = StringRegExpReplace($string, "(?s)\r(?!\n)", '\r\n') ; ??? добавляем @LF в строку, если его нет (AZJIO)
    ;Author: Prog@ndy
    $string = StringReplace(StringReplace($string, "#comments-start", "#cs", 0, 2), "#comments-end", "#ce", 0, 2)
    ; $string = StringRegExpReplace($string, "(?si)(\v|\A)\h*#cs\b.*?\v\h*#ce\b", '') ; remove simple block comments (mod AZJIO)
    #region remove nested block-comments
    Local $match, $depth, $offset, $start, $CommentsAfterce
    While 1
        $depth = 0
        $match = StringRegExp($string, "(?im)^\h*#cs\b", 1)
        $start = @extended
        If @error Then ExitLoop
        Do
            $match = StringRegExp($string, "(?im)^\h*#c([se])\b", 1, $offset)
            $offset = @extended
            Select
                Case @error
                    Return False
                Case $match[0] = "e"
                    $depth -= 1
                Case Else
                    $depth += 1
            EndSelect
        Until $depth < 1

        $string = StringLeft($string, $start - 4) & StringRegExpReplace(StringMid($string, $offset), ".*", '', 1)
;~         $string = StringLeft($string, $start-4) & StringMid($string, $offset)
    WEnd
    #endregion remove nested block-comments
    $string = StringRegExpReplace($string & @CRLF, '(?m)^((?:[^''";]*([''"]).*?\2)*[^;]*)\h*;.*$', '\1') ; remove one-line comments (недостаток - не работает если @CR без @LF)
    $string = StringRegExpReplace($string, '\s+\z', '') ; удалить пустое в конце
    Return True
EndFunc   ;==>_stripComments

Func _WinAPI_LoadKeyboardLayout($sLayoutID, $hWnd = 0)
    Local Const $WM_INPUTLANGCHANGEREQUEST = 0x50
    Local $aRet = DllCall("user32.dll", "long", "LoadKeyboardLayoutW", "wstr", Hex($sLayoutID, 8), "int", 0)

    If Not @error And $aRet[0] Then
        If $hWnd = 0 Then
            $hWnd = WinGetHandle(AutoItWinGetTitle())
        EndIf

        DllCall("user32.dll", "ptr", "SendMessage", "hwnd", $hWnd, "int", $WM_INPUTLANGCHANGEREQUEST, "int", 1, "int", $aRet[0])
        Return 1
    EndIf

    Return SetError(1)
EndFunc   ;==>_WinAPI_LoadKeyboardLayout

.

>UserGUI.au3

>FileOperations.au3

Edited by AZJIO

Share this post


Link to post
Share on other sites
AZJIO

When testing I found that _stripComments has a problem.

Try this:

Func WM_NOTIFY()
    $t = "int hwndFrom; int idFrom; int code"
    DllStructGetData($t, "code") = $NM
EndFunc

Not long ago I wanted to do a regular expression, but I failed. Here are my attempts to.

$string = StringRegExpReplace($string & @CRLF, '(?m)^((?:[^''";]*([''"]).*?\2)*[^;]*)\h*;.*$', '\1') ; remove one-line comments (недостаток - не работает если @CR без @LF)
; $string=StringRegExpReplace($string, '(?sx) (\v   (?:  [^;\v " '' ]  |  "[^\v"]*?"  | '' [^\v '' ]*? '' )*  )   \h*;[^\v]* ', '\1') ; (mod AZJIO)
; $string=StringRegExpReplace($string, '(?sx) (\v   (?:  [^;\v " '' ]  |  "[^\v"]*?"  | '' [^\v '' ]*? '' )*  )   \h*;[^\v]* ', '\1') ; (mod AZJIO)
; $string=StringRegExpReplace($string, '(?sx) (\v   (?:  (?:[^;\v " '' ])*   (?:"[^\v"]*?")*   (?:'' [^\v '' ]*? '')*   )*  )   \h*;[^\v]* ', '\1') ; (mod AZJIO)

1. The code consists of a sequence of sections of the operators, which may not be a semicolon and text enclosed in quotation marks , which can be a semicolon , but the block is complete.

2. At the end of alternating blocks can meet a semicolon, and after all is removed.

Share this post


Link to post
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
Sign in to follow this  

×