mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-11 21:27:01 -04:00
Moved clean_filename to file_utils.cpp where it belongs;
Split up images exporting, and moved it to data/formats/image git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1085 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <util/prec.hpp>
|
#include <util/prec.hpp>
|
||||||
#include <util/error.hpp>
|
#include <util/error.hpp>
|
||||||
|
#include <data/settings.hpp>
|
||||||
|
|
||||||
class Game;
|
class Game;
|
||||||
DECLARE_POINTER_TYPE(Set);
|
DECLARE_POINTER_TYPE(Set);
|
||||||
@@ -85,6 +86,10 @@ FileFormatP mtg_editor_file_format();
|
|||||||
/// Export images for each card in a set to a list of files
|
/// Export images for each card in a set to a list of files
|
||||||
void export_images(Window* parent, const SetP& set);
|
void export_images(Window* parent, const SetP& set);
|
||||||
|
|
||||||
|
/// Export the image for each card in a list of cards
|
||||||
|
void export_images(const SetP& set, vector<CardP>& cards,
|
||||||
|
const String& path, const String& filename_template, FilenameConflicts conflicts);
|
||||||
|
|
||||||
/// Export the image of a single card
|
/// Export the image of a single card
|
||||||
void export_image(const SetP& set, const CardP& card, const String& filename);
|
void export_image(const SetP& set, const CardP& card, const String& filename);
|
||||||
|
|
||||||
|
|||||||
@@ -7,11 +7,16 @@
|
|||||||
// ----------------------------------------------------------------------------- : Includes
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
#include <util/prec.hpp>
|
#include <util/prec.hpp>
|
||||||
|
#include <util/tagged_string.hpp>
|
||||||
#include <data/format/formats.hpp>
|
#include <data/format/formats.hpp>
|
||||||
#include <data/set.hpp>
|
#include <data/set.hpp>
|
||||||
|
#include <data/card.hpp>
|
||||||
#include <data/stylesheet.hpp>
|
#include <data/stylesheet.hpp>
|
||||||
#include <data/settings.hpp>
|
#include <data/settings.hpp>
|
||||||
#include <render/card/viewer.hpp>
|
#include <render/card/viewer.hpp>
|
||||||
|
#include <wx/filename.h>
|
||||||
|
|
||||||
|
DECLARE_TYPEOF_COLLECTION(CardP);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Single card export
|
// ----------------------------------------------------------------------------- : Single card export
|
||||||
|
|
||||||
@@ -59,3 +64,30 @@ Bitmap export_bitmap(const SetP& set, const CardP& card) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Multiple card export
|
// ----------------------------------------------------------------------------- : Multiple card export
|
||||||
|
|
||||||
|
|
||||||
|
void export_images(const SetP& set, vector<CardP>& cards,
|
||||||
|
const String& path, const String& filename_template, FilenameConflicts conflicts)
|
||||||
|
{
|
||||||
|
wxBusyCursor busy;
|
||||||
|
// Script
|
||||||
|
ScriptP filename_script = parse(filename_template, nullptr, true);
|
||||||
|
// Path
|
||||||
|
wxFileName fn(path);
|
||||||
|
// Export
|
||||||
|
std::set<String> used; // for CONFLICT_NUMBER_OVERWRITE
|
||||||
|
FOR_EACH_CONST(card, cards) {
|
||||||
|
// filename for this card
|
||||||
|
Context& ctx = set->getContext(card);
|
||||||
|
String filename = clean_filename(untag(ctx.eval(*filename_script)->toString()));
|
||||||
|
if (!filename) continue; // no filename -> no saving
|
||||||
|
// full path
|
||||||
|
fn.SetFullName(filename);
|
||||||
|
// does the file exist?
|
||||||
|
if (!resolve_filename_conflicts(fn, conflicts, used)) continue;
|
||||||
|
// write image
|
||||||
|
filename = fn.GetFullPath();
|
||||||
|
used.insert(filename);
|
||||||
|
export_image(set, card, filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -57,50 +57,6 @@ ImagesExportWindow::ImagesExportWindow(Window* parent, const SetP& set)
|
|||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Exporting the images
|
// ----------------------------------------------------------------------------- : Exporting the images
|
||||||
|
|
||||||
void ExportCardImages::exportImages(const SetP& set, wxFileName& fn, const String& filename_template, FilenameConflicts conflicts) {
|
|
||||||
// Script
|
|
||||||
ScriptP filename_script = parse(filename_template, nullptr, true);
|
|
||||||
// Export
|
|
||||||
std::set<String> used; // for CONFLICT_NUMBER_OVERWRITE
|
|
||||||
FOR_EACH(card, set->cards) {
|
|
||||||
if (includeCard(card)) {
|
|
||||||
// filename for this card
|
|
||||||
Context& ctx = set->getContext(card);
|
|
||||||
String filename = untag(ctx.eval(*filename_script)->toString());
|
|
||||||
if (!filename) continue; // no filename -> no saving
|
|
||||||
// sanitize filename
|
|
||||||
fn.SetFullName(clean_filename(filename));
|
|
||||||
// does the file exist?
|
|
||||||
if (fn.FileExists()) {
|
|
||||||
// file exists, what to do?
|
|
||||||
switch (conflicts) {
|
|
||||||
case CONFLICT_KEEP_OLD: goto next_card;
|
|
||||||
case CONFLICT_OVERWRITE: break;
|
|
||||||
case CONFLICT_NUMBER: {
|
|
||||||
int i = 0;
|
|
||||||
String ext = fn.GetExt();
|
|
||||||
do {
|
|
||||||
fn.SetExt(String() << ++i << _(".") << ext);
|
|
||||||
} while(fn.FileExists());
|
|
||||||
}
|
|
||||||
case CONFLICT_NUMBER_OVERWRITE: {
|
|
||||||
int i = 0;
|
|
||||||
String ext = fn.GetExt();
|
|
||||||
while(used.find(fn.GetFullPath()) != used.end()) {
|
|
||||||
fn.SetExt(String() << ++i << _(".") << ext);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// write image
|
|
||||||
filename = fn.GetFullPath();
|
|
||||||
used.insert(filename);
|
|
||||||
export_image(set, card, filename);
|
|
||||||
}
|
|
||||||
next_card:;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImagesExportWindow::onOk(wxCommandEvent&) {
|
void ImagesExportWindow::onOk(wxCommandEvent&) {
|
||||||
// Update settings
|
// Update settings
|
||||||
GameSettings& gs = settings.gameSettingsFor(*set->game);
|
GameSettings& gs = settings.gameSettingsFor(*set->game);
|
||||||
@@ -114,17 +70,17 @@ void ImagesExportWindow::onOk(wxCommandEvent&) {
|
|||||||
String name = wxFileSelector(_TITLE_("export images"),_(""), _LABEL_("filename is ignored"),_(""),
|
String name = wxFileSelector(_TITLE_("export images"),_(""), _LABEL_("filename is ignored"),_(""),
|
||||||
_LABEL_("filename is ignored")+_("|*"), wxSAVE, this);
|
_LABEL_("filename is ignored")+_("|*"), wxSAVE, this);
|
||||||
if (name.empty()) return;
|
if (name.empty()) return;
|
||||||
wxFileName fn(name);
|
// Cards to export
|
||||||
|
vector<CardP> cards;
|
||||||
|
FOR_EACH(card, set->cards) {
|
||||||
|
if (isSelected(card)) cards.push_back(card);
|
||||||
|
}
|
||||||
// Export
|
// Export
|
||||||
exportImages(set, fn, gs.images_export_filename, gs.images_export_conflicts);
|
export_images(set, cards, name, gs.images_export_filename, gs.images_export_conflicts);
|
||||||
// Done
|
// Done
|
||||||
EndModal(wxID_OK);
|
EndModal(wxID_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ImagesExportWindow::includeCard(const CardP& card) const {
|
|
||||||
return isSelected(card);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(ImagesExportWindow,CardSelectWindow)
|
BEGIN_EVENT_TABLE(ImagesExportWindow,CardSelectWindow)
|
||||||
EVT_BUTTON (wxID_OK, ImagesExportWindow::onOk)
|
EVT_BUTTON (wxID_OK, ImagesExportWindow::onOk)
|
||||||
|
|||||||
@@ -12,24 +12,11 @@
|
|||||||
#include <util/prec.hpp>
|
#include <util/prec.hpp>
|
||||||
#include <gui/card_select_window.hpp>
|
#include <gui/card_select_window.hpp>
|
||||||
#include <data/settings.hpp>
|
#include <data/settings.hpp>
|
||||||
class wxFileName;
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : ImagesExportWindow
|
|
||||||
|
|
||||||
/// Export the cards in a set
|
|
||||||
class ExportCardImages {
|
|
||||||
public:
|
|
||||||
void exportImages(const SetP& set, wxFileName& filename, const String& filename_template, FilenameConflicts conflicts);
|
|
||||||
virtual ~ExportCardImages() {}
|
|
||||||
protected:
|
|
||||||
/// Should the given card be exported?
|
|
||||||
virtual bool includeCard(const CardP& card) const { return true; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : ImagesExportWindow
|
// ----------------------------------------------------------------------------- : ImagesExportWindow
|
||||||
|
|
||||||
/// A window for selecting a subset of the cards from a set to export to images
|
/// A window for selecting a subset of the cards from a set to export to images
|
||||||
class ImagesExportWindow : public CardSelectWindow, private ExportCardImages {
|
class ImagesExportWindow : public CardSelectWindow {
|
||||||
public:
|
public:
|
||||||
ImagesExportWindow(Window* parent, const SetP& set);
|
ImagesExportWindow(Window* parent, const SetP& set);
|
||||||
|
|
||||||
@@ -38,8 +25,6 @@ class ImagesExportWindow : public CardSelectWindow, private ExportCardImages {
|
|||||||
|
|
||||||
void onOk(wxCommandEvent&);
|
void onOk(wxCommandEvent&);
|
||||||
|
|
||||||
virtual bool includeCard(const CardP& card) const;
|
|
||||||
|
|
||||||
wxTextCtrl* format;
|
wxTextCtrl* format;
|
||||||
wxChoice* conflicts;
|
wxChoice* conflicts;
|
||||||
};
|
};
|
||||||
|
|||||||
+1
-4
@@ -18,7 +18,6 @@
|
|||||||
#include <cli/text_io_handler.hpp>
|
#include <cli/text_io_handler.hpp>
|
||||||
#include <gui/welcome_window.hpp>
|
#include <gui/welcome_window.hpp>
|
||||||
#include <gui/update_checker.hpp>
|
#include <gui/update_checker.hpp>
|
||||||
#include <gui/images_export_window.hpp>
|
|
||||||
#include <gui/packages_window.hpp>
|
#include <gui/packages_window.hpp>
|
||||||
#include <gui/set/window.hpp>
|
#include <gui/set/window.hpp>
|
||||||
#include <gui/symbol/window.hpp>
|
#include <gui/symbol/window.hpp>
|
||||||
@@ -220,10 +219,8 @@ int MSE::OnRun() {
|
|||||||
path += _("/x");
|
path += _("/x");
|
||||||
out = out.substr(pos + 1);
|
out = out.substr(pos + 1);
|
||||||
}
|
}
|
||||||
wxFileName fn(path);
|
|
||||||
// export
|
// export
|
||||||
ExportCardImages exporter;
|
export_images(set, set->cards, path, out, CONFLICT_NUMBER_OVERWRITE);
|
||||||
exporter.exportImages(set, fn, out, CONFLICT_NUMBER_OVERWRITE);
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
handle_error(_("Invalid command line argument:\n") + String(argv[1]));
|
handle_error(_("Invalid command line argument:\n") + String(argv[1]));
|
||||||
|
|||||||
@@ -36,6 +36,51 @@ bool ignore_file(const String& name) {
|
|||||||
return name == _("Thumbs.db"); // winXP explorer thumbnails
|
return name == _("Thumbs.db"); // winXP explorer thumbnails
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_filename_char(Char c) {
|
||||||
|
return isAlnum(c) || c == _(' ') || c == _('_') || c == _('-') || c == _('.');
|
||||||
|
}
|
||||||
|
|
||||||
|
String clean_filename(const String& name) {
|
||||||
|
String clean;
|
||||||
|
FOR_EACH_CONST(c, name) {
|
||||||
|
if (is_filename_char(c)) {
|
||||||
|
clean += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (clean.empty() || starts_with(clean, _("."))) {
|
||||||
|
clean = _("no-name") + clean;
|
||||||
|
}
|
||||||
|
return clean;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool resolve_filename_conflicts(wxFileName& fn, FilenameConflicts conflicts, set<String>& used) {
|
||||||
|
switch (conflicts) {
|
||||||
|
case CONFLICT_KEEP_OLD:
|
||||||
|
return !fn.FileExists();
|
||||||
|
case CONFLICT_OVERWRITE:
|
||||||
|
return true;
|
||||||
|
case CONFLICT_NUMBER: {
|
||||||
|
int i = 0;
|
||||||
|
String ext = fn.GetExt();
|
||||||
|
while(fn.FileExists()) {
|
||||||
|
fn.SetExt(String() << ++i << _(".") << ext);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
case CONFLICT_NUMBER_OVERWRITE: {
|
||||||
|
int i = 0;
|
||||||
|
String ext = fn.GetExt();
|
||||||
|
while(used.find(fn.GetFullPath()) != used.end()) {
|
||||||
|
fn.SetExt(String() << ++i << _(".") << ext);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw InternalError(_("resolve_filename_conflicts: default case"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Directories
|
// ----------------------------------------------------------------------------- : Directories
|
||||||
|
|
||||||
bool create_parent_dirs(const String& file) {
|
bool create_parent_dirs(const String& file) {
|
||||||
|
|||||||
+11
-1
@@ -10,6 +10,8 @@
|
|||||||
// ----------------------------------------------------------------------------- : Includes
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
#include <util/prec.hpp>
|
#include <util/prec.hpp>
|
||||||
|
#include <data/settings.hpp>
|
||||||
|
class wxFileName;
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : File names
|
// ----------------------------------------------------------------------------- : File names
|
||||||
|
|
||||||
@@ -19,9 +21,17 @@ String normalize_filename(const String& filename);
|
|||||||
/// Normalize a filename as much as possible, for files in packages
|
/// Normalize a filename as much as possible, for files in packages
|
||||||
String normalize_internal_filename(const String& filename);
|
String normalize_internal_filename(const String& filename);
|
||||||
|
|
||||||
/// Should a file with the given name be ignored?
|
/// Should a file with the given name be ignored in packages?
|
||||||
|
/** true for hidden OS and version control files */
|
||||||
bool ignore_file(const String& name);
|
bool ignore_file(const String& name);
|
||||||
|
|
||||||
|
/// Make sure a string is safe to use as a filename
|
||||||
|
String clean_filename(const String& name);
|
||||||
|
|
||||||
|
/// Change the filename fn if it already exists, in the way described by conflicts.
|
||||||
|
/** Returns true if the filename should be used, false if failed. */
|
||||||
|
bool resolve_filename_conflicts(wxFileName& fn, FilenameConflicts conflicts, set<String>& used);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Removing and renaming
|
// ----------------------------------------------------------------------------- : Removing and renaming
|
||||||
|
|
||||||
/// Ensure that the parent directories of the given filename exist
|
/// Ensure that the parent directories of the given filename exist
|
||||||
|
|||||||
@@ -397,25 +397,6 @@ bool cannocial_name_compare(const String& as, const Char* b) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Filenames
|
|
||||||
|
|
||||||
bool is_filename_char(Char c) {
|
|
||||||
return isAlnum(c) || c == _(' ') || c == _('_') || c == _('-') || c == _('.');
|
|
||||||
}
|
|
||||||
|
|
||||||
String clean_filename(const String& name) {
|
|
||||||
String clean;
|
|
||||||
FOR_EACH_CONST(c, name) {
|
|
||||||
if (is_filename_char(c)) {
|
|
||||||
clean += c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (clean.empty() || starts_with(clean, _("."))) {
|
|
||||||
clean = _("no-name") + clean;
|
|
||||||
}
|
|
||||||
return clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Regular expressions
|
// ----------------------------------------------------------------------------- : Regular expressions
|
||||||
|
|
||||||
/// Escape a single character for use in regular expressions
|
/// Escape a single character for use in regular expressions
|
||||||
|
|||||||
@@ -196,11 +196,6 @@ bool is_substr_i(const String& str, size_t pos, const String& cmp);
|
|||||||
/// Compare two strings for equality, b may contain '_' where a contains ' '
|
/// Compare two strings for equality, b may contain '_' where a contains ' '
|
||||||
bool cannocial_name_compare(const String& a, const Char* b);
|
bool cannocial_name_compare(const String& a, const Char* b);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Filenames
|
|
||||||
|
|
||||||
/// Make sure a string is safe to use as a filename
|
|
||||||
String clean_filename(const String& name);
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : Regular expressions
|
// ----------------------------------------------------------------------------- : Regular expressions
|
||||||
|
|
||||||
/// Escape a single character for use in regular expressions
|
/// Escape a single character for use in regular expressions
|
||||||
|
|||||||
Reference in New Issue
Block a user