From 5b9b4851a5af6bf40d5d2e62cc6444a520748823 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Sat, 24 Jul 2021 06:24:18 +0700 Subject: [PATCH 1/9] chore(windows): Update crowdin strings for Azerbaijani --- windows/src/desktop/kmshell/locale/az-AZ/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/windows/src/desktop/kmshell/locale/az-AZ/strings.xml b/windows/src/desktop/kmshell/locale/az-AZ/strings.xml index bf05cfd882..8645152904 100644 --- a/windows/src/desktop/kmshell/locale/az-AZ/strings.xml +++ b/windows/src/desktop/kmshell/locale/az-AZ/strings.xml @@ -31,11 +31,11 @@ - Ləğv etmək + İmtina - Bağlamaq + Bağla @@ -43,7 +43,7 @@ - Ləğv etmək + İmtina From 6d925853d72e5c44c4486d65a156cf6719bbfd7a Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Mon, 26 Jul 2021 10:09:31 +0700 Subject: [PATCH 2/9] chore(windows): Add another round of Azerbaijani updates --- .../desktop/kmshell/locale/az-AZ/strings.xml | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/windows/src/desktop/kmshell/locale/az-AZ/strings.xml b/windows/src/desktop/kmshell/locale/az-AZ/strings.xml index 8645152904..41e0bfca1f 100644 --- a/windows/src/desktop/kmshell/locale/az-AZ/strings.xml +++ b/windows/src/desktop/kmshell/locale/az-AZ/strings.xml @@ -51,11 +51,11 @@ - Keyman hələ də çalışır. Dil klaviaturanızı istənilən vaxt istifadə etmək üçün bu işarəni vurun + Keyman hələ də işləyir. Dil klaviaturanızı istənilən vaxt istifadə etmək üçün bu nişana klikləyin - Keyman artıq çalışır. Dil klaviaturanızı istifadə etmək üçün sistem bildiriş sahəsindəki Keyman simgesini vurun + Keyman artıq işləyir. Dil klaviaturanızı istifadə etmək üçün sistem bildiriş sahəsindəki Keyman nişanına klikləyin @@ -67,7 +67,7 @@ - Klaviatura tərtibləri + Klaviatura düzülüşləri @@ -79,7 +79,7 @@ - O + S @@ -87,7 +87,7 @@ - H + Q @@ -95,15 +95,15 @@ - S + D - Əlaqə saxlayın + Əlaqədə qalın - T + Ə @@ -115,7 +115,7 @@ - Klaviatura versiyası + Klaviatura versiyası: @@ -123,7 +123,7 @@ - Veb səhifə: + Veb sayt: @@ -135,11 +135,11 @@ - Klaviatura tərtibləri: + Klaviatura düzülüşləri: - Klaviatura tərtibləri: + Klaviatura düzülüşü: @@ -155,11 +155,11 @@ - Fixed (Mövqə) + Sabit (Mövqe) - Windows tərtibatına uyğunlaşdırıldı (Yadda salıcı) + Windows düzülüşünə gətirildi (Xatırladıcı) @@ -171,43 +171,43 @@ - Dil əlavə etmək + Dil əlavə et - Ekran klaviaturasında: + Ekran klaviaturası: - Fərdiləşdirilən + Özəl - Qurulmuş + Quraşdırılmış - Qurulmamış + Quraşdırılmamış - Sənədləşməsi + Sənədləşdirmə: - Qurulmuş + Quraşdırılmış - Qurulmamış + Quraşdırılmamış - Mesaj + Mesaj: - Müəllif hüquqları: + Müəllif hüququ: @@ -215,11 +215,11 @@ - Klaviaturanı quraşdırmaq + Klaviaturanı quraşdır... - Klaviatura yüklənir... + Klaviaturanı endir... @@ -227,24 +227,24 @@ - Quraşdırılmış klaviatura yoxdur. Keyman veb saytından klaviatura düzeni qurmaq üçün Klaviaturanı Yüklə düyməsini vurun. + Qurulu heç bir klaviaturanız yoxdur. Keyman veb saytından klaviatura düzülüşünü quraşdırmaq üçün Klaviatura Endir düyməsini klikləyin. - Yalnız bir idarəedicisinizsə \'%1$s\' klaviaturasını silə bilərsiniz + Əgər administratorsunuzsa, \"%1$s\" klaviaturasını silə bilərsiniz - Klaviaturanı paylaşmaq + Klaviaturanı paylaş - Bu klaviaturanı başqa bir cihaza yükləmək üçün bu kodu tarayın + Bu klaviaturanı başqa bir cihazda yükləmək üçün bu kodu skan edin və ya - onlayn paylaşmaq + onlayn paylaşın @@ -256,35 +256,35 @@ - Başlamaq + Açılış - Ekran klaviaturasında + Ekran klaviaturası - Genişləndirilmiş + Qabaqcıl - Klaviatura qısa yol düymələri klaviatura aktivləşdirməsini dəyişir + Klaviatura qısayol düymələri klaviatura aktivləşdirməsini dəyişdirir - Ctrl + Alt ilə AltGr simulyasiya edin + Ctrl + Alt ilə \"AltGr\"i simulyasiya edin - Donanım açar düymələrini düz açarlar kimi qəbul edin + Aparat təminatı özəl düymələrinə düz düymələr kimi davran - Eyham mesajlarını göstərin + Məsləhət mesajlarını göstər - Səhvləri avtomatik olaraq keyman.com saytına bildirmək + Xətaları avtomatik olaraq keyman.com-da bildir From 6cb0b0af181d757b8de339f943c9175a66e9276f Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 5 Aug 2021 07:57:37 +0700 Subject: [PATCH 3/9] chore(ios,windows): Cherrypick 5486 --- .../KeymanEngine/az.lproj/Localizable.strings | 76 +++++++++---------- .../az.lproj/Localizable.stringsdict | 4 +- .../Keyman/az.lproj/Localizable.strings | 20 ++--- .../desktop/kmshell/locale/az-AZ/strings.xml | 4 +- 4 files changed, 52 insertions(+), 52 deletions(-) diff --git a/ios/engine/KMEI/KeymanEngine/az.lproj/Localizable.strings b/ios/engine/KMEI/KeymanEngine/az.lproj/Localizable.strings index e028de1bb2..acad880cc4 100644 --- a/ios/engine/KMEI/KeymanEngine/az.lproj/Localizable.strings +++ b/ios/engine/KMEI/KeymanEngine/az.lproj/Localizable.strings @@ -1,32 +1,32 @@ /* A descriptive message used for errors when the app is already busy downloading */ -"alert-download-error-busy" = "Onsuz da yükləməklə məşğuldur."; +"alert-download-error-busy" = "Artıq endirilir."; /* A descriptive message used when a download fails */ -"alert-download-error-detail" = "Yükləmə və ya quraşdırma zamanı xəta baş verdi."; +"alert-download-error-detail" = "Endirmə və ya quraşdırma zamanı xəta baş verdi."; /* Title for a "download failed" alert */ -"alert-download-error-title" = "Yükləmə xətası"; +"alert-download-error-title" = "Endirmə xətası"; /* Title for a general alert about errors */ "alert-error-title" = "Xəta"; /* A descriptive message used when no internet connection is detected */ -"alert-no-connection-detail" = "Keyman serverinə çata bilmədi. Zəhmət olmasa bir az sonra yenə cəhd edin."; +"alert-no-connection-detail" = "Keyman serverinə çata bilmədi. Zəhmət olmasa daha sonra yenidən sınayın."; /* Title for a "no connection" alert */ -"alert-no-connection-title" = "Əlaqə xətası"; +"alert-no-connection-title" = "Bağlantı xətası"; /* Short text for a 'back' navigational command. Used to return to the previous screen */ "command-back" = "Geri"; /* Short text for a 'cancel' command. Used to back out of a menu or install process without making changes */ -"command-cancel" = "Ləğv etmək"; +"command-cancel" = "İmtina"; /* Short text for a 'done' command. Used to back out of settings menus after changes have been made */ -"command-done" = "Bitdi"; +"command-done" = "Hazırdır"; /* Short text for an 'install' command. Used to confirm installation of a package. */ -"command-install" = "Yüklemek"; +"command-install" = "Quraşdır"; /* Short text for a 'next' navigational command. Used to advance to the next screen */ "command-next" = "Növbəti"; @@ -38,25 +38,25 @@ "command-uninstall" = "Sil"; /* Text for the command to uninstall a keyboard */ -"command-uninstall-keyboard" = "Klaviaturanı silin"; +"command-uninstall-keyboard" = "Klaviaturanı sil"; /* Confirmation text to display before uninstalling a keyboard */ "command-uninstall-keyboard-confirm" = "Bu klaviaturanı silmək istəyirsiniz?"; /* Text for the command to uninstall a lexical model */ -"command-uninstall-lexical-model" = "Lüğəti silmək"; +"command-uninstall-lexical-model" = "Lüğəti sil"; /* Confirmation text to display before uninstalling a lexical model */ "command-uninstall-lexical-model-confirm" = "Bu lüğəti silmək istəyirsiniz?"; /* Text for error when an installed file is unexpectedly missing */ -"error-missing-file" = "Lazımi bir fayl tapılmadı."; +"error-missing-file" = "Tələb olunan fayl tapıla bilmədi."; /* Text for error when an installed file is unexpectedly missing */ -"error-missing-file-critical" = "Həlledici bir fayl tapılmadı. Tətbiqi yenidən quraşdırmağa cəhd edin."; +"error-missing-file-critical" = "Kritik fayl tapıla bilmədi. Tətbiqi yenidən quraşdırmağı sınayın."; /* Text for errors in data received from search queries */ -"error-query-decoding" = "Server hazırda texniki çətinliklərlə üzləşir"; +"error-query-decoding" = "Hal-hazırda server texniki çətinliklər yaşayır"; /* A descriptive message used when a download fails */ "error-query-general" = "Serverlə əlaqə qurma xətası"; @@ -65,7 +65,7 @@ "error-query-no-data" = "Server cavab vermədi"; /* Text for general errors where not much information is known */ -"error-unknown" = "Gözlənilməz bir səhv baş verdi"; +"error-unknown" = "Gözlənilməz bir xəta baş verdi"; /* Text for error when updating a resource: cannot download because no source is available */ "error-update-no-link" = "Bu paket üçün yeniləmə mənbəyi mövcud deyil"; @@ -89,7 +89,7 @@ "installer-label-package-info" = "Paket məlumatı"; /* Label used for the language-selection tab with the package installation prompt on phones. */ -"installer-label-select-languages" = "Dil (lər) seçin"; +"installer-label-select-languages" = "Dil(lər)i seçin"; /* Label used with a package's version, as seen within the package installation prompt. Example: "Version: 14.0.0" */ "installer-label-version" = "Versiya: %@"; @@ -98,22 +98,22 @@ "installer-section-available-languages" = "Mövcud Dillər"; /* Text for the help popup for changing keyboards with the globe key */ -"keyboard-help-change" = "Klaviaturanı dəyişdirmək üçün buraya vurun"; +"keyboard-help-change" = "Klaviaturanı dəyişdirmək üçün buraya toxunun"; /* Text for the command to exit the Keyman keyboard in favor of other keyboards installed on the system */ -"keyboard-menu-exit" = "Bağlamaq %@"; +"keyboard-menu-exit" = "%@ bağla"; /* Error installing a Keyman package - could not allocate a location to install it */ -"kmp-error-file-system" = "Paketin quraşdırılması zamanı səhv - fayl sistemi xətası"; +"kmp-error-file-system" = "Paket quraşdırma xətası - fayl sistem xətası"; /* Error installing a Keyman package - could not copy package files */ -"kmp-error-file-copying" = "Paketin quraşdırılması zamanı səhv - tələb olunan faylları köçürə bilmədi"; +"kmp-error-file-copying" = "Paket quraşdırma xətası - tələb olunan fayllar kopyalana bilmədi"; /* Error opening a Keyman package - package is not valid */ -"kmp-error-invalid" = "Paketin faylı pozulub."; +"kmp-error-invalid" = "Paketin faylı zədəlidir."; /* Error installing a Keyman package - expected resource (keyboard or dictionary) is missing */ -"kmp-error-missing-resource" = "Bu paketdə tələb olunan klaviatura və ya lüğət yoxdur."; +"kmp-error-missing-resource" = "Bu paket tələb olunan klaviatura və ya lüğəti ehtiva etmir."; /* Error opening a Keyman package - cannot parse contents */ "kmp-error-no-metadata" = "Bu paket düzgün qurulmamışdır - məzmunu bilinmir."; @@ -134,16 +134,16 @@ "menu-langsettings-section-settings" = "Dil parametrləri"; /* Title for the language-specific settings menus */ -"menu-langsettings-title" = "%@ Parametrlər"; +"menu-langsettings-title" = "%@ Parametrləri"; /* Label for the toggle that enables corrections that is displayed within a language-specific settings menu */ -"menu-langsettings-toggle-correct" = "Düzəlişləri aktivləşdirmək"; +"menu-langsettings-toggle-correct" = "Düzəlişləri fəallaşdır"; /* Label for the toggle that enables predictions that is displayed within a language-specific settings menu */ -"menu-langsettings-toggle-predict" = "Proqnozları aktivləşdirmək"; +"menu-langsettings-toggle-predict" = "Təxminləri fəallaşdır"; /* Help message for a prompt that appears for confirming a lexical model download: language (1): lexical model (dictionary) name (2) */ -"menu-lexical-model-install-message" = "Bu lüğəti qurmaq istərdinizmi?"; +"menu-lexical-model-install-message" = "Bu lüğəti quraşdırmaq istəyirsiniz?"; /* Title for a prompt that appears for confirming a lexical model download: language (1): lexical model (dictionary) name (2) */ "menu-lexical-model-install-title" = "%1$@:%2$@"; @@ -152,55 +152,55 @@ "menu-lexical-model-none-message" = "Heç bir lüğət yoxdur"; /* Title for the lexical model menu, a submenu of the language-specific settings menus */ -"menu-lexical-model-title" = "%@ Lüğətlər"; +"menu-lexical-model-title" = "%@ Lüğətləri"; /* Title for the keyboard picker */ "menu-picker-title" = "Klaviaturalar"; /* Primary text for the Settings menu option to report keyboard crashes */ -"menu-settings-error-report" = "Xəta Bildirilməsinə icazə verin"; +"menu-settings-error-report" = "Xəta bildirməyə icazə ver"; /* Secondary text for the Settings menu option to report keyboard crashes */ -"menu-settings-error-report-description" = "\"Tam giriş\" tələb edə bilər"; +"menu-settings-error-report-description" = "\"Tam müraciət\" tələb edə bilər"; /* Primary text for the Settings menu local-file package installation option */ "menu-settings-install-from-file" = "Fayldan quraşdırın"; /* Secondary text for the Settings menu local-file package installation option */ -"menu-settings-install-from-file-description" = ".Kmp faylları axtarmaq"; +"menu-settings-install-from-file-description" = ".kmp fayllarını axtar"; /* Primary text for the Settings menu option that displays the iOS system menu options for the app's keyboard */ "menu-settings-system-keyboard-menu" = "Sistem Klaviatura Parametrləri"; /* Label for the "Show Banner" toggle on the main settings screen */ -"menu-settings-show-banner" = "Banner göstərmək"; +"menu-settings-show-banner" = "Banneri göstər"; /* Label for the "Get Started" automatic display toggle seen in the Settings menu */ -"menu-settings-startup-get-started" = "Başlanğıcda 'Başlayın' göstərmək"; +"menu-settings-startup-get-started" = "Başlanğıcda 'Başlayın' göstər"; /* Title for the main Settings menu */ "menu-settings-title" = "Keyman Parametrləri"; /* Short text for notification: download failure for keyboard */ -"notification-download-failure-keyboard" = "Klaviatura yüklənmədi"; +"notification-download-failure-keyboard" = "Klaviatura endirilmədi"; /* Short text for notification: download failure for lexical model */ -"notification-download-failure-lexical-model" = "Lüğət yüklənmədi"; +"notification-download-failure-lexical-model" = "Lüğət endirilmədi"; /* Short text for notification: download success for keyboard */ "notification-download-success-keyboard" = "Klaviatura uğurla endirildi"; /* Short text for notification: download success for lexical model */ -"notification-download-success-lexical-model" = "Leksik model uğurla yükləndi"; +"notification-download-success-lexical-model" = "Leksik model uğurla endirildi"; /* Short text for notification: downloading a keyboard */ -"notification-downloading-keyboard" = "Klaviatura yüklənir \\ U2026"; +"notification-downloading-keyboard" = "Klaviatura endirilir\U2026"; /* Short text for notification: downloading a lexical model */ -"notification-downloading-lexical-model" = "Lüğət yüklənir \U2026"; +"notification-downloading-lexical-model" = "Lüğət endirilir\U2026"; /* Short text for notification: an update is available */ -"notification-update-available" = "Yeniləmə mümkündür"; +"notification-update-available" = "Yeniləmə mövcuddur"; /* Short text for notification: currently updating */ "notification-update-processing" = "Yenilənir\U2026"; @@ -209,4 +209,4 @@ "success-install" = "Uğurla quraşdırıldı."; /* A title to use in alerts indicating 'success' at whatever task the user requested */ -"success-title" = "Uğur"; +"success-title" = "Uğurlu"; diff --git a/ios/engine/KMEI/KeymanEngine/az.lproj/Localizable.stringsdict b/ios/engine/KMEI/KeymanEngine/az.lproj/Localizable.stringsdict index ada8429d49..53cf61217e 100644 --- a/ios/engine/KMEI/KeymanEngine/az.lproj/Localizable.stringsdict +++ b/ios/engine/KMEI/KeymanEngine/az.lproj/Localizable.stringsdict @@ -13,9 +13,9 @@ NSStringFormatValueTypeKey u one - %u lüğət quraşdırılıb + %u lüğət quraşdırıldı other - %u lüğətlər quraşdırıldı + %u lüğət quraşdırıldı notification-update-failed diff --git a/ios/keyman/Keyman/Keyman/az.lproj/Localizable.strings b/ios/keyman/Keyman/Keyman/az.lproj/Localizable.strings index 4859b4cc9a..2fe811295e 100644 --- a/ios/keyman/Keyman/Keyman/az.lproj/Localizable.strings +++ b/ios/keyman/Keyman/Keyman/az.lproj/Localizable.strings @@ -1,5 +1,5 @@ /* Title for the bookmarks menu within the embedded browser */ -"browser-bookmarks-add-title" = "Əlfəcin əlavə etmək"; +"browser-bookmarks-add-title" = "Əlfəcin əlavə et"; /* Title for the bookmarks menu within the embedded browser */ "browser-bookmarks-none" = "Əlfəcin yoxdur"; @@ -17,7 +17,7 @@ "error-opening-page" = "Səhifə açıla bilmir"; /* Long-form used when installing a font in order to display a language properly. */ -"font-install-description" = "Bütün tətbiqlərinizdə %@ görüntüsünü düzgün görünmək üçün Quraşdır'a toxunun"; +"font-install-description" = "Bütün tətbiqlərinizdə %@ in düzgün görünməsi üçün \"Quraşdır\"a toxunun"; /* The name of the iOS Settings menu option for keyboards */ "ios-settings-keyboards" = "Klaviaturalar"; @@ -30,13 +30,13 @@ underneath the app's name within the app-specific keyboard menu.) */ "language-for-font" = "%@ Şrift"; /* Used for 'add' options within menus */ -"menu-add" = "Əlavə etmək"; +"menu-add" = "Əlavə et"; /* Used to indicate a sequence of menu options that a user needs to copy. May be chained. Example: "Keyboards (1) > Enable Keyman (2)" */ "menu-breadcrumbing" = "%1$@ > %2$@"; /* Used to exit a menu without choosing an option */ -"menu-cancel" = "Ləğv etmək"; +"menu-cancel" = "İmtina"; /* Menu option that erases all previously-typed text. */ "menu-clear-text" = "Mətni təmizlə"; @@ -51,13 +51,13 @@ underneath the app's name within the app-specific keyboard menu.) */ "menu-more" = "Daha çox"; /* Menu option used to edit keyboard and dictionary settings */ -"menu-settings" = "Parametrlər"; +"menu-settings" = "Tənzimləmələr"; /* Menu option that displays the iOS Share menu */ "menu-share" = "Paylaş"; /* Menu option that displays an embedded web browser. */ -"menu-show-browser" = "Brauzer"; +"menu-show-browser" = "Səyyah"; /* Menu option used to control in-app font size. */ "menu-text-size" = "Mətn ölçüsü"; @@ -66,16 +66,16 @@ underneath the app's name within the app-specific keyboard menu.) */ "text-size-label" = "Mətn ölçüsü:%i"; /* Text to indicate that a user should set a toggle within iOS Settings to 'active'. */ -"toggle-to-enable" = "%@ İşə salmaq"; +"toggle-to-enable" = "Fəallaşdır: %@"; /* First option on the Get Started tutorial - Add a keyboard for your language */ -"tutorial-add-keyboard" = "Sizin diliniz üçün klaviaturanı əlavə edin"; +"tutorial-add-keyboard" = "Diliniz üçün klaviatura əlavə edin"; /* Third option on the Get Started tutorial - Displays app help. */ "tutorial-show-help" = "Ətraflı məlumat"; /* Second option on the Get Started tutorial - Set up Keyman as system-wide keyboard */ -"tutorial-system-keyboard" = "Keyman ümumsistem klaviatura kimi işə salmaq"; +"tutorial-system-keyboard" = "\"Keyman\"ı geniş sistem klaviaturası kimi quraşdırın"; /* Used to display app version (as in \"Version: 1.0.2\" */ -"version-label" = "Versiya %@"; +"version-label" = "Versiya: %@"; diff --git a/windows/src/desktop/kmshell/locale/az-AZ/strings.xml b/windows/src/desktop/kmshell/locale/az-AZ/strings.xml index 41e0bfca1f..2b9d68af82 100644 --- a/windows/src/desktop/kmshell/locale/az-AZ/strings.xml +++ b/windows/src/desktop/kmshell/locale/az-AZ/strings.xml @@ -641,11 +641,11 @@ - İngilis dili + Azərbaycanca (Azəricə) - İngilis dili + Azərbaycanca (Azerbaijani) From 8fece0eced542570ec75910b51ff5e63374fc3a4 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Thu, 5 Aug 2021 08:04:36 +0700 Subject: [PATCH 4/9] fix(ios): Get Started view title i18n Cherry-pick 5d61eb08f6dd3e08820d7fd92625d389368b04ba to stable-14.0 (GetStartedViewController.swift in a different folder) --- .../GetStartedViewController/GetStartedViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/ios/keyman/Keyman/Keyman/GetStartedViewController/GetStartedViewController.swift b/ios/keyman/Keyman/Keyman/GetStartedViewController/GetStartedViewController.swift index dcdd3e553b..074fa0fe9c 100644 --- a/ios/keyman/Keyman/Keyman/GetStartedViewController/GetStartedViewController.swift +++ b/ios/keyman/Keyman/Keyman/GetStartedViewController/GetStartedViewController.swift @@ -28,6 +28,7 @@ class GetStartedViewController: UIViewController, UITableViewDelegate, UITableVi NotificationCenter.default.addObserver(self, selector: #selector(self.refreshTable), name: UIApplication.didBecomeActiveNotification, object: nil) + navItem.title = NSLocalizedString("menu-get-started", comment: "") tableView.isScrollEnabled = false let icon = UIImageView(image: #imageLiteral(resourceName: "887-notepad.png")) From ac78cc7a94df462e03789040b3d7bd948700c4e6 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Mon, 16 Aug 2021 15:53:05 +0200 Subject: [PATCH 5/9] fix(linux): Handle corrupt icon file Fixes #5584. (cherry picked from commit c8049a0cd20b0dab936c57f2fe8def8629b4eaba) --- .../keyman_config/view_installed.py | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/linux/keyman-config/keyman_config/view_installed.py b/linux/keyman-config/keyman_config/view_installed.py index 8fa650eb3b..97d6caa577 100755 --- a/linux/keyman-config/keyman_config/view_installed.py +++ b/linux/keyman-config/keyman_config/view_installed.py @@ -22,6 +22,7 @@ from keyman_config.install_window import InstallKmpWindow, find_keyman_image from keyman_config.uninstall_kmp import uninstall_kmp from keyman_config.accelerators import bind_accelerator, init_accel from keyman_config.get_kmp import user_keyboard_dir +from gi.overrides.GLib import GError class ViewInstalledWindowBase(Gtk.Window): @@ -228,19 +229,26 @@ class ViewInstalledWindow(ViewInstalledWindowBase): welcome_file = os.path.join(path, "welcome.htm") options_file = os.path.join(path, "options.htm") - icofile = os.path.join(path, kmpdata['packageID'] + bmppng) + icofile_name = os.path.join(path, kmpdata['packageID'] + bmppng) if not os.path.isfile(welcome_file): welcome_file = None if not os.path.isfile(options_file): options_file = None - if not os.path.isfile(icofile): - icofile = os.path.join(path, kmpdata['keyboardID'] + bmppng) - if not os.path.isfile(icofile): - icofile = find_keyman_image("icon_kmp.png") + if not os.path.isfile(icofile_name): + icofile_name = os.path.join(path, kmpdata['keyboardID'] + bmppng) + if not os.path.isfile(icofile_name): + icofile_name = find_keyman_image("icon_kmp.png") + + try: + icofile = GdkPixbuf.Pixbuf.new_from_file_at_size(icofile_name, 16, 16) + except GError: + _, value, _ = sys.exc_info() + logging.info("Error reading icon file %s: %s" % (icofile_name, value.message)) + icofile = None store.append([ - GdkPixbuf.Pixbuf.new_from_file_at_size(icofile, 16, 16), + icofile, kmpdata['name'], kmpdata['version'], kmpdata['packageID'], From 2c07c99239a942e4ca61690c4d9fbe5aa0a37629 Mon Sep 17 00:00:00 2001 From: Eberhard Beilharz Date: Mon, 16 Aug 2021 10:58:50 +0200 Subject: [PATCH 6/9] fix(linux): Check for valid kmp file Before trying to install we now check if it's a valid zip file. This fixes #5575. (cherry-picked from PR #5583) --- .../keyman_config/handle_install.py | 5 ++ linux/keyman-config/km-package-install | 3 +- .../tests/test_gnome_keyboards_util.py | 4 +- .../tests/test_handle_install.py | 47 +++++++++++++++---- 4 files changed, 48 insertions(+), 11 deletions(-) diff --git a/linux/keyman-config/keyman_config/handle_install.py b/linux/keyman-config/keyman_config/handle_install.py index 87541df3da..f332ef6717 100644 --- a/linux/keyman-config/keyman_config/handle_install.py +++ b/linux/keyman-config/keyman_config/handle_install.py @@ -5,6 +5,7 @@ from urllib.parse import parse_qs, urlparse from keyman_config import KeymanComUrl, __tier__ from keyman_config.install_window import InstallKmpWindow from keyman_config.get_kmp import get_download_folder, download_kmp_file +from zipfile import is_zipfile def download_and_install_package(url): @@ -42,6 +43,10 @@ def download_and_install_package(url): logging.critical("Invalid URL: " + url) return + if not is_zipfile(packageFile): + logging.critical("Not a valid KMP package: " + url) + return + if packageFile and not _install_package(packageFile, bcp47): logging.log(severity, "Can't find file " + url) diff --git a/linux/keyman-config/km-package-install b/linux/keyman-config/km-package-install index 8178e12faa..87f0860d24 100755 --- a/linux/keyman-config/km-package-install +++ b/linux/keyman-config/km-package-install @@ -9,6 +9,7 @@ from keyman_config.uninstall_kmp import uninstall_kmp import datetime import time +from zipfile import is_zipfile def get_languages(): @@ -120,7 +121,7 @@ def main(): if args.file: name, ext = os.path.splitext(args.file) - if ext != ".kmp": + if ext != ".kmp" or not is_zipfile(args.file): logging.error("km-package-install: Input file %s is not a kmp file.", args.file) logging.error("km-package-install -f ") sys.exit(2) diff --git a/linux/keyman-config/tests/test_gnome_keyboards_util.py b/linux/keyman-config/tests/test_gnome_keyboards_util.py index 67bf01b74e..ad6d116fbe 100644 --- a/linux/keyman-config/tests/test_gnome_keyboards_util.py +++ b/linux/keyman-config/tests/test_gnome_keyboards_util.py @@ -71,14 +71,14 @@ class GnomeKeyboardsUtilTests(unittest.TestCase): self.MockSettingsClass.return_value.set_value.assert_called_once_with( "sources", keyboards) - @patch('keyman_config.install_kmp.os.system') + @patch('keyman_config.os.system') def test_IsGnomeShell_RunningGnomeShell(self, mockSystem): # Setup mockSystem.return_value = 0 # Execute/Verify self.assertEqual(is_gnome_shell(), True) - @patch('keyman_config.install_kmp.os.system') + @patch('keyman_config.os.system') def test_IsGnomeShell_NotRunningGnomeShell(self, mockSystem): # Setup mockSystem.return_value = 1 diff --git a/linux/keyman-config/tests/test_handle_install.py b/linux/keyman-config/tests/test_handle_install.py index 981e38a41e..4e78bbeeb6 100644 --- a/linux/keyman-config/tests/test_handle_install.py +++ b/linux/keyman-config/tests/test_handle_install.py @@ -8,53 +8,79 @@ from keyman_config.handle_install import download_and_install_package class HandleInstallTests(unittest.TestCase): + @patch('keyman_config.handle_install.is_zipfile') @patch('keyman_config.handle_install._install_package') - def test_downloadAndInstallPackage_file(self, installPackageMethod): + def test_downloadAndInstallPackage_file(self, installPackageMethod, mockIsZipfile): + # Setup + mockIsZipfile.return_value = True + # Execute download_and_install_package('/tmp/keyboard/sil_euro_latin.kmp') # Verify installPackageMethod.assert_called_with('/tmp/keyboard/sil_euro_latin.kmp', '') + @patch('keyman_config.handle_install.is_zipfile') @patch('keyman_config.handle_install._install_package') - def test_downloadAndInstallPackage_fileUrl(self, installPackageMethod): + def test_downloadAndInstallPackage_fileUrl(self, installPackageMethod, mockIsZipfile): + # Setup + mockIsZipfile.return_value = True + # Execute download_and_install_package('file:///tmp/keyboard/sil_euro_latin.kmp') # Verify installPackageMethod.assert_called_with('/tmp/keyboard/sil_euro_latin.kmp', '') + @patch('keyman_config.handle_install.is_zipfile') @patch('keyman_config.handle_install._install_package') - def test_downloadAndInstallPackage_fileUrlWithBcp47(self, installPackageMethod): + def test_downloadAndInstallPackage_fileUrlWithBcp47(self, installPackageMethod, + mockIsZipfile): + # Setup + mockIsZipfile.return_value = True + # Execute download_and_install_package('file:///tmp/keyboard/sil_euro_latin.kmp?bcp47=dyo') # Verify installPackageMethod.assert_called_with('/tmp/keyboard/sil_euro_latin.kmp', 'dyo') + @patch('keyman_config.handle_install.is_zipfile') @patch('keyman_config.handle_install._install_package') - def test_downloadAndInstallPackage_fileUrlWithBcp47AndVersion(self, installPackageMethod): + def test_downloadAndInstallPackage_fileUrlWithBcp47AndVersion(self, installPackageMethod, + mockIsZipfile): + # Setup + mockIsZipfile.return_value = True + # Execute download_and_install_package('file:///tmp/keyboard/sil_euro_latin.kmp?bcp47=dyo&version=1') # Verify installPackageMethod.assert_called_with('/tmp/keyboard/sil_euro_latin.kmp', 'dyo') + @patch('keyman_config.handle_install.is_zipfile') @patch('keyman_config.handle_install._install_package') - def test_downloadAndInstallPackage_InvalidUrl(self, installPackageMethod): + def test_downloadAndInstallPackage_InvalidUrl(self, installPackageMethod, mockIsZipfile): + # Setup + mockIsZipfile.return_value = True + # Execute download_and_install_package('http://localhost/keyboard/sil_euro_latin.kmp') # Verify installPackageMethod.assert_not_called() + @patch('keyman_config.handle_install.is_zipfile') @patch('keyman_config.handle_install._install_package') @patch('keyman_config.get_kmp.download_kmp_file') def test_downloadAndInstallPackage_invalidUrl(self, downloadKmpFileMethod, - installPackageMethod): + installPackageMethod, mockIsZipfile): for url in ['foo://download/keyboard/sil_euro_latin', 'keyman://keyboard/sil_euro_latin', 'keyman://download/sil_euro_latin', 'keyman://download/keyboard/']: with self.subTest(url=url): + # Setup + mockIsZipfile.return_value = True + # Execute download_and_install_package(url) @@ -62,15 +88,18 @@ class HandleInstallTests(unittest.TestCase): downloadKmpFileMethod.assert_not_called() installPackageMethod.assert_not_called() + @patch('keyman_config.handle_install.is_zipfile') @patch('keyman_config.handle_install._install_package') @patch('keyman_config.get_kmp.keyman_cache_dir') @patch('keyman_config.handle_install.download_kmp_file') def test_downloadAndInstallPackage_keymanUrl(self, downloadKmpFileMethod, - keymanCacheDirMethod, installPackageMethod): + keymanCacheDirMethod, installPackageMethod, + mockIsZipfile): # Setup mockPackagePath = '/tmp/sil_euro_latin' keymanCacheDirMethod.return_value = '/tmp' downloadKmpFileMethod.return_value = mockPackagePath + mockIsZipfile.return_value = True # Execute download_and_install_package('keyman://download/keyboard/sil_euro_latin') @@ -81,16 +110,18 @@ class HandleInstallTests(unittest.TestCase): mockPackagePath) installPackageMethod.assert_called_with(mockPackagePath, '') + @patch('keyman_config.handle_install.is_zipfile') @patch('keyman_config.handle_install._install_package') @patch('keyman_config.get_kmp.keyman_cache_dir') @patch('keyman_config.handle_install.download_kmp_file') def test_downloadAndInstallPackage_keymanUrlWithBcp47(self, downloadKmpFileMethod, keymanCacheDirMethod, - installPackageMethod): + installPackageMethod, mockIsZipfile): # Setup mockPackagePath = '/tmp/sil_euro_latin' keymanCacheDirMethod.return_value = '/tmp' downloadKmpFileMethod.return_value = mockPackagePath + mockIsZipfile.return_value = True # Execute download_and_install_package('keyman://download/keyboard/sil_euro_latin?bcp47=de') From 54949d8b4307f9e52d3936861eb9e9a42056c60a Mon Sep 17 00:00:00 2001 From: jahorton Date: Wed, 18 Aug 2021 08:35:35 +0700 Subject: [PATCH 7/9] fix(oem/fv/ios): use of fat-framework for sim artifact --- oem/firstvoices/ios/build_common.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/oem/firstvoices/ios/build_common.sh b/oem/firstvoices/ios/build_common.sh index 38795147e3..80ddf2e994 100755 --- a/oem/firstvoices/ios/build_common.sh +++ b/oem/firstvoices/ios/build_common.sh @@ -125,6 +125,7 @@ else fi KEYMAN_ENGINE_FRAMEWORK_SRC="$KMEI_BUILD_DIR/build/Build/Products/$CONFIG-$PLATFORM_TARGET/KeymanEngine.framework" +KEYMAN_ENGINE_SIM_FRAMEWORK_SRC="$KMEI_BUILD_DIR/build/Build/Products/$CONFIG-universal/KeymanEngine.framework" KEYMAN_ENGINE_FRAMEWORK_DST=./ if [ $DO_UPDATE = true ]; then @@ -217,6 +218,10 @@ else fi if [ $DO_SIMULATOR_TARGET == true ]; then + echo "Replacing .framework with Simulator-compatible version" + # Replace the previous framework copy in case the main build was for release. + cp -Rf "$KEYMAN_ENGINE_SIM_FRAMEWORK_SRC" "$KEYMAN_ENGINE_FRAMEWORK_DST" + echo "Preparing .app file as Simulator-targeted build artifact." xcodebuild CODE_SIGN_ENTITLEMENTS="" CODE_SIGNING_ALLOWED="NO" CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO \ $XCODEFLAGS_EXT -scheme "$TARGET" \ From a7f5361bbac325eac81f5acaa1da3d8289b4fd6b Mon Sep 17 00:00:00 2001 From: jahorton Date: Wed, 18 Aug 2021 09:02:26 +0700 Subject: [PATCH 8/9] fix(oem/fv/ios): simulator-only framework required --- oem/firstvoices/ios/build_common.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oem/firstvoices/ios/build_common.sh b/oem/firstvoices/ios/build_common.sh index 80ddf2e994..a054caf556 100755 --- a/oem/firstvoices/ios/build_common.sh +++ b/oem/firstvoices/ios/build_common.sh @@ -125,7 +125,7 @@ else fi KEYMAN_ENGINE_FRAMEWORK_SRC="$KMEI_BUILD_DIR/build/Build/Products/$CONFIG-$PLATFORM_TARGET/KeymanEngine.framework" -KEYMAN_ENGINE_SIM_FRAMEWORK_SRC="$KMEI_BUILD_DIR/build/Build/Products/$CONFIG-universal/KeymanEngine.framework" +KEYMAN_ENGINE_SIM_FRAMEWORK_SRC="$KMEI_BUILD_DIR/build/Build/Products/$CONFIG-iphonesimulator/KeymanEngine.framework" KEYMAN_ENGINE_FRAMEWORK_DST=./ if [ $DO_UPDATE = true ]; then From 00a847becfdfa019722dc51bb449e38c023def3c Mon Sep 17 00:00:00 2001 From: jahorton Date: Wed, 18 Aug 2021 09:35:53 +0700 Subject: [PATCH 9/9] fix(oem/fv/ios): no arm64 arch for 14.0 sim builds --- oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj b/oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj index d0f19881fc..5a9af24f09 100644 --- a/oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj +++ b/oem/firstvoices/ios/FirstVoices.xcodeproj/project.pbxproj @@ -12,8 +12,6 @@ 37150F74231637EA00C73C6A /* Reachability.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37150F6F231637EA00C73C6A /* Reachability.framework */; }; 37150F75231637EA00C73C6A /* Zip.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37150F70231637EA00C73C6A /* Zip.framework */; }; 37150F76231637EA00C73C6A /* XCGLogger.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37150F71231637EA00C73C6A /* XCGLogger.framework */; }; - 3729344024613C9900C5428C /* ObjcExceptionBridging.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37150F6E231637EA00C73C6A /* ObjcExceptionBridging.framework */; }; - 3729344124613CA700C5428C /* XCGLogger.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37150F71231637EA00C73C6A /* XCGLogger.framework */; }; 3729344224613CB600C5428C /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 372A4B9C245E904A001C1F80 /* Sentry.framework */; }; 3729344324613CC200C5428C /* Zip.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 37150F70231637EA00C73C6A /* Zip.framework */; }; 372A4B9D245E904A001C1F80 /* Sentry.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 372A4B9C245E904A001C1F80 /* Sentry.framework */; }; @@ -664,6 +662,7 @@ CODE_SIGN_STYLE = Manual; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = D7TR486TEH; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Carthage/Build/iOS", @@ -694,6 +693,7 @@ CODE_SIGN_IDENTITY = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = D7TR486TEH; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Carthage/Build/iOS", @@ -721,6 +721,7 @@ CODE_SIGN_STYLE = Manual; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = D7TR486TEH; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Carthage/Build/iOS", @@ -752,6 +753,7 @@ CODE_SIGN_IDENTITY = "iPhone Distribution"; CODE_SIGN_STYLE = Manual; DEVELOPMENT_TEAM = D7TR486TEH; + "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Carthage/Build/iOS",