22#include <QtCore/QProcess>
23#include <QtCore/QCoreApplication>
24#include <QtGui/QPushButton>
25#include <QtGui/QLayout>
26#include <QtGui/QRadioButton>
27#include <QtGui/QGroupBox>
28#include <QtGui/QCloseEvent>
46#include <sys/utsname.h>
49#include "kdeversion.h"
51#include <config-compiler.h>
53class KBugReportPrivate {
57 void _k_slotConfigureEmail();
58 void _k_slotSetFrom();
59 void _k_appChanged(
int);
81 int currentSeverity() {
82 for (
int i=0;i<severityButtons.count();i++)
83 if (severityButtons[i]->isChecked())
return i;
90 :
KDialog( _parent ), d( new KBugReportPrivate(this) )
98 d->m_aboutData = aboutData ? aboutData
103 d->submitBugWeb =
false;
105 if ( d->m_aboutData->bugAddress() == QLatin1String(
"submit@bugs.kde.org") )
108 d->submitBugWeb =
true;
113 QVBoxLayout * lay =
new QVBoxLayout( parent);
118 lay->addWidget( title );
120 QGridLayout *glay =
new QGridLayout();
121 lay->addLayout(glay);
125 if ( !d->submitBugWeb )
128 QString qwtstr =
i18n(
"Your email address. If incorrect, use the Configure Email button to change it" );
129 tmpLabel =
new QLabel(
i18nc(
"Email sender address",
"From:"), parent );
130 glay->addWidget( tmpLabel, row,0 );
131 tmpLabel->setWhatsThis(qwtstr );
132 d->m_from =
new QLabel( parent );
133 glay->addWidget( d->m_from, row, 1 );
134 d->m_from->setWhatsThis(qwtstr );
140 connect( d->m_configureEmail, SIGNAL(clicked()),
this,
141 SLOT(_k_slotConfigureEmail()) );
142 glay->addWidget( d->m_configureEmail, 0, 2, 3, 1, Qt::AlignTop|Qt::AlignRight );
145 qwtstr =
i18n(
"The email address this bug report is sent to." );
146 tmpLabel =
new QLabel(
i18nc(
"Email receiver address",
"To:"), parent );
147 glay->addWidget( tmpLabel, ++row,0 );
148 tmpLabel->setWhatsThis(qwtstr );
149 tmpLabel =
new QLabel( d->m_aboutData->bugAddress(), parent );
150 tmpLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
151 glay->addWidget( tmpLabel, row, 1 );
152 tmpLabel->setWhatsThis(qwtstr );
155 i18n(
"Send this bug report to %1." , d->m_aboutData->bugAddress() ) ) );
160 d->m_configureEmail = 0;
165 QString qwtstr =
i18n(
"The application for which you wish to submit a bug report - if incorrect, please use the Report Bug menu item of the correct application" );
166 tmpLabel =
new QLabel(
i18n(
"Application: "), parent );
167 glay->addWidget( tmpLabel, row, 0 );
168 tmpLabel->setWhatsThis(qwtstr );
169 d->appcombo =
new KComboBox(
false, parent );
170 d->appcombo->setWhatsThis(qwtstr );
171 QStringList packageList;
173 packageList << QString::fromLatin1(
packages[c]);
174 d->appcombo->addItems(packageList);
175 connect(d->appcombo, SIGNAL(activated(
int)), SLOT(_k_appChanged(
int)));
176 d->appname = d->m_aboutData
177 ? d->m_aboutData->productName()
178 : qApp->applicationName() ;
179 glay->addWidget( d->appcombo, row, 1 );
181 for (; index < d->appcombo->count(); index++) {
182 if (d->appcombo->itemText(index) == d->appname) {
186 if (index == d->appcombo->count()) {
187 d->appcombo->addItem(d->appname);
189 d->appcombo->setCurrentIndex(index);
191 tmpLabel->setWhatsThis(qwtstr );
194 qwtstr =
i18n(
"The version of this application - please make sure that no newer version is available before sending a bug report" );
195 tmpLabel =
new QLabel(
i18n(
"Version:"), parent );
196 glay->addWidget( tmpLabel, ++row, 0 );
197 tmpLabel->setWhatsThis(qwtstr );
199 d->m_strVersion = d->m_aboutData->version();
201 d->m_strVersion =
i18n(
"no version set (programmer error)");
202 d->kde_version = QString::fromLatin1( KDE_VERSION_STRING );
203 d->kde_version +=
", " + QString::fromLatin1( KDE_DISTRIBUTION_TEXT );
204 if ( !d->submitBugWeb )
205 d->m_strVersion +=
' ' + d->kde_version;
206 d->m_version =
new QLabel( d->m_strVersion, parent );
207 d->m_version->setTextInteractionFlags(Qt::TextBrowserInteraction);
209 glay->addWidget( d->m_version, row, 1, 1, 2 );
210 d->m_version->setWhatsThis(qwtstr );
213 glay->addWidget( tmpLabel, ++row, 0 );
215 struct utsname unameBuf;
217 d->os = QString::fromLatin1( unameBuf.sysname ) +
218 " (" + QString::fromLatin1( unameBuf.machine ) +
") "
219 "release " + QString::fromLatin1( unameBuf.release );
221 tmpLabel =
new QLabel(d->os, parent);
222 tmpLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
223 glay->addWidget( tmpLabel, row, 1, 1, 2 );
225 tmpLabel =
new QLabel(
i18n(
"Compiler:"), parent);
226 glay->addWidget( tmpLabel, ++row, 0 );
227 tmpLabel =
new QLabel(QString::fromLatin1(KDE_COMPILER_VERSION), parent);
228 tmpLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
229 glay->addWidget( tmpLabel, row, 1, 1, 2 );
231 if ( !d->submitBugWeb )
234 d->m_bgSeverity =
new QGroupBox(
i18n(
"Se&verity"), parent );
235 static const char *
const sevNames[5] = {
"critical",
"grave",
"normal",
"wishlist",
"i18n" };
236 const QString sevTexts[5] = {
i18n(
"Critical"),
i18n(
"Grave"),
i18nc(
"normal severity",
"Normal"),
i18n(
"Wishlist"),
i18n(
"Translation") };
237 QHBoxLayout *severityLayout=
new QHBoxLayout(d->m_bgSeverity);
238 for (
int i = 0 ; i < 5 ; i++ )
241 QRadioButton *rb =
new QRadioButton( sevTexts[i], d->m_bgSeverity);
242 rb->setObjectName(sevNames[i] );
243 d->severityButtons.append(rb);
244 severityLayout->addWidget(rb);
245 if (i==2) rb->setChecked(
true);
248 lay->addWidget( d->m_bgSeverity );
251 QHBoxLayout * hlay =
new QHBoxLayout();
253 tmpLabel =
new QLabel(
i18n(
"S&ubject: "), parent );
254 hlay->addWidget( tmpLabel );
256 d->m_subject->setClearButtonShown(
true);
257 d->m_subject->setFocus();
258 tmpLabel->setBuddy( d->m_subject );
259 hlay->addWidget( d->m_subject );
261 QString
text =
i18n(
"Enter the text (in English if possible) that you wish to submit for the "
263 "If you press \"Send\", a mail message will be sent to the maintainer of "
267 label->setText( text );
268 lay->addWidget( label );
272 d->m_lineedit->setMinimumHeight( 180 );
273 d->m_lineedit->setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
274 d->m_lineedit->setLineWrapMode(QTextEdit::WidgetWidth);
275 d->m_lineedit->setCheckSpellingEnabled(
true);
276 d->m_lineedit->setSpellCheckingLanguage(
"en");
277 lay->addWidget( d->m_lineedit, 10 );
284 QString
text =
i18n(
"<qt>To submit a bug report, click on the button below. This will open a web browser "
285 "window on <a href=\"http://bugs.kde.org\">http://bugs.kde.org</a> where you will find "
286 "a form to fill in. The information displayed above will be transferred to that server.</qt>");
288 label->setOpenExternalLinks(
true );
289 label->setTextInteractionFlags( Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard );
290 label->setWordWrap(
true );
291 lay->addWidget( label );
294 d->appcombo->setFocus();
301 parent->setMinimumHeight( parent->sizeHint().height() + 20 );
312 if ( !d->submitBugWeb )
313 return d->m_lineedit->toPlainText();
320 if ( !d->submitBugWeb )
321 d->m_lineedit->setPlainText(messageBody);
324void KBugReportPrivate::_k_updateUrl()
326 url =
KUrl(
"https://bugs.kde.org/enter_bug.cgi" );
330 QStringList list = appcombo->currentText().split(
'/');
332 if (list.size() == 2) {
341void KBugReportPrivate::_k_appChanged(
int i)
343 QString appName = appcombo->itemText(i);
344 int index = appName.indexOf(
'/' );
346 appName = appName.left( index );
347 kDebug() <<
"appName " << appName;
349 QString strDisplayVersion;
350 if (appname == appName && m_aboutData) {
351 m_strVersion = m_aboutData->
version();
352 strDisplayVersion = m_strVersion;
354 m_strVersion = QLatin1String(
"unknown");
355 strDisplayVersion =
i18nc(
"unknown program name",
"unknown");
358 if ( !submitBugWeb ) {
359 m_strVersion +=
' ' + kde_version;
360 strDisplayVersion +=
' ' + kde_version;
363 m_version->setText(strDisplayVersion);
368void KBugReportPrivate::_k_slotConfigureEmail()
370 if (m_process)
return;
372 QObject::connect( m_process, SIGNAL(finished(
int,QProcess::ExitStatus)), q, SLOT(_k_slotSetFrom()) );
373 m_process->start( QString::fromLatin1(
"kcmshell4"), QStringList() << QString::fromLatin1(
"kcm_useraccount") );
374 if ( !m_process->waitForStarted() )
376 kDebug() <<
"Couldn't start kcmshell4..";
381 m_configureEmail->setEnabled(
false);
384void KBugReportPrivate::_k_slotSetFrom()
388 m_configureEmail->setEnabled(
true);
391 KConfig emailConf( QString::fromLatin1(
"emaildefaults") );
395 QString profile = QString::fromLatin1(
"PROFILE_");
396 profile += cg.readEntry( QString::fromLatin1(
"Profile"),
397 QString::fromLatin1(
"Default") );
400 QString fromaddr = profileGrp.readEntry(
"EmailAddress" );
401 if (fromaddr.isEmpty()) {
403 p = getpwuid(getuid());
404 fromaddr = QString::fromLatin1(p->pw_name);
406 QString
name = profileGrp.readEntry(
"FullName" );
408 fromaddr =
name + QString::fromLatin1(
" <") + fromaddr + QString::fromLatin1(
">");
410 m_from->setText( fromaddr );
415 if ( d->submitBugWeb ) {
420 if( d->m_lineedit->toPlainText().isEmpty() ||
421 d->m_subject->text().isEmpty() )
423 QString msg =
i18n(
"You must specify both a subject and a description "
424 "before the report can be sent.");
429 switch ( d->currentSeverity())
433 "<p>You chose the severity <b>Critical</b>. "
434 "Please note that this severity is intended only for bugs that:</p>"
435 "<ul><li>break unrelated software on the system (or the whole system)</li>"
436 "<li>cause serious data loss</li>"
437 "<li>introduce a security hole on the system where the affected package is installed</li></ul>\n"
438 "<p>Does the bug you are reporting cause any of the above damage? "
444 "<p>You chose the severity <b>Grave</b>. "
445 "Please note that this severity is intended only for bugs that:</p>"
446 "<ul><li>make the package in question unusable or mostly so</li>"
447 "<li>cause data loss</li>"
448 "<li>introduce a security hole allowing access to the accounts of users who use the affected package</li></ul>\n"
449 "<p>Does the bug you are reporting cause any of the above damage? "
458 QString msg =
i18n(
"Unable to send the bug report.\n"
459 "Please submit a bug report manually....\n"
460 "See http://bugs.kde.org/ for instructions.");
466 i18n(
"Bug report sent, thank you for your input."));
472 if( !d->submitBugWeb && ( (d->m_lineedit->toPlainText().length()>0) || d->m_subject->isModified() ) )
475 i18n(
"Close and discard\nedited message?" ),
489 kDebug() << d->severityButtons[d->currentSeverity()]->objectName();
491 QString severity = d->severityButtons[d->currentSeverity()]->objectName();
492 QString appname = d->appcombo->currentText();
493 QString os = QString::fromLatin1(
"OS: %1 (%2)\n").
494 arg(KDE_COMPILING_OS).
495 arg(KDE_DISTRIBUTION_TEXT);
505 bodyText=d->m_lineedit->toPlainText();
506 if (bodyText.length()>0)
507 if (bodyText[bodyText.length()-1]!=
'\n') bodyText+=
'\n';
510 QString
package = QString::fromLatin1("i18n_%1").arg(KGlobal::locale()->language());
511 package = package.replace('_', '-');
512 return QString::fromLatin1(
"Package: %1").arg(package) +
513 QString::fromLatin1(
"\n"
516 "Version: %2\n").arg(appname).arg(d->m_strVersion)+
517 os+QString::fromLatin1(
"\n")+bodyText;
519 appname = appname.replace(
'_',
'-');
521 return QString::fromLatin1(
"Package: %1\n"
524 .arg(appname).arg(d->m_strVersion).arg(severity)+
525 QString::fromLatin1(
"Compiler: %1\n").arg(KDE_COMPILER_VERSION)+
526 os+QString::fromLatin1(
"\n")+bodyText;
532 QString recipient ( d->m_aboutData ?
533 d->m_aboutData->bugAddress() :
534 QString::fromLatin1(
"submit@bugs.kde.org") );
538 if (command.isEmpty())
543 args <<
"--subject" << d->m_subject->text() <<
"--recipient" << recipient;
544 proc.start( command, args );
546 if (!proc.waitForStarted())
548 kError() <<
"Unable to open a pipe to " << command << endl;
551 proc.write(
text().toUtf8() );
552 proc.closeWriteChannel();
554 proc.waitForFinished();
555 kDebug() <<
"kbugreport: sendbugmail exit, status " << proc.exitStatus() <<
" code " << proc.exitCode();
558 if (proc.exitStatus() == QProcess::NormalExit && proc.exitCode() != 0) {
560 while (!proc.atEnd())
561 line = proc.readLine();
562 d->lastError = QString::fromUtf8( line );
569#include "kbugreport.moc"
A dialog box for sending bug reports.
virtual ~KBugReport()
Destructor.
QString text() const
"Configure email" has been clicked - this calls kcmshell4 System/email
QString messageBody() const
The message body of the bug report.
bool sendBugReport()
Attempt to e-mail the bug report.
void setMessageBody(const QString &messageBody)
Sets the message body of the bug report.
KBugReport(QWidget *parent=0L, bool modal=true, const KAboutData *aboutData=0L)
Creates a bug-report dialog.
virtual void closeEvent(QCloseEvent *e)
Detects when a dialog is being closed from the window manager controls.
virtual void accept()
OK has been clicked.
const KAboutData * aboutData() const
A dialog base class with standard buttons and predefined layouts.
void setButtonIcon(ButtonCode id, const KIcon &icon)
Sets the icon of any button.
void setButtonGuiItem(ButtonCode id, const KGuiItem &item)
Sets the KGuiItem directly for the button instead of using 3 methods to set the text,...
void setMainWidget(QWidget *widget)
Sets the main widget of the dialog.
virtual void closeEvent(QCloseEvent *e)
Detects when a dialog is being closed from the window manager controls.
void setButtons(ButtonCodes buttonMask)
Creates (or recreates) the button box and all the buttons in it.
@ Ok
Show Ok button. (this button accept()s the dialog; result set to QDialog::Accepted)
@ Cancel
Show Cancel-button. (this button reject()s the dialog; result set to QDialog::Rejected)
void setButtonText(ButtonCode id, const QString &text)
Sets the text of any button.
virtual void setCaption(const QString &caption)
Make a KDE compliant caption.
An abstract class for GUI data such as ToolTip and Icon.
A wrapper around QIcon that provides KDE icon features.
An enhanced QLineEdit widget for inputting text.
static QString defaultLanguage()
static void error(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Notify)
Display an "Error" dialog.
static void information(QWidget *parent, const QString &text, const QString &caption=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
Display an "Information" dialog.
static int questionYesNo(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonYes=KStandardGuiItem::yes(), const KGuiItem &buttonNo=KStandardGuiItem::no(), const QString &dontAskAgainName=QString(), Options options=Notify)
Display a simple "question" dialog.
static int warningYesNo(QWidget *parent, const QString &text, const QString &caption=QString(), const KGuiItem &buttonYes=KStandardGuiItem::yes(), const KGuiItem &buttonNo=KStandardGuiItem::no(), const QString &dontAskAgainName=QString(), Options options=Options(Notify|Dangerous))
Display a "warning" dialog.
static QString findExe(const QString &appname, const QString &pathstr=QString(), SearchOptions options=NoSearchOptions)
static QString locate(const char *type, const QString &filename, const KComponentData &cData=KGlobal::mainComponent())
void addQueryItem(const QString &_item, const QString &_value)
const char *const packages[]
QString i18n(const char *text)
QString i18nc(const char *ctxt, const char *text)
const KComponentData & mainComponent()
KComponentData activeComponent()
const char * name(StandardAction id)
This will return the internal name of a given standard action.
KGuiItem cont()
Returns the 'Continue' gui item.
KGuiItem cancel()
Returns the 'Cancel' gui item.
KGuiItem discard()
Returns the 'Discard' gui item.
KGuiItem close()
Returns the 'Close' gui item.