Пример #1
0
    def __init__(self, resizable=False, norepo=False):
        gtk.Dialog.__init__(self)
        gtklib.set_tortoise_icon(self, self.get_icon())
        gtklib.set_tortoise_keys(self)
        self.set_resizable(resizable)
        self.set_has_separator(False)
        self.earlyout = False

        self.ui = ui.ui()
        if norepo:
            repo = None
        else:
            try:
                repo = hg.repository(self.ui, path=paths.find_root())
            except error.RepoError:
                gtklib.idle_add_single_call(self.destroy)
                return
        self.repo = repo
        self.after_done = True

        # persistent settings
        name = self.get_setting_name()
        if name:
            self.settings = settings.Settings(name)

        # signal handler
        self.connect('realize', self.realized)

        # disable entire dialog
        self.set_sensitive(False)
Пример #2
0
    def operation(self):
        fm = self.filetree.get_model()
        deleting = self.command == 'remove'
        list, dellist = [], []
        for row in fm:
            if not row[0]: continue
            if deleting and row[3] in (_('unknown'), _('ignored')):
                dellist.append(row[1])
            else:
                list.append(row[1])

        if not (list or dellist):
            gdialog.Prompt(_('No files selected'),
                           _('No operation to perform'), self).run()
            return

        for file in dellist:
            try:
                os.unlink(file)
            except EnvironmentError:
                pass

        if not list:
            gtklib.idle_add_single_call(self.response, gtk.RESPONSE_CLOSE)
            return

        # prepare command line
        cmdline = ['hg', self.command, '--verbose']
        if hasattr(self, 'nobackup') and self.nobackup.get_active():
            cmdline.append('--no-backup')
        cmdline.append('--')
        cmdline += list

        # execute command
        self.execute_command(cmdline, list)
Пример #3
0
 def list_pressed(self, list, event):
     x, y = int(event.x), int(event.y)
     pathinfo = list.get_path_at_pos(x, y)
     if event.button == 1:
         if not pathinfo:
             # HACK: clear selection after this function calling,
             # against selection by getting focus
             def unselect():
                 selection = list.get_selection()
                 selection.unselect_all()
             gtklib.idle_add_single_call(unselect)
     elif event.button == 3:
         if pathinfo:
             self.show_patch_cmenu(self.list, pathinfo[0])
Пример #4
0
    def __init__(self, extra=None):
        gtk.HBox.__init__(self)

        self.fields = {}
        self.boxes = {}

        self.idle_text = None
        self.timeout_id = None

        self.append_field('status', expand=True, sep=False)

        self.pbar = gtk.ProgressBar()
        self.pbar.set_no_show_all(True)
        self.append_widget(self.pbar, pack=gtk.PACK_START)

        gtklib.idle_add_single_call(self.after_init)
Пример #5
0
    def process_queue(self, callback, args, kargs):
        # process queue
        self.hgthread.process_dialogs()

        # output to buffer
        while self.hgthread.geterrqueue().qsize():
            try:
                msg = self.hgthread.geterrqueue().get(0)
                self.log.append(hglib.toutf(msg), error=True)
            except Queue.Empty:
                pass
        while self.hgthread.getqueue().qsize():
            try:
                msg, label = self.hgthread.getqueue().get(0)
                self.log.append(hglib.toutf(msg))
            except Queue.Empty:
                pass

        # update progress bar
        self.update_progress()

        # check thread
        if not self.hgthread.isAlive():
            returncode = self.hgthread.return_code()
            if returncode == 0 and not self.already_opened:
                self.set_pbar(False)
            else:
                self.set_pbar(True)
                self.switch_to(ready=True)
                self.set_buttons(stop=False, close=True)
            if returncode is None:
                self.log.append(_('\n[command interrupted]'))
            if not returncode == 0:
                self.show_log()
            self.hgthread = None
            def call_callback():
                callback(returncode, self.useraborted, *args, **kargs)
                self.useraborted = False
            gtklib.idle_add_single_call(call_callback)
            return False # Stop polling this function
        else:
            return True # Continue polling
Пример #6
0
    def list_pressed(self, list, event):
        x, y = int(event.x), int(event.y)
        pathinfo = list.get_path_at_pos(x, y)

        if event.button == 1:
            if not pathinfo:
                # HACK: clear selection after this function calling,
                # against selection by getting focus
                def unselect():
                    selection = list.get_selection()
                    selection.unselect_all()
                gtklib.idle_add_single_call(unselect)

        elif event.button == 3 and pathinfo:
            sel = list.get_selection()
            sel_rows = sel.get_selected_rows()[1] # list of paths
            if pathinfo[0] not in sel_rows:
                sel.unselect_all()
                sel.select_path(pathinfo[0])
            return True
Пример #7
0
    def realized(self, *args):
        # set title
        reponame = self.repo and hglib.get_reponame(self.repo) or ''
        self.set_title(self.get_title(reponame))

        # add user-defined buttons
        self.buttons = {}
        for name, label, res in self.get_buttons():
            btn = self.add_button(label, res)
            self.buttons[name] = btn

        # create Abort button (add later)
        btn = gtk.Button(_('Abort'))
        btn.connect('clicked', lambda *a: self.response(gtk.RESPONSE_CANCEL))
        self.buttons['abort'] = btn

        # construct dialog body
        self.get_body(self.vbox)
        if self.earlyout:
            gtklib.idle_add_single_call(self.destroy)
            return

        # load persistent settings
        self.load_settings()

        # dialog size
        defsize = self.get_defsize()
        if defsize != (-1, -1):
            self.set_default_size(*defsize)

        # signal handler
        self.connect('response', self.dialog_response)

        # prepare to show
        self.before_show()
        self.vbox.show_all()
        gtklib.idle_add_single_call(self.after_init)
Пример #8
0
    def process_queue(self, callback, args, kargs):
        # process queue
        self.hgthread.process_dialogs()

        # receive messages from queue
        while self.hgthread.getqueue().qsize():
            try:
                msg = hglib.toutf(self.hgthread.getqueue().get(0)[0])
                self.buffer.append((msg, LOG_NORMAL))
                self.dlg.log.append(msg)
            except Queue.Empty:
                pass
        while self.hgthread.geterrqueue().qsize():
            try:
                msg = hglib.toutf(self.hgthread.geterrqueue().get(0))
                self.buffer.append((msg, LOG_ERROR))
                self.dlg.log.append(msg, error=True)
            except Queue.Empty:
                pass

        # check thread state
        if not self.hgthread.isAlive():
            returncode = self.hgthread.return_code()
            self.hgthread = None
            if len(self.get_err_buffer()) > 0:
                self.show_log(True)
            if returncode == 0 and self.cmdlist:
                def call_next():
                    self.execute_next(callback, args, kargs)
                gtklib.idle_add_single_call(call_next)
            else:
                def call_callback():
                    callback(returncode, self.get_buffer(), *args, **kargs)
                gtklib.idle_add_single_call(call_callback)
            return False # Stop polling this function
        else:
            return True # Continue polling
Пример #9
0
    def __init__(self, root='', revargs=[]):
        """ Initialize the Dialog """
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)

        gtklib.set_tortoise_icon(self, 'hg.ico')
        gtklib.set_tortoise_keys(self)
        self.root = root
        self.revargs = revargs

        self.tbar = gtk.Toolbar()
        self.tips = gtklib.Tooltips()

        tbuttons = [
                self._toolbutton(gtk.STOCK_GOTO_LAST, _('Send'),
                                 self._on_send_clicked,
                                 _('Send emails')),
                self._toolbutton(gtk.STOCK_FIND, _('Test'),
                                 self._on_test_clicked,
                                 _('Show emails which would be sent')),
                gtk.SeparatorToolItem(),
                self._toolbutton(gtk.STOCK_PREFERENCES, _('Configure'),
                                 self._on_conf_clicked,
                                 _('Configure email settings'))
            ]
        for btn in tbuttons:
            self.tbar.insert(btn, -1)
        mainvbox = gtk.VBox()
        self.add(mainvbox)
        mainvbox.pack_start(self.tbar, False, False, 2)

        # set dialog title
        if revargs[0] in ('--outgoing', '-o'):
            self.set_title(_('Email outgoing changes'))
        elif revargs[0] in ('--rev', '-r'):
            self.set_title(_('Email revisions ') + ' '.join(revargs[1:]))
        else:
            self.set_title(_('Email Mercurial Patches'))
        self.set_default_size(650, 450)

        hbox = gtk.HBox()
        envframe = gtk.Frame(_('Envelope'))
        flagframe = gtk.Frame(_('Options'))
        hbox.pack_start(envframe, True, True, 4)
        hbox.pack_start(flagframe, False, False, 4)
        mainvbox.pack_start(hbox, False, True, 4)

        # Envelope settings
        table = gtklib.LayoutTable()
        envframe.add(table)

        ## To: combo box
        self._tolist = gtk.ListStore(str)
        self._tobox = gtk.ComboBoxEntry(self._tolist, 0)
        table.add_row(_('To:'), self._tobox, padding=False)

        ## Cc: combo box
        self._cclist = gtk.ListStore(str)
        self._ccbox = gtk.ComboBoxEntry(self._cclist, 0)
        table.add_row(_('Cc:'), self._ccbox, padding=False)

        ## From: combo box
        self._fromlist = gtk.ListStore(str)
        self._frombox = gtk.ComboBoxEntry(self._fromlist, 0)
        table.add_row(_('From:'), self._frombox, padding=False)

        ## In-Reply-To: entry
        self._replyto = gtk.Entry()
        table.add_row(_('In-Reply-To:'), self._replyto, padding=False)
        self.tips.set_tip(self._replyto,
            _('Message identifier to reply to, for threading'))

        # Options
        table = gtklib.LayoutTable()
        flagframe.add(table)

        self._normal = gtk.RadioButton(None, _('Send changesets as Hg patches'))
        table.add_row(self._normal)
        self.tips.set_tip(self._normal,
                _('Hg patches (as generated by export command) are compatible '
                  'with most patch programs.  They include a header which '
                  'contains the most important changeset metadata.'))

        self._git = gtk.RadioButton(self._normal,
                _('Use extended (git) patch format'))
        table.add_row(self._git)
        self.tips.set_tip(self._git,
                _('Git patches can describe binary files, copies, and '
                  'permission changes, but recipients may not be able to '
                  'use them if they are not using git or Mercurial.'))

        self._plain = gtk.RadioButton(self._normal,
                _('Plain, do not prepend Hg header'))
        table.add_row(self._plain)
        self.tips.set_tip(self._plain,
                _('Stripping Mercurial header removes username and parent '
                  'information.  Only useful if recipient is not using '
                  'Mercurial (and does not like to see the headers).'))

        self._bundle = gtk.RadioButton(self._normal,
                _('Send single binary bundle, not patches'))
        table.add_row(self._bundle)
        if revargs[0] in ('--outgoing', '-o'):
            self.tips.set_tip(self._bundle,
                _('Bundles store complete changesets in binary form. '
                  'Upstream users can pull from them. This is the safest '
                  'way to send changes to recipient Mercurial users.'))
        else:
            self._bundle.set_sensitive(False)
            self.tips.set_tip(self._bundle,
                _('This feature is only available when sending outgoing '
                  'changesets. It is not applicable with revision ranges.'))

        self._attach = gtk.CheckButton(_('attach'))
        self.tips.set_tip(self._attach,
                _('send patches as attachments'))
        self._inline = gtk.CheckButton(_('inline'))
        self.tips.set_tip(self._inline,
                _('send patches as inline attachments'))
        self._diffstat = gtk.CheckButton(_('diffstat'))
        self.tips.set_tip(self._diffstat,
                _('add diffstat output to messages'))
        table.add_row(self._attach, self._inline, self._diffstat, padding=False)

        # Subject combo
        vbox = gtk.VBox()
        hbox = gtk.HBox()
        self._subjlist = gtk.ListStore(str)
        self._subjbox = gtk.ComboBoxEntry(self._subjlist, 0)
        hbox.pack_start(gtk.Label(_('Subject:')), False, False, 4)
        hbox.pack_start(self._subjbox, True, True, 4)

        hglib.loadextension(ui.ui(), 'patchbomb')

        # --flags was added after hg 1.3
        hasflags = False
        for arg in extensions.find('patchbomb').emailopts:
            if arg[1] == 'flag':
                hasflags = True
                break
        self._flaglist = gtk.ListStore(str)
        self._flagbox = gtk.ComboBoxEntry(self._flaglist, 0)
        if hasflags:
            hbox.pack_start(gtk.Label(_('Flags:')), False, False, 4)
            hbox.pack_start(self._flagbox, False, False, 4)
        vbox.pack_start(hbox, False, False, 4)

        # Description TextView
        accelgroup = gtk.AccelGroup()
        self.add_accel_group(accelgroup)
        self.descview = textview.UndoableTextView(accelgroup=accelgroup)
        self.descview.set_editable(True)
        fontcomment = hglib.getfontconfig()['fontcomment']
        self.descview.modify_font(pango.FontDescription(fontcomment))
        self.descbuffer = self.descview.get_buffer()
        scrolledwindow = gtk.ScrolledWindow()
        scrolledwindow.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scrolledwindow.add(self.descview)
        frame = gtk.Frame(_('Patch Series (Bundle) Description'))
        frame.set_border_width(4)
        vbox.pack_start(scrolledwindow, True, True, 4)
        vbox.set_border_width(4)
        eventbox = gtk.EventBox()
        eventbox.add(vbox)
        frame.add(eventbox)
        self._eventbox = eventbox
        mainvbox.pack_start(frame, True, True, 4)
        gtklib.idle_add_single_call(self._refresh, True)
Пример #10
0
 def _drag_receive(self, widget, context, x, y, selection, targetType, time):
     if time != self.last_drop_time:
         files = selection.get_uris()
         gtklib.idle_add_single_call(self._set_path, files[0])
         self.last_drop_time = time
Пример #11
0
    def __init__(self, repo, accelgroup=None, tooltips=None):
        gtk.VBox.__init__(self)

        self.repo = repo
        self.mqloaded = hasattr(repo, 'mq')

        # top toolbar
        tbar = gtklib.SlimToolbar(tooltips)

        ## buttons
        self.btn = {}
        popallbtn = tbar.append_button(gtk.STOCK_GOTO_TOP,
                                      _('Unapply all patches'))
        popallbtn.connect('clicked', lambda *a: self.qpop(all=True))
        self.btn['popall'] = popallbtn

        popbtn = tbar.append_button(gtk.STOCK_GO_UP,
                                   _('Unapply last patch'))
        popbtn.connect('clicked', lambda *a: self.qpop())
        self.btn['pop'] = popbtn

        pushbtn = tbar.append_button(gtk.STOCK_GO_DOWN,
                                    _('Apply next patch'))
        pushbtn.connect('clicked', lambda *a: self.qpush())
        self.btn['push'] = pushbtn

        pushallbtn = tbar.append_button(gtk.STOCK_GOTO_BOTTOM,
                                       _('Apply all patches'))
        pushallbtn.connect('clicked', lambda *a: self.qpush(all=True))
        self.btn['pushall'] = pushallbtn

        ## separator
        tbar.append_space()

        ## drop-down menu
        menubtn = gtk.MenuToolButton('')
        menubtn.set_menu(self.create_view_menu())
        tbar.append_widget(menubtn, padding=0)
        self.btn['menu'] = menubtn
        def after_init():
            menubtn.child.get_children()[0].hide()
        gtklib.idle_add_single_call(after_init)
        self.pack_start(tbar, False, False)

        closebtn = tbar.append_button(gtk.STOCK_CLOSE, _('Close'))
        closebtn.connect('clicked', lambda *a: self.emit('close-mq'))
        self.btn['close'] = closebtn

        # center pane
        mainbox = gtk.VBox()
        self.pack_start(mainbox, True, True)

        ## scrolled pane
        pane = gtk.ScrolledWindow()
        pane.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        pane.set_shadow_type(gtk.SHADOW_IN)
        mainbox.pack_start(pane)

        ### patch list
        self.model = gtk.ListStore(int, # patch index
                                   str, # patch status
                                   str, # patch name
                                   str, # summary (utf-8)
                                   str) # escaped summary (utf-8)
        self.list = gtk.TreeView(self.model)
        self.list.set_row_separator_func(self.row_sep_func)
        # To support old PyGTK (<2.12)
        if hasattr(self.list, 'set_tooltip_column'):
            self.list.set_tooltip_column(MQ_ESCAPED)
        self.list.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
        if hasattr(self.list, 'set_rubber_banding'):
            self.list.set_rubber_banding(True)
        self.list.connect('cursor-changed', self.list_sel_changed)
        self.list.connect('button-press-event', self.list_pressed)
        self.list.connect('button-release-event', self.list_released)
        self.list.connect('row-activated', self.list_row_activated)
        self.list.connect('size-allocate', self.list_size_allocated)

        ### dnd setup for patch list
        targets = [('text/uri-list', 0, MQ_DND_URI_LIST)]
        self.list.drag_dest_set(gtk.DEST_DEFAULT_MOTION | \
             gtk.DEST_DEFAULT_DROP, targets, gtk.gdk.ACTION_MOVE)
        self.list.connect('drag-data-received', self.dnd_received)

        self.cols = {}
        self.cells = {}

        def addcol(header, col_idx, right=False, resizable=False,
                   editable=False, editfunc=None):
            header = (right and '%s ' or ' %s') % header
            cell = gtk.CellRendererText()
            if editfunc:
                cell.set_property('editable', editable)
                cell.connect('edited', editfunc)
            col = gtk.TreeViewColumn(header, cell)
            col.add_attribute(cell, 'text', col_idx)
            col.set_cell_data_func(cell, self.cell_data_func)
            col.set_resizable(resizable)
            col.set_visible(self.get_property(self.col_to_prop(col_idx)))
            if right:
                col.set_alignment(1)
                cell.set_property('xalign', 1)
            self.list.append_column(col)
            self.cols[col_idx] = col
            self.cells[col_idx] = cell

        def cell_edited(cell, path, newname):
            row = self.model[path]
            if row[MQ_INDEX] < 0:
                return
            patchname = row[MQ_NAME]
            if newname != patchname:
                self.qrename(newname, patch=patchname)

        addcol(_('#'), MQ_INDEX, right=True)
        addcol(_('st'), MQ_STATUS)
        addcol(_('Patch'), MQ_NAME, editfunc=cell_edited)
        addcol(_('Summary'), MQ_SUMMARY, resizable=True)

        pane.add(self.list)

        ## command widget
        self.cmd = hgcmd.CmdWidget(style=hgcmd.STYLE_COMPACT,
                                   tooltips=tooltips)
        mainbox.pack_start(self.cmd, False, False)

        # accelerators
        if accelgroup:
            key, mod = gtk.accelerator_parse('F2')
            self.list.add_accelerator('thg-rename', accelgroup,
                    key, mod, gtk.ACCEL_VISIBLE)
            def thgrename(list):
                sel = self.list.get_selection()
                if sel.count_selected_rows() == 1:
                    model, paths = sel.get_selected_rows()
                    self.qrename_ui(model[paths[0]][MQ_NAME])
            self.list.connect('thg-rename', thgrename)

            def add(name, key, mod, func, *args):
                self.list.add_accelerator(name, accelgroup, key, mod, 0)
                self.list.connect(name, lambda *a: func(*args))
            mod = gtk.gdk.CONTROL_MASK|gtk.gdk.SHIFT_MASK
            add('mq-move-top', gtk.keysyms.Page_Up, mod,
                self.qreorder_ui, MOVE_TOP)
            add('mq-move-up', gtk.keysyms.Up, mod,
                self.qreorder_ui, MOVE_UP)
            add('mq-move-down', gtk.keysyms.Down, mod,
                self.qreorder_ui, MOVE_DOWN)
            add('mq-move-bottom', gtk.keysyms.Page_Down, mod,
                self.qreorder_ui, MOVE_BOTTOM)
            mod = gtk.gdk.CONTROL_MASK
            add('mq-pop', gtk.keysyms.Up, mod, self.qpop)
            add('mq-push', gtk.keysyms.Down, mod, self.qpush)
Пример #12
0
    def __init__(self):
        'Initialize the Dialog'
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
        gtklib.set_tortoise_icon(self, 'detect_rename.ico')
        gtklib.set_tortoise_keys(self)

        try:
            repo = hg.repository(ui.ui(), path=paths.find_root())
        except error.RepoError:
            gtklib.idle_add_single_call(self.destroy)
            return
        self.repo = repo
        self.notify_func = None
        reponame = hglib.get_reponame(repo)
        self.set_title(_('Detect Copies/Renames in %s') % reponame)
        self.settings = settings.Settings('guess')
        dims = self.settings.get_value('dims', (800, 600))
        self.set_default_size(dims[0], dims[1])

        # vbox for dialog main & status bar
        mainvbox = gtk.VBox()
        self.add(mainvbox)

        # vsplit for top & diff
        self.vpaned = gtk.VPaned()
        mainvbox.pack_start(self.vpaned, True, True, 2)
        pos = self.settings.get_value('vpaned', None)
        if pos: self.vpaned.set_position(pos)

        # vbox for top contents
        topvbox = gtk.VBox()
        self.vpaned.pack1(topvbox, True, False)

        # frame for simularity
        frame = gtk.Frame(_('Minimum Simularity Percentage'))
        topvbox.pack_start(frame, False, False, 2)

        #$ simularity slider
        self.adjustment = gtk.Adjustment(50, 0, 100, 1)
        value = self.settings.get_value('percent', None)
        if value: self.adjustment.set_value(value)
        hscale = gtk.HScale(self.adjustment)
        frame.add(hscale)

        # horizontal splitter for unknown & candidate
        self.hpaned = gtk.HPaned()
        topvbox.pack_start(self.hpaned, True, True, 2)
        pos = self.settings.get_value('hpaned', None)
        if pos: self.hpaned.set_position(pos)

        #$ frame for unknown list
        unknownframe = gtk.Frame(_('Unrevisioned Files'))
        self.hpaned.pack1(unknownframe, True, True)

        #$$ vbox for unknown list & rename/copy buttons
        unkvbox = gtk.VBox()
        unknownframe.add(unkvbox)

        #$$$ scroll window for unknown list
        scroller = gtk.ScrolledWindow()
        unkvbox.pack_start(scroller, True, True, 2)
        scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)

        #$$$$ unknown list
        unkmodel = gtk.ListStore(str, # path
                                 str) # path (utf-8)
        self.unktree = gtk.TreeView(unkmodel)
        scroller.add(self.unktree)
        self.unktree.get_selection().set_mode(gtk.SELECTION_MULTIPLE)
        cell = gtk.CellRendererText()
        cell.set_property("ellipsize", pango.ELLIPSIZE_START)

        col = gtk.TreeViewColumn('File', cell, text=1)
        self.unktree.append_column(col)
        self.unktree.set_enable_search(True)
        self.unktree.set_headers_visible(False)

        #$$$ hbox for rename/copy buttons
        btnhbox = gtk.HBox()
        unkvbox.pack_start(btnhbox, False, False, 2)

        #$$$$ rename/copy buttons in unknown frame
        self.renamebtn = gtk.Button(_('Find Renames'))
        self.renamebtn.set_sensitive(False)
        btnhbox.pack_start(self.renamebtn, False, False, 2)
        self.copybtn = gtk.Button(_('Find Copies'))
        self.copybtn.set_sensitive(False)
        btnhbox.pack_start(self.copybtn, False, False, 2)

        #$ frame for candidate list
        candidateframe = gtk.Frame(_('Candidate Matches'))
        self.hpaned.pack2(candidateframe, True, True)

        #$$ vbox for candidate list & accept button
        canvbox = gtk.VBox()
        candidateframe.add(canvbox)

        #$$$ scroll window for candidate list
        scroller = gtk.ScrolledWindow()
        canvbox.pack_start(scroller, True, True, 2)
        scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)

        #$$$$ candidate list
        canmodel = gtk.ListStore(str,  # source
                                 str,  # source (utf-8)
                                 str,  # dest
                                 str,  # dest (utf-8)
                                 str,  # percent
                                 bool) # sensitive
        self.cantree = gtk.TreeView(canmodel)
        scroller.add(self.cantree)
        self.cantree.set_rules_hint(True)
        self.cantree.set_reorderable(False)
        self.cantree.set_enable_search(False)
        self.cantree.get_selection().set_mode(gtk.SELECTION_MULTIPLE)

        cell = gtk.CellRendererText()
        cell.set_property('width-chars', 30)
        cell.set_property('ellipsize', pango.ELLIPSIZE_START)
        col = gtk.TreeViewColumn(_('Source'), cell, text=1, sensitive=5)
        col.set_resizable(True)
        self.cantree.append_column(col)

        cell = gtk.CellRendererText()
        cell.set_property('width-chars', 30)
        cell.set_property('ellipsize', pango.ELLIPSIZE_START)
        col = gtk.TreeViewColumn(_('Dest'), cell, text=3, sensitive=5)
        col.set_resizable(True)
        self.cantree.append_column(col)

        cell = gtk.CellRendererText()
        cell.set_property('width-chars', 5)
        cell.set_property('ellipsize', pango.ELLIPSIZE_NONE)
        col = gtk.TreeViewColumn('%', cell, text=4, sensitive=5)
        col.set_resizable(True)
        self.cantree.append_column(col)

        #$$$ hbox for accept button
        btnhbox = gtk.HBox()
        canvbox.pack_start(btnhbox, False, False, 2)

        #$$$$ accept button in candidate frame
        self.acceptbtn = gtk.Button(_('Accept Match'))
        btnhbox.pack_start(self.acceptbtn, False, False, 2)
        self.acceptbtn.set_sensitive(False)

        # frame for diff
        diffframe = gtk.Frame(_('Differences from Source to Dest'))
        self.vpaned.pack2(diffframe)
        diffframe.set_shadow_type(gtk.SHADOW_ETCHED_IN)

        #$ scroll window for diff
        scroller = gtk.ScrolledWindow()
        diffframe.add(scroller)
        scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)

        #$$ text view for diff
        self.buf = gtk.TextBuffer()
        self.buf.create_tag('removed', foreground=gtklib.DRED)
        self.buf.create_tag('added', foreground=gtklib.DGREEN)
        self.buf.create_tag('position', foreground=gtklib.DORANGE)
        self.buf.create_tag('header', foreground=gtklib.DBLUE)
        diffview = gtk.TextView(self.buf)
        scroller.add(diffview)
        fontdiff = hglib.getfontconfig()['fontdiff']
        diffview.modify_font(pango.FontDescription(fontdiff))
        diffview.set_wrap_mode(gtk.WRAP_NONE)
        diffview.set_editable(False)

        # status bar
        self.stbar = statusbar.StatusBar()
        mainvbox.pack_start(self.stbar, False, False, 2)

        # register signal handlers
        self.copybtn.connect('pressed', lambda b: self.find_copies())
        self.renamebtn.connect('pressed', lambda b: self.find_renames())
        self.acceptbtn.connect('pressed', lambda b: self.accept_match())

        self.unktree.get_selection().connect('changed', self.unknown_sel_change)
        self.cantree.connect('row-activated', lambda t,p,c: self.accept_match())
        self.cantree.get_selection().connect('changed', self.show_diff)
        self.connect('delete-event', lambda *a: self.save_settings())
        gtklib.idle_add_single_call(self.refresh)
Пример #13
0
 def prepare_display(self):
     val = self.repo.ui.config('tortoisehg', 'ciexclude', '')
     self.excludes = [i.strip() for i in val.split(',') if i.strip()]
     gtklib.idle_add_single_call(self.realize_status_settings)
Пример #14
0
    def __init__(self, style=STYLE_NORMAL, tooltips=None, logsize=None):
        """
        style:    String. Predefined constans of CmdWidget style. Two styles,
                  STYLE_NORMAL (progress bar + popup log viewer) and
                  STYLE_COMPACT (progress bar + embedded log viewer) are
                  available. Default: STYLE_NORMAL.
        tooltips: Reference. gtk.Tooltips instance to show tooltips of several
                  buttons. If omitted, a new instance of gtk.Tooltips will be
                  created. Default: None.
        logsize:  Tuple or list containing two numbers. Specify the size of the
                  embedded log viewer. size[0] = width, size[1] = height.  
                  If you pass -1 as width or height size, it will be set to
                  the natural size of the widget. Default: tuple(-1, 180).
        """
        gtk.VBox.__init__(self)

        self.hgthread = None
        self.last_pbar_update = 0
        self.useraborted = False
        self.is_normal = style == STYLE_NORMAL
        self.is_compact = style == STYLE_COMPACT

        # tooltips
        if tooltips is None:
            tooltips = gtklib.Tooltips()

        # log viewer
        if self.is_normal:
            self.log = CmdLogWidget()
            if logsize is None:
                logsize = (-1, 180)
            self.log.set_size_request(logsize[0], logsize[1])
            self.log.size_request()
            self.pack_start(self.log)
        elif self.is_compact:
            self.dlg = CmdLogDialog()
            def close_hook(dialog):
                self.show_log(False)
                return False
            self.dlg.set_close_hook(close_hook)
            self.log = self.dlg.get_logwidget()
        else:
            raise _('unknown CmdWidget style: %s') % style

        # progress status frame
        statframe = gtk.Frame()
        statframe.set_border_width(4)
        statframe.set_shadow_type(gtk.SHADOW_NONE)
        self.pack_start(statframe, False, False)

        # progress bar box
        self.progbox = progbox = gtklib.SlimToolbar(tooltips)
        self.pack_start(progbox, False, False)

        def add_button(stock_id, tooltip, handler, toggle=False):
            btn = progbox.append_button(stock_id, tooltip, toggle)
            btn.connect('clicked', handler)
            return btn

        ## log toggle button
        self.log_btn = add_button(gtk.STOCK_JUSTIFY_LEFT,
                _('Toggle log window'), self.log_toggled, toggle=True)

        ## result frame
        self.rframe = gtk.Frame()
        progbox.append_widget(self.rframe, expand=True)
        self.rframe.set_shadow_type(gtk.SHADOW_IN)
        rhbox = gtk.HBox()
        self.rframe.add(rhbox)

        ### result label
        self.rlabel = gtk.Label()
        rhbox.pack_end(self.rlabel, True, True, 2)
        self.rlabel.set_alignment(0, 0.5)

        def after_init():
            # result icons
            self.icons = {}
            def add_icon(name, stock):
                img = gtk.Image()
                rhbox.pack_start(img, False, False, 2)
                img.set_from_stock(stock, gtk.ICON_SIZE_SMALL_TOOLBAR)
                self.icons[name] = img
            add_icon('succeed', gtk.STOCK_APPLY)
            add_icon('error', gtk.STOCK_DIALOG_ERROR)

            # progres status label
            self.progstat = gtk.Label()
            statframe.add(self.progstat)
            self.progstat.set_alignment(0, 0.5)
            self.progstat.set_ellipsize(pango.ELLIPSIZE_END)
            self.progstat.hide()

            # progress bar
            self.pbar = gtk.ProgressBar()
            progbox.append_widget(self.pbar, expand=True)
            self.pbar.hide()

            # stop & close buttons
            if self.is_compact:
                self.stop_btn = add_button(gtk.STOCK_STOP,
                        _('Stop transaction'), self.stop_clicked)
                self.close_btn = add_button(gtk.STOCK_CLOSE,
                        _('Close this'), self.close_clicked)

            self.set_buttons(stop=False)
            if self.is_normal:
                self.show_log(False)
            if self.is_compact:
                self.set_pbar(False)
        gtklib.idle_add_single_call(after_init)
Пример #15
0
    def __init__(self, repos=[], pushmode=False):
        """ Initialize the Dialog. """
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
        gtklib.set_tortoise_icon(self, 'menusynch.ico')
        gtklib.set_tortoise_keys(self)

        self.root = paths.find_root()
        self.selected_path = None
        self.hgthread = None
        self.notify_func = None
        self.last_drop_time = None
        self.lastcmd = []

        # persistent app data
        self._settings = settings.Settings('synch')
        self.set_default_size(655, 552)

        self.paths = self.get_paths()
        self.set_title(_('%s - synchronize') % hglib.get_reponame(self.repo))

        self.connect('delete-event', self.delete)

        # toolbar
        self.tbar = gtk.Toolbar()
        self.tips = gtklib.Tooltips()
        self.stop_button = self.toolbutton(gtk.STOCK_STOP,
                _('Stop'), self.stop_clicked, tip=_('Stop the hg operation'))
        self.stop_button.set_sensitive(False)
        tbuttons = [
                self.toolbutton(gtk.STOCK_GO_DOWN,
                                 _('Incoming'),
                                 self.incoming_clicked,
                                 tip=_('Display changes that can be pulled '
                                       'from selected repository')),
                self.toolbutton(gtk.STOCK_GOTO_BOTTOM,
                                 _('   Pull   '),
                                 self.pull_clicked,
                                 tip=_('Pull changes from selected '
                                       'repository')),
                gtk.SeparatorToolItem(),
                self.toolbutton(gtk.STOCK_GO_UP,
                                 _('Outgoing'),
                                 self.outgoing_clicked,
                                 tip=_('Display local changes that will be '
                                       'pushed to selected repository')),
                self.toolbutton(gtk.STOCK_GOTO_TOP,
                                 _('Push'),
                                 self.push_clicked,
                                 tip=_('Push local changes to selected '
                                       'repository')),
                self.toolbutton(gtk.STOCK_GOTO_LAST,
                                 _('Email'),
                                 self.email_clicked,
                                 tip=_('Email local outgoing changes to '
                                       'one or more recipients')),
                self.toolbutton(gtk.STOCK_UNDO,
                                 _('Shelve'),
                                 self.shelve_clicked,
                                 tip=_('Shelve uncommited changes')),
                gtk.SeparatorToolItem(),
                self.stop_button,
                gtk.SeparatorToolItem(),
                self.toolbutton(gtk.STOCK_PREFERENCES,
                                 _('Configure'),
                                 self.conf_clicked,
                                 tip=_('Configure peer repository paths')),
                gtk.SeparatorToolItem(),
            ]
        for btn in tbuttons:
            self.tbar.insert(btn, -1)

        # Base box
        self.basevbox = basevbox = gtk.VBox()
        self.add(basevbox)
        basevbox.pack_start(self.tbar, False, False, 2)

        # Sync Target Path
        targethbox = gtk.HBox()

        ## target selection buttons
        lbl = gtk.Button(_('Repo:'))
        lbl.unset_flags(gtk.CAN_FOCUS)
        lbl.connect('clicked', self.btn_remotepath_clicked)
        targethbox.pack_start(lbl, False, False)

        lbl = gtk.Button(_('Bundle:'))
        lbl.unset_flags(gtk.CAN_FOCUS)
        lbl.connect('clicked', self.btn_bundlepath_clicked)
        targethbox.pack_start(lbl, False, False)

        ## target path combobox
        self.pathlist = gtk.ListStore(str, str)
        self.pathbox = gtk.ComboBoxEntry(self.pathlist, 0)
        self.pathtext = self.pathbox.get_child()
        cell = gtk.CellRendererText()
        self.pathbox.pack_end(cell, False)
        self.pathbox.add_attribute(cell, 'text', 1)
        targethbox.pack_start(self.pathbox, True, True)

        self.fill_path_combo()
        defrow = None
        defpushrow = None
        for i, (path, alias) in enumerate(self.pathlist):
            if alias == 'default':
                defrow = i
                if defpushrow is None:
                    defpushrow = i
            elif alias == 'default-push':
                defpushrow = i

        if repos:
            self.pathtext.set_text(hglib.toutf(repos[0]))
        elif defpushrow is not None and pushmode:
            self.pathbox.set_active(defpushrow)
        elif defrow is not None:
            self.pathbox.set_active(defrow)

        exs = [ name for name, module in extensions.extensions() ]

        # Post Pull Operation
        ppullhbox = gtk.HBox()
        self.ppulldata = [('none', _('Nothing')), ('update', _('Update'))]
        cfg = self.repo.ui.config('tortoisehg.postpull', 'none')
        if 'fetch' in exs or 'fetch' == cfg:
            self.ppulldata.append(('fetch', _('Fetch')))
        if 'rebase' in exs or 'rebase' == cfg:
            self.ppulldata.append(('rebase', _('Rebase')))
        self.ppullcombo = combo = gtk.combo_box_new_text()
        for (index, (name, label)) in enumerate(self.ppulldata):
            combo.insert_text(index, label)
        ppullhbox.pack_start(gtk.Label(_('Post Pull: ')), False, False, 2)
        ppullhbox.pack_start(self.ppullcombo, True, True)

        # Fixed options box (non-foldable)
        fixedhbox = gtk.HBox()
        fixedhbox.pack_start(targethbox, True, True, 2)
        fixedhbox.pack_start(ppullhbox, False, False, 2)

        # Advanced options (foldable)
        opthbox = gtk.HBox()
        self.expander = expander = gtk.Expander(_('Advanced Options'))
        expander.set_expanded(False)
        expander.connect_after('activate', self.expanded)
        expander.add(opthbox)

        ## checkbox options
        chkopthbox = gtk.HBox()
        self.force = gtk.CheckButton(_('Force pull or push'))
        self.tips.set_tip(self.force,
                          _('Run even when remote repository is unrelated.'))
        self.newbranch = gtk.CheckButton(_('Push new branch'))
        self.tips.set_tip(self.newbranch, _('Allow pushing a new branch'))
        self.use_proxy = gtk.CheckButton(_('Use proxy server'))
        if ui.ui().config('http_proxy', 'host', ''):
            self.use_proxy.set_active(True)
        else:
            self.use_proxy.set_sensitive(False)
        chkopthbox.pack_start(self.force, False, False, 4)
        chkopthbox.pack_start(self.newbranch, False, False, 4)
        chkopthbox.pack_start(self.use_proxy, False, False, 4)

        ## target revision option
        revhbox = gtk.HBox()
        self.reventry = gtk.Entry()
        revhbox.pack_start(gtk.Label(_('Target revision:')), False, False, 2)
        revhbox.pack_start(self.reventry, True, True, 2)
        reveventbox = gtk.EventBox()
        reveventbox.add(revhbox)
        self.tips.set_tip(reveventbox,
                          _('A specific revision up to which you '
                            'would like to push or pull.'))

        ## remote command option
        cmdhbox = gtk.HBox()
        self.cmdentry = gtk.Entry()
        cmdhbox.pack_start(gtk.Label(_('Remote command:')), False, False, 2)
        cmdhbox.pack_start(self.cmdentry, True, True, 2)
        cmdeventbox = gtk.EventBox()
        cmdeventbox.add(cmdhbox)
        self.tips.set_tip(cmdeventbox,
                          _('Name of hg executable on remote machine.'))

        revvbox = gtk.VBox()
        revvbox.pack_start(chkopthbox, False, False, 8)
        revvbox.pack_start(reveventbox, False, False, 4)
        revvbox.pack_start(cmdeventbox, False, False, 4)
        opthbox.pack_start(revvbox, True, True, 4)

        ## incoming/outgoing options
        frame = gtk.Frame(_('Incoming/Outgoing'))
        opthbox.pack_start(frame, False, False, 2)

        self.showpatch = gtk.CheckButton(_('Show patches'))
        self.newestfirst = gtk.CheckButton(_('Show newest first'))
        self.nomerge = gtk.CheckButton(_('Show no merges'))

        iovbox = gtk.VBox()
        iovbox.pack_start(self.showpatch, False, False, 2)
        iovbox.pack_start(self.newestfirst, False, False, 2)
        iovbox.pack_start(self.nomerge, False, False, 2)
        frame.add(iovbox)

        # Main option box
        topvbox = gtk.VBox()
        topvbox.pack_start(fixedhbox, True, True, 2)
        topvbox.pack_start(expander, False, False, 2)
        basevbox.pack_start(topvbox, False, False, 2)

        # hg output window
        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)
        fontlog = hglib.getfontconfig()['fontlog']
        self.textview.modify_font(pango.FontDescription(fontlog))
        scrolledwindow.add(self.textview)
        self.textview.connect('populate-popup', self.add_to_popup)
        self.textbuffer = self.textview.get_buffer()
        gtklib.configstyles(self.repo.ui)
        for tag, argdict in gtklib.TextBufferTags.iteritems():
            self.textbuffer.create_tag(tag, **argdict)
        basevbox.pack_start(scrolledwindow, True, True)

        # statusbar
        self.stbar = statusbar.StatusBar()
        basevbox.pack_end(self.stbar, False, False, 2)

        # support dropping of repos or bundle files
        self.drag_dest_set(gtk.DEST_DEFAULT_ALL,
                [("text/uri-list", 0, 1)], gtk.gdk.ACTION_COPY)
        self.connect('drag_data_received', self._drag_receive)

        # prepare to show
        self.load_settings()
        self.update_pull_setting()
        gtklib.idle_add_single_call(self.finalize_startup)
Пример #16
0
    def __init__(self, fileglob='', *pats):
        'Initialize the Dialog'
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
        gtklib.set_tortoise_icon(self, 'ignore.ico')
        gtklib.set_tortoise_keys(self)
        self.set_default_size(630, 400)

        try:
            repo = hg.repository(ui.ui(), path=paths.find_root())
        except error.RepoError:
            gtklib.idle_add_single_call(self.destroy)
            return
        self.repo = repo
        self.set_title(_('Ignore filter - %s') % hglib.get_reponame(repo))
        self.notify_func = None

        # vbox for dialog main
        mainvbox = gtk.VBox()
        self.add(mainvbox)
        mainvbox.set_border_width(2)

        ## layout table for top
        table = gtklib.LayoutTable()
        mainvbox.pack_start(table, False, False)

        ### hbox for glob entry
        self.glob_entry = gtk.Entry()
        self.glob_entry.set_text(hglib.toutf(fileglob))
        self.glob_entry.connect('activate', self.add_glob)
        glob_button = gtk.Button(_('Add'))
        glob_button.connect('clicked', self.add_glob)
        table.add_row(_('Glob:'), self.glob_entry, 0,
                      glob_button, expand=0)

        ### hbox for regexp entry
        self.regexp_entry = gtk.Entry()
        self.regexp_entry.connect('activate', self.add_regexp)
        regexp_button = gtk.Button(_('Add'))
        regexp_button.connect('clicked', self.add_regexp)
        table.add_row(_('Regexp:'), self.regexp_entry, 0,
                      regexp_button, expand=0)

        ignorefiles = [repo.wjoin('.hgignore')]
        for name, value in repo.ui.configitems('ui'):
            if name == 'ignore' or name.startswith('ignore.'):
                ignorefiles.append(os.path.expanduser(value))

        ### ignore file combo if needs
        if len(ignorefiles) > 1:
            # file selector
            combo = gtk.combo_box_new_text()
            for f in ignorefiles:
                combo.append_text(hglib.toutf(f))
            combo.set_active(0)
            combo.connect('changed', self.file_selected)
            # edit button
            edit = gtk.Button(_('Edit File'))
            edit.connect('clicked', self.edit_clicked)
            table.add_row(_('Apply to:'), combo, 0, edit,
                          padding=False, expand=0)
        self.ignorefile = ignorefiles[0]

        ## hbox for filter & unknown list
        hbox = gtk.HBox()
        mainvbox.pack_start(hbox, True, True)

        ### frame for filter list & button
        frame = gtk.Frame(_('Filters'))
        hbox.pack_start(frame, True, True, 4)
        vbox = gtk.VBox()
        frame.add(vbox)
        vbox.set_border_width(2)

        #### filter list
        scrolledwindow = gtk.ScrolledWindow()
        vbox.pack_start(scrolledwindow, True, True, 2)
        scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scrolledwindow.set_border_width(4)
        pattree = gtk.TreeView()
        scrolledwindow.add(pattree)
        pattree.set_enable_search(False)
        pattree.set_reorderable(False)
        pattree.get_selection().set_mode(gtk.SELECTION_SINGLE)
        col = gtk.TreeViewColumn(_('Patterns'), gtk.CellRendererText(), text=0)
        pattree.append_column(col)
        pattree.set_headers_visible(False)
        self.pattree = pattree

        #### remove button
        bhbox = gtk.HBox()
        vbox.pack_start(bhbox, False, False, 2)
        self.removebtn = gtk.Button(_('Remove Selected'))
        bhbox.pack_start(self.removebtn, False, False, 2)
        self.removebtn.connect('clicked', self.remove_clicked)
        self.removebtn.set_sensitive(False)

        ### frame for unknown file list & button
        frame = gtk.Frame(_('Unknown Files'))
        hbox.pack_start(frame, True, True, 4)
        vbox = gtk.VBox()
        frame.add(vbox)
        vbox.set_border_width(2)

        #### unknown file list
        scrolledwindow = gtk.ScrolledWindow()
        vbox.pack_start(scrolledwindow, True, True, 2)
        scrolledwindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scrolledwindow.set_border_width(4)
        unktree = gtk.TreeView()
        scrolledwindow.add(unktree)
        unktree.set_search_equal_func(self.unknown_search)
        col = gtk.TreeViewColumn(_('Files'), gtk.CellRendererText(), text=0)
        unktree.append_column(col)
        model = gtk.ListStore(str, str)
        unktree.set_model(model)
        unktree.set_headers_visible(False)
        self.unkmodel = model

        #### refresh button
        bhbox = gtk.HBox()
        vbox.pack_start(bhbox, False, False, 2)
        refresh = gtk.Button(_('Refresh'))
        bhbox.pack_start(refresh, False, False, 2)
        refresh.connect('pressed', lambda b: self.refresh())
        self.connect('thg-refresh', lambda w: self.refresh())

        # register signal handlers
        pattree.get_selection().connect('changed', self.pattree_rowchanged)
        unktree.get_selection().connect('changed', self.unknown_rowchanged)

        # prepare to show
        self.glob_entry.grab_focus()
        gtklib.idle_add_single_call(self.refresh)
Пример #17
0
    def __init__(self, parentwin, repo, statusbar, accelgroup=None, tooltips=None):
        gtk.VBox.__init__(self)

        self.parent_window = parentwin
        self.repo = repo
        self.pbranch = extensions.find('pbranch')
        self.statusbar = statusbar

        # top toolbar
        tbar = gtklib.SlimToolbar(tooltips)

        ## buttons
        self.btn = {}
        pmergebtn = tbar.append_button(gtk.STOCK_CONVERT,
                                      _('Merge all pending dependencies'))
        pmergebtn.connect('clicked', self.pmerge_clicked)
        self.btn['pmerge'] = pmergebtn

        pbackoutbtn = tbar.append_button(gtk.STOCK_GO_BACK,
                                   _('Backout current patch branch'))
        pbackoutbtn.connect('clicked', self.pbackout_clicked)
        self.btn['pbackout'] = pbackoutbtn

        reapplybtn = gtk.ToolButton(gtk.STOCK_GO_FORWARD)
        reapplybtn = tbar.append_button(gtk.STOCK_GO_FORWARD,
                                    _('Backport part of a changeset to a dependency'))
        reapplybtn.connect('clicked', self.reapply_clicked)
        self.btn['reapply'] = reapplybtn

        pnewbtn = tbar.append_button(gtk.STOCK_NEW,
                                       _('Start a new patch branch'))
        pnewbtn.connect('clicked', self.pnew_clicked)
        self.btn['pnew'] = pnewbtn

        pgraphbtn = tbar.append_button(gtk.STOCK_EDIT,
                                       _('Edit patch dependency graph'))
        pgraphbtn.connect('clicked', self.edit_pgraph_clicked)
        self.btn['pnew'] = pnewbtn

        ## separator
        tbar.append_space()

        ## drop-down menu
        menubtn = gtk.MenuToolButton('')
        menubtn.set_menu(self.create_view_menu())
        tbar.append_widget(menubtn, padding=0)
        self.btn['menu'] = menubtn
        def after_init():
            menubtn.child.get_children()[0].hide()
        gtklib.idle_add_single_call(after_init)
        self.pack_start(tbar, False, False)

        # center pane
        mainbox = gtk.VBox()
        self.pack_start(mainbox, True, True)

        ## scrolled pane
        pane = gtk.ScrolledWindow()
        pane.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        pane.set_shadow_type(gtk.SHADOW_IN)
        mainbox.pack_start(pane)

        ### patch list
        #### patch list model
        self.model = gtk.ListStore(
                gobject.TYPE_PYOBJECT, # node info
                gobject.TYPE_PYOBJECT, # in-lines
                gobject.TYPE_PYOBJECT, # out-lines
                str, # patch name
                str, # patch status
                str, # patch title
                str, # patch message
                str) # patch message escaped
        #### patch list view
        self.list = gtk.TreeView(self.model)
        # To support old PyGTK (<2.12)
        if hasattr(self.list, 'set_tooltip_column'):
            self.list.set_tooltip_column(M_MSGESC)
        self.list.connect('cursor-changed', self.list_sel_changed)
        self.list.connect('button-press-event', self.list_pressed)
        self.list.connect('row-activated', self.list_row_activated)
        self.list.connect('size-allocate', self.list_size_allocated)

        #### patch list columns
        self.cols = {}
        self.cells = {}

        def addcol(header, col_idx, model_idx=None, right=False, resizable=False,
                   editable=False, editfunc=None, cell_renderer=None,
                   properties=[]):
            header = (right and '%s ' or ' %s') % header
            cell = cell_renderer or gtk.CellRendererText()
            if editfunc:
                cell.set_property('editable', editable)
                cell.connect('edited', editfunc)
            col = gtk.TreeViewColumn(header, cell)
            if cell_renderer is None:
                col.add_attribute(cell, 'text', model_idx)
            col.set_resizable(resizable)
            col.set_visible(self.get_property(self.col_to_prop(col_idx)))
            if right:
                col.set_alignment(1)
                cell.set_property('xalign', 1)
            for (property_name, model_index) in properties:
                col.add_attribute(cell, property_name, model_index)
            self.list.append_column(col)
            self.cols[col_idx] = col
            self.cells[col_idx] = cell

        def cell_edited(cell, path, newname):
            row = self.model[path]
            patchname = row[M_NAME]
            if newname != patchname:
                self.qrename(newname, patch=patchname)

        #### patch list columns and cell renderers

        addcol(_('Graph'), C_GRAPH, resizable=True, 
            cell_renderer=graphcell.CellRendererGraph(),
            properties=[("node", M_NODE), 
                        ("in-lines",M_IN_LINES), 
                        ("out-lines", M_OUT_LINES)]
            )
        addcol(_('St'), C_STATUS, M_STATUS)
        addcol(_('Name'), C_NAME, M_NAME, editfunc=cell_edited)
        addcol(_('Title'), C_TITLE, M_TITLE)
        addcol(_('Message'), C_MSG, M_MSG)

        pane.add(self.list)

        ## command widget
        self.cmd = hgcmd.CmdWidget(style=hgcmd.STYLE_COMPACT,
                                   tooltips=tooltips)
        mainbox.pack_start(self.cmd, False, False)

        # accelerator
        if accelgroup:
            # TODO
            pass
Пример #18
0
    def __init__(self):
        """ Initialize the Dialog. """
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
        gtklib.set_tortoise_icon(self, 'general.ico')
        gtklib.set_tortoise_keys(self)
        self.set_default_size(600, 400)
        self.connect('delete-event', self._delete)
        self.hgthread = None
        self.inprogress = False
        self.last_pbar_update = 0

        try:
            repo = hg.repository(ui.ui(), path=paths.find_root())
        except error.RepoError:
            gtklib.idle_add_single_call(self.destroy)
            return
        self.repo = repo
        self.reponame = hglib.get_reponame(repo)
        self.set_title(_('%s - recovery') % self.reponame)

        # toolbar
        self.tbar = gtk.Toolbar()
        self.tips = gtklib.Tooltips()
        self._stop_button = self._toolbutton(gtk.STOCK_STOP,
                _('Stop'), self._stop_clicked, tip=_('Stop the hg operation'))
        self._stop_button.set_sensitive(False)
        tbuttons = [
                self._toolbutton(gtk.STOCK_CLEAR,
                                 _('Clean'),
                                 self._clean_clicked,
                                 tip=_('Clean checkout, undo all changes')),
                gtk.SeparatorToolItem(),
                self._toolbutton(gtk.STOCK_UNDO,
                                 _('Rollback'),
                                 self._rollback_clicked,
                                 tip=_('Rollback (undo) last transaction to '
                                       'repository (pull, commit, etc)')),
                gtk.SeparatorToolItem(),
                self._toolbutton(gtk.STOCK_CLEAR,
                                 _('Recover'),
                                 self._recover_clicked,
                                 tip=_('Recover from interrupted operation')),
                gtk.SeparatorToolItem(),
                self._toolbutton(gtk.STOCK_APPLY,
                                 _('Verify'),
                                 self._verify_clicked,
                                 tip=_('Validate repository consistency')),
                gtk.SeparatorToolItem(),
                self._stop_button,
                gtk.SeparatorToolItem(),
            ]
        for btn in tbuttons:
            self.tbar.insert(btn, -1)
        vbox = gtk.VBox()
        self.add(vbox)
        vbox.pack_start(self.tbar, False, False, 2)

        # hg output window
        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)
        fontlog = hglib.getfontconfig()['fontlog']
        self.textview.modify_font(pango.FontDescription(fontlog))
        scrolledwindow.add(self.textview)
        self.textbuffer = self.textview.get_buffer()
        gtklib.configstyles(repo.ui)
        for tag, argdict in gtklib.TextBufferTags.iteritems():
            self.textbuffer.create_tag(tag, **argdict)
        vbox.pack_start(scrolledwindow, True, True)

        self.progstat = gtk.Label()
        vbox.pack_start(self.progstat, False, False, 0)
        self.progstat.set_alignment(0, 0.5)
        self.progstat.set_ellipsize(pango.ELLIPSIZE_END)
        self.pbar = gtk.ProgressBar()
        vbox.pack_start(self.pbar, False, False, 2)
Пример #19
0
    def update(self):
        cmdline = ['hg', 'update', '--verbose']
        rev = hglib.fromutf(self.revcombo.get_active_text())
        cmdline.append('--rev')
        cmdline.append(rev)

        if self.opt_clean.get_active():
            cmdline.append('--clean')
        else:
            cur = self.repo['.']
            node = self.repo[rev]
            def isclean():
                '''whether WD is changed'''
                wc = self.repo[None]
                return not (wc.modified() or wc.added() or wc.removed())
            def ismergedchange():
                '''whether the local changes are merged (have 2 parents)'''
                wc = self.repo[None]
                return len(wc.parents()) == 2
            def iscrossbranch(p1, p2):
                '''whether p1 -> p2 crosses branch'''
                pa = p1.ancestor(p2)
                return p1.branch() != p2.branch() or (p1 != pa and p2 != pa)
            def islocalmerge(p1, p2, clean=None):
                if clean is None:
                    clean = isclean()
                pa = p1.ancestor(p2)
                return not clean and (p1 == pa or p2 == pa)
            def confirmupdate(clean=None):
                if clean is None:
                    clean = isclean()

                msg = _('Detected uncommitted local changes in working tree.\n'
                        'Please select to continue:\n\n')
                data = {'discard': (_('&Discard'),
                                    _('Discard - discard local changes, no backup')),
                        'shelve': (_('&Shelve'),
                                   _('Shelve - launch Shelve tool and continue')),
                        'merge': (_('&Merge'),
                                  _('Merge - allow to merge with local changes')),
                        'cancel': (_('&Cancel'), None)}

                opts = [data['discard']]
                if not ismergedchange():
                    opts.append(data['shelve'])
                if islocalmerge(cur, node, clean):
                    opts.append(data['merge'])
                opts.append(data['cancel'])

                msg += '\n'.join([ desc for label, desc in opts if desc ])
                buttons = [ label for label, desc in opts ]
                cancel = len(opts) - 1
                retcode = gdialog.CustomPrompt(_('Confirm Update'), msg, self,
                                    buttons, default=cancel, esc=cancel).run()
                retlabel = buttons[retcode]
                retid = [ id for id, (label, desc) in data.items() \
                             if label == retlabel ][0]
                return dict([(id, id == retid) for id in data.keys()])
            # If merge-by-default, we want to merge whenever possible,
            # without prompting user (similar to command-line behavior)
            defaultmerge = self.opt_merge.get_active()
            clean = isclean()
            if clean:
                cmdline.append('--check')
            elif not (defaultmerge and islocalmerge(cur, node, clean)):
                ret = confirmupdate(clean)
                if ret['discard']:
                    cmdline.append('--clean')
                elif ret['shelve']:
                    def launch_shelve():
                        from tortoisehg.hgtk import thgshelve
                        dlg = thgshelve.run(ui.ui())
                        dlg.set_transient_for(self)
                        dlg.set_modal(True)
                        dlg.display()
                        dlg.connect('destroy', lambda w: self.update())
                    gtklib.idle_add_single_call(launch_shelve)
                    return # retry later, no need to destroy
                elif ret['merge']:
                    pass # no args
                elif ret['cancel']:
                    self.cmd.log.append(_('[canceled by user]\n'), error=True)
                    self.do_switch_to(gdialog.MODE_WORKING)
                    self.abort()
                    return
                else:
                    raise _('invalid dialog result: %s') % ret

        # start updating
        self.execute_command(cmdline)
Пример #20
0
    def get_body(self, vbox):
        rev0, rev1 = self.revs
        prevs = [ctx.rev() for ctx in self.repo.parents()]
        if len(prevs) > 1:
            rev0, rev1 = prevs
        elif (not rev1 and rev1 != 0):
            gdialog.Prompt(_('Unable to merge'),
                           _('Must supply a target revision'), self).run()
            gtklib.idle_add_single_call(self.hide)
            return False
        elif (not rev0 and rev0 != 0):
            rev0 = prevs[0]
        elif rev1 == prevs[0]:
            # selected pair was backwards
            rev0, rev1 = rev1, rev0
        elif rev0 != prevs[0]:
            # working parent not in selected revision pair
            modified, added, removed, deleted = self.repo.status()[:4]
            if modified or added or removed or deleted:
                gdialog.Prompt(_('Unable to merge'),
                               _('Outstanding uncommitted changes'), self).run()
                gtklib.idle_add_single_call(self.hide)
                return False
            self.repo.ui.quiet = True
            commands.update(self.repo.ui, self.repo, rev=str(rev0), check=True)
            self.repo.ui.quiet = False

        # changeset info
        style = csinfo.panelstyle(contents=csinfo.PANEL_DEFAULT + ('ishead',),
                                  margin=5, padding=2)
        def markup_func(widget, item, value):
            if item == 'ishead' and value is False:
                text = _('Not a head revision!')
                return gtklib.markup(text, weight='bold')
            raise csinfo.UnknownItem(item)
        custom = csinfo.custom(markup=markup_func)
        factory = csinfo.factory(self.repo, custom, style, withupdate=True)

        info = factory(rev1, style={'label': _('Merge target (other)')})
        self.vbox.pack_start(info, False, False)
        self.otherframe = info
        self.otherrev = str(info.get_data('revnum'))

        info = factory(rev0, style={'label': _('Current revision (local)')})
        self.vbox.pack_start(info, False, False)
        self.localframe = info
        self.localrev = str(info.get_data('revnum'))

        # expander for advanced options
        expander = gtk.Expander(_('Advanced options'))
        self.vbox.pack_start(expander, False, False)

        # layout table for advanced options
        table = gtklib.LayoutTable()
        expander.add(table)
        
        vlist = gtk.ListStore(str,  # tool name
                              bool) # separator
        combo = gtk.ComboBoxEntry(vlist, 0)
        self.mergetool = combo
        combo.set_row_separator_func(lambda model, path: model[path][1])
        combo.child.set_width_chars(16)
        chtool = gtk.RadioButton(None, _('Use merge tool:'))
        self.mergelabel = chtool
        table.add_row(chtool, combo)
        prev = False
        for tool in hglib.mergetools(self.repo.ui):
            cur = tool.startswith('internal:')
            vlist.append((hglib.toutf(tool), prev != cur))
            prev = cur
        mtool = self.repo.ui.config('ui', 'merge', None)
        if mtool:
            combo.child.set_text(hglib.toutf(mtool))
        else:
            combo.child.set_text('')

        discard = gtk.RadioButton(chtool,
            _('Discard all changes from merge target (other) revision'))
        self.discard = discard
        table.add_row(discard)

        # prepare to show
        if len(self.repo.parents()) == 2:
            self.mergetool.set_sensitive(False)
            self.mergelabel.set_sensitive(False)
            self.discard.set_sensitive(False)
            self.buttons['merge'].set_sensitive(False)
            self.buttons['commit'].set_sensitive(True)
            self.buttons['undo'].set_sensitive(True)
        else:
            self.buttons['commit'].set_sensitive(False)
            self.buttons['undo'].set_sensitive(False)