KXmlGui

kbugreport.cpp
1 /*
2  This file is part of the KDE project
3  SPDX-FileCopyrightText: 1999 David Faure <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #include "kbugreport.h"
9 
10 #include <QCloseEvent>
11 #include <QDesktopServices>
12 #include <QDialogButtonBox>
13 #include <QFile>
14 #include <QGridLayout>
15 #include <QGroupBox>
16 #include <QHBoxLayout>
17 #include <QLabel>
18 #include <QLineEdit>
19 #include <QLocale>
20 #include <QProcess>
21 #include <QPushButton>
22 #include <QRadioButton>
23 #include <QStandardPaths>
24 #include <QTextEdit>
25 #include <QUrl>
26 #include <QUrlQuery>
27 
28 #include <KAboutData>
29 #include <KConfig>
30 #include <KEMailSettings>
31 #include <KLocalizedString>
32 #include <KMessageBox>
33 #include <KMessageDialog>
34 #include <KTitleWidget>
35 
36 #include "../kxmlgui_version.h"
37 #include "config-xmlgui.h"
38 #include "debug.h"
39 #include "systeminformation_p.h"
40 
41 #include <array>
42 
43 class KBugReportPrivate
44 {
45 public:
46  KBugReportPrivate(KBugReport *qq)
47  : q(qq)
48  , m_aboutData(KAboutData::applicationData())
49  {
50  }
51 
52  enum BugDestination {
53  BugsKdeOrg,
54  CustomEmail,
55  CustomUrl,
56  };
57 
58  // Calls kcmshell5 System/email
59  void slotConfigureEmail();
60 
61  // Sets the "From" field from the e-mail configuration.
62  // Called at creation time, but also after "Configure email" is closed.
63  void slotSetFrom();
64 
65  // Update the url to match the current OS, selected app, etc
66  void updateUrl();
67 
68  KBugReport *const q;
69  QProcess *m_process = nullptr;
70  KAboutData m_aboutData;
71 
72  QTextEdit *m_lineedit = nullptr;
73  QLineEdit *m_subject = nullptr;
74  QLabel *m_from = nullptr;
75  QLabel *m_version = nullptr;
76  QString m_strVersion;
77  QGroupBox *m_bgSeverity = nullptr;
78  QPushButton *m_configureEmail = nullptr;
79 
80  QString lastError;
81  QString kde_version;
82  QString appname;
83  QString os;
84  QUrl url;
85  QList<QRadioButton *> severityButtons;
86  int currentSeverity() const
87  {
88  for (int i = 0; i < severityButtons.count(); i++) {
89  if (severityButtons[i]->isChecked()) {
90  return i;
91  }
92  }
93  return -1;
94  }
95  BugDestination bugDestination;
96 };
97 
98 KBugReport::KBugReport(const KAboutData &aboutData, QWidget *_parent)
99  : QDialog(_parent)
100  , d(new KBugReportPrivate(this))
101 {
102  setWindowTitle(i18nc("@title:window", "Submit Bug Report"));
103 
104  QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
108 
109  d->m_aboutData = aboutData;
110  d->m_process = nullptr;
111  d->bugDestination = KBugReportPrivate::CustomEmail;
112 
113  const QString bugAddress = d->m_aboutData.bugAddress();
114  if (bugAddress == QLatin1String("[email protected]")) {
115  // This is a core KDE application -> redirect to the web form
116  d->bugDestination = KBugReportPrivate::BugsKdeOrg;
117  } else if (!QUrl(bugAddress).scheme().isEmpty()) {
118  // The bug reporting address is a URL -> redirect to that
119  d->bugDestination = KBugReportPrivate::CustomUrl;
120  }
121 
122  if (d->bugDestination != KBugReportPrivate::CustomEmail) {
124  }
125 
126  QLabel *tmpLabel;
127  QVBoxLayout *lay = new QVBoxLayout(this);
128 
129  KTitleWidget *title = new KTitleWidget(this);
130  title->setText(i18n("Submit Bug Report"));
131  title->setIconSize(QSize(32, 32));
132  title->setIcon(QIcon::fromTheme(QStringLiteral("tools-report-bug")));
133  lay->addWidget(title);
134 
135  QGridLayout *glay = new QGridLayout();
136  lay->addLayout(glay);
137 
138  int row = 0;
139 
140  if (d->bugDestination == KBugReportPrivate::CustomEmail) {
141  // From
142  QString qwtstr = i18n("Your email address. If incorrect, use the Configure Email button to change it");
143  tmpLabel = new QLabel(i18nc("Email sender address", "From:"), this);
144  glay->addWidget(tmpLabel, row, 0);
145  tmpLabel->setWhatsThis(qwtstr);
146  d->m_from = new QLabel(this);
147  glay->addWidget(d->m_from, row, 1);
148  d->m_from->setWhatsThis(qwtstr);
149 
150  // Configure email button
151  d->m_configureEmail = new QPushButton(i18nc("@action:button", "Configure Email..."), this);
152  connect(d->m_configureEmail, &QPushButton::clicked, this, [this]() {
153  d->slotConfigureEmail();
154  });
155  glay->addWidget(d->m_configureEmail, 0, 2, 3, 1, Qt::AlignTop | Qt::AlignRight);
156 
157  // To
158  qwtstr = i18n("The email address this bug report is sent to.");
159  tmpLabel = new QLabel(i18nc("Email receiver address", "To:"), this);
160  glay->addWidget(tmpLabel, ++row, 0);
161  tmpLabel->setWhatsThis(qwtstr);
162  tmpLabel = new QLabel(d->m_aboutData.bugAddress(), this);
164  glay->addWidget(tmpLabel, row, 1);
165  tmpLabel->setWhatsThis(qwtstr);
166 
168  KGuiItem(i18nc("@action:button", "&Send"),
169  QStringLiteral("mail-send"),
170  i18nc("@info:tooltip", "Send bug report."),
171  i18nc("@info:whatsthis", "Send this bug report to %1.", d->m_aboutData.bugAddress())));
172  row++;
173  } else {
174  d->m_configureEmail = nullptr;
175  d->m_from = nullptr;
176  }
177 
178  // Program name
179  QString qwtstr =
180  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");
181  tmpLabel = new QLabel(i18n("Application: "), this);
182  glay->addWidget(tmpLabel, row, 0);
183  tmpLabel->setWhatsThis(qwtstr);
184  QLabel *appLabel = new QLabel(this);
185  d->appname = d->m_aboutData.productName();
186  appLabel->setText(d->appname);
187  glay->addWidget(appLabel, row, 1);
188  tmpLabel->setWhatsThis(qwtstr);
189 
190  // Version
191  qwtstr = i18n("The version of this application - please make sure that no newer version is available before sending a bug report");
192  tmpLabel = new QLabel(i18n("Version:"), this);
193  glay->addWidget(tmpLabel, ++row, 0);
194  tmpLabel->setWhatsThis(qwtstr);
195  d->m_strVersion = d->m_aboutData.version();
196  if (d->m_strVersion.isEmpty()) {
197  d->m_strVersion = i18n("no version set (programmer error)");
198  }
199  d->kde_version = QStringLiteral(KXMLGUI_VERSION_STRING) + QLatin1String(", ") + QStringLiteral(XMLGUI_DISTRIBUTION_TEXT);
200  if (d->bugDestination != KBugReportPrivate::BugsKdeOrg) {
201  d->m_strVersion += QLatin1Char(' ') + d->kde_version;
202  }
203  d->m_version = new QLabel(d->m_strVersion, this);
204  d->m_version->setTextInteractionFlags(Qt::TextBrowserInteraction);
205  // glay->addWidget( d->m_version, row, 1 );
206  glay->addWidget(d->m_version, row, 1, 1, 2);
207  d->m_version->setWhatsThis(qwtstr);
208 
209  tmpLabel = new QLabel(i18n("OS:"), this);
210  glay->addWidget(tmpLabel, ++row, 0);
211 
212 #ifdef Q_OS_WINDOWS
213  d->os = i18nc("%1 is the operating system name, e.g. 'Windows 10', %2 is the CPU architecture, e.g. 'x86_64'",
214  "%1 (%2)",
217 #else
218  if (QSysInfo::productVersion() != QLatin1String("unknown")) {
219  d->os = i18nc(
220  "%1 is the operating system name, e.g. 'Fedora Linux', %2 is the operating system version, e.g. '35', %3 is the CPU architecture, e.g. 'x86_64'",
221  "%1 %2 (%3)",
225  } else {
226  d->os = i18nc("%1 is the operating system name, e.g. 'Fedora Linux', %2 is the CPU architecture, e.g. 'x86_64'",
227  "%1 (%2)",
230  }
231 #endif
232 
233  tmpLabel = new QLabel(d->os, this);
235  glay->addWidget(tmpLabel, row, 1, 1, 2);
236 
237  if (d->bugDestination == KBugReportPrivate::CustomEmail) {
238  // Severity
239  d->m_bgSeverity = new QGroupBox(i18nc("@title:group", "Se&verity"), this);
240 
241  struct SeverityData {
242  QString name;
243  QString text;
244  };
245  const std::array<SeverityData, 5> severityData = {{
246  {QStringLiteral("critical"), i18nc("bug severity", "Critical")},
247  {QStringLiteral("grave"), i18nc("bug severity", "Grave")},
248  {QStringLiteral("normal"), i18nc("bug severity", "Normal")},
249  {QStringLiteral("wishlist"), i18nc("bug severity", "Wishlist")},
250  {QStringLiteral("i18n"), i18nc("bug severity", "Translation")},
251  }};
252 
253  QHBoxLayout *severityLayout = new QHBoxLayout(d->m_bgSeverity);
254  for (auto &severityDatum : severityData) {
255  // Store the severity string as the name
256  QRadioButton *rb = new QRadioButton(severityDatum.text, d->m_bgSeverity);
257  rb->setObjectName(severityDatum.name);
258  d->severityButtons.append(rb);
259  severityLayout->addWidget(rb);
260  }
261  d->severityButtons[2]->setChecked(true); // default : "normal"
262 
263  lay->addWidget(d->m_bgSeverity);
264 
265  // Subject
266  QHBoxLayout *hlay = new QHBoxLayout();
267  lay->addItem(hlay);
268  tmpLabel = new QLabel(i18n("S&ubject: "), this);
269  hlay->addWidget(tmpLabel);
270  d->m_subject = new QLineEdit(this);
271  d->m_subject->setClearButtonEnabled(true);
272  d->m_subject->setFocus();
273  tmpLabel->setBuddy(d->m_subject);
274  hlay->addWidget(d->m_subject);
275 
276  QString text = i18n(
277  "Enter the text (in English if possible) that you wish to submit for the "
278  "bug report.\n"
279  "If you press \"Send\", a mail message will be sent to the maintainer of "
280  "this program.\n");
281  QLabel *label = new QLabel(this);
282 
283  label->setText(text);
284  lay->addWidget(label);
285 
286  // The multiline-edit
287  d->m_lineedit = new QTextEdit(this);
288  d->m_lineedit->setMinimumHeight(180); // make it big
289  d->m_lineedit->setWordWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
290  d->m_lineedit->setLineWrapMode(QTextEdit::WidgetWidth);
291  lay->addWidget(d->m_lineedit, 10 /*stretch*/);
292 
293  d->slotSetFrom();
294  } else {
295  // Point to the web form
296 
297  QString text;
298  if (d->bugDestination == KBugReportPrivate::BugsKdeOrg) {
299  text = i18n(
300  "<qt>To submit a bug report, click on the button below. This will open a web browser "
301  "window on <a href=\"https://bugs.kde.org\">https://bugs.kde.org</a> where you will find "
302  "a form to fill in. The information displayed above will be transferred to that server.</qt>");
303  d->updateUrl();
304  } else {
305  text = i18n(
306  "<qt>To submit a bug report, click on the button below. This will open a web browser "
307  "window on <a href=\"%1\">%2</a>.</qt>",
308  bugAddress,
309  bugAddress);
310  d->url = QUrl(bugAddress);
311  }
312 
313  lay->addSpacing(10);
314  QLabel *label = new QLabel(text, this);
315  label->setOpenExternalLinks(true);
316  label->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard);
317  label->setWordWrap(true);
318  lay->addWidget(label);
319  lay->addSpacing(10);
320 
321  QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
322  if (d->bugDestination == KBugReportPrivate::BugsKdeOrg) {
323  okButton->setText(i18nc("@action:button", "&Launch Bug Report Wizard"));
324  } else {
325  okButton->setText(i18nc("@action:button", "&Submit Bug Report"));
326  }
327  okButton->setIcon(QIcon::fromTheme(QStringLiteral("tools-report-bug")));
328  }
329 
330  lay->addWidget(buttonBox);
331  setMinimumHeight(sizeHint().height() + 20); // WORKAROUND: prevent "cropped" qcombobox
332 }
333 
334 KBugReport::~KBugReport() = default;
335 
337 {
338  if (d->bugDestination == KBugReportPrivate::CustomEmail) {
339  return d->m_lineedit->toPlainText();
340  } else {
341  return QString();
342  }
343 }
344 
345 void KBugReport::setMessageBody(const QString &messageBody)
346 {
347  if (d->bugDestination == KBugReportPrivate::CustomEmail) {
348  d->m_lineedit->setPlainText(messageBody);
349  }
350 }
351 
352 void KBugReportPrivate::updateUrl()
353 {
354  url = QUrl(QStringLiteral("https://bugs.kde.org/enter_bug.cgi"));
355  QUrlQuery query;
356  query.addQueryItem(QStringLiteral("format"), QStringLiteral("guided")); // use the guided form
357 
358  // the string format is product/component, where component is optional
359  QStringList list = appname.split(QLatin1Char('/'));
360  query.addQueryItem(QStringLiteral("product"), list[0]);
361  if (list.size() == 2) {
362  query.addQueryItem(QStringLiteral("component"), list[1]);
363  }
364 
365  query.addQueryItem(QStringLiteral("version"), m_strVersion);
366  url.setQuery(query);
367 
368  // TODO: guess and fill OS(sys_os) and Platform(rep_platform) fields
369 }
370 
371 void KBugReportPrivate::slotConfigureEmail()
372 {
373  if (m_process) {
374  return;
375  }
376 
377  const QString exec = QStandardPaths::findExecutable(QStringLiteral("kcmshell5"));
378  if (exec.isEmpty()) {
379  const QString msg = i18nc("The second arg is 'kde-cli-tools' which is the package that contains kcmshell5 (the first arg)",
380  "Could not find <application>%1</application> executable (usually it's part of the \"%2\" package).",
381  QStringLiteral("kcmshell5"),
382  QStringLiteral("kde-cli-tools"));
383  auto *dlg = new KMessageDialog(KMessageDialog::Error, msg, q);
384  dlg->setAttribute(Qt::WA_DeleteOnClose);
385  dlg->setModal(true);
386  dlg->show();
387  return;
388  }
389 
390  m_process = new QProcess;
391  QObject::connect(m_process, &QProcess::finished, q, [this]() {
392  slotSetFrom();
393  });
394  m_process->start(exec, QStringList{QStringLiteral("kcm_users")});
395  if (!m_process->waitForStarted()) {
396  // qCDebug(DEBUG_KXMLGUI) << "Couldn't start kcmshell5..";
397  delete m_process;
398  m_process = nullptr;
399  return;
400  }
401  m_configureEmail->setEnabled(false);
402 }
403 
404 void KBugReportPrivate::slotSetFrom()
405 {
406  delete m_process;
407  m_process = nullptr;
408  m_configureEmail->setEnabled(true);
409 
410  KEMailSettings emailSettings;
411  QString fromaddr = emailSettings.getSetting(KEMailSettings::EmailAddress);
412  if (fromaddr.isEmpty()) {
413  fromaddr = SystemInformation::userName();
414  } else {
415  QString name = emailSettings.getSetting(KEMailSettings::RealName);
416  if (!name.isEmpty()) {
417  fromaddr = name + QLatin1String(" <") + fromaddr + QLatin1Char('>');
418  }
419  }
420  m_from->setText(fromaddr);
421 }
422 
424 {
425  if (d->bugDestination != KBugReportPrivate::CustomEmail) {
427  return;
428  }
429 
430  if (d->m_lineedit->toPlainText().isEmpty() || d->m_subject->text().isEmpty()) {
431  QString msg = i18n(
432  "You must specify both a subject and a description "
433  "before the report can be sent.");
434  KMessageBox::error(this, msg);
435  return;
436  }
437 
438  switch (d->currentSeverity()) {
439  case 0: // critical
441  i18n("<p>You chose the severity <b>Critical</b>. "
442  "Please note that this severity is intended only for bugs that:</p>"
443  "<ul><li>break unrelated software on the system (or the whole system)</li>"
444  "<li>cause serious data loss</li>"
445  "<li>introduce a security hole on the system where the affected package is installed</li></ul>\n"
446  "<p>Does the bug you are reporting cause any of the above damage? "
447  "If it does not, please select a lower severity. Thank you.</p>"),
448  QString(),
452  return;
453  }
454  break;
455  case 1: // grave
457  this,
458  i18n("<p>You chose the severity <b>Grave</b>. "
459  "Please note that this severity is intended only for bugs that:</p>"
460  "<ul><li>make the package in question unusable or mostly so</li>"
461  "<li>cause data loss</li>"
462  "<li>introduce a security hole allowing access to the accounts of users who use the affected package</li></ul>\n"
463  "<p>Does the bug you are reporting cause any of the above damage? "
464  "If it does not, please select a lower severity. Thank you.</p>"),
465  QString(),
469  return;
470  }
471  break;
472  default:
473  break;
474  }
475  if (!sendBugReport()) {
476  QString msg = i18n(
477  "Unable to send the bug report.\n"
478  "Please submit a bug report manually....\n"
479  "See https://bugs.kde.org/ for instructions.");
480  KMessageBox::error(this, msg + QLatin1String("\n\n") + d->lastError);
481  return;
482  }
483 
484  KMessageBox::information(this, i18n("Bug report sent, thank you for your input."));
485  QDialog::accept();
486 }
487 
488 void KBugReport::closeEvent(QCloseEvent *e)
489 {
490  if (d->bugDestination == KBugReportPrivate::CustomEmail && ((d->m_lineedit->toPlainText().length() > 0) || d->m_subject->isModified())) {
491  int rc = KMessageBox::warningTwoActions(this,
492  i18n("Close and discard\nedited message?"),
493  i18nc("@title:window", "Close Message"),
496  if (rc == KMessageBox::SecondaryAction) {
497  e->ignore();
498  return;
499  }
500  }
502 }
503 
505 {
506  // qCDebug(DEBUG_KXMLGUI) << d->severityButtons[d->currentSeverity()]->objectName();
507  // Prepend the pseudo-headers to the contents of the mail
508  QString severity = d->severityButtons[d->currentSeverity()]->objectName();
509  QString appname = d->appname;
510  QString os = QStringLiteral("OS: %1 (%2)\n").arg(QStringLiteral(XMLGUI_COMPILING_OS), QStringLiteral(XMLGUI_DISTRIBUTION_TEXT));
511  QString bodyText;
512  /* for(int i = 0; i < m_lineedit->numLines(); i++)
513  {
514  QString line = m_lineedit->textLine(i);
515  if (!line.endsWith("\n"))
516  line += '\n';
517  bodyText += line;
518  }
519  */
520  bodyText = d->m_lineedit->toPlainText();
521  if (bodyText.length() > 0) {
522  if (bodyText[bodyText.length() - 1] != QLatin1Char('\n')) {
523  bodyText += QLatin1Char('\n');
524  }
525  }
526  if (severity == QLatin1String("i18n") && QLocale().language() != QLocale::system().language()) {
527  // Case 1 : i18n bug
528  QString package = QLatin1String("i18n_") + QLocale::languageToString(QLocale().language());
529  package.replace(QLatin1Char('_'), QLatin1Char('-'));
530  /* clang-format off */
531  return QLatin1String("Package: ") + package
532  + QLatin1String("\nApplication: ") + appname
533  + QLatin1String("\nVersion: ") + d->m_strVersion // not really i18n's version, so better here IMHO
534  + QLatin1Char('\n') + os
535  + QLatin1Char('\n') + bodyText;
536  /* clang-format on */
537  } else {
538  appname.replace(QLatin1Char('_'), QLatin1Char('-'));
539  // Case 2 : normal bug
540  /* clang-format off */
541  return QLatin1String("Package: ") + appname
542  + QLatin1String("\nVersion: ") + d->m_strVersion
543  + QLatin1String("\nSeverity: ") + severity
544  + QLatin1Char('\n') + os
545  + QLatin1Char('\n') + bodyText;
546  /* clang-format on */
547  }
548 }
549 
551 {
552  QString recipient = d->m_aboutData.bugAddress();
553  if (recipient.isEmpty()) {
554  recipient = QStringLiteral("[email protected]");
555  }
556 
557  QString command = QStandardPaths::findExecutable(QStringLiteral("ksendbugmail"));
558  if (command.isEmpty()) {
559  command = QFile::decodeName(CMAKE_INSTALL_PREFIX "/" KDE_INSTALL_LIBEXECDIR_KF "/ksendbugmail");
560  }
561 
562  QProcess proc;
563  QStringList args;
564  args << QStringLiteral("--subject") << d->m_subject->text() << QStringLiteral("--recipient") << recipient;
565  proc.start(command, args);
566  // qCDebug(DEBUG_KXMLGUI) << command << args;
567  if (!proc.waitForStarted()) {
568  qCCritical(DEBUG_KXMLGUI) << "Unable to open a pipe to " << command;
569  return false;
570  }
571  proc.write(text().toUtf8());
572  proc.closeWriteChannel();
573 
574  proc.waitForFinished();
575  // qCDebug(DEBUG_KXMLGUI) << "kbugreport: sendbugmail exit, status " << proc.exitStatus() << " code " << proc.exitCode();
576 
577  QByteArray line;
578  if (proc.exitStatus() == QProcess::NormalExit && proc.exitCode() != 0) {
579  // XXX not stderr?
580  while (!proc.atEnd()) {
581  line = proc.readLine();
582  }
583  d->lastError = QString::fromUtf8(line);
584  return false;
585  }
586  return true;
587 }
588 
589 #include "moc_kbugreport.cpp"
void start(const QString &program, const QStringList &arguments, QIODevice::OpenMode mode)
AlignTop
void setWhatsThis(const QString &)
void setText(const QString &)
QString fromUtf8(const char *str, int size)
virtual void reject()
bool waitForFinished(int msecs)
void setBuddy(QWidget *buddy)
QStringList split(const QString &sep, QString::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
int count(const T &value) const const
WrapAtWordBoundaryOrAnywhere
void setIconSize(const QSize &iconSize)
void clicked(bool checked)
QIcon fromTheme(const QString &name)
QString prettyProductName()
QString getSetting(KEMailSettings::Setting s) const
bool openUrl(const QUrl &url)
void setTextInteractionFlags(Qt::TextInteractionFlags flags)
virtual void closeEvent(QCloseEvent *e) override
void finished(int exitCode)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void setStandardButtons(QDialogButtonBox::StandardButtons buttons)
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
KGuiItem close()
QString findExecutable(const QString &executableName, const QStringList &paths)
KGuiItem cancel()
KSERVICE_EXPORT KService::List query(FilterFunc filterFunc)
QLocale system()
int size() const const
void accept() override
OK has been clicked.
Definition: kbugreport.cpp:423
TextBrowserInteraction
static void assign(QPushButton *button, const KGuiItem &item)
QString text() const
A complete copy of the bug report.
Definition: kbugreport.cpp:504
QString i18n(const char *text, const TYPE &arg...)
void setIcon(const QIcon &icon, ImageAlignment alignment=ImageRight)
QProcess::ExitStatus exitStatus() const const
bool isEmpty() const const
int length() const const
bool waitForStarted(int msecs)
void setWindowTitle(const QString &)
void setMessageBody(const QString &messageBody)
Sets the message body of the bug report.
Definition: kbugreport.cpp:345
virtual void accept()
ButtonCode warningTwoActions(QWidget *parent, const QString &text, const QString &title, const KGuiItem &primaryAction, const KGuiItem &secondaryAction, const QString &dontAskAgainName=QString(), Options options=Options(Notify|Dangerous))
void setText(const QString &text, MessageType type)
QString productVersion()
ButtonCode questionTwoActions(QWidget *parent, const QString &text, const QString &title, const KGuiItem &primaryAction, const KGuiItem &secondaryAction, const QString &dontAskAgainName=QString(), Options options=Notify)
void setEnabled(bool)
qint64 readLine(char *data, qint64 maxSize)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
QString & replace(int position, int n, QChar after)
void setQuery(const QString &query, QUrl::ParsingMode mode)
void setMinimumHeight(int minh)
void setIcon(const QIcon &icon)
bool sendBugReport()
Attempt to e-mail the bug report.
Definition: kbugreport.cpp:550
QString messageBody() const
The message body of the bug report.
Definition: kbugreport.cpp:336
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
QPushButton * button(QDialogButtonBox::StandardButton which) const const
QString currentCpuArchitecture()
void setObjectName(const QString &name)
QString name(StandardShortcut id)
void ignore()
KGuiItem cont()
QString i18nc(const char *context, const char *text, const TYPE &arg...)
void addWidget(QWidget *widget, int row, int column, Qt::Alignment alignment)
A dialog box for sending bug reports.
Definition: kbugreport.h:33
void addLayout(QLayout *layout, int stretch)
void information(QWidget *parent, const QString &text, const QString &title=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
virtual void addItem(QLayoutItem *item) override
void addSpacing(int size)
~KBugReport() override
Destructor.
KBugReport(const KAboutData &aboutData, QWidget *parent=nullptr)
Creates a bug-report dialog.
Definition: kbugreport.cpp:98
void setText(const QString &text)
WA_DeleteOnClose
KGuiItem discard()
void closeWriteChannel()
virtual bool atEnd() const const override
int exitCode() const const
qint64 write(const char *data, qint64 maxSize)
virtual QSize sizeHint() const const override
QString decodeName(const QByteArray &localFileName)
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Thu Sep 28 2023 04:02:35 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.