Commit a5a83f82 authored by twanvl's avatar twanvl

implemented import formats

parent 3f7b0bae
...@@ -42,6 +42,18 @@ class Card { ...@@ -42,6 +42,18 @@ class Card {
/** May return "" */ /** May return "" */
String identification() const; 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(); DECLARE_REFLECTION();
}; };
......
...@@ -139,7 +139,9 @@ class ChoiceValue : public Value { ...@@ -139,7 +139,9 @@ class ChoiceValue : public Value {
public: public:
inline ChoiceValue(const ChoiceFieldP& field) inline ChoiceValue(const ChoiceFieldP& field)
: Value(field) : Value(field)
, value(field->initial, true) , value(field->initial.empty()
? field->choices->choiceName(0) // first choice
: field->initial, true)
{} {}
DECLARE_HAS_FIELD(Choice) DECLARE_HAS_FIELD(Choice)
......
...@@ -18,9 +18,9 @@ DECLARE_TYPEOF_COLLECTION(FileFormatP); ...@@ -18,9 +18,9 @@ DECLARE_TYPEOF_COLLECTION(FileFormatP);
vector<FileFormatP> file_formats; vector<FileFormatP> file_formats;
void init_file_formats() { void init_file_formats() {
//file_formats.push_back(new_shared<MSE2FileFilter>()); file_formats.push_back(mse2_file_format());
//file_formats.push_back(new_shared<MSE1FileFilter>()); file_formats.push_back(mse1_file_format());
//file_formats.push_back(new_shared<MtgEditorFileFilter>()); file_formats.push_back(mtg_editor_file_format());
} }
String import_formats() { String import_formats() {
...@@ -47,7 +47,7 @@ String export_formats(const Game& game) { ...@@ -47,7 +47,7 @@ String export_formats(const Game& game) {
return type_strings; 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); FileFormatP format = file_formats.at(format_type);
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"));
...@@ -67,4 +67,4 @@ SetP import_set(String name) { ...@@ -67,4 +67,4 @@ SetP import_set(String name) {
// default: use first format = MSE2 format // default: use first format = MSE2 format
assert(!file_formats.empty() && file_formats[0]->canImport()); assert(!file_formats.empty() && file_formats[0]->canImport());
return file_formats[0]->importSet(name); return file_formats[0]->importSet(name);
} }
\ No newline at end of file
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
class Game; class Game;
DECLARE_POINTER_TYPE(Set); DECLARE_POINTER_TYPE(Set);
DECLARE_POINTER_TYPE(FileFormat);
// ----------------------------------------------------------------------------- : FileFormat // ----------------------------------------------------------------------------- : FileFormat
...@@ -33,7 +34,7 @@ class FileFormat { ...@@ -33,7 +34,7 @@ class FileFormat {
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(const Set& set, const String& filename) { virtual void exportSet(Set& set, const String& filename) {
throw InternalError(_("Export not supported by this file format")); throw InternalError(_("Export not supported by this file format"));
} }
}; };
...@@ -69,10 +70,13 @@ SetP import_set(String name); ...@@ -69,10 +70,13 @@ 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 /** 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 // ----------------------------------------------------------------------------- : EOF
#endif #endif
...@@ -7,5 +7,166 @@ ...@@ -7,5 +7,166 @@
// ----------------------------------------------------------------------------- : Includes // ----------------------------------------------------------------------------- : Includes
#include <data/format/formats.hpp> #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 @@ ...@@ -7,5 +7,30 @@
// ----------------------------------------------------------------------------- : Includes // ----------------------------------------------------------------------------- : Includes
#include <data/format/formats.hpp> #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 @@ ...@@ -8,4 +8,24 @@
#include <data/format/formats.hpp> #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 { ...@@ -69,6 +69,18 @@ class Set : public Packaged {
/// Styling information for a particular stylesheet /// Styling information for a particular stylesheet
IndexMap<FieldP, ValueP>& stylingDataFor(const 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: protected:
virtual String typeName() const; virtual String typeName() const;
virtual void validate(Version); virtual void validate(Version);
......
...@@ -351,14 +351,14 @@ void SetWindow::onFileNew(wxCommandEvent&) { ...@@ -351,14 +351,14 @@ void SetWindow::onFileNew(wxCommandEvent&) {
if (!askSaveAndContinue()) return; if (!askSaveAndContinue()) return;
// new set? // new set?
SetP new_set = new_set_window(this); SetP new_set = new_set_window(this);
if (new_set) set = new_set; if (new_set) setSet(new_set);
} }
void SetWindow::onFileOpen(wxCommandEvent&) { void SetWindow::onFileOpen(wxCommandEvent&) {
if (!askSaveAndContinue()) return; if (!askSaveAndContinue()) return;
wxFileDialog dlg(this, _("Open a set"), _(""), _(""), import_formats(), wxOPEN); wxFileDialog dlg(this, _("Open a set"), _(""), _(""), import_formats(), wxOPEN);
if (dlg.ShowModal() == wxID_OK) { if (dlg.ShowModal() == wxID_OK) {
set = import_set(dlg.GetPath()); setSet(import_set(dlg.GetPath()));
} }
} }
......
...@@ -15,7 +15,7 @@ DECLARE_TYPEOF_COLLECTION(ColorField::ChoiceP); ...@@ -15,7 +15,7 @@ DECLARE_TYPEOF_COLLECTION(ColorField::ChoiceP);
void ColorValueViewer::draw(RotatedDC& dc) { void ColorValueViewer::draw(RotatedDC& dc) {
// draw in the value color // draw in the value color
dc.SetPen(*wxTRANSPARENT_PEN); dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(value().value.get()); dc.SetBrush(value().value());
if (nativeLook()) { if (nativeLook()) {
// native look // native look
// find name of color // find name of color
...@@ -24,7 +24,7 @@ void ColorValueViewer::draw(RotatedDC& dc) { ...@@ -24,7 +24,7 @@ void ColorValueViewer::draw(RotatedDC& dc) {
color_name = field().default_name; color_name = field().default_name;
} else { } else {
FOR_EACH_CONST(c, field().choices) { FOR_EACH_CONST(c, field().choices) {
if (value().value.get() == c->color) { if (value().value() == c->color) {
color_name = capitalize(c->name); color_name = capitalize(c->name);
break; break;
} }
......
...@@ -87,7 +87,7 @@ class OptionalScript { ...@@ -87,7 +87,7 @@ class OptionalScript {
}; };
template <typename T> 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 // ----------------------------------------------------------------------------- : StringScript
......
...@@ -40,12 +40,18 @@ class Defaultable { ...@@ -40,12 +40,18 @@ class Defaultable {
/// Get access to the value /// Get access to the value
inline const T& operator () () const { return 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? /// Is this value in the default state?
inline bool isDefault() const { return is_default; } inline bool isDefault() const { return is_default; }
/// Set the defaultness to true /// Set the defaultness to true
inline void setDefault() { is_default = true; } inline void setDefault() { is_default = true; }
/// Set the defaultness to false
inline void unsetDefault() { is_default = false; }
/// Compare the values, ignore defaultness /// Compare the values, ignore defaultness
/** used by scriptable to check for changes */ /** used by scriptable to check for changes */
......
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