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
+10 -10
View File
@@ -33,16 +33,16 @@ A heirachical file can contain a reference to another file:
Where filename must be an absolute or relative [[type:filename]].
That file is included literally into the current one; except for indentation, the included file never escapes from the level the 'include file' line is on.
If the file to be included can vary depending on the locale that is selected, use:
>>>include localized file: <em>filename</em>
MSE will take the filename and add "_" followed by the name of the currently selected locale at the end of it.
So for example, if the locale used is the folder "en.mse-locale", the file that will be included is "filename_en"
You must provide a version of the file for each locale found in the data folder, even if it is simply a copy of the english one.
If the file to be included can vary depending on if dark mode is selected, use:
>>>include dark file: <em>filename</em>
MSE will take the filename and add "_dark" if the app is currently in dark mode. If not, then nothing is added to the filename.
If the file to be included can vary depending on the locale that is selected, use:
>>>include localized file: <em>filename</em>
MSE will take the filename and add "_" followed by the name of the currently selected locale at the end of it.
So for example, if the locale used is the folder "en.mse-locale", the file that will be included is "filename_en"
You must provide a version of the file for each locale found in the data folder, even if it is simply a copy of the english one.
If the file to be included can vary depending on if dark mode is selected, use:
>>>include dark file: <em>filename</em>
MSE will take the filename and add "_dark" if the app is currently in dark mode. If not, then nothing is added to the filename.
--Example--
For example, a [[type:set]] might look like this:
+5 -5
View File
@@ -6,10 +6,10 @@ Function: new_card
Creates a new [[type:card]] object. The card is not automatically added to a set. Use the [[fun:add_card_to_set]] function for that.
The argument is a map from card field names to values, for example @new_card([name: "My Card"])@ creates a card with the name @"My Card"@, and all other fields at their default value.
The map can also contain the following built-in keys: notes, id, linked_card_1 to linked_card_4, linked_relation_1 to linked_relation_4, stylesheet, styling_data, and extra_data. For styling_data and extra_data, the value must itself be a map from field names to values. Be sure to define a stylesheet before these.
NOTE: you should use underscores instead of spaces in field names.
The map can also contain the following built-in keys: notes, id, linked_card_1 to linked_card_4, linked_relation_1 to linked_relation_4, stylesheet, styling_data, and extra_data. For styling_data and extra_data, the value must itself be a map from field names to values. Be sure to define a stylesheet before these.
NOTE: you should use underscores instead of spaces in field names.
--Parameters--
! Parameter Type Description
@@ -26,7 +26,7 @@ NOTE: you should use underscores instead of spaces in field names.
> ])
>
> # Write an image of the card to a file
> write_image_file(my_card, file: "my_card.png")
> write_image_file(my_card, file: "my_card.png")
> # Add the card to the current set
> add_card_to_set(my_card)
+1 -1
View File
@@ -14,7 +14,7 @@ This function can only be used in an [[type:export template]], when <tt>create d
--Parameters--
! Parameter Type Description
| @input@ [[type:image]] or [[type:card]] Image or Card to write to the file.
| @file@ [[type:string]] Name of the file to write to.
| @file@ [[type:string]] Name of the file to write to.
| @width@ [[type:int]] Width in pixels to use for the image, by default the size of the image is used if available.
| @height@ [[type:int]] Height in pixels to use for the image, by default the size of the image is used if available.
| @zoom@ [[type:double]] Zoom percentage to apply to the card render.
+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,