Skip to content

Commit 4a49033

Browse files
committed
Translate the git panel, and drop a worker nothing used
Reviewing the new code again turned up two things. GitWorker was never instantiated anywhere: the panel has a worker of its own and the service layer is called directly. It is gone rather than left as a class that looks available but is not. The panel''s buttons and prompts were hard-coded English, while the language files have carried translations for exactly those strings all along -- the new stash and conflict buttons had followed the same pattern. They read from the dictionary now, which puts eighteen unused keys back to work and adds the ones the new buttons and dialogs need.
1 parent ecebdd5 commit 4a49033

5 files changed

Lines changed: 114 additions & 51 deletions

File tree

je_editor/git_client/git_action.py

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import os
22
from datetime import datetime
3-
from typing import Any, Callable
43

5-
from PySide6.QtCore import QThread, Signal
64
from git import Repo, GitCommandError, InvalidGitRepositoryError, NoSuchPathError
75

86
from je_editor.utils.logging.loggin_instance import jeditor_logger
@@ -269,29 +267,3 @@ def _ensure_repo(self) -> None:
269267

270268
# Null tree constant for initial commit diff
271269
NULL_TREE = "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
272-
273-
274-
# Worker thread wrapper
275-
class GitWorker(QThread):
276-
"""
277-
Runs a function in a separate thread to avoid blocking the UI.
278-
Emits (result, error) when done.
279-
"""
280-
done = Signal(object, object)
281-
282-
def __init__(self, fn: Callable, *args: Any, **kwargs: Any) -> None:
283-
super().__init__()
284-
# 具名執行緒:萬一它在執行中被銷毀,Qt 的中止訊息才說得出是哪一條
285-
# A named thread, so Qt's abort message says which one if it is ever
286-
# destroyed while still running
287-
self.setObjectName("GitWorker")
288-
self.fn = fn
289-
self.args = args
290-
self.kwargs = kwargs
291-
292-
def run(self) -> None:
293-
try:
294-
res = self.fn(*self.args, **self.kwargs)
295-
self.done.emit(res, None)
296-
except Exception as e:
297-
self.done.emit(None, e)

je_editor/pyside_ui/git_ui/git_client/git_client_gui.py

Lines changed: 55 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,38 @@
1212

1313
from je_editor.git_client.git_action import GitService
1414
from je_editor.utils.logging.loggin_instance import jeditor_logger
15+
from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper
1516

1617
# UI 常數 / UI constants
1718
_CLONE_REPO_LABEL = "Clone Repo"
1819
_REPO_STATUS_DEFAULT = "Status: -"
1920

2021

22+
def _text(key: str) -> str:
23+
"""
24+
取得翻譯後的文字
25+
The translated text for a key.
26+
27+
這個面板的字串原本是寫死的英文,但語言檔裡一直有對應的翻譯沒被用到。
28+
This panel's strings used to be hard-coded English while the translations for
29+
them sat unused in the language files.
30+
31+
:param key: 語言鍵 / the language key
32+
:return: 翻譯後的文字 / the translated text
33+
"""
34+
return language_wrapper.language_word_dict.get(key, key)
35+
36+
37+
def _word(key: str) -> QPushButton:
38+
"""建立一個帶翻譯文字的按鈕 / A button labelled with a translated key."""
39+
return QPushButton(_text(key))
40+
41+
42+
def _label(key: str) -> QLabel:
43+
"""建立一個帶翻譯文字的標籤 / A label showing a translated key."""
44+
return QLabel(_text(key))
45+
46+
2147
class _GitWorker(QObject):
2248
"""背景執行 Git 操作的 Worker / Background worker for Git operations"""
2349
finished = Signal(object) # result
@@ -88,16 +114,16 @@ def _run_git_in_background(self, func: Callable, on_done: Callable | None = None
88114
def _init_ui(self) -> None:
89115
# === Top controls / 上方控制區 ===
90116
self.repo_path_label = QLabel("Repository: (none)")
91-
self.open_repo_button = QPushButton("Open Repo")
117+
self.open_repo_button = _word("btn_open_repo")
92118
self.branch_selector = QComboBox()
93-
self.checkout_button = QPushButton("Checkout")
119+
self.checkout_button = _word("btn_checkout")
94120
self.clone_repo_button = QPushButton(_CLONE_REPO_LABEL)
95121
self.repo_status_label = QLabel(_REPO_STATUS_DEFAULT)
96122
self.commit_status_label = QLabel("Unpushed commits: ...")
97123

98124
top = QHBoxLayout()
99125
top.addWidget(self.repo_path_label, 1)
100-
top.addWidget(QLabel("Branch:"))
126+
top.addWidget(_label("label_branch"))
101127
top.addWidget(self.branch_selector, 1)
102128
top.addWidget(self.checkout_button)
103129
top.addWidget(self.open_repo_button)
@@ -134,21 +160,21 @@ def _init_ui(self) -> None:
134160

135161
# === Bottom: staging and commit controls / 下方:stage 與 commit 控制 ===
136162
self.commit_message_input = QLineEdit()
137-
self.commit_message_input.setPlaceholderText("Commit message...")
138-
self.stage_selected_button = QPushButton("Stage Selected")
139-
self.unstage_selected_button = QPushButton("Unstage Selected")
140-
self.stage_all_button = QPushButton("Stage All")
141-
self.commit_button = QPushButton("Commit")
142-
self.unstage_all_button = QPushButton("Unstage All")
143-
self.track_all_untracked_button = QPushButton("Track All Untracked")
144-
self.git_push_button = QPushButton("Push")
163+
self.commit_message_input.setPlaceholderText(_text("placeholder_commit_message"))
164+
self.stage_selected_button = _word("btn_stage_selected")
165+
self.unstage_selected_button = _word("btn_unstage_selected")
166+
self.stage_all_button = _word("btn_stage_all")
167+
self.commit_button = _word("btn_commit")
168+
self.unstage_all_button = _word("btn_unstage_all")
169+
self.track_all_untracked_button = _word("btn_track_all_untracked")
170+
self.git_push_button = _word("btn_push")
145171
# 收起手邊的修改與解決合併衝突 / Putting work down, and settling a merge
146-
self.stash_button = QPushButton("Stash")
147-
self.stash_pop_button = QPushButton("Pop Stash")
148-
self.resolve_button = QPushButton("Resolve Conflict")
172+
self.stash_button = _word("btn_stash")
173+
self.stash_pop_button = _word("btn_stash_pop")
174+
self.resolve_button = _word("btn_resolve_conflict")
149175

150176
bottom = QHBoxLayout()
151-
bottom.addWidget(QLabel("Message:"))
177+
bottom.addWidget(_label("label_message"))
152178
bottom.addWidget(self.commit_message_input, 1)
153179
bottom.addWidget(self.stage_selected_button)
154180
bottom.addWidget(self.unstage_selected_button)
@@ -738,7 +764,7 @@ def on_stash_changes(self) -> None:
738764
try:
739765
service.stash_save(message)
740766
except GitCommandError as error:
741-
QMessageBox.critical(self, "Error", f"Could not stash:\n{error}")
767+
QMessageBox.critical(self, "Error", f"{_text('err_stash')}:\n{error}")
742768
return
743769
self.commit_message_input.clear()
744770
self._refresh_change_list()
@@ -757,16 +783,18 @@ def on_pop_stash(self) -> None:
757783
return
758784
stashes = service.stash_list()
759785
if not stashes:
760-
QMessageBox.information(self, "Stash", "There is nothing stashed.")
786+
QMessageBox.information(
787+
self, _text("btn_stash"), _text("info_no_stash"))
761788
return
762789
chosen, confirmed = QInputDialog.getItem(
763-
self, "Pop Stash", "Take back:", stashes, 0, False)
790+
self, _text("dialog_stash_pop_title"), _text("dialog_stash_pop_prompt"),
791+
stashes, 0, False)
764792
if not confirmed or not chosen:
765793
return
766794
try:
767795
service.stash_pop(stashes.index(chosen))
768796
except GitCommandError as error:
769-
QMessageBox.critical(self, "Error", f"Could not pop the stash:\n{error}")
797+
QMessageBox.critical(self, "Error", f"{_text('err_stash_pop')}:\n{error}")
770798
return
771799
self._refresh_change_list()
772800

@@ -784,19 +812,23 @@ def on_resolve_conflict(self) -> None:
784812
return
785813
conflicts = service.conflicted_files()
786814
if not conflicts:
787-
QMessageBox.information(self, "Conflicts", "Nothing is in conflict.")
815+
QMessageBox.information(
816+
self, _text("dialog_resolve_title"), _text("info_no_conflicts"))
788817
return
789818
chosen, confirmed = QInputDialog.getItem(
790-
self, "Resolve Conflict", "File:", conflicts, 0, False)
819+
self, _text("dialog_resolve_title"), _text("dialog_resolve_file_prompt"),
820+
conflicts, 0, False)
791821
if not confirmed or not chosen:
792822
return
793823
keep, confirmed = QInputDialog.getItem(
794-
self, "Resolve Conflict", f"Keep which side of {chosen}?",
824+
self, _text("dialog_resolve_title"),
825+
_text("dialog_resolve_side_prompt").format(file=chosen),
795826
["ours", "theirs"], 0, False)
796827
if not confirmed or not keep:
797828
return
798829
if not service.resolve_conflict(chosen, keep):
799-
QMessageBox.critical(self, "Error", f"Could not resolve {chosen}.")
830+
QMessageBox.critical(
831+
self, "Error", _text("err_resolve").format(file=chosen))
800832
return
801833
self._refresh_change_list()
802834

je_editor/utils/multi_language/english.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,24 @@
204204
"placeholder_commit_message": "Commit message...",
205205
"btn_stage_all": "Stage All",
206206
"btn_commit": "Commit",
207+
"btn_checkout": "Checkout",
208+
"btn_stage_selected": "Stage Selected",
209+
"btn_unstage_selected": "Unstage Selected",
210+
"btn_unstage_all": "Unstage All",
211+
"btn_track_all_untracked": "Track All Untracked",
212+
"btn_stash": "Stash",
213+
"btn_stash_pop": "Pop Stash",
214+
"btn_resolve_conflict": "Resolve Conflict",
215+
"dialog_stash_pop_title": "Pop Stash",
216+
"dialog_stash_pop_prompt": "Take back:",
217+
"info_no_stash": "There is nothing stashed.",
218+
"err_stash": "Could not stash",
219+
"err_stash_pop": "Could not pop the stash",
220+
"dialog_resolve_title": "Resolve Conflict",
221+
"dialog_resolve_file_prompt": "File:",
222+
"dialog_resolve_side_prompt": "Keep which side of {file}?",
223+
"info_no_conflicts": "Nothing is in conflict.",
224+
"err_resolve": "Could not resolve {file}",
207225
"label_message": "Message:",
208226
"dialog_choose_repo": "Choose Git Repo",
209227
"err_open_repo": "Failed to open repository",

je_editor/utils/multi_language/traditional_chinese.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,24 @@
195195
"placeholder_commit_message": "提交訊息...",
196196
"btn_stage_all": "暫存全部",
197197
"btn_commit": "提交",
198+
"btn_checkout": "切換",
199+
"btn_stage_selected": "暫存選取",
200+
"btn_unstage_selected": "取消暫存選取",
201+
"btn_unstage_all": "全部取消暫存",
202+
"btn_track_all_untracked": "追蹤所有未追蹤檔案",
203+
"btn_stash": "收起修改",
204+
"btn_stash_pop": "取回修改",
205+
"btn_resolve_conflict": "解決衝突",
206+
"dialog_stash_pop_title": "取回修改",
207+
"dialog_stash_pop_prompt": "要取回哪一筆:",
208+
"info_no_stash": "目前沒有收起任何修改。",
209+
"err_stash": "無法收起修改",
210+
"err_stash_pop": "無法取回修改",
211+
"dialog_resolve_title": "解決衝突",
212+
"dialog_resolve_file_prompt": "檔案:",
213+
"dialog_resolve_side_prompt": "{file} 要保留哪一邊?",
214+
"info_no_conflicts": "目前沒有衝突。",
215+
"err_resolve": "無法解決 {file}",
198216
"label_message": "訊息:",
199217
"dialog_choose_repo": "選擇 Git 儲存庫",
200218
"err_open_repo": "開啟儲存庫失敗",

test/test_git_panel_stash.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,29 @@ def panel(qapp, qtbot, repo):
3535
widget.close()
3636

3737

38+
class TestTheLabelsAreTranslated:
39+
"""
40+
The panel's strings were hard-coded English while the translations for them
41+
sat unused in the language files.
42+
"""
43+
44+
def test_a_button_shows_the_translated_text(self, panel):
45+
from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper
46+
widget, _repo = panel
47+
assert widget.commit_button.text() == \
48+
language_wrapper.language_word_dict.get("btn_commit")
49+
50+
def test_the_new_buttons_are_translated_too(self, panel):
51+
from je_editor.utils.multi_language.multi_language_wrapper import language_wrapper
52+
widget, _repo = panel
53+
assert widget.stash_button.text() == \
54+
language_wrapper.language_word_dict.get("btn_stash")
55+
56+
def test_a_missing_key_falls_back_to_itself(self):
57+
from je_editor.pyside_ui.git_ui.git_client.git_client_gui import _text
58+
assert _text("no_such_key") == "no_such_key"
59+
60+
3861
class TestTheButtonsExist:
3962
"""
4063
The operations had tests but no way to reach them: GitService had no UI

0 commit comments

Comments
 (0)