Loading ballontranslator/ui/canvas.py +1 −0 Original line number Diff line number Diff line Loading @@ -514,4 +514,5 @@ class Canvas(QGraphicsScene): pass def on_search_replace_all(self): self.undoStack.push(ReplaceAllCommand(self.search_widget)) pass No newline at end of file ballontranslator/ui/imgtranspanel.py +10 −15 Original line number Diff line number Diff line Loading @@ -13,7 +13,6 @@ from .textitem import TextBlock, TextBlkItem from .fontformatpanel import FontFormatPanel class SourceTextEdit(QTextEdit): hover_enter = Signal(int) hover_leave = Signal(int) Loading Loading @@ -44,7 +43,10 @@ class SourceTextEdit(QTextEdit): self.input_method_from = -1 self.input_method_text = '' self.text_content_changed = False self.high_lighting = False self.highlighting = False def updateUndoSteps(self): self.old_undo_steps = self.document().availableUndoSteps() def on_content_changing(self, from_: int, removed: int, added: int): if not self.pre_editing: Loading @@ -53,7 +55,6 @@ class SourceTextEdit(QTextEdit): self.change_from = from_ self.change_added = added def adjustSize(self): h = self.document().documentLayout().documentSize().toSize().height() self.setFixedHeight(max(h, 50)) Loading @@ -61,13 +62,12 @@ class SourceTextEdit(QTextEdit): def on_content_changed(self): if self.text_content_changed: self.text_content_changed = False if not self.high_lighting: if not self.highlighting: self.text_changed.emit() if self.hasFocus() and not self.pre_editing: self.user_edited.emit() if not self.in_redo_undo: change_from = self.change_from added_text = '' input_method_used = False Loading @@ -90,14 +90,12 @@ class SourceTextEdit(QTextEdit): added_text = cursor.selectedText() self.user_edited_verbose.emit(change_from, added_text, input_method_used) undo_steps = self.document().availableUndoSteps() new_steps = undo_steps - self.old_undo_steps if new_steps > 0: self.old_undo_steps = undo_steps self.push_undo_stack.emit(new_steps) def setHoverEffect(self, hover: bool): try: if hover: Loading Loading @@ -132,13 +130,12 @@ class SourceTextEdit(QTextEdit): return super().focusOutEvent(event) def inputMethodEvent(self, e: QInputMethodEvent) -> None: cursor = self.textCursor() if e.preeditString() == '': self.pre_editing = False self.input_method_text = e.commitString() else: if self.pre_editing is False: cursor = self.textCursor() self.input_method_from = cursor.selectionStart() self.pre_editing = True self.input_method_event = e Loading Loading @@ -168,9 +165,6 @@ class SourceTextEdit(QTextEdit): self.in_redo_undo = False self.old_undo_steps = self.document().availableUndoSteps() def block_all_signals(self, block: bool): self.blockSignals(block) self.document().blockSignals(block) class TransTextEdit(SourceTextEdit): pass Loading Loading @@ -239,7 +233,7 @@ class TextEditCommand(QUndoCommand): super().__init__() self.edit = edit self.blkitem = blkitem self.op_counter = -1 self.op_counter = 0 self.change_from = edit.change_from self.change_added = edit.change_added self.change_removed = edit.change_removed Loading @@ -250,9 +244,10 @@ class TextEditCommand(QUndoCommand): edit.input_method_from = -1 def redo(self): if self.op_counter == 0: self.op_counter += 1 if self.op_counter <= 0: return for _ in range(self.num_steps): self.edit.redo() self.blkitem.document().redo() Loading ballontranslator/ui/scenetext_manager.py +23 −22 Original line number Diff line number Diff line Loading @@ -187,7 +187,7 @@ class CreateItemCommand(QUndoCommand): class DeleteBlkItemsCommand(QUndoCommand): def __init__(self, blk_list: List[TextBlkItem], ctrl, parent=None): super().__init__(parent) self.op_counter = -1 self.op_counter = 0 self.blk_list = [] self.pwidget_list: List[TransPairWidget] = [] self.ctrl: SceneTextManager = ctrl Loading Loading @@ -233,6 +233,13 @@ class DeleteBlkItemsCommand(QUndoCommand): self.new_counter_sum = self.sw.counter_sum if self.sw_changed: if self.sw.counter_sum > 0: idx = self.sw.get_result_edit_index(self.sw.current_edit) if self.sw.current_cursor is not None and idx != -1: self.sw.result_pos = self.sw.highlighter_list[idx].matched_map[self.sw.current_cursor.position()] if idx > 0: self.sw.result_pos += sum(self.sw.search_counter_list[: idx]) self.sw.updateCounterText() else: self.sw.setCurrentEditor(self.sw.search_rstedit_list[0]) else: self.sw.setCurrentEditor(None) Loading @@ -240,19 +247,23 @@ class DeleteBlkItemsCommand(QUndoCommand): self.ctrl.deleteTextblkItemList(self.blk_list, self.pwidget_list) def redo(self): if self.op_counter == 0: self.op_counter += 1 if self.op_counter <= 0: return self.ctrl.deleteTextblkItemList(self.blk_list, self.pwidget_list) if self.sw_changed: self.sw.counter_sum = self.new_counter_sum cursor_removed = False for edit in self.search_rstedit_list: idx = self.sw.get_result_edit_index(edit) if idx != -1: self.sw.search_rstedit_list.pop(idx) self.sw.search_counter_list.pop(idx) self.sw.highlighter_list.pop(idx) if edit == self.sw.current_edit: cursor_removed = True if cursor_removed: if self.sw.counter_sum > 0: self.sw.setCurrentEditor(self.sw.search_rstedit_list[0]) else: Loading @@ -263,20 +274,10 @@ class DeleteBlkItemsCommand(QUndoCommand): self.ctrl.recoverTextblkItemList(self.blk_list, self.pwidget_list) if self.sw_changed: self.sw.counter_sum = self.old_counter_sum for edit in self.search_rstedit_list: self.sw.search_rstedit_list += self.search_rstedit_list self.sw.search_counter_list += self.search_counter_list self.sw.highlighter_list += self.highlighter_list if self.sw.counter_sum > 0: self.sw.setCurrentEditor(self.sw.search_rstedit_list[0]) else: self.sw.setCurrentEditor(None) def mergeWith(self, command: QUndoCommand): blk_list = command.blk_list if self.blk_list != blk_list: return False return True self.sw.updateCounterText() class AutoLayoutCommand(QUndoCommand): Loading ballontranslator/ui/search_replace_widgets.py +83 −12 Original line number Diff line number Diff line from qtpy.QtWidgets import QHBoxLayout, QComboBox, QTextEdit, QLabel, QTreeView, QPlainTextEdit, QCheckBox, QMessageBox, QVBoxLayout, QStyle, QSlider, QProxyStyle, QStyle, QGraphicsDropShadowEffect, QWidget from qtpy.QtWidgets import QHBoxLayout, QComboBox, QTextEdit, QLabel, QTreeView, QPlainTextEdit, QCheckBox, QMessageBox, QVBoxLayout, QStyle, QSlider, QStyle, QGraphicsDropShadowEffect, QWidget from qtpy.QtCore import Qt, QTimer, QPointF, QRect, Signal from qtpy.QtGui import QKeyEvent, QTextDocument, QTextCursor, QHideEvent, QInputMethodEvent, QFontMetrics, QColor, QShowEvent, QSyntaxHighlighter, QTextCharFormat try: Loading Loading @@ -34,14 +34,14 @@ class HighlightMatched(QSyntaxHighlighter): def setEditor(self, edit: SourceTextEdit): old_edit = self.edit if old_edit is not None: old_edit.high_lighting = True old_edit.highlighting = True if edit is not None: self.setDocument(edit.document()) else: self.setDocument(None) self.edit = edit if old_edit is not None: old_edit.high_lighting = False old_edit.highlighting = False def set_matched_map(self, matched_map: dict): self.matched_map = matched_map Loading @@ -53,10 +53,10 @@ class HighlightMatched(QSyntaxHighlighter): def rehighlight(self) -> None: if self.edit is not None: self.edit.high_lighting = True self.edit.highlighting = True super().rehighlight() if self.edit is not None: self.edit.high_lighting = False self.edit.highlighting = False def set_current_start(self, start: int): self.current_start = start Loading @@ -65,7 +65,7 @@ class HighlightMatched(QSyntaxHighlighter): def highlightBlock(self, text: str) -> None: if self.edit is None: return self.edit.high_lighting = True self.edit.highlighting = True fmt = QTextCharFormat() fmt.setBackground(HIGHLIGHT_COLOR) block = self.currentBlock() Loading @@ -87,7 +87,7 @@ class HighlightMatched(QSyntaxHighlighter): fmt.setBackground(CURRENT_TEXT_COLOR) self.setFormat(intersect_start, length, fmt) self.edit.high_lighting = False self.edit.highlighting = False Loading Loading @@ -632,7 +632,8 @@ class SearchWidget(Widget): self.highlight_current_text() def on_replaceall_btn_clicked(self): pass if self.counter_sum > 0: self.replace_all.emit() def on_replace_btn_clicked(self): if self.current_cursor is not None: Loading Loading @@ -687,7 +688,7 @@ class SearchWidget(Widget): class ReplaceOneCommand(QUndoCommand): def __init__(self, se: SearchWidget, parent=None): super(ReplaceOneCommand, self).__init__(parent) self.op_counter = -1 self.op_counter = 0 self.sw = se self.reptxt = self.sw.replace_editor.toPlainText() self.repl_len = len(self.reptxt) Loading Loading @@ -718,10 +719,11 @@ class ReplaceOneCommand(QUndoCommand): self.rep_cursor.setPosition(self.sel_start) self.rep_cursor.setPosition(self.sel_start+self.ori_len, QTextCursor.MoveMode.KeepAnchor) self.rep_cursor.insertText(self.reptxt) self.edit.updateUndoSteps() def redo(self): if self.op_counter == 0: self.op_counter += 1 if self.op_counter <= 0: return if self.sw.current_edit is not None and self.sw.isVisible(): Loading Loading @@ -751,4 +753,73 @@ class ReplaceOneCommand(QUndoCommand): self.edit.user_edited.emit() class ReplaceAllCommand(QUndoCommand): pass No newline at end of file def __init__(self, search_widget: SearchWidget) -> None: super().__init__() self.op_counter = 0 self.sw = search_widget self.rstedit_list: List[SourceTextEdit] = [] self.blkitem_list: List[TextBlkItem] = [] for edit in self.sw.search_rstedit_list: self.rstedit_list.append(edit) find_flag = self.sw.get_find_flag() text = self.sw.search_editor.toPlainText() replace = self.sw.replace_editor.toPlainText() for edit in self.rstedit_list: redo_blk = type(edit) == TransTextEdit if redo_blk: blkitem = self.sw.textblk_item_list[edit.idx] self.blkitem_list.append(blkitem) sel_list = [] doc = edit.document() cursor = edit.textCursor() cursor.clearSelection() cursor.setPosition(0) # cursor.beginEditBlock() counter = 0 while True: counter += 1 cursor: QTextCursor = doc.find(text, cursor, find_flag) if cursor.isNull(): break if redo_blk: sel_list.append([cursor.selectionStart(), cursor.selectionEnd()]) if counter > 1: cursor.joinPreviousEditBlock() cursor.insertText(replace) if counter > 1: cursor.endEditBlock() # cursor.endEditBlock() edit.updateUndoSteps() if redo_blk: cursor = blkitem.textCursor() cursor.beginEditBlock() for sel in sel_list: cursor.setPosition(sel[0]) cursor.setPosition(sel[1], QTextCursor.MoveMode.KeepAnchor) cursor.insertText(replace) cursor.endEditBlock() edit.show() def redo(self): if self.op_counter == 0: self.op_counter += 1 return for edit in self.rstedit_list: edit.redo() edit.update() for blkitem in self.blkitem_list: blkitem.document().redo() def undo(self): for edit in self.rstedit_list: edit.undo() edit.update() for blkitem in self.blkitem_list: blkitem.document().undo() No newline at end of file Loading
ballontranslator/ui/canvas.py +1 −0 Original line number Diff line number Diff line Loading @@ -514,4 +514,5 @@ class Canvas(QGraphicsScene): pass def on_search_replace_all(self): self.undoStack.push(ReplaceAllCommand(self.search_widget)) pass No newline at end of file
ballontranslator/ui/imgtranspanel.py +10 −15 Original line number Diff line number Diff line Loading @@ -13,7 +13,6 @@ from .textitem import TextBlock, TextBlkItem from .fontformatpanel import FontFormatPanel class SourceTextEdit(QTextEdit): hover_enter = Signal(int) hover_leave = Signal(int) Loading Loading @@ -44,7 +43,10 @@ class SourceTextEdit(QTextEdit): self.input_method_from = -1 self.input_method_text = '' self.text_content_changed = False self.high_lighting = False self.highlighting = False def updateUndoSteps(self): self.old_undo_steps = self.document().availableUndoSteps() def on_content_changing(self, from_: int, removed: int, added: int): if not self.pre_editing: Loading @@ -53,7 +55,6 @@ class SourceTextEdit(QTextEdit): self.change_from = from_ self.change_added = added def adjustSize(self): h = self.document().documentLayout().documentSize().toSize().height() self.setFixedHeight(max(h, 50)) Loading @@ -61,13 +62,12 @@ class SourceTextEdit(QTextEdit): def on_content_changed(self): if self.text_content_changed: self.text_content_changed = False if not self.high_lighting: if not self.highlighting: self.text_changed.emit() if self.hasFocus() and not self.pre_editing: self.user_edited.emit() if not self.in_redo_undo: change_from = self.change_from added_text = '' input_method_used = False Loading @@ -90,14 +90,12 @@ class SourceTextEdit(QTextEdit): added_text = cursor.selectedText() self.user_edited_verbose.emit(change_from, added_text, input_method_used) undo_steps = self.document().availableUndoSteps() new_steps = undo_steps - self.old_undo_steps if new_steps > 0: self.old_undo_steps = undo_steps self.push_undo_stack.emit(new_steps) def setHoverEffect(self, hover: bool): try: if hover: Loading Loading @@ -132,13 +130,12 @@ class SourceTextEdit(QTextEdit): return super().focusOutEvent(event) def inputMethodEvent(self, e: QInputMethodEvent) -> None: cursor = self.textCursor() if e.preeditString() == '': self.pre_editing = False self.input_method_text = e.commitString() else: if self.pre_editing is False: cursor = self.textCursor() self.input_method_from = cursor.selectionStart() self.pre_editing = True self.input_method_event = e Loading Loading @@ -168,9 +165,6 @@ class SourceTextEdit(QTextEdit): self.in_redo_undo = False self.old_undo_steps = self.document().availableUndoSteps() def block_all_signals(self, block: bool): self.blockSignals(block) self.document().blockSignals(block) class TransTextEdit(SourceTextEdit): pass Loading Loading @@ -239,7 +233,7 @@ class TextEditCommand(QUndoCommand): super().__init__() self.edit = edit self.blkitem = blkitem self.op_counter = -1 self.op_counter = 0 self.change_from = edit.change_from self.change_added = edit.change_added self.change_removed = edit.change_removed Loading @@ -250,9 +244,10 @@ class TextEditCommand(QUndoCommand): edit.input_method_from = -1 def redo(self): if self.op_counter == 0: self.op_counter += 1 if self.op_counter <= 0: return for _ in range(self.num_steps): self.edit.redo() self.blkitem.document().redo() Loading
ballontranslator/ui/scenetext_manager.py +23 −22 Original line number Diff line number Diff line Loading @@ -187,7 +187,7 @@ class CreateItemCommand(QUndoCommand): class DeleteBlkItemsCommand(QUndoCommand): def __init__(self, blk_list: List[TextBlkItem], ctrl, parent=None): super().__init__(parent) self.op_counter = -1 self.op_counter = 0 self.blk_list = [] self.pwidget_list: List[TransPairWidget] = [] self.ctrl: SceneTextManager = ctrl Loading Loading @@ -233,6 +233,13 @@ class DeleteBlkItemsCommand(QUndoCommand): self.new_counter_sum = self.sw.counter_sum if self.sw_changed: if self.sw.counter_sum > 0: idx = self.sw.get_result_edit_index(self.sw.current_edit) if self.sw.current_cursor is not None and idx != -1: self.sw.result_pos = self.sw.highlighter_list[idx].matched_map[self.sw.current_cursor.position()] if idx > 0: self.sw.result_pos += sum(self.sw.search_counter_list[: idx]) self.sw.updateCounterText() else: self.sw.setCurrentEditor(self.sw.search_rstedit_list[0]) else: self.sw.setCurrentEditor(None) Loading @@ -240,19 +247,23 @@ class DeleteBlkItemsCommand(QUndoCommand): self.ctrl.deleteTextblkItemList(self.blk_list, self.pwidget_list) def redo(self): if self.op_counter == 0: self.op_counter += 1 if self.op_counter <= 0: return self.ctrl.deleteTextblkItemList(self.blk_list, self.pwidget_list) if self.sw_changed: self.sw.counter_sum = self.new_counter_sum cursor_removed = False for edit in self.search_rstedit_list: idx = self.sw.get_result_edit_index(edit) if idx != -1: self.sw.search_rstedit_list.pop(idx) self.sw.search_counter_list.pop(idx) self.sw.highlighter_list.pop(idx) if edit == self.sw.current_edit: cursor_removed = True if cursor_removed: if self.sw.counter_sum > 0: self.sw.setCurrentEditor(self.sw.search_rstedit_list[0]) else: Loading @@ -263,20 +274,10 @@ class DeleteBlkItemsCommand(QUndoCommand): self.ctrl.recoverTextblkItemList(self.blk_list, self.pwidget_list) if self.sw_changed: self.sw.counter_sum = self.old_counter_sum for edit in self.search_rstedit_list: self.sw.search_rstedit_list += self.search_rstedit_list self.sw.search_counter_list += self.search_counter_list self.sw.highlighter_list += self.highlighter_list if self.sw.counter_sum > 0: self.sw.setCurrentEditor(self.sw.search_rstedit_list[0]) else: self.sw.setCurrentEditor(None) def mergeWith(self, command: QUndoCommand): blk_list = command.blk_list if self.blk_list != blk_list: return False return True self.sw.updateCounterText() class AutoLayoutCommand(QUndoCommand): Loading
ballontranslator/ui/search_replace_widgets.py +83 −12 Original line number Diff line number Diff line from qtpy.QtWidgets import QHBoxLayout, QComboBox, QTextEdit, QLabel, QTreeView, QPlainTextEdit, QCheckBox, QMessageBox, QVBoxLayout, QStyle, QSlider, QProxyStyle, QStyle, QGraphicsDropShadowEffect, QWidget from qtpy.QtWidgets import QHBoxLayout, QComboBox, QTextEdit, QLabel, QTreeView, QPlainTextEdit, QCheckBox, QMessageBox, QVBoxLayout, QStyle, QSlider, QStyle, QGraphicsDropShadowEffect, QWidget from qtpy.QtCore import Qt, QTimer, QPointF, QRect, Signal from qtpy.QtGui import QKeyEvent, QTextDocument, QTextCursor, QHideEvent, QInputMethodEvent, QFontMetrics, QColor, QShowEvent, QSyntaxHighlighter, QTextCharFormat try: Loading Loading @@ -34,14 +34,14 @@ class HighlightMatched(QSyntaxHighlighter): def setEditor(self, edit: SourceTextEdit): old_edit = self.edit if old_edit is not None: old_edit.high_lighting = True old_edit.highlighting = True if edit is not None: self.setDocument(edit.document()) else: self.setDocument(None) self.edit = edit if old_edit is not None: old_edit.high_lighting = False old_edit.highlighting = False def set_matched_map(self, matched_map: dict): self.matched_map = matched_map Loading @@ -53,10 +53,10 @@ class HighlightMatched(QSyntaxHighlighter): def rehighlight(self) -> None: if self.edit is not None: self.edit.high_lighting = True self.edit.highlighting = True super().rehighlight() if self.edit is not None: self.edit.high_lighting = False self.edit.highlighting = False def set_current_start(self, start: int): self.current_start = start Loading @@ -65,7 +65,7 @@ class HighlightMatched(QSyntaxHighlighter): def highlightBlock(self, text: str) -> None: if self.edit is None: return self.edit.high_lighting = True self.edit.highlighting = True fmt = QTextCharFormat() fmt.setBackground(HIGHLIGHT_COLOR) block = self.currentBlock() Loading @@ -87,7 +87,7 @@ class HighlightMatched(QSyntaxHighlighter): fmt.setBackground(CURRENT_TEXT_COLOR) self.setFormat(intersect_start, length, fmt) self.edit.high_lighting = False self.edit.highlighting = False Loading Loading @@ -632,7 +632,8 @@ class SearchWidget(Widget): self.highlight_current_text() def on_replaceall_btn_clicked(self): pass if self.counter_sum > 0: self.replace_all.emit() def on_replace_btn_clicked(self): if self.current_cursor is not None: Loading Loading @@ -687,7 +688,7 @@ class SearchWidget(Widget): class ReplaceOneCommand(QUndoCommand): def __init__(self, se: SearchWidget, parent=None): super(ReplaceOneCommand, self).__init__(parent) self.op_counter = -1 self.op_counter = 0 self.sw = se self.reptxt = self.sw.replace_editor.toPlainText() self.repl_len = len(self.reptxt) Loading Loading @@ -718,10 +719,11 @@ class ReplaceOneCommand(QUndoCommand): self.rep_cursor.setPosition(self.sel_start) self.rep_cursor.setPosition(self.sel_start+self.ori_len, QTextCursor.MoveMode.KeepAnchor) self.rep_cursor.insertText(self.reptxt) self.edit.updateUndoSteps() def redo(self): if self.op_counter == 0: self.op_counter += 1 if self.op_counter <= 0: return if self.sw.current_edit is not None and self.sw.isVisible(): Loading Loading @@ -751,4 +753,73 @@ class ReplaceOneCommand(QUndoCommand): self.edit.user_edited.emit() class ReplaceAllCommand(QUndoCommand): pass No newline at end of file def __init__(self, search_widget: SearchWidget) -> None: super().__init__() self.op_counter = 0 self.sw = search_widget self.rstedit_list: List[SourceTextEdit] = [] self.blkitem_list: List[TextBlkItem] = [] for edit in self.sw.search_rstedit_list: self.rstedit_list.append(edit) find_flag = self.sw.get_find_flag() text = self.sw.search_editor.toPlainText() replace = self.sw.replace_editor.toPlainText() for edit in self.rstedit_list: redo_blk = type(edit) == TransTextEdit if redo_blk: blkitem = self.sw.textblk_item_list[edit.idx] self.blkitem_list.append(blkitem) sel_list = [] doc = edit.document() cursor = edit.textCursor() cursor.clearSelection() cursor.setPosition(0) # cursor.beginEditBlock() counter = 0 while True: counter += 1 cursor: QTextCursor = doc.find(text, cursor, find_flag) if cursor.isNull(): break if redo_blk: sel_list.append([cursor.selectionStart(), cursor.selectionEnd()]) if counter > 1: cursor.joinPreviousEditBlock() cursor.insertText(replace) if counter > 1: cursor.endEditBlock() # cursor.endEditBlock() edit.updateUndoSteps() if redo_blk: cursor = blkitem.textCursor() cursor.beginEditBlock() for sel in sel_list: cursor.setPosition(sel[0]) cursor.setPosition(sel[1], QTextCursor.MoveMode.KeepAnchor) cursor.insertText(replace) cursor.endEditBlock() edit.show() def redo(self): if self.op_counter == 0: self.op_counter += 1 return for edit in self.rstedit_list: edit.redo() edit.update() for blkitem in self.blkitem_list: blkitem.document().redo() def undo(self): for edit in self.rstedit_list: edit.undo() edit.update() for blkitem in self.blkitem_list: blkitem.document().undo() No newline at end of file