Card data in images (minimum viable)

* remove wxEmptyString

* improve style tab carousel

* create web request window

* add drop target and drop source
This commit is contained in:
GenevensiS
2025-11-28 10:42:30 +01:00
committed by GitHub
parent f5b5c0968d
commit cf0a84a8a7
49 changed files with 815 additions and 399 deletions
+1 -1
View File
@@ -66,7 +66,7 @@ void AddCardAction::perform(bool to_undo) {
FOR_EACH(linked_pair, linked_pairs) { FOR_EACH(linked_pair, linked_pairs) {
String& linked_uid = linked_pair.first.get(); String& linked_uid = linked_pair.first.get();
String& linked_relation = linked_pair.second.get(); String& linked_relation = linked_pair.second.get();
if (linked_uid == wxEmptyString) continue; if (linked_uid.empty()) continue;
// If it's an added card, replace the link // If it's an added card, replace the link
if (all_added_uids.find(linked_uid) != all_added_uids.end()) { if (all_added_uids.find(linked_uid) != all_added_uids.end()) {
all_added_uids.at(linked_uid)->updateLink(old_uid, new_uid); all_added_uids.at(linked_uid)->updateLink(old_uid, new_uid);
+13 -13
View File
@@ -53,7 +53,7 @@ String Card::identification() const {
if (!data.empty()) { if (!data.empty()) {
return data.at(0)->toString(); return data.at(0)->toString();
} else { } else {
return wxEmptyString; return _("");
} }
} }
@@ -78,7 +78,7 @@ void Card::link(const Set& set, const vector<CardP>& linked_cards, const String&
FOR_EACH(this_linked_pair, this_linked_pairs) { FOR_EACH(this_linked_pair, this_linked_pairs) {
String& this_linked_uid = this_linked_pair.first.get(); String& this_linked_uid = this_linked_pair.first.get();
if ( if (
this_linked_uid == wxEmptyString || // Not a reference this_linked_uid.empty() || // Not a reference
all_existing_uids.find(this_linked_uid) == all_existing_uids.end() // Reference to nonexistent card all_existing_uids.find(this_linked_uid) == all_existing_uids.end() // Reference to nonexistent card
) free_link_count++; ) free_link_count++;
} }
@@ -94,7 +94,7 @@ void Card::link(const Set& set, const vector<CardP>& linked_cards, const String&
FOR_EACH(this_linked_pair, this_linked_pairs) { FOR_EACH(this_linked_pair, this_linked_pairs) {
String& this_linked_uid = this_linked_pair.first.get(); String& this_linked_uid = this_linked_pair.first.get();
String& this_linked_relation = this_linked_pair.second.get(); String& this_linked_relation = this_linked_pair.second.get();
if (this_linked_uid == wxEmptyString) { if (this_linked_uid.empty()) {
this_linked_uid = linked_card->uid; this_linked_uid = linked_card->uid;
this_linked_relation = linked_relation; this_linked_relation = linked_relation;
written = true; written = true;
@@ -124,7 +124,7 @@ void Card::link(const Set& set, const vector<CardP>& linked_cards, const String&
FOR_EACH(linked_pair, linked_pairs) { FOR_EACH(linked_pair, linked_pairs) {
String& linked_uid = linked_pair.first.get(); String& linked_uid = linked_pair.first.get();
String& linked_relation = linked_pair.second.get(); String& linked_relation = linked_pair.second.get();
if (linked_uid == wxEmptyString) { if (linked_uid.empty()) {
linked_uid = uid; linked_uid = uid;
linked_relation = selected_relation; linked_relation = selected_relation;
written = true; written = true;
@@ -177,26 +177,26 @@ void Card::unlink(const vector<CardP>& unlinked_cards)
pair<String, String> Card::unlink(CardP& unlinked_card) pair<String, String> Card::unlink(CardP& unlinked_card)
{ {
String old_selected_relation = wxEmptyString; String old_selected_relation = _("");
THIS_LINKED_PAIRS(this_linked_pairs); THIS_LINKED_PAIRS(this_linked_pairs);
FOR_EACH(this_linked_pair, this_linked_pairs) { FOR_EACH(this_linked_pair, this_linked_pairs) {
String& this_linked_uid = this_linked_pair.first.get(); String& this_linked_uid = this_linked_pair.first.get();
String& this_linked_relation = this_linked_pair.second.get(); String& this_linked_relation = this_linked_pair.second.get();
if (this_linked_uid == unlinked_card->uid) { if (this_linked_uid == unlinked_card->uid) {
old_selected_relation = this_linked_relation; old_selected_relation = this_linked_relation;
this_linked_uid = wxEmptyString; this_linked_uid = _("");
this_linked_relation = wxEmptyString; this_linked_relation = _("");
} }
} }
String old_unlinked_relation = wxEmptyString; String old_unlinked_relation = _("");
OTHER_LINKED_PAIRS(unlinked_pairs, unlinked_card); OTHER_LINKED_PAIRS(unlinked_pairs, unlinked_card);
FOR_EACH(unlinked_pair, unlinked_pairs) { FOR_EACH(unlinked_pair, unlinked_pairs) {
String& unlinked_uid = unlinked_pair.first.get(); String& unlinked_uid = unlinked_pair.first.get();
String& unlinked_relation = unlinked_pair.second.get(); String& unlinked_relation = unlinked_pair.second.get();
if (unlinked_uid == uid) { if (unlinked_uid == uid) {
old_unlinked_relation = unlinked_relation; old_unlinked_relation = unlinked_relation;
unlinked_uid = wxEmptyString; unlinked_uid = _("");
unlinked_relation = wxEmptyString; unlinked_relation = _("");
} }
} }
return make_pair(old_selected_relation, old_unlinked_relation); return make_pair(old_selected_relation, old_unlinked_relation);
@@ -204,7 +204,7 @@ pair<String, String> Card::unlink(CardP& unlinked_card)
void Card::copyLink(const Set& set, String old_uid, String new_uid) { void Card::copyLink(const Set& set, String old_uid, String new_uid) {
// Find what relation we need to copy // Find what relation we need to copy
String relation_copy = wxEmptyString; String relation_copy = _("");
THIS_LINKED_PAIRS(this_linked_pairs); THIS_LINKED_PAIRS(this_linked_pairs);
FOR_EACH(this_linked_pair, this_linked_pairs) { FOR_EACH(this_linked_pair, this_linked_pairs) {
String& this_linked_uid = this_linked_pair.first.get(); String& this_linked_uid = this_linked_pair.first.get();
@@ -215,7 +215,7 @@ void Card::copyLink(const Set& set, String old_uid, String new_uid) {
} }
} }
// Nothing to copy // Nothing to copy
if (relation_copy == wxEmptyString) { if (relation_copy.empty()) {
return; return;
} }
@@ -224,7 +224,7 @@ void Card::copyLink(const Set& set, String old_uid, String new_uid) {
FOR_EACH(this_linked_pair, this_linked_pairs) { FOR_EACH(this_linked_pair, this_linked_pairs) {
String& this_linked_uid = this_linked_pair.first.get(); String& this_linked_uid = this_linked_pair.first.get();
String& this_linked_relation = this_linked_pair.second.get(); String& this_linked_relation = this_linked_pair.second.get();
if (this_linked_uid == wxEmptyString) { if (this_linked_uid.empty()) {
this_linked_uid = new_uid; this_linked_uid = new_uid;
this_linked_relation = relation_copy; this_linked_relation = relation_copy;
written = true; written = true;
+2 -20
View File
@@ -113,14 +113,9 @@ Style::Style(const FieldP& field)
, visible(true) , visible(true)
, automatic_side(AUTO_UNKNOWN) , automatic_side(AUTO_UNKNOWN)
, content_dependent(false) , content_dependent(false)
{ {}
field->styleP = this;
}
Style::~Style() Style::~Style() {}
{
fieldP->styleP = nullptr;
}
IMPLEMENT_REFLECTION(Style) { IMPLEMENT_REFLECTION(Style) {
REFLECT(z_index); REFLECT(z_index);
@@ -138,7 +133,6 @@ IMPLEMENT_REFLECTION(Style) {
void init_object(const FieldP& field, StyleP& style) { void init_object(const FieldP& field, StyleP& style) {
if (!style) style = field->newStyle(); if (!style) style = field->newStyle();
field->styleP = style;
} }
template <> StyleP read_new<Style>(Reader&) { template <> StyleP read_new<Style>(Reader&) {
throw InternalError(_("IndexMap contains nullptr StyleP the application should have crashed already")); throw InternalError(_("IndexMap contains nullptr StyleP the application should have crashed already"));
@@ -268,18 +262,6 @@ void mark_dependency_member(const Style& style, const String& name, const Depend
style.markDependencyMember(name,dep); style.markDependencyMember(name,dep);
} }
String Style::getRect() {
return _("---") +
wxString::Format(wxT("%i"), (int)(left)) +
_("-") +
wxString::Format(wxT("%i"), (int)(top)) +
_("-") +
wxString::Format(wxT("%i"), (int)(width)) +
_("-") +
wxString::Format(wxT("%i"), (int)(height)) +
_("---");
}
// ----------------------------------------------------------------------------- : StyleListener // ----------------------------------------------------------------------------- : StyleListener
void Style::addListener(StyleListener* listener) { void Style::addListener(StyleListener* listener) {
+7 -4
View File
@@ -63,7 +63,6 @@ public:
OptionalScript import_script; ///< The script to apply to the supplied value, when creating a new card. OptionalScript import_script; ///< The script to apply to the supplied value, when creating a new card.
Dependencies dependent_scripts; ///< Scripts that depend on values of this field Dependencies dependent_scripts; ///< Scripts that depend on values of this field
String package_relative_filename; String package_relative_filename;
StyleP styleP; ///< Style for this field, should have the right type! Can be null.
/// Creates a new Value corresponding to this Field /// Creates a new Value corresponding to this Field
virtual ValueP newValue() = 0; virtual ValueP newValue() = 0;
@@ -126,6 +125,13 @@ public:
inline RealPoint getPos() const { return RealPoint(left, top); } inline RealPoint getPos() const { return RealPoint(left, top); }
inline RealSize getSize() const { return RealSize(width, height); } inline RealSize getSize() const { return RealSize(width, height); }
inline RealRect getExternalRect() const { return RealRect(left, top, width, height); } inline RealRect getExternalRect() const { return RealRect(left, top, width, height); }
inline String getExternalRectString(double scale = 1.0, int offset = 0) { ///< update the style before calling this
return _("---") + wxString::Format(wxT("%i"), (int)std::ceil(scale * left + offset)) +
_("-") + wxString::Format(wxT("%i"), (int)std::ceil(scale * top)) +
_("-") + wxString::Format(wxT("%i"), (int)std::floor(scale * width)) +
_("-") + wxString::Format(wxT("%i"), (int)std::floor(scale * height)) +
_("---");
}
/// Does this style have a non-zero size (or is it scripted)? /// Does this style have a non-zero size (or is it scripted)?
bool hasSize() const; bool hasSize() const;
@@ -164,9 +170,6 @@ public:
/** change_info is a subset of StyleChange flags */ /** change_info is a subset of StyleChange flags */
void tellListeners(int changes); void tellListeners(int changes);
/// Store where on the card the field goes, to save it in filenames
String getRect();
private: private:
DECLARE_REFLECTION_VIRTUAL(); DECLARE_REFLECTION_VIRTUAL();
/// Things that are listening to changes in this style /// Things that are listening to changes in this style
+1 -1
View File
@@ -35,7 +35,7 @@ int ImageStyle::update(Context& ctx) {
// ----------------------------------------------------------------------------- : ImageValue // ----------------------------------------------------------------------------- : ImageValue
String ImageValue::toString() const { String ImageValue::toString() const {
return filename.empty() ? wxEmptyString : _("<image>"); return filename.empty() ? _("") : _("<image>");
} }
// custom reflection: convert to ScriptImageP for scripting // custom reflection: convert to ScriptImageP for scripting
+1 -1
View File
@@ -48,7 +48,7 @@ IMPLEMENT_REFLECTION_NO_SCRIPT(SymbolVariation) {
// ----------------------------------------------------------------------------- : SymbolValue // ----------------------------------------------------------------------------- : SymbolValue
String SymbolValue::toString() const { String SymbolValue::toString() const {
return filename.empty() ? wxEmptyString : _("<symbol>"); return filename.empty() ? _("") : _("<symbol>");
} }
IMPLEMENT_REFLECTION_NO_GET_MEMBER(SymbolValue) { IMPLEMENT_REFLECTION_NO_GET_MEMBER(SymbolValue) {
+1 -1
View File
@@ -206,7 +206,7 @@ void FakeTextValue::retrieve() {
if (underlying) { if (underlying) {
value.assign(untagged ? escape(*underlying) : *underlying); value.assign(untagged ? escape(*underlying) : *underlying);
} else { } else {
value.assign(wxEmptyString); value.assign(_(""));
} }
} }
+2 -2
View File
@@ -37,7 +37,7 @@ bool Font::PreloadResourceFonts(bool recursive) {
bool preloadHadErrors = false; bool preloadHadErrors = false;
wxString folder; wxString folder;
bool cont = appDir.GetFirst(&folder, wxEmptyString, wxDIR_DIRS); bool cont = appDir.GetFirst(&folder, _(""), wxDIR_DIRS);
while (cont) while (cont)
{ {
if (folder.Lower().Contains("fonts")) { if (folder.Lower().Contains("fonts")) {
@@ -65,7 +65,7 @@ bool Font::PreloadResourceFonts(bool recursive) {
void Font::TallyResourceFonts(String fontsDirectoryPath, vector<String>& fontFilePaths, bool recursive) { void Font::TallyResourceFonts(String fontsDirectoryPath, vector<String>& fontFilePaths, bool recursive) {
wxDir fontsDirectory(fontsDirectoryPath); wxDir fontsDirectory(fontsDirectoryPath);
String fontFileName = wxEmptyString; String fontFileName = _("");
bool hasNext = fontsDirectory.GetFirst(&fontFileName); bool hasNext = fontsDirectory.GetFirst(&fontFileName);
while (hasNext) { while (hasNext) {
String fontFilePath = fontsDirectoryPath + fontFileName; String fontFilePath = fontsDirectoryPath + fontFileName;
+14 -5
View File
@@ -16,6 +16,7 @@
#include <data/keyword.hpp> #include <data/keyword.hpp>
#include <util/io/package.hpp> #include <util/io/package.hpp>
#include <script/scriptable.hpp> #include <script/scriptable.hpp>
#include <wx/filename.h>
#include <wx/sstream.h> #include <wx/sstream.h>
// ----------------------------------------------------------------------------- : Clipboard serialization // ----------------------------------------------------------------------------- : Clipboard serialization
@@ -140,13 +141,21 @@ KeywordP KeywordDataObject::getKeyword(const SetP& set) {
// ----------------------------------------------------------------------------- : Card on clipboard // ----------------------------------------------------------------------------- : Card on clipboard
CardsOnClipboard::CardsOnClipboard(const SetP& set, const vector<CardP>& cards) { CardsOnClipboard::CardsOnClipboard(const SetP& set, const vector<CardP>& cards) {
// Conversion to image format // Conversion to image file
if (cards.size() < 6) {
Image img;
if (cards.size() == 1) { if (cards.size() == 1) {
Add(new wxImageDataObject(export_image(set, cards[0]))); img = export_image(set, cards[0]);
} }
else if (cards.size() < 6) { else {
Add(new wxImageDataObject(export_image(set, cards, true, 0, 1.0, 0.0))); img = export_image(set, cards, true, 0, 1.0, 0.0);
} }
String temp_path = wxFileName::CreateTempFileName(_("mse")) + _(".png");
img.SaveFile(temp_path, wxBITMAP_TYPE_PNG);
wxFileDataObject* data = new wxFileDataObject();
data->AddFile(temp_path);
Add(data);
}
// Conversion to serialized card format // Conversion to serialized card format
Add(new CardsDataObject(set, cards), true); Add(new CardsDataObject(set, cards), true);
} }
+4 -6
View File
@@ -89,14 +89,12 @@ FileFormatP mtg_editor_file_format();
// ----------------------------------------------------------------------------- : Other ways to export // ----------------------------------------------------------------------------- : Other ways to export
/// Generate a wxBitmap of one or more cards /// Generate a wxBitmap of one or more cards
Bitmap export_bitmap(const SetP& set, const CardP& card); Bitmap export_bitmap(const SetP& set, const CardP& card, const double zoom = 1.0, const Radians angle_radians = 0.0);
Bitmap export_bitmap(const SetP& set, const CardP& card, const double zoom, const Radians angle_radians = 0.0); Bitmap export_bitmap(const SetP& set, const vector<CardP>& cards, bool scale_to_lowest_dpi, int padding, const double zoom, const Radians angle_radians, vector<double>& scales_out, vector<int>& offsets_out);
Bitmap export_bitmap(const SetP& set, const vector<CardP>& cards, bool scale_to_lowest_dpi, int padding, const double zoom, const Radians angle_radians = 0.0);
/// Generate a wxImage of one or more cards /// Generate a wxImage of one or more cards
Image export_image(const SetP& set, const CardP& card); Image export_image(const SetP& set, const CardP& card, const double zoom = 1.0, const Radians angle_radians = 0.0);
Image export_image(const SetP& set, const CardP& card, const double zoom, const Radians angle_radians = 0.0); Image export_image(const SetP& set, const vector<CardP>& cards, bool scale_to_lowest_dpi = false, int padding = 0, const double zoom = 1.0, const Radians angle_radians = 0.0);
Image export_image(const SetP& set, const vector<CardP>& cards, bool scale_to_lowest_dpi, int padding, const double zoom, const Radians angle_radians = 0.0);
/// Export the image of one or more cards to a given filename /// Export the image of one or more cards to a given filename
void export_image(const SetP& set, const CardP& card, const String& filename); void export_image(const SetP& set, const CardP& card, const String& filename);
+52 -37
View File
@@ -15,6 +15,7 @@
#include <data/card.hpp> #include <data/card.hpp>
#include <data/stylesheet.hpp> #include <data/stylesheet.hpp>
#include <data/settings.hpp> #include <data/settings.hpp>
#include <script/functions/json.hpp>
#include <gui/util.hpp> #include <gui/util.hpp>
#include <render/card/viewer.hpp> #include <render/card/viewer.hpp>
#include <wx/filename.h> #include <wx/filename.h>
@@ -63,24 +64,6 @@ Rotation UnzoomedDataViewer::getRotation() const {
// ----------------------------------------------------------------------------- : wxBitmap export // ----------------------------------------------------------------------------- : wxBitmap export
Bitmap export_bitmap(const SetP& set, const CardP& card) {
if (!set) throw Error(_("no set"));
UnzoomedDataViewer viewer = UnzoomedDataViewer();
viewer.setSet(set);
viewer.setCard(card);
// size of cards
RealSize size = viewer.getRotation().getExternalSize();
// create bitmap & dc
Bitmap bitmap((int)size.width, (int)size.height);
if (!bitmap.Ok()) throw InternalError(_("Unable to create bitmap"));
wxMemoryDC dc;
dc.SelectObject(bitmap);
// draw
viewer.draw(dc);
dc.SelectObject(wxNullBitmap);
return bitmap;
}
Bitmap export_bitmap(const SetP& set, const CardP& card, const double zoom, const Radians angle_radians) { Bitmap export_bitmap(const SetP& set, const CardP& card, const double zoom, const Radians angle_radians) {
if (!set) throw Error(_("no set")); if (!set) throw Error(_("no set"));
UnzoomedDataViewer viewer = UnzoomedDataViewer(zoom, angle_radians); UnzoomedDataViewer viewer = UnzoomedDataViewer(zoom, angle_radians);
@@ -99,7 +82,7 @@ Bitmap export_bitmap(const SetP& set, const CardP& card, const double zoom, cons
return bitmap; return bitmap;
} }
Bitmap export_bitmap(const SetP& set, const vector<CardP>& cards, bool scale_to_lowest_dpi, int padding, const double zoom, const Radians angle_radians) { Bitmap export_bitmap(const SetP& set, const vector<CardP>& cards, bool scale_to_lowest_dpi, int padding, const double zoom, const Radians angle_radians, vector<double>& scales_out, vector<int>& offsets_out) {
if (!set) throw Error(_("no set")); if (!set) throw Error(_("no set"));
vector<Bitmap> bitmaps; vector<Bitmap> bitmaps;
int width = 0; int width = 0;
@@ -113,12 +96,13 @@ Bitmap export_bitmap(const SetP& set, const vector<CardP>& cards, bool scale_to_
} }
// Draw card bitmaps // Draw card bitmaps
FOR_EACH(card, cards) { FOR_EACH(card, cards) {
double scaled_zoom = zoom; double scale = zoom;
if (scale_to_lowest_dpi) { if (scale_to_lowest_dpi) {
double dpi = max(set->stylesheetFor(card).card_dpi, 150.0); double dpi = max(set->stylesheetFor(card).card_dpi, 150.0);
scaled_zoom *= lowest_dpi / dpi; scale *= lowest_dpi / dpi;
} }
UnzoomedDataViewer viewer = UnzoomedDataViewer(scaled_zoom, angle_radians); scales_out.push_back(scale);
UnzoomedDataViewer viewer = UnzoomedDataViewer(scale, angle_radians);
viewer.setSet(set); viewer.setSet(set);
viewer.setCard(card); viewer.setCard(card);
RealSize size = viewer.getRotation().getExternalSize(); RealSize size = viewer.getRotation().getExternalSize();
@@ -141,6 +125,7 @@ Bitmap export_bitmap(const SetP& set, const vector<CardP>& cards, bool scale_to_
clearDC(globalDC, *wxWHITE_BRUSH); clearDC(globalDC, *wxWHITE_BRUSH);
int offset = 0; int offset = 0;
FOR_EACH(bitmap, bitmaps) { FOR_EACH(bitmap, bitmaps) {
offsets_out.push_back(offset);
globalDC.SetDeviceOrigin(offset, 0); globalDC.SetDeviceOrigin(offset, 0);
globalDC.DrawBitmap(bitmap, 0, 0); globalDC.DrawBitmap(bitmap, 0, 0);
offset += bitmap.GetWidth() + padding; offset += bitmap.GetWidth() + padding;
@@ -151,29 +136,59 @@ Bitmap export_bitmap(const SetP& set, const vector<CardP>& cards, bool scale_to_
// ----------------------------------------------------------------------------- : wxImage export // ----------------------------------------------------------------------------- : wxImage export
Image export_image(const SetP& set, const CardP& card) {
Bitmap bitmap = export_bitmap(set, card);
Image img = bitmap.ConvertToImage();
vector<CardP> cards = { card };
CardsDataObject data(set, cards);
img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, _("<mse-data-start>") + data.GetText() + _("<mse-data-end>"));
return img;
}
Image export_image(const SetP& set, const CardP& card, const double zoom, const Radians angle_radians) { Image export_image(const SetP& set, const CardP& card, const double zoom, const Radians angle_radians) {
Bitmap bitmap = export_bitmap(set, card, zoom, angle_radians); Bitmap bitmap = export_bitmap(set, card, zoom, angle_radians);
Image img = bitmap.ConvertToImage(); Image img = bitmap.ConvertToImage();
vector<CardP> cards = { card }; String data = _("<mse-data-start>[");
CardsDataObject data(set, cards); IndexMap<FieldP, ValueP>& card_data = card->data;
img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, _("<mse-data-start>") + data.GetText() + _("<mse-data-end>")); boost::json::object& cardv = mse_to_json(card, set.get());
boost::json::object& cardv_data = cardv["data"].as_object();
for(IndexMap<FieldP, ValueP>::iterator it = card_data.begin() ; it != card_data.end() ; ++it) {
ImageValue* value = dynamic_cast<ImageValue*>(it->get());
if (value && !value->filename.empty()) {
FieldP field = (*it)->fieldP;
StyleP style = set->stylesheetFor(card).card_style.at(field->index);
if (style) {
style->update(set->getContext(card));
std::string rect = style->getExternalRectString(zoom, 0).ToStdString();
cardv_data[field->name.ToStdString()] = rect;
}
}
}
data += json_ugly_print(cardv) + _("]<mse-data-end>");
img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, data);
return img; return img;
} }
Image export_image(const SetP& set, const vector<CardP>& cards, bool scale_to_lowest_dpi, int padding, const double zoom, const Radians angle_radians) { Image export_image(const SetP& set, const vector<CardP>& cards, bool scale_to_lowest_dpi, int padding, const double zoom, const Radians angle_radians) {
Bitmap bitmap = export_bitmap(set, cards, scale_to_lowest_dpi, padding, zoom, angle_radians); vector<double> scales;
vector<int> offsets;
Bitmap bitmap = export_bitmap(set, cards, scale_to_lowest_dpi, padding, zoom, angle_radians, scales, offsets);
Image img = bitmap.ConvertToImage(); Image img = bitmap.ConvertToImage();
CardsDataObject data(set, cards); String data = _("<mse-data-start>[");
img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, _("<mse-data-start>") + data.GetText() + _("<mse-data-end>")); for (int i = 0; i < cards.size(); ++i) {
if (i > 0) data += _(",");
CardP card = cards[i];
IndexMap<FieldP, ValueP>& card_data = card->data;
boost::json::object& cardv = mse_to_json(card, set.get());
boost::json::object& cardv_data = cardv["data"].as_object();
for(IndexMap<FieldP, ValueP>::iterator it = card_data.begin() ; it != card_data.end() ; ++it) {
ImageValue* value = dynamic_cast<ImageValue*>(it->get());
if (value && !value->filename.empty()) {
FieldP field = (*it)->fieldP;
StyleSheetP stylesheet = set->stylesheetForP(card);
StyleP style = stylesheet->card_style.at(field->index);
if (style) {
style->update(set->getContext(card));
std::string rect = style->getExternalRectString(scales[i], offsets[i]).ToStdString();
cardv_data[field->name.ToStdString()] = rect;
}
}
}
data += json_ugly_print(cardv);
}
data += _("]<mse-data-end>");
img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, data);
return img; return img;
} }
+1 -1
View File
@@ -142,7 +142,7 @@ String Set::identification() const {
return v->toString(); return v->toString();
} }
} }
return wxEmptyString; return _("");
} }
+2 -2
View File
@@ -429,7 +429,7 @@ String SymbolFont::insertSymbolCode(int menu_id) const {
if (insert_symbol_menu) { if (insert_symbol_menu) {
return insert_symbol_menu->getCode(menu_id - ID_INSERT_SYMBOL_MENU_MIN, *this); return insert_symbol_menu->getCode(menu_id - ID_INSERT_SYMBOL_MENU_MIN, *this);
} else { } else {
return wxEmptyString; return _("");
} }
} }
@@ -505,7 +505,7 @@ wxMenuItem* InsertSymbolMenu::makeMenuItem(wxMenu* parent, int first_id, SymbolF
} }
if (type == Type::SUBMENU) { if (type == Type::SUBMENU) {
wxMenuItem* item = new wxMenuItem(parent, wxID_ANY, label, wxMenuItem* item = new wxMenuItem(parent, wxID_ANY, label,
wxEmptyString, wxITEM_NORMAL, _(""), wxITEM_NORMAL,
makeMenu(first_id, font)); makeMenu(first_id, font));
item->SetBitmap(wxNullBitmap); item->SetBitmap(wxNullBitmap);
return item; return item;
+56 -48
View File
@@ -24,7 +24,7 @@ GeneratedImageP GeneratedImage::toImage() const {
return const_cast<GeneratedImage*>(this)->intrusive_from_this(); return const_cast<GeneratedImage*>(this)->intrusive_from_this();
} }
Image GeneratedImage::generateConform(const Options& options) const { Image GeneratedImage::generateConform(const Options& options) {
return conform_image(generate(options),options); return conform_image(generate(options),options);
} }
@@ -81,7 +81,7 @@ Image conform_image(const Image& img, const GeneratedImage::Options& options) {
// ----------------------------------------------------------------------------- : BlankImage // ----------------------------------------------------------------------------- : BlankImage
Image BlankImage::generate(const Options& opt) const { Image BlankImage::generate(const Options& opt) {
int w = max(1, opt.width >= 0 ? opt.width : opt.height); int w = max(1, opt.width >= 0 ? opt.width : opt.height);
int h = max(1, opt.height >= 0 ? opt.height : opt.width); int h = max(1, opt.height >= 0 ? opt.height : opt.width);
Image img(w, h); Image img(w, h);
@@ -97,7 +97,7 @@ bool BlankImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : LinearBlendImage // ----------------------------------------------------------------------------- : LinearBlendImage
Image LinearBlendImage::generate(const Options& opt) const { Image LinearBlendImage::generate(const Options& opt) {
Image img = image1->generate(opt); Image img = image1->generate(opt);
linear_blend(img, image2->generate(opt), x1, y1, x2, y2); linear_blend(img, image2->generate(opt), x1, y1, x2, y2);
return img; return img;
@@ -115,7 +115,7 @@ bool LinearBlendImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : MaskedBlendImage // ----------------------------------------------------------------------------- : MaskedBlendImage
Image MaskedBlendImage::generate(const Options& opt) const { Image MaskedBlendImage::generate(const Options& opt) {
Image img = light->generate(opt); Image img = light->generate(opt);
mask_blend(img, dark->generate(opt), mask->generate(opt)); mask_blend(img, dark->generate(opt), mask->generate(opt));
return img; return img;
@@ -132,7 +132,7 @@ bool MaskedBlendImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : CombineBlendImage // ----------------------------------------------------------------------------- : CombineBlendImage
Image CombineBlendImage::generate(const Options& opt) const { Image CombineBlendImage::generate(const Options& opt) {
Image img = image1->generate(opt); Image img = image1->generate(opt);
combine_image(img, image2->generate(opt), image_combine); combine_image(img, image2->generate(opt), image_combine);
return img; return img;
@@ -149,7 +149,7 @@ bool CombineBlendImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : SetMaskImage // ----------------------------------------------------------------------------- : SetMaskImage
Image SetMaskImage::generate(const Options& opt) const { Image SetMaskImage::generate(const Options& opt) {
Image img = image->generate(opt); Image img = image->generate(opt);
set_alpha(img, mask->generate(opt)); set_alpha(img, mask->generate(opt));
return img; return img;
@@ -160,7 +160,7 @@ bool SetMaskImage::operator == (const GeneratedImage& that) const {
&& *mask == *that2->mask; && *mask == *that2->mask;
} }
Image SetAlphaImage::generate(const Options& opt) const { Image SetAlphaImage::generate(const Options& opt) {
Image img = image->generate(opt); Image img = image->generate(opt);
set_alpha(img, alpha); set_alpha(img, alpha);
return img; return img;
@@ -173,7 +173,7 @@ bool SetAlphaImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : SetCombineImage // ----------------------------------------------------------------------------- : SetCombineImage
Image SetCombineImage::generate(const Options& opt) const { Image SetCombineImage::generate(const Options& opt) {
return image->generate(opt); return image->generate(opt);
} }
ImageCombine SetCombineImage::combine() const { ImageCombine SetCombineImage::combine() const {
@@ -187,7 +187,7 @@ bool SetCombineImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : SaturateImage // ----------------------------------------------------------------------------- : SaturateImage
Image SaturateImage::generate(const Options& opt) const { Image SaturateImage::generate(const Options& opt) {
Image img = image->generate(opt); Image img = image->generate(opt);
saturate(img, amount); saturate(img, amount);
return img; return img;
@@ -200,7 +200,7 @@ bool SaturateImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : InvertImage // ----------------------------------------------------------------------------- : InvertImage
Image InvertImage::generate(const Options& opt) const { Image InvertImage::generate(const Options& opt) {
Image img = image->generate(opt); Image img = image->generate(opt);
invert(img); invert(img);
return img; return img;
@@ -212,7 +212,7 @@ bool InvertImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : RecolorImage // ----------------------------------------------------------------------------- : RecolorImage
Image RecolorImage::generate(const Options& opt) const { Image RecolorImage::generate(const Options& opt) {
Image img = image->generate(opt); Image img = image->generate(opt);
recolor(img, color); recolor(img, color);
return img; return img;
@@ -223,7 +223,7 @@ bool RecolorImage::operator == (const GeneratedImage& that) const {
&& color == that2->color; && color == that2->color;
} }
Image RecolorImage2::generate(const Options& opt) const { Image RecolorImage2::generate(const Options& opt) {
Image img = image->generate(opt); Image img = image->generate(opt);
recolor(img, red,green,blue,white); recolor(img, red,green,blue,white);
return img; return img;
@@ -239,7 +239,7 @@ bool RecolorImage2::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : FlipImage // ----------------------------------------------------------------------------- : FlipImage
Image FlipImageHorizontal::generate(const Options& opt) const { Image FlipImageHorizontal::generate(const Options& opt) {
Image img = image->generate(opt); Image img = image->generate(opt);
return flip_image_horizontal(img); return flip_image_horizontal(img);
} }
@@ -248,7 +248,7 @@ bool FlipImageHorizontal::operator == (const GeneratedImage& that) const {
return that2 && *image == *that2->image; return that2 && *image == *that2->image;
} }
Image FlipImageVertical::generate(const Options& opt) const { Image FlipImageVertical::generate(const Options& opt) {
Image img = image->generate(opt); Image img = image->generate(opt);
return flip_image_vertical(img); return flip_image_vertical(img);
} }
@@ -257,7 +257,7 @@ bool FlipImageVertical::operator == (const GeneratedImage& that) const {
return that2 && *image == *that2->image; return that2 && *image == *that2->image;
} }
Image RotateImage::generate(const Options& opt) const { Image RotateImage::generate(const Options& opt) {
Image img = image->generate(opt); Image img = image->generate(opt);
return rotate_image(img,angle); return rotate_image(img,angle);
} }
@@ -269,7 +269,7 @@ bool RotateImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : EnlargeImage // ----------------------------------------------------------------------------- : EnlargeImage
Image EnlargeImage::generate(const Options& opt) const { Image EnlargeImage::generate(const Options& opt) {
// generate 'sub' image // generate 'sub' image
Options sub_opt Options sub_opt
( int(opt.width * (border_size < 0.5 ? 1 - 2 * border_size : 0)) ( int(opt.width * (border_size < 0.5 ? 1 - 2 * border_size : 0))
@@ -307,7 +307,7 @@ bool EnlargeImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : ResizeImage // ----------------------------------------------------------------------------- : ResizeImage
Image ResizeImage::generate(const Options& opt) const { Image ResizeImage::generate(const Options& opt) {
Image img = image->generate(opt); Image img = image->generate(opt);
return resample(img, width, height); return resample(img, width, height);
} }
@@ -320,7 +320,7 @@ bool ResizeImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : BleedEdgedImage // ----------------------------------------------------------------------------- : BleedEdgedImage
Image BleedEdgedImage::generate(const Options& opt) const { Image BleedEdgedImage::generate(const Options& opt) {
// create enlarged image // create enlarged image
Image base_img = base_image->generate(opt); Image base_img = base_image->generate(opt);
int w = base_img.GetWidth(), h = base_img.GetHeight(); int w = base_img.GetWidth(), h = base_img.GetHeight();
@@ -467,7 +467,7 @@ bool BleedEdgedImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : InsertedImage // ----------------------------------------------------------------------------- : InsertedImage
Image InsertedImage::generate(const Options& opt) const { Image InsertedImage::generate(const Options& opt) {
Image base_img = base_image->generate(opt); Image base_img = base_image->generate(opt);
Image inserted_img = inserted_image->generate(opt); Image inserted_img = inserted_image->generate(opt);
int base_x = offset_x < 0 ? -offset_x : 0; int base_x = offset_x < 0 ? -offset_x : 0;
@@ -507,7 +507,7 @@ bool InsertedImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : CropImage // ----------------------------------------------------------------------------- : CropImage
Image CropImage::generate(const Options& opt) const { Image CropImage::generate(const Options& opt) {
return image->generate(opt).Size(wxSize((int)width, (int)height), wxPoint(-(int)offset_x, -(int)offset_y)); return image->generate(opt).Size(wxSize((int)width, (int)height), wxPoint(-(int)offset_x, -(int)offset_y));
} }
bool CropImage::operator == (const GeneratedImage& that) const { bool CropImage::operator == (const GeneratedImage& that) const {
@@ -568,7 +568,7 @@ UInt gaussian_blur(Byte* in, UInt* out, int w, int h, double radius) {
return total_x * total_y; return total_x * total_y;
} }
Image DropShadowImage::generate(const Options& opt) const { Image DropShadowImage::generate(const Options& opt) {
// sub image // sub image
Image img = image->generate(opt); Image img = image->generate(opt);
if (!img.HasAlpha()) { if (!img.HasAlpha()) {
@@ -611,7 +611,7 @@ bool DropShadowImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : PackagedImage // ----------------------------------------------------------------------------- : PackagedImage
Image PackagedImage::generate(const Options& opt) const { Image PackagedImage::generate(const Options& opt) {
// TODO : use opt.width and opt.height? // TODO : use opt.width and opt.height?
// open file from package // open file from package
if (!opt.package) throw ScriptError(_("Can only load images in a context where an image is expected")); if (!opt.package) throw ScriptError(_("Can only load images in a context where an image is expected"));
@@ -631,7 +631,7 @@ bool PackagedImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : BuiltInImage // ----------------------------------------------------------------------------- : BuiltInImage
Image BuiltInImage::generate(const Options& opt) const { Image BuiltInImage::generate(const Options& opt) {
// TODO : use opt.width and opt.height? // TODO : use opt.width and opt.height?
try { try {
Image img = load_resource_image(name); Image img = load_resource_image(name);
@@ -646,7 +646,7 @@ bool BuiltInImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : ArbitraryImage // ----------------------------------------------------------------------------- : ArbitraryImage
Image ArbitraryImage::generate(const Options& opt) const { Image ArbitraryImage::generate(const Options& opt) {
return image; return image;
} }
bool ArbitraryImage::operator == (const GeneratedImage& that) const { bool ArbitraryImage::operator == (const GeneratedImage& that) const {
@@ -662,7 +662,7 @@ SymbolToImage::SymbolToImage(bool is_local, const LocalFileName& filename, Age a
{} {}
SymbolToImage::~SymbolToImage() {} SymbolToImage::~SymbolToImage() {}
Image SymbolToImage::generate(const Options& opt) const { Image SymbolToImage::generate(const Options& opt) {
// TODO : use opt.width and opt.height? // TODO : use opt.width and opt.height?
Package* package = is_local ? opt.local_package : opt.package; Package* package = is_local ? opt.local_package : opt.package;
if (!package) throw ScriptError(_("Can only load images in a context where an image is expected")); if (!package) throw ScriptError(_("Can only load images in a context where an image is expected"));
@@ -698,7 +698,7 @@ ImageValueToImage::ImageValueToImage(const LocalFileName& filename, Age age)
{} {}
ImageValueToImage::~ImageValueToImage() {} ImageValueToImage::~ImageValueToImage() {}
Image ImageValueToImage::generate(const Options& opt) const { Image ImageValueToImage::generate(const Options& opt) {
// TODO : use opt.width and opt.height? // TODO : use opt.width and opt.height?
if (!opt.local_package) throw ScriptError(_("Can only load images in a context where an image is expected")); if (!opt.local_package) throw ScriptError(_("Can only load images in a context where an image is expected"));
Image image; Image image;
@@ -719,40 +719,48 @@ bool ImageValueToImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : ExternalImage // ----------------------------------------------------------------------------- : ExternalImage
Image ExternalImage::generate(const Options& opt) const { ExternalImage::ExternalImage(const String& filepath)
wxFileName fname(filepath, wxPATH_UNIX); : filepath(filepath), loaded(false)
String filePathString = fname.GetAbsolutePath(); {
filepathSanitized = filepath;
filepathSanitized.Replace(":", "-");
filepathSanitized.Replace("\\", "-");
filepathSanitized.Replace("/", "-");
}
Image ExternalImage::generate(const Options& opt) {
// has a pre-existing .mse-set file been loaded? // has a pre-existing .mse-set file been loaded?
if (opt.local_package->needSaveAs()) throw ScriptError(_ERROR_1_("can't import image without set", filePathString)); if (opt.local_package->needSaveAs()) throw ScriptError(_ERROR_1_("can't import image without set", filepath));
// does the file pointed to by filepath exist? // does the file pointed to by filepath exist?
if (!fname.FileExists()) throw ScriptError(_ERROR_1_("import not found", filePathString)); wxFileName fname(filepath, wxPATH_UNIX);
if (!fname.FileExists()) throw ScriptError(_ERROR_1_("import not found", filepath));
// add the file to the package (or overwrite it if pre-existing)
if (!loaded || !opt.local_package->existsIn(filepathSanitized)) {
auto outStream = opt.local_package->openOut(filepathSanitized);
wxFileInputStream inStream(filepath);
if (!inStream.IsOk()) throw ScriptError(_ERROR_1_("can't create file stream", filepath));
outStream->Write(inStream);
if (!outStream->IsOk()) throw ScriptError(_ERROR_1_("can't write image to set", filepath));
outStream->Close();
loaded = true;
}
// save the package with the new image
opt.local_package->save(false);
// generate Image
String fileExt = fname.GetExt(); String fileExt = fname.GetExt();
wxBitmapType bitmapType; wxBitmapType bitmapType;
if (fileExt == _("png")) bitmapType = wxBITMAP_TYPE_PNG; if (fileExt == _("png")) bitmapType = wxBITMAP_TYPE_PNG;
else if (fileExt == _("jpg") || fileExt == _("jpeg")) bitmapType = wxBITMAP_TYPE_JPEG; else if (fileExt == _("jpg") || fileExt == _("jpeg")) bitmapType = wxBITMAP_TYPE_JPEG;
else bitmapType = wxBITMAP_TYPE_BMP; else bitmapType = wxBITMAP_TYPE_BMP;
// does the file exist in the package? auto imageInputStream = opt.local_package->openIn(filepathSanitized);
String fileNameNoExtension = fname.GetName(); Image img(*imageInputStream, bitmapType);
if (!opt.local_package->existsIn(fileNameNoExtension)) {
auto outStream = opt.local_package->openOut(fileNameNoExtension);
wxFileInputStream inStream = wxFileInputStream(filepath.ToStdString());
if (!inStream.IsOk()) throw ScriptError(_ERROR_1_("can't create file stream", filePathString));
outStream->Write(inStream);
if (!outStream->IsOk()) throw ScriptError(_ERROR_1_("can't write image to set", filePathString));
outStream->Close();
}
// save the package with the new image if (!img.IsOk()) throw ScriptError(_ERROR_1_("can't import image", filepath));
opt.local_package->save(false);
auto imageInputStream = opt.local_package->openIn(fileNameNoExtension);
Image img(*imageInputStream.get(), bitmapType);
if (!img.IsOk()) throw ScriptError(_ERROR_1_("can't import image", filePathString));
return img; return img;
} }
+35 -33
View File
@@ -44,9 +44,9 @@ public:
}; };
/// Generate the image, and conform to the options /// Generate the image, and conform to the options
Image generateConform(const Options&) const; Image generateConform(const Options&);
/// Generate the image /// Generate the image
virtual Image generate(const Options&) const = 0; virtual Image generate(const Options&) = 0;
/// How must the image be combined with the background? /// How must the image be combined with the background?
virtual ImageCombine combine() const { return COMBINE_DEFAULT; } virtual ImageCombine combine() const { return COMBINE_DEFAULT; }
/// Equality should mean that every pixel in the generated images is the same if the same options are used /// Equality should mean that every pixel in the generated images is the same if the same options are used
@@ -87,7 +87,7 @@ protected:
/// An image generator that returns a blank image /// An image generator that returns a blank image
class BlankImage : public GeneratedImage { class BlankImage : public GeneratedImage {
public: public:
Image generate(const Options&) const override; Image generate(const Options&) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
bool isBlank() const override { return true; } bool isBlank() const override { return true; }
@@ -105,7 +105,7 @@ public:
inline LinearBlendImage(const GeneratedImageP& image1, const GeneratedImageP& image2, double x1, double y1, double x2, double y2) inline LinearBlendImage(const GeneratedImageP& image1, const GeneratedImageP& image2, double x1, double y1, double x2, double y2)
: image1(image1), image2(image2), x1(x1), y1(y1), x2(x2), y2(y2) : image1(image1), image2(image2), x1(x1), y1(y1), x2(x2), y2(y2)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
ImageCombine combine() const override; ImageCombine combine() const override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
bool local() const override { return image1->local() && image2->local(); } bool local() const override { return image1->local() && image2->local(); }
@@ -122,7 +122,7 @@ public:
inline MaskedBlendImage(const GeneratedImageP& light, const GeneratedImageP& dark, const GeneratedImageP& mask) inline MaskedBlendImage(const GeneratedImageP& light, const GeneratedImageP& dark, const GeneratedImageP& mask)
: light(light), dark(dark), mask(mask) : light(light), dark(dark), mask(mask)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
ImageCombine combine() const override; ImageCombine combine() const override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
bool local() const override { return light->local() && dark->local() && mask->local(); } bool local() const override { return light->local() && dark->local() && mask->local(); }
@@ -138,7 +138,7 @@ public:
inline CombineBlendImage(const GeneratedImageP& image1, const GeneratedImageP& image2, ImageCombine image_combine) inline CombineBlendImage(const GeneratedImageP& image1, const GeneratedImageP& image2, ImageCombine image_combine)
: image1(image1), image2(image2), image_combine(image_combine) : image1(image1), image2(image2), image_combine(image_combine)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
ImageCombine combine() const override; ImageCombine combine() const override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
bool local() const override { return image1->local() && image2->local(); } bool local() const override { return image1->local() && image2->local(); }
@@ -155,7 +155,7 @@ public:
inline SetMaskImage(const GeneratedImageP& image, const GeneratedImageP& mask) inline SetMaskImage(const GeneratedImageP& image, const GeneratedImageP& mask)
: SimpleFilterImage(image), mask(mask) : SimpleFilterImage(image), mask(mask)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
private: private:
GeneratedImageP mask; GeneratedImageP mask;
@@ -167,7 +167,7 @@ public:
inline SetAlphaImage(const GeneratedImageP& image, double alpha) inline SetAlphaImage(const GeneratedImageP& image, double alpha)
: SimpleFilterImage(image), alpha(alpha) : SimpleFilterImage(image), alpha(alpha)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
private: private:
double alpha; double alpha;
@@ -181,7 +181,7 @@ public:
inline SetCombineImage(const GeneratedImageP& image, ImageCombine image_combine) inline SetCombineImage(const GeneratedImageP& image, ImageCombine image_combine)
: SimpleFilterImage(image), image_combine(image_combine) : SimpleFilterImage(image), image_combine(image_combine)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
ImageCombine combine() const override; ImageCombine combine() const override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
private: private:
@@ -196,7 +196,7 @@ public:
inline SaturateImage(const GeneratedImageP& image, double amount) inline SaturateImage(const GeneratedImageP& image, double amount)
: SimpleFilterImage(image), amount(amount) : SimpleFilterImage(image), amount(amount)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
private: private:
double amount; double amount;
@@ -210,7 +210,7 @@ public:
inline InvertImage(const GeneratedImageP& image) inline InvertImage(const GeneratedImageP& image)
: SimpleFilterImage(image) : SimpleFilterImage(image)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
}; };
@@ -222,7 +222,7 @@ public:
inline RecolorImage(const GeneratedImageP& image, Color color) inline RecolorImage(const GeneratedImageP& image, Color color)
: SimpleFilterImage(image), color(color) : SimpleFilterImage(image), color(color)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
private: private:
Color color; Color color;
@@ -233,7 +233,7 @@ public:
inline RecolorImage2(const GeneratedImageP& image, Color red, Color green, Color blue, Color white) inline RecolorImage2(const GeneratedImageP& image, Color red, Color green, Color blue, Color white)
: SimpleFilterImage(image), red(red), green(green), blue(blue), white(white) : SimpleFilterImage(image), red(red), green(green), blue(blue), white(white)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
private: private:
Color red,green,blue,white; Color red,green,blue,white;
@@ -247,7 +247,7 @@ public:
inline FlipImageHorizontal(const GeneratedImageP& image) inline FlipImageHorizontal(const GeneratedImageP& image)
: SimpleFilterImage(image) : SimpleFilterImage(image)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
}; };
@@ -257,7 +257,7 @@ public:
inline FlipImageVertical(const GeneratedImageP& image) inline FlipImageVertical(const GeneratedImageP& image)
: SimpleFilterImage(image) : SimpleFilterImage(image)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
}; };
@@ -267,7 +267,7 @@ public:
inline RotateImage(const GeneratedImageP& image, Radians angle) inline RotateImage(const GeneratedImageP& image, Radians angle)
: SimpleFilterImage(image), angle(angle) : SimpleFilterImage(image), angle(angle)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
private: private:
Radians angle; Radians angle;
@@ -281,7 +281,7 @@ public:
inline EnlargeImage(const GeneratedImageP& image, double border_size) inline EnlargeImage(const GeneratedImageP& image, double border_size)
: SimpleFilterImage(image), border_size(fabs(border_size)) : SimpleFilterImage(image), border_size(fabs(border_size))
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
private: private:
double border_size; double border_size;
@@ -295,7 +295,7 @@ public:
inline ResizeImage(const GeneratedImageP& image, int width, int height) inline ResizeImage(const GeneratedImageP& image, int width, int height)
: SimpleFilterImage(image), width(max(1, width)), height(max(1, height)) : SimpleFilterImage(image), width(max(1, width)), height(max(1, height))
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
private: private:
int width; int width;
@@ -310,7 +310,7 @@ public:
inline CropImage(const GeneratedImageP& image, double width, double height, double offset_x, double offset_y) inline CropImage(const GeneratedImageP& image, double width, double height, double offset_x, double offset_y)
: SimpleFilterImage(image), width(width), height(height), offset_x(offset_x), offset_y(offset_y) : SimpleFilterImage(image), width(width), height(height), offset_x(offset_x), offset_y(offset_y)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
private: private:
double width, height; double width, height;
@@ -325,7 +325,7 @@ public:
inline BleedEdgedImage(const GeneratedImageP& base_image, double horizontal_size, double vertical_size, Color background_color) inline BleedEdgedImage(const GeneratedImageP& base_image, double horizontal_size, double vertical_size, Color background_color)
: base_image(base_image), horizontal_size(horizontal_size), vertical_size(vertical_size), background_color(background_color) : base_image(base_image), horizontal_size(horizontal_size), vertical_size(vertical_size), background_color(background_color)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
private: private:
GeneratedImageP base_image; GeneratedImageP base_image;
@@ -341,7 +341,7 @@ public:
inline InsertedImage(const GeneratedImageP& base_image, const GeneratedImageP& inserted_image, int offset_x, int offset_y, Color background_color) inline InsertedImage(const GeneratedImageP& base_image, const GeneratedImageP& inserted_image, int offset_x, int offset_y, Color background_color)
: base_image(base_image), inserted_image(inserted_image), offset_x(offset_x), offset_y(offset_y), background_color(background_color) : base_image(base_image), inserted_image(inserted_image), offset_x(offset_x), offset_y(offset_y), background_color(background_color)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
ImageCombine combine() const override; ImageCombine combine() const override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
bool local() const override { return base_image->local() && inserted_image->local(); } bool local() const override { return base_image->local() && inserted_image->local(); }
@@ -360,7 +360,7 @@ public:
: SimpleFilterImage(image), offset_x(offset_x), offset_y(offset_y) : SimpleFilterImage(image), offset_x(offset_x), offset_y(offset_y)
, shadow_alpha(shadow_alpha), shadow_blur_radius(shadow_blur_radius), shadow_color(shadow_color) , shadow_alpha(shadow_alpha), shadow_blur_radius(shadow_blur_radius), shadow_color(shadow_color)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
private: private:
double offset_x, offset_y; double offset_x, offset_y;
@@ -377,7 +377,7 @@ public:
inline PackagedImage(const String& filename) inline PackagedImage(const String& filename)
: filename(filename) : filename(filename)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
private: private:
String filename; String filename;
@@ -391,7 +391,7 @@ public:
inline BuiltInImage(const String& name) inline BuiltInImage(const String& name)
: name(name) : name(name)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
private: private:
String name; String name;
@@ -404,7 +404,7 @@ public:
inline ArbitraryImage(const Image image) inline ArbitraryImage(const Image image)
: image(image) : image(image)
{} {}
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
private: private:
Image image; Image image;
@@ -417,7 +417,7 @@ class SymbolToImage : public GeneratedImage {
public: public:
SymbolToImage(bool is_local, const LocalFileName& filename, Age age, const SymbolVariationP& variation); SymbolToImage(bool is_local, const LocalFileName& filename, Age age, const SymbolVariationP& variation);
~SymbolToImage(); ~SymbolToImage();
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
bool local() const override { return is_local; } bool local() const override { return is_local; }
@@ -439,7 +439,7 @@ class ImageValueToImage : public GeneratedImage {
public: public:
ImageValueToImage(const LocalFileName& filename, Age age); ImageValueToImage(const LocalFileName& filename, Age age);
~ImageValueToImage(); ~ImageValueToImage();
Image generate(const Options& opt) const override; Image generate(const Options& opt) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
bool local() const override { return true; } bool local() const override { return true; }
private: private:
@@ -453,11 +453,13 @@ private:
/// Load an image from the filesystem /// Load an image from the filesystem
class ExternalImage : public GeneratedImage { class ExternalImage : public GeneratedImage {
public: public:
ExternalImage(const String& filepath) : filepath(filepath) {}; ExternalImage(const String& filepath);
Image generate(const Options&) const override; Image generate(const Options&) override;
bool operator == (const GeneratedImage& that) const override; bool operator == (const GeneratedImage& that) const override;
inline String toString() { return filepath; } inline String toString() { return filepath; }
inline String toCode() const override { return _("<image>"); } inline String toCode() const override { return _("<image>"); }
private: private:
String filepath; String filepath;
String filepathSanitized;
bool loaded; ///< Make sure we at least load the image from outside the package once, as it may have been updated externally
}; };
+1 -1
View File
@@ -90,7 +90,7 @@ void HoverButtonBase::onMouseEnter(wxMouseEvent&) {
void HoverButtonBase::onMouseLeave(wxMouseEvent&) { void HoverButtonBase::onMouseLeave(wxMouseEvent&) {
hover = false; hover = false;
refreshIfNeeded(); refreshIfNeeded();
if (!help_text.empty()) set_status_text(this,wxEmptyString); if (!help_text.empty()) set_status_text(this,_(""));
} }
void HoverButtonBase::onFocus(wxFocusEvent&) { void HoverButtonBase::onFocus(wxFocusEvent&) {
focus = true; focus = true;
+2 -2
View File
@@ -27,7 +27,7 @@ AddCSVWindow::AddCSVWindow(Window* parent, const SetP& set, bool sizer)
, set(set) , set(set)
{ {
// init controls // init controls
file_path = new wxTextCtrl(this, wxID_ANY, wxEmptyString); file_path = new wxTextCtrl(this, wxID_ANY, _(""));
file_browse = new wxButton(this, ID_CARD_ADD_CSV_BROWSE, _BUTTON_("browse")); file_browse = new wxButton(this, ID_CARD_ADD_CSV_BROWSE, _BUTTON_("browse"));
separator_type = new wxChoice(this, ID_CARD_ADD_CSV_SEP, wxDefaultPosition, wxDefaultSize, 0, nullptr); separator_type = new wxChoice(this, ID_CARD_ADD_CSV_SEP, wxDefaultPosition, wxDefaultSize, 0, nullptr);
separator_type->Clear(); separator_type->Clear();
@@ -66,7 +66,7 @@ void AddCSVWindow::onSeparatorTypeChange(wxCommandEvent&) {
} }
void AddCSVWindow::onBrowseFiles(wxCommandEvent&) { void AddCSVWindow::onBrowseFiles(wxCommandEvent&) {
wxFileDialog* dlg = new wxFileDialog(this, _TITLE_("add card csv file"), settings.default_set_dir, wxEmptyString, _("CSV files|*.csv;*.tsv|All files (*.*)|*"), wxFD_OPEN); wxFileDialog* dlg = new wxFileDialog(this, _TITLE_("add card csv file"), settings.default_set_dir, _(""), _("CSV files|*.csv;*.tsv|All files (*.*)|*"), wxFD_OPEN);
if (dlg->ShowModal() == wxID_OK) { if (dlg->ShowModal() == wxID_OK) {
file_path->SetValue(dlg->GetPath()); file_path->SetValue(dlg->GetPath());
} }
+5 -5
View File
@@ -33,7 +33,7 @@ AddJSONWindow::AddJSONWindow(Window* parent, const SetP& set, bool sizer)
, set(set) , set(set)
{ {
// init controls // init controls
file_path = new wxTextCtrl(this, wxID_ANY, wxEmptyString); file_path = new wxTextCtrl(this, wxID_ANY, _(""));
file_browse = new wxButton(this, ID_CARD_ADD_JSON_BROWSE, _BUTTON_("browse")); file_browse = new wxButton(this, ID_CARD_ADD_JSON_BROWSE, _BUTTON_("browse"));
json_type = new wxChoice(this, ID_CARD_ADD_JSON_ARRAY, wxDefaultPosition, wxDefaultSize, 0, nullptr); json_type = new wxChoice(this, ID_CARD_ADD_JSON_ARRAY, wxDefaultPosition, wxDefaultSize, 0, nullptr);
json_type->Clear(); json_type->Clear();
@@ -43,7 +43,7 @@ AddJSONWindow::AddJSONWindow(Window* parent, const SetP& set, bool sizer)
} }
json_type->Append(_LABEL_("add card json custom")); json_type->Append(_LABEL_("add card json custom"));
json_type->SetSelection(0); json_type->SetSelection(0);
card_array_path = new wxTextCtrl(this, wxID_ANY, wxEmptyString); card_array_path = new wxTextCtrl(this, wxID_ANY, _(""));
setJSONType(); setJSONType();
// init sizers // init sizers
if (sizer) { if (sizer) {
@@ -68,7 +68,7 @@ AddJSONWindow::AddJSONWindow(Window* parent, const SetP& set, bool sizer)
void AddJSONWindow::setJSONType() { void AddJSONWindow::setJSONType() {
int sel = json_type->GetSelection(); int sel = json_type->GetSelection();
if (sel == json_type->GetCount() - 1) { // Custom type if (sel == json_type->GetCount() - 1) { // Custom type
card_array_path->ChangeValue(wxEmptyString); card_array_path->ChangeValue(_(""));
card_array_path->Enable(); card_array_path->Enable();
} }
else { else {
@@ -89,7 +89,7 @@ void AddJSONWindow::onJSONTypeChange(wxCommandEvent&) {
} }
void AddJSONWindow::onBrowseFiles(wxCommandEvent&) { void AddJSONWindow::onBrowseFiles(wxCommandEvent&) {
wxFileDialog* dlg = new wxFileDialog(this, _TITLE_("add card json file"), settings.default_set_dir, wxEmptyString, _("JSON files|*.json|All files (*.*)|*"), wxFD_OPEN); wxFileDialog* dlg = new wxFileDialog(this, _TITLE_("add card json file"), settings.default_set_dir, _(""), _("JSON files|*.json|All files (*.*)|*"), wxFD_OPEN);
if (dlg->ShowModal() == wxID_OK) { if (dlg->ShowModal() == wxID_OK) {
file_path->SetValue(dlg->GetPath()); file_path->SetValue(dlg->GetPath());
} }
@@ -102,7 +102,7 @@ void AddJSONWindow::onBrowseFiles(wxCommandEvent&) {
try { try {
jv = boost::json::parse(input); jv = boost::json::parse(input);
} catch (...) { } catch (...) {
queue_message(MESSAGE_ERROR, _ERROR_("add card json failed to parse")); queue_message(MESSAGE_ERROR, _ERROR_("json cant parse"));
return false; return false;
} }
// Split path into tokens // Split path into tokens
+2 -2
View File
@@ -268,8 +268,8 @@ void AutoReplaceWindow::refreshItem() {
enabled ->SetValue(ar->enabled); enabled ->SetValue(ar->enabled);
whole_word->SetValue(ar->whole_word); whole_word->SetValue(ar->whole_word);
} else { } else {
match ->SetValue(wxEmptyString); match ->SetValue(_(""));
replace ->SetValue(wxEmptyString); replace ->SetValue(_(""));
enabled ->SetValue(false); enabled ->SetValue(false);
whole_word->SetValue(false); whole_word->SetValue(false);
} }
+2 -2
View File
@@ -21,8 +21,8 @@ CardLinkWindow::CardLinkWindow(Window* parent, const SetP& set, const CardP& sel
, set(set), selected_card(selected_card) , set(set), selected_card(selected_card)
{ {
// init controls // init controls
selected_relation = new wxTextCtrl(this, wxID_ANY, wxEmptyString); selected_relation = new wxTextCtrl(this, wxID_ANY, _(""));
linked_relation = new wxTextCtrl(this, wxID_ANY, wxEmptyString); linked_relation = new wxTextCtrl(this, wxID_ANY, _(""));
relation_type = new wxChoice(this, ID_CARD_LINK_TYPE, wxDefaultPosition, wxDefaultSize, 0, nullptr); relation_type = new wxChoice(this, ID_CARD_LINK_TYPE, wxDefaultPosition, wxDefaultSize, 0, nullptr);
relation_type->Clear(); relation_type->Clear();
FOR_EACH(link, set->game->card_links) { FOR_EACH(link, set->game->card_links) {
+1 -1
View File
@@ -73,7 +73,7 @@ wxSizer* ExportWindowBase::Create() {
s->AddSpacer(4); s->AddSpacer(4);
s->Add(new wxStaticLine(this), 0, wxALL | wxEXPAND, 4); s->Add(new wxStaticLine(this), 0, wxALL | wxEXPAND, 4);
s->AddSpacer(4); s->AddSpacer(4);
card_count = new wxStaticText(this, wxID_ANY, wxEmptyString); card_count = new wxStaticText(this, wxID_ANY, _(""));
s->Add(card_count, 0, wxALL & ~wxTOP, 6); s->Add(card_count, 0, wxALL & ~wxTOP, 6);
s->AddSpacer(4); s->AddSpacer(4);
// done // done
+1 -1
View File
@@ -381,7 +381,7 @@ void DataEditor::onMouseLeave(wxMouseEvent& ev) {
} }
// clear status text // clear status text
wxFrame* frame = dynamic_cast<wxFrame*>( wxGetTopLevelParent(this) ); wxFrame* frame = dynamic_cast<wxFrame*>( wxGetTopLevelParent(this) );
if (frame) frame->SetStatusText(wxEmptyString); if (frame) frame->SetStatusText(_(""));
} }
bool DataEditor::selectViewer(ValueViewer* v) { bool DataEditor::selectViewer(ValueViewer* v) {
+231 -40
View File
@@ -11,6 +11,7 @@
#include <gui/control/card_list_column_select.hpp> #include <gui/control/card_list_column_select.hpp>
#include <gui/set/window.hpp> // for sorting all cardlists in a window #include <gui/set/window.hpp> // for sorting all cardlists in a window
#include <gui/card_link_window.hpp> #include <gui/card_link_window.hpp>
#include <gui/web_request_window.hpp>
#include <gui/util.hpp> #include <gui/util.hpp>
#include <gui/add_csv_window.hpp> #include <gui/add_csv_window.hpp>
#include <gui/add_json_window.hpp> #include <gui/add_json_window.hpp>
@@ -22,11 +23,16 @@
#include <data/settings.hpp> #include <data/settings.hpp>
#include <data/stylesheet.hpp> #include <data/stylesheet.hpp>
#include <data/format/clipboard.hpp> #include <data/format/clipboard.hpp>
#include <data/format/formats.hpp>
#include <data/action/set.hpp> #include <data/action/set.hpp>
#include <data/action/value.hpp> #include <data/action/value.hpp>
#include <script/functions/json.hpp>
#include <util/window_id.hpp> #include <util/window_id.hpp>
#include <wx/clipbrd.h> #include <wx/clipbrd.h>
#include <wx/webrequest.h>
#include <wx/wfstream.h>
#include <unordered_set> #include <unordered_set>
#include <fstream>
DECLARE_POINTER_TYPE(ChoiceValue); DECLARE_POINTER_TYPE(ChoiceValue);
@@ -51,7 +57,9 @@ CardListBase* CardSelectEvent::getTheCardList() const {
CardListBase::CardListBase(Window* parent, int id, long additional_style) CardListBase::CardListBase(Window* parent, int id, long additional_style)
: ItemList(parent, id, additional_style, true) : ItemList(parent, id, additional_style, true)
{} {
drop_target = new CardListDropTarget(this);
}
CardListBase::~CardListBase() { CardListBase::~CardListBase() {
storeColumns(); storeColumns();
@@ -141,7 +149,7 @@ void CardListBase::getSelection(vector<CardP>& out) const {
bool CardListBase::canCut() const { return canDelete(); } bool CardListBase::canCut() const { return canDelete(); }
bool CardListBase::canCopy() const { return focusCount() > 0; } bool CardListBase::canCopy() const { return focusCount() > 0; }
bool CardListBase::canPaste() const { bool CardListBase::canPaste() const {
return allowModify() && wxTheClipboard->IsSupported(CardsDataObject::format); return allowModify();
} }
bool CardListBase::canDelete() const { bool CardListBase::canDelete() const {
return allowModify() && focusCount() > 0; // TODO: check for selection? return allowModify() && focusCount() > 0; // TODO: check for selection?
@@ -159,6 +167,7 @@ bool CardListBase::doCopy() {
wxTheClipboard->Close(); wxTheClipboard->Close();
return ok; return ok;
} }
bool CardListBase::doCopyCardAndLinkedCards() { bool CardListBase::doCopyCardAndLinkedCards() {
if (!canCopy()) return false; if (!canCopy()) return false;
vector<CardP> cards_selected; vector<CardP> cards_selected;
@@ -184,22 +193,16 @@ bool CardListBase::doCopyCardAndLinkedCards() {
wxTheClipboard->Close(); wxTheClipboard->Close();
return ok; return ok;
} }
bool CardListBase::doPaste() { bool CardListBase::doPaste() {
// get data
if (!canPaste()) return false; if (!canPaste()) return false;
if (!wxTheClipboard->Open()) return false; if (!wxTheClipboard->Open()) return false;
CardsDataObject data; bool ok = wxTheClipboard->GetData(*drop_target->data_object);
bool ok = wxTheClipboard->GetData(data);
wxTheClipboard->Close(); wxTheClipboard->Close();
if (!ok) return false; if (ok) return parseData();
// get cards return false;
vector<CardP> new_cards;
ok = data.getCards(set, new_cards);
if (!ok) return false;
// add card to set
set->actions.addAction(make_unique<AddCardAction>(ADD, *set, new_cards));
return true;
} }
bool CardListBase::doDelete() { bool CardListBase::doDelete() {
// cards to delete // cards to delete
vector<CardP> cards_to_delete; vector<CardP> cards_to_delete;
@@ -210,6 +213,180 @@ bool CardListBase::doDelete() {
return true; return true;
} }
bool CardListBase::doAddCSV() {
AddCSVWindow wnd(this, set, true);
if (wnd.ShowModal() == wxID_OK) {
// The actual adding is done in this window's onOk function
return true;
}
return false;
}
bool CardListBase::doAddJSON() {
AddJSONWindow wnd(this, set, true);
if (wnd.ShowModal() == wxID_OK) {
// The actual adding is done in this window's onOk function
return true;
}
return false;
}
bool CardListBase::parseUrl(String& url, vector<CardP>& out) {
size_t j = out.size();
size_t pos = url.find("URL=");
if (pos != std::string::npos) {
url = url.substr(pos+4);
}
if (!url.StartsWith(_("http"))) return false;
WebRequestWindow wnd(this, url);
if (wnd.ShowModal() == wxID_OK) {
const String& content_type = wnd.out.GetContentType();
if (content_type.StartsWith(_("image"))) {
Image img(*wnd.out.GetStream());
if (img.IsOk()) {
parseImage(img, out);
}
else {
queue_message(MESSAGE_ERROR, _ERROR_("web request corrupted"));
}
}
else if (content_type.StartsWith(_("text"))) {
String text = wnd.out.AsString();
parseText(text, out);
}
else {
queue_message(MESSAGE_ERROR, _ERROR_("web request unsupported format"));
}
}
return j < out.size();
}
bool CardListBase::parseFiles(wxArrayString& filenames, vector<CardP>& out) {
size_t j = out.size();
for (size_t i = 0; i < filenames.size(); i++) {
// if it's an image file, try to get meta_data
Image image_file;
image_file.SetLoadFlags(image_file.GetLoadFlags() & ~wxImage::Load_Verbose);
if (image_file.LoadFile(filenames[i])) {
parseImage(image_file, out);
} else {
// if it's an url, request the data
std::ifstream ifs(filenames[i].ToStdString());
if (ifs.bad() || ifs.fail() || !ifs.good() || !ifs.is_open()) continue;
std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
wxString text(content);
if (!parseUrl(text, out)) parseText(text, out);
}
}
return j < out.size();
}
bool CardListBase::parseImage(Image& image, vector<CardP>& out) {
size_t j = out.size();
if (image.HasOption(wxIMAGE_OPTION_PNG_DESCRIPTION)) {
parseText(image.GetOption(wxIMAGE_OPTION_PNG_DESCRIPTION), out);
// crop image rects to populate image fields
for (; j < out.size(); j++) {
CardP& card = out[j];
for (IndexMap<FieldP, ValueP>::iterator it = card->data.begin(); it != card->data.end(); it++) {
ImageValue* value = dynamic_cast<ImageValue*>(it->get());
if (value && !value->filename.empty()) {
wxRect rect = value->filename.getExternalRect();
if (rect.width > 0 && rect.height > 0) {
Image& img = image.GetSubImage(rect);
LocalFileName filename = set->newFileName((*it)->fieldP->name, settings.internal_image_extension ? _(".png") : _("")); // a new unique name in the package
img.SaveFile(set->nameOut(filename), wxBITMAP_TYPE_PNG);
value->filename = filename;
}
}
}
}
}
return j < out.size();
}
bool CardListBase::parseText(String& text, vector<CardP>& out) {
size_t j = out.size();
if (size_t pos = text.find("<mse-data-start>") != wxString::npos) {
text = text.substr(pos + 15, text.find("<mse-data-end>") - pos - 15);
}
try {
ScriptValueP& sv = json_to_mse(text, set.get());
if (sv->type() == SCRIPT_COLLECTION) {
if (ScriptCustomCollection* custom = dynamic_cast<ScriptCustomCollection*>(sv.get())) {
for (size_t i = 0; i < custom->value.size(); i++) {
if (ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(custom->value[i].get())) {
out.push_back(make_intrusive<Card>(*c->getValue()));
}
}
}
} else if (ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(sv.get())) {
out.push_back(make_intrusive<Card>(*c->getValue()));
}
} catch (...) {}
return j < out.size();
}
bool CardListBase::parseData() {
wxBusyCursor wait;
wxDataFormat format = drop_target->data_object->GetReceivedFormat();
wxDataObject *data = drop_target->data_object->GetObject(format);
vector<CardP> new_cards;
if (CardsDataObject* card_data = dynamic_cast<CardsDataObject*>(data)) {
card_data->getCards(set, new_cards);
}
else switch (format.GetType())
{
case wxDF_FILENAME:
{
wxFileDataObject* file_data = static_cast<wxFileDataObject*>(data);
wxArrayString filenames = file_data->GetFilenames();
parseFiles(filenames, new_cards);
}
break;
case wxDF_PNG:
{
wxImageDataObject* image_data = static_cast<wxImageDataObject*>(data);
Image image = image_data->GetImage();
parseImage(image, new_cards);
}
break;
case wxDF_BITMAP:
{
wxBitmapDataObject* bitmap_data = static_cast<wxBitmapDataObject*>(data);
wxBitmap bitmap = bitmap_data->GetBitmap();
Image image = bitmap.ConvertToImage();
parseImage(image, new_cards);
}
break;
case wxDF_UNICODETEXT:
case wxDF_TEXT:
case wxDF_HTML:
{
wxTextDataObject* text_data = static_cast<wxTextDataObject*>(data);
String text = text_data->GetText();
if (!parseUrl(text, new_cards)) parseText(text, new_cards);
}
break;
default:
{
queue_message(MESSAGE_ERROR, _ERROR_("unknown data format"));
}
}
if (new_cards.size() > 0) {
set->actions.addAction(make_unique<AddCardAction>(ADD, *set, new_cards));
return true;
}
return false;
}
// --------------------------------------------------- : CardListBase : Card linking // --------------------------------------------------- : CardListBase : Card linking
bool CardListBase::canLink() const { bool CardListBase::canLink() const {
@@ -229,23 +406,6 @@ bool CardListBase::doUnlink(CardP unlinked_card) {
set->actions.addAction(make_unique<UnlinkCardsAction>(*set, getCard(), unlinked_card)); set->actions.addAction(make_unique<UnlinkCardsAction>(*set, getCard(), unlinked_card));
return true; return true;
} }
bool CardListBase::doAddCSV() {
AddCSVWindow wnd(this, set, true);
if (wnd.ShowModal() == wxID_OK) {
// The actual adding is done in this window's onOk function
return true;
}
return false;
}
bool CardListBase::doAddJSON() {
AddJSONWindow wnd(this, set, true);
if (wnd.ShowModal() == wxID_OK) {
// The actual adding is done in this window's onOk function
return true;
}
return false;
}
// ----------------------------------------------------------------------------- : CardListBase : Building the list // ----------------------------------------------------------------------------- : CardListBase : Building the list
@@ -347,7 +507,7 @@ void CardListBase::storeColumns() {
// store sorting // store sorting
GameSettings& gs = settings.gameSettingsFor(*set->game); GameSettings& gs = settings.gameSettingsFor(*set->game);
if (sort_by_column >= 0) gs.sort_cards_by = column_fields.at(sort_by_column)->name; if (sort_by_column >= 0) gs.sort_cards_by = column_fields.at(sort_by_column)->name;
else gs.sort_cards_by = wxEmptyString; else gs.sort_cards_by = _("");
gs.sort_cards_ascending = sort_ascending; gs.sort_cards_ascending = sort_ascending;
} }
@@ -373,11 +533,11 @@ void CardListBase::selectColumns() {
String CardListBase::OnGetItemText(long pos, long col) const { String CardListBase::OnGetItemText(long pos, long col) const {
if (col < 0 || (size_t)col >= column_fields.size()) { if (col < 0 || (size_t)col >= column_fields.size()) {
// wx may give us non existing columns! // wx may give us non existing columns!
return wxEmptyString; return _("");
} }
ValueP val = getCard(pos)->data[column_fields[col]]; ValueP val = getCard(pos)->data[column_fields[col]];
if (val) return val->toString(); if (val) return val->toString();
else return wxEmptyString; else return _("");
} }
int CardListBase::OnGetItemImage(long pos) const { int CardListBase::OnGetItemImage(long pos) const {
@@ -433,6 +593,15 @@ void CardListBase::onChar(wxKeyEvent& ev) {
} }
} }
void CardListBase::onBeginDrag(wxListEvent&) {
vector<CardP> cards;
getSelection(cards);
CardsOnClipboard* card_data = new CardsOnClipboard(set, cards);
wxDropSource drag_source(this);
drag_source.SetData(*card_data);
drag_source.DoDragDrop(wxDrag_CopyOnly);
}
void CardListBase::onDrag(wxMouseEvent& ev) { void CardListBase::onDrag(wxMouseEvent& ev) {
ev.Skip(); ev.Skip();
if (!allowModify()) return; if (!allowModify()) return;
@@ -473,14 +642,36 @@ void CardListBase::onItemActivate(wxListEvent& ev) {
sendEvent(EVENT_CARD_ACTIVATE); sendEvent(EVENT_CARD_ACTIVATE);
} }
// ----------------------------------------------------------------------------- : CardListDropTarget
CardListDropTarget::CardListDropTarget(CardListBase* card_list)
: card_list(card_list)
{
data_object = new wxDataObjectComposite();
data_object->Add(new CardsDataObject(), true);
data_object->Add(new wxFileDataObject());
data_object->Add(new wxImageDataObject());
data_object->Add(new wxTextDataObject());
SetDataObject(data_object);
}
CardListDropTarget::~CardListDropTarget() {}
wxDragResult CardListDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult defaultDragResult) {
if (!GetData()) return wxDragNone;
if (!card_list->parseData()) return wxDragError;
return wxDragCopy;
}
// ----------------------------------------------------------------------------- : CardListBase : Event table // ----------------------------------------------------------------------------- : CardListBase : Event table
BEGIN_EVENT_TABLE(CardListBase, ItemList) BEGIN_EVENT_TABLE(CardListBase, ItemList)
EVT_LIST_COL_RIGHT_CLICK (wxID_ANY, CardListBase::onColumnRightClick) EVT_LIST_COL_RIGHT_CLICK (wxID_ANY, CardListBase::onColumnRightClick)
EVT_LIST_COL_END_DRAG (wxID_ANY, CardListBase::onColumnResize) EVT_LIST_COL_END_DRAG (wxID_ANY, CardListBase::onColumnResize)
EVT_LIST_ITEM_ACTIVATED (wxID_ANY, CardListBase::onItemActivate) EVT_LIST_ITEM_ACTIVATED (wxID_ANY, CardListBase::onItemActivate)
EVT_CHAR ( CardListBase::onChar) EVT_LIST_BEGIN_DRAG (wxID_ANY, CardListBase::onBeginDrag)
EVT_MOTION ( CardListBase::onDrag) EVT_CHAR ( CardListBase::onChar)
EVT_MENU (ID_SELECT_COLUMNS, CardListBase::onSelectColumns) EVT_MOTION ( CardListBase::onDrag)
EVT_CONTEXT_MENU ( CardListBase::onContextMenu) EVT_MENU (ID_SELECT_COLUMNS, CardListBase::onSelectColumns)
EVT_CONTEXT_MENU ( CardListBase::onContextMenu)
END_EVENT_TABLE () END_EVENT_TABLE ()
+28 -2
View File
@@ -12,10 +12,12 @@
#include <gui/control/item_list.hpp> #include <gui/control/item_list.hpp>
#include <data/card.hpp> #include <data/card.hpp>
#include <data/set.hpp> #include <data/set.hpp>
#include <wx/dnd.h>
DECLARE_POINTER_TYPE(ChoiceField); DECLARE_POINTER_TYPE(ChoiceField);
DECLARE_POINTER_TYPE(Field); DECLARE_POINTER_TYPE(Field);
class CardListBase; class CardListBase;
class CardListDropTarget;
// ----------------------------------------------------------------------------- : Events // ----------------------------------------------------------------------------- : Events
@@ -67,7 +69,9 @@ public:
inline CardP getCard() const { return static_pointer_cast<Card>(selected_item); } inline CardP getCard() const { return static_pointer_cast<Card>(selected_item); }
inline void setCard(const CardP& card, bool event = false) { selectItem(card, true, event); } inline void setCard(const CardP& card, bool event = false) { selectItem(card, true, event); }
// --------------------------------------------------- : Clipboard // --------------------------------------------------- : Clipboard and Drag'n'Drop
CardListDropTarget* drop_target;
bool canCut() const override; bool canCut() const override;
bool canCopy() const override; bool canCopy() const override;
@@ -81,6 +85,13 @@ public:
bool doAddCSV(); bool doAddCSV();
bool doAddJSON(); bool doAddJSON();
// Look for cards inside some given data
bool parseData();
bool parseUrl (String& url, vector<CardP>& out);
bool parseFiles(wxArrayString& filenames, vector<CardP>& out);
bool parseText (String& text, vector<CardP>& out);
bool parseImage(Image& image, vector<CardP>& out);
// --------------------------------------------------- : Card linking // --------------------------------------------------- : Card linking
bool canLink() const; bool canLink() const;
@@ -135,7 +146,7 @@ private:
vector<FieldP> column_fields; ///< The field to use for each column (by column index) vector<FieldP> column_fields; ///< The field to use for each column (by column index)
FieldP alternate_sort_field; ///< Second field to sort by, if the column doesn't suffice FieldP alternate_sort_field; ///< Second field to sort by, if the column doesn't suffice
mutable wxListItemAttr item_attr; // for OnGetItemAttr mutable wxListItemAttr item_attr; ///< for OnGetItemAttr
public: public:
/// Open a dialog for selecting columns to be shown /// Open a dialog for selecting columns to be shown
@@ -152,7 +163,22 @@ private:
void onItemActivate (wxListEvent&); void onItemActivate (wxListEvent&);
void onSelectColumns (wxCommandEvent&); void onSelectColumns (wxCommandEvent&);
void onChar (wxKeyEvent&); void onChar (wxKeyEvent&);
void onBeginDrag (wxListEvent&);
void onDrag (wxMouseEvent&); void onDrag (wxMouseEvent&);
void onContextMenu (wxContextMenuEvent&); void onContextMenu (wxContextMenuEvent&);
}; };
// ----------------------------------------------------------------------------- : Drag'n'Drop
class CardListDropTarget : public wxDropTarget {
public:
CardListDropTarget(CardListBase* card_list);
~CardListDropTarget();
wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult defaultDragResult) override;
wxDataObjectComposite* data_object; ///< the object that acquires the data from the Clipboard or a Drag'n'Drop
private:
CardListBase* card_list; ///< the card list we are the drop target of
};
+2 -2
View File
@@ -1172,10 +1172,10 @@ bool GraphControl::hasSelection(size_t axis) const {
return axis < current_item.size() && current_item[axis] >= 0; return axis < current_item.size() && current_item[axis] >= 0;
} }
String GraphControl::getSelection(size_t axis) const { String GraphControl::getSelection(size_t axis) const {
if (!graph || axis >= current_item.size() || axis >= graph->getData()->axes.size()) return wxEmptyString; if (!graph || axis >= current_item.size() || axis >= graph->getData()->axes.size()) return _("");
GraphAxis& a = *graph->getData()->axes[axis]; GraphAxis& a = *graph->getData()->axes[axis];
int i = current_item[axis]; int i = current_item[axis];
if (i == -1 || (size_t)i >= a.groups.size()) return wxEmptyString; if (i == -1 || (size_t)i >= a.groups.size()) return _("");
return a.groups[current_item[axis]].name; return a.groups[current_item[axis]].name;
} }
vector<int> GraphControl::getSelectionIndices() const { vector<int> GraphControl::getSelectionIndices() const {
+2 -2
View File
@@ -192,7 +192,7 @@ int KeywordList::usage(const Keyword& kw) const {
// ----------------------------------------------------------------------------- : KeywordList : Item text // ----------------------------------------------------------------------------- : KeywordList : Item text
String KeywordList::OnGetItemText (long pos, long col) const { String KeywordList::OnGetItemText (long pos, long col) const {
if (sorted_list.size() == 0) return wxEmptyString; if (sorted_list.size() == 0) return _("");
const Keyword& kw = *getKeyword(pos); const Keyword& kw = *getKeyword(pos);
switch(col) { switch(col) {
@@ -218,7 +218,7 @@ String KeywordList::OnGetItemText (long pos, long col) const {
} }
return formatted; return formatted;
} }
default: return wxEmptyString; default: return _("");
} }
} }
int KeywordList::OnGetItemImage(long pos) const { int KeywordList::OnGetItemImage(long pos) const {
+13 -5
View File
@@ -24,7 +24,7 @@ bool PackageData::contains(QuickFilterPart const& query) const {
PackageList::PackageList(Window* parent, int id, int direction, bool always_focused) PackageList::PackageList(Window* parent, int id, int direction, bool always_focused)
: GalleryList(parent, id, direction, always_focused) : GalleryList(parent, id, direction, always_focused)
{ {
item_size = subcolumns[0].size = wxSize(125, 150); item_size = subcolumns[0].size = wxSize(130, 150);
SetThemeEnabled(true); SetThemeEnabled(true);
} }
@@ -43,15 +43,23 @@ void PackageList::drawItem(DC& dc, int x, int y, size_t item) {
dc.DrawBitmap(d->image, x + int(align_delta_x(ALIGN_CENTER, item_size.x, d->image.GetWidth())), y + 3, true); dc.DrawBitmap(d->image, x + int(align_delta_x(ALIGN_CENTER, item_size.x, d->image.GetWidth())), y + 3, true);
} }
// draw short name // draw short name
dc.SetFont(wxFont(12,wxFONTFAMILY_SWISS,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_BOLD,false,_("Arial"))); wxFont font = wxFont(11,wxFONTFAMILY_SWISS,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_BOLD,false,_("Arial"));
dc.SetFont(font);
dc.GetTextExtent(capitalize(d->package->short_name), &w, &h); dc.GetTextExtent(capitalize(d->package->short_name), &w, &h);
pos = align_in_rect(ALIGN_CENTER, RealSize(w,h), rect); pos = align_in_rect(ALIGN_CENTER, RealSize(w,h), rect);
dc.DrawText(capitalize(d->package->short_name), max(x+1,(int)pos.x), (int)pos.y + 110); dc.DrawText(capitalize(d->package->short_name), max(x+1,(int)pos.x), (int)pos.y + 110);
// draw name // draw full name
dc.SetFont(wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT)); font.SetPointSize(9);
font.SetWeight(wxFONTWEIGHT_NORMAL);
dc.SetFont(font);
dc.GetTextExtent(d->package->full_name, &w, &h); dc.GetTextExtent(d->package->full_name, &w, &h);
if (w > item_size.x) {
font.SetPointSize(max(7,9*item_size.x/w));
dc.SetFont(font);
dc.GetTextExtent(d->package->full_name, &w, &h);
}
RealPoint text_pos = align_in_rect(ALIGN_CENTER, RealSize(w,h), rect); RealPoint text_pos = align_in_rect(ALIGN_CENTER, RealSize(w,h), rect);
dc.DrawText(d->package->full_name, max(x+1,(int)text_pos.x), (int)text_pos.y + 130); dc.DrawText(d->package->full_name, max(x+1,(int)text_pos.x), (int)(text_pos.y + 130 + 9-font.GetPointSize()));
dc.DestroyClippingRegion(); dc.DestroyClippingRegion();
} }
+15 -16
View File
@@ -40,10 +40,10 @@ CardsPanel::CardsPanel(Window* parent, int id)
link_viewer_2 = new CardViewer(this, ID_CARD_LINK_VIEWER); link_viewer_2 = new CardViewer(this, ID_CARD_LINK_VIEWER);
link_viewer_3 = new CardViewer(this, ID_CARD_LINK_VIEWER); link_viewer_3 = new CardViewer(this, ID_CARD_LINK_VIEWER);
link_viewer_4 = new CardViewer(this, ID_CARD_LINK_VIEWER); link_viewer_4 = new CardViewer(this, ID_CARD_LINK_VIEWER);
link_relation_1 = new wxStaticText(this, ID_CARD_LINK_RELATION_1, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END); link_relation_1 = new wxStaticText(this, ID_CARD_LINK_RELATION_1, _(""), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
link_relation_2 = new wxStaticText(this, ID_CARD_LINK_RELATION_2, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END); link_relation_2 = new wxStaticText(this, ID_CARD_LINK_RELATION_2, _(""), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
link_relation_3 = new wxStaticText(this, ID_CARD_LINK_RELATION_3, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END); link_relation_3 = new wxStaticText(this, ID_CARD_LINK_RELATION_3, _(""), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
link_relation_4 = new wxStaticText(this, ID_CARD_LINK_RELATION_4, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END); link_relation_4 = new wxStaticText(this, ID_CARD_LINK_RELATION_4, _(""), wxDefaultPosition, wxDefaultSize, wxST_ELLIPSIZE_END);
link_select = new wxButton(this, ID_CARD_LINK_SELECT, _BUTTON_("link select"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); link_select = new wxButton(this, ID_CARD_LINK_SELECT, _BUTTON_("link select"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
link_unlink_1 = new wxButton(this, ID_CARD_LINK_UNLINK_1, _BUTTON_("unlink"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); link_unlink_1 = new wxButton(this, ID_CARD_LINK_UNLINK_1, _BUTTON_("unlink"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
link_unlink_2 = new wxButton(this, ID_CARD_LINK_UNLINK_2, _BUTTON_("unlink"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); link_unlink_2 = new wxButton(this, ID_CARD_LINK_UNLINK_2, _BUTTON_("unlink"), wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT);
@@ -57,6 +57,7 @@ CardsPanel::CardsPanel(Window* parent, int id)
collapse_notes->SetExtraStyle(wxWS_EX_PROCESS_UI_UPDATES); collapse_notes->SetExtraStyle(wxWS_EX_PROCESS_UI_UPDATES);
filter = nullptr; filter = nullptr;
editor->next_in_tab_order = card_list; editor->next_in_tab_order = card_list;
SetDropTarget(card_list->drop_target);
wxFont font = link_relation_1->GetFont(); wxFont font = link_relation_1->GetFont();
font.SetWeight(wxFONTWEIGHT_BOLD); font.SetWeight(wxFONTWEIGHT_BOLD);
link_relation_1->SetFont(font); link_relation_1->SetFont(font);
@@ -537,14 +538,12 @@ bool CardsPanel::canPaste() const {
else return false; else return false;
} }
void CardsPanel::doPaste() { void CardsPanel::doPaste() {
if (card_list->canPaste()) { if (card_list->doPaste()) return;
card_list->doPaste();
} else { int id = focused_control(this);
int id = focused_control(this); if (id == ID_EDITOR) editor->doPaste();
if (id == ID_EDITOR) editor->doPaste(); else if (id == ID_CARD_LINK_EDITOR) link_editor->doPaste();
else if (id == ID_CARD_LINK_EDITOR) link_editor->doPaste(); else if (id == ID_NOTES) notes->doPaste();
else if (id == ID_NOTES) notes->doPaste();
}
} }
// ----------------------------------------------------------------------------- : Text selection // ----------------------------------------------------------------------------- : Text selection
@@ -657,7 +656,7 @@ void CardsPanel::selectCard(const CardP& card) {
link_box_1->Show(false); link_box_1->Show(false);
link_editor->setCard(card); link_editor->setCard(card);
link_viewer_1->setCard(card); link_viewer_1->setCard(card);
//link_relation_1->SetLabel(wxEmptyString); //link_relation_1->SetLabel(_(""));
} }
if (count >= 2) { if (count >= 2) {
link_box_2->Show(true); link_box_2->Show(true);
@@ -668,7 +667,7 @@ void CardsPanel::selectCard(const CardP& card) {
} else { } else {
link_box_2->Show(false); link_box_2->Show(false);
link_viewer_2->setCard(card); link_viewer_2->setCard(card);
//link_relation_2->SetLabel(wxEmptyString); //link_relation_2->SetLabel(_(""));
} }
if (count >= 3) { if (count >= 3) {
link_box_3->Show(true); link_box_3->Show(true);
@@ -679,7 +678,7 @@ void CardsPanel::selectCard(const CardP& card) {
} else { } else {
link_box_3->Show(false); link_box_3->Show(false);
link_viewer_3->setCard(card); link_viewer_3->setCard(card);
//link_relation_3->SetLabel(wxEmptyString); //link_relation_3->SetLabel(_(""));
} }
if (count >= 4) { if (count >= 4) {
link_box_4->Show(true); link_box_4->Show(true);
@@ -690,7 +689,7 @@ void CardsPanel::selectCard(const CardP& card) {
} else { } else {
link_box_4->Show(false); link_box_4->Show(false);
link_viewer_4->setCard(card); link_viewer_4->setCard(card);
//link_relation_4->SetLabel(wxEmptyString); //link_relation_4->SetLabel(_(""));
} }
if (count >= 5) { if (count >= 5) {
queue_message(MESSAGE_WARNING, "DEBUG More than 4 linked cards found for card: " + card->identification()); queue_message(MESSAGE_WARNING, "DEBUG More than 4 linked cards found for card: " + card->identification());
+1 -1
View File
@@ -257,7 +257,7 @@ String KeywordsPanel::runRefScript(int find_i) {
} }
} }
} }
return wxEmptyString; return _("");
} }
// ----------------------------------------------------------------------------- : Clipboard // ----------------------------------------------------------------------------- : Clipboard
+3 -3
View File
@@ -79,8 +79,8 @@ SetWindow::SetWindow(Window* parent, const SetP& set)
menuBar->Append(menuFile, _MENU_("file")); menuBar->Append(menuFile, _MENU_("file"));
auto menuEdit = new wxMenu(); auto menuEdit = new wxMenu();
add_menu_item(menuEdit, ID_EDIT_UNDO, settings.darkModePrefix() + "undo", _MENU_1_("undo",wxEmptyString), _HELP_("undo")); add_menu_item(menuEdit, ID_EDIT_UNDO, settings.darkModePrefix() + "undo", _MENU_1_("undo",_("")), _HELP_("undo"));
add_menu_item(menuEdit, ID_EDIT_REDO, settings.darkModePrefix() + "redo", _MENU_1_("redo",wxEmptyString), _HELP_("redo")); add_menu_item(menuEdit, ID_EDIT_REDO, settings.darkModePrefix() + "redo", _MENU_1_("redo",_("")), _HELP_("redo"));
menuEdit->AppendSeparator(); menuEdit->AppendSeparator();
add_menu_item_tr(menuEdit, ID_EDIT_CUT, settings.darkModePrefix() + "cut", "cut"); add_menu_item_tr(menuEdit, ID_EDIT_CUT, settings.darkModePrefix() + "cut", "cut");
add_menu_item_tr(menuEdit, ID_EDIT_COPY, "copy", "copy"); add_menu_item_tr(menuEdit, ID_EDIT_COPY, "copy", "copy");
@@ -554,7 +554,7 @@ void SetWindow::updateRecentSets() {
// add new item // add new item
wxMenu* file_menu = mb->GetMenu(0); wxMenu* file_menu = mb->GetMenu(0);
size_t pos = file_menu->GetMenuItemCount() - 2; // last two items are separator and exit size_t pos = file_menu->GetMenuItemCount() - 2; // last two items are separator and exit
file_menu->Insert(pos, ID_FILE_RECENT + i, String(_("&")) << (i+1) << _(" ") << file, wxEmptyString); file_menu->Insert(pos, ID_FILE_RECENT + i, String(_("&")) << (i+1) << _(" ") << file, _(""));
} }
i++; i++;
} }
+4 -4
View File
@@ -83,8 +83,8 @@ void SymbolWindow::init(Window* parent, SymbolP symbol) {
menuBar->Append(menuFile, _MENU_("file")); menuBar->Append(menuFile, _MENU_("file"));
auto menuEdit = new wxMenu(); auto menuEdit = new wxMenu();
add_menu_item(menuEdit, ID_EDIT_UNDO, settings.darkModePrefix() + "undo", _MENU_1_("undo",wxEmptyString), _HELP_("undo")); add_menu_item(menuEdit, ID_EDIT_UNDO, settings.darkModePrefix() + "undo", _MENU_1_("undo",_("")), _HELP_("undo"));
add_menu_item(menuEdit, ID_EDIT_REDO, settings.darkModePrefix() + "redo", _MENU_1_("redo",wxEmptyString), _HELP_("redo")); add_menu_item(menuEdit, ID_EDIT_REDO, settings.darkModePrefix() + "redo", _MENU_1_("redo",_("")), _HELP_("redo"));
menuEdit->AppendSeparator(); menuEdit->AppendSeparator();
add_menu_item_tr(menuEdit, ID_EDIT_GROUP, "group", "group"); add_menu_item_tr(menuEdit, ID_EDIT_GROUP, "group", "group");
add_menu_item_tr(menuEdit, ID_EDIT_UNGROUP, "ungroup", "ungroup"); add_menu_item_tr(menuEdit, ID_EDIT_UNGROUP, "ungroup", "ungroup");
@@ -111,8 +111,8 @@ void SymbolWindow::init(Window* parent, SymbolP symbol) {
wxToolBar* tb = CreateToolBar(wxTB_FLAT | wxNO_BORDER | wxTB_HORIZONTAL | wxTB_TEXT); wxToolBar* tb = CreateToolBar(wxTB_FLAT | wxNO_BORDER | wxTB_HORIZONTAL | wxTB_TEXT);
add_tool_tr(tb, ID_FILE_STORE, "apply", "store_symbol", true); add_tool_tr(tb, ID_FILE_STORE, "apply", "store_symbol", true);
tb->AddSeparator(); tb->AddSeparator();
add_tool(tb, ID_EDIT_UNDO, settings.darkModePrefix() + "undo", _TOOL_("undo"), _TOOLTIP_1_("undo",wxEmptyString), _HELP_("undo")); add_tool(tb, ID_EDIT_UNDO, settings.darkModePrefix() + "undo", _TOOL_("undo"), _TOOLTIP_1_("undo",_("")), _HELP_("undo"));
add_tool(tb, ID_EDIT_REDO, settings.darkModePrefix() + "redo", _TOOL_("redo"), _TOOLTIP_1_("redo",wxEmptyString), _HELP_("redo")); add_tool(tb, ID_EDIT_REDO, settings.darkModePrefix() + "redo", _TOOL_("redo"), _TOOLTIP_1_("redo",_("")), _HELP_("redo"));
tb->AddSeparator(); tb->AddSeparator();
add_tool_tr(tb, ID_VIEW_GRID, "grid", "grid", true, wxITEM_CHECK); add_tool_tr(tb, ID_VIEW_GRID, "grid", "grid", true, wxITEM_CHECK);
add_tool_tr(tb, ID_VIEW_GRID_SNAP, "grid_snap", "snap", true, wxITEM_CHECK); add_tool_tr(tb, ID_VIEW_GRID_SNAP, "grid_snap", "snap", true, wxITEM_CHECK);
+1 -1
View File
@@ -73,7 +73,7 @@ struct FakeEvtHandlerClass : public wxEvtHandler {
ev.Skip(); ev.Skip();
} }
void onControlLeave(wxMouseEvent& ev) { void onControlLeave(wxMouseEvent& ev) {
set_status_text((wxWindow*)ev.GetEventObject(), wxEmptyString); set_status_text((wxWindow*)ev.GetEventObject(), _(""));
ev.Skip(); ev.Skip();
} }
}; };
+1 -4
View File
@@ -58,10 +58,7 @@ void ImageValueEditor::sliceImage(const Image& image, const String& filename, co
// clicked ok? // clicked ok?
if (s.ShowModal() == wxID_OK) { if (s.ShowModal() == wxID_OK) {
// store the image into the set // store the image into the set
StyleP style = field().styleP; LocalFileName new_image_file = getLocalPackage().newFileName(field().name, settings.internal_image_extension ? _(".png") : _("")); // a new unique name in the package
String rect = style ? style->getRect() : _("");
String extension = settings.internal_image_extension ? _(".png") : _("");
LocalFileName new_image_file = getLocalPackage().newFileName(field().name, rect + extension); // a new unique name in the package
// Specify a desired size based on the stylesheet and a scale multiplier defined within the user's settings. // Specify a desired size based on the stylesheet and a scale multiplier defined within the user's settings.
// Storing at a greater than 100% resolution allows for better exports >100%, but may change how images look when filters (sharpen) are applied. // Storing at a greater than 100% resolution allows for better exports >100%, but may change how images look when filters (sharpen) are applied.
+4 -4
View File
@@ -459,7 +459,7 @@ bool TextValueEditor::onChar(wxKeyEvent& ev) {
return true; return true;
} }
} }
replaceSelection(wxEmptyString, _ACTION_("backspace")); replaceSelection(_(""), _ACTION_("backspace"));
return true; return true;
case WXK_DELETE: case WXK_DELETE:
if (selection_start == selection_end) { if (selection_start == selection_end) {
@@ -470,7 +470,7 @@ bool TextValueEditor::onChar(wxKeyEvent& ev) {
moveSelection(TYPE_CURSOR, nextCharBoundary(selection_end), true, MOVE_RIGHT); moveSelection(TYPE_CURSOR, nextCharBoundary(selection_end), true, MOVE_RIGHT);
} }
} }
replaceSelection(wxEmptyString, _ACTION_("delete")); replaceSelection(_(""), _ACTION_("delete"));
return true; return true;
case WXK_RETURN: case WXK_RETURN:
if (field().multi_line) { if (field().multi_line) {
@@ -581,7 +581,7 @@ bool TextValueEditor::onContextMenu(wxMenu& m, wxContextMenuEvent& ev) {
} else { } else {
int i = 0; int i = 0;
FOR_EACH(s,suggestions) { FOR_EACH(s,suggestions) {
m.Insert(i, ID_SPELLING_SUGGEST + i, s, wxEmptyString); m.Insert(i, ID_SPELLING_SUGGEST + i, s, _(""));
i++; i++;
} }
} }
@@ -797,7 +797,7 @@ bool TextValueEditor::doCopy() {
} }
bool TextValueEditor::doDelete() { bool TextValueEditor::doDelete() {
replaceSelection(wxEmptyString, _ACTION_("cut")); replaceSelection(_(""), _ACTION_("cut"));
return true; return true;
} }
+98
View File
@@ -0,0 +1,98 @@
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) Twan van Laarhoven and the other MSE developers |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <gui/web_request_window.hpp>
#include <util/window_id.hpp>
// ----------------------------------------------------------------------------- : WebRequestWindow
WebRequestWindow::WebRequestWindow(Window* parent, const String& url, bool sizer)
: wxDialog(parent, wxID_ANY, _TITLE_("web request"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
{
// init controls
info = new wxStaticText(this, -1, _LABEL_("web request address"));
address = new wxStaticText(this, -1, url);
gauge = new wxGauge(this, wxID_ANY, 0);
// init sizers
if (sizer) {
wxSizer* s = new wxBoxSizer(wxVERTICAL);
s->Add(info, 0, wxALL, 8);
s->Add(address, 0, (wxALL & ~wxTOP), 4);
s->Add(gauge, 0, wxEXPAND | wxALL, 8);
s->Add(CreateButtonSizer(wxCANCEL), 1, wxEXPAND, 8);
s->SetSizeHints(this);
SetSizer(s);
}
// create web request
request = wxWebSession::GetDefault().CreateRequest(this, url);
if (!request.IsOk() ) {
onFail(_ERROR_("web request cant create"));
return;
}
// bind request events
Bind(wxEVT_WEBREQUEST_STATE, [this](wxWebRequestEvent& evt) {
switch (evt.GetState())
{
// request completed
case wxWebRequest::State_Completed:
{
onComplete(evt);
break;
}
// request failed
case wxWebRequest::State_Failed:
onFail(evt.GetErrorDescription());
break;
}
});
Bind(wxEVT_WEBREQUEST_DATA, [this](wxWebRequestEvent& evt) {
// request updated
onUpdate(evt);
});
// start request
request.Start();
}
void WebRequestWindow::onUpdate(wxWebRequestEvent& evt) {
off_t expected_bytes = request.GetBytesExpectedToReceive();
off_t bytes = request.GetBytesReceived();
if (expected_bytes > 0) {
gauge->SetRange(expected_bytes);
gauge->SetValue(bytes);
}
else {
gauge->Pulse();
}
}
void WebRequestWindow::onComplete(wxWebRequestEvent& evt) {
out = evt.GetResponse();
if (out.IsOk()) {
EndModal(wxID_OK);
}
else {
onFail(_ERROR_("web request corrupted"));
}
}
void WebRequestWindow::onFail(const String& message) {
info->SetLabel(_ERROR_("web request failed"));
address->SetLabel(message);
}
void WebRequestWindow::onCancel(wxCommandEvent&) {
EndModal(wxID_CANCEL);
}
BEGIN_EVENT_TABLE(WebRequestWindow, wxDialog)
EVT_BUTTON (wxID_CANCEL, WebRequestWindow::onCancel)
END_EVENT_TABLE ()
+39
View File
@@ -0,0 +1,39 @@
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) Twan van Laarhoven and the other MSE developers |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
#pragma once
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <wx/gauge.h>
#include <wx/webrequest.h>
// ----------------------------------------------------------------------------- : WebRequestWindow
/// A window for displaying the progression of a WebRequest and returning the WebResponse
class WebRequestWindow : public wxDialog {
public:
WebRequestWindow(Window* parent, const String& url, bool sizer=true);
wxWebResponse out;
protected:
DECLARE_EVENT_TABLE();
wxStaticText* info, *address;
wxGauge* gauge;
wxWebRequest request;
void onUpdate(wxWebRequestEvent& evt);
void onComplete(wxWebRequestEvent& evt);
void onFail(const String& message);
void onCancel(wxCommandEvent&);
};
+1 -1
View File
@@ -126,7 +126,7 @@ void WelcomeWindow::onSelectLanguage(wxCommandEvent&) {
} }
void WelcomeWindow::onOpenSet(wxCommandEvent&) { void WelcomeWindow::onOpenSet(wxCommandEvent&) {
wxFileDialog* dlg = new wxFileDialog(this, _TITLE_("open set"), settings.default_set_dir, wxEmptyString, import_formats(), wxFD_OPEN); wxFileDialog* dlg = new wxFileDialog(this, _TITLE_("open set"), settings.default_set_dir, _(""), import_formats(), wxFD_OPEN);
if (dlg->ShowModal() == wxID_OK) { if (dlg->ShowModal() == wxID_OK) {
settings.default_set_dir = dlg->GetDirectory(); settings.default_set_dir = dlg->GetDirectory();
wxBusyCursor wait; wxBusyCursor wait;
+3 -3
View File
@@ -754,7 +754,7 @@ SCRIPT_FUNCTION(get_card_stylesheet) {
ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(input.get()); ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(input.get());
ScriptObject<Set*>* s = dynamic_cast<ScriptObject<Set*>*>(set.get()); ScriptObject<Set*>* s = dynamic_cast<ScriptObject<Set*>*>(set.get());
if (s && c) { if (s && c) {
return to_script(&s->getValue()->stylesheetFor(c->getValue())); return to_script(s->getValue()->stylesheetForP(c->getValue()));
} }
throw ScriptError(_("invalid set or card argument")); throw ScriptError(_("invalid set or card argument"));
} }
@@ -777,8 +777,8 @@ SCRIPT_FUNCTION(get_card_from_link) {
card->linked_relation_2 == trimmed_input ? card->linked_card_2 : card->linked_relation_2 == trimmed_input ? card->linked_card_2 :
card->linked_relation_3 == trimmed_input ? card->linked_card_3 : card->linked_relation_3 == trimmed_input ? card->linked_card_3 :
card->linked_relation_4 == trimmed_input ? card->linked_card_4 : card->linked_relation_4 == trimmed_input ? card->linked_card_4 :
wxEmptyString; _("");
if (uid == wxEmptyString) return script_nil; if (uid.empty()) return script_nil;
FOR_EACH(other_card, set->cards) { FOR_EACH(other_card, set->cards) {
if (other_card->uid == uid) SCRIPT_RETURN(other_card); if (other_card->uid == uid) SCRIPT_RETURN(other_card);
} }
+10 -1
View File
@@ -30,8 +30,17 @@ SCRIPT_FUNCTION(new_card) {
CardP new_card = make_intrusive<Card>(*game); CardP new_card = make_intrusive<Card>(*game);
// iterate on the given key/value pairs // iterate on the given key/value pairs
SCRIPT_PARAM(ScriptValueP, input); SCRIPT_PARAM(ScriptValueP, input);
// check for a stylesheet first, since other things depend on it
ScriptValueP it = input->makeIterator(); ScriptValueP it = input->makeIterator();
ScriptValueP key; ScriptValueP key;
while (ScriptValueP value = it->next(&key)) {
assert(key);
if (key == script_nil) continue;
String key_name = key->toString();
if (set_stylesheet_container(*game, new_card, value, key_name, ignore_field_not_found)) break;
}
// set the rest of the key/value pairs
it = input->makeIterator();
while (ScriptValueP value = it->next(&key)) { while (ScriptValueP value = it->next(&key)) {
assert(key); assert(key);
if (key == script_nil) continue; if (key == script_nil) continue;
@@ -67,7 +76,7 @@ SCRIPT_FUNCTION(new_card) {
set_container(script_container, script_value, script_key_name); set_container(script_container, script_value, script_key_name);
} }
} }
// if the script result is not a collection, simply set the field value to the script value // if the script result is not a collection, simply set the field value to the script result
else { else {
set_container(container, script_input, key_name); set_container(container, script_input, key_name);
} }
+49 -42
View File
@@ -89,55 +89,62 @@ inline static void set_container(Value* container, ScriptValueP& value, String k
} }
} }
inline static bool set_builtin_container(const Game& game, CardP& card, ScriptValueP& value, String key_name, bool ignore_field_not_found) { inline static bool set_stylesheet_container(const Game& game, CardP& card, ScriptValueP& value, String key_name, bool ignore_field_not_found) {
// check if the given value is for a built-in field, if found set it and return true // check if the given value is for a stylesheet, if found set it and return true
key_name = unified_form(key_name); key_name = unified_form(key_name);
if (key_name == _("notes") || key_name == _("note")) { if (key_name == _("style") || key_name == _("stylesheet") || key_name == _("template")) {
card->notes = value->toString();
return true;
} else if (key_name == _("style") || key_name == _("stylesheet") || key_name == _("template")) {
if (!trim(value->toString()).empty()) { if (!trim(value->toString()).empty()) {
card->stylesheet = StyleSheet::byGameAndName(game, value->toString()); card->stylesheet = StyleSheet::byGameAndName(game, value->toString());
if (card->stylesheet) card->styling_data.init(card->stylesheet->styling_fields); if (card->stylesheet) card->styling_data.init(card->stylesheet->styling_fields);
} }
return true; return true;
} }
//else if (key_name == _("id") || key_name == _("uid")) { return false;
// card->uid = value->toString(); }
// return true;
//} inline static bool set_builtin_container(const Game& game, CardP& card, ScriptValueP& value, String key_name, bool ignore_field_not_found) {
//else if (key_name == _("linked_card") || key_name == _("linked_card_1")) { // check if the given value is for a built-in field, if found set it and return true
// card->linked_card_1 = value->toString(); key_name = unified_form(key_name);
// return true; if (key_name == _("notes") || key_name == _("note")) {
//} card->notes = value->toString();
//else if (key_name == _("linked_card_2")) { return true;
// card->linked_card_2 = value->toString(); }
// return true; else if (key_name == _("id") || key_name == _("uid")) {
//} card->uid = value->toString();
//else if (key_name == _("linked_card_3")) { return true;
// card->linked_card_3 = value->toString(); }
// return true; else if (key_name == _("linked_card") || key_name == _("linked_card_1")) {
//} card->linked_card_1 = value->toString();
//else if (key_name == _("linked_card_4")) { return true;
// card->linked_card_4 = value->toString(); }
// return true; else if (key_name == _("linked_card_2")) {
//} card->linked_card_2 = value->toString();
//else if (key_name == _("linked_relation") || key_name == _("linked_relation_1")) { return true;
// card->linked_relation_1 = value->toString(); }
// return true; else if (key_name == _("linked_card_3")) {
//} card->linked_card_3 = value->toString();
//else if (key_name == _("linked_relation_2")) { return true;
// card->linked_relation_2 = value->toString(); }
// return true; else if (key_name == _("linked_card_4")) {
//} card->linked_card_4 = value->toString();
//else if (key_name == _("linked_relation_3")) { return true;
// card->linked_relation_3 = value->toString(); }
// return true; else if (key_name == _("linked_relation") || key_name == _("linked_relation_1")) {
//} card->linked_relation_1 = value->toString();
//else if (key_name == _("linked_relation_4")) { return true;
// card->linked_relation_4 = value->toString(); }
// return true; else if (key_name == _("linked_relation_2")) {
//} card->linked_relation_2 = value->toString();
return true;
}
else if (key_name == _("linked_relation_3")) {
card->linked_relation_3 = value->toString();
return true;
}
else if (key_name == _("linked_relation_4")) {
card->linked_relation_4 = value->toString();
return true;
}
else if (key_name == _("styling_data") || key_name == _("style_data") || key_name == _("stylesheet_data") || key_name == _("template_data") || key_name == _("styling") else if (key_name == _("styling_data") || key_name == _("style_data") || key_name == _("stylesheet_data") || key_name == _("template_data") || key_name == _("styling")
|| key_name == _("styling_fields") || key_name == _("style_fields") || key_name == _("stylesheet_fields") || key_name == _("template_fields") || key_name == _("styling_fields") || key_name == _("style_fields") || key_name == _("stylesheet_fields") || key_name == _("template_fields")
|| key_name == _("extra_data") || key_name == _("extra_fields") || key_name == _("extra_card_data") || key_name == _("extra_card_fields")) { || key_name == _("extra_data") || key_name == _("extra_fields") || key_name == _("extra_card_data") || key_name == _("extra_card_fields")) {
+29 -30
View File
@@ -184,15 +184,15 @@ inline static CardP json_to_mse_card(boost::json::object& jv, Set* set) {
read(card->time_created, jv, "time_created"); read(card->time_created, jv, "time_created");
read(card->time_modified, jv, "time_modified"); read(card->time_modified, jv, "time_modified");
read(card->notes, jv, "notes"); read(card->notes, jv, "notes");
//read(card->uid, jv, "uid"); read(card->uid, jv, "uid");
//read(card->linked_card_1, jv, "linked_card_1"); read(card->linked_card_1, jv, "linked_card_1");
//read(card->linked_card_2, jv, "linked_card_2"); read(card->linked_card_2, jv, "linked_card_2");
//read(card->linked_card_3, jv, "linked_card_3"); read(card->linked_card_3, jv, "linked_card_3");
//read(card->linked_card_4, jv, "linked_card_4"); read(card->linked_card_4, jv, "linked_card_4");
//read(card->linked_relation_1, jv, "linked_relation_1"); read(card->linked_relation_1, jv, "linked_relation_1");
//read(card->linked_relation_2, jv, "linked_relation_2"); read(card->linked_relation_2, jv, "linked_relation_2");
//read(card->linked_relation_3, jv, "linked_relation_3"); read(card->linked_relation_3, jv, "linked_relation_3");
//read(card->linked_relation_4, jv, "linked_relation_4"); read(card->linked_relation_4, jv, "linked_relation_4");
// card fields // card fields
if (jv.contains("data") && jv["data"].is_object()) { if (jv.contains("data") && jv["data"].is_object()) {
boost::json::object datav = jv["data"].as_object(); boost::json::object datav = jv["data"].as_object();
@@ -315,9 +315,8 @@ inline static ScriptValueP json_to_mse(const boost::json::value& jv, Set* set) {
return to_script(integer); return to_script(integer);
} }
else if (jv.is_string()) { else if (jv.is_string()) {
std::string stdstring = boost::json::value_to<std::string>(jv); std::string string = boost::json::value_to<std::string>(jv);
String wxstring(stdstring.c_str(), wxConvUTF8); return to_script(String(string.c_str()));
return to_script(wxstring);
} }
else if (jv.is_array()) { else if (jv.is_array()) {
boost::json::array array = jv.get_array(); boost::json::array array = jv.get_array();
@@ -364,7 +363,7 @@ inline static ScriptValueP json_to_mse(const String& string, Set* set) {
boost::json::parse_options options; boost::json::parse_options options;
options.allow_invalid_utf8 = true; options.allow_invalid_utf8 = true;
boost::json::value jv = boost::json::parse(string.ToStdString(), ec, {}, options); boost::json::value jv = boost::json::parse(string.ToStdString(), ec, {}, options);
if(ec) queue_message(MESSAGE_ERROR, _ERROR_("json cant parse") + _("\n\n") + ec.message()); if(ec) return script_nil; //queue_message(MESSAGE_ERROR, _ERROR_("json cant parse") + _("\n\n") + ec.message());
return json_to_mse(jv, set); return json_to_mse(jv, set);
} }
catch (...) { catch (...) {
@@ -415,7 +414,7 @@ static void write(boost::json::object& out, const String& name, DelayedIndexMaps
if (!delayedindexmapv.empty()) out.emplace(name.ToStdString(), delayedindexmapv); if (!delayedindexmapv.empty()) out.emplace(name.ToStdString(), delayedindexmapv);
} }
inline static boost::json::object mse_to_json(PackItemP& item) { inline static boost::json::object mse_to_json(const PackItemP& item) {
boost::json::object itemv; boost::json::object itemv;
itemv.emplace("mse_object_type", "pack_item"); itemv.emplace("mse_object_type", "pack_item");
write(itemv, "name", item->name); write(itemv, "name", item->name);
@@ -424,7 +423,7 @@ inline static boost::json::object mse_to_json(PackItemP& item) {
return itemv; return itemv;
} }
inline static boost::json::object mse_to_json(PackTypeP& pack) { inline static boost::json::object mse_to_json(const PackTypeP& pack) {
boost::json::object packv; boost::json::object packv;
packv.emplace("mse_object_type", "pack_type"); packv.emplace("mse_object_type", "pack_type");
write(packv, "name", pack->name); write(packv, "name", pack->name);
@@ -441,7 +440,7 @@ inline static boost::json::object mse_to_json(PackTypeP& pack) {
return packv; return packv;
} }
inline static boost::json::object mse_to_json(KeywordP& keyword) { inline static boost::json::object mse_to_json(const KeywordP& keyword) {
boost::json::object keywordv; boost::json::object keywordv;
keywordv.emplace("mse_object_type", "keyword"); keywordv.emplace("mse_object_type", "keyword");
write(keywordv, "keyword", keyword->keyword); write(keywordv, "keyword", keyword->keyword);
@@ -452,22 +451,22 @@ inline static boost::json::object mse_to_json(KeywordP& keyword) {
return keywordv; return keywordv;
} }
inline static boost::json::object mse_to_json(CardP& card, Set* set) { inline static boost::json::object mse_to_json(const CardP& card, const Set* set) {
boost::json::object cardv; boost::json::object cardv;
cardv.emplace("mse_object_type", "card"); cardv.emplace("mse_object_type", "card");
// built-in values // built-in values
write(cardv, "time_created", card->time_created); write(cardv, "time_created", card->time_created);
write(cardv, "time_modified", card->time_modified); write(cardv, "time_modified", card->time_modified);
write(cardv, "notes", card->notes); write(cardv, "notes", card->notes);
//write(cardv, "uid", card->uid); write(cardv, "uid", card->uid);
//write(cardv, "linked_card_1", card->linked_card_1); write(cardv, "linked_card_1", card->linked_card_1);
//write(cardv, "linked_card_2", card->linked_card_2); write(cardv, "linked_card_2", card->linked_card_2);
//write(cardv, "linked_card_3", card->linked_card_3); write(cardv, "linked_card_3", card->linked_card_3);
//write(cardv, "linked_card_4", card->linked_card_4); write(cardv, "linked_card_4", card->linked_card_4);
//write(cardv, "linked_relation_1", card->linked_relation_1); write(cardv, "linked_relation_1", card->linked_relation_1);
//write(cardv, "linked_relation_2", card->linked_relation_2); write(cardv, "linked_relation_2", card->linked_relation_2);
//write(cardv, "linked_relation_3", card->linked_relation_3); write(cardv, "linked_relation_3", card->linked_relation_3);
//write(cardv, "linked_relation_4", card->linked_relation_4); write(cardv, "linked_relation_4", card->linked_relation_4);
// card fields // card fields
write(cardv, "data", card->data); write(cardv, "data", card->data);
// stylesheet // stylesheet
@@ -494,7 +493,7 @@ inline static boost::json::object mse_to_json(CardP& card, Set* set) {
return cardv; return cardv;
} }
inline static boost::json::object mse_to_json(Set* set) { inline static boost::json::object mse_to_json(const Set* set) {
boost::json::object setv; boost::json::object setv;
setv.emplace("mse_object_type", "set"); setv.emplace("mse_object_type", "set");
// built-in values // built-in values
@@ -509,19 +508,19 @@ inline static boost::json::object mse_to_json(Set* set) {
write(setv, "styling", set->styling_data); write(setv, "styling", set->styling_data);
// cards // cards
boost::json::array cardsv; boost::json::array cardsv;
for (auto card : set->cards) { for (const CardP& card : set->cards) {
cardsv.emplace_back(mse_to_json(card, set)); cardsv.emplace_back(mse_to_json(card, set));
} }
setv.emplace("cards", cardsv); setv.emplace("cards", cardsv);
// keywords // keywords
boost::json::array keywordsv; boost::json::array keywordsv;
for (auto keyword : set->keywords) { for (const KeywordP& keyword : set->keywords) {
keywordsv.emplace_back(mse_to_json(keyword)); keywordsv.emplace_back(mse_to_json(keyword));
} }
if (!keywordsv.empty()) setv.emplace("keywords", keywordsv); if (!keywordsv.empty()) setv.emplace("keywords", keywordsv);
// pack types // pack types
boost::json::array pack_typesv; boost::json::array pack_typesv;
for (auto pack_type : set->pack_types) { for (const PackTypeP& pack_type : set->pack_types) {
pack_typesv.emplace_back(mse_to_json(pack_type)); pack_typesv.emplace_back(mse_to_json(pack_type));
} }
if (!pack_typesv.empty()) setv.emplace("pack_types", pack_typesv); if (!pack_typesv.empty()) setv.emplace("pack_types", pack_typesv);
+1 -1
View File
@@ -31,7 +31,7 @@ Context& SetScriptContext::getContext(const StyleSheetP& stylesheet) {
auto it = contexts.try_emplace(stylesheet.get()); auto it = contexts.try_emplace(stylesheet.get());
Context& ctx = it.first->second; Context& ctx = it.first->second;
if (it.second) { if (it.second) {
// we created a new context // try_emplace created a new context, we now initialize it
// variables // variables
// NOTE: do not use a smart pointer for the pointer to the set, because the set owns this // NOTE: do not use a smart pointer for the pointer to the set, because the set owns this
// which would lead to a reference cycle. // which would lead to a reference cycle.
+1
View File
@@ -129,6 +129,7 @@ public:
inline bool isScripted() const { return script; } inline bool isScripted() const { return script; }
/// Has this value been read from a Reader? /// Has this value been read from a Reader?
inline bool hasBeenRead() const { return !script.unparsed.empty(); } inline bool hasBeenRead() const { return !script.unparsed.empty(); }
inline String unparsed() const { return script.unparsed; }
/// Updates the value by executing the script, returns true if the value has changed /// Updates the value by executing the script, returns true if the value has changed
inline bool update(Context& ctx) { inline bool update(Context& ctx) {
+2 -2
View File
@@ -72,14 +72,14 @@ String ActionStack::undoName() const {
if (canUndo()) { if (canUndo()) {
return _(" ") + capitalize(undo_actions.back()->getName(true)); return _(" ") + capitalize(undo_actions.back()->getName(true));
} else { } else {
return wxEmptyString; return _("");
} }
} }
String ActionStack::redoName() const { String ActionStack::redoName() const {
if (canRedo()) { if (canRedo()) {
return _(" ") + capitalize(redo_actions.back()->getName(false)); return _(" ") + capitalize(redo_actions.back()->getName(false));
} else { } else {
return wxEmptyString; return _("");
} }
} }
+4 -9
View File
@@ -272,11 +272,6 @@ String Package::nameOut(const String& file) {
} else { } else {
// create temp file // create temp file
String name = wxFileName::CreateTempFileName(_("mse")); String name = wxFileName::CreateTempFileName(_("mse"));
String rect = LocalFileName::getRect(file);
if (!rect.empty()) {
if (name.Contains(".")) name = name.BeforeLast('.') + rect + _(".") + name.AfterLast('.');
else name = name + rect;
}
it->second.tempName = name; it->second.tempName = name;
return name; return name;
} }
@@ -366,7 +361,7 @@ LocalFileName LocalFileName::fromReadString(String const& fn, String const& pref
if (!fn.empty() && clipboard_package()) { if (!fn.empty() && clipboard_package()) {
// copy file into current package // copy file into current package
try { try {
LocalFileName local_name = clipboard_package()->newFileName(_("image"), getRect(fn)); // a new unique name in the package, assume it's an image LocalFileName local_name = clipboard_package()->newFileName(_("image"), _("")); // a new unique name in the package, assume it's an image
auto out_stream = clipboard_package()->openOut(local_name); auto out_stream = clipboard_package()->openOut(local_name);
auto in_stream = Package::openAbsoluteFile(fn); auto in_stream = Package::openAbsoluteFile(fn);
out_stream->Write(*in_stream); // copy out_stream->Write(*in_stream); // copy
@@ -403,7 +398,7 @@ void Package::loadZipStream() {
} }
void Package::openDirectory(bool fast) { void Package::openDirectory(bool fast) {
if (!fast) openSubdir(wxEmptyString); if (!fast) openSubdir(_(""));
} }
void Package::openSubdir(const String& name) { void Package::openSubdir(const String& name) {
@@ -411,7 +406,7 @@ void Package::openSubdir(const String& name) {
if (!d.IsOpened()) return; // ignore errors here if (!d.IsOpened()) return; // ignore errors here
// find files // find files
String f; // filename String f; // filename
for(bool ok = d.GetFirst(&f, wxEmptyString, wxDIR_FILES | wxDIR_HIDDEN) ; ok ; ok = d.GetNext(&f)) { for(bool ok = d.GetFirst(&f, _(""), wxDIR_FILES | wxDIR_HIDDEN) ; ok ; ok = d.GetNext(&f)) {
if (ignore_file(f)) continue; if (ignore_file(f)) continue;
// add file to list of known files // add file to list of known files
addFile(name + f); addFile(name + f);
@@ -420,7 +415,7 @@ void Package::openSubdir(const String& name) {
modified = max(modified,file_time); modified = max(modified,file_time);
} }
// find subdirs // find subdirs
for(bool ok = d.GetFirst(&f, wxEmptyString, wxDIR_DIRS | wxDIR_HIDDEN) ; ok ; ok = d.GetNext(&f)) { for(bool ok = d.GetFirst(&f, _(""), wxDIR_DIRS | wxDIR_HIDDEN) ; ok ; ok = d.GetNext(&f)) {
if (!f.empty() && f.GetChar(0) != _('.')) { if (!f.empty() && f.GetChar(0) != _('.')) {
// skip directories starting with '.', like ., .. and .svn // skip directories starting with '.', like ., .. and .svn
openSubdir(name+f+_("/")); openSubdir(name+f+_("/"));
+36 -6
View File
@@ -54,12 +54,42 @@ public:
inline String const& toStringForKey() const { return fn; } inline String const& toStringForKey() const { return fn; }
/// Retreive a rect from a filename /// Retreive a rect from a filename
static String getRect(const String& file) { inline static wxRect getExternalRect(const String& filename) {
size_t first = file.find(_("---")); size_t first = filename.find(_("---"));
if (first == String::npos) return _(""); if (first == String::npos) return wxRect();
size_t last = file.find(_("---"), first+3); size_t last = filename.find(_("---"), first+3);
if (first == last) return _(""); if (last == String::npos) return wxRect();
return file.substr(first, last + 3 - first); String string = filename.substr(first + 3, last - (first + 3));
if (string.empty()) return wxRect();
size_t divider = string.find(_("-"));
if (divider == String::npos) return wxRect();
if (divider == 0) return wxRect();
int x;
if(!string.substr(0, divider).ToInt(&x)) return wxRect();
string = string.substr(divider + 1);
divider = string.find(_("-"));
if (divider == String::npos) return wxRect();
if (divider == 0) return wxRect();
int y;
if(!string.substr(0, divider).ToInt(&y)) return wxRect();
string = string.substr(divider + 1);
divider = string.find(_("-"));
if (divider == String::npos) return wxRect();
if (divider == 0) return wxRect();
int width;
if(!string.substr(0, divider).ToInt(&width)) return wxRect();
string = string.substr(divider + 1);
int height;
if(!string.ToInt(&height)) return wxRect();
return wxRect(x, y, width, height);
}
inline wxRect getExternalRect() {
return getExternalRect(fn);
} }
private: private:
+1 -1
View File
@@ -154,7 +154,7 @@ String PackageManager::openFilenameFromPackage(Packaged* package, const String&
String PackageManager::getDictionaryDir(bool l) const { String PackageManager::getDictionaryDir(bool l) const {
String dir = (l ? local : global).getDirectory(); String dir = (l ? local : global).getDirectory();
if (dir.empty()) return wxEmptyString; if (dir.empty()) return _("");
else return dir + _("/dictionaries/"); else return dir + _("/dictionaries/");
} }
+1 -1
View File
@@ -37,7 +37,7 @@ public:
/** filename is used only for error messages /** filename is used only for error messages
* package is used for looking up included files. * package is used for looking up included files.
*/ */
Reader(wxInputStream& input, Packaged* package = nullptr, const String& filename = wxEmptyString, bool ignore_invalid = false); Reader(wxInputStream& input, Packaged* package = nullptr, const String& filename = _(""), bool ignore_invalid = false);
~Reader() { showWarnings(); } ~Reader() { showWarnings(); }
+4 -4
View File
@@ -96,13 +96,13 @@ String fix_old_tags(const String& str) {
ret += c; ret += c;
if (c==_('<')) { if (c==_('<')) {
intag = true; intag = true;
tags.push(wxEmptyString); tags.push(_(""));
} else if (c==_('>') && intag) { } else if (c==_('>') && intag) {
intag = false; intag = false;
if (!starts_with(tags.top(), _("kw")) && !starts_with(tags.top(), _("atom"))) { if (!starts_with(tags.top(), _("kw")) && !starts_with(tags.top(), _("atom"))) {
// only keep keyword related stuff // only keep keyword related stuff
ret.resize(ret.size() - tags.top().size() - 2); // remove from output ret.resize(ret.size() - tags.top().size() - 2); // remove from output
tags.top() = wxEmptyString; tags.top() = _("");
} }
} else if (intag) { } else if (intag) {
tags.top() += c; tags.top() += c;
@@ -303,13 +303,13 @@ bool is_in_tag(const String& str, const String& tag, size_t start, size_t end) {
String tag_at(const String& str, size_t pos) { String tag_at(const String& str, size_t pos) {
size_t end = str.find_first_of(_(">"), pos); size_t end = str.find_first_of(_(">"), pos);
if (end == String::npos) return wxEmptyString; if (end == String::npos) return _("");
return str.substr(pos + 1, end - pos - 1); return str.substr(pos + 1, end - pos - 1);
} }
String tag_type_at(const String& str, size_t pos) { String tag_type_at(const String& str, size_t pos) {
size_t end = str.find_first_of(_(">-"), pos); size_t end = str.find_first_of(_(">-"), pos);
if (end == String::npos) return wxEmptyString; if (end == String::npos) return _("");
return str.substr(pos + 1, end - pos - 1); return str.substr(pos + 1, end - pos - 1);
} }