Commit 9e495e6e authored by twanvl's avatar twanvl

Added Package::saveCopy, which is used to implement the write_set_file script function.

parent 04ad01be
...@@ -11,6 +11,11 @@ depends on: magic.mse-game 2008-05-18 ...@@ -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: option field:
type: choice type: choice
name: grouping name: grouping
...@@ -203,6 +208,9 @@ script: ...@@ -203,6 +208,9 @@ script:
<h1>{ to_html(set.title) }</h1> <h1>{ to_html(set.title) }</h1>
<div class='copyright'>{ to_html(set.copyright) }</div> <div class='copyright'>{ to_html(set.copyright) }</div>
<div class='description'>{ to_html(set.description) }</div> <div class='description'>{ to_html(set.description) }</div>
{ if options.include_set_file then
"<div class='set-file'><a href='{ write_set_file(file:"set.mse-set") }'>Download set in MSE format</a></div>"
}
{ if options.grouping == "group by color" then { if options.grouping == "group by color" then
# Codes as by sort_index # Codes as by sort_index
write_group(title: "White", code:"A") + write_group(title: "White", code:"A") +
......
...@@ -96,6 +96,7 @@ These functions are built into the program, other [[type:function]]s can be defi ...@@ -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: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_text_file]] Write a text file to the output directory.
| [[fun:write_image_file]] Write an image 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 <<< ! Other functions <<<
| [[fun:trace]] Output a message for debugging purposes. | [[fun:trace]] Output a message for debugging purposes.
......
...@@ -18,7 +18,7 @@ This function can only be used in an [[type:export template]], when <tt>create d ...@@ -18,7 +18,7 @@ This function can only be used in an [[type:export template]], when <tt>create d
| @height@ [[type:int]] Height in pixels to use for the image, by default the size of the image is used if available. | @height@ [[type:int]] Height in pixels to use for the image, by default the size of the image is used if available.
--Examples-- --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-- --See also--
| [[fun:write_text_file]] Write a text file to the output directory. | [[fun:write_text_file]] Write a text file to the output directory.
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 <tt>create directory</tt> 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.
...@@ -16,7 +16,7 @@ This function can only be used in an [[type:export template]], when <tt>create d ...@@ -16,7 +16,7 @@ This function can only be used in an [[type:export template]], when <tt>create d
| @file@ [[type:string]] Name of the file to write to | @file@ [[type:string]] Name of the file to write to
--Examples-- --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-- --See also--
| [[fun:write_image_file]] Write an image file to the output directory. | [[fun:write_image_file]] Write an image file to the output directory.
...@@ -48,12 +48,12 @@ String export_formats(const Game& game) { ...@@ -48,12 +48,12 @@ String export_formats(const Game& game) {
return type_strings; return type_strings;
} }
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) {
FileFormatP format = file_formats.at(format_type); FileFormatP format = file_formats.at(format_index);
if (!format->canExport(*set.game)) { if (!format->canExport(*set.game)) {
throw InternalError(_("File format doesn't apply to set")); throw InternalError(_("File format doesn't apply to set"));
} }
format->exportSet(set, filename); format->exportSet(set, filename, is_copy);
} }
SetP import_set(String name) { SetP import_set(String name) {
......
...@@ -37,7 +37,8 @@ class FileFormat : public IntrusivePtrVirtualBase { ...@@ -37,7 +37,8 @@ class FileFormat : public IntrusivePtrVirtualBase {
throw InternalError(_("Import not supported by this file format")); throw InternalError(_("Import not supported by this file format"));
} }
/// Export using this filter /// 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")); throw InternalError(_("Export not supported by this file format"));
} }
}; };
...@@ -71,9 +72,9 @@ String export_formats(const Game& game); ...@@ -71,9 +72,9 @@ String export_formats(const Game& game);
SetP import_set(String name); SetP import_set(String name);
/// Save a set under the specified 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 // ----------------------------------------------------------------------------- : The formats
......
...@@ -26,10 +26,14 @@ class MSE2FileFormat : public FileFormat { ...@@ -26,10 +26,14 @@ class MSE2FileFormat : public FileFormat {
settings.addRecentFile(filename); settings.addRecentFile(filename);
return set; return set;
} }
virtual void exportSet(Set& set, const String& filename) { virtual void exportSet(Set& set, const String& filename, bool is_copy) {
set.saveAs(filename); if (is_copy) {
settings.addRecentFile(filename); set.saveCopy(filename);
set.actions.setSavePoint(); } else {
set.saveAs(filename);
settings.addRecentFile(filename);
set.actions.setSavePoint();
}
} }
}; };
......
...@@ -431,6 +431,18 @@ SCRIPT_FUNCTION(write_image_file) { ...@@ -431,6 +431,18 @@ SCRIPT_FUNCTION(write_image_file) {
SCRIPT_RETURN(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 // ----------------------------------------------------------------------------- : Init
void init_script_export_functions(Context& ctx) { void init_script_export_functions(Context& ctx) {
...@@ -440,5 +452,5 @@ 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(_("copy file"), script_copy_file);
ctx.setVariable(_("write text file"), script_write_text_file); ctx.setVariable(_("write text file"), script_write_text_file);
ctx.setVariable(_("write image file"), script_write_image_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);
} }
...@@ -86,6 +86,18 @@ void Package::open(const String& n) { ...@@ -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) { void Package::save(bool remove_unused) {
assert(!needSaveAs()); assert(!needSaveAs());
saveAs(filename, remove_unused); saveAs(filename, remove_unused);
...@@ -94,11 +106,21 @@ void Package::save(bool remove_unused) { ...@@ -94,11 +106,21 @@ void Package::save(bool remove_unused) {
void Package::saveAs(const String& name, bool remove_unused) { void Package::saveAs(const String& name, bool remove_unused) {
// type of package // type of package
if (wxDirExists(name)) { if (wxDirExists(name)) {
saveToDirectory(name, remove_unused); saveToDirectory(name, remove_unused, false);
} else { } else {
saveToZipfile (name, remove_unused); saveToZipfile (name, remove_unused, false);
} }
filename = name; 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 // cleanup : remove temp files, remove deleted files from the list
FileInfos::iterator it = files.begin(); FileInfos::iterator it = files.begin();
while (it != files.end()) { while (it != files.end()) {
...@@ -108,9 +130,9 @@ void Package::saveAs(const String& name, bool remove_unused) { ...@@ -108,9 +130,9 @@ void Package::saveAs(const String& name, bool remove_unused) {
} }
if (!it->second.keep && remove_unused) { if (!it->second.keep && remove_unused) {
// also remove the record of deleted files // also remove the record of deleted files
FileInfos::iterator toRemove = it; FileInfos::iterator to_remove = it;
++it; ++it;
files.erase(toRemove); files.erase(to_remove);
} else { } else {
// free zip entry, we will reopen the file // free zip entry, we will reopen the file
it->second.keep = false; it->second.keep = false;
...@@ -120,13 +142,11 @@ void Package::saveAs(const String& name, bool remove_unused) { ...@@ -120,13 +142,11 @@ void Package::saveAs(const String& name, bool remove_unused) {
++it; ++it;
} }
} }
// reopen only needed for zipfile }
if (!wxDirExists(name)) {
openZipfile(); void Package::clearKeepFlag() {
} else { FOR_EACH(f, files) {
// make sure we have no zip open f.second.keep = false;
delete zipStream; zipStream = nullptr;
delete fileStream; fileStream = nullptr;
} }
} }
...@@ -356,7 +376,7 @@ void Package::openZipfile() { ...@@ -356,7 +376,7 @@ void Package::openZipfile() {
loadZipStream(); 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 // write to a directory
FOR_EACH(f, files) { FOR_EACH(f, files) {
if (!f.second.keep && remove_unused) { if (!f.second.keep && remove_unused) {
...@@ -366,7 +386,8 @@ void Package::saveToDirectory(const String& saveAs, bool remove_unused) { ...@@ -366,7 +386,8 @@ void Package::saveToDirectory(const String& saveAs, bool remove_unused) {
} else if (f.second.wasWritten()) { } else if (f.second.wasWritten()) {
// move files that were updated // move files that were updated
wxRemoveFile(saveAs+_("/")+f.first); 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")); throw PackageError(_ERROR_("unable to store file"));
} }
} else if (filename != saveAs) { } else if (filename != saveAs) {
...@@ -380,7 +401,7 @@ void Package::saveToDirectory(const String& saveAs, bool remove_unused) { ...@@ -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 // create a temporary zip file name
String tempFile = saveAs + _(".tmp"); String tempFile = saveAs + _(".tmp");
wxRemoveFile(tempFile); wxRemoveFile(tempFile);
...@@ -395,8 +416,9 @@ void Package::saveToZipfile(const String& saveAs, bool remove_unused) { ...@@ -395,8 +416,9 @@ void Package::saveToZipfile(const String& saveAs, bool remove_unused) {
FOR_EACH(f, files) { FOR_EACH(f, files) {
if (!f.second.keep && remove_unused) { if (!f.second.keep && remove_unused) {
// to remove a file simply don't copy it // 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 // old file, was also in zip, not changed
// can't do this when saving a copy, since it destroys the zip entry
zipStream->CloseEntry(); zipStream->CloseEntry();
newZip->CopyEntry(f.second.zipEntry, *zipStream); newZip->CopyEntry(f.second.zipEntry, *zipStream);
f.second.zipEntry = 0; f.second.zipEntry = 0;
...@@ -408,8 +430,10 @@ void Package::saveToZipfile(const String& saveAs, bool remove_unused) { ...@@ -408,8 +430,10 @@ void Package::saveToZipfile(const String& saveAs, bool remove_unused) {
} }
} }
// close the old file // close the old file
delete zipStream; zipStream = nullptr; if (!is_copy) {
delete fileStream; fileStream = nullptr; delete zipStream; zipStream = nullptr;
delete fileStream; fileStream = nullptr;
}
} catch (Error e) { } catch (Error e) {
// when things go wrong delete the temp file // when things go wrong delete the temp file
wxRemoveFile(tempFile); wxRemoveFile(tempFile);
...@@ -540,6 +564,12 @@ void Packaged::saveAs(const String& package, bool remove_unused) { ...@@ -540,6 +564,12 @@ void Packaged::saveAs(const String& package, bool remove_unused) {
referenceFile(typeName()); referenceFile(typeName());
Package::saveAs(package, remove_unused); 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) { void Packaged::validate(Version) {
// a default for the short name // a default for the short name
......
...@@ -83,6 +83,9 @@ class Package : public IntrusivePtrVirtualBase { ...@@ -83,6 +83,9 @@ class Package : public IntrusivePtrVirtualBase {
/// Saves the package under a different filename /// Saves the package under a different filename
void saveAs(const String& package, bool remove_unused = true); 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 // --------------------------------------------------- : Managing the inside of the package
...@@ -175,8 +178,11 @@ class Package : public IntrusivePtrVirtualBase { ...@@ -175,8 +178,11 @@ class Package : public IntrusivePtrVirtualBase {
void openDirectory(); void openDirectory();
void openSubdir(const String&); void openSubdir(const String&);
void openZipfile(); void openZipfile();
void saveToZipfile(const String&, bool); void reopen();
void saveToDirectory(const String&, bool); 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); FileInfos::iterator addFile(const String& file);
}; };
...@@ -219,6 +225,7 @@ class Packaged : public Package { ...@@ -219,6 +225,7 @@ class Packaged : public Package {
void loadFully(); void loadFully();
void save(); void save();
void saveAs(const String& package, bool remove_unused = true); 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 /// Check if this package lists a dependency on the given package
/** This is done to force people to fill in the dependencies */ /** This is done to force people to fill in the dependencies */
......
...@@ -87,6 +87,7 @@ $built_in_functions = array( ...@@ -87,6 +87,7 @@ $built_in_functions = array(
'copy_file' =>'', 'copy_file' =>'',
'write_text_file' =>'', 'write_text_file' =>'',
'write_image_file' =>'', 'write_image_file' =>'',
'write_set_file' =>'',
// other // other
'trace' =>'', 'trace' =>'',
'assert' =>'', 'assert' =>'',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment