You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
381 lines
16 KiB
381 lines
16 KiB
/******************************************************************* |
|
* reportassistantdialog.cpp |
|
* Copyright 2009,2010 Dario Andres Rodriguez <andresbajotierra@gmail.com> |
|
* |
|
* This program is free software; you can redistribute it and/or |
|
* modify it under the terms of the GNU General Public License as |
|
* published by the Free Software Foundation; either version 2 of |
|
* the License, or (at your option) any later version. |
|
* |
|
* This program is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU General Public License |
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
* |
|
******************************************************************/ |
|
|
|
#include "reportassistantdialog.h" |
|
|
|
#include <QCloseEvent> |
|
|
|
#include <KMessageBox> |
|
#include <KLocalizedString> |
|
#include <KConfigGroup> |
|
|
|
#include "drkonqi.h" |
|
|
|
#include "parser/backtraceparser.h" |
|
#include "debuggermanager.h" |
|
#include "backtracegenerator.h" |
|
|
|
#include "crashedapplication.h" |
|
#include "aboutbugreportingdialog.h" |
|
#include "reportassistantpages_base.h" |
|
#include "reportassistantpages_bugzilla.h" |
|
#include "reportassistantpages_bugzilla_duplicates.h" |
|
#include "reportinterface.h" |
|
|
|
static const char KDE_BUGZILLA_DESCRIPTION[] = I18N_NOOP("the KDE Bug Tracking System"); |
|
|
|
ReportAssistantDialog::ReportAssistantDialog(QWidget * parent) : |
|
KAssistantDialog(parent), |
|
m_aboutBugReportingDialog(0), |
|
m_reportInterface(new ReportInterface(this)), |
|
m_canClose(false) |
|
{ |
|
setAttribute(Qt::WA_DeleteOnClose, true); |
|
|
|
//Set window properties |
|
setWindowTitle(i18nc("@title:window","Crash Reporting Assistant")); |
|
setWindowIcon(QIcon::fromTheme(QStringLiteral("tools-report-bug"))); |
|
buttonBox()->addButton(QDialogButtonBox::Help); |
|
|
|
connect(this, &ReportAssistantDialog::currentPageChanged, this, &ReportAssistantDialog::currentPageChanged_slot); |
|
connect(button(QDialogButtonBox::Help), &QPushButton::clicked, this, &ReportAssistantDialog::showHelp); |
|
|
|
//Create the assistant pages |
|
|
|
//-Introduction Page |
|
KConfigGroup group(KSharedConfig::openConfig(), "ReportAssistant"); |
|
const bool skipIntroduction = group.readEntry("SkipIntroduction", false); |
|
|
|
if (!skipIntroduction) { |
|
IntroductionPage * m_introduction = new IntroductionPage(this); |
|
|
|
KPageWidgetItem * m_introductionPage = new KPageWidgetItem(m_introduction, |
|
QLatin1String(PAGE_INTRODUCTION_ID)); |
|
m_pageWidgetMap.insert(QLatin1String(PAGE_INTRODUCTION_ID),m_introductionPage); |
|
m_introductionPage->setHeader(i18nc("@title","Welcome to the Reporting Assistant")); |
|
m_introductionPage->setIcon(QIcon::fromTheme(QStringLiteral("tools-report-bug"))); |
|
|
|
addPage(m_introductionPage); |
|
} |
|
|
|
//-Bug Awareness Page |
|
BugAwarenessPage * m_awareness = new BugAwarenessPage(this); |
|
connectSignals(m_awareness); |
|
|
|
KPageWidgetItem * m_awarenessPage = new KPageWidgetItem(m_awareness, |
|
QLatin1String(PAGE_AWARENESS_ID)); |
|
m_pageWidgetMap.insert(QLatin1String(PAGE_AWARENESS_ID),m_awarenessPage); |
|
m_awarenessPage->setHeader(i18nc("@title","What do you know about the crash?")); |
|
m_awarenessPage->setIcon(QIcon::fromTheme(QStringLiteral("checkbox"))); |
|
|
|
//-Crash Information Page |
|
CrashInformationPage * m_backtrace = new CrashInformationPage(this); |
|
connectSignals(m_backtrace); |
|
|
|
KPageWidgetItem * m_backtracePage = new KPageWidgetItem(m_backtrace, |
|
QLatin1String(PAGE_CRASHINFORMATION_ID)); |
|
m_pageWidgetMap.insert(QLatin1String(PAGE_CRASHINFORMATION_ID),m_backtracePage); |
|
m_backtracePage->setHeader(i18nc("@title","Fetching the Backtrace (Automatic Crash Information)")); |
|
m_backtracePage->setIcon(QIcon::fromTheme(QStringLiteral("run-build"))); |
|
|
|
//-Results Page |
|
ConclusionPage * m_conclusions = new ConclusionPage(this); |
|
connectSignals(m_conclusions); |
|
|
|
KPageWidgetItem * m_conclusionsPage = new KPageWidgetItem(m_conclusions, |
|
QLatin1String(PAGE_CONCLUSIONS_ID)); |
|
m_pageWidgetMap.insert(QLatin1String(PAGE_CONCLUSIONS_ID),m_conclusionsPage); |
|
m_conclusionsPage->setHeader(i18nc("@title","Results of the Analyzed Crash Details")); |
|
m_conclusionsPage->setIcon(QIcon::fromTheme(QStringLiteral("dialog-information"))); |
|
connect(m_conclusions, &ConclusionPage::finished, this, &ReportAssistantDialog::assistantFinished); |
|
|
|
//-Bugzilla Login |
|
BugzillaLoginPage * m_bugzillaLogin = new BugzillaLoginPage(this); |
|
connectSignals(m_bugzillaLogin); |
|
|
|
KPageWidgetItem * m_bugzillaLoginPage = new KPageWidgetItem(m_bugzillaLogin, |
|
QLatin1String(PAGE_BZLOGIN_ID)); |
|
m_pageWidgetMap.insert(QLatin1String(PAGE_BZLOGIN_ID),m_bugzillaLoginPage); |
|
m_bugzillaLoginPage->setHeader(i18nc("@title", "Login into %1", i18n(KDE_BUGZILLA_DESCRIPTION))); |
|
m_bugzillaLoginPage->setIcon(QIcon::fromTheme(QStringLiteral("user-identity"))); |
|
connect(m_bugzillaLogin, &BugzillaLoginPage::loggedTurnToNextPage, this, &ReportAssistantDialog::loginFinished); |
|
|
|
//-Bugzilla duplicates |
|
BugzillaDuplicatesPage * m_bugzillaDuplicates = new BugzillaDuplicatesPage(this); |
|
connectSignals(m_bugzillaDuplicates); |
|
|
|
KPageWidgetItem * m_bugzillaDuplicatesPage = new KPageWidgetItem(m_bugzillaDuplicates, |
|
QLatin1String(PAGE_BZDUPLICATES_ID)); |
|
m_pageWidgetMap.insert(QLatin1String(PAGE_BZDUPLICATES_ID),m_bugzillaDuplicatesPage); |
|
m_bugzillaDuplicatesPage->setHeader(i18nc("@title","Look for Possible Duplicate Reports")); |
|
m_bugzillaDuplicatesPage->setIcon(QIcon::fromTheme(QStringLiteral("repository"))); |
|
|
|
//-Bugzilla information |
|
BugzillaInformationPage * m_bugzillaInformation = new BugzillaInformationPage(this); |
|
connectSignals(m_bugzillaInformation); |
|
|
|
KPageWidgetItem * m_bugzillaInformationPage = new KPageWidgetItem(m_bugzillaInformation, |
|
QLatin1String(PAGE_BZDETAILS_ID)); |
|
m_pageWidgetMap.insert(QLatin1String(PAGE_BZDETAILS_ID),m_bugzillaInformationPage); |
|
m_bugzillaInformationPage->setHeader(i18nc("@title","Enter the Details about the Crash")); |
|
m_bugzillaInformationPage->setIcon(QIcon::fromTheme(QStringLiteral("document-edit"))); |
|
|
|
//-Bugzilla Report Preview |
|
BugzillaPreviewPage * m_bugzillaPreview = new BugzillaPreviewPage(this); |
|
|
|
KPageWidgetItem * m_bugzillaPreviewPage = new KPageWidgetItem(m_bugzillaPreview, |
|
QLatin1String(PAGE_BZPREVIEW_ID)); |
|
m_pageWidgetMap.insert(QLatin1String(PAGE_BZPREVIEW_ID),m_bugzillaPreviewPage); |
|
m_bugzillaPreviewPage->setHeader(i18nc("@title","Preview the Report")); |
|
m_bugzillaPreviewPage->setIcon(QIcon::fromTheme(QStringLiteral("document-preview"))); |
|
|
|
//-Bugzilla commit |
|
BugzillaSendPage * m_bugzillaSend = new BugzillaSendPage(this); |
|
|
|
KPageWidgetItem * m_bugzillaSendPage = new KPageWidgetItem(m_bugzillaSend, |
|
QLatin1String(PAGE_BZSEND_ID)); |
|
m_pageWidgetMap.insert(QLatin1String(PAGE_BZSEND_ID),m_bugzillaSendPage); |
|
m_bugzillaSendPage->setHeader(i18nc("@title","Sending the Crash Report")); |
|
m_bugzillaSendPage->setIcon(QIcon::fromTheme(QStringLiteral("applications-internet"))); |
|
connect(m_bugzillaSend, &BugzillaSendPage::finished, this, &ReportAssistantDialog::assistantFinished); |
|
|
|
//TODO Remember to keep the pages ordered |
|
addPage(m_awarenessPage); |
|
addPage(m_backtracePage); |
|
addPage(m_conclusionsPage); |
|
addPage(m_bugzillaLoginPage); |
|
addPage(m_bugzillaDuplicatesPage); |
|
addPage(m_bugzillaInformationPage); |
|
addPage(m_bugzillaPreviewPage); |
|
addPage(m_bugzillaSendPage); |
|
|
|
setMinimumSize(QSize(600, 400)); |
|
resize(minimumSize()); |
|
} |
|
|
|
ReportAssistantDialog::~ReportAssistantDialog() |
|
{ |
|
} |
|
|
|
void ReportAssistantDialog::connectSignals(ReportAssistantPage * page) |
|
{ |
|
//React to the changes in the assistant pages |
|
connect(page, &ReportAssistantPage::completeChanged, |
|
this, &ReportAssistantDialog::completeChanged); |
|
} |
|
|
|
void ReportAssistantDialog::currentPageChanged_slot(KPageWidgetItem * current , KPageWidgetItem * before) |
|
{ |
|
//Page changed |
|
buttonBox()->button(QDialogButtonBox::Cancel)->setEnabled(true); |
|
m_canClose = false; |
|
|
|
//Save data of the previous page |
|
if (before) { |
|
ReportAssistantPage* beforePage = dynamic_cast<ReportAssistantPage*>(before->widget()); |
|
beforePage->aboutToHide(); |
|
} |
|
|
|
//Load data of the current(new) page |
|
if (current) { |
|
ReportAssistantPage* currentPage = dynamic_cast<ReportAssistantPage*>(current->widget()); |
|
nextButton()->setEnabled(currentPage->isComplete()); |
|
currentPage->aboutToShow(); |
|
} |
|
|
|
//If the current page is the last one, disable all the buttons until the bug is sent |
|
if (current->name() == QLatin1String(PAGE_BZSEND_ID)) { |
|
nextButton()->setEnabled(false); |
|
backButton()->setEnabled(false); |
|
finishButton()->setEnabled(false); |
|
} |
|
} |
|
|
|
void ReportAssistantDialog::completeChanged(ReportAssistantPage* page, bool isComplete) |
|
{ |
|
if (page == dynamic_cast<ReportAssistantPage*>(currentPage()->widget())) { |
|
nextButton()->setEnabled(isComplete); |
|
} |
|
} |
|
|
|
void ReportAssistantDialog::assistantFinished(bool showBack) |
|
{ |
|
//The assistant finished: allow the user to close the dialog normally |
|
|
|
nextButton()->setEnabled(false); |
|
backButton()->setEnabled(showBack); |
|
finishButton()->setEnabled(true); |
|
buttonBox()->button(QDialogButtonBox::Cancel)->setEnabled(false); |
|
|
|
m_canClose = true; |
|
} |
|
|
|
void ReportAssistantDialog::loginFinished() |
|
{ |
|
//Bugzilla login finished, go to the next page |
|
if (currentPage()->name() == QLatin1String(PAGE_BZLOGIN_ID)) { |
|
next(); |
|
} |
|
} |
|
|
|
void ReportAssistantDialog::showHelp() |
|
{ |
|
//Show the bug reporting guide dialog |
|
if (!m_aboutBugReportingDialog) { |
|
m_aboutBugReportingDialog = new AboutBugReportingDialog(); |
|
} |
|
m_aboutBugReportingDialog->show(); |
|
m_aboutBugReportingDialog->raise(); |
|
m_aboutBugReportingDialog->activateWindow(); |
|
m_aboutBugReportingDialog->showSection(QLatin1String(PAGE_HELP_BEGIN_ID)); |
|
m_aboutBugReportingDialog->showSection(currentPage()->name()); |
|
} |
|
|
|
//Override KAssistantDialog "next" page implementation |
|
void ReportAssistantDialog::next() |
|
{ |
|
//Allow the widget to Ask a question to the user before changing the page |
|
ReportAssistantPage * page = dynamic_cast<ReportAssistantPage*>(currentPage()->widget()); |
|
if (page) { |
|
if (!page->showNextPage()) { |
|
return; |
|
} |
|
} |
|
|
|
const QString name = currentPage()->name(); |
|
|
|
//If the information the user can provide is not useful, skip the backtrace page |
|
if (name == QLatin1String(PAGE_AWARENESS_ID)) |
|
{ |
|
//Force save settings in the current page |
|
page->aboutToHide(); |
|
|
|
if (!(m_reportInterface->isBugAwarenessPageDataUseful())) |
|
{ |
|
setCurrentPage(m_pageWidgetMap.value(QLatin1String(PAGE_CONCLUSIONS_ID))); |
|
return; |
|
} |
|
} else if (name == QLatin1String(PAGE_CRASHINFORMATION_ID)){ |
|
//Force save settings in current page |
|
page->aboutToHide(); |
|
|
|
//If the crash is worth reporting and it is BKO, skip the Conclusions page |
|
if (m_reportInterface->isWorthReporting() && |
|
DrKonqi::crashedApplication()->bugReportAddress().isKdeBugzilla()) |
|
{ |
|
setCurrentPage(m_pageWidgetMap.value(QLatin1String(PAGE_BZLOGIN_ID))); |
|
return; |
|
} |
|
} else if (name == QLatin1String(PAGE_BZDUPLICATES_ID)) { |
|
//a duplicate has been found, yet the report is not being attached |
|
if (m_reportInterface->duplicateId() && !m_reportInterface->attachToBugNumber()) { |
|
setCurrentPage(m_pageWidgetMap.value(QLatin1String(PAGE_CONCLUSIONS_ID))); |
|
return; |
|
} |
|
} |
|
|
|
KAssistantDialog::next(); |
|
} |
|
|
|
//Override KAssistantDialog "back"(previous) page implementation |
|
//It has to mirror the custom next() implementation |
|
void ReportAssistantDialog::back() |
|
{ |
|
if (currentPage()->name() == QLatin1String(PAGE_CONCLUSIONS_ID)) |
|
{ |
|
if (m_reportInterface->duplicateId() && !m_reportInterface->attachToBugNumber()) { |
|
setCurrentPage(m_pageWidgetMap.value(QLatin1String(PAGE_BZDUPLICATES_ID))); |
|
return; |
|
} |
|
if (!(m_reportInterface->isBugAwarenessPageDataUseful())) |
|
{ |
|
setCurrentPage(m_pageWidgetMap.value(QLatin1String(PAGE_AWARENESS_ID))); |
|
return; |
|
} |
|
} |
|
|
|
if (currentPage()->name() == QLatin1String(PAGE_BZLOGIN_ID)) |
|
{ |
|
if (m_reportInterface->isWorthReporting() && |
|
DrKonqi::crashedApplication()->bugReportAddress().isKdeBugzilla()) |
|
{ |
|
setCurrentPage(m_pageWidgetMap.value(QLatin1String(PAGE_CRASHINFORMATION_ID))); |
|
return; |
|
} |
|
} |
|
|
|
KAssistantDialog::back(); |
|
} |
|
|
|
void ReportAssistantDialog::reject() |
|
{ |
|
close(); |
|
} |
|
|
|
void ReportAssistantDialog::closeEvent(QCloseEvent * event) |
|
{ |
|
//Handle the close event |
|
if (!m_canClose) { |
|
//If the assistant didn't finished yet, offer the user the possibilities to |
|
//Close, Cancel, or Save the bug report and Close" |
|
|
|
KGuiItem closeItem = KStandardGuiItem::close(); |
|
closeItem.setText(i18nc("@action:button", "Close the assistant")); |
|
|
|
KGuiItem keepOpenItem = KStandardGuiItem::cancel(); |
|
keepOpenItem.setText(i18nc("@action:button", "Cancel")); |
|
|
|
BacktraceParser::Usefulness use = |
|
DrKonqi::debuggerManager()->backtraceGenerator()->parser()->backtraceUsefulness(); |
|
if (use == BacktraceParser::ReallyUseful || use == BacktraceParser::MayBeUseful) { |
|
//Backtrace is still useful, let the user save it. |
|
KGuiItem saveBacktraceItem = KStandardGuiItem::save(); |
|
saveBacktraceItem.setText(i18nc("@action:button", "Save information and close")); |
|
|
|
int ret = KMessageBox::questionYesNoCancel(this, |
|
xi18nc("@info","Do you really want to close the bug reporting assistant? " |
|
"<note>The crash information is still valid, so " |
|
"you can save the report before closing if you want.</note>"), |
|
i18nc("@title:window","Close the Assistant"), |
|
closeItem, saveBacktraceItem, keepOpenItem, QString(), KMessageBox::Dangerous); |
|
if(ret == KMessageBox::Yes) |
|
{ |
|
event->accept(); |
|
} else if (ret == KMessageBox::No) { |
|
//Save backtrace and accept event (dialog will be closed) |
|
DrKonqi::saveReport(reportInterface()->generateReportFullText(false)); |
|
event->accept(); |
|
} else { |
|
event->ignore(); |
|
} |
|
} else { |
|
if (KMessageBox::questionYesNo(this, i18nc("@info","Do you really want to close the bug " |
|
"reporting assistant?"), |
|
i18nc("@title:window","Close the Assistant"), |
|
closeItem, keepOpenItem, QString(), KMessageBox::Dangerous) |
|
== KMessageBox::Yes) { |
|
event->accept(); |
|
} else { |
|
event->ignore(); |
|
} |
|
} |
|
} else { |
|
event->accept(); |
|
} |
|
}
|
|
|