Пример #1
0
    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
Пример #2
0
    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