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.
# -*- coding: iso-8859-1 -*-#!/usr/bin/env python# workbench.py - main TortoiseHg Window## Copyright (C) 2007-2010 Logilab. All rights reserved.## This software may be used and distributed according to the terms# of the GNU General Public License, incorporated herein by reference."""Main Qt4 application for TortoiseHg"""importsys,osimportrefromPyQt4importQtCore,QtGui,QscifromPyQt4.QtCoreimport*fromPyQt4.QtGuiimport*frommercurialimportui,hg,utilfrommercurial.errorimportRepoErrorfromtortoisehg.util.utilimporttounicodefromtortoisehg.util.utilimportrootpath,find_repositoryfromtortoisehg.hgqt.i18nimport_fromtortoisehg.hgqt.decoratorsimporttimeitfromtortoisehg.hgqt.configimportHgConfigfromtortoisehg.hgqt.qtlibimportgeticonfromtortoisehg.hgqt.quickbarimportFindInGraphlogQuickBarfromtortoisehg.hgqt.repowidgetimportRepoWidgetfromtortoisehg.hgqt.commitimportCommitWidgetfromtortoisehg.hgqt.reporegistryimportRepoRegistryViewfromtortoisehg.utilimportpathsfrommercurial.errorimportRepoErrorconnect=QObject.connectclassWorkbench(QMainWindow):"""hg repository viewer/browser application"""def__init__(self,ui,repo=None):self.ui=uiself._reload_rev=Noneself._reload_file=Noneself._loading=Trueself._scanForRepoChanges=Trueself._searchWidgets=[]self.commitwidgets={}# key: reporootQMainWindow.__init__(self)self.load_config(ui)self.setupUi()self._quickbars=[]self.disab_shortcuts=[]self.repotabs_splitter.setCollapsible(0,False)self.dummywidget=QWidget()self.stackedWidget.addWidget(self.dummywidget)self.stackedWidget.setCurrentWidget(self.dummywidget)self.setWindowTitle('TortoiseHg Workbench')self.reporegistry=rr=RepoRegistryView(ui,self)rr.setObjectName('RepoRegistryView')self.addDockWidget(Qt.LeftDockWidgetArea,rr)rr.openRepoSignal.connect(self.openRepo)ifrepo:self.addRepoTab(repo)tw=self.repoTabsWidgetconnect(tw,SIGNAL('tabCloseRequested(int)'),self.repoTabCloseRequested)connect(tw,SIGNAL('currentChanged(int)'),self.repoTabChanged)self.createActions()self.createToolbars()self.repoTabChanged()self.setupBranchCombo()self.restoreSettings()self.setAcceptDrops(True)defgotVisible(state):self.actionShowRepoRegistry.setChecked(self.reporegistry.isVisible())self.reporegistry.visibilityChanged.connect(gotVisible)defattachQuickBar(self,qbar):qbar.setParent(self)self._quickbars.append(qbar)connect(qbar,SIGNAL('escShortcutDisabled(bool)'),self.setShortcutsEnabled)self.addToolBar(Qt.BottomToolBarArea,qbar)connect(qbar,SIGNAL('visible'),self.ensureOneQuickBar)defsetShortcutsEnabled(self,enabled=True):forshinself.disab_shortcuts:sh.setEnabled(enabled)defensureOneQuickBar(self):tb=self.sender()forwinself._quickbars:ifwisnottb:w.hide()defload_config(self,ui):cfg=HgConfig(ui)fontstr=cfg.getFont()font=QFont()try:ifnotfont.fromString(fontstr):raiseExceptionexcept:print"bad font name '%s'"%fontstrfont.setFamily("Monospace")font.setFixedPitch(True)font.setPointSize(10)self._font=fontself.rowheight=cfg.getRowHeight()self.users,self.aliases=cfg.getUsers()returncfgdefaccept(self):self.close()defreject(self):self.close()defsetupUi(self):self.resize(627,721)icon=QIcon()icon.addPixmap(QPixmap(":/icons/log.svg"),QIcon.Normal,QIcon.Off)self.setWindowIcon(icon)self.centralwidget=QWidget(self)self.verticalLayout=vl=QVBoxLayout(self.centralwidget)vl.setSpacing(0) vl.setMargin(0)
self.repotabs_splitter = sp = QSplitter(self.centralwidget)
- sp.setOrientation(QtCore.Qt.Vertical)
+ sp.setOrientation(Qt.Vertical)
self.verticalLayout.addWidget(sp)
self.repoTabsWidget = tw = QTabWidget(self.repotabs_splitter)
tw.setDocumentMode(True)tw.setTabsClosable(True)tw.setMovable(True)sp=QSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding)sp.setHorizontalStretch(1)sp.setVerticalStretch(1)sp.setHeightForWidth(tw.sizePolicy().hasHeightForWidth())tw.setSizePolicy(sp)self.stackedWidget=QStackedWidget(self.repotabs_splitter)self.setCentralWidget(self.centralwidget)self.statusbar=QStatusBar(self)self.setStatusBar(self.statusbar) self.toolBar_treefilters = tb = QToolBar(_("Filter Toolbar"), self)
tb.setEnabled(True)
tb.setObjectName("toolBar_treefilters")
- self.addToolBar(QtCore.Qt.ToolBarArea(QtCore.Qt.TopToolBarArea), tb)
+ self.addToolBar(Qt.ToolBarArea(Qt.TopToolBarArea), tb)
self.toolBar_diff = tb = QToolBar(_("Diff Toolbar"), self)
tb.setObjectName("toolBar_diff")
- self.addToolBar(QtCore.Qt.ToolBarArea(QtCore.Qt.TopToolBarArea), tb)
+ self.addToolBar(Qt.ToolBarArea(Qt.TopToolBarArea), tb)
self.toolBar_help = tb = QToolBar(_("Help Toolbar"), self)
tb.setObjectName("toolBar_help")
- self.addToolBar(QtCore.Qt.ToolBarArea(QtCore.Qt.TopToolBarArea), tb)
+ self.addToolBar(Qt.ToolBarArea(Qt.TopToolBarArea), tb)
self.actionOpen_repository = a = QAction(_("&Open Repository"), self)
a.setShortcut("Ctrl+O")
self.actionRefresh=a=QAction(_("&Refresh"),self)a.setShortcut("Ctrl+R")self.actionQuit=a=QAction(_("E&xit"),self)a.setShortcut("None")a.setIconText(_("Exit"))a.setToolTip(_("Exit"))self.actionAbout=QAction(_("About"),self)self.actionDisplayAllBranches=QAction("displayAllBranches",self)self.actionHelp=QAction(_("Help"),self)self.actionBack=a=QAction(_("Back"),self)icon=QIcon()icon.addPixmap(QPixmap(":/icons/back.svg"),QIcon.Normal,QIcon.Off)a.setIcon(icon)self.actionForward=a=QAction(_("Forward"),self)icon=QIcon()icon.addPixmap(QPixmap(":/icons/forward.svg"),QIcon.Normal,QIcon.Off)a.setIcon(icon)self.actionShowPaths=a=QAction(_("Show Paths"),self)a.setCheckable(True)a=QAction(_("Show Repository Registry"),self)a.setCheckable(True)self.actionShowRepoRegistry=aself.menubar=QMenuBar(self)self.setMenuBar(self.menubar)self.menuFile=m=QMenu(_("&File"),self.menubar)m.addAction(self.actionOpen_repository)m.addAction(self.actionRefresh)m.addSeparator()m.addAction(self.actionQuit)self.menuHelp=m=QMenu(_("&Help"),self.menubar)m.addAction(self.actionAbout)m.addAction(self.actionHelp)self.menuView=m=QMenu(_("View"),self.menubar)m.addAction(self.actionShowRepoRegistry)m.addAction(self.actionShowPaths)self.menubar.addAction(self.menuFile.menuAction())self.menubar.addAction(self.menuView.menuAction())self.menubar.addAction(self.menuHelp.menuAction())self.toolBar_edit=tb=QToolBar(_("Edit Toolbar"),self)tb.setEnabled(True)tb.setObjectName("toolBar_edit")tb.addAction(self.actionRefresh)tb.addSeparator() tb.addAction(self.actionBack)
tb.addAction(self.actionForward)
tb.addSeparator()
- self.addToolBar(QtCore.Qt.ToolBarArea(QtCore.Qt.TopToolBarArea), tb)
+ self.addToolBar(Qt.ToolBarArea(Qt.TopToolBarArea), tb)
self.toolBar_help.addAction(self.actionHelp)
defshowRepoRegistry(self,show):self.reporegistry.setVisible(show)defopenRepo(self,repopath):repo=hg.repository(self.ui,path=str(repopath))self.addRepoTab(repo)deffind_root(self,url):p=str(url.toLocalFile())returnpaths.find_root(p)defdragEnterEvent(self,event):d=event.mimeData()foruind.urls():root=self.find_root(u)ifroot:event.acceptProposedAction()breakdefdropEvent(self,event):accept=Falsed=event.mimeData()foruind.urls():root=self.find_root(u)ifroot:repo=hg.repository(self.ui,path=root)self.addRepoTab(repo)accept=Trueifaccept:event.acceptProposedAction()defrepoTabCloseRequested(self,index):tw=self.repoTabsWidgetw=tw.widget(index)ifw.closeRepoWidget():tw.removeTab(index)defrepoTabChanged(self,index=0):self.setupBranchCombo()w=self.repoTabsWidget.currentWidget()mode='diff'ann=Falsetags=[]ifw:mode=w.getMode()ann=w.getAnnotate()tags=w.repo.tags().keys()w.switchedTo()else:self.actionDiffMode.setEnabled(False)self.stackedWidget.setCurrentWidget(self.dummywidget)self.actionDiffMode.setChecked(mode=='diff')self.actionAnnMode.setChecked(ann)defaddRepoTab(self,repo):'''opens the given repo in a new tab'''reponame=os.path.basename(repo.root)ifrepo.rootinself.commitwidgets:cw=self.commitwidgets[repo.root]else:pats={}opts={} cw = CommitWidget(pats, opts, root=repo.root)
self.commitwidgets[repo.root] = cw
self.stackedWidget.addWidget(cw)
- s = QtCore.QSettings()
+ s = QSettings()
cw.loadConfigs(s)
rw = RepoWidget(repo, self.stackedWidget, cw)
rw.showMessageSignal.connect(self.showMessage)rw.switchToSignal.connect(self.switchTo)tw=self.repoTabsWidgetindex=self.repoTabsWidget.addTab(rw,reponame)tw.setCurrentIndex(index)self.reporegistry.addRepo(repo.root)defswitchTo(self,widget):self.repoTabsWidget.setCurrentWidget(widget)defshowMessage(self,msg):self.statusBar().showMessage(msg)defsetupBranchCombo(self,*args):w=self.repoTabsWidget.currentWidget()ifnotw:self.branch_label_action.setEnabled(False)self.branch_comboBox_action.setEnabled(False)self.branch_comboBox.clear()returnrepo=w.repoallbranches=sorted(repo.branchtags().items())openbr=[]forbranch,brnodeinallbranches:openbr.extend(repo.branchheads(branch,closed=False))clbranches=[brforbr,nodeinallbranchesifnodenotinopenbr]branches=[brforbr,nodeinallbranchesifnodeinopenbr]ifself.branch_checkBox_action.isChecked():branches=branches+clbranchesiflen(branches)==1:self.branch_label_action.setEnabled(False)self.branch_comboBox_action.setEnabled(False)self.branch_comboBox.clear()else:branches=['']+branchesself.branchesmodel=QStringListModel(branches)self.branch_comboBox.setModel(self.branchesmodel)self.branch_label_action.setEnabled(True)self.branch_comboBox_action.setEnabled(True)branch=w.filterbranch()index=-1fori,binenumerate(branches):ifb==branch:index=ibreakself.branch_comboBox.setCurrentIndex(index)defcreateToolbars(self):# find quickbarself.find_toolbar=tb=FindInGraphlogQuickBar(self)tb.setObjectName("find_toolbar")#tb.attachFileView(self.fileview)#tb.attachHeaderView(self.revdisplay)#connect(tb, SIGNAL('revisionSelected'), self.repoview.goto)#connect(tb, SIGNAL('fileSelected'), self.tableView_filelist.selectFile)connect(tb,SIGNAL('showMessage'),self.statusBar().showMessage,Qt.QueuedConnection)self.attachQuickBar(tb)findaction=self.find_toolbar.toggleViewAction()findaction.setIcon(geticon('find'))self.toolBar_edit.addAction(findaction)# tree filters toolbarself.branch_label=QToolButton()self.branch_label.setText("Branch")self.branch_label.setStatusTip("Display graph the named branch only")self.branch_label.setPopupMode(QToolButton.InstantPopup)self.branch_menu=QMenu()cbranch_action=self.branch_menu.addAction("Display closed branches")cbranch_action.setCheckable(True)self.branch_checkBox_action=cbranch_actionself.branch_label.setMenu(self.branch_menu)self.branch_comboBox=QComboBox()connect(self.branch_comboBox,SIGNAL('activated(const QString &)'),self.refreshRevisionTable)connect(cbranch_action,SIGNAL('toggled(bool)'),self.setupBranchCombo)self.toolBar_treefilters.layout().setSpacing(3)self.branch_label_action=self.toolBar_treefilters.addWidget(self.branch_label)self.branch_comboBox_action=self.toolBar_treefilters.addWidget(self.branch_comboBox)self.toolBar_treefilters.addSeparator()self.toolBar_treefilters.addAction(self.actionSearch)self.toolBar_treefilters.addSeparator()# diff mode toolbarself.toolBar_diff.addAction(self.actionDiffMode)self.toolBar_diff.addAction(self.actionAnnMode)self.toolBar_diff.addAction(self.actionNextDiff)self.toolBar_diff.addAction(self.actionPrevDiff)defcreateActions(self):# main window actions (from .ui file)self.actionRefresh.triggered.connect(self.reload)self.actionAbout.triggered.connect(self.on_about)self.actionQuit.triggered.connect(self.close)self.actionBack.triggered.connect(self.back)self.actionForward.triggered.connect(self.forward)self.actionShowPaths.toggled.connect(self.actionShowPathsToggled)self.actionShowRepoRegistry.toggled.connect(self.showRepoRegistry)self.actionQuit.setIcon(geticon('quit'))self.actionRefresh.setIcon(geticon('reload'))self.actionDiffMode=QAction('Diff mode',self)self.actionDiffMode.setCheckable(True)connect(self.actionDiffMode,SIGNAL('toggled(bool)'),self.setMode)self.actionAnnMode=QAction('Annotate',self)self.actionAnnMode.setCheckable(True)connect(self.actionAnnMode,SIGNAL('toggled(bool)'),self.setAnnotate)self.actionSearch=QAction('Search',self)self.actionSearch.setShortcut(Qt.Key_F3)connect(self.actionSearch,SIGNAL('triggered()'),self.on_search)self.actionHelp.setShortcut(Qt.Key_F1)self.actionHelp.setIcon(geticon('help'))connect(self.actionHelp,SIGNAL('triggered()'),self.on_help)# Next/Prev diff (in full file mode)self.actionNextDiff=QAction(geticon('down'),'Next diff',self)self.actionNextDiff.setShortcut('Alt+Down')deffilled():self.actionNextDiff.setEnabled(self.fileview.fileMode()andself.fileview.nDiffs())#connect(self.fileview, SIGNAL('filled'), filled)self.actionPrevDiff=QAction(geticon('up'),'Previous diff',self)self.actionPrevDiff.setShortcut('Alt+Up')connect(self.actionNextDiff,SIGNAL('triggered()'),self.nextDiff)connect(self.actionPrevDiff,SIGNAL('triggered()'),self.prevDiff)self.actionDiffMode.setChecked(True)# Next/Prev fileself.actionNextFile=QAction('Next file',self)self.actionNextFile.setShortcut('Right')#connect(self.actionNextFile, SIGNAL('triggered()'),# self.tableView_filelist.nextFile)self.actionPrevFile=QAction('Prev file',self)self.actionPrevFile.setShortcut('Left')#connect(self.actionPrevFile, SIGNAL('triggered()'),# self.tableView_filelist.prevFile)self.addAction(self.actionNextFile)self.addAction(self.actionPrevFile)self.disab_shortcuts.append(self.actionNextFile)self.disab_shortcuts.append(self.actionPrevFile)# Next/Prev revself.actionNextRev=QAction('Next revision',self)self.actionNextRev.setShortcut('Down')#connect(self.actionNextRev, SIGNAL('triggered()'),# self.repoview.nextRev)self.actionPrevRev=QAction('Prev revision',self)self.actionPrevRev.setShortcut('Up')#connect(self.actionPrevRev, SIGNAL('triggered()'),# self.repoview.prevRev)self.addAction(self.actionNextRev)self.addAction(self.actionPrevRev)self.disab_shortcuts.append(self.actionNextRev)self.disab_shortcuts.append(self.actionPrevRev)# navigate in file viewerself.actionNextLine=QAction('Next line',self)self.actionNextLine.setShortcut(Qt.SHIFT+Qt.Key_Down)#connect(self.actionNextLine, SIGNAL('triggered()'),# self.fileview.nextLine)self.addAction(self.actionNextLine)self.actionPrevLine=QAction('Prev line',self)self.actionPrevLine.setShortcut(Qt.SHIFT+Qt.Key_Up)#connect(self.actionPrevLine, SIGNAL('triggered()'),# self.fileview.prevLine)self.addAction(self.actionPrevLine)self.actionNextCol=QAction('Next column',self)self.actionNextCol.setShortcut(Qt.SHIFT+Qt.Key_Right)#connect(self.actionNextCol, SIGNAL('triggered()'),# self.fileview.nextCol)self.addAction(self.actionNextCol)self.actionPrevCol=QAction('Prev column',self)self.actionPrevCol.setShortcut(Qt.SHIFT+Qt.Key_Left)#connect(self.actionPrevCol, SIGNAL('triggered()'),# self.fileview.prevCol)self.addAction(self.actionPrevCol)connect(self.actionOpen_repository,SIGNAL('triggered()'),self.openRepository)defactionShowPathsToggled(self,show):self.reporegistry.showPaths(show)defback(self):w=self.repoTabsWidget.currentWidget()ifw:w.back()defforward(self):w=self.repoTabsWidget.currentWidget()ifw:w.forward()defopenRepository(self):caption=_('Select repository directory to open')FD=QFileDialogpath=FD.getExistingDirectory(parent=self,caption=caption,options=FD.ShowDirsOnly|FD.ReadOnly)path=str(path)try:repo=hg.repository(self.ui,path=path)self.addRepoTab(repo)exceptRepoError:QMessageBox.warning(self,_('Failed to open repository'),_('%s is not a valid repository')%path)defsetMode(self,mode):w=self.repoTabsWidget.currentWidget()ifw:w.setMode(mode)self.actionAnnMode.setEnabled(notmode)self.actionNextDiff.setEnabled(notmode)self.actionPrevDiff.setEnabled(notmode)defsetAnnotate(self,ann):w=self.repoTabsWidget.currentWidget()ifw:w.setAnnotate(ann)defnextDiff(self):passdefprevDiff(self):passdeffile_displayed(self,filename):# self.actionPrevDiff.setEnabled(False)passdefreload(self):w=self.repoTabsWidget.currentWidget()ifw:w.reload()self.setupBranchCombo()defreloadRepository(self,root):tw=self.repoTabsWidgetforidxinrange(tw.count()):rw=tw.widget(idx)ifrw.repo.root==root:rw.reload()self.setupBranchCombo()#@timeitdefrefreshRevisionTable(self,*args,**kw):"""Starts the process of filling the HgModel"""branch=self.branch_comboBox.currentText()branch=str(branch)tw=self.repoTabsWidgetw=tw.currentWidget()ifw:w.setRepomodel(branch)ifbranch:tabtext='%s [%s]'%(w.reponame(),branch)else:tabtext=w.reponame()tw.setTabText(tw.currentIndex(),tabtext)defon_about(self,*args):""" Display about dialog """from__pkginfo__importmodname,version,short_desc,long_desctry:frommercurial.versionimportget_versionhgversion=get_version()except:frommercurial.__version__importversionashgversionmsg="<h2>About %(appname)s%(version)s</h2> (using hg %(hgversion)s)"% \
{"appname":modname,"version":version,"hgversion":hgversion}msg+="<p><i>%s</i></p>"%short_desc.capitalize()msg+="<p>%s</p>"%long_descQMessageBox.about(self,"About %s"%modname,msg)defon_help(self,*args):passdefon_search(self,*args):fromtortoisehg.hgqt.grepimportSearchWidget # todo: get root of current repo, pass to search widget
root = None
s = SearchWidget('', root, self)
- s.setAllowedAreas(QtCore.Qt.TopDockWidgetArea|
- QtCore.Qt.BottomDockWidgetArea)
+ s.setAllowedAreas(Qt.TopDockWidgetArea| Qt.BottomDockWidgetArea)
s.setObjectName("searchWidget%d" % len(self._searchWidgets))
- self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, s)
+ self.addDockWidget(Qt.BottomDockWidgetArea, s)
self._searchWidgets.append(s)
def okToContinue(self):
''' returns False if there is unsaved data If there is unsaved data, present a dialog asking the user if it is ok to discard the changes made. ''' return True
def storeSettings(self):
- s = QtCore.QSettings()
+ s = QSettings()
wb = "Workbench/"
s.setValue(wb + 'geometry', self.saveGeometry())
s.setValue(wb + 'windowState', self.saveState())
forninself.splitternames: s.setValue(wb + n, getattr(self, n).saveState())
def restoreSettings(self):
- s = QtCore.QSettings()
+ s = QSettings()
wb = "Workbench/"
self.restoreGeometry(s.value(wb + 'geometry').toByteArray())
self.restoreState(s.value(wb + 'windowState').toByteArray())
self.splitternames=[]sn=('repotabs',)forninsn:n+='_splitter'self.splitternames.append(n)getattr(self,n).restoreState(s.value(wb+n).toByteArray())defcloseEvent(self,event):ifnotself.okToContinue()ornotself.closeRepoTabs():event.ignore()else:self.storeSettings()self.reporegistry.close()defcloseRepoTabs(self):'''returns False if close should be aborted'''tw=self.repoTabsWidgetforidxinrange(tw.count()):rw=tw.widget(idx)ifnotrw.closeRepoWidget():returnFalsereturnTruedefrun(ui,*pats,**opts):repo=Noneroot=paths.find_root()ifroot:repo=hg.repository(ui,path=root)returnWorkbench(ui,repo)
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.