def __init__(self, repo, patchname, parent): super(QRenameDialog, self).__init__(parent) self.setWindowTitle(_('Patch rename - %s') % repo.displayname) f = self.windowFlags() self.setWindowFlags(f & ~Qt.WindowContextHelpButtonHint) self.setMinimumWidth(400) self.repo = repo self.oldpatchname = patchname self.newpatchname = '' self.setLayout(QVBoxLayout()) lbl = QLabel(_('Rename patch <b>%s</b> to:') % hglib.tounicode(self.oldpatchname)) self.layout().addWidget(lbl) self.le = QLineEdit(hglib.tounicode(self.oldpatchname)) self.layout().addWidget(self.le) self.cmd = cmdui.Runner(True, self) self.cmd.output.connect(self.output) self.cmd.makeLogVisible.connect(self.makeLogVisible) self.cmd.commandFinished.connect(self.onCommandFinished) BB = QDialogButtonBox bbox = QDialogButtonBox(BB.Ok|BB.Cancel) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) self.layout().addWidget(bbox) self.bbox = bbox self.focus = self.le
def __init__(self, title, message, parent, choices, default=None, esc=None, files=None): QDialog.__init__(self, parent) self.setWindowTitle(hglib.tounicode(title)) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) self.box = QHBoxLayout() self.vbox = QVBoxLayout() self.vbox.setSpacing(8) self.message_lbl = QLabel() self.message_lbl.setText(message) self.vbox.addWidget(self.message_lbl) self.choice_combo = combo = QComboBox() self.choices = choices combo.addItems([hglib.tounicode(item) for item in choices]) if default: try: combo.setCurrentIndex(choices.index(default)) except: # Ignore a missing default value pass self.vbox.addWidget(combo) self.box.addLayout(self.vbox) vbox = QVBoxLayout() self.ok = QPushButton('&OK') self.ok.clicked.connect(self.accept) vbox.addWidget(self.ok) self.cancel = QPushButton('&Cancel') self.cancel.clicked.connect(self.reject) vbox.addWidget(self.cancel) vbox.addStretch() self.box.addLayout(vbox) self.setLayout(self.box)
def _updatebranchfilter(self): """Update the list of branches""" curbranch = self.branch() if self._abranchAction.isChecked(): branches = sorted(set([self._repo[n].branch() for n in self._repo.heads() if not self._repo[n].extra().get('close')])) elif self._cbranchAction.isChecked(): branches = sorted(self._repo.branchtags().keys()) else: branches = self._repo.namedbranches # easy access to common branches (Python sorted() is stable) priomap = {self._repo.dirstate.branch(): -2, 'default': -1} branches = sorted(branches, key=lambda e: priomap.get(e, 0)) self._branchReloading = True self._branchCombo.clear() self._branchCombo.addItem(self._allBranchesLabel) for branch in branches: self._branchCombo.addItem(hglib.tounicode(branch)) self._branchCombo.setItemData(self._branchCombo.count() - 1, hglib.tounicode(branch), Qt.ToolTipRole) self._branchCombo.setEnabled(self.filterEnabled and bool(branches)) self._branchReloading = False if curbranch and curbranch not in branches: self._emitBranchChanged() # falls back to "show all" else: self.setBranch(curbranch)
def _workbench(ui, *pats, **opts): root = opts.get('root') or paths.find_root() # TODO: unclear that _workbench() is called inside qtrun(). maybe this # function should receive factory object instead of using global qtrun. w = qtrun.createWorkbench() if root: root = hglib.tounicode(root) bundle = opts.get('bundle') if bundle: w.openRepo(root, False, bundle=hglib.tounicode(bundle)) else: w.showRepo(root) if pats: q = [] for f in pats: pat = hglib.canonpaths([f])[0] if os.path.isdir(f): q.append('file("%s/**")' % pat) elif os.path.isfile(f): q.append('file("%s")' % pat) w.setRevsetFilter(root, ' or '.join(q)) if w.repoTabsWidget.count() <= 0: w.reporegistry.setVisible(True) return w
def run(ui, *pats, **opts): root = opts.get('root') or paths.find_root() if root and pats: repo = thgrepo.repository(ui, root) pats = hglib.canonpaths(pats) if len(pats) == 1 and os.path.isfile(repo.wjoin(pats[0])): from tortoisehg.hgqt.filedialogs import FileLogDialog fname = pats[0] ufname = hglib.tounicode(fname) dlg = FileLogDialog(repo, fname, None) dlg.setWindowTitle(_('Hg file log viewer [%s] - %s') % ( repo.displayname, ufname)) return dlg w = Workbench() if root: root = hglib.tounicode(root) w.showRepo(root) if pats: q = [] for pat in pats: f = repo.wjoin(pat) if os.path.isdir(f): q.append('file("%s/**")' % pat) elif os.path.isfile(f): q.append('file("%s")' % pat) w.setRevsetFilter(root, ' or '.join(q)) if w.repoTabsWidget.count() <= 0: w.reporegistry.setVisible(True) return w
def interact_handler(self, wrapper): prompt, password, choices, default = wrapper.data prompt = hglib.tounicode(prompt) if choices: dlg = QMessageBox(QMessageBox.Question, _('TortoiseHg Prompt'), prompt, parent=self.parent()) dlg.setWindowFlags(Qt.Sheet) dlg.setWindowModality(Qt.WindowModal) for index, choice in enumerate(choices): button = dlg.addButton(hglib.tounicode(choice), QMessageBox.ActionRole) button.response = index if index == default: dlg.setDefaultButton(button) dlg.exec_() button = dlg.clickedButton() if button is 0: self.responseq.put(None) else: self.responseq.put(button.response) else: mode = password and QLineEdit.Password \ or QLineEdit.Normal text, ok = qtlib.getTextInput(self.parent(), _('TortoiseHg Prompt'), prompt.title(), mode=mode) if ok: text = hglib.fromunicode(text) else: text = None self.responseq.put(text)
def savefiles(repo, files, rev, parent=None): for curfile in files: wfile = util.localpath(curfile) wfile, ext = os.path.splitext(os.path.basename(wfile)) if wfile: filename = "%s@%d%s" % (wfile, rev, ext) else: filename = "%s@%d" % (ext, rev) result = QFileDialog.getSaveFileName( parent=parent, caption=_("Save file to"), directory=hglib.tounicode(filename)) if not result: continue cwd = os.getcwd() try: os.chdir(repo.root) try: commands.cat(repo.ui, repo, curfile, rev=rev, output=hglib.fromunicode(result)) except (util.Abort, IOError), e: QMessageBox.critical(self, _('Unable to save file'), hglib.tounicode(str(e))) finally: os.chdir(cwd)
def checkPatchname(reporoot, activequeue, newpatchname, parent): if activequeue == 'patches': pn = 'patches' else: pn = 'patches-%s' % activequeue patchfile = os.sep.join([reporoot, ".hg", pn, newpatchname]) if os.path.exists(patchfile): dlg = CheckPatchnameDialog(newpatchname, parent) choice = dlg.exec_() if choice == 1: # add .OLD to existing patchfile try: os.rename(patchfile, patchfile + '.OLD') except (OSError, IOError), inst: qtlib.ErrorMsgBox(_('Rename Error'), _('Could not rename existing patchfile'), hglib.tounicode(str(inst))) return False return True elif choice == 2: # overwite existing patchfile try: os.remove(patchfile) except (OSError, IOError), inst: qtlib.ErrorMsgBox(_('Rename Error'), _('Could not delete existing patchfile'), hglib.tounicode(str(inst))) return False return True
def onNewModeToggled(self, isChecked): if isChecked: self.stwidget.tv.setEnabled(True) self.qnewOrRefreshBtn.setText(_('QNew')) self.qnewOrRefreshBtn.setEnabled(True) self.messageEditor.setEnabled(True) self.patchNameLE.setEnabled(True) self.patchNameLE.setFocus() self.patchNameLE.setText(mqutil.defaultNewPatchName(self.repo)) self.patchNameLE.selectAll() self.setMessage('') else: self.qnewOrRefreshBtn.setText(_('QRefresh')) pctx = self.repo.changectx('.') if 'qtip' in pctx.tags(): self.messageEditor.setEnabled(True) self.setMessage(hglib.tounicode(pctx.description())) name = self.repo.mq.applied[-1].name self.patchNameLE.setText(hglib.tounicode(name)) self.qnewOrRefreshBtn.setEnabled(True) self.stwidget.tv.setEnabled(True) else: self.messageEditor.setEnabled(False) self.qnewOrRefreshBtn.setEnabled(False) self.stwidget.tv.setEnabled(False) self.patchNameLE.setText('') self.setMessage('') self.patchNameLE.setEnabled(False) self.refreshStatus()
def __init__(self, repo, patchname, parent): super(QRenameDialog, self).__init__(parent) self.setWindowTitle(_('Patch rename - %s') % repo.displayname) f = self.windowFlags() self.setWindowFlags(f & ~Qt.WindowContextHelpButtonHint) self.setMinimumWidth(400) self.repo = repo self.oldpatchname = patchname self.newpatchname = '' self.setLayout(QVBoxLayout()) lbl = QLabel( _('Rename patch <b>%s</b> to:') % hglib.tounicode(self.oldpatchname)) self.layout().addWidget(lbl) self.le = QLineEdit(hglib.tounicode(self.oldpatchname)) self.layout().addWidget(self.le) self.cmd = cmdui.Runner(True, self) self.cmd.output.connect(self.output) self.cmd.makeLogVisible.connect(self.makeLogVisible) self.cmd.commandFinished.connect(self.onCommandFinished) BB = QDialogButtonBox bbox = QDialogButtonBox(BB.Ok | BB.Cancel) bbox.accepted.connect(self.accept) bbox.rejected.connect(self.reject) self.layout().addWidget(bbox) self.bbox = bbox self.focus = self.le
def _showexceptiondialog(self): from tortoisehg.hgqt.bugreport import BugReport, ExceptionMsgBox opts = {} opts['cmd'] = ' '.join(sys.argv[1:]) opts['error'] = ''.join(''.join(traceback.format_exception(*args)) for args in self.errors) etype, evalue = self.errors[0][:2] if (len(set(e[0] for e in self.errors)) == 1 and etype in self._recoverableexc): opts['values'] = evalue errstr = self._recoverableexc[etype] if etype is error.Abort and evalue.hint: errstr = u''.join( [errstr, u'<br><b>', _('hint:'), u'</b> %(arg1)s']) opts['values'] = [str(evalue), evalue.hint] dlg = ExceptionMsgBox(hglib.tounicode(str(evalue)), hglib.tounicode(errstr), opts, parent=self._mainapp.activeWindow()) elif etype is KeyboardInterrupt: if qtlib.QuestionMsgBox( hglib.tounicode(_('Keyboard interrupt')), hglib.tounicode(_('Close this application?'))): QApplication.quit() else: self.errors = [] return else: dlg = BugReport(opts, parent=self._mainapp.activeWindow()) dlg.exec_()
def _updatebranchfilter(self): """Update the list of branches""" curbranch = self.branch() if self._abranchAction.isChecked(): branches = sorted(set([self._repo[n].branch() for n in self._repo.heads() if not self._repo[n].extra().get('close')])) elif self._cbranchAction.isChecked(): branches = sorted(self._repo.branchtags().keys()) else: branches = self._repo.namedbranches self._branchReloading = True self._branchCombo.clear() self._branchCombo.addItem(self._allBranchesLabel) for branch in branches: self._branchCombo.addItem(hglib.tounicode(branch)) self._branchCombo.setItemData(self._branchCombo.count() - 1, hglib.tounicode(branch), Qt.ToolTipRole) self._branchLabel.setEnabled(self.filterEnabled and (len(branches) > 1 or self._abranchAction.isChecked())) self._branchCombo.setEnabled(self.filterEnabled and (len(branches) > 1 or self._abranchAction.isChecked())) self._branchReloading = False if not curbranch: curbranch = self._allBranchesLabel self.setBranch(curbranch)
def init_data(self, ui, pats): """calculate initial values for widgets""" fname = '' target = '' cwd = os.getcwd() try: self.root = paths.find_root() self.repo = thgrepo.repository(ui, path=self.root) except (error.RepoError): qtlib.ErrorMsgBox(_('Error'), _('Could not find or initialize the repository ' 'from folder<p>%s</p>' % cwd)) return ('', '') try: fname = scmutil.canonpath(self.root, cwd, pats[0]) target = scmutil.canonpath(self.root, cwd, pats[1]) except: pass os.chdir(self.root) fname = hglib.tounicode(util.normpath(fname)) if target: target = hglib.tounicode(util.normpath(target)) else: target = fname return (fname, target)
def runAction(self): "run wrapper for all action methods" repo, action, parent = self.repo, self.sender(), self.parent() func = action._runfunc files = [wfile for t, wfile in self.selrows if t & action._filetypes] hu = htmlui.htmlui() name = hglib.tounicode(func.__name__.title()) notify = False cwd = os.getcwd() try: os.chdir(repo.root) try: # All operations should quietly succeed. Any error should # result in a message box notify = func(parent, hu, repo, files) o, e = hu.getdata() if e: QMessageBox.warning(parent, name + _(" errors"), e) elif o: QMessageBox.information(parent, name + _(" output"), o) elif notify: wfiles = [repo.wjoin(x) for x in files] shlib.shell_notify(wfiles) except (IOError, OSError), e: err = hglib.tounicode(str(e)) QMessageBox.critical(parent, name + _(" Aborted"), err) except util.Abort, e: if e.hint: err = _("%s (hint: %s)") % (hglib.tounicode(str(e)), hglib.tounicode(e.hint)) else: err = hglib.tounicode(str(e)) QMessageBox.critical(parent, name + _(" Aborted"), err)
def getlog(self, ctx, gnode): if ctx.rev() is None: msg = None if self.unicodestar: # The Unicode symbol is a black star: msg = u'\u2605 ' + _('Working Directory') + u' \u2605' else: msg = '*** ' + _('Working Directory') + ' ***' for pctx in ctx.parents(): if self.repo._branchheads and pctx.node() not in self.repo._branchheads: text = _('Not a head revision!') msg += " " + qtlib.markup(text, fg='red', weight='bold') return msg msg = ctx.longsummary() if ctx.thgmqunappliedpatch(): effects = qtlib.geteffect('log.unapplied_patch') text = qtlib.applyeffects(' %s ' % ctx._patchname, effects) # qtlib.markup(msg, fg=UNAPPLIED_PATCH_COLOR) msg = qtlib.markup(msg) return hglib.tounicode(text + ' ') + msg if ctx.hidden(): return qtlib.markup(msg, fg=HIDDENREV_COLOR) parts = [] if ctx.thgbranchhead(): branchu = hglib.tounicode(ctx.branch()) effects = qtlib.geteffect('log.branch') parts.append(qtlib.applyeffects(u' %s ' % branchu, effects)) for mark in ctx.bookmarks(): style = 'log.bookmark' if mark == self.repo._bookmarkcurrent: bn = self.repo._bookmarks[self.repo._bookmarkcurrent] if bn in self.repo.dirstate.parents(): style = 'log.curbookmark' marku = hglib.tounicode(mark) effects = qtlib.geteffect(style) parts.append(qtlib.applyeffects(u' %s ' % marku, effects)) for tag in ctx.thgtags(): if self.repo.thgmqtag(tag): style = 'log.patch' else: style = 'log.tag' tagu = hglib.tounicode(tag) effects = qtlib.geteffect(style) parts.append(qtlib.applyeffects(u' %s ' % tagu, effects)) if msg: if ctx.thgwdparent(): msg = qtlib.markup(msg, weight='bold') else: msg = qtlib.markup(msg) parts.append(hglib.tounicode(msg)) return ' '.join(parts)
def onGuardConfigure(self): item = self.queueListWidget.currentItem() patch = item._thgpatch if item._thgguards: uguards = hglib.tounicode(' '.join(item._thgguards)) else: uguards = '' new, ok = qtlib.getTextInput(self, _('Configure guards'), _('Input new guards for %s:') % hglib.tounicode(patch), text=uguards) if not ok or new == uguards: return guards = [] for guard in hglib.fromunicode(new).split(' '): guard = guard.strip() if not guard: continue if not (guard[0] == '+' or guard[0] == '-'): self.showMessage.emit(_('Guards must begin with "+" or "-"')) continue guards.append(guard) cmdline = ['qguard', '-R', self.repo.root, '--', patch] if guards: cmdline += guards else: cmdline.insert(3, '--none') if self.cmd.running(): return self.repo.incrementBusyCount() self.qtbar.setEnabled(False) self.cmd.run(cmdline)
def __init__(self, title, message, parent, choices, default=None, esc=None, files=None): QMessageBox.__init__(self, parent) self.setWindowTitle(hglib.tounicode(title)) self.setText(hglib.tounicode(message)) if files: self.setDetailedText(hglib.tounicode('\n'.join(files))) self.hotkeys = {} for i, s in enumerate(choices): btn = self.addButton(s, QMessageBox.AcceptRole) try: char = s[s.index('&') + 1].lower() self.hotkeys[char] = btn except (ValueError, IndexError): pass if default == i: self.setDefaultButton(btn) if esc == i: self.setEscapeButton(btn)
def _updateBranchFilter(self): """Update the list of branches""" curbranch = self.branch() if self._abranchAction.isChecked(): branches = sorted(set([self._repo[n].branch() for n in self._repo.heads() if not self._repo[n].extra().get('close')])) elif self._cbranchAction.isChecked(): branches = sorted(self._repo.branchtags().keys()) else: branches = self._repo.namedbranches # easy access to common branches (Python sorted() is stable) priomap = {self._repo.dirstate.branch(): -2, 'default': -1} branches = sorted(branches, key=lambda e: priomap.get(e, 0)) self._branchCombo.blockSignals(True) self._branchCombo.clear() self._branchCombo.addItem(self._allBranchesLabel) for branch in branches: self._branchCombo.addItem(hglib.tounicode(branch)) self._branchCombo.setItemData(self._branchCombo.count() - 1, hglib.tounicode(branch), Qt.ToolTipRole) self._branchCombo.setEnabled(self.filterEnabled and bool(branches)) self._branchCombo.blockSignals(False) if curbranch and curbranch not in branches: self._emitBranchChanged() # falls back to "show all" else: self.setBranch(curbranch)
def validatePage(self): if not self._cmdsession.isFinished(): return False if len(self.repo[None].parents()) == 1: # commit succeeded, repositoryChanged() called wizard().next() if self.field('skiplast').toBool(): self.wizard().close() return True user = hglib.tounicode(qtlib.getCurrentUsername(self, self.repo, self.opts)) if not user: return False self.setTitle(_('Committing...')) self.setSubTitle(_('Please wait while committing merged files.')) opts = {'verbose': True, 'message': self.msgEntry.text(), 'user': user, 'subrepos': bool(self.opts.get('recurseinsubrepos')), 'date': hglib.tounicode(self.opts.get('date')), } commandlines = [hglib.buildcmdargs('commit', **opts)] pushafter = self.repo.ui.config('tortoisehg', 'cipushafter') if pushafter: cmd = ['push', hglib.tounicode(pushafter)] commandlines.append(cmd) self._cmdlog.show() sess = self._repoagent.runCommandSequence(commandlines, self) self._cmdsession = sess sess.commandFinished.connect(self.onCommandFinished) sess.outputReceived.connect(self._cmdlog.appendLog) return False
def checkPatchname(reporoot, activequeue, newpatchname, parent): if activequeue == 'patches': pn = 'patches' else: pn = 'patches-%s' % activequeue patchfile = os.sep.join([reporoot, ".hg", pn, newpatchname]) if os.path.exists(patchfile): dlg = CheckPatchnameDialog(newpatchname, parent) choice = dlg.exec_() if choice == 1: # add .OLD to existing patchfile try: os.rename(patchfile, patchfile + '.OLD') except (OSError, IOError), inst: qtlib.ErrorMsgBox(self.errTitle, _('Could not rename existing patchfile'), hglib.tounicode(str(inst))) return False return True elif choice == 2: # overwite existing patchfile try: os.remove(patchfile) except (OSError, IOError), inst: qtlib.ErrorMsgBox(self.errTitle, _('Could not delete existing patchfile'), hglib.tounicode(str(inst))) return False return True
def init_data(self, ui, pats): """calculate initial values for widgets""" fname = '' target = '' cwd = os.getcwd() try: self.root = paths.find_root() self.repo = thgrepo.repository(ui, path=self.root) except (error.RepoError): qtlib.ErrorMsgBox(_('Error'), _('Could not find or initialize the repository ' 'from folder<p>%s</p>' % cwd)) return ('', '') try: fname = hglib.canonpath(self.root, cwd, pats[0]) target = hglib.canonpath(self.root, cwd, pats[1]) except: pass os.chdir(self.root) fname = hglib.tounicode(util.normpath(fname)) if target: target = hglib.tounicode(util.normpath(target)) else: target = fname return (fname, target)
def _showexceptiondialog(self): from tortoisehg.hgqt.bugreport import BugReport, ExceptionMsgBox opts = {} opts['cmd'] = ' '.join(sys.argv[1:]) opts['error'] = ''.join(''.join(traceback.format_exception(*args)) for args in self.errors) etype, evalue = self.errors[0][:2] if len(self.errors) == 1 and etype in self._recoverableexc: opts['values'] = evalue errstr = self._recoverableexc[etype] if etype == error.Abort and evalue.hint: errstr = u''.join([errstr, u'<br><b>', _('hint:'), u'</b> %(arg1)s']) opts['values'] = [str(evalue), evalue.hint] dlg = ExceptionMsgBox(hglib.tounicode(str(evalue)), hglib.tounicode(errstr), opts, parent=self._mainapp.activeWindow()) elif etype is KeyboardInterrupt: if qtlib.QuestionMsgBox(_('Keyboard interrupt'), _('Close this application?')): QApplication.quit() else: self.errors = [] return else: dlg = BugReport(opts, parent=self._mainapp.activeWindow()) dlg.exec_()
def getlog(self, ctx, gnode): if ctx.rev() is None: msg = None if self.unicodestar: # The Unicode symbol is a black star: msg = u'\u2605 ' + _('Working Directory') + u' \u2605' else: msg = '*** ' + _('Working Directory') + ' ***' for pctx in ctx.parents(): if self.repo._branchheads and pctx.node( ) not in self.repo._branchheads: text = _('Not a head revision!') msg += " " + qtlib.markup(text, fg='red', weight='bold') return msg msg = ctx.longsummary() if ctx.thgmqunappliedpatch(): effects = qtlib.geteffect('log.unapplied_patch') text = qtlib.applyeffects(' %s ' % ctx._patchname, effects) # qtlib.markup(msg, fg=UNAPPLIED_PATCH_COLOR) msg = qtlib.markup(msg) return hglib.tounicode(text + ' ') + msg parts = [] if ctx.thgbranchhead(): branchu = hglib.tounicode(ctx.branch()) effects = qtlib.geteffect('log.branch') parts.append(qtlib.applyeffects(u' %s ' % branchu, effects)) for mark in ctx.bookmarks(): style = 'log.bookmark' if mark == self.repo._bookmarkcurrent: bn = self.repo._bookmarks[self.repo._bookmarkcurrent] if bn in self.repo.dirstate.parents(): style = 'log.curbookmark' marku = hglib.tounicode(mark) effects = qtlib.geteffect(style) parts.append(qtlib.applyeffects(u' %s ' % marku, effects)) for tag in ctx.thgtags(): if self.repo.thgmqtag(tag): style = 'log.patch' else: style = 'log.tag' tagu = hglib.tounicode(tag) effects = qtlib.geteffect(style) parts.append(qtlib.applyeffects(u' %s ' % tagu, effects)) if msg: if ctx.thgwdparent(): msg = qtlib.markup(msg, weight='bold') else: msg = qtlib.markup(msg) parts.append(hglib.tounicode(msg)) return ' '.join(parts)
def getlog(self, ctx, gnode): if ctx.rev() is None: msg = None if self.unicodestar: # The Unicode symbol is a black star: msg = u"\u2605 " + _("Working Directory") + u" \u2605" else: msg = "*** " + _("Working Directory") + " ***" for pctx in ctx.parents(): if self.repo._branchheads and pctx.node() not in self.repo._branchheads: text = _("Not a head revision!") msg += " " + qtlib.markup(text, fg="red", weight="bold") return msg msg = ctx.longsummary() if ctx.thgmqunappliedpatch(): effects = qtlib.geteffect("log.unapplied_patch") text = qtlib.applyeffects(" %s " % ctx._patchname, effects) # qtlib.markup(msg, fg=UNAPPLIED_PATCH_COLOR) msg = qtlib.markup(msg) return hglib.tounicode(text + " ") + msg parts = [] if ctx.thgbranchhead(): branchu = hglib.tounicode(ctx.branch()) effects = qtlib.geteffect("log.branch") parts.append(qtlib.applyeffects(u" %s " % branchu, effects)) for mark in ctx.bookmarks(): style = "log.bookmark" if mark == self.repo._bookmarkcurrent: bn = self.repo._bookmarks[self.repo._bookmarkcurrent] if bn in self.repo.dirstate.parents(): style = "log.curbookmark" marku = hglib.tounicode(mark) effects = qtlib.geteffect(style) parts.append(qtlib.applyeffects(u" %s " % marku, effects)) for tag in ctx.thgtags(): if self.repo.thgmqtag(tag): style = "log.patch" else: style = "log.tag" tagu = hglib.tounicode(tag) effects = qtlib.geteffect(style) parts.append(qtlib.applyeffects(u" %s " % tagu, effects)) if msg: if ctx.thgwdparent(): msg = qtlib.markup(msg, weight="bold") else: msg = qtlib.markup(msg) parts.append(hglib.tounicode(msg)) return " ".join(parts)
def startMonitoring(self): """Start filesystem monitoring to notify changes automatically""" if not self._fswatcher: self._fswatcher = QFileSystemWatcher(self) self._fswatcher.directoryChanged.connect(self._pollChanges) self._fswatcher.fileChanged.connect(self._pollChanges) self._fswatcher.addPath(hglib.tounicode(self.repo.path)) self._fswatcher.addPath(hglib.tounicode(self.repo.spath)) self.addMissingPaths() self._fswatcher.blockSignals(False)
def init(self): dest = self.getPath() if dest == '': qtlib.ErrorMsgBox(_('Error executing init'), _('Destination path is empty'), _('Please enter the directory path')) self.dest_edit.setFocus() return False dest = os.path.normpath(dest) self.dest_edit.setText(hglib.tounicode(dest)) udest = self.dest_edit.text() if not os.path.exists(dest): p = dest l = 0 while not os.path.exists(p): l += 1 p, t = os.path.split(p) if not t: break # already root path if l > 1: res = qtlib.QuestionMsgBox( _('Init'), _('Are you sure about adding the new repository ' '%d extra levels deep?') % l, _('Path exists up to:\n%s\nand you asked for:\n%s') % (p, udest), defaultbutton=QMessageBox.No) if not res: self.dest_edit.setFocus() return try: # create the folder, just like Hg would os.makedirs(dest) except: qtlib.ErrorMsgBox(_('Error executing init'), _('Cannot create folder %s') % udest) return False _ui = ui.ui() # dotencode is the new default repo format in Mercurial 1.7 if self.make_pre_1_7_chk.isChecked(): _ui.setconfig('format', 'dotencode', 'False') try: # create the new repo hg.repository(_ui, dest, create=1) except error.RepoError, inst: qtlib.ErrorMsgBox(_('Error executing init'), _('Unable to create new repository'), hglib.tounicode(str(inst))) return False
def revert(self): assert(self.curcl.endswith('(pending)')) cmdline = ['p4revert', '--verbose', '--config', 'extensions.perfarce=', '--repository', hglib.tounicode(self.url), hglib.tounicode(self.curcl[:-10])] self.bb.button(QDialogButtonBox.Ok).setEnabled(False) self.bb.button(QDialogButtonBox.Discard).setEnabled(False) self.showMessage.emit(_('Reverting p4 changelist...')) self._cmdsession = sess = self._repoagent.runCommand(cmdline, self) sess.commandFinished.connect(self.commandFinished)
def rename(ui, repoagent, source=None, dest=None, **opts): """rename dialog""" from tortoisehg.hgqt import rename as renamemod repo = repoagent.rawRepo() cwd = repo.getcwd() if source: source = hglib.tounicode(pathutil.canonpath(repo.root, cwd, source)) if dest: dest = hglib.tounicode(pathutil.canonpath(repo.root, cwd, dest)) iscopy = (opts.get('alias') == 'copy') return renamemod.RenameDialog(repoagent, None, source, dest, iscopy)
def deleteShelfB(self): shelf = self.currentPatchB() ushelf = hglib.tounicode(os.path.basename(shelf)) if not qtlib.QuestionMsgBox(_('Are you sure?'), _('Delete shelf file %s?') % ushelf): return try: os.unlink(shelf) self.showMessage(_('Shelf deleted')) except EnvironmentError, e: self.showMessage(hglib.tounicode(str(e)))
def init(self): dest = self.getPath() if dest == '': qtlib.ErrorMsgBox(_('Error executing init'), _('Destination path is empty'), _('Please enter the directory path')) self.dest_edit.setFocus() return False dest = os.path.normpath(dest) self.dest_edit.setText(hglib.tounicode(dest)) udest = self.dest_edit.text() if not os.path.exists(dest): p = dest l = 0 while not os.path.exists(p): l += 1 p, t = os.path.split(p) if not t: break # already root path if l > 1: res = qtlib.QuestionMsgBox(_('Init'), _('Are you sure about adding the new repository ' '%d extra levels deep?') % l, _('Path exists up to:\n%s\nand you asked for:\n%s') % (p, udest), defaultbutton=QMessageBox.No) if not res: self.dest_edit.setFocus() return try: # create the folder, just like Hg would os.makedirs(dest) except: qtlib.ErrorMsgBox(_('Error executing init'), _('Cannot create folder %s') % udest) return False _ui = ui.ui() # dotencode is the new default repo format in Mercurial 1.7 if self.make_pre_1_7_chk.isChecked(): _ui.setconfig('format', 'dotencode', 'False') try: # create the new repo hg.repository(_ui, dest, create=1) except error.RepoError, inst: qtlib.ErrorMsgBox(_('Error executing init'), _('Unable to create new repository'), hglib.tounicode(str(inst))) return False
def addMissingPaths(self): 'Add files to watcher that may have been added or replaced' existing = [f for f in self._getwatchedfiles() if os.path.isfile(f)] files = [unicode(f) for f in self._fswatcher.files()] for f in existing: if hglib.tounicode(f) not in files: dbgoutput('add file to watcher:', f) self._fswatcher.addPath(hglib.tounicode(f)) for f in self.repo.uifiles(): if f and os.path.exists(f) and hglib.tounicode(f) not in files: dbgoutput('add ui file to watcher:', f) self._fswatcher.addPath(hglib.tounicode(f))
def clearShelfB(self): shelf = self.currentPatchB() ushelf = hglib.tounicode(os.path.basename(shelf)) if not qtlib.QuestionMsgBox(_('Are you sure?'), _('Clear contents of shelf file %s?') % ushelf): return try: f = open(shelf, "w") f.close() self.showMessage(_('Shelf cleared')) except EnvironmentError, e: self.showMessage(hglib.tounicode(str(e)))
def addMissingPaths(self): 'Add files to watcher that may have been added or replaced' existing = [f for f in self._getwatchedfiles() if os.path.isfile(f)] files = [unicode(f) for f in self.watcher.files()] for f in existing: if hglib.tounicode(f) not in files: dbgoutput('add file to watcher:', f) self.watcher.addPath(hglib.tounicode(f)) for f in self.repo.uifiles()[1]: if f and os.path.exists(f) and hglib.tounicode(f) not in files: dbgoutput('add ui file to watcher:', f) self.watcher.addPath(hglib.tounicode(f))
def rebase(ui, repoagent, *pats, **opts): """rebase dialog""" from tortoisehg.hgqt import rebase as rebasemod repo = repoagent.rawRepo() if os.path.exists(repo.join('rebasestate')): # TODO: move info dialog into RebaseDialog if possible qtlib.InfoMsgBox(hglib.tounicode(_('Rebase already in progress')), hglib.tounicode(_('Resuming rebase already in ' 'progress'))) elif not opts['source'] or not opts['dest']: raise util.Abort(_('You must provide source and dest arguments')) return rebasemod.RebaseDialog(repoagent, None, **opts)
def _addMissingPaths(self): 'Add files to watcher that may have been added or replaced' existing = [f for f, (_flag, watched) in self._filesmap.iteritems() if watched and f in self._lastmtimes] files = [unicode(f) for f in self._fswatcher.files()] for f in existing: if hglib.tounicode(f) not in files: self._ui.debug('add file to watcher: %s\n' % f) self._fswatcher.addPath(hglib.tounicode(f)) for f in self._repo.uifiles(): if f and os.path.exists(f) and hglib.tounicode(f) not in files: self._ui.debug('add ui file to watcher: %s\n' % f) self._fswatcher.addPath(hglib.tounicode(f))
def goto(self, rev): """ Select revision 'rev' (can be anything understood by repo.changectx()) """ if isinstance(rev, (unicode, QString)): rev = hglib.fromunicode(rev) try: rev = self.repo.changectx(rev).rev() except error.RepoError: self.showMessage.emit(_("Can't find revision '%s'") % hglib.tounicode(str(rev))) except LookupError, e: self.showMessage.emit(hglib.tounicode(str(e)))
def rebase(ui, repoagent, *pats, **opts): """rebase dialog""" from tortoisehg.hgqt import rebase as rebasemod repo = repoagent.rawRepo() if os.path.exists(repo.join('rebasestate')): # TODO: move info dialog into RebaseDialog if possible qtlib.InfoMsgBox( hglib.tounicode(_('Rebase already in progress')), hglib.tounicode(_('Resuming rebase already in ' 'progress'))) elif not opts['source'] or not opts['dest']: raise util.Abort(_('You must provide source and dest arguments')) return rebasemod.RebaseDialog(repoagent, None, **opts)
def goto(self, rev): """ Select revision 'rev' (can be anything understood by repo.changectx()) """ if isinstance(rev, (unicode, QString)): rev = hglib.fromunicode(rev) try: rev = self.repo.changectx(rev).rev() except error.RepoError: self.showMessage.emit( _("Can't find revision '%s'") % hglib.tounicode(str(rev))) except LookupError, e: self.showMessage.emit(hglib.tounicode(str(e)))
def __init__(self, parent): QDialog.__init__(self, parent) self.setWindowTitle(_('MQ options')) layout = QFormLayout() self.setLayout(layout) self.gitcb = QCheckBox( _('Force use of git extended diff format (--git)')) layout.addRow(self.gitcb, None) self.forcecb = QCheckBox( _('Force push or pop (--force)')) layout.addRow(self.forcecb, None) self.exactcb = QCheckBox( _('Apply patch to its recorded parent (--exact)')) layout.addRow(self.exactcb, None) self.currentdatecb = QCheckBox( _('Update date field with current date (--currentdate)')) layout.addRow(self.currentdatecb, None) self.datele = QLineEdit() layout.addRow(QLabel(_('Specify an explicit date:')), self.datele) self.currentusercb = QCheckBox( _('Update author field with current user (--currentuser)')) layout.addRow(self.currentusercb, None) self.userle = QLineEdit() layout.addRow(QLabel(_('Specify an explicit author:')), self.userle) self.currentdatecb.toggled.connect(self.datele.setDisabled) self.currentusercb.toggled.connect(self.userle.setDisabled) self.gitcb.setChecked(parent.opts.get('git', False)) self.forcecb.setChecked(parent.opts.get('force', False)) self.exactcb.setChecked(parent.opts.get('exact', False)) self.currentdatecb.setChecked(parent.opts.get('currentdate', False)) self.currentusercb.setChecked(parent.opts.get('currentuser', False)) self.datele.setText(hglib.tounicode(parent.opts.get('date', ''))) self.userle.setText(hglib.tounicode(parent.opts.get('user', ''))) BB = QDialogButtonBox bb = QDialogButtonBox(BB.Ok|BB.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) self.bb = bb layout.addWidget(bb)
def appendSubrepos(self, repo=None): self._sharedpath = '' invalidRepoList = [] try: sri = None if repo is None: if not os.path.exists(self._root): self._valid = False return [hglib.fromunicode(self._root)] elif (not os.path.exists(os.path.join(self._root, '.hgsub')) and not os.path.exists( os.path.join(self._root, '.hg', 'sharedpath'))): return [] # skip repo creation, which is expensive repo = hg.repository(ui.ui(), hglib.fromunicode(self._root)) if repo.sharedpath != repo.path: self._sharedpath = hglib.tounicode(repo.sharedpath) wctx = repo['.'] sortkey = lambda x: os.path.basename(util.normpath(repo.wjoin(x))) for subpath in sorted(wctx.substate, key=sortkey): sri = None abssubpath = repo.wjoin(subpath) subtype = wctx.substate[subpath][2] sriIsValid = os.path.isdir(abssubpath) sri = _newSubrepoItem(hglib.tounicode(abssubpath), repotype=subtype) sri._valid = sriIsValid self.appendChild(sri) if not sriIsValid: self._valid = False sri._valid = False invalidRepoList.append(repo.wjoin(subpath)) return invalidRepoList if subtype == 'hg': # Only recurse into mercurial subrepos sctx = wctx.sub(subpath) invalidSubrepoList = sri.appendSubrepos(sctx._repo) if invalidSubrepoList: self._valid = False invalidRepoList += invalidSubrepoList except (EnvironmentError, error.RepoError, util.Abort), e: # Add the repo to the list of repos/subrepos # that could not be open self._valid = False if sri: sri._valid = False invalidRepoList.append(abssubpath) invalidRepoList.append(hglib.fromunicode(self._root))
def __init__(self, parent): QDialog.__init__(self, parent) self.setWindowTitle(_('MQ options')) layout = QFormLayout() self.setLayout(layout) self.gitcb = QCheckBox( _('Force use of git extended diff format (--git)')) layout.addRow(self.gitcb, None) self.forcecb = QCheckBox(_('Force push or pop (--force)')) layout.addRow(self.forcecb, None) self.exactcb = QCheckBox( _('Apply patch to its recorded parent (--exact)')) layout.addRow(self.exactcb, None) self.currentdatecb = QCheckBox( _('Update date field with current date (--currentdate)')) layout.addRow(self.currentdatecb, None) self.datele = QLineEdit() layout.addRow(QLabel(_('Specify an explicit date:')), self.datele) self.currentusercb = QCheckBox( _('Update author field with current user (--currentuser)')) layout.addRow(self.currentusercb, None) self.userle = QLineEdit() layout.addRow(QLabel(_('Specify an explicit author:')), self.userle) self.currentdatecb.toggled.connect(self.datele.setDisabled) self.currentusercb.toggled.connect(self.userle.setDisabled) self.gitcb.setChecked(parent.opts.get('git', False)) self.forcecb.setChecked(parent.opts.get('force', False)) self.exactcb.setChecked(parent.opts.get('exact', False)) self.currentdatecb.setChecked(parent.opts.get('currentdate', False)) self.currentusercb.setChecked(parent.opts.get('currentuser', False)) self.datele.setText(hglib.tounicode(parent.opts.get('date', ''))) self.userle.setText(hglib.tounicode(parent.opts.get('user', ''))) BB = QDialogButtonBox bb = QDialogButtonBox(BB.Ok | BB.Cancel) bb.accepted.connect(self.accept) bb.rejected.connect(self.reject) self.bb = bb layout.addWidget(bb)
def _reload(self): ui, repo = self.repo.ui.copy(), self.repo self.queueCombo.clear() ui.quiet = True # don't append "(active)" ui.pushbuffer() mqmod.qqueue(ui, repo, list=True) out = ui.popbuffer() for i, qname in enumerate(out.splitlines()): if qname == repo.thgactivemqname: current = i self.queueCombo.addItem(hglib.tounicode(qname)) self.queueCombo.setCurrentIndex(current) self.queueCombo.setEnabled(self.queueCombo.count() > 1) self.messages = [] for patch in repo.mq.series: ctx = repo.changectx(patch) msg = hglib.tounicode(ctx.description()) if msg: self.messages.append((patch, msg)) self.msgSelectCombo.reset(self.messages) if os.path.isdir(repo.mq.join('.hg')): self.revisionOrCommitBtn.setText(_('QCommit')) else: self.revisionOrCommitBtn.setText(_('Create MQ repo')) pctx = repo.changectx('.') newmode = self.newCheckBox.isChecked() if 'qtip' in pctx.tags(): self.stwidget.tv.setEnabled(True) self.messageEditor.setEnabled(True) self.msgSelectCombo.setEnabled(True) self.qnewOrRefreshBtn.setEnabled(True) if not newmode: self.setMessage(hglib.tounicode(pctx.description())) name = repo.mq.applied[-1].name self.patchNameLE.setText(hglib.tounicode(name)) else: self.stwidget.tv.setEnabled(newmode) self.messageEditor.setEnabled(newmode) self.msgSelectCombo.setEnabled(newmode) self.qnewOrRefreshBtn.setEnabled(newmode) if not newmode: self.setMessage('') self.patchNameLE.setText('') self.patchNameLE.setEnabled(newmode)
def refreshCombos(self): shelvea, shelveb = self.currentPatchA(), self.currentPatchB() # Note that thgshelves returns the shelve list ordered from newest to # oldest shelves = self.repo.thgshelves() disp = [_('Shelf: %s') % hglib.tounicode(s) for s in shelves] patches = self.repo.thgmqunappliedpatches disp += [_('Patch: %s') % hglib.tounicode(p) for p in patches] # store fully qualified paths self.shelves = [os.path.join(self.repo.shelfdir, s) for s in shelves] self.patches = [self.repo.mq.join(p) for p in patches] self._patchnames = dict(zip(self.patches, patches)) self.comboRefreshInProgress = True self.comboa.clear() self.combob.clear() self.comboa.addItems([self.wdir] + disp) self.combob.addItems(disp) # attempt to restore selection if shelvea == self.wdir: idxa = 0 elif shelvea in self.shelves: idxa = self.shelves.index(shelvea) + 1 elif shelvea in self.patches: idxa = len(self.shelves) + self.patches.index(shelvea) + 1 else: idxa = 0 self.comboa.setCurrentIndex(idxa) if shelveb in self.shelves: idxb = self.shelves.index(shelveb) elif shelveb in self.patches: idxb = len(self.shelves) + self.patches.index(shelveb) else: idxb = 0 self.combob.setCurrentIndex(idxb) self.comboRefreshInProgress = False self.comboAChanged(idxa) self.comboBChanged(idxb) if not patches and not shelves: self.delShelfButtonB.setEnabled(False) self.clearShelfButtonB.setEnabled(False) self.browseb.setContext(patchctx('', self.repo, None))
def data(self, index, role=Qt.DisplayRole): if not index.isValid(): return QVariant() if role == Qt.DisplayRole: data = self.rows[index.row()][index.column()] return QVariant(hglib.tounicode(data)) return QVariant()
def copyPath(parent, ui, repo, files): clip = QApplication.clipboard() absfiles = [ hglib.fromunicode(QDir.toNativeSeparators(repo.wjoin(fname))) for fname in files ] clip.setText(hglib.tounicode(os.linesep.join(absfiles)))
def runPatcher(self, fp, wfile, updatestate): ui = self.repo.ui.copy() class warncapt(ui.__class__): def warn(self, msg, *args, **opts): self.write(msg) ui.__class__ = warncapt ok = True repo = self.repo ui.pushbuffer() try: eolmode = ui.config('patch', 'eol', 'strict') if eolmode.lower() not in patch.eolmodes: eolmode = 'strict' else: eolmode = eolmode.lower() # 'updatestate' flag has no effect since hg 1.9 try: ret = patch.internalpatch(ui, repo, fp, 1, files=None, eolmode=eolmode, similarity=0) except ValueError: ret = -1 if ret < 0: ok = False self.showMessage.emit(_('Patch failed to apply')) except (patch.PatchError, EnvironmentError), err: ok = False self.showMessage.emit(hglib.tounicode(str(err)))
def refresh(self): self.repo.thginvalidate() self.repo.lfstatus = True wctx = self.repo[None] wctx.status(unknown=True) self.repo.lfstatus = False self.unrevlist.clear() dests = [] for u in wctx.unknown(): dests.append(u) for a in wctx.added(): if not wctx[a].renamed(): dests.append(a) for x in dests: item = QListWidgetItem(hglib.tounicode(x)) item.orig = x self.unrevlist.addItem(item) self.unrevlist.setItemSelected(item, x in self.pats) if dests: self.findbtn.setEnabled(True) else: self.findbtn.setEnabled(False) self.difftb.clear() self.pats = [] self.matchbtn.setEnabled(len(self.matchtv.model().rows))
def acceptMatch(self): 'User pressed "accept match" button' remdests = {} wctx = self.repo[None] m = self.matchtv.model() # If no rows are selected, ask the user if he'd like to accept all renames if self.matchtv.selectionModel().hasSelection(): itemList = [self.matchtv.model().getRow(index) \ for index in self.matchtv.selectionModel().selectedRows()] else: itemList = m.rows for item in itemList: src, dest, percent = item if dest in remdests: udest = hglib.tounicode(dest) QMessageBox.warning( self, _('Multiple sources chosen'), _('You have multiple renames selected for ' 'destination file:\n%s. Aborting!') % udest) return remdests[dest] = src for dest, src in remdests.iteritems(): if not os.path.exists(self.repo.wjoin(src)): wctx.forget([src]) # !->R wctx.copy(src, dest) self.matchtv.model().remove(dest) self.matchAccepted.emit() self.refresh()
def genSubrepoRevChangedDescription(subrelpath, sfrom, sto, repo): """Generate a subrepository revision change description""" out = [] def getLog(_ui, srepo, opts): if srepo is None: return _('changeset: %s') % opts['rev'][0][:12] _ui.pushbuffer() logOutput = '' try: commands.log(_ui, srepo, **opts) logOutput = _ui.popbuffer() if not logOutput: return _('Initial revision') + u'\n' except error.ParseError, e: # Some mercurial versions have a bug that results in # saving a subrepo node id in the .hgsubstate file # which ends with a "+" character. If that is the # case, add a warning to the output, but try to # get the revision information anyway for n, rev in enumerate(opts['rev']): if rev.endswith('+'): logOutput += _('[WARNING] Invalid subrepo ' 'revision ID:\n\t%s\n\n') % rev opts['rev'][n] = rev[:-1] commands.log(_ui, srepo, **opts) logOutput += _ui.popbuffer() return hglib.tounicode(logOutput)
def accept(self): # If the editor has been modified, we implicitly accept the changes acceptresolution = self.editor.isModified() if not acceptresolution: action = QMessageBox.warning(self, _("Warning"), _("You have marked all rejected patch chunks as resolved yet you " \ "have not modified the file on the edit panel.\n\n" \ "This probably means that no code from any of the rejected patch " \ "chunks made it into the file.\n\n"\ "Are you sure that you want to leave the file as is and " \ "consider all the rejected patch chunks as resolved?\n\n" \ "Doing so may delete them from a shelve, for example, which " \ "would mean that you would lose them forever!\n\n" "Click Yes to accept the file as is or No to continue resolving " \ "the rejected patch chunks."), QMessageBox.Yes, QMessageBox.No) if action == QMessageBox.Yes: acceptresolution = True if acceptresolution: f = QFile(hglib.tounicode(self.path)) saved = f.open(QIODevice.WriteOnly) and self.editor.write(f) if not saved: qtlib.ErrorMsgBox(_('Unable to save file'), f.errorString(), parent=self) return self.saveSettings() super(RejectsDialog, self).accept()
def _prepareQuery(self): query = unicode(self.revsetcombo.currentText()).strip() if _querytype(self._repo, query) == 'keyword': s = hglib.fromunicode(query) return hglib.tounicode(hgrevset.formatspec('keyword(%s)', s)) else: return query