PageRenderTime 34ms CodeModel.GetById 12ms app.highlight 18ms RepoModel.GetById 1ms app.codeStats 0ms

/tortoisehg/hgqt/revdetails.py

https://bitbucket.org/tortoisehg/hgtk/
Python | 241 lines | 185 code | 38 blank | 18 comment | 7 complexity | be56892010fd1b2f246823ec62863242 MD5 | raw file
  1# repowidget.py - TortoiseHg repository widget
  2#
  3# Copyright (C) 2007-2010 Logilab. All rights reserved.
  4# Copyright (C) 2010 Adrian Buehlmann <adrian@cadifra.com>
  5#
  6# This software may be used and distributed according to the terms
  7# of the GNU General Public License, incorporated herein by reference.
  8
  9from tortoisehg.hgqt.qtlib import getfont, geticon, descriptionhtmlizer
 10from tortoisehg.hgqt.i18n import _
 11from tortoisehg.hgqt.filelistmodel import HgFileListModel
 12from tortoisehg.hgqt.filelistview import HgFileListView
 13from tortoisehg.hgqt.fileview import HgFileView
 14from tortoisehg.hgqt.revpanel import RevPanelWidget
 15from tortoisehg.hgqt import thgrepo, qscilib
 16
 17from PyQt4.QtCore import *
 18from PyQt4.QtGui import *
 19
 20class RevDetailsWidget(QWidget):
 21
 22    showMessage = pyqtSignal(QString)
 23    linkActivated = pyqtSignal(unicode)
 24    grepRequested = pyqtSignal(unicode, dict)
 25    revisionSelected = pyqtSignal(int)
 26
 27    def __init__(self, repo):
 28        QWidget.__init__(self)
 29
 30        self.repo = repo
 31        self.splitternames = []
 32
 33        self._deschtmlize = descriptionhtmlizer(repo.ui)
 34        repo.configChanged.connect(self._updatedeschtmlizer)
 35
 36        # these are used to know where to go after a reload
 37        self._last_rev = None
 38        self._reload_file = None
 39
 40        self.setupUi()
 41        self.createActions()
 42        self.setupModels()
 43
 44        self.fileview.setFont(getfont('fontdiff').font())
 45        self.fileview.showMessage.connect(self.showMessage)
 46        self.fileview.grepRequested.connect(self.grepRequested)
 47        self.fileview.revisionSelected.connect(self.revisionSelected)
 48        self.restoreSettings()
 49
 50    def setRepo(self, repo):
 51        self.repo = repo
 52
 53    def setupUi(self):
 54        SP = QSizePolicy
 55        sp = SP(SP.Preferred, SP.Expanding)
 56        sp.setHorizontalStretch(0)
 57        sp.setVerticalStretch(0)
 58        sp.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
 59        self.setSizePolicy(sp)
 60
 61        # + revisiondetails_layout -----------------------------------------+
 62        # |+ filelist_splitter ........                                     |
 63        # | + tbarFileListFrame (vbox)| + cset_and_file_details_frame (vbox)|
 64        # |  + mergeToolbar           |  + revpanel                         |
 65        # +---------------------------+-------------------------------------+
 66        # |  + filelist               |  + message_splitter                 |
 67        # |                           |  :+ message                         |
 68        # |                           |  :----------------------------------+
 69        # |                           |   + fileview                        |
 70        # +---------------------------+-------------------------------------+
 71
 72        revisiondetails_layout = QVBoxLayout(self)
 73        revisiondetails_layout.setSpacing(0)
 74        revisiondetails_layout.setMargin(0)
 75        revisiondetails_layout.setContentsMargins(2, 2, 2, 2)
 76
 77        self.filelist_splitter = QSplitter(self)
 78        self.splitternames.append('filelist_splitter')
 79
 80        sp = SP(SP.Expanding, SP.Expanding)
 81        sp.setHorizontalStretch(0)
 82        sp.setVerticalStretch(0)
 83        sp.setHeightForWidth(self.filelist_splitter.sizePolicy().hasHeightForWidth())
 84        self.filelist_splitter.setSizePolicy(sp)
 85        self.filelist_splitter.setOrientation(Qt.Horizontal)
 86        self.filelist_splitter.setChildrenCollapsible(False)
 87
 88        self.mergeToolBar = QToolBar(_('Merge Toolbar'))
 89        self.mergeToolBar.setIconSize(QSize(16,16))
 90        self.filelist = HgFileListView()
 91
 92        self.tbarFileListFrame = QFrame(self.filelist_splitter)
 93        sp = SP(SP.Preferred, SP.Preferred)
 94        sp.setHorizontalStretch(3)
 95        sp.setVerticalStretch(0)
 96        sp.setHeightForWidth(
 97            self.tbarFileListFrame.sizePolicy().hasHeightForWidth())
 98        self.tbarFileListFrame.setSizePolicy(sp)
 99        self.tbarFileListFrame.setFrameShape(QFrame.NoFrame)
100        vbox = QVBoxLayout()
101        vbox.setSpacing(0)
102        vbox.setMargin(0)
103        vbox.addWidget(self.mergeToolBar)
104        vbox.addWidget(self.filelist)
105        self.tbarFileListFrame.setLayout(vbox)
106
107        self.cset_and_file_details_frame = QFrame(self.filelist_splitter)
108        sp = SP(SP.Preferred, SP.Preferred)
109        sp.setHorizontalStretch(7)
110        sp.setVerticalStretch(0)
111        sp.setHeightForWidth(
112            self.cset_and_file_details_frame.sizePolicy().hasHeightForWidth())
113        self.cset_and_file_details_frame.setSizePolicy(sp)
114        self.cset_and_file_details_frame.setFrameShape(QFrame.NoFrame)
115
116        vbox = QVBoxLayout(self.cset_and_file_details_frame)
117        vbox.setSpacing(0)
118        vbox.setSizeConstraint(QLayout.SetDefaultConstraint)
119        vbox.setMargin(0)
120        cset_and_file_details_layout = vbox
121
122        self.message_splitter = QSplitter(self.cset_and_file_details_frame)
123        self.splitternames.append('message_splitter')
124        sp = SP(SP.Preferred, SP.Expanding)
125        sp.setHorizontalStretch(0)
126        sp.setVerticalStretch(0)
127        sp.setHeightForWidth(self.message_splitter.sizePolicy().hasHeightForWidth())
128        self.message_splitter.setSizePolicy(sp)
129        self.message_splitter.setMinimumSize(QSize(50, 50))
130        self.message_splitter.setFrameShape(QFrame.NoFrame)
131        self.message_splitter.setLineWidth(0)
132        self.message_splitter.setMidLineWidth(0)
133        self.message_splitter.setOrientation(Qt.Vertical)
134        self.message_splitter.setOpaqueResize(True)
135        self.message = QTextBrowser(self.message_splitter,
136                                    lineWrapMode=QTextEdit.NoWrap,
137                                    openLinks=False)
138        self.message.minimumSizeHint = lambda: QSize(0, 25)
139        self.message.anchorClicked.connect(
140            lambda url: self.linkActivated.emit(url.toString()))
141
142        sp = SP(SP.Expanding, SP.Expanding)
143        sp.setHorizontalStretch(0)
144        sp.setVerticalStretch(2)
145        sp.setHeightForWidth(self.message.sizePolicy().hasHeightForWidth())
146        self.message.setSizePolicy(sp)
147        self.message.setMinimumSize(QSize(0, 0))
148        f = getfont('fontcomment')
149        self.message.setFont(f.font())
150        f.changed.connect(lambda font: self.message.setFont(font))
151
152        self.fileview = HgFileView(self.repo, self.message_splitter)
153        sp = SP(SP.Expanding, SP.Expanding)
154        sp.setHorizontalStretch(0)
155        sp.setVerticalStretch(5)
156        sp.setHeightForWidth(self.fileview.sizePolicy().hasHeightForWidth())
157        self.fileview.setSizePolicy(sp)
158        self.fileview.setMinimumSize(QSize(0, 0))
159
160        self.revpanel = RevPanelWidget(self.repo)
161        self.revpanel.linkActivated.connect(self.linkActivated)
162
163        cset_and_file_details_layout.addWidget(self.revpanel)
164        cset_and_file_details_layout.addWidget(self.message_splitter)
165
166        revisiondetails_layout.addWidget(self.filelist_splitter)
167
168        self.filelist.fileRevSelected.connect(self.onFileRevSelected)
169        self.filelist.clearDisplay.connect(self.fileview.clearDisplay)
170
171    def createActions(self):
172        def fileActivated():
173            idx = self.filelist.currentIndex()
174            self.filelist.fileActivated(idx, alternate=True)
175        self.actionActivateFileAlt = QAction('Activate alt. file', self)
176        self.actionActivateFileAlt.setShortcuts([Qt.ALT+Qt.Key_Return,
177                                                 Qt.ALT+Qt.Key_Enter])
178        self.actionActivateFileAlt.triggered.connect(fileActivated)
179        self.mergeToolBar.addAction(self.filelist.actionShowAllMerge)
180
181    def create_models(self):
182        self.filelistmodel = HgFileListModel(self.repo, self)
183
184    def setupModels(self):
185        self.create_models()
186        self.filelist.setModel(self.filelistmodel)
187
188    @pyqtSlot(object, object, object)
189    def onFileRevSelected(self, file, rev, status):
190        self.fileview.displayFile(file, rev, status)
191
192    def revision_selected(self, rev):
193        self._last_rev = rev
194        ctx = self.repo.changectx(rev)
195        self.revpanel.set_revision(rev)
196        self.revpanel.update(repo = self.repo)
197        self.message.setHtml('<pre>%s</pre>'
198                             % self._deschtmlize(ctx.description()))
199        self.fileview.setContext(ctx)
200        self.filelistmodel.setContext(ctx)
201
202    @pyqtSlot()
203    def _updatedeschtmlizer(self):
204        self._deschtmlize = descriptionhtmlizer(self.repo.ui)
205        self.revision_selected(self._last_rev)  # regenerate desc html
206
207    def record(self):
208        'Repo widget is reloading, record current file'
209        self._reload_file = self.filelist.currentFile()
210
211    def finishReload(self):
212        'Finish reload by re-selecting previous file'
213        if self._reload_file:
214            self.filelist.selectFile(self._reload_file)
215        elif not self.filelist.selectedIndexes():
216            self.filelist.selectRow(0)
217
218    def reload(self):
219        'Task tab is reloaded, or repowidget is refreshed'
220        if len(self.repo) <= self._last_rev:
221            self._last_rev = '.'
222        f = self.filelist.currentFile()
223        self.revision_selected(self._last_rev)
224        self.filelist.selectFile(f)
225
226    def storeSettings(self):
227        s = QSettings()
228        wb = "RevDetailsWidget/"
229        for n in self.splitternames:
230            s.setValue(wb + n, getattr(self, n).saveState())
231        s.setValue(wb + 'revpanel.expanded', self.revpanel.is_expanded())
232        self.fileview.saveSettings(s, 'revpanel/fileview')
233
234    def restoreSettings(self):
235        s = QSettings()
236        wb = "RevDetailsWidget/"
237        for n in self.splitternames:
238            getattr(self, n).restoreState(s.value(wb + n).toByteArray())
239        expanded = s.value(wb + 'revpanel.expanded', False).toBool()
240        self.revpanel.set_expanded(expanded)
241        self.fileview.loadSettings(s, 'revpanel/fileview')