def __init__(self, parent, num_rows, num_cols, popup_creator=None): grid.Grid.__init__(self, parent) self._bind_to_events() self.selection = _GridSelection(self) self.SetDefaultRenderer(grid.GridCellAutoWrapStringRenderer()) self._clipboard_handler = ClipboardHandler(self) self._history = _GridState() self.CreateGrid(num_rows, num_cols) self._popup_creator = popup_creator or PopupCreator()
def __init__(self): # Qt application self._app = QtWidgets.QApplication([sys.argv[0]]) # Translation engine (will be set by events) self._gtrans = GTransWeb() # Clipboard and its handler self._clipboard = Clipboard(self._app) self._clip_handler = ClipboardHandler(self._clipboard) self._clip_handler.set_callback(self._on_clip_changed) # Main window self._window = Window(self._translate, self._on_clipmode_changed, self._on_backendmode_changed, self._on_headless_changed, self._clipboard.get_mode_strs(), GTransWeb.BACKEND_MODES) # Buffer for selection mode self._select_buf = CallableBuffer() # Exit function should be call at exit atexit.register(self.exit)
class GridEditor(grid.Grid): _col_add_threshold = 1 _popup_items = ['Insert Cells\tCtrl-Shift-I', 'Delete Cells\tCtrl-Shift-D', '---', 'Select All\tCtrl-A', '---', 'Cut\tCtrl-X', 'Copy\tCtrl-C', 'Paste\tCtrl-V', 'Insert\tCtrl-Shift-V', '---', 'Delete\tDel'] def __init__(self, parent, num_rows, num_cols, popup_creator=None): grid.Grid.__init__(self, parent) self._bind_to_events() self.selection = _GridSelection(self) self.SetDefaultRenderer(grid.GridCellAutoWrapStringRenderer()) self._clipboard_handler = ClipboardHandler(self) self._history = _GridState() self.CreateGrid(num_rows, num_cols) self._popup_creator = popup_creator or PopupCreator() def _bind_to_events(self): self.Bind(grid.EVT_GRID_SELECT_CELL, self.OnSelectCell) self.Bind(grid.EVT_GRID_RANGE_SELECT, self.OnRangeSelect) self.Bind(grid.EVT_GRID_CELL_RIGHT_CLICK, self.OnCellRightClick) def register_context_menu_hook(self, callable): self._popup_creator.add_hook(callable) def unregister_context_menu_hook(self, callable): self._popup_creator.remove_hook(callable) def write_cell(self, row, col, value, update_history=True): if update_history: self._update_history() self._expand_if_necessary(row, col) self.SetCellValue(row, col, value) def _expand_if_necessary(self, row, col): while row >= self.NumberRows - 1: self.AppendRows(1) while col >= self.NumberCols - self._col_add_threshold: self.AppendCols(1) def has_focus(self): return self.FindFocus() == self.GridWindow def _update_history(self): self._history.change(self._get_all_content()) def _get_all_content(self): return self._get_block_content(range(self.NumberRows), range(self.NumberCols)) @property def cell_under_cursor(self): x, y = self.ScreenToClient(wx.GetMousePosition()) x -= self.RowLabelSize return self.XYToCell(*self.CalcUnscrolledPosition(x, y)) def select(self, row, column): self.SelectBlock(row, column, row, column) self.SetGridCursor(row, column) self.MakeCellVisible(row, column) def copy(self): self._clipboard_handler.copy() def cut(self): self._update_history() self._clipboard_handler.cut() self._clear_selected_cells() def _clear_selected_cells(self): for row, col in self.selection.cells(): self.write_cell(row, col, '', update_history=False) def paste(self): self._update_history() self._clipboard_handler.paste() def delete(self): self._update_history() if self.IsCellEditControlShown(): if IS_WINDOWS: self._delete_from_cell_editor() else: self._clear_selected_cells() def _delete_from_cell_editor(self): editor = self.get_cell_edit_control() start, end = editor.Selection if start == end: end += 1 editor.Remove(start, end) def _is_whole_row_selection(self): return self.SelectedRows def get_cell_edit_control(self): return self.GetCellEditor(*self.selection.cell).GetControl() def get_selected_content(self): return self._get_block_content(self.selection.rows(), self.selection.cols()) def get_single_selection_content(self): cells = self.get_selected_content() if len(cells) != 1 or len(cells[0]) != 1: return None return cells[0][0] def _current_cell_value(self): return self.GetCellValue(*self.selection.cell) def _get_block_content(self, row_range, col_range): return [[self.GetCellValue(row, col) for col in col_range] for row in row_range] def _strip_trailing_empty_cells(self, rowdata): while rowdata and not rowdata[-1]: rowdata.pop() return rowdata def undo(self): prev_data = self._history.back() if prev_data: self.ClearGrid() self._write_data(prev_data, update_history=False) def _write_data(self, data, update_history=True): for row_index, row_data in enumerate(data): for col_index, cell_value in enumerate(row_data): self.write_cell(row_index, col_index, cell_value, update_history) self.AutoSizeColumns() self.AutoSizeRows() def OnSelectCell(self, event): if self._is_whole_row_selection(): self.SelectBlock(self.selection.topleft.row, self.selection.topleft.col,self.selection.bottomright.row, self.selection.bottomright.col, addToSelected=True) else: self.selection.set_from_single_selection(event) self.AutoSizeRows() event.Skip() def OnRangeSelect(self, event): if not event.Selecting(): self.selection.clear() return if event.ControlDown(): self.SetGridCursor(event.TopRow, event.LeftCol) self.SelectBlock(event.TopRow, event.LeftCol, event.BottomRow, event.RightCol, addToSelected=False) else: self.selection.set_from_range_selection(self, event) self._ensure_selected_row_is_visible(event.BottomRow) def _ensure_selected_row_is_visible(self, bottom_row): if not self.IsVisible(bottom_row , 0) and bottom_row < self.NumberRows and self._is_whole_row_selection(): self.MakeCellVisible(bottom_row, 0) def OnCellRightClick(self, event): if hasattr(event, 'Row') and hasattr(event, 'Col'): if not (event.Row, event.Col) in self.selection.cells(): self.select(event.Row, event.Col) self.selection.set_from_single_selection(event) self._popup_creator.show(self, PopupMenuItems(self, self._popup_items), self.get_selected_content()) def OnInsertCells(self, event): self._insert_or_delete_cells(self._insert_cells, event) def OnDeleteCells(self, event): self._insert_or_delete_cells(self._delete_cells, event) def _insert_or_delete_cells(self, action, event): self._update_history() for index in self.selection.rows(): data = action(self._row_data(index)) self._write_row(index, data) self._refresh_layout() event.Skip() def _insert_cells(self, data): cols = self.selection.cols() left = right = cols[0] data[left:right] = [''] * len(cols) return self._strip_trailing_empty_cells(data) def _delete_cells(self, data): cols = self.selection.cols() left, right = cols[0], cols[-1] + 1 data[left:right] = [] return data + [''] * len(cols) def _row_data(self, row): return [self.GetCellValue(row, col) for col in range(self.NumberCols)] def _write_row(self, row, data): for col, value in enumerate(data): self.write_cell(row, col, value, update_history=False) def _refresh_layout(self): self.SetFocus() self.SetGridCursor(*self.selection.cell) self.GetParent().Sizer.Layout()
class GridEditor(grid.Grid): _col_add_threshold = 1 _popup_items = [ 'Insert Cells\tCtrl-Shift-I', 'Delete Cells\tCtrl-Shift-D', 'Insert Rows\tCtrl-I', 'Delete Rows\tCtrl-D', '---', 'Select All\tCtrl-A', '---', 'Cut\tCtrl-X', 'Copy\tCtrl-C', 'Paste\tCtrl-V', 'Insert\tCtrl-Shift-V', '---', 'Delete\tDel' ] def __init__(self, parent, num_rows, num_cols, popup_creator=None): grid.Grid.__init__(self, parent) self._bind_to_events() self.selection = _GridSelection(self) self.SetDefaultRenderer(grid.GridCellAutoWrapStringRenderer()) self._clipboard_handler = ClipboardHandler(self) self._history = _GridState() self.CreateGrid(num_rows, num_cols) self._popup_creator = popup_creator or PopupCreator() def _bind_to_events(self): self.Bind(grid.EVT_GRID_SELECT_CELL, self.OnSelectCell) self.Bind(grid.EVT_GRID_RANGE_SELECT, self.OnRangeSelect) self.Bind(grid.EVT_GRID_CELL_RIGHT_CLICK, self.OnCellRightClick) def register_context_menu_hook(self, callable): self._popup_creator.add_hook(callable) def unregister_context_menu_hook(self, callable): self._popup_creator.remove_hook(callable) def write_cell(self, row, col, value, update_history=True): if update_history: self._update_history() self._expand_if_necessary(row, col) self.SetCellValue(row, col, value) def _expand_if_necessary(self, row, col): while row >= self.NumberRows - 1: self.AppendRows(1) while col >= self.NumberCols - self._col_add_threshold: self.AppendCols(1) def has_focus(self): return self.FindFocus() == self.GridWindow def _update_history(self): self._history.change(self._get_all_content()) def _get_all_content(self): return self._get_block_content(range(self.NumberRows), range(self.NumberCols)) @property def cell_under_cursor(self): x, y = self.ScreenToClient(wx.GetMousePosition()) x -= self.RowLabelSize return self.XYToCell(*self.CalcUnscrolledPosition(x, y)) def select(self, row, column): self.SelectBlock(row, column, row, column) self.SetGridCursor(row, column) self.MakeCellVisible(row, column) def copy(self): self._clipboard_handler.copy() def cut(self): self._update_history() self._clipboard_handler.cut() self._clear_selected_cells() def _clear_selected_cells(self): for row, col in self.selection.cells(): self.write_cell(row, col, '', update_history=False) def paste(self): self._update_history() self._clipboard_handler.paste() def delete(self): self._update_history() if self.IsCellEditControlShown(): if IS_WINDOWS: self._delete_from_cell_editor() else: self._clear_selected_cells() def _delete_from_cell_editor(self): editor = self.get_cell_edit_control() start, end = editor.Selection if start == end: end += 1 editor.Remove(start, end) def _is_whole_row_selection(self): return self.SelectedRows def get_cell_edit_control(self): return self.GetCellEditor(*self.selection.cell).GetControl() def get_selected_content(self): return self._get_block_content(self.selection.rows(), self.selection.cols()) def get_single_selection_content(self): cells = self.get_selected_content() if len(cells) != 1 or len(cells[0]) != 1: return None return cells[0][0] def _current_cell_value(self): return self.GetCellValue(*self.selection.cell) def _get_block_content(self, row_range, col_range): return [[self.GetCellValue(row, col) for col in col_range] for row in row_range] def _strip_trailing_empty_cells(self, rowdata): while rowdata and not rowdata[-1]: rowdata.pop() return rowdata def undo(self): prev_data = self._history.back() if prev_data: self.ClearGrid() self._write_data(prev_data, update_history=False) def _write_data(self, data, update_history=True): for row_index, row_data in enumerate(data): for col_index, cell_value in enumerate(row_data): self.write_cell(row_index, col_index, cell_value, update_history) self.AutoSizeColumns() self.AutoSizeRows() def OnSelectCell(self, event): if self._is_whole_row_selection(): self.SelectBlock(self.selection.topleft.row, self.selection.topleft.col, self.selection.bottomright.row, self.selection.bottomright.col, addToSelected=True) else: self.selection.set_from_single_selection(event) self.AutoSizeRows() event.Skip() def OnRangeSelect(self, event): if not event.Selecting(): self.selection.clear() return if event.ControlDown(): self.SetGridCursor(event.TopRow, event.LeftCol) self.SelectBlock(event.TopRow, event.LeftCol, event.BottomRow, event.RightCol, addToSelected=False) else: self.selection.set_from_range_selection(self, event) self._ensure_selected_row_is_visible(event.BottomRow) def _ensure_selected_row_is_visible(self, bottom_row): if not self.IsVisible( bottom_row, 0 ) and bottom_row < self.NumberRows and self._is_whole_row_selection(): self.MakeCellVisible(bottom_row, 0) def OnCellRightClick(self, event): if hasattr(event, 'Row') and hasattr(event, 'Col'): if not (event.Row, event.Col) in self.selection.cells(): self.select(event.Row, event.Col) self.selection.set_from_single_selection(event) self._popup_creator.show(self, PopupMenuItems(self, self._popup_items), self.get_selected_content()) def OnInsertCells(self, event): self._insert_or_delete_cells(self._insert_cells, event) def OnDeleteCells(self, event): self._insert_or_delete_cells(self._delete_cells, event) def _insert_or_delete_cells(self, action, event): self._update_history() for index in self.selection.rows(): data = action(self._row_data(index)) self._write_row(index, data) self._refresh_layout() event.Skip() def _insert_cells(self, data): cols = self.selection.cols() left = right = cols[0] data[left:right] = [''] * len(cols) return self._strip_trailing_empty_cells(data) def _delete_cells(self, data): cols = self.selection.cols() left, right = cols[0], cols[-1] + 1 data[left:right] = [] return data + [''] * len(cols) def _row_data(self, row): return [self.GetCellValue(row, col) for col in range(self.NumberCols)] def _write_row(self, row, data): for col, value in enumerate(data): self.write_cell(row, col, value, update_history=False) def _refresh_layout(self): self.SetFocus() self.SetGridCursor(*self.selection.cell) self.GetParent().Sizer.Layout()
class GTransWebGui(object): def __init__(self): # Qt application self._app = QtWidgets.QApplication([sys.argv[0]]) # Translation engine (will be set by events) self._gtrans = GTransWeb() # Clipboard and its handler self._clipboard = Clipboard(self._app) self._clip_handler = ClipboardHandler(self._clipboard) self._clip_handler.set_callback(self._on_clip_changed) # Main window self._window = Window(self._translate, self._on_clipmode_changed, self._on_backendmode_changed, self._on_headless_changed, self._clipboard.get_mode_strs(), GTransWeb.BACKEND_MODES) # Buffer for selection mode self._select_buf = CallableBuffer() # Exit function should be call at exit atexit.register(self.exit) def run(self): ''' Run main application ''' self._app.exec_() def exit(self): ''' Exit application ''' self._gtrans.exit() def _translate(self, src_text=None): ''' Translate passed text. If not passed, it will be get from GUI. ''' # Get languages from GUI src_lang, tgt_lang = self._window.get_langs() # Source text if src_text is None: # Get text from GUI src_text = self._window.get_src_text() else: # Set text to GUI self._window.set_src_text(src_text) # Start translation tgt_text = self._gtrans.translate(src_lang, tgt_lang, src_text) # Set to GUI self._window.set_tgt_text(tgt_text) # Set to clipboard if self._window.get_overwrite(): self._clip_handler.overwrite_clip(tgt_text) def _on_clip_changed(self, src_text): ''' When clipboard changed, start to translate. ''' if self._clipboard.get_mode_str() == 'select': # Postpone by buffering self._select_buf(self._translate, src_text) else: # Translate right now self._translate(src_text) def _on_clipmode_changed(self, mode_str): ''' When GUI changed, connect to clipboard''' self._clipboard.set_mode(mode_str) def _on_backendmode_changed(self, mode_str): ''' When GUI changed, connect to gtrans ''' # Restart browser self._gtrans.exit() headless = self._gtrans.is_headless() self._gtrans = GTransWeb(backend_mode=mode_str, headless=headless) def _on_headless_changed(self, checked): ''' When GUI changed, connect to gtrans ''' checked = bool(checked) # Restart browser self._gtrans.exit() backend = self._gtrans.get_backend_mode() self._gtrans = GTransWeb(backend_mode=backend, headless=checked)