PageRenderTime 35ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/tortoisehg/hgqt/reporegistry.py

https://bitbucket.org/tortoisehg/hgtk/
Python | 274 lines | 256 code | 11 blank | 7 comment | 1 complexity | ffca090373c42a548067739719f0a986 MD5 | raw file
Possible License(s): GPL-2.0
  1. # reporegistry.py - registry for a user's repositories
  2. #
  3. # Copyright 2010 Adrian Buehlmann <adrian@cadifra.com>
  4. #
  5. # This software may be used and distributed according to the terms of the
  6. # GNU General Public License version 2 or any later version.
  7. import os
  8. from mercurial import url
  9. from tortoisehg.util import hglib
  10. from tortoisehg.hgqt.i18n import _
  11. from tortoisehg.hgqt import cmdui, qtlib, thgrepo
  12. from tortoisehg.hgqt.repotreemodel import RepoTreeModel
  13. from tortoisehg.hgqt.pathedit import PathEditDialog
  14. from tortoisehg.hgqt.clone import CloneDialog
  15. from PyQt4.QtCore import *
  16. from PyQt4.QtGui import *
  17. connect = QObject.connect
  18. def settingsfilename():
  19. """Return path to thg-reporegistry.xml as unicode"""
  20. s = QSettings()
  21. dir = os.path.dirname(unicode(s.fileName()))
  22. return dir + '/' + 'thg-reporegistry.xml'
  23. class RepoTreeView(QTreeView):
  24. contextmenu = None
  25. def __init__(self, parent, workbench):
  26. QTreeView.__init__(self, parent, allColumnsShowFocus=True)
  27. self.workbench = workbench
  28. self.selitem = None
  29. self.msg = ''
  30. self.setExpandsOnDoubleClick(False)
  31. self.setMouseTracking(True)
  32. # enable drag and drop
  33. # (see http://doc.qt.nokia.com/4.6/model-view-dnd.html)
  34. self.setDragEnabled(True)
  35. self.setAcceptDrops(True)
  36. self.setDragDropMode(QAbstractItemView.InternalMove)
  37. self.setDropIndicatorShown(True)
  38. self.createActions()
  39. self.setHeaderHidden(True)
  40. def contextMenuEvent(self, event):
  41. if not self.selitem:
  42. return
  43. menulist = self.selitem.internalPointer().menulist()
  44. if len(menulist) > 0:
  45. if not self.contextmenu:
  46. self.contextmenu = QMenu(self)
  47. else:
  48. self.contextmenu.clear()
  49. for act in menulist:
  50. if act:
  51. self.contextmenu.addAction(self._actions[act])
  52. else:
  53. self.contextmenu.addSeparator()
  54. self.contextmenu.exec_(event.globalPos())
  55. def mouseMoveEvent(self, event):
  56. self.msg = ''
  57. pos = event.pos()
  58. idx = self.indexAt(pos)
  59. if idx.isValid():
  60. item = idx.internalPointer()
  61. self.msg = item.details()
  62. self.workbench.showMessage(self.msg)
  63. super(RepoTreeView, self).mouseMoveEvent(event)
  64. def leaveEvent(self, event):
  65. if self.msg != '':
  66. self.workbench.showMessage('')
  67. def mouseDoubleClickEvent(self, event):
  68. self.showFirstTabOrOpen()
  69. def selectionChanged(self, selected, deselected):
  70. selection = self.selectedIndexes()
  71. if len(selection) == 0:
  72. self.selitem = None
  73. else:
  74. self.selitem = selection[0]
  75. def _action_defs(self):
  76. a = [("open", _("Open"), None,
  77. _("Open the repository in a new tab"), None, self.open),
  78. ("openAll", _("Open All"), None,
  79. _("Open all repositories in new tabs"), None, self.openAll),
  80. ("newGroup", _("New Group"), None,
  81. _("Create a new group"), None, self.newGroup),
  82. ("rename", _("Rename"), None,
  83. _("Rename the entry"), None, self.startRename),
  84. ("settings", _("Settings..."), None,
  85. _("View the repository's settings"), None, self.startSettings),
  86. ("remove", _("Remove from registry"), None,
  87. _("Remove the node and all its subnodes."
  88. " Repositories are not deleted from disk."),
  89. None, self.removeSelected),
  90. ("clone", _("Clone..."), None,
  91. _("Clone Repository"), None, self.cloneRepo),
  92. ("explore", _("Explore"), None,
  93. _("Open the repository in Windows Explorer"), None, self.explore),
  94. ("terminal", _("Terminal"), None,
  95. _("Open a shell terminal in repository root"), None, self.terminal),
  96. ("add", _("Add repository..."), None,
  97. _("Add a repository to this group"), None, self.addRepo),
  98. ]
  99. return a
  100. def createActions(self):
  101. self._actions = {}
  102. for name, desc, icon, tip, key, cb in self._action_defs():
  103. self._actions[name] = QAction(desc, self)
  104. QTimer.singleShot(0, self.configureActions)
  105. def configureActions(self):
  106. for name, desc, icon, tip, key, cb in self._action_defs():
  107. act = self._actions[name]
  108. '''
  109. if icon:
  110. act.setIcon(qtlib.geticon(icon))
  111. '''
  112. if tip:
  113. act.setStatusTip(tip)
  114. if key:
  115. act.setShortcut(key)
  116. if cb:
  117. act.triggered.connect(cb)
  118. self.addAction(act)
  119. def startSettings(self):
  120. if not self.selitem:
  121. return
  122. self.selitem.internalPointer().startSettings(self.parent())
  123. def startRename(self):
  124. if not self.selitem:
  125. return
  126. self.edit(self.selitem)
  127. def open(self):
  128. if not self.selitem:
  129. return
  130. self.selitem.internalPointer().open()
  131. def openAll(self):
  132. if not self.selitem:
  133. return
  134. self.selitem.internalPointer().openAll()
  135. def showFirstTabOrOpen(self):
  136. if not self.selitem:
  137. return
  138. self.selitem.internalPointer().showFirstTabOrOpen(workbench=self.workbench)
  139. def newGroup(self):
  140. m = self.model()
  141. m.addGroup(_('New Group'))
  142. def removeSelected(self):
  143. if not self.selitem:
  144. return
  145. s = self.selitem
  146. if not s.internalPointer().okToDelete(self):
  147. return
  148. m = self.model()
  149. row = s.row()
  150. parent = s.parent()
  151. m.removeRows(row, 1, parent)
  152. def cloneRepo(self):
  153. if not self.selitem:
  154. return
  155. root = self.selitem.internalPointer().rootpath()
  156. d = CloneDialog(args=[root, root + '-clone'], parent=self)
  157. def cmdfinished(res):
  158. if res == 0:
  159. dest = d.getDest()
  160. self.workbench.openRepo(dest)
  161. d.cmdfinished.connect(cmdfinished)
  162. d.show()
  163. def explore(self):
  164. if not self.selitem:
  165. return
  166. root = self.selitem.internalPointer().rootpath()
  167. self.workbench.launchExplorer(root)
  168. def terminal(self):
  169. if not self.selitem:
  170. return
  171. root = self.selitem.internalPointer().rootpath()
  172. repo = thgrepo.repository(path=root)
  173. self.workbench.launchTerminal(repo)
  174. def addRepo(self):
  175. if not self.selitem:
  176. return
  177. m = self.model()
  178. m.addRepo(self.selitem, '')
  179. def sizeHint(self):
  180. size = super(RepoTreeView, self).sizeHint()
  181. size.setWidth(QFontMetrics(self.font()).width('M') * 15)
  182. return size
  183. class RepoRegistryView(QDockWidget):
  184. openRepoSignal = pyqtSignal(QString, bool)
  185. visibilityChanged = pyqtSignal(bool)
  186. def __init__(self, workbench):
  187. QDockWidget.__init__(self, workbench)
  188. self.setFeatures(QDockWidget.DockWidgetClosable |
  189. QDockWidget.DockWidgetMovable |
  190. QDockWidget.DockWidgetFloatable)
  191. self.setWindowTitle(_('Repository Registry'))
  192. mainframe = QFrame()
  193. lay = QVBoxLayout()
  194. lay.setContentsMargins(0, 0, 0, 0)
  195. mainframe.setLayout(lay)
  196. self.setWidget(mainframe)
  197. self.tmodel = m = RepoTreeModel(self.openrepo, settingsfilename(),
  198. parent=self)
  199. self.tview = tv = RepoTreeView(self, workbench)
  200. lay.addWidget(tv)
  201. tv.setModel(m)
  202. tv.setIndentation(10)
  203. tv.setFirstColumnSpanned(0, QModelIndex(), True)
  204. self.tview.setColumnHidden(1, True)
  205. QTimer.singleShot(0, self.expand)
  206. def expand(self):
  207. self.tview.expandToDepth(0)
  208. def addRepo(self, reporoot):
  209. m = self.tmodel
  210. if m.getRepoItem(reporoot) == None:
  211. m.addRepo(None, reporoot)
  212. def openrepo(self, path, reuse=False):
  213. self.openRepoSignal.emit(hglib.tounicode(path), reuse)
  214. def showPaths(self, show):
  215. self.tview.setColumnHidden(1, not show)
  216. if show:
  217. self.tview.resizeColumnToContents(0)
  218. self.tview.resizeColumnToContents(1)
  219. def close(self):
  220. self.tmodel.write(settingsfilename())
  221. def showEvent(self, event):
  222. self.visibilityChanged.emit(True)
  223. def hideEvent(self, event):
  224. self.visibilityChanged.emit(False)