Пример #1
0
    def __init__(self, win, parent):
        Menu.__init__(self, win)
        self.win = win

        # main actions
        self.item_add(None, "Refresh", "refresh", self._item_refresh_cb)
        self.item_add(None, "Open", "folder", self._item_open_cb)
        self.item_separator_add()

        # general options
        it_gen = self.item_add(None, "General", "preference")

        it = self.item_add(it_gen, "Use relative dates", None,
                           self._item_check_opts_cb, 'date_relative')
        it.content = Check(self, state=options.date_relative)

        it_gravatar = self.item_add(it_gen, "Gravatar")
        for name in ('mm', 'identicon', 'monsterid', 'wavatar', 'retro'):
            icon = "arrow_right" if name == options.gravatar_default else None
            self.item_add(it_gravatar, name, icon,  self._item_gravatar_cb)
        self.item_separator_add(it_gravatar)
        self.item_add(it_gravatar, 'Clear icons cache', 'delete',
                      lambda m,i: GravatarPict.clear_icon_cache())

        # dag options
        it_dag = self.item_add(None, "Dag", "preference")

        it = self.item_add(it_dag, "Show remote refs", None,
                           self._item_check_opts_cb, 'show_remotes_in_dag')
        it.content = Check(self, state=options.show_remotes_in_dag)

        it = self.item_add(it_dag, "Show commit messagges", None,
                           self._item_check_opts_cb, 'show_message_in_dag')
        it.content = Check(self, state=options.show_message_in_dag)

        # diff options
        it_diff = self.item_add(None, "Diff", "preference")

        it = self.item_add(it_diff, "Wrap long lines", None,
                           self._item_wrap_line_cb)
        it.content = Check(self, state=options.diff_text_wrap)

        it_font = self.item_add(it_diff, "Font face")
        for face in ('Sans', 'Mono'):
            icon = "arrow_right" if face == options.diff_font_face else None
            self.item_add(it_font, face, icon, self._item_font_face_cb)

        it_font = self.item_add(it_diff, "Font size")
        for size in (8, 9, 10, 11, 12, 13, 14):
            icon = "arrow_right" if size == options.diff_font_size else None
            self.item_add(it_font, str(size), icon, self._item_font_size_cb)

        x, y, w, h = parent.geometry
        self.move(x, y + h)
        self.show()
Пример #2
0
    def __init__(self, parent, repo, commit):
        self.repo = repo
        self.commit = commit

        Table.__init__(self, parent,  padding=(5,5))
        self.show()

        pic = GravatarPict(self)
        pic.email_set(commit.author_email)
        self.pack(pic, 0, 0, 1, 1)
        pic.show()

        text = u'<name>{}</name>  <b>{}</b>  {}<br><br>{}'.format(commit.sha[:9],
                commit.author, format_date(commit.commit_date), commit.title)
        en = Entry(self, text=text)
        en.line_wrap = ELM_WRAP_NONE
        en.size_hint_weight = EXPAND_BOTH
        en.size_hint_align = FILL_BOTH
        self.pack(en, 1, 0, 1, 1)
        en.show()
Пример #3
0
    def __init__(self, parent, app):
        self.app = app
        self.commit = None
        self.win = parent

        Table.__init__(self, parent,  padding=(5,5))
        self.show()

        # description entry
        self.entry = Entry(self, text='Unknown', line_wrap=ELM_WRAP_MIXED,
                           size_hint_weight=EXPAND_BOTH,
                           size_hint_align=FILL_BOTH,
                           editable=False)
        self.pack(self.entry, 0, 0, 1, 1)
        self.entry.show()

        # gravatar picture
        self.picture = GravatarPict(self)
        self.picture.size_hint_align = 1.0, 0.0
        self.picture.show()
        self.pack(self.picture, 1, 0, 1, 1)

        # action buttons box
        self.action_box = Box(self, horizontal=True,
                              size_hint_weight=EXPAND_HORIZ,
                              size_hint_align=(1.0, 1.0))
        self.pack(self.action_box, 0, 1, 2, 1)
        self.action_box.show()

        # panes
        panes = Panes(self, content_left_size = 0.3, horizontal=True,
                      size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH)
        self.pack(panes, 0, 2, 2, 1)
        panes.show()

        # file list
        self.itc = GenlistItemClass(item_style='default',
                                    text_get_func=self._gl_text_get,
                                    content_get_func=self._gl_content_get)
        self.diff_list = Genlist(self, homogeneous=True, mode=ELM_LIST_COMPRESS,
                                 select_mode=ELM_OBJECT_SELECT_MODE_ALWAYS,
                                 size_hint_weight=EXPAND_BOTH,
                                 size_hint_align=FILL_BOTH)
        self.diff_list.callback_selected_add(self._list_selected_cb)
        panes.part_content_set('left', self.diff_list)

        # diff entry
        self.diff_entry = DiffedEntry(self)
        panes.part_content_set('right', self.diff_entry)
Пример #4
0
    def __init__(self, parent, repo):
        self.repo = repo
        self.commit = None
        self.win = parent

        Table.__init__(self, parent,  padding=(5,5))
        self.show()

        # gravatar picture
        self.picture = GravatarPict(self)
        self.picture.size_hint_align = 0.0, 0.0
        self.picture.show()
        self.pack(self.picture, 0, 0, 1, 2)

        # description entry
        self.entry = Entry(self, text="Unknown", line_wrap=ELM_WRAP_MIXED,
                           size_hint_weight=EXPAND_BOTH,
                           size_hint_align=FILL_BOTH,
                           editable=False)
        self.pack(self.entry, 1, 0, 1, 1)
        self.entry.show()

        # action buttons box
        self.action_box = Box(self, horizontal=True,
                              size_hint_weight=EXPAND_HORIZ,
                              size_hint_align=(0.98, 0.98))
        self.pack(self.action_box, 1, 1, 1, 1)
        self.action_box.show()

        # panes
        panes = Panes(self, content_left_size = 0.3, horizontal=True,
                      size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH)
        self.pack(panes, 0, 2, 2, 1)
        panes.show()

        # file list
        self.diff_list = List(self, size_hint_weight=EXPAND_BOTH,
                                    size_hint_align=FILL_BOTH)
        self.diff_list.callback_selected_add(self.change_selected_cb)
        panes.part_content_set("left", self.diff_list)

        # diff entry
        self.diff_entry = DiffedEntry(self)
        panes.part_content_set("right", self.diff_entry)
Пример #5
0
class DiffViewer(Table):
    def __init__(self, parent, app):
        self.app = app
        self.commit = None
        self.win = parent

        Table.__init__(self, parent,  padding=(5,5))
        self.show()

        # description entry
        self.entry = Entry(self, text='Unknown', line_wrap=ELM_WRAP_MIXED,
                           size_hint_weight=EXPAND_BOTH,
                           size_hint_align=FILL_BOTH,
                           editable=False)
        self.pack(self.entry, 0, 0, 1, 1)
        self.entry.show()

        # gravatar picture
        self.picture = GravatarPict(self)
        self.picture.size_hint_align = 1.0, 0.0
        self.picture.show()
        self.pack(self.picture, 1, 0, 1, 1)

        # action buttons box
        self.action_box = Box(self, horizontal=True,
                              size_hint_weight=EXPAND_HORIZ,
                              size_hint_align=(1.0, 1.0))
        self.pack(self.action_box, 0, 1, 2, 1)
        self.action_box.show()

        # panes
        panes = Panes(self, content_left_size = 0.3, horizontal=True,
                      size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH)
        self.pack(panes, 0, 2, 2, 1)
        panes.show()

        # file list
        self.itc = GenlistItemClass(item_style='default',
                                    text_get_func=self._gl_text_get,
                                    content_get_func=self._gl_content_get)
        self.diff_list = Genlist(self, homogeneous=True, mode=ELM_LIST_COMPRESS,
                                 select_mode=ELM_OBJECT_SELECT_MODE_ALWAYS,
                                 size_hint_weight=EXPAND_BOTH,
                                 size_hint_align=FILL_BOTH)
        self.diff_list.callback_selected_add(self._list_selected_cb)
        panes.part_content_set('left', self.diff_list)

        # diff entry
        self.diff_entry = DiffedEntry(self)
        panes.part_content_set('right', self.diff_entry)

    def _gl_text_get(self, li, part, item_data):
        if isinstance(item_data, tuple): # in real commits
            mod, staged, name, new = item_data
        else: # in local changes (item_data is the path)
            mod, staged, name, new = self.app.repo.status.changes[item_data]
        return '{} → {}'.format(name, new) if new else name

    def _gl_content_get(self, li, part, item_data):
        if isinstance(item_data, tuple): # in real commits
            mod, staged, name, new = item_data
        else: # in local changes (item_data is the path)
            mod, staged, name, new = self.app.repo.status.changes[item_data]

        if part == 'elm.swallow.icon':
            return Icon(self, standard='git-mod-'+mod)
        elif part == 'elm.swallow.end' and staged is not None:
            ck = Check(self, state=staged, propagate_events=False)
            ck.callback_changed_add(self._stage_unstage_check_cb)
            ck.data['path'] = name
            return ck

    def update_action_buttons(self, buttons):
        self.action_box.clear()
        if 'checkout' in buttons:
            bt = Button(self, text='Checkout')
            bt.callback_clicked_add(lambda b: \
                self.app.checkout_ref(self.commit.sha))
            self.action_box.pack_end(bt)
            bt.show()
        if 'revert' in buttons:
            bt = Button(self, text='Revert')
            bt.callback_clicked_add(lambda b: \
                CommitDialog(self.app, revert_commit=self.commit))
            self.action_box.pack_end(bt)
            bt.show()
        if 'cherrypick' in buttons:
            bt = Button(self, text='Cherry-pick')
            bt.callback_clicked_add(lambda b: \
                CommitDialog(self.app, cherrypick_commit=self.commit))
            self.action_box.pack_end(bt)
            bt.show()
        if 'commit' in buttons:
            bt = Button(self, text='Commit',
                        content=Icon(self, standard='git-commit'))
            bt.callback_clicked_add(lambda b: \
                CommitDialog(self.app))
            self.action_box.pack_end(bt)
            bt.show()
        if 'stash' in buttons:
            bt = Button(self, text='Stash',
                        content=Icon(self, standard='git-stash'))
            bt.callback_clicked_add(lambda b: self.app.action_stash_save())
            self.action_box.pack_end(bt)
            bt.show()
        if 'discard' in buttons:
            bt = Button(self, text='Discard',
                        content=Icon(self, standard='user-trash'))
            bt.callback_clicked_add(lambda b: DiscardDialog(self.app))
            self.action_box.pack_end(bt)
            bt.show()

    def show_commit(self, commit):
        self.commit = commit

        self.picture.email_set(commit.author_email)
        line1 = '<name>{}</name>  <b>{}</b>  {}<br>'.format(commit.sha[:9],
                 commit.author, format_date(commit.commit_date))
        line2 = line3 = line4 = ''
        if commit.committer and commit.committer != commit.author:
            line2 = '<name>Committed by:</name> <b>{}</b><br>'.format(
                     commit.committer)
        if commit.title:
            line3 = '<bigger><b>{}</b></bigger><br>'.format(
                    utf8_to_markup(commit.title.strip()))
        if commit.message:
            line4 = '<br>{}'.format(utf8_to_markup(commit.message.strip()))
        text = line1 + line2 + line3 + line4
        self.entry.text = text

        self.update_action_buttons(['checkout', 'revert', 'cherrypick'])
        self.diff_entry.text = ''
        self.diff_list.clear()
        self.app.repo.request_changes(self._changes_done_cb, commit1=commit)

    def show_local_status(self):
        self.commit = None
        self.entry.text = '<bigger><b>Local status</b></bigger>'
        self.diff_entry.text = ''
        self.picture.email_set(None)
        self.update_action_buttons(['commit', 'stash', 'discard'])
        self.diff_list.clear()
        for path in sorted(self.app.repo.status.changes):
            self.diff_list.item_append(self.itc, path)

    def refresh_diff(self):
        if self.diff_list.selected_item:
            self._list_selected_cb(self.diff_list, self.diff_list.selected_item)

    def _stage_unstage_check_cb(self, check):
        path = check.data['path']
        if check.state is True:
            self.app.repo.stage_file(self._stage_unstage_done_cb, path, path)
        else:
            self.app.repo.unstage_file(self._stage_unstage_done_cb, path, path)

    def _stage_unstage_done_cb(self, success, path):
        self.app.action_update_header()
        self.diff_list.realized_items_update()

    def _changes_done_cb(self, success, lines):
        for mod, name, new_name in lines:
            item_data = (mod, None, name, new_name)
            self.diff_list.item_append(self.itc, item_data)
        self.diff_list.first_item.selected = True

    def _list_selected_cb(self, li, item):
        if isinstance(item.data, tuple): # in real commits
            mod, staged, name, new = item.data
        else: # in local changes (item_data is the path)
            mod, staged, name, new = self.app.repo.status.changes[item.data]

        self.app.repo.request_diff(self._diff_done_cb,
                                   ref1=self.commit.sha if self.commit else None,
                                   path=name)
        self.diff_entry.line_wrap = \
            ELM_WRAP_MIXED if options.diff_text_wrap else ELM_WRAP_NONE
        self.diff_entry.loading_set()

    def _diff_done_cb(self, lines, success):
        self.diff_entry.lines_set(lines)
Пример #6
0
 def _item_gravatar_cb(self, menu, item):
     if options.gravatar_default != item.text:
         options.gravatar_default = item.text
         GravatarPict.clear_icon_cache()
Пример #7
0
    def _button_pressed_cb(self, btn):
        # close the menu if it is visible yet
        if self._menu and self._menu.visible:
            self._menu.delete()
            self._menu = None
            return

        # build a new menu
        m = Menu(self.top_widget)
        self._menu = m

        # main actions
        disabled = self.app.repo is None
        m.item_add(None, 'Refresh', 'view-refresh', 
                   self.app.action_reload_repo).disabled = disabled
        m.item_add(None, 'Open...', 'document-open',
                   self.app.action_open)
        m.item_add(None, 'Branches...', 'git-branch', 
                   self.app.action_branches).disabled = disabled
        m.item_add(None, 'Tags...', 'git-tag', 
                   self.app.action_tags).disabled = disabled
        m.item_add(None, 'Compare...', 'git-compare', 
                   self.app.action_compare).disabled = disabled
        m.item_add(None, 'Remotes...', 'git-remote', 
                   self.app.action_remotes).disabled = disabled
        m.item_add(None, 'Stashes...', 'git-stash', 
                   self.app.action_stash_show).disabled = disabled

        # general options
        m.item_separator_add()
        it_gen = m.item_add(None, 'General', 'preference')

        it = m.item_add(it_gen, 'Use relative dates', None,
                        self._item_check_opts_cb, 'date_relative')
        it.content = Check(self, state=options.date_relative)
        
        it = m.item_add(it_gen, 'Review all git commands before execution', None,
                        self._item_check_opts_cb, 'review_git_commands')
        it.content = Check(self, state=options.review_git_commands)

        it_gravatar = m.item_add(it_gen, 'Gravatar')
        for name in ('mm', 'identicon', 'monsterid', 'wavatar', 'retro'):
            icon = 'user-bookmarks' if name == options.gravatar_default else None
            m.item_add(it_gravatar, name, icon,  self._item_gravatar_cb)
        m.item_separator_add(it_gravatar)
        m.item_add(it_gravatar, 'Clear icons cache', 'user-trash',
                   lambda m,i: GravatarPict.clear_icon_cache())

        # dag options
        it_dag = m.item_add(None, 'Dag', 'preference')

        it = m.item_add(it_dag, 'Show remote refs', None,
                        self._item_check_opts_cb, 'show_remotes_in_dag')
        it.content = Check(self, state=options.show_remotes_in_dag)

        it = m.item_add(it_dag, 'Show messages', None,
                        self._item_check_opts_cb, 'show_message_in_dag')
        it.content = Check(self, state=options.show_message_in_dag)

        it = m.item_add(it_dag, 'Show authors', None,
                        self._item_check_opts_cb, 'show_author_in_dag')
        it.content = Check(self, state=options.show_author_in_dag)

        it = m.item_add(it_dag, 'Show stash items', None,
                        self._item_check_opts_cb, 'show_stash_in_dag')
        it.content = Check(self, state=options.show_stash_in_dag)

        it_numb = m.item_add(it_dag, 'Number of commits to load')
        for num in (100, 200, 500, 1000):
            icon = 'user-bookmarks' if num == options.number_of_commits_to_load else None
            m.item_add(it_numb, str(num), icon, self._item_num_commits_cb)

        # diff options
        it_diff = m.item_add(None, 'Diff', 'preference')

        it = m.item_add(it_diff, 'Wrap long lines', None,
                        self._item_wrap_line_cb)
        it.content = Check(self, state=options.diff_text_wrap)

        it_font = m.item_add(it_diff, 'Font face')
        for face in ('Sans', 'Mono'):
            icon = 'user-bookmarks' if face == options.diff_font_face else None
            m.item_add(it_font, face, icon, self._item_font_face_cb)

        it_font = m.item_add(it_diff, 'Font size')
        for size in (8, 9, 10, 11, 12, 13, 14):
            icon = 'user-bookmarks' if size == options.diff_font_size else None
            m.item_add(it_font, str(size), icon, self._item_font_size_cb)

        # quit item
        m.item_separator_add()
        m.item_add(None, 'About', 'help-about', self.app.action_about)
        m.item_add(None, 'Quit', 'application-exit', self.app.action_quit)


        # show the menu
        x, y, w, h = self.geometry
        m.move(x, y + h)
        m.show()
Пример #8
0
class DiffViewer(Table):
    def __init__(self, parent, repo):
        self.repo = repo
        self.commit = None
        self.win = parent

        Table.__init__(self, parent,  padding=(5,5))
        self.show()

        # gravatar picture
        self.picture = GravatarPict(self)
        self.picture.size_hint_align = 0.0, 0.0
        self.picture.show()
        self.pack(self.picture, 0, 0, 1, 2)

        # description entry
        self.entry = Entry(self, text="Unknown", line_wrap=ELM_WRAP_MIXED,
                           size_hint_weight=EXPAND_BOTH,
                           size_hint_align=FILL_BOTH,
                           editable=False)
        self.pack(self.entry, 1, 0, 1, 1)
        self.entry.show()

        # action buttons box
        self.action_box = Box(self, horizontal=True,
                              size_hint_weight=EXPAND_HORIZ,
                              size_hint_align=(0.98, 0.98))
        self.pack(self.action_box, 1, 1, 1, 1)
        self.action_box.show()

        # panes
        panes = Panes(self, content_left_size = 0.3, horizontal=True,
                      size_hint_weight=EXPAND_BOTH, size_hint_align=FILL_BOTH)
        self.pack(panes, 0, 2, 2, 1)
        panes.show()

        # file list
        self.diff_list = List(self, size_hint_weight=EXPAND_BOTH,
                                    size_hint_align=FILL_BOTH)
        self.diff_list.callback_selected_add(self.change_selected_cb)
        panes.part_content_set("left", self.diff_list)

        # diff entry
        self.diff_entry = DiffedEntry(self)
        panes.part_content_set("right", self.diff_entry)

    def update_action_buttons(self, buttons):
        self.action_box.clear()
        if 'revert' in buttons:
            bt = Button(self, text="Revert", disabled=True)
            self.action_box.pack_end(bt)
            bt.show()
        if 'commit' in buttons:
            bt = Button(self, text="Commit")
            bt.callback_clicked_add(lambda b: CommitDialog(self.repo, self.win))
            self.action_box.pack_end(bt)
            bt.show()
        if 'discard' in buttons:
            bt = Button(self, text="Discard", disabled=True)
            self.action_box.pack_end(bt)
            bt.show()

    def commit_set(self, repo, commit):
        self.repo = repo
        self.commit = commit

        self.diff_list.clear()
        self.diff_entry.text = ''

        if commit.sha:
            # a real commit
            text = u'<name>{0}</name>  <b>{1}</b>  {2}<br>' \
                '<bigger><b>{3}</b></bigger>'.format(commit.sha[:9],
                commit.author, format_date(commit.commit_date), commit.title)
            if commit.message:
                msg = commit.message.strip().replace('\n', '<br>')
                text += u'<br><br>{}'.format(msg)
            repo.request_changes(self.changes_done_cb, commit1=commit)
            self.update_action_buttons(['revert'])
        else:
            # or the fake 'local changes' commit
            text = "<bigger><b>Local changes</b></bigger>"
            self.show_local_status()
            self.update_action_buttons(['commit', 'discard'])

        self.entry.text = text
        self.picture.email_set(commit.author_email)

    def show_local_status(self):
        sortd = sorted(self.repo.status.changes, key=lambda c: c[2])
        for mod, staged, name in sortd:
            icon_name = 'mod_{}.png'.format(mod.lower())
            icon = Icon(self, file=theme_resource_get(icon_name))

            check = Check(self, text="", state=staged)
            check.callback_changed_add(self.stage_unstage_cb)
            check.data['path'] = name

            it = self.diff_list.item_append(name, icon, check)
            it.data['change'] = mod, name

        self.diff_list.go()

    def stage_unstage_cb(self, check):
        def stage_unstage_done_cb(success):
            self.win.update_header()

        if check.state is True:
            self.repo.stage_file(stage_unstage_done_cb, check.data['path'])
        else:
            self.repo.unstage_file(stage_unstage_done_cb, check.data['path'])

    def refresh_diff(self):
        if self.diff_list.selected_item:
            self.change_selected_cb(self.diff_list, self.diff_list.selected_item)

    def changes_done_cb(self, success, lines):
        for mod, name in lines:
            if mod in ('M', 'A', 'D'):
                icon_name = 'mod_{}.png'.format(mod.lower())
                icon = Icon(self, file=theme_resource_get(icon_name))
                it = self.diff_list.item_append(name, icon)
            else:
                it = self.diff_list.item_append('[{}] {}'.format(mod, name))
            it.data['change'] = mod, name
        self.diff_list.first_item.selected = True
        self.diff_list.go()

    def change_selected_cb(self, li, item):
        mod, path = item.data['change']
        self.repo.request_diff(self.diff_done_cb, commit1=self.commit, path=path)
        self.diff_entry.line_wrap = \
            ELM_WRAP_MIXED if options.diff_text_wrap else ELM_WRAP_NONE
        self.diff_entry.text = '<info>Loading diff, please wait...</info>'

    def diff_done_cb(self, lines, success):
        self.diff_entry.lines_set(lines)