def contextMenuEvent(self, event): """Create the context menu for the diff display.""" menu = QtGui.QMenu(self) s = selection.selection() if self.model.stageable(): if s.modified and s.modified[0] in main.model().submodules: action = menu.addAction(qtutils.icon('add.svg'), cmds.Stage.name(), cmds.run(cmds.Stage, s.modified)) action.setShortcut(cmds.Stage.SHORTCUT) menu.addAction(qtutils.git_icon(), N_('Launch git-cola'), cmds.run(cmds.OpenRepo, core.abspath(s.modified[0]))) elif s.modified: action = menu.addAction(qtutils.icon('add.svg'), N_('Stage Section'), self.stage_section) action.setShortcut(Qt.Key_H) menu.addAction(self.action_stage_selection) menu.addSeparator() menu.addAction(qtutils.icon('undo.svg'), N_('Revert Section...'), self.revert_section) menu.addAction(self.action_revert_selection) if self.model.unstageable(): if s.staged and s.staged[0] in main.model().submodules: action = menu.addAction(qtutils.icon('remove.svg'), cmds.Unstage.name(), cmds.do(cmds.Unstage, s.staged)) action.setShortcut(cmds.Unstage.SHORTCUT) menu.addAction(qtutils.git_icon(), N_('Launch git-cola'), cmds.do(cmds.OpenRepo, core.abspath(s.staged[0]))) elif s.staged: action = menu.addAction(qtutils.icon('remove.svg'), N_('Unstage Section'), self.unstage_section) action.setShortcut(Qt.Key_H) menu.addAction(self.action_unstage_selection) if self.model.stageable() or self.model.unstageable(): menu.addSeparator() menu.addAction(self.launch_editor) menu.addAction(self.launch_difftool) menu.addSeparator() action = menu.addAction(qtutils.icon('edit-copy.svg'), N_('Copy'), self.copy) action.setShortcut(QtGui.QKeySequence.Copy) action = menu.addAction(qtutils.icon('edit-select-all.svg'), N_('Select All'), self.selectAll) action.setShortcut(QtGui.QKeySequence.SelectAll) menu.exec_(self.mapToGlobal(event.pos()))
def contextMenuEvent(self, event): """Create the context menu for the diff display.""" menu = QtGui.QMenu(self) staged, modified, unmerged, untracked = cola.selection() if self.mode == self.model.mode_worktree: if modified and modified[0] in cola.model().submodules: menu.addAction(qtutils.icon('add.svg'), self.tr('Stage'), SLOT(signals.stage, modified)) menu.addAction(qtutils.git_icon(), self.tr('Launch git-cola'), SLOT(signals.open_repo, os.path.abspath(modified[0]))) elif modified: menu.addAction(qtutils.icon('add.svg'), self.tr('Stage Section'), self.stage_section) menu.addAction(self.action_stage_selection) menu.addSeparator() menu.addAction(qtutils.icon('undo.svg'), self.tr('Revert Section...'), self.revert_section) menu.addAction(self.action_revert_selection) elif self.mode == self.model.mode_index: if staged and staged[0] in cola.model().submodules: menu.addAction(qtutils.icon('remove.svg'), self.tr('Unstage'), SLOT(signals.unstage, staged)) menu.addAction(qtutils.git_icon(), self.tr('Launch git-cola'), SLOT(signals.open_repo, os.path.abspath(staged[0]))) else: menu.addAction(qtutils.icon('remove.svg'), self.tr('Unstage Section'), self.unstage_section) menu.addAction(self.action_unstage_selection) elif self.mode == self.model.mode_branch: menu.addAction(qtutils.apply_icon(), self.tr('Apply Diff to Work Tree'), self.stage_section) menu.addAction(self.action_apply_selection) elif self.mode == self.model.mode_grep: menu.addAction(qtutils.icon('open.svg'), self.tr('Launch Editor'), lambda: guicmds.goto_grep(self.selected_line())) menu.addSeparator() menu.addAction(qtutils.icon('edit-copy.svg'), 'Copy', self.copy) menu.addAction(qtutils.icon('edit-select-all.svg'), 'Select All', self.selectAll) menu.exec_(self.mapToGlobal(event.pos()))
def contextMenuEvent(self, event): """Create the context menu for the diff display.""" menu = QtGui.QMenu(self) s = cola.selection() if self.model.stageable(): if s.modified and s.modified[0] in cola.model().submodules: action = menu.addAction(qtutils.icon('add.svg'), self.tr('Stage'), SLOT(signals.stage, s.modified)) action.setShortcut(defs.stage_shortcut) menu.addAction(qtutils.git_icon(), self.tr('Launch git-cola'), SLOT(signals.open_repo, os.path.abspath(s.modified[0]))) elif s.modified: action = menu.addAction(qtutils.icon('add.svg'), self.tr('Stage Section'), self.stage_section) action.setShortcut(Qt.Key_H) menu.addAction(self.action_stage_selection) menu.addSeparator() menu.addAction(qtutils.icon('undo.svg'), self.tr('Revert Section...'), self.revert_section) menu.addAction(self.action_revert_selection) if self.model.unstageable(): if s.staged and s.staged[0] in cola.model().submodules: action = menu.addAction(qtutils.icon('remove.svg'), self.tr('Unstage'), SLOT(signals.unstage, s.staged)) action.setShortcut(defs.stage_shortcut) menu.addAction(qtutils.git_icon(), self.tr('Launch git-cola'), SLOT(signals.open_repo, os.path.abspath(s.staged[0]))) elif s.staged: action = menu.addAction(qtutils.icon('remove.svg'), self.tr('Unstage Section'), self.unstage_section) action.setShortcut(Qt.Key_H) menu.addAction(self.action_unstage_selection) menu.addSeparator() action = menu.addAction(qtutils.icon('edit-copy.svg'), 'Copy', self.copy) action.setShortcut(QtGui.QKeySequence.Copy) action = menu.addAction(qtutils.icon('edit-select-all.svg'), 'Select All', self.selectAll) action.setShortcut(QtGui.QKeySequence.SelectAll) menu.exec_(self.mapToGlobal(event.pos()))
def contextMenuEvent(self, event): """Create the context menu for the diff display.""" menu = QtGui.QMenu(self) s = cola.selection() if self.model.stageable(): if s.modified and s.modified[0] in cola.model().submodules: action = menu.addAction(qtutils.icon('add.svg'), self.tr('Stage'), SLOT(signals.stage, s.modified)) action.setShortcut(defs.stage_shortcut) menu.addAction( qtutils.git_icon(), self.tr('Launch git-cola'), SLOT(signals.open_repo, os.path.abspath(s.modified[0]))) elif s.modified: action = menu.addAction(qtutils.icon('add.svg'), self.tr('Stage Section'), self.stage_section) action.setShortcut(Qt.Key_H) menu.addAction(self.action_stage_selection) menu.addSeparator() menu.addAction(qtutils.icon('undo.svg'), self.tr('Revert Section...'), self.revert_section) menu.addAction(self.action_revert_selection) if self.model.unstageable(): if s.staged and s.staged[0] in cola.model().submodules: action = menu.addAction(qtutils.icon('remove.svg'), self.tr('Unstage'), SLOT(signals.unstage, s.staged)) action.setShortcut(defs.stage_shortcut) menu.addAction( qtutils.git_icon(), self.tr('Launch git-cola'), SLOT(signals.open_repo, os.path.abspath(s.staged[0]))) elif s.staged: action = menu.addAction(qtutils.icon('remove.svg'), self.tr('Unstage Section'), self.unstage_section) action.setShortcut(Qt.Key_H) menu.addAction(self.action_unstage_selection) menu.addSeparator() action = menu.addAction(qtutils.icon('edit-copy.svg'), 'Copy', self.copy) action.setShortcut(QtGui.QKeySequence.Copy) action = menu.addAction(qtutils.icon('edit-select-all.svg'), 'Select All', self.selectAll) action.setShortcut(QtGui.QKeySequence.SelectAll) menu.exec_(self.mapToGlobal(event.pos()))
def _create_unmerged_context_menu(self, menu, s): menu.addAction(qtutils.git_icon(), N_('Launch Merge Tool'), cmds.run(cmds.Mergetool, self.unmerged())) action = menu.addAction(qtutils.icon('add.svg'), N_('Stage Selected'), cmds.run(cmds.Stage, self.unstaged())) action.setShortcut(cmds.Stage.SHORTCUT) menu.addSeparator() action = menu.addAction(qtutils.options_icon(), cmds.LaunchEditor.name(), cmds.run(cmds.LaunchEditor)) action.setShortcut(cmds.LaunchEditor.SHORTCUT) if not utils.is_win32(): menu.addSeparator() action = menu.addAction(qtutils.file_icon(), cmds.OpenDefaultApp.name(), cmds.run(cmds.OpenDefaultApp, self.unmerged())) action.setShortcut(cmds.OpenDefaultApp.SHORTCUT) action = menu.addAction(qtutils.open_file_icon(), cmds.OpenParentDir.name(), self._open_parent_dir) action.setShortcut(cmds.OpenParentDir.SHORTCUT) menu.addSeparator() menu.addAction(self.copy_path_action) return menu
def __init__(self, argv, locale=None, gui=True): """Initialize our QApplication for translation """ i18n.install(locale) qtcompat.install() # Add the default style dir so that we find our icons icon_dir = resources.icon_dir() qtcompat.add_search_path(os.path.basename(icon_dir), icon_dir) # monkey-patch Qt's translate() to use our translate() if gui: self._app = instance(tuple(argv)) self._app.setWindowIcon(qtutils.git_icon()) self._translate_base = QtGui.QApplication.translate QtGui.QApplication.translate = self.translate else: self._app = QtCore.QCoreApplication(argv) self._translate_base = QtCore.QCoreApplication.translate QtCore.QCoreApplication.translate = self.translate # Register model commands cmds.register() # Make file descriptors binary for win32 utils.set_binary(sys.stdin) utils.set_binary(sys.stdout) utils.set_binary(sys.stderr)
def __init__(self, argv, locale=None, gui=True): cfgactions.install() i18n.install(locale) qtcompat.install() qtutils.install() # Add the default style dir so that we find our icons icon_dir = resources.icon_dir() qtcompat.add_search_path(os.path.basename(icon_dir), icon_dir) if gui: self._app = instance(tuple(argv)) self._app.setWindowIcon(qtutils.git_icon()) else: self._app = QtCore.QCoreApplication(argv) self._app.setStyleSheet(""" QMainWindow::separator { width: 3px; height: 3px; } QMainWindow::separator:hover { background: white; } """)
def apply_matches(self, match_tuple): self.match_tuple = match_tuple matched_refs, matched_paths, dirs = match_tuple QStandardItem = QtGui.QStandardItem dir_icon = qtutils.dir_icon() git_icon = qtutils.git_icon() items = [] for ref in matched_refs: item = QStandardItem() item.setText(ref) item.setIcon(git_icon) items.append(item) for match in matched_paths: item = QStandardItem() item.setText(match) if match in dirs: item.setIcon(dir_icon) else: item.setIcon(self.icon_from_filename(match)) items.append(item) self.clear() self.invisibleRootItem().appendRows(items) self.emit(SIGNAL('updated()'))
def __init__(self, argv, locale=None, gui=True, git_path=None): cfgactions.install() i18n.install(locale) qtcompat.install() qtutils.install() self.notifier = QtCore.QObject() self.notifier.connect(self.notifier, SIGNAL('update_files'), self._update_files) # Call _update_files when inotify detects changes inotify.observer(self._update_files_notifier) # Add the default style dir so that we find our icons icon_dir = resources.icon_dir() qtcompat.add_search_path(os.path.basename(icon_dir), icon_dir) if gui: self._app = current(tuple(argv), git_path) self._app.setWindowIcon(qtutils.git_icon()) self._app.setStyleSheet(""" QMainWindow::separator { width: 3px; height: 3px; } QMainWindow::separator:hover { background: white; } """) else: self._app = QtCore.QCoreApplication(argv)
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.unstaged(): action = menu.addAction(qtutils.options_icon(), cmds.LaunchEditor.name(), cmds.run(cmds.LaunchEditor)) action.setShortcut(cmds.Edit.SHORTCUT) if s.modified and self.m.stageable(): action = menu.addAction(qtutils.git_icon(), cmds.LaunchDifftool.name(), cmds.run(cmds.LaunchDifftool)) action.setShortcut(cmds.LaunchDifftool.SHORTCUT) if self.m.stageable(): menu.addSeparator() action = menu.addAction(qtutils.icon('add.svg'), N_('Stage Selected'), cmds.run(cmds.Stage, self.unstaged())) action.setShortcut(cmds.Stage.SHORTCUT) if s.modified and self.m.stageable(): if self.m.undoable(): menu.addSeparator() menu.addAction(qtutils.icon('undo.svg'), N_('Revert Unstaged Edits...'), self._revert_unstaged_edits) menu.addAction(qtutils.icon('undo.svg'), N_('Revert Uncommited Edits...'), lambda: self._revert_uncommitted_edits( self.modified())) if 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(cmds.OpenDefaultApp.SHORTCUT) action = menu.addAction(qtutils.open_file_icon(), cmds.OpenParentDir.name(), self._open_parent_dir) action.setShortcut(cmds.OpenParentDir.SHORTCUT) if s.untracked: menu.addSeparator() menu.addAction(qtutils.discard_icon(), N_('Delete File(s)...'), self._delete_files) menu.addSeparator() menu.addAction(qtutils.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) return menu
def __init__(self, argv, locale=None, gui=True, git_path=None): cfgactions.install() i18n.install(locale) qtcompat.install() qtutils.install() # Call _update_files when inotify detects changes inotify.observer(_update_files) # Add the default style dir so that we find our icons icon_dir = resources.icon_dir() qtcompat.add_search_path(os.path.basename(icon_dir), icon_dir) if gui: self._app = instance(tuple(argv), git_path) self._app.setWindowIcon(qtutils.git_icon()) else: self._app = QtCore.QCoreApplication(argv) self._app.setStyleSheet(""" QMainWindow::separator { width: 3px; height: 3px; } QMainWindow::separator:hover { background: white; } """)
def apply_matches(self, match_tuple): self.match_tuple = match_tuple matched_refs, matched_paths, dirs = match_tuple QStandardItem = QtGui.QStandardItem file_icon = qtutils.file_icon() dir_icon = qtutils.dir_icon() git_icon = qtutils.git_icon() matched_text = self.matched_text items = [] for ref in matched_refs: item = QStandardItem() item.setText(ref) item.setIcon(git_icon) items.append(item) if matched_paths and (not matched_text or matched_text in '--'): item = QStandardItem() item.setText('--') item.setIcon(file_icon) items.append(item) for match in matched_paths: item = QStandardItem() item.setText(match) if match in dirs: item.setIcon(dir_icon) else: item.setIcon(file_icon) items.append(item) self.clear() self.invisibleRootItem().appendRows(items)
def _create_unmerged_context_menu(self, menu, s): menu.addAction(qtutils.git_icon(), self.tr('Launch Merge Tool'), cmds.run(cmds.Mergetool, self.unmerged())) action = menu.addAction(qtutils.icon('add.svg'), self.tr('Stage Selected'), cmds.run(cmds.Stage, self.unstaged())) action.setShortcut(cmds.Stage.SHORTCUT) menu.addSeparator() action = menu.addAction(qtutils.options_icon(), self.tr(cmds.LaunchEditor.NAME), cmds.run(cmds.LaunchEditor)) action.setShortcut(cmds.LaunchEditor.SHORTCUT) if not utils.is_win32(): menu.addSeparator() action = menu.addAction( qtutils.file_icon(), self.tr(cmds.OpenDefaultApp.NAME), cmds.run(cmds.OpenDefaultApp, self.unmerged())) action.setShortcut(cmds.OpenDefaultApp.SHORTCUT) action = menu.addAction(qtutils.open_file_icon(), self.tr(cmds.OpenParentDir.NAME), self._open_parent_dir) action.setShortcut(cmds.OpenParentDir.SHORTCUT) menu.addSeparator() menu.addAction(self.copy_path_action) return menu
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=options_icon()) 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, '', self.apply_selection, Qt.Key_S) self.action_revert_selection = qtutils.add_action(self, '', self.revert_selection) self.action_revert_selection.setIcon(qtutils.icon('undo.svg')) self.launch_editor = qtutils.add_action(self, cmds.LaunchEditor.name(), run(cmds.LaunchEditor), cmds.LaunchEditor.SHORTCUT, 'Return', 'Enter') self.launch_editor.setIcon(qtutils.options_icon()) self.launch_difftool = qtutils.add_action(self, cmds.LaunchDifftool.name(), run(cmds.LaunchDifftool), cmds.LaunchDifftool.SHORTCUT) self.launch_difftool.setIcon(qtutils.git_icon()) model.add_observer(model.message_diff_text_changed, self._emit_text) self.connect(self, SIGNAL('set_text'), self.setPlainText)
def __init__(self, argv, locale=None, gui=True): cfgactions.install() i18n.install(locale) qtcompat.install() qtutils.install() self.notifier = QtCore.QObject() self.notifier.connect(self.notifier, SIGNAL("update_files()"), self._update_files, Qt.QueuedConnection) # Call _update_files when inotify detects changes inotify.observer(self._update_files_notifier) # Add the default style dir so that we find our icons icon_dir = resources.icon_dir() qtcompat.add_search_path(os.path.basename(icon_dir), icon_dir) if gui: self._app = current(tuple(argv)) self._app.setWindowIcon(qtutils.git_icon()) self._app.setStyleSheet( """ QMainWindow::separator { width: 3px; height: 3px; } QMainWindow::separator:hover { background: white; } """ ) else: self._app = QtCore.QCoreApplication(argv)
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=options_icon()) 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, '', self.apply_selection, Qt.Key_S) self.action_revert_selection = qtutils.add_action( self, '', self.revert_selection) self.action_revert_selection.setIcon(qtutils.icon('undo.svg')) self.launch_editor = qtutils.add_action(self, cmds.LaunchEditor.name(), run(cmds.LaunchEditor), cmds.LaunchEditor.SHORTCUT, 'Return', 'Enter') self.launch_editor.setIcon(qtutils.options_icon()) self.launch_difftool = qtutils.add_action(self, cmds.LaunchDifftool.name(), run(cmds.LaunchDifftool), cmds.LaunchDifftool.SHORTCUT) self.launch_difftool.setIcon(qtutils.git_icon()) model.add_observer(model.message_diff_text_changed, self._emit_text) self.connect(self, SIGNAL('set_text'), self.setPlainText)
def default_pixmap_as_bytes(self): xres = self.imgsize pixmap = qtutils.git_icon().pixmap(xres) byte_array = QtCore.QByteArray() buf = QtCore.QBuffer(byte_array) buf.open(QtCore.QIODevice.WriteOnly) pixmap.save(buf, "PNG") buf.close() return byte_array
def default_pixmap_as_bytes(self): xres = self.imgsize pixmap = qtutils.git_icon().pixmap(xres) byte_array = QtCore.QByteArray() buf = QtCore.QBuffer(byte_array) buf.open(QtCore.QIODevice.WriteOnly) pixmap.save(buf, 'PNG') buf.close() return byte_array
def remote_callback(): if not self.model.remotename: errmsg = self.tr('No repository selected.') qtutils.log(1, errmsg) return remote, kwargs = self.common_args() action = self.action # Check if we're about to create a new branch and warn. if action == 'push' and not self.model.remote_branch: branch = self.model.local_branch candidate = '%s/%s' % (remote, branch) if candidate not in self.model.remote_branches: title = 'Push' msg = 'Branch "%s" does not exist in %s.' % (branch, remote) msg += '\nA new remote branch will be published.' info_txt= 'Create a new remote branch?' ok_text = 'Create Remote Branch' if not qtutils.confirm(title, msg, info_txt, ok_text, default=False, icon=qtutils.git_icon()): return if not self.model.ffwd_only_checkbox: title = 'Force %s?' % action.title() ok_text = 'Force %s' % action.title() if action == 'fetch': msg = 'Non-fast-forward fetch overwrites local history!' info_txt = 'Force fetching from %s?' % remote elif action == 'push': msg = ('Non-fast-forward push overwrites published ' 'history!\n(Did you pull first?)') info_txt = 'Force push to %s?' % remote else: # pull: shouldn't happen since the controls are hidden msg = "You probably don't want to do this.\n\tContinue?" return if not qtutils.confirm(title, msg, info_txt, ok_text, default=False, icon=qtutils.discard_icon()): return # Disable the GUI by default self.view.setEnabled(False) self.progress.setEnabled(True) QtGui.QApplication.setOverrideCursor(Qt.WaitCursor) # Show a nice progress bar self.progress.setLabelText('Updating...') self.progress.show() # Use a thread to update in the background task = ActionTask(self.view, modelaction, remote, kwargs) self._tasks.append(task) QtCore.QThreadPool.globalInstance().start(task)
def update_matches(self): model = self.cmodel matches = model.local_branches + model.remote_branches + model.tags QStandardItem = QtGui.QStandardItem self.clear() for match in matches: item = QStandardItem() item.setIcon(qtutils.git_icon()) item.setText(match) self.appendRow(item)
def _create_staged_submodule_context_menu(self, menu, s): menu.addAction(qtutils.git_icon(), N_("Launch git-cola"), cmds.run(cmds.OpenRepo, core.abspath(s.staged[0]))) menu.addAction(self.launch_editor_action) menu.addSeparator() action = menu.addAction(qtutils.remove_icon(), N_("Unstage Selected"), cmds.run(cmds.Unstage, self.staged())) action.setShortcut(cmds.Unstage.SHORTCUT) menu.addSeparator() menu.addAction(self.copy_path_action) menu.addAction(self.copy_relpath_action) return menu
def _create_modified_submodule_context_menu(self, menu, s): menu.addAction(qtutils.git_icon(), N_("Launch git-cola"), cmds.run(cmds.OpenRepo, core.abspath(s.modified[0]))) menu.addAction(self.launch_editor) if self.m.stageable(): menu.addSeparator() action = menu.addAction( qtutils.icon("add.svg"), N_("Stage Selected"), cmds.run(cmds.Stage, self.unstaged()) ) action.setShortcut(cmds.Stage.SHORTCUT) menu.addSeparator() menu.addAction(self.copy_path_action) return menu
def _create_staged_submodule_context_menu(self, menu, s): menu.addAction(qtutils.git_icon(), N_('Launch git-cola'), cmds.run(cmds.OpenRepo, core.abspath(s.staged[0]))) menu.addAction(self.launch_editor) menu.addSeparator() action = menu.addAction(qtutils.icon('remove.svg'), N_('Unstage Selected'), cmds.run(cmds.Unstage, self.staged())) action.setShortcut(cmds.Unstage.SHORTCUT) menu.addSeparator() menu.addAction(self.copy_path_action) return menu
def _create_modified_submodule_context_menu(self, menu, s): menu.addAction(qtutils.git_icon(), N_('Launch git-cola'), cmds.run(cmds.OpenRepo, core.abspath(s.modified[0]))) menu.addAction(self.launch_editor_action) if self.m.stageable(): menu.addSeparator() action = menu.addAction(qtutils.icon('add.svg'), N_('Stage Selected'), cmds.run(cmds.Stage, self.unstaged())) action.setShortcut(cmds.Stage.SHORTCUT) menu.addSeparator() menu.addAction(self.copy_path_action) menu.addAction(self.copy_relpath_action) return menu
def _create_staged_context_menu(self, menu, s): if s.staged[0] in self.m.submodules: return self._create_staged_submodule_context_menu(menu, s) if self.m.unstageable(): action = menu.addAction(qtutils.icon('remove.svg'), N_('Unstage Selected'), cmds.run(cmds.Unstage, self.staged())) action.setShortcut(cmds.Unstage.SHORTCUT) menu.addSeparator() action = menu.addAction(qtutils.options_icon(), cmds.LaunchEditor.name(), cmds.run(cmds.LaunchEditor)) action.setShortcut(cmds.LaunchEditor.SHORTCUT) action = menu.addAction(qtutils.git_icon(), cmds.LaunchDifftool.name(), cmds.run(cmds.LaunchDifftool)) action.setShortcut(cmds.LaunchDifftool.SHORTCUT) if not utils.is_win32(): menu.addSeparator() action = menu.addAction(qtutils.file_icon(), cmds.OpenDefaultApp.name(), cmds.run(cmds.OpenDefaultApp, self.staged())) action.setShortcut(cmds.OpenDefaultApp.SHORTCUT) action = menu.addAction(qtutils.open_file_icon(), cmds.OpenParentDir.name(), self._open_parent_dir) action.setShortcut(cmds.OpenParentDir.SHORTCUT) if self.m.undoable(): menu.addSeparator() menu.addAction(qtutils.icon('undo.svg'), N_('Revert Unstaged Edits...'), lambda: self._revert_unstaged_edits(staged=True)) menu.addAction(qtutils.icon('undo.svg'), N_('Revert Uncommited Edits...'), self._revert_uncommitted_edits) menu.addSeparator() menu.addAction(self.copy_path_action) return menu
def _create_staged_context_menu(self, menu, s): if s.staged[0] in self.m.submodules: return self._create_staged_submodule_context_menu(menu, s) action = menu.addAction(qtutils.options_icon(), cmds.LaunchEditor.name(), cmds.run(cmds.LaunchEditor)) action.setShortcut(cmds.LaunchEditor.SHORTCUT) action = menu.addAction(qtutils.git_icon(), cmds.LaunchDifftool.name(), cmds.run(cmds.LaunchDifftool)) action.setShortcut(cmds.LaunchDifftool.SHORTCUT) if self.m.unstageable(): menu.addSeparator() action = menu.addAction(qtutils.icon('remove.svg'), N_('Unstage Selected'), cmds.run(cmds.Unstage, self.staged())) action.setShortcut(cmds.Unstage.SHORTCUT) if not utils.is_win32(): menu.addSeparator() action = menu.addAction(qtutils.file_icon(), cmds.OpenDefaultApp.name(), cmds.run(cmds.OpenDefaultApp, self.staged())) action.setShortcut(cmds.OpenDefaultApp.SHORTCUT) action = menu.addAction(qtutils.open_file_icon(), cmds.OpenParentDir.name(), self._open_parent_dir) action.setShortcut(cmds.OpenParentDir.SHORTCUT) if self.m.undoable(): menu.addSeparator() menu.addAction(qtutils.icon('undo.svg'), N_('Revert Unstaged Edits...'), lambda: self._revert_unstaged_edits(staged=True)) menu.addAction(qtutils.icon('undo.svg'), N_('Revert Uncommited Edits...'), lambda: self._revert_uncommitted_edits( self.staged())) menu.addSeparator() menu.addAction(self.copy_path_action) return menu
def _create_staged_submodule_context_menu(self, menu, s): menu.addAction(qtutils.git_icon(), N_('Launch git-cola'), cmds.run(cmds.OpenRepo, core.abspath(s.staged[0]))) menu.addAction(self.launch_editor_action) menu.addSeparator() action = menu.addAction(qtutils.remove_icon(), N_('Unstage Selected'), cmds.run(cmds.Unstage, self.staged())) action.setShortcut(hotkeys.STAGE_SELECTION) menu.addSeparator() menu.addAction(self.copy_path_action) menu.addAction(self.copy_relpath_action) menu.addAction(self.view_history_action) return menu
def _create_modified_submodule_context_menu(self, menu, s): menu.addAction(qtutils.git_icon(), self.tr('Launch git-cola'), cmds.run(cmds.OpenRepo, os.path.abspath(s.modified[0]))) action = menu.addAction(qtutils.options_icon(), self.tr(cmds.LaunchEditor.NAME), cmds.run(cmds.LaunchEditor)) action.setShortcut(cmds.Edit.SHORTCUT) if self.m.stageable(): menu.addSeparator() action = menu.addAction(qtutils.icon('add.svg'), self.tr('Stage Selected'), cmds.run(cmds.Stage, self.unstaged())) action.setShortcut(cmds.Stage.SHORTCUT) menu.addSeparator() menu.addAction(self.copy_path_action) return menu
def _create_modified_submodule_context_menu(self, menu, s): menu.addAction(qtutils.git_icon(), N_('Launch git-cola'), cmds.run(cmds.OpenRepo, core.abspath(s.modified[0]))) menu.addAction(self.launch_editor_action) if self.m.stageable(): menu.addSeparator() action = menu.addAction(qtutils.add_icon(), N_('Stage Selected'), cmds.run(cmds.Stage, self.unstaged())) action.setShortcut(hotkeys.STAGE_SELECTION) menu.addSeparator() menu.addAction(self.copy_path_action) menu.addAction(self.copy_relpath_action) menu.addAction(self.view_history_action) return menu
def _create_staged_submodule_context_menu(self, menu, s): menu.addAction(qtutils.git_icon(), N_('Launch git-cola'), cmds.run(cmds.OpenRepo, os.path.abspath(s.staged[0]))) action = menu.addAction(qtutils.options_icon(), cmds.LaunchEditor.name(), cmds.run(cmds.LaunchEditor)) action.setShortcut(cmds.LaunchEditor.SHORTCUT) menu.addSeparator() action = menu.addAction(qtutils.icon('remove.svg'), N_('Unstage Selected'), cmds.run(cmds.Unstage, self.staged())) action.setShortcut(cmds.Unstage.SHORTCUT) menu.addSeparator() menu.addAction(self.copy_path_action) return menu
def __init__(self, argv, locale=None, gui=True): """Initialize our QApplication for translation """ cfgactions.install() i18n.install(locale) qtcompat.install() qtutils.install() # Add the default style dir so that we find our icons icon_dir = resources.icon_dir() qtcompat.add_search_path(os.path.basename(icon_dir), icon_dir) # monkey-patch Qt's translate() to use our translate() if gui: self._app = instance(tuple(argv)) self._app.setWindowIcon(qtutils.git_icon()) self._translate_base = QtGui.QApplication.translate QtGui.QApplication.translate = self.translate else: self._app = QtCore.QCoreApplication(argv) self._translate_base = QtCore.QCoreApplication.translate QtCore.QCoreApplication.translate = self.translate if not hasattr(self._app, 'setStyleSheet'): self._app.setStyleSheet = lambda x: None self._app.setStyleSheet(""" QMainWindow::separator { width: 3px; height: 3px; } QMainWindow::separator:hover { background: white; } """) # Make file descriptors binary for win32 utils.set_binary(sys.stdin) utils.set_binary(sys.stdout) utils.set_binary(sys.stderr)
def __init__(self, argv, locale=None, gui=True): """Initialize our QApplication for translation """ cfgactions.install() i18n.install(locale) qtcompat.install() qtutils.install() # Add the default style dir so that we find our icons icon_dir = resources.icon_dir() qtcompat.add_search_path(os.path.basename(icon_dir), icon_dir) # monkey-patch Qt's translate() to use our translate() if gui: self._app = instance(tuple(argv)) self._app.setWindowIcon(qtutils.git_icon()) self._translate_base = QtGui.QApplication.translate QtGui.QApplication.translate = self.translate else: self._app = QtCore.QCoreApplication(argv) self._translate_base = QtCore.QCoreApplication.translate QtCore.QCoreApplication.translate = self.translate self._app.setStyleSheet(""" QMainWindow::separator { width: 3px; height: 3px; } QMainWindow::separator:hover { background: white; } """) # Make file descriptors binary for win32 utils.set_binary(sys.stdin) utils.set_binary(sys.stdout) utils.set_binary(sys.stderr)
def __init__(self, parent=None): QtGui.QDialog.__init__(self, parent) self.setWindowTitle(N_('git-cola')) self._gitdir = None self._layt = QtGui.QHBoxLayout() self._layt.setMargin(defs.margin) self._layt.setSpacing(defs.spacing) self._new_btn = QtGui.QPushButton(N_('New...')) self._new_btn.setIcon(qtutils.new_icon()) self._open_btn = QtGui.QPushButton(N_('Open...')) self._open_btn.setIcon(qtutils.open_icon()) self._clone_btn = QtGui.QPushButton(N_('Clone...')) self._clone_btn.setIcon(qtutils.git_icon()) self._close_btn = QtGui.QPushButton(N_('Close')) self._layt.addWidget(self._open_btn) self._layt.addWidget(self._clone_btn) self._layt.addWidget(self._new_btn) self._layt.addStretch() self._layt.addWidget(self._close_btn) self.model = settings.Settings() self._vlayt = QtGui.QVBoxLayout() self._vlayt.setMargin(defs.margin) self._vlayt.setSpacing(defs.margin) self._bookmark_label = QtGui.QLabel(N_('Select Repository...')) self._bookmark_label.setAlignment(Qt.AlignCenter) self._bookmark_model = QtGui.QStandardItemModel() item = QtGui.QStandardItem(N_('Select manually...')) item.setEditable(False) self._bookmark_model.appendRow(item) added = set() all_repos = self.model.bookmarks + self.model.recent for repo in all_repos: if repo in added: continue added.add(repo) item = QtGui.QStandardItem(repo) item.setEditable(False) self._bookmark_model.appendRow(item) selection_mode = QtGui.QAbstractItemView.SingleSelection self._bookmark_list = QtGui.QListView() self._bookmark_list.setSelectionMode(selection_mode) self._bookmark_list.setAlternatingRowColors(True) self._bookmark_list.setModel(self._bookmark_model) if not all_repos: self._bookmark_label.setMinimumHeight(1) self._bookmark_list.setMinimumHeight(1) self._bookmark_label.hide() self._bookmark_list.hide() self._vlayt.addWidget(self._bookmark_label) self._vlayt.addWidget(self._bookmark_list) self._vlayt.addLayout(self._layt) self.setLayout(self._vlayt) qtutils.connect_button(self._open_btn, self._open) qtutils.connect_button(self._clone_btn, self._clone) qtutils.connect_button(self._new_btn, self._new) qtutils.connect_button(self._close_btn, self.reject) self.connect(self._bookmark_list, SIGNAL('activated(const QModelIndex &)'), self._open_bookmark)
def __init__(self, model, parent=None, settings=None): MainWindow.__init__(self, parent) self.setAttribute(Qt.WA_MacMetalStyle) # Default size; this is thrown out when save/restore is used self.model = model self.settings = settings self.prefs_model = prefs_model = prefs.PreferencesModel() # The widget version is used by import/export_state(). # Change this whenever dockwidgets are removed. self.widget_version = 2 # Keeps track of merge messages we've seen self.merge_message_hash = '' # Runs asynchronous tasks self.task_runner = TaskRunner(self) self.progress = ProgressDialog('', '', self) cfg = gitcfg.current() self.browser_dockable = (cfg.get('cola.browserdockable') or cfg.get('cola.classicdockable')) if self.browser_dockable: self.browserdockwidget = create_dock(N_('Browser'), self) self.browserwidget = worktree_browser_widget(self) self.browserdockwidget.setWidget(self.browserwidget) # "Actions" widget self.actionsdockwidget = create_dock(N_('Actions'), self) self.actionsdockwidgetcontents = action.ActionButtons(self) self.actionsdockwidget.setWidget(self.actionsdockwidgetcontents) self.actionsdockwidget.toggleViewAction().setChecked(False) self.actionsdockwidget.hide() # "Repository Status" widget self.statusdockwidget = create_dock(N_('Status'), self) self.statuswidget = StatusWidget(self.statusdockwidget.titleBarWidget(), parent=self.statusdockwidget) self.statusdockwidget.setWidget(self.statuswidget) # "Switch Repository" widgets self.bookmarksdockwidget = create_dock(N_('Bookmarks'), self) self.bookmarkswidget = bookmarks.BookmarksWidget( bookmarks.BOOKMARKS, parent=self.bookmarksdockwidget) self.bookmarksdockwidget.setWidget(self.bookmarkswidget) self.recentdockwidget = create_dock(N_('Recent'), self) self.recentwidget = bookmarks.BookmarksWidget( bookmarks.RECENT_REPOS, parent=self.recentdockwidget) self.recentdockwidget.setWidget(self.recentwidget) self.recentdockwidget.hide() # "Commit Message Editor" widget self.position_label = QtGui.QLabel() font = qtutils.default_monospace_font() font.setPointSize(int(font.pointSize() * 0.8)) self.position_label.setFont(font) # make the position label fixed size to avoid layout issues fm = self.position_label.fontMetrics() width = fm.width('999:999') height = self.position_label.sizeHint().height() self.position_label.setFixedSize(width, height) self.commitdockwidget = create_dock(N_('Commit'), self) titlebar = self.commitdockwidget.titleBarWidget() titlebar.add_corner_widget(self.position_label) self.commitmsgeditor = CommitMessageEditor(model, self) self.commitdockwidget.setWidget(self.commitmsgeditor) # "Console" widget self.logwidget = LogWidget() self.logdockwidget = create_dock(N_('Console'), self) self.logdockwidget.setWidget(self.logwidget) self.logdockwidget.toggleViewAction().setChecked(False) self.logdockwidget.hide() # "Diff Viewer" widget self.diffdockwidget = create_dock(N_('Diff'), self) self.diffeditorwidget = DiffEditorWidget(self.diffdockwidget) self.diffeditor = self.diffeditorwidget.editor self.diffdockwidget.setWidget(self.diffeditorwidget) # All Actions self.unstage_all_action = add_action(self, N_('Unstage All'), cmds.run(cmds.UnstageAll)) self.unstage_all_action.setIcon(qtutils.icon('remove.svg')) self.unstage_selected_action = add_action(self, N_('Unstage From Commit'), cmds.run(cmds.UnstageSelected)) self.unstage_selected_action.setIcon(qtutils.icon('remove.svg')) self.show_diffstat_action = add_action(self, N_('Diffstat'), cmds.run(cmds.Diffstat), 'Alt+D') self.stage_modified_action = add_action(self, N_('Stage Changed Files To Commit'), cmds.run(cmds.StageModified), 'Alt+A') self.stage_modified_action.setIcon(qtutils.icon('add.svg')) self.stage_untracked_action = add_action(self, N_('Stage All Untracked'), cmds.run(cmds.StageUntracked), 'Alt+U') self.stage_untracked_action.setIcon(qtutils.icon('add.svg')) self.apply_patches_action = add_action(self, N_('Apply Patches...'), apply_patches) self.export_patches_action = add_action(self, N_('Export Patches...'), guicmds.export_patches, 'Alt+E') self.new_repository_action = add_action(self, N_('New Repository...'), guicmds.open_new_repo) self.new_repository_action.setIcon(qtutils.new_icon()) self.preferences_action = add_action(self, N_('Preferences'), self.preferences, QtGui.QKeySequence.Preferences) self.edit_remotes_action = add_action(self, N_('Edit Remotes...'), lambda: editremotes.remote_editor().exec_()) self.rescan_action = add_action(self, cmds.Refresh.name(), cmds.run(cmds.Refresh), cmds.Refresh.SHORTCUT) self.rescan_action.setIcon(qtutils.reload_icon()) self.browse_recently_modified_action = add_action(self, N_('Recently Modified Files...'), browse_recent_files, 'Shift+Ctrl+E') self.cherry_pick_action = add_action(self, N_('Cherry-Pick...'), guicmds.cherry_pick, 'Shift+Ctrl+C') self.load_commitmsg_action = add_action(self, N_('Load Commit Message...'), guicmds.load_commitmsg) self.save_tarball_action = add_action(self, N_('Save As Tarball/Zip...'), self.save_archive) self.quit_action = add_action(self, N_('Quit'), self.close, 'Ctrl+Q') self.grep_action = add_action(self, N_('Grep'), grep, 'Ctrl+G') self.merge_local_action = add_action(self, N_('Merge...'), merge.local_merge, 'Shift+Ctrl+M') self.merge_abort_action = add_action(self, N_('Abort Merge...'), merge.abort_merge) self.fetch_action = add_action(self, N_('Fetch...'), remote.fetch, 'Ctrl+F') self.push_action = add_action(self, N_('Push...'), remote.push, 'Ctrl+P') self.pull_action = add_action(self, N_('Pull...'), remote.pull, 'Shift+Ctrl+P') self.open_repo_action = add_action(self, N_('Open...'), guicmds.open_repo) self.open_repo_action.setIcon(qtutils.open_icon()) self.open_repo_new_action = add_action(self, N_('Open in New Window...'), guicmds.open_repo_in_new_window) self.open_repo_new_action.setIcon(qtutils.open_icon()) self.stash_action = add_action(self, N_('Stash...'), stash, 'Alt+Shift+S') self.clone_repo_action = add_action(self, N_('Clone...'), self.clone_repo) self.clone_repo_action.setIcon(qtutils.git_icon()) self.help_docs_action = add_action(self, N_('Documentation'), resources.show_html_docs, QtGui.QKeySequence.HelpContents) self.help_shortcuts_action = add_action(self, N_('Keyboard Shortcuts'), show_shortcuts, Qt.Key_Question) self.visualize_current_action = add_action(self, N_('Visualize Current Branch...'), cmds.run(cmds.VisualizeCurrent)) self.visualize_all_action = add_action(self, N_('Visualize All Branches...'), cmds.run(cmds.VisualizeAll)) self.search_commits_action = add_action(self, N_('Search...'), search) self.browse_branch_action = add_action(self, N_('Browse Current Branch...'), guicmds.browse_current) self.browse_other_branch_action = add_action(self, N_('Browse Other Branch...'), guicmds.browse_other) self.load_commitmsg_template_action = add_action(self, N_('Get Commit Message Template'), cmds.run(cmds.LoadCommitMessageFromTemplate)) self.help_about_action = add_action(self, N_('About'), launch_about_dialog) self.diff_expression_action = add_action(self, N_('Expression...'), guicmds.diff_expression) self.branch_compare_action = add_action(self, N_('Branches...'), compare_branches) self.create_tag_action = add_action(self, N_('Create Tag...'), create_tag) self.create_branch_action = add_action(self, N_('Create...'), create_new_branch, 'Ctrl+B') self.delete_branch_action = add_action(self, N_('Delete...'), guicmds.delete_branch) self.delete_remote_branch_action = add_action(self, N_('Delete Remote Branch...'), guicmds.delete_remote_branch) self.checkout_branch_action = add_action(self, N_('Checkout...'), guicmds.checkout_branch, 'Alt+B') self.branch_review_action = add_action(self, N_('Review...'), guicmds.review_branch) self.browse_action = add_action(self, N_('File Browser...'), worktree_browser) self.browse_action.setIcon(qtutils.git_icon()) self.dag_action = add_action(self, N_('DAG...'), self.git_dag) self.dag_action.setIcon(qtutils.git_icon()) self.rebase_start_action = add_action(self, N_('Start Interactive Rebase...'), self.rebase_start) self.rebase_edit_todo_action = add_action(self, N_('Edit...'), self.rebase_edit_todo) self.rebase_continue_action = add_action(self, N_('Continue'), self.rebase_continue) self.rebase_skip_action = add_action(self, N_('Skip Current Patch'), self.rebase_skip) self.rebase_abort_action = add_action(self, N_('Abort'), self.rebase_abort) # Relayed actions status_tree = self.statusdockwidget.widget().tree self.addAction(status_tree.delete_untracked_files_action) if not self.browser_dockable: # These shortcuts conflict with those from the # 'Browser' widget so don't register them when # the browser is a dockable tool. self.addAction(status_tree.revert_unstaged_edits_action) self.addAction(status_tree.revert_uncommitted_edits_action) self.addAction(status_tree.up_action) self.addAction(status_tree.down_action) self.addAction(status_tree.process_selection_action) self.lock_layout_action = add_action_bool(self, N_('Lock Layout'), self.set_lock_layout, False) # Create the application menu self.menubar = QtGui.QMenuBar(self) # File Menu self.file_menu = create_menu(N_('File'), self.menubar) self.open_recent_menu = self.file_menu.addMenu(N_('Open Recent')) self.open_recent_menu.setIcon(qtutils.open_icon()) self.file_menu.addAction(self.open_repo_action) self.file_menu.addAction(self.open_repo_new_action) self.file_menu.addAction(self.clone_repo_action) self.file_menu.addAction(self.new_repository_action) self.file_menu.addSeparator() self.file_menu.addAction(self.rescan_action) self.file_menu.addAction(self.edit_remotes_action) self.file_menu.addAction(self.browse_recently_modified_action) self.file_menu.addSeparator() self.file_menu.addAction(self.load_commitmsg_action) self.file_menu.addAction(self.load_commitmsg_template_action) self.file_menu.addSeparator() self.file_menu.addAction(self.apply_patches_action) self.file_menu.addAction(self.export_patches_action) self.file_menu.addAction(self.save_tarball_action) self.file_menu.addSeparator() self.file_menu.addAction(self.preferences_action) self.file_menu.addAction(self.quit_action) self.menubar.addAction(self.file_menu.menuAction()) # Actions menu self.actions_menu = create_menu(N_('Actions'), self.menubar) self.actions_menu.addAction(self.fetch_action) self.actions_menu.addAction(self.push_action) self.actions_menu.addAction(self.pull_action) self.actions_menu.addAction(self.stash_action) self.actions_menu.addSeparator() self.actions_menu.addAction(self.create_tag_action) self.actions_menu.addAction(self.cherry_pick_action) self.actions_menu.addAction(self.merge_local_action) self.actions_menu.addAction(self.merge_abort_action) self.actions_menu.addSeparator() self.actions_menu.addAction(self.grep_action) self.actions_menu.addAction(self.search_commits_action) self.menubar.addAction(self.actions_menu.menuAction()) # Staging Area Menu self.commit_menu = create_menu(N_('Staging Area'), self.menubar) self.commit_menu.setTitle(N_('Staging Area')) self.commit_menu.addAction(self.stage_modified_action) self.commit_menu.addAction(self.stage_untracked_action) self.commit_menu.addSeparator() self.commit_menu.addAction(self.unstage_all_action) self.commit_menu.addAction(self.unstage_selected_action) self.menubar.addAction(self.commit_menu.menuAction()) # Diff Menu self.diff_menu = create_menu(N_('Diff'), self.menubar) self.diff_menu.addAction(self.diff_expression_action) self.diff_menu.addAction(self.branch_compare_action) self.diff_menu.addSeparator() self.diff_menu.addAction(self.show_diffstat_action) self.menubar.addAction(self.diff_menu.menuAction()) # Branch Menu self.branch_menu = create_menu(N_('Branch'), self.menubar) self.branch_menu.addAction(self.branch_review_action) self.branch_menu.addSeparator() self.branch_menu.addAction(self.create_branch_action) self.branch_menu.addAction(self.checkout_branch_action) self.branch_menu.addAction(self.delete_branch_action) self.branch_menu.addAction(self.delete_remote_branch_action) self.branch_menu.addSeparator() self.branch_menu.addAction(self.browse_branch_action) self.branch_menu.addAction(self.browse_other_branch_action) self.branch_menu.addSeparator() self.branch_menu.addAction(self.visualize_current_action) self.branch_menu.addAction(self.visualize_all_action) self.menubar.addAction(self.branch_menu.menuAction()) # Rebase menu self.rebase_menu = create_menu(N_('Rebase'), self.actions_menu) self.rebase_menu.addAction(self.rebase_start_action) self.rebase_menu.addAction(self.rebase_edit_todo_action) self.rebase_menu.addSeparator() self.rebase_menu.addAction(self.rebase_continue_action) self.rebase_menu.addAction(self.rebase_skip_action) self.rebase_menu.addSeparator() self.rebase_menu.addAction(self.rebase_abort_action) self.menubar.addAction(self.rebase_menu.menuAction()) # View Menu self.view_menu = create_menu(N_('View'), self.menubar) self.view_menu.addAction(self.browse_action) self.view_menu.addAction(self.dag_action) self.view_menu.addSeparator() if self.browser_dockable: self.view_menu.addAction(self.browserdockwidget.toggleViewAction()) self.setup_dockwidget_view_menu() self.view_menu.addSeparator() self.view_menu.addAction(self.lock_layout_action) self.menubar.addAction(self.view_menu.menuAction()) # Help Menu self.help_menu = create_menu(N_('Help'), self.menubar) self.help_menu.addAction(self.help_docs_action) self.help_menu.addAction(self.help_shortcuts_action) self.help_menu.addAction(self.help_about_action) self.menubar.addAction(self.help_menu.menuAction()) # Set main menu self.setMenuBar(self.menubar) # Arrange dock widgets left = Qt.LeftDockWidgetArea right = Qt.RightDockWidgetArea bottom = Qt.BottomDockWidgetArea self.addDockWidget(left, self.commitdockwidget) if self.browser_dockable: self.addDockWidget(left, self.browserdockwidget) self.tabifyDockWidget(self.browserdockwidget, self.commitdockwidget) self.addDockWidget(left, self.diffdockwidget) self.addDockWidget(right, self.statusdockwidget) self.addDockWidget(right, self.bookmarksdockwidget) self.addDockWidget(right, self.recentdockwidget) self.addDockWidget(bottom, self.actionsdockwidget) self.addDockWidget(bottom, self.logdockwidget) self.tabifyDockWidget(self.actionsdockwidget, self.logdockwidget) # Listen for model notifications model.add_observer(model.message_updated, self._update) model.add_observer(model.message_mode_changed, lambda x: self._update()) prefs_model.add_observer(prefs_model.message_config_updated, self._config_updated) # Set a default value self.show_cursor_position(1, 0) self.connect(self.open_recent_menu, SIGNAL('aboutToShow()'), self.build_recent_menu) self.connect(self.commitmsgeditor, SIGNAL('cursorPosition(int,int)'), self.show_cursor_position) self.connect(self.diffeditor, SIGNAL('diff_options_updated()'), self.statuswidget.refresh) self.connect(self, SIGNAL('update'), self._update_callback) self.connect(self, SIGNAL('install_config_actions'), self._install_config_actions) # Install .git-config-defined actions self._config_task = None self.install_config_actions() # Restore saved settings if not self.restore_state(settings=settings): self.resize(987, 610) self.set_initial_size() self.statusdockwidget.widget().setFocus() # Route command output here Interaction.log_status = self.logwidget.log_status Interaction.log = self.logwidget.log Interaction.log(version.git_version_str() + '\n' + N_('git cola version %s') % version.version())
def __init__(self, opts, parent): standard.Dialog.__init__(self, parent=parent) self.setWindowModality(QtCore.Qt.WindowModal) self.setAttribute(Qt.WA_MacMetalStyle) self.setWindowTitle(self.tr('Create Tag')) self.opts = opts self.main_layt = QtGui.QVBoxLayout(self) self.main_layt.setContentsMargins(6, 12, 6, 6) # Form layout for inputs self.input_form_layt = QtGui.QFormLayout() self.input_form_layt.setFieldGrowthPolicy(QtGui.QFormLayout.ExpandingFieldsGrow) # Tag label self.tag_name_label = QtGui.QLabel(self) self.tag_name_label.setText(self.tr('Name')) self.input_form_layt.setWidget(0, QtGui.QFormLayout.LabelRole, self.tag_name_label) self.tag_name = text.HintedLineEdit('vX.Y.Z', self) self.tag_name.setToolTip(self.tr('Specifies the tag name')) self.input_form_layt.setWidget(0, QtGui.QFormLayout.FieldRole, self.tag_name) # Sign Tag self.sign_label = QtGui.QLabel(self) self.sign_label.setText(self.tr('Sign Tag')) self.input_form_layt.setWidget(1, QtGui.QFormLayout.LabelRole, self.sign_label) self.sign_tag = QtGui.QCheckBox(self) self.sign_tag.setToolTip( self.tr('Whether to sign the tag (git tag -s)')) self.input_form_layt.setWidget(1, QtGui.QFormLayout.FieldRole, self.sign_tag) self.main_layt.addLayout(self.input_form_layt) # Tag message self.tag_msg_label = QtGui.QLabel(self) self.tag_msg_label.setText(self.tr('Message')) self.input_form_layt.setWidget(2, QtGui.QFormLayout.LabelRole, self.tag_msg_label) self.tag_msg = text.HintedTextEdit('Tag message...', self) self.tag_msg.setToolTip(self.tr('Specifies the tag message')) self.tag_msg.enable_hint(True) self.input_form_layt.setWidget(2, QtGui.QFormLayout.FieldRole, self.tag_msg) # Revision self.rev_label = QtGui.QLabel(self) self.rev_label.setText(self.tr('Revision')) self.input_form_layt.setWidget(3, QtGui.QFormLayout.LabelRole, self.rev_label) self.revision = completion.GitRefLineEdit() self.revision.setText(self.opts.revision) self.revision.setToolTip(self.tr('Specifies the SHA-1 to tag')) self.input_form_layt.setWidget(3, QtGui.QFormLayout.FieldRole, self.revision) # Buttons self.button_hbox_layt = QtGui.QHBoxLayout() self.button_hbox_layt.addStretch() self.create_button = qt.create_button(text='Create Tag', icon=qtutils.git_icon()) self.button_hbox_layt.addWidget(self.create_button) self.main_layt.addLayout(self.button_hbox_layt) self.close_button = qt.create_button(text='Close') self.button_hbox_layt.addWidget(self.close_button) connect_button(self.close_button, self.accept) connect_button(self.create_button, self.create_tag) self.resize(506, 295)
def action_callback(self): action = self.action if action == FETCH: model_action = self.model.fetch elif action == PUSH: model_action = self.push_to_all else: # if action == PULL: model_action = self.model.pull remote_name = ustr(self.remote_name.text()) if not remote_name: errmsg = N_('No repository selected.') Interaction.log(errmsg) return remote, kwargs = self.common_args() self.selected_remotes = qtutils.selected_items(self.remotes, self.model.remotes) # Check if we're about to create a new branch and warn. remote_branch = ustr(self.remote_branch.text()) local_branch = ustr(self.local_branch.text()) if action == PUSH and not remote_branch: branch = local_branch candidate = '%s/%s' % (remote, branch) if candidate not in self.model.remote_branches: title = N_('Push') args = dict(branch=branch, remote=remote) msg = N_('Branch "%(branch)s" does not exist in "%(remote)s".\n' 'A new remote branch will be published.') % args info_txt= N_('Create a new remote branch?') ok_text = N_('Create Remote Branch') if not qtutils.confirm(title, msg, info_txt, ok_text, default=False, icon=qtutils.git_icon()): return if not self.ffwd_only_checkbox.isChecked(): if action == FETCH: title = N_('Force Fetch?') msg = N_('Non-fast-forward fetch overwrites local history!') info_txt = N_('Force fetching from %s?') % remote ok_text = N_('Force Fetch') elif action == PUSH: title = N_('Force Push?') msg = N_('Non-fast-forward push overwrites published ' 'history!\n(Did you pull first?)') info_txt = N_('Force push to %s?') % remote ok_text = N_('Force Push') else: # pull: shouldn't happen since the controls are hidden msg = "You probably don't want to do this.\n\tContinue?" return if not qtutils.confirm(title, msg, info_txt, ok_text, default=False, icon=qtutils.discard_icon()): return # Disable the GUI by default self.action_button.setEnabled(False) self.close_button.setEnabled(False) # Use a thread to update in the background task = ActionTask(self.task_runner, model_action, remote, kwargs) self.task_runner.start(task, progress=self.progress, finish=self.action_completed)
def __init__(self, parent=None): QtGui.QTreeWidget.__init__(self, parent) self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) self.headerItem().setHidden(True) self.setAllColumnsShowFocus(True) self.setSortingEnabled(False) self.setUniformRowHeights(True) self.setAnimated(True) self.setRootIsDecorated(False) self.setIndentation(0) self.setDragEnabled(True) self.add_item(N_('Staged'), hide=True) self.add_item(N_('Unmerged'), hide=True) self.add_item(N_('Modified'), hide=True) self.add_item(N_('Untracked'), hide=True) # Used to restore the selection self.old_scroll = None self.old_selection = None self.old_contents = None self.old_current_item = None self.expanded_items = set() self.process_selection_action = qtutils.add_action(self, cmds.StageOrUnstage.name(), cmds.run(cmds.StageOrUnstage), hotkeys.STAGE_SELECTION) self.revert_unstaged_edits_action = qtutils.add_action(self, cmds.RevertUnstagedEdits.name(), cmds.run(cmds.RevertUnstagedEdits), hotkeys.REVERT) icon = qtutils.theme_icon('edit-undo.svg') self.revert_unstaged_edits_action.setIcon(icon) self.launch_difftool_action = qtutils.add_action(self, cmds.LaunchDifftool.name(), cmds.run(cmds.LaunchDifftool), hotkeys.DIFF) self.launch_difftool_action.setIcon(qtutils.git_icon()) self.launch_editor_action = qtutils.add_action(self, cmds.LaunchEditor.name(), cmds.run(cmds.LaunchEditor), hotkeys.EDIT, *hotkeys.ACCEPT) self.launch_editor_action.setIcon(qtutils.options_icon()) if not utils.is_win32(): self.open_using_default_app = qtutils.add_action(self, cmds.OpenDefaultApp.name(), self._open_using_default_app, hotkeys.PRIMARY_ACTION) self.open_using_default_app.setIcon(qtutils.file_icon()) self.open_parent_dir_action = qtutils.add_action(self, cmds.OpenParentDir.name(), self._open_parent_dir, hotkeys.SECONDARY_ACTION) self.open_parent_dir_action.setIcon(qtutils.open_file_icon()) self.up_action = qtutils.add_action(self, N_('Move Up'), self.move_up, hotkeys.MOVE_UP, hotkeys.MOVE_UP_SECONDARY) self.down_action = qtutils.add_action(self, N_('Move Down'), self.move_down, hotkeys.MOVE_DOWN, hotkeys.MOVE_DOWN_SECONDARY) self.copy_path_action = qtutils.add_action(self, N_('Copy Path to Clipboard'), self.copy_path, hotkeys.COPY) self.copy_path_action.setIcon(qtutils.theme_icon('edit-copy.svg')) self.copy_relpath_action = qtutils.add_action(self, N_('Copy Relative Path to Clipboard'), self.copy_relpath, hotkeys.CUT) self.copy_relpath_action.setIcon(qtutils.theme_icon('edit-copy.svg')) self.view_history_action = qtutils.add_action(self, N_('View History...'), self.view_history, hotkeys.HISTORY) # MoveToTrash and Delete use the same shortcut. # We will only bind one of them, depending on whether or not the # MoveToTrash command is avaialble. When available, the hotkey # is bound to MoveToTrash, otherwise it is bound to Delete. if cmds.MoveToTrash.AVAILABLE: self.move_to_trash_action = qtutils.add_action(self, N_('Move file(s) to trash'), self._trash_untracked_files, hotkeys.TRASH) self.move_to_trash_action.setIcon(qtutils.discard_icon()) delete_shortcut = hotkeys.DELETE_FILE else: self.move_to_trash_action = None delete_shortcut = hotkeys.DELETE_FILE_SECONDARY self.delete_untracked_files_action = qtutils.add_action(self, N_('Delete File(s)...'), self._delete_untracked_files, delete_shortcut) self.delete_untracked_files_action.setIcon(qtutils.discard_icon()) self.connect(self, SIGNAL('about_to_update()'), self._about_to_update, Qt.QueuedConnection) self.connect(self, SIGNAL('updated()'), self._updated, Qt.QueuedConnection) self.m = main.model() self.m.add_observer(self.m.message_about_to_update, self.about_to_update) self.m.add_observer(self.m.message_updated, self.updated) self.connect(self, SIGNAL('itemSelectionChanged()'), self.show_selection) self.connect(self, SIGNAL('itemDoubleClicked(QTreeWidgetItem*,int)'), self.double_clicked) self.connect(self, SIGNAL('itemCollapsed(QTreeWidgetItem*)'), lambda x: self.update_column_widths()) self.connect(self, SIGNAL('itemExpanded(QTreeWidgetItem*)'), lambda x: self.update_column_widths())
def launch_difftool(widget): icon = qtutils.git_icon() return cmd_action(widget, cmds.LaunchDifftool, icon)
def __init__(self, model, parent=None, settings=None): MainWindow.__init__(self, parent) self.setAttribute(Qt.WA_MacMetalStyle) # Default size; this is thrown out when save/restore is used self.model = model self.settings = settings self.prefs_model = prefs_model = prefs.PreferencesModel() # The widget version is used by import/export_state(). # Change this whenever dockwidgets are removed. self.widget_version = 2 # Keeps track of merge messages we've seen self.merge_message_hash = '' cfg = gitcfg.instance() self.browser_dockable = (cfg.get('cola.browserdockable') or cfg.get('cola.classicdockable')) if self.browser_dockable: self.browserdockwidget = create_dock(N_('Browser'), self) self.browserwidget = worktree_browser_widget(self) self.browserdockwidget.setWidget(self.browserwidget) # "Actions" widget self.actionsdockwidget = create_dock(N_('Actions'), self) self.actionsdockwidgetcontents = action.ActionButtons(self) self.actionsdockwidget.setWidget(self.actionsdockwidgetcontents) self.actionsdockwidget.toggleViewAction().setChecked(False) self.actionsdockwidget.hide() # "Repository Status" widget self.statuswidget = StatusWidget(self) self.statusdockwidget = create_dock(N_('Status'), self) self.statusdockwidget.setWidget(self.statuswidget) # "Switch Repository" widget self.bookmarksdockwidget = create_dock(N_('Bookmarks'), self) self.bookmarkswidget = BookmarksWidget(parent=self.bookmarksdockwidget) self.bookmarksdockwidget.setWidget(self.bookmarkswidget) # "Commit Message Editor" widget self.position_label = QtGui.QLabel() font = qtutils.default_monospace_font() font.setPointSize(int(font.pointSize() * 0.8)) self.position_label.setFont(font) # make the position label fixed size to avoid layout issues fm = self.position_label.fontMetrics() width = fm.width('999:999') height = self.position_label.sizeHint().height() self.position_label.setFixedSize(width, height) self.commitdockwidget = create_dock(N_('Commit'), self) titlebar = self.commitdockwidget.titleBarWidget() titlebar.add_corner_widget(self.position_label) self.commitmsgeditor = CommitMessageEditor(model, self) self.commitdockwidget.setWidget(self.commitmsgeditor) # "Console" widget self.logwidget = LogWidget() self.logdockwidget = create_dock(N_('Console'), self) self.logdockwidget.setWidget(self.logwidget) self.logdockwidget.toggleViewAction().setChecked(False) self.logdockwidget.hide() # "Diff Viewer" widget self.diffdockwidget = create_dock(N_('Diff'), self) self.diffeditor = DiffEditor(self.diffdockwidget) self.diffdockwidget.setWidget(self.diffeditor) # All Actions self.unstage_all_action = add_action(self, N_('Unstage All'), cmds.run(cmds.UnstageAll)) self.unstage_all_action.setIcon(qtutils.icon('remove.svg')) self.unstage_selected_action = add_action( self, N_('Unstage From Commit'), cmds.run(cmds.UnstageSelected)) self.unstage_selected_action.setIcon(qtutils.icon('remove.svg')) self.show_diffstat_action = add_action(self, N_('Diffstat'), cmds.run(cmds.Diffstat), 'Alt+D') self.stage_modified_action = add_action( self, N_('Stage Changed Files To Commit'), cmds.run(cmds.StageModified), 'Alt+A') self.stage_modified_action.setIcon(qtutils.icon('add.svg')) self.stage_untracked_action = add_action(self, N_('Stage All Untracked'), cmds.run(cmds.StageUntracked), 'Alt+U') self.stage_untracked_action.setIcon(qtutils.icon('add.svg')) self.apply_patches_action = add_action(self, N_('Apply Patches...'), apply_patches) self.export_patches_action = add_action(self, N_('Export Patches...'), guicmds.export_patches, 'Alt+E') self.new_repository_action = add_action(self, N_('New Repository...'), guicmds.open_new_repo) self.new_repository_action.setIcon(qtutils.new_icon()) self.preferences_action = add_action(self, N_('Preferences'), self.preferences, QtGui.QKeySequence.Preferences, 'Ctrl+O') self.edit_remotes_action = add_action( self, N_('Edit Remotes...'), lambda: editremotes.remote_editor().exec_()) self.rescan_action = add_action(self, cmds.Refresh.name(), cmds.run(cmds.Refresh), cmds.Refresh.SHORTCUT) self.rescan_action.setIcon(qtutils.reload_icon()) self.browse_recently_modified_action = add_action( self, N_('Recently Modified Files...'), browse_recent_files, 'Shift+Ctrl+E') self.cherry_pick_action = add_action(self, N_('Cherry-Pick...'), guicmds.cherry_pick, 'Shift+Ctrl+C') self.load_commitmsg_action = add_action(self, N_('Load Commit Message...'), guicmds.load_commitmsg) self.save_tarball_action = add_action(self, N_('Save As Tarball/Zip...'), self.save_archive) self.quit_action = add_action(self, N_('Quit'), self.close, 'Ctrl+Q') self.manage_bookmarks_action = add_action(self, N_('Bookmarks...'), self.manage_bookmarks) self.grep_action = add_action(self, N_('Grep'), grep, 'Ctrl+G') self.merge_local_action = add_action(self, N_('Merge...'), merge.local_merge) self.merge_abort_action = add_action(self, N_('Abort Merge...'), merge.abort_merge) self.fetch_action = add_action(self, N_('Fetch...'), remote.fetch, 'Ctrl+F') self.push_action = add_action(self, N_('Push...'), remote.push, 'Ctrl+P') self.pull_action = add_action(self, N_('Pull...'), remote.pull, 'Shift+Ctrl+P') self.open_repo_action = add_action(self, N_('Open...'), guicmds.open_repo) self.open_repo_action.setIcon(qtutils.open_icon()) self.open_repo_new_action = add_action(self, N_('Open in New Window...'), guicmds.open_repo_in_new_window) self.open_repo_new_action.setIcon(qtutils.open_icon()) self.stash_action = add_action(self, N_('Stash...'), stash, 'Alt+Shift+S') self.clone_repo_action = add_action(self, N_('Clone...'), guicmds.clone_repo) self.clone_repo_action.setIcon(qtutils.git_icon()) self.help_docs_action = add_action(self, N_('Documentation'), resources.show_html_docs, QtGui.QKeySequence.HelpContents) self.help_shortcuts_action = add_action(self, N_('Keyboard Shortcuts'), show_shortcuts, QtCore.Qt.Key_Question) self.visualize_current_action = add_action( self, N_('Visualize Current Branch...'), cmds.run(cmds.VisualizeCurrent)) self.visualize_all_action = add_action(self, N_('Visualize All Branches...'), cmds.run(cmds.VisualizeAll)) self.search_commits_action = add_action(self, N_('Search...'), search) self.browse_branch_action = add_action(self, N_('Browse Current Branch...'), guicmds.browse_current) self.browse_other_branch_action = add_action( self, N_('Browse Other Branch...'), guicmds.browse_other) self.load_commitmsg_template_action = add_action( self, N_('Get Commit Message Template'), cmds.run(cmds.LoadCommitMessageFromTemplate)) self.help_about_action = add_action(self, N_('About'), launch_about_dialog) self.diff_expression_action = add_action(self, N_('Expression...'), guicmds.diff_expression) self.branch_compare_action = add_action(self, N_('Branches...'), compare_branches) self.create_tag_action = add_action(self, N_('Create Tag...'), create_tag) self.create_branch_action = add_action(self, N_('Create...'), create_new_branch, 'Ctrl+B') self.delete_branch_action = add_action(self, N_('Delete...'), guicmds.delete_branch) self.delete_remote_branch_action = add_action( self, N_('Delete Remote Branch...'), guicmds.delete_remote_branch) self.checkout_branch_action = add_action(self, N_('Checkout...'), guicmds.checkout_branch, 'Alt+B') self.branch_review_action = add_action(self, N_('Review...'), guicmds.review_branch) self.browse_action = add_action(self, N_('File Browser...'), worktree_browser) self.browse_action.setIcon(qtutils.git_icon()) self.dag_action = add_action(self, N_('DAG...'), self.git_dag) self.dag_action.setIcon(qtutils.git_icon()) self.rebase_start_action = add_action( self, N_('Start Interactive Rebase...'), self.rebase_start) self.rebase_edit_todo_action = add_action(self, N_('Edit...'), self.rebase_edit_todo) self.rebase_continue_action = add_action(self, N_('Continue'), self.rebase_continue) self.rebase_skip_action = add_action(self, N_('Skip Current Patch'), self.rebase_skip) self.rebase_abort_action = add_action(self, N_('Abort'), self.rebase_abort) # Relayed actions status_tree = self.statusdockwidget.widget().tree self.addAction(status_tree.revert_unstaged_edits_action) self.addAction(status_tree.delete_untracked_files_action) if not self.browser_dockable: # These shortcuts conflict with those from the # 'Browser' widget so don't register them when # the browser is a dockable tool. self.addAction(status_tree.up_action) self.addAction(status_tree.down_action) self.addAction(status_tree.process_selection_action) self.lock_layout_action = add_action_bool(self, N_('Lock Layout'), self.set_lock_layout, False) # Create the application menu self.menubar = QtGui.QMenuBar(self) # File Menu self.file_menu = create_menu(N_('File'), self.menubar) self.open_recent_menu = self.file_menu.addMenu(N_('Open Recent')) self.open_recent_menu.setIcon(qtutils.open_icon()) self.file_menu.addAction(self.open_repo_action) self.file_menu.addAction(self.open_repo_new_action) self.file_menu.addAction(self.clone_repo_action) self.file_menu.addAction(self.new_repository_action) self.file_menu.addSeparator() self.file_menu.addAction(self.rescan_action) self.file_menu.addAction(self.edit_remotes_action) self.file_menu.addAction(self.browse_recently_modified_action) self.file_menu.addAction(self.manage_bookmarks_action) self.file_menu.addSeparator() self.file_menu.addAction(self.load_commitmsg_action) self.file_menu.addAction(self.load_commitmsg_template_action) self.file_menu.addSeparator() self.file_menu.addAction(self.apply_patches_action) self.file_menu.addAction(self.export_patches_action) self.file_menu.addAction(self.save_tarball_action) self.file_menu.addSeparator() self.file_menu.addAction(self.preferences_action) self.file_menu.addAction(self.quit_action) self.menubar.addAction(self.file_menu.menuAction()) # Actions menu self.actions_menu = create_menu(N_('Actions'), self.menubar) self.actions_menu.addAction(self.fetch_action) self.actions_menu.addAction(self.push_action) self.actions_menu.addAction(self.pull_action) self.actions_menu.addAction(self.stash_action) self.actions_menu.addSeparator() self.actions_menu.addAction(self.create_tag_action) self.actions_menu.addAction(self.cherry_pick_action) self.actions_menu.addAction(self.merge_local_action) self.actions_menu.addAction(self.merge_abort_action) self.actions_menu.addSeparator() self.actions_menu.addAction(self.grep_action) self.actions_menu.addAction(self.search_commits_action) self.menubar.addAction(self.actions_menu.menuAction()) # Staging Area Menu self.commit_menu = create_menu(N_('Staging Area'), self.menubar) self.commit_menu.setTitle(N_('Staging Area')) self.commit_menu.addAction(self.stage_modified_action) self.commit_menu.addAction(self.stage_untracked_action) self.commit_menu.addSeparator() self.commit_menu.addAction(self.unstage_all_action) self.commit_menu.addAction(self.unstage_selected_action) self.menubar.addAction(self.commit_menu.menuAction()) # Diff Menu self.diff_menu = create_menu(N_('Diff'), self.menubar) self.diff_menu.addAction(self.diff_expression_action) self.diff_menu.addAction(self.branch_compare_action) self.diff_menu.addSeparator() self.diff_menu.addAction(self.show_diffstat_action) self.menubar.addAction(self.diff_menu.menuAction()) # Branch Menu self.branch_menu = create_menu(N_('Branch'), self.menubar) self.branch_menu.addAction(self.branch_review_action) self.branch_menu.addSeparator() self.branch_menu.addAction(self.create_branch_action) self.branch_menu.addAction(self.checkout_branch_action) self.branch_menu.addAction(self.delete_branch_action) self.branch_menu.addAction(self.delete_remote_branch_action) self.branch_menu.addSeparator() self.branch_menu.addAction(self.browse_branch_action) self.branch_menu.addAction(self.browse_other_branch_action) self.branch_menu.addSeparator() self.branch_menu.addAction(self.visualize_current_action) self.branch_menu.addAction(self.visualize_all_action) self.menubar.addAction(self.branch_menu.menuAction()) # Rebase menu self.rebase_menu = create_menu(N_('Rebase'), self.actions_menu) self.rebase_menu.addAction(self.rebase_start_action) self.rebase_menu.addAction(self.rebase_edit_todo_action) self.rebase_menu.addSeparator() self.rebase_menu.addAction(self.rebase_continue_action) self.rebase_menu.addAction(self.rebase_skip_action) self.rebase_menu.addSeparator() self.rebase_menu.addAction(self.rebase_abort_action) self.menubar.addAction(self.rebase_menu.menuAction()) # View Menu self.view_menu = create_menu(N_('View'), self.menubar) self.view_menu.addAction(self.browse_action) self.view_menu.addAction(self.dag_action) self.view_menu.addSeparator() if self.browser_dockable: self.view_menu.addAction(self.browserdockwidget.toggleViewAction()) self.setup_dockwidget_view_menu() self.view_menu.addSeparator() self.view_menu.addAction(self.lock_layout_action) self.menubar.addAction(self.view_menu.menuAction()) # Help Menu self.help_menu = create_menu(N_('Help'), self.menubar) self.help_menu.addAction(self.help_docs_action) self.help_menu.addAction(self.help_shortcuts_action) self.help_menu.addAction(self.help_about_action) self.menubar.addAction(self.help_menu.menuAction()) # Set main menu self.setMenuBar(self.menubar) # Arrange dock widgets left = Qt.LeftDockWidgetArea right = Qt.RightDockWidgetArea bottom = Qt.BottomDockWidgetArea self.addDockWidget(left, self.commitdockwidget) if self.browser_dockable: self.addDockWidget(left, self.browserdockwidget) self.tabifyDockWidget(self.browserdockwidget, self.commitdockwidget) self.addDockWidget(left, self.diffdockwidget) self.addDockWidget(right, self.statusdockwidget) self.addDockWidget(right, self.bookmarksdockwidget) self.addDockWidget(bottom, self.actionsdockwidget) self.addDockWidget(bottom, self.logdockwidget) self.tabifyDockWidget(self.actionsdockwidget, self.logdockwidget) # Listen for model notifications model.add_observer(model.message_updated, self._update) model.add_observer(model.message_mode_changed, lambda x: self._update()) prefs_model.add_observer(prefs_model.message_config_updated, self._config_updated) # Set a default value self.show_cursor_position(1, 0) self.connect(self.open_recent_menu, SIGNAL('aboutToShow()'), self.build_recent_menu) self.connect(self.commitmsgeditor, SIGNAL('cursorPosition(int,int)'), self.show_cursor_position) self.connect(self.diffeditor, SIGNAL('diff_options_updated()'), self.statuswidget.refresh) self.connect(self, SIGNAL('update'), self._update_callback) self.connect(self, SIGNAL('install_config_actions'), self._install_config_actions) # Install .git-config-defined actions self._config_task = None self.install_config_actions() # Restore saved settings if not self.restore_state(settings=settings): self.resize(987, 610) self.set_initial_size() self.statusdockwidget.widget().setFocus() # Route command output here Interaction.log_status = self.logwidget.log_status Interaction.log = self.logwidget.log Interaction.log(version.git_version_str() + '\n' + N_('git cola version %s') % version.version())
def __init__(self, model, parent): MainWindow.__init__(self, parent) # Default size; this is thrown out when save/restore is used self.resize(987, 610) self.model = model self.prefs_model = prefs_model = prefs.PreferencesModel() # Internal field used by import/export_state(). # Change this whenever dockwidgets are removed. self.widget_version = 2 # Keeps track of merge messages we've seen self.merge_message_hash = '' self.setAcceptDrops(True) self.setAttribute(Qt.WA_MacMetalStyle) cfg = gitcfg.instance() self.classic_dockable = (cfg.get('cola.browserdockable') or cfg.get('cola.classicdockable')) if self.classic_dockable: self.classicdockwidget = create_dock(N_('Browser'), self) self.classicwidget = classic_widget(self) self.classicdockwidget.setWidget(self.classicwidget) # "Actions" widget self.actionsdockwidget = create_dock(N_('Action'), self) self.actionsdockwidgetcontents = action.ActionButtons(self) self.actionsdockwidget.setWidget(self.actionsdockwidgetcontents) self.actionsdockwidget.toggleViewAction().setChecked(False) self.actionsdockwidget.hide() # "Repository Status" widget self.statuswidget = StatusWidget(self) self.statusdockwidget = create_dock(N_('Status'), self) self.statusdockwidget.setWidget(self.statuswidget) # "Commit Message Editor" widget self.position_label = QtGui.QLabel() font = qtutils.default_monospace_font() font.setPointSize(int(font.pointSize() * 0.8)) self.position_label.setFont(font) self.commitdockwidget = create_dock(N_('Commit'), self) titlebar = self.commitdockwidget.titleBarWidget() titlebar.add_corner_widget(self.position_label) self.commitmsgeditor = CommitMessageEditor(model, self) self.commitdockwidget.setWidget(self.commitmsgeditor) # "Console" widget self.logwidget = LogWidget() self.logdockwidget = create_dock(N_('Console'), self) self.logdockwidget.setWidget(self.logwidget) self.logdockwidget.toggleViewAction().setChecked(False) self.logdockwidget.hide() # "Diff Viewer" widget self.diffdockwidget = create_dock(N_('Diff'), self) self.diffeditor = DiffEditor(self.diffdockwidget) self.diffdockwidget.setWidget(self.diffeditor) # "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_toolbutton(text=N_('Options'), icon=options_icon(), tooltip=N_('Diff Options')) 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) self.diffopts_button.setPopupMode(QtGui.QToolButton.InstantPopup) titlebar = self.diffdockwidget.titleBarWidget() titlebar.add_corner_widget(self.diffopts_button) # All Actions self.menu_unstage_all = add_action(self, N_('Unstage All'), cmds.run(cmds.UnstageAll)) self.menu_unstage_all.setIcon(qtutils.icon('remove.svg')) self.menu_unstage_selected = add_action(self, N_('Unstage From Commit'), cmds.run(cmds.UnstageSelected)) self.menu_unstage_selected.setIcon(qtutils.icon('remove.svg')) self.menu_show_diffstat = add_action(self, N_('Diffstat'), cmds.run(cmds.Diffstat), 'Alt+D') self.menu_stage_modified = add_action(self, N_('Stage Changed Files To Commit'), cmds.run(cmds.StageModified), 'Alt+A') self.menu_stage_modified.setIcon(qtutils.icon('add.svg')) self.menu_stage_untracked = add_action(self, N_('Stage All Untracked'), cmds.run(cmds.StageUntracked), 'Alt+U') self.menu_stage_untracked.setIcon(qtutils.icon('add.svg')) self.menu_export_patches = add_action(self, N_('Export Patches...'), guicmds.export_patches, 'Alt+E') self.menu_preferences = add_action(self, N_('Preferences'), self.preferences, QtGui.QKeySequence.Preferences, 'Ctrl+O') self.menu_edit_remotes = add_action(self, N_('Edit Remotes...'), lambda: editremotes.edit().exec_()) self.menu_rescan = add_action(self, cmds.Refresh.name(), cmds.run(cmds.Refresh), cmds.Refresh.SHORTCUT) self.menu_rescan.setIcon(qtutils.reload_icon()) self.menu_browse_recent = add_action(self, N_('Recently Modified Files...'), browse_recent, 'Shift+Ctrl+E') self.menu_cherry_pick = add_action(self, N_('Cherry-Pick...'), guicmds.cherry_pick, 'Ctrl+P') self.menu_load_commitmsg = add_action(self, N_('Load Commit Message...'), guicmds.load_commitmsg) self.menu_save_tarball = add_action(self, N_('Save As Tarball/Zip...'), self.save_archive) self.menu_quit = add_action(self, N_('Quit'), self.close, 'Ctrl+Q') self.menu_manage_bookmarks = add_action(self, N_('Bookmarks...'), manage_bookmarks) self.menu_grep = add_action(self, N_('Grep'), guicmds.grep, 'Ctrl+G') self.menu_merge_local = add_action(self, N_('Merge...'), merge.local_merge) self.menu_merge_abort = add_action(self, N_('Abort Merge...'), merge.abort_merge) self.menu_fetch = add_action(self, N_('Fetch...'), remote.fetch) self.menu_push = add_action(self, N_('Push...'), remote.push) self.menu_pull = add_action(self, N_('Pull...'), remote.pull) self.menu_open_repo = add_action(self, N_('Open...'), guicmds.open_repo) self.menu_open_repo.setIcon(qtutils.open_icon()) self.menu_stash = add_action(self, N_('Stash...'), stash.stash, 'Alt+Shift+S') self.menu_clone_repo = add_action(self, N_('Clone...'), guicmds.clone_repo) self.menu_clone_repo.setIcon(qtutils.git_icon()) self.menu_help_docs = add_action(self, N_('Documentation'), resources.show_html_docs, QtGui.QKeySequence.HelpContents) self.menu_help_shortcuts = add_action(self, N_('Keyboard Shortcuts'), show_shortcuts, QtCore.Qt.Key_Question) self.menu_visualize_current = add_action(self, N_('Visualize Current Branch...'), cmds.run(cmds.VisualizeCurrent)) self.menu_visualize_all = add_action(self, N_('Visualize All Branches...'), cmds.run(cmds.VisualizeAll)) self.menu_search_commits = add_action(self, N_('Search...'), search) self.menu_browse_branch = add_action(self, N_('Browse Current Branch...'), guicmds.browse_current) self.menu_browse_other_branch = add_action(self, N_('Browse Other Branch...'), guicmds.browse_other) self.menu_load_commitmsg_template = add_action(self, N_('Get Commit Message Template'), cmds.run(cmds.LoadCommitTemplate)) self.menu_help_about = add_action(self, N_('About'), launch_about_dialog) self.menu_diff_expression = add_action(self, N_('Expression...'), guicmds.diff_expression) self.menu_branch_compare = add_action(self, N_('Branches...'), compare_branches) self.menu_create_tag = add_action(self, N_('Create Tag...'), create_tag) self.menu_create_branch = add_action(self, N_('Create...'), create_new_branch, 'Ctrl+B') self.menu_delete_branch = add_action(self, N_('Delete...'), guicmds.delete_branch) self.menu_delete_remote_branch = add_action(self, N_('Delete Remote Branch...'), guicmds.delete_remote_branch) self.menu_checkout_branch = add_action(self, N_('Checkout...'), guicmds.checkout_branch, 'Alt+B') self.menu_rebase_branch = add_action(self, N_('Rebase...'), guicmds.rebase) self.menu_branch_review = add_action(self, N_('Review...'), guicmds.review_branch) self.menu_classic = add_action(self, N_('Browser...'), cola_classic) self.menu_classic.setIcon(qtutils.git_icon()) self.menu_dag = add_action(self, N_('DAG...'), lambda: git_dag(self.model).show()) self.menu_dag.setIcon(qtutils.git_icon()) # Relayed actions if not self.classic_dockable: # These shortcuts conflict with those from the # 'Browser' widget so don't register them when # the browser is a dockable tool. status_tree = self.statusdockwidget.widget().tree self.addAction(status_tree.up) self.addAction(status_tree.down) self.addAction(status_tree.process_selection) # Create the application menu self.menubar = QtGui.QMenuBar(self) # File Menu self.file_menu = create_menu(N_('File'), self.menubar) self.file_menu.addAction(self.menu_preferences) self.file_menu.addSeparator() self.file_menu.addAction(self.menu_open_repo) self.menu_open_recent = self.file_menu.addMenu(N_('Open Recent')) self.file_menu.addSeparator() self.file_menu.addAction(self.menu_clone_repo) self.file_menu.addAction(self.menu_manage_bookmarks) self.file_menu.addSeparator() self.file_menu.addAction(self.menu_edit_remotes) self.file_menu.addAction(self.menu_rescan) self.file_menu.addSeparator() self.file_menu.addAction(self.menu_browse_recent) self.file_menu.addSeparator() self.file_menu.addAction(self.menu_load_commitmsg) self.file_menu.addAction(self.menu_load_commitmsg_template) self.file_menu.addSeparator() self.file_menu.addAction(self.menu_save_tarball) self.file_menu.addAction(self.menu_export_patches) self.file_menu.addAction(self.menu_quit) # Add to menubar self.menubar.addAction(self.file_menu.menuAction()) # Commit Menu self.commit_menu = create_menu(N_('Index'), self.menubar) self.commit_menu.setTitle(N_('Index')) self.commit_menu.addAction(self.menu_stage_modified) self.commit_menu.addAction(self.menu_stage_untracked) self.commit_menu.addSeparator() self.commit_menu.addAction(self.menu_unstage_all) self.commit_menu.addAction(self.menu_unstage_selected) # Add to menubar self.menubar.addAction(self.commit_menu.menuAction()) # Branch Menu self.branch_menu = create_menu(N_('Branch'), self.menubar) self.branch_menu.addAction(self.menu_branch_review) self.branch_menu.addSeparator() self.branch_menu.addAction(self.menu_create_branch) self.branch_menu.addAction(self.menu_checkout_branch) self.branch_menu.addAction(self.menu_rebase_branch) self.branch_menu.addAction(self.menu_delete_branch) self.branch_menu.addAction(self.menu_delete_remote_branch) self.branch_menu.addSeparator() self.branch_menu.addAction(self.menu_browse_branch) self.branch_menu.addAction(self.menu_browse_other_branch) self.branch_menu.addSeparator() self.branch_menu.addAction(self.menu_visualize_current) self.branch_menu.addAction(self.menu_visualize_all) # Add to menubar self.menubar.addAction(self.branch_menu.menuAction()) # Actions menu self.actions_menu = create_menu(N_('Actions'), self.menubar) self.actions_menu.addAction(self.menu_fetch) self.actions_menu.addAction(self.menu_push) self.actions_menu.addAction(self.menu_pull) self.actions_menu.addAction(self.menu_stash) self.actions_menu.addSeparator() self.actions_menu.addAction(self.menu_create_tag) self.actions_menu.addAction(self.menu_cherry_pick) self.actions_menu.addAction(self.menu_merge_local) self.actions_menu.addAction(self.menu_merge_abort) self.actions_menu.addSeparator() self.actions_menu.addAction(self.menu_grep) self.actions_menu.addAction(self.menu_search_commits) # Add to menubar self.menubar.addAction(self.actions_menu.menuAction()) # Diff Menu self.diff_menu = create_menu(N_('Diff'), self.menubar) self.diff_menu.addAction(self.menu_diff_expression) self.diff_menu.addAction(self.menu_branch_compare) self.diff_menu.addSeparator() self.diff_menu.addAction(self.menu_show_diffstat) # Add to menubar self.menubar.addAction(self.diff_menu.menuAction()) # Tools Menu self.tools_menu = create_menu(N_('Tools'), self.menubar) self.tools_menu.addAction(self.menu_classic) self.tools_menu.addAction(self.menu_dag) self.tools_menu.addSeparator() if self.classic_dockable: self.tools_menu.addAction(self.classicdockwidget.toggleViewAction()) self.setup_dockwidget_tools_menu() self.menubar.addAction(self.tools_menu.menuAction()) # Help Menu self.help_menu = create_menu(N_('Help'), self.menubar) self.help_menu.addAction(self.menu_help_docs) self.help_menu.addAction(self.menu_help_shortcuts) self.help_menu.addAction(self.menu_help_about) # Add to menubar self.menubar.addAction(self.help_menu.menuAction()) # Set main menu self.setMenuBar(self.menubar) # Arrange dock widgets left = Qt.LeftDockWidgetArea right = Qt.RightDockWidgetArea bottom = Qt.BottomDockWidgetArea self.addDockWidget(left, self.commitdockwidget) if self.classic_dockable: self.addDockWidget(left, self.classicdockwidget) self.tabifyDockWidget(self.classicdockwidget, self.commitdockwidget) self.addDockWidget(left, self.diffdockwidget) self.addDockWidget(bottom, self.actionsdockwidget) self.addDockWidget(bottom, self.logdockwidget) self.tabifyDockWidget(self.actionsdockwidget, self.logdockwidget) self.addDockWidget(right, self.statusdockwidget) # Listen for model notifications model.add_observer(model.message_updated, self._update_view) prefs_model.add_observer(prefs_model.message_config_updated, self._config_updated) # Set a default value self.show_cursor_position(1, 0) self.connect(self.menu_open_recent, SIGNAL('aboutToShow()'), self.build_recent_menu) self.connect(self.commitmsgeditor, SIGNAL('cursorPosition(int,int)'), self.show_cursor_position) self.connect(self, SIGNAL('update'), self._update_callback) self.connect(self, SIGNAL('install_config_actions'), self._install_config_actions) # Install .git-config-defined actions self._config_task = None self.install_config_actions() # Restore saved settings if not qtutils.apply_state(self): self.set_initial_size() self.statusdockwidget.widget().setFocus() # Route command output here Interaction.log_status = self.logwidget.log_status Interaction.log = self.logwidget.log Interaction.log(version.git_version_str() + '\n' + N_('git cola version %s') % version.version())
def __init__(self, opts, parent=None): standard.Dialog.__init__(self, parent=parent) self.opts = opts self.setAttribute(Qt.WA_MacMetalStyle) self.setWindowTitle(N_('Create Tag')) if parent is not None: self.setWindowModality(QtCore.Qt.WindowModal) # Tag label self.tag_name_label = QtGui.QLabel(self) self.tag_name_label.setText(N_('Name')) self.tag_name = text.HintedLineEdit(N_('vX.Y.Z'), self) self.tag_name.set_value(opts.name) self.tag_name.setToolTip(N_('Specifies the tag name')) # Sign Tag self.sign_label = QtGui.QLabel(self) self.sign_label.setText(N_('Sign Tag')) self.sign_tag = QtGui.QCheckBox(self) self.sign_tag.setChecked(opts.sign) self.sign_tag.setToolTip(N_('Whether to sign the tag (git tag -s)')) # Tag message self.tag_msg_label = QtGui.QLabel(self) self.tag_msg_label.setText(N_('Message')) self.tag_msg = text.HintedTextEdit(N_('Tag message...'), self) self.tag_msg.setToolTip(N_('Specifies the tag message')) self.tag_msg.hint.enable(True) # Revision self.rev_label = QtGui.QLabel(self) self.rev_label.setText(N_('Revision')) self.revision = completion.GitRefLineEdit() self.revision.setText(self.opts.ref) self.revision.setToolTip(N_('Specifies the SHA-1 to tag')) # Buttons self.create_button = qtutils.create_button(text=N_('Create Tag'), icon=qtutils.git_icon()) self.close_button = qtutils.create_button(text=N_('Close')) # Form layout for inputs self.input_layout = qtutils.form(defs.margin, defs.spacing, (self.tag_name_label, self.tag_name), (self.tag_msg_label, self.tag_msg), (self.rev_label, self.revision), (self.sign_label, self.sign_tag)) self.button_layout = qtutils.hbox(defs.no_margin, defs.spacing, qtutils.STRETCH, self.create_button, self.close_button) self.main_layt = qtutils.vbox(defs.margin, defs.spacing, self.input_layout, self.button_layout) self.setLayout(self.main_layt) self.resize(506, 295) connect_button(self.close_button, self.accept) connect_button(self.create_button, self.create_tag)
def __init__(self, opts, parent=None): standard.Dialog.__init__(self, parent=parent) self.setAttribute(Qt.WA_MacMetalStyle) self.setWindowTitle(N_('Create Tag')) if parent is not None: self.setWindowModality(QtCore.Qt.WindowModal) self.opts = opts self.main_layt = QtGui.QVBoxLayout(self) self.main_layt.setContentsMargins(6, 12, 6, 6) # Form layout for inputs self.input_form_layt = QtGui.QFormLayout() self.input_form_layt.setFieldGrowthPolicy(QtGui.QFormLayout.ExpandingFieldsGrow) # Tag label self.tag_name_label = QtGui.QLabel(self) self.tag_name_label.setText(N_('Name')) self.input_form_layt.setWidget(0, QtGui.QFormLayout.LabelRole, self.tag_name_label) self.tag_name = text.HintedLineEdit(N_('vX.Y.Z'), self) self.tag_name.set_value(opts.name) self.tag_name.setToolTip(N_('Specifies the tag name')) self.input_form_layt.setWidget(0, QtGui.QFormLayout.FieldRole, self.tag_name) # Sign Tag self.sign_label = QtGui.QLabel(self) self.sign_label.setText(N_('Sign Tag')) self.input_form_layt.setWidget(1, QtGui.QFormLayout.LabelRole, self.sign_label) self.sign_tag = QtGui.QCheckBox(self) self.sign_tag.setChecked(opts.sign) self.sign_tag.setToolTip(N_('Whether to sign the tag (git tag -s)')) self.input_form_layt.setWidget(1, QtGui.QFormLayout.FieldRole, self.sign_tag) self.main_layt.addLayout(self.input_form_layt) # Tag message self.tag_msg_label = QtGui.QLabel(self) self.tag_msg_label.setText(N_('Message')) self.input_form_layt.setWidget(2, QtGui.QFormLayout.LabelRole, self.tag_msg_label) self.tag_msg = text.HintedTextEdit(N_('Tag message...'), self) self.tag_msg.setToolTip(N_('Specifies the tag message')) self.tag_msg.enable_hint(True) self.input_form_layt.setWidget(2, QtGui.QFormLayout.FieldRole, self.tag_msg) # Revision self.rev_label = QtGui.QLabel(self) self.rev_label.setText(N_('Revision')) self.input_form_layt.setWidget(3, QtGui.QFormLayout.LabelRole, self.rev_label) self.revision = completion.GitRefLineEdit() self.revision.setText(self.opts.ref) self.revision.setToolTip(N_('Specifies the SHA-1 to tag')) self.input_form_layt.setWidget(3, QtGui.QFormLayout.FieldRole, self.revision) # Buttons self.button_hbox_layt = QtGui.QHBoxLayout() self.button_hbox_layt.addStretch() self.create_button = qtutils.create_button(text=N_('Create Tag'), icon=qtutils.git_icon()) self.button_hbox_layt.addWidget(self.create_button) self.main_layt.addLayout(self.button_hbox_layt) self.close_button = qtutils.create_button(text=N_('Close')) self.button_hbox_layt.addWidget(self.close_button) connect_button(self.close_button, self.accept) connect_button(self.create_button, self.create_tag) self.resize(506, 295)
def action_callback(self): action = self.action if action == FETCH: model_action = self.model.fetch elif action == PUSH: model_action = self.push_to_all else: # if action == PULL: model_action = self.model.pull remote_name = ustr(self.remote_name.text()) if not remote_name: errmsg = N_('No repository selected.') Interaction.log(errmsg) return remote, kwargs = self.common_args() self.selected_remotes = qtutils.selected_items(self.remotes, self.model.remotes) # Check if we're about to create a new branch and warn. remote_branch = ustr(self.remote_branch.text()) local_branch = ustr(self.local_branch.text()) if action == PUSH and not remote_branch: branch = local_branch candidate = '%s/%s' % (remote, branch) if candidate not in self.model.remote_branches: title = N_('Push') args = dict(branch=branch, remote=remote) msg = N_( 'Branch "%(branch)s" does not exist in "%(remote)s".\n' 'A new remote branch will be published.') % args info_txt = N_('Create a new remote branch?') ok_text = N_('Create Remote Branch') if not qtutils.confirm( title, msg, info_txt, ok_text, icon=qtutils.git_icon()): return if not self.ffwd_only_checkbox.isChecked(): if action == FETCH: title = N_('Force Fetch?') msg = N_('Non-fast-forward fetch overwrites local history!') info_txt = N_('Force fetching from %s?') % remote ok_text = N_('Force Fetch') elif action == PUSH: title = N_('Force Push?') msg = N_('Non-fast-forward push overwrites published ' 'history!\n(Did you pull first?)') info_txt = N_('Force push to %s?') % remote ok_text = N_('Force Push') else: # pull: shouldn't happen since the controls are hidden msg = "You probably don't want to do this.\n\tContinue?" return if not qtutils.confirm(title, msg, info_txt, ok_text, default=False, icon=qtutils.discard_icon()): return # Disable the GUI by default self.action_button.setEnabled(False) self.close_button.setEnabled(False) # Use a thread to update in the background task = ActionTask(self.task_runner, model_action, remote, kwargs) self.task_runner.start(task, progress=self.progress, finish=self.action_completed)
def contextMenuEvent(self, event): """Create the context menu for the diff display.""" menu = QtGui.QMenu(self) s = selection.selection() filename = selection.filename() if self.model.stageable() and s.modified: if s.modified[0] in main.model().submodules: action = menu.addAction(qtutils.icon('add.svg'), cmds.Stage.name(), cmds.run(cmds.Stage, s.modified)) action.setShortcut(cmds.Stage.SHORTCUT) menu.addAction(qtutils.git_icon(), N_('Launch git-cola'), cmds.run(cmds.OpenRepo, core.abspath(s.modified[0]))) else: if self.has_selection(): apply_text = N_('Stage Selected Lines') revert_text = N_('Revert Selected Lines...') else: apply_text = N_('Stage Diff Hunk') revert_text = N_('Revert Diff Hunk...') self.action_apply_selection.setText(apply_text) self.action_apply_selection.setIcon(qtutils.icon('add.svg')) self.action_revert_selection.setText(revert_text) menu.addAction(self.action_apply_selection) menu.addAction(self.action_revert_selection) if self.model.unstageable(): if s.staged and s.staged[0] in main.model().submodules: action = menu.addAction(qtutils.icon('remove.svg'), cmds.Unstage.name(), cmds.do(cmds.Unstage, s.staged)) action.setShortcut(cmds.Unstage.SHORTCUT) menu.addAction(qtutils.git_icon(), N_('Launch git-cola'), cmds.do(cmds.OpenRepo, core.abspath(s.staged[0]))) elif s.staged: if self.has_selection(): apply_text = N_('Unstage Selected Lines') else: apply_text = N_('Unstage Diff Hunk') self.action_apply_selection.setText(apply_text) self.action_apply_selection.setIcon(qtutils.icon('remove.svg')) menu.addAction(self.action_apply_selection) if self.model.stageable() or self.model.unstageable(): # Do not show the "edit" action when the file does not exist. # Untracked files exist by definition. if filename and core.exists(filename): menu.addSeparator() menu.addAction(self.launch_editor) # Removed files can still be diffed. menu.addAction(self.launch_difftool) menu.addSeparator() action = menu.addAction(qtutils.icon('edit-copy.svg'), N_('Copy'), self.copy) action.setShortcut(QtGui.QKeySequence.Copy) action = menu.addAction(qtutils.icon('edit-select-all.svg'), N_('Select All'), self.selectAll) action.setShortcut(QtGui.QKeySequence.SelectAll) menu.exec_(self.mapToGlobal(event.pos()))
def __init__(self, parent=None): QtGui.QDialog.__init__(self, parent) self.setWindowTitle(N_("git-cola")) self.repodir = None self.task_runner = TaskRunner(self) self.progress = ProgressDialog("", "", self) self.new_button = QtGui.QPushButton(N_("New...")) self.new_button.setIcon(qtutils.new_icon()) self.open_button = QtGui.QPushButton(N_("Open...")) self.open_button.setIcon(qtutils.open_icon()) self.clone_button = QtGui.QPushButton(N_("Clone...")) self.clone_button.setIcon(qtutils.git_icon()) self.close_button = QtGui.QPushButton(N_("Close")) settings = Settings() settings.load() self.bookmarks_label = QtGui.QLabel(N_("Select Repository...")) self.bookmarks_label.setAlignment(Qt.AlignCenter) self.bookmarks_model = QtGui.QStandardItemModel() item = QtGui.QStandardItem(N_("Select manually...")) item.setEditable(False) self.bookmarks_model.appendRow(item) added = set() all_repos = settings.bookmarks + settings.recent for repo in all_repos: if repo in added: continue added.add(repo) item = QtGui.QStandardItem(repo) item.setEditable(False) self.bookmarks_model.appendRow(item) selection_mode = QtGui.QAbstractItemView.SingleSelection self.bookmarks = QtGui.QListView() self.bookmarks.setSelectionMode(selection_mode) self.bookmarks.setAlternatingRowColors(True) self.bookmarks.setModel(self.bookmarks_model) if not all_repos: self.bookmarks_label.setMinimumHeight(1) self.bookmarks.setMinimumHeight(1) self.bookmarks_label.hide() self.bookmarks.hide() self.button_layout = qtutils.hbox( defs.no_margin, defs.spacing, self.open_button, self.clone_button, self.new_button, qtutils.STRETCH, self.close_button, ) self.main_layout = qtutils.vbox( defs.margin, defs.spacing, self.bookmarks_label, self.bookmarks, self.button_layout ) self.setLayout(self.main_layout) qtutils.connect_button(self.open_button, self.open_repo) qtutils.connect_button(self.clone_button, self.clone_repo) qtutils.connect_button(self.new_button, self.new_repo) qtutils.connect_button(self.close_button, self.reject) self.connect(self.bookmarks, SIGNAL("activated(const QModelIndex &)"), self.open_bookmark)
def create_context_menu(self): """Set up the status menu for the repo status tree.""" s = self.selection() menu = QtGui.QMenu(self) selection = self.selected_indexes() if selection: category, idx = selection[0] # A header item e.g. 'Staged', 'Modified', etc. if category == self.idx_header: if idx == self.idx_staged: menu.addAction(qtutils.icon('remove.svg'), self.tr('Unstage All'), SLOT(signals.unstage_all)) return menu elif idx == self.idx_unmerged: action = menu.addAction(qtutils.icon('add.svg'), self.tr('Stage Merged'), SLOT(signals.stage_unmerged)) action.setShortcut(defs.stage_shortcut) return menu elif idx == self.idx_modified: action = menu.addAction(qtutils.icon('add.svg'), self.tr('Stage Modified'), SLOT(signals.stage_modified)) action.setShortcut(defs.stage_shortcut) return menu elif idx == self.idx_untracked: action = menu.addAction(qtutils.icon('add.svg'), self.tr('Stage Untracked'), SLOT(signals.stage_untracked)) action.setShortcut(defs.stage_shortcut) return menu if s.staged and self.m.unstageable(): action = menu.addAction(qtutils.icon('remove.svg'), self.tr('Unstage Selected'), SLOT(signals.unstage, self.staged())) action.setShortcut(defs.stage_shortcut) if s.staged and s.staged[0] in self.m.submodules: menu.addAction(qtutils.git_icon(), self.tr('Launch git-cola'), SLOT(signals.open_repo, os.path.abspath(s.staged[0]))) menu.addSeparator() menu.addAction(self.copy_path_action) return menu elif s.staged: menu.addSeparator() action = menu.addAction(qtutils.git_icon(), self.tr('Launch Diff Tool'), SLOT(signals.difftool, True, self.staged())) action.setShortcut(defs.difftool_shortcut) action = menu.addAction(qtutils.options_icon(), self.tr('Launch Editor'), SLOT(signals.edit, self.staged())) action.setShortcut(defs.editor_shortcut) if not utils.is_win32(): menu.addSeparator() action = menu.addAction(qtutils.file_icon(), self.tr(self.txt_default_app), SLOT(signals.open_default_app, self.staged())) action.setShortcut(defs.default_app_shortcut) action = menu.addAction(qtutils.open_file_icon(), self.tr(self.txt_parent_dir), self._open_parent_dir) action.setShortcut(defs.parent_dir_shortcut) if self.m.undoable(): menu.addSeparator() menu.addAction(qtutils.icon('undo.svg'), self.tr('Revert Unstaged Edits...'), lambda: self._revert_unstaged_edits(staged=True)) menu.addSeparator() menu.addAction(self.copy_path_action) return menu if s.unmerged: menu.addAction(qtutils.git_icon(), self.tr('Launch Merge Tool'), SLOT(signals.mergetool, self.unmerged())) action = menu.addAction(qtutils.icon('add.svg'), self.tr('Stage Selected'), SLOT(signals.stage, self.unstaged())) action.setShortcut(defs.stage_shortcut) menu.addSeparator() action = menu.addAction(qtutils.options_icon(), self.tr('Launch Editor'), SLOT(signals.edit, self.unmerged())) action.setShortcut(defs.editor_shortcut) if not utils.is_win32(): menu.addSeparator() action = menu.addAction(qtutils.file_icon(), self.tr(self.txt_default_app), SLOT(signals.open_default_app, self.unmerged())) action.setShortcut(defs.default_app_shortcut) action = menu.addAction(qtutils.open_file_icon(), self.tr(self.txt_parent_dir), self._open_parent_dir) action.setShortcut(defs.parent_dir_shortcut) menu.addSeparator() menu.addAction(self.copy_path_action) return menu modified_submodule = (s.modified and s.modified[0] in self.m.submodules) if self.m.stageable(): action = menu.addAction(qtutils.icon('add.svg'), self.tr('Stage Selected'), SLOT(signals.stage, self.unstaged())) action.setShortcut(defs.stage_shortcut) menu.addSeparator() if s.modified and self.m.stageable() and not modified_submodule: action = menu.addAction(qtutils.git_icon(), self.tr('Launch Diff Tool'), SLOT(signals.difftool, False, self.modified())) action.setShortcut(defs.difftool_shortcut) if modified_submodule: menu.addAction(qtutils.git_icon(), self.tr('Launch git-cola'), SLOT(signals.open_repo, os.path.abspath(s.modified[0]))) elif self.unstaged(): action = menu.addAction(qtutils.options_icon(), self.tr('Launch Editor'), SLOT(signals.edit, self.unstaged())) action.setShortcut(defs.editor_shortcut) if not utils.is_win32(): menu.addSeparator() action = menu.addAction(qtutils.file_icon(), self.tr(self.txt_default_app), SLOT(signals.open_default_app, self.unstaged())) action.setShortcut(defs.default_app_shortcut) action = menu.addAction(qtutils.open_file_icon(), self.tr(self.txt_parent_dir), self._open_parent_dir) action.setShortcut(defs.parent_dir_shortcut) menu.addSeparator() if s.modified and self.m.stageable() and not modified_submodule: if self.m.undoable(): menu.addAction(qtutils.icon('undo.svg'), self.tr('Revert Unstaged Edits...'), self._revert_unstaged_edits) menu.addAction(qtutils.icon('undo.svg'), self.tr('Revert Uncommited Edits...'), self._revert_uncommitted_edits) if s.untracked: menu.addSeparator() menu.addAction(qtutils.discard_icon(), self.tr('Delete File(s)...'), self._delete_files) menu.addSeparator() menu.addAction(qtutils.icon('edit-clear.svg'), self.tr('Add to .gitignore'), SLOT(signals.ignore, map(lambda x: '/' + x, self.untracked()))) menu.addSeparator() menu.addAction(self.copy_path_action) return menu
def __init__(self, parent=None): QtGui.QTreeWidget.__init__(self, parent) self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) self.headerItem().setHidden(True) self.setAllColumnsShowFocus(True) self.setSortingEnabled(False) self.setUniformRowHeights(True) self.setAnimated(True) self.setRootIsDecorated(False) self.setIndentation(0) self.setDragEnabled(True) self.add_item(N_('Staged'), hide=True) self.add_item(N_('Unmerged'), hide=True) self.add_item(N_('Modified'), hide=True) self.add_item(N_('Untracked'), hide=True) # Used to restore the selection self.old_scroll = None self.old_selection = None self.old_contents = None self.old_current_item = None self.expanded_items = set() self.process_selection_action = qtutils.add_action(self, cmds.StageOrUnstage.name(), cmds.run(cmds.StageOrUnstage), cmds.StageOrUnstage.SHORTCUT) self.revert_unstaged_edits_action = qtutils.add_action(self, cmds.RevertUnstagedEdits.name(), cmds.run(cmds.RevertUnstagedEdits), cmds.RevertUnstagedEdits.SHORTCUT) self.revert_unstaged_edits_action.setIcon(qtutils.icon('undo.svg')) self.revert_uncommitted_edits_action = qtutils.add_action(self, cmds.RevertUncommittedEdits.name(), cmds.run(cmds.RevertUncommittedEdits), cmds.RevertUncommittedEdits.SHORTCUT) self.revert_uncommitted_edits_action.setIcon(qtutils.icon('undo.svg')) self.launch_difftool_action = qtutils.add_action(self, cmds.LaunchDifftool.name(), cmds.run(cmds.LaunchDifftool), cmds.LaunchDifftool.SHORTCUT) self.launch_difftool_action.setIcon(qtutils.git_icon()) self.launch_editor_action = qtutils.add_action(self, cmds.LaunchEditor.name(), cmds.run(cmds.LaunchEditor), cmds.LaunchEditor.SHORTCUT, 'Return', 'Enter') self.launch_editor_action.setIcon(qtutils.options_icon()) if not utils.is_win32(): self.open_using_default_app = qtutils.add_action(self, cmds.OpenDefaultApp.name(), self._open_using_default_app, cmds.OpenDefaultApp.SHORTCUT) self.open_using_default_app.setIcon(qtutils.file_icon()) self.open_parent_dir_action = qtutils.add_action(self, cmds.OpenParentDir.name(), self._open_parent_dir, cmds.OpenParentDir.SHORTCUT) self.open_parent_dir_action.setIcon(qtutils.open_file_icon()) self.up_action = qtutils.add_action(self, N_('Move Up'), self.move_up, Qt.Key_K) self.down_action = qtutils.add_action(self, N_('Move Down'), self.move_down, Qt.Key_J) self.copy_path_action = qtutils.add_action(self, N_('Copy Path to Clipboard'), self.copy_path, QtGui.QKeySequence.Copy) self.copy_path_action.setIcon(qtutils.theme_icon('edit-copy.svg')) self.copy_relpath_action = qtutils.add_action(self, N_('Copy Relative Path to Clipboard'), self.copy_relpath, QtGui.QKeySequence.Cut) self.copy_relpath_action.setIcon(qtutils.theme_icon('edit-copy.svg')) if cmds.MoveToTrash.AVAILABLE: self.move_to_trash_action = qtutils.add_action(self, N_('Move file(s) to trash'), self._trash_untracked_files, cmds.MoveToTrash.SHORTCUT) self.move_to_trash_action.setIcon(qtutils.discard_icon()) delete_shortcut = cmds.Delete.SHORTCUT else: self.move_to_trash_action = None delete_shortcut = cmds.Delete.ALT_SHORTCUT self.delete_untracked_files_action = qtutils.add_action(self, N_('Delete File(s)...'), self._delete_untracked_files, delete_shortcut) self.delete_untracked_files_action.setIcon(qtutils.discard_icon()) self.connect(self, SIGNAL('about_to_update'), self._about_to_update) self.connect(self, SIGNAL('updated'), self._updated) self.m = main.model() self.m.add_observer(self.m.message_about_to_update, self.about_to_update) self.m.add_observer(self.m.message_updated, self.updated) self.connect(self, SIGNAL('itemSelectionChanged()'), self.show_selection) self.connect(self, SIGNAL('itemDoubleClicked(QTreeWidgetItem*,int)'), self.double_clicked) self.connect(self, SIGNAL('itemCollapsed(QTreeWidgetItem*)'), lambda x: self.update_column_widths()) self.connect(self, SIGNAL('itemExpanded(QTreeWidgetItem*)'), lambda x: self.update_column_widths())
def __init__(self, model, parent=None): Dialog.__init__(self, parent=parent) self.setAttribute(Qt.WA_MacMetalStyle) self.setWindowTitle(N_('Create Branch')) if parent is not None: self.setWindowModality(Qt.WindowModal) self.model = model self.opts = CreateOpts(model) self.thread = CreateThread(self.opts, self) self.progress = QtGui.QProgressDialog(self) self.progress.setRange(0, 0) self.progress.setCancelButton(None) self.progress.setWindowTitle(N_('Create Branch')) self.progress.setWindowModality(Qt.WindowModal) self.branch_name_label = QtGui.QLabel() self.branch_name_label.setText(N_('Branch Name')) self.branch_name = QtGui.QLineEdit() self.rev_label = QtGui.QLabel() self.rev_label.setText(N_('Starting Revision')) self.revision = completion.GitRefLineEdit() current = gitcmds.current_branch() if current: self.revision.setText(current) self.local_radio = QtGui.QRadioButton() self.local_radio.setText(N_('Local branch')) self.local_radio.setChecked(True) self.remote_radio = QtGui.QRadioButton() self.remote_radio.setText(N_('Tracking branch')) self.tag_radio = QtGui.QRadioButton() self.tag_radio.setText(N_('Tag')) self.branch_list = QtGui.QListWidget() self.update_existing_label = QtGui.QLabel() self.update_existing_label.setText(N_('Update Existing Branch:')) self.no_update_radio = QtGui.QRadioButton() self.no_update_radio.setText(N_('No')) self.ffwd_only_radio = QtGui.QRadioButton() self.ffwd_only_radio.setText(N_('Fast Forward Only')) self.ffwd_only_radio.setChecked(True) self.reset_radio = QtGui.QRadioButton() self.reset_radio.setText(N_('Reset')) self.fetch_checkbox = QtGui.QCheckBox() self.fetch_checkbox.setText(N_('Fetch Tracking Branch')) self.fetch_checkbox.setChecked(True) self.checkout_checkbox = QtGui.QCheckBox() self.checkout_checkbox.setText(N_('Checkout After Creation')) self.checkout_checkbox.setChecked(True) self.create_button = qtutils.create_button(text=N_('Create Branch'), icon=qtutils.git_icon()) self.create_button.setDefault(True) self.close_button = qtutils.create_button(text=N_('Close')) self.rev_start_group = QtGui.QGroupBox() self.rev_start_group.setTitle(N_('Starting Revision')) self.option_group = QtGui.QGroupBox() self.option_group.setTitle(N_('Options')) self.options_checkbox_layout = qtutils.vbox(defs.margin, defs.spacing, self.fetch_checkbox, self.checkout_checkbox) self.options_bottom_layout = qtutils.hbox(defs.margin, defs.spacing, self.options_checkbox_layout, qtutils.STRETCH) self.branch_name_layout = qtutils.hbox(defs.margin, defs.spacing, self.branch_name_label, self.branch_name) self.rev_start_radiobtn_layout = qtutils.hbox(defs.margin, defs.spacing, self.local_radio, self.remote_radio, self.tag_radio, qtutils.STRETCH) self.rev_start_textinput_layout = qtutils.hbox(defs.no_margin, defs.spacing, self.rev_label, self.revision) self.rev_start_layout = qtutils.vbox(defs.no_margin, defs.spacing, self.rev_start_radiobtn_layout, self.branch_list, self.rev_start_textinput_layout) self.rev_start_group.setLayout(self.rev_start_layout) self.options_radio_layout = qtutils.hbox(defs.no_margin, defs.spacing, self.update_existing_label, self.no_update_radio, self.ffwd_only_radio, self.reset_radio) self.options_grp_layout = qtutils.vbox(defs.no_margin, defs.spacing, self.options_radio_layout, self.options_bottom_layout) self.option_group.setLayout(self.options_grp_layout) self.buttons_layout = qtutils.hbox(defs.margin, defs.spacing, self.create_button, self.close_button) self.options_section_layout = qtutils.hbox(defs.no_margin, defs.spacing, self.option_group, self.buttons_layout) self.main_layout = qtutils.vbox(defs.margin, defs.spacing, self.branch_name_layout, self.rev_start_group, self.options_section_layout) self.setLayout(self.main_layout) qtutils.connect_button(self.close_button, self.reject) qtutils.connect_button(self.create_button, self.create_branch) qtutils.connect_button(self.local_radio, self.display_model) qtutils.connect_button(self.remote_radio, self.display_model) qtutils.connect_button(self.tag_radio, self.display_model) self.connect(self.branch_list, SIGNAL('itemSelectionChanged()'), self.branch_item_changed) self.connect(self.thread, SIGNAL(COMMAND_SIGNAL), self.thread_command, Qt.QueuedConnection) self.connect(self.thread, SIGNAL('done(PyQt_PyObject)'), self.thread_done, Qt.QueuedConnection) self.resize(555, 333) self.display_model()
def action_callback(self): action = self.action if action == FETCH: model_action = self.model.fetch elif action == PUSH: model_action = self.model.push else: # if action == PULL: model_action = self.model.pull remote_name = unicode(self.remote_name.text()) if not remote_name: errmsg = self.tr('No repository selected.') qtutils.log(1, errmsg) return remote, kwargs = self.common_args() # Check if we're about to create a new branch and warn. remote_branch = unicode(self.remote_branch.text()) local_branch = unicode(self.local_branch.text()) if action == PUSH and not remote_branch: branch = local_branch candidate = '%s/%s' % (remote, branch) if candidate not in self.model.remote_branches: title = self.tr(PUSH) msg = 'Branch "%s" does not exist in %s.' % (branch, remote) msg += '\nA new remote branch will be published.' info_txt = 'Create a new remote branch?' ok_text = 'Create Remote Branch' if not qtutils.confirm(title, msg, info_txt, ok_text, default=False, icon=qtutils.git_icon()): return if not self.ffwd_only_checkbox.isChecked(): title = 'Force %s?' % action.title() ok_text = 'Force %s' % action.title() if action == FETCH: msg = 'Non-fast-forward fetch overwrites local history!' info_txt = 'Force fetching from %s?' % remote elif action == PUSH: msg = ('Non-fast-forward push overwrites published ' 'history!\n(Did you pull first?)') info_txt = 'Force push to %s?' % remote else: # pull: shouldn't happen since the controls are hidden msg = "You probably don't want to do this.\n\tContinue?" return if not qtutils.confirm(title, msg, info_txt, ok_text, default=False, icon=qtutils.discard_icon()): return # Disable the GUI by default self.setEnabled(False) self.progress.setEnabled(True) QtGui.QApplication.setOverrideCursor(Qt.WaitCursor) # Show a nice progress bar self.progress_thread.start() self.progress.show() # Use a thread to update in the background task = ActionTask(self, model_action, remote, kwargs) self.tasks.append(task) QtCore.QThreadPool.globalInstance().start(task)
def contextMenuEvent(self, event): """Create the context menu for the diff display.""" menu = QtGui.QMenu(self) s = selection.selection() filename = selection.filename() if s.modified and self.model.stageable(): if s.modified[0] in main.model().submodules: action = menu.addAction(qtutils.icon('add.svg'), cmds.Stage.name(), cmds.run(cmds.Stage, s.modified)) action.setShortcut(cmds.Stage.SHORTCUT) menu.addAction( qtutils.git_icon(), N_('Launch git-cola'), cmds.run(cmds.OpenRepo, core.abspath(s.modified[0]))) elif s.modified[0] not in main.model().unstaged_deleted: if self.has_selection(): apply_text = N_('Stage Selected Lines') revert_text = N_('Revert Selected Lines...') else: apply_text = N_('Stage Diff Hunk') revert_text = N_('Revert Diff Hunk...') self.action_apply_selection.setText(apply_text) self.action_apply_selection.setIcon(qtutils.icon('add.svg')) self.action_revert_selection.setText(revert_text) menu.addAction(self.action_apply_selection) menu.addAction(self.action_revert_selection) if s.staged and self.model.unstageable(): if s.staged[0] in main.model().submodules: action = menu.addAction(qtutils.icon('remove.svg'), cmds.Unstage.name(), cmds.do(cmds.Unstage, s.staged)) action.setShortcut(cmds.Unstage.SHORTCUT) menu.addAction( qtutils.git_icon(), N_('Launch git-cola'), cmds.do(cmds.OpenRepo, core.abspath(s.staged[0]))) elif s.staged[0] not in main.model().staged_deleted: if self.has_selection(): apply_text = N_('Unstage Selected Lines') else: apply_text = N_('Unstage Diff Hunk') self.action_apply_selection.setText(apply_text) self.action_apply_selection.setIcon(qtutils.icon('remove.svg')) menu.addAction(self.action_apply_selection) if self.model.stageable() or self.model.unstageable(): # Do not show the "edit" action when the file does not exist. # Untracked files exist by definition. if filename and core.exists(filename): menu.addSeparator() menu.addAction(self.launch_editor) # Removed files can still be diffed. menu.addAction(self.launch_difftool) menu.addSeparator() action = menu.addAction(qtutils.icon('edit-copy.svg'), N_('Copy'), self.copy) action.setShortcut(QtGui.QKeySequence.Copy) action = menu.addAction(qtutils.icon('edit-select-all.svg'), N_('Select All'), self.selectAll) action.setShortcut(QtGui.QKeySequence.SelectAll) menu.exec_(self.mapToGlobal(event.pos()))
def __init__(self, model, parent): MainWindow.__init__(self, parent) # Default size; this is thrown out when save/restore is used self.resize(987, 610) self.model = model self.prefs_model = prefs_model = PreferencesModel() # Internal field used by import/export_state(). # Change this whenever dockwidgets are removed. self.widget_version = 1 # Keeps track of merge messages we've seen self.merge_message_hash = '' self.setAcceptDrops(True) self.setAttribute(Qt.WA_MacMetalStyle) # Dockwidget options qtcompat.set_common_dock_options(self) cfg = gitcfg.instance() self.classic_dockable = (cfg.get('cola.browserdockable') or cfg.get('cola.classicdockable')) if self.classic_dockable: self.classicdockwidget = create_dock('Browser', self) self.classicwidget = classic_widget(self) self.classicdockwidget.setWidget(self.classicwidget) # "Actions" widget self.actionsdockwidget = create_dock('Action', self) self.actionsdockwidgetcontents = qt.QFlowLayoutWidget(self) layout = self.actionsdockwidgetcontents.layout() self.stage_button = create_button(text='Stage', layout=layout) self.unstage_button = create_button(text='Unstage', layout=layout) self.rescan_button = create_button(text='Rescan', layout=layout) self.fetch_button = create_button(text='Fetch...', layout=layout) self.push_button = create_button(text='Push...', layout=layout) self.pull_button = create_button(text='Pull...', layout=layout) self.stash_button = create_button(text='Stash...', layout=layout) layout.addStretch() self.actionsdockwidget.setWidget(self.actionsdockwidgetcontents) # "Repository Status" widget self.statusdockwidget = create_dock('Status', self) self.statusdockwidget.setWidget(StatusWidget(self)) # "Commit Message Editor" widget self.position_label = QtGui.QLabel() font = qtutils.default_monospace_font() font.setPointSize(int(font.pointSize() * 0.8)) self.position_label.setFont(font) self.commitdockwidget = create_dock('Commit', self) titlebar = self.commitdockwidget.titleBarWidget() titlebar.add_corner_widget(self.position_label) self.commitmsgeditor = CommitMessageEditor(model, self) relay_signal(self, self.commitmsgeditor, SIGNAL(signals.amend_mode)) relay_signal(self, self.commitmsgeditor, SIGNAL(signals.signoff)) relay_signal(self, self.commitmsgeditor, SIGNAL(signals.load_previous_message)) self.commitdockwidget.setWidget(self.commitmsgeditor) # "Console" widget self.logwidget = LogWidget() self.logdockwidget = create_dock('Console', self) self.logdockwidget.setWidget(self.logwidget) cola.notifier().connect(signals.log_cmd, self.logwidget.log) # "Diff Viewer" widget self.diffdockwidget = create_dock('Diff', self) self.diffeditor = DiffEditor(self.diffdockwidget) self.diffdockwidget.setWidget(self.diffeditor) # All Actions self.menu_unstage_all = add_action(self, 'Unstage All', emit(self, signals.unstage_all)) self.menu_unstage_all.setIcon(qtutils.icon('remove.svg')) self.menu_unstage_selected = add_action(self, 'Unstage From Commit', emit(self, signals.unstage_selected)) self.menu_unstage_selected.setIcon(qtutils.icon('remove.svg')) self.menu_show_diffstat = add_action(self, 'Diffstat', emit(self, signals.diffstat), 'Alt+D') self.menu_stage_modified = add_action(self, 'Stage Changed Files To Commit', emit(self, signals.stage_modified), 'Alt+A') self.menu_stage_modified.setIcon(qtutils.icon('add.svg')) self.menu_stage_untracked = add_action(self, 'Stage All Untracked', emit(self, signals.stage_untracked), 'Alt+U') self.menu_stage_untracked.setIcon(qtutils.icon('add.svg')) self.menu_export_patches = add_action(self, 'Export Patches...', guicmds.export_patches, 'Alt+E') self.menu_preferences = add_action(self, 'Preferences', lambda: preferences(model=prefs_model), QtGui.QKeySequence.Preferences, 'Ctrl+O') self.menu_edit_remotes = add_action(self, 'Edit Remotes...', lambda: editremotes.edit().exec_()) self.menu_rescan = add_action(self, 'Rescan', emit(self, signals.rescan_and_refresh), 'Ctrl+R') self.menu_rescan.setIcon(qtutils.reload_icon()) self.menu_browse_recent = add_action(self, 'Recently Modified Files...', browse_recent, 'Shift+Ctrl+E') self.menu_cherry_pick = add_action(self, 'Cherry-Pick...', guicmds.cherry_pick, 'Ctrl+P') self.menu_load_commitmsg = add_action(self, 'Load Commit Message...', guicmds.load_commitmsg) self.menu_save_tarball = add_action(self, 'Save As Tarball/Zip...', self.save_archive) self.menu_quit = add_action(self, 'Quit', self.close, 'Ctrl+Q') self.menu_manage_bookmarks = add_action(self, 'Bookmarks...', manage_bookmarks) self.menu_grep = add_action(self, 'Grep', guicmds.grep) self.menu_merge_local = add_action(self, 'Merge...', merge.local_merge) self.menu_merge_abort = add_action(self, 'Abort Merge...', merge.abort_merge) self.menu_fetch = add_action(self, 'Fetch...', remote.fetch) self.menu_push = add_action(self, 'Push...', remote.push) self.menu_pull = add_action(self, 'Pull...', remote.pull) self.menu_open_repo = add_action(self, 'Open...', guicmds.open_repo) self.menu_open_repo.setIcon(qtutils.open_icon()) self.menu_stash = add_action(self, 'Stash...', stash.stash, 'Alt+Shift+S') self.menu_clone_repo = add_action(self, 'Clone...', guicmds.clone_repo) self.menu_clone_repo.setIcon(qtutils.git_icon()) self.menu_help_docs = add_action(self, 'Documentation', resources.show_html_docs, QtGui.QKeySequence.HelpContents) self.menu_help_shortcuts = add_action(self, 'Keyboard Shortcuts', show_shortcuts, QtCore.Qt.Key_Question) self.menu_visualize_current = add_action(self, 'Visualize Current Branch...', emit(self, signals.visualize_current)) self.menu_visualize_all = add_action(self, 'Visualize All Branches...', emit(self, signals.visualize_all)) self.menu_search_commits = add_action(self, 'Search...', search) self.menu_browse_branch = add_action(self, 'Browse Current Branch...', guicmds.browse_current) self.menu_browse_other_branch = add_action(self, 'Browse Other Branch...', guicmds.browse_other) self.menu_load_commitmsg_template = add_action(self, 'Get Commit Message Template', emit(self, signals.load_commit_template)) self.menu_help_about = add_action(self, 'About', launch_about_dialog) self.menu_branch_diff = add_action(self, 'SHA-1...', guicmds.diff_revision) self.menu_diff_expression = add_action(self, 'Expression...', guicmds.diff_expression) self.menu_branch_compare = add_action(self, 'Branches...', compare_branches) self.menu_create_tag = add_action(self, 'Create Tag...', create_tag) self.menu_create_branch = add_action(self, 'Create...', create_new_branch, 'Ctrl+B') self.menu_delete_branch = add_action(self, 'Delete...', guicmds.branch_delete) self.menu_checkout_branch = add_action(self, 'Checkout...', guicmds.checkout_branch, 'Alt+B') self.menu_rebase_branch = add_action(self, 'Rebase...', guicmds.rebase) self.menu_branch_review = add_action(self, 'Review...', guicmds.review_branch) self.menu_classic = add_action(self, 'Browser...', cola_classic) self.menu_classic.setIcon(qtutils.git_icon()) self.menu_dag = add_action(self, 'DAG...', lambda: git_dag(self.model)) self.menu_dag.setIcon(qtutils.git_icon()) # Relayed actions if not self.classic_dockable: # These shortcuts conflict with those from the # 'Browser' widget so don't register them when # the browser is a dockable tool. status_tree = self.statusdockwidget.widget().tree self.addAction(status_tree.up) self.addAction(status_tree.down) self.addAction(status_tree.process_selection) self.addAction(status_tree.launch_difftool) # Create the application menu self.menubar = QtGui.QMenuBar(self) # File Menu self.file_menu = create_menu('&File', self.menubar) self.file_menu.addAction(self.menu_preferences) self.file_menu.addSeparator() self.file_menu.addAction(self.menu_open_repo) self.menu_open_recent = self.file_menu.addMenu(tr('Open Recent')) self.file_menu.addSeparator() self.file_menu.addAction(self.menu_clone_repo) self.file_menu.addAction(self.menu_manage_bookmarks) self.file_menu.addSeparator() self.file_menu.addAction(self.menu_edit_remotes) self.file_menu.addAction(self.menu_rescan) self.file_menu.addSeparator() self.file_menu.addAction(self.menu_browse_recent) self.file_menu.addSeparator() self.file_menu.addAction(self.menu_load_commitmsg) self.file_menu.addAction(self.menu_load_commitmsg_template) self.file_menu.addSeparator() self.file_menu.addAction(self.menu_save_tarball) self.file_menu.addAction(self.menu_quit) # Add to menubar self.menubar.addAction(self.file_menu.menuAction()) # Commit Menu self.commit_menu = create_menu('Co&mmit', self.menubar) self.commit_menu.setTitle(tr('Commit@@verb')) self.commit_menu.addAction(self.menu_stage_modified) self.commit_menu.addAction(self.menu_stage_untracked) self.commit_menu.addSeparator() self.commit_menu.addAction(self.menu_unstage_all) self.commit_menu.addAction(self.menu_unstage_selected) self.commit_menu.addSeparator() self.commit_menu.addAction(self.menu_search_commits) # Add to menubar self.menubar.addAction(self.commit_menu.menuAction()) # Branch Menu self.branch_menu = create_menu('B&ranch', self.menubar) self.branch_menu.addAction(self.menu_branch_review) self.branch_menu.addSeparator() self.branch_menu.addAction(self.menu_create_branch) self.branch_menu.addAction(self.menu_checkout_branch) self.branch_menu.addAction(self.menu_rebase_branch) self.branch_menu.addAction(self.menu_delete_branch) self.branch_menu.addSeparator() self.branch_menu.addAction(self.menu_browse_branch) self.branch_menu.addAction(self.menu_browse_other_branch) self.branch_menu.addSeparator() self.branch_menu.addAction(self.menu_visualize_current) self.branch_menu.addAction(self.menu_visualize_all) # Add to menubar self.menubar.addAction(self.branch_menu.menuAction()) # Actions menu self.actions_menu = create_menu('Act&ions', self.menubar) self.actions_menu.addAction(self.menu_merge_local) self.actions_menu.addAction(self.menu_stash) self.actions_menu.addSeparator() self.actions_menu.addAction(self.menu_fetch) self.actions_menu.addAction(self.menu_push) self.actions_menu.addAction(self.menu_pull) self.actions_menu.addSeparator() self.actions_menu.addAction(self.menu_create_tag) self.actions_menu.addSeparator() self.actions_menu.addAction(self.menu_export_patches) self.actions_menu.addAction(self.menu_cherry_pick) self.actions_menu.addSeparator() self.actions_menu.addAction(self.menu_merge_abort) self.actions_menu.addAction(self.menu_grep) # Add to menubar self.menubar.addAction(self.actions_menu.menuAction()) # Diff Menu self.diff_menu = create_menu('&Diff', self.menubar) self.diff_menu.addAction(self.menu_branch_diff) self.diff_menu.addAction(self.menu_diff_expression) self.diff_menu.addAction(self.menu_branch_compare) self.diff_menu.addSeparator() self.diff_menu.addAction(self.menu_show_diffstat) # Add to menubar self.menubar.addAction(self.diff_menu.menuAction()) # Tools Menu self.tools_menu = create_menu('&Tools', self.menubar) self.tools_menu.addAction(self.menu_classic) self.tools_menu.addAction(self.menu_dag) self.tools_menu.addSeparator() if self.classic_dockable: self.tools_menu.addAction(self.classicdockwidget.toggleViewAction()) self.setup_dockwidget_tools_menu() self.menubar.addAction(self.tools_menu.menuAction()) # Help Menu self.help_menu = create_menu('&Help', self.menubar) self.help_menu.addAction(self.menu_help_docs) self.help_menu.addAction(self.menu_help_shortcuts) self.help_menu.addAction(self.menu_help_about) # Add to menubar self.menubar.addAction(self.help_menu.menuAction()) # Set main menu self.setMenuBar(self.menubar) # Arrange dock widgets top = Qt.TopDockWidgetArea bottom = Qt.BottomDockWidgetArea self.addDockWidget(top, self.commitdockwidget) if self.classic_dockable: self.addDockWidget(top, self.classicdockwidget) self.addDockWidget(top, self.statusdockwidget) self.addDockWidget(top, self.actionsdockwidget) self.addDockWidget(bottom, self.logdockwidget) if self.classic_dockable: self.tabifyDockWidget(self.classicdockwidget, self.commitdockwidget) self.tabifyDockWidget(self.logdockwidget, self.diffdockwidget) # Listen for model notifications model.add_observer(model.message_updated, self._update_view) prefs_model.add_observer(prefs_model.message_config_updated, self._config_updated) # Set a default value self.show_cursor_position(1, 0) # Add button callbacks connect_button(self.rescan_button, emit(self, signals.rescan_and_refresh)) connect_button(self.fetch_button, remote.fetch) connect_button(self.push_button, remote.push) connect_button(self.pull_button, remote.pull) connect_button(self.stash_button, stash.stash) connect_button(self.stage_button, self.stage) connect_button(self.unstage_button, self.unstage) self.connect(self.menu_open_recent, SIGNAL('aboutToShow()'), self.build_recent_menu) self.connect(self.commitmsgeditor, SIGNAL('cursorPosition(int,int)'), self.show_cursor_position) self.connect(self, SIGNAL('update'), self._update_callback) self.connect(self, SIGNAL('install_config_actions'), self._install_config_actions) # Install .git-config-defined actions self._config_task = None self.install_config_actions() # Restore saved settings qtutils.apply_state(self) self.statusdockwidget.widget().setFocus() log(0, version.git_version_str() + '\ncola version ' + version.version())