Example #1
0
def start():
    global _thread

    cfg = gitcfg.instance()
    if not cfg.get('cola.inotify', True):
        msg = N_('inotify is disabled because "cola.inotify" is false')
        Interaction.log(msg)
        return

    if not AVAILABLE:
        if utils.is_win32():
            msg = N_('file notification: disabled\n'
                     'Note: install pywin32 to enable.\n')
        elif utils.is_linux():
            msg = N_('inotify: disabled\n'
                     'Note: install python-pyinotify to enable inotify.\n')
        else:
            return

        if utils.is_debian():
            msg += N_('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 = N_('File notification enabled.')
    else:
        msg = N_('inotify enabled.')
    Interaction.log(msg)
Example #2
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')
        cola.notifier().broadcast(signals.log_cmd, 0, msg)
        return

    # Start the notification thread
    _thread = GitNotifier()
    _thread.start()
    if utils.is_win32():
        msg = 'file notification: enabled'
    else:
        msg = 'inotify support: enabled'
    cola.notifier().broadcast(signals.log_cmd, 0, msg)
Example #3
0
def start():
    global _thread

    cfg = gitcfg.instance()
    if not cfg.get('cola.inotify', True):
        msg = N_('inotify is disabled because "cola.inotify" is false')
        Interaction.log(msg)
        return

    if not AVAILABLE:
        if utils.is_win32():
            msg = N_('file notification: disabled\n'
                     'Note: install pywin32 to enable.\n')
        elif utils.is_linux():
            msg = N_('inotify: disabled\n'
                     'Note: install python-pyinotify to enable inotify.\n')
        else:
            return

        if utils.is_debian():
            msg += N_('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 = N_('File notification enabled.')
    else:
        msg = N_('inotify enabled.')
    Interaction.log(msg)
Example #4
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')
        cola.notifier().broadcast(signals.log_cmd, 0, msg)
        return

    # Start the notification thread
    _thread = GitNotifier()
    _thread.start()
    if utils.is_win32():
        msg = 'file notification: enabled'
    else:
        msg = 'inotify support: enabled'
    cola.notifier().broadcast(signals.log_cmd, 0, msg)
Example #5
0
    def run(self):
        """Create the inotify WatchManager and generate FileSysEvents"""

        if utils.is_win32():
            self.run_win32()
            return

        # Only capture events that git cares about
        self._wmgr = WatchManager()
        if self._is_pyinotify_08x():
            notifier = Notifier(self._wmgr, FileSysEvent(), timeout=self._timeout)
        else:
            notifier = Notifier(self._wmgr, FileSysEvent())

        self._watch_directory(self._path)

        # Register files/directories known to git
        for filename in core.decode(self._git.ls_files()).splitlines():
            filename = os.path.realpath(filename)
            directory = os.path.dirname(filename)
            self._watch_directory(directory)

        # self._running signals app termination.  The timeout is a tradeoff
        # between fast notification response and waiting too long to exit.
        while self._running:
            if self._is_pyinotify_08x():
                check = notifier.check_events()
            else:
                check = notifier.check_events(timeout=self._timeout)
            if not self._running:
                break
            if check:
                notifier.read_events()
                notifier.process_events()
        notifier.stop()
Example #6
0
    def _create_unmerged_context_menu(self, menu, s):
        menu.addAction(qtutils.git_icon(), self.tr('Launch Merge Tool'),
                       cmds.run(cmds.Mergetool, self.unmerged()))

        action = menu.addAction(qtutils.icon('add.svg'),
                                self.tr('Stage Selected'),
                                cmds.run(cmds.Stage, self.unstaged()))
        action.setShortcut(cmds.Stage.SHORTCUT)
        menu.addSeparator()
        action = menu.addAction(qtutils.options_icon(),
                                self.tr(cmds.LaunchEditor.NAME),
                                cmds.run(cmds.LaunchEditor))
        action.setShortcut(cmds.LaunchEditor.SHORTCUT)

        if not utils.is_win32():
            menu.addSeparator()
            action = menu.addAction(
                qtutils.file_icon(), self.tr(cmds.OpenDefaultApp.NAME),
                cmds.run(cmds.OpenDefaultApp, self.unmerged()))
            action.setShortcut(cmds.OpenDefaultApp.SHORTCUT)

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

        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        return menu
Example #7
0
    def _create_unstaged_context_menu(self, menu, s):
        modified_submodule = (s.modified and
                              s.modified[0] in self.m.submodules)
        if modified_submodule:
            return self._create_modified_submodule_context_menu(menu, s)

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

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

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

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

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

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

        if s.untracked:
            menu.addSeparator()
            menu.addAction(qtutils.discard_icon(),
                           N_('Delete File(s)...'), self._delete_files)
            menu.addSeparator()
            menu.addAction(qtutils.icon('edit-clear.svg'),
                           N_('Add to .gitignore'),
                           cmds.run(cmds.Ignore,
                                map(lambda x: '/' + x, self.untracked())))
        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        return menu
Example #8
0
    def _create_unmerged_context_menu(self, menu, s):
        menu.addAction(qtutils.git_icon(),
                       self.tr('Launch Merge Tool'),
                       cmds.run(cmds.Mergetool, self.unmerged()))

        action = menu.addAction(qtutils.icon('add.svg'),
                                self.tr('Stage Selected'),
                                cmds.run(cmds.Stage, self.unstaged()))
        action.setShortcut(cmds.Stage.SHORTCUT)
        menu.addSeparator()
        action = menu.addAction(qtutils.options_icon(),
                                self.tr(cmds.LaunchEditor.NAME),
                                cmds.run(cmds.LaunchEditor))
        action.setShortcut(cmds.LaunchEditor.SHORTCUT)

        if not utils.is_win32():
            menu.addSeparator()
            action = menu.addAction(qtutils.file_icon(),
                    self.tr(cmds.OpenDefaultApp.NAME),
                    cmds.run(cmds.OpenDefaultApp, self.unmerged()))
            action.setShortcut(cmds.OpenDefaultApp.SHORTCUT)

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

        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        return menu
Example #9
0
    def _create_staged_context_menu(self, menu, s):
        if s.staged[0] in self.m.submodules:
            return self._create_staged_submodule_context_menu(menu, s)

        if self.m.unstageable():
            action = menu.addAction(qtutils.icon('remove.svg'),
                                    N_('Unstage Selected'),
                                    cmds.run(cmds.Unstage, self.staged()))
            action.setShortcut(cmds.Unstage.SHORTCUT)

        menu.addAction(self.launch_editor)
        menu.addAction(self.launch_difftool)

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

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

        if self.m.undoable():
            menu.addSeparator()
            menu.addAction(self.revert_unstaged_edits_action)
            menu.addAction(qtutils.icon('undo.svg'),
                           N_('Revert Uncommited Edits...'),
                           lambda: self._revert_uncommitted_edits(
                                        self.staged()))
        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        return menu
Example #10
0
    def _create_unmerged_context_menu(self, menu, s):
        menu.addAction(self.launch_difftool_action)

        action = menu.addAction(icons.add(), N_('Stage Selected'),
                                cmds.run(cmds.Stage, self.unstaged()))
        action.setShortcut(hotkeys.STAGE_SELECTION)
        menu.addSeparator()
        menu.addAction(self.launch_editor_action)

        if not utils.is_win32():
            menu.addSeparator()
            open_default = cmds.run(cmds.OpenDefaultApp, self.unmerged())
            action = menu.addAction(icons.default_app(),
                                    cmds.OpenDefaultApp.name(), open_default)
            action.setShortcut(hotkeys.PRIMARY_ACTION)

            action = menu.addAction(icons.folder(), cmds.OpenParentDir.name(),
                                    self._open_parent_dir)
            action.setShortcut(hotkeys.SECONDARY_ACTION)

        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        menu.addAction(self.copy_relpath_action)
        menu.addAction(self.view_history_action)
        return menu
Example #11
0
    def _create_unstaged_context_menu(self, menu, s):
        modified_submodule = (s.modified and
                              s.modified[0] in self.m.submodules)
        if modified_submodule:
            return self._create_modified_submodule_context_menu(menu, s)

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

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

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

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

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

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

        if s.untracked:
            menu.addSeparator()
            menu.addAction(qtutils.discard_icon(),
                           N_('Delete File(s)...'), self._delete_files)
            menu.addSeparator()
            menu.addAction(qtutils.icon('edit-clear.svg'),
                           N_('Add to .gitignore'),
                           cmds.run(cmds.Ignore,
                                map(lambda x: '/' + x, self.untracked())))
        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        return menu
Example #12
0
 def do(self):
     if not self.paths:
         return
     if utils.is_win32():
         utils.fork(["git", "mergetool", "--no-prompt", "--"] + self.paths)
     else:
         utils.fork(["xterm", "-e", "git", "mergetool", "--no-prompt", "--"] + self.paths)
Example #13
0
    def _create_unmerged_context_menu(self, menu, s):
        menu.addAction(self.launch_difftool_action)

        action = menu.addAction(icons.add(), N_('Stage Selected'),
                                cmds.run(cmds.Stage, self.unstaged()))
        action.setShortcut(hotkeys.STAGE_SELECTION)
        menu.addSeparator()
        menu.addAction(self.launch_editor_action)

        if not utils.is_win32():
            menu.addSeparator()
            open_default = cmds.run(cmds.OpenDefaultApp, self.unmerged())
            action = menu.addAction(icons.default_app(),
                                    cmds.OpenDefaultApp.name(), open_default)
            action.setShortcut(hotkeys.PRIMARY_ACTION)

            action = menu.addAction(icons.folder(),
                                    cmds.OpenParentDir.name(),
                                    self._open_parent_dir)
            action.setShortcut(hotkeys.SECONDARY_ACTION)

        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        menu.addAction(self.copy_relpath_action)
        menu.addAction(self.view_history_action)
        menu.addAction(self.view_blame_action)
        return menu
Example #14
0
    def _create_staged_context_menu(self, menu, s):
        if s.staged[0] in self.m.submodules:
            return self._create_staged_submodule_context_menu(menu, s)

        if self.m.unstageable():
            action = menu.addAction(icons.remove(), N_("Unstage Selected"), cmds.run(cmds.Unstage, self.staged()))
            action.setShortcut(hotkeys.STAGE_SELECTION)

        # Do all of the selected items exist?
        all_exist = all(not i in self.m.staged_deleted and core.exists(i) for i in self.staged())

        if all_exist:
            menu.addAction(self.launch_editor_action)
            menu.addAction(self.launch_difftool_action)

        if all_exist and not utils.is_win32():
            menu.addSeparator()
            open_default = cmds.run(cmds.OpenDefaultApp, self.staged())
            action = menu.addAction(icons.default_app(), cmds.OpenDefaultApp.name(), open_default)
            action.setShortcut(hotkeys.PRIMARY_ACTION)

            action = menu.addAction(icons.folder(), cmds.OpenParentDir.name(), self._open_parent_dir)
            action.setShortcut(hotkeys.SECONDARY_ACTION)

        if self.m.undoable():
            menu.addSeparator()
            menu.addAction(self.revert_unstaged_edits_action)

        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        menu.addAction(self.copy_relpath_action)
        menu.addAction(self.view_history_action)
        menu.addAction(self.view_blame_action)
        return menu
Example #15
0
    def _create_unmerged_context_menu(self, menu, s):
        menu.addAction(self.launch_difftool_action)

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

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

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

        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        menu.addAction(self.copy_relpath_action)
        return menu
Example #16
0
    def _create_staged_context_menu(self, menu, s):
        if s.staged[0] in self.m.submodules:
            return self._create_staged_submodule_context_menu(menu, s)

        if self.m.unstageable():
            action = menu.addAction(
                qtutils.remove_icon(), N_("Unstage Selected"), cmds.run(cmds.Unstage, self.staged())
            )
            action.setShortcut(cmds.Unstage.SHORTCUT)

        # Do all of the selected items exist?
        all_exist = all(not i in self.m.staged_deleted and core.exists(i) for i in self.staged())

        if all_exist:
            menu.addAction(self.launch_editor_action)
            menu.addAction(self.launch_difftool_action)

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

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

        if self.m.undoable():
            menu.addSeparator()
            menu.addAction(self.revert_unstaged_edits_action)

        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        menu.addAction(self.copy_relpath_action)
        return menu
Example #17
0
 def do(self):
     if not self.paths:
         return
     if utils.is_win32():
         utils.fork(['git', 'mergetool', '--no-prompt', '--'] + self.paths)
     else:
         utils.fork(['xterm', '-e',
                     'git', 'mergetool', '--no-prompt', '--'] + self.paths)
Example #18
0
 def do(self):
     if not self.paths:
         return
     if utils.is_win32():
         utils.fork(['git', 'mergetool', '--no-prompt', '--'] + self.paths)
     else:
         utils.fork(['xterm', '-e',
                     'git', 'mergetool', '--no-prompt', '--'] + self.paths)
Example #19
0
    def _create_unstaged_context_menu(self, menu, s):
        modified_submodule = (s.modified and
                              s.modified[0] in self.m.submodules)
        if modified_submodule:
            return self._create_modified_submodule_context_menu(menu, s)

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

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

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

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

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

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

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

        if all_exist and s.untracked:
            menu.addSeparator()
            if self.move_to_trash_action is not None:
                menu.addAction(self.move_to_trash_action)
            menu.addAction(self.delete_untracked_files_action)
            menu.addSeparator()
            menu.addAction(qtutils.icon('edit-clear.svg'),
                           N_('Add to .gitignore'),
                           cmds.run(cmds.Ignore,
                                map(lambda x: '/' + x, self.untracked())))
        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        return menu
Example #20
0
    def _create_unstaged_context_menu(self, menu, s):
        modified_submodule = (s.modified and
                              s.modified[0] in self.m.submodules)
        if modified_submodule:
            return self._create_modified_submodule_context_menu(menu, s)

        if self.m.stageable():
            action = menu.addAction(qtutils.add_icon(),
                                    N_('Stage Selected'),
                                    cmds.run(cmds.Stage, self.unstaged()))
            action.setShortcut(hotkeys.STAGE_SELECTION)

        # Do all of the selected items exist?
        all_exist = all(not i in self.m.unstaged_deleted and core.exists(i)
                        for i in self.staged())

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

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

        if s.modified and self.m.stageable():
            if self.m.undoable():
                menu.addSeparator()
                menu.addAction(self.revert_unstaged_edits_action)

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

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

        if all_exist and s.untracked:
            menu.addSeparator()
            if self.move_to_trash_action is not None:
                menu.addAction(self.move_to_trash_action)
            menu.addAction(self.delete_untracked_files_action)
            menu.addSeparator()
            menu.addAction(qtutils.theme_icon('edit-clear.svg'),
                           N_('Add to .gitignore'),
                           cmds.run(cmds.Ignore,
                                map(lambda x: '/' + x, self.untracked())))
        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        menu.addAction(self.copy_relpath_action)
        if not selection.selection_model().is_empty():
            menu.addAction(self.view_history_action)
        return menu
Example #21
0
    def _create_unstaged_context_menu(self, menu, s):
        modified_submodule = (s.modified and
                              s.modified[0] in self.m.submodules)
        if modified_submodule:
            return self._create_modified_submodule_context_menu(menu, s)

        if self.m.stageable():
            action = menu.addAction(icons.add(), N_('Stage Selected'),
                                    cmds.run(cmds.Stage, self.unstaged()))
            action.setShortcut(hotkeys.STAGE_SELECTION)

        # Do all of the selected items exist?
        all_exist = all(i not in self.m.unstaged_deleted and core.exists(i)
                        for i in self.staged())

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

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

        if s.modified and self.m.stageable():
            if self.m.undoable():
                menu.addSeparator()
                menu.addAction(self.revert_unstaged_edits_action)

        if all_exist and self.unstaged() and not utils.is_win32():
            menu.addSeparator()
            open_default = cmds.run(cmds.OpenDefaultApp, self.unstaged())
            action = menu.addAction(icons.default_app(),
                                    cmds.OpenDefaultApp.name(), open_default)
            action.setShortcut(hotkeys.PRIMARY_ACTION)

            action = menu.addAction(icons.folder(),
                                    cmds.OpenParentDir.name(),
                                    self._open_parent_dir)
            action.setShortcut(hotkeys.SECONDARY_ACTION)

        if all_exist and s.untracked:
            menu.addSeparator()
            if self.move_to_trash_action is not None:
                menu.addAction(self.move_to_trash_action)
            menu.addAction(self.delete_untracked_files_action)
            menu.addSeparator()
            menu.addAction(icons.edit(),
                           N_('Add to .gitignore'),
                           cmds.run(cmds.Ignore,
                                    [('/' + x) for x in self.untracked()]))
        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        menu.addAction(self.copy_relpath_action)
        if not selection.selection_model().is_empty():
            menu.addAction(self.view_history_action)
            menu.addAction(self.view_blame_action)
        return menu
Example #22
0
 def do(self):
     s = selection.selection()
     if s.unmerged:
         paths = s.unmerged
         if utils.is_win32():
             core.fork(['git', 'mergetool', '--no-prompt', '--'] + paths)
         else:
             core.fork(['xterm', '-e',
                        'git', 'mergetool', '--no-prompt', '--'] + paths)
     else:
         difftool.run()
Example #23
0
    def _create_unstaged_context_menu(self, menu, s):
        modified_submodule = (s.modified
                              and s.modified[0] in self.m.submodules)
        if modified_submodule:
            return self._create_modified_submodule_context_menu(menu, s)

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

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

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

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

        if s.modified and self.m.stageable():
            if self.m.undoable():
                menu.addSeparator()
                menu.addAction(self.revert_unstaged_edits_action)
                menu.addAction(self.revert_uncommitted_edits_action)

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

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

        if all_exist and s.untracked:
            menu.addSeparator()
            if self.move_to_trash_action is not None:
                menu.addAction(self.move_to_trash_action)
            menu.addAction(self.delete_untracked_files_action)
            menu.addSeparator()
            menu.addAction(
                qtutils.icon('edit-clear.svg'), N_('Add to .gitignore'),
                cmds.run(cmds.Ignore, map(lambda x: '/' + x,
                                          self.untracked())))
        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        menu.addAction(self.copy_relpath_action)
        return menu
Example #24
0
 def do(self):
     s = selection.selection()
     if s.unmerged:
         paths = s.unmerged
         if utils.is_win32():
             core.fork(['git', 'mergetool', '--no-prompt', '--'] + paths)
         else:
             core.fork(
                 ['xterm', '-e', 'git', 'mergetool', '--no-prompt', '--'] +
                 paths)
     else:
         difftool.run()
Example #25
0
    def _create_unstaged_context_menu(self, menu, s):
        modified_submodule = s.modified and s.modified[0] in self.m.submodules
        if modified_submodule:
            return self._create_modified_submodule_context_menu(menu, s)

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

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

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

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

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

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

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

        if all_exist and s.untracked:
            menu.addSeparator()
            menu.addAction(qtutils.discard_icon(), N_("Delete File(s)..."), self._delete_files)
            menu.addSeparator()
            menu.addAction(
                qtutils.icon("edit-clear.svg"),
                N_("Add to .gitignore"),
                cmds.run(cmds.Ignore, map(lambda x: "/" + x, self.untracked())),
            )
        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        return menu
Example #26
0
 def do(self):
     s = selection.selection()
     if s.unmerged:
         paths = s.unmerged
         if utils.is_win32():
             core.fork(['git', 'mergetool', '--no-prompt', '--'] + paths)
         else:
             cmd = _config.terminal()
             argv = utils.shell_split(cmd)
             argv.extend(['git', 'mergetool', '--no-prompt', '--'])
             argv.extend(paths)
             core.fork(argv)
     else:
         difftool.run()
Example #27
0
 def do(self):
     s = selection.selection()
     if s.unmerged:
         paths = s.unmerged
         if utils.is_win32():
             core.fork(['git', 'mergetool', '--no-prompt', '--'] + paths)
         else:
             cmd = _config.terminal()
             argv = utils.shell_split(cmd)
             argv.extend(['git', 'mergetool', '--no-prompt', '--'])
             argv.extend(paths)
             core.fork(argv)
     else:
         difftool.run()
Example #28
0
def default_history_browser():
    if utils.is_win32():
        # On Windows, a sensible default is "python git-cola dag"
        # which is different than `gitk` below, but is preferred
        # because we don't have to guess paths.
        git_cola = sys.argv[0]
        python = sys.executable
        argv = [python, git_cola, 'dag']
        argv = core.prep_for_subprocess(argv)
        default = core.decode(subprocess.list2cmdline(argv))
    else:
        # The `gitk` script can be launched as-is on unix
        default = 'gitk'
    return default
Example #29
0
def default_history_browser():
    if utils.is_win32():
        # On Windows, a sensible default is "python git-cola dag"
        # which is different than `gitk` below, but is preferred
        # because we don't have to guess paths.
        git_cola = sys.argv[0].replace("\\", '/')
        python = sys.executable.replace("\\", '/')
        argv = [python, git_cola, 'dag']
        argv = core.prep_for_subprocess(argv)
        default = core.decode(subprocess.list2cmdline(argv))
    else:
        # The `gitk` script can be launched as-is on unix
        default = 'gitk'
    return default
Example #30
0
 def do(self):
     s = selection.selection()
     if s.unmerged:
         paths = s.unmerged
         if utils.is_win32():
             core.fork(["git", "mergetool", "--no-prompt", "--"] + paths)
         else:
             cfg = gitcfg.current()
             cmd = cfg.terminal()
             argv = utils.shell_split(cmd)
             argv.extend(["git", "mergetool", "--no-prompt", "--"])
             argv.extend(paths)
             core.fork(argv)
     else:
         difftool.run()
Example #31
0
    def _create_unstaged_context_menu(self, menu, s):
        modified_submodule = s.modified and s.modified[0] in self.m.submodules
        if modified_submodule:
            return self._create_modified_submodule_context_menu(menu, s)

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

        # Do all of the selected items exist?
        all_exist = all(not i in self.m.unstaged_deleted and core.exists(i) for i in self.staged())

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

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

        if s.modified and self.m.stageable():
            if self.m.undoable():
                menu.addSeparator()
                menu.addAction(self.revert_unstaged_edits_action)

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

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

        if all_exist and s.untracked:
            menu.addSeparator()
            if self.move_to_trash_action is not None:
                menu.addAction(self.move_to_trash_action)
            menu.addAction(self.delete_untracked_files_action)
            menu.addSeparator()
            menu.addAction(
                qtutils.theme_icon("edit-clear.svg"),
                N_("Add to .gitignore"),
                cmds.run(cmds.Ignore, map(lambda x: "/" + x, self.untracked())),
            )
        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        menu.addAction(self.copy_relpath_action)
        return menu
Example #32
0
def _create_instance():
    thread_class = None
    cfg = gitcfg.current()
    if not cfg.get('cola.inotify', True):
        msg = N_('File system change monitoring: disabled because'
                 ' "cola.inotify" is false.\n')
        Interaction.log(msg)
    elif AVAILABLE == 'inotify':
        thread_class = _InotifyThread
    elif AVAILABLE == 'pywin32':
        thread_class = _Win32Thread
    else:
        if utils.is_win32():
            msg = N_('File system change monitoring: disabled because pywin32'
                     ' is not installed.\n')
            Interaction.log(msg)
        elif utils.is_linux():
            msg = N_('File system change monitoring: disabled because libc'
                     ' does not support the inotify system calls.\n')
            Interaction.log(msg)
    return _Monitor(thread_class)
Example #33
0
def _create_instance():
    thread_class = None
    cfg = gitcfg.current()
    if not cfg.get('cola.inotify', True):
        msg = N_('File system change monitoring: disabled because'
                 ' "cola.inotify" is false.\n')
        Interaction.log(msg)
    elif AVAILABLE == 'inotify':
        thread_class = _InotifyThread
    elif AVAILABLE == 'pywin32':
        thread_class = _Win32Thread
    else:
        if utils.is_win32():
            msg = N_('File system change monitoring: disabled because pywin32'
                     ' is not installed.\n')
            Interaction.log(msg)
        elif utils.is_linux():
            msg = N_('File system change monitoring: disabled because libc'
                     ' does not support the inotify system calls.\n')
            Interaction.log(msg)
    return _Monitor(thread_class)
Example #34
0
    def _create_staged_context_menu(self, menu, s):
        if s.staged[0] in self.m.submodules:
            return self._create_staged_submodule_context_menu(menu, s)

        if self.m.unstageable():
            action = menu.addAction(qtutils.remove_icon(),
                                    N_('Unstage Selected'),
                                    cmds.run(cmds.Unstage, self.staged()))
            action.setShortcut(hotkeys.STAGE_SELECTION)

        # Do all of the selected items exist?
        all_exist = all(not i in self.m.staged_deleted and core.exists(i)
                        for i in self.staged())

        if all_exist:
            menu.addAction(self.launch_editor_action)
            menu.addAction(self.launch_difftool_action)

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

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

        if self.m.undoable():
            menu.addSeparator()
            menu.addAction(self.revert_unstaged_edits_action)

        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        menu.addAction(self.copy_relpath_action)
        menu.addAction(self.view_history_action)
        return menu
Example #35
0
    def _create_staged_context_menu(self, menu, s):
        if s.staged[0] in self.m.submodules:
            return self._create_staged_submodule_context_menu(menu, s)

        if self.m.unstageable():
            action = menu.addAction(
                qtutils.icon("remove.svg"), N_("Unstage Selected"), cmds.run(cmds.Unstage, self.staged())
            )
            action.setShortcut(cmds.Unstage.SHORTCUT)

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

        if all_exist:
            menu.addAction(self.launch_editor)
            menu.addAction(self.launch_difftool)

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

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

        if self.m.undoable():
            menu.addSeparator()
            menu.addAction(self.revert_unstaged_edits_action)
            menu.addAction(
                qtutils.icon("undo.svg"),
                N_("Revert Uncommited Edits..."),
                lambda: self._revert_uncommitted_edits(self.staged()),
            )
        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        return menu
Example #36
0
    def _create_staged_context_menu(self, menu, s):
        if s.staged[0] in self.m.submodules:
            return self._create_staged_submodule_context_menu(menu, s)

        if self.m.unstageable():
            action = menu.addAction(qtutils.icon('remove.svg'),
                                    N_('Unstage Selected'),
                                    cmds.run(cmds.Unstage, self.staged()))
            action.setShortcut(cmds.Unstage.SHORTCUT)

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

        if all_exist:
            menu.addAction(self.launch_editor_action)
            menu.addAction(self.launch_difftool_action)

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

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

        if self.m.undoable():
            menu.addSeparator()
            menu.addAction(self.revert_unstaged_edits_action)

        menu.addSeparator()
        menu.addAction(self.copy_path_action)
        menu.addAction(self.copy_relpath_action)
        return menu
Example #37
0
    def run(self):
        """Create the inotify WatchManager and generate FileSysEvents"""

        if utils.is_win32():
            self.run_win32()
            return

        # Only capture events that git cares about
        self._wmgr = WatchManager()
        if self._is_pyinotify_08x():
            notifier = Notifier(self._wmgr,
                                FileSysEvent(),
                                timeout=self._timeout)
        else:
            notifier = Notifier(self._wmgr, FileSysEvent())

        self._watch_directory(self._path)

        # Register files/directories known to git
        for filename in self._git.ls_files()[STDOUT].splitlines():
            filename = core.realpath(filename)
            directory = os.path.dirname(filename)
            self._watch_directory(directory)

        # self._running signals app termination.  The timeout is a tradeoff
        # between fast notification response and waiting too long to exit.
        while self._running:
            if self._is_pyinotify_08x():
                check = notifier.check_events()
            else:
                check = notifier.check_events(timeout=self._timeout)
            if not self._running:
                break
            if check:
                notifier.read_events()
                notifier.process_events()
        notifier.stop()
Example #38
0
def find_git():
    """Return the path of git.exe, or None if we can't find it."""
    if not utils.is_win32():
        return None  # UNIX systems have git in their $PATH

    # If the user wants to use a Git/bin/ directory from a non-standard
    # directory then they can write its location into
    # ~/.config/git-cola/git-bindir
    git_bindir = os.path.expanduser(os.path.join('~', '.config', 'git-cola',
                                                 'git-bindir'))
    if core.exists(git_bindir):
        custom_path = core.read(git_bindir).strip()
        if custom_path and core.exists(custom_path):
            return custom_path

    # Try to find Git's bin/ directory in one of the typical locations
    pf = os.environ.get('ProgramFiles', 'C:\\Program Files')
    pf32 = os.environ.get('ProgramFiles(x86)', 'C:\\Program Files (x86)')
    for p in [pf32, pf, 'C:\\']:
        candidate = os.path.join(p, 'Git\\bin')
        if os.path.isdir(candidate):
            return candidate

    return None
Example #39
0
def find_git():
    """Return the path of git.exe, or None if we can't find it."""
    if not utils.is_win32():
        return None  # UNIX systems have git in their $PATH

    # If the user wants to use a Git/bin/ directory from a non-standard
    # directory then they can write its location into
    # ~/.config/git-cola/git-bindir
    git_bindir = os.path.expanduser(os.path.join('~', '.config', 'git-cola',
                                                 'git-bindir'))
    if core.exists(git_bindir):
        custom_path = core.read(git_bindir).strip()
        if custom_path and core.exists(custom_path):
            return custom_path

    # Try to find Git's bin/ directory in one of the typical locations
    pf = os.environ.get('ProgramFiles', 'C:\\Program Files')
    pf32 = os.environ.get('ProgramFiles(x86)', 'C:\\Program Files (x86)')
    for p in [pf32, pf, 'C:\\']:
        candidate = os.path.join(p, 'Git\\bin')
        if os.path.isdir(candidate):
            return candidate

    return None
Example #40
0
    def __init__(self, parent=None):
        QtGui.QTreeWidget.__init__(self, parent)

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

        ok = icons.ok()
        compare = icons.compare()
        question = icons.question()
        self.add_toplevel_item(N_('Staged'), ok, hide=True)
        self.add_toplevel_item(N_('Unmerged'), compare, hide=True)
        self.add_toplevel_item(N_('Modified'), compare, hide=True)
        self.add_toplevel_item(N_('Untracked'), question, hide=True)

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

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

        self.revert_unstaged_edits_action = qtutils.add_action(
            self, cmds.RevertUnstagedEdits.name(),
            cmds.run(cmds.RevertUnstagedEdits), hotkeys.REVERT)
        self.revert_unstaged_edits_action.setIcon(icons.undo())

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

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

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

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

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

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

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

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

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

        self.view_blame_action = qtutils.add_action(
            self, N_('Blame...'), self.view_blame, hotkeys.BLAME)

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

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

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

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

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

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

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

        self.connect(self, SIGNAL('itemExpanded(QTreeWidgetItem*)'),
                     lambda x: self.update_column_widths())
Example #41
0
    def __init__(self, parent=None):
        QtGui.QTreeWidget.__init__(self, parent)

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

        ok = icons.ok()
        compare = icons.compare()
        question = icons.question()
        self.add_toplevel_item(N_('Staged'), ok, hide=True)
        self.add_toplevel_item(N_('Unmerged'), compare, hide=True)
        self.add_toplevel_item(N_('Modified'), compare, hide=True)
        self.add_toplevel_item(N_('Untracked'), question, hide=True)

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

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

        self.revert_unstaged_edits_action = qtutils.add_action(
            self, cmds.RevertUnstagedEdits.name(),
            cmds.run(cmds.RevertUnstagedEdits), hotkeys.REVERT)
        self.revert_unstaged_edits_action.setIcon(icons.undo())

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        self.connect(self, SIGNAL('itemExpanded(QTreeWidgetItem*)'),
                     lambda x: self.update_column_widths())
Example #42
0
    def __init__(self, parent=None):
        QtGui.QTreeWidget.__init__(self, parent)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        self.connect(self, SIGNAL('itemExpanded(QTreeWidgetItem*)'),
                     lambda x: self.update_column_widths())
Example #43
0
    def __init__(self, parent=None):
        QtGui.QTreeWidget.__init__(self, parent)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        self.connect(self, SIGNAL("itemExpanded(QTreeWidgetItem*)"), lambda x: self.update_column_widths())
Example #44
0
from threading import Timer
from threading import Lock

try:
    import pyinotify
    from pyinotify import ProcessEvent
    from pyinotify import WatchManager
    from pyinotify import Notifier
    from pyinotify import EventsCodes
    AVAILABLE = True
except ImportError:
    ProcessEvent = object
    AVAILABLE = False

from cola import utils
if utils.is_win32():
    try:
        import win32file
        import win32con
        import pywintypes
        import win32event
        AVAILABLE = True
    except ImportError:
        ProcessEvent = object
        AVAILABLE = False

from PyQt4 import QtCore

from cola import gitcfg
from cola import cmds
from cola import core
Example #45
0
    def __init__(self, parent):
        QtGui.QTreeWidget.__init__(self, parent)

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

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

        # Used to restore the selection
        self.old_scroll = None
        self.old_selection = None
        self.old_contents = None

        self.expanded_items = set()

        self.process_selection = qtutils.add_action(self,
                N_('Stage / Unstage'), self._process_selection,
                cmds.Stage.SHORTCUT)

        self.launch_difftool = qtutils.add_action(self,
                cmds.LaunchDifftool.name(),
                cmds.run(cmds.LaunchDifftool),
                cmds.LaunchDifftool.SHORTCUT)
        self.launch_difftool.setIcon(qtutils.icon('git.svg'))

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

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

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

        self.up = qtutils.add_action(self,
                N_('Move Up'), self.move_up, Qt.Key_K)
        self.down = qtutils.add_action(self,
                N_('Move Down'), self.move_down, Qt.Key_J)

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

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

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

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

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

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

        self.connect(self,
                     SIGNAL('itemExpanded(QTreeWidgetItem*)'),
                     lambda x: self.update_column_widths())
Example #46
0
from threading import Timer
from threading import Lock
from cola import utils

try:
    import pyinotify
    from pyinotify import ProcessEvent
    from pyinotify import WatchManager
    from pyinotify import Notifier
    from pyinotify import EventsCodes
    AVAILABLE = True
except ImportError:
    ProcessEvent = object
    AVAILABLE = False

if utils.is_win32():
    try:
        import win32file
        import win32con
        import pywintypes
        import win32event
        AVAILABLE = True
    except ImportError:
        ProcessEvent = object
        AVAILABLE = False

from PyQt4 import QtCore

import cola
from cola import core
from cola import signals
Example #47
0
    def create_context_menu(self):
        """Set up the status menu for the repo status tree."""
        s = self.selection()
        menu = QtGui.QMenu(self)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        menu.addSeparator()

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

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

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

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

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

        self.process_selection = qtutils.add_action(self,
                                                    N_('Stage / Unstage'),
                                                    self._process_selection,
                                                    cmds.Stage.SHORTCUT)

        self.revert_unstaged_edits_action = qtutils.add_action(
            self, N_('Revert Unstaged Edits...'),
            cmds.run(cmds.RevertUnstagedEdits),
            cmds.RevertUnstagedEdits.SHORTCUT)
        self.revert_unstaged_edits_action.setIcon(qtutils.icon('undo.svg'))

        self.launch_difftool = qtutils.add_action(
            self, cmds.LaunchDifftool.name(), cmds.run(cmds.LaunchDifftool),
            cmds.LaunchDifftool.SHORTCUT)
        self.launch_difftool.setIcon(qtutils.icon('git.svg'))

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

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

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

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

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

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

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

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

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

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

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

        self.connect(self, SIGNAL('itemExpanded(QTreeWidgetItem*)'),
                     lambda x: self.update_column_widths())
Example #49
0
    def __init__(self, parent):
        QtGui.QTreeWidget.__init__(self, parent)

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

        self.add_item('Staged', 'plus.png', hide=True)
        self.add_item('Unmerged', 'unmerged.png', hide=True)
        self.add_item('Modified', 'modified.png', hide=True)
        self.add_item('Untracked', 'untracked.png', hide=True)

        # Used to restore the selection
        self.old_scroll = None
        self.old_selection = None
        self.old_contents = None

        self.expanded_items = set()

        self.process_selection = qtutils.add_action(self,
                'Process Selection', self._process_selection,
                defs.stage_shortcut)

        self.launch_difftool = qtutils.add_action(self,
                'Launch Diff Tool', self._launch_difftool,
                defs.difftool_shortcut)
        self.launch_difftool.setIcon(qtutils.icon('git.svg'))

        self.launch_editor = qtutils.add_action(self,
                'Launch Editor', self._launch_editor,
                defs.editor_shortcut)
        self.launch_editor.setIcon(qtutils.options_icon())

        if not utils.is_win32():
            self.open_using_default_app = qtutils.add_action(self,
                    self.txt_default_app,
                    self._open_using_default_app,
                    defs.default_app_shortcut)
            self.open_using_default_app.setIcon(qtutils.file_icon())

            self.open_parent_dir = qtutils.add_action(self,
                    self.txt_parent_dir,
                    self._open_parent_dir,
                    defs.parent_dir_shortcut)
            self.open_parent_dir.setIcon(qtutils.open_file_icon())

        self.up = qtutils.add_action(self,
                'Move Up', self.move_up, Qt.Key_K)
        self.down = qtutils.add_action(self,
                'Move Down', self.move_down, Qt.Key_J)

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

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

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

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

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

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

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