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

/tortoisehg/hgqt/bugreport.py

https://bitbucket.org/tortoisehg/hgtk/
Python | 166 lines | 144 code | 13 blank | 9 comment | 4 complexity | 64b2a522e01a12f8f8427ed3ad2b4305 MD5 | raw file
  1# bugreport.py - Report Python tracebacks to the user
  2#
  3# Copyright 2010 Steve Borho <steve@borho.org>
  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
  9import sys
 10
 11from mercurial import extensions, ui
 12from tortoisehg.util import hglib, version
 13from tortoisehg.hgqt.i18n import _
 14
 15from PyQt4.QtCore import *
 16from PyQt4.QtGui import *
 17
 18class BugReport(QDialog):
 19
 20    def __init__(self, opts, parent=None):
 21        super(BugReport, self).__init__(parent)
 22
 23        self.text = self.gettext(opts)
 24
 25        layout = QVBoxLayout()
 26
 27        tb = QTextBrowser()
 28        tb.setHtml('<pre>' + Qt.escape(self.text) + '</pre>')
 29        tb.setWordWrapMode(QTextOption.NoWrap)
 30        layout.addWidget(tb)
 31
 32        # dialog buttons
 33        BB = QDialogButtonBox
 34        bb = QDialogButtonBox(BB.Ok|BB.Save)
 35        bb.accepted.connect(self.accept)
 36        bb.button(BB.Save).clicked.connect(self.save)
 37        bb.button(BB.Ok).setDefault(True)
 38        bb.addButton(_('Quit'), BB.DestructiveRole).clicked.connect(qApp.quit)
 39        layout.addWidget(bb)
 40
 41        self.setLayout(layout)
 42        self.setWindowTitle(_('TortoiseHg Bug Report'))
 43        self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
 44        self.resize(650, 400)
 45        self._readsettings()
 46
 47    def gettext(self, opts):
 48        text = '{{{\n#!python\n' # Wrap in Bitbucket wiki preformat markers
 49        text += _('** Please report this bug to'
 50                ' http://bitbucket.org/tortoisehg/thg/issues\n')
 51        text += '** Mercurial version (%s).  TortoiseHg version (%s)\n' % (
 52                hglib.hgversion, version.version())
 53        text += '** Command: %s\n' % (hglib.tounicode(opts.get('cmd', 'N/A')))
 54        text += '** CWD: %s\n' % hglib.tounicode(os.getcwd())
 55        extlist = [x[0] for x in extensions.extensions()]
 56        text += '** Extensions loaded: %s\n' % ', '.join(extlist)
 57        text += '** Python version: %s\n' % sys.version.replace('\n', '')
 58        if os.name == 'nt':
 59            text += self.getarch()
 60        text += '** Qt-%s PyQt-%s\n' % (QT_VERSION_STR, PYQT_VERSION_STR)
 61        text += hglib.tounicode(opts.get('error', 'N/A'))
 62        text += '\n}}}'
 63        return text
 64
 65    def getarch(self):
 66        text = '** Windows version: %s\n' % str(sys.getwindowsversion())
 67        arch = 'unknown (failed to import win32api)'
 68        try:
 69            import win32api
 70            arch = 'unknown'
 71            archval = win32api.GetNativeSystemInfo()[0]
 72            if archval == 9:
 73                arch = 'x64'
 74            elif archval == 0:
 75                arch = 'x86'
 76        except (ImportError, AttributeError):
 77            pass
 78        text += '** Processor architecture: %s\n' % arch
 79        return text
 80
 81    def save(self):
 82        try:
 83            fd = QFileDialog(self)
 84            fname = fd.getSaveFileName(self,
 85                        _('Save error report to'),
 86                        os.path.join(os.getcwd(), 'bugreport.txt'),
 87                        _('Text files (*.txt)'))
 88            if fname:
 89                open(fname, 'wb').write(self.text)
 90        except (EnvironmentError), e:
 91            QMessageBox.critical(self, _('Error writing file'), str(e))
 92
 93    def accept(self):
 94        self._writesettings()
 95        super(BugReport, self).accept()
 96
 97    def reject(self):
 98        self._writesettings()
 99        super(BugReport, self).reject()
100
101    def _readsettings(self):
102        s = QSettings()
103        self.restoreGeometry(s.value('bugreport/geom').toByteArray())
104
105    def _writesettings(self):
106        s = QSettings()
107        s.setValue('bugreport/geom', self.saveGeometry())
108
109class ExceptionMsgBox(QDialog):
110    """Message box for recoverable exception"""
111    def __init__(self, main, text, opts, parent=None):
112        super(ExceptionMsgBox, self).__init__(parent)
113        self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint)
114        self.setWindowTitle(_('TortoiseHg Error'))
115
116        self._opts = opts
117
118        labelflags = Qt.TextSelectableByMouse | Qt.LinksAccessibleByMouse
119
120        self.setLayout(QVBoxLayout())
121
122        if '%(arg' in text:
123            values = opts.get('values', [])
124            msgopts = {}
125            for i, val in enumerate(values):
126                msgopts['arg' + str(i)] = Qt.escape(val)
127            try:
128                text = text % msgopts
129            except Exception, e:
130                print e, msgopts
131        else:
132            self._mainlabel = QLabel('<b>%s</b>' % Qt.escape(main),
133                                     textInteractionFlags=labelflags)
134            self.layout().addWidget(self._mainlabel)
135
136        text = text + "<br><br>" + _('If you still have trouble, '
137              '<a href="#bugreport">please file a bug report</a>.')
138        self._textlabel = QLabel(text, wordWrap=True,
139                                 textInteractionFlags=labelflags)
140        self._textlabel.linkActivated.connect(self._openlink)
141        self.layout().addWidget(self._textlabel)
142
143        bb = QDialogButtonBox(QDialogButtonBox.Close, centerButtons=True)
144        bb.rejected.connect(self.reject)
145        self.layout().addWidget(bb)
146
147    @pyqtSlot(QString)
148    def _openlink(self, ref):
149        ref = str(ref)
150        if ref == '#bugreport':
151            return BugReport(self._opts, self).exec_()
152        if ref.startswith('#edit:'):
153            from tortoisehg.hgqt import wctxactions
154            fname, lineno = ref[6:].rsplit(':', 1)
155            # A chicken-egg problem here, we need a ui to get your
156            # editor in order to repair your ui config file.
157            wctxactions.edit(self, ui.ui(), None, [fname], lineno, None)
158
159def run(ui, *pats, **opts):
160    return BugReport(opts)
161
162if __name__ == "__main__":
163    app = QApplication(sys.argv)
164    form = BugReport({'cmd':'cmd', 'error':'error'})
165    form.show()
166    app.exec_()