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()
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()
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 __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)
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)
def _item_gravatar_cb(self, menu, item): if options.gravatar_default != item.text: options.gravatar_default = item.text GravatarPict.clear_icon_cache()
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()
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)