Example #1
0
    def action_completed(self, task, status, output):
        # Grab the results of the action and finish up
        self.progress_thread.stop()
        self.progress_thread.wait()
        if task in self.tasks:
            self.tasks.remove(task)

        already_up_to_date = self.tr('Already up-to-date.')

        if not output: # git fetch --tags --verbose doesn't print anything...
            output = already_up_to_date

        self.setEnabled(True)
        self.progress.close()
        QtGui.QApplication.restoreOverrideCursor()

        result = 'returned exit status %d' % status
        message = '"git %s" %s' % (self.action.lower(), result)
        if output:
            message += '\n\n' + output

        # Force the status to 1 so that we always display the log
        Interaction.log(message)

        if status == 0:
            self.accept()
            return

        if self.action == PUSH:
            message += '\n\nHave you rebased/pulled lately?'

        Interaction.critical(self.windowTitle(),
                             message=message, details=output)
Example #2
0
 def do(self):
     if self.keep_index:
         args = ['save', '--keep-index', self.stash_name]
     else:
         args = ['save', self.stash_name]
     status, output = git.stash(with_stderr=True, with_status=True, *args)
     Interaction.log_status(status, output, '')
Example #3
0
    def _revert_unstaged_edits(self, staged=False):
        if not self.m.undoable():
            return
        if staged:
            items_to_undo = self.staged()
        else:
            items_to_undo = self.modified()

        if items_to_undo:
            if not qtutils.confirm(
                    N_('Revert Unstaged Changes?'),
                    N_('This operation drops unstaged changes.\n'
                       'These changes cannot be recovered.'),
                    N_('Revert the unstaged changes?'),
                    N_('Revert Unstaged Changes'),
                    default=True,
                    icon=qtutils.icon('undo.svg')):
                return
            args = []
            if not staged and self.m.amending():
                args.append(self.m.head)
            cmds.do(cmds.Checkout, args + ['--'] + items_to_undo)
        else:
            msg = N_('No files selected for checkout from HEAD.')
            Interaction.log(msg)
Example #4
0
    def do(self):
        if not self.filenames:
            return
        filename = self.filenames[0]
        if not core.exists(filename):
            return
        editor = prefs.editor()
        opts = []

        if self.line_number is None:
            opts = self.filenames
        else:
            # Single-file w/ line-numbers (likely from grep)
            editor_opts = {
                "*vim*": ["+" + self.line_number, filename],
                "*emacs*": ["+" + self.line_number, filename],
                "*textpad*": ["%s(%s,0)" % (filename, self.line_number)],
                "*notepad++*": ["-n" + self.line_number, filename],
            }

            opts = self.filenames
            for pattern, opt in editor_opts.items():
                if fnmatch(editor, pattern):
                    opts = opt
                    break

        try:
            core.fork(utils.shell_split(editor) + opts)
        except Exception as e:
            message = N_('Cannot exec "%s": please configure your editor') % editor
            details = core.decode(e.strerror)
            Interaction.critical(N_("Error Editing File"), message, details)
Example #5
0
 def do(self):
     if self.index:
         args = ['apply', '--index', self.selection]
     else:
         args = ['apply', self.selection]
     status, output = git.stash(with_stderr=True, with_status=True, *args)
     Interaction.log_status(status, output, '')
Example #6
0
    def do(self):
        diff_text = ""
        num_patches = len(self.patches)
        orig_head = self.model.git.rev_parse("HEAD")[STDOUT]

        for idx, patch in enumerate(self.patches):
            status, out, err = self.model.git.am(patch)
            # Log the git-am command
            Interaction.log_status(status, out, err)

            if num_patches > 1:
                diff = self.model.git.diff("HEAD^!", stat=True)[STDOUT]
                diff_text += N_("PATCH %(current)d/%(count)d") % dict(current=idx + 1, count=num_patches)
                diff_text += " - %s:\n%s\n\n" % (os.path.basename(patch), diff)

        diff_text += N_("Summary:") + "\n"
        diff_text += self.model.git.diff(orig_head, stat=True)[STDOUT]

        # Display a diffstat
        self.model.set_diff_text(diff_text)
        self.model.update_file_status()

        basenames = "\n".join([os.path.basename(p) for p in self.patches])
        Interaction.information(
            N_("Patch(es) Applied"), (N_("%d patch(es) applied.") + "\n\n%s") % (len(self.patches), basenames)
        )
Example #7
0
    def do(self):
        log_msg = N_('Tagging "%(revision)s" as "%(name)s"') % dict(revision=self._revision, name=self._name)
        opts = {}
        try:
            if self._message:
                opts["F"] = utils.tmp_filename("tag-message")
                core.write(opts["F"], self._message)

            if self._sign:
                log_msg += " (%s)" % N_("GPG-signed")
                opts["s"] = True
            else:
                opts["a"] = bool(self._message)
            status, output, err = self.model.git.tag(self._name, self._revision, **opts)
        finally:
            if "F" in opts:
                os.unlink(opts["F"])

        if output:
            log_msg += "\n" + (N_("Output: %s") % output)

        Interaction.log_status(status, log_msg, err)
        if status == 0:
            self.model.update_status()
        return (status, output, err)
Example #8
0
 def do(self):
     (status, out, err) = (1, "", "")
     with GitXBaseContext(GIT_XBASE_TITLE=N_("Rebase"), GIT_XBASE_ACTION=N_("Rebase")):
         status, out, err = self.model.git.rebase(skip=True)
     Interaction.log_status(status, out, err)
     self.model.update_status()
     return status, out, err
Example #9
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=icons.cola()):
                    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=icons.discard()):
                return

        # Disable the GUI by default
        self.buttons.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)
Example #10
0
 def do(self):
     with GitXBaseContext(
             GIT_XBASE_TITLE=N_('Edit Rebase'),
             GIT_XBASE_ACTION=N_('Save')):
         status, out, err = self.model.git.rebase(edit_todo=True)
     Interaction.log_status(status, out, err)
     self.model.update_status()
Example #11
0
def _send_msg():
    if git.GIT_COLA_TRACE == 'trace':
        msg = ('info: Trace enabled.  '
               'Many of commands reported with "trace" use git\'s stable '
               '"plumbing" API and are not intended for typical '
               'day-to-day use.  Here be dragons')
        Interaction.log(msg)
Example #12
0
 def do(self):
     if self.index:
         args = ['apply', '--index', self.selection]
     else:
         args = ['apply', self.selection]
     status, out, err = git.stash(*args)
     Interaction.log_status(status, out, err)
Example #13
0
 def do(self):
     if self.keep_index:
         args = ['save', '--keep-index', self.stash_name]
     else:
         args = ['save', self.stash_name]
     status, out, err = git.stash(*args)
     Interaction.log_status(status, out, err)
Example #14
0
def start():
    global _thread
    if not AVAILABLE:
        if utils.is_win32():
            msg = ('file notification: disabled\n'
                   'Note: install pywin32 to enable.\n')
        elif utils.is_linux():
            msg = ('inotify: disabled\n'
                   'Note: install python-pyinotify to enable inotify.\n')
        else:
            return

        if utils.is_debian():
            msg += ('On Debian systems '
                    'try: sudo aptitude install python-pyinotify')
        Interaction.log(msg)
        return

    # Start the notification thread
    _thread = GitNotifier()
    _thread.start()
    if utils.is_win32():
        msg = 'file notification: enabled'
    else:
        msg = 'inotify support: enabled'
    Interaction.log(msg)
Example #15
0
    def do(self):
        log_msg = (N_('Tagging "%(revision)s" as "%(name)s"') %
                   dict(revision=self._revision, name=self._name))
        opts = {}
        if self._message:
            opts['F'] = utils.tmp_filename('tag-message')
            core.write(opts['F'], self._message)

        if self._sign:
            log_msg += ' (%s)' % N_('GPG-signed')
            opts['s'] = True
            status, output, err = self.model.git.tag(self._name,
                                                     self._revision, **opts)
        else:
            opts['a'] = bool(self._message)
            status, output, err = self.model.git.tag(self._name,
                                                     self._revision, **opts)
        if 'F' in opts:
            os.unlink(opts['F'])

        if output:
            log_msg += '\n' + (N_('Output: %s') % output)

        Interaction.log_status(status, log_msg, err)
        if status == 0:
            self.model.update_status()
Example #16
0
 def do(self):
     status, out, err = self.model.git.checkout(*self.argv)
     Interaction.log_status(status, out, err)
     if self.checkout_branch:
         self.model.update_status()
     else:
         self.model.update_file_status()
Example #17
0
    def thread_done(self, results):
        self.setEnabled(True)
        self.progress.close()
        QtGui.QApplication.restoreOverrideCursor()

        detail_lines = []
        for (cmd, status, out, err) in results:
            if status != 0:
                Interaction.critical(
                        N_('Error Creating Branch'),
                        (N_('"%(command)s" returned exit status "%(status)d"') %
                         dict(command='git '+cmd, status=status)))
                return
            line = '"git %s" returned exit status %d' % (cmd, status)
            detail_lines.append(line)
            if out:
                detail_lines.append(out)
            if err:
                detail_lines.append(err)
            detail_lines.append('')
        details = '\n'.join(detail_lines)
        qtutils.information(N_('Create Branch'),
                            N_('Branch created'),
                            details=details)
        self.accept()
Example #18
0
 def cherry_pick(self):
     widget = self.commit_list
     row, selected = qtutils.selected_row(widget)
     if not selected or len(self.results) < row:
         return
     revision = self.results[row][0]
     Interaction.log_status(*git.cherry_pick(revision))
Example #19
0
    def action_completed(self, task, status, out, err):
        # Grab the results of the action and finish up
        self.action_button.setEnabled(True)
        self.close_button.setEnabled(True)

        already_up_to_date = N_('Already up-to-date.')

        if not out: # git fetch --tags --verbose doesn't print anything...
            out = already_up_to_date

        command = 'git %s' % self.action.lower()
        message = (N_('"%(command)s" returned exit status %(status)d') %
                   dict(command=command, status=status))
        details = ''
        if out:
            details = out
        if err:
            details += '\n\n' + err

        log_message = message
        if details:
            log_message += '\n\n' + details
        Interaction.log(log_message)

        if status == 0:
            self.accept()
            return

        if self.action == PUSH:
            message += '\n\n'
            message += N_('Have you rebased/pulled lately?')

        Interaction.critical(self.windowTitle(),
                             message=message, details=details)
Example #20
0
    def do(self):
        # Create the commit message file
        msg = self.strip_comments(self.msg)
        tmpfile = utils.tmp_filename('commit-message')
        try:
            core.write(tmpfile, msg)

            # Run 'git commit'
            status, out, err = self.model.git.commit(F=tmpfile,
                                                     v=True,
                                                     gpg_sign=self.sign,
                                                     amend=self.amend,
                                                     no_verify=self.no_verify)
        finally:
            core.unlink(tmpfile)

        if status == 0:
            ResetMode.do(self)
            self.model.set_commitmsg(self.new_commitmsg)
            msg = N_('Created commit: %s') % out
        else:
            msg = N_('Commit failed: %s') % out
        Interaction.log_status(status, msg, err)

        return status, out, err
Example #21
0
 def export_patch(self):
     widget = self.commit_list
     row, selected = qtutils.selected_row(widget)
     if not selected or len(self.results) < row:
         return
     revision = self.results[row][0]
     Interaction.log_status(*gitcmds.export_patchset(revision, revision))
Example #22
0
    def do(self):
        log_msg = 'Tagging: "%s" as "%s"' % (self._revision, self._name)
        opts = {}
        if self._message:
            opts['F'] = utils.tmp_filename('tag-message')
            utils.write(opts['F'], self._message)

        if self._sign:
            log_msg += ', GPG-signed'
            opts['s'] = True
            status, output = self.model.git.tag(self._name,
                                                self._revision,
                                                with_status=True,
                                                with_stderr=True,
                                                **opts)
        else:
            opts['a'] = bool(self._message)
            status, output = self.model.git.tag(self._name,
                                                self._revision,
                                                with_status=True,
                                                with_stderr=True,
                                                **opts)
        if 'F' in opts:
            os.unlink(opts['F'])

        if output:
            log_msg += '\nOutput:\n%s' % output

        Interaction.log_status(status, log_msg, '')
        if status == 0:
            self.model.update_status()
Example #23
0
    def do(self):
        if not self.filenames:
            return
        filename = self.filenames[0]
        if not core.exists(filename):
            return
        editor = prefs.editor()
        opts = []

        if self.line_number is None:
            opts = self.filenames
        else:
            # Single-file w/ line-numbers (likely from grep)
            editor_opts = {
                    '*vim*': ['+'+self.line_number, filename],
                    '*emacs*': ['+'+self.line_number, filename],
                    '*textpad*': ['%s(%s,0)' % (filename, self.line_number)],
                    '*notepad++*': ['-n'+self.line_number, filename],
            }

            opts = self.filenames
            for pattern, opt in editor_opts.items():
                if fnmatch(editor, pattern):
                    opts = opt
                    break

        try:
            core.fork(utils.shell_split(editor) + opts)
        except Exception as e:
            message = (N_('Cannot exec "%s": please configure your editor') %
                       editor)
            Interaction.critical(N_('Error Editing File'),
                                 message, str(e))
Example #24
0
    def do(self):
        parser = DiffParser(self.model.filename, self.model.diff_text)
        if self.has_selection:
            patch = parser.generate_patch(self.first_line_idx,
                                          self.last_line_idx,
                                          reverse=self.reverse)
        else:
            patch = parser.generate_hunk_patch(self.first_line_idx,
                                               reverse=self.reverse)
        if patch is None:
            return

        cfg = gitcfg.current()
        tmp_path = utils.tmp_filename('patch')
        try:
            core.write(tmp_path, patch,
                       encoding=cfg.file_encoding(self.model.filename))
            if self.apply_to_worktree:
                status, out, err = self.model.apply_diff_to_worktree(tmp_path)
            else:
                status, out, err = self.model.apply_diff(tmp_path)
        finally:
            os.unlink(tmp_path)
        Interaction.log_status(status, out, err)
        self.model.update_file_status(update_index=True)
Example #25
0
    def do(self):
        diff_text = ""
        num_patches = len(self.patches)
        orig_head = self.model.git.rev_parse("HEAD")

        for idx, patch in enumerate(self.patches):
            status, output = self.model.git.am(patch, with_status=True, with_stderr=True)
            # Log the git-am command
            Interaction.log_status(status, output, "")

            if num_patches > 1:
                diff = self.model.git.diff("HEAD^!", stat=True)
                diff_text += "Patch %d/%d - " % (idx + 1, num_patches)
                diff_text += "%s:\n%s\n\n" % (os.path.basename(patch), diff)

        diff_text += "Summary:\n"
        diff_text += self.model.git.diff(orig_head, stat=True)

        # Display a diffstat
        self.model.set_diff_text(diff_text)

        self.model.update_file_status()

        Interaction.information(
            "Patch(es) Applied",
            "%d patch(es) applied:\n\n%s" % (len(self.patches), "\n".join(map(os.path.basename, self.patches))),
        )
Example #26
0
    def do(self):
        diff_text = ''
        num_patches = len(self.patches)
        orig_head = self.model.git.rev_parse('HEAD')

        for idx, patch in enumerate(self.patches):
            status, output = self.model.git.am(patch,
                                               with_status=True,
                                               with_stderr=True)
            # Log the git-am command
            Interaction.log_status(status, output, '')

            if num_patches > 1:
                diff = self.model.git.diff('HEAD^!', stat=True)
                diff_text += 'Patch %d/%d - ' % (idx+1, num_patches)
                diff_text += '%s:\n%s\n\n' % (os.path.basename(patch), diff)

        diff_text += 'Summary:\n'
        diff_text += self.model.git.diff(orig_head, stat=True)

        # Display a diffstat
        self.model.set_diff_text(diff_text)

        self.model.update_file_status()

        Interaction.information(
                'Patch(es) Applied',
                '%d patch(es) applied:\n\n%s' %
                (len(self.patches),
                 '\n'.join(map(os.path.basename, self.patches))))
Example #27
0
 def do(self):
     status, output = self.model.git.checkout(with_stderr=True, with_status=True, *self.argv)
     Interaction.log_status(status, output, "")
     if self.checkout_branch:
         self.model.update_status()
     else:
         self.model.update_file_status()
Example #28
0
    def action_completed(self, task, status, output):
        # Grab the results of the action and finish up
        self.progress_thread.stop()
        self.progress_thread.wait()
        if task in self.tasks:
            self.tasks.remove(task)

        already_up_to_date = N_('Already up-to-date.')

        if not output: # git fetch --tags --verbose doesn't print anything...
            output = already_up_to_date

        self.setEnabled(True)
        self.progress.close()
        QtGui.QApplication.restoreOverrideCursor()

        command = 'git %s' % self.action.lower()
        message = (N_('"%(command)s" returned exit status %(status)d') %
                   dict(command=command, status=status))
        if output:
            message += '\n\n' + output

        Interaction.log(message)

        if status == 0:
            self.accept()
            return

        if self.action == PUSH:
            message += '\n\n'
            message += N_('Have you rebased/pulled lately?')

        Interaction.critical(self.windowTitle(),
                             message=message, details=output)
Example #29
0
def report_clone_repo_errors(task):
    """Report errors from the clone task if they exist"""
    if task.cmd is None or task.cmd.ok:
        return
    Interaction.critical(task.cmd.error_message,
                         message=task.cmd.error_message,
                         details=task.cmd.error_details)
Example #30
0
    def do(self):
        diff_text = ''
        num_patches = len(self.patches)
        orig_head = self.model.git.rev_parse('HEAD')[STDOUT]

        for idx, patch in enumerate(self.patches):
            status, out, err = self.model.git.am(patch)
            # Log the git-am command
            Interaction.log_status(status, out, err)

            if num_patches > 1:
                diff = self.model.git.diff('HEAD^!', stat=True)[STDOUT]
                diff_text += (N_('PATCH %(current)d/%(count)d') %
                              dict(current=idx+1, count=num_patches))
                diff_text += ' - %s:\n%s\n\n' % (os.path.basename(patch), diff)

        diff_text += N_('Summary:') + '\n'
        diff_text += self.model.git.diff(orig_head, stat=True)[STDOUT]

        # Display a diffstat
        self.model.set_diff_text(diff_text)
        self.model.update_file_status()

        basenames = '\n'.join([os.path.basename(p) for p in self.patches])
        Interaction.information(
                N_('Patch(es) Applied'),
                (N_('%d patch(es) applied.') + '\n\n%s') %
                    (len(self.patches), basenames))
Example #31
0
 def do(self):
     msg = N_('Untracking: %s') % (', '.join(self.paths))
     Interaction.log(msg)
     with CommandDisabled(UpdateFileStatus):
         status, out, err = self.model.untrack_paths(self.paths)
     Interaction.log_status(status, out, err)
Example #32
0
 def _log_enabled_message():
     msg = N_('File system change monitoring: enabled.\n')
     Interaction.safe_log(msg)
Example #33
0
 def save(self):
     """Saves the bookmarks settings and exits"""
     self.model.save()
     Interaction.information(N_('Bookmarks Saved'),
                             N_('Successfully saved bookmarks'))
     self.save_button.setEnabled(False)
Example #34
0
 def do(self):
     status, out, err = git.stash('drop', self.stash_sha1)
     Interaction.log_status(status, out, err)
Example #35
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 = 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 = self.remote_branch.text()
        local_branch = 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=icons.cola()):
                    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=icons.discard()):
                return

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

        # Use a thread to update in the background
        task = ActionTask(self, model_action, remote, kwargs)
        self.runtask.start(task,
                           progress=self.progress,
                           finish=self.action_completed)
Example #36
0
 def confirm(self):
     title = N_('Delete Remote')
     question = N_('Delete remote?')
     info = N_('Delete remote "%s"') % self.remote
     ok_btn = N_('Delete')
     return Interaction.confirm(title, question, info, ok_btn)
Example #37
0
 def confirm(self):
     repo = self.repo
     title = msg = N_('Remove %s from the recent list?') % repo
     info = N_('%s will be removed from your recent repositories.') % repo
     ok_text = N_('Remove')
     return Interaction.confirm(title, msg, info, ok_text, icon=self.icon)
Example #38
0
 def do(self):
     with GitXBaseContext(GIT_XBASE_TITLE=N_('Edit Rebase'),
                          GIT_XBASE_ACTION=N_('Save')):
         status, out, err = self.model.git.rebase(edit_todo=True)
     Interaction.log_status(status, out, err)
     self.model.update_status()
Example #39
0
 def cherry_pick(self):
     revision = self.selected_revision()
     if revision is not None:
         Interaction.log_status(*git.cherry_pick(revision))
Example #40
0
 def thread_command(self, status, output):
     Interaction.log_status(status, output)
Example #41
0
 def fail(self, status, out, err):
     title = msg = self.error_message()
     details = self.error_details() or out + err
     Interaction.critical(title, message=msg, details=details)
Example #42
0
 def do(self):
     status, out, err = self.model.rename_branch(self.branch,
                                                 self.new_branch)
     Interaction.log_status(status, out, err)
Example #43
0
 def do(self):
     msg = N_('Unstaging: %s') % (', '.join(self.paths))
     Interaction.log(msg)
     with CommandDisabled(UpdateFileStatus):
         self.model.unstage_paths(self.paths)
Example #44
0
 def confirm(self):
     repo = self.repo
     title = msg = N_('Delete Bookmark?')
     info = N_('%s will be removed from your bookmarks.') % repo
     ok_text = N_('Delete Bookmark')
     return Interaction.confirm(title, msg, info, ok_text, icon=self.icon)
Example #45
0
 def do(self):
     status, out, err = self.model.delete_branch(self.branch)
     Interaction.log_status(status, out, err)
Example #46
0
    def __init__(self, model, parent):
        MainWindow.__init__(self, parent)
        # Default size; this is thrown out when save/restore is used
        self.resize(987, 610)
        self.model = model
        self.prefs_model = prefs_model = prefs.PreferencesModel()

        # Internal field used by import/export_state().
        # Change this whenever dockwidgets are removed.
        self.widget_version = 1

        # Keeps track of merge messages we've seen
        self.merge_message_hash = ''

        self.setAcceptDrops(True)
        self.setAttribute(Qt.WA_MacMetalStyle)

        # Dockwidget options
        qtcompat.set_common_dock_options(self)

        cfg = gitcfg.instance()
        self.classic_dockable = (cfg.get('cola.browserdockable')
                                 or cfg.get('cola.classicdockable'))
        if self.classic_dockable:
            self.classicdockwidget = create_dock('Browser', self)
            self.classicwidget = classic_widget(self)
            self.classicdockwidget.setWidget(self.classicwidget)

        # "Actions" widget
        self.actionsdockwidget = create_dock('Action', self)
        self.actionsdockwidgetcontents = qt.QFlowLayoutWidget(self)
        layout = self.actionsdockwidgetcontents.layout()
        self.stage_button = create_button(text='Stage', layout=layout)
        self.unstage_button = create_button(text='Unstage', layout=layout)
        self.rescan_button = create_button(text='Rescan', layout=layout)
        self.fetch_button = create_button(text='Fetch...', layout=layout)
        self.push_button = create_button(text='Push...', layout=layout)
        self.pull_button = create_button(text='Pull...', layout=layout)
        self.stash_button = create_button(text='Stash...', layout=layout)
        layout.addStretch()
        self.actionsdockwidget.setWidget(self.actionsdockwidgetcontents)

        # "Repository Status" widget
        self.statusdockwidget = create_dock('Status', self)
        self.statusdockwidget.setWidget(StatusWidget(self))

        # "Commit Message Editor" widget
        self.position_label = QtGui.QLabel()
        font = qtutils.default_monospace_font()
        font.setPointSize(int(font.pointSize() * 0.8))
        self.position_label.setFont(font)
        self.commitdockwidget = create_dock('Commit', self)
        titlebar = self.commitdockwidget.titleBarWidget()
        titlebar.add_corner_widget(self.position_label)

        self.commitmsgeditor = CommitMessageEditor(model, self)
        self.commitdockwidget.setWidget(self.commitmsgeditor)

        # "Console" widget
        self.logwidget = LogWidget()
        self.logdockwidget = create_dock('Console', self)
        self.logdockwidget.setWidget(self.logwidget)

        # "Diff Viewer" widget
        self.diffdockwidget = create_dock('Diff', self)
        self.diffeditor = DiffEditor(self.diffdockwidget)
        self.diffdockwidget.setWidget(self.diffeditor)

        # All Actions
        self.menu_unstage_all = add_action(self, 'Unstage All',
                                           cmds.run(cmds.UnstageAll))
        self.menu_unstage_all.setIcon(qtutils.icon('remove.svg'))

        self.menu_unstage_selected = add_action(self, 'Unstage From Commit',
                                                cmds.run(cmds.UnstageSelected))
        self.menu_unstage_selected.setIcon(qtutils.icon('remove.svg'))

        self.menu_show_diffstat = add_action(self, 'Diffstat',
                                             cmds.run(cmds.Diffstat), 'Alt+D')

        self.menu_stage_modified = add_action(self,
                                              'Stage Changed Files To Commit',
                                              cmds.run(cmds.StageModified),
                                              'Alt+A')
        self.menu_stage_modified.setIcon(qtutils.icon('add.svg'))

        self.menu_stage_untracked = add_action(self, 'Stage All Untracked',
                                               cmds.run(cmds.StageUntracked),
                                               'Alt+U')
        self.menu_stage_untracked.setIcon(qtutils.icon('add.svg'))

        self.menu_export_patches = add_action(self, 'Export Patches...',
                                              guicmds.export_patches, 'Alt+E')
        self.menu_preferences = add_action(self, 'Preferences',
                                           self.preferences,
                                           QtGui.QKeySequence.Preferences,
                                           'Ctrl+O')

        self.menu_edit_remotes = add_action(self, 'Edit Remotes...',
                                            lambda: editremotes.edit().exec_())
        self.menu_rescan = add_action(self, cmds.RescanAndRefresh.NAME,
                                      cmds.run(cmds.RescanAndRefresh),
                                      cmds.RescanAndRefresh.SHORTCUT)
        self.menu_rescan.setIcon(qtutils.reload_icon())

        self.menu_browse_recent = add_action(self,
                                             'Recently Modified Files...',
                                             browse_recent, 'Shift+Ctrl+E')

        self.menu_cherry_pick = add_action(self, 'Cherry-Pick...',
                                           guicmds.cherry_pick, 'Ctrl+P')

        self.menu_load_commitmsg = add_action(self, 'Load Commit Message...',
                                              guicmds.load_commitmsg)

        self.menu_save_tarball = add_action(self, 'Save As Tarball/Zip...',
                                            self.save_archive)

        self.menu_quit = add_action(self, 'Quit', self.close, 'Ctrl+Q')
        self.menu_manage_bookmarks = add_action(self, 'Bookmarks...',
                                                manage_bookmarks)
        self.menu_grep = add_action(self, 'Grep', guicmds.grep, 'Ctrl+G')
        self.menu_merge_local = add_action(self, 'Merge...', merge.local_merge)

        self.menu_merge_abort = add_action(self, 'Abort Merge...',
                                           merge.abort_merge)

        self.menu_fetch = add_action(self, 'Fetch...', remote.fetch)
        self.menu_push = add_action(self, 'Push...', remote.push)
        self.menu_pull = add_action(self, 'Pull...', remote.pull)

        self.menu_open_repo = add_action(self, 'Open...', guicmds.open_repo)
        self.menu_open_repo.setIcon(qtutils.open_icon())

        self.menu_stash = add_action(self, 'Stash...', stash.stash,
                                     'Alt+Shift+S')

        self.menu_clone_repo = add_action(self, 'Clone...', guicmds.clone_repo)
        self.menu_clone_repo.setIcon(qtutils.git_icon())

        self.menu_help_docs = add_action(self, 'Documentation',
                                         resources.show_html_docs,
                                         QtGui.QKeySequence.HelpContents)

        self.menu_help_shortcuts = add_action(self, 'Keyboard Shortcuts',
                                              show_shortcuts,
                                              QtCore.Qt.Key_Question)

        self.menu_visualize_current = add_action(
            self, 'Visualize Current Branch...',
            cmds.run(cmds.VisualizeCurrent))
        self.menu_visualize_all = add_action(self, 'Visualize All Branches...',
                                             cmds.run(cmds.VisualizeAll))
        self.menu_search_commits = add_action(self, 'Search...', search)
        self.menu_browse_branch = add_action(self, 'Browse Current Branch...',
                                             guicmds.browse_current)
        self.menu_browse_other_branch = add_action(self,
                                                   'Browse Other Branch...',
                                                   guicmds.browse_other)
        self.menu_load_commitmsg_template = add_action(
            self, 'Get Commit Message Template',
            cmds.run(cmds.LoadCommitTemplate))
        self.menu_help_about = add_action(self, 'About', launch_about_dialog)

        self.menu_branch_diff = add_action(self, 'SHA-1...',
                                           guicmds.diff_revision)
        self.menu_diff_expression = add_action(self, 'Expression...',
                                               guicmds.diff_expression)
        self.menu_branch_compare = add_action(self, 'Branches...',
                                              compare_branches)

        self.menu_create_tag = add_action(self, 'Create Tag...', create_tag)

        self.menu_create_branch = add_action(self, 'Create...',
                                             create_new_branch, 'Ctrl+B')

        self.menu_delete_branch = add_action(self, 'Delete...',
                                             guicmds.branch_delete)

        self.menu_checkout_branch = add_action(self, 'Checkout...',
                                               guicmds.checkout_branch,
                                               'Alt+B')
        self.menu_rebase_branch = add_action(self, 'Rebase...', guicmds.rebase)
        self.menu_branch_review = add_action(self, 'Review...',
                                             guicmds.review_branch)

        self.menu_classic = add_action(self, 'Browser...', cola_classic)
        self.menu_classic.setIcon(qtutils.git_icon())

        self.menu_dag = add_action(self, 'DAG...', lambda: git_dag(self.model))
        self.menu_dag.setIcon(qtutils.git_icon())

        # Relayed actions
        if not self.classic_dockable:
            # These shortcuts conflict with those from the
            # 'Browser' widget so don't register them when
            # the browser is a dockable tool.
            status_tree = self.statusdockwidget.widget().tree
            self.addAction(status_tree.up)
            self.addAction(status_tree.down)
            self.addAction(status_tree.process_selection)

        # Create the application menu
        self.menubar = QtGui.QMenuBar(self)

        # File Menu
        self.file_menu = create_menu('&File', self.menubar)
        self.file_menu.addAction(self.menu_preferences)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.menu_open_repo)
        self.menu_open_recent = self.file_menu.addMenu(tr('Open Recent'))
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.menu_clone_repo)
        self.file_menu.addAction(self.menu_manage_bookmarks)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.menu_edit_remotes)
        self.file_menu.addAction(self.menu_rescan)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.menu_browse_recent)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.menu_load_commitmsg)
        self.file_menu.addAction(self.menu_load_commitmsg_template)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.menu_save_tarball)
        self.file_menu.addAction(self.menu_quit)
        # Add to menubar
        self.menubar.addAction(self.file_menu.menuAction())

        # Commit Menu
        self.commit_menu = create_menu('Co&mmit', self.menubar)
        self.commit_menu.setTitle(tr('Commit@@verb'))
        self.commit_menu.addAction(self.menu_stage_modified)
        self.commit_menu.addAction(self.menu_stage_untracked)
        self.commit_menu.addSeparator()
        self.commit_menu.addAction(self.menu_unstage_all)
        self.commit_menu.addAction(self.menu_unstage_selected)
        self.commit_menu.addSeparator()
        self.commit_menu.addAction(self.menu_search_commits)
        # Add to menubar
        self.menubar.addAction(self.commit_menu.menuAction())

        # Branch Menu
        self.branch_menu = create_menu('B&ranch', self.menubar)
        self.branch_menu.addAction(self.menu_branch_review)
        self.branch_menu.addSeparator()
        self.branch_menu.addAction(self.menu_create_branch)
        self.branch_menu.addAction(self.menu_checkout_branch)
        self.branch_menu.addAction(self.menu_rebase_branch)
        self.branch_menu.addAction(self.menu_delete_branch)
        self.branch_menu.addSeparator()
        self.branch_menu.addAction(self.menu_browse_branch)
        self.branch_menu.addAction(self.menu_browse_other_branch)
        self.branch_menu.addSeparator()
        self.branch_menu.addAction(self.menu_visualize_current)
        self.branch_menu.addAction(self.menu_visualize_all)
        # Add to menubar
        self.menubar.addAction(self.branch_menu.menuAction())

        # Actions menu
        self.actions_menu = create_menu('Act&ions', self.menubar)
        self.actions_menu.addAction(self.menu_merge_local)
        self.actions_menu.addAction(self.menu_stash)
        self.actions_menu.addSeparator()
        self.actions_menu.addAction(self.menu_fetch)
        self.actions_menu.addAction(self.menu_push)
        self.actions_menu.addAction(self.menu_pull)
        self.actions_menu.addSeparator()
        self.actions_menu.addAction(self.menu_create_tag)
        self.actions_menu.addSeparator()
        self.actions_menu.addAction(self.menu_export_patches)
        self.actions_menu.addAction(self.menu_cherry_pick)
        self.actions_menu.addSeparator()
        self.actions_menu.addAction(self.menu_merge_abort)
        self.actions_menu.addAction(self.menu_grep)
        # Add to menubar
        self.menubar.addAction(self.actions_menu.menuAction())

        # Diff Menu
        self.diff_menu = create_menu('&Diff', self.menubar)
        self.diff_menu.addAction(self.menu_branch_diff)
        self.diff_menu.addAction(self.menu_diff_expression)
        self.diff_menu.addAction(self.menu_branch_compare)
        self.diff_menu.addSeparator()
        self.diff_menu.addAction(self.menu_show_diffstat)
        # Add to menubar
        self.menubar.addAction(self.diff_menu.menuAction())

        # Tools Menu
        self.tools_menu = create_menu('&Tools', self.menubar)
        self.tools_menu.addAction(self.menu_classic)
        self.tools_menu.addAction(self.menu_dag)
        self.tools_menu.addSeparator()
        if self.classic_dockable:
            self.tools_menu.addAction(
                self.classicdockwidget.toggleViewAction())

        self.setup_dockwidget_tools_menu()
        self.menubar.addAction(self.tools_menu.menuAction())

        # Help Menu
        self.help_menu = create_menu('&Help', self.menubar)
        self.help_menu.addAction(self.menu_help_docs)
        self.help_menu.addAction(self.menu_help_shortcuts)
        self.help_menu.addAction(self.menu_help_about)
        # Add to menubar
        self.menubar.addAction(self.help_menu.menuAction())

        # Set main menu
        self.setMenuBar(self.menubar)

        # Arrange dock widgets
        top = Qt.TopDockWidgetArea
        bottom = Qt.BottomDockWidgetArea

        self.addDockWidget(top, self.commitdockwidget)
        if self.classic_dockable:
            self.addDockWidget(top, self.classicdockwidget)
        self.addDockWidget(top, self.statusdockwidget)
        self.addDockWidget(top, self.actionsdockwidget)
        self.addDockWidget(bottom, self.logdockwidget)
        if self.classic_dockable:
            self.tabifyDockWidget(self.classicdockwidget,
                                  self.commitdockwidget)
        self.tabifyDockWidget(self.logdockwidget, self.diffdockwidget)

        # Listen for model notifications
        model.add_observer(model.message_updated, self._update_view)

        prefs_model.add_observer(prefs_model.message_config_updated,
                                 self._config_updated)

        # Set a default value
        self.show_cursor_position(1, 0)

        # Add button callbacks
        connect_button(self.rescan_button, cmds.run(cmds.RescanAndRefresh))
        connect_button(self.fetch_button, remote.fetch)
        connect_button(self.push_button, remote.push)
        connect_button(self.pull_button, remote.pull)
        connect_button(self.stash_button, stash.stash)

        connect_button(self.stage_button, self.stage)
        connect_button(self.unstage_button, self.unstage)

        self.connect(self.menu_open_recent, SIGNAL('aboutToShow()'),
                     self.build_recent_menu)

        self.connect(self.commitmsgeditor, SIGNAL('cursorPosition(int,int)'),
                     self.show_cursor_position)
        self.connect(self, SIGNAL('update'), self._update_callback)
        self.connect(self, SIGNAL('install_config_actions'),
                     self._install_config_actions)

        # Install .git-config-defined actions
        self._config_task = None
        self.install_config_actions()

        self.dockwidgets = (
            self.logdockwidget,
            self.commitdockwidget,
            self.statusdockwidget,
            self.diffdockwidget,
            self.actionsdockwidget,
        )
        # Restore saved settings
        qtutils.apply_state(self)

        self.statusdockwidget.widget().setFocus()

        # Route command output here
        Interaction.log_status = self.logwidget.log_status
        Interaction.log = self.logwidget.log

        Interaction.log(version.git_version_str() + '\ncola version ' +
                        version.version())
Example #47
0
    def __init__(self, model, parent=None):
        MainWindow.__init__(self, parent)
        # Default size; this is thrown out when save/restore is used
        self.resize(987, 610)
        self.model = model
        self.prefs_model = prefs_model = prefs.PreferencesModel()

        # The widget version is used by import/export_state().
        # Change this whenever dockwidgets are removed.
        self.widget_version = 2

        # Keeps track of merge messages we've seen
        self.merge_message_hash = ''

        self.setAcceptDrops(True)
        self.setAttribute(Qt.WA_MacMetalStyle)

        cfg = gitcfg.instance()
        self.browser_dockable = (cfg.get('cola.browserdockable')
                                 or cfg.get('cola.classicdockable'))
        if self.browser_dockable:
            self.browserdockwidget = create_dock(N_('Browser'), self)
            self.browserwidget = worktree_browser_widget(self)
            self.browserdockwidget.setWidget(self.browserwidget)

        # "Actions" widget
        self.actionsdockwidget = create_dock(N_('Actions'), self)
        self.actionsdockwidgetcontents = action.ActionButtons(self)
        self.actionsdockwidget.setWidget(self.actionsdockwidgetcontents)
        self.actionsdockwidget.toggleViewAction().setChecked(False)
        self.actionsdockwidget.hide()

        # "Repository Status" widget
        self.statuswidget = StatusWidget(self)
        self.statusdockwidget = create_dock(N_('Status'), self)
        self.statusdockwidget.setWidget(self.statuswidget)

        # "Commit Message Editor" widget
        self.position_label = QtGui.QLabel()
        font = qtutils.default_monospace_font()
        font.setPointSize(int(font.pointSize() * 0.8))
        self.position_label.setFont(font)
        self.commitdockwidget = create_dock(N_('Commit'), self)
        titlebar = self.commitdockwidget.titleBarWidget()
        titlebar.add_corner_widget(self.position_label)

        self.commitmsgeditor = CommitMessageEditor(model, self)
        self.commitdockwidget.setWidget(self.commitmsgeditor)

        # "Console" widget
        self.logwidget = LogWidget()
        self.logdockwidget = create_dock(N_('Console'), self)
        self.logdockwidget.setWidget(self.logwidget)
        self.logdockwidget.toggleViewAction().setChecked(False)
        self.logdockwidget.hide()

        # "Diff Viewer" widget
        self.diffdockwidget = create_dock(N_('Diff'), self)
        self.diffeditor = DiffEditor(self.diffdockwidget)
        self.diffdockwidget.setWidget(self.diffeditor)

        # "Diff Options" tool menu
        self.diff_ignore_space_at_eol_action = add_action(
            self, N_('Ignore changes in whitespace at EOL'),
            self._update_diff_opts)
        self.diff_ignore_space_at_eol_action.setCheckable(True)

        self.diff_ignore_space_change_action = add_action(
            self, N_('Ignore changes in amount of whitespace'),
            self._update_diff_opts)
        self.diff_ignore_space_change_action.setCheckable(True)

        self.diff_ignore_all_space_action = add_action(
            self, N_('Ignore all whitespace'), self._update_diff_opts)
        self.diff_ignore_all_space_action.setCheckable(True)

        self.diff_function_context_action = add_action(
            self, N_('Show whole surrounding functions of changes'),
            self._update_diff_opts)
        self.diff_function_context_action.setCheckable(True)

        self.diffopts_button = create_toolbutton(text=N_('Options'),
                                                 icon=options_icon(),
                                                 tooltip=N_('Diff Options'))
        self.diffopts_menu = create_menu(N_('Diff Options'),
                                         self.diffopts_button)

        self.diffopts_menu.addAction(self.diff_ignore_space_at_eol_action)
        self.diffopts_menu.addAction(self.diff_ignore_space_change_action)
        self.diffopts_menu.addAction(self.diff_ignore_all_space_action)
        self.diffopts_menu.addAction(self.diff_function_context_action)
        self.diffopts_button.setMenu(self.diffopts_menu)
        self.diffopts_button.setPopupMode(QtGui.QToolButton.InstantPopup)

        titlebar = self.diffdockwidget.titleBarWidget()
        titlebar.add_corner_widget(self.diffopts_button)

        # All Actions
        self.menu_unstage_all = add_action(self, N_('Unstage All'),
                                           cmds.run(cmds.UnstageAll))
        self.menu_unstage_all.setIcon(qtutils.icon('remove.svg'))

        self.menu_unstage_selected = add_action(self,
                                                N_('Unstage From Commit'),
                                                cmds.run(cmds.UnstageSelected))
        self.menu_unstage_selected.setIcon(qtutils.icon('remove.svg'))

        self.menu_show_diffstat = add_action(self, N_('Diffstat'),
                                             cmds.run(cmds.Diffstat), 'Alt+D')

        self.menu_stage_modified = add_action(
            self, N_('Stage Changed Files To Commit'),
            cmds.run(cmds.StageModified), 'Alt+A')
        self.menu_stage_modified.setIcon(qtutils.icon('add.svg'))

        self.menu_stage_untracked = add_action(self, N_('Stage All Untracked'),
                                               cmds.run(cmds.StageUntracked),
                                               'Alt+U')
        self.menu_stage_untracked.setIcon(qtutils.icon('add.svg'))

        self.menu_export_patches = add_action(self, N_('Export Patches...'),
                                              guicmds.export_patches, 'Alt+E')

        self.new_repository = add_action(self, N_('New Repository...'),
                                         guicmds.open_new_repo)
        self.new_repository.setIcon(qtutils.new_icon())

        self.menu_preferences = add_action(self, N_('Preferences'),
                                           self.preferences,
                                           QtGui.QKeySequence.Preferences,
                                           'Ctrl+O')

        self.menu_edit_remotes = add_action(self, N_('Edit Remotes...'),
                                            lambda: editremotes.edit().exec_())
        self.menu_rescan = add_action(self, cmds.Refresh.name(),
                                      cmds.run(cmds.Refresh),
                                      cmds.Refresh.SHORTCUT)
        self.menu_rescan.setIcon(qtutils.reload_icon())

        self.menu_browse_recent = add_action(self,
                                             N_('Recently Modified Files...'),
                                             browse_recent, 'Shift+Ctrl+E')

        self.menu_cherry_pick = add_action(self, N_('Cherry-Pick...'),
                                           guicmds.cherry_pick, 'Ctrl+P')

        self.menu_load_commitmsg = add_action(self,
                                              N_('Load Commit Message...'),
                                              guicmds.load_commitmsg)

        self.menu_save_tarball = add_action(self, N_('Save As Tarball/Zip...'),
                                            self.save_archive)

        self.menu_quit = add_action(self, N_('Quit'), self.close, 'Ctrl+Q')
        self.menu_manage_bookmarks = add_action(self, N_('Bookmarks...'),
                                                manage_bookmarks)
        self.menu_grep = add_action(self, N_('Grep'), guicmds.grep, 'Ctrl+G')
        self.menu_merge_local = add_action(self, N_('Merge...'),
                                           merge.local_merge)

        self.menu_merge_abort = add_action(self, N_('Abort Merge...'),
                                           merge.abort_merge)

        self.menu_fetch = add_action(self, N_('Fetch...'), remote.fetch)
        self.menu_push = add_action(self, N_('Push...'), remote.push)
        self.menu_pull = add_action(self, N_('Pull...'), remote.pull)

        self.menu_open_repo = add_action(self, N_('Open...'),
                                         guicmds.open_repo)
        self.menu_open_repo.setIcon(qtutils.open_icon())

        self.menu_stash = add_action(self, N_('Stash...'), stash,
                                     'Alt+Shift+S')

        self.menu_clone_repo = add_action(self, N_('Clone...'),
                                          guicmds.clone_repo)
        self.menu_clone_repo.setIcon(qtutils.git_icon())

        self.menu_help_docs = add_action(self, N_('Documentation'),
                                         resources.show_html_docs,
                                         QtGui.QKeySequence.HelpContents)

        self.menu_help_shortcuts = add_action(self, N_('Keyboard Shortcuts'),
                                              show_shortcuts,
                                              QtCore.Qt.Key_Question)

        self.menu_visualize_current = add_action(
            self, N_('Visualize Current Branch...'),
            cmds.run(cmds.VisualizeCurrent))
        self.menu_visualize_all = add_action(self,
                                             N_('Visualize All Branches...'),
                                             cmds.run(cmds.VisualizeAll))
        self.menu_search_commits = add_action(self, N_('Search...'), search)
        self.menu_browse_branch = add_action(self,
                                             N_('Browse Current Branch...'),
                                             guicmds.browse_current)
        self.menu_browse_other_branch = add_action(
            self, N_('Browse Other Branch...'), guicmds.browse_other)
        self.menu_load_commitmsg_template = add_action(
            self, N_('Get Commit Message Template'),
            cmds.run(cmds.LoadCommitMessageFromTemplate))
        self.menu_help_about = add_action(self, N_('About'),
                                          launch_about_dialog)

        self.menu_diff_expression = add_action(self, N_('Expression...'),
                                               guicmds.diff_expression)
        self.menu_branch_compare = add_action(self, N_('Branches...'),
                                              compare_branches)

        self.menu_create_tag = add_action(self, N_('Create Tag...'),
                                          create_tag)

        self.menu_create_branch = add_action(self, N_('Create...'),
                                             create_new_branch, 'Ctrl+B')

        self.menu_delete_branch = add_action(self, N_('Delete...'),
                                             guicmds.delete_branch)

        self.menu_delete_remote_branch = add_action(
            self, N_('Delete Remote Branch...'), guicmds.delete_remote_branch)

        self.menu_checkout_branch = add_action(self, N_('Checkout...'),
                                               guicmds.checkout_branch,
                                               'Alt+B')
        self.menu_branch_review = add_action(self, N_('Review...'),
                                             guicmds.review_branch)

        self.menu_browse = add_action(self, N_('Browser...'), worktree_browser)
        self.menu_browse.setIcon(qtutils.git_icon())

        self.menu_dag = add_action(self, N_('DAG...'),
                                   lambda: git_dag(self.model).show())
        self.menu_dag.setIcon(qtutils.git_icon())

        self.rebase_start_action = add_action(
            self, N_('Start Interactive Rebase...'), self.rebase_start)

        self.rebase_edit_todo_action = add_action(self, N_('Edit...'),
                                                  self.rebase_edit_todo)

        self.rebase_continue_action = add_action(self, N_('Continue'),
                                                 self.rebase_continue)

        self.rebase_skip_action = add_action(self, N_('Skip Current Patch'),
                                             self.rebase_skip)

        self.rebase_abort_action = add_action(self, N_('Abort'),
                                              self.rebase_abort)

        # Relayed actions
        if not self.browser_dockable:
            # These shortcuts conflict with those from the
            # 'Browser' widget so don't register them when
            # the browser is a dockable tool.
            status_tree = self.statusdockwidget.widget().tree
            self.addAction(status_tree.up)
            self.addAction(status_tree.down)
            self.addAction(status_tree.process_selection)

        self.lock_layout_action = add_action_bool(self, N_('Lock Layout'),
                                                  self.set_lock_layout, False)

        # Create the application menu
        self.menubar = QtGui.QMenuBar(self)

        # File Menu
        self.file_menu = create_menu(N_('File'), self.menubar)
        self.file_menu.addAction(self.new_repository)
        self.file_menu.addAction(self.menu_open_repo)
        self.menu_open_recent = self.file_menu.addMenu(N_('Open Recent'))
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.menu_clone_repo)
        self.file_menu.addAction(self.menu_manage_bookmarks)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.menu_edit_remotes)
        self.file_menu.addAction(self.menu_rescan)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.menu_browse_recent)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.menu_load_commitmsg)
        self.file_menu.addAction(self.menu_load_commitmsg_template)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.menu_save_tarball)
        self.file_menu.addAction(self.menu_export_patches)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.menu_preferences)
        self.file_menu.addAction(self.menu_quit)
        self.menubar.addAction(self.file_menu.menuAction())

        # Actions menu
        self.actions_menu = create_menu(N_('Actions'), self.menubar)
        self.actions_menu.addAction(self.menu_fetch)
        self.actions_menu.addAction(self.menu_push)
        self.actions_menu.addAction(self.menu_pull)
        self.actions_menu.addAction(self.menu_stash)
        self.actions_menu.addSeparator()
        self.actions_menu.addAction(self.menu_create_tag)
        self.actions_menu.addAction(self.menu_cherry_pick)
        self.actions_menu.addAction(self.menu_merge_local)
        self.actions_menu.addAction(self.menu_merge_abort)
        self.actions_menu.addSeparator()
        self.actions_menu.addAction(self.menu_grep)
        self.actions_menu.addAction(self.menu_search_commits)
        self.menubar.addAction(self.actions_menu.menuAction())

        # Index Menu
        self.commit_menu = create_menu(N_('Index'), self.menubar)
        self.commit_menu.setTitle(N_('Index'))
        self.commit_menu.addAction(self.menu_stage_modified)
        self.commit_menu.addAction(self.menu_stage_untracked)
        self.commit_menu.addSeparator()
        self.commit_menu.addAction(self.menu_unstage_all)
        self.commit_menu.addAction(self.menu_unstage_selected)
        self.menubar.addAction(self.commit_menu.menuAction())

        # Diff Menu
        self.diff_menu = create_menu(N_('Diff'), self.menubar)
        self.diff_menu.addAction(self.menu_diff_expression)
        self.diff_menu.addAction(self.menu_branch_compare)
        self.diff_menu.addSeparator()
        self.diff_menu.addAction(self.menu_show_diffstat)
        self.menubar.addAction(self.diff_menu.menuAction())

        # Branch Menu
        self.branch_menu = create_menu(N_('Branch'), self.menubar)
        self.branch_menu.addAction(self.menu_branch_review)
        self.branch_menu.addSeparator()
        self.branch_menu.addAction(self.menu_create_branch)
        self.branch_menu.addAction(self.menu_checkout_branch)
        self.branch_menu.addAction(self.menu_delete_branch)
        self.branch_menu.addAction(self.menu_delete_remote_branch)
        self.branch_menu.addSeparator()
        self.branch_menu.addAction(self.menu_browse_branch)
        self.branch_menu.addAction(self.menu_browse_other_branch)
        self.branch_menu.addSeparator()
        self.branch_menu.addAction(self.menu_visualize_current)
        self.branch_menu.addAction(self.menu_visualize_all)
        self.menubar.addAction(self.branch_menu.menuAction())

        # Rebase menu
        self.rebase_menu = create_menu(N_('Rebase'), self.actions_menu)
        self.rebase_menu.addAction(self.rebase_start_action)
        self.rebase_menu.addAction(self.rebase_edit_todo_action)
        self.rebase_menu.addSeparator()
        self.rebase_menu.addAction(self.rebase_continue_action)
        self.rebase_menu.addAction(self.rebase_skip_action)
        self.rebase_menu.addSeparator()
        self.rebase_menu.addAction(self.rebase_abort_action)
        self.menubar.addAction(self.rebase_menu.menuAction())

        # View Menu
        self.view_menu = create_menu(N_('View'), self.menubar)
        self.view_menu.addAction(self.menu_browse)
        self.view_menu.addAction(self.menu_dag)
        self.view_menu.addSeparator()
        if self.browser_dockable:
            self.view_menu.addAction(self.browserdockwidget.toggleViewAction())

        self.setup_dockwidget_view_menu()
        self.view_menu.addSeparator()
        self.view_menu.addAction(self.lock_layout_action)
        self.menubar.addAction(self.view_menu.menuAction())

        # Help Menu
        self.help_menu = create_menu(N_('Help'), self.menubar)
        self.help_menu.addAction(self.menu_help_docs)
        self.help_menu.addAction(self.menu_help_shortcuts)
        self.help_menu.addAction(self.menu_help_about)
        self.menubar.addAction(self.help_menu.menuAction())

        # Set main menu
        self.setMenuBar(self.menubar)

        # Arrange dock widgets
        left = Qt.LeftDockWidgetArea
        right = Qt.RightDockWidgetArea
        bottom = Qt.BottomDockWidgetArea

        self.addDockWidget(left, self.commitdockwidget)
        if self.browser_dockable:
            self.addDockWidget(left, self.browserdockwidget)
            self.tabifyDockWidget(self.browserdockwidget,
                                  self.commitdockwidget)
        self.addDockWidget(left, self.diffdockwidget)
        self.addDockWidget(bottom, self.actionsdockwidget)
        self.addDockWidget(bottom, self.logdockwidget)
        self.tabifyDockWidget(self.actionsdockwidget, self.logdockwidget)

        self.addDockWidget(right, self.statusdockwidget)

        # Listen for model notifications
        model.add_observer(model.message_updated, self._update)
        model.add_observer(model.message_mode_changed,
                           lambda x: self._update())

        prefs_model.add_observer(prefs_model.message_config_updated,
                                 self._config_updated)

        # Set a default value
        self.show_cursor_position(1, 0)

        self.connect(self.menu_open_recent, SIGNAL('aboutToShow()'),
                     self.build_recent_menu)

        self.connect(self.commitmsgeditor, SIGNAL('cursorPosition(int,int)'),
                     self.show_cursor_position)
        self.connect(self, SIGNAL('update'), self._update_callback)
        self.connect(self, SIGNAL('install_config_actions'),
                     self._install_config_actions)

        # Install .git-config-defined actions
        self._config_task = None
        self.install_config_actions()

        # Restore saved settings
        if not qtutils.apply_state(self):
            self.set_initial_size()

        self.statusdockwidget.widget().setFocus()

        # Route command output here
        Interaction.log_status = self.logwidget.log_status
        Interaction.log = self.logwidget.log
        Interaction.log(version.git_version_str() + '\n' +
                        N_('git cola version %s') % version.version())
Example #48
0
    def execute(command,
                _cwd=None,
                _decode=True,
                _encoding=None,
                _raw=False,
                _stdin=None,
                _stderr=subprocess.PIPE,
                _stdout=subprocess.PIPE,
                _readonly=False):
        """
        Execute a command and returns its output

        :param command: argument list to execute.
        :param _cwd: working directory, defaults to the current directory.
        :param _decode: whether to decode output, defaults to True.
        :param _encoding: default encoding, defaults to None (utf-8).
        :param _raw: do not strip trailing whitespace.
        :param _stdin: optional stdin filehandle.
        :returns (status, out, err): exit status, stdout, stderr

        """
        # Allow the user to have the command executed in their working dir.
        if not _cwd:
            _cwd = core.getcwd()

        extra = {}
        if sys.platform == 'win32':
            # If git-cola is invoked on Windows using "start pythonw git-cola",
            # a console window will briefly flash on the screen each time
            # git-cola invokes git, which is very annoying.  The code below
            # prevents this by ensuring that any window will be hidden.
            startupinfo = subprocess.STARTUPINFO()
            startupinfo.dwFlags = subprocess.STARTF_USESHOWWINDOW
            startupinfo.wShowWindow = subprocess.SW_HIDE
            extra['startupinfo'] = startupinfo

        if hasattr(os, 'setsid'):
            # SSH uses the SSH_ASKPASS variable only if the process is really
            # detached from the TTY (stdin redirection and setting the
            # SSH_ASKPASS environment variable is not enough).  To detach a
            # process from the console it should fork and call os.setsid().
            extra['preexec_fn'] = os.setsid

        # Start the process
        # Guard against thread-unsafe .git/index.lock files
        if not _readonly:
            INDEX_LOCK.acquire()
        status, out, err = core.run_command(command,
                                            cwd=_cwd,
                                            encoding=_encoding,
                                            stdin=_stdin,
                                            stdout=_stdout,
                                            stderr=_stderr,
                                            **extra)
        # Let the next thread in
        if not _readonly:
            INDEX_LOCK.release()

        if not _raw and out is not None:
            out = out.rstrip('\n')

        cola_trace = GIT_COLA_TRACE
        if cola_trace == 'trace':
            msg = 'trace: ' + subprocess.list2cmdline(command)
            Interaction.log_status(status, msg, '')
        elif cola_trace == 'full':
            if out or err:
                core.stderr("%s -> %d: '%s' '%s'" %
                            (' '.join(command), status, out, err))
            else:
                core.stderr("%s -> %d" % (' '.join(command), status))
        elif cola_trace:
            core.stderr(' '.join(command))

        # Allow access to the command's status code
        return (status, out, err)
Example #49
0
 def do(self):
     msg = 'Untracking: %s' % (', '.join(self.paths))
     Interaction.log(msg)
     status, out = self.model.untrack_paths(self.paths)
     Interaction.log_status(status, out, '')
Example #50
0
def _send_msg():
    if git.GIT_COLA_TRACE == 'trace':
        msg = 'info: debug mode enabled using GIT_COLA_TRACE=trace'
        Interaction.log(msg)
Example #51
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 = N_('No repository selected.')
            Interaction.log(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 = 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.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)
Example #52
0
                    count += 1
                    continue
                INDEX_LOCK.release()
                raise
            except:
                INDEX_LOCK.release()
                raise
        # Let the next thread in
        INDEX_LOCK.release()
        output = with_stderr and (out+err) or out
        if not with_raw_output:
            output = output.rstrip('\n')

        if cola_trace == 'trace':
            msg = 'trace: ' + subprocess.list2cmdline(command)
            Interaction.log_status(status, msg, '')
        elif cola_trace == 'full':
            if output:
                print("%s -> %d: '%s'" % (command, status, output))
            else:
                print("%s -> %d" % (command, status))
        elif cola_trace:
            print(' '.join(command))

        # Allow access to the command's status code
        if with_status:
            return (status, output)
        else:
            return output

    def transform_kwargs(self, **kwargs):
Example #53
0
 def do(self):
     status, out, err = self.model.git.rebase('--continue')
     Interaction.log_status(status, out, err)
     self.model.update_status()
Example #54
0
 def do(self):
     msg = 'Unstaging: %s' % (', '.join(self.paths))
     Interaction.log(msg)
     self.model.unstage_paths(self.paths)
Example #55
0
 def do(self):
     status, out, err = self.model.git.rebase(abort=True)
     Interaction.log_status(status, out, err)
     self.model.update_status()
Example #56
0
    def do(self):
        for env in ('FILENAME', 'REVISION', 'ARGS'):
            try:
                compat.unsetenv(env)
            except KeyError:
                pass
        rev = None
        args = None
        opts = _config.get_guitool_opts(self.action_name)
        cmd = opts.get('cmd')
        if 'title' not in opts:
            opts['title'] = cmd

        if 'prompt' not in opts or opts.get('prompt') is True:
            prompt = N_('Run "%s"?') % cmd
            opts['prompt'] = prompt

        if opts.get('needsfile'):
            filename = selection.filename()
            if not filename:
                Interaction.information(
                    N_('Please select a file'),
                    N_('"%s" requires a selected file.') % cmd)
                return False
            compat.setenv('FILENAME', filename)

        if opts.get('revprompt') or opts.get('argprompt'):
            while True:
                ok = Interaction.confirm_config_action(cmd, opts)
                if not ok:
                    return False
                rev = opts.get('revision')
                args = opts.get('args')
                if opts.get('revprompt') and not rev:
                    title = N_('Invalid Revision')
                    msg = N_('The revision expression cannot be empty.')
                    Interaction.critical(title, msg)
                    continue
                break

        elif opts.get('confirm'):
            title = os.path.expandvars(opts.get('title'))
            prompt = os.path.expandvars(opts.get('prompt'))
            if Interaction.question(title, prompt):
                return
        if rev:
            compat.setenv('REVISION', rev)
        if args:
            compat.setenv('ARGS', args)
        title = os.path.expandvars(cmd)
        Interaction.log(N_('Running command: %s') % title)
        cmd = ['sh', '-c', cmd]

        if opts.get('noconsole'):
            status, out, err = core.run_command(cmd)
        else:
            status, out, err = Interaction.run_command(title, cmd)

        Interaction.log_status(status, out and (N_('Output: %s') % out) or '',
                               err and (N_('Errors: %s') % err) or '')

        if not opts.get('norescan'):
            self.model.update_status()
        return status
Example #57
0
    def __init__(self, model, parent=None, settings=None):
        standard.MainWindow.__init__(self, parent)
        self.setAttribute(Qt.WA_MacMetalStyle)

        # Default size; this is thrown out when save/restore is used
        self.model = model
        self.settings = settings
        self.prefs_model = prefs_model = prefs.PreferencesModel()

        # The widget version is used by import/export_state().
        # Change this whenever dockwidgets are removed.
        self.widget_version = 2

        # Keeps track of merge messages we've seen
        self.merge_message_hash = ''

        # Runs asynchronous tasks
        self.task_runner = TaskRunner(self)
        self.progress = standard.ProgressDialog('', '', self)

        cfg = gitcfg.current()
        self.browser_dockable = (cfg.get('cola.browserdockable') or
                                 cfg.get('cola.classicdockable'))
        if self.browser_dockable:
            self.browserdockwidget = create_dock(N_('Browser'), self)
            self.browserwidget = browse.worktree_browser_widget(self)
            self.browserdockwidget.setWidget(self.browserwidget)

        # "Actions" widget
        self.actionsdockwidget = create_dock(N_('Actions'), self)
        self.actionsdockwidgetcontents = action.ActionButtons(self)
        self.actionsdockwidget.setWidget(self.actionsdockwidgetcontents)
        self.actionsdockwidget.toggleViewAction().setChecked(False)
        self.actionsdockwidget.hide()

        # "Repository Status" widget
        self.statusdockwidget = create_dock(N_('Status'), self)
        titlebar = self.statusdockwidget.titleBarWidget()
        self.statuswidget = status.StatusWidget(titlebar,
                                                parent=self.statusdockwidget)
        self.statusdockwidget.setWidget(self.statuswidget)

        # "Switch Repository" widgets
        self.bookmarksdockwidget = create_dock(N_('Favorites'), self)
        self.bookmarkswidget = bookmarks.BookmarksWidget(
                bookmarks.BOOKMARKS, parent=self.bookmarksdockwidget)
        self.bookmarksdockwidget.setWidget(self.bookmarkswidget)

        self.recentdockwidget = create_dock(N_('Recent'), self)
        self.recentwidget = bookmarks.BookmarksWidget(
                bookmarks.RECENT_REPOS, parent=self.recentdockwidget)
        self.recentdockwidget.setWidget(self.recentwidget)
        self.recentdockwidget.hide()

        # "Commit Message Editor" widget
        self.position_label = QtGui.QLabel()
        font = qtutils.default_monospace_font()
        font.setPointSize(int(font.pointSize() * 0.8))
        self.position_label.setFont(font)

        # make the position label fixed size to avoid layout issues
        fm = self.position_label.fontMetrics()
        width = fm.width('999:999')
        height = self.position_label.sizeHint().height()
        self.position_label.setFixedSize(width, height)

        self.commitdockwidget = create_dock(N_('Commit'), self)
        titlebar = self.commitdockwidget.titleBarWidget()
        titlebar.add_corner_widget(self.position_label)

        self.commitmsgeditor = commitmsg.CommitMessageEditor(model, self)
        self.commitdockwidget.setWidget(self.commitmsgeditor)

        # "Console" widget
        self.logwidget = log.LogWidget()
        self.logdockwidget = create_dock(N_('Console'), self)
        self.logdockwidget.setWidget(self.logwidget)
        self.logdockwidget.toggleViewAction().setChecked(False)
        self.logdockwidget.hide()

        # "Diff Viewer" widget
        self.diffdockwidget = create_dock(N_('Diff'), self)
        self.diffeditorwidget = diff.DiffEditorWidget(self.diffdockwidget)
        self.diffeditor = self.diffeditorwidget.editor
        self.diffdockwidget.setWidget(self.diffeditorwidget)

        # All Actions
        self.unstage_all_action = add_action(self,
                N_('Unstage All'), cmds.run(cmds.UnstageAll))
        self.unstage_all_action.setIcon(qtutils.icon('remove.svg'))

        self.unstage_selected_action = add_action(self,
                N_('Unstage From Commit'), cmds.run(cmds.UnstageSelected))
        self.unstage_selected_action.setIcon(qtutils.icon('remove.svg'))

        self.show_diffstat_action = add_action(self,
                N_('Diffstat'), cmds.run(cmds.Diffstat), 'Alt+D')

        self.stage_modified_action = add_action(self,
                N_('Stage Changed Files To Commit'),
                cmds.run(cmds.StageModified), 'Alt+A')
        self.stage_modified_action.setIcon(qtutils.icon('add.svg'))

        self.stage_untracked_action = add_action(self,
                N_('Stage All Untracked'),
                cmds.run(cmds.StageUntracked), 'Alt+U')
        self.stage_untracked_action.setIcon(qtutils.icon('add.svg'))

        self.apply_patches_action = add_action(self,
                N_('Apply Patches...'), patch.apply_patches)

        self.export_patches_action = add_action(self,
                N_('Export Patches...'), guicmds.export_patches, 'Alt+E')

        self.new_repository_action = add_action(self,
                N_('New Repository...'), guicmds.open_new_repo)
        self.new_repository_action.setIcon(qtutils.new_icon())

        self.preferences_action = add_action(self,
                N_('Preferences'), self.preferences,
                QtGui.QKeySequence.Preferences)

        self.edit_remotes_action = add_action(self,
                N_('Edit Remotes...'), lambda: editremotes.remote_editor().exec_())

        self.rescan_action = add_action(self,
                cmds.Refresh.name(),
                cmds.run(cmds.Refresh),
                *cmds.Refresh.SHORTCUTS)
        self.rescan_action.setIcon(qtutils.reload_icon())

        self.find_files_action = add_action(self,
                N_('Find Files'), finder.finder, 'Ctrl+T', 'T')
        self.find_files_action.setIcon(qtutils.theme_icon('zoom-in.png'))

        self.browse_recently_modified_action = add_action(self,
                N_('Recently Modified Files...'),
                recent.browse_recent_files, 'Shift+Ctrl+E')

        self.cherry_pick_action = add_action(self,
                N_('Cherry-Pick...'),
                guicmds.cherry_pick, 'Shift+Ctrl+C')

        self.load_commitmsg_action = add_action(self,
                N_('Load Commit Message...'), guicmds.load_commitmsg)

        self.save_tarball_action = add_action(self,
                N_('Save As Tarball/Zip...'), self.save_archive)

        self.quit_action = add_action(self,
                N_('Quit'), self.close, 'Ctrl+Q')
        self.grep_action = add_action(self,
                N_('Grep'), grep.grep, 'Ctrl+G')
        self.merge_local_action = add_action(self,
                N_('Merge...'), merge.local_merge, 'Shift+Ctrl+M')

        self.merge_abort_action = add_action(self,
                N_('Abort Merge...'), merge.abort_merge)

        self.fetch_action = add_action(self,
                N_('Fetch...'), remote.fetch, 'Ctrl+F')
        self.push_action = add_action(self,
                N_('Push...'), remote.push, 'Ctrl+P')
        self.pull_action = add_action(self,
                N_('Pull...'), remote.pull, 'Shift+Ctrl+P')

        self.open_repo_action = add_action(self,
                N_('Open...'), guicmds.open_repo)
        self.open_repo_action.setIcon(qtutils.open_icon())

        self.open_repo_new_action = add_action(self,
                N_('Open in New Window...'), guicmds.open_repo_in_new_window)
        self.open_repo_new_action.setIcon(qtutils.open_icon())

        self.stash_action = add_action(self,
                N_('Stash...'), stash.stash, 'Alt+Shift+S')

        self.clone_repo_action = add_action(self,
                N_('Clone...'), self.clone_repo)
        self.clone_repo_action.setIcon(qtutils.git_icon())

        self.help_docs_action = add_action(self,
                N_('Documentation'), resources.show_html_docs,
                QtGui.QKeySequence.HelpContents)

        self.help_shortcuts_action = add_action(self,
                N_('Keyboard Shortcuts'), about.show_shortcuts,
                Qt.Key_Question)

        self.visualize_current_action = add_action(self,
                N_('Visualize Current Branch...'),
                cmds.run(cmds.VisualizeCurrent))
        self.visualize_all_action = add_action(self,
                N_('Visualize All Branches...'),
                cmds.run(cmds.VisualizeAll))
        self.search_commits_action = add_action(self,
                N_('Search...'), search.search)
        self.browse_branch_action = add_action(self,
                N_('Browse Current Branch...'), guicmds.browse_current)
        self.browse_other_branch_action = add_action(self,
                N_('Browse Other Branch...'), guicmds.browse_other)
        self.load_commitmsg_template_action = add_action(self,
                N_('Get Commit Message Template'),
                cmds.run(cmds.LoadCommitMessageFromTemplate))
        self.help_about_action = add_action(self,
                N_('About'), about.launch_about_dialog)

        self.diff_expression_action = add_action(self,
                N_('Expression...'), guicmds.diff_expression)
        self.branch_compare_action = add_action(self,
                N_('Branches...'), compare.compare_branches)

        self.create_tag_action = add_action(self,
                N_('Create Tag...'), createtag.create_tag)

        self.create_branch_action = add_action(self,
                N_('Create...'), createbranch.create_new_branch, 'Ctrl+B')

        self.delete_branch_action = add_action(self,
                N_('Delete...'), guicmds.delete_branch)

        self.delete_remote_branch_action = add_action(self,
                N_('Delete Remote Branch...'), guicmds.delete_remote_branch)

        self.rename_branch_action = add_action(self,
                N_('Rename Branch...'), guicmds.rename_branch)

        self.checkout_branch_action = add_action(self,
                N_('Checkout...'), guicmds.checkout_branch, 'Alt+B')
        self.branch_review_action = add_action(self,
                N_('Review...'), guicmds.review_branch)

        self.browse_action = add_action(self,
                N_('File Browser...'), browse.worktree_browser)
        self.browse_action.setIcon(qtutils.git_icon())

        self.dag_action = add_action(self, N_('DAG...'), self.git_dag)
        self.dag_action.setIcon(qtutils.git_icon())

        self.rebase_start_action = add_action(self,
                N_('Start Interactive Rebase...'), self.rebase_start)

        self.rebase_edit_todo_action = add_action(self,
                N_('Edit...'), self.rebase_edit_todo)

        self.rebase_continue_action = add_action(self,
                N_('Continue'), self.rebase_continue)

        self.rebase_skip_action = add_action(self,
                N_('Skip Current Patch'), self.rebase_skip)

        self.rebase_abort_action = add_action(self,
                N_('Abort'), self.rebase_abort)

        # Relayed actions
        status_tree = self.statusdockwidget.widget().tree
        self.addAction(status_tree.delete_untracked_files_action)

        if not self.browser_dockable:
            # These shortcuts conflict with those from the
            # 'Browser' widget so don't register them when
            # the browser is a dockable tool.
            self.addAction(status_tree.revert_unstaged_edits_action)
            self.addAction(status_tree.revert_uncommitted_edits_action)
            self.addAction(status_tree.up_action)
            self.addAction(status_tree.down_action)
            self.addAction(status_tree.process_selection_action)

        self.lock_layout_action = add_action_bool(self,
                N_('Lock Layout'), self.set_lock_layout, False)

        # Create the application menu
        self.menubar = QtGui.QMenuBar(self)

        # File Menu
        self.file_menu = create_menu(N_('File'), self.menubar)
        self.file_menu.addAction(self.new_repository_action)
        self.open_recent_menu = self.file_menu.addMenu(N_('Open Recent'))
        self.open_recent_menu.setIcon(qtutils.open_icon())
        self.file_menu.addAction(self.open_repo_action)
        self.file_menu.addAction(self.open_repo_new_action)
        self.file_menu.addAction(self.clone_repo_action)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.rescan_action)
        self.file_menu.addAction(self.find_files_action)
        self.file_menu.addAction(self.edit_remotes_action)
        self.file_menu.addAction(self.browse_recently_modified_action)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.load_commitmsg_action)
        self.file_menu.addAction(self.load_commitmsg_template_action)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.apply_patches_action)
        self.file_menu.addAction(self.export_patches_action)
        self.file_menu.addAction(self.save_tarball_action)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.preferences_action)
        self.file_menu.addAction(self.quit_action)
        self.menubar.addAction(self.file_menu.menuAction())

        # Actions menu
        self.actions_menu = create_menu(N_('Actions'), self.menubar)
        self.actions_menu.addAction(self.fetch_action)
        self.actions_menu.addAction(self.push_action)
        self.actions_menu.addAction(self.pull_action)
        self.actions_menu.addAction(self.stash_action)
        self.actions_menu.addSeparator()
        self.actions_menu.addAction(self.create_tag_action)
        self.actions_menu.addAction(self.cherry_pick_action)
        self.actions_menu.addAction(self.merge_local_action)
        self.actions_menu.addAction(self.merge_abort_action)
        self.actions_menu.addSeparator()
        self.actions_menu.addAction(self.grep_action)
        self.actions_menu.addAction(self.search_commits_action)
        self.menubar.addAction(self.actions_menu.menuAction())

        # Staging Area Menu
        self.commit_menu = create_menu(N_('Staging Area'), self.menubar)
        self.commit_menu.setTitle(N_('Staging Area'))
        self.commit_menu.addAction(self.stage_modified_action)
        self.commit_menu.addAction(self.stage_untracked_action)
        self.commit_menu.addSeparator()
        self.commit_menu.addAction(self.unstage_all_action)
        self.commit_menu.addAction(self.unstage_selected_action)
        self.menubar.addAction(self.commit_menu.menuAction())

        # Diff Menu
        self.diff_menu = create_menu(N_('Diff'), self.menubar)
        self.diff_menu.addAction(self.diff_expression_action)
        self.diff_menu.addAction(self.branch_compare_action)
        self.diff_menu.addSeparator()
        self.diff_menu.addAction(self.show_diffstat_action)
        self.menubar.addAction(self.diff_menu.menuAction())

        # Branch Menu
        self.branch_menu = create_menu(N_('Branch'), self.menubar)
        self.branch_menu.addAction(self.branch_review_action)
        self.branch_menu.addSeparator()
        self.branch_menu.addAction(self.create_branch_action)
        self.branch_menu.addAction(self.checkout_branch_action)
        self.branch_menu.addAction(self.delete_branch_action)
        self.branch_menu.addAction(self.delete_remote_branch_action)
        self.branch_menu.addAction(self.rename_branch_action)
        self.branch_menu.addSeparator()
        self.branch_menu.addAction(self.browse_branch_action)
        self.branch_menu.addAction(self.browse_other_branch_action)
        self.branch_menu.addSeparator()
        self.branch_menu.addAction(self.visualize_current_action)
        self.branch_menu.addAction(self.visualize_all_action)
        self.menubar.addAction(self.branch_menu.menuAction())

        # Rebase menu
        self.rebase_menu = create_menu(N_('Rebase'), self.actions_menu)
        self.rebase_menu.addAction(self.rebase_start_action)
        self.rebase_menu.addAction(self.rebase_edit_todo_action)
        self.rebase_menu.addSeparator()
        self.rebase_menu.addAction(self.rebase_continue_action)
        self.rebase_menu.addAction(self.rebase_skip_action)
        self.rebase_menu.addSeparator()
        self.rebase_menu.addAction(self.rebase_abort_action)
        self.menubar.addAction(self.rebase_menu.menuAction())

        # View Menu
        self.view_menu = create_menu(N_('View'), self.menubar)
        self.view_menu.addAction(self.browse_action)
        self.view_menu.addAction(self.dag_action)
        self.view_menu.addSeparator()
        if self.browser_dockable:
            self.view_menu.addAction(self.browserdockwidget.toggleViewAction())

        self.setup_dockwidget_view_menu()
        self.view_menu.addSeparator()
        self.view_menu.addAction(self.lock_layout_action)
        self.menubar.addAction(self.view_menu.menuAction())

        # Help Menu
        self.help_menu = create_menu(N_('Help'), self.menubar)
        self.help_menu.addAction(self.help_docs_action)
        self.help_menu.addAction(self.help_shortcuts_action)
        self.help_menu.addAction(self.help_about_action)
        self.menubar.addAction(self.help_menu.menuAction())

        # Set main menu
        self.setMenuBar(self.menubar)

        # Arrange dock widgets
        left = Qt.LeftDockWidgetArea
        right = Qt.RightDockWidgetArea
        bottom = Qt.BottomDockWidgetArea

        self.addDockWidget(left, self.commitdockwidget)
        if self.browser_dockable:
            self.addDockWidget(left, self.browserdockwidget)
            self.tabifyDockWidget(self.browserdockwidget, self.commitdockwidget)
        self.addDockWidget(left, self.diffdockwidget)
        self.addDockWidget(right, self.statusdockwidget)
        self.addDockWidget(right, self.bookmarksdockwidget)
        self.addDockWidget(right, self.recentdockwidget)
        self.addDockWidget(bottom, self.actionsdockwidget)
        self.addDockWidget(bottom, self.logdockwidget)
        self.tabifyDockWidget(self.actionsdockwidget, self.logdockwidget)


        # Listen for model notifications
        model.add_observer(model.message_updated, self._update)
        model.add_observer(model.message_mode_changed, lambda x: self._update())

        prefs_model.add_observer(prefs_model.message_config_updated,
                                 self._config_updated)

        # Set a default value
        self.show_cursor_position(1, 0)

        self.connect(self.open_recent_menu, SIGNAL('aboutToShow()'),
                     self.build_recent_menu)

        self.connect(self.commitmsgeditor, SIGNAL('cursorPosition(int,int)'),
                     self.show_cursor_position)

        self.connect(self.diffeditor, SIGNAL('diff_options_updated()'),
                     self.statuswidget.refresh)

        self.connect(self, SIGNAL('update'), self._update_callback)
        self.connect(self, SIGNAL('install_config_actions'),
                     self._install_config_actions)

        # Install .git-config-defined actions
        self._config_task = None
        self.install_config_actions()

        # Restore saved settings
        if not self.restore_state(settings=settings):
            self.resize(987, 610)
            self.set_initial_size()

        self.statusdockwidget.widget().setFocus()

        # Route command output here
        Interaction.log_status = self.logwidget.log_status
        Interaction.log = self.logwidget.log
        Interaction.log(version.git_version_str() + '\n' +
                        N_('git cola version %s') % version.version())
Example #58
0
    def __init__(self, model, parent=None, settings=None):
        standard.MainWindow.__init__(self, parent)
        self.setAttribute(Qt.WA_MacMetalStyle)

        # Default size; this is thrown out when save/restore is used
        self.model = model
        self.settings = settings
        self.prefs_model = prefs_model = prefs.PreferencesModel()

        # The widget version is used by import/export_state().
        # Change this whenever dockwidgets are removed.
        self.widget_version = 2

        # Runs asynchronous tasks
        self.runtask = qtutils.RunTask()
        self.progress = standard.ProgressDialog('', '', self)

        create_dock = qtutils.create_dock
        cfg = gitcfg.current()
        self.browser_dockable = (cfg.get('cola.browserdockable')
                                 or cfg.get('cola.classicdockable'))
        if self.browser_dockable:
            self.browserdockwidget = create_dock(N_('Browser'), self)
            self.browserwidget = browse.worktree_browser_widget(self)
            self.browserdockwidget.setWidget(self.browserwidget)

        # "Actions" widget
        self.actionsdockwidget = create_dock(N_('Actions'), self)
        self.actionsdockwidgetcontents = action.ActionButtons(self)
        self.actionsdockwidget.setWidget(self.actionsdockwidgetcontents)
        self.actionsdockwidget.toggleViewAction().setChecked(False)
        self.actionsdockwidget.hide()

        # "Repository Status" widget
        self.statusdockwidget = create_dock(N_('Status'), self)
        titlebar = self.statusdockwidget.titleBarWidget()
        self.statuswidget = status.StatusWidget(titlebar,
                                                parent=self.statusdockwidget)
        self.statusdockwidget.setWidget(self.statuswidget)

        # "Switch Repository" widgets
        self.bookmarksdockwidget = create_dock(N_('Favorites'), self)
        self.bookmarkswidget = bookmarks.BookmarksWidget(
            bookmarks.BOOKMARKS, parent=self.bookmarksdockwidget)
        self.bookmarksdockwidget.setWidget(self.bookmarkswidget)

        self.recentdockwidget = create_dock(N_('Recent'), self)
        self.recentwidget = bookmarks.BookmarksWidget(
            bookmarks.RECENT_REPOS, parent=self.recentdockwidget)
        self.recentdockwidget.setWidget(self.recentwidget)
        self.recentdockwidget.hide()

        # "Commit Message Editor" widget
        self.position_label = QtGui.QLabel()
        self.position_label.setAlignment(Qt.AlignCenter)
        font = qtutils.default_monospace_font()
        font.setPointSize(int(font.pointSize() * 0.8))
        self.position_label.setFont(font)

        # make the position label fixed size to avoid layout issues
        fm = self.position_label.fontMetrics()
        width = fm.width('99:999') + defs.spacing
        self.position_label.setMinimumWidth(width)

        self.commitdockwidget = create_dock(N_('Commit'), self)
        titlebar = self.commitdockwidget.titleBarWidget()
        titlebar.add_corner_widget(self.position_label)

        self.commitmsgeditor = commitmsg.CommitMessageEditor(model, self)
        self.commitdockwidget.setWidget(self.commitmsgeditor)

        # "Console" widget
        self.logwidget = log.LogWidget()
        self.logdockwidget = create_dock(N_('Console'), self)
        self.logdockwidget.setWidget(self.logwidget)
        self.logdockwidget.toggleViewAction().setChecked(False)
        self.logdockwidget.hide()

        # "Diff Viewer" widget
        self.diffdockwidget = create_dock(N_('Diff'), self)
        self.diffeditorwidget = diff.DiffEditorWidget(self.diffdockwidget)
        self.diffeditor = self.diffeditorwidget.editor
        self.diffdockwidget.setWidget(self.diffeditorwidget)

        # All Actions
        add_action = qtutils.add_action
        self.unstage_all_action = add_action(self, N_('Unstage All'),
                                             cmds.run(cmds.UnstageAll))
        self.unstage_all_action.setIcon(icons.remove())

        self.unstage_selected_action = add_action(
            self, N_('Unstage From Commit'), cmds.run(cmds.UnstageSelected))
        self.unstage_selected_action.setIcon(icons.remove())

        self.show_diffstat_action = add_action(self, N_('Diffstat'),
                                               cmds.run(cmds.Diffstat),
                                               hotkeys.DIFFSTAT)

        self.stage_modified_action = add_action(
            self, N_('Stage Changed Files To Commit'),
            cmds.run(cmds.StageModified), hotkeys.STAGE_MODIFIED)
        self.stage_modified_action.setIcon(icons.add())

        self.stage_untracked_action = add_action(self,
                                                 N_('Stage All Untracked'),
                                                 cmds.run(cmds.StageUntracked),
                                                 hotkeys.STAGE_UNTRACKED)
        self.stage_untracked_action.setIcon(icons.add())

        self.apply_patches_action = add_action(self, N_('Apply Patches...'),
                                               patch.apply_patches)

        self.export_patches_action = add_action(self, N_('Export Patches...'),
                                                guicmds.export_patches,
                                                hotkeys.EXPORT)

        self.new_repository_action = add_action(self, N_('New Repository...'),
                                                guicmds.open_new_repo)
        self.new_repository_action.setIcon(icons.new())

        self.preferences_action = add_action(self, N_('Preferences'),
                                             self.preferences,
                                             QtGui.QKeySequence.Preferences)

        self.edit_remotes_action = add_action(
            self, N_('Edit Remotes...'),
            lambda: editremotes.remote_editor().exec_())

        self.rescan_action = add_action(self, cmds.Refresh.name(),
                                        cmds.run(cmds.Refresh),
                                        *hotkeys.REFRESH_HOTKEYS)
        self.rescan_action.setIcon(icons.sync())

        self.find_files_action = add_action(self, N_('Find Files'),
                                            finder.finder, hotkeys.FINDER,
                                            hotkeys.FINDER_SECONDARY)
        self.find_files_action.setIcon(icons.zoom_in())

        self.browse_recently_modified_action = add_action(
            self, N_('Recently Modified Files...'), recent.browse_recent_files,
            hotkeys.EDIT_SECONDARY)

        self.cherry_pick_action = add_action(self, N_('Cherry-Pick...'),
                                             guicmds.cherry_pick,
                                             hotkeys.CHERRY_PICK)

        self.load_commitmsg_action = add_action(self,
                                                N_('Load Commit Message...'),
                                                guicmds.load_commitmsg)

        self.save_tarball_action = add_action(self,
                                              N_('Save As Tarball/Zip...'),
                                              self.save_archive)

        self.quit_action = add_action(self, N_('Quit'), self.close,
                                      hotkeys.QUIT)
        self.grep_action = add_action(self, N_('Grep'), grep.grep,
                                      hotkeys.GREP)
        self.merge_local_action = add_action(self, N_('Merge...'),
                                             merge.local_merge, hotkeys.MERGE)

        self.merge_abort_action = add_action(self, N_('Abort Merge...'),
                                             merge.abort_merge)

        self.fetch_action = add_action(self, N_('Fetch...'), remote.fetch,
                                       hotkeys.FETCH)
        self.push_action = add_action(self, N_('Push...'), remote.push,
                                      hotkeys.PUSH)
        self.pull_action = add_action(self, N_('Pull...'), remote.pull,
                                      hotkeys.PULL)

        self.open_repo_action = add_action(self, N_('Open...'),
                                           guicmds.open_repo, hotkeys.OPEN)
        self.open_repo_action.setIcon(icons.folder())

        self.open_repo_new_action = add_action(self,
                                               N_('Open in New Window...'),
                                               guicmds.open_repo_in_new_window)
        self.open_repo_new_action.setIcon(icons.folder())

        self.stash_action = add_action(self, N_('Stash...'), stash.stash,
                                       hotkeys.STASH)

        self.clone_repo_action = add_action(self, N_('Clone...'),
                                            self.clone_repo)
        self.clone_repo_action.setIcon(icons.repo())

        self.help_docs_action = add_action(self, N_('Documentation'),
                                           resources.show_html_docs,
                                           QtGui.QKeySequence.HelpContents)

        self.help_shortcuts_action = add_action(self, N_('Keyboard Shortcuts'),
                                                about.show_shortcuts,
                                                hotkeys.QUESTION)

        self.visualize_current_action = add_action(
            self, N_('Visualize Current Branch...'),
            cmds.run(cmds.VisualizeCurrent))
        self.visualize_all_action = add_action(self,
                                               N_('Visualize All Branches...'),
                                               cmds.run(cmds.VisualizeAll))
        self.search_commits_action = add_action(self, N_('Search...'),
                                                search.search)
        self.browse_branch_action = add_action(self,
                                               N_('Browse Current Branch...'),
                                               guicmds.browse_current)
        self.browse_other_branch_action = add_action(
            self, N_('Browse Other Branch...'), guicmds.browse_other)
        self.load_commitmsg_template_action = add_action(
            self, N_('Get Commit Message Template'),
            cmds.run(cmds.LoadCommitMessageFromTemplate))
        self.help_about_action = add_action(self, N_('About'),
                                            about.launch_about_dialog)

        self.diff_expression_action = add_action(self, N_('Expression...'),
                                                 guicmds.diff_expression)
        self.branch_compare_action = add_action(self, N_('Branches...'),
                                                compare.compare_branches)

        self.create_tag_action = add_action(
            self, N_('Create Tag...'),
            lambda: createtag.create_tag(settings=settings))

        self.create_branch_action = add_action(
            self, N_('Create...'),
            lambda: createbranch.create_new_branch(settings=settings),
            hotkeys.BRANCH)

        self.delete_branch_action = add_action(self, N_('Delete...'),
                                               guicmds.delete_branch)

        self.delete_remote_branch_action = add_action(
            self, N_('Delete Remote Branch...'), guicmds.delete_remote_branch)

        self.rename_branch_action = add_action(self, N_('Rename Branch...'),
                                               guicmds.rename_branch)

        self.checkout_branch_action = add_action(self, N_('Checkout...'),
                                                 guicmds.checkout_branch,
                                                 hotkeys.CHECKOUT)
        self.branch_review_action = add_action(self, N_('Review...'),
                                               guicmds.review_branch)

        self.browse_action = add_action(self, N_('File Browser...'),
                                        browse.worktree_browser)
        self.browse_action.setIcon(icons.cola())

        self.dag_action = add_action(self, N_('DAG...'), self.git_dag)
        self.dag_action.setIcon(icons.cola())

        self.rebase_start_action = add_action(
            self, N_('Start Interactive Rebase...'), self.rebase_start)

        self.rebase_edit_todo_action = add_action(self, N_('Edit...'),
                                                  self.rebase_edit_todo)

        self.rebase_continue_action = add_action(self, N_('Continue'),
                                                 self.rebase_continue)

        self.rebase_skip_action = add_action(self, N_('Skip Current Patch'),
                                             self.rebase_skip)

        self.rebase_abort_action = add_action(self, N_('Abort'),
                                              self.rebase_abort)

        # For "Start Rebase" only, reverse the first argument to setEnabled()
        # so that we can operate on it as a group.
        # We can do this because can_rebase == not is_rebasing
        set_disabled = lambda x: self.rebase_start_action.setEnabled(not x)
        self.rebase_start_action_proxy = utils.Proxy(self.rebase_start_action,
                                                     setEnabled=set_disabled)

        self.rebase_group = utils.Group(self.rebase_start_action_proxy,
                                        self.rebase_edit_todo_action,
                                        self.rebase_continue_action,
                                        self.rebase_skip_action,
                                        self.rebase_abort_action)

        self.lock_layout_action = qtutils.add_action_bool(
            self, N_('Lock Layout'), self.set_lock_layout, False)

        # Create the application menu
        self.menubar = QtGui.QMenuBar(self)

        # File Menu
        create_menu = qtutils.create_menu
        self.file_menu = create_menu(N_('File'), self.menubar)
        self.file_menu.addAction(self.new_repository_action)
        self.open_recent_menu = self.file_menu.addMenu(N_('Open Recent'))
        self.open_recent_menu.setIcon(icons.folder())
        self.file_menu.addAction(self.open_repo_action)
        self.file_menu.addAction(self.open_repo_new_action)
        self.file_menu.addAction(self.clone_repo_action)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.rescan_action)
        self.file_menu.addAction(self.find_files_action)
        self.file_menu.addAction(self.edit_remotes_action)
        self.file_menu.addAction(self.browse_recently_modified_action)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.load_commitmsg_action)
        self.file_menu.addAction(self.load_commitmsg_template_action)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.apply_patches_action)
        self.file_menu.addAction(self.export_patches_action)
        self.file_menu.addAction(self.save_tarball_action)
        self.file_menu.addSeparator()
        self.file_menu.addAction(self.preferences_action)
        self.file_menu.addAction(self.quit_action)
        self.menubar.addAction(self.file_menu.menuAction())

        # Actions menu
        self.actions_menu = create_menu(N_('Actions'), self.menubar)
        self.actions_menu.addAction(self.fetch_action)
        self.actions_menu.addAction(self.push_action)
        self.actions_menu.addAction(self.pull_action)
        self.actions_menu.addAction(self.stash_action)
        self.actions_menu.addSeparator()
        self.actions_menu.addAction(self.create_tag_action)
        self.actions_menu.addAction(self.cherry_pick_action)
        self.actions_menu.addAction(self.merge_local_action)
        self.actions_menu.addAction(self.merge_abort_action)
        self.actions_menu.addSeparator()
        self.actions_menu.addAction(self.grep_action)
        self.actions_menu.addAction(self.search_commits_action)
        self.menubar.addAction(self.actions_menu.menuAction())

        # Staging Area Menu
        self.commit_menu = create_menu(N_('Staging Area'), self.menubar)
        self.commit_menu.setTitle(N_('Staging Area'))
        self.commit_menu.addAction(self.stage_modified_action)
        self.commit_menu.addAction(self.stage_untracked_action)
        self.commit_menu.addSeparator()
        self.commit_menu.addAction(self.unstage_all_action)
        self.commit_menu.addAction(self.unstage_selected_action)
        self.menubar.addAction(self.commit_menu.menuAction())

        # Diff Menu
        self.diff_menu = create_menu(N_('Diff'), self.menubar)
        self.diff_menu.addAction(self.diff_expression_action)
        self.diff_menu.addAction(self.branch_compare_action)
        self.diff_menu.addSeparator()
        self.diff_menu.addAction(self.show_diffstat_action)
        self.menubar.addAction(self.diff_menu.menuAction())

        # Branch Menu
        self.branch_menu = create_menu(N_('Branch'), self.menubar)
        self.branch_menu.addAction(self.branch_review_action)
        self.branch_menu.addSeparator()
        self.branch_menu.addAction(self.create_branch_action)
        self.branch_menu.addAction(self.checkout_branch_action)
        self.branch_menu.addAction(self.delete_branch_action)
        self.branch_menu.addAction(self.delete_remote_branch_action)
        self.branch_menu.addAction(self.rename_branch_action)
        self.branch_menu.addSeparator()
        self.branch_menu.addAction(self.browse_branch_action)
        self.branch_menu.addAction(self.browse_other_branch_action)
        self.branch_menu.addSeparator()
        self.branch_menu.addAction(self.visualize_current_action)
        self.branch_menu.addAction(self.visualize_all_action)
        self.menubar.addAction(self.branch_menu.menuAction())

        # Rebase menu
        self.rebase_menu = create_menu(N_('Rebase'), self.actions_menu)
        self.rebase_menu.addAction(self.rebase_start_action)
        self.rebase_menu.addAction(self.rebase_edit_todo_action)
        self.rebase_menu.addSeparator()
        self.rebase_menu.addAction(self.rebase_continue_action)
        self.rebase_menu.addAction(self.rebase_skip_action)
        self.rebase_menu.addSeparator()
        self.rebase_menu.addAction(self.rebase_abort_action)
        self.menubar.addAction(self.rebase_menu.menuAction())

        # View Menu
        self.view_menu = create_menu(N_('View'), self.menubar)
        self.view_menu.addAction(self.browse_action)
        self.view_menu.addAction(self.dag_action)
        self.view_menu.addSeparator()
        if self.browser_dockable:
            self.view_menu.addAction(self.browserdockwidget.toggleViewAction())

        self.setup_dockwidget_view_menu()
        self.view_menu.addSeparator()
        self.view_menu.addAction(self.lock_layout_action)
        self.menubar.addAction(self.view_menu.menuAction())

        # Help Menu
        self.help_menu = create_menu(N_('Help'), self.menubar)
        self.help_menu.addAction(self.help_docs_action)
        self.help_menu.addAction(self.help_shortcuts_action)
        self.help_menu.addAction(self.help_about_action)
        self.menubar.addAction(self.help_menu.menuAction())

        # Set main menu
        self.setMenuBar(self.menubar)

        # Arrange dock widgets
        left = Qt.LeftDockWidgetArea
        right = Qt.RightDockWidgetArea
        bottom = Qt.BottomDockWidgetArea

        self.addDockWidget(left, self.commitdockwidget)
        if self.browser_dockable:
            self.addDockWidget(left, self.browserdockwidget)
            self.tabifyDockWidget(self.browserdockwidget,
                                  self.commitdockwidget)
        self.addDockWidget(left, self.diffdockwidget)
        self.addDockWidget(right, self.statusdockwidget)
        self.addDockWidget(right, self.bookmarksdockwidget)
        self.addDockWidget(right, self.recentdockwidget)
        self.addDockWidget(bottom, self.actionsdockwidget)
        self.addDockWidget(bottom, self.logdockwidget)
        self.tabifyDockWidget(self.actionsdockwidget, self.logdockwidget)

        # Listen for model notifications
        model.add_observer(model.message_updated, self._update)
        model.add_observer(model.message_mode_changed,
                           lambda x: self._update())

        prefs_model.add_observer(prefs_model.message_config_updated,
                                 self._config_updated)

        # Set a default value
        self.show_cursor_position(1, 0)

        self.connect(self.open_recent_menu, SIGNAL('aboutToShow()'),
                     self.build_recent_menu)

        self.connect(self.commitmsgeditor, SIGNAL('cursorPosition(int,int)'),
                     self.show_cursor_position)

        self.connect(self.diffeditor, SIGNAL('diff_options_updated()'),
                     self.statuswidget.refresh)

        self.connect(self.diffeditor, SIGNAL('move_down()'),
                     self.statuswidget.move_down)

        self.connect(self.diffeditor, SIGNAL('move_up()'),
                     self.statuswidget.move_up)

        self.connect(self.commitmsgeditor, SIGNAL('move_down()'),
                     self.statuswidget.move_down)

        self.connect(self.commitmsgeditor, SIGNAL('move_up()'),
                     self.statuswidget.move_up)

        self.connect(self, SIGNAL('update()'), self._update_callback,
                     Qt.QueuedConnection)

        self.connect(self, SIGNAL('install_cfg_actions(PyQt_PyObject)'),
                     self._install_config_actions, Qt.QueuedConnection)

        # Install .git-config-defined actions
        self.init_config_actions()

        # Restore saved settings
        if not self.restore_state(settings=settings):
            self.resize(987, 610)
            self.set_initial_size()

        self.statusdockwidget.widget().setFocus()

        # Route command output here
        Interaction.log_status = self.logwidget.log_status
        Interaction.log = self.logwidget.log
        Interaction.safe_log = self.logwidget.safe_log
        Interaction.log(version.git_version_str() + '\n' +
                        N_('git cola version %s') % version.version())
Example #59
0
 def do(self):
     status, out, err = gitcmds.format_patchsets(self.to_export, self.revs)
     Interaction.log_status(status, out, err)
Example #60
0
 def export_patch(self):
     revision = self.selected_revision()
     if revision is not None:
         Interaction.log_status(*gitcmds.export_patchset(revision,
                                                         revision))