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