Ejemplo n.º 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)
Ejemplo n.º 2
0
    def __init__(self, command, pats):
        gtk.Dialog.__init__(self)
        gtklib.set_tortoise_icon(self, "hg.ico")
        gtklib.set_tortoise_keys(self)
        self.set_has_separator(False)
        self.set_default_size(400, 500)
        self.connect("response", self.dialog_response)

        entry = gtk.Entry()
        self.vbox.pack_start(entry, False, True)

        def newfolder_notify(newfolder):
            curpath = entry.get_text()
            newpath = os.path.join(curpath, newfolder)
            newpath = hglib.toutf(os.path.abspath(newpath))
            root = paths.find_root(newpath)
            if root:
                self.set_title(root + " - " + _("browser"))
            else:
                self.set_title(_("browser"))
            entry.set_text(newpath)
            browse.chdir(newpath)

        browse = BrowsePane(newfolder_notify)
        scroller = gtk.ScrolledWindow()
        scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scroller.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        scroller.add(browse)
        self.vbox.pack_start(scroller, True, True)
        self.show_all()

        cwd = hglib.toutf(os.getcwd())
        entry.connect("activate", self.entry_activated, browse)
        entry.set_text(cwd)
        browse.chdir(cwd)
Ejemplo n.º 3
0
    def __init__(self, title=_('Command Log')):
        gtk.Window.__init__(self, type=gtk.WINDOW_TOPLEVEL)
        gtklib.set_tortoise_icon(self, 'hg.ico')
        accelgroup, mod = gtklib.set_tortoise_keys(self)
        self.set_title(title)
        self.set_default_size(320, 240)
        self.connect('delete-event', self.should_live)

        # accelerators
        key, modifier = gtk.accelerator_parse('Escape')
        self.add_accelerator('thg-close', accelgroup, key, modifier,
                             gtk.ACCEL_VISIBLE)
        self.connect('thg-close', self.should_live)
        self.connect('thg-exit', self.should_live)

        # log viewer
        self.log = CmdLogWidget()
        self.add(self.log)

        # change window decorations
        self.realize()
        if self.window:
            self.window.set_decorations(gtk.gdk.DECOR_BORDER | \
                                        gtk.gdk.DECOR_RESIZEH | \
                                        gtk.gdk.DECOR_TITLE | \
                                        gtk.gdk.DECOR_MENU | \
                                        gtk.gdk.DECOR_MINIMIZE)
Ejemplo n.º 4
0
    def __init__(self, gotofunc):
        super(GotoRevDialog, self).__init__(flags=gtk.DIALOG_MODAL)
        gtklib.set_tortoise_icon(self, 'menulog.ico')
        gtklib.set_tortoise_keys(self)
        self.set_has_separator(False)

        self._btn_goto = gtk.Button(_('Select'))
        self._btn_goto.connect('clicked', self._btn_goto_clicked)
        self.action_area.pack_end(self._btn_goto)

        self.set_title(_('Select Revision'))

        self.gotofunc = gotofunc

        self.tips = gtklib.Tooltips()

        hbox = gtk.HBox()
        self.revEntry = gtk.Entry()
        self.revEntry.connect('activate', self._btn_goto_clicked)
        hbox.pack_start(self.revEntry, True, True, 4)
        eventbox = gtk.EventBox()
        eventbox.add(hbox)
        self.tips.set_tip(
            eventbox, _('revision number, changeset ID, branch or tag'))
        self.vbox.pack_start(eventbox, False, False, 4)

        self.revEntry.grab_focus()

        self.show_all()
Ejemplo n.º 5
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)
Ejemplo n.º 6
0
    def __init__(self, repo, pats, ctx1a, sa, ctx1b, sb, ctx2, cpy):
        'Initialize the Dialog'
        gtk.Dialog.__init__(self, title=_('Visual Diffs'))
        gtklib.set_tortoise_icon(self, 'menushowchanged.ico')
        gtklib.set_tortoise_keys(self)

        if ctx2.rev() is None:
            title = _('working changes')
        elif ctx1a == ctx2.parents()[0]:
            title = _('changeset ') + str(ctx2.rev())
        else:
            title = _('revisions %d to %d') % (ctx1a.rev(), ctx2.rev())
        title = _('Visual Diffs - ') + title
        if pats:
            title += _(' filtered')
        self.set_title(title)

        self.set_default_size(400, 250)
        self.set_has_separator(False)
        self.reponame=hglib.get_reponame(repo)

        self.ctxs = (ctx1a, ctx1b, ctx2)
        self.copies = cpy
        self.ui = repo.ui

        lbl = gtk.Label(_('Temporary files are removed when this dialog '
                          'is closed'))
        self.vbox.pack_start(lbl, False, False, 2)

        scroller = gtk.ScrolledWindow()
        scroller.set_shadow_type(gtk.SHADOW_IN)
        scroller.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        treeview = gtk.TreeView()
        self.treeview = treeview
        treeview.get_selection().set_mode(gtk.SELECTION_SINGLE)
        treeview.set_search_equal_func(self.search_filelist)
        scroller.add(treeview)
        self.vbox.pack_start(scroller, True, True, 2)

        treeview.connect('row-activated', self.rowactivated)
        treeview.set_headers_visible(False)
        treeview.set_property('enable-grid-lines', True)
        treeview.set_enable_search(False)

        accelgroup = gtk.AccelGroup()
        self.add_accel_group(accelgroup)
        mod = gtklib.get_thg_modifier()
        key, modifier = gtk.accelerator_parse(mod+'d')
        treeview.add_accelerator('thg-diff', accelgroup, key,
                        modifier, gtk.ACCEL_VISIBLE)
        treeview.connect('thg-diff', self.rowactivated)

        cell = gtk.CellRendererText()
        stcol = gtk.TreeViewColumn('Status', cell)
        stcol.set_resizable(True)
        stcol.add_attribute(cell, 'text', 0)
        treeview.append_column(stcol)

        cell = gtk.CellRendererText()
        fcol = gtk.TreeViewColumn('Filename', cell)
        fcol.set_resizable(True)
        fcol.add_attribute(cell, 'text', 1)
        treeview.append_column(fcol)

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

        tools = hglib.difftools(repo.ui)
        preferred = besttool(repo.ui, tools)
        self.diffpath, self.diffopts, self.mergeopts = tools[preferred]

        hbox = gtk.HBox()
        self.vbox.pack_start(hbox, False, False, 2)

        if ctx2.rev() is None:
            pass
            # Do not offer directory diffs when the working directory
            # is being referenced directly
        elif ctx1b:
            self.p1button = gtk.Button(_('Dir diff to p1'))
            self.p1button.connect('pressed', self.p1dirdiff)
            self.p2button = gtk.Button(_('Dir diff to p2'))
            self.p2button.connect('pressed', self.p2dirdiff)
            self.p3button = gtk.Button(_('3-way dir diff'))
            self.p3button.connect('pressed', self.threewaydirdiff)
            hbox.pack_end(self.p3button, False, False)
            hbox.pack_end(self.p2button, False, False)
            hbox.pack_end(self.p1button, False, False)
        else:
            self.dbutton = gtk.Button(_('Directory diff'))
            self.dbutton.connect('pressed', self.p1dirdiff)
            hbox.pack_end(self.dbutton, False, False)

        self.update_diff_buttons(preferred)

        if len(tools) > 1:
            combo = gtk.combo_box_new_text()
            for i, name in enumerate(tools.iterkeys()):
                combo.append_text(name)
                if name == preferred:
                    defrow = i
            combo.set_active(defrow)
            combo.connect('changed', self.toolselect, tools)
            hbox.pack_start(combo, False, False, 2)

            patterns = repo.ui.configitems('diff-patterns')
            patterns = [(p, t) for p,t in patterns if t in tools]
            filesel = treeview.get_selection()
            filesel.connect('changed', self.fileselect, repo, combo, tools,
                            patterns, preferred)

        gobject.idle_add(self.fillmodel, repo, model, sa, sb)
Ejemplo n.º 7
0
    def __init__(self, webdir_conf):
        """ Initialize the Dialog """
        gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
        gtklib.set_tortoise_icon(self, 'proxy.ico')
        gtklib.set_tortoise_keys(self)

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

        # Pipe stderr, stdout to self.write
        self._queue = Queue.Queue()
        sys.stdout = self
        sys.stderr = self

        # Set a closed attribute to better mimic stderr (issue #891)
        self.closed = True

        # Override mercurial.commands.serve() with our own version
        # that supports being stopped
        commands.table.update(thg_serve_cmd)

        self._url = None
        self._root = paths.find_root()
        self._webdirconf = webdir_conf
        self._get_config()
        self.set_default_size(500, 300)

        # toolbar
        self.tbar = gtk.Toolbar()
        self.tooltips = gtklib.Tooltips()
        self._button_start = self._toolbutton(gtk.STOCK_MEDIA_PLAY,
                                              _('Start'),
                                              self._on_start_clicked,
                                              tip=_('Start server'))
        self._button_stop  = self._toolbutton(gtk.STOCK_MEDIA_STOP,
                                              _('Stop'),
                                              self._on_stop_clicked,
                                              tip=_('Stop server'))
        self._button_browse = self._toolbutton(gtk.STOCK_HOME,
                                              _('Browse'),
                                              self._on_browse_clicked,
                                              tip=_('Launch browser to view repository'))
        self._button_conf = self._toolbutton(gtk.STOCK_PREFERENCES,
                                              _('Configure'),
                                              self._on_conf_clicked,
                                              tip=_('Configure web settings'))

        tbuttons = [
                self._button_start,
                self._button_stop,
                gtk.SeparatorToolItem(),
                self._button_browse,
                gtk.SeparatorToolItem(),
                self._button_conf,
            ]
        for btn in tbuttons:
            self.tbar.insert(btn, -1)

        vbox = gtk.VBox()
        self.add(vbox)
        vbox.pack_start(self.tbar, False, False, 2)

        # revision input
        revbox = gtk.HBox()
        self._port_input = gtk.Entry()
        self._port_input.set_text(self.defport)
        revbox.pack_start(gtk.Label(_('HTTP Port:')), False, False, 4)
        revbox.pack_start(self._port_input, False, False)
        vbox.pack_start(revbox, False, False, 2)

        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()
        vbox.pack_start(scrolledwindow, True, True)
        self._set_button_states()
Ejemplo n.º 8
0
    def _setup_gtk(self):
        self.set_title(self.get_title())
        gtklib.set_tortoise_icon(self, self.get_icon())
        gtklib.set_tortoise_keys(self)

        self.ismaximized = False
        self.isiconified = False
        self.lastpos = self._setting_winpos
        self.connect('window-state-event', self.windowstate)
        self.connect('set-focus', self.setfocus)

        # Minimum size
        minx, miny = self.get_minsize()
        self.set_size_request(minx, miny)
        # Initial size
        defx, defy = self.get_defsize()
        self.set_default_size(defx, defy)
        if self._setting_wasmax:
            self.maximize()

        # Restore position if it is still on screen
        screen = self.get_screen()
        w, h = screen.get_width(), screen.get_height()
        x, y = self._setting_winpos
        if x >= 0 and x < w and y >= 0 and y < h:
            self.move(x, y)

        self.tooltips = gtklib.Tooltips()
        toolbar = gtk.Toolbar()
        tbuttons =  self.get_tbbuttons()
        for tbutton in tbuttons:
            toolbar.insert(tbutton, -1)
        for x in toolbar.get_children():
            x.set_homogeneous(True)
        self.toolbar = toolbar

        # Subclass returns the main body
        body = self.get_body()

        # Subclass provides extra stuff in bottom hbox
        extras = self.get_extras()

        menus = self.get_menu_list()
        if menus:
            allmenus = [
            dict(text=_('_Tools'), subitems=[
                dict(text=_('Repository Explorer'), func=self.launch,
                    args=['log'], icon='menulog.ico'),
                dict(text=_('Commit'), func=self.launch,
                    args=['commit'], icon='menucommit.ico'),
                dict(text=_('Datamine'), func=self.launch,
                    args=['datamine'], icon='menurepobrowse.ico'),
                dict(text=_('Recovery'), func=self.launch,
                    args=['recover'], icon='general.ico'),
                dict(text=_('Serve'), func=self.launch,
                    args=['serve'], icon='proxy.ico'),
                dict(text=_('Shelve'), func=self.launch,
                    args=['shelve'], icon='shelve.ico'),
                dict(text=_('Synchronize'), func=self.launch,
                    args=['synch'], icon='menusynch.ico'),
                dict(text=_('Settings'), func=self.launch,
                    args=['repoconfig'], icon='settings_repo.ico')])
                ] + menus + [
            dict(text=_('_Help'), subitems=[
                dict(text=_('Contents'), func=self.helpcontents,
                    icon=gtk.STOCK_INFO),
                dict(text=_('Index'), func=self.helpindex,
                    icon=gtk.STOCK_HELP),
                dict(text=_('About'), func=self.launch,
                    args=['about'], icon=gtk.STOCK_ABOUT)])
                ]
            def build(menus, nobuild=False):
                mb = gtklib.MenuBuilder()
                for d in menus:
                    text = d['text']
                    if text == '----':
                        mb.append_sep()
                        continue
                    subitems = d.get('subitems')
                    if subitems:
                        sub = build(subitems)
                        item = mb.append_submenu(text, sub, **d)
                    else:
                        if 'rg' in d:
                            d.update(group=self.menuitems.get(d['rg']))
                        item = mb.append(text, d.get('func'), **d)
                    name = d.get('name')
                    if name:
                        self.menuitems[name] = item
                if nobuild:
                    return mb.get_menus()
                return mb.build()
            menubar = gtk.MenuBar()
            for menu in build(allmenus, nobuild=True):
                menubar.append(menu)

        vbox = gtk.VBox(False, 0)
        self.add(vbox)
        if menus:
            vbox.pack_start(menubar, False, False, 0)

        self.toolbar_box = gtk.VBox()
        vbox.pack_start(self.toolbar_box, False, False, 0)
        if self.show_toolbar_on_start():
            self._show_toolbar(True)

        vbox.pack_start(body, True, True, 0)
        if extras:
            vbox.pack_end(extras, False, False, 0)

        self.connect('destroy', self._destroying)
Ejemplo n.º 9
0
    def __init__(self, cmdline, progressbar=True, text=None):
        if type(cmdline) is tuple:
            self.cmdlist = list(cmdline)[1:]
            cmdline = cmdline[0]
        else:
            self.cmdlist = []
        title = text or ' '.join(cmdline)
        if len(title) > 80:
            title = hglib.tounicode(title)[:80] + '...'
        title = hglib.toutf(title.replace('\n', ' '))
        gtk.Dialog.__init__(self, title=title, flags=gtk.DIALOG_MODAL)
        self.set_has_separator(False)

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

        self.set_default_size(520, 400)

        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('thg-accept', self._on_ok_clicked)

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

        self.vbox.pack_start(scrolledwindow, True, True)
        self.connect('map_event', self._on_window_map_event)

        self.show_all()
Ejemplo n.º 10
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)
Ejemplo n.º 11
0
    def __init__(self, model, apply_func):
        super(LogDetailsDialog, self).__init__(
            flags=gtk.DIALOG_MODAL)
        self.set_has_separator(False)
        self.connect('response', self.dialog_response)

        self.apply_func = apply_func
        self.dirty = False

        gtklib.set_tortoise_icon(self, 'general.ico')
        gtklib.set_tortoise_keys(self)

        # add dialog buttons
        self.okbtn = self.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
        self.cancelbtn = self.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CLOSE)
        self.applybtn = self.add_button(gtk.STOCK_APPLY, gtk.RESPONSE_APPLY)
        self.set_default_response(gtk.RESPONSE_OK)

        self.set_title(_('Log Details'))

        self.set_default_size(350, 120)

        hbox = gtk.HBox()
        lb = gtk.Label(_('Columns') + ':')
        hbox.pack_start(lb, False, False, 6)
        self.vbox.pack_start(gtk.HBox(), False, False, 3)
        self.vbox.pack_start(hbox, False, False)

        mainhbox = gtk.HBox()
        self.vbox.pack_start(mainhbox)

        leftvbox = gtk.VBox()
        rightvbox = gtk.VBox()
        mainhbox.pack_start(leftvbox, True, True)
        mainhbox.pack_start(gtk.VBox(), False, False, 0)
        mainhbox.pack_start(rightvbox, False, False, 4)

        tv = self.tv = gtk.TreeView(model)
        tv.set_headers_visible(False)

        cr = gtk.CellRendererToggle()
        cr.set_property('activatable', True)

        def toggled(cell, path):
            model[path][0] = not model[path][0]
            self.dirty = True
            self.update_buttons()

        cr.connect('toggled', toggled)

        show_col = gtk.TreeViewColumn('', cr, active=0)
        tv.append_column(show_col)

        cr = gtk.CellRendererText()
        info_col = gtk.TreeViewColumn('', cr, text=1)
        tv.append_column(info_col)

        def activated(treeview, path, column):
            toggled(None, path)
        tv.connect('row-activated', activated)

        frm = gtk.Frame()
        frm.add(tv)

        vbox = gtk.VBox()
        vbox.set_border_width(4)
        vbox.pack_start(frm)

        leftvbox.pack_start(vbox, True, True)

        self.up_button = gtk.Button(_('Move Up'))
        self.up_button.connect('clicked', self.up_clicked)

        self.down_button = gtk.Button(_('Move Down'))
        self.down_button.connect('clicked', self.down_clicked)

        rightvbox.pack_start(self.up_button, False, False, 2)
        rightvbox.pack_start(self.down_button, False, False, 4)

        self.tv.connect('cursor-changed', lambda tv: self.update_buttons())

        self.show_all()
Ejemplo n.º 12
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)
Ejemplo n.º 13
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)
Ejemplo n.º 14
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)