1 | /* |
2 | This file is part of the KDE project |
3 | SPDX-FileCopyrightText: 1999 David Faure <faure@kde.org> |
4 | |
5 | SPDX-License-Identifier: LGPL-2.0-or-later |
6 | */ |
7 | |
8 | #include "kbugreport.h" |
9 | |
10 | #include <QDesktopServices> |
11 | #include <QDialogButtonBox> |
12 | #include <QHBoxLayout> |
13 | #include <QLabel> |
14 | #include <QPushButton> |
15 | #include <QUrl> |
16 | #include <QUrlQuery> |
17 | |
18 | #include <KAboutData> |
19 | #include <KConfig> |
20 | #include <KLocalizedString> |
21 | #include <KMessageBox> |
22 | #include <KMessageDialog> |
23 | #include <KTitleWidget> |
24 | |
25 | #include "config-xmlgui.h" |
26 | #include "systeminformation_p.h" |
27 | #include <kxmlgui_version.h> |
28 | |
29 | class KBugReportPrivate |
30 | { |
31 | public: |
32 | KBugReportPrivate(KBugReport *qq) |
33 | : q(qq) |
34 | { |
35 | } |
36 | |
37 | enum BugDestination { |
38 | BugsKdeOrg, |
39 | CustomUrl, |
40 | }; |
41 | |
42 | // Update the url to match the current OS, selected app, etc |
43 | void updateUrl(); |
44 | |
45 | KBugReport *const q; |
46 | |
47 | QLabel *m_version = nullptr; |
48 | QString m_strVersion; |
49 | |
50 | QString lastError; |
51 | QString kde_version; |
52 | QString appname; |
53 | QString os; |
54 | QUrl url; |
55 | BugDestination bugDestination = KBugReportPrivate::CustomUrl; |
56 | }; |
57 | |
58 | KBugReport::KBugReport(const KAboutData &aboutData, QWidget *_parent) |
59 | : QDialog(_parent) |
60 | , d(new KBugReportPrivate(this)) |
61 | { |
62 | setWindowTitle(i18nc("@title:window" , "Submit Bug Report" )); |
63 | |
64 | QDialogButtonBox *buttonBox = new QDialogButtonBox(this); |
65 | buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); |
66 | connect(sender: buttonBox, signal: &QDialogButtonBox::accepted, context: this, slot: &QDialog::accept); |
67 | connect(sender: buttonBox, signal: &QDialogButtonBox::rejected, context: this, slot: &QDialog::reject); |
68 | |
69 | const QString bugAddress = aboutData.bugAddress(); |
70 | if (bugAddress == QLatin1String("submit@bugs.kde.org" )) { |
71 | // This is a core KDE application -> redirect to the web form |
72 | d->bugDestination = KBugReportPrivate::BugsKdeOrg; |
73 | } else if (!QUrl(bugAddress).scheme().isEmpty()) { |
74 | // The bug reporting address is a URL -> redirect to that |
75 | d->bugDestination = KBugReportPrivate::CustomUrl; |
76 | } |
77 | |
78 | KGuiItem::assign(button: buttonBox->button(which: QDialogButtonBox::Cancel), item: KStandardGuiItem::close()); |
79 | |
80 | QLabel *tmpLabel; |
81 | QVBoxLayout *lay = new QVBoxLayout(this); |
82 | |
83 | KTitleWidget *title = new KTitleWidget(this); |
84 | title->setText(i18n("Submit Bug Report" )); |
85 | title->setIconSize(QSize(32, 32)); |
86 | title->setIcon(icon: QIcon::fromTheme(QStringLiteral("tools-report-bug" ))); |
87 | lay->addWidget(title); |
88 | |
89 | QGridLayout *glay = new QGridLayout(); |
90 | lay->addLayout(layout: glay); |
91 | |
92 | int row = 0; |
93 | |
94 | // Program name |
95 | QString qwtstr = |
96 | 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" ); |
97 | tmpLabel = new QLabel(i18n("Application: " ), this); |
98 | glay->addWidget(tmpLabel, row, column: 0); |
99 | tmpLabel->setWhatsThis(qwtstr); |
100 | QLabel *appLabel = new QLabel(this); |
101 | d->appname = aboutData.productName(); |
102 | appLabel->setText(d->appname); |
103 | glay->addWidget(appLabel, row, column: 1); |
104 | tmpLabel->setWhatsThis(qwtstr); |
105 | |
106 | // Version |
107 | qwtstr = i18n("The version of this application - please make sure that no newer version is available before sending a bug report" ); |
108 | tmpLabel = new QLabel(i18n("Version:" ), this); |
109 | glay->addWidget(tmpLabel, row: ++row, column: 0); |
110 | tmpLabel->setWhatsThis(qwtstr); |
111 | d->m_strVersion = aboutData.version(); |
112 | if (d->m_strVersion.isEmpty()) { |
113 | d->m_strVersion = i18n("no version set (programmer error)" ); |
114 | } |
115 | d->kde_version = QStringLiteral(KXMLGUI_VERSION_STRING); |
116 | if (d->bugDestination != KBugReportPrivate::BugsKdeOrg) { |
117 | d->m_strVersion += QLatin1Char(' ') + d->kde_version; |
118 | } |
119 | d->m_version = new QLabel(d->m_strVersion, this); |
120 | d->m_version->setTextInteractionFlags(Qt::TextBrowserInteraction); |
121 | // glay->addWidget( d->m_version, row, 1 ); |
122 | glay->addWidget(d->m_version, row, column: 1, rowSpan: 1, columnSpan: 2); |
123 | d->m_version->setWhatsThis(qwtstr); |
124 | |
125 | tmpLabel = new QLabel(i18n("OS:" ), this); |
126 | glay->addWidget(tmpLabel, row: ++row, column: 0); |
127 | |
128 | #ifdef Q_OS_WINDOWS |
129 | d->os = i18nc("%1 is the operating system name, e.g. 'Windows 10', %2 is the CPU architecture, e.g. 'x86_64'" , |
130 | "%1 (%2)" , |
131 | QSysInfo::prettyProductName(), |
132 | QSysInfo::currentCpuArchitecture()); |
133 | #else |
134 | if (QSysInfo::productVersion() != QLatin1String("unknown" )) { |
135 | d->os = i18nc( |
136 | "%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'" , |
137 | "%1 %2 (%3)" , |
138 | QSysInfo::prettyProductName(), |
139 | QSysInfo::productVersion(), |
140 | QSysInfo::currentCpuArchitecture()); |
141 | } else { |
142 | d->os = i18nc("%1 is the operating system name, e.g. 'Fedora Linux', %2 is the CPU architecture, e.g. 'x86_64'" , |
143 | "%1 (%2)" , |
144 | QSysInfo::prettyProductName(), |
145 | QSysInfo::currentCpuArchitecture()); |
146 | } |
147 | #endif |
148 | |
149 | tmpLabel = new QLabel(d->os, this); |
150 | tmpLabel->setTextInteractionFlags(Qt::TextBrowserInteraction); |
151 | glay->addWidget(tmpLabel, row, column: 1, rowSpan: 1, columnSpan: 2); |
152 | // Point to the web form |
153 | |
154 | QString text; |
155 | if (d->bugDestination == KBugReportPrivate::BugsKdeOrg) { |
156 | text = i18n( |
157 | "<qt>To submit a bug report, click on the button below. This will open a web browser " |
158 | "window on <a href=\"https://bugs.kde.org\">https://bugs.kde.org</a> where you will find " |
159 | "a form to fill in. The information displayed above will be transferred to that server.</qt>" ); |
160 | d->updateUrl(); |
161 | } else { |
162 | text = i18n( |
163 | "<qt>To submit a bug report, click on the button below. This will open a web browser " |
164 | "window on <a href=\"%1\">%2</a>.</qt>" , |
165 | bugAddress, |
166 | bugAddress); |
167 | d->url = QUrl(bugAddress); |
168 | } |
169 | |
170 | lay->addSpacing(size: 10); |
171 | QLabel *label = new QLabel(text, this); |
172 | label->setOpenExternalLinks(true); |
173 | label->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::LinksAccessibleByKeyboard); |
174 | label->setWordWrap(true); |
175 | lay->addWidget(label); |
176 | lay->addSpacing(size: 10); |
177 | |
178 | QPushButton *okButton = buttonBox->button(which: QDialogButtonBox::Ok); |
179 | if (d->bugDestination == KBugReportPrivate::BugsKdeOrg) { |
180 | okButton->setText(i18nc("@action:button" , "&Launch Bug Report Wizard" )); |
181 | } else { |
182 | okButton->setText(i18nc("@action:button" , "&Submit Bug Report" )); |
183 | } |
184 | okButton->setIcon(QIcon::fromTheme(QStringLiteral("tools-report-bug" ))); |
185 | |
186 | lay->addWidget(buttonBox); |
187 | setMinimumHeight(sizeHint().height() + 20); // WORKAROUND: prevent "cropped" qcombobox |
188 | } |
189 | |
190 | KBugReport::~KBugReport() = default; |
191 | |
192 | void KBugReportPrivate::updateUrl() |
193 | { |
194 | url = QUrl(QStringLiteral("https://bugs.kde.org/enter_bug.cgi" )); |
195 | QUrlQuery query; |
196 | query.addQueryItem(QStringLiteral("format" ), QStringLiteral("guided" )); // use the guided form |
197 | |
198 | // the string format is product/component, where component is optional |
199 | QStringList list = appname.split(sep: QLatin1Char('/')); |
200 | query.addQueryItem(QStringLiteral("product" ), value: list[0]); |
201 | if (list.size() == 2) { |
202 | query.addQueryItem(QStringLiteral("component" ), value: list[1]); |
203 | } |
204 | |
205 | query.addQueryItem(QStringLiteral("version" ), value: m_strVersion); |
206 | url.setQuery(query); |
207 | |
208 | // TODO: guess and fill OS(sys_os) and Platform(rep_platform) fields |
209 | } |
210 | |
211 | void KBugReport::accept() |
212 | { |
213 | QDesktopServices::openUrl(url: d->url); |
214 | QDialog::accept(); |
215 | } |
216 | |
217 | #include "moc_kbugreport.cpp" |
218 | |