Mercurial and Git clients can push and pull from this alias URL to interact with this repository. You can change to which repository an alias points by going to the Aliases link on the project page.
# commit.py - TortoiseHg's commit widget and standalone dialog## Copyright 2010 Steve Borho <steve@borho.org>## This software may be used and distributed according to the terms of the# GNU General Public License version 2, incorporated herein by reference.importosfrommercurialimporthg,ui,cmdutil,util,dispatch,errorfrommercurial.nodeimportshortasshort_hexfrom PyQt4.QtCore import *
from PyQt4.QtGui import *
+from PyQt4.Qsci import QsciScintilla, QsciAPIs, QsciLexerMakefilefrom tortoisehg.hgqt.i18n import _
from tortoisehg.util import hglib, shlib, paths, wconfig
-from tortoisehg.hgqt import qtlib, status, cmdui, branchop, revpanel
+from tortoisehg.hgqt import qtlib, status, cmdui, branchop, revpanel, lexersfrom tortoisehg.hgqt.sync import loadIniFile
# Technical Debt for CommitWidget
# qtlib decode failure dialog (ask for retry locale, suggest HGENCODING)# Need a unicode-to-UTF8 function# spell check / tab completion
# in-memory patching / committing chunk selected files
+class MessageEntry(QsciScintilla):+ escapePressed = pyqtSignal()+ refreshPressed = pyqtSignal()++ def __init__(self, parent=None):+ super(MessageEntry, self).__init__(parent)+ self.setEdgeColor(QColor('LightSalmon'))+ self.setEdgeMode(QsciScintilla.EdgeLine)+ self.setWrapMode(QsciScintilla.WrapNone)+ self.setReadOnly(False)+ self.setUtf8(True)+ self.setMarginWidth(1, 0)+ self.setFont(qtlib.getfont('fontcomment').font())+ self.setCaretWidth(10)+ self.setCaretLineBackgroundColor(QColor("#e6fff0"))+ self.setCaretLineVisible(True)+ self.setAutoIndent(True)+ self.setAutoCompletionThreshold(2)+ self.setAutoCompletionSource(QsciScintilla.AcsAPIs)+ self.setAutoCompletionFillupsEnabled(True)+ self.setLexer(QsciLexerMakefile(self))+ self.lexer().setFont(qtlib.getfont('fontcomment').font())+ self.setMatchedBraceBackgroundColor(Qt.yellow)+ self.setIndentationsUseTabs(False)+ self.setBraceMatching(QsciScintilla.SloppyBraceMatch)+ #self.setIndentationGuidesBackgroundColor(QColor("#e6e6de"))+ #self.setFolding(QsciScintilla.BoxedFoldStyle)+ self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)+ self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)++ def refresh(self, repo):+ self.setEdgeColumn(repo.summarylen)+ self.setIndentationWidth(repo.tabwidth)+ self.setTabWidth(repo.tabwidth)+ if repo.wsvisible == 'Visible':+ self.setWhitespaceVisibility(QsciScintilla.WsVisible)+ elif repo.wsvisible == 'VisibleAfterIndent':+ self.setWhitespaceVisibility(QsciScintilla.WsVisibleAfterIndent)+ else:+ self.setWhitespaceVisibility(QsciScintilla.WsInvisible)++ def keyPressEvent(self, event):+ if event.key() == Qt.Key_Escape:+ self.escapePressed.emit()+ return+ if event.matches(QKeySequence.Refresh):+ self.refreshPressed.emit()+ return+ super(MessageEntry, self).keyPressEvent(event)+class CommitWidget(QWidget):
'A widget that encompasses a StatusWidget and commit extras'
commitButtonName = pyqtSignal(QString)
linkActivated=pyqtSignal(QString)showMessage=pyqtSignal(unicode)commitComplete=pyqtSignal()escapePressed=pyqtSignal()refreshPressed=pyqtSignal()progress=pyqtSignal(QString,object,QString,QString,object)output=pyqtSignal(QString,QString)makeLogVisible=pyqtSignal(bool)def__init__(self,pats,opts,root=None,embedded=False,parent=None):QWidget.__init__(self,parent=parent)self.opts=opts# user, dateself.stwidget=status.StatusWidget(pats,opts,root,self)self.stwidget.showMessage.connect(self.showMessage)self.stwidget.progress.connect(self.progress) self.stwidget.linkActivated.connect(self.linkActivated)
self.stwidget.escapePressed.connect(self.escapePressed)
self.stwidget.refreshPressed.connect(self.refreshPressed)
+ self.stwidget.fileDisplayed.connect(self.fileDisplayed) self.msghistory = []
self.qref = False
self.repo=repo=self.stwidget.repoself.runner=cmdui.Runner(_('Commit'),notembedded,self)self.runner.output.connect(self.output)self.runner.progress.connect(self.progress)self.runner.makeLogVisible.connect(self.makeLogVisible)self.runner.commandFinished.connect(self.commandFinished)repo.configChanged.connect(self.configChanged)repo.repositoryChanged.connect(self.repositoryChanged)repo.workingBranchChanged.connect(self.workingBranchChanged)self.opts['pushafter']=repo.ui.config('tortoisehg','cipushafter','')self.opts['autoinc']=repo.ui.config('tortoisehg','autoinc','')layout=QVBoxLayout()layout.setContentsMargins(2,2,2,2)layout.addWidget(self.stwidget)self.setLayout(layout)vbox=QVBoxLayout()vbox.setMargin(0)vbox.setContentsMargins(*(0,)*4)hbox=QHBoxLayout()hbox.setMargin(0)hbox.setContentsMargins(*(0,)*4)branchbutton=QPushButton(_('Branch: '))branchbutton.pressed.connect(self.branchOp)self.branchbutton=branchbuttonself.branchop=Nonehbox.addWidget(branchbutton)self.detailsbutton=QPushButton(_('Details'))self.detailsbutton.pressed.connect(self.details)hbox.addWidget(self.detailsbutton)msgcombo=MessageHistoryCombo()msgcombo.activated.connect(self.msgSelected)hbox.addWidget(msgcombo,1)hbox.addSpacing(2)vbox.addLayout(hbox,0)self.buttonHBox=hbox self.pcsinfo = revpanel.ParentWidget(repo)
vbox.addWidget(self.pcsinfo, 0)
- msgte = QPlainTextEdit()
- msgte.setLineWrapMode(QPlainTextEdit.NoWrap)- msgfont = qtlib.getfont('fontcomment')
- msgte.setFont(msgfont.font())
-msgfont.changed.connect(lambda fnt: msgte.setFont(fnt))-msgte.textChanged.connect(self.msgChanged)
- msgte.setContextMenuPolicy(Qt.CustomContextMenu)
- msgte.customContextMenuRequested.connect(self.menuRequested)
+ msgte = MessageEntry(self)
+ msgte.escapePressed.connect(self.escapePressed)
+ msgte.refreshPressed.connect(self.refreshPressed)
+#msgte.textChanged.connect(self.msgChanged)
+#msgte.setContextMenuPolicy(Qt.CustomContextMenu)
+#msgte.customContextMenuRequested.connect(self.menuRequested)
vbox.addWidget(msgte, 1)
upperframe = QFrame()
SP=QSizePolicysp=SP(SP.Expanding,SP.Expanding)sp.setHorizontalStretch(1)upperframe.setSizePolicy(sp)upperframe.setLayout(vbox)self.split=QSplitter(Qt.Vertical)sp=SP(SP.Expanding,SP.Expanding)sp.setHorizontalStretch(1)sp.setVerticalStretch(0)self.split.setSizePolicy(sp)# Add our widgets to the top of our splitterself.split.addWidget(upperframe)# Add status widget document frame below our splitter# this reparents the docf from the status splitterself.split.addWidget(self.stwidget.docf) # add our splitter where the docf used to be
self.stwidget.split.addWidget(self.split)
- msgte.setFocus()- # Yuki's Mockup: http://bitbucket.org/kuy/thg-qt/wiki/Home self.msgte = msgte
self.msgcombo = msgcombo
+ @pyqtSlot(QString, QString)+ def fileDisplayed(self, wfilestr, contents):+ 'Status widget is displaying a new file'+ wfile = hglib.fromunicode(wfilestr)+ contents = hglib.fromunicode(contents)+ if not (wfile and contents):+ return+ self._apis = QsciAPIs(self.msgte.lexer())+ tokens = set()+ for wfile in self.stwidget.getChecked():+ tokens.add(wfile)+ tokens.add(os.path.basename(wfile))+ try:+ from pygments.lexers import guess_lexer_for_filename+ from pygments.token import Token+ lexer = guess_lexer_for_filename(wfile, contents)+ for tokentype, value in lexer.get_tokens(contents):+ if tokentype is Token.Name and len(value) > 4:+ tokens.add(value)+ except (pygments.util.ClassNotFound, ImportError):+ pass+ for n in sorted(list(tokens)):+ self._apis.add(n)+ self._apis.apiPreparationFinished.connect(self.apiPrepFinished)+ self._apis.prepare()++ def apiPrepFinished(self):+ 'QsciAPIs has finished parsing displayed file'+ self.msgte.lexer().setAPIs(self._apis)+ def details(self):
dlg = DetailsDialog(self.opts, self.userhist, self)
dlg.setWindowFlags(Qt.Sheet)
dlg.setWindowModality(Qt.WindowModal)ifdlg.exec_()==QDialog.Accepted:self.opts.update(dlg.outopts)defworkingBranchChanged(self):'Repository has detected a change in .hg/branch'self.refresh()defrepositoryChanged(self):'Repository has detected a changelog / dirstate change'self.refresh()defconfigChanged(self):'Repository is reporting its config files have changed'self.refresh()defreload(self):'User has requested a reload'self.repo.thginvalidate()self.refresh()self.stwidget.refreshWctx()# Trigger reload of working contextdefrefresh(self):# Update qrefresh modeifself.repo.changectx('.').thgmqappliedpatch():self.commitButtonName.emit(_('QRefresh'))ifnotself.qref:self.initQRefreshMode()else:self.commitButtonName.emit(_('Commit')) if self.qref:
self.endQRefreshMode()
+ self.msgte.refresh(self.repo)+ # Update message list
self.msgcombo.reset(self.msghistory)
# Update branch operation buttoncur=hglib.tounicode(self.repo[None].branch())ifself.branchopisNone:title=_('Branch: ')+curelifself.branchop==False:title=_('Close Branch: ')+curelse:title=_('New Branch: ')+self.branchopself.branchbutton.setText(title)# Update parent csinfo widgetself.pcsinfo.set_revision(None)self.pcsinfo.update()definitQRefreshMode(self):'Working parent is a patch. Is it refreshable?'qtip=self.repo['qtip']ifqtip!=self.repo['.']:self.showMessage.emit(_('Cannot refresh non-tip patch'))self.commitButtonName.emit(_('N/A')) return
self.opts['user'] = qtip.user()
self.opts['date'] = hglib.displaytime(qtip.date())
- self.msgte.setPlainText(hglib.tounicode(qtip.description()))
- self.msgte.document().setModified(False)- self.msgte.moveCursor(QTextCursor.End)+ self.setMessage(hglib.tounicode(qtip.description()))
self.qref = True
def endQRefreshMode(self):
- self.msgte.clear()
+ self.setMessage('')
self.opts['user'] = ''
self.opts['date'] = ''
self.qref = False
- def msgChanged(self):- text = self.msgte.toPlainText()- self.buttonHBox.setEnabled(not text.isEmpty())- sumlen, maxlen = self.getLengths()- if not sumlen and not maxlen:- self.msgte.setExtraSelections([])- return- pos, nextpos = 0, 0- sels = []- for i, line in enumerate(text.split('\n')):- length = len(line)- pos = nextpos- nextpos += length + 1 # include \n- if i == 0:- if length < sumlen or not sumlen:- continue- pos += sumlen- elif i == 1:- if length == 0 or not sumlen:- continue- else:- if length < maxlen or not maxlen:- continue- pos += maxlen- sel = QTextEdit.ExtraSelection()- sel._bgcolor = QColor('LightSalmon')- sel._fgcolor = QColor('Black')- sel.format.setBackground(sel._bgcolor)- sel.format.setForeground(sel._fgcolor)- sel.cursor = QTextCursor(self.msgte.document())- sel.cursor.setPosition(pos)- sel.cursor.movePosition(QTextCursor.EndOfLine, QTextCursor.KeepAnchor)- sels.append(sel)- self.msgte.setExtraSelections(sels)- def msgReflow(self):
'User pressed Control-E, reflow current paragraph'
if QApplication.focusWidget() != self.msgte:
return
+ # TODO: broken by Qsci+ return self.reflowBlock(self.msgte.textCursor().block())
def reflowBlock(self, block):
- sumlen, maxlen = self.getLengths()- if not maxlen:- return+ sumlen = self.repo.summarylen # In QtTextDocument land, a block is a sequence of text ending
# in (and including) a carriage return. Aka, a line of text.
while block.length() and block.previous().length() > 1:
block=block.previous()begin=block.position()whileblock.length()andblock.next().length()>1:block=block.next()end=block.position()+block.length()-1# select the contiguous lines of text under the cursorcursor=self.msgte.textCursor()cursor.setPosition(begin,QTextCursor.MoveAnchor)cursor.setPosition(end,QTextCursor.KeepAnchor)sentence=cursor.selection().toPlainText().simplified()parts=sentence.split(' ',QString.SkipEmptyParts)lines=QStringList() line = QStringList()
partslen = 0
for part in parts:
- if partslen + len(line) + len(part) + 1 > maxlen:
+ if partslen + len(line) + len(part) + 1 > sumlen:
if line:
lines.append(line.join(' '))
line, partslen = QStringList(), 0
line.append(part)partslen+=len(part)ifline:lines.append(line.join(' '))reflow=lines.join('\n')# Replace selection with new sentencecursor.insertText(reflow) return cursor.block()
def menuRequested(self, point):
+ # TODO: broken by Qsci+ return cursor = self.msgte.cursorForPosition(point)
point = self.msgte.mapToGlobal(point)
def apply():
-sumlen,maxlen=self.getLengths()- if not maxlen:- return
+#TODO:brokenby Qsci+ return
+ sumlen = self.repo.summarylen block = self.msgte.document().firstBlock()
while block != self.msgte.document().end():
- if block.length() > maxlen:
+ if block.length() > sumlen:
block = self.reflowBlock(block)
block = block.next()
def paste():
+ # TODO: broken by Qsci+ return files = self.stwidget.getChecked()
cursor.insertText(', '.join(files))
def settings():
from tortoisehg.hgqt.settings import SettingsDialog
dlg = SettingsDialog(True, focus='tortoisehg.summarylen')
-self.repo.incrementBusyCount()- ret = dlg.exec_()
- self.repo.decrementBusyCount()- if ret == QDialog.Accepted:- self.msgChanged()+ dlg.exec_()
menu = self.msgte.createStandardContextMenu()
for name, func in [(_('Paste &Filenames'), paste),
(_('App&ly Format'),apply),(_('C&onfigure Format'),settings)]:defadd(name,func):action=menu.addAction(name)action.triggered.connect(lambda:func()) add(name, func)
return menu.exec_(point)
- def getLengths(self):- try:- sumlen = int(self.repo.ui.config('tortoisehg', 'summarylen', 0))- maxlen = int(self.repo.ui.config('tortoisehg', 'messagewrap', 0))- except (TypeError, ValueError):- sumlen, maxlen = 0, 0- return sumlen, maxlen- def restoreState(self, data):
return self.stwidget.restoreState(data)
defsaveState(self):returnself.stwidget.saveState()defbranchOp(self):d=branchop.BranchOpDialog(self.repo,self.branchop,self)d.setWindowFlags(Qt.Sheet)d.setWindowModality(Qt.WindowModal)ifd.exec_()==QDialog.Accepted:self.branchop=d.branchopself.refresh()defcanUndo(self):'Returns undo description or None if not valid'ifos.path.exists(self.repo.sjoin('undo')):try:args=self.repo.opener('undo.desc','r').read().splitlines()ifargs[1]!='commit':returnNonereturn_('Rollback commit to revision %d')%(int(args[0])-1)except(IOError,IndexError,ValueError):passreturnNonedefrollback(self):msg=self.canUndo()ifnotmsg:returnd=QMessageBox.question(self,_('Confirm Undo'),msg,QMessageBox.Ok|QMessageBox.Cancel)ifd!=QMessageBox.Ok:returnself.repo.incrementBusyCount()self.repo.rollback()self.repo.decrementBusyCount()self.reload() QTimer.singleShot(500, lambda: shlib.shell_notify([self.repo.root]))
def getMessage(self):
- text = self.msgte.toPlainText()
+ text = self.msgte.text()
try:
text = hglib.fromunicode(text, 'strict')
except UnicodeEncodeError:
pass# TODO return text
def msgSelected(self, index):
+ # TODO: broken by QSci+ return doc = self.msgte.document()
if not doc.isEmpty() and doc.isModified():
d = QMessageBox.question(self, _('Confirm Discard Message'),
_('Discard current commit message?'), QMessageBox.Ok | QMessageBox.Cancel)
if d != QMessageBox.Ok:
return
- self.msgte.setPlainText(self.msghistory[index])
- self.msgte.document().setModified(False)- self.msgte.moveCursor(QTextCursor.End)+ self.setMessage(self.msghistory[index])
self.msgte.setFocus()
+ def setMessage(self, msg):+ self.msgte.setText(msg)+ lines = self.msgte.lines()+ if lines:+ lines -= 1+ pos = self.msgte.lineLength(lines)+ self.msgte.setCursorPosition(lines, pos)+ self.msgte.ensureLineVisible(lines)+ self.msgte.setModified(False)+ def canExit(self):
# Usually safe to exit, since we're saving messages implicitly
# We'll ask the user for confirmation later, if they have any
# files partially selected.returnTruedefloadConfigs(self,s):'Load history, etc, from QSettings instance'repoid=str(self.repo[0])# message history is stored in unicodeself.split.restoreState(s.value('commit/split').toByteArray())self.msghistory=list(s.value('commit/history-'+repoid).toStringList())self.msghistory=[mforminself.msghistoryifm]self.msgcombo.reset(self.msghistory)self.userhist=s.value('commit/userhist').toStringList() self.userhist = [u for u in self.userhist if u]
try:
curmsg = self.repo.opener('cur-message.txt').read()
- self.msgte.setPlainText(hglib.tounicode(curmsg))
- self.msgte.document().setModified(False)- self.msgte.moveCursor(QTextCursor.End)+ self.setMessage(hglib.tounicode(curmsg))
except EnvironmentError:
pass
defstoreConfigs(self,s):'Save history, etc, in QSettings instance'repoid=str(self.repo[0])s.setValue('commit/history-'+repoid,self.msghistory)s.setValue('commit/split',self.split.saveState())s.setValue('commit/userhist',self.userhist)try:ifself.qref:# don't store patch summary as current working commentmsg=''else:# current message is stored in local encodingmsg=self.getMessage()self.repo.opener('cur-message.txt','w').write(msg)exceptEnvironmentError: pass
def addMessageToHistory(self):
- umsg = self.msgte.toPlainText()
+ umsg = self.msgte.text()
if not umsg:
return
if umsg in self.msghistory:
self.msghistory.remove(umsg)self.msghistory.insert(0,umsg)self.msghistory=self.msghistory[:10]defaddUsernameToHistory(self,user):ifuserinself.userhist:self.userhist.remove(user)self.userhist.insert(0,user)self.userhist=self.userhist[:10]defgetCurrentUsername(self):# 1. Override has highest priorityuser=self.opts.get('user')ifuser:returnuser# 2. Read from repositorytry:returnself.repo.ui.username()excepterror.Abort:pass# 3. Get a username from the userQMessageBox.information(self,_('Please enter a username'),_('You must identify yourself to Mercurial'),QMessageBox.Ok)fromtortoisehg.hgqt.settingsimportSettingsDialogdlg=SettingsDialog(False,focus='ui.username')dlg.exec_()self.repo.ui.invalidateui()try:returnself.repo.ui.username()excepterror.Abort:returnNonedefcommit(self):repo=self.repomsg=self.getMessage()ifnotmsg:qtlib.WarningMsgBox(_('Nothing Commited'),_('Please enter commit message'),parent=self)self.msgte.setFocus()returnifself.branchopisNone:brcmd=[]elifself.branchop==False:brcmd=['--close-branch']else:brcmd=[]# TODO: Need a unicode-to-UTF8 functionnewbranch=hglib.fromunicode(self.branchop)ifnewbranchinrepo.branchtags():# response: 0=Yes, 1=No, 2=Cancelifnewbranchin[p.branch()forpinrepo.parents()]:resp=0else:rev=repo[newbranch].rev()resp=qtlib.CustomPrompt(_('Confirm Branch Change'),_('Named branch "%s" already exists, ''last used in revision %d\n''Yes\t- Make commit restarting this named branch\n''No\t- Make commit without changing branch\n''Cancel\t- Cancel this commit')%(newbranch,rev),self,(_('&Yes'),_('&No'),_('Cancel')),2,2).run()else:resp=qtlib.CustomPrompt(_('Confirm New Branch'),_('Create new named branch "%s" with this commit?\n''Yes\t- Start new branch with this commit\n''No\t- Make commit without branch change\n''Cancel\t- Cancel this commit')%newbranch,self,(_('&Yes'),_('&No'),_('Cancel')),2,2).run()ifresp==0:repo.dirstate.setbranch(newbranch)elifresp==2:returnfiles=self.stwidget.getChecked('MAR?!S')ifnot(filesorbrcmdorrepo[None].branch()!=repo['.'].branch() \
orself.qref):qtlib.WarningMsgBox(_('No files checked'),_('No modified files checkmarked for commit'),parent=self)self.stwidget.tv.setFocus()returniflen(repo.parents())>1:files=[]user=self.getCurrentUsername()ifnotuser:returnself.addUsernameToHistory(user)commandlines=[]checkedUnknowns=self.stwidget.getChecked('?I')ifcheckedUnknowns:res=qtlib.CustomPrompt(_('Confirm Add'),_('Add checked untracked files?'),self,(_('&OK'),_('Cancel')),0,1,checkedUnknowns).run()ifres==0:cmd=['add','--repository',repo.root]+ \
[repo.wjoin(f)forfincheckedUnknowns]commandlines.append(cmd)else:returncheckedMissing=self.stwidget.getChecked('!')ifcheckedMissing:res=qtlib.CustomPrompt(_('Confirm Remove'),_('Remove checked deleted files?'),self,(_('&OK'),_('Cancel')),0,1,checkedMissing).run()ifres==0:cmd=['remove','--repository',repo.root]+ \
[repo.wjoin(f)forfincheckedMissing]commandlines.append(cmd)else:returntry:date=self.opts.get('date')ifdate:util.parsedate(date)dcmd=['--date',date]else:dcmd=[]excepterror.Abort,e:self.showMessage.emit(hglib.tounicode(str(e)))dcmd=[]cmdline=['commit','--repository',repo.root,'--verbose','--user',user,'--message',msg]ifself.qref:cmdline[0]='qrefresh'files=[]cmdline+=dcmd+brcmd+[repo.wjoin(f)forfinfiles]forfnameinself.opts.get('autoinc','').split(','):fname=fname.strip()iffname:cmdline.extend(['--include',fname])commandlines.append(cmdline)ifself.opts.get('pushafter'):cmd=['push','--repository',repo.root,self.opts['pushafter']]commandlines.append(cmd)repo.incrementBusyCount()self.runner.run(*commandlines)defcommandFinished(self,ret):self.repo.decrementBusyCount()ifret==0: self.addMessageToHistory()
if not self.qref:
self.msgte.clear()
- self.msgte.document().setModified(False)
+ self.msgte.setModified(False)
self.commitComplete.emit()
self.stwidget.refreshWctx()
defkeyPressEvent(self,event):ifevent.key()in(Qt.Key_Return,Qt.Key_Enter):ifevent.modifiers()==Qt.ControlModifier:self.commit()returnifevent.modifiers()==Qt.ControlModifierandevent.key()==Qt.Key_E:self.msgReflow()returnsuper(CommitWidget,self).keyPressEvent(event)classMessageHistoryCombo(QComboBox):def__init__(self,parent=None):QComboBox.__init__(self,parent)self.reset([])defreset(self,msgs):self.clear()self.addItem(_('Recent commit messages...'))self.loaded=Falseself.msgs=msgsdefshowPopup(self):ifnotself.loaded:self.clear()forsinself.msgs:self.addItem(s.split('\n',1)[0][:70])self.loaded=TrueQComboBox.showPopup(self)classDetailsDialog(QDialog):'Utility dialog for configuring uncommon settings'def__init__(self,opts,userhistory,parent):QDialog.__init__(self,parent)self.repo=parent.repolayout=QVBoxLayout()self.setLayout(layout)hbox=QHBoxLayout()self.usercb=QCheckBox(_('Set username:'))usercombo=QComboBox()usercombo.setEditable(True)usercombo.setEnabled(False)self.usercb.toggled.connect(usercombo.setEnabled)l=[]ifopts.get('user'):val=hglib.tounicode(opts['user'])self.usercb.setChecked(True)l.append(val)try:val=hglib.tounicode(self.repo.ui.username())l.append(val)exceptutil.Abort:passfornameinuserhistory:ifnamenotinl:l.append(name)fornameinl:usercombo.addItem(name)self.usercombo=usercombousersaverepo=QPushButton(_('Save in Repo'))usersaverepo.clicked.connect(self.saveInRepo)usersaverepo.setEnabled(False)self.usercb.toggled.connect(usersaverepo.setEnabled)usersaveglobal=QPushButton(_('Save Global'))usersaveglobal.clicked.connect(self.saveGlobal)usersaveglobal.setEnabled(False)self.usercb.toggled.connect(usersaveglobal.setEnabled)hbox.addWidget(self.usercb)hbox.addWidget(self.usercombo)hbox.addWidget(usersaverepo)hbox.addWidget(usersaveglobal)layout.addLayout(hbox)hbox=QHBoxLayout()self.datecb=QCheckBox(_('Set Date:'))self.datele=QLineEdit()self.datele.setEnabled(False)self.datecb.toggled.connect(self.datele.setEnabled)curdate=QPushButton(_('Update'))curdate.setEnabled(False)self.datecb.toggled.connect(curdate.setEnabled)curdate.clicked.connect(lambda:self.datele.setText(hglib.tounicode(hglib.displaytime(util.makedate()))))ifopts.get('date'):self.datele.setText(opts['date'])self.datecb.setChecked(True)else:self.datecb.setChecked(False)curdate.clicked.emit(True)hbox.addWidget(self.datecb)hbox.addWidget(self.datele)hbox.addWidget(curdate)layout.addLayout(hbox)hbox=QHBoxLayout()self.pushaftercb=QCheckBox(_('Push After Commit:'))self.pushafterle=QLineEdit()self.pushafterle.setEnabled(False)self.pushaftercb.toggled.connect(self.pushafterle.setEnabled)pushaftersave=QPushButton(_('Save in Repo'))pushaftersave.clicked.connect(self.savePushAfter)pushaftersave.setEnabled(False)self.pushaftercb.toggled.connect(pushaftersave.setEnabled)ifopts.get('pushafter'):val=hglib.tounicode(opts['pushafter'])self.pushafterle.setText(val)self.pushaftercb.setChecked(True)hbox.addWidget(self.pushaftercb)hbox.addWidget(self.pushafterle)hbox.addWidget(pushaftersave)layout.addLayout(hbox)hbox=QHBoxLayout()self.autoinccb=QCheckBox(_('Auto Includes:'))self.autoincle=QLineEdit()self.autoincle.setEnabled(False)self.autoinccb.toggled.connect(self.autoincle.setEnabled)autoincsave=QPushButton(_('Save in Repo'))autoincsave.clicked.connect(self.saveAutoInc)autoincsave.setEnabled(False)self.autoinccb.toggled.connect(autoincsave.setEnabled)ifopts.get('autoinc'):val=hglib.tounicode(opts['autoinc'])self.autoincle.setText(val)self.autoinccb.setChecked(True)hbox.addWidget(self.autoinccb)hbox.addWidget(self.autoincle)hbox.addWidget(autoincsave)layout.addLayout(hbox)hbox=QHBoxLayout()# qnew/shelve-patch creation dialog (in another file)lbl=QLabel(_('New patch (QNew)'))self.patchle=QLineEdit()self.patchle.returnPressed.connect(self.newPatch)createpatch=QPushButton(_('Create'))createpatch.clicked.connect(self.newPatch)defchanged(text):createpatch.setEnabled(bool(text))self.patchle.textChanged.connect(changed)createpatch.setEnabled(False)hbox.addWidget(lbl)hbox.addWidget(self.patchle)hbox.addWidget(createpatch)layout.addStretch(10)layout.addLayout(hbox)BB=QDialogButtonBoxbb=QDialogButtonBox(BB.Ok|BB.Cancel)bb.accepted.connect(self.accept)bb.rejected.connect(self.reject)self.bb=bblayout.addWidget(bb)self.setWindowTitle('%s - commit details'%self.repo.displayname)defnewPatch(self):name=hglib.fromunicode(self.patchle.text())# TODOdefsaveInRepo(self):fn=os.path.join(self.repo.root,'.hg','hgrc')self.saveToPath([fn])defsaveGlobal(self):self.saveToPath(util.user_rcpath())defsaveToPath(self,path):fn,cfg=loadIniFile(path,self)ifnothasattr(cfg,'write'):qtlib.WarningMsgBox(_('Unable to save username'),_('Iniparse must be installed.'),parent=self)returniffnisNone:returntry:user=hglib.fromunicode(self.usercombo.currentText())ifuser:cfg.set('ui','username',user)else:try:delcfg['ui']['username']exceptKeyError:passwconfig.writefile(cfg,fn)exceptIOError,e:qtlib.WarningMsgBox(_('Unable to write configuration file'),hglib.tounicode(e),parent=self)defsavePushAfter(self):path=os.path.join(self.repo.root,'.hg','hgrc')fn,cfg=loadIniFile([path],self)ifnothasattr(cfg,'write'):qtlib.WarningMsgBox(_('Unable to save after commit push'),_('Iniparse must be installed.'),parent=self)returniffnisNone:returntry:remote=hglib.fromunicode(self.pushafterle.text())ifremote:cfg.set('tortoisehg','cipushafter',remote)else:try:delcfg['tortoisehg']['cipushafter']exceptKeyError:passwconfig.writefile(cfg,fn)exceptIOError,e:qtlib.WarningMsgBox(_('Unable to write configuration file'),hglib.tounicode(e),parent=self)defsaveAutoInc(self):path=os.path.join(self.repo.root,'.hg','hgrc')fn,cfg=loadIniFile([path],self)ifnothasattr(cfg,'write'):qtlib.WarningMsgBox(_('Unable to save auto include list'),_('Iniparse must be installed.'),parent=self)returniffnisNone:returntry:list=hglib.fromunicode(self.autoincle.text())iflist:cfg.set('tortoisehg','autoinc',list)else:try:delcfg['tortoisehg']['autoinc']exceptKeyError:passwconfig.writefile(cfg,fn)exceptIOError,e:qtlib.WarningMsgBox(_('Unable to write configuration file'),hglib.tounicode(e),parent=self)defaccept(self):outopts={}ifself.datecb.isChecked():date=hglib.fromunicode(self.datele.text())try:util.parsedate(date)excepterror.Abort,e:qtlib.WarningMsgBox(_('Invalid date format'),hglib.tounicode(e),parent=self)returnoutopts['date']=dateelse:outopts['date']=''ifself.usercb.isChecked():user=hglib.fromunicode(self.usercombo.currentText())else:user=''outopts['user']=userifnotuser:try:self.repo.ui.username()exceptutil.Abort,e:qtlib.WarningMsgBox(_('No username configured'),hglib.tounicode(e),parent=self)returnifself.pushaftercb.isChecked():remote=hglib.fromunicode(self.pushafterle.text())outopts['pushafter']=remoteelse:outopts['pushafter']=''self.outopts=outoptsQDialog.accept(self)classCommitDialog(QDialog):'Standalone commit tool, a wrapper for CommitWidget'def__init__(self,pats,opts,parent=None):QDialog.__init__(self,parent)self.pats=patsself.opts=optslayout=QVBoxLayout()layout.setContentsMargins(2,2,2,2)layout.setMargin(0)self.setLayout(layout)commit=CommitWidget(pats,opts,opts.get('root'),False,self)layout.addWidget(commit,1)self.statusbar=cmdui.ThgStatusBar(self)self.statusbar.setSizeGripEnabled(False)commit.showMessage.connect(self.statusbar.showMessage)commit.progress.connect(self.statusbar.progress)commit.linkActivated.connect(self.linkActivated)commit.escapePressed.connect(self.reject)commit.refreshPressed.connect(self.refresh)BB=QDialogButtonBoxbb=QDialogButtonBox(BB.Ok|BB.Cancel|BB.Discard)bb.accepted.connect(self.accept)bb.rejected.connect(self.reject)bb.button(BB.Discard).setText('Undo')bb.button(BB.Discard).clicked.connect(commit.rollback)bb.button(BB.Cancel).setDefault(False)bb.button(BB.Discard).setDefault(False)bb.button(BB.Ok).setDefault(True)self.bb=bbhbox=QHBoxLayout()hbox.setMargin(0)hbox.setContentsMargins(*(0,)*4)hbox.addWidget(self.statusbar)hbox.addWidget(self.bb)layout.addLayout(hbox)s=QSettings()commit.restoreState(s.value('commit/state').toByteArray())self.restoreGeometry(s.value('commit/geom').toByteArray())commit.loadConfigs(s)commit.repo.repositoryChanged.connect(self.updateUndo)commit.commitComplete.connect(self.postcommit)commit.commitButtonName.connect(self.setButtonName)self.setWindowTitle('%s - commit'%commit.repo.displayname) self.commit = commit
self.commit.reload()
self.updateUndo()
+ self.commit.msgte.setFocus() def linkActivated(self, link):
link = hglib.fromunicode(link)
iflink.startswith('subrepo:'):fromtortoisehg.hgqt.runimportqtrunqtrun(run,ui.ui(),root=link[8:])defsetButtonName(self,name):self.bb.button(QDialogButtonBox.Ok).setText(name)defupdateUndo(self):BB=QDialogButtonBoxundomsg=self.commit.canUndo()ifundomsg:self.bb.button(BB.Discard).setEnabled(True)self.bb.button(BB.Discard).setToolTip(undomsg)else:self.bb.button(BB.Discard).setEnabled(False)self.bb.button(BB.Discard).setToolTip('')defkeyPressEvent(self,event):ifevent.key()==Qt.Key_Escape:self.reject()returnelifevent.matches(QKeySequence.Refresh):self.refresh()returnsuper(CommitDialog,self).keyPressEvent(event)defrefresh(self):self.updateUndo()self.commit.reload()defpostcommit(self):repo=self.commit.stwidget.repoifrepo.ui.configbool('tortoisehg','closeci'):self.reject()returndefaccept(self):self.commit.commit()defreject(self):ifself.commit.canExit():s=QSettings()s.setValue('commit/state',self.commit.saveState())s.setValue('commit/geom',self.saveGeometry())self.commit.storeConfigs(s)QDialog.reject(self)defrun(ui,*pats,**opts):returnCommitDialog(hglib.canonpaths(pats),opts)
Attach a Trello Card
Add a tag
Your session has expired
You are no longer logged in. Please log in and try your request again.
Filter RSS Feed
This RSS feed URL allows you to see the contents of your current filter using any feed reader.
This link includes a special authentication token. If you share the URL with anyone else, they can see this RSS feed's activity. You can disable these tokens when needed.
Your current filter is unsaved; changing it won't affect this RSS feed.