예제 #1
0
    def update(self, items, uselimit=True):
        """Update the item list.

        Public arguments:
        items: List of revision numbers and/or patch file paths.
               You can pass a mixed list. The order will be respected.
        uselimit: If True, some of items will be shown.

        return: True if the item list was updated successfully,
                False if it wasn't updated.
        """
        # setup
        self.clear()
        self.curfactory = csinfo.factory(self.currepo, self.custom)

        # initialize variables
        self.curitems = items

        if not items or not self.currepo:
            self.updatestatus()
            return False

        if self.compactchk.isChecked():
            self.csvbox.setSpacing(0)
        else:
            self.csvbox.setSpacing(_SPACING)

        # determine the items to show
        if uselimit and self.limit < len(items):
            showitems, lastitem = items[:self.limit - 1], items[-1]
        else:
            showitems, lastitem = items, None
        numshow = len(showitems) + (lastitem and 1 or 0)
        self.showitems = showitems + (lastitem and [lastitem] or [])

        # show items
        for item in showitems:
            self.insertcs(item)
        if lastitem:
            self.csvbox.addWidget(QLabel("..."))
            self.insertcs(lastitem)
        self.updatestatus()
        return True
예제 #2
0
    def initializePage(self):
        if self.layout():
            return
        self.setTitle(_('Prepare to merge'))
        self.setSubTitle(_('Verify merge targets and ensure your working '
                           'directory is clean.'))
        self.setLayout(QVBoxLayout())

        repo = self.repo
        contents = ('ishead',) + csinfo.PANEL_DEFAULT
        style = csinfo.panelstyle(contents=contents)
        def markup_func(widget, item, value):
            if item == 'ishead' and value is False:
                text = _('Not a head revision!')
                return qtlib.markup(text, fg='red', weight='bold')
            raise csinfo.UnknownItem(item)
        custom = csinfo.custom(markup=markup_func)
        create = csinfo.factory(repo, custom, style, withupdate=True)

        ## merge target
        other_sep = qtlib.LabeledSeparator(_('Merge from (other revision)'))
        self.layout().addWidget(other_sep)
        try:
            otherCsInfo = create(self.wizard().otherrev)
            self.layout().addWidget(otherCsInfo)
            self.otherCsInfo = otherCsInfo
        except error.RepoLookupError:
            qtlib.InfoMsgBox(_('Unable to merge'),
                             _('Merge revision not specified or not found'))
            QTimer.singleShot(0, self.wizard().close)

        ## current revision
        local_sep = qtlib.LabeledSeparator(_('Merge to (working directory)'))
        self.layout().addWidget(local_sep)
        localCsInfo = create(self.wizard().localrev)
        self.layout().addWidget(localCsInfo)
        self.localCsInfo = localCsInfo

        ## working directory status
        wd_sep = qtlib.LabeledSeparator(_('Working directory status'))
        self.layout().addWidget(wd_sep)

        self.groups = qtlib.WidgetGroups()

        wdbox = QHBoxLayout()
        self.layout().addLayout(wdbox)
        self.wd_status = qtlib.StatusLabel()
        self.wd_status.set_status(_('Checking...'))
        wdbox.addWidget(self.wd_status)
        wd_prog = QProgressBar()
        wd_prog.setMaximum(0)
        wd_prog.setTextVisible(False)
        self.groups.add(wd_prog, 'prog')
        wdbox.addWidget(wd_prog, 1)

        wd_merged = QLabel(_('The working directory is already <b>merged</b>. '
                             '<a href="skip"><b>Continue</b></a> or '
                             '<a href="discard"><b>discard</b></a> existing '
                             'merge.'))
        wd_merged.linkActivated.connect(self.onLinkActivated)
        wd_merged.setWordWrap(True)
        self.groups.add(wd_merged, 'merged')
        self.layout().addWidget(wd_merged)

        text = _('Before merging, you must <a href="commit"><b>commit</b></a>, '
                 '<a href="shelve"><b>shelve</b></a> to patch, '
                 'or <a href="discard"><b>discard</b></a> changes.')
        wd_text = QLabel(text)
        wd_text.setWordWrap(True)
        wd_text.linkActivated.connect(self.onLinkActivated)
        self.wd_text = wd_text
        self.groups.add(wd_text, 'dirty')
        self.layout().addWidget(wd_text)

        wdbox = QHBoxLayout()
        self.layout().addLayout(wdbox)
        wd_alt = QLabel(_('Or use:'))
        self.groups.add(wd_alt, 'dirty')
        wdbox.addWidget(wd_alt)
        force_chk = QCheckBox(_('Force a merge with outstanding changes '
                                '(-f/--force)'))
        force_chk.toggled.connect(lambda c: self.completeChanged.emit())
        self.registerField('force', force_chk)
        self.groups.add(force_chk, 'dirty')
        wdbox.addWidget(force_chk)

        ### options
        expander = qtlib.ExpanderLabel(_('Options'), False)
        expander.expanded.connect(self.toggleShowOptions)
        self.layout().addWidget(expander)
        self.expander = expander

        ### discard option
        discard_chk = QCheckBox(_('Discard all changes from merge target '
                                  '(other) revision'))
        self.registerField('discard', discard_chk)
        self.layout().addWidget(discard_chk)
        self.discard_chk = discard_chk

        ## auto-resolve
        autoresolve_chk = QCheckBox(_('Automatically resolve merge conflicts '
                                      'where possible'))
        autoresolve_chk.setChecked(
            repo.ui.configbool('tortoisehg', 'autoresolve', False))
        self.registerField('autoresolve', autoresolve_chk)
        self.layout().addWidget(autoresolve_chk)
        self.autoresolve_chk = autoresolve_chk

        self.groups.set_visible(False, 'dirty')
        self.groups.set_visible(False, 'merged')
        self.toggleShowOptions(self.expander.is_expanded())
예제 #3
0
    def __init__(self, repoagent, rev=None, parent=None):
        super(MatchDialog, self).__init__(parent)
        self.setWindowFlags(self.windowFlags() & \
                            ~Qt.WindowContextHelpButtonHint)

        self.revsetexpression = ''
        self._repoagent = repoagent

        # base layout box
        box = QVBoxLayout()
        box.setSpacing(6)

        ## main layout grid
        self.grid = QGridLayout()
        self.grid.setSpacing(6)
        self.grid.setColumnStretch(1, 1)
        box.addLayout(self.grid)

        ### matched revision combo
        self.rev_combo = combo = QComboBox()
        combo.setEditable(True)
        combo.setMinimumContentsLength(30)  # cut long name
        self.grid.addWidget(QLabel(_('Find revisions matching fields of:')),
                            0, 0)
        self.grid.addWidget(combo, 0, 1)

        if rev is None:
            rev = self.repo.dirstate.branch()
        else:
            rev = str(rev)
        combo.addItem(hglib.tounicode(rev))
        combo.setCurrentIndex(0)
        # make it easy to match the workding directory parent revision
        combo.addItem(hglib.tounicode('.'))

        tags = list(self.repo.tags()) + self.repo._bookmarks.keys()
        tags.sort(reverse=True)
        for tag in tags:
            combo.addItem(hglib.tounicode(tag))

        ### matched revision info
        self.rev_to_match_info_text = QLabel()
        self.rev_to_match_info_text.setVisible(False)
        style = csinfo.panelstyle(contents=('cset', 'branch', 'close', 'user',
               'dateage', 'parents', 'children', 'tags', 'graft', 'transplant',
               'p4', 'svn', 'converted'), selectable=True,
               expandable=True)
        factory = csinfo.factory(self.repo, style=style)
        self.rev_to_match_info = factory()
        self.rev_to_match_info.setSizePolicy(QSizePolicy.Preferred,
                                             QSizePolicy.Fixed)
        self.rev_to_match_info_lbl = QLabel(_('Revision to Match:'))
        self.grid.addWidget(self.rev_to_match_info_lbl, 1, 0,
                            Qt.AlignLeft | Qt.AlignTop)
        self.grid.addWidget(self.rev_to_match_info, 1, 1)
        self.grid.addWidget(self.rev_to_match_info_text, 1, 1)

        ### fields that will be matched
        self.optbox = QVBoxLayout()
        self.optbox.setSpacing(6)
        expander = qtlib.ExpanderLabel(_('Fields to match:'), False)
        expander.expanded.connect(self.show_options)
        row = self.grid.rowCount()
        self.grid.addWidget(expander, row, 0, Qt.AlignLeft | Qt.AlignTop)
        self.grid.addLayout(self.optbox, row, 1)

        self.summary_chk = QCheckBox(_('Summary (first description line)'))
        self.description_chk = QCheckBox(_('Description'))
        self.desc_btngroup = QButtonGroup()
        self.desc_btngroup.setExclusive(False)
        self.desc_btngroup.addButton(self.summary_chk)
        self.desc_btngroup.addButton(self.description_chk)
        self.desc_btngroup.buttonClicked.connect(
            self._selectSummaryOrDescription)

        self.author_chk = QCheckBox(_('Author'))
        self.date_chk = QCheckBox(_('Date'))
        self.files_chk = QCheckBox(_('Files'))
        self.diff_chk = QCheckBox(_('Diff contents'))
        self.substate_chk = QCheckBox(_('Subrepo states'))
        self.branch_chk = QCheckBox(_('Branch'))
        self.parents_chk = QCheckBox(_('Parents'))
        self.phase_chk = QCheckBox(_('Phase'))
        self._hideable_chks = (self.branch_chk, self.phase_chk,
                               self.parents_chk)

        self.optbox.addWidget(self.summary_chk)
        self.optbox.addWidget(self.description_chk)
        self.optbox.addWidget(self.author_chk)
        self.optbox.addWidget(self.date_chk)
        self.optbox.addWidget(self.files_chk)
        self.optbox.addWidget(self.diff_chk)
        self.optbox.addWidget(self.substate_chk)
        self.optbox.addWidget(self.branch_chk)
        self.optbox.addWidget(self.parents_chk)
        self.optbox.addWidget(self.phase_chk)

        s = QSettings()

        #### Persisted Options
        self.summary_chk.setChecked(s.value('matching/summary', False).toBool())
        self.description_chk.setChecked(
            s.value('matching/description', True).toBool())
        self.author_chk.setChecked(s.value('matching/author', True).toBool())
        self.branch_chk.setChecked(s.value('matching/branch', False).toBool())
        self.date_chk.setChecked(s.value('matching/date', True).toBool())
        self.files_chk.setChecked(s.value('matching/files', False).toBool())
        self.diff_chk.setChecked(s.value('matching/diff', False).toBool())
        self.parents_chk.setChecked(s.value('matching/parents', False).toBool())
        self.phase_chk.setChecked(s.value('matching/phase', False).toBool())
        self.substate_chk.setChecked(
            s.value('matching/substate', False).toBool())

        ## bottom buttons
        buttons = QDialogButtonBox()
        self.close_btn = buttons.addButton(QDialogButtonBox.Close)
        self.close_btn.clicked.connect(self.reject)
        self.close_btn.setAutoDefault(False)
        self.match_btn = buttons.addButton(_('&Match'),
                                            QDialogButtonBox.ActionRole)
        self.match_btn.clicked.connect(self.match)
        box.addWidget(buttons)

        # signal handlers
        self.rev_combo.editTextChanged.connect(self.update_info)

        # dialog setting
        self.setLayout(box)
        self.layout().setSizeConstraint(QLayout.SetMinAndMaxSize)
        self.setWindowTitle(_('Find matches - %s') % repoagent.displayName())
        self.setWindowIcon(qtlib.geticon('hg-update'))

        # prepare to show
        self.update_info()
        if not self.match_btn.isEnabled():
            self.rev_combo.lineEdit().selectAll()  # need to change rev

        # expand options if a hidden one is checked
        hiddenOptionsChecked = self.hiddenSettingIsChecked()
        self.show_options(hiddenOptionsChecked)
        expander.set_expanded(hiddenOptionsChecked)
예제 #4
0
    def initializePage(self):
        if self.layout():
            return
        self.setTitle(_('Prepare to backout'))
        self.setSubTitle(
            _('Verify backout revision and ensure your working '
              'directory is clean.'))
        self.setLayout(QVBoxLayout())

        self.groups = qtlib.WidgetGroups()

        repo = self.repo
        try:
            bctx = repo[self.wizard().backoutrev]
            pctx = repo['.']
        except error.RepoLookupError:
            qtlib.InfoMsgBox(_('Unable to backout'),
                             _('Backout revision not found'))
            QTimer.singleShot(0, self.wizard().close)
            return

        if pctx == bctx:
            lbl = _('Backing out a parent revision is a single step operation')
            self.layout().addWidget(QLabel(u'<b>%s</b>' % lbl))
            self.wizard().parentbackout = True

        op1, op2 = repo.dirstate.parents()
        if op1 is None:
            qtlib.InfoMsgBox(_('Unable to backout'),
                             _('Backout requires a parent revision'))
            QTimer.singleShot(0, self.wizard().close)
            return

        a = repo.changelog.ancestor(op1, bctx.node())
        if a != bctx.node():
            qtlib.InfoMsgBox(_('Unable to backout'),
                             _('Cannot backout change on a different branch'))
            QTimer.singleShot(0, self.wizard().close)

        ## backout revision
        style = csinfo.panelstyle(contents=csinfo.PANEL_DEFAULT)
        create = csinfo.factory(repo, None, style, withupdate=True)
        sep = qtlib.LabeledSeparator(_('Backout revision'))
        self.layout().addWidget(sep)
        backoutCsInfo = create(bctx.rev())
        self.layout().addWidget(backoutCsInfo)

        ## current revision
        contents = ('ishead', ) + csinfo.PANEL_DEFAULT
        style = csinfo.panelstyle(contents=contents)

        def markup_func(widget, item, value):
            if item == 'ishead' and value is False:
                text = _('Not a head, backout will create a new head!')
                return qtlib.markup(text, fg='red', weight='bold')
            raise csinfo.UnknownItem(item)

        custom = csinfo.custom(markup=markup_func)
        create = csinfo.factory(repo, custom, style, withupdate=True)

        sep = qtlib.LabeledSeparator(_('Current local revision'))
        self.layout().addWidget(sep)
        localCsInfo = create(pctx.rev())
        self.layout().addWidget(localCsInfo)
        self.localCsInfo = localCsInfo

        ## Merge revision backout handling
        if len(bctx.parents()) > 1:
            # Show two radio buttons letting the user which merge revision
            # parent to backout to
            p1rev = bctx.p1().rev()
            p2rev = bctx.p2().rev()

            def setBackoutMergeParentRev(rev):
                self.wizard().backoutmergeparentrev = rev

            setBackoutMergeParentRev(p1rev)

            sep = qtlib.LabeledSeparator(_('Merge parent to backout to'))
            self.layout().addWidget(sep)
            self.layout().addWidget(
                QLabel(
                    _('To backout a <b>merge</b> revision you must select which '
                      'parent to backout to '
                      '(i.e. whose changes will be <i>kept</i>)')))

            self.actionFirstParent = QRadioButton(
                _('First Parent: revision %s (%s)') \
                % (p1rev, str(bctx.p1())), self)
            self.actionFirstParent.setCheckable(True)
            self.actionFirstParent.setChecked(True)
            self.actionFirstParent.setShortcut('CTRL+1')
            self.actionFirstParent.setToolTip(
                _('Backout to the first parent of the merge revision'))
            self.actionFirstParent.clicked.connect(
                lambda: setBackoutMergeParentRev(p1rev))

            self.actionSecondParent = QRadioButton(
                _('Second Parent: revision %s (%s)') % (p2rev, str(bctx.p2())),
                self)
            self.actionSecondParent.setCheckable(True)
            self.actionSecondParent.setShortcut('CTRL+2')
            self.actionSecondParent.setToolTip(
                _('Backout to the second parent of the merge revision'))
            self.actionSecondParent.clicked.connect(
                lambda: setBackoutMergeParentRev(p2rev))

            self.layout().addWidget(self.actionFirstParent)
            self.layout().addWidget(self.actionSecondParent)

        ## working directory status
        sep = qtlib.LabeledSeparator(_('Working directory status'))
        self.layout().addWidget(sep)

        wdbox = QHBoxLayout()
        self.layout().addLayout(wdbox)
        self.wd_status = qtlib.StatusLabel()
        self.wd_status.set_status(_('Checking...'))
        wdbox.addWidget(self.wd_status)
        wd_prog = QProgressBar()
        wd_prog.setMaximum(0)
        wd_prog.setTextVisible(False)
        self.groups.add(wd_prog, 'prog')
        wdbox.addWidget(wd_prog, 1)

        text = _(
            'Before backout, you must <a href="commit"><b>commit</b></a>, '
            '<a href="shelve"><b>shelve</b></a> to patch, '
            'or <a href="discard"><b>discard</b></a> changes.')
        wd_text = QLabel(text)
        wd_text.setWordWrap(True)
        wd_text.linkActivated.connect(self.onLinkActivated)
        self.wd_text = wd_text
        self.groups.add(wd_text, 'dirty')
        self.layout().addWidget(wd_text)

        ## auto-resolve
        autoresolve_chk = QCheckBox(
            _('Automatically resolve merge conflicts '
              'where possible'))
        autoresolve_chk.setChecked(
            repo.ui.configbool('tortoisehg', 'autoresolve', False))
        self.registerField('autoresolve', autoresolve_chk)
        self.layout().addWidget(autoresolve_chk)
        self.autoresolve_chk = autoresolve_chk
        self.groups.set_visible(False, 'dirty')
예제 #5
0
    def __init__(self, repoagent, rev=None, parent=None, opts={}):
        super(UpdateDialog, self).__init__(parent)
        self.setWindowFlags(self.windowFlags() & \
                            ~Qt.WindowContextHelpButtonHint)

        self._repoagent = repoagent
        repo = repoagent.rawRepo()

        # base layout box
        box = QVBoxLayout()
        box.setSpacing(6)

        ## main layout grid
        self.grid = QGridLayout()
        self.grid.setSpacing(6)
        box.addLayout(self.grid)

        ### target revision combo
        self.rev_combo = combo = QComboBox()
        combo.setEditable(True)
        self.grid.addWidget(QLabel(_('Update to:')), 0, 0)
        self.grid.addWidget(combo, 0, 1)

        # Give the combo box a minimum width that will ensure that the dialog is
        # large enough to fit the additional progress bar that will appear when
        # updating subrepositories.
        combo.setMinimumWidth(450)

        # always include integer revision
        try:
            assert not isinstance(rev, (unicode, QString))
            ctx = self.repo[rev]
            if isinstance(ctx.rev(), int):  # could be None or patch name
                combo.addItem(str(ctx.rev()))
        except error.RepoLookupError:
            pass

        for name in repo.namedbranches:
            combo.addItem(hglib.tounicode(name))

        tags = list(self.repo.tags()) + repo._bookmarks.keys()
        tags.sort(reverse=True)
        for tag in tags:
            combo.addItem(hglib.tounicode(tag))

        if rev is None:
            selecturev = hglib.tounicode(self.repo.dirstate.branch())
        else:
            selecturev = hglib.tounicode(str(rev))
        selectindex = combo.findText(selecturev)
        if selectindex >= 0:
            combo.setCurrentIndex(selectindex)
        else:
            combo.setEditText(selecturev)

        ### target revision info
        items = ('%(rev)s', ' %(branch)s', ' %(tags)s', '<br />%(summary)s')
        style = csinfo.labelstyle(contents=items, width=350, selectable=True)
        factory = csinfo.factory(self.repo, style=style)
        self.target_info = factory()
        self.grid.addWidget(QLabel(_('Target:')), 1, 0,
                            Qt.AlignLeft | Qt.AlignTop)
        self.grid.addWidget(self.target_info, 1, 1)

        ### parent revision info
        self.ctxs = self.repo[None].parents()
        if len(self.ctxs) == 2:
            self.p1_info = factory()
            self.grid.addWidget(QLabel(_('Parent 1:')), 2, 0,
                                Qt.AlignLeft | Qt.AlignTop)
            self.grid.addWidget(self.p1_info, 2, 1)
            self.p2_info = factory()
            self.grid.addWidget(QLabel(_('Parent 2:')), 3, 0,
                                Qt.AlignLeft | Qt.AlignTop)
            self.grid.addWidget(self.p2_info, 3, 1)
        else:
            self.p1_info = factory()
            self.grid.addWidget(QLabel(_('Parent:')), 2, 0,
                                Qt.AlignLeft | Qt.AlignTop)
            self.grid.addWidget(self.p1_info, 2, 1)

        ### options
        self.optbox = QVBoxLayout()
        self.optbox.setSpacing(6)
        expander = qtlib.ExpanderLabel(_('Options:'), False)
        expander.expanded.connect(self.show_options)
        row = self.grid.rowCount()
        self.grid.addWidget(expander, row, 0, Qt.AlignLeft | Qt.AlignTop)
        self.grid.addLayout(self.optbox, row, 1)

        self.verbose_chk = QCheckBox(_('List updated files (--verbose)'))
        self.discard_chk = QCheckBox(
            _('Discard local changes, no backup '
              '(-C/--clean)'))
        self.merge_chk = QCheckBox(_('Always merge (when possible)'))
        self.autoresolve_chk = QCheckBox(
            _('Automatically resolve merge conflicts '
              'where possible'))
        self.showlog_chk = QCheckBox(_('Always show command log'))
        self.optbox.addWidget(self.verbose_chk)
        self.optbox.addWidget(self.discard_chk)
        self.optbox.addWidget(self.merge_chk)
        self.optbox.addWidget(self.autoresolve_chk)
        self.optbox.addWidget(self.showlog_chk)

        s = QSettings()

        self.discard_chk.setChecked(bool(opts.get('clean')))

        #### Persisted Options
        self.merge_chk.setChecked(QSettings().value('update/merge',
                                                    False).toBool())

        self.autoresolve_chk.setChecked(
            repo.ui.configbool('tortoisehg', 'autoresolve', False)
            or s.value('update/autoresolve', False).toBool())

        self.showlog_chk.setChecked(s.value('update/showlog', False).toBool())
        self.verbose_chk.setChecked(s.value('update/verbose', False).toBool())

        ## command widget
        self.cmd = cmdui.Widget(True, True, self)
        self.cmd.commandStarted.connect(self.command_started)
        self.cmd.commandFinished.connect(self.command_finished)
        self.cmd.commandCanceling.connect(self.command_canceling)
        self.cmd.output.connect(self.output)
        self.cmd.makeLogVisible.connect(self.makeLogVisible)
        self.cmd.progress.connect(self.progress)
        box.addWidget(self.cmd)

        ## bottom buttons
        buttons = QDialogButtonBox()
        self.cancel_btn = buttons.addButton(QDialogButtonBox.Cancel)
        self.cancel_btn.clicked.connect(self.cancel_clicked)
        self.close_btn = buttons.addButton(QDialogButtonBox.Close)
        self.close_btn.clicked.connect(self.reject)
        self.close_btn.setAutoDefault(False)
        self.update_btn = buttons.addButton(_('&Update'),
                                            QDialogButtonBox.ActionRole)
        self.update_btn.clicked.connect(self.update)
        self.detail_btn = buttons.addButton(_('Detail'),
                                            QDialogButtonBox.ResetRole)
        self.detail_btn.setAutoDefault(False)
        self.detail_btn.setCheckable(True)
        self.detail_btn.toggled.connect(self.detail_toggled)
        box.addWidget(buttons)

        # signal handlers
        self.rev_combo.editTextChanged.connect(self.update_info)
        self.discard_chk.toggled.connect(self.update_info)

        # dialog setting
        self.setLayout(box)
        self.layout().setSizeConstraint(QLayout.SetFixedSize)
        self.setWindowTitle(_('Update - %s') % self.repo.displayname)
        self.setWindowIcon(qtlib.geticon('hg-update'))

        # prepare to show
        self.cmd.setHidden(True)
        self.cancel_btn.setHidden(True)
        self.detail_btn.setHidden(True)
        self.merge_chk.setHidden(True)
        self.autoresolve_chk.setHidden(True)
        self.showlog_chk.setHidden(True)
        self.update_info()
        if not self.update_btn.isEnabled():
            self.rev_combo.lineEdit().selectAll()  # need to change rev

        # expand options if a hidden one is checked
        hiddenOptionsChecked = self.hiddenSettingIsChecked()
        self.show_options(hiddenOptionsChecked)
        expander.set_expanded(hiddenOptionsChecked)
예제 #6
0
    def __init__(self, repo, rev=None, parent=None, opts={}):
        super(MatchDialog, self).__init__(parent)
        self.setWindowFlags(self.windowFlags() & \
                            ~Qt.WindowContextHelpButtonHint)

        self.revsetexpression = ''
        self._finished = False
        self.repo = repo

        # base layout box
        box = QVBoxLayout()
        box.setSpacing(6)

        ## main layout grid
        self.grid = QGridLayout()
        self.grid.setSpacing(6)
        box.addLayout(self.grid)

        ### matched revision combo
        self.rev_combo = combo = QComboBox()
        combo.setEditable(True)
        self.grid.addWidget(QLabel(_('Find revisions matching fields of:')), 0,
                            0)
        self.grid.addWidget(combo, 0, 1)

        # Give the combo box a minimum width that will ensure that the dialog is
        # large enough to fit the additional progress bar that will appear when
        # updating subrepositories.
        combo.setMinimumWidth(450)

        if rev is None:
            rev = self.repo.dirstate.branch()
        else:
            rev = str(rev)
        combo.addItem(hglib.tounicode(rev))
        combo.setCurrentIndex(0)
        # make it easy to match the workding directory parent revision
        combo.addItem(hglib.tounicode('.'))

        tags = list(self.repo.tags()) + repo._bookmarks.keys()
        tags.sort(reverse=True)
        for tag in tags:
            combo.addItem(hglib.tounicode(tag))

        ### matched revision info
        self.rev_to_match_info_text = QLabel()
        self.rev_to_match_info_text.setShown(False)
        style = csinfo.panelstyle(contents=('cset', 'branch', 'close', 'user',
                                            'dateage', 'parents', 'children',
                                            'tags', 'graft', 'transplant',
                                            'p4', 'svn', 'converted'),
                                  selectable=True,
                                  expandable=True)
        factory = csinfo.factory(self.repo, style=style)
        self.rev_to_match_info = factory()
        self.rev_to_match_info_lbl = QLabel(_('Revision to Match:'))
        self.grid.addWidget(self.rev_to_match_info_lbl, 1, 0,
                            Qt.AlignLeft | Qt.AlignTop)
        self.grid.addWidget(self.rev_to_match_info, 1, 1)
        self.grid.addWidget(self.rev_to_match_info_text, 1, 1)

        ### fields that will be matched
        self.optbox = QVBoxLayout()
        self.optbox.setSpacing(6)
        expander = qtlib.ExpanderLabel(_('Fields to match:'), False)
        expander.expanded.connect(self.show_options)
        row = self.grid.rowCount()
        self.grid.addWidget(expander, row, 0, Qt.AlignLeft | Qt.AlignTop)
        self.grid.addLayout(self.optbox, row, 1)

        self.summary_chk = QCheckBox(_('Summary (first description line)'))
        self.description_chk = QCheckBox(_('Description'))
        self.desc_btngroup = QButtonGroup()
        self.desc_btngroup.setExclusive(False)
        self.desc_btngroup.addButton(self.summary_chk)
        self.desc_btngroup.addButton(self.description_chk)
        self.desc_btngroup.buttonClicked.connect(
            self._selectSummaryOrDescription)

        self.author_chk = QCheckBox(_('Author'))
        self.date_chk = QCheckBox(_('Date'))
        self.files_chk = QCheckBox(_('Files'))
        self.diff_chk = QCheckBox(_('Diff contents'))
        self.substate_chk = QCheckBox(_('Subrepo states'))
        self.branch_chk = QCheckBox(_('Branch'))
        self.parents_chk = QCheckBox(_('Parents'))
        self.phase_chk = QCheckBox(_('Phase'))
        self._hideable_chks = (
            self.branch_chk,
            self.phase_chk,
            self.parents_chk,
        )

        has_diff_matching = hglib.hgversion >= "2.3"

        self.optbox.addWidget(self.summary_chk)
        self.optbox.addWidget(self.description_chk)
        self.optbox.addWidget(self.author_chk)
        self.optbox.addWidget(self.date_chk)
        self.optbox.addWidget(self.files_chk)
        if has_diff_matching:
            # if mercurial does not have a "diff" matching mode,
            # we simply "hide" the diff checkbox,
            # to make the saveSettings() method simpler
            self.optbox.addWidget(self.diff_chk)
        self.optbox.addWidget(self.substate_chk)
        self.optbox.addWidget(self.branch_chk)
        self.optbox.addWidget(self.parents_chk)
        self.optbox.addWidget(self.phase_chk)

        s = QSettings()

        #### Persisted Options
        self.summary_chk.setChecked(
            s.value('matching/summary', False).toBool())
        self.description_chk.setChecked(
            s.value('matching/description', True).toBool())
        self.author_chk.setChecked(s.value('matching/author', True).toBool())
        self.branch_chk.setChecked(s.value('matching/branch', False).toBool())
        self.date_chk.setChecked(s.value('matching/date', True).toBool())
        self.files_chk.setChecked(s.value('matching/files', False).toBool())
        self.diff_chk.setChecked(s.value('matching/diff', False).toBool())
        self.parents_chk.setChecked(
            s.value('matching/parents', False).toBool())
        self.phase_chk.setChecked(s.value('matching/phase', False).toBool())
        self.substate_chk.setChecked(
            s.value('matching/substate', False).toBool())

        ## bottom buttons
        buttons = QDialogButtonBox()
        self.close_btn = buttons.addButton(QDialogButtonBox.Close)
        self.close_btn.clicked.connect(self.reject)
        self.close_btn.setAutoDefault(False)
        self.match_btn = buttons.addButton(_('&Match'),
                                           QDialogButtonBox.ActionRole)
        self.match_btn.clicked.connect(self.match)
        box.addWidget(buttons)

        # signal handlers
        self.rev_combo.editTextChanged.connect(self.update_info)

        # dialog setting
        self.setLayout(box)
        self.layout().setSizeConstraint(QLayout.SetFixedSize)
        self.setWindowTitle(_('Find matches - %s') % self.repo.displayname)
        self.setWindowIcon(qtlib.geticon('hg-update'))

        # prepare to show
        self.update_info()
        if not self.match_btn.isEnabled():
            self.rev_combo.lineEdit().selectAll()  # need to change rev

        # expand options if a hidden one is checked
        hiddenOptionsChecked = self.hiddenSettingIsChecked()
        self.show_options(hiddenOptionsChecked)
        expander.set_expanded(hiddenOptionsChecked)
예제 #7
0
    def __init__(self, repo, rev=None, parent=None, opts={}):
        super(MatchDialog, self).__init__(parent)
        self.setWindowFlags(self.windowFlags() & \
                            ~Qt.WindowContextHelpButtonHint)

        self.revsetexpression = ''
        self._finished = False
        self.repo = repo

        # base layout box
        box = QVBoxLayout()
        box.setSpacing(6)

        ## main layout grid
        self.grid = QGridLayout()
        self.grid.setSpacing(6)
        box.addLayout(self.grid)

        ### matched revision combo
        self.rev_combo = combo = QComboBox()
        combo.setEditable(True)
        self.grid.addWidget(QLabel(_('Find revisions matching fields of:')), 0, 0)
        self.grid.addWidget(combo, 0, 1)

        # Give the combo box a minimum width that will ensure that the dialog is
        # large enough to fit the additional progress bar that will appear when
        # updating subrepositories.
        combo.setMinimumWidth(450)

        if rev is None:
            rev = self.repo.dirstate.branch()
        else:
            rev = str(rev)
        combo.addItem(hglib.tounicode(rev))
        combo.setCurrentIndex(0)
        # make it easy to match the workding directory parent revision
        combo.addItem(hglib.tounicode('.'))

        tags = list(self.repo.tags()) + repo._bookmarks.keys()
        tags.sort(reverse=True)
        for tag in tags:
            combo.addItem(hglib.tounicode(tag))

        ### matched revision info
        self.rev_to_match_info_text = QLabel()
        self.rev_to_match_info_text.setShown(False)
        style = csinfo.panelstyle(contents=('cset', 'branch', 'close', 'user',
               'dateage', 'parents', 'children', 'tags', 'graft', 'transplant',
               'p4', 'svn', 'converted'), selectable=True,
               expandable=True)
        factory = csinfo.factory(self.repo, style=style)
        self.rev_to_match_info = factory()
        self.rev_to_match_info_lbl = QLabel(_('Revision to Match:'))
        self.grid.addWidget(self.rev_to_match_info_lbl, 1, 0, Qt.AlignLeft | Qt.AlignTop)
        self.grid.addWidget(self.rev_to_match_info, 1, 1)
        self.grid.addWidget(self.rev_to_match_info_text, 1, 1)

        ### fields that will be matched
        self.optbox = QVBoxLayout()
        self.optbox.setSpacing(6)
        expander = qtlib.ExpanderLabel(_('Fields to match:'), False)
        expander.expanded.connect(self.show_options)
        row = self.grid.rowCount()
        self.grid.addWidget(expander, row, 0, Qt.AlignLeft | Qt.AlignTop)
        self.grid.addLayout(self.optbox, row, 1)

        self.summary_chk = QCheckBox(_('Summary (first description line)'))
        self.description_chk = QCheckBox(_('Description'))
        self.desc_btngroup = QButtonGroup()
        self.desc_btngroup.setExclusive(False)
        self.desc_btngroup.addButton(self.summary_chk)
        self.desc_btngroup.addButton(self.description_chk)
        self.desc_btngroup.buttonClicked.connect(self._selectSummaryOrDescription)

        self.author_chk = QCheckBox(_('Author'))
        self.date_chk = QCheckBox(_('Date'))
        self.files_chk = QCheckBox(_('Files'))
        self.diff_chk = QCheckBox(_('Diff contents'))
        self.substate_chk = QCheckBox(_('Subrepo states'))
        self.branch_chk = QCheckBox(_('Branch'))
        self.parents_chk = QCheckBox(_('Parents'))
        self.phase_chk = QCheckBox(_('Phase'))
        self._hideable_chks = (self.branch_chk, self.phase_chk, self.parents_chk,)

        has_diff_matching = hglib.hgversion >= "2.3"

        self.optbox.addWidget(self.summary_chk)
        self.optbox.addWidget(self.description_chk)
        self.optbox.addWidget(self.author_chk)
        self.optbox.addWidget(self.date_chk)
        self.optbox.addWidget(self.files_chk)
        if has_diff_matching:
            # if mercurial does not have a "diff" matching mode,
            # we simply "hide" the diff checkbox,
            # to make the saveSettings() method simpler
            self.optbox.addWidget(self.diff_chk)
        self.optbox.addWidget(self.substate_chk)
        self.optbox.addWidget(self.branch_chk)
        self.optbox.addWidget(self.parents_chk)
        self.optbox.addWidget(self.phase_chk)

        s = QSettings()

        #### Persisted Options
        self.summary_chk.setChecked(s.value('matching/summary', False).toBool())
        self.description_chk.setChecked(s.value('matching/description', True).toBool())
        self.author_chk.setChecked(s.value('matching/author', True).toBool())
        self.branch_chk.setChecked(s.value('matching/branch', False).toBool())
        self.date_chk.setChecked(s.value('matching/date', True).toBool())
        self.files_chk.setChecked(s.value('matching/files', False).toBool())
        self.diff_chk.setChecked(s.value('matching/diff', False).toBool())
        self.parents_chk.setChecked(s.value('matching/parents', False).toBool())
        self.phase_chk.setChecked(s.value('matching/phase', False).toBool())
        self.substate_chk.setChecked(s.value('matching/substate', False).toBool())

        ## bottom buttons
        buttons = QDialogButtonBox()
        self.close_btn = buttons.addButton(QDialogButtonBox.Close)
        self.close_btn.clicked.connect(self.reject)
        self.close_btn.setAutoDefault(False)
        self.match_btn = buttons.addButton(_('&Match'),
                                            QDialogButtonBox.ActionRole)
        self.match_btn.clicked.connect(self.match)
        box.addWidget(buttons)

        # signal handlers
        self.rev_combo.editTextChanged.connect(self.update_info)

        # dialog setting
        self.setLayout(box)
        self.layout().setSizeConstraint(QLayout.SetFixedSize)
        self.setWindowTitle(_('Find matches - %s') % self.repo.displayname)
        self.setWindowIcon(qtlib.geticon('hg-update'))

        # prepare to show
        self.update_info()
        if not self.match_btn.isEnabled():
            self.rev_combo.lineEdit().selectAll()  # need to change rev

        # expand options if a hidden one is checked
        hiddenOptionsChecked = self.hiddenSettingIsChecked()
        self.show_options(hiddenOptionsChecked)
        expander.set_expanded(hiddenOptionsChecked)
예제 #8
0
    def __init__(self, repoagent, otherrev, parent):
        super(SummaryPage, self).__init__(repoagent, parent)
        self._wctxcleaner = wctxcleaner.WctxCleaner(repoagent, self)
        self._wctxcleaner.checkStarted.connect(self._onCheckStarted)
        self._wctxcleaner.checkFinished.connect(self._onCheckFinished)

        self.setTitle(_('Prepare to merge'))
        self.setSubTitle(_('Verify merge targets and ensure your working '
                           'directory is clean.'))
        self.setLayout(QVBoxLayout())

        repo = self.repo
        contents = ('ishead',) + csinfo.PANEL_DEFAULT
        style = csinfo.panelstyle(contents=contents)
        def markup_func(widget, item, value):
            if item == 'ishead' and value is False:
                text = _('Not a head revision!')
                return qtlib.markup(text, fg='red', weight='bold')
            raise csinfo.UnknownItem(item)
        custom = csinfo.custom(markup=markup_func)
        create = csinfo.factory(repo, custom, style, withupdate=True)

        ## merge target
        other_sep = qtlib.LabeledSeparator(_('Merge from (other revision)'))
        self.layout().addWidget(other_sep)
        otherCsInfo = create(otherrev)
        self.layout().addWidget(otherCsInfo)
        self.otherCsInfo = otherCsInfo

        ## current revision
        local_sep = qtlib.LabeledSeparator(_('Merge to (working directory)'))
        self.layout().addWidget(local_sep)
        localCsInfo = create(str(repo['.'].rev()))
        self.layout().addWidget(localCsInfo)
        self.localCsInfo = localCsInfo

        ## working directory status
        wd_sep = qtlib.LabeledSeparator(_('Working directory status'))
        self.layout().addWidget(wd_sep)

        self.groups = qtlib.WidgetGroups()

        wdbox = QHBoxLayout()
        self.layout().addLayout(wdbox)
        self.wd_status = qtlib.StatusLabel()
        self.wd_status.set_status(_('Checking...'))
        wdbox.addWidget(self.wd_status)
        wd_prog = QProgressBar()
        wd_prog.setMaximum(0)
        wd_prog.setTextVisible(False)
        self.groups.add(wd_prog, 'prog')
        wdbox.addWidget(wd_prog, 1)

        wd_merged = QLabel(_('The working directory is already <b>merged</b>. '
                             '<a href="skip"><b>Continue</b></a> or '
                             '<a href="discard"><b>discard</b></a> existing '
                             'merge.'))
        wd_merged.linkActivated.connect(self.onLinkActivated)
        wd_merged.setWordWrap(True)
        self.groups.add(wd_merged, 'merged')
        self.layout().addWidget(wd_merged)

        text = _('Before merging, you must <a href="commit"><b>commit</b></a>, '
                 '<a href="shelve"><b>shelve</b></a> to patch, '
                 'or <a href="discard"><b>discard</b></a> changes.')
        wd_text = QLabel(text)
        wd_text.setWordWrap(True)
        wd_text.linkActivated.connect(self._wctxcleaner.runCleaner)
        self.wd_text = wd_text
        self.groups.add(wd_text, 'dirty')
        self.layout().addWidget(wd_text)

        wdbox = QHBoxLayout()
        self.layout().addLayout(wdbox)
        wd_alt = QLabel(_('Or use:'))
        self.groups.add(wd_alt, 'dirty')
        wdbox.addWidget(wd_alt)
        force_chk = QCheckBox(_('Force a merge with outstanding changes '
                                '(-f/--force)'))
        force_chk.toggled.connect(lambda c: self.completeChanged.emit())
        self.registerField('force', force_chk)
        self.groups.add(force_chk, 'dirty')
        wdbox.addWidget(force_chk)

        ### discard option
        discard_chk = QCheckBox(_('Discard all changes from the other '
                                  'revision'))
        self.registerField('discard', discard_chk)
        self.layout().addWidget(discard_chk)

        ## auto-resolve
        autoresolve_chk = QCheckBox(_('Automatically resolve merge conflicts '
                                      'where possible'))
        self.registerField('autoresolve', autoresolve_chk)
        self.layout().addWidget(autoresolve_chk)

        self.groups.set_visible(False, 'dirty')
        self.groups.set_visible(False, 'merged')
예제 #9
0
    def __init__(self, repoagent, rev=None, parent=None):
        super(RemoteUpdateWidget, self).__init__(parent)
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        self._repoagent = repoagent
        repo = repoagent.rawRepo()

        ## main layout
        form = QFormLayout()
        form.setContentsMargins(0, 0, 0, 0)
        form.setSpacing(6)
        self.setLayout(form)

        ### target path combo
        self.path_combo = pcombo = QComboBox()
        pcombo.setEditable(True)
        pcombo.addItems([hglib.tounicode(path)
                         for _name, path in repo.ui.configitems('paths')])
        form.addRow(_('Location:'), pcombo)

        ### target revision combo
        self.rev_combo = combo = QComboBox()
        combo.setEditable(True)
        form.addRow(_('Update to:'), combo)

        combo.addItems(map(hglib.tounicode, hglib.namedbranches(repo)))
        tags = list(self.repo.tags()) + repo._bookmarks.keys()
        tags.sort(reverse=True)
        combo.addItems(map(hglib.tounicode, tags))

        if rev is None:
            selecturev = hglib.tounicode(self.repo.dirstate.branch())
        else:
            selecturev = hglib.tounicode(str(rev))
        selectindex = combo.findText(selecturev)
        if selectindex >= 0:
            combo.setCurrentIndex(selectindex)
        else:
            combo.setEditText(selecturev)

        ### target revision info
        items = ('%(rev)s', ' %(branch)s', ' %(tags)s', '<br />%(summary)s')
        style = csinfo.labelstyle(contents=items, width=350, selectable=True)
        factory = csinfo.factory(self.repo, style=style)
        self.target_info = factory()
        form.addRow(_('Target:'), self.target_info)

        ### Options
        self.optbox = QVBoxLayout()
        self.optbox.setSpacing(6)
        self.optexpander = expander = qtlib.ExpanderLabel(_('Options:'), False)
        expander.expanded.connect(self.show_options)
        form.addRow(expander, self.optbox)

        self.discard_chk = QCheckBox(_('Discard remote changes, no backup '
                                       '(-C/--clean)'))
        self.push_chk = QCheckBox(_('Perform a push before updating'
                                        ' (-p/--push)'))
        self.newbranch_chk = QCheckBox(_('Allow pushing new branches'
                                        ' (--new-branch)'))
        self.force_chk = QCheckBox(_('Force push to remote location'
                                        ' (-f/--force)'))
        self.optbox.addWidget(self.discard_chk)
        self.optbox.addWidget(self.push_chk)
        self.optbox.addWidget(self.newbranch_chk)
        self.optbox.addWidget(self.force_chk)

        # signal handlers
        self.rev_combo.editTextChanged.connect(self.update_info)

        # prepare to show
        self.push_chk.setHidden(True)
        self.newbranch_chk.setHidden(True)
        self.force_chk.setHidden(True)
        self.update_info()
예제 #10
0
    def __init__(self, repoagent, rev=None, parent=None, opts={}):
        super(UpdateWidget, self).__init__(parent)
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        self._repoagent = repoagent
        repo = repoagent.rawRepo()

        ## main layout
        form = QFormLayout()
        form.setContentsMargins(0, 0, 0, 0)
        form.setSpacing(6)
        self.setLayout(form)

        ### target revision combo
        self.rev_combo = combo = QComboBox()
        combo.setEditable(True)
        combo.setMinimumContentsLength(30)  # cut long name
        combo.installEventFilter(qtlib.BadCompletionBlocker(combo))
        form.addRow(_('Update to:'), combo)

        # always include integer revision
        try:
            assert not isinstance(rev, (unicode, QString))
            ctx = self.repo[rev]
            if isinstance(ctx.rev(), int):  # could be None or patch name
                combo.addItem(str(ctx.rev()))
        except error.RepoLookupError:
            pass

        combo.addItems(map(hglib.tounicode, hglib.namedbranches(repo)))
        tags = list(self.repo.tags()) + repo._bookmarks.keys()
        tags.sort(reverse=True)
        combo.addItems(map(hglib.tounicode, tags))

        if rev is None:
            selecturev = hglib.tounicode(self.repo.dirstate.branch())
        else:
            selecturev = hglib.tounicode(str(rev))
        selectindex = combo.findText(selecturev)
        if selectindex >= 0:
            combo.setCurrentIndex(selectindex)
        else:
            combo.setEditText(selecturev)

        ### target revision info
        items = ('%(rev)s', ' %(branch)s', ' %(tags)s', '<br />%(summary)s')
        style = csinfo.labelstyle(contents=items, width=350, selectable=True)
        factory = csinfo.factory(self.repo, style=style)
        self.target_info = factory()
        form.addRow(_('Target:'), self.target_info)

        ### parent revision info
        self.ctxs = self.repo[None].parents()
        if len(self.ctxs) == 2:
            self.p1_info = factory()
            form.addRow(_('Parent 1:'), self.p1_info)
            self.p2_info = factory()
            form.addRow(_('Parent 2:'), self.p2_info)
        else:
            self.p1_info = factory()
            form.addRow(_('Parent:'), self.p1_info)

        # show a subrepo "pull path" combo, with the
        # default path as the first (and default) path
        self.path_combo_label = QLabel(_('Pull subrepos from:'))
        self.path_combo = QComboBox(self)
        syncpaths = dict(repo.ui.configitems('paths'))
        aliases = sorted(syncpaths)
        # make sure that the default path is the first one
        if 'default' in aliases:
            aliases.remove('default')
            aliases.insert(0, 'default')
        for n, alias in enumerate(aliases):
            self.path_combo.addItem(hglib.tounicode(alias))
            self.path_combo.setItemData(
                n, hglib.tounicode(syncpaths[alias]))
        self.path_combo.currentIndexChanged.connect(
            self._updatePathComboTooltip)
        self._updatePathComboTooltip(0)
        form.addRow(self.path_combo_label, self.path_combo)

        ### options
        self.optbox = QVBoxLayout()
        self.optbox.setSpacing(6)
        self.optexpander = expander = qtlib.ExpanderLabel(_('Options:'), False)
        expander.expanded.connect(self.show_options)
        form.addRow(expander, self.optbox)

        self.verbose_chk = QCheckBox(_('List updated files (--verbose)'))
        self.discard_chk = QCheckBox(_('Discard local changes, no backup '
                                       '(-C/--clean)'))
        self.merge_chk = QCheckBox(_('Always merge (when possible)'))
        self.autoresolve_chk = QCheckBox(_('Automatically resolve merge '
                                           'conflicts where possible'))
        self.optbox.addWidget(self.verbose_chk)
        self.optbox.addWidget(self.discard_chk)
        self.optbox.addWidget(self.merge_chk)
        self.optbox.addWidget(self.autoresolve_chk)

        self.discard_chk.setChecked(bool(opts.get('clean')))

        # signal handlers
        self.rev_combo.editTextChanged.connect(self.update_info)
        self.discard_chk.toggled.connect(self.update_info)

        # prepare to show
        self.merge_chk.setHidden(True)
        self.autoresolve_chk.setHidden(True)
        self.update_info()
        if not self.canRunCommand():
            # need to change rev
            self.rev_combo.lineEdit().selectAll()
예제 #11
0
    def initializePage(self):
        if self.layout():
            return
        self.setTitle(_('Prepare to backout'))
        self.setSubTitle(_('Verify backout revision and ensure your working '
                           'directory is clean.'))
        self.setLayout(QVBoxLayout())

        self.groups = qtlib.WidgetGroups()

        repo = self.repo
        try:
            bctx = repo[self.wizard().backoutrev]
            pctx = repo['.']
        except error.RepoLookupError:
            qtlib.InfoMsgBox(_('Unable to backout'),
                             _('Backout revision not found'))
            QTimer.singleShot(0, self.wizard().close)
            return

        if pctx == bctx:
            lbl = _('Backing out a parent revision is a single step operation')
            self.layout().addWidget(QLabel(u'<b>%s</b>' % lbl))
            self.wizard().parentbackout = True

        op1, op2 = repo.dirstate.parents()
        if op1 is None:
            qtlib.InfoMsgBox(_('Unable to backout'),
                             _('Backout requires a parent revision'))
            QTimer.singleShot(0, self.wizard().close)
            return

        a = repo.changelog.ancestor(op1, bctx.node())
        if a != bctx.node():
            qtlib.InfoMsgBox(_('Unable to backout'),
                             _('Cannot backout change on a different branch'))
            QTimer.singleShot(0, self.wizard().close)

        ## backout revision
        style = csinfo.panelstyle(contents=csinfo.PANEL_DEFAULT)
        create = csinfo.factory(repo, None, style, withupdate=True)
        sep = qtlib.LabeledSeparator(_('Backout revision'))
        self.layout().addWidget(sep)
        backoutCsInfo = create(bctx.rev())
        self.layout().addWidget(backoutCsInfo)

        ## current revision
        contents = ('ishead',) + csinfo.PANEL_DEFAULT
        style = csinfo.panelstyle(contents=contents)
        def markup_func(widget, item, value):
            if item == 'ishead' and value is False:
                text = _('Not a head, backout will create a new head!')
                return qtlib.markup(text, fg='red', weight='bold')
            raise csinfo.UnknownItem(item)
        custom = csinfo.custom(markup=markup_func)
        create = csinfo.factory(repo, custom, style, withupdate=True)

        sep = qtlib.LabeledSeparator(_('Current local revision'))
        self.layout().addWidget(sep)
        localCsInfo = create(pctx.rev())
        self.layout().addWidget(localCsInfo)
        self.localCsInfo = localCsInfo

        ## Merge revision backout handling
        if len(bctx.parents()) > 1:
            # Show two radio buttons letting the user which merge revision
            # parent to backout to
            p1rev = bctx.p1().rev()
            p2rev = bctx.p2().rev()

            def setBackoutMergeParentRev(rev):
                self.wizard().backoutmergeparentrev = rev

            setBackoutMergeParentRev(p1rev)

            sep = qtlib.LabeledSeparator(_('Merge parent to backout to'))
            self.layout().addWidget(sep)
            self.layout().addWidget(QLabel(
                _('To backout a <b>merge</b> revision you must select which '
                'parent to backout to '
                '(i.e. whose changes will be <i>kept</i>)')))

            self.actionFirstParent = QRadioButton(
                _('First Parent: revision %s (%s)') \
                % (p1rev, str(bctx.p1())), self)
            self.actionFirstParent.setCheckable(True)
            self.actionFirstParent.setChecked(True)
            self.actionFirstParent.setShortcut('CTRL+1')
            self.actionFirstParent.setToolTip(
                _('Backout to the first parent of the merge revision'))
            self.actionFirstParent.clicked.connect(
                lambda: setBackoutMergeParentRev(p1rev))

            self.actionSecondParent = QRadioButton(
                _('Second Parent: revision %s (%s)')
                % (p2rev, str(bctx.p2())), self)
            self.actionSecondParent.setCheckable(True)
            self.actionSecondParent.setShortcut('CTRL+2')
            self.actionSecondParent.setToolTip(
                _('Backout to the second parent of the merge revision'))
            self.actionSecondParent.clicked.connect(
                lambda: setBackoutMergeParentRev(p2rev))

            self.layout().addWidget(self.actionFirstParent)
            self.layout().addWidget(self.actionSecondParent)

        ## working directory status
        sep = qtlib.LabeledSeparator(_('Working directory status'))
        self.layout().addWidget(sep)

        wdbox = QHBoxLayout()
        self.layout().addLayout(wdbox)
        self.wd_status = qtlib.StatusLabel()
        self.wd_status.set_status(_('Checking...'))
        wdbox.addWidget(self.wd_status)
        wd_prog = QProgressBar()
        wd_prog.setMaximum(0)
        wd_prog.setTextVisible(False)
        self.groups.add(wd_prog, 'prog')
        wdbox.addWidget(wd_prog, 1)

        text = _('Before backout, you must <a href="commit"><b>commit</b></a>, '
                 '<a href="shelve"><b>shelve</b></a> to patch, '
                 'or <a href="discard"><b>discard</b></a> changes.')
        wd_text = QLabel(text)
        wd_text.setWordWrap(True)
        wd_text.linkActivated.connect(self.onLinkActivated)
        self.wd_text = wd_text
        self.groups.add(wd_text, 'dirty')
        self.layout().addWidget(wd_text)

        ## auto-resolve
        autoresolve_chk = QCheckBox(_('Automatically resolve merge conflicts '
                                      'where possible'))
        autoresolve_chk.setChecked(
            repo.ui.configbool('tortoisehg', 'autoresolve', False))
        self.registerField('autoresolve', autoresolve_chk)
        self.layout().addWidget(autoresolve_chk)
        self.autoresolve_chk = autoresolve_chk
        self.groups.set_visible(False, 'dirty')
예제 #12
0
    def __init__(self, repo, rev=None, parent=None, opts={}):
        super(UpdateDialog, self).__init__(parent)
        self.setWindowFlags(self.windowFlags() & \
                            ~Qt.WindowContextHelpButtonHint)

        self._finished = False
        self.repo = repo

        # base layout box
        box = QVBoxLayout()
        box.setSpacing(6)

        ## main layout grid
        self.grid = QGridLayout()
        self.grid.setSpacing(6)
        box.addLayout(self.grid)

        ### target revision combo
        self.rev_combo = combo = QComboBox()
        combo.setEditable(True)
        self.grid.addWidget(QLabel(_('Update to:')), 0, 0)
        self.grid.addWidget(combo, 0, 1)

        # Give the combo box a minimum width that will ensure that the dialog is
        # large enough to fit the additional progress bar that will appear when
        # updating subrepositories.
        combo.setMinimumWidth(450)

        if rev is None:
            rev = self.repo.dirstate.branch()
        else:
            rev = str(rev)
        combo.addItem(hglib.tounicode(rev))
        combo.setCurrentIndex(0)

        for name in repo.namedbranches:
            combo.addItem(name)

        tags = list(self.repo.tags()) + repo._bookmarks.keys()
        tags.sort(reverse=True)
        for tag in tags:
            combo.addItem(hglib.tounicode(tag))

        ### target revision info
        items = ('%(rev)s', ' %(branch)s', ' %(tags)s', '<br />%(summary)s')
        style = csinfo.labelstyle(contents=items, width=350, selectable=True)
        factory = csinfo.factory(self.repo, style=style)
        self.target_info = factory()
        self.grid.addWidget(QLabel(_('Target:')), 1, 0, Qt.AlignLeft | Qt.AlignTop)
        self.grid.addWidget(self.target_info, 1, 1)

        ### parent revision info
        self.ctxs = self.repo[None].parents()
        if len(self.ctxs) == 2:
            self.p1_info = factory()
            self.grid.addWidget(QLabel(_('Parent 1:')), 2, 0, Qt.AlignLeft | Qt.AlignTop)
            self.grid.addWidget(self.p1_info, 2, 1)
            self.p2_info = factory()
            self.grid.addWidget(QLabel(_('Parent 2:')), 3, 0, Qt.AlignLeft | Qt.AlignTop)
            self.grid.addWidget(self.p2_info, 3, 1)
        else:
            self.p1_info = factory()
            self.grid.addWidget(QLabel(_('Parent:')), 2, 0, Qt.AlignLeft | Qt.AlignTop)
            self.grid.addWidget(self.p1_info, 2, 1)

        ### options
        self.optbox = QVBoxLayout()
        self.optbox.setSpacing(6)
        expander = qtlib.ExpanderLabel(_('Options:'), False)
        expander.expanded.connect(self.show_options)
        row = self.grid.rowCount()
        self.grid.addWidget(expander, row, 0, Qt.AlignLeft | Qt.AlignTop)
        self.grid.addLayout(self.optbox, row, 1)

        self.verbose_chk = QCheckBox(_('List updated files (--verbose)'))
        self.discard_chk = QCheckBox(_('Discard local changes, no backup '
                                       '(-C/--clean)'))
        self.merge_chk = QCheckBox(_('Always merge (when possible)'))
        self.autoresolve_chk = QCheckBox(_('Automatically resolve merge conflicts '
                                           'where possible'))
        self.showlog_chk = QCheckBox(_('Always show command log'))
        self.optbox.addWidget(self.verbose_chk)
        self.optbox.addWidget(self.discard_chk)
        self.optbox.addWidget(self.merge_chk)
        self.optbox.addWidget(self.autoresolve_chk)
        self.optbox.addWidget(self.showlog_chk)

        s = QSettings()

        self.discard_chk.setChecked(bool(opts.get('clean')))

        #### Persisted Options
        self.merge_chk.setChecked(
            QSettings().value('update/merge', False).toBool())

        self.autoresolve_chk.setChecked(
            repo.ui.configbool('tortoisehg', 'autoresolve', False) or
                s.value('update/autoresolve', False).toBool())

        self.showlog_chk.setChecked(s.value('update/showlog', False).toBool())
        self.verbose_chk.setChecked(s.value('update/verbose', False).toBool())

        ## command widget
        self.cmd = cmdui.Widget(True, True, self)
        self.cmd.commandStarted.connect(self.command_started)
        self.cmd.commandFinished.connect(self.command_finished)
        self.cmd.commandCanceling.connect(self.command_canceling)
        self.cmd.output.connect(self.output)
        self.cmd.makeLogVisible.connect(self.makeLogVisible)
        self.cmd.progress.connect(self.progress)
        box.addWidget(self.cmd)

        ## bottom buttons
        buttons = QDialogButtonBox()
        self.cancel_btn = buttons.addButton(QDialogButtonBox.Cancel)
        self.cancel_btn.clicked.connect(self.cancel_clicked)
        self.close_btn = buttons.addButton(QDialogButtonBox.Close)
        self.close_btn.clicked.connect(self.reject)
        self.close_btn.setAutoDefault(False)
        self.update_btn = buttons.addButton(_('&Update'),
                                            QDialogButtonBox.ActionRole)
        self.update_btn.clicked.connect(self.update)
        self.detail_btn = buttons.addButton(_('Detail'),
                                            QDialogButtonBox.ResetRole)
        self.detail_btn.setAutoDefault(False)
        self.detail_btn.setCheckable(True)
        self.detail_btn.toggled.connect(self.detail_toggled)
        box.addWidget(buttons)

        # signal handlers
        self.rev_combo.editTextChanged.connect(self.update_info)
        self.discard_chk.toggled.connect(self.update_info)

        # dialog setting
        self.setLayout(box)
        self.layout().setSizeConstraint(QLayout.SetFixedSize)
        self.setWindowTitle(_('Update - %s') % self.repo.displayname)
        self.setWindowIcon(qtlib.geticon('hg-update'))

        # prepare to show
        self.cmd.setHidden(True)
        self.cancel_btn.setHidden(True)
        self.detail_btn.setHidden(True)
        self.merge_chk.setHidden(True)
        self.autoresolve_chk.setHidden(True)
        self.showlog_chk.setHidden(True)
        self.update_info()
        if not self.update_btn.isEnabled():
            self.rev_combo.lineEdit().selectAll()  # need to change rev

        # expand options if a hidden one is checked
        self.show_options(self.hiddenSettingIsChecked())
예제 #13
0
    def initializePage(self):
        if self.layout():
            return
        self.setTitle(_('Prepare to merge'))
        self.setSubTitle(
            _('Verify merge targets and ensure your working '
              'directory is clean.'))
        self.setLayout(QVBoxLayout())

        repo = self.repo
        contents = ('ishead', ) + csinfo.PANEL_DEFAULT
        style = csinfo.panelstyle(contents=contents)

        def markup_func(widget, item, value):
            if item == 'ishead' and value is False:
                text = _('Not a head revision!')
                return qtlib.markup(text, fg='red', weight='bold')
            raise csinfo.UnknownItem(item)

        custom = csinfo.custom(markup=markup_func)
        create = csinfo.factory(repo, custom, style, withupdate=True)

        ## merge target
        other_sep = qtlib.LabeledSeparator(_('Merge from (other revision)'))
        self.layout().addWidget(other_sep)
        try:
            otherCsInfo = create(self.wizard().otherrev)
            self.layout().addWidget(otherCsInfo)
            self.otherCsInfo = otherCsInfo
        except error.RepoLookupError:
            qtlib.InfoMsgBox(_('Unable to merge'),
                             _('Merge revision not specified or not found'))
            QTimer.singleShot(0, self.wizard().close)

        ## current revision
        local_sep = qtlib.LabeledSeparator(_('Merge to (working directory)'))
        self.layout().addWidget(local_sep)
        localCsInfo = create(self.wizard().localrev)
        self.layout().addWidget(localCsInfo)
        self.localCsInfo = localCsInfo

        ## working directory status
        wd_sep = qtlib.LabeledSeparator(_('Working directory status'))
        self.layout().addWidget(wd_sep)

        self.groups = qtlib.WidgetGroups()

        wdbox = QHBoxLayout()
        self.layout().addLayout(wdbox)
        self.wd_status = qtlib.StatusLabel()
        self.wd_status.set_status(_('Checking...'))
        wdbox.addWidget(self.wd_status)
        wd_prog = QProgressBar()
        wd_prog.setMaximum(0)
        wd_prog.setTextVisible(False)
        self.groups.add(wd_prog, 'prog')
        wdbox.addWidget(wd_prog, 1)

        wd_merged = QLabel(
            _('The working directory is already <b>merged</b>. '
              '<a href="skip"><b>Continue</b></a> or '
              '<a href="discard"><b>discard</b></a> existing '
              'merge.'))
        wd_merged.linkActivated.connect(self.onLinkActivated)
        wd_merged.setWordWrap(True)
        self.groups.add(wd_merged, 'merged')
        self.layout().addWidget(wd_merged)

        text = _(
            'Before merging, you must <a href="commit"><b>commit</b></a>, '
            '<a href="shelve"><b>shelve</b></a> to patch, '
            'or <a href="discard"><b>discard</b></a> changes.')
        wd_text = QLabel(text)
        wd_text.setWordWrap(True)
        wd_text.linkActivated.connect(self.onLinkActivated)
        self.wd_text = wd_text
        self.groups.add(wd_text, 'dirty')
        self.layout().addWidget(wd_text)

        wdbox = QHBoxLayout()
        self.layout().addLayout(wdbox)
        wd_alt = QLabel(_('Or use:'))
        self.groups.add(wd_alt, 'dirty')
        wdbox.addWidget(wd_alt)
        force_chk = QCheckBox(
            _('Force a merge with outstanding changes '
              '(-f/--force)'))
        force_chk.toggled.connect(lambda c: self.completeChanged.emit())
        self.registerField('force', force_chk)
        self.groups.add(force_chk, 'dirty')
        wdbox.addWidget(force_chk)

        ### options
        expander = qtlib.ExpanderLabel(_('Options'), False)
        expander.expanded.connect(self.toggleShowOptions)
        self.layout().addWidget(expander)
        self.expander = expander

        ### discard option
        discard_chk = QCheckBox(
            _('Discard all changes from merge target '
              '(other) revision'))
        self.registerField('discard', discard_chk)
        self.layout().addWidget(discard_chk)
        self.discard_chk = discard_chk

        ## auto-resolve
        autoresolve_chk = QCheckBox(
            _('Automatically resolve merge conflicts '
              'where possible'))
        autoresolve_chk.setChecked(
            repo.ui.configbool('tortoisehg', 'autoresolve', False))
        self.registerField('autoresolve', autoresolve_chk)
        self.layout().addWidget(autoresolve_chk)
        self.autoresolve_chk = autoresolve_chk

        self.groups.set_visible(False, 'dirty')
        self.groups.set_visible(False, 'merged')
        self.toggleShowOptions(self.expander.is_expanded())
예제 #14
0
    def __init__(self, repoagent, backoutrev, parentbackout, parent):
        super(SummaryPage, self).__init__(repoagent, parent)
        self._wctxcleaner = wctxcleaner.WctxCleaner(repoagent, self)
        self._wctxcleaner.checkStarted.connect(self._onCheckStarted)
        self._wctxcleaner.checkFinished.connect(self._onCheckFinished)
        self.setTitle(_('Prepare to backout'))
        self.setSubTitle(_('Verify backout revision and ensure your working '
                           'directory is clean.'))
        self.setLayout(QVBoxLayout())

        self.groups = qtlib.WidgetGroups()

        repo = self.repo
        bctx = repo[backoutrev]
        pctx = repo['.']

        if parentbackout:
            lbl = _('Backing out a parent revision is a single step operation')
            self.layout().addWidget(QLabel(u'<b>%s</b>' % lbl))

        ## backout revision
        style = csinfo.panelstyle(contents=csinfo.PANEL_DEFAULT)
        create = csinfo.factory(repo, None, style, withupdate=True)
        sep = qtlib.LabeledSeparator(_('Backout revision'))
        self.layout().addWidget(sep)
        backoutCsInfo = create(bctx.rev())
        self.layout().addWidget(backoutCsInfo)

        ## current revision
        contents = ('ishead',) + csinfo.PANEL_DEFAULT
        style = csinfo.panelstyle(contents=contents)
        def markup_func(widget, item, value):
            if item == 'ishead' and value is False:
                text = _('Not a head, backout will create a new head!')
                return qtlib.markup(text, fg='red', weight='bold')
            raise csinfo.UnknownItem(item)
        custom = csinfo.custom(markup=markup_func)
        create = csinfo.factory(repo, custom, style, withupdate=True)

        sep = qtlib.LabeledSeparator(_('Current local revision'))
        self.layout().addWidget(sep)
        localCsInfo = create(pctx.rev())
        self.layout().addWidget(localCsInfo)
        self.localCsInfo = localCsInfo

        ## working directory status
        sep = qtlib.LabeledSeparator(_('Working directory status'))
        self.layout().addWidget(sep)

        wdbox = QHBoxLayout()
        self.layout().addLayout(wdbox)
        self.wd_status = qtlib.StatusLabel()
        self.wd_status.set_status(_('Checking...'))
        wdbox.addWidget(self.wd_status)
        wd_prog = QProgressBar()
        wd_prog.setMaximum(0)
        wd_prog.setTextVisible(False)
        self.groups.add(wd_prog, 'prog')
        wdbox.addWidget(wd_prog, 1)

        text = _('Before backout, you must <a href="commit"><b>commit</b></a>, '
                 '<a href="shelve"><b>shelve</b></a> to patch, '
                 'or <a href="discard"><b>discard</b></a> changes.')
        wd_text = QLabel(text)
        wd_text.setWordWrap(True)
        wd_text.linkActivated.connect(self._wctxcleaner.runCleaner)
        self.wd_text = wd_text
        self.groups.add(wd_text, 'dirty')
        self.layout().addWidget(wd_text)

        ## auto-resolve
        autoresolve_chk = QCheckBox(_('Automatically resolve merge conflicts '
                                      'where possible'))
        self.registerField('autoresolve', autoresolve_chk)
        self.layout().addWidget(autoresolve_chk)
        self.groups.set_visible(False, 'dirty')