def commit(self): """Attempt to create a commit from the index and commit message.""" if not bool(self.summary.value()): # Describe a good commit message error_msg = N_( 'Please supply a commit message.\n\n' 'A good commit message has the following format:\n\n' '- First line: Describe in one sentence what you did.\n' '- Second line: Blank\n' '- Remaining lines: Describe why this change is good.\n') Interaction.log(error_msg) Interaction.information(N_('Missing Commit Message'), error_msg) return msg = self.commit_message(raw=False) if not self.model.staged: error_msg = N_( 'No changes to commit.\n\n' 'You must stage at least 1 file before you can commit.') if self.model.modified: informative_text = N_('Would you like to stage and ' 'commit all modified files?') if not qtutils.confirm(N_('Stage and commit?'), error_msg, informative_text, N_('Stage and Commit'), default=True, icon=icons.save()): return else: Interaction.information(N_('Nothing to commit'), error_msg) return cmds.do(cmds.StageModified) # Warn that amending published commits is generally bad amend = self.amend_action.isChecked() if (amend and self.model.is_commit_published() and not qtutils.confirm( N_('Rewrite Published Commit?'), N_('This commit has already been published.\n' 'This operation will rewrite published history.\n' 'You probably don\'t want to do this.'), N_('Amend the published commit?'), N_('Amend Commit'), default=False, icon=icons.save())): return no_verify = self.bypass_commit_hooks_action.isChecked() sign = self.sign_action.isChecked() status, out, err = cmds.do(cmds.Commit, amend, msg, sign, no_verify=no_verify) if status != 0: Interaction.critical( N_('Commit failed'), N_('"git commit" returned exit code %s') % (status, ), out + err)
def commit(self): """Attempt to create a commit from the index and commit message.""" if not bool(self.summary.value()): # Describe a good commit message error_msg = N_('' 'Please supply a commit message.\n\n' 'A good commit message has the following format:\n\n' '- First line: Describe in one sentence what you did.\n' '- Second line: Blank\n' '- Remaining lines: Describe why this change is good.\n') Interaction.log(error_msg) Interaction.information(N_('Missing Commit Message'), error_msg) return msg = self.commit_message(raw=False) if not self.model.staged: error_msg = N_('' 'No changes to commit.\n\n' 'You must stage at least 1 file before you can commit.') if self.model.modified: informative_text = N_('Would you like to stage and ' 'commit all modified files?') if not qtutils.confirm( N_('Stage and commit?'), error_msg, informative_text, N_('Stage and Commit'), default=True, icon=icons.save()): return else: Interaction.information(N_('Nothing to commit'), error_msg) return cmds.do(cmds.StageModified) # Warn that amending published commits is generally bad amend = self.amend_action.isChecked() if (amend and self.model.is_commit_published() and not qtutils.confirm( N_('Rewrite Published Commit?'), N_('This commit has already been published.\n' 'This operation will rewrite published history.\n' 'You probably don\'t want to do this.'), N_('Amend the published commit?'), N_('Amend Commit'), default=False, icon=icons.save())): return no_verify = self.bypass_commit_hooks_action.isChecked() sign = self.sign_action.isChecked() status, out, err = cmds.do(cmds.Commit, amend, msg, sign, no_verify=no_verify) if status != 0: Interaction.critical(N_('Commit failed'), N_('"git commit" returned exit code %s') % (status,), out + err)
def save_archive(self): filename = self.filename if not filename: return if core.exists(filename): title = N_('Overwrite File?') msg = N_('The file "%s" exists and will be overwritten.') % filename info_txt = N_('Overwrite "%s"?') % filename ok_txt = N_('Overwrite') if not qtutils.confirm(title, msg, info_txt, ok_txt, default=False, icon=icons.save()): return self.accept()
def save_archive(self): filename = self.filename if not filename: return if core.exists(filename): title = N_('Overwrite File?') msg = N_( 'The file "%s" exists and will be overwritten.') % filename info_txt = N_('Overwrite "%s"?') % filename ok_txt = N_('Overwrite') if not qtutils.confirm( title, msg, info_txt, ok_txt, default=False, icon=icons.save()): return self.accept()
def create_tag(self): """Verifies inputs and emits a notifier tag message.""" revision = self.revision.value() tag_name = self.tag_name.value() tag_msg = self.tag_msg.value() sign_tag = self.sign_tag.isChecked() if not revision: qtutils.critical(N_('Missing Revision'), N_('Please specify a revision to tag.')) return elif not tag_name: qtutils.critical(N_('Missing Name'), N_('Please specify a name for the new tag.')) return elif (sign_tag and not tag_msg and not qtutils.confirm(N_('Missing Tag Message'), N_('Tag-signing was requested but the tag ' 'message is empty.'), N_('An unsigned, lightweight tag will be ' 'created instead.\n' 'Create an unsigned tag?'), N_('Create Unsigned Tag'), default=False, icon=icons.save())): return status, output, err = cmds.do(cmds.Tag, tag_name, revision, sign=sign_tag, message=tag_msg) if status == 0: qtutils.information(N_('Tag Created'), N_('Created a new tag named "%s"') % tag_name, details=tag_msg or None) self.close() else: qtutils.critical( N_('Error: could not create tag "%s"') % tag_name, (N_('git tag returned exit code %s') % status) + ((output + err) and ('\n\n' + output + err) or ''))
def create_tag(self): """Verifies inputs and emits a notifier tag message.""" revision = self.revision.value() tag_name = self.tag_name.value() tag_msg = self.tag_msg.value() sign_tag = self.sign_tag.isChecked() if not revision: qtutils.critical(N_('Missing Revision'), N_('Please specify a revision to tag.')) return elif not tag_name: qtutils.critical(N_('Missing Name'), N_('Please specify a name for the new tag.')) return elif (sign_tag and not tag_msg and not qtutils.confirm(N_('Missing Tag Message'), N_('Tag-signing was requested but the tag ' 'message is empty.'), N_('An unsigned, lightweight tag will be ' 'created instead.\n' 'Create an unsigned tag?'), N_('Create Unsigned Tag'), default=False, icon=icons.save())): return status, output, err = cmds.do(cmds.Tag, tag_name, revision, sign=sign_tag, message=tag_msg) if status == 0: qtutils.information(N_('Tag Created'), N_('Created a new tag named "%s"') % tag_name, details=tag_msg or None) self.close() else: qtutils.critical(N_('Error: could not create tag "%s"') % tag_name, (N_('git tag returned exit code %s') % status) + ((output+err) and ('\n\n' + output + err) or ''))
def __init__(self, ref, shortref=None, parent=None): QtGui.QDialog.__init__(self, parent) if parent is not None: self.setWindowModality(Qt.WindowModal) # input self.ref = ref if shortref is None: shortref = ref # outputs self.fmt = None filename = '%s-%s' % (os.path.basename(core.getcwd()), shortref) self.prefix = filename + '/' self.filename = filename # widgets self.setWindowTitle(N_('Save Archive')) self.filetext = QtGui.QLineEdit() self.filetext.setText(self.filename) self.browse = qtutils.create_toolbutton(icon=icons.file_zip()) self.format_strings = ( git.archive('--list')[STDOUT].rstrip().splitlines()) self.format_combo = QtGui.QComboBox() self.format_combo.setEditable(False) self.format_combo.addItems(self.format_strings) self.close_button = qtutils.close_button() self.save_button = qtutils.create_button(text=N_('Save'), icon=icons.save(), default=True) self.prefix_label = QtGui.QLabel() self.prefix_label.setText(N_('Prefix')) self.prefix_text = QtGui.QLineEdit() self.prefix_text.setText(self.prefix) self.prefix_group = ExpandableGroupBox() self.prefix_group.setTitle(N_('Advanced')) # layouts self.filelayt = qtutils.hbox(defs.no_margin, defs.spacing, self.browse, self.filetext, self.format_combo) self.prefixlayt = qtutils.hbox(defs.margin, defs.spacing, self.prefix_label, self.prefix_text) self.prefix_group.setLayout(self.prefixlayt) self.prefix_group.set_expanded(False) self.btnlayt = qtutils.hbox(defs.no_margin, defs.spacing, qtutils.STRETCH, self.close_button, self.save_button) self.mainlayt = qtutils.vbox(defs.margin, defs.no_spacing, self.filelayt, self.prefix_group, qtutils.STRETCH, self.btnlayt) self.setLayout(self.mainlayt) self.resize(defs.scale(520), defs.scale(10)) # initial setup; done before connecting to avoid # signal/slot side-effects if 'tar.gz' in self.format_strings: idx = self.format_strings.index('tar.gz') elif 'zip' in self.format_strings: idx = self.format_strings.index('zip') else: idx = 0 self.format_combo.setCurrentIndex(idx) self.update_filetext_for_format(idx) # connections self.connect(self.filetext, SIGNAL('textChanged(QString)'), self.filetext_changed) self.connect(self.prefix_text, SIGNAL('textChanged(QString)'), self.prefix_text_changed) self.connect(self.format_combo, SIGNAL('currentIndexChanged(int)'), self.update_filetext_for_format) self.connect(self.prefix_group, SIGNAL('expanded(bool)'), self.prefix_group_expanded) self.connect(self, SIGNAL('accepted()'), self.archive_saved) qtutils.connect_button(self.browse, self.choose_filename) qtutils.connect_button(self.close_button, self.reject) qtutils.connect_button(self.save_button, self.save_archive)
def __init__(self, parent): standard.Dialog.__init__(self, parent) self.setAttribute(Qt.WA_MacMetalStyle) self.setWindowTitle(N_('Search')) self.mode_combo = QtGui.QComboBox() self.browse_button = create_toolbutton(icon=icons.folder(), tooltip=N_('Browse...')) self.query = QtGui.QLineEdit() self.start_date = QtGui.QDateEdit() self.start_date.setCurrentSection(QtGui.QDateTimeEdit.YearSection) self.start_date.setCalendarPopup(True) self.start_date.setDisplayFormat(N_('yyyy-MM-dd')) self.end_date = QtGui.QDateEdit() self.end_date.setCurrentSection(QtGui.QDateTimeEdit.YearSection) self.end_date.setCalendarPopup(True) self.end_date.setDisplayFormat(N_('yyyy-MM-dd')) icon = icons.search() self.search_button = qtutils.create_button(text=N_('Search'), icon=icon, default=True) self.max_count = QtGui.QSpinBox() self.max_count.setMinimum(5) self.max_count.setMaximum(9995) self.max_count.setSingleStep(5) self.max_count.setValue(500) self.commit_list = QtGui.QListWidget() self.commit_list.setMinimumSize(QtCore.QSize(1, 1)) self.commit_list.setAlternatingRowColors(True) selection_mode = QtGui.QAbstractItemView.SingleSelection self.commit_list.setSelectionMode(selection_mode) self.commit_text = DiffTextEdit(self, whitespace=False) self.button_export = qtutils.create_button(text=N_('Export Patches'), icon=icons.diff()) self.button_cherrypick = qtutils.create_button(text=N_('Cherry Pick'), icon=icons.save()) self.button_close = qtutils.close_button() self.top_layout = qtutils.hbox(defs.no_margin, defs.button_spacing, self.query, self.start_date, self.end_date, self.browse_button, self.search_button, qtutils.STRETCH, self.mode_combo, self.max_count) self.splitter = qtutils.splitter(Qt.Vertical, self.commit_list, self.commit_text) self.bottom_layout = qtutils.hbox(defs.no_margin, defs.spacing, self.button_export, self.button_cherrypick, qtutils.STRETCH, self.button_close) self.main_layout = qtutils.vbox(defs.margin, defs.spacing, self.top_layout, self.splitter, self.bottom_layout) self.setLayout(self.main_layout) if self.parent(): self.resize(self.parent().width(), self.parent().height()) else: self.resize(720, 500)
def __init__(self, model, parent): QtGui.QWidget.__init__(self, parent) self.model = model self.spellcheck_initialized = False self._linebreak = None self._textwidth = None self._tabwidth = None # Actions self.signoff_action = qtutils.add_action(self, cmds.SignOff.name(), cmds.run(cmds.SignOff), hotkeys.SIGNOFF) self.signoff_action.setToolTip(N_('Sign off on this commit')) self.commit_action = qtutils.add_action(self, N_('Commit@@verb'), self.commit, hotkeys.COMMIT) self.commit_action.setToolTip(N_('Commit staged changes')) self.clear_action = qtutils.add_action(self, N_('Clear...'), self.clear) self.launch_editor = actions.launch_editor(self) self.launch_difftool = actions.launch_difftool(self) self.stage_or_unstage = actions.stage_or_unstage(self) self.move_up = actions.move_up(self) self.move_down = actions.move_down(self) # Widgets self.summary = CommitSummaryLineEdit() self.summary.setMinimumHeight(defs.tool_button_height) self.summary.extra_actions.append(self.clear_action) self.summary.extra_actions.append(None) self.summary.extra_actions.append(self.signoff_action) self.summary.extra_actions.append(self.commit_action) self.summary.extra_actions.append(None) self.summary.extra_actions.append(self.launch_editor) self.summary.extra_actions.append(self.launch_difftool) self.summary.extra_actions.append(self.stage_or_unstage) self.summary.extra_actions.append(None) self.summary.extra_actions.append(self.move_up) self.summary.extra_actions.append(self.move_down) self.description = CommitMessageTextEdit() self.description.extra_actions.append(self.clear_action) self.description.extra_actions.append(None) self.description.extra_actions.append(self.signoff_action) self.description.extra_actions.append(self.commit_action) self.description.extra_actions.append(None) self.description.extra_actions.append(self.launch_editor) self.description.extra_actions.append(self.launch_difftool) self.description.extra_actions.append(self.stage_or_unstage) self.description.extra_actions.append(None) self.description.extra_actions.append(self.move_up) self.description.extra_actions.append(self.move_down) commit_button_tooltip = N_('Commit staged changes\n' 'Shortcut: Ctrl+Enter') self.commit_button = qtutils.create_toolbutton( text=N_('Commit@@verb'), tooltip=commit_button_tooltip, icon=icons.save()) self.commit_group = Group(self.commit_action, self.commit_button) self.actions_menu = QtGui.QMenu() self.actions_button = qtutils.create_toolbutton( icon=icons.configure(), tooltip=N_('Actions...')) self.actions_button.setMenu(self.actions_menu) self.actions_button.setPopupMode(QtGui.QToolButton.InstantPopup) qtutils.hide_button_menu_indicator(self.actions_button) self.actions_menu.addAction(self.signoff_action) self.actions_menu.addAction(self.commit_action) self.actions_menu.addSeparator() # Amend checkbox self.amend_action = self.actions_menu.addAction( N_('Amend Last Commit')) self.amend_action.setCheckable(True) self.amend_action.setShortcut(hotkeys.AMEND) self.amend_action.setShortcutContext(Qt.ApplicationShortcut) # Bypass hooks self.bypass_commit_hooks_action = self.actions_menu.addAction( N_('Bypass Commit Hooks')) self.bypass_commit_hooks_action.setCheckable(True) self.bypass_commit_hooks_action.setChecked(False) # Sign commits cfg = gitcfg.current() self.sign_action = self.actions_menu.addAction( N_('Create Signed Commit')) self.sign_action.setCheckable(True) self.sign_action.setChecked(cfg.get('cola.signcommits', False)) # Spell checker self.check_spelling_action = self.actions_menu.addAction( N_('Check Spelling')) self.check_spelling_action.setCheckable(True) self.check_spelling_action.setChecked(False) # Line wrapping self.autowrap_action = self.actions_menu.addAction( N_('Auto-Wrap Lines')) self.autowrap_action.setCheckable(True) self.autowrap_action.setChecked(prefs.linebreak()) # Commit message self.actions_menu.addSeparator() self.load_commitmsg_menu = self.actions_menu.addMenu( N_('Load Previous Commit Message')) self.connect(self.load_commitmsg_menu, SIGNAL('aboutToShow()'), self.build_commitmsg_menu) self.fixup_commit_menu = self.actions_menu.addMenu( N_('Fixup Previous Commit')) self.connect(self.fixup_commit_menu, SIGNAL('aboutToShow()'), self.build_fixup_menu) self.toplayout = qtutils.hbox(defs.no_margin, defs.spacing, self.actions_button, self.summary, self.commit_button) self.toplayout.setContentsMargins(defs.margin, defs.no_margin, defs.no_margin, defs.no_margin) self.mainlayout = qtutils.vbox(defs.no_margin, defs.spacing, self.toplayout, self.description) self.setLayout(self.mainlayout) qtutils.connect_button(self.commit_button, self.commit) # Broadcast the amend mode qtutils.connect_action_bool(self.amend_action, cmds.run(cmds.AmendMode)) qtutils.connect_action_bool(self.check_spelling_action, self.toggle_check_spelling) # Handle the one-off autowrapping qtutils.connect_action_bool(self.autowrap_action, self.set_linebreak) qtutils.add_action(self.summary, N_('Move Down'), self.focus_description, *hotkeys.ACCEPT) qtutils.add_action(self.summary, N_('Move Down'), self.summary_cursor_down, hotkeys.DOWN) self.selection_model = selection_model = selection.selection_model() selection_model.add_observer(selection_model.message_selection_changed, self._update) self.model.add_observer(self.model.message_commit_message_changed, self._set_commit_message) self.connect(self, SIGNAL('set_commit_message(PyQt_PyObject)'), self.set_commit_message, Qt.QueuedConnection) self.connect(self.summary, SIGNAL('cursorPosition(int,int)'), self.emit_position) self.connect(self.description, SIGNAL('cursorPosition(int,int)'), # description starts at line 2 lambda row, col: self.emit_position(row + 2, col)) # Keep model informed of changes self.connect(self.summary, SIGNAL('textChanged(QString)'), self.commit_summary_changed) self.connect(self.description, SIGNAL('textChanged()'), self.commit_message_changed) self.connect(self.description, SIGNAL('leave()'), self.focus_summary) self.connect(self, SIGNAL('update()'), self._update_callback, Qt.QueuedConnection) self.setFont(qtutils.diff_font()) self.summary.hint.enable(True) self.description.hint.enable(True) self.commit_group.setEnabled(False) self.setFocusProxy(self.summary) self.set_tabwidth(prefs.tabwidth()) self.set_textwidth(prefs.textwidth()) self.set_linebreak(prefs.linebreak()) # Loading message commit_msg = '' commit_msg_path = commit_message_path() if commit_msg_path: commit_msg = core.read(commit_msg_path) self.set_commit_message(commit_msg) # Allow tab to jump from the summary to the description self.setTabOrder(self.summary, self.description)
def __init__(self, model, parent=None): Dialog.__init__(self, parent=parent) self.model = model self.stashes = [] self.revids = [] self.names = [] self.setWindowTitle(N_('Stash')) self.setAttribute(QtCore.Qt.WA_MacMetalStyle) if parent is not None: self.setWindowModality(QtCore.Qt.WindowModal) self.resize(parent.width(), 420) else: self.resize(700, 420) self.stash_list = QtGui.QListWidget(self) self.stash_text = DiffTextEdit(self) self.button_apply = qtutils.create_toolbutton( text=N_('Apply'), tooltip=N_('Apply the selected stash'), icon=icons.ok()) self.button_save = qtutils.create_toolbutton( text=N_('Save'), tooltip=N_('Save modified state to new stash'), icon=icons.save()) self.button_drop = qtutils.create_toolbutton( text=N_('Drop'), tooltip=N_('Drop the selected stash'), icon=icons.discard()) self.button_close = qtutils.close_button() self.keep_index = qtutils.checkbox(text=N_('Keep Index'), checked=True) # Arrange layouts self.splitter = qtutils.splitter(Qt.Horizontal, self.stash_list, self.stash_text) self.btn_layt = qtutils.hbox(defs.no_margin, defs.spacing, self.button_save, self.button_apply, self.button_drop, self.keep_index, qtutils.STRETCH, self.button_close) self.main_layt = qtutils.vbox(defs.margin, defs.spacing, self.splitter, self.btn_layt) self.setLayout(self.main_layt) self.splitter.setSizes([self.width() // 3, self.width() * 2 // 3]) self.update_from_model() self.update_actions() self.setTabOrder(self.button_save, self.button_apply) self.setTabOrder(self.button_apply, self.button_drop) self.setTabOrder(self.button_drop, self.keep_index) self.setTabOrder(self.keep_index, self.button_close) self.connect(self.stash_list, SIGNAL('itemSelectionChanged()'), self.item_selected) qtutils.connect_button(self.button_apply, self.stash_apply) qtutils.connect_button(self.button_save, self.stash_save) qtutils.connect_button(self.button_drop, self.stash_drop) qtutils.connect_button(self.button_close, self.close)
def __init__(self, model, parent=None): Dialog.__init__(self, parent=parent) self.model = model self.stashes = [] self.revids = [] self.names = [] self.setWindowTitle(N_('Stash')) self.setAttribute(QtCore.Qt.WA_MacMetalStyle) if parent is not None: self.setWindowModality(QtCore.Qt.WindowModal) self.resize(parent.width(), 420) else: self.resize(700, 420) self.stash_list = QtGui.QListWidget(self) self.stash_text = DiffTextEdit(self) self.button_apply = qtutils.create_toolbutton( text=N_('Apply'), tooltip=N_('Apply the selected stash'), icon=icons.ok()) self.button_save = qtutils.create_toolbutton( text=N_('Save'), tooltip=N_('Save modified state to new stash'), icon=icons.save()) self.button_drop = qtutils.create_toolbutton( text=N_('Drop'), tooltip=N_('Drop the selected stash'), icon=icons.discard()) self.button_close = qtutils.close_button() self.keep_index = qtutils.checkbox(text=N_('Keep Index'), checked=True) # Arrange layouts self.splitter = qtutils.splitter(Qt.Horizontal, self.stash_list, self.stash_text) self.btn_layt = qtutils.hbox(defs.no_margin, defs.spacing, self.button_save, self.button_apply, self.button_drop, self.keep_index, qtutils.STRETCH, self.button_close) self.main_layt = qtutils.vbox(defs.margin, defs.spacing, self.splitter, self.btn_layt) self.setLayout(self.main_layt) self.splitter.setSizes([self.width()//3, self.width()*2//3]) self.update_from_model() self.update_actions() self.setTabOrder(self.button_save, self.button_apply) self.setTabOrder(self.button_apply, self.button_drop) self.setTabOrder(self.button_drop, self.keep_index) self.setTabOrder(self.keep_index, self.button_close) self.connect(self.stash_list, SIGNAL('itemSelectionChanged()'), self.item_selected) qtutils.connect_button(self.button_apply, self.stash_apply) qtutils.connect_button(self.button_save, self.stash_save) qtutils.connect_button(self.button_drop, self.stash_drop) qtutils.connect_button(self.button_close, self.close)