From 42d40dbd1ecfc4607222fcdea1db62de21829040 Mon Sep 17 00:00:00 2001 From: twanvl Date: Sun, 24 Aug 2008 19:48:51 +0000 Subject: [PATCH] Added Package::saveCopy, which is used to implement the write_set_file script function. git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1169 0fc631ac-6414-0410-93d0-97cfa31319b6 --- .../export-template | 8 +++ doc/function/index.txt | 1 + doc/function/write_image_file.txt | 2 +- doc/function/write_set_file.txt | 23 +++++++ doc/function/write_text_file.txt | 2 +- src/data/format/formats.cpp | 6 +- src/data/format/formats.hpp | 7 +- src/data/format/mse2.cpp | 12 ++-- src/script/functions/export.cpp | 14 +++- src/util/io/package.cpp | 64 ++++++++++++++----- src/util/io/package.hpp | 11 +++- .../drupal/mse-drupal-modules/highlight.inc | 1 + 12 files changed, 119 insertions(+), 32 deletions(-) create mode 100644 doc/function/write_set_file.txt diff --git a/data/magic-spoiler.mse-export-template/export-template b/data/magic-spoiler.mse-export-template/export-template index bacfa52b..da1673c4 100644 --- a/data/magic-spoiler.mse-export-template/export-template +++ b/data/magic-spoiler.mse-export-template/export-template @@ -11,6 +11,11 @@ depends on: magic.mse-game 2008-05-18 ######################################################################################## +option field: + type: boolean + name: include set file + description: Should a link to the MSE set file be included in the spoiler? + initial: no option field: type: choice name: grouping @@ -203,6 +208,9 @@ script:

{ to_html(set.title) }

{ to_html(set.description) }
+ { if options.include_set_file then + "
Download set in MSE format
" + } { if options.grouping == "group by color" then # Codes as by sort_index write_group(title: "White", code:"A") + diff --git a/doc/function/index.txt b/doc/function/index.txt index 5a7b4ab9..01a98bd5 100644 --- a/doc/function/index.txt +++ b/doc/function/index.txt @@ -96,6 +96,7 @@ These functions are built into the program, other [[type:function]]s can be defi | [[fun:copy_file]] Copy a file from the [[type:export template]] to the output directory. | [[fun:write_text_file]] Write a text file to the output directory. | [[fun:write_image_file]] Write an image file to the output directory. +| [[fun:write_set_file]] Write a MSE set file to the output directory. ! Other functions <<< | [[fun:trace]] Output a message for debugging purposes. diff --git a/doc/function/write_image_file.txt b/doc/function/write_image_file.txt index a454b623..19de6c8d 100644 --- a/doc/function/write_image_file.txt +++ b/doc/function/write_image_file.txt @@ -18,7 +18,7 @@ This function can only be used in an [[type:export template]], when create d | @height@ [[type:int]] Height in pixels to use for the image, by default the size of the image is used if available. --Examples-- -> write_image("image_out.png", linear_blend(...)) == "image_out.png" # image_out.png now contains the given image +> write_image_file(file:"image_out.png", linear_blend(...)) == "image_out.png" # image_out.png now contains the given image --See also-- | [[fun:write_text_file]] Write a text file to the output directory. diff --git a/doc/function/write_set_file.txt b/doc/function/write_set_file.txt new file mode 100644 index 00000000..3b4e4aef --- /dev/null +++ b/doc/function/write_set_file.txt @@ -0,0 +1,23 @@ +Function: write_set_file + +--Usage-- +> write_set_file(set:the_set, file: filename) + +Write the current set to a file in the output directory. +If a file with the given name already exists it is overwritten. + +Returns the name of the file written. + +This function can only be used in an [[type:export template]], when create directory is true. + +--Parameters-- +! Parameter Type Description +| @set@ [[type:set]] Set to write to the file. +| @file@ [[type:string]] Name of the file to write to + +--Examples-- +> write_set_file(file:"the-set.mse-set") == "the-set.mse-set" # the-set.mse-set now contains the set + +--See also-- +| [[fun:write_image_file]] Write an image file to the output directory. +| [[fun:write_text_file]] Write a text file to the output directory. diff --git a/doc/function/write_text_file.txt b/doc/function/write_text_file.txt index fc578c6a..de2c7d0b 100644 --- a/doc/function/write_text_file.txt +++ b/doc/function/write_text_file.txt @@ -16,7 +16,7 @@ This function can only be used in an [[type:export template]], when create d | @file@ [[type:string]] Name of the file to write to --Examples-- -> write_file("index.html", lots_of_html_code) == "index.html" # index.html now contains the given text +> write_text_file(file:"index.html", lots_of_html_code) == "index.html" # index.html now contains the given text --See also-- | [[fun:write_image_file]] Write an image file to the output directory. diff --git a/src/data/format/formats.cpp b/src/data/format/formats.cpp index 1bc83b1d..b8bdd556 100644 --- a/src/data/format/formats.cpp +++ b/src/data/format/formats.cpp @@ -48,12 +48,12 @@ String export_formats(const Game& game) { return type_strings; } -void export_set(Set& set, const String& filename, size_t format_type) { - FileFormatP format = file_formats.at(format_type); +void export_set(Set& set, const String& filename, size_t format_index, bool is_copy) { + FileFormatP format = file_formats.at(format_index); if (!format->canExport(*set.game)) { throw InternalError(_("File format doesn't apply to set")); } - format->exportSet(set, filename); + format->exportSet(set, filename, is_copy); } SetP import_set(String name) { diff --git a/src/data/format/formats.hpp b/src/data/format/formats.hpp index 7b456155..312c753b 100644 --- a/src/data/format/formats.hpp +++ b/src/data/format/formats.hpp @@ -37,7 +37,8 @@ class FileFormat : public IntrusivePtrVirtualBase { throw InternalError(_("Import not supported by this file format")); } /// Export using this filter - virtual void exportSet(Set& set, const String& filename) { + /** If is_copy, then the set should not be modified */ + virtual void exportSet(Set& set, const String& filename, bool is_copy = false) { throw InternalError(_("Export not supported by this file format")); } }; @@ -71,9 +72,9 @@ String export_formats(const Game& game); SetP import_set(String name); /// Save a set under the specified name. -/** filterType specifies what format to use for saving, used as index in the list of file formats +/** format_index specifies what format to use for saving, used as index in the list of file formats */ -void export_set(Set& set, const String& filename, size_t format_type); +void export_set(Set& set, const String& filename, size_t format_index, bool is_copy = false); // ----------------------------------------------------------------------------- : The formats diff --git a/src/data/format/mse2.cpp b/src/data/format/mse2.cpp index 8f7ae735..4e306ee5 100644 --- a/src/data/format/mse2.cpp +++ b/src/data/format/mse2.cpp @@ -26,10 +26,14 @@ class MSE2FileFormat : public FileFormat { settings.addRecentFile(filename); return set; } - virtual void exportSet(Set& set, const String& filename) { - set.saveAs(filename); - settings.addRecentFile(filename); - set.actions.setSavePoint(); + virtual void exportSet(Set& set, const String& filename, bool is_copy) { + if (is_copy) { + set.saveCopy(filename); + } else { + set.saveAs(filename); + settings.addRecentFile(filename); + set.actions.setSavePoint(); + } } }; diff --git a/src/script/functions/export.cpp b/src/script/functions/export.cpp index f0b42f32..4de6d517 100644 --- a/src/script/functions/export.cpp +++ b/src/script/functions/export.cpp @@ -431,6 +431,18 @@ SCRIPT_FUNCTION(write_image_file) { SCRIPT_RETURN(file); } +SCRIPT_FUNCTION(write_set_file) { + guard_export_info(_("write_set_file")); + // output path + SCRIPT_PARAM(String, file); // file to write to + String out_path = get_export_full_path(file); + // export + SCRIPT_PARAM_C(Set*, set); + set->saveCopy(out_path); // TODO: use export_set instead? + SCRIPT_RETURN(file); + +} + // ----------------------------------------------------------------------------- : Init void init_script_export_functions(Context& ctx) { @@ -440,5 +452,5 @@ void init_script_export_functions(Context& ctx) { ctx.setVariable(_("copy file"), script_copy_file); ctx.setVariable(_("write text file"), script_write_text_file); ctx.setVariable(_("write image file"), script_write_image_file); - //ctx.setVariable(_("write set file"), script_write_set_file);//TODO + ctx.setVariable(_("write set file"), script_write_set_file); } diff --git a/src/util/io/package.cpp b/src/util/io/package.cpp index 2bf8f22d..0bc59cd8 100644 --- a/src/util/io/package.cpp +++ b/src/util/io/package.cpp @@ -86,6 +86,18 @@ void Package::open(const String& n) { } } +void Package::reopen() { + if (wxDirExists(filename)) { + // make sure we have no zip open + delete zipStream; zipStream = nullptr; + delete fileStream; fileStream = nullptr; + } else { + // reopen only needed for zipfile + openZipfile(); + } +} + + void Package::save(bool remove_unused) { assert(!needSaveAs()); saveAs(filename, remove_unused); @@ -94,11 +106,21 @@ void Package::save(bool remove_unused) { void Package::saveAs(const String& name, bool remove_unused) { // type of package if (wxDirExists(name)) { - saveToDirectory(name, remove_unused); + saveToDirectory(name, remove_unused, false); } else { - saveToZipfile (name, remove_unused); + saveToZipfile (name, remove_unused, false); } filename = name; + removeTempFiles(remove_unused); + reopen(); +} + +void Package::saveCopy(const String& name) { + saveToZipfile(name, true, true); + clearKeepFlag(); +} + +void Package::removeTempFiles(bool remove_unused) { // cleanup : remove temp files, remove deleted files from the list FileInfos::iterator it = files.begin(); while (it != files.end()) { @@ -108,9 +130,9 @@ void Package::saveAs(const String& name, bool remove_unused) { } if (!it->second.keep && remove_unused) { // also remove the record of deleted files - FileInfos::iterator toRemove = it; + FileInfos::iterator to_remove = it; ++it; - files.erase(toRemove); + files.erase(to_remove); } else { // free zip entry, we will reopen the file it->second.keep = false; @@ -120,13 +142,11 @@ void Package::saveAs(const String& name, bool remove_unused) { ++it; } } - // reopen only needed for zipfile - if (!wxDirExists(name)) { - openZipfile(); - } else { - // make sure we have no zip open - delete zipStream; zipStream = nullptr; - delete fileStream; fileStream = nullptr; +} + +void Package::clearKeepFlag() { + FOR_EACH(f, files) { + f.second.keep = false; } } @@ -356,7 +376,7 @@ void Package::openZipfile() { loadZipStream(); } -void Package::saveToDirectory(const String& saveAs, bool remove_unused) { +void Package::saveToDirectory(const String& saveAs, bool remove_unused, bool is_copy) { // write to a directory FOR_EACH(f, files) { if (!f.second.keep && remove_unused) { @@ -366,7 +386,8 @@ void Package::saveToDirectory(const String& saveAs, bool remove_unused) { } else if (f.second.wasWritten()) { // move files that were updated wxRemoveFile(saveAs+_("/")+f.first); - if (!wxRenameFile(f.second.tempName, saveAs+_("/")+f.first)) { + if (!(is_copy ? wxCopyFile (f.second.tempName, saveAs+_("/")+f.first) + : wxRenameFile(f.second.tempName, saveAs+_("/")+f.first))) { throw PackageError(_ERROR_("unable to store file")); } } else if (filename != saveAs) { @@ -380,7 +401,7 @@ void Package::saveToDirectory(const String& saveAs, bool remove_unused) { } } -void Package::saveToZipfile(const String& saveAs, bool remove_unused) { +void Package::saveToZipfile(const String& saveAs, bool remove_unused, bool is_copy) { // create a temporary zip file name String tempFile = saveAs + _(".tmp"); wxRemoveFile(tempFile); @@ -395,8 +416,9 @@ void Package::saveToZipfile(const String& saveAs, bool remove_unused) { FOR_EACH(f, files) { if (!f.second.keep && remove_unused) { // to remove a file simply don't copy it - } else if (f.second.zipEntry && !f.second.wasWritten()) { + } else if (!is_copy && f.second.zipEntry && !f.second.wasWritten()) { // old file, was also in zip, not changed + // can't do this when saving a copy, since it destroys the zip entry zipStream->CloseEntry(); newZip->CopyEntry(f.second.zipEntry, *zipStream); f.second.zipEntry = 0; @@ -408,8 +430,10 @@ void Package::saveToZipfile(const String& saveAs, bool remove_unused) { } } // close the old file - delete zipStream; zipStream = nullptr; - delete fileStream; fileStream = nullptr; + if (!is_copy) { + delete zipStream; zipStream = nullptr; + delete fileStream; fileStream = nullptr; + } } catch (Error e) { // when things go wrong delete the temp file wxRemoveFile(tempFile); @@ -540,6 +564,12 @@ void Packaged::saveAs(const String& package, bool remove_unused) { referenceFile(typeName()); Package::saveAs(package, remove_unused); } +void Packaged::saveCopy(const String& package) { + WITH_DYNAMIC_ARG(writing_package, this); + writeFile(typeName(), *this, fileVersion()); + referenceFile(typeName()); + Package::saveCopy(package); +} void Packaged::validate(Version) { // a default for the short name diff --git a/src/util/io/package.hpp b/src/util/io/package.hpp index 70692040..4513542a 100644 --- a/src/util/io/package.hpp +++ b/src/util/io/package.hpp @@ -83,6 +83,9 @@ class Package : public IntrusivePtrVirtualBase { /// Saves the package under a different filename void saveAs(const String& package, bool remove_unused = true); + /// Saves the package under a different filename, but keep the old one open + void saveCopy(const String& package); + // --------------------------------------------------- : Managing the inside of the package @@ -175,8 +178,11 @@ class Package : public IntrusivePtrVirtualBase { void openDirectory(); void openSubdir(const String&); void openZipfile(); - void saveToZipfile(const String&, bool); - void saveToDirectory(const String&, bool); + void reopen(); + void removeTempFiles(bool remove_unused); + void clearKeepFlag(); + void saveToZipfile(const String&, bool remove_unused, bool is_copy); + void saveToDirectory(const String&, bool remove_unused, bool is_copy); FileInfos::iterator addFile(const String& file); }; @@ -219,6 +225,7 @@ class Packaged : public Package { void loadFully(); void save(); void saveAs(const String& package, bool remove_unused = true); + void saveCopy(const String& package); /// Check if this package lists a dependency on the given package /** This is done to force people to fill in the dependencies */ diff --git a/tools/website/drupal/mse-drupal-modules/highlight.inc b/tools/website/drupal/mse-drupal-modules/highlight.inc index 654fb594..162f87d8 100644 --- a/tools/website/drupal/mse-drupal-modules/highlight.inc +++ b/tools/website/drupal/mse-drupal-modules/highlight.inc @@ -87,6 +87,7 @@ $built_in_functions = array( 'copy_file' =>'', 'write_text_file' =>'', 'write_image_file' =>'', + 'write_set_file' =>'', // other 'trace' =>'', 'assert' =>'',