Add a notification to report the last crash

This commit is contained in:
David Capello 2014-08-20 00:11:19 -03:00
parent 6bafe23ed7
commit 44c6f9400e
16 changed files with 248 additions and 24 deletions

View File

@ -22,6 +22,9 @@
<combobox id="screen_scale" />
</hbox>
<check text="Show timeline automatically" id="autotimeline" tooltip="Show the timeline automatically&#10;when a new frame or layer is added." />
<separator horizontal="true" />
<link id="locate_file" text="Locate Configuration File" />
<link id="locate_crash_folder" text="Locate Crash Folder" />
</vbox>
<!-- Editor -->
@ -90,7 +93,6 @@
</hbox>
<separator horizontal="true" />
<hbox>
<link id="locate_file" text="Locate File" />
<boxfiller />
<hbox homogeneous="true">
<button text="&amp;OK" closewindow="true" id="button_ok" magnet="true" width="60" />

View File

@ -0,0 +1,19 @@
<!-- Aseprite -->
<!-- Copyright (C) 2014 by David Capello -->
<gui>
<window text="Crash Report" id="send_crash">
<vbox>
<label text="Please send the following file:" />
<link id="filename" text="" url="" />
<label text="to this email:" />
<entry readonly="true" text="support@aseprite.org" maxsize="256" />
<label text="explaining what you was doing when the program crashed." />
<separator horizontal="true" />
<button text="Do it later" closewindow="true" />
<button id="delete_file" text="Delete file, I've already sent it" closewindow="true" />
</vbox>
</window>
</gui>

View File

@ -144,6 +144,7 @@ add_library(app-lib
res/palettes_loader_delegate.cpp
res/resources_loader.cpp
resource_finder.cpp
send_crash.cpp
settings/ui_settings_impl.cpp
shell.cpp
thumbnail_generator.cpp
@ -186,9 +187,9 @@ add_library(app-lib
ui/main_window.cpp
ui/mini_editor.cpp
ui/notifications.cpp
ui/palettes_listbox.cpp
ui/palette_popup.cpp
ui/palette_view.cpp
ui/palettes_listbox.cpp
ui/popup_window_pin.cpp
ui/resources_listbox.cpp
ui/skin/button_icon_impl.cpp

View File

@ -45,6 +45,7 @@
#include "app/modules/palettes.h"
#include "app/recent_files.h"
#include "app/resource_finder.h"
#include "app/send_crash.h"
#include "app/settings/settings.h"
#include "app/shell.h"
#include "app/tools/tool_box.h"
@ -71,6 +72,7 @@
#include "ui/intern.h"
#include "ui/ui.h"
#include <allegro.h>
#include <iostream>
#include <memory>
@ -258,6 +260,9 @@ int App::run()
webServer.start();
#endif
app::SendCrash sendCrash;
sendCrash.search();
// Run the GUI main message loop
gui_run();
@ -346,9 +351,9 @@ RecentFiles* App::getRecentFiles() const
return &m_modules->m_recent_files;
}
void App::showNotification(const char* text, const char* url)
void App::showNotification(INotificationDelegate* del)
{
m_mainWindow->showNotification(text, url);
m_mainWindow->showNotification(del);
}
// Updates palette and redraw the screen.

View File

@ -40,8 +40,10 @@ namespace raster {
}
namespace app {
class Document;
class DocumentExporter;
class INotificationDelegate;
class LegacyModules;
class LoggerModule;
class MainWindow;
@ -71,7 +73,7 @@ namespace app {
RecentFiles* getRecentFiles() const;
MainWindow* getMainWindow() const { return m_mainWindow; }
void showNotification(const char* text, const char* url);
void showNotification(INotificationDelegate* del);
// App Signals
Signal0<void> Exit;

View File

@ -27,6 +27,7 @@
#include "app/app.h"
#include "app/ini_file.h"
#include "base/bind.h"
#include "base/launcher.h"
#include <ctime>
#include <sstream>
@ -169,7 +170,7 @@ void CheckUpdateThreadLauncher::onMonitoringTick()
case updater::CheckUpdateResponse::Critical:
case updater::CheckUpdateResponse::Major:
App::instance()->showNotification("New Version Available!", m_response.getUrl().c_str());
App::instance()->showNotification(this);
break;
}
@ -210,6 +211,17 @@ void CheckUpdateThreadLauncher::checkForUpdates()
}
}
std::string CheckUpdateThreadLauncher::notificationText()
{
return "New Version Available!";
}
void CheckUpdateThreadLauncher::notificationClick()
{
if (!m_response.getUrl().empty())
base::launcher::open_url(m_response.getUrl());
}
}
#endif // ENABLE_UPDATER

View File

@ -22,6 +22,7 @@
#ifdef ENABLE_UPDATER
#include "app/notification_delegate.h"
#include "base/thread.h"
#include "base/unique_ptr.h"
#include "ui/timer.h"
@ -31,7 +32,7 @@ namespace app {
class CheckUpdateBackgroundJob;
class CheckUpdateThreadLauncher {
class CheckUpdateThreadLauncher : public INotificationDelegate {
public:
CheckUpdateThreadLauncher();
~CheckUpdateThreadLauncher();
@ -45,6 +46,9 @@ namespace app {
return m_response;
}
virtual std::string notificationText() override;
virtual void notificationClick() override;
private:
void onMonitoringTick();
void checkForUpdates();

View File

@ -29,6 +29,7 @@
#include "app/load_widget.h"
#include "app/modules/editors.h"
#include "app/modules/gui.h"
#include "app/resource_finder.h"
#include "app/settings/document_settings.h"
#include "app/settings/settings.h"
#include "app/ui/color_button.h"
@ -114,8 +115,13 @@ public:
// Reset button
checkedBgReset()->Click.connect(Bind<void>(&OptionsWindow::onResetCheckedBg, this));
// Locate config file
// Links
locateFile()->Click.connect(Bind<void>(&OptionsWindow::onLocateConfigFile, this));
#if WIN32
locateCrashFolder()->Click.connect(Bind<void>(&OptionsWindow::onLocateCrashFolder, this));
#else
locateCrashFolder()->setVisible(false);
#endif
// Undo limit
undoSizeLimit()->setTextf("%d", m_settings->undoSizeLimit());
@ -188,6 +194,12 @@ private:
m_checked_bg_color2->setColor(app::Color::fromRgb(192, 192, 192));
}
void onLocateCrashFolder() {
app::ResourceFinder rf;
rf.includeHomeDir(".");
app::launcher::open_folder(rf.defaultFilename());
}
void onLocateConfigFile() {
app::launcher::open_folder(app::get_config_file());
}

View File

@ -0,0 +1,36 @@
/* Aseprite
* Copyright (C) 2001-2014 David Capello
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_NOTIFICATION_DELEGATE_H_INCLUDED
#define APP_NOTIFICATION_DELEGATE_H_INCLUDED
#pragma once
#include <string>
namespace app {
class INotificationDelegate {
public:
virtual ~INotificationDelegate() { }
virtual std::string notificationText() = 0;
virtual void notificationClick() = 0;
};
}
#endif

83
src/app/send_crash.cpp Normal file
View File

@ -0,0 +1,83 @@
/* Aseprite
* Copyright (C) 2001-2014 David Capello
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/send_crash.h"
#include "app/app.h"
#include "app/resource_finder.h"
#include "base/bind.h"
#include "base/fs.h"
#include "base/launcher.h"
#include "generated_send_crash.h"
namespace app {
const char* SendCrash::kDefaultCrashName = "Aseprite-crash.dmp";
void SendCrash::search()
{
#ifdef WIN32
app::ResourceFinder rf;
rf.includeHomeDir(kDefaultCrashName);
m_dumpFilename = rf.defaultFilename();
if (base::is_file(m_dumpFilename)) {
App::instance()->showNotification(this);
}
#endif
}
std::string SendCrash::notificationText()
{
return "Report last crash";
}
void SendCrash::notificationClick()
{
if (m_dumpFilename.empty()) {
ui::Alert::show("Crash Report<<Nothing to report||&OK");
return;
}
app::gen::SendCrash dlg;
dlg.filename()->setText(m_dumpFilename);
dlg.filename()->Click.connect(Bind(&SendCrash::onClickFilename, this));
dlg.openWindowInForeground();
if (dlg.getKiller() == dlg.deleteFile()) {
try {
base::delete_file(m_dumpFilename);
m_dumpFilename = "";
}
catch (const std::exception& ex) {
ui::Alert::show("Error<<%s||&OK", ex.what());
}
}
}
void SendCrash::onClickFilename()
{
base::launcher::open_folder(m_dumpFilename);
}
} // namespace app

46
src/app/send_crash.h Normal file
View File

@ -0,0 +1,46 @@
/* Aseprite
* Copyright (C) 2001-2014 David Capello
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_SEND_CRASH_H_INCLUDED
#define APP_SEND_CRASH_H_INCLUDED
#pragma once
#include "app/notification_delegate.h"
#include <string>
namespace app {
class SendCrash : public INotificationDelegate {
public:
static const char* kDefaultCrashName;
void search();
virtual std::string notificationText() override;
virtual void notificationClick() override;
private:
void onClickFilename();
std::string m_dumpFilename;
};
} // namespace app
#endif // APP_SEND_CRASH_H_INCLUDED

View File

@ -157,9 +157,9 @@ void MainWindow::reloadMenus()
invalidate();
}
void MainWindow::showNotification(const char* text, const char* url)
void MainWindow::showNotification(INotificationDelegate* del)
{
m_notifications->addLink(text, url);
m_notifications->addLink(del);
m_notifications->setVisible(true);
m_notifications->getParent()->layout();
}

View File

@ -31,6 +31,7 @@ namespace app {
class ColorBar;
class ContextBar;
class INotificationDelegate;
class MainMenuBar;
class MiniEditorWindow;
class Notifications;
@ -61,7 +62,7 @@ namespace app {
void start();
void reloadMenus();
void showNotification(const char* text, const char* url);
void showNotification(INotificationDelegate* del);
Mode getMode() const { return m_mode; }
void setMode(Mode mode);

View File

@ -22,6 +22,7 @@
#include "app/ui/notifications.h"
#include "app/notification_delegate.h"
#include "app/ui/skin/skin_theme.h"
#include "app/ui/skin/style.h"
#include "base/launcher.h"
@ -37,21 +38,19 @@ static const char* kFlag = "flag";
class NotificationItem : public MenuItem {
public:
NotificationItem(const char* text, const char* url)
: MenuItem(text),
m_url(url) {
NotificationItem(INotificationDelegate* del)
: MenuItem(del->notificationText()),
m_delegate(del) {
}
protected:
void onClick() override {
MenuItem::onClick();
if (!m_url.empty())
base::launcher::open_url(m_url);
m_delegate->notificationClick();
}
private:
std::string m_url;
INotificationDelegate* m_delegate;
};
Notifications::Notifications()
@ -61,9 +60,9 @@ Notifications::Notifications()
{
}
void Notifications::addLink(const char* text, const char* url)
void Notifications::addLink(INotificationDelegate* del)
{
m_popup.addChild(new NotificationItem(text, url));
m_popup.addChild(new NotificationItem(del));
m_withNotifications = true;
}

View File

@ -28,11 +28,13 @@ namespace app {
class Style;
}
class INotificationDelegate;
class Notifications : public ui::Button {
public:
Notifications();
void addLink(const char* text, const char* url);
void addLink(INotificationDelegate* del);
protected:
void onPreferredSize(ui::PreferredSizeEvent& ev) override;

View File

@ -23,6 +23,7 @@
#include "app/app.h"
#include "app/console.h"
#include "app/resource_finder.h"
#include "app/send_crash.h"
#include "base/exception.h"
#include "base/memory.h"
#include "base/memory_dump.h"
@ -52,11 +53,10 @@ namespace {
#endif
};
bool getMemoryDumpFilename(std::string& filename)
{
bool getMemoryDumpFilename(std::string& filename) {
#ifdef WIN32
app::ResourceFinder rf;
rf.includeBinDir("aseprite-memory.dmp");
rf.includeHomeDir(app::SendCrash::kDefaultCrashName);
filename = rf.defaultFilename();
return true;
#else