2
* Copyright (c) 2013 Mark Liversedge (liversedge@gmail.com)
4
* This program is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License as published by the Free
6
* Software Foundation; either version 2 of the License, or (at your option)
9
* This program is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14
* You should have received a copy of the GNU General Public License along
15
* with this program; if not, write to the Free Software Foundation, Inc., 51
16
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
#include "GcCrashDialog.h"
21
#include "GcUpgrade.h"
26
#include "MetricAggregator.h"
29
#define GCC_VERSION QString("%1.%2.%3").arg(__GNUC__).arg(__GNUC_MINOR__).arg(__GNUC_PATCHLEVEL__)
31
#ifdef GC_HAVE_QWTPLOT3D
32
#include "qwt3d_global.h"
36
#include "ICalendar.h"
43
#ifdef GC_HAVE_LIBOAUTH
55
GcCrashDialog::GcCrashDialog(QDir home) : QDialog(NULL, Qt::Dialog), home(home)
57
setAttribute(Qt::WA_DeleteOnClose, true); // caller must delete me, once they've extracted the name
58
setWindowTitle(QString(tr("%1 Crash Recovery").arg(home.dirName())));
60
QVBoxLayout *layout = new QVBoxLayout(this);
62
QHBoxLayout *toprow = new QHBoxLayout;
64
QPushButton *critical = new QPushButton(style()->standardIcon(QStyle::SP_MessageBoxCritical), "", this);
65
critical->setFixedSize(128,128);
66
critical->setFlat(true);
67
critical->setIconSize(QSize(120,120));
68
critical->setAutoFillBackground(false);
69
critical->setFocusPolicy(Qt::NoFocus);
71
QLabel *header = new QLabel(this);
72
header->setWordWrap(true);
73
header->setTextFormat(Qt::RichText);
74
header->setText(tr("<b>GoldenCheetah appears to have PREVIOUSLY crashed for this athlete. "
75
"</b><br><br>The report below gives some diagnostic information "
76
"that will be useful to the developers. Feel free to post this with a "
77
"short description of what was occurring when the crash happened to the "
78
"<href a=\"https://groups.google.com/forum/?fromgroups=#!forum/golden-cheetah-users\">"
79
"GoldenCheetah forums</href><br>"
80
"<b><br>We respect privacy - this log does NOT contain ids, passwords or personal information.</b><br>"
81
"<b><br>When this dialog is closed the athlete will be opened.</b>"));
83
toprow->addWidget(critical);
84
toprow->addWidget(header);
85
layout->addLayout(toprow);
87
report = new QWebView(this);
88
report->setContentsMargins(0,0,0,0);
89
report->page()->view()->setContentsMargins(0,0,0,0);
90
report->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
91
report->setAcceptDrops(false);
93
QFont defaultFont; // mainwindow sets up the defaults.. we need to apply
94
report->settings()->setFontSize(QWebSettings::DefaultFontSize, defaultFont.pointSize()+1);
95
report->settings()->setFontFamily(QWebSettings::StandardFont, defaultFont.family());
97
layout->addWidget(report);
99
QHBoxLayout *lastRow = new QHBoxLayout;
100
QPushButton *saveAsButton = new QPushButton(tr("Save Crash Report..."), this);
101
connect(saveAsButton, SIGNAL(clicked()), this, SLOT(saveAs()));
102
QPushButton *OKButton = new QPushButton(tr("Close"), this);
103
connect(OKButton, SIGNAL(clicked()), this, SLOT(accept()));
105
lastRow->addWidget(saveAsButton);
106
lastRow->addStretch();
107
lastRow->addWidget(OKButton);
108
layout->addLayout(lastRow);
113
QString GcCrashDialog::versionHTML()
127
os = QString("Mac OS X 10.%1").arg(QSysInfo::MacintoshVersion - 2);
128
if (QSysInfo::MacintoshVersion == QSysInfo::MV_SNOWLEOPARD)
129
os += " Snow Leopard";
130
else if (QSysInfo::MacintoshVersion == QSysInfo::MV_LION)
132
else if (QSysInfo::MacintoshVersion == 10)
133
os += " Mountain Lion";
137
// -- SCHEMA VERSION ----
138
QString schemaVersion = QString("%1").arg(DBSchemaVersion);
141
QString srmio = "none";
148
QString d2xx = "none";
155
QString oauth = "none";
157
#ifdef GC_HAVE_LIBOAUTH
158
oauth = LIBOAUTH_VERSION;
162
QString qwtplot3d = "none";
164
#ifdef GC_HAVE_QWTPLOT3D
165
qwtplot3d = QString::number(QWT3D_MAJOR_VERSION) + "."
166
+ QString::number(QWT3D_MINOR_VERSION) + "."
167
+ QString::number(QWT3D_PATCH_VERSION);
171
QString kml = "none";
178
QString ical = "none";
185
QString usbxpress = "none";
186
#ifdef GC_HAVE_USBXPRESS
191
QString libusb = "none";
192
#ifdef GC_HAVE_LIBUSB
197
QString vlc = "none";
203
QString clucene = "none";
204
#ifdef GC_HAVE_LUCENE
205
clucene = _CL_VERSION;
208
// -- LION SUPPORT ----
210
QString lionSupport = "no";
217
QString wfapi = WFApi::getInstance()->apiVersion();
219
QString wfapi = QString("none");
222
QString gc_version = tr(
223
"<p>Build date: %1 %2"
231
.arg(GcUpgrade::version())
235
.arg("(developer build)")
240
QString lib_version = tr(
242
"<tr><td colspan=\"2\">QT</td><td>%1</td></tr>"
243
"<tr><td colspan=\"2\">QWT</td><td>%2</td></tr>"
244
"<tr><td colspan=\"2\">GCC</td><td>%3</td></tr>"
245
"<tr><td colspan=\"2\">SRMIO</td><td>%4</td></tr>"
246
"<tr><td colspan=\"2\">OAUTH</td><td>%5</td></tr>"
247
"<tr><td colspan=\"2\">D2XX</td><td>%6</td></tr>"
248
"<tr><td colspan=\"2\">QWTPLOT3D</td><td>%7</td></tr>"
249
"<tr><td colspan=\"2\">KML</td><td>%8</td></tr>"
250
"<tr><td colspan=\"2\">ICAL</td><td>%9</td></tr>"
251
"<tr><td colspan=\"2\">USBXPRESS</td><td>%10</td></tr>"
252
"<tr><td colspan=\"2\">LIBUSB</td><td>%11</td></tr>"
253
"<tr><td colspan=\"2\">Wahoo API</td><td>%12</td></tr>"
254
"<tr><td colspan=\"2\">VLC</td><td>%13</td></tr>"
255
"<tr><td colspan=\"2\">LUCENE</td><td>%14</td></tr>"
257
"<tr><td colspan=\"2\">LION SUPPORT</td><td>%15</td></tr>"
262
.arg(QWT_VERSION_STR)
280
QString versionText = QString("<center>" + gc_version + lib_version + "</center>");
286
GcCrashDialog::setHTML()
291
text += QString("<center><h3>Cyclist: \"%1\"</h3></center><br>").arg(home.dirName());
294
text += "<center><h3>Version Info</h3></center>";
295
text += versionHTML();
298
text += "<center><h3>Metric Log</h3></center>";
299
text += "<center><table border=0 cellspacing=10 width=\"90%\">";
300
QFile metriclog(home.absolutePath() + "/" + "metric.log");
301
if (metriclog.open(QIODevice::ReadOnly)) {
303
// read in line by line and add to diag file
304
QTextStream in(&metriclog);
305
while (!in.atEnd()) {
306
QString lines = in.readLine();
307
foreach(QString line, lines.split('\r')) {
308
text += "<tr><td align=\"center\">" + line + "</td></tr>";
314
text += "</table></center>";
317
text += "<center><h3>Athlete Directory</h3></center>";
318
text += "<center><table border=0 cellspacing=10 width=\"90%\">";
319
foreach(QString file, home.entryList(QDir::NoFilter, QDir::Time)) {
320
text += QString("<tr><td align=\"right\"> %1</td><td align=\"left\">%2</td></tr>")
322
.arg(QFileInfo(home.absolutePath() + "/" + file).lastModified().toString());
324
text += "</table></center>";
328
text += "<center><h3>All Settings</h3></center>";
329
text += "<center><table border=0 cellspacing=10 width=\"90%\">";
330
foreach(QString key, appsettings->allKeys()) {
333
// we do not disclose user names and passwords or key ids
334
if (key.endsWith("/user") || key.endsWith("/pass") || key.endsWith("/key")) continue;
336
// we do not disclose personally identifiable information
337
if (key.endsWith("/dob") || key.endsWith("/weight") ||
338
key.endsWith("/sex") || key.endsWith("/bio")) continue;
341
text += QString("<tr><td align=\"right\" width=\"50%\"> %1</td><td align=\"left\">"
342
"<span style=\"max-width:50%;\">%2</span></td></tr>")
344
.arg(appsettings->value(NULL, key).toString().leftJustified(60, ' ', true));
346
text += "</table></center>";
349
report->page()->mainFrame()->setHtml(text);
353
GcCrashDialog::saveAs()
355
QString fileName = QFileDialog::getSaveFileName( this, tr("Save Diagnostics"), QDir::homePath(), tr("Text File (*.txt)"));
358
QFile file(fileName);
360
QTextStream out(&file);
361
out.setCodec("UTF-8");
363
if (file.open(QIODevice::WriteOnly)) {
366
out << report->page()->mainFrame()->toPlainText();