PageRenderTime 26ms CodeModel.GetById 12ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/tortoisehg/hgqt/qfold.py

https://bitbucket.org/tortoisehg/hgtk/
Python | 188 lines | 148 code | 32 blank | 8 comment | 16 complexity | 7ea98034348739153b85aad448cb6a8e MD5 | raw file
  1# qfold.py - QFold dialog for TortoiseHg
  2#
  3# Copyright 2010 Steve Borho <steve@borho.org>
  4# Copyright 2010 Johan Samyn <johan.samyn@gmail.com>
  5#
  6# This software may be used and distributed according to the terms of the
  7# GNU General Public License version 2, incorporated herein by reference.
  8
  9import os
 10
 11from PyQt4.QtCore import *
 12from PyQt4.QtGui import *
 13from PyQt4.Qsci import QsciScintilla, QsciAPIs, QsciLexerMakefile
 14
 15from hgext import mq
 16
 17from tortoisehg.util import hglib
 18from tortoisehg.hgqt.i18n import _
 19from tortoisehg.hgqt import cmdui, qscilib, qtlib
 20from tortoisehg.hgqt.commit import MessageEntry
 21
 22class QFoldDialog(QDialog):
 23
 24    output = pyqtSignal(QString, QString)
 25    makeLogVisible = pyqtSignal(bool)
 26
 27    def __init__(self, repo, patches, parent):
 28        super(QFoldDialog, self).__init__(parent)
 29        self.setWindowTitle(_('Patch fold - %s') % repo.displayname)
 30
 31        f = self.windowFlags()
 32        self.setWindowFlags(f & ~Qt.WindowContextHelpButtonHint)
 33
 34        self.setLayout(QVBoxLayout())
 35
 36        mlbl = QLabel(_('New patch message:'))
 37        self.layout().addWidget(mlbl)
 38        self.msgte = MessageEntry()
 39        self.msgte.setContextMenuPolicy(Qt.CustomContextMenu)
 40        self.msgte.customContextMenuRequested.connect(self.menuRequested)
 41        self.msgte.installEventFilter(qscilib.KeyPressInterceptor(self))
 42        self.layout().addWidget(self.msgte)
 43
 44        self.keepchk = QCheckBox(_('Keep patch files'))
 45        self.keepchk.setChecked(True)
 46        self.layout().addWidget(self.keepchk)
 47
 48        self.repo = repo
 49        q = self.repo.mq
 50        q.parse_series()
 51        self.patches = [p for p in q.series if p in patches]
 52
 53        class PatchListWidget(QListWidget):
 54            def __init__(self, parent):
 55                QListWidget.__init__(self, parent)
 56                self.setCurrentRow(0)
 57            def focusInEvent(self, event):
 58                i = self.item(self.currentRow())
 59                if i:
 60                    self.parent().parent().showSummary(i)
 61                QListWidget.focusInEvent(self, event)
 62            def dropEvent(self, event):
 63                QListWidget.dropEvent(self, event)
 64                spp = self.parent().parent()
 65                spp.msgte.setText(spp.composeMsg(self.getPatchList()))
 66            def getPatchList(self):
 67                return [hglib.fromunicode(self.item(i).text()) \
 68                        for i in xrange(0, self.count())]
 69
 70        ugb = QGroupBox(_('Patches to fold'))
 71        ugb.setLayout(QVBoxLayout())
 72        ugb.layout().setContentsMargins(*(0,)*4)
 73        self.ulw = PatchListWidget(self)
 74        self.ulw.setDragDropMode(QListView.InternalMove)
 75        ugb.layout().addWidget(self.ulw)
 76        self.ulw.currentItemChanged.connect(lambda:
 77                self.showSummary(self.ulw.item(self.ulw.currentRow())))
 78        self.layout().addWidget(ugb)
 79
 80        for p in self.patches:
 81            item = QListWidgetItem(hglib.tounicode(p))
 82            item.setFlags(Qt.ItemIsSelectable |
 83                          Qt.ItemIsEnabled |
 84                          Qt.ItemIsDragEnabled)
 85            self.ulw.addItem(item)
 86
 87        slbl = QLabel(_('Summary:'))
 88        self.layout().addWidget(slbl)
 89        self.summ = QTextEdit()
 90        self.summ.setFont(qtlib.getfont('fontcomment').font())
 91        self.summ.setMaximumHeight(80)
 92        self.summ.setReadOnly(True)
 93        self.summ.setFocusPolicy(Qt.NoFocus)
 94        self.layout().addWidget(self.summ)
 95
 96        self.cmd = cmdui.Runner()
 97        self.cmd.output.connect(self.output)
 98        self.cmd.makeLogVisible.connect(self.makeLogVisible)
 99
100        BB = QDialogButtonBox
101        bbox = QDialogButtonBox(BB.Ok|BB.Cancel)
102        bbox.accepted.connect(self.accept)
103        bbox.rejected.connect(self.reject)
104        self.layout().addWidget(bbox)
105        self.bbox = bbox
106
107        self.repo.configChanged.connect(self.configChanged)
108
109        self._readsettings()
110
111        self.msgte.setText(self.composeMsg(self.patches))
112        self.msgte.refresh(self.repo)
113        self.focus = self.msgte
114
115    def showSummary(self, item):
116        patchname = hglib.fromunicode(item.text())
117        txt = '\n'.join(mq.patchheader(self.repo.mq.join(patchname)).message)
118        self.summ.setText(hglib.tounicode(txt))
119
120    def composeMsg(self, patches):
121        return '\n* * *\n'.join(
122              [self.repo.changectx('qtip').description()]
123              + [self.repo.changectx(p).description() for p in patches])
124
125    def getMessage(self):
126        text = self.msgte.text()
127        try:
128            text = hglib.fromunicode(text, 'strict')
129        except UnicodeEncodeError:
130            pass # TODO (see commit.py)
131        return text
132
133    def configChanged(self):
134        '''Repository is reporting its config files have changed'''
135        self.msgte.refresh(self.repo)
136
137    def accept(self):
138        self._writesettings()
139        self.bbox.setDisabled(True)
140        cmdline = ['qfold', '--repository', self.repo.root]
141        if self.keepchk.isChecked():
142            cmdline += ['--keep']
143        cmdline += ['--message', self.getMessage()]
144        cmdline += ['--']
145        cmdline += self.ulw.getPatchList()
146        def finished():
147            self.repo.decrementBusyCount()
148            QDialog.accept(self)
149        self.repo.incrementBusyCount()
150        self.cmd.commandFinished.connect(finished)
151        self.cmd.run(cmdline)
152
153    def menuRequested(self, point):
154        line = self.msgte.lineAt(point)
155        point = self.msgte.mapToGlobal(point)
156
157        def apply():
158            line = 0
159            while True:
160                line = self.mste.reflowBlock(line)
161                if line is None:
162                    break;
163        def settings():
164            from tortoisehg.hgqt.settings import SettingsDialog
165            dlg = SettingsDialog(True, focus='tortoisehg.summarylen')
166            dlg.exec_()
167
168        menu = self.msgte.createStandardContextMenu()
169        menu.addSeparator()
170        for name, func in [(_('App&ly Format'), apply),
171                           (_('C&onfigure Format'), settings)]:
172            def add(name, func):
173                action = menu.addAction(name)
174                action.triggered.connect(lambda: func())
175            add(name, func)
176        return menu.exec_(point)
177
178    def closeEvent(self, event):
179        self._writesettings()
180        super(QFoldDialog, self).closeEvent(event)
181
182    def _readsettings(self):
183        s = QSettings()
184        self.restoreGeometry(s.value('qfold/geom').toByteArray())
185
186    def _writesettings(self):
187        s = QSettings()
188        s.setValue('qfold/geom', self.saveGeometry())