~blueyed/apport/bug532944-lucid

« back to all changes in this revision

Viewing changes to qt4/apport-qt4

  • Committer: mh21 at piware
  • Date: 2007-02-07 17:50:24 UTC
  • mto: This revision was merged to the branch mainline in revision 550.
  • Revision ID: mh21@piware.de-20070207175024-1g4xvehjmqiub61z
QT4 implementation.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/python
 
2
 
 
3
'''QT4 Apport user interface.
 
4
 
 
5
Copyright (C) 2007 Michael Hofmann <mh21@piware.de>
 
6
 
 
7
This program is free software; you can redistribute it and/or modify it
 
8
under the terms of the GNU General Public License as published by the
 
9
Free Software Foundation; either version 2 of the License, or (at your
 
10
option) any later version.  See http://www.gnu.org/copyleft/gpl.html for
 
11
the full text of the license.
 
12
'''
 
13
 
 
14
# FIXME: taskbar entry, header for problem details treewidget, binary data
 
15
 
 
16
import os.path, sys, subprocess
 
17
from PyQt4.QtCore import *
 
18
from PyQt4.QtGui import *
 
19
from PyQt4 import uic
 
20
from gettext import gettext as _
 
21
import apport.ui
 
22
 
 
23
class QT4Dialog(QDialog):
 
24
    '''QT4 dialog wrapper.'''
 
25
 
 
26
    def __init__(self, ui, title, heading, text):
 
27
        QDialog.__init__(self)
 
28
 
 
29
        dialog = uic.loadUi(os.path.join(os.path.dirname(sys.argv[0]), ui), self)
 
30
 
 
31
        self.setWindowTitle (title)
 
32
        self.findChild(QLabel, 'heading').setText('<h2>%s</h2>' % heading)
 
33
        self.findChild(QLabel, 'text').setText(text)
 
34
 
 
35
    def on_buttons_clicked(self, button):
 
36
        self.actionButton = button
 
37
        if self.sender().buttonRole(button) == QDialogButtonBox.ActionRole:
 
38
            button.window().done (2)
 
39
 
 
40
    def addbutton(self, button):
 
41
        return self.findChild(QDialogButtonBox, 'buttons').addButton(
 
42
                button, QDialogButtonBox.ActionRole)
 
43
 
 
44
class QT4ErrorDialog(QT4Dialog):
 
45
    '''QT4 Error dialog wrapper.'''
 
46
 
 
47
    def __init__(self, title, heading, text, checker = None):
 
48
        QT4Dialog.__init__(self, 'error.ui', title, heading, text)
 
49
 
 
50
        self.setMaximumSize(1, 1)
 
51
        self.findChild(QLabel, 'icon').setPixmap(QMessageBox.standardIcon
 
52
                (QMessageBox.Critical))
 
53
 
 
54
        self.checker = self.findChild(QCheckBox, 'checker')
 
55
        if checker:
 
56
            self.checker.setText(checker)
 
57
        else:
 
58
            self.checker.hide()
 
59
 
 
60
    def checked(self):
 
61
        return self.checker.isChecked()
 
62
 
 
63
class QT4ProgressDialog(QT4Dialog):
 
64
    '''QT4 Progress dialog wrapper.'''
 
65
 
 
66
    def __init__(self, title, heading, text):
 
67
        QT4Dialog.__init__(self, 'progress.ui', title, heading, text)
 
68
 
 
69
        self.setMaximumSize(1, 1)
 
70
 
 
71
    def on_buttons_clicked(self, button):
 
72
        QT4Dialog.on_buttons_clicked(self, button)
 
73
        if self.sender().buttonRole(button) == QDialogButtonBox.RejectRole:
 
74
            sys.exit(0)
 
75
 
 
76
    def set(self, value = None):
 
77
        progress = self.findChild(QProgressBar, 'progress')
 
78
        if not value:
 
79
            progress.setRange(0, 0)
 
80
            progress.setValue(0)
 
81
        else:
 
82
            progress.setRange(0, 1000)
 
83
            progress.setValue(value * 1000)
 
84
 
 
85
class QT4UserInterface(apport.ui.UserInterface):
 
86
    '''QT4 UserInterface.'''
 
87
 
 
88
    def w(self, widget):
 
89
        '''Shortcut for getting a widget.'''
 
90
 
 
91
        return self.widgets.get_widget(widget)
 
92
 
 
93
    def __init__(self):
 
94
        apport.ui.UserInterface.__init__(self)
 
95
 
 
96
        self.app = QApplication([])
 
97
 
 
98
    #
 
99
    # ui_* implementation of abstract UserInterface classes
 
100
    #
 
101
 
 
102
    def ui_present_crash(self, desktop_entry):
 
103
        # adapt dialog heading and label appropriately
 
104
        if desktop_entry:
 
105
            name = desktop_entry.getName()
 
106
            heading = _('Sorry, %s closed unexpectedly.') % name
 
107
        elif self.report.has_key('ExecutablePath'):
 
108
            name = os.path.basename(self.report['ExecutablePath'])
 
109
            heading = _('Sorry, the program "%s" closed unexpectedly.') % name
 
110
        else:
 
111
            name = self.cur_package
 
112
            heading = _('Sorry, %s closed unexpectedly.') % name
 
113
 
 
114
        dialog = QT4ErrorDialog (name, heading,
 
115
                _('If you were not doing anything confidential (entering '
 
116
                'passwords or other private information), you can help to '
 
117
                'improve the application by reporting the problem.'), 
 
118
                _('&Ignore future crashes of this program version'))
 
119
 
 
120
        reportbutton = dialog.addbutton(_('&Report Problem...'))
 
121
 
 
122
        if desktop_entry and self.report.has_key('ExecutablePath') and \
 
123
            os.path.dirname(self.report['ExecutablePath']) in \
 
124
            os.environ['PATH'].split(':') and \
 
125
            subprocess.call(['pgrep', '-x',
 
126
                os.path.basename(self.report['ExecutablePath']),
 
127
                '-u', str(os.geteuid())], stdout=subprocess.PIPE) != 0:
 
128
            restartButton = dialog.addbutton(_('Restart &Program'))
 
129
 
 
130
        # show crash notification dialog
 
131
        response = dialog.exec_()
 
132
        blacklist = dialog.checked()
 
133
 
 
134
        if response == QDialog.Rejected:
 
135
            return {'action': 'cancel', 'blacklist': blacklist}
 
136
        if dialog.actionButton == reportbutton:
 
137
            return {'action': 'report', 'blacklist': blacklist}
 
138
        if dialog.actionButton == restartbutton:
 
139
            return {'action': 'restart', 'blacklist': blacklist}
 
140
        # Fallback
 
141
        return {'action': 'cancel', 'blacklist': blacklist}
 
142
 
 
143
    def ui_present_package_error(self):
 
144
        dialog = QT4ErrorDialog (self.report['Package'], 
 
145
                _('Sorry, the package "%s" failed to install or upgrade.') % 
 
146
                name,
 
147
                _('You can help the developers to fix the package by '
 
148
                    'reporting the problem.'))
 
149
 
 
150
        reportbutton = dialog.addbutton(_('&Report Problem...'))
 
151
 
 
152
        response = dialog.exec_()
 
153
 
 
154
        if response == QDialog.Rejected:
 
155
            return 'cancel'
 
156
        if dialog.actionButton == reportbutton:
 
157
            return 'report'
 
158
        # Fallback
 
159
        return 'cancel'
 
160
 
 
161
    def ui_present_kernel_error(self):
 
162
        dialog = QT4ErrorDialog (_('Kernel Error'),
 
163
                _('Sorry, the kernel encountered a serious problem'),
 
164
                _('Your system might become unstable now and might need to be '
 
165
                    'restarted.\n\nYou can help the developers to fix the '
 
166
                    'problem by reporting it.'))
 
167
 
 
168
        reportbutton = dialog.addbutton(_('&Report Problem...'))
 
169
 
 
170
        response = dialog.exec_()
 
171
 
 
172
        if response == QDialog.Rejected:
 
173
            return 'cancel'
 
174
        if dialog.actionButton == reportbutton:
 
175
            return 'report'
 
176
        # Fallback
 
177
        return 'cancel'
 
178
 
 
179
    def ui_present_report_details(self):
 
180
        # Let's get the dialog and modify it to our needs
 
181
        dialog = QT4Dialog ('bugreport.ui', 
 
182
                self.report.get('Package', 'Ubuntu').split()[0],
 
183
                _('Send problem report to the developers?'),
 
184
                _('After the problem report has been sent, please fill out '
 
185
                    'the form in the automatically opening web browser.'))
 
186
 
 
187
        sendbutton = dialog.addbutton(_('&Send'))
 
188
 
 
189
        # report contents in expander
 
190
        details = dialog.findChild (QTreeWidget, 'details')
 
191
        for key in self.report:
 
192
            keyitem = QTreeWidgetItem([key]);
 
193
            details.addTopLevelItem (keyitem)
 
194
 
 
195
            if self.report[key]:
 
196
                lines = self.report[key].splitlines()
 
197
                for line in lines:
 
198
                    QTreeWidgetItem(keyitem, [line])
 
199
                if len(lines) < 4:
 
200
                    keyitem.setExpanded(True)
 
201
            else:
 
202
                QTreeWidgetItem (keyitem, _('(binary data)'))
 
203
 
 
204
        # complete/reduced radio buttons
 
205
        if self.report.has_key('CoreDump'):
 
206
            dialog.findChild(QRadioButton, 'complete').setText(
 
207
                    _('Complete report (recommended; %s)') % 
 
208
                    self.format_filesize(self.get_complete_size()))
 
209
            dialog.findChild(QRadioButton, 'reduced').setText(
 
210
                    _('Reduced report (slow Internet connection; %s)') % 
 
211
                    self.format_filesize(self.get_reduced_size()))
 
212
        else:
 
213
            dialog.findChild(QFrame, 'options').hide()
 
214
 
 
215
        response = dialog.exec_()
 
216
 
 
217
        if response == QDialog.Rejected:
 
218
            return 'cancel'
 
219
        # Fallback
 
220
        if dialog.actionButton != sendbutton:
 
221
            return 'cancel'
 
222
        if dialog.findChild(QRadioButton, 'reduced').isChecked():
 
223
            return 'reduced'
 
224
        if dialog.findChild(QRadioButton, 'complete').isChecked():
 
225
            return 'full'
 
226
        # Fallback
 
227
        return 'undefined'
 
228
 
 
229
    def ui_info_message(self, title, text):
 
230
        QMessageBox.information (None, title, text, 
 
231
                QMessageBox.Close, QMessageBox.Close)
 
232
 
 
233
    def ui_error_message(self, title, text):
 
234
        QMessageBox.critical (None, title, text, 
 
235
                QMessageBox.Close, QMessageBox.Close)
 
236
 
 
237
    def ui_start_info_collection_progress(self):
 
238
        self.progress = QT4ProgressDialog (
 
239
                _('Collecting Problem Information'), 
 
240
                _('Collecting problem information'), 
 
241
                _('The collected information can be send to the developers to '
 
242
                    'improve the application. This might take some minutes.'))
 
243
        self.progress.set()
 
244
        self.progress.show()
 
245
 
 
246
    def ui_pulse_info_collection_progress(self):
 
247
        self.progress.set()
 
248
        QCoreApplication.processEvents()
 
249
 
 
250
    def ui_stop_info_collection_progress(self):
 
251
        self.progress.hide()
 
252
 
 
253
    def ui_start_upload_progress(self):
 
254
        '''Open a window with an definite progress bar, telling the user to
 
255
        wait while debug information is being uploaded.'''
 
256
 
 
257
        self.progress = QT4ProgressDialog (
 
258
                _('Uploading Problem Information'), 
 
259
                _('Uploading problem information'), 
 
260
                _('The collected information is sent to the bug tracking '
 
261
                    'system. This might take some minutes.'))
 
262
        self.progress.show()
 
263
 
 
264
    def ui_set_upload_progress(self, progress):
 
265
        '''Set the progress bar in the debug data upload progress
 
266
        window to the given ratio (between 0 and 1, or None for indefinite
 
267
        progress).
 
268
 
 
269
        This function is called every 100 ms.'''
 
270
 
 
271
        if progress:
 
272
            self.progress.set(progress)
 
273
        else:
 
274
            self.progress.set()
 
275
        QCoreApplication.processEvents()
 
276
 
 
277
    def ui_stop_upload_progress(self):
 
278
        '''Close debug data upload progress window.'''
 
279
 
 
280
        self.progress.hide()
 
281
 
 
282
if __name__ == '__main__':
 
283
    app = QT4UserInterface()
 
284
    app.run_argv()