Example #1
0
 def browse_callback(self):
     paths = QtGui.QFileDialog.getOpenFileNames(self, N_("Choose Path(s)"))
     if not paths:
         return
     filepaths = []
     lenprefix = len(core.getcwd()) + 1
     for path in map(lambda x: ustr(x), paths):
         if not path.startswith(core.getcwd()):
             continue
         filepaths.append(path[lenprefix:])
     query = subprocess.list2cmdline(filepaths)
     self.query.setText(query)
     if query:
         self.search_callback()
Example #2
0
 def open_repo(self):
     self.repodir = self.get_selected_bookmark()
     if not self.repodir:
         self.repodir = qtutils.opendir_dialog(N_('Open Git Repository...'),
                                               core.getcwd())
     if self.repodir:
         self.accept()
Example #3
0
    def test_git_config(self):
        """Test cola.git.config()"""
        self.git('config', 'section.key', 'value')
        model = MainModel(cwd=core.getcwd())
        value = model.git.config('section.key', get=True)

        self.assertEqual(value, (0, 'value', ''))

        #  Test config_set
        model.config_set('section.bool', True)
        value = model.git.config('section.bool', get=True)

        self.assertEqual(value, (0, 'true', ''))
        model.config_set('section.bool', False)

        # Test config_dict
        config_dict = model.config_dict(local=True)

        self.assertEqual(config_dict['section_key'], 'value')
        self.assertEqual(config_dict['section_bool'], False)

        # Test config_dict --global
        global_dict = model.config_dict(local=False)

        self.assertEqual(type(global_dict), dict)
Example #4
0
 def setUp(self, commit=True):
     TmpPathTestCase.setUp(self)
     self.initialize_repo()
     if commit:
         self.commit_files()
     git.instance().set_worktree(core.getcwd())
     gitcfg.instance().reset()
     gitcmds.clear_cache()
Example #5
0
 def setUp(self, commit=True):
     TmpPathTestCase.setUp(self)
     self.initialize_repo()
     if commit:
         self.commit_files()
     git.current().set_worktree(core.getcwd())
     gitcfg.current().reset()
     gitcmds.reset()
Example #6
0
 def commitData(self, session_mgr):
     """Save session data"""
     if self.view is None:
         return
     sid = session_mgr.sessionId()
     skey = session_mgr.sessionKey()
     session_id = '%s_%s' % (sid, skey)
     session = Session(session_id, repo=core.getcwd())
     self.view.save_state(settings=session)
Example #7
0
    def execute(command,
                _cwd=None,
                _decode=True,
                _encoding=None,
                _raw=False,
                _stdin=None,
                _stderr=subprocess.PIPE,
                _stdout=subprocess.PIPE):
        """
        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':
            command = map(replace_carot, command)
            extra['shell'] = True

        # Start the process
        # Guard against thread-unsafe .git/index.lock files
        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
        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:
                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 #8
0
 def add(self):
     path, ok = qtutils.prompt(N_('Path to git repository'),
                               title=N_('Enter Git Repository'),
                               text=core.getcwd())
     if not ok:
         return
     self.settings.bookmarks.append(path)
     self.update_bookmarks()
     self.save()
Example #9
0
def clone_repo(spawn=True):
    """
    Present GUI controls for cloning a repository

    A new cola session is invoked when 'spawn' is True.

    """
    url, ok = qtutils.prompt(N_('Path or URL to clone (Env. $VARS okay)'))
    url = os.path.expandvars(url)
    if not ok or not url:
        return None
    try:
        # Pick a suitable basename by parsing the URL
        newurl = url.replace('\\', '/').rstrip('/')
        default = newurl.rsplit('/', 1)[-1]
        if default == '.git':
            # The end of the URL is /.git, so assume it's a file path
            default = os.path.basename(os.path.dirname(newurl))
        if default.endswith('.git'):
            # The URL points to a bare repo
            default = default[:-4]
        if url == '.':
            # The URL is the current repo
            default = os.path.basename(core.getcwd())
        if not default:
            raise
    except:
        Interaction.information(
                N_('Error Cloning'),
                N_('Could not parse Git URL: "%s"') % url)
        Interaction.log(N_('Could not parse Git URL: "%s"') % url)
        return None

    # Prompt the user for a directory to use as the parent directory
    msg = N_('Select a parent directory for the new clone')
    dirname = qtutils.opendir_dialog(msg, main.model().getcwd())
    if not dirname:
        return None
    count = 1
    destdir = os.path.join(dirname, default)
    olddestdir = destdir
    if core.exists(destdir):
        # An existing path can be specified
        msg = (N_('"%s" already exists, cola will create a new directory') %
               destdir)
        Interaction.information('Directory Exists', msg)

    # Make sure the new destdir doesn't exist
    while core.exists(destdir):
        destdir = olddestdir + str(count)
        count += 1
    if cmds.do(cmds.Clone, url, destdir, spawn=spawn):
        return destdir
    return None
Example #10
0
    def test_git_commit(self):
        """Test running 'git commit' via cola.git"""
        self.write_file('A', 'A')
        self.write_file('B', 'B')
        self.git('add', 'A', 'B')

        model = MainModel(cwd=core.getcwd())
        model.git.commit(m='commit test')
        log = self.git('log', '--pretty=oneline')

        self.assertEqual(len(log.splitlines()), 1)
Example #11
0
File: main.py Project: pwr/git-cola
    def _update_callback(self):
        """Update the title with the current branch and directory name."""
        alerts = []
        branch = self.model.currentbranch
        curdir = core.getcwd()
        is_merging = self.model.is_merging
        is_rebasing = self.model.is_rebasing

        msg = N_("Repository: %s") % curdir
        msg += "\n"
        msg += N_("Branch: %s") % branch

        if is_rebasing:
            msg += "\n\n"
            msg += N_(
                "This repository is currently being rebased.\n"
                "Resolve conflicts, commit changes, and run:\n"
                "    Rebase > Continue"
            )
            alerts.append(N_("Rebasing"))

        elif is_merging:
            msg += "\n\n"
            msg += N_("This repository is in the middle of a merge.\n" "Resolve conflicts and commit changes.")
            alerts.append(N_("Merging"))

        if self.mode == self.model.mode_amend:
            alerts.append(N_("Amending"))

        l = unichr(0xAB)
        r = unichr(0xBB)
        title = "%s: %s %s%s" % (
            self.model.project,
            branch,
            alerts and ((r + " %s " + l + " ") % ", ".join(alerts)) or "",
            self.model.git.worktree(),
        )

        self.setWindowTitle(title)
        self.commitdockwidget.setToolTip(msg)
        self.commitmsgeditor.set_mode(self.mode)
        self.update_actions()

        if not self.model.amending():
            # Check if there's a message file in .git/
            merge_msg_path = gitcmds.merge_message_path()
            if merge_msg_path is None:
                return
            merge_msg_hash = utils.checksum(merge_msg_path)
            if merge_msg_hash == self.merge_message_hash:
                return
            self.merge_message_hash = merge_msg_hash
            cmds.do(cmds.LoadCommitMessageFromFile, merge_msg_path)
Example #12
0
    def _updated_callback(self):
        branch = self.model.currentbranch
        curdir = core.getcwd()
        msg = N_("Repository: %s") % curdir
        msg += "\n"
        msg += N_("Branch: %s") % branch
        self.setToolTip(msg)

        title = N_("%(project)s: %(branch)s - Browse") % dict(project=self.model.project, branch=branch)
        if self.mode == self.model.mode_amend:
            title += " %s" % N_("(Amending)")
        self.setWindowTitle(title)
Example #13
0
    def _updated_callback(self):
        branch = self.model.currentbranch
        curdir = core.getcwd()
        msg = N_('Repository: %s') % curdir
        msg += '\n'
        msg += N_('Branch: %s') % branch
        self.setToolTip(msg)

        title = N_('%(project)s: %(branch)s - Browse') % dict(project=self.model.project, branch=branch)
        if self.mode == self.model.mode_amend:
            title += ' %s' % N_('(Amending)')
        self.setWindowTitle(title)
Example #14
0
 def setUp(self):
     TmpPathTestCase.setUp(self)
     self.initialize_repo()
     self.context = context = mock.Mock()
     context.git = git.create()
     context.git.set_worktree(core.getcwd())
     context.cfg = gitcfg.create(context)
     context.model = self.model = main.create(self.context)
     self.git = context.git
     self.cfg = context.cfg
     self.cfg.reset()
     gitcmds.reset()
Example #15
0
    def test_git_commit(self):
        """Test running 'git commit' via cola.git"""
        self.shell("""
            echo A > A
            echo B > B
            git add A B
            """)

        model = MainModel(cwd=core.getcwd())
        model.git.commit(m='commit test')
        log = helper.pipe('git log --pretty=oneline | wc -l')

        self.assertEqual(log.strip(), '1')
Example #16
0
 def add_bookmark(self):
     path, ok = qtutils.prompt(N_('Path to git repository'),
                               title=N_('Enter Git Repository'),
                               text=core.getcwd())
     if not ok:
         return
     normpath = utils.expandpath(path)
     if git.is_git_worktree(normpath):
         self.settings.add_bookmark(normpath)
         self.settings.save()
         self.refresh()
     else:
         qtutils.critical(N_('Error'),
                          N_('%s is not a Git repository.') % path)
Example #17
0
def add_common_arguments(parser):
    # We also accept 'git cola version'
    parser.add_argument("--version", default=False, action="store_true", help="print version number")

    # Specifies a git repository to open
    parser.add_argument(
        "-r", "--repo", metavar="<repo>", default=core.getcwd(), help="open the specified git repository"
    )

    # Specifies that we should prompt for a repository at startup
    parser.add_argument("--prompt", action="store_true", default=False, help="prompt for a repository")

    # Resume an X Session Management session
    parser.add_argument("-session", metavar="<session>", default=None, help=argparse.SUPPRESS)
Example #18
0
def add_common_arguments(parser):
    # We also accept 'git cola version'
    parser.add_argument('--version', default=False, action='store_true',
                        help='print version number')

    # Specifies a git repository to open
    parser.add_argument('-r', '--repo', metavar='<repo>', default=core.getcwd(),
                        help='open the specified git repository')

    # Specifies that we should prompt for a repository at startup
    parser.add_argument('--prompt', action='store_true', default=False,
                        help='prompt for a repository')

    # Resume an X Session Management session
    parser.add_argument('-session', metavar='<session>', default=None,
                        help=argparse.SUPPRESS)
Example #19
0
    def _update_callback(self):
        """Update the title with the current branch and directory name."""
        branch = self.model.currentbranch
        curdir = core.getcwd()
        is_rebasing = self.model.is_rebasing

        msg = N_('Repository: %s') % curdir
        msg += '\n'
        msg += N_('Branch: %s') % branch
        if is_rebasing:
            msg += '\n\n'
            msg += N_('This repository is currently being rebased.\n'
                      'Resolve conflicts, commit changes, and run:\n'
                      '    Rebase > Continue')
        self.commitdockwidget.setToolTip(msg)

        alerts = []
        if is_rebasing:
            alerts.append(N_('Rebasing').upper())
        if self.mode == self.model.mode_amend:
            alerts.append(N_('Amending').upper())

        l = unichr(0xab)
        r = unichr(0xbb)
        title = ('%s: %s %s%s' % (
                    self.model.project,
                    branch,
                    alerts and ((r+' %s '+l+' ') % ', '.join(alerts)) or '',
                    self.model.git.worktree()))
        self.setWindowTitle(title)
        self.commitmsgeditor.set_mode(self.mode)
        self.update_rebase_actions(is_rebasing)

        if not self.model.amending():
            # Check if there's a message file in .git/
            merge_msg_path = gitcmds.merge_message_path()
            if merge_msg_path is None:
                return
            merge_msg_hash = utils.checksum(merge_msg_path)
            if merge_msg_hash == self.merge_message_hash:
                return
            self.merge_message_hash = merge_msg_hash
            cmds.do(cmds.LoadCommitMessageFromFile, merge_msg_path)
Example #20
0
    def _update_callback(self):
        """Update the title with the current branch and directory name."""
        alerts = []
        branch = self.model.currentbranch
        curdir = core.getcwd()
        is_merging = self.model.is_merging
        is_rebasing = self.model.is_rebasing

        msg = N_("Repository: %s") % curdir
        msg += "\n"
        msg += N_("Branch: %s") % branch

        if is_rebasing:
            msg += "\n\n"
            msg += N_(
                "This repository is currently being rebased.\n"
                "Resolve conflicts, commit changes, and run:\n"
                "    Rebase > Continue"
            )
            alerts.append(N_("Rebasing"))

        elif is_merging:
            msg += "\n\n"
            msg += N_("This repository is in the middle of a merge.\n" "Resolve conflicts and commit changes.")
            alerts.append(N_("Merging"))

        if self.mode == self.model.mode_amend:
            alerts.append(N_("Amending"))

        l = unichr(0xAB)
        r = unichr(0xBB)
        title = "%s: %s %s%s" % (
            self.model.project,
            branch,
            alerts and ((r + " %s " + l + " ") % ", ".join(alerts)) or "",
            self.model.git.worktree(),
        )

        self.setWindowTitle(title)
        self.commitdockwidget.setToolTip(msg)
        self.commitmsgeditor.set_mode(self.mode)
        self.update_actions()
Example #21
0
    def _update_callback(self):
        """Update the title with the current branch and directory name."""
        alerts = []
        branch = self.model.currentbranch
        curdir = core.getcwd()
        is_merging = self.model.is_merging
        is_rebasing = self.model.is_rebasing

        msg = N_('Repository: %s') % curdir
        msg += '\n'
        msg += N_('Branch: %s') % branch

        if is_rebasing:
            msg += '\n\n'
            msg += N_('This repository is currently being rebased.\n'
                      'Resolve conflicts, commit changes, and run:\n'
                      '    Rebase > Continue')
            alerts.append(N_('Rebasing'))

        elif is_merging:
            msg += '\n\n'
            msg += N_('This repository is in the middle of a merge.\n'
                      'Resolve conflicts and commit changes.')
            alerts.append(N_('Merging'))

        if self.mode == self.model.mode_amend:
            alerts.append(N_('Amending'))

        l = unichr(0xab)
        r = unichr(0xbb)
        title = ('%s: %s %s%s' % (
                    self.model.project,
                    branch,
                    alerts and ((r+' %s '+l+' ') % ', '.join(alerts)) or '',
                    self.model.git.worktree()))

        self.setWindowTitle(title)
        self.commitdockwidget.setToolTip(msg)
        self.commitmsgeditor.set_mode(self.mode)
        self.update_actions()
Example #22
0
    def worktree(self):
        if self._worktree:
            return self._worktree
        self.git_dir()
        if self._git_dir:
            curdir = self._git_dir
        else:
            curdir = core.getcwd()

        if is_git_dir(join(curdir, ".git")):
            return curdir

        # Handle bare repositories
        if len(os.path.basename(curdir)) > 4 and curdir.endswith(".git"):
            return curdir
        if "GIT_WORK_TREE" in os.environ:
            self._worktree = core.getenv("GIT_WORK_TREE")
        if not self._worktree or not core.isdir(self._worktree):
            if self._git_dir:
                gitparent = join(core.abspath(self._git_dir), "..")
                self._worktree = core.abspath(gitparent)
                self.set_cwd(self._worktree)
        return self._worktree
Example #23
0
 def git_dir(self):
     if self.is_valid():
         return self._git_dir
     if 'GIT_DIR' in os.environ:
         self._git_dir = core.getenv('GIT_DIR')
     if self._git_dir:
         curpath = core.abspath(self._git_dir)
     else:
         curpath = core.abspath(core.getcwd())
     # Search for a .git directory
     while curpath:
         if is_git_dir(curpath):
             self._git_dir = curpath
             break
         gitpath = join(curpath, '.git')
         if is_git_dir(gitpath):
             self._git_dir = gitpath
             break
         curpath, dummy = os.path.split(curpath)
         if not dummy:
             break
     self._git_file_path = read_git_file(self._git_dir)
     return self._git_dir
Example #24
0
    def __init__(self, ref, shortref=None, parent=None):
        QtGui.QDialog.__init__(self, parent)
        if parent is not None:
            self.setWindowModality(Qt.WindowModal)

        # input
        self.ref = ref
        if shortref is None:
            shortref = ref

        # outputs
        self.fmt = None

        filename = '%s-%s' % (os.path.basename(core.getcwd()), shortref)
        self.prefix = filename + '/'
        self.filename = filename

        # widgets
        self.setWindowTitle(N_('Save Archive'))

        self.filetext = QtGui.QLineEdit()
        self.filetext.setText(self.filename)

        self.browse = QtGui.QToolButton()
        self.browse.setAutoRaise(True)
        style = self.style()
        self.browse.setIcon(style.standardIcon(QtGui.QStyle.SP_DirIcon))

        self.format_strings = (
                git.archive('--list')[STDOUT].rstrip().splitlines())
        self.format_combo = QtGui.QComboBox()
        self.format_combo.setEditable(False)
        self.format_combo.addItems(self.format_strings)

        self.cancel = QtGui.QPushButton()
        self.cancel.setText(N_('Cancel'))

        self.save = QtGui.QPushButton()
        self.save.setText(N_('Save'))
        self.save.setDefault(True)

        self.prefix_label = QtGui.QLabel()
        self.prefix_label.setText(N_('Prefix'))
        self.prefix_text = QtGui.QLineEdit()
        self.prefix_text.setText(self.prefix)

        self.prefix_group = ExpandableGroupBox()
        self.prefix_group.setTitle(N_('Advanced'))

        # layouts
        self.filelayt = qtutils.hbox(defs.no_margin, defs.spacing,
                                     self.browse, self.filetext,
                                     self.format_combo)

        self.prefixlayt = qtutils.hbox(defs.margin, defs.spacing,
                                       self.prefix_label, self.prefix_text)
        self.prefix_group.setLayout(self.prefixlayt)
        self.prefix_group.set_expanded(False)

        self.btnlayt = qtutils.hbox(defs.no_margin, defs.spacing,
                                    qtutils.STRETCH, self.cancel, self.save)

        self.mainlayt = qtutils.vbox(defs.margin, defs.no_spacing,
                                     self.filelayt, self.prefix_group,
                                     qtutils.STRETCH, self.btnlayt)
        self.setLayout(self.mainlayt)
        self.resize(555, 0)

        # initial setup; done before connecting to avoid
        # signal/slot side-effects
        if 'tar.gz' in self.format_strings:
            idx = self.format_strings.index('tar.gz')
        elif 'zip' in self.format_strings:
            idx = self.format_strings.index('zip')
        else:
            idx = 0
        self.format_combo.setCurrentIndex(idx)
        self.update_filetext_for_format(idx)

        # connections
        self.connect(self.filetext, SIGNAL('textChanged(QString)'),
                     self.filetext_changed)

        self.connect(self.prefix_text, SIGNAL('textChanged(QString)'),
                     self.prefix_text_changed)

        self.connect(self.format_combo, SIGNAL('currentIndexChanged(int)'),
                     self.update_filetext_for_format)

        self.connect(self.prefix_group, SIGNAL('expanded(bool)'),
                     self.prefix_group_expanded)

        self.connect(self, SIGNAL('accepted()'), self.archive_saved)

        qtutils.connect_button(self.browse, self.choose_filename)
        qtutils.connect_button(self.cancel, self.reject)
        qtutils.connect_button(self.save, self.save_archive)
Example #25
0
 def getcwd(self):
     """If we've chosen a directory then use it, otherwise use current"""
     if self.directory:
         return self.directory
     return core.getcwd()
Example #26
0
    def __init__(self, parent=None):
        super(ApplyPatches, self).__init__(parent=parent)
        self.setAttribute(Qt.WA_MacMetalStyle)
        self.setWindowTitle(N_('Apply Patches'))
        self.setAcceptDrops(True)
        if parent is not None:
            self.setWindowModality(Qt.WindowModal)

        self.curdir = core.getcwd()
        self.inner_drag = False

        self.usage = QtGui.QLabel()
        self.usage.setText(N_("""
            <p>
                Drag and drop or use the <strong>Add</strong> button to add
                patches to the list
            </p>
            """))

        self.tree = PatchTreeWidget(parent=self)
        self.tree.setHeaderHidden(True)

        self.add_button = qtutils.create_toolbutton(
                text=N_('Add'), icon=icons.add(),
                tooltip=N_('Add patches (+)'))

        self.remove_button = qtutils.create_toolbutton(
                text=N_('Remove'), icon=icons.remove(),
                tooltip=N_('Remove selected (Delete)'))

        self.apply_button = qtutils.create_button(
                text=N_('Apply'), icon=icons.ok())

        self.close_button = qtutils.close_button()

        self.add_action = qtutils.add_action(self,
                N_('Add'), self.add_files, hotkeys.ADD_ITEM)

        self.remove_action = qtutils.add_action(self,
                N_('Remove'), self.tree.remove_selected,
                hotkeys.DELETE, hotkeys.BACKSPACE, hotkeys.REMOVE_ITEM)

        self.top_layout = qtutils.hbox(defs.no_margin, defs.button_spacing,
                                       self.add_button, self.remove_button,
                                       qtutils.STRETCH, self.usage)

        self.bottom_layout = qtutils.hbox(defs.no_margin, defs.button_spacing,
                                          self.apply_button, qtutils.STRETCH,
                                          self.close_button)

        self.main_layout = qtutils.vbox(defs.margin, defs.spacing,
                                        self.top_layout, self.tree,
                                        self.bottom_layout)
        self.setLayout(self.main_layout)

        qtutils.connect_button(self.add_button, self.add_files)
        qtutils.connect_button(self.remove_button, self.tree.remove_selected)
        qtutils.connect_button(self.apply_button, self.apply_patches)
        qtutils.connect_button(self.close_button, self.close)

        if not self.restore_state():
            self.resize(666, 420)
Example #27
0
 def git_dir(self):
     if not self.paths.git_dir:
         path = core.abspath(core.getcwd())
         self._find_git_directory(path)
     return self.paths.git_dir
Example #28
0
 def closeEvent(self, event):
     s = settings.Settings()
     s.add_recent(core.getcwd())
     self.save_state(handler=s)
     self.QtClass.closeEvent(self, event)
Example #29
0
    def __init__(self, parent=None):
        standard.Dialog.__init__(self, parent)
        self.setAttribute(Qt.WA_MacMetalStyle)
        self.setWindowTitle(N_('Find Files'))
        if parent is not None:
            self.setWindowModality(Qt.WindowModal)

        self.input_label = QtGui.QLabel(os.path.basename(core.getcwd()) + '/')
        self.input_txt = completion.GitTrackedLineEdit(hint=N_('<path> ...'))
        self.input_txt.hint.enable(True)

        self.tree = filetree.FileTree(parent=self)

        self.edit_button = qtutils.edit_button()
        self.edit_button.setShortcut(hotkeys.EDIT)

        text = cmds.OpenDefaultApp.name()
        icon = icons.default_app()
        self.open_default_button = qtutils.create_button(text=text, icon=icon)
        self.open_default_button.setShortcut(hotkeys.PRIMARY_ACTION)

        self.button_group = Group(self.edit_button, self.open_default_button)
        self.button_group.setEnabled(False)

        self.refresh_button = qtutils.refresh_button()
        self.refresh_button.setShortcut(hotkeys.REFRESH)

        self.help_button = qtutils.create_button(
            text=N_('Help'),
            tooltip=N_('Show help\nShortcut: ?'),
            icon=icons.question())

        self.close_button = qtutils.close_button()

        self.input_layout = qtutils.hbox(defs.no_margin, defs.button_spacing,
                                         self.input_label, self.input_txt)

        self.bottom_layout = qtutils.hbox(defs.no_margin, defs.button_spacing,
                                          self.edit_button,
                                          self.open_default_button,
                                          self.refresh_button,
                                          self.help_button, qtutils.STRETCH,
                                          self.close_button)

        self.main_layout = qtutils.vbox(defs.margin, defs.no_spacing,
                                        self.input_layout, self.tree,
                                        self.bottom_layout)
        self.setLayout(self.main_layout)
        self.setFocusProxy(self.input_txt)

        self.worker_thread = FindFilesThread(self)
        self.connect(self.worker_thread, SIGNAL('result(PyQt_PyObject)'),
                     self.process_result, Qt.QueuedConnection)

        self.connect(self.input_txt, SIGNAL('textChanged(QString)'),
                     lambda s: self.search())
        self.connect(self.input_txt, SIGNAL('activated()'), self.focus_tree)
        self.connect(self.input_txt, SIGNAL('down()'), self.focus_tree)
        self.connect(self.input_txt, SIGNAL('enter()'), self.focus_tree)
        self.connect(self.input_txt, SIGNAL('return()'), self.focus_tree)

        self.connect(self.tree, SIGNAL('itemSelectionChanged()'),
                     self.tree_item_selection_changed)
        self.connect(self.tree, SIGNAL('up()'), self.focus_input)
        self.connect(self.tree, SIGNAL('space()'), self.open_default)

        qtutils.add_action(self, 'Focus Input', self.focus_input,
                           hotkeys.FOCUS, hotkeys.FINDER)

        self.show_help_action = qtutils.add_action(self, N_('Show Help'),
                                                   show_help, hotkeys.QUESTION)

        qtutils.connect_button(self.edit_button, self.edit)
        qtutils.connect_button(self.open_default_button, self.open_default)
        qtutils.connect_button(self.refresh_button, self.search)
        qtutils.connect_button(self.help_button, show_help)
        qtutils.connect_button(self.close_button, self.close)
        qtutils.add_close_action(self)

        if not self.restore_state():
            width, height = qtutils.default_size(parent, 666, 420)
            self.resize(width, height)
Example #30
0
 def closeEvent(self, event):
     settings = Settings()
     settings.load()
     settings.add_recent(core.getcwd())
     self.save_state(settings=settings)
     self.QtClass.closeEvent(self, event)
Example #31
0
 def __init__(self):
     self._git_cwd = None  #: The working directory used by execute()
     self._worktree = None
     self._git_file_path = None
     self.set_worktree(core.getcwd())
Example #32
0
    def execute(command,
                _cwd=None,
                _decode=True,
                _encoding=None,
                _raw=False,
                _stdin=None,
                _stderr=subprocess.PIPE,
                _stdout=subprocess.PIPE):
        """
        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

        # Start the process
        # Guard against thread-unsafe .git/index.lock files
        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
        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 #33
0
 def setUp(self):
     helper.GitRepositoryTestCase.setUp(self)
     self.model = main.MainModel(cwd=core.getcwd())
Example #34
0
    def __init__(self, ref, shortref=None, parent=None):
        QtGui.QDialog.__init__(self, parent)
        if parent is not None:
            self.setWindowModality(Qt.WindowModal)

        # input
        self.ref = ref
        if shortref is None:
            shortref = ref

        # outputs
        self.fmt = None

        filename = '%s-%s' % (os.path.basename(core.getcwd()), shortref)
        self.prefix = filename + '/'
        self.filename = filename

        # widgets
        self.setWindowTitle(N_('Save Archive'))

        self.filetext = QtGui.QLineEdit()
        self.filetext.setText(self.filename)

        self.browse = qtutils.create_toolbutton(icon=icons.file_zip())

        self.format_strings = (
                git.archive('--list')[STDOUT].rstrip().splitlines())
        self.format_combo = QtGui.QComboBox()
        self.format_combo.setEditable(False)
        self.format_combo.addItems(self.format_strings)

        self.close_button = qtutils.close_button()
        self.save_button = qtutils.create_button(text=N_('Save'),
                                                 icon=icons.save(),
                                                 default=True)
        self.prefix_label = QtGui.QLabel()
        self.prefix_label.setText(N_('Prefix'))
        self.prefix_text = QtGui.QLineEdit()
        self.prefix_text.setText(self.prefix)

        self.prefix_group = ExpandableGroupBox()
        self.prefix_group.setTitle(N_('Advanced'))

        # layouts
        self.filelayt = qtutils.hbox(defs.no_margin, defs.spacing,
                                     self.browse, self.filetext,
                                     self.format_combo)

        self.prefixlayt = qtutils.hbox(defs.margin, defs.spacing,
                                       self.prefix_label, self.prefix_text)
        self.prefix_group.setLayout(self.prefixlayt)
        self.prefix_group.set_expanded(False)

        self.btnlayt = qtutils.hbox(defs.no_margin, defs.spacing,
                                    qtutils.STRETCH, self.close_button,
                                    self.save_button)

        self.mainlayt = qtutils.vbox(defs.margin, defs.no_spacing,
                                     self.filelayt, self.prefix_group,
                                     qtutils.STRETCH, self.btnlayt)
        self.setLayout(self.mainlayt)
        self.resize(defs.scale(520), defs.scale(10))

        # initial setup; done before connecting to avoid
        # signal/slot side-effects
        if 'tar.gz' in self.format_strings:
            idx = self.format_strings.index('tar.gz')
        elif 'zip' in self.format_strings:
            idx = self.format_strings.index('zip')
        else:
            idx = 0
        self.format_combo.setCurrentIndex(idx)
        self.update_filetext_for_format(idx)

        # connections
        self.connect(self.filetext, SIGNAL('textChanged(QString)'),
                     self.filetext_changed)

        self.connect(self.prefix_text, SIGNAL('textChanged(QString)'),
                     self.prefix_text_changed)

        self.connect(self.format_combo, SIGNAL('currentIndexChanged(int)'),
                     self.update_filetext_for_format)

        self.connect(self.prefix_group, SIGNAL('expanded(bool)'),
                     self.prefix_group_expanded)

        self.connect(self, SIGNAL('accepted()'), self.archive_saved)

        qtutils.connect_button(self.browse, self.choose_filename)
        qtutils.connect_button(self.close_button, self.reject)
        qtutils.connect_button(self.save_button, self.save_archive)
Example #35
0
 def __init__(self):
     self._git_cwd = None #: The working directory used by execute()
     self._worktree = None
     self._git_file_path = None
     self.set_worktree(core.getcwd())
Example #36
0
    def __init__(self, parent=None):
        standard.Dialog.__init__(self, parent)
        self.setAttribute(Qt.WA_MacMetalStyle)
        self.setWindowTitle(N_('Find Files'))
        if parent is not None:
            self.setWindowModality(Qt.WindowModal)

        self.input_label = QtGui.QLabel(os.path.basename(core.getcwd()) + '/')
        self.input_txt = completion.GitTrackedLineEdit(hint=N_('<path> ...'))
        self.input_txt.enable_hint(True)

        self.tree = filetree.FileTree(parent=self)

        self.edit_button = QtGui.QPushButton(N_('Edit'))
        self.edit_button.setIcon(qtutils.open_file_icon())
        self.edit_button.setEnabled(False)
        self.edit_button.setShortcut(cmds.Edit.SHORTCUT)

        self.open_default_button = QtGui.QPushButton(
            cmds.OpenDefaultApp.name())
        self.open_default_button.setIcon(qtutils.open_file_icon())
        self.open_default_button.setEnabled(False)
        self.open_default_button.setShortcut(cmds.OpenDefaultApp.SHORTCUT)

        self.refresh_button = QtGui.QPushButton(N_('Refresh'))
        self.refresh_button.setIcon(qtutils.reload_icon())
        self.refresh_button.setShortcut(QtGui.QKeySequence.Refresh)

        self.help_button = qtutils.create_button(
            text=N_('Help'),
            tooltip=N_('Show help\nShortcut: ?'),
            icon=qtutils.help_icon())

        self.close_button = QtGui.QPushButton(N_('Close'))

        self.input_layout = qtutils.hbox(defs.no_margin, defs.button_spacing,
                                         self.input_label, self.input_txt)

        self.bottom_layout = qtutils.hbox(defs.no_margin, defs.button_spacing,
                                          self.edit_button,
                                          self.open_default_button,
                                          self.refresh_button,
                                          self.help_button, qtutils.STRETCH,
                                          self.close_button)

        self.main_layout = qtutils.vbox(defs.margin, defs.no_spacing,
                                        self.input_layout, self.tree,
                                        self.bottom_layout)
        self.setLayout(self.main_layout)
        self.setFocusProxy(self.input_txt)

        self.worker_thread = FindFilesThread(self)
        self.connect(self.worker_thread, SIGNAL('result'), self.process_result)

        self.connect(self.input_txt, SIGNAL('textChanged(QString)'),
                     lambda s: self.search())
        self.connect(self.input_txt, SIGNAL('activated()'), self.focus_tree)
        self.connect(self.input_txt, SIGNAL('down()'), self.focus_tree)
        self.connect(self.input_txt, SIGNAL('enter()'), self.focus_tree)
        self.connect(self.input_txt, SIGNAL('return()'), self.focus_tree)

        self.connect(self.tree, SIGNAL('itemSelectionChanged()'),
                     self.tree_item_selection_changed)
        self.connect(self.tree, SIGNAL('up()'), self.focus_input)
        self.connect(self.tree, SIGNAL('space()'), self.open_default)

        qtutils.add_action(self, 'Focus Input', self.focus_input, 'Ctrl+L',
                           'Ctrl+T')

        self.show_help_action = qtutils.add_action(self, N_('Show Help'),
                                                   show_help, Qt.Key_Question)

        qtutils.connect_button(self.edit_button, self.edit)
        qtutils.connect_button(self.open_default_button, self.open_default)
        qtutils.connect_button(self.refresh_button, self.search)
        qtutils.connect_button(self.help_button, show_help)
        qtutils.connect_button(self.close_button, self.close)
        qtutils.add_close_action(self)

        if not self.restore_state():
            width, height = qtutils.default_size(parent, 666, 420)
            self.resize(width, height)
Example #37
0
 def test_project(self):
     """Test the 'project' attribute."""
     project = os.path.basename(self.test_path())
     self.model.set_worktree(core.getcwd())
     self.assertEqual(self.model.project, project)
Example #38
0
 def setUp(self):
     helper.GitRepositoryTestCase.setUp(self)
     self.model = MainModel(cwd=core.getcwd())
Example #39
0
 def setUp(self):
     helper.GitRepositoryTestCase.setUp(self, commit=False)
     self.model = MainModel(cwd=core.getcwd())
Example #40
0
 def worktree(self):
     if not self.paths.worktree:
         path = core.abspath(core.getcwd())
         self._find_git_directory(path)
     return self.paths.worktree
Example #41
0
    def __init__(self, parent=None):
        super(ApplyPatches, self).__init__(parent=parent)
        self.setAttribute(Qt.WA_MacMetalStyle)
        self.setWindowTitle(N_('Apply Patches'))
        self.setAcceptDrops(True)
        if parent is not None:
            self.setWindowModality(Qt.WindowModal)

        self.curdir = core.getcwd()
        self.inner_drag = False

        self.usage = QtGui.QLabel()
        self.usage.setText(
            N_("""
            <p>
                Drag and drop or use the <strong>Add</strong> button to add
                patches to the list
            </p>
            """))

        self.tree = PatchTreeWidget(parent=self)
        self.tree.setHeaderHidden(True)

        self.add_button = qtutils.create_toolbutton(
            text=N_('Add'),
            icon=qtutils.add_icon(),
            tooltip=N_('Add patches (+)'))

        self.remove_button = qtutils.create_toolbutton(
            text=N_('Remove'),
            icon=qtutils.remove_icon(),
            tooltip=N_('Remove selected (Delete)'))

        self.apply_button = qtutils.create_button(text=N_('Apply'),
                                                  icon=qtutils.apply_icon())

        self.close_button = qtutils.create_button(text=N_('Close'),
                                                  icon=qtutils.close_icon())

        self.add_action = qtutils.add_action(self, N_('Add'), self.add_files,
                                             hotkeys.ADD_ITEM)

        self.remove_action = qtutils.add_action(self, N_('Remove'),
                                                self.tree.remove_selected,
                                                hotkeys.DELETE,
                                                hotkeys.BACKSPACE,
                                                hotkeys.REMOVE_ITEM)

        self.top_layout = qtutils.hbox(defs.no_margin, defs.button_spacing,
                                       self.add_button, self.remove_button,
                                       qtutils.STRETCH, self.usage)

        self.bottom_layout = qtutils.hbox(defs.no_margin, defs.button_spacing,
                                          self.apply_button, qtutils.STRETCH,
                                          self.close_button)

        self.main_layout = qtutils.vbox(defs.margin, defs.spacing,
                                        self.top_layout, self.tree,
                                        self.bottom_layout)
        self.setLayout(self.main_layout)

        qtutils.connect_button(self.add_button, self.add_files)
        qtutils.connect_button(self.remove_button, self.tree.remove_selected)
        qtutils.connect_button(self.apply_button, self.apply_patches)
        qtutils.connect_button(self.close_button, self.close)

        if not self.restore_state():
            self.resize(666, 420)
Example #42
0
    def execute(command,
                _cwd=None,
                _decode=True,
                _encoding=None,
                _raw=False,
                _stdin=None,
                _stderr=subprocess.PIPE,
                _stdout=subprocess.PIPE):
        """
        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

        # Start the process
        # Guard against thread-unsafe .git/index.lock files
        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
        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 #43
0
 def test_git_config(self):
     """Test cola.git.config()"""
     self.git('config', 'section.key', 'value')
     model = MainModel(self.context, cwd=core.getcwd())
     value = model.git.config('section.key', get=True)
     self.assertEqual(value, (0, 'value', ''))
Example #44
0
    def __init__(self):
        self.paths = Paths()

        self._git_cwd = None  #: The working directory used by execute()
        self._valid = {}  #: Store the result of is_git_dir() for performance
        self.set_worktree(core.getcwd())
Example #45
0
 def closeEvent(self, event):
     s = settings.Settings()
     s.add_recent(core.getcwd())
     qtutils.save_state(self, handler=s)
     self.QtClass.closeEvent(self, event)
Example #46
0
 def closeEvent(self, event):
     settings = Settings()
     settings.load()
     settings.add_recent(core.getcwd())
     self.save_state(settings=settings)
     self.QtClass.closeEvent(self, event)
Example #47
0
 def save_settings(self):
     settings = Settings()
     settings.load()
     settings.add_recent(core.getcwd())
     return self.save_state(settings=settings)