PageRenderTime 36ms CodeModel.GetById 10ms app.highlight 22ms RepoModel.GetById 1ms app.codeStats 0ms

/tortoisehg/hgqt/reporegistry.py

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