def get_accelgroup(self): accelgroup = gtk.AccelGroup() mod = gtklib.get_thg_modifier() gtklib.add_accelerator(self.filetree, 'thg-diff', accelgroup, mod+'d') self.filetree.connect('thg-diff', self.thgdiff) self.connect('thg-refresh', self.thgrefresh) # set CTRL-c accelerator for copy-clipboard gtklib.add_accelerator(self.chunks.difftree(), 'copy-clipboard', accelgroup, mod+'c') def scroll_diff_notebook(widget, direction=gtk.SCROLL_PAGE_DOWN): page_num = self.diff_notebook.get_current_page() page = self.diff_notebook.get_nth_page(page_num) page.emit("scroll-child", direction, False) def toggle_filetree_selection(*arguments): self.sel_clicked(not self.selcb.get_active()) def next_diff_notebook_page(*arguments): notebook = self.diff_notebook if notebook.get_current_page() >= len(notebook) - 1: notebook.set_current_page(0) else: notebook.next_page() def previous_diff_notebook_page(*arguments): notebook = self.diff_notebook if notebook.get_current_page() <= 0: notebook.set_current_page(len(notebook) - 1) else: notebook.prev_page() # signal, accelerator key, handler, (parameters) status_accelerators = [ ('status-scroll-down', 'bracketright', scroll_diff_notebook, (gtk.SCROLL_PAGE_DOWN,)), ('status-scroll-up', 'bracketleft', scroll_diff_notebook, (gtk.SCROLL_PAGE_UP,)), ('status-next-file', 'period', gtklib.move_treeview_selection, (self.filetree, 1)), ('status-previous-file', 'comma', gtklib.move_treeview_selection, (self.filetree, -1)), ('status-select-all', 'u', toggle_filetree_selection, ()), ('status-next-page', 'p', next_diff_notebook_page, ()), ('status-previous-page', '<Shift>p', previous_diff_notebook_page, ()), ] for signal, accelerator, handler, parameters in status_accelerators: gtklib.add_accelerator(self, signal, accelgroup, mod + accelerator) self.connect(signal, handler, *parameters) return accelgroup
def __init__(self, title, message, parent, type=gtk.MESSAGE_INFO): SimpleMessage.__init__(self, parent, gtk.DIALOG_MODAL, type, gtk.BUTTONS_CLOSE) self.set_title('TortoiseHg') self.set_markup(gtklib.markup(hglib.toutf(title), weight='bold')) self.format_secondary_text(hglib.toutf(message)) mod = gtklib.get_thg_modifier() key, modifier = gtk.accelerator_parse(mod+'Return') accel_group = gtk.AccelGroup() self.add_accel_group(accel_group) try: buttons = self.get_children()[0].get_children()[1].get_children() buttons[0].add_accelerator('clicked', accel_group, key, modifier, gtk.ACCEL_VISIBLE) except IndexError: pass
def get_body(self): """ Initialize the Dialog. """ self.grep_cmenu = self.grep_context_menu() self.changedesc = {} self.newpagecount = 1 self.currev = None vbox = gtk.VBox() notebook = gtk.Notebook() notebook.set_tab_pos(gtk.POS_TOP) notebook.set_scrollable(True) notebook.popup_enable() notebook.show() self.notebook = notebook vbox.pack_start(self.notebook, True, True, 2) self.stop_button.set_sensitive(False) accelgroup = gtk.AccelGroup() self.add_accel_group(accelgroup) mod = gtklib.get_thg_modifier() key, modifier = gtk.accelerator_parse(mod+'w') notebook.add_accelerator('thg-close', accelgroup, key, modifier, gtk.ACCEL_VISIBLE) notebook.connect('thg-close', self.close_notebook) key, modifier = gtk.accelerator_parse(mod+'n') notebook.add_accelerator('thg-new', accelgroup, key, modifier, gtk.ACCEL_VISIBLE) notebook.connect('thg-new', self.new_notebook) # status bar hbox = gtk.HBox() style = csinfo.labelstyle(contents=('%(shortuser)s@%(revnum)s ' '%(dateage)s', ' "%(summary)s"',), selectable=True) self.cslabel = csinfo.create(self.repo, style=style) hbox.pack_start(self.cslabel, False, False, 4) self.stbar = statusbar.StatusBar() hbox.pack_start(self.stbar) vbox.pack_start(hbox, False, False) return vbox
def __init__(self, buffer=None, accelgroup=None): if buffer is None: buffer = UndoableTextBuffer() gtk.TextView.__init__(self, buffer) if accelgroup: mod = gtklib.get_thg_modifier() key, modifier = gtk.accelerator_parse(mod+'z') self.add_accelerator('thg-undo', accelgroup, key, modifier, gtk.ACCEL_VISIBLE) def do_undo(view): buffer = self.get_buffer() if hasattr(buffer, 'undo'): buffer.undo() self.connect('thg-undo', do_undo) key, modifier = gtk.accelerator_parse(mod+'y') self.add_accelerator('thg-redo', accelgroup, key, modifier, gtk.ACCEL_VISIBLE) def do_redo(view): buffer = self.get_buffer() if hasattr(buffer, 'redo'): buffer.redo() self.connect('thg-redo', do_redo)
def __init__(self, repo, pats, ctx1a, sa, ctx1b, sb, ctx2, cpy): 'Initialize the Dialog' gtk.Dialog.__init__(self, title=_('Visual Diffs')) gtklib.set_tortoise_icon(self, 'menushowchanged.ico') gtklib.set_tortoise_keys(self) if ctx2.rev() is None: title = _('working changes') elif ctx1a == ctx2.parents()[0]: title = _('changeset ') + str(ctx2.rev()) else: title = _('revisions %d to %d') % (ctx1a.rev(), ctx2.rev()) title = _('Visual Diffs - ') + title if pats: title += _(' filtered') self.set_title(title) self.set_default_size(400, 250) self.set_has_separator(False) self.reponame=hglib.get_reponame(repo) self.ctxs = (ctx1a, ctx1b, ctx2) self.copies = cpy self.ui = repo.ui lbl = gtk.Label(_('Temporary files are removed when this dialog ' 'is closed')) self.vbox.pack_start(lbl, False, False, 2) scroller = gtk.ScrolledWindow() scroller.set_shadow_type(gtk.SHADOW_IN) scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) treeview = gtk.TreeView() self.treeview = treeview treeview.get_selection().set_mode(gtk.SELECTION_SINGLE) treeview.set_search_equal_func(self.search_filelist) scroller.add(treeview) self.vbox.pack_start(scroller, True, True, 2) treeview.connect('row-activated', self.rowactivated) treeview.set_headers_visible(False) treeview.set_property('enable-grid-lines', True) treeview.set_enable_search(False) accelgroup = gtk.AccelGroup() self.add_accel_group(accelgroup) mod = gtklib.get_thg_modifier() key, modifier = gtk.accelerator_parse(mod+'d') treeview.add_accelerator('thg-diff', accelgroup, key, modifier, gtk.ACCEL_VISIBLE) treeview.connect('thg-diff', self.rowactivated) cell = gtk.CellRendererText() stcol = gtk.TreeViewColumn('Status', cell) stcol.set_resizable(True) stcol.add_attribute(cell, 'text', 0) treeview.append_column(stcol) cell = gtk.CellRendererText() fcol = gtk.TreeViewColumn('Filename', cell) fcol.set_resizable(True) fcol.add_attribute(cell, 'text', 1) treeview.append_column(fcol) model = gtk.ListStore(str, str) treeview.set_model(model) tools = hglib.difftools(repo.ui) preferred = besttool(repo.ui, tools) self.diffpath, self.diffopts, self.mergeopts = tools[preferred] hbox = gtk.HBox() self.vbox.pack_start(hbox, False, False, 2) if ctx2.rev() is None: pass # Do not offer directory diffs when the working directory # is being referenced directly elif ctx1b: self.p1button = gtk.Button(_('Dir diff to p1')) self.p1button.connect('pressed', self.p1dirdiff) self.p2button = gtk.Button(_('Dir diff to p2')) self.p2button.connect('pressed', self.p2dirdiff) self.p3button = gtk.Button(_('3-way dir diff')) self.p3button.connect('pressed', self.threewaydirdiff) hbox.pack_end(self.p3button, False, False) hbox.pack_end(self.p2button, False, False) hbox.pack_end(self.p1button, False, False) else: self.dbutton = gtk.Button(_('Directory diff')) self.dbutton.connect('pressed', self.p1dirdiff) hbox.pack_end(self.dbutton, False, False) self.update_diff_buttons(preferred) if len(tools) > 1: combo = gtk.combo_box_new_text() for i, name in enumerate(tools.iterkeys()): combo.append_text(name) if name == preferred: defrow = i combo.set_active(defrow) combo.connect('changed', self.toolselect, tools) hbox.pack_start(combo, False, False, 2) patterns = repo.ui.configitems('diff-patterns') patterns = [(p, t) for p,t in patterns if t in tools] filesel = treeview.get_selection() filesel.connect('changed', self.fileselect, repo, combo, tools, patterns, preferred) gobject.idle_add(self.fillmodel, repo, model, sa, sb)
def add_annotate_page(self, path, revid): ''' Add new annotation page to notebook. Start scan of file 'path' revision history, start annotate of supplied revision 'revid'. ''' if revid == '.': ctx = self.repo.parents()[0] try: fctx = ctx.filectx(path) except error.LookupError: gdialog.Prompt(_('File is unrevisioned'), _('Unable to annotate ') + path, self).run() return rev = fctx.filelog().linkrev(fctx.filerev()) revid = str(rev) else: rev = long(revid) frame = gtk.Frame() frame.set_border_width(10) vbox = gtk.VBox() graphopts = { 'date': None, 'no_merges':False, 'only_merges':False, 'keyword':[], 'branch':None, 'pats':[], 'revrange':[], 'revlist':[], 'noheads':False, 'orig-tip':len(self.repo), 'branch-view':False, 'rev':[], 'npreviews':0 } graphopts['filehist'] = path # File log revision graph graphview = LogTreeView(self.repo, 5000) graphview.set_property('rev-column-visible', True) graphview.set_property('msg-column-visible', True) graphview.set_property('user-column-visible', True) graphview.set_property('age-column-visible', True) graphview.set_columns(['graph', 'rev', 'msg', 'user', 'age']) graphview.connect('revisions-loaded', self.revisions_loaded, rev) graphview.refresh(True, [path], graphopts) # Annotation text tree view treeview = gtk.TreeView() treeview.get_selection().set_mode(gtk.SELECTION_SINGLE) treeview.set_property('fixed-height-mode', True) treeview.set_border_width(0) accelgroup = gtk.AccelGroup() self.add_accel_group(accelgroup) mod = gtklib.get_thg_modifier() key, modifier = gtk.accelerator_parse(mod+'d') treeview.add_accelerator('thg-diff', accelgroup, key, modifier, gtk.ACCEL_VISIBLE) treeview.connect('thg-diff', self.annotate_thgdiff) results = gtk.ListStore(str, # revision id str, # file line (utf-8) str, # description (utf-8, escaped) str, # file path (utf-8) str, # color str, # author (utf-8) str) # line number treeview.set_model(results) treeview.set_search_equal_func(self.search_in_file) context_menu = self.ann_header_context_menu(treeview) for title, width, col, emode, visible in ( (_('Line'), 8, ACOL_LNUM, pango.ELLIPSIZE_NONE, True), (_('Rev'), 10, ACOL_REVID, pango.ELLIPSIZE_NONE, True), (_('File'), 15, ACOL_PATH, pango.ELLIPSIZE_START, False), (_('User'), 15, ACOL_USER, pango.ELLIPSIZE_END, False), (_('Source'), 80, ACOL_LINE, pango.ELLIPSIZE_END, True)): cell = gtk.CellRendererText() cell.set_property('width-chars', width) cell.set_property('ellipsize', emode) cell.set_property('family', 'Monospace') column = gtk.TreeViewColumn(title) column.set_resizable(True) column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) column.set_fixed_width(cell.get_size(treeview)[2]) column.pack_start(cell, expand=True) column.add_attribute(cell, 'text', col) column.add_attribute(cell, 'background', ACOL_COLOR) column.set_visible(visible) treeview.append_column(column) self.add_header_context_menu(column, context_menu) treeview.set_headers_clickable(True) if hasattr(treeview, 'set_tooltip_column'): treeview.set_tooltip_column(ACOL_DESC) results.path = path results.rev = revid scroller = gtk.ScrolledWindow() scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroller.add(treeview) vpaned = gtk.VPaned() vpaned.pack1(graphview, True, True) vpaned.pack2(scroller, True, True) vbox.pack_start(vpaned, True, True) frame.add(vbox) frame.show_all() hbox = gtk.HBox() lbl = gtk.Label(hglib.toutf(os.path.basename(path) + '@' + revid)) close = self.create_tab_close_button() close.connect('clicked', self.close_page, frame) hbox.pack_start(lbl, True, True, 2) hbox.pack_start(close, False, False) hbox.show_all() num = self.notebook.append_page_menu(frame, hbox, gtk.Label(hglib.toutf(path + '@' + revid))) if hasattr(self.notebook, 'set_tab_reorderable'): self.notebook.set_tab_reorderable(frame, True) self.notebook.set_current_page(num) graphview.connect('revision-selected', self.log_selection_changed, path) objs = (frame, treeview, path, graphview) graphview.treeview.connect('row-activated', self.log_activate, objs) graphview.treeview.connect('button-release-event', self.ann_button_release, objs) graphview.treeview.connect('popup-menu', self.ann_popup_menu, objs) treeview.connect("cursor-changed", self.ann_selection_changed) treeview.connect('button-release-event', self.ann_button_release, objs) treeview.connect('popup-menu', self.ann_popup_menu, objs) treeview.connect('row-activated', self.ann_row_act, objs) self.stbar.begin(msg=_('Loading history...'))
def add_search_page(self): frame = gtk.Frame() frame.set_border_width(10) vbox = gtk.VBox() search_hbox = gtk.HBox() regexp = gtk.Entry() includes = gtk.Entry() if self.cwd.startswith(self.repo.root): try: relpath = util.canonpath(self.repo.root, self.cwd, '.') includes.set_text(relpath) except util.Abort: # Some paths inside root are invalid (.hg/*) pass excludes = gtk.Entry() search = gtk.Button(_('Search')) search_hbox.pack_start(gtk.Label(_('Regexp:')), False, False, 4) search_hbox.pack_start(regexp, True, True, 4) search_hbox.pack_start(gtk.Label(_('Includes:')), False, False, 4) search_hbox.pack_start(includes, True, True, 4) search_hbox.pack_start(gtk.Label(_('Excludes:')), False, False, 4) search_hbox.pack_start(excludes, True, True, 4) search_hbox.pack_start(search, False, False, 4) self.tooltips.set_tip(search, _('Start this search')) self.tooltips.set_tip(regexp, _('Regular expression search pattern')) self.tooltips.set_tip(includes, _('Comma separated list of ' 'inclusion patterns. By default, the entire repository ' 'is searched.')) self.tooltips.set_tip(excludes, _('Comma separated list of ' 'exclusion patterns. Exclusion patterns are applied ' 'after inclusion patterns.')) vbox.pack_start(search_hbox, False, False, 4) hbox = gtk.HBox() follow = gtk.CheckButton(_('Follow copies and renames')) ignorecase = gtk.CheckButton(_('Ignore case')) linenum = gtk.CheckButton(_('Show line numbers')) showall = gtk.CheckButton(_('Show all matching revisions')) hbox.pack_start(follow, False, False, 4) hbox.pack_start(ignorecase, False, False, 4) hbox.pack_start(linenum, False, False, 4) hbox.pack_start(showall, False, False, 4) vbox.pack_start(hbox, False, False, 4) treeview = gtk.TreeView() treeview.get_selection().set_mode(gtk.SELECTION_SINGLE) treeview.set_rules_hint(True) treeview.set_property('fixed-height-mode', True) treeview.connect("cursor-changed", self.grep_selection_changed) treeview.connect('button-release-event', self.grep_button_release) treeview.connect('popup-menu', self.grep_popup_menu) treeview.connect('row-activated', self.grep_row_act) accelgroup = gtk.AccelGroup() self.add_accel_group(accelgroup) mod = gtklib.get_thg_modifier() key, modifier = gtk.accelerator_parse(mod+'d') treeview.add_accelerator('thg-diff', accelgroup, key, modifier, gtk.ACCEL_VISIBLE) treeview.connect('thg-diff', self.grep_thgdiff) results = gtk.ListStore(str, # revision id str, # matched line (utf-8) str, # description (utf-8, escaped) str) # file path (utf-8) treeview.set_model(results) treeview.set_search_equal_func(self.search_in_grep) for title, width, ttype, col, emode in ( (_('Rev'), 10, 'text', GCOL_REVID, pango.ELLIPSIZE_NONE), (_('File'), 25, 'text', GCOL_PATH, pango.ELLIPSIZE_START), (_('Matches'), 80, 'markup', GCOL_LINE, pango.ELLIPSIZE_END)): cell = gtk.CellRendererText() cell.set_property('width-chars', width) cell.set_property('ellipsize', emode) cell.set_property('family', 'Monospace') column = gtk.TreeViewColumn(title) column.set_resizable(True) column.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED) column.set_fixed_width(cell.get_size(treeview)[2]) column.pack_start(cell, expand=True) column.add_attribute(cell, ttype, col) treeview.append_column(column) if hasattr(treeview, 'set_tooltip_column'): treeview.set_tooltip_column(GCOL_DESC) scroller = gtk.ScrolledWindow() scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroller.add(treeview) vbox.pack_start(scroller, True, True) frame.add(vbox) frame.show_all() hbox = gtk.HBox() lbl = gtk.Label(_('Search %d') % self.newpagecount) close = self.create_tab_close_button() close.connect('clicked', self.close_page, frame) hbox.pack_start(lbl, True, True, 2) hbox.pack_start(close, False, False) hbox.show_all() num = self.notebook.append_page(frame, hbox) self.newpagecount += 1 objs = (treeview.get_model(), frame, regexp, follow, ignorecase, excludes, includes, linenum, showall, search_hbox) # Clicking 'search' or hitting Enter in any text entry triggers search search.connect('clicked', self.trigger_search, objs) regexp.connect('activate', self.trigger_search, objs) includes.connect('activate', self.trigger_search, objs) excludes.connect('activate', self.trigger_search, objs) # Includes/excludes must disable following copies objs = (includes, excludes, follow) includes.connect('changed', self.update_following_possible, objs) excludes.connect('changed', self.update_following_possible, objs) self.update_following_possible(includes, objs) if hasattr(self.notebook, 'set_tab_reorderable'): self.notebook.set_tab_reorderable(frame, True) self.notebook.set_current_page(num) regexp.grab_focus()
def get_body(self): embedded = bool(self.stbar) use_expander = embedded and self.ui.configbool( 'tortoisehg', 'changeset-expander') self.curfile = '' if self.repo.ui.configbool('tortoisehg', 'copyhash'): sel = (os.name == 'nt') and 'CLIPBOARD' or 'PRIMARY' self.clipboard = gtk.Clipboard(selection=sel) else: self.clipboard = None self.filemenu = self.file_context_menu() details_frame_parent = gtk.VBox() # changeset frame details_frame = gtk.Frame() details_frame.set_shadow_type(gtk.SHADOW_ETCHED_IN) scroller = gtk.ScrolledWindow() scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) details_frame.add(scroller) self.diffscroller = scroller details_box = gtk.VBox() scroller.add_with_viewport(details_box) scroller.child.set_shadow_type(gtk.SHADOW_NONE) ## changeset panel def revid_markup(revid, **kargs): opts = dict(face='monospace', size='9000') opts.update(kargs) return gtklib.markup(revid, **opts) def data_func(widget, item, ctx): def summary_line(desc): desc = hglib.tounicode(desc.replace('\0', '').split('\n')[0]) return hglib.toutf(desc[:80]) def revline_data(ctx, hl=False, branch=None): if isinstance(ctx, basestring): return ctx desc = ctx.description() return (str(ctx.rev()), str(ctx), summary_line(desc), hl, branch) if item == 'cset': return revline_data(ctx) elif item == 'branch': value = hglib.toutf(ctx.branch()) return value != 'default' and value or None elif item == 'parents': pindex = self.diff_other_parent() and 1 or 0 pctxs = ctx.parents() parents = [] for pctx in pctxs: highlight = len(pctxs) == 2 and pctx == pctxs[pindex] branch = None if hasattr(pctx, 'branch') and pctx.branch() != ctx.branch(): branch = pctx.branch() parents.append(revline_data(pctx, highlight, branch)) return parents elif item == 'children': children = [] for cctx in ctx.children(): branch = None if hasattr(cctx, 'branch') and cctx.branch() != ctx.branch(): branch = cctx.branch() children.append(revline_data(cctx, branch=branch)) return children elif item in ('transplant', 'p4', 'svn'): ts = widget.get_data(item, usepreset=True) if not ts: return None try: tctx = self.repo[ts] return revline_data(tctx) except (error.LookupError, error.RepoLookupError, error.RepoError): return ts elif item == 'patch': if hasattr(ctx, '_patchname'): desc = ctx.description() return (ctx._patchname, str(ctx), summary_line(desc)) return None raise csinfo.UnknownItem(item) def label_func(widget, item): if item == 'cset': return _('Changeset:') elif item == 'parents': return _('Parent:') elif item == 'children': return _('Child:') elif item == 'patch': return _('Patch:') raise csinfo.UnknownItem(item) def markup_func(widget, item, value): def revline_markup(revnum, revid, summary, highlight=None, branch=None): revnum = gtklib.markup(revnum) summary = gtklib.markup(summary) if revid: revid = revid_markup(revid) if branch: return '%s (%s) %s %s' % (revnum, revid, branch, summary) return '%s (%s) %s' % (revnum, revid, summary) else: if branch: return '%s - %s %s' % (revnum, branch, summary) return '%s - %s' % (revnum, summary) if item in ('cset', 'transplant', 'patch', 'p4', 'svn'): if isinstance(value, basestring): return revid_markup(value) return revline_markup(*value) elif item in ('parents', 'children'): csets = [] for cset in value: if isinstance(cset, basestring): csets.append(revid_markup(cset)) else: csets.append(revline_markup(*cset)) return csets raise csinfo.UnknownItem(item) def widget_func(widget, item, markups): def linkwidget(revnum, revid, summary, highlight=None, branch=None): # revision label opts = dict(underline='single', color=gtklib.BLUE) if highlight: opts['weight'] = 'bold' rev = '%s (%s)' % (gtklib.markup(revnum, **opts), revid_markup(revid, **opts)) revlabel = gtk.Label() revlabel.set_markup(rev) revlabel.set_selectable(True) revlabel.connect('button-release-event', self.link_event, revnum) # summary & branch label sum = gtklib.markup(summary) if branch: sum = gtklib.markup(branch, color=gtklib.NORMAL, background=gtklib.PGREEN) + ' ' + sum sumlabel = gtk.Label() sumlabel.set_markup(sum) sumlabel.set_selectable(True) box = gtk.HBox() box.pack_start(revlabel, False, False) box.pack_start(sumlabel, True, True, 4) return box def genwidget(param): if isinstance(param, basestring): label = gtk.Label() label.set_markup(param) label.set_selectable(True) return label return linkwidget(*param) if item in ('parents', 'children'): csets = widget.get_data(item) return [genwidget(cset) for cset in csets] elif item == 'transplant': cset = widget.get_data(item) return genwidget(cset) raise csinfo.UnknownItem(item) custom = csinfo.custom(data=data_func, label=label_func, markup=markup_func, widget=widget_func) self.csetstyle = csinfo.panelstyle(contents=('cset', 'branch', 'user', 'dateage', 'parents', 'children', 'tags', 'transplant', 'p4', 'svn'), selectable=True) self.patchstyle = csinfo.panelstyle(contents=('patch', 'branch', 'user', 'dateage', 'parents'), selectable=True) if use_expander: self.csetstyle['expander'] = True self.patchstyle['expander'] = True self.summarypanel = csinfo.create(self.repo, custom=custom) ## summary box (summarypanel + separator) self.summarybox = gtk.VBox() if use_expander: # don't scroll summarybox details_frame_parent.pack_start(self.summarybox, False, False) else: # scroll summarybox details_box.pack_start(self.summarybox, False, False) self.summarybox.pack_start(self.summarypanel, False, False) self.summarybox.pack_start(gtk.HSeparator(), False, False) ## changeset diff details_text = gtk.TextView() details_text.set_wrap_mode(gtk.WRAP_NONE) details_text.connect('populate-popup', self.add_to_popup) details_text.set_editable(False) details_text.modify_font(self.fonts['comment']) details_box.pack_start(details_text) self._buffer = gtk.TextBuffer() self.setup_tags() details_text.set_buffer(self._buffer) self.textview = details_text ## file list filelist_tree = gtk.TreeView() filelist_tree.set_headers_visible(False) filesel = filelist_tree.get_selection() filesel.connect('changed', self.filelist_rowchanged) self._filesel = filesel filelist_tree.connect('button-release-event', self.file_button_release) filelist_tree.connect('popup-menu', self.file_popup_menu) filelist_tree.connect('row-activated', self.file_row_act) filelist_tree.set_search_equal_func(self.search_filelist) filelist_tree.modify_font(self.fonts['list']) self._filelist_tree = filelist_tree accelgroup = gtk.AccelGroup() if self.glog_parent: self.glog_parent.add_accel_group(accelgroup) else: self.add_accel_group(accelgroup) mod = gtklib.get_thg_modifier() key, modifier = gtk.accelerator_parse(mod+'d') filelist_tree.add_accelerator('thg-diff', accelgroup, key, modifier, gtk.ACCEL_VISIBLE) filelist_tree.connect('thg-diff', self.thgdiff) def scroll_details(widget, direction=gtk.SCROLL_PAGE_DOWN): self.diffscroller.emit("scroll-child", direction, False) # signal, accelerator key, handler, (parameters,) status_accelerators = [ ('status-scroll-down', 'bracketright', scroll_details, (gtk.SCROLL_PAGE_DOWN,)), ('status-scroll-up', 'bracketleft', scroll_details, (gtk.SCROLL_PAGE_UP,)), ('status-next-file', 'period', gtklib.move_treeview_selection, (filelist_tree, 1)), ('status-previous-file', 'comma', gtklib.move_treeview_selection, (filelist_tree, -1)), ] for signal, accelerator, handler, param in status_accelerators: root = self.glog_parent or self gtklib.add_accelerator(root, signal, accelgroup, mod + accelerator) root.connect(signal, handler, *param) self._filelist = gtk.ListStore( gobject.TYPE_STRING, # MAR status gobject.TYPE_STRING, # filename (utf-8 encoded) gobject.TYPE_STRING, # filename ) filelist_tree.set_model(self._filelist) column = gtk.TreeViewColumn() filelist_tree.append_column(column) iconcell = gtk.CellRendererPixbuf() filecell = gtk.CellRendererText() column.pack_start(iconcell, expand=False) column.pack_start(filecell, expand=False) column.add_attribute(filecell, 'text', 1) size = gtk.ICON_SIZE_SMALL_TOOLBAR addedpixbuf = gtklib.get_icon_pixbuf('fileadd.ico', size) removedpixbuf = gtklib.get_icon_pixbuf('filedelete.ico', size) modifiedpixbuf = gtklib.get_icon_pixbuf('filemodify.ico', size) def cell_seticon(column, cell, model, iter): state = model.get_value(iter, 0) pixbuf = None if state == 'A': pixbuf = addedpixbuf elif state == 'R': pixbuf = removedpixbuf elif state == 'M': pixbuf = modifiedpixbuf cell.set_property('pixbuf', pixbuf) column.set_cell_data_func(iconcell, cell_seticon) list_frame = gtk.Frame() list_frame.set_shadow_type(gtk.SHADOW_ETCHED_IN) scroller = gtk.ScrolledWindow() scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) scroller.add(filelist_tree) flbox = gtk.VBox() list_frame.add(flbox) self.parent_box = gtk.VBox() flbox.pack_start(self.parent_box, False, False) flbox.pack_start(scroller) btn = gtk.CheckButton(_('Diff to second Parent')) btn.connect('toggled', self.parent_toggled) # don't pack btn yet to keep it initially invisible self.parent_button = btn self._hpaned = gtk.HPaned() self._hpaned.pack1(list_frame, True, True) self._hpaned.pack2(details_frame_parent, True, True) self._hpaned.set_position(self._setting_hpos) details_frame_parent.pack_start(details_frame, True, True) if embedded: # embedded by changelog browser return self._hpaned else: # add status bar for main app vbox = gtk.VBox() vbox.pack_start(self._hpaned, True, True) self.stbar = statusbar.StatusBar() self.stbar.show() vbox.pack_start(gtk.HSeparator(), False, False) vbox.pack_start(self.stbar, False, False) return vbox