From d91ca36eddc602493d87e4097685002ee965c081 Mon Sep 17 00:00:00 2001 From: David Capello Date: Tue, 5 Jul 2016 18:17:16 -0300 Subject: [PATCH] Add forward compatibility in .ase decoder for layer groups As v1.2 can save .ase files with groups, we have added support to make flat the file and move all layers to the top level, removing all groups. (Just in case the user want to go back to v1.1 after using v1.2 features.) --- src/app/file/ase_format.cpp | 80 ++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 2 deletions(-) diff --git a/src/app/file/ase_format.cpp b/src/app/file/ase_format.cpp index 07c992f1a..aae44646c 100644 --- a/src/app/file/ase_format.cpp +++ b/src/app/file/ase_format.cpp @@ -1,5 +1,5 @@ // Aseprite -// Copyright (C) 2001-2015 David Capello +// Copyright (C) 2001-2016 David Capello // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as @@ -9,6 +9,7 @@ #include "config.h" #endif +#include "app/context.h" #include "app/document.h" #include "app/file/file.h" #include "app/file/file_format.h" @@ -16,10 +17,12 @@ #include "base/cfile.h" #include "base/exception.h" #include "base/file_handle.h" +#include "base/path.h" #include "doc/doc.h" +#include "ui/alert.h" #include "zlib.h" -#include +#include #define ASE_FILE_MAGIC 0xA5E0 #define ASE_FILE_FRAME_MAGIC 0xF1FA @@ -122,6 +125,8 @@ static void ase_file_read_frame_tags_chunk(FILE* f, FrameTags* frameTags); static void ase_file_write_frame_tags_chunk(FILE* f, ASE_FrameHeader* frame_header, const FrameTags* frameTags); static void ase_file_read_user_data_chunk(FILE* f, UserData* userData); static void ase_file_write_user_data_chunk(FILE* f, ASE_FrameHeader* frame_header, const UserData* userData); +static bool ase_has_groups(LayerFolder* layer); +static void ase_ungroup_all(LayerFolder* layer); class ChunkWriter { public: @@ -159,6 +164,7 @@ class AseFormat : public FileFormat { } bool onLoad(FileOp* fop) override; + bool onPostLoad(FileOp* fop) override; #ifdef ENABLE_SAVE bool onSave(FileOp* fop) override; #endif @@ -327,6 +333,34 @@ bool AseFormat::onLoad(FileOp* fop) } } +bool AseFormat::onPostLoad(FileOp* fop) +{ + LayerFolder* folder = fop->document()->sprite()->folder(); + + // Forward Compatibility: In 1.1 we convert a file with layer groups + // (saved with 1.2) as top level layers + std::string ver = VERSION; + bool flat = (ver[0] == '1' && + ver[1] == '.' && + ver[2] == '1'); + if (flat && ase_has_groups(folder)) { + if (fop->context() && + fop->context()->isUIAvailable() && + ui::Alert::show("Warning" + "<filename()).c_str(), + PACKAGE, ver.c_str()) != 1) { + return false; + } + ase_ungroup_all(folder); + } + return true; +} + #ifdef ENABLE_SAVE bool AseFormat::onSave(FileOp* fop) @@ -1497,4 +1531,46 @@ static void ase_file_write_user_data_chunk(FILE* f, ASE_FrameHeader* frame_heade } } +static bool ase_has_groups(LayerFolder* folder) +{ + for (Layer* child : folder->getLayersList()) { + if (child->isFolder()) + return true; + } + return false; +} + +static void ase_ungroup_all(LayerFolder* folder) +{ + LayerFolder* root = folder->sprite()->folder(); + LayerList list = folder->getLayersList(); + + for (Layer* child : list) { + if (child->isFolder()) { + ase_ungroup_all(static_cast(child)); + folder->removeLayer(child); + } + else if (folder != root) { + // Create a new name adding all group layer names + { + std::string name; + for (Layer* layer=child; layer!=root; layer=layer->parent()) { + if (!name.empty()) + name.insert(0, "-"); + name.insert(0, layer->name()); + } + child->setName(name); + } + + folder->removeLayer(child); + root->addLayer(child); + } + } + + if (folder != root) { + ASSERT(folder->getLayersCount() == 0); + delete folder; + } +} + } // namespace app