convert to CRLF line endings

This commit is contained in:
GenevensiS
2026-01-05 01:01:18 +01:00
parent 168f6abe51
commit fbf2023848
68 changed files with 822 additions and 822 deletions
+2 -2
View File
@@ -212,7 +212,7 @@ String ChangeCardHasStylingAction::getName(bool to_undo) const {
void ChangeCardHasStylingAction::perform(bool to_undo) {
card->has_styling = !card->has_styling;
swap(card->styling_data, styling_data);
}
}
// ----------------------------------------------------------------------------- : Change notes
@@ -239,7 +239,7 @@ void ChangeCardUIDAction::perform(bool to_undo) {
c->updateLink(card->uid, uid);
}
swap(card->uid, uid);
}
}
// ----------------------------------------------------------------------------- : Pack types
+2 -2
View File
@@ -147,7 +147,7 @@ public:
Set& set; ///< The set to copy styling from
CardP card; ///< The affected card
IndexMap<FieldP,ValueP> styling_data; ///< The old styling of the card
};
};
// ----------------------------------------------------------------------------- : Change notes
@@ -177,7 +177,7 @@ public:
//private:
CardP card; ///< The affected card
String uid; ///< Its old uid
};
};
// ----------------------------------------------------------------------------- : Pack types
+3 -3
View File
@@ -36,7 +36,7 @@ void ValueAction::setCard(CardP const& card) {
}
// ----------------------------------------------------------------------------- : Simple
unique_ptr<ValueAction> value_action(const TextValueP& value, const Defaultable<String>& new_value) {
return make_unique<SimpleValueAction<TextValue, false>>(value, new_value);
}
@@ -208,7 +208,7 @@ String ScriptStyleEvent::getName(bool) const {
}
void ScriptStyleEvent::perform(bool) {
assert(false); // this action is just an event, it should not be performed
}
}
// ----------------------------------------------------------------------------- : Bulk action
@@ -235,7 +235,7 @@ void BulkAction::perform(bool to_undo) {
bool BulkAction::merge(const Action& action) {
return false;
}
}
// ----------------------------------------------------------------------------- : Action performer
+8 -8
View File
@@ -298,32 +298,32 @@ CardP Card::getLinkedOtherFace(const Set& set) {
return getLinkedOtherFace(set.cards);
}
vector<CardP> Card::getLinkedCardsFromLink(const vector<CardP>& cards, const String& link, bool erase_if_no_card) {
vector<CardP> other_cards;
vector<CardP> Card::getLinkedCardsFromLink(const vector<CardP>& cards, const String& link, bool erase_if_no_card) {
vector<CardP> other_cards;
THIS_LINKED_PAIRS(this_linked_pairs);
FOR_EACH(this_linked_pair, this_linked_pairs) {
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_relation == link) {
CardP other_card = getCardFromUid(cards, this_linked_uid);
if (other_card) other_cards.push_back(other_card);
if (other_card) other_cards.push_back(other_card);
else if (erase_if_no_card) {
this_linked_relation = _("");
this_linked_uid = _("");
}
}
}
}
return other_cards;
return other_cards;
}
vector<CardP> Card::getLinkedCardsFromLink(const Set& set, const String& link, bool erase_if_no_card) {
return getLinkedCardsFromLink(set.cards, link, erase_if_no_card);
}
CardP Card::getCardFromUid(const vector<CardP>& cards, const String& uid) {
CardP Card::getCardFromUid(const vector<CardP>& cards, const String& uid) {
FOR_EACH(card, cards) {
if (card->uid == uid) return card;
}
return nullptr;
return nullptr;
}
CardP Card::getCardFromUid(const Set& set, const String& uid) {
return getCardFromUid(set.cards, uid);
+3 -3
View File
@@ -90,10 +90,10 @@ public:
void updateLink(String old_uid, String new_uid);
vector<pair<CardP, String>> getLinkedCards(const vector<CardP>& cards);
vector<pair<CardP, String>> getLinkedCards(const Set& set);
vector<pair<CardP, String>> getLinkedCards(const Set& set);
vector<CardP> getLinkedCardsFromLink(const vector<CardP>& cards, const String& link, bool erase_if_no_card);
vector<CardP> getLinkedCardsFromLink(const Set& set, const String& link, bool erase_if_no_card);
vector<CardP> getLinkedCardsFromLink(const vector<CardP>& cards, const String& link, bool erase_if_no_card);
vector<CardP> getLinkedCardsFromLink(const Set& set, const String& link, bool erase_if_no_card);
CardP getLinkedOtherFace(const vector<CardP>& cards);
CardP getLinkedOtherFace(const Set& set);
+8 -8
View File
@@ -126,23 +126,23 @@ public:
inline RealPoint getPos() const { return RealPoint(left, top); }
inline RealSize getSize() const { return RealSize(width, height); }
inline RealRect getExternalRect() const { return RealRect(left, top, width, height); }
inline std::string getExternalRectString(double scale, Radians angle, double bleed, int img_width, int img_height, int img_offset) { ///< update the style before calling this
inline std::string getExternalRectString(double scale, Radians angle, double bleed, int img_width, int img_height, int img_offset) { ///< update the style before calling this
double x = left * scale, y = top * scale;
double w = width * scale, h = height * scale;
RealRect rect(x, y, w, h);
int degrees = 0;
RealRect rect(x, y, w, h);
int degrees = 0;
if (is_rad0(angle)) {
} else if (is_rad180(angle)) {
rect = RealRect(img_width - x - w, img_height - y - h, w, h);
rect = RealRect(img_width - x - w, img_height - y - h, w, h);
degrees = 180;
} else if (is_rad90(angle)) {
rect = RealRect(y, img_height - x - w, h, w);
rect = RealRect(y, img_height - x - w, h, w);
degrees = 90;
} else if (is_rad270(angle)) {
rect = RealRect(img_width - y - h, x, h, w);
rect = RealRect(img_width - y - h, x, h, w);
degrees = 270;
} else {
return "";
} else {
return "";
}
return "<mse-crop-data>" + std::to_string((int)std::ceil (rect.x + bleed + img_offset)) +
"-" + std::to_string((int)std::ceil (rect.y + bleed)) +
+1 -1
View File
@@ -39,7 +39,7 @@ IMPLEMENT_REFLECTION(ChoiceField) {
}
void ChoiceField::after_reading(Version ver) {
Field::after_reading(ver);
Field::after_reading(ver);
if (choices->choices.size() < 1) {
choices->choices.push_back(make_intrusive<Choice>(name));
}
+1 -1
View File
@@ -40,7 +40,7 @@ public:
String default_name; ///< Name of "default" value
map<String,Color> choice_colors; ///< Colors for the various choices (when color_cardlist)
map<String,Color> choice_colors_cardlist; ///< Colors for the various choices, for in the card list
bool is_slider = false; ///< Should the UI be displayed as a slider?
bool is_slider = false; ///< Should the UI be displayed as a slider?
void initDependencies(Context&, const Dependency&) const override;
void after_reading(Version ver) override;
+2 -2
View File
@@ -89,9 +89,9 @@ void ColorStyle::checkContentDependencies(Context& ctx, const Dependency& dep) c
left_width .initDependencies(ctx, dep);
right_width .initDependencies(ctx, dep);
top_width .initDependencies(ctx, dep);
bottom_width.initDependencies(ctx, dep);
bottom_width.initDependencies(ctx, dep);
Style::checkContentDependencies(ctx, dep);
}
}
// ----------------------------------------------------------------------------- : ColorValue
+1 -1
View File
@@ -63,7 +63,7 @@ public:
Scriptable<double> bottom_width; ///< Width of the colored region on the bottom side
ImageCombine combine; ///< How to combine image with the background
int update(Context&) override;
int update(Context&) override;
void checkContentDependencies(Context&, const Dependency&) const override;
};
+10 -10
View File
@@ -54,17 +54,17 @@ public:
ScriptableImage default_image; ///< Placeholder image when the user hasn't set one.
Scriptable<bool> store_in_metadata; ///< Is the image stored in full in the metadata when exporting?
int update(Context&) override;
inline std::string getExternalImageString(const SetP& set, ImageValue* value) { ///< update the style before calling this
int update(Context&) override;
inline std::string getExternalImageString(const SetP& set, ImageValue* value) { ///< update the style before calling this
auto imageInputStream = set->openIn(value->filename);
Image img(*imageInputStream, wxBITMAP_TYPE_PNG);
if (!img.IsOk()) throw ScriptError(_ERROR_2_("file not found", value->filename.toStringForKey(), set));
String temppath = wxFileName::CreateTempFileName(_("mse")) + _(".png");
img.SaveFile(temppath);
std::string s = "<mse-image-data>" + fileToUTF8(temppath.ToStdString()) + "</mse-image-data>";
wxRemoveFile(temppath);
wxRemoveFile(temppath.substr(0, temppath.size() - 4));
return s;
if (!img.IsOk()) throw ScriptError(_ERROR_2_("file not found", value->filename.toStringForKey(), set));
String temppath = wxFileName::CreateTempFileName(_("mse")) + _(".png");
img.SaveFile(temppath);
std::string s = "<mse-image-data>" + fileToUTF8(temppath.ToStdString()) + "</mse-image-data>";
wxRemoveFile(temppath);
wxRemoveFile(temppath.substr(0, temppath.size() - 4));
return s;
}
};
+4 -4
View File
@@ -162,15 +162,15 @@ wxFont Font::toWxFont(double scale) const {
if (flags & FONT_CODE) {
if (size_i < 2) {
font = wxFont(wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, weight_i, underline(), _("Courier New"));
if (strikethrough()) font.MakeStrikethrough();
font = wxFont(wxNORMAL_FONT->GetPointSize(), wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, weight_i, underline(), _("Courier New"));
if (strikethrough()) font.MakeStrikethrough();
return font;
} else {
font = wxFont(size_i, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, weight_i, underline(), _("Courier New"));
}
} else if (name().empty()) {
font = *wxNORMAL_FONT;
font.SetPointSize(size > 1 ? size_i : int(scale * font.GetPointSize()));
font.SetPointSize(size > 1 ? size_i : int(scale * font.GetPointSize()));
if (strikethrough()) font.MakeStrikethrough();
return font;
} else if (flags & FONT_ITALIC && !italic_name().empty()) {
@@ -188,7 +188,7 @@ wxFont Font::toWxFont(double scale) const {
// make it independent of screen dpi, always use 96 dpi
// TODO: do something more sensible, and more portable
font.SetPixelSize(wxSize(0, -(int)(scale*size*96.0/72.0 + 0.5) ));
#endif
#endif
if (strikethrough()) font.MakeStrikethrough();
return font;
}
+11 -11
View File
@@ -15,7 +15,7 @@
#include <data/stylesheet.hpp>
#include <data/keyword.hpp>
#include <util/io/package.hpp>
#include <script/scriptable.hpp>
#include <script/scriptable.hpp>
#include <wx/filename.h>
#include <wx/sstream.h>
@@ -145,20 +145,20 @@ KeywordP KeywordDataObject::getKeyword(const SetP& set) {
CardsOnClipboard::CardsOnClipboard(const SetP& set, const String id, const vector<CardP>& cards) {
// Conversion to image file
if (cards.size() < 6) {
Image img;
if (cards.size() == 1) {
if (cards.size() < 6) {
Image img;
if (cards.size() == 1) {
img = export_image(set, cards[0]);
}
}
else {
img = export_image(set, cards);
}
String temp_path = wxFileName::CreateTempFileName(_("mse")) + _(".png");
img.SaveFile(temp_path, wxBITMAP_TYPE_PNG);
wxFileDataObject* data = new wxFileDataObject();
data->AddFile(temp_path);
}
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, id, cards), true);
}
+2 -2
View File
@@ -93,8 +93,8 @@ Image export_image(const SetP& set, const CardP& card, const bool write_metadata
Image export_image(const SetP& set, const vector<CardP>& cards, const int padding = 2, const double global_zoom = 1.0, const bool use_zoom_setting = true, const bool use_rotation_setting = true, const bool use_bleed_setting = false);
/// Export the image of one or more cards to a given filename, using the app's zoom, rotation and bleed settings, and including metadata
void export_image(const SetP& set, const CardP& card, const String& filename);
void export_image(const SetP& set, const vector<CardP>& cards, const String& path, const String& filename_template, FilenameConflicts conflicts);
void export_image(const SetP& set, const CardP& card, const String& filename);
void export_image(const SetP& set, const vector<CardP>& cards, const String& path, const String& filename_template, FilenameConflicts conflicts);
/// Export a set to Magic Workstation format
void export_mws(Window* parent, const SetP& set);
+68 -68
View File
@@ -19,14 +19,14 @@
#include <data/settings.hpp>
#include <script/functions/json.hpp>
#include <gui/util.hpp>
#include <render/card/viewer.hpp>
#include <render/card/viewer.hpp>
class ZoomedUnrotatedDataViewer : public DataViewer {
public:
ZoomedUnrotatedDataViewer(double zoom) : zoom(zoom) {};
virtual ~ZoomedUnrotatedDataViewer() {};
Rotation getRotation() const override;
private:
Rotation getRotation() const override;
private:
double zoom;
};
@@ -36,14 +36,14 @@ Rotation ZoomedUnrotatedDataViewer::getRotation() const {
// ----------------------------------------------------------------------------- : wxImage export
Image export_image(const SetP& set, const CardP& card, const bool write_metadata, const double zoom, const Radians angle_radians, const double bleed_pixels) {
Image export_image(const SetP& set, const CardP& card, const bool write_metadata, const double zoom, const Radians angle_radians, const double bleed_pixels) {
if (!set) throw Error(_("no set"));
/// create and zoom
/// create and zoom
ZoomedUnrotatedDataViewer viewer = ZoomedUnrotatedDataViewer(zoom);
viewer.setSet(set);
viewer.setCard(card);
RealSize size = viewer.getRotation().getExternalSize();
int bleed = lround(bleed_pixels);
int bleed = lround(bleed_pixels);
Bitmap bitmap((int)size.width + 2 * bleed, (int)size.height + 2 * bleed);
if (!bitmap.Ok()) throw InternalError(_("Unable to create bitmap"));
wxMemoryDC dc;
@@ -51,18 +51,18 @@ Image export_image(const SetP& set, const CardP& card, const bool write_metadata
dc.SetDeviceOrigin(bleed, bleed);
viewer.draw(dc);
dc.SelectObject(wxNullBitmap);
Image img = bitmap.ConvertToImage();
/// rotate
img = rotate_image(img, angle_radians);
/// add print bleed edge
int width = img.GetWidth(), height = img.GetHeight();
bleed = max(0, min(width-1, min(height-1, bleed)));
Image img = bitmap.ConvertToImage();
/// rotate
img = rotate_image(img, angle_radians);
/// add print bleed edge
int width = img.GetWidth(), height = img.GetHeight();
bleed = max(0, min(width-1, min(height-1, bleed)));
if (size.width < bleed + 2 || size.height < bleed + 2) {
queue_message(MESSAGE_ERROR, _("Image too small to add bleed edge"));
}
else {
}
else {
if (!img.HasAlpha()) img.InitAlpha();
Byte* pixels = img.GetData();
Byte* alpha = img.GetAlpha();
@@ -126,17 +126,17 @@ Image export_image(const SetP& set, const CardP& card, const bool write_metadata
pixels[3 * pixel + 2] = pixels[3 * mirror + 2];
alpha[pixel] = alpha[mirror];
}
}
}
/// add metadata
}
}
/// add metadata
if (write_metadata) {
String metadata = _("<mse-card-data>[");
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();
StyleSheetP stylesheet = set->stylesheetForP(card);
if (!settings.stylesheetSettingsFor(*stylesheet).card_notes_export()) cardv["notes"] = "";
if (!settings.stylesheetSettingsFor(*stylesheet).card_notes_export()) cardv["notes"] = "";
// iterate over all image fields
for(IndexMap<FieldP, ValueP>::iterator it = card_data.begin() ; it != card_data.end() ; ++it) {
ImageValue* value = dynamic_cast<ImageValue*>(it->get());
@@ -144,64 +144,64 @@ Image export_image(const SetP& set, const CardP& card, const bool write_metadata
FieldP field = (*it)->fieldP;
ImageStyle* style = dynamic_cast<ImageStyle*>(stylesheet->card_style.at(field->index).get());
if (style) {
style->update(set->getContext(card));
// store the entire image in the metadata
if (style->store_in_metadata()) {
std::string bytes = style->getExternalImageString(set, value);
cardv_data[field->name.ToStdString()] = bytes;
}
// store only crop coordinates
else {
style->update(set->getContext(card));
// store the entire image in the metadata
if (style->store_in_metadata()) {
std::string bytes = style->getExternalImageString(set, value);
cardv_data[field->name.ToStdString()] = bytes;
}
// store only crop coordinates
else {
std::string rect = style->getExternalRectString(zoom, angle_radians, bleed_pixels, width, height, 0);
cardv_data[field->name.ToStdString()] = rect;
cardv_data[field->name.ToStdString()] = rect;
}
}
}
}
metadata += json_ugly_print(cardv) + _("]</mse-card-data>");
img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata);
}
}
return img;
}
Image export_image( const SetP& set, const vector<CardP>& cards,
const int padding,
const double global_zoom,
const bool use_zoom_setting,
const bool use_rotation_setting,
Image export_image( const SetP& set, const vector<CardP>& cards,
const int padding,
const double global_zoom,
const bool use_zoom_setting,
const bool use_rotation_setting,
const bool use_bleed_setting) {
if (!set) throw Error(_("no set"));
if (cards.size() == 0) throw Error(_("no cards"));
vector<Image> imgs;
vector<int> offsets;
vector<int> offsets;
vector<double> zooms;
vector<double> angles;
vector<double> bleeds;
// Draw card images
FOR_EACH(card, cards) {
FOR_EACH(card, cards) {
Settings::ExportSettings card_settings = settings.exportSettingsFor(set->stylesheetFor(card));
double zoom = use_zoom_setting ? global_zoom * card_settings.zoom : global_zoom;
double angle = use_rotation_setting ? card_settings.angle_radians : 0.0;
double bleed = use_bleed_setting ? card_settings.bleed_pixels : 0.0;
imgs.push_back(export_image(set, card, false, zoom, angle, bleed));
zooms.push_back(zoom);
angles.push_back(angle);
imgs.push_back(export_image(set, card, false, zoom, angle, bleed));
zooms.push_back(zoom);
angles.push_back(angle);
bleeds.push_back(bleed);
}
}
int global_width = 0;
int global_height = 0;
vector<int> widths;
vector<int> heights;
FOR_EACH(img, imgs) {
int width = img.GetWidth();
int height = img.GetHeight();
widths.push_back(width);
heights.push_back(height);
offsets.push_back(global_width);
global_width += padding + width;
global_height = max(global_height, height);
}
FOR_EACH(img, imgs) {
int width = img.GetWidth();
int height = img.GetHeight();
widths.push_back(width);
heights.push_back(height);
offsets.push_back(global_width);
global_width += padding + width;
global_height = max(global_height, height);
}
global_width -= padding;
// Draw global image
Image global_img = Image(global_width, global_height);
@@ -215,11 +215,11 @@ Image export_image( const SetP& set, const vector<CardP>& cards,
pixels[3 * i + 1] = 0;
pixels[3 * i + 2] = 0;
alpha[i] = 0;
}
}
// Paste card images
FOR_EACH_2(img, imgs, offset, offsets) {
global_img.Paste(img, offset, 0);
}
FOR_EACH_2(img, imgs, offset, offsets) {
global_img.Paste(img, offset, 0);
}
// Write metadata
String metadata = _("<mse-card-data>[");
for (int i = 0; i < cards.size(); ++i) {
@@ -233,19 +233,19 @@ Image export_image( const SetP& set, const vector<CardP>& cards,
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;
FieldP field = (*it)->fieldP;
ImageStyle* style = dynamic_cast<ImageStyle*>(stylesheet->card_style.at(field->index).get());
if (style) {
style->update(set->getContext(card));
// store the entire image in the metadata
if (style->store_in_metadata()) {
std::string bytes = style->getExternalImageString(set, value);
cardv_data[field->name.ToStdString()] = bytes;
}
// store only crop coordinates
else {
style->update(set->getContext(card));
// store the entire image in the metadata
if (style->store_in_metadata()) {
std::string bytes = style->getExternalImageString(set, value);
cardv_data[field->name.ToStdString()] = bytes;
}
// store only crop coordinates
else {
std::string rect = style->getExternalRectString(zooms[i], angles[i], bleeds[i], widths[i], heights[i], offsets[i]);
cardv_data[field->name.ToStdString()] = rect;
cardv_data[field->name.ToStdString()] = rect;
}
}
}
@@ -253,14 +253,14 @@ Image export_image( const SetP& set, const vector<CardP>& cards,
metadata += json_ugly_print(cardv);
}
metadata += _("]</mse-card-data>");
global_img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata);
global_img.SetOption(wxIMAGE_OPTION_PNG_DESCRIPTION, metadata);
return global_img;
}
void export_image(const SetP& set, const CardP& card, const String& filename) {
void export_image(const SetP& set, const CardP& card, const String& filename) {
const StyleSheet& stylesheet = set->stylesheetFor(card);
StyleSheetSettings& stylesheet_settings = settings.stylesheetSettingsFor(stylesheet);
StyleSheetSettings& stylesheet_settings = settings.stylesheetSettingsFor(stylesheet);
Settings::ExportSettings export_settings = settings.exportSettingsFor(stylesheet);
Image img = export_image(set, card, true, export_settings.zoom, export_settings.angle_radians, export_settings.bleed_pixels);
img.SaveFile(filename);
+17 -17
View File
@@ -67,7 +67,7 @@ IMPLEMENT_REFLECTION(Game) {
REFLECT_NO_SCRIPT(auto_replaces);
}
void Game::validate(Version v) {
void Game::validate(Version v) {
// check that we have at least one card field
if (card_fields.size() < 1) {
throw Error(_ERROR_1_("no card fields", name()));
@@ -123,11 +123,11 @@ void Game::validate(Version v) {
card_fields_alt_names.emplace(unified_name, field->name);
}
}
}
// front face/back face card link
card_links.insert(card_links.begin(), make_intrusive<CardLink>());
}
// front face/back face card link
card_links.insert(card_links.begin(), make_intrusive<CardLink>());
card_links[0]->selected.default_ = _("Front Face");
card_links[0]->selected.translations = std::unordered_map<String, String>{
card_links[0]->selected.translations = std::unordered_map<String, String>{
{_("ch-s"), _("卡片正面")},
{_("ch-t"), _("卡片正面")},
{_("da"), _("Forside")},
@@ -140,9 +140,9 @@ void Game::validate(Version v) {
{_("ko"), _("카드 앞면")},
{_("pl"), _("Przód")},
{_("pt-br"), _("Frente")},
{_("ru"), _("Лицевая сторона")}
};
card_links[0]->linked.default_ = _("Back Face");
{_("ru"), _("Лицевая сторона")}
};
card_links[0]->linked.default_ = _("Back Face");
card_links[0]->linked.translations = std::unordered_map<String, String>{
{_("ch-s"), _("卡片背面")},
{_("ch-t"), _("卡片背面")},
@@ -156,27 +156,27 @@ void Game::validate(Version v) {
{_("ko"), _("카드 뒷면")},
{_("pl"), _("Tył")},
{_("pt-br"), _("Verso")},
{_("ru"), _("Обратная сторона")}
};
{_("ru"), _("Обратная сторона")}
};
// localized card link names map
for (auto it = card_links.begin(); it != card_links.end(); ++it) {
CardLinkP link = *it;
String selected_default = link->selected.default_;
String selected_default = link->selected.default_;
for (auto selected_it = link->selected.translations.begin(); selected_it != link->selected.translations.end(); selected_it++) {
String selected_tr = unified_form(selected_it->second);
String selected_tr = unified_form(selected_it->second);
if (card_links_alt_names.find(selected_tr) != card_links_alt_names.end() && card_links_alt_names[selected_tr] != selected_default) {
queue_message(MESSAGE_WARNING, _ERROR_3_("link duplicate", selected_tr, card_links_alt_names[selected_tr], selected_default));
}
}
card_links_alt_names.emplace(selected_tr, selected_default);
}
String linked_default = link->linked.default_;
String linked_default = link->linked.default_;
for (auto linked_it = link->linked.translations.begin(); linked_it != link->linked.translations.end(); linked_it++) {
String linked_tr = unified_form(linked_it->second);
String linked_tr = unified_form(linked_it->second);
if (card_links_alt_names.find(linked_tr) != card_links_alt_names.end() && card_links_alt_names[linked_tr] != linked_default) {
queue_message(MESSAGE_WARNING, _ERROR_3_("link duplicate", linked_tr, card_links_alt_names[linked_tr], linked_default));
}
}
card_links_alt_names.emplace(linked_tr, linked_default);
}
}
}
}
+2 -2
View File
@@ -37,8 +37,8 @@ IMPLEMENT_REFLECTION(Installer) {
void Installer::validate(Version file_app_version) {
Packaged::validate(file_app_version);
// load icons where possible
FOR_EACH(p,packages) {
String url = p->icon_url;
FOR_EACH(p,packages) {
String url = p->icon_url;
if (settings.darkMode() && !p->dark_icon_url.empty()) {
url = p->dark_icon_url;
}
+5 -5
View File
@@ -108,11 +108,11 @@ IndexMap<FieldP, ValueP>& Set::stylingDataFor(const CardP& card) {
}
void Set::referenceActionStackFiles() {
referenceActionStackFiles(true);
referenceActionStackFiles(true);
referenceActionStackFiles(false);
}
void Set::referenceActionStackFiles(bool undo) {
for (auto&& action : undo ? actions.undo_actions : actions.redo_actions) {
void Set::referenceActionStackFiles(bool undo) {
for (auto&& action : undo ? actions.undo_actions : actions.redo_actions) {
try {
SimpleValueAction<ImageValue, false>& v = dynamic_cast<SimpleValueAction<ImageValue, false>&>(*action);
if (ImageValue* v2 = dynamic_cast<ImageValue*>(v.valueP.get())) {
@@ -125,9 +125,9 @@ void Set::referenceActionStackFiles(bool undo) {
referenceFile(v.new_value.toStringForWriting());
referenceFile(v2->filename.toStringForWriting());
}
} catch (...) {} }
} catch (...) {} }
}
}
}
String Set::identification() const {
// an identifying field
+4 -4
View File
@@ -89,12 +89,12 @@ public:
/// Styling information for a particular stylesheet
IndexMap<FieldP, ValueP>& stylingDataFor(const StyleSheet&);
/// Styling information for a particular card
IndexMap<FieldP, ValueP>& stylingDataFor(const CardP& card);
/// Make sure the image and symbol files from
IndexMap<FieldP, ValueP>& stylingDataFor(const CardP& card);
/// Make sure the image and symbol files from
/// the ActionStack are saved so we can undo
void referenceActionStackFiles();
void referenceActionStackFiles(bool undo);
void referenceActionStackFiles(bool undo);
/// Get the identification of this set, an identification is something like a name, title, etc.
/** May return "" */
+40 -40
View File
@@ -54,7 +54,7 @@ IMPLEMENT_REFLECTION_ENUM(FilenameConflicts) {
}
const vector<int> Settings::scale_choices = { 50,66,75,80,100,120,125,150,175,200 };
const int COLUMN_NOT_INITIALIZED = -100000;
ColumnSettings::ColumnSettings()
@@ -103,11 +103,11 @@ void GameSettings::initDefaults(const Game& game) {
ar->custom = false;
auto_replaces.push_back(ar);
}
}
// make sure things aren't in a problematic state
}
// make sure things aren't in a problematic state
for (auto it = cardlist_columns.begin(); it != cardlist_columns.end(); ++it) {
if (it->second.width < 20) it->second.width = 20;
}
}
if (images_export_filename.Trim().empty()) images_export_filename = _("{card.name}.png");
}
@@ -174,13 +174,13 @@ IMPLEMENT_REFLECTION_ENUM(CutterLinesType) {
VALUE_N("none", CUTTER_NONE);
}
// ----------------------------------------------------------------------------- : Dark mode settings
IMPLEMENT_REFLECTION_ENUM(DarkModeType) {
VALUE_N("yes", DARKMODE_YES);
VALUE_N("system", DARKMODE_SYSTEM);
VALUE_N("no", DARKMODE_NO);
}
// ----------------------------------------------------------------------------- : Dark mode settings
IMPLEMENT_REFLECTION_ENUM(DarkModeType) {
VALUE_N("yes", DARKMODE_YES);
VALUE_N("system", DARKMODE_SYSTEM);
VALUE_N("no", DARKMODE_NO);
}
// ----------------------------------------------------------------------------- : Settings
@@ -234,7 +234,7 @@ GameSettings& Settings::gameSettingsFor(const Game& game) {
if (!gs) gs = make_intrusive<GameSettings>();
gs->initDefaults(game);
return *gs;
}
}
ColumnSettings& Settings::columnSettingsFor(const Game& game, const Field& field) {
// Get game info
@@ -248,7 +248,7 @@ ColumnSettings& Settings::columnSettingsFor(const Game& game, const Field& field
cs.width = field.card_list_width;
}
return cs;
}
}
StyleSheetSettings& Settings::stylesheetSettingsFor(const StyleSheet& stylesheet) {
// Use the canonical form here since the stylesheet name will be used as a stored key.
@@ -257,37 +257,37 @@ StyleSheetSettings& Settings::stylesheetSettingsFor(const StyleSheet& stylesheet
if (!ss) ss = make_intrusive<StyleSheetSettings>();
ss->useDefault(default_stylesheet_settings); // update default settings
return *ss;
}
}
double Settings::exportScaleSettingsFor(const StyleSheet& stylesheet) {
StyleSheetSettings& ss = stylesheetSettingsFor(stylesheet);
int export_scale = ss.export_scale_selection();
if (export_scale == 0) return adaptiveScaleSettingsFor(stylesheet, 300.0, 50.0);
if (export_scale == 1) return adaptiveScaleSettingsFor(stylesheet, 300.0, 1.0);
if (export_scale == 2) return adaptiveScaleSettingsFor(stylesheet, 150.0, 1.0);
int export_scale = ss.export_scale_selection();
if (export_scale == 0) return adaptiveScaleSettingsFor(stylesheet, 300.0, 50.0);
if (export_scale == 1) return adaptiveScaleSettingsFor(stylesheet, 300.0, 1.0);
if (export_scale == 2) return adaptiveScaleSettingsFor(stylesheet, 150.0, 1.0);
return (double)scale_choices[export_scale - 3] / 100.0;
}
}
double Settings::importScaleSettingsFor(const StyleSheet& stylesheet) {
if (import_scale_selection == 0) return exportScaleSettingsFor(stylesheet);
if (import_scale_selection == 1) return adaptiveScaleSettingsFor(stylesheet, 300.0, 50.0);
if (import_scale_selection == 2) return adaptiveScaleSettingsFor(stylesheet, 300.0, 1.0);
if (import_scale_selection == 3) return adaptiveScaleSettingsFor(stylesheet, 150.0, 1.0);
if (import_scale_selection == 0) return exportScaleSettingsFor(stylesheet);
if (import_scale_selection == 1) return adaptiveScaleSettingsFor(stylesheet, 300.0, 50.0);
if (import_scale_selection == 2) return adaptiveScaleSettingsFor(stylesheet, 300.0, 1.0);
if (import_scale_selection == 3) return adaptiveScaleSettingsFor(stylesheet, 150.0, 1.0);
return (double)scale_choices[import_scale_selection - 4] / 100.0;
}
double Settings::adaptiveScaleSettingsFor(const StyleSheet& stylesheet, double dpi_target, double dpi_leeway) {
if (abs(stylesheet.card_dpi - dpi_target) <= dpi_leeway) return 1.0;
}
double Settings::adaptiveScaleSettingsFor(const StyleSheet& stylesheet, double dpi_target, double dpi_leeway) {
if (abs(stylesheet.card_dpi - dpi_target) <= dpi_leeway) return 1.0;
return dpi_target / max(10.0, stylesheet.card_dpi);
}
}
Settings::ExportSettings Settings::exportSettingsFor(const StyleSheet& stylesheet) {
StyleSheetSettings& ss = stylesheetSettingsFor(stylesheet);
double zoom = settings.exportScaleSettingsFor(stylesheet);
double zoom = settings.exportScaleSettingsFor(stylesheet);
double angle = ss.card_normal_export() ? 0.0 : deg_to_rad(ss.card_angle());
double bleed = ss.card_bleed_export() ? (stylesheet.card_dpi / 300.0) * 36.0 * zoom : 0.0; // 36 pixels of bleed on a 300 DPI print
double bleed = ss.card_bleed_export() ? (stylesheet.card_dpi / 300.0) * 36.0 * zoom : 0.0; // 36 pixels of bleed on a 300 DPI print
return ExportSettings{zoom, angle, bleed};
}
}
IndexMap<FieldP,ValueP>& Settings::exportOptionsFor(const ExportTemplate& export_template) {
return export_options.get(export_template.name(), export_template.option_fields);
@@ -306,17 +306,17 @@ String Settings::settingsFile() {
bool Settings::darkMode() {
return wxSystemSettings::GetAppearance().IsDark();
}
}
String Settings::darkModePrefix() {
if (darkMode()) return _("dark_");
if (darkMode()) return _("dark_");
return _("");
}
}
Color Settings::darkModeColor() {
if (darkMode()) return wxColor(15,8,0);
if (darkMode()) return wxColor(15,8,0);
return wxColor(240,247,255);
}
}
IMPLEMENT_REFLECTION_NO_SCRIPT(Settings) {
REFLECT(locale);
@@ -377,10 +377,10 @@ void Settings::read() {
wxFileInputStream file(filename);
if (!file.Ok()) return; // failure is not an error
Reader reader(file, nullptr, filename);
reader.handle_greedy(*this);
// make sure things aren't in a problematic state
if (locale.Trim().empty()) locale = _("en");
if (symbol_grid_size < 30) symbol_grid_size = 30;
reader.handle_greedy(*this);
// make sure things aren't in a problematic state
if (locale.Trim().empty()) locale = _("en");
if (symbol_grid_size < 30) symbol_grid_size = 30;
if (default_stylesheet_settings.card_zoom < 0.5) default_stylesheet_settings.card_zoom = 1.0;
}
}
+29 -29
View File
@@ -113,22 +113,22 @@ public:
DECLARE_REFLECTION();
};
// ----------------------------------------------------------------------------- : Printing settings
enum CutterLinesType
{ CUTTER_ALL
, CUTTER_NO_INTERSECTION
, CUTTER_NONE
};
// ----------------------------------------------------------------------------- : Dark mode settings
enum DarkModeType
{ DARKMODE_SYSTEM
, DARKMODE_NO
, DARKMODE_YES
};
// ----------------------------------------------------------------------------- : Printing settings
enum CutterLinesType
{ CUTTER_ALL
, CUTTER_NO_INTERSECTION
, CUTTER_NONE
};
// ----------------------------------------------------------------------------- : Dark mode settings
enum DarkModeType
{ DARKMODE_SYSTEM
, DARKMODE_NO
, DARKMODE_YES
};
// ----------------------------------------------------------------------------- : Settings
@@ -175,10 +175,10 @@ public:
String default_game;
// --------------------------------------------------- : Game/stylesheet specific
struct ExportSettings {
double zoom, angle_radians, bleed_pixels;
};
};
/// Get the settings object for a specific game
GameSettings& gameSettingsFor (const Game& game);
@@ -188,10 +188,10 @@ public:
StyleSheetSettings& stylesheetSettingsFor (const StyleSheet& stylesheet);
double exportScaleSettingsFor (const StyleSheet& stylesheet);
double importScaleSettingsFor (const StyleSheet& stylesheet);
double adaptiveScaleSettingsFor (const StyleSheet& stylesheet, double target_dpi, double leeway_dpi);
ExportSettings exportSettingsFor (const StyleSheet& stylesheet);
double adaptiveScaleSettingsFor (const StyleSheet& stylesheet, double target_dpi, double leeway_dpi);
ExportSettings exportSettingsFor (const StyleSheet& stylesheet);
static const vector<int> scale_choices;
static const vector<int> scale_choices;
private:
map<String,GameSettingsP> game_settings;
@@ -215,24 +215,24 @@ public:
// --------------------------------------------------- : Dark Mode
DarkModeType dark_mode_type;
/// Is the app currently displayed in dark mode?
bool darkMode();
DarkModeType dark_mode_type;
/// Is the app currently displayed in dark mode?
bool darkMode();
/// Prefix for resource files depending on dark mode
String darkModePrefix();
String darkModePrefix();
/// Background color for windows depending on dark mode
Color darkModeColor();
Color darkModeColor();
// --------------------------------------------------- : Special game stuff
String apprentice_location;
// --------------------------------------------------- : Internal settings
// --------------------------------------------------- : Internal settings
int import_scale_selection;
bool allow_image_download;
// --------------------------------------------------- : Update checking
// --------------------------------------------------- : Update checking
#if USE_OLD_STYLE_UPDATE_CHECKER
String updates_url;
@@ -243,7 +243,7 @@ public:
bool check_updates_all; ///< Check updates of all packages, not just the program
String website_url;
// --------------------------------------------------- : Installation settings
// --------------------------------------------------- : Installation settings
InstallType install_type;
+12 -12
View File
@@ -484,24 +484,24 @@ wxMenu* InsertSymbolMenu::makeMenu(int id, SymbolFont& font) const {
wxMenuItem* InsertSymbolMenu::makeMenuItem(wxMenu* parent, int first_id, SymbolFont& font) const {
String label = this->label.get();
// ensure that we are not defining an accelerator...
// ensure that we are not defining an accelerator...
// everything after a tab is considered to be an accelerator by wxMenuItem
int accel_pos = label.find_last_of('\t');
if (accel_pos != label.npos && accel_pos > 0) {
String accel = label.substr(accel_pos+1);
int accel_pos = label.find_last_of('\t');
if (accel_pos != label.npos && accel_pos > 0) {
String accel = label.substr(accel_pos+1);
#ifdef __WXMSW__
// if there is a + or - in the accelerator, replace the tab with spaces (simply adding a space does not work)
if (accel.Contains("+") || accel.Contains("-")) {
label = label.substr(0, accel_pos) + _(" ") + accel;
}
// otherwise simply add a space after the tab if there isn't one
else {
// if there is a + or - in the accelerator, replace the tab with spaces (simply adding a space does not work)
if (accel.Contains("+") || accel.Contains("-")) {
label = label.substr(0, accel_pos) + _(" ") + accel;
}
// otherwise simply add a space after the tab if there isn't one
else {
label.Replace(_("\t "), _("\t"));
label.Replace(_("\t"), _("\t "));
label.Replace(_("\t"), _("\t "));
}
#else
label = label.substr(0, accel_pos) + _(" ") + accel; // replace the tab with spaces
#endif
#endif
}
if (type == Type::SUBMENU) {
wxMenuItem* item = new wxMenuItem(parent, wxID_ANY, label,
+23 -23
View File
@@ -332,8 +332,8 @@ Image BleedEdgedImage::generate(const Options& opt) {
}
bool is_landscape = w > h;
int dw = int(w * (horizontal_size > 0.0 ? horizontal_size : is_landscape ? 0.037 : 0.048));
int dh = int(h * (vertical_size > 0.0 ? vertical_size : is_landscape ? 0.048 : 0.037));
dw = min(w-1, max(0, dw));
int dh = int(h * (vertical_size > 0.0 ? vertical_size : is_landscape ? 0.048 : 0.037));
dw = min(w-1, max(0, dw));
dh = min(h-1, max(0, dh));
if (dw <= 0 && dh <= 0) {
return base_img;
@@ -680,32 +680,32 @@ bool ImageValueToImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : ImportedImage
ImportedImage::ImportedImage(Set* set, const String& filepath)
{
loadpath = filepath;
{
loadpath = filepath;
// has the set already been saved at least once?
if (set->needSaveAs()) throw ScriptError(_ERROR_1_("can't import image without set", loadpath));
// does the file pointed to by filepath exist?
if (!wxFileName(loadpath, wxPATH_UNIX).FileExists()) throw ScriptError(_ERROR_1_("import not found", loadpath));
if (!wxFileName(loadpath, wxPATH_UNIX).FileExists()) throw ScriptError(_ERROR_1_("import not found", loadpath));
// is the file an image?
Image img;
img.LoadFile(loadpath);
if (!img.IsOk()) throw ScriptError(_ERROR_1_("import not image", loadpath));
Image img;
img.LoadFile(loadpath);
if (!img.IsOk()) throw ScriptError(_ERROR_1_("import not image", loadpath));
// add the file to the set (or overwrite it if pre-existing), save set
savename = normalize_internal_filename(loadpath);
savename.Replace(":", "-");
savename.Replace("/", "-");
auto outStream = set->openOut(savename);
auto outStream = set->openOut(savename);
img.SaveFile(*outStream, wxBITMAP_TYPE_PNG);
if (!outStream->IsOk()) throw ScriptError(_ERROR_1_("can't write image to set", loadpath));
outStream->Close();
set->save(false);
}
Image ImportedImage::generate(const Options& opt) {
Image ImportedImage::generate(const Options& opt) {
auto imageInputStream = opt.local_package->openIn(savename);
Image img(*imageInputStream, wxBITMAP_TYPE_PNG);
@@ -722,34 +722,34 @@ bool ImportedImage::operator == (const GeneratedImage& that) const {
// ----------------------------------------------------------------------------- : DownloadedImage
DownloadedImage::DownloadedImage(Set* set, const String& url)
{
loadpath = url;
{
loadpath = url;
// has the set already been saved at least once?
if (set->needSaveAs()) throw ScriptError(_ERROR_1_("can't download image without set", loadpath));
// can we download the data?
// can we download the data?
WebRequestWindow wnd(loadpath);
if (wnd.ShowModal() != wxID_OK) throw ScriptError(_ERROR_1_("can't download image", loadpath));
// is the data an image?
const String& content_type = wnd.out.GetContentType();
if (!content_type.StartsWith(_("image"))) throw ScriptError(_ERROR_1_("download not image", loadpath));
if (wnd.ShowModal() != wxID_OK) throw ScriptError(_ERROR_1_("can't download image", loadpath));
// is the data an image?
const String& content_type = wnd.out.GetContentType();
if (!content_type.StartsWith(_("image"))) throw ScriptError(_ERROR_1_("download not image", loadpath));
Image img(*wnd.out.GetStream());
if (!img.IsOk()) throw ScriptError(_ERROR_("web request corrupted"));
if (!img.IsOk()) throw ScriptError(_ERROR_("web request corrupted"));
// add the file to the set (or overwrite it if pre-existing), save set
savename = normalize_internal_filename(loadpath);
savename.Replace(":", "-");
savename.Replace("/", "-");
auto outStream = set->openOut(savename);
auto outStream = set->openOut(savename);
img.SaveFile(*outStream, wxBITMAP_TYPE_PNG);
if (!outStream->IsOk()) throw ScriptError(_ERROR_1_("can't write image to set", loadpath));
outStream->Close();
set->save(false);
}
Image DownloadedImage::generate(const Options& opt) {
Image DownloadedImage::generate(const Options& opt) {
auto imageInputStream = opt.local_package->openIn(savename);
Image img(*imageInputStream, wxBITMAP_TYPE_PNG);
+3 -3
View File
@@ -17,7 +17,7 @@
DECLARE_POINTER_TYPE(GeneratedImage);
DECLARE_POINTER_TYPE(SymbolVariation);
class Package;
class Set;
class Set;
// ----------------------------------------------------------------------------- : GeneratedImage
@@ -455,10 +455,10 @@ private:
class ExternalImage : public GeneratedImage {
public:
inline String toString() { return savename; }
inline String toCode() const override { return _("<image>"); }
inline String toCode() const override { return _("<image>"); }
protected:
String loadpath;
String loadpath;
String savename;
};
+2 -2
View File
@@ -134,9 +134,9 @@ Image resample(const Image& img_in, int width, int height) {
return img_out;
}
}
Image resample(const Image& img_in, double zoom) {
Image resample(const Image& img_in, double zoom) {
return resample(img_in, (int)(img_in.GetWidth() * zoom), (int)(img_in.GetHeight() * zoom));
}
}
void resample_and_clip(const Image& img_in, Image& img_out, wxRect rect) {
// mask to alpha
+8 -8
View File
@@ -33,14 +33,14 @@ void AboutWindow::onPaint(wxPaintEvent& ev) {
draw(dc);
}
const char* MSE_AUTHORS[] = {
"Twan van Laarhoven (twanvl)",
"Sean Hunt (coppro)",
"Alissa Rao (Lymia)",
"Olivier Bocksberger (G-e-n-e-v-e-n-s-i-S)",
"Brendan Hagan (haganbmj)",
"Thomas Tkacz (TomTkacz)",
"CaiCai (247321453)"
const char* MSE_AUTHORS[] = {
"Twan van Laarhoven (twanvl)",
"Sean Hunt (coppro)",
"Alissa Rao (Lymia)",
"Olivier Bocksberger (G-e-n-e-v-e-n-s-i-S)",
"Brendan Hagan (haganbmj)",
"Thomas Tkacz (TomTkacz)",
"CaiCai (247321453)"
};
void AboutWindow::draw(DC& dc) {
+143 -143
View File
@@ -30,11 +30,11 @@
#include <data/action/value.hpp>
#include <script/functions/json.hpp>
#include <util/window_id.hpp>
#include <wx/clipbrd.h>
#include <wx/webrequest.h>
#include <wx/clipbrd.h>
#include <wx/webrequest.h>
#include <wx/wfstream.h>
#include <unordered_set>
#include <fstream>
#include <fstream>
DECLARE_POINTER_TYPE(ChoiceValue);
@@ -59,8 +59,8 @@ CardListBase* CardSelectEvent::getTheCardList() const {
CardListBase::CardListBase(Window* parent, int id, long additional_style)
: ItemList(parent, id, additional_style, true)
{
drop_target = new CardListDropTarget(this);
{
drop_target = new CardListDropTarget(this);
}
CardListBase::~CardListBase() {
@@ -168,7 +168,7 @@ bool CardListBase::doCopy() {
bool ok = wxTheClipboard->SetData(new CardsOnClipboard(set, _(""), cards_to_copy)); // ignore result
wxTheClipboard->Close();
return ok;
}
}
bool CardListBase::doCopyCardAndLinkedCards() {
if (!canCopy()) return false;
@@ -194,16 +194,16 @@ bool CardListBase::doCopyCardAndLinkedCards() {
bool ok = wxTheClipboard->SetData(new CardsOnClipboard(set, _(""), cards_to_copy)); // ignore result
wxTheClipboard->Close();
return ok;
}
}
bool CardListBase::doPaste() {
if (!canPaste()) return false;
if (!wxTheClipboard->Open()) return false;
bool ok = wxTheClipboard->GetData(*drop_target->data_object);
wxTheClipboard->Close();
if (ok) return parseData(false);
wxTheClipboard->Close();
if (ok) return parseData(false);
return false;
}
}
bool CardListBase::doDelete() {
// cards to delete
@@ -213,7 +213,7 @@ bool CardListBase::doDelete() {
// delete cards
set->actions.addAction(make_unique<AddCardAction>(REMOVE, *set, cards_to_delete));
return true;
}
}
bool CardListBase::doAddCSV() {
AddCSVWindow wnd(this, set, true);
@@ -231,7 +231,7 @@ bool CardListBase::doAddJSON() {
return true;
}
return false;
}
}
bool CardListBase::doBulkModification() {
BulkModificationWindow wnd(this, set, true);
@@ -240,133 +240,133 @@ bool CardListBase::doBulkModification() {
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(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();
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(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])) {
Image image_file;
image_file.SetLoadFlags(image_file.GetLoadFlags() & ~wxImage::Load_Verbose);
if (image_file.LoadFile(filenames[i])) {
parseImage(image_file, out);
} else {
} else {
// if it's an url, request the data
std::ifstream ifs(filenames[i].ToStdString());
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);
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();
}
return j < out.size();
}
bool CardListBase::parseImage(Image& image, vector<CardP>& out) {
size_t j = out.size();
if (image.HasOption(wxIMAGE_OPTION_PNG_DESCRIPTION)) {
auto text = image.GetOption(wxIMAGE_OPTION_PNG_DESCRIPTION);
parseText(text, out);
// crop image rects to populate image fields
bool CardListBase::parseImage(Image& image, vector<CardP>& out) {
size_t j = out.size();
if (image.HasOption(wxIMAGE_OPTION_PNG_DESCRIPTION)) {
auto text = image.GetOption(wxIMAGE_OPTION_PNG_DESCRIPTION);
parseText(text, out);
// crop image rects to populate image fields
for (; j < out.size(); j++) {
CardP& card = out[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 = wxRect(0,0,0,0);
int degrees = 0;
value->filename.getExternalRect(rect, degrees);
if (rect.width > 0 && rect.height > 0) {
Image img = image.GetSubImage(rect);
img = rotate_image(img, deg_to_rad(360-degrees));
if (value && !value->filename.empty()) {
wxRect rect = wxRect(0,0,0,0);
int degrees = 0;
value->filename.getExternalRect(rect, degrees);
if (rect.width > 0 && rect.height > 0) {
Image img = image.GetSubImage(rect);
img = rotate_image(img, deg_to_rad(360-degrees));
LocalFileName filename = set->newFileName("cropped_image", _(".png")); // a new unique name in the package
img.SaveFile(set->nameOut(filename), wxBITMAP_TYPE_PNG);
value->filename = filename;
}
img.SaveFile(set->nameOut(filename), wxBITMAP_TYPE_PNG);
value->filename = filename;
}
}
}
}
}
}
}
return j < out.size();
}
bool CardListBase::parseText(String& text, vector<CardP>& out) {
}
bool CardListBase::parseText(String& text, vector<CardP>& out) {
size_t j = out.size();
if (size_t pos = text.find("<mse-card-data>") != wxString::npos) {
text = text.substr(pos + 14, text.find("</mse-card-data>") - pos - 14);
}
try {
ScriptValueP sv = json_to_mse(text, set.get());
if (size_t pos = text.find("<mse-card-data>") != wxString::npos) {
text = text.substr(pos + 14, text.find("</mse-card-data>") - pos - 14);
}
try {
ScriptValueP sv = json_to_mse(text, set.get());
if (sv->type() == SCRIPT_COLLECTION) {
if (ScriptCustomCollection* custom = dynamic_cast<ScriptCustomCollection*>(sv.get())) {
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()));
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 (...) {}
// recreate images to populate image fields
}
} catch (...) {}
// recreate images to populate image fields
for (int k = j; k < out.size(); k++) {
CardP& card = out[k];
CardP& card = out[k];
for (IndexMap<FieldP, ValueP>::iterator it = card->data.begin(); it != card->data.end(); it++) {
ImageValue* value = dynamic_cast<ImageValue*>(it->get());
if (value) {
Image img = value->filename.getExternalImage();
if (img.IsOk()) {
if (value) {
Image img = value->filename.getExternalImage();
if (img.IsOk()) {
LocalFileName filename = set->newFileName(_("decoded_image"), _(".png")); // a new unique name in the package
img.SaveFile(set->nameOut(filename), wxBITMAP_TYPE_PNG);
value->filename = filename;
}
img.SaveFile(set->nameOut(filename), wxBITMAP_TYPE_PNG);
value->filename = filename;
}
}
}
}
}
return j < out.size();
}
}
bool CardListBase::parseData(bool ignore_cards_from_own_card_list) {
wxBusyCursor wait;
wxDataFormat format = drop_target->data_object->GetReceivedFormat();
wxDataObject *data = drop_target->data_object->GetObject(format);
wxDataObject *data = drop_target->data_object->GetObject(format);
vector<CardP> new_cards;
if (CardsDataObject* card_data = dynamic_cast<CardsDataObject*>(data)) {
if (CardsDataObject* card_data = dynamic_cast<CardsDataObject*>(data)) {
String id = ignore_cards_from_own_card_list ? drop_target->ignored_id : _("");
card_data->getCards(set, id, new_cards);
}
@@ -374,25 +374,25 @@ bool CardListBase::parseData(bool ignore_cards_from_own_card_list) {
{
case wxDF_FILENAME:
{
wxFileDataObject* file_data = static_cast<wxFileDataObject*>(data);
wxArrayString filenames = file_data->GetFilenames();
wxFileDataObject* file_data = static_cast<wxFileDataObject*>(data);
wxArrayString filenames = file_data->GetFilenames();
parseFiles(filenames, new_cards);
}
break;
break;
case wxDF_PNG:
{
wxImageDataObject* image_data = static_cast<wxImageDataObject*>(data);
Image image = image_data->GetImage();
wxImageDataObject* image_data = static_cast<wxImageDataObject*>(data);
Image image = image_data->GetImage();
parseImage(image, new_cards);
}
break;
break;
case wxDF_BITMAP:
{
{
wxBitmapDataObject* bitmap_data = static_cast<wxBitmapDataObject*>(data);
wxBitmap bitmap = bitmap_data->GetBitmap();
Image image = bitmap.ConvertToImage();
wxBitmap bitmap = bitmap_data->GetBitmap();
Image image = bitmap.ConvertToImage();
parseImage(image, new_cards);
}
break;
@@ -401,24 +401,24 @@ bool CardListBase::parseData(bool ignore_cards_from_own_card_list) {
case wxDF_TEXT:
case wxDF_HTML:
{
wxTextDataObject* text_data = static_cast<wxTextDataObject*>(data);
String text = text_data->GetText();
wxTextDataObject* text_data = static_cast<wxTextDataObject*>(data);
String text = text_data->GetText();
if (!parseUrl(text, new_cards)) parseText(text, new_cards);
}
break;
default:
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;
}
if (new_cards.size() > 0) {
set->actions.addAction(make_unique<AddCardAction>(ADD, *set, new_cards));
return true;
}
return false;
}
}
// --------------------------------------------------- : CardListBase : Card linking
@@ -624,18 +624,18 @@ void CardListBase::onChar(wxKeyEvent& ev) {
} else {
ev.Skip();
}
}
}
void CardListBase::onBeginDrag(wxListEvent&) {
vector<CardP> cards;
getSelection(cards);
String transaction_id = generate_uid();
CardsOnClipboard* card_data = new CardsOnClipboard(set, transaction_id, cards);
drop_target->ignored_id = transaction_id;
void CardListBase::onBeginDrag(wxListEvent&) {
vector<CardP> cards;
getSelection(cards);
String transaction_id = generate_uid();
CardsOnClipboard* card_data = new CardsOnClipboard(set, transaction_id, cards);
drop_target->ignored_id = transaction_id;
wxDropSource drag_source(this);
drag_source.SetData(*card_data);
drag_source.DoDragDrop(wxDrag_CopyOnly);
}
}
void CardListBase::onDrag(wxMouseEvent& ev) {
ev.Skip();
@@ -679,31 +679,31 @@ void CardListBase::onItemActivate(wxListEvent& ev) {
// ----------------------------------------------------------------------------- : CardListDropTarget
CardListDropTarget::CardListDropTarget(CardListBase* card_list)
: card_list(card_list), ignored_id(_(""))
{
data_object = new wxDataObjectComposite();
CardListDropTarget::CardListDropTarget(CardListBase* card_list)
: card_list(card_list), ignored_id(_(""))
{
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);
SetDataObject(data_object);
}
CardListDropTarget::~CardListDropTarget() {}
wxDragResult CardListDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult defaultDragResult) {
if (!GetData()) return wxDragNone;
if (!card_list->parseData(true)) return wxDragError;
wxDragResult CardListDropTarget::OnData(wxCoord x, wxCoord y, wxDragResult defaultDragResult) {
if (!GetData()) return wxDragNone;
if (!card_list->parseData(true)) return wxDragError;
return wxDragCopy;
}
}
// ----------------------------------------------------------------------------- : CardListBase : Event table
BEGIN_EVENT_TABLE(CardListBase, ItemList)
EVT_LIST_COL_RIGHT_CLICK (wxID_ANY, CardListBase::onColumnRightClick)
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_LIST_BEGIN_DRAG (wxID_ANY, CardListBase::onBeginDrag)
EVT_CHAR ( CardListBase::onChar)
EVT_MOTION ( CardListBase::onDrag)
+17 -17
View File
@@ -12,7 +12,7 @@
#include <gui/control/item_list.hpp>
#include <data/card.hpp>
#include <data/set.hpp>
#include <wx/dnd.h>
#include <wx/dnd.h>
DECLARE_POINTER_TYPE(ChoiceField);
DECLARE_POINTER_TYPE(Field);
@@ -70,8 +70,8 @@ public:
inline void setCard(const CardP& card, bool event = false) { selectItem(card, true, event); }
// --------------------------------------------------- : Clipboard and Drag'n'Drop
CardListDropTarget* drop_target;
CardListDropTarget* drop_target;
bool canCut() const override;
bool canCopy() const override;
@@ -81,20 +81,20 @@ public:
bool doCopy() override;
bool doCopyCardAndLinkedCards();
bool doPaste() override;
bool doDelete() override;
bool doDelete() override;
// Try to perform a bulk operation, return success
bool doAddCSV();
bool doAddJSON();
bool doAddJSON();
bool doBulkModification();
// Look for cards inside some given data
bool parseData(bool ignore_cards_from_own_card_list);
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);
// Look for cards inside some given data
bool parseData(bool ignore_cards_from_own_card_list);
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
@@ -170,7 +170,7 @@ private:
void onBeginDrag (wxListEvent&);
void onDrag (wxMouseEvent&);
void onContextMenu (wxContextMenuEvent&);
};
};
// ----------------------------------------------------------------------------- : Drag'n'Drop
@@ -179,12 +179,12 @@ public:
CardListDropTarget(CardListBase* card_list);
~CardListDropTarget();
wxDragResult OnData(wxCoord x, wxCoord y, wxDragResult defaultDragResult) override;
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
wxDataObjectComposite* data_object; ///< the object that acquires the data from the Clipboard or a Drag'n'Drop
String ignored_id; ///< the id of the transaction we need to ignore (the one coming from our own card_list)
private:
private:
CardListBase* card_list; ///< the card list we are the drop target of
};
+10 -10
View File
@@ -42,22 +42,22 @@ void PackageList::drawItem(DC& dc, int x, int y, size_t item) {
if (d->image.Ok()) {
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
wxFont font = wxFont(11,wxFONTFAMILY_SWISS,wxFONTSTYLE_NORMAL,wxFONTWEIGHT_BOLD,false,_("Arial"));
dc.SetFont(font);
dc.GetTextExtent(capitalize(d->package->short_name), &w, &h);
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);
// draw full name
// draw full name
font.SetPointSize(9);
font.SetWeight(wxFONTWEIGHT_NORMAL);
dc.SetFont(font);
dc.GetTextExtent(d->package->full_name, &w, &h);
if (w > item_size.x) {
font.SetPointSize(max(7,9*item_size.x/w));
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);
}
dc.GetTextExtent(d->package->full_name, &w, &h);
}
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 + 9-font.GetPointSize()));
dc.DestroyClippingRegion();
@@ -92,9 +92,9 @@ void PackageList::showData(const String& pattern) {
Image img;
Bitmap bmp;
if (stream && image_load_file(img, *stream)) {
bmp = Bitmap(img);
if (bmp.GetWidth() > 150 || bmp.GetHeight() > 150) {
queue_message(MESSAGE_WARNING, _ERROR_1_("icon too large", p->relativeFilename()));
bmp = Bitmap(img);
if (bmp.GetWidth() > 150 || bmp.GetHeight() > 150) {
queue_message(MESSAGE_WARNING, _ERROR_1_("icon too large", p->relativeFilename()));
}
}
// add to list
+3 -3
View File
@@ -34,11 +34,11 @@ private:
bool ProcessEvent(wxEvent& ev) override {
int t = ev.GetEventType();
bool is_tab = false;
try {
bool is_tab = false;
try {
is_tab = dynamic_cast<wxKeyEvent&>(ev).GetUnicodeKey() == WXK_TAB;
} catch (...) {}
if ( is_tab
if ( is_tab
|| t == wxEVT_LEFT_DOWN || t == wxEVT_RIGHT_DOWN
|| t == wxEVT_MOVE
|| t == wxEVT_MENU_HIGHLIGHT || t == wxEVT_MENU_OPEN
+1 -1
View File
@@ -482,7 +482,7 @@ void ImageSlicePreview::draw(DC& dc) {
assert(image.GetWidth() == slice.target_size.GetWidth() && image.GetHeight() == slice.target_size.GetHeight());
mask.setAlpha(image);
if (image.HasAlpha()) {
// create bitmap
// create bitmap
int width = image.GetWidth(), height = image.GetHeight();
bitmap = Bitmap(width, height);
wxMemoryDC mdc; mdc.SelectObject(bitmap);
+6 -6
View File
@@ -38,7 +38,7 @@ public:
Color background; ///< Color for areas outside the source image
bool allow_outside; ///< Allow the slice to extend outside the source image? TODO: This currently crashes
bool aspect_fixed; ///< Aspect ratio lock?
// Filters
bool sharpen;
int sharpen_amount;
@@ -71,9 +71,9 @@ public:
Image getImage() const;
// --------------------------------------------------- : Previously Used Settings
static map<String, String> previously_used_settings_path; // map from cardname to filename
static map<pair<String, String>, pair<wxRect, int>> previously_used_settings_value; // map from filename+cardname pair to settings
static map<String, String> previously_used_settings_path; // map from cardname to filename
static map<pair<String, String>, pair<wxRect, int>> previously_used_settings_value; // map from filename+cardname pair to settings
// --------------------------------------------------- : Data
private:
@@ -133,8 +133,8 @@ public:
/// Notify that the slice was updated
void update();
int grid;
int grid;
// --------------------------------------------------- : Data
private:
+1 -1
View File
@@ -219,7 +219,7 @@ void PackageUpdateList::initItems() {
if (p && p->description->icon.Ok()) { // it has an icon
ti.setIcon(p->description->icon);
} else if (p) { // it doesn't have an icon (yet)
ti.setIcon(load_resource_image(_("installer_package")));
ti.setIcon(load_resource_image(_("installer_package")));
String icon_url = settings.darkMode() && !p->description->dark_icon_url.empty() ? p->description->dark_icon_url : p->description->icon_url;
if (!icon_url.empty()) {
// download icon
+16 -16
View File
@@ -168,10 +168,10 @@ GlobalPreferencesPage::GlobalPreferencesPage(Window* parent)
}
n++;
}
open_sets_in_new_window->SetValue(settings.open_sets_in_new_window);
dark_mode->Append(_LABEL_("dark mode system"));
dark_mode->Append(_LABEL_("dark mode no"));
dark_mode->Append(_LABEL_("dark mode yes"));
open_sets_in_new_window->SetValue(settings.open_sets_in_new_window);
dark_mode->Append(_LABEL_("dark mode system"));
dark_mode->Append(_LABEL_("dark mode no"));
dark_mode->Append(_LABEL_("dark mode yes"));
dark_mode->SetSelection((int)settings.dark_mode_type);
// init sizer
wxSizer* s = new wxBoxSizer(wxVERTICAL);
@@ -285,22 +285,22 @@ TransfersPreferencesPage::TransfersPreferencesPage(Window* parent) : Preferences
non_normal_export = new wxCheckBox(this, wxID_ANY, _BUTTON_("rotation export"));
bleed_export = new wxCheckBox(this, wxID_ANY, _BUTTON_("bleed export"));
notes_export = new wxCheckBox(this, wxID_ANY, _BUTTON_("notes export"));
export_scale = new wxChoice (this, ID_EXPORT_ZOOM);
export_scale = new wxChoice (this, ID_EXPORT_ZOOM);
allow_image_download = new wxCheckBox(this, wxID_ANY, _BUTTON_("allow image download"));
import_scale = new wxChoice (this, ID_IMPORT_ZOOM);
// set values
non_normal_export-> SetValue(!settings.default_stylesheet_settings.card_normal_export());
bleed_export-> SetValue( settings.default_stylesheet_settings.card_bleed_export());
notes_export-> SetValue( settings.default_stylesheet_settings.card_notes_export());
export_scale->Append(_LABEL_("export around 300"));
export_scale->Append(_LABEL_("export force 300"));
export_scale->Append(_LABEL_("export force 150"));
export_scale->Append(_LABEL_("export force 150"));
for (int i : Settings::scale_choices) {
export_scale->Append(String::Format(_("%d%%"), i));
}
int default_export_scale = settings.default_stylesheet_settings.export_scale_selection();
}
int default_export_scale = settings.default_stylesheet_settings.export_scale_selection();
if (default_export_scale < 0 || default_export_scale > (int)export_scale->GetCount() - 1) default_export_scale = 0;
export_scale->SetSelection(default_export_scale);
@@ -311,13 +311,13 @@ TransfersPreferencesPage::TransfersPreferencesPage(Window* parent) : Preferences
import_scale->Append(_LABEL_("export force 150"));
for (int i : Settings::scale_choices) {
import_scale->Append(String::Format(_("%d%%"), i));
}
int default_import_scale = settings.import_scale_selection;
}
int default_import_scale = settings.import_scale_selection;
if (default_import_scale < 0 || default_import_scale > import_scale->GetCount() - 1) default_import_scale = 0;
import_scale->SetSelection(default_import_scale);
// init sizers
wxSizer* s = new wxBoxSizer(wxVERTICAL);
wxSizer* s = new wxBoxSizer(wxVERTICAL);
wxSizer* s2 = new wxStaticBoxSizer(wxVERTICAL, this, _LABEL_("export"));
s2->Add(new wxStaticText(this, wxID_ANY, _LABEL_("export desc")), 0, wxALL & ~wxLEFT, 4);
wxSizer* s3 = new wxBoxSizer(wxHORIZONTAL);
@@ -348,9 +348,9 @@ void TransfersPreferencesPage::store() {
settings.default_stylesheet_settings.card_normal_export = !non_normal_export->GetValue();
settings.default_stylesheet_settings.card_bleed_export = bleed_export->GetValue();
settings.default_stylesheet_settings.card_notes_export = notes_export->GetValue();
settings.default_stylesheet_settings.export_scale_selection = export_scale->GetSelection();
settings.default_stylesheet_settings.export_scale_selection = export_scale->GetSelection();
settings.allow_image_download = allow_image_download->GetValue();
settings.allow_image_download = allow_image_download->GetValue();
settings.import_scale_selection = import_scale->GetSelection();
}
+33 -33
View File
@@ -22,64 +22,64 @@ DECLARE_POINTER_TYPE(PrintJob);
class PrintJob : public IntrusivePtrBase<PrintJob> {
public:
PrintJob(const SetP& set, const vector<CardP>& cards)
PrintJob(const SetP& set, const vector<CardP>& cards)
: set(set), cards(cards) {
default_size_mm.width = set->stylesheet->card_width * 25.4 / set->stylesheet->card_dpi;
default_size_mm.height = set->stylesheet->card_height * 25.4 / set->stylesheet->card_dpi;
threshold_top = 0.75 * default_size_mm.width;
threshold_bottom = 0.1;
threshold_size = RealSize(0.03 * default_size_mm.width, 0.03 * default_size_mm.height);
default_size_mm.height = set->stylesheet->card_height * 25.4 / set->stylesheet->card_dpi;
threshold_top = 0.75 * default_size_mm.width;
threshold_bottom = 0.1;
threshold_size = RealSize(0.03 * default_size_mm.width, 0.03 * default_size_mm.height);
}
SetP set;
vector<CardP> cards; ///< Cards selected by the user for print
RealSize default_size_mm; ///< Size of a card with the default stylesheet in millimetres, without bleed
// align cards that are at most this far appart in millimeters
double threshold_top;
// consider cards that are this close to already be aligned
double threshold_bottom;
// snap cards that are within this to the default size
// align cards that are at most this far appart in millimeters
double threshold_top;
// consider cards that are this close to already be aligned
double threshold_bottom;
// snap cards that are within this to the default size
RealSize threshold_size;
struct CardLayout {
CardLayout(const CardP& card, const RealSize& size_mm, const RealSize& size_px, double bleed_size_px, Radians rotation)
: card(card), size_mm(size_mm), size_px(size_px), bleed_size_px(bleed_size_px), rot(rotation), other_face(-1) {}
struct CardLayout {
CardLayout(const CardP& card, const RealSize& size_mm, const RealSize& size_px, double bleed_size_px, Radians rotation)
: card(card), size_mm(size_mm), size_px(size_px), bleed_size_px(bleed_size_px), rot(rotation), other_face(-1) {}
bool operator<(const CardLayout& that) const {
return size_mm.width > that.size_mm.width; // put the widest cards first
}
}
CardP card;
RealSize size_mm;
RealSize size_px;
double bleed_size_px;
Radians rot;
double bleed_size_px;
Radians rot;
RealSize pos;
int other_face;
};
};
void init(const RealSize& page_size);
RealSize page_size; ///< Size of a page in millimetres
vector<CardLayout> card_layouts; ///< Locations of the cards on the pages
vector<CardLayout> sorted_layouts; ///< Same as card_layouts, but sorted from widest to narrowest
vector<vector<CardLayout>> page_layouts; ///< The CardLayout grouped by page
vector<RealSize> page_margins; ///< The empty space on the sides of the pages
vector<CardLayout> card_layouts; ///< Locations of the cards on the pages
vector<CardLayout> sorted_layouts; ///< Same as card_layouts, but sorted from widest to narrowest
vector<vector<CardLayout>> page_layouts; ///< The CardLayout grouped by page
vector<RealSize> page_margins; ///< The empty space on the sides of the pages
/// Is this job uninitialized?
inline bool empty() const { return page_layouts.empty(); }
inline bool empty() const { return page_layouts.empty(); }
private:
// calculate the width and height of each card in millimeters
// calculate the width and height of each card in millimeters
void measure_cards();
CardLayout measure_card(const CardP& card);
// calculate where the cards go on the pages
// calculate where the cards go on the pages
void layout_cards();
// if two cards are almost aligned, align them
// if two cards are almost aligned, align them
void align_cards();
// center the cards on the middle of each page
// center the cards on the middle of each page
void center_cards();
};
+7 -7
View File
@@ -56,8 +56,8 @@ CardsPanel::CardsPanel(Window* parent, int id)
collapse_notes = new HoverButton(nodes_panel, ID_COLLAPSE_NOTES, _("btn_collapse"), Color(), false);
collapse_notes->SetExtraStyle(wxWS_EX_PROCESS_UI_UPDATES);
filter = nullptr;
editor->next_in_tab_order = card_list;
SetDropTarget(card_list->drop_target);
editor->next_in_tab_order = card_list;
SetDropTarget(card_list->drop_target);
wxFont font = link_relation_1->GetFont();
font.SetWeight(wxFONTWEIGHT_BOLD);
link_relation_1->SetFont(font);
@@ -152,8 +152,8 @@ CardsPanel::CardsPanel(Window* parent, int id)
menuFormat = new wxMenu();
add_menu_item_tr(menuFormat, ID_FORMAT_BOLD, settings.darkModePrefix() + "bold", "bold", wxITEM_CHECK);
add_menu_item_tr(menuFormat, ID_FORMAT_ITALIC, settings.darkModePrefix() + "italic", "italic", wxITEM_CHECK);
add_menu_item_tr(menuFormat, ID_FORMAT_UNDERLINE, settings.darkModePrefix() + "underline", "underline", wxITEM_CHECK);
add_menu_item_tr(menuFormat, ID_FORMAT_ITALIC, settings.darkModePrefix() + "italic", "italic", wxITEM_CHECK);
add_menu_item_tr(menuFormat, ID_FORMAT_UNDERLINE, settings.darkModePrefix() + "underline", "underline", wxITEM_CHECK);
add_menu_item_tr(menuFormat, ID_FORMAT_STRIKETHROUGH, settings.darkModePrefix() + "strikethrough", "strikethrough", wxITEM_CHECK);
add_menu_item_tr(menuFormat, ID_FORMAT_SYMBOL, settings.darkModePrefix() + "symbol", "symbols", wxITEM_CHECK);
add_menu_item_tr(menuFormat, ID_FORMAT_REMINDER, settings.darkModePrefix() + "reminder", "reminder_text", wxITEM_CHECK);
@@ -286,8 +286,8 @@ wxMenu* CardsPanel::makeAddCardsSubmenu(bool add_single_card_option) {
void CardsPanel::initUI(wxToolBar* tb, wxMenuBar* mb) {
// Toolbar
add_tool_tr(tb, ID_FORMAT_BOLD, settings.darkModePrefix() + "bold", "bold", false, wxITEM_CHECK);
add_tool_tr(tb, ID_FORMAT_ITALIC, settings.darkModePrefix() + "italic", "italic", false, wxITEM_CHECK);
add_tool_tr(tb, ID_FORMAT_UNDERLINE, settings.darkModePrefix() + "underline", "underline", false, wxITEM_CHECK);
add_tool_tr(tb, ID_FORMAT_ITALIC, settings.darkModePrefix() + "italic", "italic", false, wxITEM_CHECK);
add_tool_tr(tb, ID_FORMAT_UNDERLINE, settings.darkModePrefix() + "underline", "underline", false, wxITEM_CHECK);
add_tool_tr(tb, ID_FORMAT_STRIKETHROUGH, settings.darkModePrefix() + "strikethrough", "strikethrough", false, wxITEM_CHECK);
add_tool_tr(tb, ID_FORMAT_SYMBOL, settings.darkModePrefix() + "symbol", "symbols", false, wxITEM_CHECK);
add_tool_tr(tb, ID_FORMAT_REMINDER, settings.darkModePrefix() + "reminder", "reminder_text", false, wxITEM_CHECK);
@@ -455,7 +455,7 @@ void CardsPanel::onCommand(int id) {
}
case ID_CARD_AND_LINK_COPY:
card_list->doCopyCardAndLinkedCards();
break;
break;
case ID_CARD_BULK:
card_list->doBulkModification();
break;
+3 -3
View File
@@ -103,9 +103,9 @@ private:
bool notes_below_editor;
/// Update card counts
void updateCardCounts();
int selected_cards_count = 0;
int filtered_cards_count = 0;
void updateCardCounts();
int selected_cards_count = 0;
int filtered_cards_count = 0;
int total_cards_count = 0;
/// Move the notes panel below the editor or below the card list
void updateNotesPosition();
+4 -4
View File
@@ -35,8 +35,8 @@ void SetInfoPanel::onChangeSet() {
void SetInfoPanel::initUI(wxToolBar* tb, wxMenuBar* mb) {
// Toolbar
add_tool_tr(tb, ID_FORMAT_BOLD, settings.darkModePrefix() + "bold", "bold", false, wxITEM_CHECK);
add_tool_tr(tb, ID_FORMAT_ITALIC, settings.darkModePrefix() + "italic", "italic", false, wxITEM_CHECK);
add_tool_tr(tb, ID_FORMAT_UNDERLINE, settings.darkModePrefix() + "underline", "underline", false, wxITEM_CHECK);
add_tool_tr(tb, ID_FORMAT_ITALIC, settings.darkModePrefix() + "italic", "italic", false, wxITEM_CHECK);
add_tool_tr(tb, ID_FORMAT_UNDERLINE, settings.darkModePrefix() + "underline", "underline", false, wxITEM_CHECK);
add_tool_tr(tb, ID_FORMAT_STRIKETHROUGH, settings.darkModePrefix() + "strikethrough", "strikethrough", false, wxITEM_CHECK);
add_tool_tr(tb, ID_FORMAT_SYMBOL, settings.darkModePrefix() + "symbol", "symbols", false, wxITEM_CHECK);
add_tool_tr(tb, ID_FORMAT_REMINDER, settings.darkModePrefix() + "reminder", "reminder_text", false, wxITEM_CHECK);
@@ -44,8 +44,8 @@ void SetInfoPanel::initUI(wxToolBar* tb, wxMenuBar* mb) {
// Menus
auto menuFormat = new wxMenu();
add_menu_item_tr(menuFormat, ID_FORMAT_BOLD, settings.darkModePrefix() + "bold", "bold", wxITEM_CHECK);
add_menu_item_tr(menuFormat, ID_FORMAT_ITALIC, settings.darkModePrefix() + "italic", "italic", wxITEM_CHECK);
add_menu_item_tr(menuFormat, ID_FORMAT_UNDERLINE, settings.darkModePrefix() + "underline", "underline", wxITEM_CHECK);
add_menu_item_tr(menuFormat, ID_FORMAT_ITALIC, settings.darkModePrefix() + "italic", "italic", wxITEM_CHECK);
add_menu_item_tr(menuFormat, ID_FORMAT_UNDERLINE, settings.darkModePrefix() + "underline", "underline", wxITEM_CHECK);
add_menu_item_tr(menuFormat, ID_FORMAT_STRIKETHROUGH, settings.darkModePrefix() + "strikethrough", "strikethrough", wxITEM_CHECK);
add_menu_item_tr(menuFormat, ID_FORMAT_SYMBOL, settings.darkModePrefix() + "symbol", "symbols", wxITEM_CHECK);
add_menu_item_tr(menuFormat, ID_FORMAT_REMINDER, settings.darkModePrefix() + "reminder", "reminder_text", wxITEM_CHECK);
+22 -22
View File
@@ -185,21 +185,21 @@ protected:
private:
GameP game;
bool show_empty;
vector<StatsDimensionP> dimensions; ///< Dimensions, sorted by position_hint
vector<StatsDimensionP> dimensions; ///< Dimensions, sorted by position_hint
static const int NAME_COLUMN_WIDTH = 210;
static const int DIMENSION_COLUMN_WIDTH = 18;
static const int COLUMN_HEIGHT = 23;
static const int COLUMN_HEIGHT = 23;
DECLARE_EVENT_TABLE();
void onMotion(wxMouseEvent& ev) {
void onMotion(wxMouseEvent& ev) {
wxFrame* frame = dynamic_cast<wxFrame*>(wxGetTopLevelParent(this));
if (frame) frame->SetStatusText(dimensions[findItem(ev)]->description.get());
if (frame) frame->SetStatusText(dimensions[findItem(ev)]->description.get());
}
void onMouseLeave(wxMouseEvent& ev) {
void onMouseLeave(wxMouseEvent& ev) {
wxFrame* frame = dynamic_cast<wxFrame*>(wxGetTopLevelParent(this));
if (frame) frame->SetStatusText(String());
if (frame) frame->SetStatusText(String());
}
};
@@ -243,11 +243,11 @@ void StatDimensionList::drawItem(DC& dc, int x, int y, size_t item) {
}
StatsDimension& dim = *dimensions.at(item - show_empty);
// draw icon
if(!dim.icon.Ok()) {
String filename = dim.icon_filename;
if(!dim.icon.Ok()) {
String filename = dim.icon_filename;
if (settings.darkMode() && !dim.dark_icon_filename.empty()) {
filename = dim.dark_icon_filename;
}
}
if (!filename.empty()) {
auto file = game->openIn(filename);
Image img(*file);
@@ -493,12 +493,12 @@ void StatsPanel::showCategory(const GraphType* prefer_layout) {
dim->groups.empty() ? nullptr : &dim->groups
)
);
}
// find global_script values
vector<ScriptValueP> global_values;
Context& global_ctx = set->getContext();
ScriptValueP global_ctx_value = global_ctx.getVariableOpt("global_value");
for (size_t d = 0 ; d < dims.size() ; ++d) {
}
// find global_script values
vector<ScriptValueP> global_values;
Context& global_ctx = set->getContext();
ScriptValueP global_ctx_value = global_ctx.getVariableOpt("global_value");
for (size_t d = 0 ; d < dims.size() ; ++d) {
auto& dim = dims[d];
try {
ScriptValueP global_value = dim->global_script.invoke(global_ctx);
@@ -513,7 +513,7 @@ void StatsPanel::showCategory(const GraphType* prefer_layout) {
Context& ctx = set->getContext(set->cards[i]);
GraphElementP e = make_intrusive<GraphElement>(i);
bool show = true;
for (size_t d = 0 ; d < dims.size() ; ++d) {
for (size_t d = 0 ; d < dims.size() ; ++d) {
auto& dim = dims[d];
ctx.setVariable("global_value", global_values[d]);
try {
@@ -534,8 +534,8 @@ void StatsPanel::showCategory(const GraphType* prefer_layout) {
assert(e->values.size() == dims.size());
d.elements.push_back(e);
}
}
// restore old global value if any
}
// restore old global value if any
if (global_ctx_value) global_ctx.setVariable("global_value", global_ctx_value);
// split lists
size_t dim_id = 0;
@@ -590,14 +590,14 @@ void StatsPanel::filterCards() {
BEGIN_EVENT_TABLE(StatsPanel, wxPanel)
EVT_GRAPH_SELECT(wxID_ANY, StatsPanel::onGraphSelect)
END_EVENT_TABLE()
END_EVENT_TABLE()
#if USE_DIMENSION_LISTS
#if USE_DIMENSION_LISTS
BEGIN_EVENT_TABLE(StatDimensionList, GalleryList)
EVT_MOTION(StatDimensionList::onMotion)
EVT_LEAVE_WINDOW(StatDimensionList::onMouseLeave)
END_EVENT_TABLE()
#endif
#endif
// ----------------------------------------------------------------------------- : Selection
+1 -1
View File
@@ -200,7 +200,7 @@ END_EVENT_TABLE()
DropDownChoiceList::DropDownChoiceList(Window* parent, bool is_submenu, ValueViewer& cve, ChoiceField::ChoiceP group)
: DropDownChoiceListBase(parent, is_submenu, cve, group)
{
{
// determine if slider
if (itemCount() > 1 && field().is_slider) {
is_slider = true;
+7 -7
View File
@@ -51,17 +51,17 @@ bool ImageValueEditor::onLeftDClick(const RealPoint&, wxMouseEvent&) {
void ImageValueEditor::sliceImage(const Image& image, const String& filename, const String& cardname) {
if (!image.Ok()) return;
// determine import scale based on the user's settings.
double import_scale = 1.0;
StyleSheetP stylesheet = editor().getCard()->stylesheet;
if (!stylesheet) stylesheet = editor().getSet()->stylesheet;
if (stylesheet) import_scale = settings.importScaleSettingsFor(*stylesheet);
RealSize target_size = RealSize(style().getSize() * import_scale);
target_size = RealSize((int)target_size.width, (int)target_size.height);
double import_scale = 1.0;
StyleSheetP stylesheet = editor().getCard()->stylesheet;
if (!stylesheet) stylesheet = editor().getSet()->stylesheet;
if (stylesheet) import_scale = settings.importScaleSettingsFor(*stylesheet);
RealSize target_size = RealSize(style().getSize() * import_scale);
target_size = RealSize((int)target_size.width, (int)target_size.height);
// mask
GeneratedImage::Options options((int)target_size.width, (int)target_size.height, &parent.getStylePackage(), &parent.getLocalPackage());
AlphaMask mask;
style().mask.getNoCache(options, mask);
// slice
// slice
ImageSliceWindow s(wxGetTopLevelParent(&editor()), image, filename, cardname, target_size, mask);
// clicked ok?
if (s.ShowModal() == wxID_OK) {
+1 -1
View File
@@ -44,7 +44,7 @@ void SymbolValueEditor::drawButton(RotatedDC& dc, int button, const String& text
double y = 0;
// draw button
draw_button(&editor(), dc.getDC(), dc.trRectToBB(RealRect(x,y,width,height)), false, down, true);
// draw text
// draw text
dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
RealSize text_size = dc.GetTextExtent(text);
dc.DrawText(text, align_in_rect((Alignment)(ALIGN_BOTTOM | ALIGN_CENTER), text_size, RealRect(x, y, width,height*0.9)));
+1 -1
View File
@@ -96,7 +96,7 @@ int MSE::OnRun() {
cli.init();
package_manager.init();
settings.read();
SetAppearance((Appearance)settings.dark_mode_type);
SetAppearance((Appearance)settings.dark_mode_type);
the_locale = Locale::byName(settings.locale);
nag_about_ascii_version();
+1 -1
View File
@@ -11,7 +11,7 @@
// ----------------------------------------------------------------------------- : CompoundTextElement
void CompoundTextElement::draw(RotatedDC& dc, double scale, const RealRect& rect, const double* xs, DrawWhat what, size_t start, size_t end, bool native_look) const {
void CompoundTextElement::draw(RotatedDC& dc, double scale, const RealRect& rect, const double* xs, DrawWhat what, size_t start, size_t end, bool native_look) const {
for (auto const& e : children) {
size_t start_ = max(start, e->start);
size_t end_ = min(end, e->end);
+7 -7
View File
@@ -19,15 +19,15 @@ void FontTextElement::draw(RotatedDC& dc, double scale, const RealRect& rect, co
if (!text.empty() && text.GetChar(text.size() - 1) == _('\n')) {
text = text.substr(0, text.size() - 1); // don't draw last \n
}
// draw
Color font_color = font->color;
RealSize margin(0, 0);
if (native_look) {
font->color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
margin = RealSize(1., 0);
// draw
Color font_color = font->color;
RealSize margin(0, 0);
if (native_look) {
font->color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
margin = RealSize(1., 0);
}
dc.SetFont(*font, scale);
dc.DrawTextWithShadow(text, *font, rect.position() + margin);
dc.DrawTextWithShadow(text, *font, rect.position() + margin);
if (native_look) font->color = font_color;
}
+8 -8
View File
@@ -21,8 +21,8 @@ bool ChoiceValueViewer::prepare(RotatedDC& dc) {
}
void ChoiceValueViewer::draw(RotatedDC& dc) {
drawFieldBorder(dc);
if (style().render_style & RENDER_HIDDEN) return;
// render background
if (style().render_style & RENDER_HIDDEN) return;
// render background
if (nativeLook()) {
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
dc.SetPen(*wxTRANSPARENT_PEN);
@@ -107,17 +107,17 @@ void draw_choice_viewer(RotatedDC& dc, ValueViewer& viewer, ChoiceStyle& style,
Alignment text_align = style.alignment;
if (style.render_style & RENDER_IMAGE) {
text_align = ALIGN_MIDDLE_LEFT; // can't align both text and image in the same way
}
}
Font& font = style.font;
Color font_color = font.color;
if (viewer.nativeLook()) {
font.color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
margin += 1.;
Color font_color = font.color;
if (viewer.nativeLook()) {
font.color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
margin += 1.;
}
dc.SetFont(font, 1.0);
RealSize size = dc.GetTextExtent(text);
RealPoint text_pos = align_in_rect(text_align, size, dc.getInternalRect()) + RealSize(margin, 0);
dc.DrawTextWithShadow(text, font, text_pos);
dc.DrawTextWithShadow(text, font, text_pos);
if (viewer.nativeLook()) font.color = font_color;
}
}
+2 -2
View File
@@ -29,12 +29,12 @@ void ColorValueViewer::draw(RotatedDC& dc) {
break;
}
}
}
}
// draw background
dc.SetPen(*wxTRANSPARENT_PEN);
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
dc.DrawRectangle(RealRect(40, 0, dc.getWidth()-40, dc.getHeight()));
// draw color
// draw color
dc.SetPen(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
dc.SetBrush(value().value());
dc.DrawRectangle(RealRect(0, 0, 40, dc.getHeight()));
+12 -12
View File
@@ -24,13 +24,13 @@ bool MultipleChoiceValueViewer::prepare(RotatedDC& dc) {
void MultipleChoiceValueViewer::draw(RotatedDC& dc) {
drawFieldBorder(dc);
if (style().render_style & RENDER_HIDDEN) return;
RealPoint pos = align_in_rect(style().alignment, RealSize(0,0), dc.getInternalRect());
// render background
RealPoint pos = align_in_rect(style().alignment, RealSize(0,0), dc.getInternalRect());
// render background
if (nativeLook()) {
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
dc.SetPen(*wxTRANSPARENT_PEN);
dc.DrawRectangle(RealRect(0, 0, dc.getWidth(), dc.getHeight()));
}
}
// selected choices
vector<String> selected;
value().get(selected);
@@ -44,7 +44,7 @@ void MultipleChoiceValueViewer::draw(RotatedDC& dc) {
if (active) select_it++;
drawChoice(dc, pos, choice, active);
}
} else if (style().render_style & RENDER_LIST) {
} else if (style().render_style & RENDER_LIST) {
// render only selected choices
FOR_EACH(choice, selected) {
drawChoice(dc, pos, choice);
@@ -76,21 +76,21 @@ void MultipleChoiceValueViewer::drawChoice(RotatedDC& dc, RealPoint& pos, const
}
}
if (style().render_style & RENDER_TEXT) {
// draw text
// draw text
Font& font = style().font;
Color font_color = font.color;
RealSize margin(0, 0);
if (nativeLook()) {
font.color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
margin = RealSize(1., 0);
Color font_color = font.color;
RealSize margin(0, 0);
if (nativeLook()) {
font.color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
margin = RealSize(1., 0);
}
String text = tr(getStylePackage(), choice, capitalize_sentence);
dc.SetFont(font,1);
RealSize text_size = dc.GetTextExtent(text);
RealPoint text_pos = align_in_rect(ALIGN_MIDDLE_LEFT, text_size, RealRect(pos.x + size.width + 1, pos.y, 0,size.height)) + margin;
RealPoint text_pos = align_in_rect(ALIGN_MIDDLE_LEFT, text_size, RealRect(pos.x + size.width + 1, pos.y, 0,size.height)) + margin;
dc.DrawTextWithShadow(text, font, text_pos);
size = add_horizontal(size, text_size);
if (nativeLook()) font.color = font_color;
if (nativeLook()) font.color = font_color;
}
// next position
pos = move_in_direction(style().direction, pos, size, style().spacing);
+10 -10
View File
@@ -43,9 +43,9 @@ void PackageChoiceValueViewer::initItems() {
}
void PackageChoiceValueViewer::draw(RotatedDC& dc) {
drawFieldBorder(dc);
// draw background
if (nativeLook()) {
drawFieldBorder(dc);
// draw background
if (nativeLook()) {
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
dc.SetPen(*wxTRANSPARENT_PEN);
dc.DrawRectangle(RealRect(0, 0, dc.getWidth(), dc.getHeight()));
@@ -67,16 +67,16 @@ void PackageChoiceValueViewer::draw(RotatedDC& dc) {
if (image.Ok()) {
dc.DrawBitmap(image, RealPoint(0,0));
}
// draw text
// draw text
Font& font = style().font;
Color font_color = font.color;
RealSize margin(0, 0);
if (nativeLook()) {
font.color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
margin = RealSize(1., 0);
Color font_color = font.color;
RealSize margin(0, 0);
if (nativeLook()) {
font.color = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT);
margin = RealSize(1., 0);
}
dc.SetFont(font, 1.0);
RealPoint pos = align_in_rect(ALIGN_MIDDLE_LEFT, RealSize(0, dc.GetCharHeight()), dc.getInternalRect()) + RealSize(17., 0) + margin;
dc.DrawTextWithShadow(text, font, pos);
dc.DrawTextWithShadow(text, font, pos);
if (nativeLook()) font.color = font_color;
}
+3 -3
View File
@@ -20,9 +20,9 @@ bool TextValueViewer::prepare(RotatedDC& dc) {
}
void TextValueViewer::draw(RotatedDC& dc) {
drawFieldBorder(dc);
// draw background
if (nativeLook()) {
drawFieldBorder(dc);
// draw background
if (nativeLook()) {
dc.SetBrush(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
dc.SetPen(*wxTRANSPARENT_PEN);
dc.DrawRectangle(RealRect(0, 0, dc.getWidth(), dc.getHeight()));
+109 -109
View File
@@ -764,7 +764,7 @@ SCRIPT_FUNCTION(get_card_export_settings) {
ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(input.get());
ScriptObject<Set*>* s = dynamic_cast<ScriptObject<Set*>*>(set.get());
if (s && c) {
Settings::ExportSettings card_settings = settings.exportSettingsFor(s->getValue()->stylesheetFor(c->getValue()));
Settings::ExportSettings card_settings = settings.exportSettingsFor(s->getValue()->stylesheetFor(c->getValue()));
ScriptCustomCollectionP ret(new ScriptCustomCollection());
ret->value.push_back(to_script(lround(card_settings.zoom * 100)));
ret->value.push_back(to_script(lround(rad_to_deg(card_settings.angle_radians))));
@@ -782,148 +782,148 @@ SCRIPT_FUNCTION(get_card_from_uid) {
SCRIPT_FUNCTION(get_cards_from_link) {
SCRIPT_PARAM_C(Set*, set);
SCRIPT_PARAM_C(ScriptValueP, input);
CardP input_card = nullptr;
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
input_card = ic->getValue();
}
else if (input->type() == SCRIPT_STRING) {
input_card = Card::getCardFromUid(*set, input->toString());
}
if (!input_card) {
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
return script_nil;
SCRIPT_PARAM_C(ScriptValueP, input);
CardP input_card = nullptr;
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
input_card = ic->getValue();
}
else if (input->type() == SCRIPT_STRING) {
input_card = Card::getCardFromUid(*set, input->toString());
}
if (!input_card) {
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
return script_nil;
}
SCRIPT_PARAM(String, linked_relation);
ScriptCustomCollectionP ret(new ScriptCustomCollection());
vector<CardP> other_cards = input_card->getLinkedCardsFromLink(*set, linked_relation, true);
if (other_cards.size() > 0) {
FOR_EACH(other_card, other_cards) {
ret->value.push_back(to_script(other_card));
}
ScriptCustomCollectionP ret(new ScriptCustomCollection());
vector<CardP> other_cards = input_card->getLinkedCardsFromLink(*set, linked_relation, true);
if (other_cards.size() > 0) {
FOR_EACH(other_card, other_cards) {
ret->value.push_back(to_script(other_card));
}
}
else if (set->game->card_links_alt_names.find(linked_relation) != set->game->card_links_alt_names.end()) {
other_cards = input_card->getLinkedCardsFromLink(*set, set->game->card_links_alt_names[linked_relation], true);
FOR_EACH(other_card, other_cards) {
ret->value.push_back(to_script(other_card));
}
}
else if (set->game->card_links_alt_names.find(linked_relation) != set->game->card_links_alt_names.end()) {
other_cards = input_card->getLinkedCardsFromLink(*set, set->game->card_links_alt_names[linked_relation], true);
FOR_EACH(other_card, other_cards) {
ret->value.push_back(to_script(other_card));
}
}
return ret;
}
}
SCRIPT_FUNCTION(get_front_face) {
SCRIPT_PARAM_C(Set*, set);
SCRIPT_PARAM_C(ScriptValueP, input);
CardP input_card = nullptr;
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
input_card = ic->getValue();
}
else if (input->type() == SCRIPT_STRING) {
input_card = Card::getCardFromUid(*set, input->toString());
}
if (!input_card) {
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
return script_nil;
}
vector<CardP> other_cards = input_card->getLinkedCardsFromLink(*set, "Front Face", true);
if (other_cards.size() == 0) return script_nil;
SCRIPT_PARAM_C(ScriptValueP, input);
CardP input_card = nullptr;
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
input_card = ic->getValue();
}
else if (input->type() == SCRIPT_STRING) {
input_card = Card::getCardFromUid(*set, input->toString());
}
if (!input_card) {
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
return script_nil;
}
vector<CardP> other_cards = input_card->getLinkedCardsFromLink(*set, "Front Face", true);
if (other_cards.size() == 0) return script_nil;
if (other_cards.size() > 1) queue_message(MESSAGE_WARNING, _ERROR_1_("multiple front faces", input_card->identification()));
SCRIPT_RETURN(other_cards[0]);
}
SCRIPT_FUNCTION(get_back_face) {
SCRIPT_PARAM_C(Set*, set);
SCRIPT_PARAM_C(ScriptValueP, input);
CardP input_card = nullptr;
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
input_card = ic->getValue();
}
else if (input->type() == SCRIPT_STRING) {
input_card = Card::getCardFromUid(*set, input->toString());
}
if (!input_card) {
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
return script_nil;
}
vector<CardP> other_cards = input_card->getLinkedCardsFromLink(*set, "Back Face", true);
if (other_cards.size() == 0) return script_nil;
SCRIPT_PARAM_C(ScriptValueP, input);
CardP input_card = nullptr;
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
input_card = ic->getValue();
}
else if (input->type() == SCRIPT_STRING) {
input_card = Card::getCardFromUid(*set, input->toString());
}
if (!input_card) {
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
return script_nil;
}
vector<CardP> other_cards = input_card->getLinkedCardsFromLink(*set, "Back Face", true);
if (other_cards.size() == 0) return script_nil;
if (other_cards.size() > 1) queue_message(MESSAGE_WARNING, _ERROR_1_("multiple back faces", input_card->identification()));
SCRIPT_RETURN(other_cards[0]);
}
SCRIPT_FUNCTION(add_link) {
SCRIPT_PARAM_C(Set*, set);
SCRIPT_PARAM_C(ScriptValueP, input);
CardP input_card = nullptr;
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
input_card = ic->getValue();
}
else if (input->type() == SCRIPT_STRING) {
input_card = Card::getCardFromUid(*set, input->toString());
}
if (!input_card) {
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
return script_nil;
SCRIPT_PARAM_C(ScriptValueP, input);
CardP input_card = nullptr;
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
input_card = ic->getValue();
}
SCRIPT_PARAM(ScriptValueP, linked_card);
else if (input->type() == SCRIPT_STRING) {
input_card = Card::getCardFromUid(*set, input->toString());
}
if (!input_card) {
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
return script_nil;
}
SCRIPT_PARAM(ScriptValueP, linked_card);
CardP other_card = nullptr;
if (ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(linked_card.get())) {
other_card = c->getValue();
}
else if (linked_card->type() == SCRIPT_STRING) {
other_card = Card::getCardFromUid(*set, linked_card->toString());
}
if (!other_card) {
queue_message(MESSAGE_WARNING, _ERROR_("could not find linked"));
return script_nil;
if (ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(linked_card.get())) {
other_card = c->getValue();
}
else if (linked_card->type() == SCRIPT_STRING) {
other_card = Card::getCardFromUid(*set, linked_card->toString());
}
if (!other_card) {
queue_message(MESSAGE_WARNING, _ERROR_("could not find linked"));
return script_nil;
}
SCRIPT_PARAM(String, selected_relation);
SCRIPT_PARAM(String, linked_relation);
input_card->link(*set, other_card, selected_relation, linked_relation);
SCRIPT_PARAM(String, linked_relation);
input_card->link(*set, other_card, selected_relation, linked_relation);
SCRIPT_RETURN(other_card);
}
SCRIPT_FUNCTION(remove_links) {
SCRIPT_PARAM_C(Set*, set);
ScriptCustomCollectionP ret(new ScriptCustomCollection());
SCRIPT_PARAM_C(ScriptValueP, input);
CardP input_card = nullptr;
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
input_card = ic->getValue();
}
else if (input->type() == SCRIPT_STRING) {
input_card = Card::getCardFromUid(*set, input->toString());
}
if (!input_card) {
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
return ret;
}
SCRIPT_PARAM_C(ScriptValueP, input);
CardP input_card = nullptr;
if (ScriptObject<CardP>* ic = dynamic_cast<ScriptObject<CardP>*>(input.get())) {
input_card = ic->getValue();
}
else if (input->type() == SCRIPT_STRING) {
input_card = Card::getCardFromUid(*set, input->toString());
}
if (!input_card) {
queue_message(MESSAGE_ERROR, _ERROR_("could not find input"));
return ret;
}
vector<CardP> other_cards;
SCRIPT_PARAM_DEFAULT(ScriptValueP, linked_card, script_nil);
if (linked_card != script_nil) {
SCRIPT_PARAM_DEFAULT(ScriptValueP, linked_card, script_nil);
if (linked_card != script_nil) {
CardP other_card = nullptr;
if (ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(linked_card.get())) {
other_card = c->getValue();
}
else if (linked_card->type() == SCRIPT_STRING) {
other_card = Card::getCardFromUid(*set, linked_card->toString());
}
if (!other_card) {
queue_message(MESSAGE_WARNING, _ERROR_("could not find linked"));
}
else other_cards.push_back(other_card);
if (ScriptObject<CardP>* c = dynamic_cast<ScriptObject<CardP>*>(linked_card.get())) {
other_card = c->getValue();
}
else if (linked_card->type() == SCRIPT_STRING) {
other_card = Card::getCardFromUid(*set, linked_card->toString());
}
if (!other_card) {
queue_message(MESSAGE_WARNING, _ERROR_("could not find linked"));
}
else other_cards.push_back(other_card);
}
SCRIPT_PARAM_DEFAULT(ScriptValueP, linked_relation, script_nil);
if (linked_relation != script_nil) {
if (linked_relation->type() == SCRIPT_STRING) {
vector<CardP> other_other_cards = input_card->getLinkedCardsFromLink(*set, linked_relation->toString(), true);
other_cards.insert(other_cards.end(), other_other_cards.begin(), other_other_cards.end());
if (linked_relation != script_nil) {
if (linked_relation->type() == SCRIPT_STRING) {
vector<CardP> other_other_cards = input_card->getLinkedCardsFromLink(*set, linked_relation->toString(), true);
other_cards.insert(other_cards.end(), other_other_cards.begin(), other_other_cards.end());
}
}
input_card->unlink(other_cards);
FOR_EACH(other_card, other_cards) {
ret->value.push_back(to_script(other_card));
}
}
input_card->unlink(other_cards);
FOR_EACH(other_card, other_cards) {
ret->value.push_back(to_script(other_card));
}
return ret;
}
+9 -9
View File
@@ -29,16 +29,16 @@ SCRIPT_FUNCTION(new_card) {
// create a new card object
CardP new_card = make_intrusive<Card>(*game);
// iterate on the given key/value pairs
SCRIPT_PARAM(ScriptValueP, input);
// check for a stylesheet first, since other things depend on it
SCRIPT_PARAM(ScriptValueP, input);
// check for a stylesheet first, since other things depend on it
ScriptValueP it = input->makeIterator();
ScriptValueP key;
while (ScriptValueP value = it->next(&key)) {
assert(key);
if (key == script_nil || value == script_nil) continue;
String key_name = key->toString();
if (set_stylesheet_container(*game, new_card, value, key_name, ignore_field_not_found)) break;
}
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)) {
@@ -60,7 +60,7 @@ SCRIPT_FUNCTION(new_card) {
ScriptValueP script_input = field->import_script.invoke(ctx, true);
// if the script result is a collection, iterate on the key/value pairs
// treat the keys as field names and the values as what to populate those fields with
if (script_input->type() == SCRIPT_COLLECTION) {
if (script_input->type() == SCRIPT_COLLECTION) {
// check for a stylesheet first, since other things depend on it
ScriptValueP script_it = script_input->makeIterator();
ScriptValueP script_key;
@@ -68,8 +68,8 @@ SCRIPT_FUNCTION(new_card) {
assert(script_key);
if (script_key == script_nil || script_value == script_nil) continue;
String script_key_name = script_key->toString();
if (set_stylesheet_container(*game, new_card, script_value, script_key_name, ignore_field_not_found)) break;
}
if (set_stylesheet_container(*game, new_card, script_value, script_key_name, ignore_field_not_found)) break;
}
// iterate on the rest of the key/value pairs given by the script
script_it = script_input->makeIterator();
while (ScriptValueP script_value = script_it->next(&script_key)) {
@@ -103,7 +103,7 @@ SCRIPT_FUNCTION(new_card) {
ScriptValueP ctx_card = ctx.getVariableOpt(SCRIPT_VAR_card);
ctx.setVariable(SCRIPT_VAR_card, to_script(new_card));
ScriptValueP script_input = game->import_script.invoke(ctx, true);
if (script_input->type() == SCRIPT_COLLECTION) {
if (script_input->type() == SCRIPT_COLLECTION) {
// check for a stylesheet first, since other things depend on it
ScriptValueP script_it = script_input->makeIterator();
ScriptValueP script_key;
@@ -111,7 +111,7 @@ SCRIPT_FUNCTION(new_card) {
assert(script_key);
if (script_key == script_nil || script_value == script_nil) continue;
String script_key_name = script_key->toString();
if (set_stylesheet_container(*game, new_card, script_value, script_key_name, ignore_field_not_found)) break;
if (set_stylesheet_container(*game, new_card, script_value, script_key_name, ignore_field_not_found)) break;
}
// iterate on the rest of the key/value pairs given by the script
script_it = script_input->makeIterator();
+1 -1
View File
@@ -440,7 +440,7 @@ SCRIPT_FUNCTION(write_image_file) {
// get image
Image img;
SCRIPT_PARAM(Set*, set);
SCRIPT_PARAM_C(ScriptValueP, input);
SCRIPT_PARAM_C(ScriptValueP, input);
ScriptObject<CardP>* card = dynamic_cast<ScriptObject<CardP>*>(input.get()); // is the input a card or image?
if (card) {
SCRIPT_PARAM_DEFAULT(double, zoom, 100.0);
+4 -4
View File
@@ -39,12 +39,12 @@ SCRIPT_FUNCTION(to_card_image) {
if (use_user_settings) {
// Use the User's Preferences for Export Zoom, Angle and Bleed settings.
Settings::ExportSettings card_settings = settings.exportSettingsFor(set->stylesheetFor(input));
zoom = card_settings.zoom;
angle = card_settings.angle_radians;
zoom = card_settings.zoom;
angle = card_settings.angle_radians;
bleed = card_settings.bleed_pixels;
} else {
// Use the provided (or defaulted) Zoom, Angle and Bleed.
zoom = zoom / 100.0;
zoom = zoom / 100.0;
angle = deg_to_rad(angle);
}
return make_intrusive<ArbitraryImage>(export_image(set, input, true, zoom, angle, bleed));
@@ -56,7 +56,7 @@ SCRIPT_FUNCTION(import_image) {
return make_intrusive<ImportedImage>(set, input);
}
SCRIPT_FUNCTION(download_image) {
SCRIPT_FUNCTION(download_image) {
if (!settings.allow_image_download) return script_nil;
SCRIPT_PARAM(Set*, set);
SCRIPT_PARAM(String, input);
+12 -12
View File
@@ -106,11 +106,11 @@ void CachedScriptableImage::generateCached(const GeneratedImage::Options& option
*size = cached_size;
// do the options match?
Radians relative_rotation = options.angle + rad360 - cached_options_angle;
bool ok = almost_equal(cached_options_size.width, options.width) &&
almost_equal(cached_options_size.height, options.height) &&
almost_equal(cached_options_zoom, options.zoom) &&
cached_options_preserve_aspect == options.preserve_aspect &&
cached_options_saturate == options.saturate &&
bool ok = almost_equal(cached_options_size.width, options.width) &&
almost_equal(cached_options_size.height, options.height) &&
almost_equal(cached_options_zoom, options.zoom) &&
cached_options_preserve_aspect == options.preserve_aspect &&
cached_options_saturate == options.saturate &&
is_straight(relative_rotation); // we only need an {0,90,180,270} degree rotation compared to the cached one, this doesn't reduce image quality
// image or bitmap?
if (*combine <= COMBINE_NORMAL) {
@@ -131,19 +131,19 @@ void CachedScriptableImage::generateCached(const GeneratedImage::Options& option
*image = cached_i;
return;
}
}
// store the options as they were asked for
cached_options_size = RealSize(options.width, options.height);
cached_options_zoom = options.zoom;
cached_options_preserve_aspect = options.preserve_aspect;
cached_options_saturate = options.saturate;
}
// store the options as they were asked for
cached_options_size = RealSize(options.width, options.height);
cached_options_zoom = options.zoom;
cached_options_preserve_aspect = options.preserve_aspect;
cached_options_saturate = options.saturate;
cached_options_angle = options.angle;
// hack(part1): temporarily set angle to 0, do actual rotation after applying mask
const_cast<GeneratedImage::Options&>(options).angle = 0;
// generate
cached_i = generate(options);
assert(cached_i.Ok());
const_cast<GeneratedImage::Options&>(options).angle = cached_options_angle;
const_cast<GeneratedImage::Options&>(options).angle = cached_options_angle;
// store the size as it actually is (may have been changed by conform_image() when we generated the image)
*size = cached_size = RealSize(options.width, options.height);
if (mask) {
+1 -1
View File
@@ -100,7 +100,7 @@ public:
private:
Image cached_i; ///< The cached image
Bitmap cached_b; ///< *or* the cached bitmap
RealSize cached_size; ///< The size of the image before rotating, may be different than the options size
RealSize cached_size; ///< The size of the image before rotating, may be different than the options size
/// The options as they were last specified
RealSize cached_options_size = RealSize(-1.0,-1.0);
double cached_options_zoom;
+2 -2
View File
@@ -223,8 +223,8 @@ public:
inline ScriptConcatCollection(ScriptValueP a, ScriptValueP b) : a(a), b(b) {}
ScriptValueP getMember(const String& name) const override;
ScriptValueP getIndex(int index) const override;
ScriptValueP makeIterator() const override;
ScriptValueP getA() { return a; }
ScriptValueP makeIterator() const override;
ScriptValueP getA() { return a; }
ScriptValueP getB() { return b; }
int itemCount() const override { return a->itemCount() + b->itemCount(); }
+2 -2
View File
@@ -106,8 +106,8 @@ public:
/// Actions to be undone.
vector<unique_ptr<Action>> undo_actions;
/// Actions to be redone
vector<unique_ptr<Action>> redo_actions;
vector<unique_ptr<Action>> redo_actions;
private:
/// Point at which the file was saved, corresponds to the top of the undo stack at that point
const Action* save_point;
+16 -16
View File
@@ -20,7 +20,7 @@
// ----------------------------------------------------------------------------- : Package : outside
IMPLEMENT_DYNAMIC_ARG(Package*, writing_package, nullptr);
IMPLEMENT_DYNAMIC_ARG(Package*, clipboard_package, nullptr);
IMPLEMENT_DYNAMIC_ARG(Package*, clipboard_package, nullptr);
Package::Package()
: zipStream (nullptr)
@@ -98,8 +98,8 @@ void Package::save(bool remove_unused) {
saveAs(filename, remove_unused);
}
void Package::saveAs(const String& name, bool remove_unused, bool as_directory) {
if (Set* s = dynamic_cast<Set*>(this)) s->referenceActionStackFiles();
void Package::saveAs(const String& name, bool remove_unused, bool as_directory) {
if (Set* s = dynamic_cast<Set*>(this)) s->referenceActionStackFiles();
// type of package
if (wxDirExists(name) || as_directory) {
saveToDirectory(name, remove_unused, false);
@@ -111,7 +111,7 @@ void Package::saveAs(const String& name, bool remove_unused, bool as_directory)
reopen();
}
void Package::saveCopy(const String& name) {
void Package::saveCopy(const String& name) {
if (Set* s = dynamic_cast<Set*>(this)) s->referenceActionStackFiles();
saveToZipfile(name, true, true);
clearKeepFlag();
@@ -227,15 +227,15 @@ unique_ptr<wxInputStream> Package::openIn(const String& file) {
FileInfos::iterator it = files.find(normalize_internal_filename(file));
if (it == files.end()) {
// does it look like a relative filename?
if (size_t pos = filename.find(_(".mse-")) != String::npos) {
// check for nested folder
pos = filename.find_last_of(_("/\\"));
String nestedFilename = filename + filename.SubString(pos, filename.size()) + wxFileName::GetPathSeparator() + file;
if (size_t pos = filename.find(_(".mse-")) != String::npos) {
// check for nested folder
pos = filename.find_last_of(_("/\\"));
String nestedFilename = filename + filename.SubString(pos, filename.size()) + wxFileName::GetPathSeparator() + file;
if (wxFileExists(nestedFilename)) {
throw PackageError(_ERROR_1_("nested folder", filename));
}
else {
throw PackageError(_ERROR_2_("file not found package like", file, filename));
else {
throw PackageError(_ERROR_2_("file not found package like", file, filename));
}
}
}
@@ -593,14 +593,14 @@ Packaged::Packaged()
, fully_loaded(true)
{}
unique_ptr<wxInputStream> Packaged::openIconFile() {
String filename = icon_filename;
unique_ptr<wxInputStream> Packaged::openIconFile() {
String filename = icon_filename;
if (!dark_icon_filename.empty()) {
if (settings.darkMode()) {
wxFileName fn (dark_icon_filename);
if (settings.darkMode()) {
wxFileName fn (dark_icon_filename);
String extension = fn.GetExt();
filename = dark_icon_filename.Replace(extension, _("")) + "_dark" + extension;
}
filename = dark_icon_filename.Replace(extension, _("")) + "_dark" + extension;
}
else filename = dark_icon_filename;
}
if (!filename.empty()) {
+44 -44
View File
@@ -13,7 +13,7 @@
#include <util/error.hpp>
#include <util/file_utils.hpp>
#include <util/vcs.hpp>
#include <data/format/file_to_text.h>
#include <data/format/file_to_text.h>
class Package;
class wxFileInputStream;
@@ -55,70 +55,70 @@ public:
inline String const& toStringForKey() const { return fn; }
/// Retreive a rect from a filename
inline static void getExternalRect(const String& filename, wxRect& rect_out, int& degrees_out) {
inline static void getExternalRect(const String& filename, wxRect& rect_out, int& degrees_out) {
size_t first = filename.find(_("<mse-crop-data>"));
if (first == String::npos) return;
size_t last = filename.find(_("</mse-crop-data>"), first + 15);
if (last == String::npos) return;
String string = filename.substr(first + 15, last - (first + 15));
if (string.empty()) return;
size_t last = filename.find(_("</mse-crop-data>"), first + 15);
if (last == String::npos) return;
String string = filename.substr(first + 15, last - (first + 15));
if (string.empty()) return;
size_t divider = string.find(_("-"));
if (divider == String::npos) return;
if (divider == 0) return;
int x;
if(!string.substr(0, divider).ToInt(&x)) return;
string = string.substr(divider + 1);
int x;
if(!string.substr(0, divider).ToInt(&x)) return;
string = string.substr(divider + 1);
divider = string.find(_("-"));
if (divider == String::npos) return;
if (divider == 0) return;
int y;
if(!string.substr(0, divider).ToInt(&y)) return;
string = string.substr(divider + 1);
int y;
if(!string.substr(0, divider).ToInt(&y)) return;
string = string.substr(divider + 1);
divider = string.find(_("-"));
if (divider == String::npos) return;
if (divider == 0) return;
int width;
if(!string.substr(0, divider).ToInt(&width)) return;
string = string.substr(divider + 1);
int width;
if(!string.substr(0, divider).ToInt(&width)) return;
string = string.substr(divider + 1);
divider = string.find(_("-"));
if (divider == String::npos) return;
if (divider == 0) return;
int height;
if(!string.substr(0, divider).ToInt(&height)) return;
string = string.substr(divider + 1);
if(!string.ToInt(&degrees_out)) return;
int height;
if(!string.substr(0, divider).ToInt(&height)) return;
string = string.substr(divider + 1);
if(!string.ToInt(&degrees_out)) return;
rect_out = wxRect(x, y, width, height);
}
inline void getExternalRect(wxRect& rect_out, int& degrees_out) {
getExternalRect(fn, rect_out, degrees_out);
}
inline void getExternalRect(wxRect& rect_out, int& degrees_out) {
getExternalRect(fn, rect_out, degrees_out);
}
/// Retreive an image from a filename
inline static Image getExternalImage(const String& filename) {
Image img;
inline static Image getExternalImage(const String& filename) {
Image img;
size_t first = filename.find(_("<mse-image-data>"));
if (first == String::npos) return img;
size_t last = filename.find(_("</mse-image-data>"), first + 16);
if (last == String::npos) return img;
std::string s = filename.substr(first + 16, last - (first + 16)).ToStdString();
if (s.empty()) return img;
const std::string& temppath = (wxFileName::CreateTempFileName(_("mse")) + _(".png")).ToStdString();
UTF8ToFile(temppath, s);
img.LoadFile(temppath, wxBITMAP_TYPE_PNG);
wxRemoveFile(temppath);
wxRemoveFile(temppath.substr(0, temppath.size() - 4));
return img;
size_t last = filename.find(_("</mse-image-data>"), first + 16);
if (last == String::npos) return img;
std::string s = filename.substr(first + 16, last - (first + 16)).ToStdString();
if (s.empty()) return img;
const std::string& temppath = (wxFileName::CreateTempFileName(_("mse")) + _(".png")).ToStdString();
UTF8ToFile(temppath, s);
img.LoadFile(temppath, wxBITMAP_TYPE_PNG);
wxRemoveFile(temppath);
wxRemoveFile(temppath.substr(0, temppath.size() - 4));
return img;
}
inline Image getExternalImage() {
return getExternalImage(fn);
}
inline Image getExternalImage() {
return getExternalImage(fn);
}
private:
LocalFileName(const wxString& fn) : fn(fn) {}
+8 -8
View File
@@ -357,14 +357,14 @@ template <> void Reader::handle(Vector2D& vec) {
template <> void Reader::handle(LocalFileName& f) {
f = LocalFileName::fromReadString(this->getValue());
}
String Reader::addLocale(String filename) {
return filename + _("_") + settings.locale;
}
String Reader::addDark(String filename) {
return filename + (settings.darkMode() ? _("_dark") : _(""));
}
String Reader::addLocale(String filename) {
return filename + _("_") + settings.locale;
}
String Reader::addDark(String filename) {
return filename + (settings.darkMode() ? _("_dark") : _(""));
}
// ----------------------------------------------------------------------------- : EnumReader
+5 -5
View File
@@ -116,10 +116,10 @@ public:
/// The package being read from
inline Packaged* getPackage() const { return package; }
String addLocale(String);
String addDark(String);
String addLocale(String);
String addDark(String);
/// Set the value that will be returned by the next getValue() call (may mess up the state of the reader)
inline void setValue(const String& value) { state = UNHANDLED; previous_value = value; };
@@ -181,7 +181,7 @@ private:
/** Maybe the key is "include file" */
template <typename T>
void unknownKey(T& v) {
if (key == _("include_file") || key == _("include_localized_file") || key == _("include_dark_file")) {
if (key == _("include_file") || key == _("include_localized_file") || key == _("include_dark_file")) {
value = key == _("include_localized_file") ? addLocale(value) : key == _("include_dark_file") ? addDark(value) : value;
auto [stream, include_package] = openFileFromPackage(package, value);
Reader sub_reader(*stream, include_package, value, ignore_invalid);
+1 -1
View File
@@ -16,7 +16,7 @@
using boost::tribool;
// ----------------------------------------------------------------------------- : Writer
Writer::Writer(OutputStream& output)
: indentation(0)
, output(output)
+1 -1
View File
@@ -73,7 +73,7 @@ public:
// special behaviour
void handle(const GameP&);
void handle(const StyleSheetP&);
/// Indentation of the current block
int indentation;
private:
+1 -1
View File
@@ -115,7 +115,7 @@ enum ChildMenuID {
ID_CARD_ADD_CSV_BROWSE,
ID_CARD_ADD_JSON,
ID_CARD_ADD_JSON_ARRAY,
ID_CARD_ADD_JSON_BROWSE,
ID_CARD_ADD_JSON_BROWSE,
ID_CARD_BULK,
ID_CARD_BULK_TYPE,
ID_CARD_BULK_FIELD,