def sync_selection(self): """Push selection into the selection model.""" staged = [] unmerged = [] modified = [] untracked = [] state = State(staged, unmerged, modified, untracked) paths = self.selected_paths() model = main.model() model_staged = utils.add_parents(model.staged) model_modified = utils.add_parents(model.modified) model_unmerged = utils.add_parents(model.unmerged) model_untracked = utils.add_parents(model.untracked) for path in paths: if path in model_unmerged: unmerged.append(path) elif path in model_untracked: untracked.append(path) elif path in model_staged: staged.append(path) elif path in model_modified: modified.append(path) else: staged.append(path) # Push the new selection into the model. selection_model().set_selection(state) return paths
def sync_selection(self): """Push selection into the selection model.""" staged = [] unmerged = [] modified = [] untracked = [] state = State(staged, unmerged, modified, untracked) paths = self.selected_paths() model = main.model() model_staged = utils.add_parents(set(model.staged)) model_modified = utils.add_parents(set(model.modified)) model_unmerged = utils.add_parents(set(model.unmerged)) model_untracked = utils.add_parents(set(model.untracked)) for path in paths: if path in model_unmerged: unmerged.append(path) elif path in model_untracked: untracked.append(path) elif path in model_staged: staged.append(path) elif path in model_modified: modified.append(path) else: staged.append(path) # Push the new selection into the model. selection_model().set_selection(state) return paths
def show_selection(self): """Show the selected item.""" # Sync the selection model selection.selection_model().set_selection(self.selection()) selected_indexes = self.selected_indexes() if not selected_indexes: if self.m.amending(): cmds.do(cmds.SetDiffText, '') else: cmds.do(cmds.ResetMode) return category, idx = selected_indexes[0] # A header item e.g. 'Staged', 'Modified', etc. if category == self.idx_header: cls = { self.idx_staged: cmds.DiffStagedSummary, self.idx_modified: cmds.Diffstat, # TODO implement UnmergedSummary #self.idx_unmerged: cmds.UnmergedSummary, self.idx_untracked: cmds.UntrackedSummary, }.get(idx, cmds.Diffstat) cmds.do(cls) # A staged file elif category == self.idx_staged: cmds.do(cmds.DiffStaged, self.staged()) # A modified file elif category == self.idx_modified: cmds.do(cmds.Diff, self.modified()) elif category == self.idx_unmerged: cmds.do(cmds.Diff, self.unmerged()) elif category == self.idx_untracked: cmds.do(cmds.ShowUntracked, self.unstaged())
def process_diff_selection(self, reverse=False, apply_to_worktree=False): """Implement un/staging of the selected line(s) or hunk.""" if selection.selection_model().is_empty(): return first_line_idx, last_line_idx = self.selected_lines() cmds.do(cmds.ApplyDiffSelection, first_line_idx, last_line_idx, self.has_selection(), reverse, apply_to_worktree)
def process_diff_selection(self, staged=True, apply_to_worktree=False): """Implement un/staging of selected lines or sections.""" if selection.selection_model().is_empty(): return offset, selection_text = self.offset_and_selection() cmds.do(cmds.ApplyDiffSelection, staged, offset, selection_text, apply_to_worktree)
def unstage(self): """Unstage selected files, or all files if no selection exists.""" paths = selection_model().staged if not paths: cmds.do(cmds.UnstageAll) else: cmds.do(cmds.Unstage, paths)
def stage(self): """Stage selected files, or all files if no selection exists.""" paths = selection_model().unstaged if not paths: cmds.do(cmds.StageModified) else: cmds.do(cmds.Stage, paths)
def _update_files(self, update_index=False): display_untracked = prefs.display_untracked() state = gitcmds.worktree_state_dict(head=self.head, update_index=update_index, display_untracked=display_untracked) self.staged = state.get('staged', []) self.modified = state.get('modified', []) self.unmerged = state.get('unmerged', []) self.untracked = state.get('untracked', []) self.submodules = state.get('submodules', set()) self.upstream_changed = state.get('upstream_changed', []) sel = selection_model() if self.is_empty(): sel.reset() else: sel.update(self) if selection_model().is_empty(): self.set_diff_text('')
def _create_unstaged_context_menu(self, menu, s): modified_submodule = (s.modified and s.modified[0] in self.m.submodules) if modified_submodule: return self._create_modified_submodule_context_menu(menu, s) if self.m.stageable(): action = menu.addAction(qtutils.add_icon(), N_('Stage Selected'), cmds.run(cmds.Stage, self.unstaged())) action.setShortcut(hotkeys.STAGE_SELECTION) # Do all of the selected items exist? all_exist = all(not i in self.m.unstaged_deleted and core.exists(i) for i in self.staged()) if all_exist and self.unstaged(): menu.addAction(self.launch_editor_action) if all_exist and s.modified and self.m.stageable(): menu.addAction(self.launch_difftool_action) if s.modified and self.m.stageable(): if self.m.undoable(): menu.addSeparator() menu.addAction(self.revert_unstaged_edits_action) if all_exist and self.unstaged() and not utils.is_win32(): menu.addSeparator() action = menu.addAction(qtutils.file_icon(), cmds.OpenDefaultApp.name(), cmds.run(cmds.OpenDefaultApp, self.unstaged())) action.setShortcut(hotkeys.PRIMARY_ACTION) action = menu.addAction(qtutils.open_file_icon(), cmds.OpenParentDir.name(), self._open_parent_dir) action.setShortcut(hotkeys.SECONDARY_ACTION) if all_exist and s.untracked: menu.addSeparator() if self.move_to_trash_action is not None: menu.addAction(self.move_to_trash_action) menu.addAction(self.delete_untracked_files_action) menu.addSeparator() menu.addAction(qtutils.theme_icon('edit-clear.svg'), N_('Add to .gitignore'), cmds.run(cmds.Ignore, map(lambda x: '/' + x, self.untracked()))) menu.addSeparator() menu.addAction(self.copy_path_action) menu.addAction(self.copy_relpath_action) if not selection.selection_model().is_empty(): menu.addAction(self.view_history_action) return menu
def _create_unstaged_context_menu(self, menu, s): modified_submodule = (s.modified and s.modified[0] in self.m.submodules) if modified_submodule: return self._create_modified_submodule_context_menu(menu, s) if self.m.stageable(): action = menu.addAction(icons.add(), N_('Stage Selected'), cmds.run(cmds.Stage, self.unstaged())) action.setShortcut(hotkeys.STAGE_SELECTION) # Do all of the selected items exist? all_exist = all(i not in self.m.unstaged_deleted and core.exists(i) for i in self.staged()) if all_exist and self.unstaged(): menu.addAction(self.launch_editor_action) if all_exist and s.modified and self.m.stageable(): menu.addAction(self.launch_difftool_action) if s.modified and self.m.stageable(): if self.m.undoable(): menu.addSeparator() menu.addAction(self.revert_unstaged_edits_action) if all_exist and self.unstaged() and not utils.is_win32(): menu.addSeparator() open_default = cmds.run(cmds.OpenDefaultApp, self.unstaged()) action = menu.addAction(icons.default_app(), cmds.OpenDefaultApp.name(), open_default) action.setShortcut(hotkeys.PRIMARY_ACTION) action = menu.addAction(icons.folder(), cmds.OpenParentDir.name(), self._open_parent_dir) action.setShortcut(hotkeys.SECONDARY_ACTION) if all_exist and s.untracked: menu.addSeparator() if self.move_to_trash_action is not None: menu.addAction(self.move_to_trash_action) menu.addAction(self.delete_untracked_files_action) menu.addSeparator() menu.addAction(icons.edit(), N_('Add to .gitignore'), cmds.run(cmds.Ignore, [('/' + x) for x in self.untracked()])) menu.addSeparator() menu.addAction(self.copy_path_action) menu.addAction(self.copy_relpath_action) if not selection.selection_model().is_empty(): menu.addAction(self.view_history_action) menu.addAction(self.view_blame_action) return menu
def view_history(self): """Signal that we should view history for paths.""" cmds.do(cmds.VisualizePaths, selection.union(selection.selection_model()))
def view_blame(self): """Signal that we should view blame for paths.""" cmds.do(cmds.BlamePaths, selection.union(selection.selection_model()))
def copy_path(self): """Copy a selected path to the clipboard""" filename = selection.selection_model().filename() if filename is not None: curdir = os.getcwdu() qtutils.set_clipboard(os.path.join(curdir, filename))
def __init__(self): Unstage.__init__(self, selection.selection_model().staged)
def __init__(self, parent, titlebar): DiffTextEdit.__init__(self, parent) self.model = model = main.model() # "Diff Options" tool menu self.diff_ignore_space_at_eol_action = add_action( self, N_('Ignore changes in whitespace at EOL'), self._update_diff_opts) self.diff_ignore_space_at_eol_action.setCheckable(True) self.diff_ignore_space_change_action = add_action( self, N_('Ignore changes in amount of whitespace'), self._update_diff_opts) self.diff_ignore_space_change_action.setCheckable(True) self.diff_ignore_all_space_action = add_action( self, N_('Ignore all whitespace'), self._update_diff_opts) self.diff_ignore_all_space_action.setCheckable(True) self.diff_function_context_action = add_action( self, N_('Show whole surrounding functions of changes'), self._update_diff_opts) self.diff_function_context_action.setCheckable(True) self.diffopts_button = create_action_button(tooltip=N_('Diff Options'), icon=icons.configure()) self.diffopts_menu = create_menu(N_('Diff Options'), self.diffopts_button) self.diffopts_menu.addAction(self.diff_ignore_space_at_eol_action) self.diffopts_menu.addAction(self.diff_ignore_space_change_action) self.diffopts_menu.addAction(self.diff_ignore_all_space_action) self.diffopts_menu.addAction(self.diff_function_context_action) self.diffopts_button.setMenu(self.diffopts_menu) qtutils.hide_button_menu_indicator(self.diffopts_button) titlebar.add_corner_widget(self.diffopts_button) self.action_apply_selection = qtutils.add_action( self, 'Apply', self.apply_selection, hotkeys.STAGE_DIFF) self.action_revert_selection = qtutils.add_action( self, 'Revert', self.revert_selection, hotkeys.REVERT) self.action_revert_selection.setIcon(icons.undo()) self.launch_editor = actions.launch_editor(self, 'Return', 'Enter') self.launch_difftool = actions.launch_difftool(self) self.stage_or_unstage = actions.stage_or_unstage(self) # Emit up/down signals so that they can be routed by the main widget self.move_down = actions.move_down(self) self.move_up = actions.move_up(self) model.add_observer(model.message_diff_text_changed, self._emit_text) self.selection_model = selection_model = selection.selection_model() selection_model.add_observer(selection_model.message_selection_changed, self._update) self.connect(self, SIGNAL('update()'), self._update_callback, Qt.QueuedConnection) self.connect(self, SIGNAL('set_text(PyQt_PyObject)'), self.setPlainText)
def copy_path(self): """Copy a selected path to the clipboard""" filename = selection.selection_model().filename() qtutils.copy_path(filename)
def __init__(self, parent, titlebar): DiffTextEdit.__init__(self, parent) self.model = model = main.model() # "Diff Options" tool menu self.diff_ignore_space_at_eol_action = add_action( self, N_('Ignore changes in whitespace at EOL'), self._update_diff_opts) self.diff_ignore_space_at_eol_action.setCheckable(True) self.diff_ignore_space_change_action = add_action( self, N_('Ignore changes in amount of whitespace'), self._update_diff_opts) self.diff_ignore_space_change_action.setCheckable(True) self.diff_ignore_all_space_action = add_action( self, N_('Ignore all whitespace'), self._update_diff_opts) self.diff_ignore_all_space_action.setCheckable(True) self.diff_function_context_action = add_action( self, N_('Show whole surrounding functions of changes'), self._update_diff_opts) self.diff_function_context_action.setCheckable(True) self.diffopts_button = create_action_button( tooltip=N_('Diff Options'), icon=icons.configure()) self.diffopts_menu = create_menu(N_('Diff Options'), self.diffopts_button) self.diffopts_menu.addAction(self.diff_ignore_space_at_eol_action) self.diffopts_menu.addAction(self.diff_ignore_space_change_action) self.diffopts_menu.addAction(self.diff_ignore_all_space_action) self.diffopts_menu.addAction(self.diff_function_context_action) self.diffopts_button.setMenu(self.diffopts_menu) qtutils.hide_button_menu_indicator(self.diffopts_button) titlebar.add_corner_widget(self.diffopts_button) self.action_apply_selection = qtutils.add_action( self, 'Apply', self.apply_selection, hotkeys.STAGE_DIFF) self.action_revert_selection = qtutils.add_action( self, 'Revert', self.revert_selection, hotkeys.REVERT) self.action_revert_selection.setIcon(icons.undo()) self.launch_editor = actions.launch_editor(self, 'Return', 'Enter') self.launch_difftool = actions.launch_difftool(self) self.stage_or_unstage = actions.stage_or_unstage(self) # Emit up/down signals so that they can be routed by the main widget self.move_down = actions.move_down(self) self.move_up = actions.move_up(self) model.add_observer(model.message_diff_text_changed, self._emit_text) self.selection_model = selection_model = selection.selection_model() selection_model.add_observer(selection_model.message_selection_changed, self._update) self.connect(self, SIGNAL('update()'), self._update_callback, Qt.QueuedConnection) self.connect(self, SIGNAL('set_text(PyQt_PyObject)'), self.setPlainText)
def copy_path(self, absolute=True): """Copy a selected path to the clipboard""" filename = selection.selection_model().filename() qtutils.copy_path(filename, absolute=absolute)
def __init__(self, model, parent): QtGui.QWidget.__init__(self, parent) self.model = model self.spellcheck_initialized = False self._linebreak = None self._textwidth = None self._tabwidth = None # Actions self.signoff_action = qtutils.add_action(self, cmds.SignOff.name(), cmds.run(cmds.SignOff), hotkeys.SIGNOFF) self.signoff_action.setToolTip(N_('Sign off on this commit')) self.commit_action = qtutils.add_action(self, N_('Commit@@verb'), self.commit, hotkeys.COMMIT) self.commit_action.setToolTip(N_('Commit staged changes')) self.clear_action = qtutils.add_action(self, N_('Clear...'), self.clear) self.launch_editor = actions.launch_editor(self) self.launch_difftool = actions.launch_difftool(self) self.stage_or_unstage = actions.stage_or_unstage(self) self.move_up = actions.move_up(self) self.move_down = actions.move_down(self) # Widgets self.summary = CommitSummaryLineEdit() self.summary.setMinimumHeight(defs.tool_button_height) self.summary.extra_actions.append(self.clear_action) self.summary.extra_actions.append(None) self.summary.extra_actions.append(self.signoff_action) self.summary.extra_actions.append(self.commit_action) self.summary.extra_actions.append(None) self.summary.extra_actions.append(self.launch_editor) self.summary.extra_actions.append(self.launch_difftool) self.summary.extra_actions.append(self.stage_or_unstage) self.summary.extra_actions.append(None) self.summary.extra_actions.append(self.move_up) self.summary.extra_actions.append(self.move_down) self.description = CommitMessageTextEdit() self.description.extra_actions.append(self.clear_action) self.description.extra_actions.append(None) self.description.extra_actions.append(self.signoff_action) self.description.extra_actions.append(self.commit_action) self.description.extra_actions.append(None) self.description.extra_actions.append(self.launch_editor) self.description.extra_actions.append(self.launch_difftool) self.description.extra_actions.append(self.stage_or_unstage) self.description.extra_actions.append(None) self.description.extra_actions.append(self.move_up) self.description.extra_actions.append(self.move_down) commit_button_tooltip = N_('Commit staged changes\n' 'Shortcut: Ctrl+Enter') self.commit_button = qtutils.create_toolbutton( text=N_('Commit@@verb'), tooltip=commit_button_tooltip, icon=icons.download()) self.commit_group = Group(self.commit_action, self.commit_button) self.actions_menu = qtutils.create_menu(N_('Actions'), self) self.actions_button = qtutils.create_toolbutton( icon=icons.configure(), tooltip=N_('Actions...')) self.actions_button.setMenu(self.actions_menu) self.actions_button.setPopupMode(QtGui.QToolButton.InstantPopup) qtutils.hide_button_menu_indicator(self.actions_button) self.actions_menu.addAction(self.signoff_action) self.actions_menu.addAction(self.commit_action) self.actions_menu.addSeparator() # Amend checkbox self.amend_action = self.actions_menu.addAction( N_('Amend Last Commit')) self.amend_action.setCheckable(True) self.amend_action.setShortcut(hotkeys.AMEND) self.amend_action.setShortcutContext(Qt.ApplicationShortcut) # Bypass hooks self.bypass_commit_hooks_action = self.actions_menu.addAction( N_('Bypass Commit Hooks')) self.bypass_commit_hooks_action.setCheckable(True) self.bypass_commit_hooks_action.setChecked(False) # Sign commits cfg = gitcfg.current() self.sign_action = self.actions_menu.addAction( N_('Create Signed Commit')) self.sign_action.setCheckable(True) self.sign_action.setChecked(cfg.get('cola.signcommits', False)) # Spell checker self.check_spelling_action = self.actions_menu.addAction( N_('Check Spelling')) self.check_spelling_action.setCheckable(True) self.check_spelling_action.setChecked(False) # Line wrapping self.autowrap_action = self.actions_menu.addAction( N_('Auto-Wrap Lines')) self.autowrap_action.setCheckable(True) self.autowrap_action.setChecked(prefs.linebreak()) # Commit message self.actions_menu.addSeparator() self.load_commitmsg_menu = self.actions_menu.addMenu( N_('Load Previous Commit Message')) self.connect(self.load_commitmsg_menu, SIGNAL('aboutToShow()'), self.build_commitmsg_menu) self.fixup_commit_menu = self.actions_menu.addMenu( N_('Fixup Previous Commit')) self.connect(self.fixup_commit_menu, SIGNAL('aboutToShow()'), self.build_fixup_menu) self.toplayout = qtutils.hbox(defs.no_margin, defs.spacing, self.actions_button, self.summary, self.commit_button) self.toplayout.setContentsMargins(defs.margin, defs.no_margin, defs.no_margin, defs.no_margin) self.mainlayout = qtutils.vbox(defs.no_margin, defs.spacing, self.toplayout, self.description) self.setLayout(self.mainlayout) qtutils.connect_button(self.commit_button, self.commit) # Broadcast the amend mode qtutils.connect_action_bool(self.amend_action, cmds.run(cmds.AmendMode)) qtutils.connect_action_bool(self.check_spelling_action, self.toggle_check_spelling) # Handle the one-off autowrapping qtutils.connect_action_bool(self.autowrap_action, self.set_linebreak) qtutils.add_action(self.summary, N_('Move Down'), self.focus_description, *hotkeys.ACCEPT) qtutils.add_action(self.summary, N_('Move Down'), self.summary_cursor_down, hotkeys.DOWN) self.selection_model = selection_model = selection.selection_model() selection_model.add_observer(selection_model.message_selection_changed, self._update) self.model.add_observer(self.model.message_commit_message_changed, self._set_commit_message) self.connect(self, SIGNAL('set_commit_message(PyQt_PyObject)'), self.set_commit_message, Qt.QueuedConnection) self.connect(self.summary, SIGNAL('cursorPosition(int,int)'), self.emit_position) self.connect(self.description, SIGNAL('cursorPosition(int,int)'), # description starts at line 2 lambda row, col: self.emit_position(row + 2, col)) # Keep model informed of changes self.connect(self.summary, SIGNAL('textChanged(QString)'), self.commit_summary_changed) self.connect(self.description, SIGNAL('textChanged()'), self.commit_message_changed) self.connect(self.description, SIGNAL('leave()'), self.focus_summary) self.connect(self, SIGNAL('update()'), self._update_callback, Qt.QueuedConnection) self.setFont(qtutils.diff_font()) self.summary.hint.enable(True) self.description.hint.enable(True) self.commit_group.setEnabled(False) self.setFocusProxy(self.summary) self.set_tabwidth(prefs.tabwidth()) self.set_textwidth(prefs.textwidth()) self.set_linebreak(prefs.linebreak()) # Loading message commit_msg = '' commit_msg_path = commit_message_path() if commit_msg_path: commit_msg = core.read(commit_msg_path) self.set_commit_message(commit_msg) # Allow tab to jump from the summary to the description self.setTabOrder(self.summary, self.description)
def __init__(self, model, parent): QtGui.QWidget.__init__(self, parent) self.model = model self.spellcheck_initialized = False self._linebreak = None self._textwidth = None self._tabwidth = None # Actions self.signoff_action = qtutils.add_action(self, cmds.SignOff.name(), cmds.run(cmds.SignOff), hotkeys.SIGNOFF) self.signoff_action.setToolTip(N_('Sign off on this commit')) self.commit_action = qtutils.add_action(self, N_('Commit@@verb'), self.commit, hotkeys.COMMIT) self.commit_action.setToolTip(N_('Commit staged changes')) self.clear_action = qtutils.add_action(self, N_('Clear...'), self.clear) self.launch_editor = actions.launch_editor(self) self.launch_difftool = actions.launch_difftool(self) self.stage_or_unstage = actions.stage_or_unstage(self) self.move_up = actions.move_up(self) self.move_down = actions.move_down(self) # Widgets self.summary = CommitSummaryLineEdit() self.summary.setMinimumHeight(defs.tool_button_height) self.summary.extra_actions.append(self.clear_action) self.summary.extra_actions.append(None) self.summary.extra_actions.append(self.signoff_action) self.summary.extra_actions.append(self.commit_action) self.summary.extra_actions.append(None) self.summary.extra_actions.append(self.launch_editor) self.summary.extra_actions.append(self.launch_difftool) self.summary.extra_actions.append(self.stage_or_unstage) self.summary.extra_actions.append(None) self.summary.extra_actions.append(self.move_up) self.summary.extra_actions.append(self.move_down) self.description = CommitMessageTextEdit() self.description.extra_actions.append(self.clear_action) self.description.extra_actions.append(None) self.description.extra_actions.append(self.signoff_action) self.description.extra_actions.append(self.commit_action) self.description.extra_actions.append(None) self.description.extra_actions.append(self.launch_editor) self.description.extra_actions.append(self.launch_difftool) self.description.extra_actions.append(self.stage_or_unstage) self.description.extra_actions.append(None) self.description.extra_actions.append(self.move_up) self.description.extra_actions.append(self.move_down) commit_button_tooltip = N_('Commit staged changes\n' 'Shortcut: Ctrl+Enter') self.commit_button = qtutils.create_toolbutton( text=N_('Commit@@verb'), tooltip=commit_button_tooltip, icon=icons.download()) self.commit_group = Group(self.commit_action, self.commit_button) self.actions_menu = QtGui.QMenu() self.actions_button = qtutils.create_toolbutton( icon=icons.configure(), tooltip=N_('Actions...')) self.actions_button.setMenu(self.actions_menu) self.actions_button.setPopupMode(QtGui.QToolButton.InstantPopup) qtutils.hide_button_menu_indicator(self.actions_button) self.actions_menu.addAction(self.signoff_action) self.actions_menu.addAction(self.commit_action) self.actions_menu.addSeparator() # Amend checkbox self.amend_action = self.actions_menu.addAction( N_('Amend Last Commit')) self.amend_action.setCheckable(True) self.amend_action.setShortcut(hotkeys.AMEND) self.amend_action.setShortcutContext(Qt.ApplicationShortcut) # Bypass hooks self.bypass_commit_hooks_action = self.actions_menu.addAction( N_('Bypass Commit Hooks')) self.bypass_commit_hooks_action.setCheckable(True) self.bypass_commit_hooks_action.setChecked(False) # Sign commits cfg = gitcfg.current() self.sign_action = self.actions_menu.addAction( N_('Create Signed Commit')) self.sign_action.setCheckable(True) self.sign_action.setChecked(cfg.get('cola.signcommits', False)) # Spell checker self.check_spelling_action = self.actions_menu.addAction( N_('Check Spelling')) self.check_spelling_action.setCheckable(True) self.check_spelling_action.setChecked(False) # Line wrapping self.autowrap_action = self.actions_menu.addAction( N_('Auto-Wrap Lines')) self.autowrap_action.setCheckable(True) self.autowrap_action.setChecked(prefs.linebreak()) # Commit message self.actions_menu.addSeparator() self.load_commitmsg_menu = self.actions_menu.addMenu( N_('Load Previous Commit Message')) self.connect(self.load_commitmsg_menu, SIGNAL('aboutToShow()'), self.build_commitmsg_menu) self.fixup_commit_menu = self.actions_menu.addMenu( N_('Fixup Previous Commit')) self.connect(self.fixup_commit_menu, SIGNAL('aboutToShow()'), self.build_fixup_menu) self.toplayout = qtutils.hbox(defs.no_margin, defs.spacing, self.actions_button, self.summary, self.commit_button) self.toplayout.setContentsMargins(defs.margin, defs.no_margin, defs.no_margin, defs.no_margin) self.mainlayout = qtutils.vbox(defs.no_margin, defs.spacing, self.toplayout, self.description) self.setLayout(self.mainlayout) qtutils.connect_button(self.commit_button, self.commit) # Broadcast the amend mode qtutils.connect_action_bool(self.amend_action, cmds.run(cmds.AmendMode)) qtutils.connect_action_bool(self.check_spelling_action, self.toggle_check_spelling) # Handle the one-off autowrapping qtutils.connect_action_bool(self.autowrap_action, self.set_linebreak) qtutils.add_action(self.summary, N_('Move Down'), self.focus_description, *hotkeys.ACCEPT) qtutils.add_action(self.summary, N_('Move Down'), self.summary_cursor_down, hotkeys.DOWN) self.selection_model = selection_model = selection.selection_model() selection_model.add_observer(selection_model.message_selection_changed, self._update) self.model.add_observer(self.model.message_commit_message_changed, self._set_commit_message) self.connect(self, SIGNAL('set_commit_message(PyQt_PyObject)'), self.set_commit_message, Qt.QueuedConnection) self.connect(self.summary, SIGNAL('cursorPosition(int,int)'), self.emit_position) self.connect( self.description, SIGNAL('cursorPosition(int,int)'), # description starts at line 2 lambda row, col: self.emit_position(row + 2, col)) # Keep model informed of changes self.connect(self.summary, SIGNAL('textChanged(QString)'), self.commit_summary_changed) self.connect(self.description, SIGNAL('textChanged()'), self.commit_message_changed) self.connect(self.description, SIGNAL('leave()'), self.focus_summary) self.connect(self, SIGNAL('update()'), self._update_callback, Qt.QueuedConnection) self.setFont(qtutils.diff_font()) self.summary.hint.enable(True) self.description.hint.enable(True) self.commit_group.setEnabled(False) self.setFocusProxy(self.summary) self.set_tabwidth(prefs.tabwidth()) self.set_textwidth(prefs.textwidth()) self.set_linebreak(prefs.linebreak()) # Loading message commit_msg = '' commit_msg_path = commit_message_path() if commit_msg_path: commit_msg = core.read(commit_msg_path) self.set_commit_message(commit_msg) # Allow tab to jump from the summary to the description self.setTabOrder(self.summary, self.description)