示例#1
0
文件: status.py 项目: queer1/git-cola
    def _create_unstaged_context_menu(self, menu, s):
        modified_submodule = (s.modified and
                              s.modified[0] in self.m.submodules)
        if modified_submodule:
            return self._create_modified_submodule_context_menu(menu, s)

        if self.unstaged():
            action = menu.addAction(qtutils.options_icon(),
                                    cmds.LaunchEditor.name(),
                                    cmds.run(cmds.LaunchEditor))
            action.setShortcut(cmds.Edit.SHORTCUT)

        if s.modified and self.m.stageable():
            action = menu.addAction(qtutils.git_icon(),
                                    cmds.LaunchDifftool.name(),
                                    cmds.run(cmds.LaunchDifftool))
            action.setShortcut(cmds.LaunchDifftool.SHORTCUT)

        if self.m.stageable():
            menu.addSeparator()
            action = menu.addAction(qtutils.icon('add.svg'),
                                    N_('Stage Selected'),
                                    cmds.run(cmds.Stage, self.unstaged()))
            action.setShortcut(cmds.Stage.SHORTCUT)

        if s.modified and self.m.stageable():
            if self.m.undoable():
                menu.addSeparator()
                menu.addAction(qtutils.icon('undo.svg'),
                               N_('Revert Unstaged Edits...'),
                               self._revert_unstaged_edits)
                menu.addAction(qtutils.icon('undo.svg'),
                               N_('Revert Uncommited Edits...'),
                               lambda: self._revert_uncommitted_edits(
                                            self.modified()))

        if self.unstaged() and not utils.is_win32():
            menu.addSeparator()
            action = menu.addAction(qtutils.file_icon(),
                    cmds.OpenDefaultApp.name(),
                    cmds.run(cmds.OpenDefaultApp, self.unstaged()))
            action.setShortcut(cmds.OpenDefaultApp.SHORTCUT)

            action = menu.addAction(qtutils.open_file_icon(),
                    cmds.OpenParentDir.name(),
                    self._open_parent_dir)
            action.setShortcut(cmds.OpenParentDir.SHORTCUT)

        if s.untracked:
            menu.addSeparator()
            menu.addAction(qtutils.discard_icon(),
                           N_('Delete File(s)...'), self._delete_files)
            menu.addSeparator()
            menu.addAction(qtutils.icon('edit-clear.svg'),
                           N_('Add to .gitignore'),
                           cmds.run(cmds.Ignore,
                                map(lambda x: '/' + x, self.untracked())))
        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        return menu
示例#2
0
    def __init__(self, parent):
        standard.Dialog.__init__(self, parent=parent)
        self.model = settings.Settings()

        self.resize(494, 238)
        self.setWindowTitle(N_('Bookmarks'))
        if parent is not None:
            self.setWindowModality(Qt.WindowModal)
        self.layt = QtGui.QVBoxLayout(self)
        self.layt.setMargin(defs.margin)
        self.layt.setSpacing(defs.spacing)

        self.bookmarks = QtGui.QListWidget(self)
        self.bookmarks.setAlternatingRowColors(True)
        self.bookmarks.setSelectionMode(QtGui.QAbstractItemView
                                             .ExtendedSelection)

        self.layt.addWidget(self.bookmarks)
        self.button_layout = QtGui.QHBoxLayout()

        self.open_button = QtGui.QPushButton(self)
        self.open_button.setText(N_('Open'))
        self.open_button.setIcon(qtutils.open_icon())
        self.open_button.setEnabled(False)
        self.button_layout.addWidget(self.open_button)

        self.add_button = QtGui.QPushButton(self)
        self.add_button.setText(N_('Add'))
        self.add_button.setIcon(qtutils.icon('add.svg'))
        self.button_layout.addWidget(self.add_button)

        self.delete_button = QtGui.QPushButton(self)
        self.delete_button.setText(N_('Delete'))
        self.delete_button.setIcon(qtutils.discard_icon())
        self.delete_button.setEnabled(False)
        self.button_layout.addWidget(self.delete_button)
        self.button_layout.addStretch()

        self.save_button = QtGui.QPushButton(self)
        self.save_button.setText(N_('Save'))
        self.save_button.setIcon(qtutils.save_icon())
        self.save_button.setEnabled(False)
        self.button_layout.addWidget(self.save_button)

        self.close_button = QtGui.QPushButton(self)
        self.close_button.setText(N_('Close'))
        self.button_layout.addWidget(self.close_button)

        self.layt.addLayout(self.button_layout)

        self.connect(self.bookmarks, SIGNAL('itemSelectionChanged()'),
                     self.item_selection_changed)

        qtutils.connect_button(self.open_button, self.open_repo)
        qtutils.connect_button(self.add_button, self.add)
        qtutils.connect_button(self.delete_button, self.delete)
        qtutils.connect_button(self.save_button, self.save)
        qtutils.connect_button(self.close_button, self.accept)

        self.update_bookmarks()
示例#3
0
    def _delete_files(self):
        files = self.untracked()
        count = len(files)
        if count == 0:
            return

        title = N_('Delete Files?')
        msg = N_('The following files will be deleted:') + '\n\n'

        fileinfo = subprocess.list2cmdline(files)
        if len(fileinfo) > 2048:
            fileinfo = fileinfo[:2048].rstrip() + '...'
        msg += fileinfo

        info_txt = N_('Delete %d file(s)?') % count
        ok_txt = N_('Delete Files')

        if qtutils.confirm(
                title,
                msg,
                info_txt,
                ok_txt,
                default=True,
                icon=qtutils.discard_icon()):
            cmds.do(cmds.Delete, files)
示例#4
0
文件: status.py 项目: pked12/git-cola
    def _create_unstaged_context_menu(self, menu, s):
        modified_submodule = (s.modified and
                              s.modified[0] in self.m.submodules)
        if modified_submodule:
            return self._create_modified_submodule_context_menu(menu, s)

        if self.unstaged():
            action = menu.addAction(qtutils.options_icon(),
                                    cmds.LaunchEditor.name(),
                                    cmds.run(cmds.LaunchEditor))
            action.setShortcut(cmds.Edit.SHORTCUT)

        if s.modified and self.m.stageable():
            action = menu.addAction(qtutils.git_icon(),
                                    cmds.LaunchDifftool.name(),
                                    cmds.run(cmds.LaunchDifftool))
            action.setShortcut(cmds.LaunchDifftool.SHORTCUT)

        if self.m.stageable():
            menu.addSeparator()
            action = menu.addAction(qtutils.icon('add.svg'),
                                    N_('Stage Selected'),
                                    cmds.run(cmds.Stage, self.unstaged()))
            action.setShortcut(cmds.Stage.SHORTCUT)

        if s.modified and self.m.stageable():
            if self.m.undoable():
                menu.addSeparator()
                menu.addAction(qtutils.icon('undo.svg'),
                               N_('Revert Unstaged Edits...'),
                               self._revert_unstaged_edits)
                menu.addAction(qtutils.icon('undo.svg'),
                               N_('Revert Uncommited Edits...'),
                               lambda: self._revert_uncommitted_edits(
                                            self.modified()))

        if self.unstaged() and not utils.is_win32():
            menu.addSeparator()
            action = menu.addAction(qtutils.file_icon(),
                    cmds.OpenDefaultApp.name(),
                    cmds.run(cmds.OpenDefaultApp, self.unstaged()))
            action.setShortcut(cmds.OpenDefaultApp.SHORTCUT)

            action = menu.addAction(qtutils.open_file_icon(),
                    cmds.OpenParentDir.name(),
                    self._open_parent_dir)
            action.setShortcut(cmds.OpenParentDir.SHORTCUT)

        if s.untracked:
            menu.addSeparator()
            menu.addAction(qtutils.discard_icon(),
                           N_('Delete File(s)...'), self._delete_files)
            menu.addSeparator()
            menu.addAction(qtutils.icon('edit-clear.svg'),
                           N_('Add to .gitignore'),
                           cmds.run(cmds.Ignore,
                                map(lambda x: '/' + x, self.untracked())))
        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        return menu
示例#5
0
    def __init__(self, parent):
        standard.Dialog.__init__(self, parent=parent)
        self.settings = Settings()
        self.settings.load()

        self.resize(494, 238)
        self.setWindowTitle(N_('Bookmarks'))
        if parent is not None:
            self.setWindowModality(Qt.WindowModal)
        self.layt = QtGui.QVBoxLayout(self)
        self.layt.setMargin(defs.margin)
        self.layt.setSpacing(defs.spacing)

        self.bookmarks = QtGui.QListWidget(self)
        self.bookmarks.setAlternatingRowColors(True)
        self.bookmarks.setSelectionMode(QtGui.QAbstractItemView
                                             .ExtendedSelection)

        self.layt.addWidget(self.bookmarks)
        self.button_layout = QtGui.QHBoxLayout()

        self.open_button = qtutils.create_button(text=N_('Open'),
                icon=qtutils.open_icon())
        self.open_button.setEnabled(False)
        self.button_layout.addWidget(self.open_button)

        self.add_button = qtutils.create_button(text=N_('Add'),
                icon=qtutils.add_icon())
        self.button_layout.addWidget(self.add_button)

        self.delete_button = QtGui.QPushButton(self)
        self.delete_button.setText(N_('Delete'))
        self.delete_button.setIcon(qtutils.discard_icon())
        self.delete_button.setEnabled(False)
        self.button_layout.addWidget(self.delete_button)
        self.button_layout.addStretch()

        self.save_button = QtGui.QPushButton(self)
        self.save_button.setText(N_('Save'))
        self.save_button.setIcon(qtutils.save_icon())
        self.save_button.setEnabled(False)
        self.button_layout.addWidget(self.save_button)

        self.close_button = QtGui.QPushButton(self)
        self.close_button.setText(N_('Close'))
        self.button_layout.addWidget(self.close_button)

        self.layt.addLayout(self.button_layout)

        self.connect(self.bookmarks, SIGNAL('itemSelectionChanged()'),
                     self.item_selection_changed)

        qtutils.connect_button(self.open_button, self.open_repo)
        qtutils.connect_button(self.add_button, self.add)
        qtutils.connect_button(self.delete_button, self.delete)
        qtutils.connect_button(self.save_button, self.save)
        qtutils.connect_button(self.close_button, self.accept)

        self.update_bookmarks()
示例#6
0
    def __init__(self, parent=None):
        standard.StandardDialog.__init__(self, parent=parent)

        self.setWindowModality(QtCore.Qt.WindowModal)
        self.setWindowTitle(self.tr('Stash'))
        self.resize(600, 200)

        self._label = QtGui.QLabel()
        self._label.setText('<center>Stash List</center>')

        self.stash_list = QtGui.QListWidget(self)

        self.button_apply =\
            self.toolbutton(self.tr('Apply'),
                            self.tr('Apply the selected stash'),
                            qtutils.apply_icon())
        self.button_save =\
            self.toolbutton(self.tr('Save'),
                            self.tr('Save modified state to new stash'),
                            qtutils.save_icon())
        self.button_remove = \
            self.toolbutton(self.tr('Remove'),
                            self.tr('Remove the selected stash'),
                            qtutils.discard_icon())
        self.button_close = \
            self.pushbutton(self.tr('Close'),
                            self.tr('Close'), qtutils.close_icon())

        self.keep_index = QtGui.QCheckBox(self)
        self.keep_index.setText(self.tr('Keep Index'))
        self.keep_index.setChecked(True)

        self.setTabOrder(self.button_save, self.button_apply)
        self.setTabOrder(self.button_apply, self.button_remove)
        self.setTabOrder(self.button_remove, self.keep_index)
        self.setTabOrder(self.keep_index, self.button_close)

        # Arrange layouts
        self._main_layt = QtGui.QVBoxLayout(self)
        self._main_layt.setMargin(6)
        self._main_layt.setSpacing(6)

        self._btn_layt = QtGui.QHBoxLayout()
        self._btn_layt.setMargin(0)
        self._btn_layt.setSpacing(4)

        self._btn_layt.addWidget(self.button_save)
        self._btn_layt.addWidget(self.button_apply)
        self._btn_layt.addWidget(self.button_remove)
        self._btn_layt.addWidget(self.keep_index)
        self._btn_layt.addStretch()
        self._btn_layt.addWidget(self.button_close)

        self._main_layt.addWidget(self._label)
        self._main_layt.addWidget(self.stash_list)
        self._main_layt.addItem(self._btn_layt)
示例#7
0
        def remote_callback():
            if not self.model.remotename:
                errmsg = self.tr('No repository selected.')
                qtutils.log(1, errmsg)
                return
            remote, kwargs = self.common_args()
            action = self.action

            # Check if we're about to create a new branch and warn.
            if action == 'push' and not self.model.remote_branch:
                branch = self.model.local_branch
                candidate = '%s/%s' % (remote, branch)
                if candidate not in self.model.remote_branches:
                    title = 'Push'
                    msg = 'Branch "%s" does not exist in %s.' % (branch, remote)
                    msg += '\nA new remote branch will be published.'
                    info_txt= 'Create a new remote branch?'
                    ok_text = 'Create Remote Branch'
                    if not qtutils.confirm(title, msg, info_txt, ok_text,
                                           default=False,
                                           icon=qtutils.git_icon()):
                        return

            if not self.model.ffwd_only_checkbox:
                title = 'Force %s?' % action.title()
                ok_text = 'Force %s' % action.title()

                if action == 'fetch':
                    msg = 'Non-fast-forward fetch overwrites local history!'
                    info_txt = 'Force fetching from %s?' % remote
                elif action == 'push':
                    msg = ('Non-fast-forward push overwrites published '
                           'history!\n(Did you pull first?)')
                    info_txt = 'Force push to %s?' % remote
                else: # pull: shouldn't happen since the controls are hidden
                    msg = "You probably don't want to do this.\n\tContinue?"
                    return

                if not qtutils.confirm(title, msg, info_txt, ok_text,
                                       default=False,
                                       icon=qtutils.discard_icon()):
                    return

            # Disable the GUI by default
            self.view.setEnabled(False)
            self.progress.setEnabled(True)
            QtGui.QApplication.setOverrideCursor(Qt.WaitCursor)

            # Show a nice progress bar
            self.progress.setLabelText('Updating...')
            self.progress.show()

            # Use a thread to update in the background
            task = ActionTask(self.view, modelaction, remote, kwargs)
            self._tasks.append(task)
            QtCore.QThreadPool.globalInstance().start(task)
示例#8
0
 def clear(self):
     if not qtutils.confirm(
             N_('Clear commit message?'),
             N_('The commit message will be cleared.'),
             N_('This cannot be undone.  Clear commit message?'),
             N_('Clear commit message'),
             default=True,
             icon=qtutils.discard_icon()):
         return
     self.model.set_commitmsg('')
示例#9
0
 def clear(self):
     if not qtutils.confirm(
         N_("Clear commit message?"),
         N_("The commit message will be cleared."),
         N_("This cannot be undone.  Clear commit message?"),
         N_("Clear commit message"),
         default=True,
         icon=qtutils.discard_icon(),
     ):
         return
     self.model.set_commitmsg("")
示例#10
0
文件: status.py 项目: B-Rich/git-cola
    def _create_unstaged_context_menu(self, menu, s):
        modified_submodule = s.modified and s.modified[0] in self.m.submodules
        if modified_submodule:
            return self._create_modified_submodule_context_menu(menu, s)

        if self.m.stageable():
            action = menu.addAction(
                qtutils.icon("add.svg"), N_("Stage Selected"), cmds.run(cmds.Stage, self.unstaged())
            )
            action.setShortcut(cmds.Stage.SHORTCUT)

        # Do all of the selected items exist?
        unstaged_items = self.unstaged_items()
        all_exist = all([i.exists for i in unstaged_items])

        if all_exist and self.unstaged():
            menu.addAction(self.launch_editor)

        if all_exist and s.modified and self.m.stageable():
            menu.addAction(self.launch_difftool)

        if s.modified and self.m.stageable():
            if self.m.undoable():
                menu.addSeparator()
                menu.addAction(self.revert_unstaged_edits_action)
                menu.addAction(
                    qtutils.icon("undo.svg"),
                    N_("Revert Uncommited Edits..."),
                    lambda: self._revert_uncommitted_edits(self.modified()),
                )

        if all_exist and self.unstaged() and not utils.is_win32():
            menu.addSeparator()
            action = menu.addAction(
                qtutils.file_icon(), cmds.OpenDefaultApp.name(), cmds.run(cmds.OpenDefaultApp, self.unstaged())
            )
            action.setShortcut(cmds.OpenDefaultApp.SHORTCUT)

            action = menu.addAction(qtutils.open_file_icon(), cmds.OpenParentDir.name(), self._open_parent_dir)
            action.setShortcut(cmds.OpenParentDir.SHORTCUT)

        if all_exist and s.untracked:
            menu.addSeparator()
            menu.addAction(qtutils.discard_icon(), N_("Delete File(s)..."), self._delete_files)
            menu.addSeparator()
            menu.addAction(
                qtutils.icon("edit-clear.svg"),
                N_("Add to .gitignore"),
                cmds.run(cmds.Ignore, map(lambda x: "/" + x, self.untracked())),
            )
        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        return menu
示例#11
0
 def delete_bookmark(self):
     """Removes a bookmark from the bookmarks list"""
     item = self.selected_item()
     if not item:
         return
     if self.style == BOOKMARKS:
         cmd = cmds.RemoveBookmark
     elif self.style == RECENT_REPOS:
         cmd = cmds.RemoveRecent
     else:
         return
     ok, status, out, err = cmds.do(cmd, self.settings, item.path,
                                    icon=qtutils.discard_icon())
     if ok:
         self.refresh()
示例#12
0
 def delete_bookmark(self):
     """Removes a bookmark from the bookmarks list"""
     item = self.selected_item()
     if not item:
         return
     repo = item.path
     title = N_('Delete Bookmark?')
     msg = N_('Delete Bookmark?')
     info_text = N_('%s will be removed from your bookmarks.') % repo
     ok_text = N_('Delete Bookmark')
     if not Interaction.confirm(
             title, msg, info_text, ok_text, icon=qtutils.discard_icon()):
         return
     self.settings.remove_bookmark(repo)
     self.settings.save()
     self.refresh()
示例#13
0
 def delete_bookmark(self):
     """Removes a bookmark from the bookmarks list"""
     item = self.selected_item()
     if not item:
         return
     repo = item.path
     title = N_('Delete Bookmark?')
     msg = N_('Delete Bookmark?')
     info_text = N_('%s will be removed from your bookmarks.') % repo
     ok_text = N_('Delete Bookmark')
     if not Interaction.confirm(title, msg, info_text, ok_text,
                                icon=qtutils.discard_icon()):
         return
     self.settings.remove_bookmark(repo)
     self.settings.save()
     self.refresh()
示例#14
0
文件: view.py 项目: mwh/git-cola
 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('Drop Stash?',
                            'Recovering a dropped stash is not possible.',
                            'Drop the "%s" stash?' % name,
                            'Drop Stash',
                            default=False,
                            icon=qtutils.discard_icon()):
         return
     self.emit(SIGNAL(drop_stash), selection)
     self.update_from_model()
     self.stash_view.setPlainText('')
示例#15
0
 def delete_bookmark(self):
     """Removes a bookmark from the bookmarks list"""
     item = self.selected_item()
     if not item:
         return
     if self.style == BOOKMARKS:
         cmd = cmds.RemoveBookmark
     elif self.style == RECENT_REPOS:
         cmd = cmds.RemoveRecent
     else:
         return
     ok, status, out, err = cmds.do(cmd,
                                    self.settings,
                                    item.path,
                                    icon=qtutils.discard_icon())
     if ok:
         self.refresh()
示例#16
0
文件: stash.py 项目: jmdcal/git-cola
 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('')
示例#17
0
 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('Drop Stash?',
                            'Recovering a dropped stash is not possible.',
                            'Drop the "%s" stash?' % name,
                            'Drop Stash',
                            default=True,
                            icon=qtutils.discard_icon()):
         return
     cmds.do(DropStash, selection)
     self.update_from_model()
     self.stash_text.setPlainText('')
示例#18
0
 def stash_remove(self):
     """Drops the currently selected stash
     """
     selection = self.selected_stash()
     name = self.selected_name()
     if not selection:
         return
     if not qtutils.confirm(self.view,
                            'Remove Stash?',
                            'Remove "%s"?' % name,
                            'Recovering these changes may not be possible.',
                            'Remove',
                            icon=qtutils.discard_icon()):
         return
     qtutils.log(*self.model.git.stash('drop', selection,
                                       with_stderr=True,
                                       with_status=True))
     self.update_model()
示例#19
0
    def closeEvent(self, event):
        if self.proc.state() != QtCore.QProcess.NotRunning:
            # The process is still running, make sure we really want to abort.
            title = N_('Abort Action')
            msg = N_('An action is still running.\n'
                     'Terminating it could result in data loss.')
            info_text = N_('Abort the action?')
            ok_text = N_('Abort Action')
            if qtutils.confirm(title, msg, info_text, ok_text,
                               default=False, icon=qtutils.discard_icon()):
                self.abortProc()
                event.accept()
            else:
                event.ignore()
        else:
            event.accept()

        return standard.Dialog.closeEvent(self, event)
示例#20
0
    def _delete_files(self):
        files = self.untracked()
        count = len(files)
        if count == 0:
            return

        title = "Delete Files?"
        msg = self.tr("The following files will be deleted:\n\n")

        fileinfo = subprocess.list2cmdline(files)
        if len(fileinfo) > 2048:
            fileinfo = fileinfo[:2048].rstrip() + "..."
        msg += fileinfo

        info_txt = unicode(self.tr("Delete %d file(s)?")) % count
        ok_txt = "Delete Files"

        if qtutils.confirm(title, msg, info_txt, ok_txt, default=False, icon=qtutils.discard_icon()):
            cola.notifier().broadcast(signals.delete, files)
示例#21
0
    def _delete_files(self):
        files = self.untracked()
        count = len(files)
        if count == 0:
            return

        title = N_('Delete Files?')
        msg = N_('The following files will be deleted:') + '\n\n'

        fileinfo = subprocess.list2cmdline(files)
        if len(fileinfo) > 2048:
            fileinfo = fileinfo[:2048].rstrip() + '...'
        msg += fileinfo

        info_txt = N_('Delete %d file(s)?') % count
        ok_txt = N_('Delete Files')

        if qtutils.confirm(title, msg, info_txt, ok_txt,
                           default=True,
                           icon=qtutils.discard_icon()):
            cmds.do(cmds.Delete, files)
示例#22
0
    def _delete_files(self):
        files = self.untracked()
        count = len(files)
        if count == 0:
            return

        title = 'Delete Files?'
        msg = self.tr('The following files will be deleted:\n\n')

        fileinfo = subprocess.list2cmdline(files)
        if len(fileinfo) > 2048:
            fileinfo = fileinfo[:2048].rstrip() + '...'
        msg += fileinfo

        info_txt = unicode(self.tr('Delete %d file(s)?')) % count
        ok_txt = 'Delete Files'

        if qtutils.confirm(title, msg, info_txt, ok_txt,
                           default=True,
                           icon=qtutils.discard_icon()):
            cola.notifier().broadcast(signals.delete, files)
示例#23
0
文件: status.py 项目: Jobava/git-cola
    def __init__(self, parent=None):
        QtGui.QTreeWidget.__init__(self, parent)

        self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
        self.headerItem().setHidden(True)
        self.setAllColumnsShowFocus(True)
        self.setSortingEnabled(False)
        self.setUniformRowHeights(True)
        self.setAnimated(True)
        self.setRootIsDecorated(False)
        self.setIndentation(0)
        self.setDragEnabled(True)

        self.add_item(N_('Staged'), hide=True)
        self.add_item(N_('Unmerged'), hide=True)
        self.add_item(N_('Modified'), hide=True)
        self.add_item(N_('Untracked'), hide=True)

        # Used to restore the selection
        self.old_scroll = None
        self.old_selection = None
        self.old_contents = None
        self.old_current_item = None
        self.expanded_items = set()

        self.process_selection_action = qtutils.add_action(self,
                cmds.StageOrUnstage.name(),
                cmds.run(cmds.StageOrUnstage), hotkeys.STAGE_SELECTION)

        self.revert_unstaged_edits_action = qtutils.add_action(self,
                cmds.RevertUnstagedEdits.name(),
                cmds.run(cmds.RevertUnstagedEdits), hotkeys.REVERT)
        icon = qtutils.theme_icon('edit-undo.svg')
        self.revert_unstaged_edits_action.setIcon(icon)

        self.launch_difftool_action = qtutils.add_action(self,
                cmds.LaunchDifftool.name(),
                cmds.run(cmds.LaunchDifftool), hotkeys.DIFF)
        self.launch_difftool_action.setIcon(qtutils.git_icon())

        self.launch_editor_action = qtutils.add_action(self,
                cmds.LaunchEditor.name(),
                cmds.run(cmds.LaunchEditor), hotkeys.EDIT, *hotkeys.ACCEPT)
        self.launch_editor_action.setIcon(qtutils.options_icon())

        if not utils.is_win32():
            self.open_using_default_app = qtutils.add_action(self,
                    cmds.OpenDefaultApp.name(),
                    self._open_using_default_app, hotkeys.PRIMARY_ACTION)
            self.open_using_default_app.setIcon(qtutils.file_icon())

            self.open_parent_dir_action = qtutils.add_action(self,
                    cmds.OpenParentDir.name(),
                    self._open_parent_dir, hotkeys.SECONDARY_ACTION)
            self.open_parent_dir_action.setIcon(qtutils.open_file_icon())

        self.up_action = qtutils.add_action(self,
                N_('Move Up'), self.move_up,
                hotkeys.MOVE_UP, hotkeys.MOVE_UP_SECONDARY)

        self.down_action = qtutils.add_action(self,
                N_('Move Down'), self.move_down,
                hotkeys.MOVE_DOWN, hotkeys.MOVE_DOWN_SECONDARY)

        self.copy_path_action = qtutils.add_action(self,
                N_('Copy Path to Clipboard'), self.copy_path, hotkeys.COPY)
        self.copy_path_action.setIcon(qtutils.theme_icon('edit-copy.svg'))

        self.copy_relpath_action = qtutils.add_action(self,
                N_('Copy Relative Path to Clipboard'),
                self.copy_relpath, hotkeys.CUT)
        self.copy_relpath_action.setIcon(qtutils.theme_icon('edit-copy.svg'))

        self.view_history_action = qtutils.add_action(self,
                N_('View History...'),
                self.view_history, hotkeys.HISTORY)

        # MoveToTrash and Delete use the same shortcut.
        # We will only bind one of them, depending on whether or not the
        # MoveToTrash command is avaialble.  When available, the hotkey
        # is bound to MoveToTrash, otherwise it is bound to Delete.
        if cmds.MoveToTrash.AVAILABLE:
            self.move_to_trash_action = qtutils.add_action(self,
                    N_('Move file(s) to trash'),
                    self._trash_untracked_files, hotkeys.TRASH)
            self.move_to_trash_action.setIcon(qtutils.discard_icon())
            delete_shortcut = hotkeys.DELETE_FILE
        else:
            self.move_to_trash_action = None
            delete_shortcut = hotkeys.DELETE_FILE_SECONDARY

        self.delete_untracked_files_action = qtutils.add_action(self,
                N_('Delete File(s)...'),
                self._delete_untracked_files, delete_shortcut)
        self.delete_untracked_files_action.setIcon(qtutils.discard_icon())

        self.connect(self, SIGNAL('about_to_update()'),
                     self._about_to_update, Qt.QueuedConnection)
        self.connect(self, SIGNAL('updated()'),
                     self._updated, Qt.QueuedConnection)

        self.m = main.model()
        self.m.add_observer(self.m.message_about_to_update,
                            self.about_to_update)
        self.m.add_observer(self.m.message_updated, self.updated)

        self.connect(self, SIGNAL('itemSelectionChanged()'),
                     self.show_selection)

        self.connect(self, SIGNAL('itemDoubleClicked(QTreeWidgetItem*,int)'),
                     self.double_clicked)

        self.connect(self, SIGNAL('itemCollapsed(QTreeWidgetItem*)'),
                     lambda x: self.update_column_widths())

        self.connect(self, SIGNAL('itemExpanded(QTreeWidgetItem*)'),
                     lambda x: self.update_column_widths())
示例#24
0
    def action_callback(self):
        action = self.action
        if action == FETCH:
            model_action = self.model.fetch
        elif action == PUSH:
            model_action = self.model.push
        else:  # if action == PULL:
            model_action = self.model.pull

        remote_name = unicode(self.remote_name.text())
        if not remote_name:
            errmsg = self.tr('No repository selected.')
            qtutils.log(1, errmsg)
            return
        remote, kwargs = self.common_args()

        # Check if we're about to create a new branch and warn.
        remote_branch = unicode(self.remote_branch.text())
        local_branch = unicode(self.local_branch.text())

        if action == PUSH and not remote_branch:
            branch = local_branch
            candidate = '%s/%s' % (remote, branch)
            if candidate not in self.model.remote_branches:
                title = self.tr(PUSH)
                msg = 'Branch "%s" does not exist in %s.' % (branch, remote)
                msg += '\nA new remote branch will be published.'
                info_txt = 'Create a new remote branch?'
                ok_text = 'Create Remote Branch'
                if not qtutils.confirm(title,
                                       msg,
                                       info_txt,
                                       ok_text,
                                       default=False,
                                       icon=qtutils.git_icon()):
                    return

        if not self.ffwd_only_checkbox.isChecked():
            title = 'Force %s?' % action.title()
            ok_text = 'Force %s' % action.title()

            if action == FETCH:
                msg = 'Non-fast-forward fetch overwrites local history!'
                info_txt = 'Force fetching from %s?' % remote
            elif action == PUSH:
                msg = ('Non-fast-forward push overwrites published '
                       'history!\n(Did you pull first?)')
                info_txt = 'Force push to %s?' % remote
            else:  # pull: shouldn't happen since the controls are hidden
                msg = "You probably don't want to do this.\n\tContinue?"
                return

            if not qtutils.confirm(title,
                                   msg,
                                   info_txt,
                                   ok_text,
                                   default=False,
                                   icon=qtutils.discard_icon()):
                return

        # Disable the GUI by default
        self.setEnabled(False)
        self.progress.setEnabled(True)
        QtGui.QApplication.setOverrideCursor(Qt.WaitCursor)

        # Show a nice progress bar
        self.progress_thread.start()
        self.progress.show()

        # Use a thread to update in the background
        task = ActionTask(self, model_action, remote, kwargs)
        self.tasks.append(task)
        QtCore.QThreadPool.globalInstance().start(task)
示例#25
0
文件: stash.py 项目: jmdcal/git-cola
    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)
示例#26
0
    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)
示例#27
0
    def action_callback(self):
        action = self.action
        if action == FETCH:
            model_action = self.model.fetch
        elif action == PUSH:
            model_action = self.push_to_all
        else: # if action == PULL:
            model_action = self.model.pull

        remote_name = ustr(self.remote_name.text())
        if not remote_name:
            errmsg = N_('No repository selected.')
            Interaction.log(errmsg)
            return
        remote, kwargs = self.common_args()
        self.selected_remotes = qtutils.selected_items(self.remotes,
                                                       self.model.remotes)

        # Check if we're about to create a new branch and warn.
        remote_branch = ustr(self.remote_branch.text())
        local_branch = ustr(self.local_branch.text())

        if action == PUSH and not remote_branch:
            branch = local_branch
            candidate = '%s/%s' % (remote, branch)
            if candidate not in self.model.remote_branches:
                title = N_('Push')
                args = dict(branch=branch, remote=remote)
                msg = N_('Branch "%(branch)s" does not exist in "%(remote)s".\n'
                         'A new remote branch will be published.') % args
                info_txt= N_('Create a new remote branch?')
                ok_text = N_('Create Remote Branch')
                if not qtutils.confirm(title, msg, info_txt, ok_text,
                                       default=False,
                                       icon=qtutils.git_icon()):
                    return

        if not self.ffwd_only_checkbox.isChecked():
            if action == FETCH:
                title = N_('Force Fetch?')
                msg = N_('Non-fast-forward fetch overwrites local history!')
                info_txt = N_('Force fetching from %s?') % remote
                ok_text = N_('Force Fetch')
            elif action == PUSH:
                title = N_('Force Push?')
                msg = N_('Non-fast-forward push overwrites published '
                         'history!\n(Did you pull first?)')
                info_txt = N_('Force push to %s?') % remote
                ok_text = N_('Force Push')
            else: # pull: shouldn't happen since the controls are hidden
                msg = "You probably don't want to do this.\n\tContinue?"
                return

            if not qtutils.confirm(title, msg, info_txt, ok_text,
                                   default=False,
                                   icon=qtutils.discard_icon()):
                return

        # Disable the GUI by default
        self.action_button.setEnabled(False)
        self.close_button.setEnabled(False)

        # Use a thread to update in the background
        task = ActionTask(self.task_runner, model_action, remote, kwargs)
        self.task_runner.start(task,
                               progress=self.progress,
                               finish=self.action_completed)
示例#28
0
文件: status.py 项目: mwh/git-cola
    def create_context_menu(self):
        """Set up the status menu for the repo status tree."""
        staged, modified, unmerged, untracked = self.selection()
        menu = QtGui.QMenu(self)

        enable_staging = self.m.enable_staging()
        if not enable_staging:
            menu.addAction(qtutils.icon('remove.svg'),
                           self.tr('Unstage Selected'),
                           SLOT(signals.unstage, self.staged()))

        if staged and staged[0] in self.m.submodules:
            menu.addAction(qtutils.git_icon(),
                           self.tr('Launch git-cola'),
                           SLOT(signals.open_repo, os.path.abspath(staged[0])))
            return menu
        elif staged:
            menu.addSeparator()
            menu.addAction(qtutils.icon('open.svg'),
                           self.tr('Launch Editor'),
                           SLOT(signals.edit, self.staged()))
            menu.addAction(qtutils.git_icon(),
                           self.tr('Launch Diff Tool'),
                           SLOT(signals.difftool, True, self.staged()))
            menu.addSeparator()
            menu.addAction(qtutils.icon('undo.svg'),
                           self.tr('Revert Unstaged Edits...'),
                           lambda: self._revert_unstaged_edits(use_staged=True))
            return menu

        if unmerged:
            menu.addAction(qtutils.git_icon(),
                           self.tr('Launch Merge Tool'),
                           SLOT(signals.mergetool, self.unmerged()))
            menu.addAction(qtutils.icon('open.svg'),
                           self.tr('Launch Editor'),
                           SLOT(signals.edit, self.unmerged()))
            menu.addSeparator()
            menu.addAction(qtutils.icon('add.svg'),
                           self.tr('Stage Selected'),
                           SLOT(signals.stage, self.unmerged()))
            return menu

        modified_submodule = (modified and
                              modified[0] in self.m.submodules)
        if enable_staging:
            menu.addAction(qtutils.icon('add.svg'),
                           self.tr('Stage Selected'),
                           SLOT(signals.stage, self.unstaged()))
            menu.addSeparator()

        if modified_submodule:
            menu.addAction(qtutils.git_icon(),
                           self.tr('Launch git-cola'),
                           SLOT(signals.open_repo,
                                os.path.abspath(modified[0])))
        elif self.unstaged():
            menu.addAction(qtutils.icon('open.svg'),
                           self.tr('Launch Editor'),
                           SLOT(signals.edit, self.unstaged()))

        if modified and enable_staging and not modified_submodule:
            menu.addAction(qtutils.git_icon(),
                           self.tr('Launch Diff Tool'),
                           SLOT(signals.difftool, False, self.modified()))
            menu.addSeparator()
            menu.addAction(qtutils.icon('undo.svg'),
                           self.tr('Revert Unstaged Edits...'),
                           self._revert_unstaged_edits)
            menu.addAction(qtutils.icon('undo.svg'),
                           self.tr('Revert Uncommited Edits...'),
                           self._revert_uncommitted_edits)

        if untracked:
            menu.addSeparator()
            menu.addAction(qtutils.discard_icon(),
                           self.tr('Delete File(s)...'), self._delete_files)
            menu.addSeparator()
            menu.addAction(qtutils.icon('edit-clear.svg'),
                           self.tr('Add to .gitignore'),
                           SLOT(signals.ignore,
                                map(lambda x: '/' + x, self.untracked())))
        return menu
示例#29
0
    def __init__(self, parent=None):
        QtGui.QTreeWidget.__init__(self, parent)

        self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
        self.headerItem().setHidden(True)
        self.setAllColumnsShowFocus(True)
        self.setSortingEnabled(False)
        self.setUniformRowHeights(True)
        self.setAnimated(True)
        self.setRootIsDecorated(False)
        self.setIndentation(0)
        self.setDragEnabled(True)

        self.add_item(N_('Staged'), hide=True)
        self.add_item(N_('Unmerged'), hide=True)
        self.add_item(N_('Modified'), hide=True)
        self.add_item(N_('Untracked'), hide=True)

        # Used to restore the selection
        self.old_scroll = None
        self.old_selection = None
        self.old_contents = None
        self.old_current_item = None
        self.expanded_items = set()

        self.process_selection_action = qtutils.add_action(self,
                cmds.StageOrUnstage.name(),
                cmds.run(cmds.StageOrUnstage),
                cmds.StageOrUnstage.SHORTCUT)

        self.revert_unstaged_edits_action = qtutils.add_action(self,
                cmds.RevertUnstagedEdits.name(),
                cmds.run(cmds.RevertUnstagedEdits),
                cmds.RevertUnstagedEdits.SHORTCUT)
        self.revert_unstaged_edits_action.setIcon(qtutils.icon('undo.svg'))

        self.revert_uncommitted_edits_action = qtutils.add_action(self,
                cmds.RevertUncommittedEdits.name(),
                cmds.run(cmds.RevertUncommittedEdits),
                cmds.RevertUncommittedEdits.SHORTCUT)
        self.revert_uncommitted_edits_action.setIcon(qtutils.icon('undo.svg'))

        self.launch_difftool_action = qtutils.add_action(self,
                cmds.LaunchDifftool.name(),
                cmds.run(cmds.LaunchDifftool),
                cmds.LaunchDifftool.SHORTCUT)
        self.launch_difftool_action.setIcon(qtutils.git_icon())

        self.launch_editor_action = qtutils.add_action(self,
                cmds.LaunchEditor.name(),
                cmds.run(cmds.LaunchEditor),
                cmds.LaunchEditor.SHORTCUT,
                'Return', 'Enter')
        self.launch_editor_action.setIcon(qtutils.options_icon())

        if not utils.is_win32():
            self.open_using_default_app = qtutils.add_action(self,
                    cmds.OpenDefaultApp.name(),
                    self._open_using_default_app,
                    cmds.OpenDefaultApp.SHORTCUT)
            self.open_using_default_app.setIcon(qtutils.file_icon())

            self.open_parent_dir_action = qtutils.add_action(self,
                    cmds.OpenParentDir.name(),
                    self._open_parent_dir,
                    cmds.OpenParentDir.SHORTCUT)
            self.open_parent_dir_action.setIcon(qtutils.open_file_icon())

        self.up_action = qtutils.add_action(self,
                N_('Move Up'), self.move_up, Qt.Key_K)

        self.down_action = qtutils.add_action(self,
                N_('Move Down'), self.move_down, Qt.Key_J)

        self.copy_path_action = qtutils.add_action(self,
                N_('Copy Path to Clipboard'),
                self.copy_path, QtGui.QKeySequence.Copy)
        self.copy_path_action.setIcon(qtutils.theme_icon('edit-copy.svg'))

        self.copy_relpath_action = qtutils.add_action(self,
                N_('Copy Relative Path to Clipboard'),
                self.copy_relpath, QtGui.QKeySequence.Cut)
        self.copy_relpath_action.setIcon(qtutils.theme_icon('edit-copy.svg'))

        if cmds.MoveToTrash.AVAILABLE:
            self.move_to_trash_action = qtutils.add_action(self,
                    N_('Move file(s) to trash'),
                    self._trash_untracked_files, cmds.MoveToTrash.SHORTCUT)
            self.move_to_trash_action.setIcon(qtutils.discard_icon())
            delete_shortcut = cmds.Delete.SHORTCUT
        else:
            self.move_to_trash_action = None
            delete_shortcut = cmds.Delete.ALT_SHORTCUT

        self.delete_untracked_files_action = qtutils.add_action(self,
                N_('Delete File(s)...'),
                self._delete_untracked_files, delete_shortcut)
        self.delete_untracked_files_action.setIcon(qtutils.discard_icon())

        self.connect(self, SIGNAL('about_to_update'), self._about_to_update)
        self.connect(self, SIGNAL('updated'), self._updated)

        self.m = main.model()
        self.m.add_observer(self.m.message_about_to_update,
                            self.about_to_update)
        self.m.add_observer(self.m.message_updated, self.updated)

        self.connect(self, SIGNAL('itemSelectionChanged()'),
                     self.show_selection)

        self.connect(self, SIGNAL('itemDoubleClicked(QTreeWidgetItem*,int)'),
                     self.double_clicked)

        self.connect(self, SIGNAL('itemCollapsed(QTreeWidgetItem*)'),
                     lambda x: self.update_column_widths())

        self.connect(self, SIGNAL('itemExpanded(QTreeWidgetItem*)'),
                     lambda x: self.update_column_widths())
示例#30
0
文件: remote.py 项目: pwr/git-cola
    def action_callback(self):
        action = self.action
        if action == FETCH:
            model_action = self.model.fetch
        elif action == PUSH:
            model_action = self.push_to_all
        else:  # if action == PULL:
            model_action = self.model.pull

        remote_name = unicode(self.remote_name.text())
        if not remote_name:
            errmsg = N_("No repository selected.")
            Interaction.log(errmsg)
            return
        remote, kwargs = self.common_args()
        self.selected_remotes = qtutils.selected_items(self.remotes, self.model.remotes)

        # Check if we're about to create a new branch and warn.
        remote_branch = unicode(self.remote_branch.text())
        local_branch = unicode(self.local_branch.text())

        if action == PUSH and not remote_branch:
            branch = local_branch
            candidate = "%s/%s" % (remote, branch)
            if candidate not in self.model.remote_branches:
                title = N_("Push")
                args = dict(branch=branch, remote=remote)
                msg = (
                    N_('Branch "%(branch)s" does not exist in "%(remote)s".\n' "A new remote branch will be published.")
                    % args
                )
                info_txt = N_("Create a new remote branch?")
                ok_text = N_("Create Remote Branch")
                if not qtutils.confirm(title, msg, info_txt, ok_text, default=False, icon=qtutils.git_icon()):
                    return

        if not self.ffwd_only_checkbox.isChecked():
            if action == FETCH:
                title = N_("Force Fetch?")
                msg = N_("Non-fast-forward fetch overwrites local history!")
                info_txt = N_("Force fetching from %s?") % remote
                ok_text = N_("Force Fetch")
            elif action == PUSH:
                title = N_("Force Push?")
                msg = N_("Non-fast-forward push overwrites published " "history!\n(Did you pull first?)")
                info_txt = N_("Force push to %s?") % remote
                ok_text = N_("Force Push")
            else:  # pull: shouldn't happen since the controls are hidden
                msg = "You probably don't want to do this.\n\tContinue?"
                return

            if not qtutils.confirm(title, msg, info_txt, ok_text, default=False, icon=qtutils.discard_icon()):
                return

        # Disable the GUI by default
        self.action_button.setEnabled(False)
        self.close_button.setEnabled(False)
        QtGui.QApplication.setOverrideCursor(Qt.WaitCursor)

        # Show a nice progress bar
        self.progress.show()
        self.progress_thread.start()

        # Use a thread to update in the background
        task = ActionTask(self, model_action, remote, kwargs)
        self.tasks.append(task)
        QtCore.QThreadPool.globalInstance().start(task)
示例#31
0
    def __init__(self, parent=None):
        QtGui.QTreeWidget.__init__(self, parent)

        self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
        self.headerItem().setHidden(True)
        self.setAllColumnsShowFocus(True)
        self.setSortingEnabled(False)
        self.setUniformRowHeights(True)
        self.setAnimated(True)
        self.setRootIsDecorated(False)
        self.setIndentation(0)
        self.setDragEnabled(True)

        self.add_item(N_("Staged"), hide=True)
        self.add_item(N_("Unmerged"), hide=True)
        self.add_item(N_("Modified"), hide=True)
        self.add_item(N_("Untracked"), hide=True)

        # Used to restore the selection
        self.old_scroll = None
        self.old_selection = None
        self.old_contents = None
        self.old_current_item = None
        self.expanded_items = set()

        self.process_selection_action = qtutils.add_action(
            self, cmds.StageOrUnstage.name(), cmds.run(cmds.StageOrUnstage), cmds.StageOrUnstage.SHORTCUT
        )

        self.revert_unstaged_edits_action = qtutils.add_action(
            self, cmds.RevertUnstagedEdits.name(), cmds.run(cmds.RevertUnstagedEdits), cmds.RevertUnstagedEdits.SHORTCUT
        )
        self.revert_unstaged_edits_action.setIcon(qtutils.theme_icon("edit-undo.svg"))

        self.launch_difftool_action = qtutils.add_action(
            self, cmds.LaunchDifftool.name(), cmds.run(cmds.LaunchDifftool), cmds.LaunchDifftool.SHORTCUT
        )
        self.launch_difftool_action.setIcon(qtutils.git_icon())

        self.launch_editor_action = qtutils.add_action(
            self, cmds.LaunchEditor.name(), cmds.run(cmds.LaunchEditor), cmds.LaunchEditor.SHORTCUT, "Return", "Enter"
        )
        self.launch_editor_action.setIcon(qtutils.options_icon())

        if not utils.is_win32():
            self.open_using_default_app = qtutils.add_action(
                self, cmds.OpenDefaultApp.name(), self._open_using_default_app, cmds.OpenDefaultApp.SHORTCUT
            )
            self.open_using_default_app.setIcon(qtutils.file_icon())

            self.open_parent_dir_action = qtutils.add_action(
                self, cmds.OpenParentDir.name(), self._open_parent_dir, cmds.OpenParentDir.SHORTCUT
            )
            self.open_parent_dir_action.setIcon(qtutils.open_file_icon())

        self.up_action = qtutils.add_action(self, N_("Move Up"), self.move_up, Qt.Key_K)

        self.down_action = qtutils.add_action(self, N_("Move Down"), self.move_down, Qt.Key_J)

        self.copy_path_action = qtutils.add_action(
            self, N_("Copy Path to Clipboard"), self.copy_path, QtGui.QKeySequence.Copy
        )
        self.copy_path_action.setIcon(qtutils.theme_icon("edit-copy.svg"))

        self.copy_relpath_action = qtutils.add_action(
            self, N_("Copy Relative Path to Clipboard"), self.copy_relpath, QtGui.QKeySequence.Cut
        )
        self.copy_relpath_action.setIcon(qtutils.theme_icon("edit-copy.svg"))

        # MoveToTrash and Delete use the same shortcut.
        # We will only bind one of them, depending on whether or not the
        # MoveToTrash command is avaialble.  When available, the hotkey
        # is bound to MoveToTrash, otherwise it is bound to Delete.
        if cmds.MoveToTrash.AVAILABLE:
            self.move_to_trash_action = qtutils.add_action(
                self, N_("Move file(s) to trash"), self._trash_untracked_files, cmds.MoveToTrash.SHORTCUT
            )
            self.move_to_trash_action.setIcon(qtutils.discard_icon())
            delete_shortcut = []
        else:
            self.move_to_trash_action = None
            delete_shortcut = [cmds.Delete.SHORTCUT]

        self.delete_untracked_files_action = qtutils.add_action(
            self, N_("Delete File(s)..."), self._delete_untracked_files, *delete_shortcut
        )
        self.delete_untracked_files_action.setIcon(qtutils.discard_icon())

        self.connect(self, SIGNAL("about_to_update()"), self._about_to_update, Qt.QueuedConnection)
        self.connect(self, SIGNAL("updated()"), self._updated, Qt.QueuedConnection)

        self.m = main.model()
        self.m.add_observer(self.m.message_about_to_update, self.about_to_update)
        self.m.add_observer(self.m.message_updated, self.updated)

        self.connect(self, SIGNAL("itemSelectionChanged()"), self.show_selection)

        self.connect(self, SIGNAL("itemDoubleClicked(QTreeWidgetItem*,int)"), self.double_clicked)

        self.connect(self, SIGNAL("itemCollapsed(QTreeWidgetItem*)"), lambda x: self.update_column_widths())

        self.connect(self, SIGNAL("itemExpanded(QTreeWidgetItem*)"), lambda x: self.update_column_widths())
示例#32
0
    def action_callback(self):
        action = self.action
        if action == FETCH:
            model_action = self.model.fetch
        elif action == PUSH:
            model_action = self.push_to_all
        else:  # if action == PULL:
            model_action = self.model.pull

        remote_name = ustr(self.remote_name.text())
        if not remote_name:
            errmsg = N_('No repository selected.')
            Interaction.log(errmsg)
            return
        remote, kwargs = self.common_args()
        self.selected_remotes = qtutils.selected_items(self.remotes,
                                                       self.model.remotes)

        # Check if we're about to create a new branch and warn.
        remote_branch = ustr(self.remote_branch.text())
        local_branch = ustr(self.local_branch.text())

        if action == PUSH and not remote_branch:
            branch = local_branch
            candidate = '%s/%s' % (remote, branch)
            if candidate not in self.model.remote_branches:
                title = N_('Push')
                args = dict(branch=branch, remote=remote)
                msg = N_(
                    'Branch "%(branch)s" does not exist in "%(remote)s".\n'
                    'A new remote branch will be published.') % args
                info_txt = N_('Create a new remote branch?')
                ok_text = N_('Create Remote Branch')
                if not qtutils.confirm(
                        title, msg, info_txt, ok_text,
                        icon=qtutils.git_icon()):
                    return

        if not self.ffwd_only_checkbox.isChecked():
            if action == FETCH:
                title = N_('Force Fetch?')
                msg = N_('Non-fast-forward fetch overwrites local history!')
                info_txt = N_('Force fetching from %s?') % remote
                ok_text = N_('Force Fetch')
            elif action == PUSH:
                title = N_('Force Push?')
                msg = N_('Non-fast-forward push overwrites published '
                         'history!\n(Did you pull first?)')
                info_txt = N_('Force push to %s?') % remote
                ok_text = N_('Force Push')
            else:  # pull: shouldn't happen since the controls are hidden
                msg = "You probably don't want to do this.\n\tContinue?"
                return

            if not qtutils.confirm(title,
                                   msg,
                                   info_txt,
                                   ok_text,
                                   default=False,
                                   icon=qtutils.discard_icon()):
                return

        # Disable the GUI by default
        self.action_button.setEnabled(False)
        self.close_button.setEnabled(False)

        # Use a thread to update in the background
        task = ActionTask(self.task_runner, model_action, remote, kwargs)
        self.task_runner.start(task,
                               progress=self.progress,
                               finish=self.action_completed)
示例#33
0
    def create_context_menu(self):
        """Set up the status menu for the repo status tree."""
        s = self.selection()
        menu = QtGui.QMenu(self)

        selection = self.selected_indexes()
        if selection:
            category, idx = selection[0]
            # A header item e.g. 'Staged', 'Modified', etc.
            if category == self.idx_header:
                if idx == self.idx_staged:
                    menu.addAction(qtutils.icon('remove.svg'),
                                   self.tr('Unstage All'),
                                   SLOT(signals.unstage_all))
                    return menu
                elif idx == self.idx_unmerged:
                    action = menu.addAction(qtutils.icon('add.svg'),
                                            self.tr('Stage Merged'),
                                            SLOT(signals.stage_unmerged))
                    action.setShortcut(defs.stage_shortcut)
                    return menu
                elif idx == self.idx_modified:
                    action = menu.addAction(qtutils.icon('add.svg'),
                                            self.tr('Stage Modified'),
                                            SLOT(signals.stage_modified))
                    action.setShortcut(defs.stage_shortcut)
                    return menu

                elif idx == self.idx_untracked:
                    action = menu.addAction(qtutils.icon('add.svg'),
                                            self.tr('Stage Untracked'),
                                            SLOT(signals.stage_untracked))
                    action.setShortcut(defs.stage_shortcut)
                    return menu

        if s.staged and self.m.unstageable():
            action = menu.addAction(qtutils.icon('remove.svg'),
                                    self.tr('Unstage Selected'),
                                    SLOT(signals.unstage, self.staged()))
            action.setShortcut(defs.stage_shortcut)

        if s.staged and s.staged[0] in self.m.submodules:
            menu.addAction(qtutils.git_icon(),
                           self.tr('Launch git-cola'),
                           SLOT(signals.open_repo,
                                os.path.abspath(s.staged[0])))
            menu.addSeparator()
            menu.addAction(self.copy_path_action)
            return menu
        elif s.staged:
            menu.addSeparator()
            action = menu.addAction(qtutils.git_icon(),
                                    self.tr('Launch Diff Tool'),
                                    SLOT(signals.difftool, True,
                                         self.staged()))
            action.setShortcut(defs.difftool_shortcut)

            action = menu.addAction(qtutils.options_icon(),
                                    self.tr('Launch Editor'),
                                    SLOT(signals.edit, self.staged()))
            action.setShortcut(defs.editor_shortcut)

            if not utils.is_win32():
                menu.addSeparator()
                action = menu.addAction(qtutils.file_icon(),
                        self.tr(self.txt_default_app),
                        SLOT(signals.open_default_app, self.staged()))
                action.setShortcut(defs.default_app_shortcut)

                action = menu.addAction(qtutils.open_file_icon(),
                        self.tr(self.txt_parent_dir),
                        self._open_parent_dir)
                action.setShortcut(defs.parent_dir_shortcut)

            if self.m.undoable():
                menu.addSeparator()
                menu.addAction(qtutils.icon('undo.svg'),
                               self.tr('Revert Unstaged Edits...'),
                               lambda: self._revert_unstaged_edits(staged=True))
            menu.addSeparator()
            menu.addAction(self.copy_path_action)
            return menu

        if s.unmerged:
            menu.addAction(qtutils.git_icon(),
                           self.tr('Launch Merge Tool'),
                           SLOT(signals.mergetool, self.unmerged()))

            action = menu.addAction(qtutils.icon('add.svg'),
                                    self.tr('Stage Selected'),
                                    SLOT(signals.stage, self.unstaged()))
            action.setShortcut(defs.stage_shortcut)
            menu.addSeparator()
            action = menu.addAction(qtutils.options_icon(),
                                    self.tr('Launch Editor'),
                                    SLOT(signals.edit, self.unmerged()))
            action.setShortcut(defs.editor_shortcut)

            if not utils.is_win32():
                menu.addSeparator()
                action = menu.addAction(qtutils.file_icon(),
                        self.tr(self.txt_default_app),
                        SLOT(signals.open_default_app, self.unmerged()))
                action.setShortcut(defs.default_app_shortcut)

                action = menu.addAction(qtutils.open_file_icon(),
                        self.tr(self.txt_parent_dir),
                        self._open_parent_dir)
                action.setShortcut(defs.parent_dir_shortcut)

            menu.addSeparator()
            menu.addAction(self.copy_path_action)
            return menu

        modified_submodule = (s.modified and
                              s.modified[0] in self.m.submodules)
        if self.m.stageable():
            action = menu.addAction(qtutils.icon('add.svg'),
                                    self.tr('Stage Selected'),
                                    SLOT(signals.stage, self.unstaged()))
            action.setShortcut(defs.stage_shortcut)
            menu.addSeparator()

        if s.modified and self.m.stageable() and not modified_submodule:
            action = menu.addAction(qtutils.git_icon(),
                                    self.tr('Launch Diff Tool'),
                                    SLOT(signals.difftool, False,
                                         self.modified()))
            action.setShortcut(defs.difftool_shortcut)

        if modified_submodule:
            menu.addAction(qtutils.git_icon(),
                           self.tr('Launch git-cola'),
                           SLOT(signals.open_repo,
                                os.path.abspath(s.modified[0])))
        elif self.unstaged():
            action = menu.addAction(qtutils.options_icon(),
                                    self.tr('Launch Editor'),
                                    SLOT(signals.edit, self.unstaged()))
            action.setShortcut(defs.editor_shortcut)
            if not utils.is_win32():
                menu.addSeparator()
                action = menu.addAction(qtutils.file_icon(),
                        self.tr(self.txt_default_app),
                        SLOT(signals.open_default_app, self.unstaged()))
                action.setShortcut(defs.default_app_shortcut)

                action = menu.addAction(qtutils.open_file_icon(),
                        self.tr(self.txt_parent_dir),
                        self._open_parent_dir)
                action.setShortcut(defs.parent_dir_shortcut)

        menu.addSeparator()

        if s.modified and self.m.stageable() and not modified_submodule:
            if self.m.undoable():
                menu.addAction(qtutils.icon('undo.svg'),
                               self.tr('Revert Unstaged Edits...'),
                               self._revert_unstaged_edits)
                menu.addAction(qtutils.icon('undo.svg'),
                               self.tr('Revert Uncommited Edits...'),
                               self._revert_uncommitted_edits)

        if s.untracked:
            menu.addSeparator()
            menu.addAction(qtutils.discard_icon(),
                           self.tr('Delete File(s)...'), self._delete_files)
            menu.addSeparator()
            menu.addAction(qtutils.icon('edit-clear.svg'),
                           self.tr('Add to .gitignore'),
                           SLOT(signals.ignore,
                                map(lambda x: '/' + x, self.untracked())))
        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        return menu
示例#34
0
    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)