diff --git a/.gitignore b/.gitignore index e1dfdb1a..45afc62c 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,5 @@ Notepad++/ *.swp *.ipch *.exp + +build/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 49348b48..be60dee4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -105,6 +105,7 @@ set (project_sources src/Engine/Engine.cpp src/Tools.cpp src/UserSettings.cpp + src/Localization.cpp src/Compare.cpp src/LibGit2/LibGit2Helper.cpp src/NppHelpers.cpp @@ -198,3 +199,9 @@ else() DESTINATION "${INSTALL_PATH}/libs" ) endif() + +# Install language translation files into plugin languages directory +install (DIRECTORY res/languages/ + DESTINATION "${INSTALL_PATH}/languages" + FILES_MATCHING PATTERN "*.ini" +) diff --git a/README.md b/README.md index e48a12f6..f1c5bf55 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,14 @@ To install the plugin manually: 2. Copy the contents of the desired ComparePlus [release](https://github.com/pnedev/comparePlus/releases) zip file into the newly created folder. Please use the correct archive version based on your Notepad++ architecture - x86, x64 or ARM64. - ComparePlus.dll : The core plugin DLL. -- `libs` sub-folder : Contains the libs libgit2.dll and sqlite.dll needed for the Diff against Git and SVN commands. -3. Restart Notepad++. +- `libs` sub-folder : Contains the libs `libgit2.dll` and `sqlite.dll` needed for the Diff against Git and SVN commands. +3. Copy the `languages` folder (contains `*.ini` translation files) next to `ComparePlus.dll` if you want localized menus. +4. Restart Notepad++. + +Localization +------------------------------- +Translation files (*.ini) are loaded from `plugins/ComparePlus/languages/`. +To contribute a translation copy `english.ini`, rename it (e.g. `italian.ini`) and translate the values (left side keys stay the same). ------------------------------- diff --git a/res/languages/arabic.ini b/res/languages/arabic.ini new file mode 100644 index 00000000..9c3a7519 --- /dev/null +++ b/res/languages/arabic.ini @@ -0,0 +1,81 @@ +[menu] +CMD_SET_FIRST=تعيين كأول للمقارنة +CMD_COMPARE=مقارنة +CMD_COMPARE_SEL=مقارنة التحديدات +CMD_FIND_UNIQUE=البحث عن الخطوط الفريدة +CMD_FIND_UNIQUE_SEL=البحث عن الخطوط الفريدة في التحديدات +CMD_LAST_SAVE_DIFF=الفرق منذ آخر حفظ +CMD_CLIPBOARD_DIFF=مقارنة الملف/التحديد مع الحافظة +CMD_SVN_DIFF=فرق SVN +CMD_GIT_DIFF=فرق Git +CMD_CLEAR_ACTIVE=مسح المقارنة النشطة +CMD_CLEAR_ALL=مسح جميع المقارنات +CMD_FIRST=أول كتلة فرق +CMD_PREV=كتلة الفرق السابقة +CMD_NEXT=كتلة الفرق التالية +CMD_LAST=آخر كتلة فرق +CMD_PREV_CHANGE_POS=الفرق السابق في الخط المُعدّل +CMD_NEXT_CHANGE_POS=الفرق التالي في الخط المُعدّل +CMD_COMPARE_SUMMARY=ملخص المقارنة النشطة +CMD_COPY_VISIBLE=نسخ جميع/الخطوط المرئية المحددة +CMD_DELETE_VISIBLE=حذف جميع/الخطوط المرئية المحددة +CMD_BOOKMARK_VISIBLE=إضافة علامة مرجعية لجميع/الخطوط المرئية المحددة +CMD_GENERATE_PATCH=إنشاء رقعة +CMD_APPLY_PATCH=تطبيق الرقعة على الملف الحالي +CMD_REVERT_PATCH=إعادة الرقعة على الملف الحالي +CMD_COMPARE_OPTIONS=خيارات المقارنة (تجاهل، إلخ)... +CMD_DIFFS_VISUAL_FILTERS=مرشحات الفرق البصرية... +CMD_NAV_BAR=شريط التنقل +CMD_AUTO_RECOMPARE=إعادة المقارنة تلقائياً عند التغيير +CMD_SETTINGS=الإعدادات... +CMD_ABOUT=المساعدة/حول... + +[messages] +FindUnique=البحث عن فريد +Compare=مقارنة +Detect=كشف +Ignore=تجاهل +EmptyLines=الخطوط الفارغة +FoldedLines=الخطوط المطوية +HiddenLines=الخطوط المخفية +EOL=EOL +AllSpaces=جميع المسافات +ChangedSpaces=المسافات المُغيّرة +Case=حالة الأحرف +Regex=تعبير منتظم +Moves=التحركات +SubBlockDiffs=فرق الكتل الفرعية +SubLineMoves=تحركات الخطوط الفرعية +CharDiffs=فرق الأحرف +DiffLines=خطوط الفرق +Added=مُضاف +Removed=مُزال +Moved=مُحرّك +Changed=مُغيّر +MatchingLines=الخطوط المتطابقة +ComparisonOptions=خيارات المقارنة +NoDetectIgnore=لم يتم استخدام خيارات الكشف والتجاهل. +NoIgnore=لم يتم استخدام خيارات التجاهل. +FileManuallyChanged=تم تغيير الملف يدوياً، يرجى إعادة المقارنة! +FileChanged=تم تغيير الملف، قد تكون نتائج المقارنة غير دقيقة! +LastSave= ** آخر حفظ +Clipboard= ** الحافظة +SVN= ** SVN +Git= ** Git +Moves=/التحركات +SubBlockDiffs=/فرق الكتل الفرعية +SubLineMoves=/تحركات الخطوط الفرعية +CharDiffs=/فرق الأحرف +Detect=كشف: +Ignore=تجاهل: +EOL=/EOL +AllSpaces=/جميع المسافات +ChangedSpaces=/المسافات المُغيّرة +Case=/حالة الأحرف +Regex=/تعبير منتظم +Selections=التحديدات: +EOLMessage=يبدو أن الملفات تختلف في نهايات الخطوط (EOL). إذا كان الأمر كذلك، فسيظهر جميع الخطوط مختلفة.\n\nهل تريد تجاهل اختلافات EOL لهذه المقارنة؟ + +[settings] +NewFileInLeftView=ملف جديد في العرض الأيسر +OldFileInLeftView=ملف قديم في العرض الأيسر diff --git a/res/languages/chinese.ini b/res/languages/chinese.ini new file mode 100644 index 00000000..364b7ecf --- /dev/null +++ b/res/languages/chinese.ini @@ -0,0 +1,81 @@ +[menu] +CMD_SET_FIRST=设置第一个进行比较 +CMD_COMPARE=比较 +CMD_COMPARE_SEL=比较选择 +CMD_FIND_UNIQUE=查找唯一行 +CMD_FIND_UNIQUE_SEL=查找选择中的唯一行 +CMD_LAST_SAVE_DIFF=与上次保存的差异 +CMD_CLIPBOARD_DIFF=将文件/选择与剪贴板比较 +CMD_SVN_DIFF=SVN 差异 +CMD_GIT_DIFF=Git 差异 +CMD_CLEAR_ACTIVE=清除活动比较 +CMD_CLEAR_ALL=清除所有比较 +CMD_FIRST=第一个差异块 +CMD_PREV=上一个差异块 +CMD_NEXT=下一个差异块 +CMD_LAST=最后一个差异块 +CMD_PREV_CHANGE_POS=修改行中的上一个差异 +CMD_NEXT_CHANGE_POS=修改行中的下一个差异 +CMD_COMPARE_SUMMARY=活动比较摘要 +CMD_COPY_VISIBLE=复制所有/选定的可见行 +CMD_DELETE_VISIBLE=删除所有/选定的可见行 +CMD_BOOKMARK_VISIBLE=为所有/选定的可见行添加书签 +CMD_GENERATE_PATCH=生成补丁 +CMD_APPLY_PATCH=将补丁应用到当前文件 +CMD_REVERT_PATCH=还原当前文件的补丁 +CMD_COMPARE_OPTIONS=比较选项(忽略等)... +CMD_DIFFS_VISUAL_FILTERS=差异可视过滤器... +CMD_NAV_BAR=导航栏 +CMD_AUTO_RECOMPARE=更改时自动重新比较 +CMD_SETTINGS=设置... +CMD_ABOUT=帮助/关于... + +[messages] +FindUnique=查找唯一 +Compare=比较 +Detect=检测 +Ignore=忽略 +EmptyLines=空行 +FoldedLines=折叠行 +HiddenLines=隐藏行 +EOL=EOL +AllSpaces=所有空格 +ChangedSpaces=更改的空格 +Case=大小写 +Regex=正则表达式 +Moves=移动 +SubBlockDiffs=子块差异 +SubLineMoves=子行移动 +CharDiffs=字符差异 +DiffLines=差异行 +Added=已添加 +Removed=已删除 +Moved=已移动 +Changed=已更改 +MatchingLines=匹配行 +ComparisonOptions=比较选项 +NoDetectIgnore=未使用检测和忽略选项。 +NoIgnore=未使用忽略选项。 +FileManuallyChanged=文件已手动更改,请重新比较! +FileChanged=文件已更改,比较结果可能不准确! +LastSave= ** 上次保存 +Clipboard= ** 剪贴板 +SVN= ** SVN +Git= ** Git +Moves=/移动 +SubBlockDiffs=/子块差异 +SubLineMoves=/子行移动 +CharDiffs=/字符差异 +Detect=检测: +Ignore=忽略: +EOL=/EOL +AllSpaces=/所有空格 +ChangedSpaces=/更改的空格 +Case=/大小写 +Regex=/正则表达式 +Selections=选择: +EOLMessage=文件似乎在行尾(EOL)上有所不同。如果是这种情况,所有行都会显示为不同。\n\n您是否要忽略此比较的 EOL 差异? + +[settings] +NewFileInLeftView=左侧视图中的新文件 +OldFileInLeftView=左侧视图中的旧文件 diff --git a/res/languages/english.ini b/res/languages/english.ini new file mode 100644 index 00000000..cc6e2736 --- /dev/null +++ b/res/languages/english.ini @@ -0,0 +1,81 @@ +[menu] +CMD_SET_FIRST=Set as First to Compare +CMD_COMPARE=Compare +CMD_COMPARE_SEL=Compare Selections +CMD_FIND_UNIQUE=Find Unique Lines +CMD_FIND_UNIQUE_SEL=Find Unique Lines in Selections +CMD_LAST_SAVE_DIFF=Diff since last Save +CMD_CLIPBOARD_DIFF=Compare file/selection to Clipboard +CMD_SVN_DIFF=SVN Diff +CMD_GIT_DIFF=Git Diff +CMD_CLEAR_ACTIVE=Clear Active Compare +CMD_CLEAR_ALL=Clear All Compares +CMD_FIRST=First Diff Block +CMD_PREV=Previous Diff Block +CMD_NEXT=Next Diff Block +CMD_LAST=Last Diff Block +CMD_PREV_CHANGE_POS=Previous Diff in Changed Line +CMD_NEXT_CHANGE_POS=Next Diff in Changed Line +CMD_COMPARE_SUMMARY=Active Compare Summary +CMD_COPY_VISIBLE=Copy all/selected visible lines +CMD_DELETE_VISIBLE=Delete all/selected visible lines +CMD_BOOKMARK_VISIBLE=Bookmark all/selected visible lines +CMD_GENERATE_PATCH=Generate Patch +CMD_APPLY_PATCH=Apply Patch on current file +CMD_REVERT_PATCH=Revert Patch on current file +CMD_COMPARE_OPTIONS=Compare Options (ignore, etc.)... +CMD_DIFFS_VISUAL_FILTERS=Diffs Visual Filters... +CMD_NAV_BAR=Navigation Bar +CMD_AUTO_RECOMPARE=Auto Re-Compare on Change +CMD_SETTINGS=Settings... +CMD_ABOUT=Help / About... + +[messages] +FindUnique=Find Unique +Compare=Compare +Detect=Detect +Ignore=Ignore +EmptyLines=Empty Lines +FoldedLines=Folded Lines +HiddenLines=Hidden Lines +EOL=EOL +AllSpaces=All Spaces +ChangedSpaces=Changed Spaces +Case=Case +Regex=Regex +Moves=Moves +SubBlockDiffs=Sub-block Diffs +SubLineMoves=Sub-line Moves +CharDiffs=Char Diffs +DiffLines=Diff Lines +Added=Added +Removed=Removed +Moved=Moved +Changed=Changed +MatchingLines=Matching Lines +ComparisonOptions=Comparison options +NoDetectIgnore=No Detect and Ignore options used. +NoIgnore=No Ignore options used. +FileManuallyChanged=FILE MANUALLY CHANGED, PLEASE RE-COMPARE! +FileChanged=FILE CHANGED, COMPARE RESULTS MIGHT BE INACCURATE! +LastSave= ** Last Save +Clipboard= ** Clipboard +SVN= ** SVN +Git= ** Git +Moves=/Moves +SubBlockDiffs=/Sub-block Diffs +SubLineMoves=/Sub-line Moves +CharDiffs=/Char Diffs +Detect=Detect: +Ignore=Ignore: +EOL=/EOL +AllSpaces=/All Spaces +ChangedSpaces=/Changed Spaces +Case=/Case +Regex=/Regex +Selections=Selections: +EOLMessage=Seems like files differ in line endings (EOL). If that's the case all lines will appear different.\n\nWould you like to ignore EOL differences for this compare? + +[settings] +NewFileInLeftView=New file in left view +OldFileInLeftView=Old file in left view diff --git a/res/languages/esperanto.ini b/res/languages/esperanto.ini new file mode 100644 index 00000000..9e363e10 --- /dev/null +++ b/res/languages/esperanto.ini @@ -0,0 +1,81 @@ +[menu] +CMD_SET_FIRST=Agordi kiel Unua por Kompari +CMD_COMPARE=Kompari +CMD_COMPARE_SEL=Kompari Elektojn +CMD_FIND_UNIQUE=Serĉi Unikajn Liniojn +CMD_FIND_UNIQUE_SEL=Serĉi Unikajn Liniojn en Elektoj +CMD_LAST_SAVE_DIFF=Diferenco ekde Lasta Konservo +CMD_CLIPBOARD_DIFF=Kompari dosieron/elekton al Tondujo +CMD_SVN_DIFF=SVN Diferenco +CMD_GIT_DIFF=Git Diferenco +CMD_CLEAR_ACTIVE=Viŝi Aktivan Komparon +CMD_CLEAR_ALL=Viŝi Ĉiujn Komparojn +CMD_FIRST=Unua Diferenca Bloko +CMD_PREV=Antaŭa Diferenca Bloko +CMD_NEXT=Sekva Diferenca Bloko +CMD_LAST=Lasta Diferenca Bloko +CMD_PREV_CHANGE_POS=Antaŭa Diferenco en Ŝanĝita Linio +CMD_NEXT_CHANGE_POS=Sekva Diferenco en Ŝanĝita Linio +CMD_COMPARE_SUMMARY=Aktiva Kompara Resumo +CMD_COPY_VISIBLE=Kopii ĉiujn/elektitajn videblajn liniojn +CMD_DELETE_VISIBLE=Forigi ĉiujn/elektitajn videblajn liniojn +CMD_BOOKMARK_VISIBLE=Legosigni ĉiujn/elektitajn videblajn liniojn +CMD_GENERATE_PATCH=Generi Flikaĵon +CMD_APPLY_PATCH=Apliki Flikaĵon al aktuala dosiero +CMD_REVERT_PATCH=Malfari Flikaĵon al aktuala dosiero +CMD_COMPARE_OPTIONS=Komparaj Opcioj (ignori, ktp.)... +CMD_DIFFS_VISUAL_FILTERS=Diferencaj Vida Filtriloj... +CMD_NAV_BAR=Naviga Breto +CMD_AUTO_RECOMPARE=Aŭtomata Re-Komparo ĉe Ŝanĝo +CMD_SETTINGS=Agordoj... +CMD_ABOUT=Helpo / Pri... + +[messages] +FindUnique=Serĉi Unikajn +Compare=Kompari +Detect=Detekti +Ignore=Ignori +EmptyLines=Malplenaj Linioj +FoldedLines=Falditaj Linioj +HiddenLines=Kaŝitaj Linioj +EOL=Linifino +AllSpaces=Ĉiuj Spacoj +ChangedSpaces=Ŝanĝitaj Spacoj +Case=Uskleco +Regex=Regula Esprimo +Moves=Movoj +SubBlockDiffs=Sub-blokaj Diferencoj +SubLineMoves=Sub-liniaj Movoj +CharDiffs=Signaj Diferencoj +DiffLines=Diferencaj Linioj +Added=Aldonita +Removed=Forigita +Moved=Movita +Changed=Ŝanĝita +MatchingLines=Kongruaj Linioj +ComparisonOptions=Komparaj opcioj +NoDetectIgnore=Neniuj Detekt- kaj Ignor-opcioj uzataj. +NoIgnore=Neniuj Ignor-opcioj uzataj. +FileManuallyChanged=DOSIERO MANE ŜANĜITA, BONVOLU RE-KOMpari! +FileChanged=DOSIERO ŜANĜITA, KOMPARAJ REZULTOJ POVAS ESTI NEĜUSTAJ! +LastSave= ** Lasta Konservo +Clipboard= ** Tondujo +SVN= ** SVN +Git= ** Git +Moves=/Movoj +SubBlockDiffs=/Sub-blokaj Diferencoj +SubLineMoves=/Sub-liniaj Movoj +CharDiffs=/Signaj Diferencoj +Detect=Detekti: +Ignore=Ignori: +EOL=/Linifino +AllSpaces=/Ĉiuj Spacoj +ChangedSpaces=/Ŝanĝitaj Spacoj +Case=/Uskleco +Regex=/Regula Esprimo +Selections=Elektoj: +EOLMessage=Ŝajnas, ke dosieroj diferencas en linifinoj (EOL). Se tio estas la kazo, ĉiuj linioj aperos diferencaj.\n\nĈu vi volas ignori EOL-diferencojn por ĉi tiu komparo? + +[settings] +NewFileInLeftView=Nova dosiero en maldekstra vido +OldFileInLeftView=Malanta dosiero en maldekstra vido diff --git a/res/languages/french.ini b/res/languages/french.ini new file mode 100644 index 00000000..28868806 --- /dev/null +++ b/res/languages/french.ini @@ -0,0 +1,81 @@ +[menu] +CMD_SET_FIRST=Définir comme premier à comparer +CMD_COMPARE=Comparer +CMD_COMPARE_SEL=Comparer les sélections +CMD_FIND_UNIQUE=Trouver les lignes uniques +CMD_FIND_UNIQUE_SEL=Trouver les lignes uniques dans les sélections +CMD_LAST_SAVE_DIFF=Diff depuis la dernière sauvegarde +CMD_CLIPBOARD_DIFF=Comparer le fichier/sélection avec le presse-papiers +CMD_SVN_DIFF=Diff SVN +CMD_GIT_DIFF=Diff Git +CMD_CLEAR_ACTIVE=Effacer la comparaison active +CMD_CLEAR_ALL=Effacer toutes les comparaisons +CMD_FIRST=Premier bloc de diff +CMD_PREV=Bloc de diff précédent +CMD_NEXT=Bloc de diff suivant +CMD_LAST=Dernier bloc de diff +CMD_PREV_CHANGE_POS=Diff précédent dans la ligne modifiée +CMD_NEXT_CHANGE_POS=Diff suivant dans la ligne modifiée +CMD_COMPARE_SUMMARY=Résumé de la comparaison active +CMD_COPY_VISIBLE=Copier toutes/les lignes visibles sélectionnées +CMD_DELETE_VISIBLE=Supprimer toutes/les lignes visibles sélectionnées +CMD_BOOKMARK_VISIBLE=Marquer toutes/les lignes visibles sélectionnées +CMD_GENERATE_PATCH=Générer un patch +CMD_APPLY_PATCH=Appliquer le patch sur le fichier actuel +CMD_REVERT_PATCH=Annuler le patch sur le fichier actuel +CMD_COMPARE_OPTIONS=Options de comparaison (ignorer, etc.)... +CMD_DIFFS_VISUAL_FILTERS=Filtres visuels des diffs... +CMD_NAV_BAR=Barre de navigation +CMD_AUTO_RECOMPARE=Re-comparer automatiquement lors des modifications +CMD_SETTINGS=Paramètres... +CMD_ABOUT=Aide / À propos... + +[messages] +FindUnique=Trouver unique +Compare=Comparer +Detect=Détecter +Ignore=Ignorer +EmptyLines=Lignes vides +FoldedLines=Lignes repliées +HiddenLines=Lignes masquées +EOL=EOL +AllSpaces=Tous les espaces +ChangedSpaces=Espaces modifiés +Case=Casse +Regex=Regex +Moves=Déplacements +SubBlockDiffs=Diffs de sous-blocs +SubLineMoves=Déplacements de sous-lignes +CharDiffs=Diffs de caractères +DiffLines=Lignes de diff +Added=Ajouté +Removed=Supprimé +Moved=Déplacé +Changed=Modifié +MatchingLines=Lignes correspondantes +ComparisonOptions=Options de comparaison +NoDetectIgnore=Aucune option Détecter et Ignorer utilisée. +NoIgnore=Aucune option Ignorer utilisée. +FileManuallyChanged=FICHIER MODIFIÉ MANUELLEMENT, VEUILLEZ RE-COMPARER ! +FileChanged=FICHIER MODIFIÉ, LES RÉSULTATS DE COMPARAISON POURRAIENT ÊTRE INEXACTS ! +LastSave= ** Dernière sauvegarde +Clipboard= ** Presse-papiers +SVN= ** SVN +Git= ** Git +Moves=/Déplacements +SubBlockDiffs=/Diffs de sous-blocs +SubLineMoves=/Déplacements de sous-lignes +CharDiffs=/Diffs de caractères +Detect=Détecter : +Ignore=Ignorer : +EOL=/EOL +AllSpaces=/Tous les espaces +ChangedSpaces=/Espaces modifiés +Case=/Casse +Regex=/Regex +Selections=Sélections : +EOLMessage=Il semble que les fichiers diffèrent dans les fins de ligne (EOL). Si c'est le cas, toutes les lignes apparaîtront différentes.\n\nVoulez-vous ignorer les différences EOL pour cette comparaison ? + +[settings] +NewFileInLeftView=Nouveau fichier dans la vue gauche +OldFileInLeftView=Ancien fichier dans la vue gauche diff --git a/res/languages/german.ini b/res/languages/german.ini new file mode 100644 index 00000000..7ffa0beb --- /dev/null +++ b/res/languages/german.ini @@ -0,0 +1,81 @@ +[menu] +CMD_SET_FIRST=Als Erstes zum Vergleichen festlegen +CMD_COMPARE=Vergleichen +CMD_COMPARE_SEL=Auswahlen vergleichen +CMD_FIND_UNIQUE=Eindeutige Zeilen finden +CMD_FIND_UNIQUE_SEL=Eindeutige Zeilen in Auswahlen finden +CMD_LAST_SAVE_DIFF=Diff seit letzter Speicherung +CMD_CLIPBOARD_DIFF=Datei/Auswahl mit Zwischenablage vergleichen +CMD_SVN_DIFF=SVN Diff +CMD_GIT_DIFF=Git Diff +CMD_CLEAR_ACTIVE=Aktiven Vergleich löschen +CMD_CLEAR_ALL=Alle Vergleiche löschen +CMD_FIRST=Erster Diff-Block +CMD_PREV=Vorheriger Diff-Block +CMD_NEXT=Nächster Diff-Block +CMD_LAST=Letzter Diff-Block +CMD_PREV_CHANGE_POS=Vorheriger Diff in geänderter Zeile +CMD_NEXT_CHANGE_POS=Nächster Diff in geänderter Zeile +CMD_COMPARE_SUMMARY=Aktive Vergleichsübersicht +CMD_COPY_VISIBLE=Alle/ausgewählte sichtbare Zeilen kopieren +CMD_DELETE_VISIBLE=Alle/ausgewählte sichtbare Zeilen löschen +CMD_BOOKMARK_VISIBLE=Alle/ausgewählte sichtbare Zeilen markieren +CMD_GENERATE_PATCH=Patch generieren +CMD_APPLY_PATCH=Patch auf aktuelle Datei anwenden +CMD_REVERT_PATCH=Patch auf aktuelle Datei zurücksetzen +CMD_COMPARE_OPTIONS=Vergleichsoptionen (ignorieren, etc.)... +CMD_DIFFS_VISUAL_FILTERS=Diffs visuelle Filter... +CMD_NAV_BAR=Navigationsleiste +CMD_AUTO_RECOMPARE=Automatisch bei Änderung neu vergleichen +CMD_SETTINGS=Einstellungen... +CMD_ABOUT=Hilfe / Über... + +[messages] +FindUnique=Eindeutige finden +Compare=Vergleichen +Detect=Erkennen +Ignore=Ignorieren +EmptyLines=Leere Zeilen +FoldedLines=Gefaltete Zeilen +HiddenLines=Versteckte Zeilen +EOL=EOL +AllSpaces=Alle Leerzeichen +ChangedSpaces=Geänderte Leerzeichen +Case=Groß-/Kleinschreibung +Regex=Regex +Moves=Verschiebungen +SubBlockDiffs=Sub-Block-Diffs +SubLineMoves=Sub-Zeilen-Verschiebungen +CharDiffs=Zeichen-Diffs +DiffLines=Diff-Zeilen +Added=Hinzugefügt +Removed=Entfernt +Moved=Verschoben +Changed=Geändert +MatchingLines=Übereinstimmende Zeilen +ComparisonOptions=Vergleichsoptionen +NoDetectIgnore=Keine Erkennen- und Ignorieren-Optionen verwendet. +NoIgnore=Keine Ignorieren-Optionen verwendet. +FileManuallyChanged=DATEI MANUELL GEÄNDERT, BITTE NEU VERGLEICHEN! +FileChanged=DATEI GEÄNDERT, VERGLEICHSERGEBNISSE KÖNNTEN UNGENAU SEIN! +LastSave= ** Letzte Speicherung +Clipboard= ** Zwischenablage +SVN= ** SVN +Git= ** Git +Moves=/Verschiebungen +SubBlockDiffs=/Sub-Block-Diffs +SubLineMoves=/Sub-Zeilen-Verschiebungen +CharDiffs=/Zeichen-Diffs +Detect=Erkennen: +Ignore=Ignorieren: +EOL=/EOL +AllSpaces=/Alle Leerzeichen +ChangedSpaces=/Geänderte Leerzeichen +Case=/Groß-/Kleinschreibung +Regex=/Regex +Selections=Auswahlen: +EOLMessage=Es scheint, als unterscheiden sich die Dateien in den Zeilenenden (EOL). In diesem Fall werden alle Zeilen unterschiedlich erscheinen.\n\nMöchten Sie EOL-Unterschiede für diesen Vergleich ignorieren? + +[settings] +NewFileInLeftView=Neue Datei in linker Ansicht +OldFileInLeftView=Alte Datei in linker Ansicht diff --git a/res/languages/hindi.ini b/res/languages/hindi.ini new file mode 100644 index 00000000..19c595f6 --- /dev/null +++ b/res/languages/hindi.ini @@ -0,0 +1,81 @@ +[menu] +CMD_SET_FIRST=तुलना के लिए पहला सेट करें +CMD_COMPARE=तुलना करें +CMD_COMPARE_SEL=चयन तुलना करें +CMD_FIND_UNIQUE=अद्वितीय पंक्तियाँ खोजें +CMD_FIND_UNIQUE_SEL=चयन में अद्वितीय पंक्तियाँ खोजें +CMD_LAST_SAVE_DIFF=अंतिम सहेजे जाने से अंतर +CMD_CLIPBOARD_DIFF=फ़ाइल/चयन को क्लिपबोर्ड से तुलना करें +CMD_SVN_DIFF=SVN अंतर +CMD_GIT_DIFF=Git अंतर +CMD_CLEAR_ACTIVE=सक्रिय तुलना साफ़ करें +CMD_CLEAR_ALL=सभी तुलनाएँ साफ़ करें +CMD_FIRST=पहला अंतर ब्लॉक +CMD_PREV=पिछला अंतर ब्लॉक +CMD_NEXT=अगला अंतर ब्लॉक +CMD_LAST=अंतिम अंतर ब्लॉक +CMD_PREV_CHANGE_POS=संशोधित पंक्ति में पिछला अंतर +CMD_NEXT_CHANGE_POS=संशोधित पंक्ति में अगला अंतर +CMD_COMPARE_SUMMARY=सक्रिय तुलना सारांश +CMD_COPY_VISIBLE=सभी/चयनित दृश्यमान पंक्तियाँ कॉपी करें +CMD_DELETE_VISIBLE=सभी/चयनित दृश्यमान पंक्तियाँ हटाएँ +CMD_BOOKMARK_VISIBLE=सभी/चयनित दृश्यमान पंक्तियों को बुकमार्क करें +CMD_GENERATE_PATCH=पैच जनरेट करें +CMD_APPLY_PATCH=वर्तमान फ़ाइल पर पैच लागू करें +CMD_REVERT_PATCH=वर्तमान फ़ाइल का पैच वापस लें +CMD_COMPARE_OPTIONS=तुलना विकल्प (अनदेखा करें, आदि)... +CMD_DIFFS_VISUAL_FILTERS=अंतर दृश्य फ़िल्टर... +CMD_NAV_BAR=नेविगेशन बार +CMD_AUTO_RECOMPARE=परिवर्तन पर स्वतः पुनः तुलना करें +CMD_SETTINGS=सेटिंग्स... +CMD_ABOUT=सहायता/के बारे में... + +[messages] +FindUnique=अद्वितीय खोजें +Compare=तुलना करें +Detect=पता लगाएँ +Ignore=अनदेखा करें +EmptyLines=खाली पंक्तियाँ +FoldedLines=मुड़ी हुई पंक्तियाँ +HiddenLines=छुपी हुई पंक्तियाँ +EOL=EOL +AllSpaces=सभी रिक्त स्थान +ChangedSpaces=परिवर्तित रिक्त स्थान +Case=केस +Regex=रेगुलर एक्सप्रेशन +Moves=आंदोलन +SubBlockDiffs=उप-ब्लॉक अंतर +SubLineMoves=उप-पंक्ति आंदोलन +CharDiffs=वर्ण अंतर +DiffLines=अंतर पंक्तियाँ +Added=जोड़ा गया +Removed=हटाया गया +Moved=स्थानांतरित +Changed=परिवर्तित +MatchingLines=मिलान पंक्तियाँ +ComparisonOptions=तुलना विकल्प +NoDetectIgnore=कोई पता लगाने और अनदेखा करने के विकल्प उपयोग नहीं किए गए। +NoIgnore=कोई अनदेखा करने के विकल्प उपयोग नहीं किए गए। +FileManuallyChanged=फ़ाइल को मैन्युअल रूप से बदला गया है, कृपया पुनः तुलना करें! +FileChanged=फ़ाइल बदली गई है, तुलना परिणाम गलत हो सकते हैं! +LastSave= ** अंतिम सहेजा गया +Clipboard= ** क्लिपबोर्ड +SVN= ** SVN +Git= ** Git +Moves=/आंदोलन +SubBlockDiffs=/उप-ब्लॉक अंतर +SubLineMoves=/उप-पंक्ति आंदोलन +CharDiffs=/वर्ण अंतर +Detect=पता लगाएँ: +Ignore=अनदेखा करें: +EOL=/EOL +AllSpaces=/सभी रिक्त स्थान +ChangedSpaces=/परिवर्तित रिक्त स्थान +Case=/केस +Regex=/रेगुलर एक्सप्रेशन +Selections=चयन: +EOLMessage=ऐसा लगता है कि फ़ाइलें पंक्ति के अंत (EOL) में भिन्न हैं। यदि ऐसा है, तो सभी पंक्तियाँ भिन्न दिखाई देंगी।\n\nक्या आप इस तुलना के लिए EOL अंतर को अनदेखा करना चाहते हैं? + +[settings] +NewFileInLeftView=बाईं दृश्य में नई फ़ाइल +OldFileInLeftView=बाईं दृश्य में पुरानी फ़ाइल diff --git a/res/languages/japanese.ini b/res/languages/japanese.ini new file mode 100644 index 00000000..c786003a --- /dev/null +++ b/res/languages/japanese.ini @@ -0,0 +1,81 @@ +[menu] +CMD_SET_FIRST=比較する最初のものを設定 +CMD_COMPARE=比較 +CMD_COMPARE_SEL=選択を比較 +CMD_FIND_UNIQUE=一意の行を検索 +CMD_FIND_UNIQUE_SEL=選択内の一意の行を検索 +CMD_LAST_SAVE_DIFF=最終保存からの差分 +CMD_CLIPBOARD_DIFF=ファイル/選択をクリップボードと比較 +CMD_SVN_DIFF=SVN 差分 +CMD_GIT_DIFF=Git 差分 +CMD_CLEAR_ACTIVE=アクティブな比較をクリア +CMD_CLEAR_ALL=すべての比較をクリア +CMD_FIRST=最初の差分ブロック +CMD_PREV=前の差分ブロック +CMD_NEXT=次の差分ブロック +CMD_LAST=最後の差分ブロック +CMD_PREV_CHANGE_POS=変更行内の前の差分 +CMD_NEXT_CHANGE_POS=変更行内の次の差分 +CMD_COMPARE_SUMMARY=アクティブな比較の概要 +CMD_COPY_VISIBLE=すべて/選択された可視行をコピー +CMD_DELETE_VISIBLE=すべて/選択された可視行を削除 +CMD_BOOKMARK_VISIBLE=すべて/選択された可視行にブックマーク +CMD_GENERATE_PATCH=パッチを生成 +CMD_APPLY_PATCH=パッチを現在のファイルに適用 +CMD_REVERT_PATCH=現在のファイルのパッチを元に戻す +CMD_COMPARE_OPTIONS=比較オプション(無視など)... +CMD_DIFFS_VISUAL_FILTERS=差分の視覚フィルター... +CMD_NAV_BAR=ナビゲーションバー +CMD_AUTO_RECOMPARE=変更時に自動再比較 +CMD_SETTINGS=設定... +CMD_ABOUT=ヘルプ/バージョン情報... + +[messages] +FindUnique=一意を検索 +Compare=比較 +Detect=検出 +Ignore=無視 +EmptyLines=空行 +FoldedLines=折りたたまれた行 +HiddenLines=非表示行 +EOL=EOL +AllSpaces=すべてのスペース +ChangedSpaces=変更されたスペース +Case=大文字小文字 +Regex=正規表現 +Moves=移動 +SubBlockDiffs=サブブロック差分 +SubLineMoves=サブ行移動 +CharDiffs=文字差分 +DiffLines=差分行 +Added=追加 +Removed=削除 +Moved=移動 +Changed=変更 +MatchingLines=一致行 +ComparisonOptions=比較オプション +NoDetectIgnore=検出および無視オプションが使用されていません。 +NoIgnore=無視オプションが使用されていません。 +FileManuallyChanged=ファイルが手動で変更されました、再比較してください! +FileChanged=ファイルが変更されました、比較結果が不正確になる可能性があります! +LastSave= ** 最終保存 +Clipboard= ** クリップボード +SVN= ** SVN +Git= ** Git +Moves=/移動 +SubBlockDiffs=/サブブロック差分 +SubLineMoves=/サブ行移動 +CharDiffs=/文字差分 +Detect=検出: +Ignore=無視: +EOL=/EOL +AllSpaces=/すべてのスペース +ChangedSpaces=/変更されたスペース +Case=/大文字小文字 +Regex=/正規表現 +Selections=選択: +EOLMessage=ファイルが行末(EOL)で異なるようです。その場合、すべての行が異なるように表示されます。\n\nこの比較でEOLの違いを無視しますか? + +[settings] +NewFileInLeftView=左ビューに新しいファイル +OldFileInLeftView=左ビューに古いファイル diff --git a/res/languages/portuguese.ini b/res/languages/portuguese.ini new file mode 100644 index 00000000..d1d915fa --- /dev/null +++ b/res/languages/portuguese.ini @@ -0,0 +1,81 @@ +[menu] +CMD_SET_FIRST=Definir como primeiro para comparar +CMD_COMPARE=Comparar +CMD_COMPARE_SEL=Comparar seleções +CMD_FIND_UNIQUE=Buscar linhas únicas +CMD_FIND_UNIQUE_SEL=Buscar linhas únicas nas seleções +CMD_LAST_SAVE_DIFF=Diferença desde o último salvamento +CMD_CLIPBOARD_DIFF=Comparar arquivo/seleção com área de transferência +CMD_SVN_DIFF=Diferença SVN +CMD_GIT_DIFF=Diferença Git +CMD_CLEAR_ACTIVE=Limpar comparação ativa +CMD_CLEAR_ALL=Limpar todas as comparações +CMD_FIRST=Primeiro bloco de diferenças +CMD_PREV=Bloco de diferenças anterior +CMD_NEXT=Próximo bloco de diferenças +CMD_LAST=Último bloco de diferenças +CMD_PREV_CHANGE_POS=Diferença anterior na linha modificada +CMD_NEXT_CHANGE_POS=Próxima diferença na linha modificada +CMD_COMPARE_SUMMARY=Resumo da comparação ativa +CMD_COPY_VISIBLE=Copiar todas/as linhas visíveis selecionadas +CMD_DELETE_VISIBLE=Excluir todas/as linhas visíveis selecionadas +CMD_BOOKMARK_VISIBLE=Marcar todas/as linhas visíveis selecionadas +CMD_GENERATE_PATCH=Gerar patch +CMD_APPLY_PATCH=Aplicar patch no arquivo atual +CMD_REVERT_PATCH=Reverter patch do arquivo atual +CMD_COMPARE_OPTIONS=Opções de comparação (ignorar, etc.)... +CMD_DIFFS_VISUAL_FILTERS=Filtros visuais de diferenças... +CMD_NAV_BAR=Barra de navegação +CMD_AUTO_RECOMPARE=Recomparar automaticamente ao alterar +CMD_SETTINGS=Configurações... +CMD_ABOUT=Ajuda/Sobre... + +[messages] +FindUnique=Buscar único +Compare=Comparar +Detect=Detectar +Ignore=Ignorar +EmptyLines=Linhas vazias +FoldedLines=Linhas dobradas +HiddenLines=Linhas ocultas +EOL=EOL +AllSpaces=Todos os espaços +ChangedSpaces=Espaços alterados +Case=Caixa +Regex=Expressão regular +Moves=Movimentos +SubBlockDiffs=Diferenças de subblocos +SubLineMoves=Movimentos de sublinhas +CharDiffs=Diferenças de caracteres +DiffLines=Linhas de diferenças +Added=Adicionado +Removed=Removido +Moved=Movido +Changed=Alterado +MatchingLines=Linhas correspondentes +ComparisonOptions=Opções de comparação +NoDetectIgnore=Nenhuma opção de detectar e ignorar foi usada. +NoIgnore=Nenhuma opção de ignorar foi usada. +FileManuallyChanged=ARQUIVO ALTERADO MANUALMENTE, POR FAVOR RECOMPARE! +FileChanged=ARQUIVO ALTERADO, OS RESULTADOS DA COMPARAÇÃO PODEM SER INEXATOS! +LastSave= ** Último salvamento +Clipboard= ** Área de transferência +SVN= ** SVN +Git= ** Git +Moves=/Movimentos +SubBlockDiffs=/Diferenças de subblocos +SubLineMoves=/Movimentos de sublinhas +CharDiffs=/Diferenças de caracteres +Detect=Detectar: +Ignore=Ignorar: +EOL=/EOL +AllSpaces=/Todos os espaços +ChangedSpaces=/Espaços alterados +Case=/Caixa +Regex=/Expressão regular +Selections=Seleções: +EOLMessage=Parece que os arquivos diferem nos finais de linha (EOL). Se for o caso, todas as linhas aparecerão diferentes.\n\nVocê deseja ignorar as diferenças de EOL para esta comparação? + +[settings] +NewFileInLeftView=Novo arquivo na vista esquerda +OldFileInLeftView=Arquivo antigo na vista esquerda diff --git a/res/languages/russian.ini b/res/languages/russian.ini new file mode 100644 index 00000000..7f36eca6 --- /dev/null +++ b/res/languages/russian.ini @@ -0,0 +1,81 @@ +[menu] +CMD_SET_FIRST=Установить как первый для сравнения +CMD_COMPARE=Сравнить +CMD_COMPARE_SEL=Сравнить выделения +CMD_FIND_UNIQUE=Найти уникальные строки +CMD_FIND_UNIQUE_SEL=Найти уникальные строки в выделениях +CMD_LAST_SAVE_DIFF=Разница с момента последнего сохранения +CMD_CLIPBOARD_DIFF=Сравнить файл/выделение с буфером обмена +CMD_SVN_DIFF=Разница SVN +CMD_GIT_DIFF=Разница Git +CMD_CLEAR_ACTIVE=Очистить активное сравнение +CMD_CLEAR_ALL=Очистить все сравнения +CMD_FIRST=Первый блок различий +CMD_PREV=Предыдущий блок различий +CMD_NEXT=Следующий блок различий +CMD_LAST=Последний блок различий +CMD_PREV_CHANGE_POS=Предыдущее различие в изменённой строке +CMD_NEXT_CHANGE_POS=Следующее различие в изменённой строке +CMD_COMPARE_SUMMARY=Сводка активного сравнения +CMD_COPY_VISIBLE=Копировать все/выделенные видимые строки +CMD_DELETE_VISIBLE=Удалить все/выделенные видимые строки +CMD_BOOKMARK_VISIBLE=Добавить закладки на все/выделенные видимые строки +CMD_GENERATE_PATCH=Создать патч +CMD_APPLY_PATCH=Применить патч к текущему файлу +CMD_REVERT_PATCH=Отменить патч текущего файла +CMD_COMPARE_OPTIONS=Параметры сравнения (игнорировать и т.д.)... +CMD_DIFFS_VISUAL_FILTERS=Визуальные фильтры различий... +CMD_NAV_BAR=Панель навигации +CMD_AUTO_RECOMPARE=Автоматически пересравнивать при изменении +CMD_SETTINGS=Настройки... +CMD_ABOUT=Справка/О программе... + +[messages] +FindUnique=Найти уникальное +Compare=Сравнить +Detect=Обнаружить +Ignore=Игнорировать +EmptyLines=Пустые строки +FoldedLines=Свёрнутые строки +HiddenLines=Скрытые строки +EOL=EOL +AllSpaces=Все пробелы +ChangedSpaces=Изменённые пробелы +Case=Регистр +Regex=Регулярное выражение +Moves=Перемещения +SubBlockDiffs=Различия подблоков +SubLineMoves=Перемещения подстрок +CharDiffs=Различия символов +DiffLines=Строки различий +Added=Добавлено +Removed=Удалено +Moved=Перемещено +Changed=Изменено +MatchingLines=Совпадающие строки +ComparisonOptions=Параметры сравнения +NoDetectIgnore=Не использовались параметры обнаружения и игнорирования. +NoIgnore=Не использовались параметры игнорирования. +FileManuallyChanged=ФАЙЛ ИЗМЕНЁН ВРУЧНУЮ, ПОЖАЛУЙСТА, ПЕРЕСРАВНИТЕ! +FileChanged=ФАЙЛ ИЗМЕНЁН, РЕЗУЛЬТАТЫ СРАВНЕНИЯ МОГУТ БЫТЬ НЕТОЧНЫМИ! +LastSave= ** Последнее сохранение +Clipboard= ** Буфер обмена +SVN= ** SVN +Git= ** Git +Moves=/Перемещения +SubBlockDiffs=/Различия подблоков +SubLineMoves=/Перемещения подстрок +CharDiffs=/Различия символов +Detect=Обнаружить: +Ignore=Игнорировать: +EOL=/EOL +AllSpaces=/Все пробелы +ChangedSpaces=/Изменённые пробелы +Case=/Регистр +Regex=/Регулярное выражение +Selections=Выделения: +EOLMessage=Похоже, что файлы различаются в окончаниях строк (EOL). Если это так, все строки будут отображаться как различные.\n\nХотите ли вы игнорировать различия EOL для этого сравнения? + +[settings] +NewFileInLeftView=Новый файл в левом представлении +OldFileInLeftView=Старый файл в левом представлении diff --git a/res/languages/spanish.ini b/res/languages/spanish.ini new file mode 100644 index 00000000..6fd4a8b3 --- /dev/null +++ b/res/languages/spanish.ini @@ -0,0 +1,81 @@ +[menu] +CMD_SET_FIRST=Establecer como primero para comparar +CMD_COMPARE=Comparar +CMD_COMPARE_SEL=Comparar selecciones +CMD_FIND_UNIQUE=Buscar líneas únicas +CMD_FIND_UNIQUE_SEL=Buscar líneas únicas en selecciones +CMD_LAST_SAVE_DIFF=Diferencia desde el último guardado +CMD_CLIPBOARD_DIFF=Comparar archivo/selección con portapapeles +CMD_SVN_DIFF=Diferencia SVN +CMD_GIT_DIFF=Diferencia Git +CMD_CLEAR_ACTIVE=Borrar comparación activa +CMD_CLEAR_ALL=Borrar todas las comparaciones +CMD_FIRST=Primer bloque de diferencias +CMD_PREV=Bloque de diferencias anterior +CMD_NEXT=Siguiente bloque de diferencias +CMD_LAST=Último bloque de diferencias +CMD_PREV_CHANGE_POS=Diferencia anterior en línea modificada +CMD_NEXT_CHANGE_POS=Siguiente diferencia en línea modificada +CMD_COMPARE_SUMMARY=Resumen de comparación activa +CMD_COPY_VISIBLE=Copiar todas/las líneas visibles seleccionadas +CMD_DELETE_VISIBLE=Eliminar todas/las líneas visibles seleccionadas +CMD_BOOKMARK_VISIBLE=Marcar todas/las líneas visibles seleccionadas +CMD_GENERATE_PATCH=Generar parche +CMD_APPLY_PATCH=Aplicar parche al archivo actual +CMD_REVERT_PATCH=Revertir parche del archivo actual +CMD_COMPARE_OPTIONS=Opciones de comparación (ignorar, etc.)... +CMD_DIFFS_VISUAL_FILTERS=Filtros visuales de diferencias... +CMD_NAV_BAR=Barra de navegación +CMD_AUTO_RECOMPARE=Recomparar automáticamente al cambiar +CMD_SETTINGS=Configuración... +CMD_ABOUT=Ayuda/Acerca de... + +[messages] +FindUnique=Buscar único +Compare=Comparar +Detect=Detectar +Ignore=Ignorar +EmptyLines=Líneas vacías +FoldedLines=Líneas plegadas +HiddenLines=Líneas ocultas +EOL=EOL +AllSpaces=Todos los espacios +ChangedSpaces=Espacios cambiados +Case=Mayúsculas +Regex=Expresión regular +Moves=Movimientos +SubBlockDiffs=Diferencias de subbloques +SubLineMoves=Movimientos de sublíneas +CharDiffs=Diferencias de caracteres +DiffLines=Líneas de diferencias +Added=Agregado +Removed=Eliminado +Moved=Movido +Changed=Cambiado +MatchingLines=Líneas coincidentes +ComparisonOptions=Opciones de comparación +NoDetectIgnore=No se usaron opciones de detectar e ignorar. +NoIgnore=No se usaron opciones de ignorar. +FileManuallyChanged=¡ARCHIVO CAMBIADO MANUALMENTE, POR FAVOR RECOMPARE! +FileChanged=¡ARCHIVO CAMBIADO, LOS RESULTADOS DE COMPARACIÓN PUEDEN SER INEXACTOS! +LastSave= ** Último guardado +Clipboard= ** Portapapeles +SVN= ** SVN +Git= ** Git +Moves=/Movimientos +SubBlockDiffs=/Diferencias de subbloques +SubLineMoves=/Movimientos de sublíneas +CharDiffs=/Diferencias de caracteres +Detect=Detectar: +Ignore=Ignorar: +EOL=/EOL +AllSpaces=/Todos los espacios +ChangedSpaces=/Espacios cambiados +Case=/Mayúsculas +Regex=/Expresión regular +Selections=Selecciones: +EOLMessage=Parece que los archivos difieren en los finales de línea (EOL). Si es así, todas las líneas aparecerán diferentes.\n\n¿Desea ignorar las diferencias de EOL para esta comparación? + +[settings] +NewFileInLeftView=Nuevo archivo en vista izquierda +OldFileInLeftView=Archivo antiguo en vista izquierda diff --git a/src/Compare.cpp b/src/Compare.cpp index 8cdc656e..cda6c061 100644 --- a/src/Compare.cpp +++ b/src/Compare.cpp @@ -51,6 +51,7 @@ #include "NavDialog.h" #include "Engine.h" #include "resource.h" +#include "Localization.h" #ifndef NDEBUG @@ -4385,6 +4386,8 @@ void OpenAboutDlg() tab.pszText = name; TabCtrl_SetItem(hNppTabBar, posFromBuffId(dLogBuf), &tab); + + ::SendMessageW(nppData._nppHandle, NPPM_HIDETABBAR, 0, FALSE); } } else @@ -4410,7 +4413,10 @@ void OpenAboutDlg() void createMenu() { - wcscpy_s(funcItem[CMD_SET_FIRST]._itemName, menuItemSize, L"Set as First to Compare"); + std::string uiLang = getUILanguage(); + if (uiLang.empty()) uiLang = "english"; // ensure deterministic base + + wcscpy_s(funcItem[CMD_SET_FIRST]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_SET_FIRST").c_str()); funcItem[CMD_SET_FIRST]._pFunc = SetAsFirst; funcItem[CMD_SET_FIRST]._pShKey = new ShortcutKey; funcItem[CMD_SET_FIRST]._pShKey->_isAlt = true; @@ -4418,7 +4424,7 @@ void createMenu() funcItem[CMD_SET_FIRST]._pShKey->_isShift = false; funcItem[CMD_SET_FIRST]._pShKey->_key = '1'; - wcscpy_s(funcItem[CMD_COMPARE]._itemName, menuItemSize, L"Compare"); + wcscpy_s(funcItem[CMD_COMPARE]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_COMPARE").c_str()); funcItem[CMD_COMPARE]._pFunc = CompareWhole; funcItem[CMD_COMPARE]._pShKey = new ShortcutKey; funcItem[CMD_COMPARE]._pShKey->_isAlt = true; @@ -4426,7 +4432,7 @@ void createMenu() funcItem[CMD_COMPARE]._pShKey->_isShift = false; funcItem[CMD_COMPARE]._pShKey->_key = 'C'; - wcscpy_s(funcItem[CMD_COMPARE_SEL]._itemName, menuItemSize, L"Compare Selections"); + wcscpy_s(funcItem[CMD_COMPARE_SEL]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_COMPARE_SEL").c_str()); funcItem[CMD_COMPARE_SEL]._pFunc = CompareSelections; funcItem[CMD_COMPARE_SEL]._pShKey = new ShortcutKey; funcItem[CMD_COMPARE_SEL]._pShKey->_isAlt = true; @@ -4434,7 +4440,7 @@ void createMenu() funcItem[CMD_COMPARE_SEL]._pShKey->_isShift = false; funcItem[CMD_COMPARE_SEL]._pShKey->_key = 'N'; - wcscpy_s(funcItem[CMD_FIND_UNIQUE]._itemName, menuItemSize, L"Find Unique Lines"); + wcscpy_s(funcItem[CMD_FIND_UNIQUE]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_FIND_UNIQUE").c_str()); funcItem[CMD_FIND_UNIQUE]._pFunc = FindUnique; funcItem[CMD_FIND_UNIQUE]._pShKey = new ShortcutKey; funcItem[CMD_FIND_UNIQUE]._pShKey->_isAlt = true; @@ -4442,7 +4448,7 @@ void createMenu() funcItem[CMD_FIND_UNIQUE]._pShKey->_isShift = true; funcItem[CMD_FIND_UNIQUE]._pShKey->_key = 'C'; - wcscpy_s(funcItem[CMD_FIND_UNIQUE_SEL]._itemName, menuItemSize, L"Find Unique Lines in Selections"); + wcscpy_s(funcItem[CMD_FIND_UNIQUE_SEL]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_FIND_UNIQUE_SEL").c_str()); funcItem[CMD_FIND_UNIQUE_SEL]._pFunc = FindSelectionsUnique; funcItem[CMD_FIND_UNIQUE_SEL]._pShKey = new ShortcutKey; funcItem[CMD_FIND_UNIQUE_SEL]._pShKey->_isAlt = true; @@ -4450,7 +4456,7 @@ void createMenu() funcItem[CMD_FIND_UNIQUE_SEL]._pShKey->_isShift = true; funcItem[CMD_FIND_UNIQUE_SEL]._pShKey->_key = 'N'; - wcscpy_s(funcItem[CMD_LAST_SAVE_DIFF]._itemName, menuItemSize, L"Diff since last Save"); + wcscpy_s(funcItem[CMD_LAST_SAVE_DIFF]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_LAST_SAVE_DIFF").c_str()); funcItem[CMD_LAST_SAVE_DIFF]._pFunc = LastSaveDiff; funcItem[CMD_LAST_SAVE_DIFF]._pShKey = new ShortcutKey; funcItem[CMD_LAST_SAVE_DIFF]._pShKey->_isAlt = true; @@ -4458,7 +4464,7 @@ void createMenu() funcItem[CMD_LAST_SAVE_DIFF]._pShKey->_isShift = false; funcItem[CMD_LAST_SAVE_DIFF]._pShKey->_key = 'D'; - wcscpy_s(funcItem[CMD_CLIPBOARD_DIFF]._itemName, menuItemSize, L"Compare file/selection to Clipboard"); + wcscpy_s(funcItem[CMD_CLIPBOARD_DIFF]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_CLIPBOARD_DIFF").c_str()); funcItem[CMD_CLIPBOARD_DIFF]._pFunc = ClipboardDiff; funcItem[CMD_CLIPBOARD_DIFF]._pShKey = new ShortcutKey; funcItem[CMD_CLIPBOARD_DIFF]._pShKey->_isAlt = true; @@ -4466,7 +4472,7 @@ void createMenu() funcItem[CMD_CLIPBOARD_DIFF]._pShKey->_isShift = false; funcItem[CMD_CLIPBOARD_DIFF]._pShKey->_key = 'M'; - wcscpy_s(funcItem[CMD_SVN_DIFF]._itemName, menuItemSize, L"SVN Diff"); + wcscpy_s(funcItem[CMD_SVN_DIFF]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_SVN_DIFF").c_str()); funcItem[CMD_SVN_DIFF]._pFunc = SvnDiff; funcItem[CMD_SVN_DIFF]._pShKey = new ShortcutKey; funcItem[CMD_SVN_DIFF]._pShKey->_isAlt = true; @@ -4474,7 +4480,7 @@ void createMenu() funcItem[CMD_SVN_DIFF]._pShKey->_isShift = false; funcItem[CMD_SVN_DIFF]._pShKey->_key = 'V'; - wcscpy_s(funcItem[CMD_GIT_DIFF]._itemName, menuItemSize, L"Git Diff"); + wcscpy_s(funcItem[CMD_GIT_DIFF]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_GIT_DIFF").c_str()); funcItem[CMD_GIT_DIFF]._pFunc = GitDiff; funcItem[CMD_GIT_DIFF]._pShKey = new ShortcutKey; funcItem[CMD_GIT_DIFF]._pShKey->_isAlt = true; @@ -4482,7 +4488,7 @@ void createMenu() funcItem[CMD_GIT_DIFF]._pShKey->_isShift = false; funcItem[CMD_GIT_DIFF]._pShKey->_key = 'G'; - wcscpy_s(funcItem[CMD_CLEAR_ACTIVE]._itemName, menuItemSize, L"Clear Active Compare"); + wcscpy_s(funcItem[CMD_CLEAR_ACTIVE]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_CLEAR_ACTIVE").c_str()); funcItem[CMD_CLEAR_ACTIVE]._pFunc = ClearActiveCompare; funcItem[CMD_CLEAR_ACTIVE]._pShKey = new ShortcutKey; funcItem[CMD_CLEAR_ACTIVE]._pShKey->_isAlt = true; @@ -4490,10 +4496,10 @@ void createMenu() funcItem[CMD_CLEAR_ACTIVE]._pShKey->_isShift = false; funcItem[CMD_CLEAR_ACTIVE]._pShKey->_key = 'X'; - wcscpy_s(funcItem[CMD_CLEAR_ALL]._itemName, menuItemSize, L"Clear All Compares"); + wcscpy_s(funcItem[CMD_CLEAR_ALL]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_CLEAR_ALL").c_str()); funcItem[CMD_CLEAR_ALL]._pFunc = ClearAllCompares; - wcscpy_s(funcItem[CMD_FIRST]._itemName, menuItemSize, L"First Diff Block"); + wcscpy_s(funcItem[CMD_FIRST]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_FIRST").c_str()); funcItem[CMD_FIRST]._pFunc = First; funcItem[CMD_FIRST]._pShKey = new ShortcutKey; funcItem[CMD_FIRST]._pShKey->_isAlt = true; @@ -4501,7 +4507,7 @@ void createMenu() funcItem[CMD_FIRST]._pShKey->_isShift = false; funcItem[CMD_FIRST]._pShKey->_key = VK_PRIOR; - wcscpy_s(funcItem[CMD_PREV]._itemName, menuItemSize, L"Previous Diff Block"); + wcscpy_s(funcItem[CMD_PREV]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_PREV").c_str()); funcItem[CMD_PREV]._pFunc = Prev; funcItem[CMD_PREV]._pShKey = new ShortcutKey; funcItem[CMD_PREV]._pShKey->_isAlt = true; @@ -4509,7 +4515,7 @@ void createMenu() funcItem[CMD_PREV]._pShKey->_isShift = false; funcItem[CMD_PREV]._pShKey->_key = VK_PRIOR; - wcscpy_s(funcItem[CMD_NEXT]._itemName, menuItemSize, L"Next Diff Block"); + wcscpy_s(funcItem[CMD_NEXT]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_NEXT").c_str()); funcItem[CMD_NEXT]._pFunc = Next; funcItem[CMD_NEXT]._pShKey = new ShortcutKey; funcItem[CMD_NEXT]._pShKey->_isAlt = true; @@ -4517,7 +4523,7 @@ void createMenu() funcItem[CMD_NEXT]._pShKey->_isShift = false; funcItem[CMD_NEXT]._pShKey->_key = VK_NEXT; - wcscpy_s(funcItem[CMD_LAST]._itemName, menuItemSize, L"Last Diff Block"); + wcscpy_s(funcItem[CMD_LAST]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_LAST").c_str()); funcItem[CMD_LAST]._pFunc = Last; funcItem[CMD_LAST]._pShKey = new ShortcutKey; funcItem[CMD_LAST]._pShKey->_isAlt = true; @@ -4525,7 +4531,7 @@ void createMenu() funcItem[CMD_LAST]._pShKey->_isShift = false; funcItem[CMD_LAST]._pShKey->_key = VK_NEXT; - wcscpy_s(funcItem[CMD_PREV_CHANGE_POS]._itemName, menuItemSize, L"Previous Diff in Changed Line"); + wcscpy_s(funcItem[CMD_PREV_CHANGE_POS]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_PREV_CHANGE_POS").c_str()); funcItem[CMD_PREV_CHANGE_POS]._pFunc = PrevChangePos; funcItem[CMD_PREV_CHANGE_POS]._pShKey = new ShortcutKey; funcItem[CMD_PREV_CHANGE_POS]._pShKey->_isAlt = true; @@ -4533,7 +4539,7 @@ void createMenu() funcItem[CMD_PREV_CHANGE_POS]._pShKey->_isShift = true; funcItem[CMD_PREV_CHANGE_POS]._pShKey->_key = VK_PRIOR; - wcscpy_s(funcItem[CMD_NEXT_CHANGE_POS]._itemName, menuItemSize, L"Next Diff in Changed Line"); + wcscpy_s(funcItem[CMD_NEXT_CHANGE_POS]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_NEXT_CHANGE_POS").c_str()); funcItem[CMD_NEXT_CHANGE_POS]._pFunc = NextChangePos; funcItem[CMD_NEXT_CHANGE_POS]._pShKey = new ShortcutKey; funcItem[CMD_NEXT_CHANGE_POS]._pShKey->_isAlt = true; @@ -4541,50 +4547,107 @@ void createMenu() funcItem[CMD_NEXT_CHANGE_POS]._pShKey->_isShift = true; funcItem[CMD_NEXT_CHANGE_POS]._pShKey->_key = VK_NEXT; - wcscpy_s(funcItem[CMD_COMPARE_SUMMARY]._itemName, menuItemSize, L"Active Compare Summary"); + wcscpy_s(funcItem[CMD_COMPARE_SUMMARY]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_COMPARE_SUMMARY").c_str()); funcItem[CMD_COMPARE_SUMMARY]._pFunc = ActiveCompareSummary; - wcscpy_s(funcItem[CMD_COPY_VISIBLE]._itemName, menuItemSize, L"Copy all/selected visible lines"); + wcscpy_s(funcItem[CMD_COPY_VISIBLE]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_COPY_VISIBLE").c_str()); funcItem[CMD_COPY_VISIBLE]._pFunc = CopyVisibleLines; - wcscpy_s(funcItem[CMD_DELETE_VISIBLE]._itemName, menuItemSize, L"Delete all/selected visible lines"); + wcscpy_s(funcItem[CMD_DELETE_VISIBLE]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_DELETE_VISIBLE").c_str()); funcItem[CMD_DELETE_VISIBLE]._pFunc = DeleteVisibleLines; - wcscpy_s(funcItem[CMD_BOOKMARK_VISIBLE]._itemName, menuItemSize, L"Bookmark all/selected visible lines"); + wcscpy_s(funcItem[CMD_BOOKMARK_VISIBLE]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_BOOKMARK_VISIBLE").c_str()); funcItem[CMD_BOOKMARK_VISIBLE]._pFunc = BookmarkVisibleLines; - wcscpy_s(funcItem[CMD_GENERATE_PATCH]._itemName, menuItemSize, L"Generate Patch"); + wcscpy_s(funcItem[CMD_GENERATE_PATCH]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_GENERATE_PATCH").c_str()); funcItem[CMD_GENERATE_PATCH]._pFunc = GeneratePatch; - wcscpy_s(funcItem[CMD_APPLY_PATCH]._itemName, menuItemSize, L"Apply Patch on current file"); + wcscpy_s(funcItem[CMD_APPLY_PATCH]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_APPLY_PATCH").c_str()); funcItem[CMD_APPLY_PATCH]._pFunc = ApplyPatch; - wcscpy_s(funcItem[CMD_REVERT_PATCH]._itemName, menuItemSize, L"Revert Patch on current file"); + wcscpy_s(funcItem[CMD_REVERT_PATCH]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_REVERT_PATCH").c_str()); funcItem[CMD_REVERT_PATCH]._pFunc = RevertPatch; - wcscpy_s(funcItem[CMD_COMPARE_OPTIONS]._itemName, menuItemSize, L"Compare Options (ignore, etc.)..."); + wcscpy_s(funcItem[CMD_COMPARE_OPTIONS]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_COMPARE_OPTIONS").c_str()); funcItem[CMD_COMPARE_OPTIONS]._pFunc = OpenCompareOptionsDlg; - wcscpy_s(funcItem[CMD_DIFFS_VISUAL_FILTERS]._itemName, menuItemSize, L"Diffs Visual Filters..."); + wcscpy_s(funcItem[CMD_DIFFS_VISUAL_FILTERS]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_DIFFS_VISUAL_FILTERS").c_str()); funcItem[CMD_DIFFS_VISUAL_FILTERS]._pFunc = OpenVisualFiltersDlg; - wcscpy_s(funcItem[CMD_NAV_BAR]._itemName, menuItemSize, L"Navigation Bar"); + wcscpy_s(funcItem[CMD_NAV_BAR]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_NAV_BAR").c_str()); funcItem[CMD_NAV_BAR]._pFunc = ToggleNavigationBar; - wcscpy_s(funcItem[CMD_AUTO_RECOMPARE]._itemName, menuItemSize, L"Auto Re-Compare on Change"); + wcscpy_s(funcItem[CMD_AUTO_RECOMPARE]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_AUTO_RECOMPARE").c_str()); funcItem[CMD_AUTO_RECOMPARE]._pFunc = AutoRecompare; - wcscpy_s(funcItem[CMD_SETTINGS]._itemName, menuItemSize, L"Settings..."); + wcscpy_s(funcItem[CMD_SETTINGS]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_SETTINGS").c_str()); funcItem[CMD_SETTINGS]._pFunc = OpenSettingsDlg; #ifdef DLOG wcscpy_s(funcItem[CMD_ABOUT]._itemName, menuItemSize, L"Show debug log"); #else - wcscpy_s(funcItem[CMD_ABOUT]._itemName, menuItemSize, L"Help / About..."); + wcscpy_s(funcItem[CMD_ABOUT]._itemName, menuItemSize, getLocalizedString(uiLang, "menu", "CMD_ABOUT").c_str()); #endif funcItem[CMD_ABOUT]._pFunc = OpenAboutDlg; } +// Refresh existing menu item captions using current UI language (called after NPPN_READY) +static void refreshMenuCaptions() +{ + std::string uiLang = getUILanguage(); + if (uiLang.empty()) return; + HMENU hMenu = (HMENU)::SendMessageW(nppData._nppHandle, NPPM_GETMENUHANDLE, NPPPLUGINMENU, 0); + if (!hMenu) return; + // Update all items except About (which may be debug conditional) + struct { int id; const char* key; } items[] = { + { CMD_SET_FIRST, "CMD_SET_FIRST" }, + { CMD_COMPARE, "CMD_COMPARE" }, + { CMD_COMPARE_SEL, "CMD_COMPARE_SEL" }, + { CMD_FIND_UNIQUE, "CMD_FIND_UNIQUE" }, + { CMD_FIND_UNIQUE_SEL, "CMD_FIND_UNIQUE_SEL" }, + { CMD_LAST_SAVE_DIFF, "CMD_LAST_SAVE_DIFF" }, + { CMD_CLIPBOARD_DIFF, "CMD_CLIPBOARD_DIFF" }, + { CMD_SVN_DIFF, "CMD_SVN_DIFF" }, + { CMD_GIT_DIFF, "CMD_GIT_DIFF" }, + { CMD_CLEAR_ACTIVE, "CMD_CLEAR_ACTIVE" }, + { CMD_CLEAR_ALL, "CMD_CLEAR_ALL" }, + { CMD_FIRST, "CMD_FIRST" }, + { CMD_PREV, "CMD_PREV" }, + { CMD_NEXT, "CMD_NEXT" }, + { CMD_LAST, "CMD_LAST" }, + { CMD_PREV_CHANGE_POS, "CMD_PREV_CHANGE_POS" }, + { CMD_NEXT_CHANGE_POS, "CMD_NEXT_CHANGE_POS" }, + { CMD_COMPARE_SUMMARY, "CMD_COMPARE_SUMMARY" }, + { CMD_COPY_VISIBLE, "CMD_COPY_VISIBLE" }, + { CMD_DELETE_VISIBLE, "CMD_DELETE_VISIBLE" }, + { CMD_BOOKMARK_VISIBLE, "CMD_BOOKMARK_VISIBLE" }, + { CMD_GENERATE_PATCH, "CMD_GENERATE_PATCH" }, + { CMD_APPLY_PATCH, "CMD_APPLY_PATCH" }, + { CMD_REVERT_PATCH, "CMD_REVERT_PATCH" }, + { CMD_COMPARE_OPTIONS, "CMD_COMPARE_OPTIONS" }, + { CMD_DIFFS_VISUAL_FILTERS, "CMD_DIFFS_VISUAL_FILTERS" }, + { CMD_NAV_BAR, "CMD_NAV_BAR" }, + { CMD_AUTO_RECOMPARE, "CMD_AUTO_RECOMPARE" }, + { CMD_SETTINGS, "CMD_SETTINGS" } +#ifndef DLOG + ,{ CMD_ABOUT, "CMD_ABOUT" } +#endif + }; + for (auto &it : items) { + std::wstring localized = getLocalizedString(uiLang, "menu", it.key); + if(localized.empty()) continue; + wchar_t current[256] = {0}; + if (GetMenuStringW(hMenu, funcItem[it.id]._cmdID, current, _countof(current), MF_BYCOMMAND)) { + wchar_t* tab = wcschr(current, L'\t'); + if (tab) { + localized.append(tab); // keep existing accelerator part (e.g. "\tCtrl+Alt+C") + } + } + ModifyMenuW(hMenu, funcItem[it.id]._cmdID, MF_BYCOMMAND | MF_STRING, funcItem[it.id]._cmdID, localized.c_str()); + } + DrawMenuBar(nppData._nppHandle); +} + void freeToolbarObjects(toolbarIconsWithDarkMode& tb) { @@ -5031,6 +5094,18 @@ void onToolBarReady() void onNppReady() { + // Force refresh UI language now that NPPN_READY is received (language file name becomes available only now) + std::string refreshedLang = getUILanguage(true); + if (refreshedLang.empty()) + { + // fallback to english if still not available + refreshedLang = "english"; + } + else if (refreshedLang != "english") + { + refreshMenuCaptions(); + } + // It's N++'s job actually to disable its scroll menu commands but since it's not the case provide this as a patch if (isSingleView()) NppSettings::get().enableNppScrollCommands(false); @@ -6057,7 +6132,8 @@ void onFileSaved(LRESULT buffId) const int tabPos = posFromBuffId(otherFile.buffId); TabCtrl_GetItem(hNppTabBar, tabPos, &tab); - wcscat_s(tabText, _countof(tabText), L" - Outdated"); + _snwprintf_s(tabText, _countof(tabText), _TRUNCATE, L"%s - Outdated", + ::PathFindFileNameW(otherFile.name)); ::SendMessageW(nppData._nppHandle, NPPM_HIDETABBAR, 0, TRUE); @@ -6301,8 +6377,22 @@ extern "C" __declspec(dllexport) void beNotified(SCNotification* notifyCode) } -extern "C" __declspec(dllexport) LRESULT messageProc(UINT, WPARAM, LPARAM) +extern "C" __declspec(dllexport) LRESULT messageProc(UINT Message, WPARAM wParam, LPARAM lParam) { + constexpr UINT WM_INITMENUPOPUP_CONST = 0x0117; + if (Message == WM_INITMENUPOPUP_CONST) + { + std::string cur = getUILanguage(); + if (!cur.empty()) + { + static std::string last; + if (last != cur) + { + refreshMenuCaptions(); + last = cur; + } + } + } return TRUE; } diff --git a/src/Localization.cpp b/src/Localization.cpp new file mode 100644 index 00000000..02fbc4a2 --- /dev/null +++ b/src/Localization.cpp @@ -0,0 +1,162 @@ +#include "Localization.h" +#include "NppHelpers.h" +#include +#include +#include +#include +#include + +// Minimal localization: +// - Language INI files live in /languages/.ini (fallback relative ./languages/ during development) +// - Keys stored flat as "section.key" (all lowercase) +// - Lookup order: active language -> english -> original key text +// - No built-in strings; english.ini is authoritative. Missing english.ini causes raw keys to appear. +// - Thread-safe lazy load; no eviction. + +static std::mutex g_langDataMutex; // protect map +static std::unordered_map> g_langData; + +static std::string toLower(const std::string &s){ + std::string r = s; for(char &c: r) c = (char)tolower((unsigned char)c); return r; } + +// Resolve plugin directory to build absolute path to /languages even when CWD differs +static std::string getLanguagesDir() { + static std::string cachedDir; + if (!cachedDir.empty()) return cachedDir; + HMODULE hm{}; + if (GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + reinterpret_cast(&getUILanguage), &hm)) { + char pathBuf[MAX_PATH]; + if (GetModuleFileNameA(hm, pathBuf, sizeof(pathBuf))) { + PathRemoveFileSpecA(pathBuf); + std::string base(pathBuf); + cachedDir = base + "/languages/"; + return cachedDir; + } + } + // Fallback: relative (development scenario) + cachedDir = "languages/"; + return cachedDir; +} + +static bool g_warnedMissingEnglish = false; + +static void loadLangIfNeeded(const std::string &lang){ + std::lock_guard lock(g_langDataMutex); + if(g_langData.find(lang)!=g_langData.end()) return; + std::unordered_map entries; + + std::string path = getLanguagesDir() + lang + ".ini"; + std::ifstream ifs(path, std::ios::binary); + if(!ifs.is_open()){ + if(lang != "english") { + // fallback silently to english (which may itself be missing -> then keys return raw) + loadLangIfNeeded("english"); + auto it = g_langData.find("english"); + if(it != g_langData.end()) { + g_langData[lang] = it->second; // copy english entries + } else { + g_langData[lang]; // empty map placeholder + } + return; + } else { + // english missing: leave empty; lookups will fall back to key names + g_langData[lang]; + if(!g_warnedMissingEnglish) { + OutputDebugStringA("[ComparePlus][Localization] Warning: english.ini not found; showing raw keys.\n"); + g_warnedMissingEnglish = true; + } + return; + } + } + + std::string currentSection; + std::string line; + while(std::getline(ifs,line)){ + while(!line.empty() && (line.back()=='\r' || line.back()=='\n')) line.pop_back(); + if(line.empty() || line[0]==';' || line[0]=='#') continue; + if(line.front()=='[' && line.back()==']'){ + currentSection = toLower(line.substr(1,line.size()-2)); + continue; + } + size_t eq = line.find('='); + if(eq==std::string::npos) continue; + std::string key = toLower(line.substr(0,eq)); + std::string val = line.substr(eq+1); + // trim spaces + auto trim=[&](std::string &s){ while(!s.empty() && (s.back()==' '||s.back()=='\t')) s.pop_back(); size_t i=0; while(i lock(g_langDataMutex); + auto l = g_langData.find(langLow); + if (l != g_langData.end()) { + auto kIt = l->second.find(flatKey); + if (kIt != l->second.end()) return kIt->second; + } + if (langLow != "english") { + // one-shot fallback to english (ensure loaded) + loadLangIfNeeded("english"); + auto e = g_langData.find("english"); + if (e != g_langData.end()) { + auto kIt = e->second.find(flatKey); + if (kIt != e->second.end()) return kIt->second; + } + } + std::wstring w; w.assign(key.begin(), key.end()); + return w; +} + +// Try to query Notepad++ for active native language file. +// API expects char* buffer (ANSI). Returns length (not including null) or 0. +static std::string queryNppNativeLangFile(){ + if(!nppData._nppHandle) return {}; + char buf[512] = {0}; + LRESULT len = ::SendMessageA(nppData._nppHandle, NPPM_GETNATIVELANGFILENAME, (WPARAM)sizeof(buf), (LPARAM)buf); + if(len <= 0 || (size_t)len >= sizeof(buf)) return {}; + return std::string(buf, (size_t)len); +} + +// Removed best-match heuristic: we don't attempt partial/substring matches anymore. + +std::string getUILanguage(bool forceRefresh){ + static std::string cached; + if(forceRefresh) cached.clear(); + if(!cached.empty()) return cached; + + std::string nppFile = queryNppNativeLangFile(); + if(nppFile.empty()) { + // Defer caching until we actually get a filename; return empty so caller can fallback at UI-time + return std::string(); + } + // Extract basename (strip path & extension) + std::string lower = toLower(nppFile); + size_t slash = lower.find_last_of("/\\"); + if(slash != std::string::npos) lower = lower.substr(slash+1); + size_t dot = lower.find_last_of('.'); + if(dot != std::string::npos) lower = lower.substr(0,dot); + if(lower.empty()) lower = "english"; + // Verify file exists (except for english which can be built-in) + if(lower != "english") { + std::string testPath = getLanguagesDir() + lower + ".ini"; + DWORD attr = GetFileAttributesA(testPath.c_str()); + if(attr == INVALID_FILE_ATTRIBUTES || (attr & FILE_ATTRIBUTE_DIRECTORY)) { + lower = "english"; + } + } + cached = lower; + return cached; +} diff --git a/src/Localization.h b/src/Localization.h new file mode 100644 index 00000000..acf272c5 --- /dev/null +++ b/src/Localization.h @@ -0,0 +1,26 @@ +/* + * This file is part of ComparePlus plugin for Notepad++ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include +#include +#include + +// Localization functions +extern std::string getUILanguage(bool forceRefresh = false); +extern std::wstring getLocalizedString(const std::string& lang, const std::string& section, const std::string& key); diff --git a/src/NavDlg/NavDialog.h b/src/NavDlg/NavDialog.h index 89652b0c..ebe3ef18 100644 --- a/src/NavDlg/NavDialog.h +++ b/src/NavDlg/NavDialog.h @@ -36,6 +36,9 @@ class NavDialog : public DockingDlgInterface NavDialog(const NavDialog&) = delete; NavDialog& operator=(const NavDialog&) = delete; + // Bring base class virtual functions into scope to avoid hiding warnings + using DockingDlgInterface::init; + void init(HINSTANCE hInst); void destroy() {}; diff --git a/src/NppAPI/DockingFeature/DockingDlgInterface.h b/src/NppAPI/DockingFeature/DockingDlgInterface.h index 4665a1ee..d0d44b61 100644 --- a/src/NppAPI/DockingFeature/DockingDlgInterface.h +++ b/src/NppAPI/DockingFeature/DockingDlgInterface.h @@ -33,6 +33,9 @@ class DockingDlgInterface : public StaticDialog DockingDlgInterface() = default; explicit DockingDlgInterface(int dlgID): _dlgID(dlgID) {} + // Bring base class virtual functions into scope to avoid hiding warnings + using StaticDialog::init; + void init(HINSTANCE hInst, HWND parent) override { StaticDialog::init(hInst, parent); wchar_t temp[MAX_PATH]; diff --git a/src/NppAPI/DockingFeature/StaticDialog.h b/src/NppAPI/DockingFeature/StaticDialog.h index 7d061111..e01f3c90 100644 --- a/src/NppAPI/DockingFeature/StaticDialog.h +++ b/src/NppAPI/DockingFeature/StaticDialog.h @@ -48,6 +48,10 @@ public : return (_hSelf != nullptr); } + // Bring base class virtual functions into scope to avoid hiding warnings + using Window::init; + using Window::display; + void getMappedChildRect(HWND hChild, RECT& rcChild) const; void getMappedChildRect(int idChild, RECT& rcChild) const; void redrawDlgItem(const int nIDDlgItem, bool forceUpdate = false) const; diff --git a/src/SettingsDlg/ColorCombo.h b/src/SettingsDlg/ColorCombo.h index 4870a34d..75e5c932 100644 --- a/src/SettingsDlg/ColorCombo.h +++ b/src/SettingsDlg/ColorCombo.h @@ -31,6 +31,10 @@ public : }; ~ColorCombo () {}; + + // Bring base class virtual functions into scope to avoid hiding warnings + using Window::init; + virtual void init(HINSTANCE hInst, HWND hNpp, HWND hCombo); virtual void destroy() { diff --git a/src/SettingsDlg/ColorPopup.h b/src/SettingsDlg/ColorPopup.h index a602baff..9ef3981f 100644 --- a/src/SettingsDlg/ColorPopup.h +++ b/src/SettingsDlg/ColorPopup.h @@ -31,6 +31,9 @@ public : ColorPopup(COLORREF defaultColor) : Window(), _isColorChooserLaunched(false), _color(defaultColor) {}; ~ColorPopup(){}; + // Bring base class virtual functions into scope to avoid hiding warnings + using Window::init; + void init(HINSTANCE hInst, HWND hParent, HWND hNpp) { _hNpp = hNpp; Window::init(hInst, hParent); diff --git a/src/SettingsDlg/SettingsDialog.cpp b/src/SettingsDlg/SettingsDialog.cpp index 770204dd..a7221276 100644 --- a/src/SettingsDlg/SettingsDialog.cpp +++ b/src/SettingsDlg/SettingsDialog.cpp @@ -27,6 +27,8 @@ #include "NppHelpers.h" +#include "Localization.h" + static const int c_Highlight_transp_min = 0; static const int c_Highlight_transp_max = 100; @@ -85,8 +87,9 @@ INT_PTR CALLBACK SettingsDialog::run_dlgProc(UINT Message, WPARAM wParam, LPARAM if (isRTLwindow(nppData._nppHandle)) { - SetDlgItemTextW(_hSelf, IDC_NEW_IN_SUB, L"New file in left view"); - SetDlgItemTextW(_hSelf, IDC_OLD_IN_SUB, L"Old file in left view"); + std::string lang = getUILanguage(); + SetDlgItemTextW(_hSelf, IDC_NEW_IN_SUB, getLocalizedString(lang, "settings", "NewFileInLeftView").c_str()); + SetDlgItemTextW(_hSelf, IDC_OLD_IN_SUB, getLocalizedString(lang, "settings", "OldFileInLeftView").c_str()); } SetParams();