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