mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
implemented import formats
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@102 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -42,6 +42,18 @@ class Card {
|
||||
/** May return "" */
|
||||
String identification() const;
|
||||
|
||||
/// Find a value in the data by name and type
|
||||
template <typename T> T& value(const String& name) {
|
||||
for(IndexMap<FieldP, ValueP>::iterator it = data.begin() ; it != data.end() ; ++it) {
|
||||
if ((*it)->fieldP->name == name) {
|
||||
T* ret = dynamic_cast<T*>(it->get());
|
||||
if (!ret) throw InternalError(_("Card field with name '")+name+_("' doesn't have the right type"));
|
||||
return *ret;
|
||||
}
|
||||
}
|
||||
throw InternalError(_("Expected a card field with name '")+name+_("'"));
|
||||
}
|
||||
|
||||
DECLARE_REFLECTION();
|
||||
};
|
||||
|
||||
|
||||
@@ -139,7 +139,9 @@ class ChoiceValue : public Value {
|
||||
public:
|
||||
inline ChoiceValue(const ChoiceFieldP& field)
|
||||
: Value(field)
|
||||
, value(field->initial, true)
|
||||
, value(field->initial.empty()
|
||||
? field->choices->choiceName(0) // first choice
|
||||
: field->initial, true)
|
||||
{}
|
||||
DECLARE_HAS_FIELD(Choice)
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@ DECLARE_TYPEOF_COLLECTION(FileFormatP);
|
||||
vector<FileFormatP> file_formats;
|
||||
|
||||
void init_file_formats() {
|
||||
//file_formats.push_back(new_shared<MSE2FileFilter>());
|
||||
//file_formats.push_back(new_shared<MSE1FileFilter>());
|
||||
//file_formats.push_back(new_shared<MtgEditorFileFilter>());
|
||||
file_formats.push_back(mse2_file_format());
|
||||
file_formats.push_back(mse1_file_format());
|
||||
file_formats.push_back(mtg_editor_file_format());
|
||||
}
|
||||
|
||||
String import_formats() {
|
||||
@@ -47,7 +47,7 @@ String export_formats(const Game& game) {
|
||||
return type_strings;
|
||||
}
|
||||
|
||||
void export_set(const Set& set, const String& filename, size_t format_type) {
|
||||
void export_set(Set& set, const String& filename, size_t format_type) {
|
||||
FileFormatP format = file_formats.at(format_type);
|
||||
if (!format->canExport(*set.game)) {
|
||||
throw InternalError(_("File format doesn't apply to set"));
|
||||
@@ -67,4 +67,4 @@ SetP import_set(String name) {
|
||||
// default: use first format = MSE2 format
|
||||
assert(!file_formats.empty() && file_formats[0]->canImport());
|
||||
return file_formats[0]->importSet(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
class Game;
|
||||
DECLARE_POINTER_TYPE(Set);
|
||||
DECLARE_POINTER_TYPE(FileFormat);
|
||||
|
||||
// ----------------------------------------------------------------------------- : FileFormat
|
||||
|
||||
@@ -33,7 +34,7 @@ class FileFormat {
|
||||
throw InternalError(_("Import not supported by this file format"));
|
||||
}
|
||||
/// Export using this filter
|
||||
virtual void exportSet(const Set& set, const String& filename) {
|
||||
virtual void exportSet(Set& set, const String& filename) {
|
||||
throw InternalError(_("Export not supported by this file format"));
|
||||
}
|
||||
};
|
||||
@@ -69,10 +70,13 @@ 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
|
||||
*/
|
||||
void export_set(const Set& set, const String& filename, size_t format_type);
|
||||
void export_set(Set& set, const String& filename, size_t format_type);
|
||||
|
||||
// ----------------------------------------------------------------------------- : Export
|
||||
// ----------------------------------------------------------------------------- : The formats
|
||||
|
||||
FileFormatP mse1_file_format();
|
||||
FileFormatP mse2_file_format();
|
||||
FileFormatP mtg_editor_file_format();
|
||||
|
||||
// ----------------------------------------------------------------------------- : EOF
|
||||
#endif
|
||||
|
||||
+162
-1
@@ -7,5 +7,166 @@
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <data/format/formats.hpp>
|
||||
#include <data/set.hpp>
|
||||
#include <data/game.hpp>
|
||||
#include <data/stylesheet.hpp>
|
||||
#include <data/card.hpp>
|
||||
#include <data/field/text.hpp>
|
||||
#include <data/field/choice.hpp>
|
||||
#include <data/field/image.hpp>
|
||||
#include <wx/wfstream.h>
|
||||
|
||||
// ----------------------------------------------------------------------------- :
|
||||
// ----------------------------------------------------------------------------- : MSE1FileFormat
|
||||
|
||||
/// The file format of MSE1 files
|
||||
class MSE1FileFormat : public FileFormat {
|
||||
public:
|
||||
virtual String extension() { return _("mse"); }
|
||||
virtual String name() { return _("Magic Set Editor version 1 files (*.mse)"); }
|
||||
virtual bool canImport() { return true; }
|
||||
virtual bool canExport(const Game&) { return false; }
|
||||
virtual SetP importSet(const String& filename);
|
||||
};
|
||||
|
||||
FileFormatP mse1_file_format() {
|
||||
return new_shared<MSE1FileFormat>();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Importing
|
||||
|
||||
// read a card from a mse1 file, add to the set when done
|
||||
void read_mse1_card(Set& set, wxFileInputStream& f, wxTextInputStream& file);
|
||||
|
||||
SetP MSE1FileFormat::importSet(const String& filename) {
|
||||
wxFileInputStream f(filename);
|
||||
#ifdef UNICODE
|
||||
wxTextInputStream file(f, _('\n'), wxConvLibc);
|
||||
#else
|
||||
wxTextInputStream file(f);
|
||||
#endif
|
||||
// create set
|
||||
SetP set(new Set);
|
||||
set->game = Game::byName(_("magic"));
|
||||
set->data.init(set->game->set_fields);
|
||||
|
||||
// file version check
|
||||
String format = file.ReadLine();
|
||||
if (format.substr(0,8) != _("MTG Set8")) {
|
||||
throw ParseError(_("Expected MSE format version 8\nTo convert files made with older versions of Magic Set Editor:\n 1. Download the latest version 1 from http:;//magicsetedtitor.sourceforge.net\n 2. Open the set, then save the set\n 3. Try to open them again in this program."));
|
||||
}
|
||||
// read general info
|
||||
set->value<TextValue>(_("title")) .value = file.ReadLine();
|
||||
set->value<TextValue>(_("artist")) .value = file.ReadLine();
|
||||
set->value<TextValue>(_("copyright")).value = file.ReadLine();
|
||||
file.ReadLine(); // border color, ignored
|
||||
String stylesheet = file.ReadLine();
|
||||
file.ReadLine(); // apprentice prefix ('MY'), ignored
|
||||
file.ReadLine(); // 'formatN'?, not even used by MSE1 :S, ignored
|
||||
file.ReadLine(); // 'formatS'?, same, ignored
|
||||
file.ReadLine(); // symbol filename, ignored
|
||||
file.ReadLine(); // use black symbol for all rarities, ignored
|
||||
String desc, line;
|
||||
while (!f.Eof()) {
|
||||
line = file.ReadLine();
|
||||
if (line == _("\xFF")) break;
|
||||
desc += line;
|
||||
}
|
||||
set->value<TextValue>(_("description")).value = desc;
|
||||
|
||||
// load stylesheet
|
||||
if (stylesheet.substr(0,3) == _("old")) {
|
||||
try {
|
||||
set->stylesheet = StyleSheet::byGameAndName(*set->game, _("old"));
|
||||
} catch (Error) {
|
||||
// If old style doesn't work try the new one
|
||||
set->stylesheet = StyleSheet::byGameAndName(*set->game, _("new"));
|
||||
}
|
||||
} else {
|
||||
set->stylesheet = StyleSheet::byGameAndName(*set->game, _("new"));
|
||||
}
|
||||
|
||||
// read cards
|
||||
CardP current_card;
|
||||
while (!f.Eof()) {
|
||||
read_mse1_card(*set, f, file);
|
||||
}
|
||||
|
||||
// done
|
||||
return set;
|
||||
}
|
||||
|
||||
void read_mse1_card(Set& set, wxFileInputStream& f, wxTextInputStream& file) {
|
||||
CardP card(new Card(*set.game));
|
||||
while (!f.Eof()) {
|
||||
// read a line
|
||||
String line = file.ReadLine();
|
||||
if (line.empty()) continue;
|
||||
Char type = line.GetChar(0);
|
||||
line = line.substr(1);
|
||||
// interpret this line
|
||||
switch (type) {
|
||||
case 'A': { // done
|
||||
set.cards.push_back(card);
|
||||
return;
|
||||
} case 'B': { // name
|
||||
card->value<TextValue>(_("name")) .value.assign(line);
|
||||
break;
|
||||
} case 'C': case 'D': { // image filename
|
||||
String image_file = set.newFileName(_("image"),_("")); // a new unique name in the package
|
||||
if (wxCopyFile(line, set.nameOut(image_file), true)) {
|
||||
card->value<ImageValue>(_("image")) .filename = image_file;
|
||||
}
|
||||
break;
|
||||
} case 'E': { // super type
|
||||
card->value<TextValue>(_("super type")) .value.assign(line);
|
||||
break;
|
||||
} case 'F': { // sub type
|
||||
card->value<TextValue>(_("sub type")) .value.assign(line);
|
||||
break;
|
||||
} case 'G': { // casting cost
|
||||
card->value<TextValue>(_("casting cost")).value.assign(line);
|
||||
break;
|
||||
} case 'H': { // rarity
|
||||
String rarity;
|
||||
if (line == _("(U)")) rarity = _("uncommon");
|
||||
else if (line == _("(R)")) rarity = _("rare");
|
||||
else rarity = _("common");
|
||||
card->value<ChoiceValue>(_("rarity")) .value.assign(rarity);
|
||||
break;
|
||||
} case 'I': { // power/thoughness
|
||||
size_t pos = line.find_first_of(_('/'));
|
||||
if (pos != String::npos) {
|
||||
card->value<TextValue>(_("power")) .value.assign(line.substr(0, pos));
|
||||
card->value<TextValue>(_("toughness")) .value.assign(line.substr(pos+1));
|
||||
}
|
||||
break;
|
||||
} case 'J': { // rule text or part of text
|
||||
Defaultable<String>& text = card->value<TextValue>(_("rule text")).value;
|
||||
if (!text().empty()) text.mutate() += _('\n');
|
||||
text.mutate() += line;
|
||||
break;
|
||||
} case 'K': { // flavor text or part of text
|
||||
Defaultable<String>& text = card->value<TextValue>(_("flavor text")).value;
|
||||
if (!text().empty()) text.mutate() += _('\n');
|
||||
text.mutate() += line;
|
||||
break;
|
||||
} case 'L': { // card color (if not default)
|
||||
// decode color
|
||||
String color;
|
||||
if (line == _("1")) color = _("white");
|
||||
else if (line == _("2")) color = _("blue");
|
||||
else if (line == _("3")) color = _("black");
|
||||
else if (line == _("4")) color = _("red");
|
||||
else if (line == _("5")) color = _("green");
|
||||
else if (line == _("6")) color = _("colorless");
|
||||
else if (line == _("7")) color = _("land");
|
||||
else if (line == _("9")) color = _("multicolor");
|
||||
else color = _("colorless");
|
||||
card->value<ChoiceValue>(_("card color")).value.assign(color);
|
||||
break;
|
||||
} default: {
|
||||
throw ParseError(_("Not a valid MSE1 file"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,5 +7,30 @@
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <data/format/formats.hpp>
|
||||
#include <data/set.hpp>
|
||||
#include <data/settings.hpp>
|
||||
|
||||
// ----------------------------------------------------------------------------- :
|
||||
// ----------------------------------------------------------------------------- : MSE2FileFormat
|
||||
|
||||
/// The file format of MSE2 files
|
||||
class MSE2FileFormat : public FileFormat {
|
||||
public:
|
||||
virtual String extension() { return _("mse-set"); }
|
||||
virtual String name() { return _("Magic Set Editor sets (*.mse-set)"); }
|
||||
virtual bool canImport() { return true; }
|
||||
virtual bool canExport(const Game&) { return true; }
|
||||
virtual SetP importSet(const String& filename) {
|
||||
settings.addRecentFile(filename);
|
||||
SetP set(new Set);
|
||||
set->open(filename);
|
||||
return set;
|
||||
}
|
||||
virtual void exportSet(Set& set, const String& filename) {
|
||||
set.saveAs(filename);
|
||||
set.actions.setSavePoint();;
|
||||
}
|
||||
};
|
||||
|
||||
FileFormatP mse2_file_format() {
|
||||
return new_shared<MSE2FileFormat>();
|
||||
}
|
||||
|
||||
@@ -8,4 +8,24 @@
|
||||
|
||||
#include <data/format/formats.hpp>
|
||||
|
||||
// ----------------------------------------------------------------------------- :
|
||||
// ----------------------------------------------------------------------------- : MtgEditorFileFormat
|
||||
|
||||
/// The file format of Mtg Editor files
|
||||
class MtgEditorFileFormat : public FileFormat {
|
||||
public:
|
||||
virtual String extension() { return _("set"); }
|
||||
virtual String name() { return _("Mtg Editor files (*.set)"); }
|
||||
virtual bool canImport() { return true; }
|
||||
virtual bool canExport(const Game&) { return false; }
|
||||
virtual SetP importSet(const String& filename);
|
||||
};
|
||||
|
||||
FileFormatP mtg_editor_file_format() {
|
||||
return new_shared<MtgEditorFileFormat>();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Importing
|
||||
|
||||
SetP MtgEditorFileFormat::importSet(const String& filename) {
|
||||
return SetP();//TODO
|
||||
}
|
||||
|
||||
@@ -69,6 +69,18 @@ class Set : public Packaged {
|
||||
/// Styling information for a particular stylesheet
|
||||
IndexMap<FieldP, ValueP>& stylingDataFor(const StyleSheet&);
|
||||
|
||||
/// Find a value in the data by name and type
|
||||
template <typename T> T& value(const String& name) {
|
||||
for(IndexMap<FieldP, ValueP>::iterator it = data.begin() ; it != data.end() ; ++it) {
|
||||
if ((*it)->fieldP->name == name) {
|
||||
T* ret = dynamic_cast<T*>(it->get());
|
||||
if (!ret) throw InternalError(_("Set field with name '")+name+_("' doesn't have the right type"));
|
||||
return *ret;
|
||||
}
|
||||
}
|
||||
throw InternalError(_("Expected a set field with name '")+name+_("'"));
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual String typeName() const;
|
||||
virtual void validate(Version);
|
||||
|
||||
@@ -351,14 +351,14 @@ void SetWindow::onFileNew(wxCommandEvent&) {
|
||||
if (!askSaveAndContinue()) return;
|
||||
// new set?
|
||||
SetP new_set = new_set_window(this);
|
||||
if (new_set) set = new_set;
|
||||
if (new_set) setSet(new_set);
|
||||
}
|
||||
|
||||
void SetWindow::onFileOpen(wxCommandEvent&) {
|
||||
if (!askSaveAndContinue()) return;
|
||||
wxFileDialog dlg(this, _("Open a set"), _(""), _(""), import_formats(), wxOPEN);
|
||||
if (dlg.ShowModal() == wxID_OK) {
|
||||
set = import_set(dlg.GetPath());
|
||||
setSet(import_set(dlg.GetPath()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ DECLARE_TYPEOF_COLLECTION(ColorField::ChoiceP);
|
||||
void ColorValueViewer::draw(RotatedDC& dc) {
|
||||
// draw in the value color
|
||||
dc.SetPen(*wxTRANSPARENT_PEN);
|
||||
dc.SetBrush(value().value.get());
|
||||
dc.SetBrush(value().value());
|
||||
if (nativeLook()) {
|
||||
// native look
|
||||
// find name of color
|
||||
@@ -24,7 +24,7 @@ void ColorValueViewer::draw(RotatedDC& dc) {
|
||||
color_name = field().default_name;
|
||||
} else {
|
||||
FOR_EACH_CONST(c, field().choices) {
|
||||
if (value().value.get() == c->color) {
|
||||
if (value().value() == c->color) {
|
||||
color_name = capitalize(c->name);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ class OptionalScript {
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline ScriptValueP toScript(const Defaultable<T>& v) { return toScript(v.get()); }
|
||||
inline ScriptValueP toScript(const Defaultable<T>& v) { return toScript(v()); }
|
||||
|
||||
// ----------------------------------------------------------------------------- : StringScript
|
||||
|
||||
|
||||
@@ -40,12 +40,18 @@ class Defaultable {
|
||||
|
||||
/// Get access to the value
|
||||
inline const T& operator () () const { return value; }
|
||||
inline const T& get () const { return value; }
|
||||
/// Get access to the value, for changing it
|
||||
inline T& mutate () {
|
||||
is_default = false;
|
||||
return value;
|
||||
}
|
||||
|
||||
/// Is this value in the default state?
|
||||
inline bool isDefault() const { return is_default; }
|
||||
/// Set the defaultness to true
|
||||
inline void setDefault() { is_default = true; }
|
||||
/// Set the defaultness to false
|
||||
inline void unsetDefault() { is_default = false; }
|
||||
|
||||
/// Compare the values, ignore defaultness
|
||||
/** used by scriptable to check for changes */
|
||||
|
||||
Reference in New Issue
Block a user