mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-14 13:21:34 +00:00
Show alert when we upgrade an existent extension
This commit is contained in:
parent
19f6dcfc58
commit
4ccecdeda2
@ -24,6 +24,8 @@
|
||||
#include "base/bind.h"
|
||||
#include "base/convert_to.h"
|
||||
#include "base/fs.h"
|
||||
#include "base/string.h"
|
||||
#include "base/version.h"
|
||||
#include "doc/image.h"
|
||||
#include "render/render.h"
|
||||
#include "she/display.h"
|
||||
@ -76,6 +78,8 @@ class OptionsWindow : public app::gen::Options {
|
||||
setEnabled(extension->isEnabled());
|
||||
}
|
||||
|
||||
Extension* extension() { return m_extension; }
|
||||
|
||||
bool isEnabled() const {
|
||||
ASSERT(m_extension);
|
||||
return m_extension->isEnabled();
|
||||
@ -725,12 +729,51 @@ private:
|
||||
|
||||
ASSERT(!filename.empty());
|
||||
|
||||
Extensions& exts = App::instance()->extensions();
|
||||
ExtensionInfo info = exts.getCompressedExtensionInfo(filename.front());
|
||||
|
||||
// Check if the extension already exist
|
||||
for (auto ext : exts) {
|
||||
if (base::string_to_lower(ext->name()) !=
|
||||
base::string_to_lower(info.name))
|
||||
continue;
|
||||
|
||||
bool isDowngrade =
|
||||
base::Version(info.version.c_str()) <
|
||||
base::Version(ext->version().c_str());
|
||||
|
||||
// Uninstall?
|
||||
if (ui::Alert::show(
|
||||
"Update Extension"
|
||||
"<<The extension '%s' already exists."
|
||||
"<<Do you want to %s from v%s to v%s?"
|
||||
"||&Yes||&No",
|
||||
ext->name().c_str(),
|
||||
(isDowngrade ? "downgrade": "upgrade"),
|
||||
ext->version().c_str(),
|
||||
info.version.c_str()) != 1)
|
||||
return;
|
||||
|
||||
// Uninstall old version
|
||||
if (ext->canBeUninstalled()) {
|
||||
exts.uninstallExtension(ext);
|
||||
|
||||
ExtensionItem* item = getItemByExtension(ext);
|
||||
if (item)
|
||||
deleteExtensionItem(item);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
Extension* extension =
|
||||
App::instance()->extensions().installCompressedExtension(filename.front());
|
||||
Extension* ext =
|
||||
exts.installCompressedExtension(filename.front(), info);
|
||||
|
||||
// Enable extension
|
||||
exts.enableExtension(ext, true);
|
||||
|
||||
// Add the new extension in the listbox
|
||||
ExtensionItem* item = new ExtensionItem(extension);
|
||||
ExtensionItem* item = new ExtensionItem(ext);
|
||||
extensionsList()->addChild(item);
|
||||
extensionsList()->selectChild(item);
|
||||
extensionsList()->layout();
|
||||
@ -762,18 +805,29 @@ private:
|
||||
|
||||
try {
|
||||
item->uninstall();
|
||||
|
||||
// Remove the item from the list
|
||||
extensionsList()->removeChild(item);
|
||||
extensionsList()->layout();
|
||||
|
||||
item->deferDelete();
|
||||
deleteExtensionItem(item);
|
||||
}
|
||||
catch (std::exception& ex) {
|
||||
Console::showException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
void deleteExtensionItem(ExtensionItem* item) {
|
||||
// Remove the item from the list
|
||||
extensionsList()->removeChild(item);
|
||||
extensionsList()->layout();
|
||||
item->deferDelete();
|
||||
}
|
||||
|
||||
ExtensionItem* getItemByExtension(Extension* ext) {
|
||||
for (auto child : extensionsList()->children()) {
|
||||
ExtensionItem* item = dynamic_cast<ExtensionItem*>(child);
|
||||
if (item && item->extension() == ext)
|
||||
return item;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void onOpenExtensionFolder() {
|
||||
ExtensionItem* item = dynamic_cast<ExtensionItem*>(extensionsList()->getSelectedChild());
|
||||
if (item)
|
||||
|
@ -175,11 +175,13 @@ void Extension::DitheringMatrixInfo::destroyMatrix()
|
||||
|
||||
Extension::Extension(const std::string& path,
|
||||
const std::string& name,
|
||||
const std::string& version,
|
||||
const std::string& displayName,
|
||||
const bool isEnabled,
|
||||
const bool isBuiltinExtension)
|
||||
: m_path(path)
|
||||
, m_name(name)
|
||||
, m_version(version)
|
||||
, m_displayName(displayName)
|
||||
, m_isEnabled(isEnabled)
|
||||
, m_isInstalled(true)
|
||||
@ -418,45 +420,58 @@ void Extensions::uninstallExtension(Extension* extension)
|
||||
{
|
||||
extension->uninstall();
|
||||
generateExtensionSignals(extension);
|
||||
|
||||
auto it = std::find(m_extensions.begin(),
|
||||
m_extensions.end(), extension);
|
||||
ASSERT(it != m_extensions.end());
|
||||
if (it != m_extensions.end())
|
||||
m_extensions.erase(it);
|
||||
|
||||
delete extension;
|
||||
}
|
||||
|
||||
Extension* Extensions::installCompressedExtension(const std::string& zipFn)
|
||||
ExtensionInfo Extensions::getCompressedExtensionInfo(const std::string& zipFn)
|
||||
{
|
||||
std::string dstExtensionPath =
|
||||
ExtensionInfo info;
|
||||
info.dstPath =
|
||||
base::join_path(m_userExtensionsPath,
|
||||
base::get_file_title(zipFn));
|
||||
|
||||
// First of all we read the package.json file inside the .zip to
|
||||
// know 1) the extension name, 2) that the .json file can be parsed
|
||||
// correctly, 3) the final destination directory.
|
||||
std::string commonPath;
|
||||
{
|
||||
ReadArchive in(zipFn);
|
||||
archive_entry* entry;
|
||||
while ((entry = in.readEntry()) != nullptr) {
|
||||
const std::string entryFn = archive_entry_pathname(entry);
|
||||
if (base::get_file_name(entryFn) != kPackageJson)
|
||||
continue;
|
||||
ReadArchive in(zipFn);
|
||||
archive_entry* entry;
|
||||
while ((entry = in.readEntry()) != nullptr) {
|
||||
const std::string entryFn = archive_entry_pathname(entry);
|
||||
if (base::get_file_name(entryFn) != kPackageJson)
|
||||
continue;
|
||||
|
||||
commonPath = base::get_file_path(entryFn);
|
||||
if (!commonPath.empty() &&
|
||||
entryFn.size() > commonPath.size())
|
||||
commonPath.push_back(entryFn[commonPath.size()]);
|
||||
|
||||
std::stringstream out;
|
||||
in.copyDataTo(out);
|
||||
|
||||
std::string err;
|
||||
auto json = json11::Json::parse(out.str(), err);
|
||||
if (err.empty()) {
|
||||
auto name = json["name"].string_value();
|
||||
dstExtensionPath = base::join_path(m_userExtensionsPath, name);
|
||||
}
|
||||
break;
|
||||
info.commonPath = base::get_file_path(entryFn);
|
||||
if (!info.commonPath.empty() &&
|
||||
entryFn.size() > info.commonPath.size()) {
|
||||
info.commonPath.push_back(entryFn[info.commonPath.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
// Uncompress zipFn in dstExtensionPath
|
||||
std::stringstream out;
|
||||
in.copyDataTo(out);
|
||||
|
||||
std::string err;
|
||||
auto json = json11::Json::parse(out.str(), err);
|
||||
if (err.empty()) {
|
||||
info.name = json["name"].string_value();
|
||||
info.version = json["version"].string_value();
|
||||
info.dstPath = base::join_path(m_userExtensionsPath, info.name);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
Extension* Extensions::installCompressedExtension(const std::string& zipFn,
|
||||
const ExtensionInfo& info)
|
||||
{
|
||||
// Uncompress zipFn in info.dstPath
|
||||
{
|
||||
ReadArchive in(zipFn);
|
||||
WriteArchive out;
|
||||
@ -468,17 +483,17 @@ Extension* Extensions::installCompressedExtension(const std::string& zipFn)
|
||||
|
||||
LOG("EXT: Original filename in zip <%s>...\n", fn.c_str());
|
||||
|
||||
if (!commonPath.empty()) {
|
||||
if (!info.commonPath.empty()) {
|
||||
// Check mismatch with package.json common path
|
||||
if (fn.compare(0, commonPath.size(), commonPath) != 0)
|
||||
if (fn.compare(0, info.commonPath.size(), info.commonPath) != 0)
|
||||
continue;
|
||||
|
||||
fn.erase(0, commonPath.size());
|
||||
fn.erase(0, info.commonPath.size());
|
||||
if (fn.empty())
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string fullFn = base::join_path(dstExtensionPath, fn);
|
||||
const std::string fullFn = base::join_path(info.dstPath, fn);
|
||||
archive_entry_set_pathname(entry, fullFn.c_str());
|
||||
|
||||
LOG("EXT: Uncompressing file <%s> to <%s>\n",
|
||||
@ -489,8 +504,8 @@ Extension* Extensions::installCompressedExtension(const std::string& zipFn)
|
||||
}
|
||||
|
||||
Extension* extension = loadExtension(
|
||||
dstExtensionPath,
|
||||
base::join_path(dstExtensionPath, kPackageJson),
|
||||
info.dstPath,
|
||||
base::join_path(info.dstPath, kPackageJson),
|
||||
false);
|
||||
if (!extension)
|
||||
throw base::Exception("Error adding the new extension");
|
||||
@ -522,6 +537,7 @@ Extension* Extensions::loadExtension(const std::string& path,
|
||||
err.c_str());
|
||||
}
|
||||
auto name = json["name"].string_value();
|
||||
auto version = json["version"].string_value();
|
||||
auto displayName = json["displayName"].string_value();
|
||||
|
||||
LOG("EXT: Extension '%s' loaded\n", name.c_str());
|
||||
@ -529,6 +545,7 @@ Extension* Extensions::loadExtension(const std::string& path,
|
||||
base::UniquePtr<Extension> extension(
|
||||
new Extension(path,
|
||||
name,
|
||||
version,
|
||||
displayName,
|
||||
// Extensions are enabled by default
|
||||
get_config_bool("extensions", name.c_str(), true),
|
||||
|
@ -27,6 +27,13 @@ namespace app {
|
||||
|
||||
class Extensions;
|
||||
|
||||
struct ExtensionInfo {
|
||||
std::string name;
|
||||
std::string version;
|
||||
std::string dstPath;
|
||||
std::string commonPath;
|
||||
};
|
||||
|
||||
class Extension {
|
||||
friend class Extensions;
|
||||
public:
|
||||
@ -49,6 +56,7 @@ namespace app {
|
||||
|
||||
Extension(const std::string& path,
|
||||
const std::string& name,
|
||||
const std::string& version,
|
||||
const std::string& displayName,
|
||||
const bool isEnabled,
|
||||
const bool isBuiltinExtension);
|
||||
@ -56,6 +64,7 @@ namespace app {
|
||||
|
||||
const std::string& path() const { return m_path; }
|
||||
const std::string& name() const { return m_name; }
|
||||
const std::string& version() const { return m_version; }
|
||||
const std::string& displayName() const { return m_displayName; }
|
||||
|
||||
const ExtensionItems& themes() const { return m_themes; }
|
||||
@ -88,6 +97,7 @@ namespace app {
|
||||
std::map<std::string, DitheringMatrixInfo> m_ditheringMatrices;
|
||||
std::string m_path;
|
||||
std::string m_name;
|
||||
std::string m_version;
|
||||
std::string m_displayName;
|
||||
bool m_isEnabled;
|
||||
bool m_isInstalled;
|
||||
@ -107,7 +117,9 @@ namespace app {
|
||||
|
||||
void enableExtension(Extension* extension, const bool state);
|
||||
void uninstallExtension(Extension* extension);
|
||||
Extension* installCompressedExtension(const std::string& zipFn);
|
||||
ExtensionInfo getCompressedExtensionInfo(const std::string& zipFn);
|
||||
Extension* installCompressedExtension(const std::string& zipFn,
|
||||
const ExtensionInfo& info);
|
||||
|
||||
std::string themePath(const std::string& themeId);
|
||||
std::string palettePath(const std::string& palId);
|
||||
|
Loading…
x
Reference in New Issue
Block a user