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>
53 class 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
99 : (KGlobal::activeComponent().isValid() ? KGlobal::activeComponent().aboutData()
100 : KGlobal::mainComponent().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 );
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)");
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);
324 void KBugReportPrivate::_k_updateUrl()
326 url =
KUrl(
"https://bugs.kde.org/enter_bug.cgi" );
327 url.addQueryItem(
"format",
"guided" );
330 QStringList list = appcombo->currentText().split(
'/');
331 url.addQueryItem(
"product", list[0] );
332 if (list.size() == 2) {
333 url.addQueryItem(
"component", list[1] );
336 url.addQueryItem(
"version", m_strVersion );
341 void 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;
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);
368 void 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);
384 void 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);
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"