mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-02 13:20:12 +00:00
Add automatic check for updates with app::CheckUpdateThreadLauncher
and show notifications in StatusBar. + Added updater library. + Removed "Check for New Version" command.
This commit is contained in:
parent
c7cf74228b
commit
cf9a296e5d
@ -325,7 +325,6 @@
|
|||||||
<item command="QuickReference" text="Quick &Reference" />
|
<item command="QuickReference" text="Quick &Reference" />
|
||||||
<separator />
|
<separator />
|
||||||
<item command="Donate" text="&Donate" />
|
<item command="Donate" text="&Donate" />
|
||||||
<item command="CheckUpdates" text="&Check for New Version" />
|
|
||||||
<separator />
|
<separator />
|
||||||
<item command="About" text="&About" />
|
<item command="About" text="&About" />
|
||||||
</menu>
|
</menu>
|
||||||
|
@ -51,7 +51,7 @@ if (CMAKE_USE_PTHREADS_INIT)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
# All libraries for .exe files
|
# All libraries for .exe files
|
||||||
set(all_libs aseprite-library undo-lib filters-lib gui-lib gfx-lib net-lib base-lib
|
set(all_libs aseprite-library undo-lib updater-lib filters-lib gui-lib gfx-lib net-lib base-lib
|
||||||
${libs3rdparty} allegro ${sys_libs})
|
${libs3rdparty} allegro ${sys_libs})
|
||||||
|
|
||||||
# Directories where .h files can be found
|
# Directories where .h files can be found
|
||||||
@ -76,6 +76,7 @@ add_subdirectory(gfx)
|
|||||||
add_subdirectory(gui)
|
add_subdirectory(gui)
|
||||||
add_subdirectory(net)
|
add_subdirectory(net)
|
||||||
add_subdirectory(undo)
|
add_subdirectory(undo)
|
||||||
|
add_subdirectory(updater)
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# aseprite library
|
# aseprite library
|
||||||
@ -100,6 +101,7 @@ add_library(aseprite-library
|
|||||||
undo_transaction.cpp
|
undo_transaction.cpp
|
||||||
xml_exception.cpp
|
xml_exception.cpp
|
||||||
xml_widgets.cpp
|
xml_widgets.cpp
|
||||||
|
app/check_update.cpp
|
||||||
app/color.cpp
|
app/color.cpp
|
||||||
app/color_utils.cpp
|
app/color_utils.cpp
|
||||||
commands/cmd_about.cpp
|
commands/cmd_about.cpp
|
||||||
@ -110,7 +112,6 @@ add_library(aseprite-library
|
|||||||
commands/cmd_change_color.cpp
|
commands/cmd_change_color.cpp
|
||||||
commands/cmd_change_image_type.cpp
|
commands/cmd_change_image_type.cpp
|
||||||
commands/cmd_change_pen.cpp
|
commands/cmd_change_pen.cpp
|
||||||
commands/cmd_check_updates.cpp
|
|
||||||
commands/cmd_clear.cpp
|
commands/cmd_clear.cpp
|
||||||
commands/cmd_close_file.cpp
|
commands/cmd_close_file.cpp
|
||||||
commands/cmd_configure_tools.cpp
|
commands/cmd_configure_tools.cpp
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
|
|
||||||
|
#include "app/check_update.h"
|
||||||
#include "app/color_utils.h"
|
#include "app/color_utils.h"
|
||||||
#include "base/exception.h"
|
#include "base/exception.h"
|
||||||
#include "base/unique_ptr.h"
|
#include "base/unique_ptr.h"
|
||||||
@ -157,8 +158,12 @@ App::App(int argc, char* argv[])
|
|||||||
set_current_palette(NULL, true);
|
set_current_palette(NULL, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int App::run()
|
int App::run()
|
||||||
{
|
{
|
||||||
|
app::CheckUpdateThreadLauncher checkUpdate;
|
||||||
|
|
||||||
// Initialize GUI interface
|
// Initialize GUI interface
|
||||||
if (isGui()) {
|
if (isGui()) {
|
||||||
View* view;
|
View* view;
|
||||||
@ -282,6 +287,10 @@ int App::run()
|
|||||||
// Support to drop files from Windows explorer
|
// Support to drop files from Windows explorer
|
||||||
install_drop_files();
|
install_drop_files();
|
||||||
|
|
||||||
|
// Launch the thread to check for updates.
|
||||||
|
checkUpdate.launch();
|
||||||
|
|
||||||
|
// Run the GUI main message loop
|
||||||
gui_run();
|
gui_run();
|
||||||
|
|
||||||
uninstall_drop_files();
|
uninstall_drop_files();
|
||||||
|
184
src/app/check_update.cpp
Normal file
184
src/app/check_update.cpp
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
/* ASE - Allegro Sprite Editor
|
||||||
|
* Copyright (C) 2001-2011 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "app/check_update.h"
|
||||||
|
|
||||||
|
#include "app.h"
|
||||||
|
#include "base/bind.h"
|
||||||
|
#include "core/cfg.h"
|
||||||
|
#include "modules/gui.h"
|
||||||
|
#include "widgets/statebar.h"
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
|
||||||
|
class CheckUpdateBackgroundJob : public updater::CheckUpdateDelegate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CheckUpdateBackgroundJob()
|
||||||
|
: m_canceled(false)
|
||||||
|
, m_received(false) { }
|
||||||
|
|
||||||
|
virtual ~CheckUpdateBackgroundJob() { }
|
||||||
|
|
||||||
|
void cancel()
|
||||||
|
{
|
||||||
|
m_canceled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isCanceled() const
|
||||||
|
{
|
||||||
|
return m_canceled;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isReceived() const
|
||||||
|
{
|
||||||
|
return m_received;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendRequest(const updater::Uuid& uuid, const std::string& extraParams)
|
||||||
|
{
|
||||||
|
m_checker.checkNewVersion(uuid, extraParams, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const updater::CheckUpdateResponse& getResponse() const
|
||||||
|
{
|
||||||
|
return m_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// CheckUpdateDelegate implementation
|
||||||
|
virtual void onResponse(updater::CheckUpdateResponse& data)
|
||||||
|
{
|
||||||
|
m_response = data;
|
||||||
|
m_received = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool m_canceled;
|
||||||
|
bool m_received;
|
||||||
|
updater::CheckUpdate m_checker;
|
||||||
|
updater::CheckUpdateResponse m_response;
|
||||||
|
};
|
||||||
|
|
||||||
|
CheckUpdateThreadLauncher::CheckUpdateThreadLauncher()
|
||||||
|
: m_received(false)
|
||||||
|
, m_guiMonitor(NULL)
|
||||||
|
, m_inits(get_config_int("Updater", "Inits", 0))
|
||||||
|
, m_exits(get_config_int("Updater", "Exits", 0))
|
||||||
|
{
|
||||||
|
// Minimal stats: number of initializations
|
||||||
|
set_config_int("Updater", "Inits", get_config_int("Updater", "Inits", 0)+1);
|
||||||
|
flush_config_file();
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckUpdateThreadLauncher::~CheckUpdateThreadLauncher()
|
||||||
|
{
|
||||||
|
if (m_guiMonitor) {
|
||||||
|
remove_gui_monitor(m_guiMonitor);
|
||||||
|
m_guiMonitor = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_thread) {
|
||||||
|
if (m_bgJob)
|
||||||
|
m_bgJob->cancel();
|
||||||
|
|
||||||
|
m_thread->join();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Minimal stats: number of exits
|
||||||
|
set_config_int("Updater", "Exits", get_config_int("Updater", "Exits", 0)+1);
|
||||||
|
flush_config_file();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckUpdateThreadLauncher::launch()
|
||||||
|
{
|
||||||
|
if (m_uuid.empty())
|
||||||
|
m_uuid = get_config_string("Updater", "Uuid", "");
|
||||||
|
|
||||||
|
m_bgJob.reset(new CheckUpdateBackgroundJob);
|
||||||
|
m_thread.reset(new base::thread(Bind<void>(&CheckUpdateThreadLauncher::checkForUpdates, this)));
|
||||||
|
|
||||||
|
// Start a timer to monitor the progress of the background job
|
||||||
|
// executed in "m_thread". The "monitorProxy" method will be called
|
||||||
|
// periodically by the GUI main thread.
|
||||||
|
m_guiMonitor = add_gui_monitor(CheckUpdateThreadLauncher::monitorProxy, NULL, (void*)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CheckUpdateThreadLauncher::isReceived() const
|
||||||
|
{
|
||||||
|
return m_received;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckUpdateThreadLauncher::monitorActivity()
|
||||||
|
{
|
||||||
|
// If we do not receive a response yet...
|
||||||
|
if (!m_received)
|
||||||
|
return; // Skip and wait the next call.
|
||||||
|
|
||||||
|
// Depending on the type of update received
|
||||||
|
switch (m_response.getUpdateType()) {
|
||||||
|
|
||||||
|
case updater::CheckUpdateResponse::NoUpdate:
|
||||||
|
// Nothing to do, we are up-to-date
|
||||||
|
break;
|
||||||
|
|
||||||
|
case updater::CheckUpdateResponse::Critical:
|
||||||
|
case updater::CheckUpdateResponse::Major:
|
||||||
|
app_get_statusbar()->showNotification("New Version!", m_response.getUrl().c_str());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the new UUID
|
||||||
|
if (!m_response.getUuid().empty()) {
|
||||||
|
m_uuid = m_response.getUuid();
|
||||||
|
set_config_string("Updater", "Uuid", m_uuid.c_str());
|
||||||
|
flush_config_file();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the monitor
|
||||||
|
remove_gui_monitor(m_guiMonitor);
|
||||||
|
m_guiMonitor = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckUpdateThreadLauncher::monitorProxy(void* data)
|
||||||
|
{
|
||||||
|
((CheckUpdateThreadLauncher*)data)->monitorActivity();
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method is executed in a special thread to send the HTTP request.
|
||||||
|
void CheckUpdateThreadLauncher::checkForUpdates()
|
||||||
|
{
|
||||||
|
// Add mini-stats in the request
|
||||||
|
std::stringstream extraParams;
|
||||||
|
extraParams << "inits=" << m_inits
|
||||||
|
<< "&exits=" << m_exits;
|
||||||
|
|
||||||
|
// Send the HTTP request to check for updates.
|
||||||
|
m_bgJob->sendRequest(m_uuid, extraParams.str());
|
||||||
|
|
||||||
|
if (m_bgJob->isReceived()) {
|
||||||
|
m_received = true;
|
||||||
|
m_response = m_bgJob->getResponse();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
68
src/app/check_update.h
Normal file
68
src/app/check_update.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/* ASE - Allegro Sprite Editor
|
||||||
|
* Copyright (C) 2001-2011 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_CHECK_UPDATE_H_INCLUDED
|
||||||
|
#define APP_CHECK_UPDATE_H_INCLUDED
|
||||||
|
|
||||||
|
#include "base/thread.h"
|
||||||
|
#include "base/unique_ptr.h"
|
||||||
|
#include "updater/check_update.h"
|
||||||
|
|
||||||
|
struct Monitor;
|
||||||
|
|
||||||
|
namespace app {
|
||||||
|
|
||||||
|
class CheckUpdateBackgroundJob;
|
||||||
|
|
||||||
|
class CheckUpdateThreadLauncher
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CheckUpdateThreadLauncher();
|
||||||
|
~CheckUpdateThreadLauncher();
|
||||||
|
|
||||||
|
void launch();
|
||||||
|
|
||||||
|
bool isReceived() const;
|
||||||
|
|
||||||
|
const updater::CheckUpdateResponse& getResponse() const
|
||||||
|
{
|
||||||
|
return m_response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void monitorActivity();
|
||||||
|
static void monitorProxy(void* data);
|
||||||
|
|
||||||
|
void checkForUpdates();
|
||||||
|
|
||||||
|
updater::Uuid m_uuid;
|
||||||
|
UniquePtr<base::thread> m_thread;
|
||||||
|
UniquePtr<CheckUpdateBackgroundJob> m_bgJob;
|
||||||
|
bool m_received;
|
||||||
|
updater::CheckUpdateResponse m_response;
|
||||||
|
Monitor* m_guiMonitor;
|
||||||
|
|
||||||
|
// Mini-stats
|
||||||
|
int m_inits;
|
||||||
|
int m_exits;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -1,107 +0,0 @@
|
|||||||
/* ASE - Allegro Sprite Editor
|
|
||||||
* Copyright (C) 2001-2011 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
#include <allegro.h>
|
|
||||||
|
|
||||||
#include "base/convert_to.h"
|
|
||||||
#include "base/string.h"
|
|
||||||
#include "commands/command.h"
|
|
||||||
#include "launcher.h"
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// about
|
|
||||||
|
|
||||||
class CheckUpdatesCommand : public Command
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CheckUpdatesCommand();
|
|
||||||
Command* clone() const { return new CheckUpdatesCommand(*this); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void onExecute(Context* context);
|
|
||||||
};
|
|
||||||
|
|
||||||
CheckUpdatesCommand::CheckUpdatesCommand()
|
|
||||||
: Command("CheckUpdates",
|
|
||||||
"Check for New Version",
|
|
||||||
CmdUIOnlyFlag)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckUpdatesCommand::onExecute(Context* context)
|
|
||||||
{
|
|
||||||
std::string url;
|
|
||||||
url += WEBSITE;
|
|
||||||
url += "update/?v=";
|
|
||||||
url += VERSION; // ASE version
|
|
||||||
|
|
||||||
// Operating system
|
|
||||||
std::string os;
|
|
||||||
switch (os_type) {
|
|
||||||
case OSTYPE_WIN3: os = "win3"; break;
|
|
||||||
case OSTYPE_WIN95: os = "win95"; break;
|
|
||||||
case OSTYPE_WIN98: os = "win98"; break;
|
|
||||||
case OSTYPE_WINME: os = "winme"; break;
|
|
||||||
case OSTYPE_WINNT: os = "winnt"; break;
|
|
||||||
case OSTYPE_WIN2000: os = "win2000"; break;
|
|
||||||
case OSTYPE_WINXP: os = "winxp"; break;
|
|
||||||
case OSTYPE_WIN2003: os = "win2003"; break;
|
|
||||||
case OSTYPE_WINVISTA: os = "winvista"; break;
|
|
||||||
case OSTYPE_OS2: os = "os2"; break;
|
|
||||||
case OSTYPE_WARP: os = "warp"; break;
|
|
||||||
case OSTYPE_DOSEMU: os = "dosemu"; break;
|
|
||||||
case OSTYPE_OPENDOS: os = "opendos"; break;
|
|
||||||
case OSTYPE_LINUX: os = "linux"; break;
|
|
||||||
case OSTYPE_SUNOS: os = "sunos"; break;
|
|
||||||
case OSTYPE_FREEBSD: os = "freebsd"; break;
|
|
||||||
case OSTYPE_NETBSD: os = "netbsd"; break;
|
|
||||||
case OSTYPE_IRIX: os = "irix"; break;
|
|
||||||
case OSTYPE_DARWIN: os = "darwin"; break;
|
|
||||||
case OSTYPE_QNX: os = "qnx"; break;
|
|
||||||
case OSTYPE_UNIX: os = "unix"; break;
|
|
||||||
case OSTYPE_BEOS: os = "beos"; break;
|
|
||||||
case OSTYPE_MACOS: os = "macos"; break;
|
|
||||||
case OSTYPE_MACOSX: os = "macosx"; break;
|
|
||||||
default:
|
|
||||||
os = "unknown";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
url += "&os=" + os;
|
|
||||||
|
|
||||||
// Version of the operating system
|
|
||||||
if (os_version >= 0) {
|
|
||||||
url += "&osver=";
|
|
||||||
url += base::convert_to<base::string>(os_version);
|
|
||||||
}
|
|
||||||
if (os_revision >= 0) {
|
|
||||||
url += "&osrev=";
|
|
||||||
url += base::convert_to<base::string>(os_revision);
|
|
||||||
}
|
|
||||||
|
|
||||||
Launcher::openUrl(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
// CommandFactory
|
|
||||||
|
|
||||||
Command* CommandFactory::createCheckUpdatesCommand()
|
|
||||||
{
|
|
||||||
return new CheckUpdatesCommand;
|
|
||||||
}
|
|
@ -25,7 +25,6 @@ FOR_EACH_COMMAND(CelProperties)
|
|||||||
FOR_EACH_COMMAND(ChangeColor)
|
FOR_EACH_COMMAND(ChangeColor)
|
||||||
FOR_EACH_COMMAND(ChangeImageType)
|
FOR_EACH_COMMAND(ChangeImageType)
|
||||||
FOR_EACH_COMMAND(ChangePen)
|
FOR_EACH_COMMAND(ChangePen)
|
||||||
FOR_EACH_COMMAND(CheckUpdates)
|
|
||||||
FOR_EACH_COMMAND(Clear)
|
FOR_EACH_COMMAND(Clear)
|
||||||
FOR_EACH_COMMAND(CloseAllFiles)
|
FOR_EACH_COMMAND(CloseAllFiles)
|
||||||
FOR_EACH_COMMAND(CloseEditor)
|
FOR_EACH_COMMAND(CloseEditor)
|
||||||
|
16
src/updater/CMakeLists.txt
Normal file
16
src/updater/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
# ASE - Allegro Sprite Editor
|
||||||
|
# Copyright (C) 2001-2011 David Capello
|
||||||
|
|
||||||
|
set(UPDATER_LIB_SOURCES
|
||||||
|
check_update.cpp
|
||||||
|
user_agent.cpp)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
set(UPDATER_LIB_SOURCES ${UPDATER_LIB_SOURCES} user_agent_win.c)
|
||||||
|
else()
|
||||||
|
if(APPLE)
|
||||||
|
set(UPDATER_LIB_SOURCES ${UPDATER_LIB_SOURCES} user_agent_mac.m)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_library(updater-lib ${UPDATER_LIB_SOURCES})
|
150
src/updater/check_update.cpp
Normal file
150
src/updater/check_update.cpp
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/* ASE - Allegro Sprite Editor
|
||||||
|
* Copyright (C) 2001-2011 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "updater/check_update.h"
|
||||||
|
|
||||||
|
#include "base/bind.h"
|
||||||
|
#include "base/convert_to.h"
|
||||||
|
#include "net/http_headers.h"
|
||||||
|
#include "net/http_request.h"
|
||||||
|
#include "net/http_response.h"
|
||||||
|
#include "tinyxml.h"
|
||||||
|
#include "updater/user_agent.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#define UPDATE_URL WEBSITE "update/?xml=1"
|
||||||
|
|
||||||
|
namespace updater {
|
||||||
|
|
||||||
|
CheckUpdateResponse::CheckUpdateResponse()
|
||||||
|
: m_type(Unknown)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckUpdateResponse::CheckUpdateResponse(const CheckUpdateResponse& other)
|
||||||
|
: m_type(other.m_type)
|
||||||
|
, m_version(other.m_version)
|
||||||
|
, m_url(other.m_url)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckUpdateResponse::CheckUpdateResponse(const std::string& responseBody)
|
||||||
|
: m_type(Unknown)
|
||||||
|
{
|
||||||
|
TiXmlDocument doc;
|
||||||
|
doc.Parse(responseBody.c_str());
|
||||||
|
|
||||||
|
TiXmlHandle handle(&doc);
|
||||||
|
TiXmlElement* xmlUpdate = handle.FirstChild("update").ToElement();
|
||||||
|
if (!xmlUpdate) {
|
||||||
|
// TODO show error?
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* latest_attr = xmlUpdate->Attribute("latest");
|
||||||
|
const char* version_attr = xmlUpdate->Attribute("version");
|
||||||
|
const char* type_attr = xmlUpdate->Attribute("type");
|
||||||
|
const char* url_attr = xmlUpdate->Attribute("url");
|
||||||
|
const char* uuid_attr = xmlUpdate->Attribute("uuid");
|
||||||
|
|
||||||
|
if (latest_attr && strcmp(latest_attr, "1") == 0)
|
||||||
|
m_type = NoUpdate;
|
||||||
|
|
||||||
|
if (type_attr) {
|
||||||
|
if (strcmp(type_attr, "critical") == 0)
|
||||||
|
m_type = Critical;
|
||||||
|
else if (strcmp(type_attr, "major") == 0)
|
||||||
|
m_type = Major;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version_attr)
|
||||||
|
m_version = base::convert_to<base::Version>(std::string(version_attr));
|
||||||
|
|
||||||
|
if (url_attr)
|
||||||
|
m_url = url_attr;
|
||||||
|
|
||||||
|
if (uuid_attr)
|
||||||
|
m_uuid = uuid_attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
class CheckUpdate::CheckUpdateImpl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CheckUpdateImpl() { }
|
||||||
|
~CheckUpdateImpl() { }
|
||||||
|
|
||||||
|
void abort()
|
||||||
|
{
|
||||||
|
// TODO impl
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkNewVersion(const Uuid& uuid, const std::string& extraParams, CheckUpdateDelegate* delegate)
|
||||||
|
{
|
||||||
|
using namespace base;
|
||||||
|
using namespace net;
|
||||||
|
|
||||||
|
std::string url = UPDATE_URL;
|
||||||
|
if (!uuid.empty()) {
|
||||||
|
url += "&uuid=";
|
||||||
|
url += uuid;
|
||||||
|
}
|
||||||
|
if (!extraParams.empty()) {
|
||||||
|
url += "&";
|
||||||
|
url += extraParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpRequest request(url);
|
||||||
|
HttpHeaders headers;
|
||||||
|
headers.setHeader("User-Agent", getUserAgent());
|
||||||
|
request.setHeaders(headers);
|
||||||
|
|
||||||
|
std::stringstream body;
|
||||||
|
HttpResponse response(&body);
|
||||||
|
request.send(response);
|
||||||
|
|
||||||
|
CheckUpdateResponse data(body.str());
|
||||||
|
delegate->onResponse(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
CheckUpdate::CheckUpdate()
|
||||||
|
: m_impl(new CheckUpdateImpl)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CheckUpdate::~CheckUpdate()
|
||||||
|
{
|
||||||
|
delete m_impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckUpdate::abort()
|
||||||
|
{
|
||||||
|
m_impl->abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CheckUpdate::checkNewVersion(const Uuid& uuid, const std::string& extraParams, CheckUpdateDelegate* delegate)
|
||||||
|
{
|
||||||
|
m_impl->checkNewVersion(uuid, extraParams, delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
105
src/updater/check_update.h
Normal file
105
src/updater/check_update.h
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/* ASE - Allegro Sprite Editor
|
||||||
|
* Copyright (C) 2001-2011 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 UPDATER_CHECK_UPDATE_H_INCLUDED
|
||||||
|
#define UPDATER_CHECK_UPDATE_H_INCLUDED
|
||||||
|
|
||||||
|
#include "base/disable_copying.h"
|
||||||
|
#include "base/version.h"
|
||||||
|
|
||||||
|
namespace updater {
|
||||||
|
|
||||||
|
typedef std::string Uuid;
|
||||||
|
|
||||||
|
// Data received by a "check new version" request.
|
||||||
|
class CheckUpdateResponse
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Type {
|
||||||
|
Unknown,
|
||||||
|
NoUpdate, // No update available. You've the latest version.
|
||||||
|
Critical, // There are critical bugs fixed.
|
||||||
|
Major // New major version.
|
||||||
|
};
|
||||||
|
|
||||||
|
CheckUpdateResponse();
|
||||||
|
CheckUpdateResponse(const CheckUpdateResponse& other);
|
||||||
|
CheckUpdateResponse(const std::string& responseBody);
|
||||||
|
|
||||||
|
// Returns the type of the available update.
|
||||||
|
Type getUpdateType() const { return m_type; }
|
||||||
|
|
||||||
|
// Returns the latest version available to be downloaded.
|
||||||
|
base::Version getLatestVersion() const { return m_version; }
|
||||||
|
|
||||||
|
// Returns the URL to download the new version.
|
||||||
|
std::string getUrl() const { return m_url; }
|
||||||
|
|
||||||
|
// Returns a UUID to be assigned to this user. This parameter is
|
||||||
|
// returned only when the request is done without an existent
|
||||||
|
// UUID.
|
||||||
|
Uuid getUuid() const { return m_uuid; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
Type m_type;
|
||||||
|
base::Version m_version;
|
||||||
|
std::string m_url;
|
||||||
|
Uuid m_uuid;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Delegate called by CheckUpdate when the request to the server is
|
||||||
|
// done. It must be implemented by the client of CheckUpdate.
|
||||||
|
class CheckUpdateDelegate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~CheckUpdateDelegate() { }
|
||||||
|
|
||||||
|
// Returns true when the user is quitting the application so he does
|
||||||
|
// not want to continue checking for updates.
|
||||||
|
// virtual bool abortRequest() = 0;
|
||||||
|
|
||||||
|
// Called by CheckUpdate::checkNewVersion() when the response from
|
||||||
|
// the "updates server" is received.
|
||||||
|
virtual void onResponse(CheckUpdateResponse& data) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Checks for new versions.
|
||||||
|
class CheckUpdate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CheckUpdate();
|
||||||
|
~CheckUpdate();
|
||||||
|
|
||||||
|
// Cancels any operation in progress. It is called automatically in
|
||||||
|
// the destructor.
|
||||||
|
void abort();
|
||||||
|
|
||||||
|
// Sends a request to the "updates server" and calls the delegate
|
||||||
|
// when the response is received.
|
||||||
|
void checkNewVersion(const Uuid& uuid, const std::string& extraParams, CheckUpdateDelegate* delegate);
|
||||||
|
|
||||||
|
private:
|
||||||
|
class CheckUpdateImpl;
|
||||||
|
CheckUpdateImpl* m_impl;
|
||||||
|
|
||||||
|
DISABLE_COPYING(CheckUpdate);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace updater
|
||||||
|
|
||||||
|
#endif
|
101
src/updater/user_agent.cpp
Normal file
101
src/updater/user_agent.cpp
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/* ASE - Allegro Sprite Editor
|
||||||
|
* Copyright (C) 2001-2011 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#if _WIN32 // Windows
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
extern "C" BOOL IsWow64();
|
||||||
|
|
||||||
|
#elif __APPLE__ // Mac OS X
|
||||||
|
|
||||||
|
extern "C" void getMacOSXVersion(int* major, int* minor, int* bugFix);
|
||||||
|
|
||||||
|
#else // Unix-like system
|
||||||
|
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace updater {
|
||||||
|
|
||||||
|
std::string getUserAgent()
|
||||||
|
{
|
||||||
|
std::stringstream userAgent;
|
||||||
|
|
||||||
|
// ASEPRITE name and version
|
||||||
|
|
||||||
|
userAgent << PACKAGE << "/" << VERSION << " (";
|
||||||
|
|
||||||
|
#if _WIN32
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Windows
|
||||||
|
|
||||||
|
OSVERSIONINFOEX osv;
|
||||||
|
osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||||
|
::GetVersionEx((OSVERSIONINFO*)&osv);
|
||||||
|
|
||||||
|
userAgent << "Windows";
|
||||||
|
switch (osv.wProductType) {
|
||||||
|
case VER_NT_DOMAIN_CONTROLLER:
|
||||||
|
case VER_NT_SERVER:
|
||||||
|
userAgent << " Server";
|
||||||
|
break;
|
||||||
|
case VER_NT_WORKSTATION:
|
||||||
|
userAgent << " NT";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
userAgent << " " << osv.dwMajorVersion << "." << osv.dwMinorVersion;
|
||||||
|
|
||||||
|
if (osv.wServicePackMajor > 0)
|
||||||
|
userAgent << " SP" << osv.wServicePackMajor;
|
||||||
|
|
||||||
|
if (IsWow64())
|
||||||
|
userAgent << "; WOW64";
|
||||||
|
|
||||||
|
#elif __APPLE__
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Mac OS X
|
||||||
|
|
||||||
|
int major, minor, bugFix;
|
||||||
|
getMacOSXVersion(&major, &minor, &bugFix);
|
||||||
|
userAgent << "Mac OS X " << major << "." << minor << "." << bugFix;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------
|
||||||
|
// Unix like
|
||||||
|
|
||||||
|
struct utsname utsn;
|
||||||
|
uname(&utsn);
|
||||||
|
userAgent << utsn.sysname << " " utsn.release;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
userAgent << ")";
|
||||||
|
return userAgent.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace updater
|
32
src/updater/user_agent.h
Normal file
32
src/updater/user_agent.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/* ASE - Allegro Sprite Editor
|
||||||
|
* Copyright (C) 2001-2011 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 UPDATER_USER_AGENT_H_INCLUDED
|
||||||
|
#define UPDATER_USER_AGENT_H_INCLUDED
|
||||||
|
|
||||||
|
#include "base/disable_copying.h"
|
||||||
|
|
||||||
|
#include <iosfwd>
|
||||||
|
|
||||||
|
namespace updater {
|
||||||
|
|
||||||
|
std::string getUserAgent();
|
||||||
|
|
||||||
|
} // namespace updater
|
||||||
|
|
||||||
|
#endif // UPDATER_USER_AGENT_H_INCLUDED
|
47
src/updater/user_agent_mac.m
Normal file
47
src/updater/user_agent_mac.m
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/* ASE - Allegro Sprite Editor
|
||||||
|
* Copyright (C) 2001-2011 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
void getMacOSXVersion(int* major, int* minor, int* bugFix)
|
||||||
|
{
|
||||||
|
OSErr err;
|
||||||
|
SInt32 systemVersion, versionMajor, versionMinor, versionBugFix;
|
||||||
|
if (Gestalt(gestaltSystemVersion, &systemVersion) != noErr) goto fail;
|
||||||
|
if (systemVersion < 0x1040) {
|
||||||
|
if (major) *major = ((systemVersion & 0xF000) >> 12) * 10 + ((systemVersion & 0x0F00) >> 8);
|
||||||
|
if (minor) *minor = (systemVersion & 0x00F0) >> 4;
|
||||||
|
if (bugFix) *bugFix = (systemVersion & 0x000F);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ((err = Gestalt(gestaltSystemVersionMajor, &versionMajor)) != noErr) goto fail;
|
||||||
|
if ((err = Gestalt(gestaltSystemVersionMinor, &versionMinor)) != noErr) goto fail;
|
||||||
|
if ((err = Gestalt(gestaltSystemVersionBugFix, &versionBugFix)) != noErr) goto fail;
|
||||||
|
if (major) *major = versionMajor;
|
||||||
|
if (minor) *minor = versionMinor;
|
||||||
|
if (bugFix) *bugFix = versionBugFix;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
if (major) *major = 10;
|
||||||
|
if (minor) *minor = 0;
|
||||||
|
if (bugFix) *bugFix = 0;
|
||||||
|
}
|
37
src/updater/user_agent_win.c
Normal file
37
src/updater/user_agent_win.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/* ASE - Allegro Sprite Editor
|
||||||
|
* Copyright (C) 2001-2011 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS)(HANDLE, PBOOL);
|
||||||
|
|
||||||
|
static LPFN_ISWOW64PROCESS fnIsWow64Process = NULL;
|
||||||
|
|
||||||
|
BOOL IsWow64()
|
||||||
|
{
|
||||||
|
BOOL isWow64 = FALSE;
|
||||||
|
|
||||||
|
fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle("kernel32"),
|
||||||
|
"IsWow64Process");
|
||||||
|
if (fnIsWow64Process != NULL)
|
||||||
|
fnIsWow64Process(GetCurrentProcess(), &isWow64);
|
||||||
|
|
||||||
|
return isWow64;
|
||||||
|
}
|
@ -137,6 +137,22 @@ StatusBar::StatusBar()
|
|||||||
m_commandsBox = box1;
|
m_commandsBox = box1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create the box to show notifications.
|
||||||
|
{
|
||||||
|
Box* box1 = new Box(JI_HORIZONTAL);
|
||||||
|
Box* box2 = new Box(JI_VERTICAL);
|
||||||
|
|
||||||
|
jwidget_set_border(box1, 2*jguiscale(), 1*jguiscale(), 2*jguiscale(), 2*jguiscale());
|
||||||
|
jwidget_noborders(box2);
|
||||||
|
jwidget_expansive(box2, true);
|
||||||
|
|
||||||
|
m_linkLabel = new LinkLabel((std::string(WEBSITE) + "donate/").c_str(), "Support This Project");
|
||||||
|
|
||||||
|
box1->addChild(box2);
|
||||||
|
box1->addChild(m_linkLabel);
|
||||||
|
m_notificationsBox = box1;
|
||||||
|
}
|
||||||
|
|
||||||
// Construct move-pixels box
|
// Construct move-pixels box
|
||||||
{
|
{
|
||||||
Box* filler = new Box(JI_HORIZONTAL);
|
Box* filler = new Box(JI_HORIZONTAL);
|
||||||
@ -153,6 +169,8 @@ StatusBar::StatusBar()
|
|||||||
m_transparentColor->Change.connect(Bind<void>(&StatusBar::onTransparentColorChange, this));
|
m_transparentColor->Change.connect(Bind<void>(&StatusBar::onTransparentColorChange, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addChild(m_notificationsBox);
|
||||||
|
|
||||||
App::instance()->CurrentToolChange.connect(&StatusBar::onCurrentToolChange, this);
|
App::instance()->CurrentToolChange.connect(&StatusBar::onCurrentToolChange, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,6 +180,9 @@ StatusBar::~StatusBar()
|
|||||||
delete *it;
|
delete *it;
|
||||||
|
|
||||||
delete m_tipwindow; // widget
|
delete m_tipwindow; // widget
|
||||||
|
delete m_movePixelsBox;
|
||||||
|
delete m_commandsBox;
|
||||||
|
delete m_notificationsBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusBar::addListener(StatusBarListener* listener)
|
void StatusBar::addListener(StatusBarListener* listener)
|
||||||
@ -209,8 +230,8 @@ bool StatusBar::setStatusText(int msecs, const char *format, ...)
|
|||||||
m_timeout = ji_clock + msecs;
|
m_timeout = ji_clock + msecs;
|
||||||
m_state = SHOW_TEXT;
|
m_state = SHOW_TEXT;
|
||||||
|
|
||||||
this->setText(buf);
|
setText(buf);
|
||||||
this->invalidate();
|
invalidate();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -254,8 +275,8 @@ void StatusBar::showTip(int msecs, const char *format, ...)
|
|||||||
|
|
||||||
// Set the text in status-bar (with inmediate timeout)
|
// Set the text in status-bar (with inmediate timeout)
|
||||||
m_timeout = ji_clock;
|
m_timeout = ji_clock;
|
||||||
this->setText(buf);
|
setText(buf);
|
||||||
this->invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StatusBar::showColor(int msecs, const char* text, const Color& color, int alpha)
|
void StatusBar::showColor(int msecs, const char* text, const Color& color, int alpha)
|
||||||
@ -312,6 +333,14 @@ Color StatusBar::getTransparentColor()
|
|||||||
return m_transparentColor->getColor();
|
return m_transparentColor->getColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StatusBar::showNotification(const char* text, const char* link)
|
||||||
|
{
|
||||||
|
m_linkLabel->setText(text);
|
||||||
|
m_linkLabel->setUrl(link);
|
||||||
|
layout();
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// Progress bars stuff
|
// Progress bars stuff
|
||||||
|
|
||||||
@ -377,6 +406,12 @@ bool StatusBar::onProcessMessage(Message* msg)
|
|||||||
|
|
||||||
case JM_SETPOS:
|
case JM_SETPOS:
|
||||||
jrect_copy(this->rc, &msg->setpos.rect);
|
jrect_copy(this->rc, &msg->setpos.rect);
|
||||||
|
{
|
||||||
|
JRect rc = jrect_new_copy(this->rc);
|
||||||
|
rc->x1 = rc->x2 - m_notificationsBox->getPreferredSize().w;
|
||||||
|
jwidget_set_rect(m_notificationsBox, rc);
|
||||||
|
jrect_free(rc);
|
||||||
|
}
|
||||||
{
|
{
|
||||||
JRect rc = jrect_new_copy(this->rc);
|
JRect rc = jrect_new_copy(this->rc);
|
||||||
rc->x2 -= jrect_w(rc)/4 + 4*jguiscale();
|
rc->x2 -= jrect_w(rc)/4 + 4*jguiscale();
|
||||||
@ -393,17 +428,6 @@ bool StatusBar::onProcessMessage(Message* msg)
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case JM_CLOSE:
|
|
||||||
if (!hasChild(m_commandsBox)) {
|
|
||||||
// Append the "m_commandsBox" so it is destroyed in StatusBar dtor.
|
|
||||||
addChild(m_commandsBox);
|
|
||||||
}
|
|
||||||
if (!hasChild(m_movePixelsBox)) {
|
|
||||||
// Append the "m_movePixelsBox" so it is destroyed in StatusBar dtor.
|
|
||||||
addChild(m_movePixelsBox);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JM_DRAW: {
|
case JM_DRAW: {
|
||||||
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
|
SkinTheme* theme = static_cast<SkinTheme*>(this->getTheme());
|
||||||
int text_color = ji_color_foreground();
|
int text_color = ji_color_foreground();
|
||||||
@ -506,7 +530,7 @@ bool StatusBar::onProcessMessage(Message* msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Show layers only when we are not moving pixels
|
// Show layers only when we are not moving pixels
|
||||||
else if (!this->hasChild(m_movePixelsBox)) {
|
else if (!hasChild(m_movePixelsBox)) {
|
||||||
// Available width for layers buttons
|
// Available width for layers buttons
|
||||||
int width = jrect_w(rc)/4;
|
int width = jrect_w(rc)/4;
|
||||||
|
|
||||||
@ -517,6 +541,11 @@ bool StatusBar::onProcessMessage(Message* msg)
|
|||||||
const ActiveDocumentReader document(UIContext::instance());
|
const ActiveDocumentReader document(UIContext::instance());
|
||||||
const Sprite* sprite(document ? document->getSprite(): NULL);
|
const Sprite* sprite(document ? document->getSprite(): NULL);
|
||||||
if (sprite) {
|
if (sprite) {
|
||||||
|
if (hasChild(m_notificationsBox)) {
|
||||||
|
removeChild(m_notificationsBox);
|
||||||
|
invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
const LayerFolder* folder = sprite->getFolder();
|
const LayerFolder* folder = sprite->getFolder();
|
||||||
LayerConstIterator it = folder->get_layer_begin();
|
LayerConstIterator it = folder->get_layer_begin();
|
||||||
LayerConstIterator end = folder->get_layer_end();
|
LayerConstIterator end = folder->get_layer_end();
|
||||||
@ -554,22 +583,10 @@ bool StatusBar::onProcessMessage(Message* msg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int x1 = rc->x2-width;
|
if (!hasChild(m_notificationsBox)) {
|
||||||
int x2 = rc->x2;
|
addChild(m_notificationsBox);
|
||||||
bool hot = (0 == m_hot_layer);
|
invalidate();
|
||||||
|
}
|
||||||
theme->draw_bounds_nw(doublebuffer,
|
|
||||||
x1, rc->y1, x2, rc->y2,
|
|
||||||
hot ? PART_TOOLBUTTON_HOT_NW:
|
|
||||||
PART_TOOLBUTTON_NORMAL_NW,
|
|
||||||
hot ? theme->get_button_hot_face_color():
|
|
||||||
theme->get_button_normal_face_color());
|
|
||||||
|
|
||||||
textout_centre_ex(doublebuffer, this->getFont(), "Donate",
|
|
||||||
(x1+x2)/2,
|
|
||||||
(rc->y1+rc->y2)/2-text_height(this->getFont())/2,
|
|
||||||
hot ? theme->get_button_hot_text_color():
|
|
||||||
theme->get_button_normal_text_color(), -1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (LockedDocumentException&) {
|
catch (LockedDocumentException&) {
|
||||||
@ -591,8 +608,8 @@ bool StatusBar::onProcessMessage(Message* msg)
|
|||||||
case JM_MOUSEENTER: {
|
case JM_MOUSEENTER: {
|
||||||
bool state = (UIContext::instance()->getActiveDocument() != NULL);
|
bool state = (UIContext::instance()->getActiveDocument() != NULL);
|
||||||
|
|
||||||
if (!this->hasChild(m_movePixelsBox)) {
|
if (!hasChild(m_movePixelsBox)) {
|
||||||
if (!this->hasChild(m_commandsBox) && state) {
|
if (state && !hasChild(m_commandsBox)) {
|
||||||
m_b_first->setEnabled(state);
|
m_b_first->setEnabled(state);
|
||||||
m_b_prev->setEnabled(state);
|
m_b_prev->setEnabled(state);
|
||||||
m_b_play->setEnabled(state);
|
m_b_play->setEnabled(state);
|
||||||
@ -601,12 +618,15 @@ bool StatusBar::onProcessMessage(Message* msg)
|
|||||||
|
|
||||||
updateFromLayer();
|
updateFromLayer();
|
||||||
|
|
||||||
|
if (hasChild(m_notificationsBox))
|
||||||
|
removeChild(m_notificationsBox);
|
||||||
|
|
||||||
addChild(m_commandsBox);
|
addChild(m_commandsBox);
|
||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
else {
|
else if (!state && !hasChild(m_notificationsBox)) {
|
||||||
// Status text for donations
|
addChild(m_notificationsBox);
|
||||||
setStatusText(0, "Click the \"Donate\" button to support ASE development");
|
invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -696,14 +716,6 @@ bool StatusBar::onProcessMessage(Message* msg)
|
|||||||
invalidate();
|
invalidate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// Call "Donate" command
|
|
||||||
Command* donate = CommandsModule::instance()
|
|
||||||
->getCommandByName(CommandId::Donate);
|
|
||||||
|
|
||||||
Params params;
|
|
||||||
UIContext::instance()->executeCommand(donate, ¶ms);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (LockedDocumentException&) {
|
catch (LockedDocumentException&) {
|
||||||
// Do nothing...
|
// Do nothing...
|
||||||
@ -712,7 +724,7 @@ bool StatusBar::onProcessMessage(Message* msg)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case JM_MOUSELEAVE:
|
case JM_MOUSELEAVE:
|
||||||
if (this->hasChild(m_commandsBox)) {
|
if (hasChild(m_commandsBox)) {
|
||||||
// If we want restore the state-bar and the slider doesn't have
|
// If we want restore the state-bar and the slider doesn't have
|
||||||
// the capture...
|
// the capture...
|
||||||
if (jmanager_get_capture() != m_slider) {
|
if (jmanager_get_capture() != m_slider) {
|
||||||
@ -818,3 +830,4 @@ void StatusBar::updateFromLayer()
|
|||||||
m_slider->setEnabled(false);
|
m_slider->setEnabled(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,10 +20,12 @@
|
|||||||
#define WIDGETS_STATEBAR_H_INCLUDED
|
#define WIDGETS_STATEBAR_H_INCLUDED
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#include "app/color.h"
|
#include "app/color.h"
|
||||||
#include "base/compiler_specific.h"
|
#include "base/compiler_specific.h"
|
||||||
#include "gui/base.h"
|
#include "gui/base.h"
|
||||||
|
#include "gui/link_label.h"
|
||||||
#include "gui/widget.h"
|
#include "gui/widget.h"
|
||||||
#include "listeners.h"
|
#include "listeners.h"
|
||||||
|
|
||||||
@ -87,6 +89,9 @@ public:
|
|||||||
Progress* addProgress();
|
Progress* addProgress();
|
||||||
void removeProgress(Progress* progress);
|
void removeProgress(Progress* progress);
|
||||||
|
|
||||||
|
// Method to show notifications (each notification can contain a link).
|
||||||
|
void showNotification(const char* text, const char* link);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool onProcessMessage(Message* msg) OVERRIDE;
|
bool onProcessMessage(Message* msg) OVERRIDE;
|
||||||
|
|
||||||
@ -121,6 +126,10 @@ private:
|
|||||||
Button* m_b_next; // Go to next frame
|
Button* m_b_next; // Go to next frame
|
||||||
Button* m_b_last; // Go to last frame
|
Button* m_b_last; // Go to last frame
|
||||||
|
|
||||||
|
// Box of notifications.
|
||||||
|
Widget* m_notificationsBox;
|
||||||
|
LinkLabel* m_linkLabel;
|
||||||
|
|
||||||
// Box with move-pixels commands (when the user drag-and-drop selected pixels using the editor)
|
// Box with move-pixels commands (when the user drag-and-drop selected pixels using the editor)
|
||||||
Box* m_movePixelsBox;
|
Box* m_movePixelsBox;
|
||||||
Widget* m_transparentLabel;
|
Widget* m_transparentLabel;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user