示例#1
0
 def annotate_wait(self, thread, q, model, curdate, colormap, frame):
     """
     Handle all the messages currently in the queue (if any).
     """
     while q.qsize():
         line = q.get(0).rstrip('\r\n')
         try:
             (revpath, text) = line.split(':', 1)
             revid, path = revpath.lstrip().split(' ', 1)
             rowrev = long(revid)
         except ValueError:
             continue
         tip, user = self.get_rev_desc(rowrev)
         ctx = self.repo.changectx(rowrev)
         color = colormap.get_color(ctx, curdate)
         model.append((revid, toutf(text), tip, toutf(path.strip()),
                 color, toutf(user)))
     if thread.isAlive():
         return True
     else:
         if threading.activeCount() == 1:
             self.stop_button.set_sensitive(False)
         frame._mythread = None
         self.stbar.end()
         return False
示例#2
0
 def __init__(self, title, files, parent, primary=None):
     SimpleMessage.__init__(self, parent, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO)
     self.set_title(toutf("Confirm " + title))
     if primary is None:
         primary = title + " file" + ((len(files) > 1 and "s") or "") + "?"
     primary = "<b>" + primary + "</b>"
     self.set_markup(toutf(primary))
     message = ""
     for i, file in enumerate(files):
         message += "   " + file + "\n"
         if i == 9:
             message += "   ...\n"
             break
     self.format_secondary_text(toutf(message))
示例#3
0
 def prepare_diff(self, difflines, offset, fname):
     '''Borrowed from hgview; parses changeset diffs'''
     DIFFHDR = "=== %s ===\n"
     idx = 0
     outlines = []
     tags = []
     filespos = []
     def addtag( name, offset, length ):
         if tags and tags[-1][0] == name and tags[-1][2]==offset:
             tags[-1][2] += length
         else:
             tags.append( [name, offset, offset+length] )
     stats = [0,0]
     statmax = 0
     for i,l1 in enumerate(difflines):
         l = toutf(l1)
         if l.startswith("diff"):
             txt = toutf(DIFFHDR % fname)
             addtag( "greybg", offset, len(txt) )
             outlines.append(txt)
             markname = "file%d" % idx
             idx += 1
             statmax = max( statmax, stats[0]+stats[1] )
             stats = [0,0]
             filespos.append(( markname, offset, stats ))
             offset += len(txt.decode('utf-8'))
             continue
         elif l.startswith("+++"):
             continue
         elif l.startswith("---"):
             continue
         elif l.startswith("+"):
             tag = "green"
             stats[0] += 1
         elif l.startswith("-"):
             stats[1] += 1
             tag = "red"
         elif l.startswith("@@"):
             tag = "blue"
         else:
             tag = "black"
         l = l+"\n"
         length = len(l.decode('utf-8'))
         addtag( tag, offset, length )
         outlines.append( l )
         offset += length
     statmax = max( statmax, stats[0]+stats[1] )
     return filespos, tags, outlines, statmax
示例#4
0
        def dohgdiff():
            difftext = StringIO.StringIO()
            try:
                if len(files) != 0:
                    wfiles = [self.repo.wjoin(x) for x in files]
                    fns, matchfn, anypats = cmdutil.matchpats(self.repo, wfiles, self.opts)
                    patch.diff(self.repo, self._node1, self._node2, fns, match=matchfn,
                               fp=difftext, opts=patch.diffopts(self.ui, self.opts))

                buffer = gtk.TextBuffer()
                buffer.create_tag('removed', foreground='#900000')
                buffer.create_tag('added', foreground='#006400')
                buffer.create_tag('position', foreground='#FF8000')
                buffer.create_tag('header', foreground='#000090')

                difftext.seek(0)
                iter = buffer.get_start_iter()
                for line in difftext:
                    line = toutf(line)
                    if line.startswith('---') or line.startswith('+++'):
                        buffer.insert_with_tags_by_name(iter, line, 'header')
                    elif line.startswith('-'):
                        buffer.insert_with_tags_by_name(iter, line, 'removed')
                    elif line.startswith('+'):
                        buffer.insert_with_tags_by_name(iter, line, 'added')
                    elif line.startswith('@@'):
                        buffer.insert_with_tags_by_name(iter, line, 'position')
                    else:
                        buffer.insert(iter, line)

                self.diff_text.set_buffer(buffer)
            finally:
                difftext.close()
示例#5
0
    def get_diffs(self, iterator, nodes, pctx, buf, filelist):
        if self.curnodes != nodes:
            return False

        try:
            status, file, txt = iterator.next()
        except StopIteration:
            self.stbar.end()
            return False

        lines = txt.splitlines()
        eob = buf.get_end_iter()
        offset = eob.get_offset()
        fileoffs, tags, lines, statmax = self.prepare_diff(lines, offset, file)
        for l in lines:
            buf.insert(eob, l)

        # inserts the tags
        for name, p0, p1 in tags:
            i0 = buf.get_iter_at_offset(p0)
            i1 = buf.get_iter_at_offset(p1)
            txt = buf.get_text(i0, i1)
            buf.apply_tag_by_name(name, i0, i1)
            
        # inserts the marks
        for mark, offset, stats in fileoffs:
            pos = buf.get_iter_at_offset(offset)
            mark = 'mark_%d' % offset
            buf.create_mark(mark, pos)
            filelist.append((status, toutf(file), mark, True, stats))
        sob, eob = buf.get_bounds()
        buf.apply_tag_by_name("mono", pos, eob)
        return True
示例#6
0
 def _write(self, msg, append=True):
     msg = hglib.toutf(msg)
     if append:
         enditer = self.textbuffer.get_end_iter()
         self.textbuffer.insert(enditer, msg)
     else:
         self.textbuffer.set_text(msg)
示例#7
0
    def _do_reload_status(self):
        """Clear out the existing ListStore model and reload it from the repository status. 
        Also recheck and reselect files that remain in the list.
        """
        self.repo.dirstate.invalidate()
        self.repo.invalidate()

        # The following code was copied from the status function in mercurial\commands.py
        # and modified slightly to work here
        
        # node2 is None (the working dir) when 0 or 1 rev is specificed
        self._node1, self._node2 = cmdutil.revpair(self.repo, self.opts.get('rev'))
    
        files, matchfn, anypats = cmdutil.matchpats(self.repo, self.pats, self.opts)
        cwd = (self.pats and self.repo.getcwd()) or ''
        modified, added, removed, deleted, unknown, ignored, clean = [
            n for n in self.repo.status(node1=self._node1, node2=self._node2, files=files,
                                 match=matchfn,
                                 list_ignored=self.test_opt('ignored'),
                                 list_clean=self.test_opt('clean'))]

        changetypes = (('modified', 'M', modified),
                       ('added', 'A', added),
                       ('removed', 'R', removed),
                       ('deleted', '!', deleted),
                       ('unknown', '?', unknown),
                       ('ignored', 'I', ignored))
    
        explicit_changetypes = changetypes + (('clean', 'C', clean),)

        # List of the currently checked and selected files to pass on to the new data
        recheck = [entry[2] for entry in self.model if entry[0]]
        reselect = [self.model[iter][2] for iter in self.tree.get_selection().get_selected_rows()[1]]

        # Load the new data into the tree's model
        self.tree.hide()
        self.model.clear()
    
        for opt, char, changes in ([ct for ct in explicit_changetypes
                                    if self.test_opt(ct[0])] or changetypes) :
            for file in changes:
                file = util.localpath(file)
                self.model.append([file in recheck, char, toutf(file), file])

        self._update_check_count()
        
        selection = self.tree.get_selection()
        selected = False
        for row in self.model:
            if row[2] in reselect:
                selection.select_iter(row.iter)
                selected = True

        if not selected:
            selection.select_path((0,))

        self.tree.show()
        self.tree.grab_focus()
        return True
示例#8
0
 def write(self, msg, append=True):
     msg = toutf(msg)
     if append:
         enditer = self.textbuffer.get_end_iter()
         self.textbuffer.insert(enditer, msg)
         self.textview.scroll_to_mark(self.textbuffer.get_insert(), 0)
     else:
         self.textbuffer.set_text(msg)
示例#9
0
 def _grep_selection_changed(self, treeview):
     """
     Callback for when the user selects grep output.
     """
     (path, focus) = treeview.get_cursor()
     model = treeview.get_model()
     if path is not None and model is not None:
         iter = model.get_iter(path)
         self.currev = model[iter][self.COL_REVID]
         self.curpath = fromutf(model[iter][self.COL_PATH])
         self.stbar.set_status_text(toutf(model[iter][self.COL_TOOLTIP]))
示例#10
0
 def grep_wait(self, thread, q, model, search_hbox, regexp, frame):
     """
     Handle all the messages currently in the queue (if any).
     """
     while q.qsize():
         line = q.get(0).rstrip('\r\n')
         try:
             (path, revid, text) = line.split(':', 2)
         except ValueError:
             continue
         tip, user = self.get_rev_desc(long(revid))
         model.append((revid, toutf(text), tip, toutf(path)))
     if thread.isAlive():
         return True
     else:
         if threading.activeCount() == 1:
             self.stop_button.set_sensitive(False)
         frame._mythread = None
         search_hbox.set_sensitive(True)
         regexp.grab_focus()
         self.stbar.end()
         return False
示例#11
0
    def trigger_annotate(self, rev, objs):
        '''
        User has selected a file revision to annotate.  Trigger a
        background thread to perform the annotation.  Disable the select
        button until this operation is complete.
        '''
        (frame, model, path) = objs
        q = Queue.Queue()
        args = [self.repo.root, q, 'annotate', '--follow', '--number',
                '--rev', str(rev), path]
        thread = threading.Thread(target=hgcmd_toq, args=args)
        thread.start()
        frame._mythread = thread
        self.stop_button.set_sensitive(True)

        # date of selected revision
        ctx = self.repo.changectx(long(rev))
        curdate = ctx.date()[0]
        # date of initial revision
        fctx = self.repo.filectx(path, fileid=0)
        basedate = fctx.date()[0]
        agedays = (curdate - basedate) / (24 * 60 * 60)
        colormap = AnnotateColorSaturation(agedays)

        model.clear()
        self.stbar.begin()
        self.stbar.set_status_text(toutf('hg ' + ' '.join(args[2:])))

        hbox = gtk.HBox()
        lbl = gtk.Label(toutf(os.path.basename(path) + '@' + str(rev)))
        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()
        self.notebook.set_tab_label(frame, hbox)

        gobject.timeout_add(50, self.annotate_wait, thread, q, model,
                curdate, colormap, frame)
示例#12
0
 def log_selection_changed(self, graphview, path, label, button):
     row = graphview.get_revision()
     rev = row[treemodel.REVID]
     self.currev = str(rev)
     ctx = self.repo.changectx(rev)
     filectx = ctx.filectx(path)
     info = filectx.renamed()
     if info:
         (rpath, node) = info
         frev = self.repo.file(rpath).linkrev(node)
         button.set_label(toutf('%s@%s' % (rpath, frev)))
         button.show()
         button.set_sensitive(True)
         label.set_text('Follow Rename:')
     else:
         button.hide()
         button.set_sensitive(False)
         label.set_text('')
示例#13
0
 def process_queue(self):
     """
     Handle all the messages currently in the queue (if any).
     """
     self.hgthread.process_dialogs()
     enditer = self.textbuffer.get_end_iter()
     while self.hgthread.getqueue().qsize():
         try:
             msg = self.hgthread.getqueue().get(0)
             self.textbuffer.insert(enditer, toutf(msg))
             self.textview.scroll_to_mark(self.textbuffer.get_insert(), 0)
         except Queue.Empty:
             pass
     self.update_progress()
     if not self.hgthread.isAlive():
         self._button_ok.set_sensitive(True)
         self._button_stop.set_sensitive(False)            
         self.returncode = self.hgthread.return_code()
         if self.returncode is None:
             self.write("\n[command interrupted]")
         return False # Stop polling this function
     else:
         return True
示例#14
0
    def _fill_buffer(self, buf, rev, ctx, filelist):
        self.stbar.begin('Retrieving changeset data...')
        
        def title_line(title, text, tag):
            pad = ' ' * (12 - len(title))
            utext = toutf(title + pad + text)
            buf.insert_with_tags_by_name(eob, utext, tag)
            buf.insert(eob, "\n")

        # TODO: Add toggle for gmtime/localtime
        eob = buf.get_end_iter()
        date = time.strftime("%Y-%m-%d %H:%M:%S", time.gmtime(ctx.date()[0]))
        if self.clipboard:
            self.clipboard.set_text(short(ctx.node()))
        change = str(rev) + ':' + short(ctx.node())
        tags = ' '.join(ctx.tags())
        parents = self.parents

        title_line('changeset:', change, 'changeset')
        if ctx.branch() != 'default':
            title_line('branch:', ctx.branch(), 'greybg')
        title_line('user/date:', ctx.user() + '\t' + date, 'changeset')
        for p in parents:
            pctx = self.repo.changectx(p)
            summary = pctx.description().splitlines()[0]
            summary = toutf(summary)
            change = str(p) + ':' + short(self.repo.changelog.node(p))
            title = 'parent:'
            title += ' ' * (12 - len(title))
            buf.insert_with_tags_by_name(eob, title, 'parent')
            buf.insert_with_tags_by_name(eob, change, 'link')
            buf.insert_with_tags_by_name(eob, ' ' + summary, 'parent')
            buf.insert(eob, "\n")
        for n in self.repo.changelog.children(ctx.node()):
            cctx = self.repo.changectx(n)
            summary = cctx.description().splitlines()[0]
            summary = toutf(summary)
            childrev = self.repo.changelog.rev(n)
            change = str(childrev) + ':' + short(n)
            title = 'child:'
            title += ' ' * (12 - len(title))
            buf.insert_with_tags_by_name(eob, title, 'parent')
            buf.insert_with_tags_by_name(eob, change, 'link')
            buf.insert_with_tags_by_name(eob, ' ' + summary, 'parent')
            buf.insert(eob, "\n")
        for n in self.repo.changelog.children(ctx.node()):
            childrev = self.repo.changelog.rev(n)
        if tags: title_line('tags:', tags, 'tag')

        log = toutf(ctx.description())
        buf.insert(eob, '\n' + log + '\n\n')

        if self.parent_toggle.get_active():
            parent = self.repo.changelog.node(parents[1])
        elif parents:
            parent = self.repo.changelog.node(parents[0])
        else:
            parent = nullid

        buf.create_mark('begmark', buf.get_start_iter())
        filelist.append(('*', '[Description]', 'begmark', False, ()))
        pctx = self.repo.changectx(parent)

        nodes = parent, ctx.node()
        iterator = self.diff_generator(*nodes)
        gobject.idle_add(self.get_diffs, iterator, nodes, pctx, buf, filelist)
        self.curnodes = nodes
示例#15
0
 def title_line(title, text, tag):
     pad = ' ' * (12 - len(title))
     utext = toutf(title + pad + text)
     buf.insert_with_tags_by_name(eob, utext, tag)
     buf.insert(eob, "\n")
示例#16
0
 def __init__(self, title, message, parent):
     SimpleMessage.__init__(self, parent, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_CLOSE)
     self.set_title(toutf(title))
     self.set_markup("<b>" + toutf(message) + "</b>")
示例#17
0
    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.workingctx().parents()[0]
            try:
                fctx = ctx.filectx(path)
            except revlog.LookupError:
                Prompt('File is unrevisioned',
                        'Unable to annotate ' + path, self).run()
                return
            rev = fctx.filelog().linkrev(fctx.filenode())
            revid = str(rev)
        else:
            rev = long(revid)

        frame = gtk.Frame()
        frame.set_border_width(10)
        vbox = gtk.VBox()

        # File log revision graph
        graphview = TreeView(self.repo, 5000, self.stbar)
        graphview.connect('revisions-loaded', self.revisions_loaded, rev)
        graphview.refresh(True, None, {'filehist':path, 'filerev':rev})
        graphview.set_property('rev-column-visible', True)
        graphview.set_property('date-column-visible', True)

        hbox = gtk.HBox()
        followlabel = gtk.Label('')
        follow = gtk.Button('Follow')
        follow.connect('clicked', self.follow_rename)
        follow.hide()
        follow.set_sensitive(False)
        hbox.pack_start(gtk.Label(''), True, True)
        hbox.pack_start(followlabel, False, False)
        hbox.pack_start(follow, False, False)

        # 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)
        treeview.connect("cursor-changed", self._ann_selection_changed)
        treeview.connect('button-release-event', self._ann_button_release)
        treeview.connect('popup-menu', self._ann_popup_menu)
        treeview.connect('row-activated', self._ann_row_act)

        results = gtk.ListStore(str, str, str, str, str, str)
        treeview.set_model(results)

        context_menu = self.ann_header_context_menu(treeview)
        for title, width, col, emode, visible in (
                ('Rev', 10, self.COL_REVID, pango.ELLIPSIZE_NONE, True),
                ('File', 15, self.COL_PATH, pango.ELLIPSIZE_START, False),
                ('User', 15, self.COL_USER, pango.ELLIPSIZE_END, False),
                ('Matches', 80, self.COL_TEXT, 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", self.COL_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(self.COL_TOOLTIP)
        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)
        vbox.pack_start(hbox, False, False)
        frame.add(vbox)
        frame.show_all()

        hbox = gtk.HBox()
        lbl = gtk.Label(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(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, followlabel, follow)

        objs = (frame, treeview.get_model(), path)
        graphview.treeview.connect('row-activated', self.log_activate, objs)
        graphview.treeview.connect('button-release-event',
                self._ann_button_release)
        graphview.treeview.connect('popup-menu', self._ann_popup_menu)
示例#18
0
    def __init__(self, cmdline, progressbar=True, width=520, height=400):
        title = 'hg ' + ' '.join(cmdline[1:])
        gtk.Dialog.__init__(self,
                            title=title,
                            flags=gtk.DIALOG_MODAL, 
                            #buttons=(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)
                            )

        set_tortoise_icon(self, 'hg.ico')
        self.cmdline = cmdline
        self.returncode = None

        # construct dialog
        self.set_default_size(width, height)

        self._button_stop = gtk.Button("Stop")
        self._button_stop.connect('clicked', self._on_stop_clicked)
        self.action_area.pack_start(self._button_stop)
        
        self._button_ok = gtk.Button("Close")
        self._button_ok.connect('clicked', self._on_ok_clicked)
        self.action_area.pack_start(self._button_ok)

        self.connect('delete-event', self._delete)
        self.connect('response', self._response)

        self.pbar = None
        if progressbar:
            self.last_pbar_update = 0

            hbox = gtk.HBox()
            
            self.status_text = gtk.Label()
            self.status_text.set_text(toutf(" ".join(cmdline).replace("\n", " ")))
            self.status_text.set_alignment(0, 0.5)
            self.status_text.set_ellipsize(pango.ELLIPSIZE_END)
            hbox.pack_start(self.status_text, True, True, 3)

            # Create a centering alignment object
            align = gtk.Alignment(0.0, 0.0, 1, 0)
            hbox.pack_end(align, False, False, 3)
            align.show()
            
            # create the progress bar
            self.pbar = gtk.ProgressBar()
            align.add(self.pbar)
            self.pbar.pulse()
            self.pbar.show()

            self.vbox.pack_start(hbox, False, False, 3)

        scrolledwindow = gtk.ScrolledWindow()
        scrolledwindow.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        self.textview = gtk.TextView(buffer=None)
        self.textview.set_editable(False)
        self.textview.modify_font(pango.FontDescription("Monospace"))
        scrolledwindow.add(self.textview)
        self.textbuffer = self.textview.get_buffer()
        
        self.vbox.pack_start(scrolledwindow, True, True)
        self.connect('map_event', self._on_window_map_event)

        self.show_all()