def __init__(self, model, parent=None, title=None, multiselect=True, syntax=True): QtGui.QDialog.__init__(self, parent) self.model = model if title: self.setWindowTitle(title) self.commit_list = QtGui.QListWidget() if multiselect: mode = QtGui.QAbstractItemView.ExtendedSelection else: mode = QtGui.QAbstractItemView.SingleSelection self.commit_list.setSelectionMode(mode) self.commit_list.setAlternatingRowColors(True) self.commit_text = DiffTextEdit(self, whitespace=False) self.label = QtGui.QLabel() self.label.setText(N_('Revision Expression:')) self.revision = QtGui.QLineEdit() self.revision.setReadOnly(True) self.select_button = QtGui.QPushButton(N_('Select')) self.select_button.setIcon(qtutils.apply_icon()) self.select_button.setEnabled(False) self.select_button.setDefault(True) self.close_button = QtGui.QPushButton(N_('Close')) # Make the list widget slighty larger self.splitter = qtutils.splitter(Qt.Vertical, self.commit_list, self.commit_text) self.splitter.setSizes([100, 150]) self.input_layout = qtutils.hbox(defs.no_margin, defs.spacing, self.label, self.revision, self.select_button, self.close_button) self.main_layout = qtutils.vbox(defs.margin, defs.margin, self.splitter, self.input_layout) self.setLayout(self.main_layout) self.connect(self.commit_list, SIGNAL('itemSelectionChanged()'), self.commit_sha1_selected) self.connect(self.commit_list, SIGNAL('itemDoubleClicked(QListWidgetItem*)'), self.commit_sha1_double_clicked) qtutils.connect_button(self.select_button, self.accept) qtutils.connect_button(self.close_button, self.reject) self.resize(700, 420)
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, parent): standard.Dialog.__init__(self, parent) self.setAttribute(QtCore.Qt.WA_MacMetalStyle) self.setWindowTitle(N_('Search')) self.mode_combo = QtGui.QComboBox() self.browse_button = create_toolbutton(icon=dir_icon(), 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')) self.search_button = QtGui.QPushButton() self.search_button.setText(N_('Search')) self.search_button.setDefault(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) self.commit_list.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) self.commit_text = DiffTextEdit(self, whitespace=False) self.button_export = QtGui.QPushButton() self.button_export.setText(N_('Export Patches')) self.button_cherrypick = QtGui.QPushButton() self.button_cherrypick.setText(N_('Cherry Pick')) self.button_close = QtGui.QPushButton() self.button_close.setText(N_('Close')) self.top_layout = QtGui.QHBoxLayout() self.top_layout.setMargin(0) self.top_layout.setSpacing(defs.button_spacing) self.top_layout.addWidget(self.query) self.top_layout.addWidget(self.start_date) self.top_layout.addWidget(self.end_date) self.top_layout.addWidget(self.browse_button) self.top_layout.addWidget(self.search_button) self.top_layout.addStretch() self.top_layout.addWidget(self.mode_combo) self.top_layout.addWidget(self.max_count) self.splitter = QtGui.QSplitter() self.splitter.setHandleWidth(defs.handle_width) self.splitter.setOrientation(QtCore.Qt.Vertical) self.splitter.setChildrenCollapsible(True) self.splitter.addWidget(self.commit_list) self.splitter.addWidget(self.commit_text) self.bottom_layout = QtGui.QHBoxLayout() self.bottom_layout.setMargin(0) self.bottom_layout.setSpacing(defs.spacing) self.bottom_layout.addWidget(self.button_export) self.bottom_layout.addWidget(self.button_cherrypick) self.bottom_layout.addStretch() self.bottom_layout.addWidget(self.button_close) self.main_layout = QtGui.QVBoxLayout() self.main_layout.setMargin(defs.margin) self.main_layout.setSpacing(defs.spacing) self.main_layout.addLayout(self.top_layout) self.main_layout.addWidget(self.splitter) self.main_layout.addLayout(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=None): Dialog.__init__(self, parent=parent) self.setAttribute(QtCore.Qt.WA_MacMetalStyle) self.model = model self.stashes = [] self.revids = [] self.names = [] self.setWindowModality(QtCore.Qt.WindowModal) self.setWindowTitle(N_('Stash')) if parent: self.resize(parent.width(), 420) else: self.resize(700, 420) self.stash_list = QtGui.QListWidget(self) self.stash_text = DiffTextEdit(self) self.button_apply =\ self.toolbutton(N_('Apply'), N_('Apply the selected stash'), qtutils.apply_icon()) self.button_save =\ self.toolbutton(N_('Save'), N_('Save modified state to new stash'), qtutils.save_icon()) self.button_drop = \ self.toolbutton(N_('Drop'), N_('Drop the selected stash'), qtutils.discard_icon()) self.button_close = \ self.pushbutton(N_('Close'), N_('Close'), qtutils.close_icon()) self.keep_index = QtGui.QCheckBox(self) self.keep_index.setText(N_('Keep Index')) self.keep_index.setChecked(True) # Arrange layouts self.main_layt = QtGui.QVBoxLayout() self.main_layt.setMargin(defs.margin) self.main_layt.setSpacing(defs.spacing) self.btn_layt = QtGui.QHBoxLayout() self.btn_layt.setMargin(0) self.btn_layt.setSpacing(defs.spacing) self.splitter = QtGui.QSplitter() self.splitter.setHandleWidth(defs.handle_width) self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setChildrenCollapsible(True) self.splitter.setStretchFactor(0, 1) self.splitter.setStretchFactor(1, 1) self.splitter.insertWidget(0, self.stash_list) self.splitter.insertWidget(1, self.stash_text) self.btn_layt.addWidget(self.button_save) self.btn_layt.addWidget(self.button_apply) self.btn_layt.addWidget(self.button_drop) self.btn_layt.addWidget(self.keep_index) self.btn_layt.addStretch() self.btn_layt.addWidget(self.button_close) self.main_layt.addWidget(self.splitter) self.main_layt.addLayout(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)
class StashView(Dialog): def __init__(self, model, parent=None): Dialog.__init__(self, parent=parent) self.setAttribute(QtCore.Qt.WA_MacMetalStyle) self.model = model self.stashes = [] self.revids = [] self.names = [] self.setWindowModality(QtCore.Qt.WindowModal) self.setWindowTitle(N_('Stash')) if parent: self.resize(parent.width(), 420) else: self.resize(700, 420) self.stash_list = QtGui.QListWidget(self) self.stash_text = DiffTextEdit(self) self.button_apply =\ self.toolbutton(N_('Apply'), N_('Apply the selected stash'), qtutils.apply_icon()) self.button_save =\ self.toolbutton(N_('Save'), N_('Save modified state to new stash'), qtutils.save_icon()) self.button_drop = \ self.toolbutton(N_('Drop'), N_('Drop the selected stash'), qtutils.discard_icon()) self.button_close = \ self.pushbutton(N_('Close'), N_('Close'), qtutils.close_icon()) self.keep_index = QtGui.QCheckBox(self) self.keep_index.setText(N_('Keep Index')) self.keep_index.setChecked(True) # Arrange layouts self.main_layt = QtGui.QVBoxLayout() self.main_layt.setMargin(defs.margin) self.main_layt.setSpacing(defs.spacing) self.btn_layt = QtGui.QHBoxLayout() self.btn_layt.setMargin(0) self.btn_layt.setSpacing(defs.spacing) self.splitter = QtGui.QSplitter() self.splitter.setHandleWidth(defs.handle_width) self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setChildrenCollapsible(True) self.splitter.setStretchFactor(0, 1) self.splitter.setStretchFactor(1, 1) self.splitter.insertWidget(0, self.stash_list) self.splitter.insertWidget(1, self.stash_text) self.btn_layt.addWidget(self.button_save) self.btn_layt.addWidget(self.button_apply) self.btn_layt.addWidget(self.button_drop) self.btn_layt.addWidget(self.keep_index) self.btn_layt.addStretch() self.btn_layt.addWidget(self.button_close) self.main_layt.addWidget(self.splitter) self.main_layt.addLayout(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 close(self): self.accept() cmds.do(cmds.Rescan) def toolbutton(self, text, tooltip, icon): return qtutils.create_toolbutton(text=text, tooltip=tooltip, icon=icon) def pushbutton(self, text, tooltip, icon): btn = QtGui.QPushButton(self) btn.setText(text) btn.setToolTip(tooltip) btn.setIcon(icon) return btn def selected_stash(self): """Returns the stash name of the currently selected stash """ list_widget = self.stash_list stash_list = self.revids return qtutils.selected_item(list_widget, stash_list) def selected_name(self): list_widget = self.stash_list stash_list = self.names return qtutils.selected_item(list_widget, stash_list) def item_selected(self): """Shows the current stash in the main view.""" self.update_actions() selection = self.selected_stash() if not selection: return diff_text = self.model.stash_diff(selection) self.stash_text.setPlainText(diff_text) def update_actions(self): has_changes = self.model.has_stashable_changes() has_stash = bool(self.selected_stash()) self.button_save.setEnabled(has_changes) self.button_apply.setEnabled(has_stash) self.button_drop.setEnabled(has_stash) def update_from_model(self): """Initiates git queries on the model and updates the view """ stashes, revids, names = self.model.stash_info() self.stashes = stashes self.revids = revids self.names = names self.stash_list.clear() self.stash_list.addItems(self.stashes) def stash_apply(self): """Applies the currently selected stash """ selection = self.selected_stash() if not selection: return index = self.keep_index.isChecked() cmds.do(ApplyStash, selection, index) self.accept() cmds.do(cmds.Rescan) def stash_save(self): """Saves the worktree in a stash This prompts the user for a stash name and creates a git stash named accordingly. """ stash_name, ok = qtutils.prompt(N_('Save Stash'), N_('Enter a name for the stash')) if not ok or not stash_name: return # Sanitize the stash name stash_name = utils.sanitize(stash_name) if stash_name in self.names: qtutils.critical( N_('Error: Stash exists'), N_('A stash named "%s" already exists') % stash_name) return keep_index = self.keep_index.isChecked() cmds.do(SaveStash, stash_name, keep_index) self.accept() cmds.do(cmds.Rescan) def stash_drop(self): """Drops the currently selected stash """ selection = self.selected_stash() name = self.selected_name() if not selection: return if not qtutils.confirm( N_('Drop Stash?'), N_('Recovering a dropped stash is not possible.'), N_('Drop the "%s" stash?') % name, N_('Drop Stash'), default=True, icon=qtutils.discard_icon()): return cmds.do(DropStash, selection) self.update_from_model() self.stash_text.setPlainText('')
class SelectCommitsDialog(QtGui.QDialog): def __init__(self, model, parent=None, title=None, multiselect=True, syntax=True): QtGui.QDialog.__init__(self, parent) self.model = model if title: self.setWindowTitle(title) self.commit_list = QtGui.QListWidget() if multiselect: mode = QtGui.QAbstractItemView.ExtendedSelection else: mode = QtGui.QAbstractItemView.SingleSelection self.commit_list.setSelectionMode(mode) self.commit_list.setAlternatingRowColors(True) self.commit_text = DiffTextEdit(self, whitespace=False) self.label = QtGui.QLabel() self.label.setText(N_('Revision Expression:')) self.revision = QtGui.QLineEdit() self.revision.setReadOnly(True) self.select_button = QtGui.QPushButton(N_('Select')) self.select_button.setIcon(qtutils.apply_icon()) self.select_button.setEnabled(False) self.select_button.setDefault(True) self.close_button = QtGui.QPushButton(N_('Close')) # Make the list widget slighty larger self.splitter = QtGui.QSplitter() self.splitter.setOrientation(QtCore.Qt.Vertical) self.splitter.setHandleWidth(defs.handle_width) self.splitter.setSizes([100, 150]) self.splitter.addWidget(self.commit_list) self.splitter.addWidget(self.commit_text) self.input_layout = QtGui.QHBoxLayout() self.input_layout.setMargin(0) self.input_layout.setSpacing(defs.spacing) self.input_layout.addWidget(self.label) self.input_layout.addWidget(self.revision) self.input_layout.addWidget(self.select_button) self.input_layout.addWidget(self.close_button) self.main_layout = QtGui.QVBoxLayout() self.main_layout.setMargin(defs.margin) self.main_layout.setSpacing(defs.margin) self.main_layout.addWidget(self.splitter) self.main_layout.addLayout(self.input_layout) self.setLayout(self.main_layout) self.connect(self.commit_list, SIGNAL('itemSelectionChanged()'), self.commit_sha1_selected) qtutils.connect_button(self.select_button, self.accept) qtutils.connect_button(self.close_button, self.reject) #self.setTabOrder(self.commit_list, self.commit_text) #self.setTabOrder(self.commit_text, self.revision) #self.setTabOrder(self.revision, self.select_button) #self.setTabOrder(self.select_button, self.close_button) #self.setTabOrder(self.close_button, self.commit_list) self.resize(700, 420) def select_commits(self): summaries = self.model.summaries if not summaries: msg = N_('No commits exist in this branch.') Interaction.log(msg) return [] qtutils.set_items(self.commit_list, summaries) self.show() if self.exec_() != QtGui.QDialog.Accepted: return [] revs = self.model.revisions return qtutils.selection_list(self.commit_list, revs) def commit_sha1_selected(self): row, selected = qtutils.selected_row(self.commit_list) self.select_button.setEnabled(selected) if not selected: self.commit_text.setText('') self.revision.setText('') return # Get the sha1 and put it in the revision line sha1 = self.model.revision_sha1(row) self.revision.setText(sha1) self.revision.selectAll() # Display the sha1's commit commit_diff = gitcmds.commit_diff(sha1) self.commit_text.setText(commit_diff)
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 =\ self.toolbutton(N_('Apply'), N_('Apply the selected stash'), qtutils.apply_icon()) self.button_save =\ self.toolbutton(N_('Save'), N_('Save modified state to new stash'), qtutils.save_icon()) self.button_drop = \ self.toolbutton(N_('Drop'), N_('Drop the selected stash'), qtutils.discard_icon()) self.button_close = \ self.pushbutton(N_('Close'), N_('Close'), qtutils.close_icon()) self.keep_index = QtGui.QCheckBox(self) self.keep_index.setText(N_('Keep Index')) self.keep_index.setChecked(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, parent): super(SearchWidget, self).__init__(parent) self.setAttribute(QtCore.Qt.WA_MacMetalStyle) self.setWindowTitle(self.tr('Search')) self.mode_combo = QtGui.QComboBox() self.browse_button = create_toolbutton(icon=dir_icon(), tooltip='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(self.tr('yyyy-MM-dd')) self.end_date = QtGui.QDateEdit() self.end_date.setCurrentSection(QtGui.QDateTimeEdit.YearSection) self.end_date.setCalendarPopup(True) self.end_date.setDisplayFormat(self.tr('yyyy-MM-dd')) self.search_button = QtGui.QPushButton() self.search_button.setText(self.tr('Search')) self.search_button.setDefault(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) self.commit_list.setSelectionMode(QtGui.QAbstractItemView.SingleSelection) self.commit_text = DiffTextEdit(self, whitespace=False) self.commit_text.setTabChangesFocus(True) self.commit_text.setReadOnly(True) self.button_export = QtGui.QPushButton() self.button_export.setText(self.tr('Export Patches')) self.button_cherrypick = QtGui.QPushButton() self.button_cherrypick.setText(self.tr('Cherry Pick')) self.button_close = QtGui.QPushButton() self.button_close.setText(self.tr('Close')) self.top_layout = QtGui.QHBoxLayout() self.top_layout.setMargin(0) self.top_layout.setSpacing(defs.button_spacing) self.top_layout.addWidget(self.query) self.top_layout.addWidget(self.start_date) self.top_layout.addWidget(self.end_date) self.top_layout.addWidget(self.browse_button) self.top_layout.addWidget(self.search_button) self.top_layout.addStretch() self.top_layout.addWidget(self.mode_combo) self.top_layout.addWidget(self.max_count) self.splitter = QtGui.QSplitter() self.splitter.setHandleWidth(defs.handle_width) self.splitter.setOrientation(QtCore.Qt.Vertical) self.splitter.setChildrenCollapsible(True) self.splitter.addWidget(self.commit_list) self.splitter.addWidget(self.commit_text) self.bottom_layout = QtGui.QHBoxLayout() self.bottom_layout.setMargin(0) self.bottom_layout.setSpacing(defs.spacing) self.bottom_layout.addWidget(self.button_export) self.bottom_layout.addWidget(self.button_cherrypick) self.bottom_layout.addStretch() self.bottom_layout.addWidget(self.button_close) self.main_layout = QtGui.QVBoxLayout() self.main_layout.setMargin(defs.margin) self.main_layout.setSpacing(defs.spacing) self.main_layout.addLayout(self.top_layout) self.main_layout.addWidget(self.splitter) self.main_layout.addLayout(self.bottom_layout) self.setLayout(self.main_layout) if self.parent(): self.resize(self.parent().width(), self.parent().height()) else: self.resize(720, 500)
class SelectCommitsDialog(QtGui.QDialog): def __init__(self, model, parent=None, title=None, multiselect=True, syntax=True): QtGui.QDialog.__init__(self, parent) self.model = model if title: self.setWindowTitle(title) self.commit_list = QtGui.QListWidget() if multiselect: mode = QtGui.QAbstractItemView.ExtendedSelection else: mode = QtGui.QAbstractItemView.SingleSelection self.commit_list.setSelectionMode(mode) self.commit_list.setAlternatingRowColors(True) self.commit_text = DiffTextEdit(self, whitespace=False) self.label = QtGui.QLabel() self.label.setText(N_('Revision Expression:')) self.revision = QtGui.QLineEdit() self.revision.setReadOnly(True) self.select_button = QtGui.QPushButton(N_('Select')) self.select_button.setIcon(qtutils.apply_icon()) self.select_button.setEnabled(False) self.select_button.setDefault(True) self.close_button = QtGui.QPushButton(N_('Close')) # Make the list widget slighty larger self.splitter = qtutils.splitter(Qt.Vertical, self.commit_list, self.commit_text) self.splitter.setSizes([100, 150]) self.input_layout = qtutils.hbox(defs.no_margin, defs.spacing, self.label, self.revision, self.select_button, self.close_button) self.main_layout = qtutils.vbox(defs.margin, defs.margin, self.splitter, self.input_layout) self.setLayout(self.main_layout) self.connect(self.commit_list, SIGNAL('itemSelectionChanged()'), self.commit_sha1_selected) qtutils.connect_button(self.select_button, self.accept) qtutils.connect_button(self.close_button, self.reject) self.resize(700, 420) def select_commits(self): summaries = self.model.summaries if not summaries: msg = N_('No commits exist in this branch.') Interaction.log(msg) return [] qtutils.set_items(self.commit_list, summaries) self.show() if self.exec_() != QtGui.QDialog.Accepted: return [] revs = self.model.revisions return qtutils.selected_items(self.commit_list, revs) def commit_sha1_selected(self): sha1 = qtutils.selected_item(self.commit_list, self.model.revisions) selected = (sha1 is not None) self.select_button.setEnabled(selected) if not selected: self.commit_text.setText('') self.revision.setText('') return self.revision.setText(sha1) self.revision.selectAll() # Display the sha1's commit commit_diff = gitcmds.commit_diff(sha1) self.commit_text.setText(commit_diff)
def __init__(self, model, parent): standard.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) # Dockwidget options qtcompat.set_common_dock_options(self) self.classic_dockable = gitcfg.instance().get('cola.classicdockable') if self.classic_dockable: self.classicdockwidget = create_dock('Cola Classic', self) self.classicwidget = classic_widget(self) self.classicdockwidget.setWidget(self.classicwidget) # "Actions" widget self.actiondockwidget = create_dock('Actions', self) self.actiondockwidgetcontents = qt.QFlowLayoutWidget(self) layout = self.actiondockwidgetcontents.layout() self.stage_button = create_button('Stage', layout) self.unstage_button = create_button('Unstage', layout) self.rescan_button = create_button('Rescan', layout) self.fetch_button = create_button('Fetch...', layout) self.push_button = create_button('Push...', layout) self.pull_button = create_button('Pull...', layout) self.stash_button = create_button('Stash...', layout) self.alt_button = create_button('Exit Diff Mode', layout) self.alt_button.hide() layout.addStretch() self.actiondockwidget.setWidget(self.actiondockwidgetcontents) # "Repository Status" widget self.statusdockwidget = create_dock('Repository Status', self) self.statusdockwidget.setWidget(StatusWidget(self)) # "Commit Message Editor" widget self.commitdockwidget = create_dock('Commit Message Editor', self) 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) # "Command Output" widget logwidget = qtutils.logger() logwidget.setFont(diff_font()) self.logdockwidget = create_dock('Command Output', self) self.logdockwidget.setWidget(logwidget) # "Diff Viewer" widget self.diffdockwidget = create_dock('Diff Viewer', self) self.diff_viewer = DiffTextEdit(self.diffdockwidget) self.diffdockwidget.setWidget(self.diff_viewer) # 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), 'Ctrl+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, 'Ctrl+E') self.menu_preferences = add_action(self, 'Preferences', lambda: preferences(model=prefs_model), QtGui.QKeySequence.Preferences, 'Ctrl+O') self.menu_rescan = add_action(self, 'Rescan', emit(self, signals.rescan), 'Ctrl+R') self.menu_rescan.setIcon(qtutils.reload_icon()) 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_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...', guicmds.fetch) self.menu_push = add_action(self, 'Push...', guicmds.push) self.menu_pull = add_action(self, 'Pull...', guicmds.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_diff_branch = add_action(self, 'Apply Changes From Branch...', guicmds.diff_branch) self.menu_branch_compare = add_action(self, 'Branches...', compare.branch_compare) 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', lambda: self.model.git.web__browse(resources.html_docs()), QtGui.QKeySequence.HelpContents) self.menu_commit_compare = add_action(self, 'Commits...', compare.compare) self.menu_commit_compare_file = add_action(self, 'Commits Touching File...', compare.compare_file) 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.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.branch_diff) self.menu_diff_expression = add_action(self, 'Expression...', guicmds.diff_expression) self.menu_create_tag = add_action(self, 'Create Tag...', createtag.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, 'Cola Classic...', 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()) # 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.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_rescan) self.file_menu.addSeparator() 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_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) self.branch_menu.addSeparator() self.branch_menu.addAction(self.menu_diff_branch) # 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.addSeparator() self.diff_menu.addAction(self.menu_branch_compare) self.diff_menu.addAction(self.menu_commit_compare) self.diff_menu.addAction(self.menu_commit_compare_file) 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.tools_menu.addAction(self.diffdockwidget.toggleViewAction()) self.tools_menu.addAction(self.actiondockwidget.toggleViewAction()) self.tools_menu.addAction(self.commitdockwidget.toggleViewAction()) self.tools_menu.addAction(self.statusdockwidget.toggleViewAction()) self.tools_menu.addAction(self.logdockwidget.toggleViewAction()) 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_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.actiondockwidget) 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_message_observer(model.message_mode_changed, self._mode_changed) model.add_message_observer(model.message_updated, self._update_view) prefs_model.add_message_observer(prefs_model.message_config_updated, self._config_updated) # Add button callbacks connect_button(self.rescan_button, emit(self, signals.rescan)) connect_button(self.alt_button, emit(self, signals.reset_mode)) connect_button(self.fetch_button, guicmds.fetch) connect_button(self.push_button, guicmds.push) connect_button(self.pull_button, guicmds.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, SIGNAL('update'), self._update_callback) self.connect(self, SIGNAL('apply_state'), self.apply_state) 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 self._gui_state_task = None self._load_gui_state() log(0, self.model.git_version + '\ncola version ' + version.version())
class MainView(standard.MainWindow): def __init__(self, model, parent): standard.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) # Dockwidget options qtcompat.set_common_dock_options(self) self.classic_dockable = gitcfg.instance().get('cola.classicdockable') if self.classic_dockable: self.classicdockwidget = create_dock('Cola Classic', self) self.classicwidget = classic_widget(self) self.classicdockwidget.setWidget(self.classicwidget) # "Actions" widget self.actiondockwidget = create_dock('Actions', self) self.actiondockwidgetcontents = qt.QFlowLayoutWidget(self) layout = self.actiondockwidgetcontents.layout() self.stage_button = create_button('Stage', layout) self.unstage_button = create_button('Unstage', layout) self.rescan_button = create_button('Rescan', layout) self.fetch_button = create_button('Fetch...', layout) self.push_button = create_button('Push...', layout) self.pull_button = create_button('Pull...', layout) self.stash_button = create_button('Stash...', layout) self.alt_button = create_button('Exit Diff Mode', layout) self.alt_button.hide() layout.addStretch() self.actiondockwidget.setWidget(self.actiondockwidgetcontents) # "Repository Status" widget self.statusdockwidget = create_dock('Repository Status', self) self.statusdockwidget.setWidget(StatusWidget(self)) # "Commit Message Editor" widget self.commitdockwidget = create_dock('Commit Message Editor', self) 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) # "Command Output" widget logwidget = qtutils.logger() logwidget.setFont(diff_font()) self.logdockwidget = create_dock('Command Output', self) self.logdockwidget.setWidget(logwidget) # "Diff Viewer" widget self.diffdockwidget = create_dock('Diff Viewer', self) self.diff_viewer = DiffTextEdit(self.diffdockwidget) self.diffdockwidget.setWidget(self.diff_viewer) # 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), 'Ctrl+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, 'Ctrl+E') self.menu_preferences = add_action(self, 'Preferences', lambda: preferences(model=prefs_model), QtGui.QKeySequence.Preferences, 'Ctrl+O') self.menu_rescan = add_action(self, 'Rescan', emit(self, signals.rescan), 'Ctrl+R') self.menu_rescan.setIcon(qtutils.reload_icon()) 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_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...', guicmds.fetch) self.menu_push = add_action(self, 'Push...', guicmds.push) self.menu_pull = add_action(self, 'Pull...', guicmds.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_diff_branch = add_action(self, 'Apply Changes From Branch...', guicmds.diff_branch) self.menu_branch_compare = add_action(self, 'Branches...', compare.branch_compare) 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', lambda: self.model.git.web__browse(resources.html_docs()), QtGui.QKeySequence.HelpContents) self.menu_commit_compare = add_action(self, 'Commits...', compare.compare) self.menu_commit_compare_file = add_action(self, 'Commits Touching File...', compare.compare_file) 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.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.branch_diff) self.menu_diff_expression = add_action(self, 'Expression...', guicmds.diff_expression) self.menu_create_tag = add_action(self, 'Create Tag...', createtag.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, 'Cola Classic...', 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()) # 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.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_rescan) self.file_menu.addSeparator() 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_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) self.branch_menu.addSeparator() self.branch_menu.addAction(self.menu_diff_branch) # 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.addSeparator() self.diff_menu.addAction(self.menu_branch_compare) self.diff_menu.addAction(self.menu_commit_compare) self.diff_menu.addAction(self.menu_commit_compare_file) 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.tools_menu.addAction(self.diffdockwidget.toggleViewAction()) self.tools_menu.addAction(self.actiondockwidget.toggleViewAction()) self.tools_menu.addAction(self.commitdockwidget.toggleViewAction()) self.tools_menu.addAction(self.statusdockwidget.toggleViewAction()) self.tools_menu.addAction(self.logdockwidget.toggleViewAction()) 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_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.actiondockwidget) 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_message_observer(model.message_mode_changed, self._mode_changed) model.add_message_observer(model.message_updated, self._update_view) prefs_model.add_message_observer(prefs_model.message_config_updated, self._config_updated) # Add button callbacks connect_button(self.rescan_button, emit(self, signals.rescan)) connect_button(self.alt_button, emit(self, signals.reset_mode)) connect_button(self.fetch_button, guicmds.fetch) connect_button(self.push_button, guicmds.push) connect_button(self.pull_button, guicmds.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, SIGNAL('update'), self._update_callback) self.connect(self, SIGNAL('apply_state'), self.apply_state) 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 self._gui_state_task = None self._load_gui_state() log(0, self.model.git_version + '\ncola version ' + version.version()) # Qt overrides def closeEvent(self, event): """Save state in the settings manager.""" qtutils.save_state(self) standard.MainWindow.closeEvent(self, event) # Accessors mode = property(lambda self: self.model.mode) def _mode_changed(self, mode): """React to mode changes; hide/show the "Exit Diff Mode" button.""" if mode in (self.model.mode_branch, self.model.mode_review, self.model.mode_diff, self.model.mode_diff_expr): height = self.stage_button.minimumHeight() self.alt_button.setMinimumHeight(height) self.alt_button.show() else: self.alt_button.setMinimumHeight(1) self.alt_button.hide() def _config_updated(self, source, config, value): if config == 'cola.fontdiff': font = QtGui.QFont() if not font.fromString(value): return self._set_diff_font(font) qtutils.logger().setFont(font) self.diff_viewer.setFont(font) self.commitmsgeditor.commitmsg.setFont(font) elif config == 'cola.tabwidth': # variable-tab-width setting self.diff_viewer.set_tab_width(value) def install_config_actions(self): """Install .gitconfig-defined actions""" self._config_task = self._start_config_actions_task() def _start_config_actions_task(self): """Do the expensive "get_config_actions()" call in the background""" class ConfigActionsTask(QtCore.QRunnable): def __init__(self, sender): QtCore.QRunnable.__init__(self) self._sender = sender def run(self): names = cfgactions.get_config_actions() self._sender.emit(SIGNAL('install_config_actions'), names) task = ConfigActionsTask(self) QtCore.QThreadPool.globalInstance().start(task) return task def _install_config_actions(self, names): """Install .gitconfig-defined actions""" if not names: return menu = self.actions_menu menu.addSeparator() for name in names: menu.addAction(name, emit(self, signals.run_config_action, name)) def _update_view(self): self.emit(SIGNAL('update')) def _update_callback(self): """Update the title with the current branch and directory name.""" branch = self.model.currentbranch curdir = core.decode(os.getcwd()) msg = 'Repository: %s\nBranch: %s' % (curdir, branch) self.commitdockwidget.setToolTip(msg) title = '%s: %s' % (self.model.project, branch) if self.mode in (self.model.mode_diff, self.model.mode_diff_expr): title += ' *** diff mode***' elif self.mode == self.model.mode_review: title += ' *** review mode***' elif self.mode == self.model.mode_amend: title += ' *** amending ***' self.setWindowTitle(title) self.commitmsgeditor.set_mode(self.mode) if not self.model.read_only() and self.mode != self.model.mode_amend: # Check if there's a message file in .git/ merge_msg_path = gitcmds.merge_message_path() if merge_msg_path is None: return merge_msg_hash = utils.checksum(core.decode(merge_msg_path)) if merge_msg_hash == self.merge_message_hash: return self.merge_message_hash = merge_msg_hash cola.notifier().broadcast(signals.load_commit_message, core.decode(merge_msg_path)) def apply_state(self, state): """Imports data for save/restore""" # 1 is the widget version; change when widgets are added/removed standard.MainWindow.apply_state(self, state) qtutils.apply_window_state(self, state, 1) def export_state(self): """Exports data for save/restore""" state = standard.MainWindow.export_state(self) return qtutils.export_window_state(self, state, self.widget_version) def _load_gui_state(self): """Restores the gui from the preferences file.""" self._gui_state_task = self._start_gui_state_loading_thread() def _start_gui_state_loading_thread(self): """Do expensive file reading and json decoding in the background""" class LoadGUIStateTask(QtCore.QRunnable): def __init__(self, sender): QtCore.QRunnable.__init__(self) self._sender = sender def run(self): state = settings.Settings().get_gui_state(self._sender) self._sender.emit(SIGNAL('apply_state'), state) task = LoadGUIStateTask(self) QtCore.QThreadPool.globalInstance().start(task) return task def stage(self): """Stage selected files, or all files if no selection exists.""" paths = cola.selection_model().unstaged if not paths: cola.notifier().broadcast(signals.stage_modified) else: cola.notifier().broadcast(signals.stage, paths) def unstage(self): """Unstage selected files, or all files if no selection exists.""" paths = cola.selection_model().staged if not paths: cola.notifier().broadcast(signals.unstage_all) else: cola.notifier().broadcast(signals.unstage, paths) def dragEnterEvent(self, event): """Accepts drops""" standard.MainWindow.dragEnterEvent(self, event) event.acceptProposedAction() def dropEvent(self, event): """Apply dropped patches with git-am""" event.accept() urls = event.mimeData().urls() if not urls: return paths = map(lambda x: unicode(x.path()), urls) patches = [p for p in paths if p.endswith('.patch')] dirs = [p for p in paths if os.path.isdir(p)] dirs.sort() for d in dirs: patches.extend(self._gather_patches(d)) # Broadcast the patches to apply cola.notifier().broadcast(signals.apply_patches, patches) def _gather_patches(self, path): """Find patches in a subdirectory""" patches = [] for root, subdirs, files in os.walk(path): for name in [f for f in files if f.endswith('.patch')]: patches.append(os.path.join(root, name)) return patches
def __init__(self, model, parent): standard.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) # Dockwidget options qtcompat.set_common_dock_options(self) self.classic_dockable = gitcfg.instance().get("cola.classicdockable") if self.classic_dockable: self.classicdockwidget = create_dock("Cola Classic", self) self.classicwidget = classic_widget(self) self.classicdockwidget.setWidget(self.classicwidget) # "Actions" widget self.actionsdockwidget = create_dock("Actions", 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) self.alt_button = create_button(text="Exit Diff Mode", layout=layout) self.alt_button.hide() layout.addStretch() self.actionsdockwidget.setWidget(self.actionsdockwidgetcontents) # "Repository Status" widget self.statusdockwidget = create_dock("Repository Status", self) self.statusdockwidget.setWidget(StatusWidget(self)) # "Commit Message Editor" widget self.commitdockwidget = create_dock("Commit Message Editor", self) 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) # "Command Output" widget logwidget = qtutils.logger() logwidget.setFont(diff_font()) self.logdockwidget = create_dock("Command Output", self) self.logdockwidget.setWidget(logwidget) # "Diff Viewer" widget self.diffdockwidget = create_dock("Diff Viewer", self) self.diff_viewer = DiffTextEdit(self.diffdockwidget) self.diffdockwidget.setWidget(self.diff_viewer) # 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_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_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...", guicmds.fetch) self.menu_push = add_action(self, "Push...", guicmds.push) self.menu_pull = add_action(self, "Pull...", guicmds.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_diff_branch = add_action(self, "Apply Changes From Branch...", guicmds.diff_branch) self.menu_branch_compare = add_action(self, "Branches...", compare.branch_compare) 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_commit_compare = add_action(self, "Commits...", compare.compare) self.menu_commit_compare_file = add_action(self, "Commits Touching File...", compare.compare_file) 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.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.branch_diff) self.menu_diff_expression = add_action(self, "Expression...", guicmds.diff_expression) self.menu_create_tag = add_action(self, "Create Tag...", createtag.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, "Cola Classic...", 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 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.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_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_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) self.branch_menu.addSeparator() self.branch_menu.addAction(self.menu_diff_branch) # 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.addSeparator() self.diff_menu.addAction(self.menu_branch_compare) self.diff_menu.addAction(self.menu_commit_compare) self.diff_menu.addAction(self.menu_commit_compare_file) 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_message_observer(model.message_mode_changed, self._mode_changed) model.add_message_observer(model.message_updated, self._update_view) prefs_model.add_message_observer(prefs_model.message_config_updated, self._config_updated) # Add button callbacks connect_button(self.rescan_button, emit(self, signals.rescan_and_refresh)) connect_button(self.alt_button, emit(self, signals.reset_mode)) connect_button(self.fetch_button, guicmds.fetch) connect_button(self.push_button, guicmds.push) connect_button(self.pull_button, guicmds.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, SIGNAL("update"), self._update_callback) self.connect(self, SIGNAL("apply_state"), self.apply_state) 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 self._gui_state_task = None self._load_gui_state() log(0, self.model.git_version + "\ncola version " + version.version())
class MainView(standard.MainWindow): def __init__(self, model, parent): standard.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) # Dockwidget options qtcompat.set_common_dock_options(self) self.classic_dockable = gitcfg.instance().get("cola.classicdockable") if self.classic_dockable: self.classicdockwidget = create_dock("Cola Classic", self) self.classicwidget = classic_widget(self) self.classicdockwidget.setWidget(self.classicwidget) # "Actions" widget self.actionsdockwidget = create_dock("Actions", 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) self.alt_button = create_button(text="Exit Diff Mode", layout=layout) self.alt_button.hide() layout.addStretch() self.actionsdockwidget.setWidget(self.actionsdockwidgetcontents) # "Repository Status" widget self.statusdockwidget = create_dock("Repository Status", self) self.statusdockwidget.setWidget(StatusWidget(self)) # "Commit Message Editor" widget self.commitdockwidget = create_dock("Commit Message Editor", self) 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) # "Command Output" widget logwidget = qtutils.logger() logwidget.setFont(diff_font()) self.logdockwidget = create_dock("Command Output", self) self.logdockwidget.setWidget(logwidget) # "Diff Viewer" widget self.diffdockwidget = create_dock("Diff Viewer", self) self.diff_viewer = DiffTextEdit(self.diffdockwidget) self.diffdockwidget.setWidget(self.diff_viewer) # 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_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_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...", guicmds.fetch) self.menu_push = add_action(self, "Push...", guicmds.push) self.menu_pull = add_action(self, "Pull...", guicmds.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_diff_branch = add_action(self, "Apply Changes From Branch...", guicmds.diff_branch) self.menu_branch_compare = add_action(self, "Branches...", compare.branch_compare) 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_commit_compare = add_action(self, "Commits...", compare.compare) self.menu_commit_compare_file = add_action(self, "Commits Touching File...", compare.compare_file) 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.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.branch_diff) self.menu_diff_expression = add_action(self, "Expression...", guicmds.diff_expression) self.menu_create_tag = add_action(self, "Create Tag...", createtag.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, "Cola Classic...", 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 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.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_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_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) self.branch_menu.addSeparator() self.branch_menu.addAction(self.menu_diff_branch) # 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.addSeparator() self.diff_menu.addAction(self.menu_branch_compare) self.diff_menu.addAction(self.menu_commit_compare) self.diff_menu.addAction(self.menu_commit_compare_file) 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_message_observer(model.message_mode_changed, self._mode_changed) model.add_message_observer(model.message_updated, self._update_view) prefs_model.add_message_observer(prefs_model.message_config_updated, self._config_updated) # Add button callbacks connect_button(self.rescan_button, emit(self, signals.rescan_and_refresh)) connect_button(self.alt_button, emit(self, signals.reset_mode)) connect_button(self.fetch_button, guicmds.fetch) connect_button(self.push_button, guicmds.push) connect_button(self.pull_button, guicmds.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, SIGNAL("update"), self._update_callback) self.connect(self, SIGNAL("apply_state"), self.apply_state) 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 self._gui_state_task = None self._load_gui_state() log(0, self.model.git_version + "\ncola version " + version.version()) # Qt overrides def closeEvent(self, event): """Save state in the settings manager.""" qtutils.save_state(self) standard.MainWindow.closeEvent(self, event) # Accessors mode = property(lambda self: self.model.mode) def _mode_changed(self, mode): """React to mode changes; hide/show the "Exit Diff Mode" button.""" if mode in (self.model.mode_branch, self.model.mode_review, self.model.mode_diff, self.model.mode_diff_expr): height = self.stage_button.minimumHeight() self.alt_button.setMinimumHeight(height) self.alt_button.show() else: self.alt_button.setMinimumHeight(1) self.alt_button.hide() def _config_updated(self, source, config, value): if config == "cola.fontdiff": font = QtGui.QFont() if not font.fromString(value): return qtutils.logger().setFont(font) self.diff_viewer.setFont(font) self.commitmsgeditor.setFont(font) elif config == "cola.tabwidth": # variable-tab-width setting self.diff_viewer.set_tab_width(value) def install_config_actions(self): """Install .gitconfig-defined actions""" self._config_task = self._start_config_actions_task() def _start_config_actions_task(self): """Do the expensive "get_config_actions()" call in the background""" class ConfigActionsTask(QtCore.QRunnable): def __init__(self, sender): QtCore.QRunnable.__init__(self) self._sender = sender def run(self): names = cfgactions.get_config_actions() self._sender.emit(SIGNAL("install_config_actions"), names) task = ConfigActionsTask(self) QtCore.QThreadPool.globalInstance().start(task) return task def _install_config_actions(self, names): """Install .gitconfig-defined actions""" if not names: return menu = self.actions_menu menu.addSeparator() for name in names: menu.addAction(name, emit(self, signals.run_config_action, name)) def _update_view(self): self.emit(SIGNAL("update")) def _update_callback(self): """Update the title with the current branch and directory name.""" branch = self.model.currentbranch curdir = core.decode(os.getcwd()) msg = "Repository: %s\nBranch: %s" % (curdir, branch) self.commitdockwidget.setToolTip(msg) title = "%s: %s" % (self.model.project, branch) if self.mode in (self.model.mode_diff, self.model.mode_diff_expr): title += " *** diff mode***" elif self.mode == self.model.mode_review: title += " *** review mode***" elif self.mode == self.model.mode_amend: title += " *** amending ***" self.setWindowTitle(title) self.commitmsgeditor.set_mode(self.mode) if not self.model.read_only() and self.mode != self.model.mode_amend: # Check if there's a message file in .git/ merge_msg_path = gitcmds.merge_message_path() if merge_msg_path is None: return merge_msg_hash = utils.checksum(core.decode(merge_msg_path)) if merge_msg_hash == self.merge_message_hash: return self.merge_message_hash = merge_msg_hash cola.notifier().broadcast(signals.load_commit_message, core.decode(merge_msg_path)) def apply_state(self, state): """Imports data for save/restore""" # 1 is the widget version; change when widgets are added/removed standard.MainWindow.apply_state(self, state) qtutils.apply_window_state(self, state, 1) def export_state(self): """Exports data for save/restore""" state = standard.MainWindow.export_state(self) return qtutils.export_window_state(self, state, self.widget_version) def _load_gui_state(self): """Restores the gui from the preferences file.""" self._gui_state_task = self._start_gui_state_loading_thread() def _start_gui_state_loading_thread(self): """Do expensive file reading and json decoding in the background""" class LoadGUIStateTask(QtCore.QRunnable): def __init__(self, sender): QtCore.QRunnable.__init__(self) self._sender = sender def run(self): state = settings.Settings().get_gui_state(self._sender) self._sender.emit(SIGNAL("apply_state"), state) task = LoadGUIStateTask(self) QtCore.QThreadPool.globalInstance().start(task) return task def setup_dockwidget_tools_menu(self): # Hotkeys for toggling the dock widgets dockwidgets = ( (self.logdockwidget, "Alt+0"), (self.commitdockwidget, "Alt+1"), (self.statusdockwidget, "Alt+2"), (self.diffdockwidget, "Alt+3"), (self.actionsdockwidget, "Alt+4"), ) for dockwidget, shortcut in dockwidgets: # Associate the action with the shortcut action = dockwidget.toggleViewAction() action.setShortcut(shortcut) self.tools_menu.addAction(action) def showdock(show, dockwidget=dockwidget): if show: dockwidget.raise_() dockwidget.widget().setFocus(True) else: self.setFocus(True) self.addAction(action) connect_action_bool(action, showdock) # Create a new shortcut Shift+<shortcut> that gives focus action = QtGui.QAction(self) action.setShortcut("Shift+" + shortcut) def focusdock(dockwidget=dockwidget, showdock=showdock): if dockwidget.toggleViewAction().isChecked(): showdock(True) else: dockwidget.toggleViewAction().trigger() self.addAction(action) connect_action(action, focusdock) def stage(self): """Stage selected files, or all files if no selection exists.""" paths = cola.selection_model().unstaged if not paths: cola.notifier().broadcast(signals.stage_modified) else: cola.notifier().broadcast(signals.stage, paths) def unstage(self): """Unstage selected files, or all files if no selection exists.""" paths = cola.selection_model().staged if not paths: cola.notifier().broadcast(signals.unstage_all) else: cola.notifier().broadcast(signals.unstage, paths) def dragEnterEvent(self, event): """Accepts drops""" standard.MainWindow.dragEnterEvent(self, event) event.acceptProposedAction() def dropEvent(self, event): """Apply dropped patches with git-am""" event.accept() urls = event.mimeData().urls() if not urls: return paths = map(lambda x: unicode(x.path()), urls) patches = [p for p in paths if p.endswith(".patch")] dirs = [p for p in paths if os.path.isdir(p)] dirs.sort() for d in dirs: patches.extend(self._gather_patches(d)) # Broadcast the patches to apply cola.notifier().broadcast(signals.apply_patches, patches) def _gather_patches(self, path): """Find patches in a subdirectory""" patches = [] for root, subdirs, files in os.walk(path): for name in [f for f in files if f.endswith(".patch")]: patches.append(os.path.join(root, name)) return patches
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)
class StashView(Dialog): 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 =\ self.toolbutton(N_('Apply'), N_('Apply the selected stash'), qtutils.apply_icon()) self.button_save =\ self.toolbutton(N_('Save'), N_('Save modified state to new stash'), qtutils.save_icon()) self.button_drop = \ self.toolbutton(N_('Drop'), N_('Drop the selected stash'), qtutils.discard_icon()) self.button_close = \ self.pushbutton(N_('Close'), N_('Close'), qtutils.close_icon()) self.keep_index = QtGui.QCheckBox(self) self.keep_index.setText(N_('Keep Index')) self.keep_index.setChecked(True) # Arrange layouts self.main_layt = QtGui.QVBoxLayout() self.main_layt.setMargin(defs.margin) self.main_layt.setSpacing(defs.spacing) self.btn_layt = QtGui.QHBoxLayout() self.btn_layt.setMargin(defs.no_margin) self.btn_layt.setSpacing(defs.spacing) self.splitter = QtGui.QSplitter() self.splitter.setHandleWidth(defs.handle_width) self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setChildrenCollapsible(True) self.splitter.setStretchFactor(0, 1) self.splitter.setStretchFactor(1, 1) self.splitter.insertWidget(0, self.stash_list) self.splitter.insertWidget(1, self.stash_text) self.btn_layt.addWidget(self.button_save) self.btn_layt.addWidget(self.button_apply) self.btn_layt.addWidget(self.button_drop) self.btn_layt.addWidget(self.keep_index) self.btn_layt.addStretch() self.btn_layt.addWidget(self.button_close) self.main_layt.addWidget(self.splitter) self.main_layt.addLayout(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 close(self): self.accept() cmds.do(cmds.Rescan) def toolbutton(self, text, tooltip, icon): return qtutils.create_toolbutton(text=text, tooltip=tooltip, icon=icon) def pushbutton(self, text, tooltip, icon): btn = QtGui.QPushButton(self) btn.setText(text) btn.setToolTip(tooltip) btn.setIcon(icon) return btn def selected_stash(self): """Returns the stash name of the currently selected stash """ list_widget = self.stash_list stash_list = self.revids return qtutils.selected_item(list_widget, stash_list) def selected_name(self): list_widget = self.stash_list stash_list = self.names return qtutils.selected_item(list_widget, stash_list) def item_selected(self): """Shows the current stash in the main view.""" self.update_actions() selection = self.selected_stash() if not selection: return diff_text = self.model.stash_diff(selection) self.stash_text.setPlainText(diff_text) def update_actions(self): has_changes = self.model.has_stashable_changes() has_stash = bool(self.selected_stash()) self.button_save.setEnabled(has_changes) self.button_apply.setEnabled(has_stash) self.button_drop.setEnabled(has_stash) def update_from_model(self): """Initiates git queries on the model and updates the view """ stashes, revids, names = self.model.stash_info() self.stashes = stashes self.revids = revids self.names = names self.stash_list.clear() self.stash_list.addItems(self.stashes) def stash_apply(self): """Applies the currently selected stash """ selection = self.selected_stash() if not selection: return index = self.keep_index.isChecked() cmds.do(ApplyStash, selection, index) self.accept() cmds.do(cmds.Rescan) def stash_save(self): """Saves the worktree in a stash This prompts the user for a stash name and creates a git stash named accordingly. """ stash_name, ok = qtutils.prompt(N_('Save Stash'), N_('Enter a name for the stash')) if not ok or not stash_name: return # Sanitize the stash name stash_name = utils.sanitize(stash_name) if stash_name in self.names: qtutils.critical(N_('Error: Stash exists'), N_('A stash named "%s" already exists') % stash_name) return keep_index = self.keep_index.isChecked() cmds.do(SaveStash, stash_name, keep_index) self.accept() cmds.do(cmds.Rescan) def stash_drop(self): """Drops the currently selected stash """ selection = self.selected_stash() name = self.selected_name() if not selection: return if not qtutils.confirm(N_('Drop Stash?'), N_('Recovering a dropped stash is not possible.'), N_('Drop the "%s" stash?') % name, N_('Drop Stash'), default=True, icon=qtutils.discard_icon()): return cmds.do(DropStash, selection) self.update_from_model() self.stash_text.setPlainText('')
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 =\ self.toolbutton(N_('Apply'), N_('Apply the selected stash'), qtutils.apply_icon()) self.button_save =\ self.toolbutton(N_('Save'), N_('Save modified state to new stash'), qtutils.save_icon()) self.button_drop = \ self.toolbutton(N_('Drop'), N_('Drop the selected stash'), qtutils.discard_icon()) self.button_close = \ self.pushbutton(N_('Close'), N_('Close'), qtutils.close_icon()) self.keep_index = QtGui.QCheckBox(self) self.keep_index.setText(N_('Keep Index')) self.keep_index.setChecked(True) # Arrange layouts self.main_layt = QtGui.QVBoxLayout() self.main_layt.setMargin(defs.margin) self.main_layt.setSpacing(defs.spacing) self.btn_layt = QtGui.QHBoxLayout() self.btn_layt.setMargin(defs.no_margin) self.btn_layt.setSpacing(defs.spacing) self.splitter = QtGui.QSplitter() self.splitter.setHandleWidth(defs.handle_width) self.splitter.setOrientation(QtCore.Qt.Horizontal) self.splitter.setChildrenCollapsible(True) self.splitter.setStretchFactor(0, 1) self.splitter.setStretchFactor(1, 1) self.splitter.insertWidget(0, self.stash_list) self.splitter.insertWidget(1, self.stash_text) self.btn_layt.addWidget(self.button_save) self.btn_layt.addWidget(self.button_apply) self.btn_layt.addWidget(self.button_drop) self.btn_layt.addWidget(self.keep_index) self.btn_layt.addStretch() self.btn_layt.addWidget(self.button_close) self.main_layt.addWidget(self.splitter) self.main_layt.addLayout(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)
class SelectCommitsDialog(QtGui.QDialog): def __init__(self, model, parent=None, title=None, multiselect=True, syntax=True): QtGui.QDialog.__init__(self, parent) self.model = model if title: self.setWindowTitle(title) self.commit_list = QtGui.QListWidget() if multiselect: mode = QtGui.QAbstractItemView.ExtendedSelection else: mode = QtGui.QAbstractItemView.SingleSelection self.commit_list.setSelectionMode(mode) self.commit_list.setAlternatingRowColors(True) self.commit_text = DiffTextEdit(self, whitespace=False) self.label = QtGui.QLabel() self.label.setText(N_('Revision Expression:')) self.revision = QtGui.QLineEdit() self.revision.setReadOnly(True) self.select_button = qtutils.ok_button(N_('Select'), enabled=False, default=True) self.close_button = qtutils.close_button() # Make the list widget slighty larger self.splitter = qtutils.splitter(Qt.Vertical, self.commit_list, self.commit_text) self.splitter.setSizes([100, 150]) self.input_layout = qtutils.hbox(defs.no_margin, defs.spacing, self.label, self.revision, self.select_button, self.close_button) self.main_layout = qtutils.vbox(defs.margin, defs.margin, self.splitter, self.input_layout) self.setLayout(self.main_layout) self.connect(self.commit_list, SIGNAL('itemSelectionChanged()'), self.commit_sha1_selected) self.connect(self.commit_list, SIGNAL('itemDoubleClicked(QListWidgetItem*)'), self.commit_sha1_double_clicked) qtutils.connect_button(self.select_button, self.accept) qtutils.connect_button(self.close_button, self.reject) self.resize(700, 420) def selected_commit(self): return qtutils.selected_item(self.commit_list, self.model.revisions) def selected_commits(self): return qtutils.selected_items(self.commit_list, self.model.revisions) def select_commits(self): summaries = self.model.summaries if not summaries: msg = N_('No commits exist in this branch.') Interaction.log(msg) return [] qtutils.set_items(self.commit_list, summaries) self.show() if self.exec_() != QtGui.QDialog.Accepted: return [] return self.selected_commits() def commit_sha1_selected(self): sha1 = self.selected_commit() selected = sha1 is not None self.select_button.setEnabled(selected) if not selected: self.commit_text.setText('') self.revision.setText('') return self.revision.setText(sha1) self.revision.selectAll() # Display the sha1's commit commit_diff = gitcmds.commit_diff(sha1) self.commit_text.setText(commit_diff) def commit_sha1_double_clicked(self, item): sha1 = self.selected_commit() if sha1: self.accept()